From a541a7a5cf002805e8400978599989cae134e57a Mon Sep 17 00:00:00 2001
From: Jun Ohtani
Date: Sun, 31 Dec 2023 15:36:22 +0000
Subject: [PATCH] rebuilding site Sun Dec 31 15:36:22 UTC 2023
---
atom.xml | 2 +-
blog/2023/12/31/review-2023/index.html | 2 +-
elasticsearch.json | 2 +-
index.xml | 2 +-
orama.json | 2 +-
post/index.xml | 2 +-
.../\346\214\257\343\202\212\350\277\224\343\202\212/index.xml" | 2 +-
7 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/atom.xml b/atom.xml
index 106b558448..1ca337447f 100644
--- a/atom.xml
+++ b/atom.xml
@@ -63,7 +63,7 @@ Amazonのプロダクトデータを使ってもうちょっとやろうと思
全然終わる気配がないw</p>
<p>ローカルでの開発環境などをDev containerにちょっとずつしています。
Slackのボット、検索の遊び場、このブログ環境など。Dockerが必要にはなりますが、VSCodeとDev containerで環境を隔離できるし、VSCodeの拡張もコンテナごとに入れるのもできたりと便利です。</p>
-<p>最後は、検索技術勉強会を再開したことです。再始動という感じで4年ぶり?に再開しました(<a href="https://search-tech.connpass.com/event/303330/">12月に開催した時のページ</a>)。残念ながら私は裏方をしてただけで、当日は参加できてないのですが、次回(たぶん4月くらい)は参加するつもりです。再開の声を上げてくれた<a href="https://twitter.com/takuya-b">@takuya-a</a>さんありがとう。<a href="http://bit.ly/SpeakerSearchTechTalk">絶賛スピーカーを募集中</a>です。</p>
+<p>最後は、検索技術勉強会を再開したことです。再始動という感じで4年ぶり?に再開しました(<a href="https://search-tech.connpass.com/event/303330/">12月に開催した時のページ</a>)。残念ながら私は裏方をしてただけで、当日は参加できてないのですが、次回(たぶん4月くらい)は参加するつもりです。再開の声を上げてくれた<a href="https://twitter.com/takuya_b">@takuya_a</a>さんありがとう。<a href="http://bit.ly/SpeakerSearchTechTalk">絶賛スピーカーを募集中</a>です。</p>
<h2 id="来年の抱負">来年の抱負</h2>
<p>さて、来年の抱負です。</p>
<ul>
diff --git a/blog/2023/12/31/review-2023/index.html b/blog/2023/12/31/review-2023/index.html
index 073b9d6460..a8037e569b 100644
--- a/blog/2023/12/31/review-2023/index.html
+++ b/blog/2023/12/31/review-2023/index.html
@@ -279,7 +279,7 @@ 振り返り(今年あったで
全然終わる気配がないw
ローカルでの開発環境などをDev containerにちょっとずつしています。
Slackのボット、検索の遊び場、このブログ環境など。Dockerが必要にはなりますが、VSCodeとDev containerで環境を隔離できるし、VSCodeの拡張もコンテナごとに入れるのもできたりと便利です。
-最後は、検索技術勉強会を再開したことです。再始動という感じで4年ぶり?に再開しました(12月に開催した時のページ)。残念ながら私は裏方をしてただけで、当日は参加できてないのですが、次回(たぶん4月くらい)は参加するつもりです。再開の声を上げてくれた@takuya-aさんありがとう。絶賛スピーカーを募集中です。
+最後は、検索技術勉強会を再開したことです。再始動という感じで4年ぶり?に再開しました(12月に開催した時のページ)。残念ながら私は裏方をしてただけで、当日は参加できてないのですが、次回(たぶん4月くらい)は参加するつもりです。再開の声を上げてくれた@takuya_aさんありがとう。絶賛スピーカーを募集中です。
来年の抱負
さて、来年の抱負です。
diff --git a/elasticsearch.json b/elasticsearch.json
index aed94e580e..0a7bb89019 100644
--- a/elasticsearch.json
+++ b/elasticsearch.json
@@ -1 +1 @@
-[{"contents":"今年も振り返りブログをリビングで書いています(ドミノ倒しすごいな)。 FMVのキーボードで書いているのでタイポがつらい。。。\n振り返り(2022年に書いた抱負から) まずは振り返りをと。\nフリーランス継続 今年も個人事業主として乗り越えられました。 ZOZOさんには今年も引き続きお世話になっている感じです。 そのほかにベクトル検索のお手伝いをしたり、OpenSearchを調べたりといった仕事を手伝っています。 今年も完全にリモートで作業していましたが、イベントに出かけたりできました。 来年はもう少し出かける感じになるかな? 今年はすこしのんびり仕事をしていたので、来年はもう少し仕事探さないとかな(営業しないとなあ)\nプログラミング 今年はプログラムを書いたほうかなと。 Goで個人用ですが、Slackのボットを書いてみたり(GoでSlackのボットを作った話 | @johtaniの日記 3rd | @johtani\u0026rsquo;s blog 3rd edition)、公開されているAmazonのプロダクトデータを使って検索アプリを書いてみたり。 プロダクト用のアプリを書いているわけではないですが、ちょっとずつコードを読んだり書いたりしています。\nベクトル検索まわりをさわる がっつりとまではいかないですが、Elasticsearchのベクトル検索の調査をやったりしました。 Amazonのプロダクトデータを使ってもうちょっとやろうと思いつつ、そこまでは手が回せてない感じですが。 速度という面でどうやって折り合いをつけつつ導入するのか? どういうシーンでつかうのがいいのか? どのモデル選ぶのか?とか気になることだらけ。 なんか、みなさんがどうしてるのか気になってしょうがないので、話をしてもいいよという方は連絡をもらえるとうれしいかもなぁ。 ベクトル検索とかLLMの周りの動きがはやすぎてついていけてるのかどうか。。。\n本を読む 今年は比較的読んだかも?\n単体テストの考え方/使い方 ユーザーの問題解決とプロダクトの成功を導く エンジニアのためのドキュメントライティング ザ・ダークパターン ユーザーの心や行動をあざむくデザイン これまでの仕事 これからの仕事 機械学習による検索ランキング改善ガイド ソフトウェア設計のトレードオフと誤り 初めてのGo言語 買って読んでない本ももっとあるんですが。。。\n振り返り(今年あったできごと) ここからは今年の出来事を。 今年もずっと自宅でしごとしてました。 あとは少し仕事が少なめだったのでゲームが多くなってしまったかも?(本読めばいいのに。。。)\nゲーム(ONI、ゼルダ、FactorioのSpace Exploration) Dev container導入 検索技術勉強会の再開 ゼルダの新作面白かったですね。年初はOxigen Not Includedをやっていたのに、ゼルダが出てからはご無沙汰中です。ゼルダが終わった後は、ゼルダロスになってPythonを書いたりしていたのですが、うっかりFactorioのSpace Explorationを始めてしまい大変なことに。。。 全然終わる気配がないw\nローカルでの開発環境などをDev containerにちょっとずつしています。 Slackのボット、検索の遊び場、このブログ環境など。Dockerが必要にはなりますが、VSCodeとDev containerで環境を隔離できるし、VSCodeの拡張もコンテナごとに入れるのもできたりと便利です。\n最後は、検索技術勉強会を再開したことです。再始動という感じで4年ぶり?に再開しました(12月に開催した時のページ)。残念ながら私は裏方をしてただけで、当日は参加できてないのですが、次回(たぶん4月くらい)は参加するつもりです。再開の声を上げてくれた@takuya-aさんありがとう。絶賛スピーカーを募集中です。\n来年の抱負 さて、来年の抱負です。\nフリーランス継続 プログラミング継続 ベクトル検索の使い方をいろいろ試す 本を読んだブログを書く 今年もなんとかフリーランスを継続できましたが、そろそろ営業をしないといけないのかも? ということで、外でしゃべったりもしていかないとなぁと。 あとは、検索ってどうやって導入すればいいのか?検索どうすれば改善できる?みたいなところのお手伝いをもっとしたいと思っています。 昨年出したこの本もあるので(『検索システム ― 実務者のための開発改善ガイドブック』 – 技術書出版と販売のラムダノート)、勉強会をやろうとしているところに顔を出したりしたいなあ。 外部の人を呼んで社内勉強会とかをできるというところがあれば参加したいので、声をかけてもらえればと。\nプログラミングはGo言語を触ったし、今年後半には検索の画面回りのプロダクトを触ってTypeScriptを勉強していこうかなという気になっています(なっているだけかもしれない?)。\nベクトル検索の使い方は、LLMだったりRAGだったりが世の中を席巻しているのもあり、いろんな記事が出てきて全然追いつけていません。だれか、少人数で勉強会とかやると興味ある人とかいるかなぁ? こんなブログ見つけたよ、こんな論文があったよ、こんな使い方したらよかったよとかの共有をやるとみんな楽になったりしないかなぁ?\n今年は時々出かけて移動するタイミングで書籍を読んでいました。 読んだだけになってるのもあるので、少しでもいいからブログか何かに残しとかないとな。\nさて、今年は少しゆっくりできたので、来年はもうちょっといろんなところに顔を出しつつ、新しい仕事もできるといいなぁ。 勉強会もスピーカー集めをがんばるぞと。\nということで、今年もあと少しというところで無事書き終わりました。 来年もよろしくお願いいたします。よいお年をー\n","date":1704008961,"dir":"post/2023/","id":"d869fb48cb9acba03dc639481524ee80","lang":"ja","lastmod":1704008961,"permalink":"https://blog.johtani.info/blog/2023/12/31/review-2023/","publishdate":"2023-12-31T07:49:21Z","summary":"今年も振り返りブログをリビングで書いています(ドミノ倒しすごいな)。 FMVのキーボードで書いているのでタイポがつらい。。。 振り返り(2022","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2023)"},{"contents":"この記事は、情報検索・検索技術 Advent Calendar 2023の15日目の記事です。\n昨年に続き2回目の情報検索のAdvent Calendar参戦です。\n今年は、夏にオンライン参加したBerlin Buzzwordsの「The Debate Returns (with more vectors) Which Search Engine?」というセッションでPhilippさんが話題に出したOrama searchという検索エンジンを紹介してみようと思います(Oramaが正式名称なのかな?)。\nOramaという検索エンジン 公式サイトのトップにも記載がありますが、エッジで動作する全文検索&ベクトル検索エンジンというもののようです。 なにそれ?という感じがしますが、オープンソース版のドキュメントを見るともう少しわかりやすい説明になっています。\nOrama is a fast, batteries-included, full-text and vector search engine entirely written in TypeScript, with zero dependencies.\nOramaはTypeScriptで書かれた、依存なしで利用できる検索エンジンということです(batteries-includedって初めて見たかも。「必要なものがそろってる」とかいう意味みたい(参考:英語のWikipedia))。\n以下は公式サイトにあるサンプルです。\ncreateでスキーマの定義をした検索エンジンのインスタンスを生成します。 insertで先ほど生成した検索エンジンにデータをインデックスします(後で紹介しますが、一括でインデックスするメソッドも用意されています)。 searchで検索し、検索した結果が返ってきます。 以上です。あとは、必要に応じてGUIを用意するだけです。\nimport { create, insert, search } from \u0026#39;@orama/orama\u0026#39; const db = await create({ schema: { title: \u0026#39;string\u0026#39;, director: \u0026#39;string\u0026#39;, isFavorite: \u0026#39;boolean\u0026#39;, year: \u0026#39;number\u0026#39; } }) await insert(db, { title: \u0026#39;The Prestige\u0026#39;, director: \u0026#39;Christopher Nolan\u0026#39;, isFavorite: true, year: 2006 }) const searchResults = await search(db, { term: \u0026#39;prestige\u0026#39;, where: { isFavorite: true, year: { between: [2000, 2008] } } }) サクッと動きそうですよね?依存関係がなくTypeScriptで書かれているということは静的なサイトなどでコンテンツを検索するのに使えるのでは?\nということで、自分のブログに組み込んでみました。 今回は組み込んだ時の流れと気になった点などを紹介します。 Hugoに組み込む際になるべく簡単にしたかったので、unpkg.comで公開されているJavaScriptだけを利用する形で検索ページを作ってみました。 JavaScriptやTypeScriptは不慣れなので効率がよくなかったり、間違っている点があればコメントなどをいただけると嬉しいです。\n構成 私のブログサイトはHugoで生成(参考:Hugo導入時の記事)して、GitHub Pagesとして公開しています。 現在のブログ検索にはAlgoliaを利用しているのですが、テスト目的としてOramaも使えるようにしてみました(右上のメニューでOramaをクリックすると以下で説明するOramaによる検索を試すことができます。\n今回実装してみたのは次のような流れです(日本語検索対応については後で説明します)。\nHugoでJSONのリストを生成(これまでと一緒) 1.で生成したリストをもとにNodeのスクリプトでOramaのインデックスファイルを作成 2.で作成したファイルを公開 画面で3.のファイルをダウンロードして検索 1. HugoでJSONのリストを生成(これまでと一緒) HugoでJSONのリストを生成します。Algoliaに記事を登録するのにも利用している仕組みです。 検索に利用する記事の情報を1記事を1つのオブジェクトとして出力します。1つの配列に記事ごとのオブジェクトが入っているJSONファイルになります。\n少しだけ特殊なことをしています。 ブログ記事にTagsというフィールドのありなしで処理を分岐しています。 Oramaが配列にNullを受け取った場合にうまく動かなかったので出力するJSON側で調整しています(あとで再確認してIssueあげておかないと)\n2. 1.で生成したリストをもとにNodeのスクリプトでOramaのインデックスファイルを作成 最初に紹介した公式のサンプルの場合、毎回Oramaのインスタンスを生成した後にインデックス登録の処理を行わなければいけません。 ただ、Hugoで生成したコンテンツは特に動的に更新があるわけでもないので、検索画面を表示するたびにインデックス登録するのも無駄が多い気がします。 Orama単体で最初に実装した時には、1.で作成した記事一覧のJSONをOramaで実装した検索ページのスクリプトが呼ばれたタイミングでフェッチし、insertMultiple(複数登録用のメソッド)を呼び出す実装にしていました。\nOramaでは、あらかじめ作成したOramaのデータベースを永続化・リストアするためのData Persistenceプラグインが提供されています。 インデックスに登録する処理コストはHugoでコンテンツを生成した直後に行い、検索画面では作成済みのインデックスファイルをフェッチしてリストアする形にすることにしました。インデックスと記事のJSONデータを含んだファイルになるので、元の記事一覧のJSONよりはファイルサイズが大きくなってしまいますが、処理時間も含めて考えると許容できるサイズではないかなと。\n次のスクリプトは1.で生成したJSONファイルを読み込んで、Oramaでインデックスした後にdpackというバイナリ形式でファイルに保存しています。 こののプラグインで選択できる形式は現時点ではjson、binary(デフォルト=msgpack)、dpackの3種類になります。 残念ながら今回試したところ、binaryではエラーが発生したので、dpackを使用しました。\n3. 2.で作成したファイルを公開 単にGitHub Pagesに公開しているだけです。 ブラウザが2.で作成したインデックスファイルをフェッチしてから利用するためです。\n4. 画面で3.のファイルをダウンロードして検索 あとは検索画面です(長すぎるので、styleの部分は省略しています)。\nまず、必要なライブラリなどを読み込みます(下のソースコードの1行目から14行目)。\nOramaだけであれば問題ないのですが、OramaのプラグインがOramaをモジュールとして参照しているため、importmapとして定義しています。 Oramaのプラグインがいくつか利用しているものがあったので、まとめてimportmapに定義してあります。\n次に、検索窓(search-searchbar)や検索結果(search-hits)などのHTMLタグを用意します。 ヒット件数と検索にかかった時間も取れるので、表示する場所としてstatsも用意してあります。\n22行目からが実際の処理になります。\n28行目で、手順2.で作成したインデックスのファイルをフェッチします。 32行目でフェッチしたファイルから取り出した文字列をリストアして、Oramaのインスタンスを生成します。 34行目のtokenizerに関しては日本語対応で説明します。\n48行目のquery関数がクエリの組み立て+検索の処理です。search-inputで入力されたテキストをtermとして渡して検索をしています(56行目)。 検索した結果のリストをもとに検索結果のHTMLタグを組み上げていきます。 検索結果には後述する@orama/highlightのモジュールを利用してスニペットを追加しています。\n日本語対応 残念ながらOramaは公式には日本語をサポートしていません(サポートしているスキーマに設定できるlanguageの一覧(=STEMMERSにあるものだけ指定可能)。一覧と実装分けたほうがいい気がするけど?)。 ただ、tokenize関数を変更できるようにしてくれています。これを利用して、少しトリッキーな形で日本語対応しました。\n先ほどの手順2.でOramaのcreate関数として、componentsに次のtokenizerを渡します。\nlanguageはenglishですが、日本語をtokenizeする処理に次のように書き換えました。 stemmingは今回は行わない(=用意されているstemmerを使えない)のでfalse、normalizationCacheは空のMapを用意しておかないとエラーが出るので、new Map()しています。 この設定を使ってcreateすることで、\ncomponents: { tokenizer: { language: \u0026#34;english\u0026#34;, stemming: false, normalizationCache: new Map(), tokenize: (raw) =\u0026gt; { return tokenize(raw) }, }, }, 少しわかりにくいですが、tokenizerのtokenize関数の中で呼び出しているreturn tokenize(raw)の部分はwakachigakiというライブラリのtokenize関数となっています。\nwakachigakiというライブラリ Elasticsearchなどのサーバー上で動作させる検索エンジンではkuromojiなどの辞書を内包した形態素解析器を利用するのが通常です。 ただ、今回はブラウザだけで完結した簡単な検索を行う仕組みをOramaを使って提供しようと考えました(kuromoji.jsというのもありますが、辞書のサイズがそこそこのサイズです)。 ですので、辞書ファイルのない軽量の形態素解析ライブラリとして、wakachigakiというライブラリ(=6.2Kbの軽量日本語分かち書きライブラリ)を利用してみました。\n最初はTinySegmenterの利用をしていたのですが、wakachigakiのサイトにもあるように、TypeScriptやES Moduleでも利用できる形式となっていたのでこちらに切り替えました。\n辞書もっていないため、品詞でのフィルタリングや読みを利用した処理はできませんが、日本語の文章を分かち書きしてくれます。\ntokenize関数の設定 OramaのTokenizerインタフェースのtokenizeは入力の文字列をstring[]として返すことを期待しています。 wakachigakiのtokenizeも文字列を引数にとり、string[]を返すので、そのまま呼び出すだけにしてあります。\nただ、今回のブログ検索の実装では、検索窓に入力された文字列も特に何も処理せずにtokenizeに渡す形にしています。 クエリパーサーなどを考える場合は、検索窓に入力された文字列を前処理したりする必要がありますが今回はいったんこれで。。。\ndata-persistenceはcomponentsはpersistしない 手順2.で導入した、data-persistenceプラグインですが、現在の実装ではOramaが生成したデータベース(転置インデックス)だけを永続化しています。 独自に設定したtokenizerは残念ながら含まれていませんでした。 手順4.の検索画面のコードの34行目の部分(下記)で、フェッチしたインデックスデータからrestoreした後のOramaのインスタンスのtokenizerに手順2.と同じ設定のtokenizerを設定することで検索時にも同じトークナイズがされるようになります(今の仕組みだと修正した場合には、両方のソースコードを修正しないといけないのがちょっと面倒かも?)。\ndb.tokenizer = { language: \u0026#34;english\u0026#34;, stemming: false, normalizationCache: new Map(), tokenize: (raw) =\u0026gt; { return tokenize(raw) }, } tokenizerはOramaの検索エンジンのインスタンスに紐づく設定となっているので、フィールドごとに切り替えるといったことも現在では想定されていない気がします。\nハイライト ハイライトのために、インデックスデータに単語のポジションを保存するためのプラグインも提供されています。 このポジションは検索の単語がヒットしドキュメントのどの位置に出てくるのか?をあらかじめデータとして保存しておくことで、ハイライトのたびに単語の位置を毎回計算しなくてもよくするためのものと思われます。\nこれを利用してもよかったのですが、今回は@orama/highlightというモジュールを利用することにしました。 検索にヒットしたドキュメントの元の文章と検索のキーワードを入力すると検索キーワードの周りにハイライトのHTMLタグを埋め込んでくれるライブラリを利用しました。これは普通に他でも便利かも?\n余力があればプラグインを利用した時のインデックスのサイズの違いや検索時の速度の違いを調べてみるのもいいかもしれないです。\nそのほかの機能 今回は利用していませんが、Oramaにはそのほかの機能も用意されています(公式ドキュメントの検索の紹介のページ)。詳細は公式ドキュメントをご覧ください。\nTypo tolerance Facet/Filter Vector Search Geo Search Grouping Threshold Preflight Oramaで(まだ?)できないこと 今回触ってみて、現在のOramaの実装ではできなそうなことがいくつかあったので書き出しておきます。 あくまでも現時点のことです。今後実装される可能性もあります。\nデフォルトでは、searchのtermに渡した文字列をtokenizeし、出力されたトークン列(単語の配列)のそれぞれのトークン(単語)にヒットしたドキュメントが全て検索結果に含まれます。 検索結果のドキュメントはBM25でスコアリングされるので、多くのトークンが含まれるものが上位に来る可能性が高いです。\nただ、特定の単語を含まない検索、ANDやOR検索など凝ったクエリは現在は書けないようです(Issueがある)。\nfilterは別途用意されているので、例えばファセットで表示したカテゴリで絞り込んだ状態にするといったことはできそうです。\n残課題 とりあえず日本語をなんとなく検索できるようにすることはできました。 が、気になることもいっぱいありました。 時間を見つけてTypeScriptなどを勉強しながら探っていく感じでしょうか。\nインデックスを小さくする方法 今回はブログ記事のサマリー(Hugoで生成されるSummary)でインデックスを作ったので、インデックスのサイズはまだ小さくなっています(といっても1MB超えてるけど)。ブログ記事全体を検索できるようにする場合は、インデックスファイルが大きくなります。\nこれは、OramaがデフォルトではインデックスしたJSON自体もインデックス(ドキュメントストア)に保存しているためです。 ですので、Oramaに登録したJSONデータ+検索用のインデックスがインデックスファイルとなります。 ただ、検索だけができればよい場合は、出来上がったインデックスがあればドキュメントのIDは取得できます。\n公式ドキュメントでもそのことに触れているページがあります(参考:Remote document storing)。\nまだちゃんと実装を見ていませんが、ブログ記事本体の文字列はドキュメントストアに保存しないようにすれば検索はできるが、容量が大きくならないといった工夫ができそうです。\nただ、検索結果にハイライトを含んだスニペットを表示したい場合は、コンテンツ文字列が必要になってくるので、代わりに何かしらの仕組みを考える必要が出てきます(例えばサマリー部分の文字列だけ保存しておいて、ハイライトはそこだけを対象とするなど)。\nそのほか そのほかに思いつくのはこの辺でしょうか?\nオートコンプリート:Oramaというよりも、JavaScriptやTypeScriptでうまく実装できるのか?という話のような気がしますが。。。 ファセット対応:機能としては存在していますが、今回は実装が間に合いませんでした。 Vector Search:検索キーワードのベクトルをどうやって作るのか?という問題が残りそう。コンテンツのベクトルだけで関連ページの表示みたいなことはできるかも?(動的にやる必要がないので、事前計算して各ページに埋め込むほうがよさそうだけど) Geo Search:緯度経度があるデータを探し出してこないと? relevanceの処理の変更:BM25以外に切り替えることができるかどうか(Oramaのソースとにらめっこしないといけなそう) tokenizeの改良:辞書を利用する形態素解析ライブラリやAPIを利用してみたり、「てにをは」といった1文字のひらがなを削ることで、無駄な検索ヒットを減らしてみたり。大文字小文字の正規化も必要。 検索ログの解析:検索ログを保存する仕組みなどはないので、Google AnalyticsやほかのAPIなどを用意する? まとめ ということで、Oramaという検索エンジン?ライブラリ?を利用して日本語のブログ検索を実装してみました。 まだ、機能が少ない部分もありますが、少数のデータをブラウザだけで簡単に検索できる仕組みをGitHub Pagesだけで提供することができそうです。 今回は静的なファイルだけで完結する形にしましたが、TypeScriptで利用できる簡単な検索エンジンライブラリとして使ってみるとまた別の面白さもあるかもしれないです。 まだ触っていない機能は思いついたこと(=残課題に書いたこと)もあるので、ちょっと試行錯誤してみようかなぁ。\n","date":1702566000,"dir":"post/2023/","id":"476e17b6f854414033d5cec1470774ee","lang":"ja","lastmod":1702566000,"permalink":"https://blog.johtani.info/blog/2023/12/15/introduce-orama-to-blog/","publishdate":"2023-12-15T00:00:00+09:00","summary":"この記事は、情報検索・検索技術 Advent Calendar 2023の15日目の記事です。 昨年に続き2回目の情報検索のAdvent Calendar参戦です。 今年は、夏","tags":["orama","search"],"title":"Oramaという検索エンジンでブログ検索を作ってみた"},{"contents":"PySpaアドベントカレンダーの12/08のエントリーです。昨日は渋川さんのアンラーニングで失敗した話でした。\n私は、今年は昨年の続きっぽい話を。\n音楽の再生とか停止とか 今年もリモートで仕事を継続しています。 昨年、OwnToneという音楽サーバーを導入しましたが、ミーティング開始時や終了後に音楽の停止や再生をするのに、ブラウザで操作するのはちょっと面倒です。 加えて、ミーティングする際には実際には\n音楽を止める 電気をつける といったことをっやります。 音楽再生についても\n音楽を再生する アンプの音は音楽再生用の音量にする といった複数のことを行います。\n基本的にPCの前にいるし、Slackを常に開いているからSlackのBotを作ると便利になるのでは? ということで、自分専用のSlack Botを作ってみました。\nGitHubリポジトリ 全く誰の役にも立たないけど、公開しています。\nhttps://github.com/johtani/smarthome Goで実装 知り合いに勧められたということもあり、Goをあまり触ったことがなかったので、Goでやってみました。時々新しい言語を触ってみたくなるので。。。\nコマンドパターンのような作りで、コマンド(操作)を増やしていく感じで実装してはみたのですが、この書き方がいいのかはまだよくわかっていないです。\nActionという単体の操作(例:OwnToneの一時停止)を、操作したい機器の操作ごとに作成しています。 インターフェースとしてはRunだけを定義しています。\ntype Action interface { Run() (string, error) } それらの操作(Action)をひとまとめにしたものをSubcommandという形で定義して、SlackのBotにはSubcommandの名前を送って処理を実行する形にしています。\ntype Subcommand struct { Definition actions []action.Action ignoreError bool } やりたいことを追加するタイミングで時々リファクタしたりもしていますが、基本はこんな感じです。 細かな実装はさておき、今回ボットを作るときの観点をいくつか。\n宅内ネットワーク 音楽サーバーのOwnToneもですが、YAMAHAのアンプのAPIも見つけたのでこれらの操作をボットから行っています。どちらも自宅のネットワークにあるので、今回作成したボットも同じネットワークで動作します。\n外部に公開されたHTTPのエンドポイントがあればよいのですが、今回は用意していません。 SlackのAPIではこれに対応したアプリを作るときのためにSocket Modeを用意してくれています。\nドキュメントがしっかりしているのもあり、チュートリアルなどを見つつ特に迷うことなく構築できました。\n基本的には「特定のチャンネルでボットがメンションされたら動作する」という挙動だけしか実装していないので、特に今回はこれで困ることもありませんでした(世の中の人たちはもっとすごいSlackの使い方をしていそうだけど。。。)。\n対象となるものたち ボットから操作しているのは今のところ3種類です。\nSwitchBot OwnTone YAMAHAのアンプ SwitchBot SwitchBotについては、go-siwtchbotを利用しています。 電気、エアコン、空気清浄機、サーキュレーターのオンオフをSwitchBot経由でやっています。\n室内灯の明るさのために、SwitchBot側でシーンを設定している(一番暗い明るさで電気をつける)ので、そこが少しと特殊でしょうか?\nあとは、SwitchBotの温湿度計を3つ(室内2つ、室外1つ)おいてあるので、これらの温度を表示するコマンドも用意しました。\nそれぞれの機器の電池残量(電池の絵文字の右側)を表示してます(書斎が2つあるように見えますが、温湿度計の名前なので、同じ部屋においてあります。。。温度が高いほうがデスクトップPCの近くにある)。 防水の温湿度計があるので、外の気温もわかるのは便利です。\nOwnTone JSONのAPIが用意されていますが、特にクライアントライブラリなどは用意されていません。 今回は、用意されているAPIのごく一部だけを利用するので、net/httpのClientでJSONを投げています。 必要になったらowntone/clientにメソッドを追加していく感じです。\nhttps://github.com/johtani/smarthome/blob/master/subcommand/action/owntone/client.go#L45 再生、一時停止、プレイリストの取得、音量指定あたりを実装しています。 音の出力先はAirPlay(次に出てくるYamahaのアンプ)になっています。\nあと、JSON APIのサンプルをChatGPTに渡して、「このJSONをレスポンスに受け取る処理をGoで書いてください」と聞いて処理を書いたりしました(細かいのはどう聞いたか覚えてないけど)。\nYAMAHAのアンプ ググって探してきましたが、利用しているYAMAHAのアンプにYXC(Yamaha Extented Control)と呼ばれるAPIが用意されていました。 PDFでAPIの仕様が公開されていたので、この資料とにらめっこしながら、必要そうなAPIを実行するクライアントを実装しました。 こちらは、OwnToneのAPIの処理をすでに書いた後だったので、それをもとに必要な実装を追加しただけです。\nちなみに、アンプの電源をONにするAPIは実装していません。\nOwnToneで音楽を再生する(AirPlayで信号が送られるみたい) シーン選択(Nintendo SwitchやPS5のシーンを用意している)のAPIを呼び出す という処理をすると自動で電源がONになりました。スタンバイしている状態でもAPIはリクエストを受け付ける状態になっているようです。 また、PS5のシーンを呼び出したら、PS5自体も起動するのが便利だったりします。HDMI経由で信号が飛んでるのかな? 「ミーティング開始」や「音楽停止」コマンドではアンプの電源をオフするAPIを呼び出すようにしています。\nタイポ対応 「入力間違いしちゃうんです、人間だもの。。。」\nということで、10月にタイポ対応の処理を入れてみました。 タイポ対応前の実装では、入力された文字列がコマンドの文字列と完全一致した場合にだけ、コマンドが実行される形になっていました。 結構タイポしちゃうので、完全一致で見つからない場合の処理として、入力された文字列とコマンド名のレーベンシュタイン距離が2以下のものを探し、その中で距離が一番小さな値のコマンドを実行する形にしてみました。 コマンド数はたかが知れているのでコマンドのリストを全部チェックする形にしています。 タイポするとこんな感じ。\nレーベンシュタイン距離の計算にはGo-edlibを利用しています。OSS便利ですね。\nやってよかったこと ミーティング開始時などのいくつかの手順が簡素化できたので満足しています。 SwitchBotの操作もスマホをわざわざ操作しなくてもいいですし(仕事してるとキーボードとSlackは常に使ってるし)。 また、副次的な効果として、部屋の外から電源を切り忘れていたり、エアコンの切り忘れなどの場合に、スマホから遠隔でまとめた処理ができるのが便利です。\n今後やってみたいこと こういうのがあるともうちょっと便利かもなぁ?というのもあるので今後も気が向いたらコマンドなどを追加していく予定です。 今のところこんなことやりたいなというのがいくつかあります。\nキーワードに関連する曲の再生 OwnTone自体に検索の仕組みがついているので、キーワードを受け付けてそれに関する曲を流す Flexispotの操作 ミーティングの時は立ち上がっているので、机をスタンディングの状態にしたい 電子工作しないとだめかも? Webカメラ用ライトの点灯 ミーティング時に明かりが必要なのですが、物理スイッチのOn/Off これも電子工作かな? 定期的に温度をBotに表示させるとと面白いかも? まとめ ということで、新しいプログラミング言語にも触れたし、作業環境も便利になって一石二鳥でした。 新しいプログラミング言語触るのはやっぱたのしいですね。\n","date":1701961200,"dir":"post/2023/","id":"516a7aa07f8faa6b7aa38beb5010cf8c","lang":"ja","lastmod":1701961200,"permalink":"https://blog.johtani.info/blog/2023/12/08/smarthome-bot/","publishdate":"2023-12-08T00:00:00+09:00","summary":"PySpaアドベントカレンダーの12/08のエントリーです。昨日は渋川さんのアンラーニングで失敗した話でした。 私は、今年は昨年の続きっぽい話","tags":["misc","music","bot"],"title":"GoでSlackのボットを作った話"},{"contents":"「機械学習による検索ランキング改善ガイド」を読みました。\n著者の鈴木さんより献本いただいたのを読み終わったのでレビューと、あとおまけです。\n紹介とレビュー どんな本なのか?は打田さんが書かれたブログ、「ブックレビュー:『機械学習による検索ランキング改善ガイド』 - Tomoko Uchida - Medium」に詳しく書かれているので、そちらも参考にしてもらうほうがわかりやすいと思います(丸投げ)。\n読みながらいくつかツイートしていたので、そちらも参考のために貼っておきいます。\nオライリーの検索ランキング本、負荷テストのことも書いてある、すごいhttps://t.co/YPnB6kxFY2\n\u0026mdash; Jun Ohtani (@johtani) August 28, 2023 私のレビュー わかりやすく検索の基本を紹介しつつ、本書のメインであるランキング改善について全体の流れが書かれています。 ランキング改善のやり方といっても、手法の話だけではなく、プロジェクトとしてどの様に進めていくべきなのか?また、関係するものはどんなものがあり(システムだけではなくチームについても書かれていたり)、どういう判断をもちながら運用していくのか?、負荷テストにまで言及されています。\n読んでいて特に私が気に入ったのは以下のような話でした\nランキング改善を進める前にきちんと解ける問題なのか?それ以前にやることはないのかを考えましょう マッチング改善についても少しだけ触れられているが、メインはランキングについてだと明記されている 実際に体験されたのであろう落とし穴の話 負荷テストについて1章設けてある! ハンズオンのパートでもレイテンシの話がされている 付録としてベクトル検索についても触れてある 日本語でまとまって読める本があるのは本当に幸せですよね。\nおまけ 書籍ではハンズオンで、Elasticsearchとランキング学習のプラグインであるelasticsearch-learning-to-rankを利用しています(GitHubにサンプルが公開されています)。 書籍ではElasticsearchが7.13.4、プラグインが1.5.7-es7.13.4というバージョンになっていました。\nブログを書いている時点でのElasticsearchは8.x系になっています。せっかくなので、書籍を読みながら現時点で最新のものに置き換えてみるというのをやってみました。\nElasticsearchは8.10.2が最新なのですが、ランキング学習のプラグインはサードパティ製で、1.5.8-es8.8.2が最新版となっています。 ハンズオンのサンプルコードをフォークして、以下の構成にして動くようにしてみました。\nElasticsearch : 8.8.2 learning-to-rankプラグイン : 1.5.8-es8.8.2 Kibana : 8.8.2 Python : 3.10 Elasticsearch、プラグイン、Kibanaのアップグレード Elastic社が提供しているDockerイメージが利用されているので、バージョン番号を書き換えました。 あとは、learning-to-rankプラグインのバージョンを書き換えるついでに、elasticsearch-pluginコマンドで直接ダウンロードさせる形に書き換えました。\nhttps://github.com/johtani/building-search-app-w-ml/blob/es8/part2/app/search-engine/Dockerfile\nPython3.10にアップグレード 本当は必要なかったのですが、Pythonのイメージもついでに3.10にしました。 ただ、このおかげでインストールされるXGBoostのバージョンも1系から2系に上がってしまい、XGBoostを利用してモデル生成をする処理でエラーが出るようになってしまいました。。。\n2系へのアップグレードは手間がかかりそうだということで、pipコマンドでのインストールでのバージョンを\u0026lt;2として、1系をインストールすることで回避しました。\nhttps://github.com/johtani/building-search-app-w-ml/blob/es8/part2/app/workspace/Dockerfile\nelasticsearch-pyのアップグレード Elasticsearchを8系にしたので、クライアントライブラリ側も8系に書き換えました(元は7.17以下に固定されていた)。 pipで7系に固定されていたものを外して最新のもの(8系)をインストールするようにしました。 これだけでも特に問題なく動いたのですが、「DeprecationWarning」が出ている部分が1か所だけあります(サンプルではDeprecationWarningが出力されない形になっていましたが、出力するように変更しました)。\nElastic公式のドキュメントにMigrate to 8.0というページが公開されています。Pythonクライアントのアップグレードを行う際はこちらを参考にすると指針が記載されています。\n今回のサンプルコードではsearchの時の引数としてbodyを渡していたのですが、8系のクライアントライブラリからこちらが廃止になり、queryやrescoreなど個別の引数を渡す形に変更されています(search APIのリファレンス)。 ですので、bodyを**bodyでアンパックして渡すようにしただけです。サンプルコードがわかりやすく書かれているので変更も少しで済みました。\nhttps://github.com/johtani/building-search-app-w-ml/blob/es8/part2/app/workspace/collect_responses.py#L59\n一応、これでエラーが出ないで動きました。 すべて適用した、フォークして修正したブランチはhttps://github.com/johtani/building-search-app-w-ml/tree/es8で公開しています。\nまとめ すごくわかりやすいうえに、手を動かしながらどんなデータを使ってどんなことをやるのかが体験できる良い本でした。 理論的な話だけでなく、システムとしてどういうものが必要で、どういうことをやらないといけないのか?というのがわかるのがイメージできるのは重要だと思います。\n最後は広告ですが、ランキング改善以外の検索システムについて学べる本を検索システム ― 実務者のための開発改善ガイドブック – 技術書出版と販売のラムダノート出していますので、こちらも参考書として読んでいただけるとうれしいです。\n","date":1695612744,"dir":"post/2023/","id":"7f78b02c531f09602ba4e140132d26a2","lang":"ja","lastmod":1695612744,"permalink":"https://blog.johtani.info/blog/2023/09/25/read-search-raking-guide/","publishdate":"2023-09-25T03:32:24Z","summary":"「機械学習による検索ランキング改善ガイド」を読みました。 著者の鈴木さんより献本いただいたのを読み終わったのでレビューと、あとおまけです。 紹介","tags":["読書","elasticsearch"],"title":"機械学習による検索ランキング改善ガイドを読みました"},{"contents":"趣味?(検索エンジンに関する趣味プロジェクト)でPythonのプログラムを書いています。 ベクトル検索などの確認なども含めて、Jupyter Notebookで簡単なAPIの呼び出しを書いていましたが、検索はやはり画面があるほうがにぎやかでいいですよね。 ということで、画面周りで調べものをしていた時のことを後日の自分のためのメモとして残しておきます。\nSearch UIとSearchkit ということで、それほど手がかからないで検索の画面をサクッと作る方法がないか?ということでちょっとだけ探してみました。 最初にElasticsearchを利用していることもあり、すぐに検索の画面を作れるライブラリ・フレームワーク・コンポーネントがないかな?ということで思いついたのが次の2つでした。\nElastic Search UI Searchkit どちらも直接Elasticsearchに接続して検索をすることができるコンポーネントです。 Elasticsearchだけで完結していればそれでおしまいだったのですが、今回はバックエンド経由でElasticsearchに検索を書ける必要があります(ベクトル検索の仕組みもデモをしたいため、クエリの文字列をLLMなどでベクトルにしてからknn検索をすることになります)。\nSearch UIの構成 もともとSearch UIはElasticのApp SearchのGUI構築向けのコンポーネントとして作られました。 最近になって、直接Elasticsearchに接続できるコネクターを提供しています(ベータだけど)。 このコネクターを利用した場合は、ざっくりですが、このような流れになります。\nまた、Search UIはCustom Connectorの仕組みも用意しており(ConnectorのAPIが宣言されているのでそのAPIで独自実装が可能)、これを利用することで、ブラウザではなくバックエンド(Node)でElasticsearch Connectorを利用するような構成も取れるようになっています。\n改めて要件をまとめると ということで、やりたいことは\n簡単にUIが作れる バックエンドはPythonを経由して検索したい となります。 Searchkitも調べようかと思いましたが、いったんはSearch UIのCustom ConnectorでPythonでFastAPIでバックエンドのAPIを実装して、Search UIの想定しているリクエスト・レスポンスに変換すればいいかな?ということにしました。\nとりあえずSearch UI+Custom Connectorからのリクエスト・レスポンス(フロントからバックエンドへの出入りの部分)を記録し、 Search UI+Elasticsearch Connectorのときのリクエスト・レスポンス(バックエンドからEsへのの出入りの部分)も記録して、 参考にしながらバックエンドを実装しようと試みました。 Search UIのCustom Connectorのサンプルとなっていた、Node上でElasticsearch Connectorを動かしている部分をPythonで簡単に再実装しようという試みです(まったく同じ実装にする必要はなく、必要最低限の機能(検索窓、ファセット、ページング)が動作するところを目指します)。\nElasticsearch API connectorの調査 方針が決まったので、Search UIがElasticsearch API Connectorに渡しているリクエストをブラウザのデバッグ機能を使って追いかけてみると。。。 内部でSearchkitを読んでいる??ことがわかりました。\nElasticsearch API Connectorがリクエストを変換しているのかと思っていたのですが、実は内部にもう一段変換が行われていました。\n方針を決めたつもりが、Searchkitが出てきてしまったので、Searchkitも調べてみることに。。。 なお、Search UIにElasticsearch API Connectorを導入したのがどうやら、Searchkitの作者で、現在はElasticのエンジニアになられているようです。\nSearchkitとは? Search UIが利用しているSearchkitは、3.0ですが、Searchkit本家のリポジトリを見ると4.x.0となっています。\nどうして新しいものをSearch UIで使っていないのかな?と思いつつ調べてみたところ、Searchkit V4のブログを発見しました。\nSearchkit V4 integrates with Algolia’s Instantsearch library, which is a Search UI library built by Algolia. Instantsearch is an amazing library, and it’s been used by many companies and supports many frameworks like React, Vue and Angular. ブログより引用\nどうやら、V4ではコンセプトをガラッと変更されたようで、Algoliaがオープンソースとして開発しているInstantSearchのコネクター(アダプター)としてSearchkit V4を開発しているようです。 これは最近出てきている検索エンジンのTypesenseやMeilisearchの戦略にもなっています。\nなお、SearchkitのGitHubリポジトリやSearch UIのリポジトリを見ていると、Search UIの開発(およびSearchkitの3系)は現在は活発に行われていないように見えました。 Searchkit V4はちょっとずつ開発が進んでいるようです。\nまとめ? 一応Searchkit V4の現状やInstantSearchもすこしだけ見てみたのですが、今回の私のプロジェクトでは検索画面はまだそこまで重要度は高くないので、いったん調べていたSearch UI+Pythonのバックエンドの構成で動作する最小限を実装したところで終わりにしました。 なので、Searchkit V4+InstantSearchの構成はまた今度という感じです。\nなお、Search UIの方は5月からコミットがされていないようです。どうも開発しているチームが別件で忙しそうだなというのを感じました。\n","date":1692768764,"dir":"post/2023/","id":"8f58cbe5f2ce85c22569af765de3f8d3","lang":"ja","lastmod":1692768764,"permalink":"https://blog.johtani.info/blog/2023/08/23/search-ui-and-searchkit/","publishdate":"2023-08-23T05:32:44Z","summary":"趣味?(検索エンジンに関する趣味プロジェクト)でPythonのプログラムを書いています。 ベクトル検索などの確認なども含めて、Jupyter N","tags":["searchkit","search-ui","画面"],"title":"search-UIとSearchkitと検索画面"},{"contents":"いくつかある環境をDev Containerで動くように変えていますが、最初に導入した時に疑問点だった「コンテナ名」について解消したのでメモを残しておきます。\nコンテナ名の指定 最初のDev Container導入の記事で、起動したコンテナの名前が自動で付与されて、ランダムに変わるという疑問点を書いていました。\ndocker-compose.yml対応の記事ではdocker-compose.ymlを利用すると、コンテナ名はファイル内で定義されたサービス名で起動されて見やすくなると気づきました。\nやはり、Dev Containerでイメージを指定している場合もわかりやすいコンテナ名がいいなと思ったところで、「runArgs」を思い出しました。 Dev Containerからコンテナを起動するときに渡す引数が書けるじゃないですか。そういえば、むかしdockerコマンドを使う時に名前を指定した記憶があったなと。ということで、Google検索です。「docker command args container name」で検索しましたw\n--nameというオプションで起動時のコンテナの名前の指定ができます。ということで、このブログを生成するためのdevcontainer.jsonに\u0026quot;runArgs\u0026quot;でコンテナ名を指定してコンテナ起動ができるようになりました(「ブログ記述環境としてのDev Container」という記事のdevcontainer.jsonにrunArgsの行を追加しただけ)。\n{ \u0026#34;name\u0026#34;: \u0026#34;Hugo - blog generator\u0026#34;, \u0026#34;image\u0026#34;: \u0026#34;mcr.microsoft.com/devcontainers/javascript-node:16\u0026#34;, \u0026#34;runArgs\u0026#34;: [\u0026#34;--name\u0026#34;, \u0026#34;blog_generator\u0026#34;], \u0026#34;postCreateCommand\u0026#34;: \u0026#34;/bin/sh ./.devcontainer/postCreateCommand.sh\u0026#34;, ... ","date":1690420969,"dir":"post/2023/","id":"f9e847ee886bdb9ab5583eeb6eabbd51","lang":"ja","lastmod":1690420969,"permalink":"https://blog.johtani.info/blog/2023/07/27/container-name-in-devcontainer/","publishdate":"2023-07-27T01:22:49Z","summary":"いくつかある環境をDev Containerで動くように変えていますが、最初に導入した時に疑問点だった「コンテナ名」について解消したのでメモを","tags":["dev container"],"title":"VS CodeとDev Container(コンテナ名の指定)"},{"contents":"このブログの生成には、Hugoを利用しています。 ブログ移行日記(その1)に書いてありますが、当時はbrewでインストールしていました。 また、Windowsに移行したタイミングで、WSL2のUbuntuにaptでhugoをインストールして利用していました。 WSL2の環境が壊れなければこのままでもいいのですが、最近Dev Containerを触っていたので、このブログを書く環境(おもにHugo)もDev Containerにできるのでは?と気づきました。\nということで、Hugo+αの環境をDev Container化したので、そのメモです。\n必要なもの ブログを書いて、記事を構築して、公開するところまでに利用するのは次のようなものです。\ngit Hugo node atomic-algolia GitHubのプライベートリポジトリでHugoのプロジェクトを管理しています。 また、GitHub Pagesで公開しており、生成したHTMLもgitコマンドを利用してGitHubにpushしています。 このため、gitコマンドが必要です。\nコンテンツの生成はHugoコマンドを利用します(テーマの適用とかいろいろ)。\nあと、Algoliaでブログを検索できるようにしており(ブログ移行日記(その4)参照)、Algoliaへドキュメントのデータをアップロードするために、atomic-algoliaを利用しています。こちらは、nodeのモジュールであるので、nodeの環境も必要です。\nベースにするイメージ Dev Container Templatesというリポジトリが公開されています。 こちらを探すと、元となるdevcontainer.jsonが見つかることがあります。 Hugoのものがあるか探してみましたが、残念ながら見つかったのはJekyllのテンプレートでした。 今回は、nodeの環境が必要なのでjavascript-nodeを元に編集していきます。\n手元のUbuntuのnodeのバージョンが16だったので、バージョン16のイメージを指定します(devcontainer.jsonは後述)。\nHugoの追加 Hugoのテンプレートはなかったのですが、Dev Container FeaturesにHugoのfeatureが用意されていました。 featuresに1行追加するだけでコンテナにHugoをインストールしてくれる便利ものです。\nMarkdownの環境 Dev Container Templatesを探索していて見つけたMarkdownのテンプレートも参考にしてみました。 VS CodeのMarkdown向けの拡張機能がいくつかリストアップされていたので、ついでに追加です。 markdown-all-in-oneやmarkdownlintはこれまでも利用していたので、他のものも便利だろうということで。 他の物はどんなものかを後で調べてみる予定です。\n作った.devcontainerの設定はこちら ということで、出来上がった設定は以下の通りです。\ndevcontainer.json { \u0026#34;name\u0026#34;: \u0026#34;Hugo - blog generator\u0026#34;, \u0026#34;image\u0026#34;: \u0026#34;mcr.microsoft.com/devcontainers/javascript-node:16\u0026#34;, \u0026#34;postCreateCommand\u0026#34;: \u0026#34;/bin/sh ./.devcontainer/postCreateCommand.sh\u0026#34;, \u0026#34;features\u0026#34;: { \u0026#34;ghcr.io/devcontainers/features/hugo:1\u0026#34;: {} }, \u0026#34;customizations\u0026#34;: { \u0026#34;vscode\u0026#34;: { \u0026#34;extensions\u0026#34;: [ \u0026#34;yzhang.markdown-all-in-one\u0026#34;, \u0026#34;streetsidesoftware.code-spell-checker\u0026#34;, \u0026#34;DavidAnson.vscode-markdownlint\u0026#34;, \u0026#34;shd101wyy.markdown-preview-enhanced\u0026#34;, \u0026#34;bierner.github-markdown-preview\u0026#34; ] } } } postCreateCommand.shでは、npm installで、必要なモジュールのインストールをコンテナビルド後に実行できるようにしました。 (apt updateはなくてもいいな)\npostCreateCommand.sh #!/bin/sh # postCreateCommand.sh echo \u0026#34;START Install\u0026#34; sudo apt update sudo chown -R vscode:vscode . npm install echo \u0026#34;FINISH Install\u0026#34; まとめ ということで、ここ最近Dev Containerについて色々調べていたのでサクッとDev Container化ができました。 まぁ、HugoのFeatureが用意されていて、他に大したことをやっていないというのが大きいのですが。 このブログは今回構築したDev Containerで生成して公開した記事になります。\n","date":1690189832,"dir":"post/2023/","id":"7884b62c561b999b9358d52779a18218","lang":"ja","lastmod":1690189832,"permalink":"https://blog.johtani.info/blog/2023/07/24/introduce-dev-container-to-hugo-env/","publishdate":"2023-07-24T09:10:32Z","summary":"このブログの生成には、Hugoを利用しています。 ブログ移行日記(その1)に書いてありますが、当時はbrewでインストールしていました。 また、","tags":["hugo","dev container"],"title":"ブログ記述環境としてのDev Container"},{"contents":"WSL2にUbuntuを入れて、開発とかはこちらを利用しています。 また、Docker DesktopもWSL2のバックエンドエンジンを利用しています。\n知り合いとの話で、Ubuntuの外付けのSSDをマウントしたという話が出てきて、それだと遅くない?Ubuntu自体を移動できるんじゃないかな?という 流れになりました。 知り合いは、特に移動とかは考えてなかったのですが、自分のディスクの容量が今どのくらい使われているのかが気になり、調べてみると、 Cドライブの使用率が90%を超えてるじゃないですか。\nWizTreeというソフトを前回入れていたのを思い出して、再度調べてみたところUbuntuらしきvhdxファイルのサイズが171GB、Docker Desktopのデータ領域のvhdxファイルのサイズが81GBと、結構な割合です。\n前回は、Hyper-V管理ツールで仮想ディスクの圧縮処理を行ったのですが、Dドライブに移行したほうが安心できそうな気がしたので、移動の方法を調べました。\nWSLコマンドのドキュメントが公式で公開されています。こちらのコマンドを元に作業をしました。 また、ググって出てきた記事も参考にさせていただきました。ありがとうございます。\nwsl をDドライブに入れ直してディスク拡張する | blog.ojisan.io WSL2環境をコピー(複製)する方法 - Qiita まずは確認と停止 WSL2で使っているディストリビューションを確認します。コマンドは以下の通り。 実行した結果も含まれています。コマンドの実行にはコマンドプロンプトを使用しました。公式ドキュメントのドキュメントではスニペットはPower Shellと書かれてますが、コマンドプロンプトでも大丈夫そうでした。\nD:\\\u0026gt;wsl -l -v NAME STATE VERSION * Ubuntu Running 2 docker-desktop Running 2 docker-desktop-data Running 2 残念ながら、wslのコマンドでは実体がどこにあるのかを調べることができなかったですが、WizTreeでディレクトリ名などを見ていたのでなんとなう予測ができました。 (これ、他に知る方法あるのかなぁ?)\nディストリビューションの移動は次のような手順になります。\nwslのshutdown エクスポート(ディストリビューションのコピー) 今あるディストリビューションを削除 インポート(今ある名前で2.のファイルをインポート) まずは停止です。これをやらないとエクスポートができないので。\nD:\\\u0026gt;wsl --shutdown エクスポート 次にエクスポートです。 今回は以下の2種類の仮想環境をエクスポートします。\nUbuntu docker-desktop-data エクスポートでは、元のディストリビューションのファイル(Cドライブにあるファイル)が消えることはありません。 また、エクスポートの形式として、tarとvhdxの2種類が指定できます。 エクスポートのコマンドのデフォルトはtar形式ですが、エクスポート元のファイルがvhdxなので、vhdxでエクスポートしたほうがCPUにやさしかったです。 ちなみに、docker-desktop-dataはtar形式でエクスポートしてインポートしました。tar形式の場合は、ディスクのサイズが小さくなる可能性があるみたいです(不要なデータがvhdxの中に残っていたりする影響かと)。\nコマンドは以下の通りです(詳細は公式ドキュメントを参照してください)。出力ディレクトリはあらかじめ作っておきました(作ってない場合の挙動は未確認です。)\nD:\\\u0026gt;wsl --export Ubuntu .\\wsl\\Ubuntu\\ext4.vhdx --vhd docker-desktop-dataはtar形式です。\nD:\\\u0026gt;wsl --export docker-desktop-data .\\Docker\\ docker-desktop-data.tar ディストリビューションの削除(こわい?) 今ついているディストリビューション名を利用したいので、いったん、Cドライブ上にあるディストリビューションを削除する必要があります。 コマンドは公式ドキュメントにある--unregisterオプションを利用します。 以下のコマンドはUbuntuですが、docker-desktop-dataもやりました。\nD:\\\u0026gt;wsl --unregister Ubuntu ちなみに、このコマンドを実行すると、Cドライブの容量がいきなり空きました。 コマンドいっぱつでなくなりました。きちんとエクスポートしてから実行しましょう。 (なんなら、一度、別名でインポートして動作確認するのもいいかもしれないです。私はしましたw)\nインポート インポートするオプションも2種類あります。vhdxファイルの場合は、インプレースでのインポート(vhdxファイルをそのまま利用する形式)が可能です。 Ubuntuについてはこちらを利用しました。この場合、vhdxファイルがそのまま利用されるため、バックアップとしては利用できなくなります。今回は170GBもあるので、これでいいかと。\nD:\\\u0026gt;wsl --import-in-place Ubuntu .\\wsl\\Ubuntu\\ext4.vhdx tarファイル(docker-desktop-data)の場合は、通常のインポートを行いました。\nwsl --import docker-desktop-data D:\\Docker\\docker-desktop-data\\ D:\\Docker\\docker-desktop-data.tar この場合、tarファイルは残ったままで、新たにD:\\Docker\\docker-desktop-data\\ディレクトリにext4.vhdxファイルが作られました。 バックアップも取りつつ移行したい場合は--importがいいかもしれません。 また、WSLはバージョン1とバージョン2があり、インポートの際にこの部分も気にする必要があるようです。 今回はすべてバージョン2で、かつ、wslのデフォルトのバージョンを2にしてあったので特に意識していません。\nUbuntu起動ユーザーの指定と注意点 公式ドキュメントに、既存のユーザーを変更するコマンドの記載があります。 インポートしたディストリビューションは、デフォルトユーザーがrootになっていることがあるようなので、Ubuntuのユーザーを次のようなコマンドで変更しました。\nubuntu config --default-user johtani 公式ドキュメントの警告にもありますが、実行可能ランチャーがない場合があります。 今回のubuntuは、WSL2でUbuntuをインストールした時に作成されたコマンドで、unregisterした後にimportしてもきちんと動いたので問題にはなりませんでした。これは、インポートするときに、既存のディストリビューション名を利用したためと思われます。\nエクスポートやインポートの検証するために、NewUbuntuという名前で別途インポートした時には、NewUbuntuという実行可能ランチャーは作成されず、上記のデフォルトユーザーの設定は別の方法が必要になります(罠だ)\ndocker-desktop-dataのほうは、特に変更してないけど動いてそうだからいいのかな? 前の設定の確認とかやっておくのがいいんだろうな、本当は。。。\nまとめ ということで、Cドライブに300GB近い空きができて、心の余裕もできました。 今回は、同じPC内で別のドライブへの移動でしたが、他のPCにもこれで移行ができそうですね。 たまにはバックアップをとっておくのもいいのかも?と思いました(やるかどうかはまた別の話)\n","date":1690180128,"dir":"post/2023/","id":"ed431877ce11fe403fee77f7d26ce637","lang":"ja","lastmod":1690180128,"permalink":"https://blog.johtani.info/blog/2023/07/24/move-distribution-to-another-disk/","publishdate":"2023-07-24T06:28:48Z","summary":"WSL2にUbuntuを入れて、開発とかはこちらを利用しています。 また、Docker DesktopもWSL2のバックエンドエンジンを利用して","tags":["wsl","windows"],"title":"WSL2のディストリビューションの環境移行"},{"contents":"前回の記事で、VS Code+Dev Containerを導入しました。 残課題として「マルチコンテナ化」があるという話もしました。今回はDev Containerのdocker-compose.yml対応をした話をメモとして残しておきます。 実際、VS Code + Dev Containerに移行した後に、Esを起動してアプリからつなげるというのがうまくいかないというのがあったので対応がんばりました。。。\nDev Containerのdocker compose設定 この記事ではすでにdocker-compose.ymlが存在している状態の話をします。 変更する前は、devcontainer.jsonでベースのコンテナイメージの指定、マウントの設定などを行っていましたが、docker-compose.ymlにいくつかを移動しないといけません。 対応した時の作業の流れは以下のような感じです。\nワークスペース用のDockerfileの作成 docker-compose.ymlにワークスペース用のサービスを追加 devcontainer.jsonをdokcer-compose.ymlを利用する形に書き換え アプリでの接続文字列をlocalhostからdocker-compose.ymlのサービス名に変更 参考:対応した時のコミットです。差分などはこちらをごらんください。\ndevcontainerのリポジトリにPython+PostgreSQLのサンプルが公開されており、こちらを参考にしながら作業をしました。\n1. Dockerfileの作成 docker-compose.ymlだけでも完結するのかもしれないですが、いろいろやりたいことも出てくるかもしれないので別のファイルに切り出しました。 といっても、コンテナのイメージはdevcontainer.jsonに記述していたものを使っています。\nARG VARIANT=3.11-bookworm FROM mcr.microsoft.com/devcontainers/python:${VARIANT} ENV PYTHONUNBUFFERED 1 ENV TZ Asia/Tokyo TZはdevcontainer.jsonで指定していたものを、こちらに移行した形になります。 PYTHONUNBUFFEREDは参考にしたDockerfileの記載です。標準出力・エラーをバッファリングしない指定になっています。\n2. dokcer-compose.ymlにサービス追加 backendという名前のサービスをdevcontainer(VS Code)から接続するコンテナのサービス名にしています。\nservices: backend: build: context: . dockerfile: .devcontainer/Dockerfile init: true environment: - TZ=Asia/Tokyo command: sleep infinity volumes: - .:/workspace/search-research:cached - venv-search-research-backend:/workspace/search-research/.venv ... volumes: venv-search-research-backend: 1.で作成したDockerfileを利用します。docker-compose.ymlファイル自体は、プロジェクトのルートディレクトリに配置していますが、Dockerfileは.devcontainerディレクトリに入れたため、contextとdockerfileはこのような指定になっています。\ninitは、devcontainer.jsonで指定していた\u0026quot;runArgs\u0026quot;: [\u0026quot;--init\u0026quot;],の設定になります。\ncommandの部分は、コンテナが起動したままにしておくための設定です。\nvolumesでは2つのボリュームに関しての指定があります。 1つ目の/workspace...は、VS Codeがコンテナにプロジェクトをマウントする場所の指定です。 devcontainer.jsonだけを利用していた場合は意識していませんでしたが、/workspace/プロジェクト名というディレクトリにプロジェクトがマウントされていました。 docker-compose.ymlを利用する場合は、明示的に指定が必要です。 2つ目のvenv-...は.venvのディレクトリをコンテナの中だけのものにする設定を移植したものになります。 前回の記事ではコンテナIDをボリューム名に含めていましたが、こちらのほうがわかりやすいかと思い、プロジェクトの名前とサービス名をつけるようにしてみました。 Dev Containerで起動した場合はsearch-research_venv-search-research-backendという名前がついています(最初の部分はDev Containerがつけてるのかな?)\n3. dovcontainer.jsonの変更 devcountainer.jsonから呼び出すものの準備ができたので、devcontainer.jsonを書き換えます。 公式のドキュメントとしてDocker Compose向けのプロパティが紹介されています。 変更したものは次のような形です。\n{ \u0026#34;name\u0026#34;: \u0026#34;search-research\u0026#34;, \u0026#34;dockerComposeFile\u0026#34;: \u0026#34;../docker-compose.yml\u0026#34;, \u0026#34;service\u0026#34;: \u0026#34;backend\u0026#34;, \u0026#34;workspaceFolder\u0026#34;: \u0026#34;/workspace/search-research\u0026#34;, \u0026#34;postCreateCommand\u0026#34;: \u0026#34;/bin/sh ./.devcontainer/postCreateCommand.sh\u0026#34;, \u0026#34;customizations\u0026#34;: { ... dockerComposeFile : 利用するdocker-compose.ymlのファイルパス service:VS Codeが利用するワークスペース用のサービス名 workspaceFoldeer:VS Codeがコンテナに接続したときに開くフォルダのパス を指定します。これで、VS Codeでこのプロジェクトを開いた時に、Dev Containerがdocker-compose.ymlを使ってコンテナの起動(ビルドとか)を行ってくれます。\n4. アプリの接続文字列の書き換え こちらはおまけです。 PythonのアプリからElasticsearchに接続するときの文字列として、Dev Container化の前は、http://localhost:9200と指定をしていました。 Elasticsearch用のサービス(es)で、ポートフォワードをしていたためです。\nアプリ側もコンテナ化したので、Docker Composeが名前の解決をしてくれるので、http://es:9200という接続文字列で接続ができるようになりました。\nということで、ここまでで、VS Codeでプロジェクトを開くと、2つのコンテナ(backendとes)が起動してVS Code上でPythonアプリからEsへの接続ができるようになりました。\n追加の変更 参考のプルリクでは、上記まででしたがさらにいくつかの変更をそのあとやっています。\n起動するサービスの指定(開発だけするときはEsを起動したくない) devcontainer.jsonでrunServicesを使って指定できます(公式ドキュメント) GPUをコンテナから利用できるように devcontainer.jsonでfeaturesのnvidia-cudaを指定し、docker-compose.ymlでnvidiaのドライバーなどを設定することで対応しました。 nvidiaが公開しているcuda対応のコンテナイメージでもよかったのですが、こちらのほうが楽そうだったという理由です。featuresとコンテナのビルド、postCreateCommandの順序などはもうちょっと勉強しないといけない気がしています。 これらの対応はこちらのコミットで対応しています。\nGPUの対応は、私個人の環境はこれでいいのですが、複数の人がこのリポジトリを使う場合はどうやって切り替えたりするんだろう?という疑問が残っています。。。 今回はrinna/japanese-clipのモデルを使って、テキストからベクトルを生成する部分の処理のためにGPUを使いたいというモチベーションがあり、コンテナでもGPUを使えるようにしています(CPUだと時間がすごくかかる。。。)。\nサービス起動の新たな問題点 runServicesで起動するサービス名を指定したのはよかったのですが、Elasticsearchのサービスを起動して、データ登録や検索の確認を行おうと思った時に、EsのコンテナをVS Codeだけで起動する方法がまだわかっていません。。。 一度コンテナをビルドした後なら、「Remote Explorer」でOther Containerというくくりで表示され、右クリックで起動や停止ができそうなのだけど、新規サービスをdocker-compose.ymlに追加した場合は、自分でターミナルなどでコンテナのビルドをしないといけないかもしれないです。もうちょっと調べてみないとなぁ。\n副次的な効果 Docker Compose対応をしたことで、前回の記事での疑問点のうち、「コンテナ名」「VolumeのID」については懸念点がなくなりました。\n「コンテナ名」は、docker-compose.ymlのサービス名がコンテナ起動時に名前として利用されるため、Docker Desktopで見た時などの探しにくさはなくなりました。 ただ、「イメージ名」については、いまだに2つできています。「-uid」がつかないものの代わりに、search-research-backendというイメージが作られています。 ただし、実際に利用されるのは前回の記事に書いたようなvsc-search-research-bf04371c017c8d2f1dd5ad2529841b02e9ea1d1aaa4354c19edf53cef3f0c13b-uidという名前のイメージです。\n「VolumeのID」については、docker-compose.ymlのファイルで自分で名前をつけるようにしたので、コンテナのIDが利用されなくなったという次第です。 代わりに、プロジェクト名である「search-research」という名前を直接記述しているので、変数などで置き換えたほうがいいのかも?という気がしています。\nまとめ ということで、複数のコンテナを利用するプロジェクトでVS Code+Dev Container対応ができそうだということがわかりました。 ついでに、GPU対応もできたのでこれで、やっと他の検索エンジン対応などができる気がしています。 (その前にpre-commitを保存時にチェックする形に変更かなぁ) やりたいことからちょっとずつ外れている気もするけれど、新しいことを調べるのは楽しいですね。\n","date":1689902010,"dir":"post/2023/","id":"086b4fd5f77021a0a2aa6b0e90061486","lang":"ja","lastmod":1689902010,"permalink":"https://blog.johtani.info/blog/2023/07/21/multi-containers-with-dev-container/","publishdate":"2023-07-21T10:13:30+09:00","summary":"前回の記事で、VS Code+Dev Containerを導入しました。 残課題として「マルチコンテナ化」があるという話もしました。今回はDev C","tags":["python","dev container"],"title":"VS CodeとDev Container(docker-compose.yml対応)"},{"contents":"前回の記事で、pre-commitとPyCharmとWindowsの組み合わせで困っていることを書きました。 これについて、知り合いとチャットで話をしていて、それほどPyCharmにこだわりもないよなぁということになり、 であれば、ISIDのブログ(Dev Containerを使ってステップバイステップで作るPythonアプリケーション開発環境 - ISID テックブログ)を試してみるとすっきりするかもしれないとなり、Dev Container対応をブログを参考に行ってみました。\n順を追ってブログで説明されているので、どういう仕組みなのか、どの設定が何を意味しているのか?がとてもよくわかりやすくすんなり対応することができました。\nブログの手順をなぞっているところでいくつか固有の手順や疑問点が出てきたのでブログに書き記しておきます。 結果は、コミットしてあるものを見てください。\nブログとは違う手順 まずはISIDのブログとは違う点をいくつか。\n.venvはいったん削除 ブログでは新規のプロジェクトを作成していく過程で、コンテナ化した環境を作った後に.venvをDockerコンテナのボリュームにして、最後に仮想環境のPythonを生成していました。 私の場合は、すでにホストOS(実際にはWSL2のUbuntuだけど)で.venvのディレクトリを作成してある状態だったので、いったん削除する必要がありました。 すでに存在する.venvがbindマウントされてしまっている状態になるため、Dockerのボリュームとの整合性が取れなくなるようです。\nこの作業を行う前か、途中でDev Containerを停止した状態で、.venvを削除することで問題なくDockerのボリュームに仮想環境のPythonが登録されるようになります。\npostCreateCommand.shの呼び出し方 ファイルに実行権限がないと、実行権限エラーが出ました。 実行権限を与えるか、次のような記述で動くようになりました。 今は、ファイルに実行権限をつけるのではなく、次のような記述にしていますが、何か問題あるかな?\n\u0026#34;postCreateCommand\u0026#34;: \u0026#34;/bin/sh ./.devcontainer/postCreateCommand.sh\u0026#34;, 実際に動作しているログを見ると\n/bin/sh -c /bin/sh ./.devcontainer/postCreateCommand.sh\nとなっているので、少し気持ち悪いのだけれども。。。\npostCreateCommand.shの追加処理 今回Dev Containerを適用したプロジェクトでは、sentencepieceを利用します。 この、sentencepieceをpoetryがインストールするタイミングで、cmakeを要求してきました。 今回利用しているDocker Imageにはcmakeは含まれていないため、以下の処理を追加しています。\nsudo apt update sudo apt-get install cmake -y また、rinna/japanese-clipも利用しているのですが、こちらは、poetryで追加してインストールでは依存するパッケージがインストールされないため、pipコマンドを利用するようにしています。\npip install git+https://github.com/rinnakk/japanese-clip.git コンテナイメージを作った後にやりたいことを、自由にスクリプトで書けるのは便利ですね。\npre-commitのスクリプトの再生成 こちらも、既存の環境が残っているとPythonへのパスの違いの問題が出たので、作り直しました。 .git/hooks/pre-commitのファイルを削除し、pre-commit installをやったものをリポジトリにコミットしてあります。\n疑問点 作業をしていて疑問点もいくつか出てきたのでメモを残しておきます。ちなみに、これらの疑問について実際に調べるまでには至っていません。 時間を見て解決できればなぁと(できるのか?)。\nImageが2つ Dev Containerの設定を書いた後に、コンテナをビルドすると、Docker DesktopのImagesにイメージが出来上がります。 この時、イメージが2つできあがっています(なぜ?)。\nREPOSITORY TAG IMAGE ID CREATED SIZE vsc-search-research-bf04371c017c8d2f1dd5ad2529841b02e9ea1d1aaa4354c19edf53cef3f0c13b-features-uid latest 25c7e23416ec 3 days ago 1.69GB vsc-search-research-bf04371c017c8d2f1dd5ad2529841b02e9ea1d1aaa4354c19edf53cef3f0c13b-features latest fcf9eaeb2187 3 days ago 1.69GB こんな感じで、最後に-uidがついているかいないかの違いです。 実際にコンテナ起動時に利用されるのは-uidがついているものになります。 なぜ2つになっているのか、1つにする設定などがあるのか?といったところが気になるところです。\nContainerの名前 devcontainer.jsonの設定を書き換えて、コンテナをリビルドすると起動したコンテナの名前が自動で割り振られているようです。 今は、fervent_hopperとなっています。ランダムにつけられているようなのですが、名前を付ける方法はないのかなぁ?と。\ndevcontainer.jsonにはnameというプロパティもあるのですが、この値がどこで使われているのかはよくわかっていません。 Remote Explorerでコンテナの一覧が見えますが、ここでは、リポジトリ名が利用されているようです。\nVolumeのIDはどこから? devcontainer.jsonで次のような記述で、.venvのディレクトリようにDockerにボリュームを作っています。\n\u0026#34;mounts\u0026#34;: [ \u0026#34;source=venv-${devcontainerId},target=${containerWorkspaceFolder}/.venv,type=volume\u0026#34; ], 実際にコンテナでマウントされている情報を見ると\n/workspaces/search-research/.venv /var/lib/docker/volumes/venv-04emir9hi2caivtjunfe3l17452hkbb3hdut1qflbrn8n924ho5c/_data となっています。 04emir9hi2caivtjunfe3l17452hkbb3hdut1qflbrn8n924ho5cがdevcontainerIdに相当するのだとは思うのですが、誰がつけたものかなどがまだよくわかっていません。 もうちょっとわかりやすいものが使えるほうが嬉しいかも?と思っていたりします。 (複数Dev Containerを使い始めると、Docker Desktopで見ると、どのボリュームがどのDev Containerに紐づいているかがぱっと見ではわからない)\n.vscodeディレクトリどうしよう? たぶん、VS Codeを触っている過程で、何かの設定をしてしまったのだとは思うのですが、 .vscode/settings.jsonというファイルができており、次のような内容になっています。\n{ \u0026#34;git.ignoreLimitWarning\u0026#34;: true } 何か意味があるかも?ということで、コミットしてリポジトリに入れたのですが、いらないのかもしれないなぁと。\n残作業 とりあえず、VS CodeでPython環境ができて、VS CodeのTerminalでPythonのプログラムが実行できるのはわかった段階です。 いくつか、今後調べながらやる必要があるものが残っているのでメモとして残しておきます。\nマルチコンテナ化 今回Dev Containerに対応したプロジェクトでは、検索エンジンもDockerのコンテナとして起動して、Pythonのプログラムから接続したいと思っています。 となると、docker composeでいろいろと起動するほうがネットワークなどの設定も楽になるのでは?と思っているところです。 Dev Containerのテンプレートがいくつか用意されており、その中に「Python 3 \u0026amp; PostgreSQL (postgres)」というのを見つけたので、このあたりが参考になるのでは?と考えているところです。\npre-commitではなく、保存時にフォーマット pre-commit+localのコマンドも動くようにはなったのですが、保存時にフォーマットなどをかける設定もISIDのブログで記載がありました。 コミットしようとして、怒られるよりも、保存時に怒られたりするほうがいいかも?という気分になってきています。 どこまでが切り替え可能なのか?なども見ながら対応してみようかなと。\nもう少し開発してみて改善点を探っていく とりあえず動いたという段階です。 PyCharmとの違いがあるはずで(たとえば、git周りのGUIの違いとか)、そのあたりでどんな違いがあり、どんなものがあると嬉しいのか?といったものを調べる必要もあるかなと考えています。 TerminalでCtrl+rがうまく使えなかったり(Auto Hot Keyで検索のショートカットに割り当ててしまっているから。。。)などもあるので、この辺も調べていきたいなと。 Windows Terminalを使えたりするのかなぁ?\nまとめ さて、とりあえず、VS CodeでPythonのDev Container環境を作って動くところまでは来ました。 PyCharmを使いこなしていなかったのもあり、それほど違和感なく移行できるような気がしています。 調べることはまだまだあるし、プログラム書くつもりが、環境を整える方向に話がずれている気もしますが、まぁ面白いのでよしとするかなぁ。 いろいろまだまだ知らないことだらけです。。。\n","date":1689254123,"dir":"post/2023/","id":"a12474027c91fad5a861aa9919817d72","lang":"ja","lastmod":1689254123,"permalink":"https://blog.johtani.info/blog/2023/07/13/introduce-vs-code-and-dev-container/","publishdate":"2023-07-13T22:15:23+09:00","summary":"前回の記事で、pre-commitとPyCharmとWindowsの組み合わせで困っていることを書きました。 これについて、知り合いとチャット","tags":["python","dev container"],"title":"VS CodeとDev Containerの導入(まだ途中)"},{"contents":"最近、趣味(検索エンジンに関する趣味プロジェクト)でPythonのプログラムを書き始めました。\nきちんとPythonのプログラムをプロジェクトとして書いたことがないので、 Pythonのプロジェクトのディレクトリ構成などを手探りで進めているところです。 コードのフォーマットとかもやらないとなぁ?と知り合いのいるSlackでつぶやいたところ、gitのpre-commitフェーズでblackなどのフォーマットやスタイルを修正してくれるツールを実行する方法を教えてもらいました(PRまで送ってもらえたのでありがたい)。\nで、pre-commit周りの設定などを変えている段階で遭遇した問題点についてログを残しておこうと重いブログを書いています。 残念ながら現時点では解決してないんですけどね。。。\n手元の環境 簡単に環境を書いておくとこんな感じです。\nWindows上のPyCharmを開発で使用 プロジェクトのディレクトリはWSL2のUbuntu上 Python、gitはUbuntuのものを利用 プロジェクトのルートディレクトリにある.venvにvenvでPythonの仮想環境を作成してある 問題点 遭遇したpre-commitの問題点は次の通りです。\npre-commitの設定でrepo:localでローカルのプロジェクトにインストールしたコマンドを利用するように変更 すると、PyCharmでコミットすると、blackなどのコマンドが見つからない ターミナルでコミットするときはきちんと動作する 色々調べて試行錯誤した結果、現在はrepo:localでのローカルコマンドを使用する方法はあきらめました。 移行は、作業記録みたいなものです。どういう流れでpre-commitを取り込み、ローカルに切り替え、切り戻したかという話です。\npre-commitとpre-commit 最初に少し戸惑ったのは、pre-commitというツールとgitのpre-commitフックです。 gitのpre-commitのフックのために作られたPython製のpre-commitというツールがあります。\nこのPython製のツールを利用することで、プロジェクトに.pre-commit-config.yamlという設定ファイルを置けば設定に記述されたツールをgit commitのタイミングで実行してくれます。 実際には、pre-commitというツールの初期設定のタイミングでpre-commit installというコマンドを実行して .git/hooks/pre-commitというスクリプトが生成されます。 gitコマンドはcommitされた時に(commit前のフェーズ)でこのスクリプトを実行し、そこで.pre-commit-config.yamlが参照されています。\n.pre-commit-config.yamlの記述は次のようなものになります(最初にもらったPRより)。\nrepos: - repo: https://github.com/psf/black rev: 23.3.0 hooks: - id: black args: [\u0026#34;--line-length\u0026#34;, \u0026#34;120\u0026#34;, \u0026#34;.\u0026#34;] - repo: https://github.com/pycqa/flake8 rev: 6.0.0 hooks: - id: flake8 - repo: https://github.com/pycqa/isort rev: 5.12.0 hooks: - id: isort args: [\u0026#34;--profile\u0026#34;, \u0026#34;black\u0026#34;, \u0026#34;--filter-files\u0026#34;, \u0026#34;--multi-line\u0026#34;, \u0026#34;3\u0026#34;] - repo: https://github.com/pre-commit/mirrors-mypy rev: v1.4.1 hooks: - id: mypy 実際に、PRを取り込んで動かしてみたところ、blackなどが動いて行末のスーペースの除去や未使用のimportについて指摘をしてくれました。 便利だなと思ったのですが、ここで疑問が。\n今回は対象とするプロジェクトはpoetryで依存パッケージの管理を行っています。 今回、上記を動かすためにpoetryに追加されたものはpre-commitだけでした。 「あれ?blackとかはどこにあって、どうやって動いてるんだ?」という疑問が出てきます。 コンフィグファイルにはパスなどの記載をせず、それぞれのgithubリポジトリの記載とバージョンがあるからです。\npre-commitが使用するツールのインストール先 調べてみたところ、どうやらホームディレクトリにある.cache/pre-commitにblackなどのコマンドが見つかりました。 pre-commitツールが設定ファイルを基に、必要なコマンドをgithubからダウンロードしてきて実行時に利用しているようです。 pre-commitは便利なのだけど、せっかくPythonのプロジェクトだしそれぞれのツールはpoetryでpyproject.tomlでバージョンや設定を管理したほうがすっきりするのではないか?ということで、少し調べてみました。\n同じようなことを考えている方がブログを残していてくれました(Pythonレポジトリ用のpre-commit環境を整える)。 設定をpyproject.tomlに移行し、そのあと、ローカルのpetryでblackなどのコマンド類をインストールして利用する設定に書き換えています。 先人の肩に乗っかって、手元で同じようにpre-commitの設定ファイルのrepoをlocalに書き換えていき(その時のコミット)、ターミナルでpoetry run pre-commit run -aで動作確認できました。\nPyCharmでコミットしたらエラー ですが、実際に変更した状態でPyCharmからコミットしたら、コマンドが見つかりませんというエラーが出ます。。。 WSL2のターミナルでgit commitした場合は問題ありません。 どうして?となりますよね。。。。\n.git/hooks/pre-commitはPyCharm、ターミナルのどちらからも実行されています。 ですが、PyCharmではblackなどが見つからないというエラーが出ました。\n.git/hooks/pre-commitを見てみると、python実行するためのpythonのパスはプロジェクトにある.venv/bin/pythonを指定しています。 デバッグのために、このスクリプトにecho $PATHを差し込んで、git commitをPyCharmとターミナルからそれぞれ実行してみたところ、大きな違いがあります。\nターミナルで実行した場合は、\u0026lt;プロジェクトのディレクトリ\u0026gt;/.venv/binもPATH環境変数に存在していました。このため、.venv/binにあるblackなどを実行できています。\nPyCharmはWindowsから起動しています。プロジェクトのインタプリタとしては、WSL2のUbuntuにある.venv/bin/pythonを指定しているためもあり(?)、出力されたパスは/mnt/c/などのWindowsのパスなども入っていたりしますが、\u0026lt;プロジェクトのディレクトリ\u0026gt;/.venv/binは見つかりません。\nここからはソースコードは読んでいないので憶測ですが、.git/hooks/pre-commitで呼び出されているpre-commitツール(Python製)は、設定ファイルで指定されたコマンド(blackなど)を、コマンドとして今の呼び出されたコンテキストで実行しているのではないかということです。 実際、ターミナル上でもsource .venv/bin/activateを実行していない状態だとコマンドが見つからないというエラーが出ました。\n対処方法は? ということで、今考えられる対処方法としては次の通りです。\n.git/hooks/pre-commitのスクリプトを修正して、\u0026lt;プロジェクトのディレクトリ\u0026gt;/.venv/binのパスを見えるようにする PyCharmで何かしらの設定を探す PyCharmではgit操作しない repo:localはあきらめて、.pre-commit-config.yamlでblackなどは管理して、pyproject.tomlからは除外する 1.ですが、.git/hooks/pre-commitはprecommit intallを実行すると自動で生成されるスクリプトです。自分の環境で書き換えたとしても他の人が同じ環境を作るときにパッチを当てるなどをしないといけなくなります。\n2.はそれらしい設定を見つけることができませんでした。\n3.はめんどくさいですよね。。。ターミナルでgitのコメントを日本語で書くためにいくつか他の設定を考えないといけないです。。。\nということで、今回は4.の対処をとりました。やりたいことは、ツールや環境をそろえるのではなく、プロジェクトでやりたいことをやることなので。。。\nまとめ 最終的には元に戻ってしまいました(pyproject.tomlに設定周りは移動した)。 Windows環境がちょっとややこしくしてるかもな?というのと、個人のプロジェクトなのでそこまで気にしなくてもいいのでは?というのもありそうです。 それにしても、世の中の皆さんはフォーマッターとかどのタイミングで動かしてるんだろう?とかどういう環境構築してるんだろう?とか気になってます。 最近だとこういうディレクトリ構造にする、こういうツールを使うと便利などあれば、コメントいただけると嬉しいです。\n教えてもらったISIDのブログ(Dev Containerを使ってステップバイステップで作るPythonアプリケーション開発環境 - ISID テックブログ)も参考にさせてもらおうと思ってるところです。Pythonの環境をコンテナに移動したいなぁというのもあるので。ただ、PyCharmだからこのブログの通りには行かないけど(VS Codeに移るのも検討したほうがいいのかなぁ)。\n参考サイト Git - Git フック pre-commit Pythonレポジトリ用のpre-commit環境を整える Dev Containerを使ってステップバイステップで作るPythonアプリケーション開発環境 - ISID テックブログ ","date":1688954148,"dir":"post/2023/","id":"698cf3cbd796161d82c9ac438ebab5d2","lang":"ja","lastmod":1688954148,"permalink":"https://blog.johtani.info/blog/2023/07/10/pre-commit-and-python/","publishdate":"2023-07-10T10:55:48+09:00","summary":"最近、趣味(検索エンジンに関する趣味プロジェクト)でPythonのプログラムを書き始めました。 きちんとPythonのプログラムをプロジェクト","tags":["python"],"title":"pre-commitとvenvとPyCharm(困ったな?)"},{"contents":"今年もこの季節がやってきました。 Berlin Buzzwordsにオンラインで出張してました。 今年もハイブリッド開催をしてくれたので、オンラインで参加できました。 現地ではブースが出たり、朝食なども用意されているようでした。今年は昨年と違いマスク必須でもなくなったようです。 MICESも去年同様、現地開催のみのようです(今見たら、昨年のビデオとスライドが公開されてるので、時間見つけてみてみよう)。\n今年はうれしいことに検索に絡むセッションが大多数でした。世の中的にChatGPTの盛り上がりやベクトル検索がいろんな検索エンジンで使えるようになってきたこともあり、 大規模言語モデルと検索エンジン、ベクトルデータベースに関する話がたくさんありました(昨年まではKafkaやストリーム処理の話も多かったんですが)。\nということで、今年もセッションを見ながら残したメモを公開しておきます。\n簡単にメモ What defines the “open” in “open AI”? セッションページ:What defines the “open” in “open AI”? 動画: Jennifer Ding - What defines the \u0026ldquo;open\u0026rdquo; in \u0026ldquo;open AI\u0026rdquo;? - YouTube \u0026ldquo;OpenAI\u0026quot;の話ではなく、オープンなAIとは?という話で、ライセンスの話であったり、コミュニティ(データセットの公開とかベンチマークの共有とか)に関する話であったり。 後半は気を抜いてしまって話をうまく聞き取れてないので、興味がある方はビデオで。。。\nVectorize Your Open Source Search Engine セッションページ:Vectorize Your Open Source Search Engine 動画: Atita Arora - Vectorize Your Open Source Search Engine - YouTube ベクトル検索が流行ってきてるけど、これまでの検索(エンジン)に対して、どうやってベクトル検索を取り入れる?という話です。 ベクトル検索ってどんなもので、どういうことの助けになりそうか?じゃあ、どうやって、これまでの検索が改善したかを見ていくのか? という、これからベクトル検索を取り入れようとしている時にどのようなアーキテクチャにして、 どのような考慮するポイント(モデルの選択とかスケーラビリティとか)にどんなものがあるのか?といった紹介でした。 ざっくりですが、ベクトル検索やるのにどんなことをやっていけばよいのか?という地図になるようなセッションでした。\nSupercharging your transformers with synthetic query generation and lexical search セッションページ: Supercharging your transformers with synthetic query generation and lexical search 動画: Milind Shyani - Supercharging your transformers with synthetic query generation and lexical search - YouTube AWSの人の話でした。こちらもトランスフォーマーが検索に使えると便利だよねという話なのですが。 LLMを使うと高コストでサイズがどんどん大きくなっていて、小さな学習済みのモデルだといまいちな精度でだし、 ファインチューニングしたい場合、ドメインに特化したデータはなかなかないよね。とくにデータ(検索したいもの)はあるけど、クエリがないということがよくあるよね。 そこで、LLMを使って、データからクエリを作って、正解データを作り、それでファインチューニングすればいいのでは? ということで、やってみました、どうでしたという話でした。\nブログなどもあるので参考にすると面白いかも\nThe Debate Returns (with more vectors) Which Search Engine? セッションページ:The Debate Returns (with more vectors) Which Search Engine? 動画:Charlie Hull - The Debate Returns (with more vectors) Which Search Engine? - YouTube 今年も検索エンジンの人を集めてパネルディスカッションです。今年は次の方たちが参加してディスカッションでした。\n参加者 Jo:Vespaの人。ランキングとかがよくできてるからVespa好き Alessandro:Apache Solrの人。SolrのPMCメンバー。なんでSolr?Pure OSSだし。スケーラブルだ Etienne:Weaviateの人。新しいAI nativeなベクトルデータベース Philipp:Elasticの人。 Kacper:Qdrantの人。 質問は次のようなものでした。\n最初の質問:スケールの話。スケールアウトかな? 2つ目の質問:どんなアプリケーションが適していないか? 3つ目の質問:どうやってAIをサポートできるの? 4つ目の質問:どうやってコミュニティにアプローチしてる? 5つ目の質問:自分の検索エンジンが使えない時に何を使う? 6つ目の質問:今後に何が面白そう? 最後の質問:あなたの検索エンジンが使われてるユースケースで一番好きなものは? 2つ目や5つ目の質問が面白いですよね。実際の内容はぜひビデオを見ていただくのがいいかと(メモも取ったけど、聞いてもらうほうが面白そうだし)。\nWhat\u0026rsquo;s coming next with Apache Lucene? セッションページ:What\u0026rsquo;s coming next with Apache Lucene? 動画:Uwe Schindler - What\u0026rsquo;s coming next with Apache Lucene? - YouTube 毎年恒例Uweさん。今年Luceneが25周年という話で、これまでの進化の話を駆け足でしてくれました。 あとは、後半は来週9.7が出るよということで、9.7で入ってくるベクトルの距離計算の最適化に関して説明してくれています。 次のバージョンのElasticsearchでもこの最適化が使えるようになるという話もされていましたので、ベクトル検索を使ってる方は、次のバージョンも楽しみですね。\nBuilding MLOps Infrastructure at Japan\u0026rsquo;s Largest C2C E-Commerce Site セッションページ:Building MLOps Infrastructure at Japan\u0026rsquo;s Largest C2C E-Commerce Site 動画:Berlin Buzzwords 2023: Building MLOps Infrastructure at Japan\u0026rsquo;s Largest C2C E-Commerce Site - YouTube メルカリの検索システムに関係しているMLOps周りがどうやって進化してきたのか?という話でした。 英語にいらすとやの絵があるスライドがドイツで使われているのがとても新鮮ですw\nHighly Available Search at Shopify セッションページ:Highly Available Search at Shopify 動画:Khosrow Ebrahimpour - Highly Available Search at Shopify - YouTube Shopifyの検索プラットフォームチームの人の、Shopifyの検索プラットフォームがどういったものか?(EsとKafka使ってる)どんな工夫をしているか?という話です。 Kubeconでも他の同僚の方が話をされている見たいで、そちらも参考になるとのことでした(動画)。 スキーマ変更時の話とかもあり、実践的でした。最後に将来的な話でやはりベクトル検索というキーワードが出てきていました。あとは、データ量が大きいのでスケーリングの挑戦もあるとのこと。\nUsing Dense Vector search at the EU Publications Office セッションページ:Using Dense Vector search at the EU Publications Office 動画:Martin Bayton - Using Dense Vector search at the EU Publications Office - YouTube EUのPublication Office(日本だと公文書館とかになるのかなぁ?)の検索サービスで、Googleみたいなこと(検索結果の上にスニペットが出たり、そこにハイライトされたり)をやってみたいよね?という話みたいでした。実際公開してるかはわからないですが、途中からはPureinsightsという会社のプラットフォームで似たようなことをやるデモになってました。\nGoogleでも12%のクエリが、質問の自然文になっているという話で、検索結果にナレッジグラフからの情報(スニペットとか、質問に対する答えとか、地図とか)が出るようになってきていますと。 それをPublication Officeのデータで再現したデモを行った後に、どんな感じのアーキテクチャなのか?という概略を説明されています。国会図書館とかの検索サービスやってる方が興味を持ったりするかもなーと思ったり、思わなかったり?\nLearning to hybrid search セッションページ:Learning to hybrid search 動画:Berlin Buzzwords 2023: Learning to hybrid search - YouTube これまたキーワード検索とセマンティック検索のハイブリッドの話です。 よくハイブリッド検索というのを聞きますが、データだったりベンチマークなどの話があまりないですよね?昨年AmazonがECSIというデータセットを公開したりしています(rejasupotaroさんが年末に書かれた記事にも出てきていました)。 これにLearn to Rankとかもテストできるようなデータ(レビューや評価、カテゴリーとか)を拡張したものを作って、それをもとにいろいろとハイブリッド検索で精度を測ってみたというお話でした。 Metarankというリランキングエンジンの会社の方たちで、Metarankを使ってハイブリッドな検索結果のリランキングで精度がどのように上げられるか?という話です。 今年のTRECのProduct Search Trackの話もされていました。 これが元ネタのブログかな?\nCatch the fraud — with observability and analytics セッションページ:Catch the fraud — with observability and analytics 動画:まだ? 最後は元同僚のセッションです。こちらは検索ではなく、ちょっと自虐的なネタをもとにしたオブザバビリティおよび分析のお話です。 コミュニティの人たちの貢献(ブログ書いたりプルリク送ったり、どこかで話をしたり)を計測して、年間の貢献者に対してプレゼントを上げるというのをやっているみたいです。 で、昨年の最も貢献した人にMac Bookをプレゼントするというすばらしい(暴挙)話で、チートしようとした人がいてそれを分析した話でしたw 締め切り直前に信じられない量の貢献したという登録がブラジルからあり、何かおかしいよね?ということで、Elastic Stackのオブザバビリティの機能などを元に分析してチートした人を除外していったよという話でした。 Kibanaが使いやすくなってるのがわかるセッションで面白かったです。\nまとめ 検索がまたすごく盛り上がってきたなーという時間があるカンファレンスでした。みんな似たような話(ベクトル検索、LLM、AIなど)だったりしますが、 知らないプロダクトで興味が出てくるものもあったし、Amazonのデータセットがあるからいろいろ試してみることもできそうだなぁと。\nすでにビデオが公開されはじめているので、気になったセッションのビデオも見てから後日またブログを書こうとおもいます (たぶん、一覧が作成されるので後日リンクを貼っておきます)。\n来年の予定(6月11日から開催)も公開されていましたし。来年も楽しみですね。 来年はプロダクションでベクトル検索やってみた話とかがさらに出てくるのかなぁ?\n","date":1687278645,"dir":"post/2023/","id":"9335522f4c8dbc7256a42a091e6e00bc","lang":"ja","lastmod":1687278645,"permalink":"https://blog.johtani.info/blog/2023/06/21/attend-berlin-buzzwords-2023/","publishdate":"2023-06-21T01:30:45+09:00","summary":"今年もこの季節がやってきました。 Berlin Buzzwordsにオンラインで出張してました。 今年もハイブリッド開催をしてくれたので、オンラインで参加で","tags":["conference","belin buzzwords"],"title":"今年もオンラインでBerlin Buzzwordsに参加した"},{"contents":"今年もなんとか振り返りブログを書いてます(時間大丈夫かな?w)。紅白をリアタイで見ながら。\n振り返り(2021年に書いた抱負から) まずは振り返りをと。\nフリーランス継続 ありがたいことに個人事業主として今年も1年乗り越えられました。 ZOZOさんには引き続きお世話になっている感じです。 10月からは今月末まで別のお客さんを手伝っていたりという感じでした(アップグレードの手伝いとか)。 相変わらず完全リモートで作業をさせていただいてます。\nただ、来年は今の所、余力がある感じになっているので、新しい仕事を見つけたいところだなあという感じです。 検索で何かお手伝いできることあれば、気軽にお声がけいただければと。\nプログラミング Linderaの大須賀さんのおかげで、レビューは定期的にやらせていただいてますw 業務がっつりというほどではないのですが、検証用のコードを書いたりはしています。\n個人用では、BGM環境のためにシェルを書いたり、文字化けしてるデータを解析したりするのにコードを書いてますが、もうちょっと量を増やしたいところです。 コードがっつり書く仕事をやらせてもらうのとかやらせてもらうのがいいかもなぁ。\n書くよりもどうしても読むほうが多くなってる気がします。\nブッチャー本ちゃんと読む 全部ではないですが、ZOZOさんで輪読をしたりしていました。 が、自分で全部読むといったところまではできてないです。\n読んだ本のブログを書く これはできてないですね。 読むのはちょとちゃってるんですが、ブログを書くところまではできてない。 メモとりながら読みたいですね。\n振り返り(今年あったできごと) ここからは今年の出来事を。 今年もずっと自宅で仕事した。来年は出張とかできるのかなあ?\n自宅環境 今年もDIY 検索ペンギン本が出版された 仕事場を模様替えしました。 今年もずっとWindows環境をメインで仕事をしていました。 年末まではM1 Macを借りて作業するという経験もできたのでよかったです。 今年仕事の環境は少し変わって、AVアンプ(譲り受けたもの)+Polk Audioのスピーカーで音が良くなりましたw あと、机の天板を大きくして、作業がやりやすくなりました。写真はそのうち。\n仕事場の模様替えにもなるのですが、今年のDIYはラブリコ+有孔ボードでケーブルやキーボードをすっきり片付けられる環境を作ってみました。 壁を有効活用できるのはよかったです。こちらについては、別途ブログを書こうと思います。\n今年最大のニュースは検索ペンギン本を出版したことです。 声をかけていただいた打田さんには感謝です。著者の皆さん検索システムを色々と手掛けられているので良い本になったと思います。\n『検索システム ― 実務者のための開発改善ガイドブック』 – 技術書出版と販売のラムダノート おー、届いたー pic.twitter.com/RbY5tOe9GB\n\u0026mdash; Jun Ohtani (@johtani) May 17, 2022 いろんなところで輪読も開催されているようで、顔を出してみたいなぁ。 輪読やってます!外部の人を呼んでもOKという方がいたら、参加してみたいのでTwitterでメンションしてもらえると嬉しいです。\n来年の抱負 ということで、来年の抱負です。\nフリーランス継続 プログラミング ベクトル検索まわりをさわる 本を読む 今年もありがたいことに仕事を継続していただけて、乗り越えられました。 来年も価値を提供できるように頑張っていきます。 もっといろんな会社の検索システムを見てみたいですし、検索エンジン入れてみたけどここからどうすればいい?という方も増えて来ているような気がするので、気軽に声をかけていただければと。\nプログラミングは、家の音楽ファイルの文字化けを直すプログラムをもう少しちゃんと書いてからブログを書きたいなと。まぁ、個人的なプログラムなので誰も嬉しくないかもですが(色々検討した結果Javaで書いてる)。 あとは、オライリーさんの初めてのGo言語を買ったのもあるので、前にRustで書いたElasticsearchへのBulk登録のツールをGoで書いてみようかなと考えているところです。みんなはデータ登録するときはどうしてるんだろう?\nNLPでBERTなどによる目まぐるしい進歩の影響もあり、ベクトル検索やセマンティック検索といった検索技術が各社から出て来ています。 ElasticsearchでもGAされたのもあり、今後ますます注目を浴びる技術になるのだろうなと。 ただ、これまでの検索とどう組み合わせるのがいいのか?どう言ったメリットデメリットがあるのか?向き不向きは?といったものもあるので、仕組みを調べながら色々と試行錯誤してみたいと思っています。\nさいごは、毎年書いてる気もしますが、本を読むのもやらんとなぁ。 あたらしいネタを仕入れては実践できる時間もとりつつ、他のことにも目を向けたいと思っています。\n今年は仕事の変化も少し出て来ているので、来年は新しいことをいくつかやってみたいところです。 あとは、外に出る機会が増やせるといいなぁ、少しずつ人から刺激をもらいたいと思っています。\nさて、今年は年内に無事描き終わりました。 来年もよろしくお願いいたします、良い年にしたいなー。\n","date":1672486684,"dir":"post/2022/","id":"df30d810068e4656498e5972c6de7e3d","lang":"ja","lastmod":1672486684,"permalink":"https://blog.johtani.info/blog/2022/12/31/review-2022/","publishdate":"2022-12-31T20:38:04+09:00","summary":"今年もなんとか振り返りブログを書いてます(時間大丈夫かな?w)。紅白をリアタイで見ながら。 振り返り(2021年に書いた抱負から) まずは振り返","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2022)"},{"contents":"PySpaアドベントカレンダーの12/15のエントリーです。昨日はtaichiさんでした。 今年はDIYではなく、PCにまつわる話を。\n仕事中はBGMが基本 フリーランスを始めて(2020年初頭)からすぐに、自宅で仕事をする情勢になりました。 打合せをしていないとき、カンファレンスの発表などの動画を見ていないときは基本的にBGMをかけて作業をしています。 音源としては、CDなどから音楽ファイルにしたり、AmazonやSonyのサイトで購入した音楽ファイルなどがNASにあります。\n今年10月までの環境 2020年の後半に次のような環境を構築して今年の10月まで使っていました。\nLibreELECをラズパイ4に入れて、Kodiのリモコンをスマホに入れたら快適になった\n\u0026mdash; Jun Ohtani (@johtani) October 20, 2020 KODIと呼ばれるマルチメディアセンター?のようなソフトで、それを動かす最小限のOSとして、LibreELECが公開されています。 これをラズパイ4に入れて、NASからファイルをSSDにコピーしてそれをラズパイに接続して音楽を聞いていました。 毎回ラズパイの画面を見に行くのも面倒なので、再生などの操作にはAndroid用のKodiのリモコンアプリを使っていました。\n場所も取らないのでよかったのですが、使っているといくつか問題点が。\n時々調子悪(音が出ない、リモコンからつながらない、無反応など)くなって、ラズパイ再起動 音楽ファイルを購入して増えた時に、外付けSSDを取り外してPCでコピーしたり スマホじゃないと再生できない(PCのクライアントもあったのかもだけど調べてなかった) Ubuntu on Mac mini 10月に模様替えをして、2012年製のMac Miniが宙ぶらりんになりました。 さすがに古いしメインマシンがWindowsになっているのもあり、macOSである必要も特にないので、Ubuntu 22.04を入れて何かに使えるのでは?と。 また、1TBのSSDに内臓ディスクを乗せ換えていたのもあり、音楽再生に使ってみようということに。 なので、Kodiの環境で困っていた点も考慮して、ほしい機能を元にちょっと探してみました。\n音楽再生 on Ubuntu 音楽再生でほしい要件としては次のようなものです。\nUbuntuで音楽再生できるソフト(あたりまえ) PCから操作したい(できればブラウザ) 音楽ファイルの更新(ローカルでもいいけどNASからもってきたり) 日本語の曲情報も表示 対象音楽ファイルが豊富(そんなに制限があるものはないだろうなぁ) 上記の要件をもとに適当にググって見つけてきたのがOwnToneというソフトでした。\nOwnTone OwnToneの説明は公式サイトを見ていただくとして、OwnToneにしてよかったなというのが以下の点です。\nインストールが簡単(apt-getでインストールできる) サポートフォーマットが豊富 Web UIがついてる(ブラウザで見えるし、スマホでもOK。どのブラウザから見ても今の状況も分かる) 簡単だけど検索できる プレイリスト対応(ファイルパスを入れるだけ) サムネイルとかも出てくる(どうやってんだろう?w) AirPlayで再生できる(AVアンプを利用しており、そこにAirPlayで再生できてる) OSS(まだソースは見たことないですがw) 再生画面例\nやっぱ検索も気になるよね?\n日本語も検索できるな。 pic.twitter.com/EF6WHkJKli\n\u0026mdash; Jun Ohtani (@johtani) October 19, 2022 とりあえず、インストールして画面もすぐに出て操作も簡単で、便利な世の中になったなーと感動しましたw\nただ、音がヘッドフォン端子に刺したアナログ出力先のスピーカーではなく、本体のスピーカーで最初はなってしまいましたww Linuxの音周りが全然わかってない問題が発覚。\n幸い、先週のPyspa Advent Calendarのエントリーを書いていたaodag先生に助言をいただき、alsamixerで音の設定を見たところ、ヘッドフォン端子がミュートされていたので、ミュートを外して無事再生できました。 インストール当初はYAMAHAのアクティブスピーカーにJust Mixer経由でヘッドフォン端子(アナログ)で出力して音楽再生をしていました。 今は(この記事を書いてる現時点で)、AVアンプのAirPlayにOwnToneから音を流している形で聞いています(便利なんだけど、当初の想定とは異なる、理由は後述)。\nファイルのコピーとか さて、上にも書きましたが、NASにバックアップもかねて音楽ファイルを保存してあります。 新しく買ったファイルもここに置くようになっています。 OwnToneのMac MiniからNASをネットワーク経由で見に行くのもいいのですが、できればローカルにあったほうがネットに影響も出ないなと。\nということで、定期的にNASをウォッチしてMac Miniにファイルをコピーするようなプログラム(Bashスクリプト)を書いてみました。 毎回購入後に手で実行もめんどくさいので毎日夜中にcron実行するような設定になっています。\nスクリプトの中身は次のような感じです。\nfindコマンドで特定の日時(最近コピーしたファイルの日付)以降(-newermtオプション)のファイルのリスト(音楽ファイルの拡張子に限定)を取得 取得したリストをもとに以下の操作 ファイルをコピー コピーしたファイルをコピーした日付のプレイリストを作って入れる(プレイリストはパスだけ書けばOK) mp4形式だと聞けない端末もあるので、soundconverterコマンドでmp3に変換してNASに戻す 最新のファイルの日付を保存(次回のfindコマンド) ファイルがあったら、OwnToneの再読み込みのエンドポイントをcurlでキック NASはSambaでマウントして、見えるようにしてあります。 やっぱり、自動化便利ですねぇ。 気に入った曲を買ってNASに入れとけば聞けるようになるのは本当に便利。\n他にもスマートプレイリストとかもあるので、活用しないとな。\n今後の課題 さて、すごく便利になったのですが、課題も残っています。\n音声出力問題 アナログ出力はaodag先生の助言ですぐに解決したのですが、takabowから譲り受けたAVアンプを導入してから実は音の出力がうまくいっていません。\nHDMI、光端子出力でAVアンプにつなごうとしたのですが、私のUbuntu力(Linux力?)が全然不足しているのでうまくいっていません。ググりつつ、HDMI、光出力でamixerというコマンドで音声ファイルを鳴らすところまでは行ったのですが、OwnToneに設定するとうまくいかない状況です。 結局、解決してないのですが、AVアンプのAirPlayのレシーバー経由で音楽再生ができてしまったので、とりあえずAirPlayで運用することにしました。時間を見つけてaodag先生の記事を読み直して再チャレンジしないとな(けど、鳴ってるしなぁ、音w)。\n文字化け問題 これは、OwnToneというよりはもともとあった問題です。 古い音楽ファイルだったり、Wav形式のファイルなど、様々な形式のファイルを持っています。 音楽サーバーとは別に、音楽ファイルの検索をできるようにしつつ、付加的な情報(Wikimediaなどのデータとか)を付与して、検索できるようにしてみようと思い、音楽ファイルからメタデータを抜き出して、ElasticのApp Searchにいれるデータを作るツールを書いたりしています。 この時にも文字化けに遭遇しました。\n様々な音楽ファイルにはメタデータを付与することができる仕様が決まっています(ID3タグ - Wikipediaなど)。 ただ、文字コードの情報が入っていなかったり、デフォルトとは違う文字コードでデータを付与したファイルがあったり、いろいろな原因で文字化けしているものがあります。 昨年Amazonで購入したmp3の中にも文字化けしているものもあったりします。Wavファイルに付与されたタグなどは、容赦なくShift-JISだったりしますが、読み込むソフトはUTF-8で読もうとしたり。。。\n検索サーバーにデータを抜き出して入れるツールを書いているときは、元のファイルを変更することなく、抜き出す時点でいくつかの文字化けに対応した処理を書いたのですが、今回のOwnToneで曲を流すと結局、元のファイルをきれいにしないとダメだということに気づきました(すぐわかるだろ。。。)\nということで、書いている途中のツールをもとに、根本的な文字化けのファイルのメタデータをきれいにするプログラムを書かないといけないなぁと。\nちなみに、メタデータの抜き出しにはJavaでプログラムを書いており、JAudiotaggerというライブラリを利用しています。 Pythonや他のJavaのライブラリを試そうとしたのですが、文字コードが決め打ちで抜かれているものが多く、ライブラリから読みだした時点ですでにどうしようもない状態のものが多いといった問題からこのライブラリにたどり着きました(まぁ、まだちゃんとしたものができていないんですけどね)。\n検索サーバー OwnToneのUIはブラウザでうごきます。 検索窓もついています。 が、先ほども書いたように、他にもデータを追加して、いろんな検索をしてみたいなぁと(ドラマに使われてたとか、CMにつかわれてたとかとか)。 検索が好きでいろいろとやってるので、その辺も遊んでみたいなぁと思っているところです(実際、ElasticのApp SearchにWikidataから生成した類義語を入れてみたりしている)。\nこうやってブログにしてしまったので、課題をつぶしていなかったら、Twitterなどでつついてくださいw\nまとめ 構成図とかは書かなかったですが、OwnToneを使うと簡単にWeb UIが入った音楽サーバーが使えるようになって、仕事がはかどりますよという記事でした。 他にもこれに関するネタを募集してますので、コメントもらえるとうれしいです(Twitterでメンションも大歓迎)。\n","date":1671030358,"dir":"post/2022/","id":"67c2ae6761e89be0fa66db9623b40d30","lang":"ja","lastmod":1671030358,"permalink":"https://blog.johtani.info/blog/2022/12/15/music-server-on-mac-mini/","publishdate":"2022-12-15T00:05:58+09:00","summary":"PySpaアドベントカレンダーの12/15のエントリーです。昨日はtaichiさんでした。 今年はDIYではなく、PCにまつわる話を。 仕事中は","tags":["misc","music"],"title":"仕事中のBGM環境"},{"contents":"本記事は情報検索・検索技術 Advent Calendar 2022の9日目の記事です。\nだいぶ間が空いてしまいましたが、日本語のオートコンプリートに関する記事の続きです。 という感じで、Suggesterのデータ構造とか仕組みを書こうと思っていたのですが、思ったよりも調べないといけないことが多くて挫折しました。。。 (これの続きは年末年始で調べて書くはず?)\nということで、代わりにElasticsearch/OpenSearchのアーキテクチャの変更に関してさらっとまとめてお茶を濁してみようと思います。\n発端はElasticON Tokyo? 先週の11月30日に、ElasticのオフラインイベントであるElasticON Tokyoが開催され参加しました。 参加しようと思ったのは、10月の頭にElasticのブログで公開された「Stateless — your new state of find with Elasticsearch」というアーキテクチャの変更がきっかけです。\n(図はElasticのブログから引用)\nElasticsearchはLuceneのインデックスを分散したシステムとしてスケールアウトできるようにするという目的でリリースされました。 インデックスをシャードという単位で複数のElasticsearchのノードにデータを保存し、レプリカを作ることで分散する仕組みを実装していました。 Elasticsearchでは、インデックスのレプリカは、作成したインデックスを定期的にコピーするのではなく、登録するデータがElasticsearchのクラスターにやってきた時に、 データ自体をコピー先にも配り、プライマリーやレプリカとなるシャードがあるノード上でそれぞれインデックスに登録する処理を行うという処理の流れです(古いけど、わかりやすい説明はこちら)。 この場合、インデックスにデータを登録する処理(転置インデックスのデータ構造に変換する処理など)は、レプリカの数だけ同じ処理がクラスター上で発生します。\nこの基本的なアーキテクチャをもとに、保持するデータの鮮度(新しいデータのほうが検索頻度が高い、インデックス登録する時はマシンは多く、古くなったデータが入ったインデックスはコストが低いマシンになど)などを元に、クラスター内のノードの特性を異なるものが混在するような複雑な仕組みを作ってきました。 いろいろなデータの持ち方などで多くのデータなどを保持できるようにしてきたのですが、クラスター全体としては、検索の負荷のピークをさばけるような構成を基本的に保持しておくというかんがえです。\nただ、昨今は必要に応じてスケールアウト(リクエストが増えたりデータ量が増えた時)、スケールイン(夜中は利用者が少ないからクラスターを小さくしたい時)できるような仕組みのほうが求められています。 そこで、発表されたのが上記のブログであり、上図の新しいアーキテクチャです。 計算処理(データを登録、検索する処理)とストレージを分離し、さらに登録する処理と検索する処理も分離した構成です。 このようなアーキテクチャにすることで、登録処理の演算コストがレプリカごとに必要ではなくなり、検索の部分だけだったり、登録の部分だけをスケールアウト・インできるような自由度が手に入ります。 また、ストレージ部分でレプリカを担保(S3とかのオブジェクトストレージで冗長性を担保)できれば、レプリカのストレージコストも必要なくなります。\nというブログが発表されたのですが、詳細などはまだよくわからなかったのでElasticON Tokyoに参加して詳しい話が聞けるのかなぁと期待していました。\n参加当日の朝のびっくりするニュース 11月30日の朝に起きて、出かけようかと思っていたところに、AWSのre:Inventで発表されたニュースが舞い込んできました。\nほー(まだタイトルしか読んでない)https://t.co/KK22duaBNH\n\u0026mdash; Jun Ohtani (@johtani) November 29, 2022 Amazon OpenSearchがServerlessオプションを発表というニュースです。 (Amazon OpenSearchとは、AWSがElasticsearchをフォークして始めた検索エンジンで、Amazon OpenSearch Serviceというのは、AWSがそれをSaaSとして提供しているものです)\nまぁ、気になりますよね、「Serverless」ってキーワードに。 ElasticON Tokyoに向かう電車でブログを読んだり、どんな仕組みかを調べたので、それを簡単にまとめておきます。\nプレビュー段階(Tokyoリージョンではもう試せる) これまでのAmazon OpenSearch Serviceとは別(オンザフライで移行はできない?) 「コレクション」という単位でクラスターを管理(スケールインとかアウトとか) コレクションにはタイプがあり、タイムシリーズ(ログとか)か検索のユースケースなのかで使い分ける(公式ドキュメント) インデックス処理と検索処理で計算ユニット(OCU)が別々にスケールできる(下図) 作成されたインデックスはAmazon S3に保存され、そこで冗長性は担保される。(下図) 検索処理のユニットはS3のデータをローカルに持ってきて処理をできる データ登録とかのAPIは基本的にServerlessかどうかで違いはなさそう(これまで通りのクライアントでアクセスとかで競う) 設定した範囲でいいかんじにスケールアウトインしてくれそう(ほんとかな?) もちろん、いくつか制限がある(サポートしてないプラグインとか操作もある) (図はAWSのドキュメントより引用)\n発表時のブログでは詳しくはわからないのですが、公式ドキュメントではさらに詳しく説明がありました。 こちらを読むほうが仕組みがわかると思います。 今後もどんどんドキュメントは充実していくんだろうなと。今ならまだサクッと読める量ですw\nただ、「サーバーレス」という定義が私はよくわかりませんでした。 公式ドキュメントを読むとコレクションを作ると少なくとも4つのOCUが起動しているみたいで課金されると記載があります。\nまぁ、Elasticの発表と同様に、これまでは最大負荷の時を元にクラスターを維持せずとも、より柔軟に検索だけ、登録処理だけを一時的にスケールできるとコストを下げられそうですね。 すぐに誰かが使ってみたブログなどを出してくれると思うので、細かな使用感などはそのうちわかってくるかと。\n今後は? ElasticもAWSも考え方の基本となっているのは、Berlin BuzzwordsでAmazonのMikeさん(Luceneのコミッター)が2019年に発表されたものだと思っています。 アーキテクチャの変更がどんな影響が出るかはわからないですが、少なくとも検索のユースケースでよりスケールアウトしやすくなるだろうなと。 どちらもSaaSとしての仕組みとして提供するので、検索エンジンそのものの機能として公開されるかはわからないです。 ですが、そのほかの検索エンジンも出てきていますし、今後も検索エンジンから目をはなせないです。 今回は残念ながら触っていませんが、時間を見つけて使ってみたいです(Elasticも早く出してくれないかなー)\nということで、当初の予定とは違うブログになってしまいました。。。 技術的な深い話はまたどこかで。。。\n参考文献 Stateless — your new state of find with Elasticsearch | Elastic Blog Preview: Amazon OpenSearch Serverless – Run Search and Analytics Workloads without Managing Clusters | AWS News Blog Berlin Buzzwords 2019: Michael Sokolov \u0026amp; Mike McCandless–E-Commerce search at scale on Apache Lucene - YouTube ","date":1670516125,"dir":"post/2022/","id":"9693a1e77dee5785b1dc61ccffd2e906","lang":"ja","lastmod":1670516125,"permalink":"https://blog.johtani.info/blog/2022/12/09/open-search-serverless/","publishdate":"2022-12-09T01:15:25+09:00","summary":"本記事は情報検索・検索技術 Advent Calendar 2022の9日目の記事です。 だいぶ間が空いてしまいましたが、日本語のオートコンプリートに関する記事の続きです。","tags":["elasticsearch","opensearch"],"title":"ElasticsearchのアーキテクチャとStateless / Serverless"},{"contents":"前回は日本語用オートコンプリートのためのAnalyzerとして、どうやって使うのかを簡単に紹介しました。\n今回はもう少し、いろんなパターンを試してみたいと思います。\nローマ字入力のゆれ 前回のサンプルでも「吾輩\u0026hellip;」のデータをサジェストするためのサンプルとして、「wagah」という「わがはい」をローマ字にしたものを利用しました。\nちなみにローマ字というとどんなものを思い起こしますか? 普通は学校で習ったヘボン式あたりだと思います。 Kuromojiの読みでローマ字出力するには通常、kuromoji_readingformでuse_romajiをtrueにします。 以下、「吾輩」のサンプルです。\nGET _analyze { \u0026#34;text\u0026#34;: [\u0026#34;吾輩\u0026#34;], \u0026#34;tokenizer\u0026#34;: \u0026#34;kuromoji_tokenizer\u0026#34;, \u0026#34;filter\u0026#34;: [ { \u0026#34;type\u0026#34;: \u0026#34;kuromoji_readingform\u0026#34;, \u0026#34;use_romaji\u0026#34;: true } ] } レスポンス { \u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;wagahai\u0026#34;, \u0026#34;start_offset\u0026#34;: 0, \u0026#34;end_offset\u0026#34;: 2, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 0 } ] } 「吾輩」の場合は特に問題ないのですが、ローマ字による日本語入力の場合、次のような単語を入力するときに、ゆれが生じます。\nシャボン=「shabon」 新橋=「shimbashi」 括弧内はkuromoji_readingformで出力したもの(=ヘボン式のローマ字)です。 ですが、ローマ字入力の場合は「syabon」や「shabon」と入力したり、「sinbasi」や「sinnbasi」と入力すると思います。 JapaneseCompletionAnalyzerを利用したCompletion Suggesterの場合、これらのゆれも考慮してサジェストしてくれるようになっています。 前回のサンプルデータを用いると次のような感じです。\nGET aozora_index/_search { \u0026#34;explain\u0026#34;: true, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: { \u0026#34;prefix\u0026#34;: \u0026#34;sha\u0026#34;, \u0026#34;completion\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;suggest_ja\u0026#34; } } } } GET aozora_index/_search { \u0026#34;explain\u0026#34;: true, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: { \u0026#34;prefix\u0026#34;: \u0026#34;sya\u0026#34;, \u0026#34;completion\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;suggest_ja\u0026#34; } } } } これらのリクエストは、「しゃ」について2パターンになっていますが、結果はどちらも次のものが返ってきます(このレスはsyaのレスになります)。\n{ \u0026#34;took\u0026#34;: 1, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;sya\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 3, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;シャドウ・ワーク\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;000739\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;シャドウ・ワーク\u0026#34;, \u0026#34;朝倉 克彦\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;シャボン玉\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;045054\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;シャボン玉\u0026#34;, \u0026#34;豊島 与志雄\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;上海\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;050899\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;上海\u0026#34;, \u0026#34;横光 利一\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;斜坑\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;002095\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;斜坑\u0026#34;, \u0026#34;夢野 久作\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;社会事情と科学的精神\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;053864\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;社会事情と科学的精神\u0026#34;, \u0026#34;石原 純\u0026#34; ] } } ] } ] } } 「sinnba」や「shinba」も試してみました。\nGET aozora_index/_search { \u0026#34;explain\u0026#34;: true, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: { \u0026#34;prefix\u0026#34;: \u0026#34;sinnba\u0026#34;, \u0026#34;completion\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;suggest_ja\u0026#34; } } }, \u0026#34;_source\u0026#34;: [\u0026#34;suggest_ja\u0026#34;] } GET aozora_index/_search { \u0026#34;explain\u0026#34;: true, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: { \u0026#34;prefix\u0026#34;: \u0026#34;shinba\u0026#34;, \u0026#34;completion\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;suggest_ja\u0026#34; } } }, \u0026#34;_source\u0026#34;: [\u0026#34;suggest_ja\u0026#34;] } これらも同じ結果です。\n{ \u0026#34;took\u0026#34;: 0, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;shinba\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 6, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;しんばい\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;044942\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;しんばい\u0026#34;, \u0026#34;村山 籌子\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;新橋\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;002409\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;新橋\u0026#34;, \u0026#34;北原 白秋\u0026#34; ] } } ] } ] } } 入力されるパターンを想定した実装がされているので対応できている形です。 使い方が楽なだけでなく、より使いやすくなってるのは便利ですね。\nうまくいかないパターン 万事OKかというと残念ながらそうでもありません。 うまくいかないパターンもあります(これが本当にうまくいかないかは難しい話な気がしますが)。 「日本」という漢字ですが、「にほん」「にっぽん」どちらとも読めますよね? これらを試してみると次のようになります(リクエストは省略します)。\nまず「にほん」\n{ \u0026#34;took\u0026#34;: 0, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;にほん\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 3, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;日本橋\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;004565\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本橋\u0026#34;, \u0026#34;泉 鏡花\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本橋\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;045357\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本橋\u0026#34;, \u0026#34;牧野 信一\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本橋あたり\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;047648\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本橋あたり\u0026#34;, \u0026#34;長谷川 時雨\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本橋附近\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;055666\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本橋附近\u0026#34;, \u0026#34;田山 花袋\u0026#34; ] } } ] } ] } } 次に「にっぽん」\n{ \u0026#34;took\u0026#34;: 1, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;にっぽん\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 4, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;日本アルプスの五仙境\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;056269\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本アルプスの五仙境\u0026#34;, \u0026#34;木暮 理太郎\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本出版協会論\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;049436\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本出版協会論\u0026#34;, \u0026#34;嶋中 雄作\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本文化と科学的思想\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;055750\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本文化と科学的思想\u0026#34;, \u0026#34;石原 純\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本文化のために\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;003183\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本文化のために\u0026#34;, \u0026#34;宮本 百合子\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本文化の特殊性\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;055290\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本文化の特殊性\u0026#34;, \u0026#34;戸坂 潤\u0026#34; ] } } ] } ] } } 最後に「日本」\n{ \u0026#34;took\u0026#34;: 1, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;日本\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 2, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;日本アルプスの五仙境\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;056269\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本アルプスの五仙境\u0026#34;, \u0026#34;木暮 理太郎\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本出版協会論\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;049436\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本出版協会論\u0026#34;, \u0026#34;嶋中 雄作\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本文化とは何ぞや(其二)\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;002940\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本文化とは何ぞや(其二)\u0026#34;, \u0026#34;内藤 湖南\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本文化と科学的思想\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;055750\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本文化と科学的思想\u0026#34;, \u0026#34;石原 純\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本文化のために\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;003183\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本文化のために\u0026#34;, \u0026#34;宮本 百合子\u0026#34; ] } } ] } ] } } 最初の「にほん」は「日本橋」がヒットしているようです。返ってきたoptionsの数は4件しかなく、どうやらこれがすべてのようです(取得件数はデフォルト5件)。 2番目の「にっぽん」は「日本」という単語から始まるものがヒットしていますが、「日本橋」はなさそうでした。 最後に「日本」という漢字を入力にした場合は2つの合計が帰ってきているようです(今回のレスポンス例にはありませんが、サイズを大きくすると「日本橋」が帰ってきていました)。\nどうしてそうなるの? JapaneseCompletionAnalyzerの基本的な動作としては、\nKuromojiが単語に区切る 区切られた単語ごとに読みを持っている 元の単語と読みをローマ字にしたものが最終的に出てくる というような動きです。 この時、単語には「1つ」の読みが対応しています。 読みから単語を探そうとすると、読みの違い(ゆれ)を吸収することはできないためです。 JapaneseCompletionAanlyzerは3点目のローマ字のゆれに対応していますが、入力となる読みのゆれまでは対応できないです。 対応しているといいかどうかというのも難しい判断になる気もします。。。\nそのほかの例としては次のようなものもあります。 これは、今回のオートコンプリートの話とは少しずれてるかもしれませんが、1番目の処理の結果が変わってくる例です。 「南方熊楠」という名前の間にスペースがあるかないかで、出力される読みが変わってくる例です。\nGET _analyze { \u0026#34;text\u0026#34;: [\u0026#34;南方 熊楠\u0026#34;], \u0026#34;tokenizer\u0026#34;: \u0026#34;kuromoji_tokenizer\u0026#34;, \u0026#34;filter\u0026#34;: [\u0026#34;kuromoji_readingform\u0026#34;] } GET _analyze { \u0026#34;text\u0026#34;: [\u0026#34;南方熊楠\u0026#34;], \u0026#34;tokenizer\u0026#34;: \u0026#34;kuromoji_tokenizer\u0026#34;, \u0026#34;filter\u0026#34;: [\u0026#34;kuromoji_readingform\u0026#34;] } # GET _analyze { \u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;ナンポウ\u0026#34;, \u0026#34;start_offset\u0026#34;: 0, \u0026#34;end_offset\u0026#34;: 2, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 0 }, { \u0026#34;token\u0026#34;: \u0026#34;クマグス\u0026#34;, \u0026#34;start_offset\u0026#34;: 3, \u0026#34;end_offset\u0026#34;: 5, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 1 } ] } # GET _analyze { \u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;ミナカタ\u0026#34;, \u0026#34;start_offset\u0026#34;: 0, \u0026#34;end_offset\u0026#34;: 2, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 0 }, { \u0026#34;token\u0026#34;: \u0026#34;クマグス\u0026#34;, \u0026#34;start_offset\u0026#34;: 2, \u0026#34;end_offset\u0026#34;: 4, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 1 } ] } 人名や地名は1つの漢字に対して多くの読みが存在しているので大変です。。。 どうしてこれは出てこないんだろう?と不思議に思った場合は、_analyze APIを使ってどういう動きなのかを見てみるのがいいかと。\nまとめ ということで、少しだけですが、こんなことができるよ、できないよというのを書いてみました。 挙動をしっていれば、なんでこうなってるんだっけ?といったことを調べる役に立つかと思います。 入力された文字をもとにどれをサジェストするかなどについてはもう少し違う動きなので、中の仕組みをそろそろ書かないとなぁ。\n参考 同形異音語 - Wikipedia ","date":1660099802,"dir":"post/2022/","id":"73279888a8fe482c836fb19ca23318dc","lang":"ja","lastmod":1660099802,"permalink":"https://blog.johtani.info/blog/2022/08/10/jp-auto-completion-2/","publishdate":"2022-08-10T11:50:02+09:00","summary":"前回は日本語用オートコンプリートのためのAnalyzerとして、どうやって使うのかを簡単に紹介しました。 今回はもう少し、いろんなパターンを試","tags":["elasticsearch","lucene"],"title":"ローマ字入力のゆれと読み(JapaneseCompletionAnalyzerその2)"},{"contents":"風のうわさで、日本語用のオートコンプリートのためのTokenFilterとAnalyzerがLuceneに取り込まれたと聞きました(LUCENE-10102)。 Elasticsearchでも使えるかなぁ?ということで調べたところ(調べた?聞いた?)、どうやら8.1から利用できるようになっている(GitHub Issue #81858)みたいです(まだ、公式ドキュメントには記載がないのですが)。\n8/17追記\n作者の打田さんがブログ書いてたの見落としてた(もしくは見たけど忘れてた)ので貼っておきます。マルチテナンシー下での Query Auto Completion 設計・運用戦略 - LegalForce Engineering Blog\nということで、こんな感じで使えるよというのを試してみました。\nどういうもの? 日本語入力方法を考慮したオートコンプリート用のトークンを生成してくれるTokenFilterと、 それをLuceneのSuggesterで動くようにしたAnalyzerが用意されています。 Elasticsearchでは、Kuromojiプラグインにそれらを使えるようになっています(バージョン8.1.0以降)。 KuromojiTokenizerと一緒に利用する前提の仕組みとなります。\nオートコンプリートとは? 検索窓などでキー入力をしていると、入力した文字で始まる単語の一覧が現れることがあると思います。 あの機能がオートコンプリートと呼ばれるものです。search-as-you-typeとも呼ばれることもあります。 (検索ペンギン本にも書いてあるので興味のある方はぜひ!(ステマ)) 入力された文字列を含むパターンもありますが、今回紹介するものは入力された文字で始まる単語を見つけてくる機能になります。\n何がなんで追加されたの? 日本語の入力方法は、かな入力の人もいればローマ字入力の人もいます。 ですので、オートコンプリートでの入力として、「しゃ」という入力が来る場合もあれば、「sha」というローマ字入力途中のものが来る場合もあります。 これらを考慮したトークンの扱いができるように、 JapaneseCompletionFilterというクラスが追加されています。 内部的にはKuromojiTokenizerでトークンに分割された後に、もともとのトークンと同じポジションで読みをローマ字にしたものを出力します。 JapaneseCompletionAnalyzerは上記Filterをすぐに使えるようにしたAnalyzerです。\n動かし方 百聞は一見に如かずということで、Elasticsearchでの使い方を見たほうが分かりやすいので、簡単に動かしてみることにします。\nインストールとインデックスの用意 Elasticsearch(8.1以上)とKuromojiのプラグインをインストールします(今回試したのは8.3.1)。\nサンプルデータ なにかいいデータはないものか?と思っていたところ夏休みだというのを思い出しました。 夏休みといえば読書感想文だ、ということで、書籍のタイトルがいいかもなと。 青空文庫の著者名と書籍のタイトルの一覧を見つけたのでそちらのデータを使って試してみました。\nCSV to JSON CSVファイルは最後の参考にある青空文庫のページから、「公開中 作家別作品一覧:全て(CSV形式、zip圧縮)」をダウンロードしたものを利用しました。 CSVファイルだったので、jqコマンドで必要な部分だけをNDJSONの形でとりあえずファイルに出力します。\ncat list_person_all_utf8.csv | tr -d \u0026#39;\u0026#34;\u0026#39; | jq -c -R \u0026#39;split(\u0026#34;,\u0026#34;) | {\u0026#34;auth_id\u0026#34;: .[0] | tonumber, \u0026#34;author\u0026#34;: .[1], \u0026#34;id\u0026#34;: .[2] , \u0026#34;title\u0026#34;: .[3], \u0026#34;suggest_ja\u0026#34;: [.[3], .[1]]}\u0026#39; 次のようなJSONが1行ずつ出力されます。\n{\u0026#34;auth_id\u0026#34;:1257,\u0026#34;author\u0026#34;:\u0026#34;アーヴィング ワシントン\u0026#34;,\u0026#34;id\u0026#34;:\u0026#34;056078\u0026#34;,\u0026#34;title\u0026#34;:\u0026#34;駅伝馬車\u0026#34;,\u0026#34;suggest_ja\u0026#34;:[\u0026#34;駅伝馬車\u0026#34;,\u0026#34;アーヴィング ワシントン\u0026#34;]} suggest_jaがオートコンプリートの対象となるデータになります。今回は著作と著者にしてみました。 あとは次に紹介するスキーマでインデックスを作成して、適当なプログラムを使ってBulkでElasticsearchに登録しましょう(私は個人作のツールで入れました)。\nインデックス オートコンプリート用のSuggesterを利用するための特殊なフィールド(completion)を利用したフィールドを用意します。 ちなみに、今回はLUCENE-10102に記載があった設定をそのまま使わせていただきました。 そのほかのフィールドは今回は特に必要はないのでおまけです。\nPUT aozora_index { \u0026#34;mappings\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;completion\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;japanese_completion_index\u0026#34;, \u0026#34;search_analyzer\u0026#34;: \u0026#34;japanese_completion_query\u0026#34;, \u0026#34;preserve_separators\u0026#34;: false, \u0026#34;preserve_position_increments\u0026#34;: true, \u0026#34;max_input_length\u0026#34;: 50 }, \u0026#34;auth_id\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;author\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;fields\u0026#34;: { \u0026#34;keyword\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;keyword\u0026#34;, \u0026#34;ignore_above\u0026#34;: 256 } }, \u0026#34;analyzer\u0026#34;: \u0026#34;kuromoji\u0026#34; }, \u0026#34;author_id\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34; }, \u0026#34;id\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34; }, \u0026#34;title\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;fields\u0026#34;: { \u0026#34;keyword\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;keyword\u0026#34;, \u0026#34;ignore_above\u0026#34;: 256 } }, \u0026#34;analyzer\u0026#34;: \u0026#34;kuromoji\u0026#34; } } }, \u0026#34;settings\u0026#34;: { \u0026#34;index\u0026#34;: { \u0026#34;number_of_shards\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;analysis\u0026#34;: { \u0026#34;analyzer\u0026#34;: { \u0026#34;japanese_completion_index\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;index\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;kuromoji_completion\u0026#34; }, \u0026#34;japanese_completion_query\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;query\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;kuromoji_completion\u0026#34; } } } } } } 動作確認 ここまでで、インデックスとデータの用意ができました。 オートコンプリートを実現するためにはElasticsearchのSuggesterという機能の、Completion Suggesterを利用します。検索の仕方が通常のものとは少し異なります。 ちなみに、速度重視のためにインメモリで動いているとの記載がドキュメントにあります。\nCompletion Suggesterのクエリ Suggester用のクエリがあるのでこちらを使います。 例えば、「wagah」という入力がある時に、サジェストする内容を取得するには次のようなリクエストになります。\nGET aozora_index/_search { \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: { \u0026#34;prefix\u0026#34;: \u0026#34;wagah\u0026#34;, \u0026#34;completion\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;suggest_ja\u0026#34; } } }, \u0026#34;_source\u0026#34;: [\u0026#34;title\u0026#34;, \u0026#34;author\u0026#34;] } 最初の「suggest」がsuggest用のパラメータを意味しています。 次の「title-suggest」は好きな名前をつけられます。レスポンスにこの名前がついた配列がサジェストの結果になります(同時に3. 複数suggestを呼び出せるので、対応した結果が分かるように名前が付けられます)。 「prefix」に入力の文字列を渡します。 「completion」がsuggesterのタイプの指定です。今回はCompletion Suggesterなので「completion」を指定します。その中に「field」でcompletionに利用するフィールド名を指定します。先ほどのスキーマでcompletionタイプを指定したフィールドです。今回は「suggest_ja」になります。 「_source」は結果を見やすくするために、ヒットしたデータの一部だけ取得するオプションです。 すると、次のような結果が返ってきます。\n{ \u0026#34;took\u0026#34;: 1, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;wagah\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 5, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;『吾輩は猫である』中篇自序\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;002671\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;『吾輩は猫である』中篇自序\u0026#34;, \u0026#34;夏目 漱石\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;わが俳諧修業\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;003771\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;わが俳諧修業\u0026#34;, \u0026#34;芥川 竜之介\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;わが母をおもう\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;003997\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;わが母をおもう\u0026#34;, \u0026#34;宮本 百合子\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;わが母を語る\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;049723\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;わが母を語る\u0026#34;, \u0026#34;上村 松園\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;吾輩は猫である\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;000789\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;吾輩は猫である\u0026#34;, \u0026#34;夏目 漱石\u0026#34; ] } } ] } ] } } 「suggest」の「title-suggest」がCompletion Suggesterのレスポンスになります。 最初の「text」は入力の「prefix」の値です。「offset」、「length」もこの文字に関する情報なので特に気にしなくてもいいかと。 「options」がサジェストされた内容になります。それぞれの「text」がサジェストされた文字列になります。「suggest_ja」には著作と著者名を入れましたが、今回は著作が「text」に帰ってきていることがわかります。 次に著者名でもやってみましょう。 「太宰」という入力が来たものとしてリクエストを投げます。\nGET aozora_index/_search { \u0026#34;explain\u0026#34;: true, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: { \u0026#34;prefix\u0026#34;: \u0026#34;太宰\u0026#34;, \u0026#34;completion\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;suggest_ja\u0026#34; } } } } レスポンスは次のようになります。\n{ \u0026#34;took\u0026#34;: 1, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;太宰\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 2, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;太宰 治\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;000236\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;ア、秋\u0026#34;, \u0026#34;太宰 治\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;太宰 治\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;001572\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;I can speak\u0026#34;, \u0026#34;太宰 治\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;太宰 治\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;001578\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;愛と美について\u0026#34;, \u0026#34;太宰 治\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;太宰 治\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;046597\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;青森\u0026#34;, \u0026#34;太宰 治\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;太宰 治\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;004357\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;青森\u0026#34;, \u0026#34;太宰 治\u0026#34; ] } } ] } ] } } 先ほどとは異なり、「options」の中の個々の「text」はすべて「太宰 治」になってしまいました。 登録したデータは著作の一覧ですが、「suggest_ja」には著作と著者名を入れたためです。 これでは、実際に検索窓に実装したときに同じものが並んでしまいます。 こんな時のためのオプション「skip_duplicates」が用意されています。 先ほどのリクエストに「\u0026ldquo;skip_duplicates\u0026rdquo;: true」を追加します。\nGET aozora_index/_search { \u0026#34;explain\u0026#34;: true, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: { \u0026#34;prefix\u0026#34;: \u0026#34;太宰\u0026#34;, \u0026#34;completion\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;suggest_ja\u0026#34;, \u0026#34;skip_duplicates\u0026#34;: true } } }, \u0026#34;_source\u0026#34;: [\u0026#34;suggest_ja\u0026#34;] } するとレスポンスは次のように変化します。\n{ \u0026#34;took\u0026#34;: 1, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;太宰\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 2, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;太宰 治\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;000236\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;ア、秋\u0026#34;, \u0026#34;太宰 治\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;太宰治との一日\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;042582\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;太宰治との一日\u0026#34;, \u0026#34;豊島 与志雄\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;太宰治情死考\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;043137\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;太宰治情死考\u0026#34;, \u0026#34;坂口 安吾\u0026#34; ] } } ] } ] } } 「options」は3つに減り、重複していないことがわかります。 「text」が同じ場合は最初に出てきたものを返すようです(注意:結果から観測しているだけで、実装はまだ見ていません)。 (なお、今回は説明を省きますが、入力データでスコアを指定することも可能になっています)。 そのほかにもCompletion Suggesterにはいくつか仕組みが用意されているのですが、それはまた今度にでも。\nまとめ ということで、Luceneコミッターの打田さんに感謝です。 便利な仕組みが簡単に使えるようになるのはとてもありがたいですね。\nまずは簡単にどういうものかとどうやって使うのかを記事にしてみました。 中の動きや、注意点、これまでとの違いなどは次の記事にしようと思います。 そういえば、公式ドキュメントにはまだ出てきてないな、それを書こうと思ってついでに動かしてみたんだけど、追加するのはまた後日かな。。。\n参考資料 青空文庫 - 公開中 作家リスト:全て [LUCENE-10102] Add JapaneseCompletionFilter for Input Method-aware auto-completion - ASF JIRA Expose Japanese completion filter to kuromoji analysis plugin by mocobeta · Pull Request #81858 · elastic/elasticsearch Suggesters | Elasticsearch Guide [8.3] | Elastic ","date":1660028402,"dir":"post/2022/","id":"6639ec6f88c4976f8ca20fa840f169e3","lang":"ja","lastmod":1660028402,"permalink":"https://blog.johtani.info/blog/2022/08/09/japanese-auto-completion/","publishdate":"2022-08-09T16:00:02+09:00","summary":"風のうわさで、日本語用のオートコンプリートのためのTokenFilterとAnalyzerがLuceneに取り込まれたと聞きました(LUCE","tags":["lucene","elasticsearch"],"title":"日本語用オートコンプリートのためのAnalyzer"},{"contents":"Hugoを0.84から0.92にアップデートをする際に、これまでのブログ記事やレイアウトファイルを修正したので個人的にメモを残しておきます。\nなんでアップデート? うっかり魔がさして、メインのWSL2のUbuntuを20.04から22.04にアップグレードしました。。。 新規に22.04を落としてきて移行ではなく。 皆さんはまねしないほうがいいですよ! アップデートした後にGitの環境がおかしくなったりと大変でした。 WSL2のUbuntuではHugoでブログのビルド、いろんな確認のためのElasticsearchの起動、個人的なプログラムとかを書く環境として利用しています。\nで、Ubuntuを上げたところ無事(?)Hugoもアップデートされたわけです。 最初はGitでfetchが出来なくなって修正していましたが、そのほかの動作確認を行なう段階でHugoでブログがビルドできなくなっていることが判明しました。\nバージョンアップに伴う修正 hugoコマンドを実行すると、いくつかのERRORとWARNが出力されました。 次のようなものです。\nhugo v0.92.2+extended linux/amd64 BuildDate=2022-02-23T16:47:50Z VendorInfo=ubuntu:0.92.2-1 ERROR 2022/08/05 13:22:32 Page.URL is deprecated and will be removed in Hugo 0.93.0. Use .Permalink or .RelPermalink. If what you want is the front matter URL value, use .Params.url WARN 2022/08/05 13:22:32 The \u0026#34;tweet\u0026#34; shortcode will soon require two named parameters: user and id. See \u0026#34;/home/johtani/blog_generator/content/post/2020/2020-12-04-build_corne_choc.md:46:1\u0026#34; ... ERROR 2022/08/05 13:22:33 Failed to get JSON resource \u0026#34;https://publish.twitter.com/oembed?dnt=fa... If you feel that this should not be logged as an ERROR, you can ignore it by adding this to your site config: ignoreErrors = [\u0026#34;error-remote-getjson\u0026#34;] ERROR 2022/08/05 18:44:11 Page.UniqueID is deprecated and will be removed in Hugo 0.93.0. Use .File.UniqueID ERROR 2022/08/05 18:44:11 Page.Dir is deprecated and will be removed in Hugo 0.93.0. Use .File.Dir Page.URLなどがdeprecatedに 最初と最後2行のERRORがこちらになります。 どうやら、Pageオブジェクトの変数に変更があったようです(まだdeprecatedであり、存在はしていそう?)。 レイアウト(テンプレート)ファイルで「Previous Post」や「Next Post」といったリンクを作ったり、 Algoliaに登録するためのJSONファイルを生成するところでURL文字列を取得するために参照していました。\nログ出力でどのように変更すればよいのか?という記載があるので便利ですね。 ただ、どのファイルにこの記述があるのかはログに出てなかったので少しだけ苦労しました。\n実際には「UniqueID」という文字列でディレクトリ内を検索してあたりを付けた感じです。 利用させていただいているテーマ(Clean White)がすでにアップデートに対応されていたのでそちらが参考になりました。\nいくつか、テーマをもとに修正したテンプレートがlayoutsディレクトリにあったので、それらを修正した形です(参考のリンクはテーマのファイルになります)。\n.URLを.Permalinkに変更(参考:single.html) .UniqueIDを.File.UniqueIDに変更(参考:list.algolia.json) tweetのshortcodeの引数が増えた これまでは以下のようにIDだけで良かったのですが、userとidという2つの引数が必須になるという変更が入ったようです。\n変更前:\n{{ \u0026lt;tweet 1449214872143609860\u0026gt; }} 変更後:\n{{ \u0026lt;tweet user=\u0026#34;johtani\u0026#34; id=\u0026#34;1449214872143609860\u0026#34;\u0026gt; }} WARNにはファイル名、行番号が出力されていたので、1つずつ修正していきました。 結構な量があったので、地味に大変でした、 公開しているブログを見ながら、該当するツイートを見つけてはuserを指定していく部分が特に。 自分のツイート以外もブログに貼っていたので画一的には対処できなくて。。。\nなにかプログラムで機械的に対応ができたかもなぁ。\n鍵付きツイートによるエラー tweetのshortcode対応を行なった後でもビルドがエラーになっており、次のようなエラーが消えないままでした(エラーの一部は省略しています)。 (幸いにも)1つのツイートだけ、ブログ記事を書いた後で鍵付きになってしまった方のツイートがあったようで、ツイート用のJSONが取得できなくてエラーになっていました。\nERROR 2022/08/05 13:22:33 Failed to get JSON resource \u0026#34;https://publish.twitter.com/oembed?dnt=fa... If you feel that this should not be logged as an ERROR, you can ignore it by adding this to your site config: ignoreErrors = [\u0026#34;error-remote-getjson\u0026#34;] こちらもログに対処方法が出ています。 config.tomlにignoreErrors = [\u0026quot;error-remote-getjson\u0026quot;]を追加すれば、エラーが出力されなくなりビルドも成功するようになります。 ただ、tweet以外でもエラーが出る可能性がありそうで、その場合に、ブログに書いたつもりが一部が出力されないまま公開されそうな気がします。 なので、今回はconfig.tomlに該当の設定を追加するのではなく、ブログ記事から該当のツイートを消す対応をしました。 幸いにも、ツイートを消してもブログ記事自体には影響がありませんでした。\n.hugo_build.lockファイルが生成される これは、エラーではないのですがgit addしようとした際に、ファイルが増えていたのでどういったファイルなのかを調べました。 0.89.0から追加されたロックファイルのようです(参考:0.89.0のリリースノート)。 こちらは特に保管する必要もなさそうなので.gitignoreに追加して対処しました。\nまとめ ということで、気軽にUbuntuをアップグレードしないほうがいいですね。。。 期せずしてHugoのアップグレードができたのは良かったかもなw\n参考 【WSL2】Ubuntu 20.04.4 LTS を 22.04 LTS へアップグレードした ","date":1659689954,"dir":"post/2022/","id":"167a7c9d579ce6f2cebf64a6f6329ecb","lang":"ja","lastmod":1659689954,"permalink":"https://blog.johtani.info/blog/2022/08/05/upgrade-hugo-accidentally/","publishdate":"2022-08-05T17:59:14+09:00","summary":"Hugoを0.84から0.92にアップデートをする際に、これまでのブログ記事やレイアウトファイルを修正したので個人的にメモを残しておきます。","tags":["hugo"],"title":"Hugoをアップデートした"},{"contents":"今回はQuerqyのElasticsearchのプラグインがどんなつくりになっているか?をちょっとだけ調べてみました。 SolrでもElasticsearchでも使えるという形なので、どんなつくりになっているのかな?と思ったのが発端です。\nGitHubのリポジトリ GitHubにリポジトリが公開されています。 2つのリポジトリに分かれています。\nEs向けのプラグイン コアのライブラリ どちらもJavaのライブラリで、ビルドシステムとしてはMavenを利用しています。 コアのライブラリのリポジトリにはさらに、以下の2つが存在しています。\nlucene向けライブラリ(Solr向けのモジュールもこちらに含まれる) コアライブラリ pom.xmlを読んだところ、次のような依存関係になっています(それ以外にも使ってるライブラリはあるけど)。\nEsプラグイン -\u0026gt; Lucene向けライブラリ -\u0026gt; コアライブラリ Esプラグイン Es向けのエンドポイントの実装、Esのクエリの組み立てを行なっています。 Rewriterの実装については、Lucene向けライブラリ、コアライブラリを利用する形になります。\nquerqy用のQueryBuilderを実装しており、EsがクエリをパースするタイミングでRewriterなどを呼び出してクエリの書き換えを行う仕組みです。 なお、Es向けのクエリの組み立てと書きましたが、ほとんどLuceneのクエリの組み立てになっています(そりゃそうだ)。 実際にquerqyのクエリ組み立て処理を行っているのは、Lucene向けライブラリのQueryParsingControllerになります。 いくつかのRewriterは、生のEsクエリをルールなどとして登録することができるようになっています。 これらのクエリのパースをEs側にやらせる処理の部分もこちらで定義されている感じです。\nそのほかに、ドキュメントには記載がないエンドポイントが2つ用意されていました。 インデックスに登録してあるRewriterの設定を各ノードでキャッシュする仕組みがあって、そのキャッシュの操作(クリア、リロード)用みたいです。 これらは、Rewriterの追加、削除のアクションの内部で呼び出されているので、ユーザー側で呼び出す必要はなさそうです。\nLucene向けライブラリ Luceneに関連する処理がまとめられています。 Es内部ではLuceneを使って検索処理が行なわれるため、Luceneのクエリを組み立てる必要があります。 querqyとしてLuceneのクエリを組み立てるときに必要なクラスがこのライブラリに含まれています。\nまた、Word Break Rewriterの実装はコアライブラリではなくこちらのライブラリに実装されています。 これは、Luceneのタームディクショナリを活用したRewriterになっているため、Lucene必須となっているからのようです。 (まだちゃんと実装を見ていないので、どんな活用の仕方をしているのかまではわかっていませんが。。。)\nコアライブラリ Rewriterの設定のパース処理、クエリのリライト処理の実装がまとめられています。 querqyのクエリが、Rewriterの処理に基づいて、querqyとして定義されたクエリのモデルに一旦変換される作りになっています。 Lucene向けライブラリやEs向けプラグインはこの内部のクエリモデルになったものをもとに、Lucene向けのクエリに書き換えていくというながれになっています。\nまとめ ざっくりですが、どんな構成なのかを見てみました。 Esのプラグインとなっているのですが、プラグインではなく、外部に出すことってできるのかな?と思いつつ、なんとなくソースを読んでみました。 パターンとしては、Lucene向けのクエリからEs向けのクエリを組み立てるとかの無駄な努力が必要になる気もするけど。。。 Luceneを使っていない検索エンジンに対しては、コアライブラリをもとに、それぞれの検索エンジンむけのクエリを組み立てる仕組みを作る形になると思います。 その際、Rewriterの設定を保持する仕組み、querqyが置き換えたクエリのマッピングができるか?といった点を考える必要がありそうです。 デバッグとかするときに、EsのクエリDSLのJSONとして見れるといいなぁと思ってたけど、そんなことできるかなぁ?\n","date":1658300650,"dir":"post/2022/","id":"3384ea6bb47d70f8ca94b4510813f36a","lang":"ja","lastmod":1658300650,"permalink":"https://blog.johtani.info/blog/2022/07/20/querqy-architecture/","publishdate":"2022-07-20T16:04:10+09:00","summary":"今回はQuerqyのElasticsearchのプラグインがどんなつくりになっているか?をちょっとだけ調べてみました。 SolrでもElast","tags":["elasticsearch"],"title":"Querqyの調査(その2:アーキテクチャ)"},{"contents":"Querqyというクエリのリライト用のプラグインがあるのでどんなものかを調べてみました。とりあえずは概要をドキュメントから追いかけてみた感じです。対応しているのはSolrとElasticsearch(以降、Es)になります。手元にはEsの環境があるのでそちらで試してみました。\nなにもの? EsやSolrのプラグインで、ルールやパラメータを利用して、クエリの書き換えをEsやSolr側で行えるプラグインです。 なお、本記事ではEsのプラグインを説明します。 今回はドキュメントを読みながらメモを取った感じなので、詳細については公式ドキュメントを見ていただくのが良いかと。 手元では動作させてみましたが、今回の記事ではざっとメモを取っただけになります。\nインストール Esのpluginコマンドでインストール可能ですが、Mavenにアップロードされているバージョンは限定的なので、必要に応じて自分でビルドする必要があります。 対応しているかは、公式ドキュメントのInstallationのプルダウンが参考になります。\nどうやって使うの? Query DSLにquerqyというクエリが追加されるので、あとはドキュメントをもとにクエリを組み立てるクエリを書いていきます。 すると、プラグインが指定されたルールに従い、EsのQueryに書き換え、実際の検索が実行して結果が返ってきます。 普通にmatchなどの既存のQueryと同レベルのものになるので、既存のEsのクエリと組み合わせた使い方もできるようです。\nサンプルとして紹介されている短めのクエリ(このクエリではルールによるクエリの書き換えはない)。\nGET ecommerce/_search { \u0026#34;query\u0026#34;: { \u0026#34;querqy\u0026#34;: { \u0026#34;matching_query\u0026#34;: { \u0026#34;query\u0026#34;: \u0026#34;notebook\u0026#34; }, \u0026#34;query_fields\u0026#34;: [ \u0026#34;title^3.0\u0026#34;, \u0026#34;brand^2.1\u0026#34;, \u0026#34;short_description\u0026#34;] } } } また、書き換え(Rewriter)の設定をElasticsearchに対して保存できるエンドポイント_querqy/rewriterが用意されています。\nSynonymの書き換えを行なうサンプル(後述するCommon Rules Rewriterの設定)。\nPUT /_querqy/rewriter/common_rules { \u0026#34;class\u0026#34;: \u0026#34;querqy.elasticsearch.rewriter.SimpleCommonRulesRewriterFactory\u0026#34;, \u0026#34;config\u0026#34;: { \u0026#34;rules\u0026#34; : \u0026#34;notebook =\u0026gt;\\nSYNONYM: laptop\u0026#34; } } どんな書き換えができるの? 用意されているRewriterは2022年7月時点では次のようなものになります(がんばれば、Javaで実装すれば自作もできそう)。\nCommon Rules Rewriter Replace Rewriter Number Unit Rewriter Word Break Rewriter また、複数のRewriterをチェインして使うこともできる。記述した順番で適用されます。 それぞれのRewriterについて簡単にメモを。\nCommon Rules Rewriter シノニム、結果のブースト、フィルター、結果に対して追加情報を付与したりできます。\nrulesにルールを記載していきます。 以下のようなフォーマットになっています。 クエリが入力に合致したら、ルールが適用される形です。プロパティは後述しますが、ルールの適用する順序などをハンドリングするために使用します。\n入力 =\u0026gt; ルール ルール @プロパティ @プロパティ 入力部分に関する書式 ルールの左辺に該当する部分で、クエリに入力された文字列がマッチするかどうかで、右辺のルールを適用するかがきまります。\n入力の一致の条件は次のような感じです。 完全一致、前方一致、後方一致の使い分けが可能。ダブルクォート\u0026quot;で制御 デフォルトでは、大文字小文字の区別なし(後述するオプションで変更可能) 単語の末尾にワイルドカード*で1文字以上にマッチ。入力の最後にだけ利用可能 書き換えの命令(ルール) 右辺に利用できる命令で、次のようなものがあります。\nSYNONYM 同義語展開するための命令です。Synonym Token Filterとの違いは、複数のルールを同時に適用できます。 フィールドに依存しない設定なのでメンテナンスが楽になるとのこと。 ただし、双方向の設定はないため、例えば\u0026quot;personal computer\u0026quot;と\u0026quot;pc\u0026quot;の場合、2つの設定を個別に定義する必要があります。 また、ステミングなどには未対応なので、\u0026ldquo;personal computers\u0026quot;も対応する場合はこれも追加する必要があります。 類義語ごとに重みを変えることが可能になっています。同列ではなく、同義語のスコアを下げるなどで、リコールを増加させつつ、入力語のスコアを上位にすると行ったことが可能です。\nUP/DOWN 入力文字列がマッチした場合に、追加のクエリを正か負のブーストをしつつ追加できます。 例えば、「iphone」と検索された場合に、「apple」もクエリとして追加しつつスコアをブーストし、「case」のクエリをスコアを下げるように追加できます。 これにより、アクセサリーではなく本体が検索結果の上位に出てくるような仕組みを提供できます。\nFILTER UP/DOWNではクエリとして追加されていたが、こちらはフィルターとして追加されます(=スコアで調整ではなく、結果から除外される)。\nDELETE クエリからキーワードを削除できます。 単語自体をそのまま削除することも、入力された単語に合わせて他の単語を削除することもできます。\nDECORATE 2022年7月時点でEsでは利用不可で、Solrのみで利用可能です(なので読み飛ばしました)。\nプロパティ 各ルールの設定にタグをつけられるような機能です。 このプロパティを利用して、ルールのソートやフィルタリングなどが可能になります。 複数のルールにクエリがマッチした場合に、優先度が最高のものだけを適用したり、プロパティに特定の値を持っているものだけを採用したりできます。 なお、プロパティは命令のあとに記述する必要があります(パーサーの関係かな?)。\nReplace Rewriter クエリタームの置き換え用のRewriterです。クエリの正規化処理として、他のRewriterの前処理に利用したりできます。 サンプルではタイポの修正などに利用したり、不要な語の除去などがあげてありました。\nWord Break Rewriter クエリトークンを分解・結合します。 たとえばドイツ語は、複合語と呼ばれる個別の意味の単語を結合した1つの単語を持っているため、個別の意味に分解して検索すると便利なことがあります。 そういった単語を辞書を基にして分割できるようにする機能です。 辞書とは実際のインデックスのタームディクショナリのことと思われます(要調査。どのインデックスのフィールドを指し示すのかなど、設定とドキュメントではよくわからない)。 なお、利用可能な形態素解析を基にした実装はドイツ語のみとなっており、また、分解の時には形態素解析を考慮しますが結合時には考慮しません。\nNumber-Unit Rewriter クエリの数値と単位を判別し、対象となるフィールドにマッチさせます。範囲での一致や完全一致やブーストが可能です。 単位をもとにして、特定のフィールドに対する数値のクエリに書き換えることができます。\nShingle Rewriter Solrのみで利用可能なので読み飛ばしました。\nルールはどこに保存されるの? .querqyというインデックスが内部で作成され、そこに保存されます(公式ドキュメントより)。 (ちなみに、Mappingはこんな感じみたいです)。 現状、プラグインでは設定したRewriterの取得ができないようなので、自分で登録した設定がどんなものかは、このインデックスを検索する必要がありそうです。\n気になった点・改善点? 気になった点があったので。\nRewriterのエンドポイントは、登録・更新・削除のみ対応しており、登録したものの確認は直接インデックスを見に行くしかなさそうです(Issueは作られてた)。 [要検証]書き換えられたクエリがどんなものか?は残念ながら確認できなそうで、_validate/queryで最終的なLuceneレベルのクエリで確認するしかなさそう? スキーマ側で定義したものと、Querqyで定義したものの兼ね合いがどういう形になるのか?などを気にする必要があるのが注意点かも。組み合わせたときの副作用などがどんなことになりそうか?が予測がつきにくそう。 Rewriterの定義自体のテストはどうしたものか? まとめ とりあえず、ざっとドキュメントを見ながらメモを取った感じです。 設定などの記述が独自のものなので、そこに慣れていく必要がありそうです(特にルールの改行の部分とか)。 次は実際にどんな感じで使えそうか、既存の仕組みとの違いは?みたいなところをもう少し見ていきたいとおもいます。\n参考文献 querqy/querqy: Query preprocessor for Java-based search engines (Querqy Core and Solr implementation) Getting started with Querqy — querqy.org documentation ","date":1658285563,"dir":"post/2022/","id":"779e444b4bc720a9eed97f19c41e8773","lang":"ja","lastmod":1658285563,"permalink":"https://blog.johtani.info/blog/2022/07/20/intro-querqy/","publishdate":"2022-07-20T11:52:43+09:00","summary":"Querqyというクエリのリライト用のプラグインがあるのでどんなものかを調べてみました。とりあえずは概要をドキュメントから追いかけてみた感じ","tags":["elasticsearch"],"title":"Querqyの調査(その1)"},{"contents":"今年もBerlin Buzzwordsにオンライン出張してました。 今年はハイブリッドな開催だったようで、現地で再開している人もいるようでした。 ブースもあったみたいです。ちなみに、現地で参加する人はマスク必須のようでした(Health \u0026amp; Safetyというページが用意されていました)。 昨年オンラインだったMICESは現地のみでの開催みたいで見ることはできなかったです(録画公開されないかなぁ)。\nさて、いくつか見たセッションで面白かったものがあったので簡単にメモを。 すでにセッションのビデオがYouTubeで公開されているので、興味のある方は見てみてください。\n面白かったセッション The future of Lucene\u0026rsquo;s MMapDirectory: Why use it and what\u0026rsquo;s coming with Java 19 and later? セッションページ: The future of Lucene\u0026rsquo;s MMapDirectory: Why use it and what\u0026rsquo;s coming with Java 19 and later? :: Berlin Buzzwords 2022 動画:Uwe Schindler – The future of Lucene\u0026rsquo;s MMapDirectory: Why use it \u0026amp; what\u0026rsquo;s coming with Java19 \u0026amp; later - YouTube 毎年恒例になってる気も? 前半は昨年も話をした内容で、後半はJava 19がリリースされたら、Previewという形でフラグを立てて使えるようになるようです。 使えるようにするから、テストしてみて!という感じで終わっていますw\nScaling an online search engine to thousands of physical stores セッションページ:Scaling an online search engine to thousands of physical stores :: Berlin Buzzwords 2022 :: pretalx 動画:Aline Paponaud – Scaling an online search engine to thousands of physical stores - YouTube 数千の実店舗の商品をオンラインで検索できるようにしつつ、オンラインのマーケットプレイスのような検索も一緒にできるようにしたというお話でした。 インデックスの構成をどう工夫したのか?とかどういうクラスター構成にして、どんなことをモニタリングしてるよ?というお話です。 実際の店舗がどんなものかなどは出てこなかったので、少しイメージは沸きにくかったのですが、どんなことを考えながらインデックスの構成とか考慮したよという話はおもしろかったです。 実際に検索したときに、実店舗のデータがどんな感じで結果として表示されたりするのか?といった点はわからなかったので、そのあたりの話をもうちょっと聞いてみたかったなぁ。\nOffline Ranking Validation - Predicting A/B Test Results セッションページ:Offline Ranking Validation - Predicting A/B Test Results :: Berlin Buzzwords 2022 :: pretalx 動画:Andrea Schütt \u0026amp; Yunus Lutz – Offline Ranking Validation - Predicting A/B Test Results - YouTube otto.deというECサイトでのランキングをどうやって改善していくか?という話。 現在はマニュアルなチューニングをコンテキストごとにやっているけど、リクエスト量とかデータとかが増えてきてて、このままマニュアルで改善していくのも大変なので、 モデルベースのランキングを開発できないか?というのをはじめていますよと。 そのために、これまでのデータから、A/Bテストの結果を予測できるモデルが作れないか?というのをやっていますという話。 いくつかわからない単語も出てきたので、誰か詳しい人教えて!\nAI-powered Semantic Search; A story of broken promises? セッションページ:AI-powered Semantic Search; A story of broken promises? :: Berlin Buzzwords 2022 :: pretalx 動画:Jo Kristian Bergum – AI-powered Semantic Search; A story of broken promises? - YouTube Vespaの開発にかかわってる方の、Semantic Searchに関する話。 Semantic Searchが流行り始めていて、どうやればできるのか?という話が出てきています。 けど、どういうものでどういう点に気を付けたほうがいい?という話でした。 LtRってこんなもの、そのあとに出てきたLLM(Large Language Model)でどうやって検索の改善に使えるの?というのが分かりやすく説明されていました。 それらの説明の後、BEIRという論文を紹介しつつ、LLMを使うときの注意点の話がありました。\nBERTとかをちょっと勉強してたのもあり、なんとなくそうだよなぁと思っていた結論と同じ結論が出てきたので面白いと感じました。 BEIRの論文は時間を見つけて読んでみないとな。\nHybrid search \u0026gt; sum of its parts? セッションページ: Hybrid search \u0026gt; sum of its parts? :: Berlin Buzzwords 2022 :: pretalx 動画:Lester Solbakken – Hybrid search: Greater than the sum of its parts? - YouTube こちらもVespaの人の話。 先ほどのSemantic Searchの話では、Semantic Searchがどんなものか?という話でした。 が、それだけで検索ができるわけでもないので、キーワードサーチとSemantic Searchの両方をうまく活用するには?というのがこのセッションでした。 最終的にはVespaを使うとうまくハイブリッドできるよという話ですが、考え方は参考になるかなと。 Vespaも触ってみたいなぁ。\nThe life of a search engine administrator セッションページ:The life of a search engine administrator :: Berlin Buzzwords 2022 :: pretalx 動画:Lucian Precup \u0026amp; Vincent Bréhin – The life of a search engine administrator - YouTube 検索システムの管理者ってどんなことやるの?それにはどんなことができるツールがあるといいの?という話です。 まぁ、ツールについてはこの会社の人たちのツールの宣伝なのですが、検索システムを作って育てていくのにどんなことを考えたりするのか?という参考になるかなぁと。\nShould we stop using distance in our location-based data recommendation models? セッションページ:Should we stop using distance in our location-based data recommendation models? :: Berlin Buzzwords 2022 :: pretalx 動画:Charlie Davies – Should we stop using distance in our location-based data recommendation models? - YouTube TravelTimeという会社を立ち上げた人の話。 位置に関する情報って重要だし、検索するときに利用しますよね?例えば、ホテル決めたりとか、仕事探したりするときに。 ということで、位置情報を検索エンジンで利用する方法(Bounding Box、ポリゴン、距離)をまず紹介して、どんなユースケースで使えるかという話があります。 また、それとは別に検索速度(いかに検索を速く返すか)も重要だという話があります(ウォルマートはページロード時間を1秒早くしてコンバージョンが2%あがったとか)。 で、実際に検索結果に距離とかでるけど、実際に知りたいのはどのくらいの時間で行けるのか?という話だったりしませんか?と。 公共交通機関を使ったりする場合に、実際に45分で移動できる距離というのは半径5マイルとかできまるものではないのに、単純に位置情報を利用した距離だけでソートしていいの?という問いかけから、 その辺を考慮した検索ができるAPIを開発しているよ、検索速度もはやいよというお話でした。 残念ながら具体的にどうやって作っているのか?というのはなかったですが、観点がおもしろかったです。\nWord2Vec model to generate synonyms on the fly in Apache Lucene セッションページ:Word2Vec model to generate synonyms on the fly in Apache Lucene :: Berlin Buzzwords 2022 :: pretalx 動画:Daniele Antuzi \u0026amp; Ilaria Petreti – Word2Vec model to generate synonyms on the fly in Apache Lucene - YouTube Word2Vecのモデルを使った、Apache LuceneのSynonym Filterを開発中だよという話 DeepLearning4Jを使ってみたが、遅くて使えなかったんだけど、最近Luceneに入ったkNNを使うことでそれなりの速度で使えそうなものができるかもよ?って感じでした。 モデル学習用のツールも作ってて、イタリア語のWikipediaで学習したものでちょっと動かしたらそれっぽい感じになってるという話でした。 まだ途中でいくつかやりたいことがあるという話で、実用はまだ先のようでした。例えば、1単語のSynonymにしか対応してないとか、モデルをインメモリでしか動かせないとか。\nQAでも出たのですが、Word2Vecだと対義語も類似していると判定されてしまうと思うので、その辺がどうなっているのかなぁ?という疑問があります。 ルールベースの類義語ではないので、調整するのはどうやるのかなぁ、学習用のコーパスをいい感じにするとかなのかな?とか、気になるところです。\nNrtSearch: Yelp’s fast, scalable, and cost-effective open source search engine セッションページ:NrtSearch: Yelp’s fast, scalable, and cost-effective open source search engine :: Berlin Buzzwords 2022 :: pretalx 動画:Umesh Dangat – NrtSearch: Yelp’s fast, scalable, and cost-effective open source search engine - YouTube YelpがLuceneベースで開発をしているNrtSearchというOSSの話です。 Elasticsearchを使っていたんだけど、どういった点が問題点になってどういうモチベーションでNrtSearchを開発したのか?を説明しています。 アーキテクチャがどんなもので、実際に動かしてみてどんな利点があって、どんな点が問題として出てきているか、将来どんなことをやろうとしているかがわかります。 QAでもいろんな質問が出ていて面白いです。\nまとめ ということで、簡単でしたがセッションの感想でした。 Neural/Semantic Searchというのがセッションのタイトルなどに入っているのが多くなってるなぁという感想です(ちょっとやってみたい気はしてるんだよなぁ)。 すでにYouTubeに動画が公開されているので興味があるセッションを見つけてみてください。 Berlin Buzzwordsの次の日に開催されたMICESも観てみたかったですが、オンラインでも参加できる形式で海外のカンファレンスが開催されるのはとても助かりますね(ヨーロッパだと時差もそれほど大変じゃないし)。 けど、落ち着いたらまたオフラインで参加してみたいなぁ。\n","date":1655283615,"dir":"post/2022/","id":"f56c19442484b3e4f47875b58b3f72b2","lang":"ja","lastmod":1655283615,"permalink":"https://blog.johtani.info/blog/2022/06/15/ttend-berlin-buzzwords-online/","publishdate":"2022-06-15T18:00:15+09:00","summary":"今年もBerlin Buzzwordsにオンライン出張してました。 今年はハイブリッドな開催だったようで、現地で再開している人もいるようでした。","tags":["conference","berlin buzzwords"],"title":"今年もオンラインでBerlin Buzzwordsに参加した"},{"contents":"7.16で正式リリースされましたが、Elasticsearchの新しいJavaのクライアントが出ています。 使ってみたので、ちょっとだけ紹介でもしてみようかな。\nこのクライアントが出るまでは、ElasticsearchのJavaクライアント(REST版)はElasticsearch本体の一部として実装・管理されていました(Elasticsearchのリポジトリにあるclientディレクトリ)。\nHTTP経由でElasticsearchにアクセスするクライアントだったのですが、Elasticsearch本体のリポジトリで管理されていることもあり、Elasticsearch本体で利用されているクラスを使用していました。 このため、クライアントライブラリなのですが、Elasticsearch本体のJarが必要になりサイズが大きくなっていました。 また、JavaのObjectへの詰め替えなどの機能も備えておらず、すこし古臭い感じでもあります。 この辺りを刷新する目的もあり新しいクライアントが公開されたようです。 3月くらいに触った時はまだ、ドキュメントが揃ってなかったのですが利用方法などが増えているので移行も楽になってきているようです。 根本的に作り直されたため、これまでのREST Clientとは使い方が違います。ですので、jarだけの差し替えでこれまで動いていたプログラムを移行ができるわけではないので注意が必要です。\nどの辺が便利? 順次移行が可能 これまでのRESTクライアントとはパッケージ名もjarも別モノになっています。 ですので、少しずつ新しいJava Clientに切り替えていくことが可能になっています。 根本的に使い方が変わっているので、大きなシステムのクライアントを全部切り替えるのは結構大変かと思います。 ですので、Indexをしている部分だけとか、検索部分だけなどといった部分的な置き換えをしつつ新しいクライアントに慣れていくことができます。\nラムダっぽく書ける 検索のクエリのサンプルを見るとわかりますが、こんな感じでクエリが書けます(公式ドキュメントより抜粋)。\nSearchResponse\u0026lt;Product\u0026gt; response = esClient.search(s -\u0026gt; s .index(\u0026#34;products\u0026#34;) .query(q -\u0026gt; q .match(t -\u0026gt; t .field(\u0026#34;name\u0026#34;) .query(searchText) ) ), Product.class ); また、最後で渡しているProduct.classは、検索結果をどのクラスのインスタンスにして返すかの指定です。 Elasticsearchのレスポンス(JSON)から値をコピーして返してくれるようになっています。 ですので、値を入れ替える処理を書く必要がなくなっています。\nJSON文字列をそのまま使える 触り始めてからリリース(7.17.2より後なら使える)された、JSON文字列からリクエストを作る機能もあります。\nこれまでのREST Clientだと、Elasticsearchへのリクエストを必ずJavaのメソッドで構築する必要がありました。 今回のこの機能を利用すると、JSON文字列(やファイル)からリクエストオブジェクトを作るためのメソッド.withJson()が提供されています。 例えば、スキーマや設定変更用のリクエストのJSONなどは、Kibanaやcurlから試験的に投げたリクエスト(JSON)と同じものを使いたいことが多いです。また、ElasticsearchのAPIは数が多く、ドキュメントを見ながら利用方法を調べてJSONでまず試行錯誤することが多いです。 このwithJsonメソッドを利用することで、動作確認などをしたJSONがそのままソースにも利用できるので、リクエスト変更時の確認なども容易になると思います。\n使ってみて困ったのは? 便利な面も多いのですが、使っていて少し困ったこともあったのでそれもメモを残しておきます。\nどんなリクエストを投げているかが不明 先ほども書きましたが、Elasticsearchのリクエストを試行錯誤するときは公式ドキュメントを見ながら、Kibanaなどを利用して試すことが多いです。 ですので、自分がやりたいことのJSONは手元にあることが多いです。 ただ、プログラムでクエリを組み立てる必要も出てきます。この時、実際にRESTリクエストとしてどんなJSONを投げているのかを知りたいことがあります(実際、検索クエリ作っててメソッドの使い方がうまくいかなくて四苦八苦してました)。 4月時点では簡単にリクエストで投げているJSONを文字列としてログに出すメソッドなどは用意されていないようでした。 デバッグ用に次のようなメソッドを書いてみました。 Elasticsearchへ投げるRequestのクラス(例:CreateTemplateRequestとか)を引数に渡すことで、JSON文字列に変換できるようになっています(StringWriterに書き出されてる)。 ここのLoggerはサンプルです。writer.toString()で取り出せる文字列がJSON文字列になっているので、ログに出してみるなり、ファイルに落とすなりしてデバッグのお供にしてください。\nimport java.io.StringWriter; import co.elastic.clients.elasticsearch._types.RequestBase; import co.elastic.clients.json.SimpleJsonpMapper; import jakarta.json.stream.JsonGenerator; ... private void printRequestBodyJsonForDebug(RequestBase request) { //for debug Logger.log(\u0026#34;** Debug print start **\u0026#34;); StringWriter writer = new StringWriter(); SimpleJsonpMapper mapper = new SimpleJsonpMapper(); JsonGenerator generator = mapper.jsonProvider().createGenerator(writer); mapper.serialize(request, generator); generator.close(); Logger.log(writer.toString()); Logger.log(\u0026#34;** Debug print finish **\u0026#34;); } プラグインなどで提供されるクエリが書けない LtRプラグインなどは、Elasticsearchの検索クエリを拡張しています。 残念ながら、現時点(2022/06/13)ではカスタムクエリを新しいJavaクライアントで利用しようとした場合、エラーが発生してしまいます(知らないJSONだと判断されてしまいます)。\nGitHubのIssueとして「[roadmap] Add support for plugin-defined custom components · Issue #252 · elastic/elasticsearch-java」があります。 これに対応されたら、拡張されたクエリも利用できるようになるでしょう。 プラグインなどで拡張されているものを使いたい場合は、残念ながら既存のRESTクライアントを当面は使うことになりそうです。\nまとめ 新しいElasticsearchのJavaクライアントを簡単ですが触ってみて、気になった点を記事にしました。 JavaのObjectに詰め替えてくれる機能など便利になっているので使ってみてください。 ドキュメントもちょっとずつ増えているようで、使い方も分かりやすくなっていました(触った時はレスポンスの扱い方などがJavaDocしか用意されてなかったんです)。 説明が欲しいなぁと思うことがあれば、GitHubにIssueを上げてみるといいかもです。\n参考 公式ドキュメント Java Clientチームの人がカンファレンスで利用したスライド ","date":1655119446,"dir":"post/2022/","id":"5eebdf85fd1726db301194bfeeee4377","lang":"ja","lastmod":1655119446,"permalink":"https://blog.johtani.info/blog/2022/06/13/new-elasticsearch-java-client/","publishdate":"2022-06-13T20:24:06+09:00","summary":"7.16で正式リリースされましたが、Elasticsearchの新しいJavaのクライアントが出ています。 使ってみたので、ちょっとだけ紹介で","tags":["elasticsearch","java"],"title":"Elasticsearchの新しいJavaクライアント"},{"contents":"Azure Cognitive Searchで2月に新しい機能が公開されました。 「Index Alias」(インデックスの別名)です。まだ、パブリックプレビューの段階ですが、ドキュメントなどが公開されていたのでどんな機能かを調べてみました。なお、本ブログの内容は2022/05/18時点での内容となります、ご注意ください。\n公式ドキュメント まずは公式ドキュメントです。1つ目の「インデックスの別名を作成する」の冒頭で別名(エイリアス)がどんなものかを説明しています。\nインデックスの別名を作成する - Azure Cognitive Search | Microsoft Docs エイリアスの作成または更新 (2021-04-30-Preview) - Azure Cognitive Search | Microsoft Docs Alias Operations (2021-04-30-Preview) - Azure Cognitive Search | Microsoft Docs REST APIのドキュメント(2022/05/18現在、日本語のページだと左のメニューが壊れているため、どんなAPIがあるかがわかりにくいため、Alias Operationsのページは英語のリンクになっています)\nインデックスエイリアスってどんなもの? 文字通り、インデックスにエイリアス(別名)をつけることができるようになります。 Azure Cognitive Searchでは残念ながらインデックスを作成するタイミング以外ではインデックスの名前を変更できません。 このため、インデックスのスキーマ(Analyzerの設定変更など)を変更したい場合、新しいインデックスを作成します。 新しいインデックスの名前はこれまでのものとは別の名前になってしまうため、アプリケーションで指定しているインデックス名も書き換える必要が出てきます。 利用しているアプリが複数ある場合は、すべて変更が必要です。\n今回出てきたエイリアスを利用することで、アプリケーションではエイリアスを指定することで、アプリケーション側の変更なくインデックスを入れ替えることができるようになります。\nエイリアスの操作方法 公式ドキュメントにAPIの一覧や利用方法の記載があるので詳細はそちらをご覧ください。 本ブログでは、いくつか利用するときに気になった点を書き残しておきます。\n作成 aliasesというエンドポイントにエイリアスの名前とインデックス名をPOSTすることで作成できます。 以下のサンプルは公式ドキュメントの例です。\nPOST /aliases?api-version=2021-04-30-preview { \u0026#34;name\u0026#34;: \u0026#34;my-alias\u0026#34;, \u0026#34;indexes\u0026#34;: [\u0026#34;hotel-samples-index\u0026#34;] } ちなみに、インデックスの指定がindexesで配列になっていますが、公式ドキュメントに以下の記述があり、複数の指定はできないです(エラーが返ってきます)。\nindexes 配列に指定できるインデックスの名前は 1 つだけです。\nまた、1つのインデックスに対して複数のエイリアスをつけることは問題ありません。\n確認 エイリアスのリストも取得できます。\nGET /aliases?api-version=2021-04-30-preview 現在どんなエイリアスが、どのインデックスに対して付与されているかがリストで取得できます。 きちんと作成されたかどうかなどの確認にも使えるかと思います(もちろんエイリアス名を指定したGETも可能です)\n検索での利用 検索のREST APIでインデックス名を指定していた部分をエイリアス名に置き換えるだけです。\nPOST /indexes/my-alias/docs/search?api-version=2021-04-30-preview { \u0026#34;search\u0026#34;: \u0026#34;pool spa +airport\u0026#34;, \u0026#34;searchMode\u0026#34;: any, \u0026#34;queryType\u0026#34;: \u0026#34;simple\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;HotelId, HotelName, Category, Description\u0026#34;, \u0026#34;count\u0026#34;: true } 更新 エイリアスの更新(インデックスの入れ替え)は作成と同じリクエストです。 更新が成功すれば204のステータスコードが返ってきます(エイリアス初回作成時は201) なお、ドキュメントには以下のような記述があります。入れ替え時の注意点になるかと(入れ替えのタイミングをきちんと制御したい場合は、少しだけアプリケーションを停止するなどが必要かと思います)。\n別名に対する更新がシステムに反映されるまでに最大 10 秒かかります。以前その別名が対応付けられていたインデックスを削除するのは、10 秒以上待ってからにしてください。\n削除 もちろん削除もできます。\nDELETE /aliases/my-alias エイリアスを利用する場合の注意点 便利なエイリアスですが、エイリアスが使用できない場合もあるので注意が必要です。\nデータ登録のAPIと検索のAPIでのみエイリアス名を利用可能 インデックスの設定変更やAnalyze Text APIではこれまで通りインデックス名を指定します。 また、エイリアス名はインデクサー機能でtargetIndexNameにも指定できません。 エイリアス名がついているインデックスは削除不可 エイリアスがついているインデックスを削除しようとした場合はエラーが出るようになっています。 まずはエイリアスを削除してからインデックスを削除するという手順になります。 まとめ 簡単ですが、インデックスのエイリアスに関しての紹介でした。まだパブリックプレビューなので正式リリース時点では利用方法が変わっている可能性もあります。こちらは注意してください。\n正式公開されればですが、今後Azure Cognitive Searchを使ったアプリを開発する場合はインデックスエイリアスを利用することを基本にするのがいいかもなと思います (ちなみに、Elasticsearchにもインデックスエイリアスの機能がありますが、異なる点が多いので同じものとは思わないほうがよさそうです)。\n","date":1652856857,"dir":"post/2022/","id":"7cc21814165879f72529e91682ece5c6","lang":"ja","lastmod":1652856857,"permalink":"https://blog.johtani.info/blog/2022/05/18/index-alias-in-azure-cognitive-search/","publishdate":"2022-05-18T15:54:17+09:00","summary":"Azure Cognitive Searchで2月に新しい機能が公開されました。 「Index Alias」(インデックスの別名)です。まだ、パブリックプレビューの段階です","tags":["azure search"],"title":"インデックスエイリアス - Azure Cognitive Searchの新機能"},{"contents":"年末までに知り合いと次の論文を読んだので軽くまとめておきます。\nExtreme Multi-label Learning for Semantic Matching in Product Search なんで読んだの? 前回読んだ理由と一緒ですが、Semantic Searchに絡んだ検索の論文であり、Amazonの製品検索での話も関係していたので読みました。\nどんな論文? Amazonの製品検索でセマンティックマッチングを利用する方法、レイテンシを低くしつつ再現率を改善できるような仕組みを検討して評価した論文です。 実際には商品検索のマッチングを大規模なマルチラベル問題(Extreme Multi-label Classification:以下ではXMC問題とする)として定義して、その問題を効率よく解く方法について検討評価しています。\n検索には大きく2つのフェーズがあります。マッチング(クエリにヒットした文書の集合を求める)とランキング(マッチングのデータを関連性の高い順序で並べる)です。 前回のMSの論文では、マッチング後のランキングのフェーズで言語モデルを利用した並び替えを行う話でした。 今回の論文ではマッチングに関してセマンティックサーチを有効活用できないか?という論文になります。 転置インデックスベースの(語彙による)検索では、スペルミスや類義語などを検索することが難しいです。 語彙以外のデータ(クリックや購入といったユーザーの行動や製品の意味的表現など)を学習できる埋め込みベースのニューラルモデルを活用して、マッチングを補完する方法を検討しています。 下図のようにあくまで転置インデックスベースの検索の補完として利用するみたいです(論文に掲載されていたアーキテクチャ)。\nXMC問題とは? セマンティックサーチを行なう場合、埋め込みベースのニューラルモデル(例えばBERTとか)を利用することが多いですが、 クエリトークンを埋め込み空間にベクトル化する部分が推論のボトルネック(レイテンシが高くなる)になることが多いです。 これは、ニューラルネットワークの複雑さに依存します。 低レイテンシになるように、複雑ではないエンコーダーを用いることもありますが今度は性能(精度)が良くなくなります。\nそこで、この論文ではセマンティックマッチングをXMC問題として定義し、これを効率よく解くための手法を提案しています。 ここで、XMCの問題とは、入力(今回はクエリ)に対して、最も関連性の高い複数のラベル(今回は製品)を出力することとなります。 Amazonでの製品なのでほんとに大規模(ラベル=製品=1億件)です。\n従来のXMC問題を解くための手法として、疎な線形モデルの手法、パーティションベースの手法、グラフベースの手法などが列挙されています。 疎な線形モデルの手法では、ナイーブなOVR(one-versus-rest)だと出力となるラベルの数に対して線形に推論時間も大きくなるため、今回の用途には適しません。 この論文ではパーティションベースの手法として、推論時間を短くできるツリーベースで疎な線形モデルの手法を評価しています。\nどういう仕組み? ツリーベースのモデルは次のような感じです。 PECOSのXR-Linearモデルを利用しています。 モデルに関する詳細についてはこちらの論文に詳しく載っているようです(まだ読んでいないです、、、)。\n一番上に入力として与えられるxがクエリ(ベクトル)で一番下の四角が製品にあたるラベル(Y={1,...,l,...L})です。 これらが与えられたときに最も関連性の高い上位k件のラベル(製品)を出力するモデルを生成します。 モデルのパラメータは、学習データとして(x, y)(ここで、y∈{0, 1}^𝐿、すなわちクエリに製品がマッチするかしないかの二値)を使って調整します。\nこれは、ツリーのそれぞれの階層のノードで、その下の層に関連するデータがあるかどうか?という分類を学習すればよいことになります。 学習データとしては、入力と最下層のラベルにマッチするかどうかというデータです。 これをもとに、ツリーの最下層のデータをもとにひとつ上の層の分類器の学習をすればよいことになります。\n推論は出来上がったツリーベースのモデルに対して、ビームサーチで行ないます。 この時、それぞれの層のノードの分類器では推論の効率化のために枝刈りの閾値を設定しています。 本論文で閾値の違いによる精度とレイテンシの比較も行われています。 また、ビームサーチのビームサイズを変化させた場合の性能についても実験しています。\nどうやって検証した? 次のようなデータを用いてAWS上にモデル構築、推論のシステムを用意し実験しています。\n10億件以上のポジティブなクエリ-商品ペアのデータセット クエリ:2億4千万、商品:1億 ポジティブなペアとは、クリック数や購入数の集計値が閾値以上。ただし、データセットとしては集計値は利用していない。 トレーニングセット:12か月分の検索ログ 評価用テストセット:1か月分の検索ログ(12%の製品はトレーニングセットには出てこない) というデーセットをもとに上記のモデルを学習しています。 特徴量はクエリテキストと製品のタイトルをもとにTF-IDFをいくつかのパターンで導出したものが使われています。 詳しくは論文の結果に関する表などを見ていただくとして。。。\n結果として、1億件の商品カタログで60.9%のRecall@100を1.25ミリ秒/リクエストという低レイテンシで達成したとなっています。\n気になる点は? 知り合いと3人で読んでいて次のような気になる点が出てきました。\nツリーの構築をするときに、製品のラベルの並び順(製品のクラスタリング?に他製品が似た場所に来る感じ)が推論の効率の良し悪しに影響するんじゃないの?=Amazonではないところではうまくいかない? PECOSの論文読まないといけない? 製品が増えたときにモデルの組み換えとかどうするの? コールドスタート問題という形で今後の課題として書かれていたので、今後に期待 転置インデックスでのマッチングの補完として利用しているということだったけど、ランキングはどうしてるんだろう? 別のランキング用の指標があるのかな?上位k件とした場合にどうやって、決めているのか? モデル更新のタイミングはどのくらいのスパンなんだろう? まとめ&感想 セマンティック検索の処理を分類問題に置き換えてその手法を用いて行い、実際のシステムに適用できそうな速度と精度を出しているのが面白かったです。 セマンティック検索にもいろんな手法があるのだなと(そして、いろいろ勉強しないといけないんだなと。。。)。\n気になる点にも書きましたが、ツリーの作り方になにかコツがあるのか?他の検索結果と組み合わせるときに、どのような基準で上位を選択しているのか?など疑問点も残っています。 個人的には特にどのように既存のシステムにくっつけていくのかというところが気になっています。 論文の続編でその辺の話が出てくるのかなぁ?\nツリーの作り方に関するPECOSの論文を誰か解説してくれると嬉しいかもなぁと思いつつ、とりあえずブログに書き残してみました。参考になるかなぁ。。。\n参考文献 Extreme Multi-label Learning for Semantic Matching in Product Search - ACM Extreme multi-label learning for semantic matching in product search - Amazon Science PECOS: Prediction for Enormous and Correlated Output Spaces 数えきれないほどの分類を行うExtreme Classification - Technical Hedgehog ","date":1641980462,"dir":"post/2022/","id":"0645bdb1cdf88ec74288d503eb71839c","lang":"ja","lastmod":1641980462,"permalink":"https://blog.johtani.info/blog/2022/01/12/reading-xmc-for-semantic-search-in-prod/","publishdate":"2022-01-12T18:41:02+09:00","summary":"年末までに知り合いと次の論文を読んだので軽くまとめておきます。 Extreme Multi-label Learning for Semantic Matching in Product Search なんで読んだの? 前回読んだ理由と一緒ですが、Semantic","tags":["search","paper"],"title":"Extreme Multi-label Learning for Semantic Matching in Product Searchという論文を読んだ"},{"contents":"今年も振り返りブログです。録画した紅白をオッかけ再生して気になるアーティストだけ見ながら書ています。\n振り返り(2020年に書いた抱負から) まずは去年の抱負を元に書きます。今年もコロナウィルスの影響が年末まで続き、ほとんどで書けなかったです。\nフリーランス継続? ありがたいことに個人事業主として無事1年を終えられました。 夏頃は5社ほどお手伝いをさせていただき、年末時点では3社をお手伝いさせていただいています。\n昨年の振り返りで書いた2社はありがたいことに継続していただいています。\n今年も完全リモートで仕事が終わりました。オミクロン株が来ているし、来年春くらいにはミーティングに出かけられるかなぁ。 相変わらず検索のお手伝いをしています。手伝いをしつつ勉強させていただいている感じです。 ありがたし。\nプログラミング ちょっとペースダウンしています。。。\nextract-kana-java 新しく書いたのはこれくらいかな。 SudachiやNeologdのkuromojiでフリガナを出力して違いを見るというコマンドツールです。 ちょっと比較してみたくなったので書いて公開しました。\nあとは、Sudachiをいろいろと触り始めています。 来年はそのへんをもうちょっと何かできるかなぁ。 コーディングしないとよくないなぁと思っているので、強制的になんかやらないとだ。\n検索の勉強 仕事でやってます。ブッチャー本は昨年買って手を付けてませんが。。。 来年は少しずつやる予定です。 あとは、Azure Cognitive SearchのSemantic Searchを触った関係でSemantic Searchに関する論文を探してちょっとずつ読んでいます。 知り合いと読んでいたAmazonの論文をブログにまとめるのは来年早々に。。。\n検索のポッドキャスト? これはできませんでした。重い腰が上がらない。 公開しないまでも雑談したいなぁ。\n振り返り(今年あったできごと) ここからは今年の出来事を。\n自宅環境 キーボード以外もDIY 検索Slack爆誕 車買い替えた WindowsノートPC買った 今年もずっと自宅で仕事でした。 昨年だいぶそろえていたのでそれほど変更はないですが。\n2月バージョン 切り替えてからずっとWindowsです。Macもブラウズ用に使ってはいますが。 ただ、Windowsといっても、プログラムなどに関する環境はほぼWSL2になっています。コマンドプロンプトは触ってないなぁ。 今年最後に更新された自宅環境は椅子になります。 詳しくは昨日のブログをご覧ください。\nキーボードもDIYしましたが、今年はほかにも少しDIYしました。\n今年のDIYキーボードとコントローラーラック このブログにも書きましたが、来年はキーマップやファーム関連を触っていきたいなと。あとロータリーエンコーダー。。。 BLE化は快適で、3台のPCの切り替えがとっても便利です。\ntakuya_aさんの鶴の一声で検索のSlackが爆誕しました。 検索に関連する情報交換ができる場として楽しませてもらってます。 年末には検索100本ノックの話が立ち上がってきています。 来年も面白い話が聞けそうでワクワクしています。\nあとは、車を買い替えました。初のハイブリッドです。 まだまだ慣れないですが、燃費とかがとても楽しみです。\n結局まだ出かけていませんが、出かけられるようにFMV Zeroを購入しました。 このブログもリビングでFMV Zeroで書いています(まだちゃんとセットアップしていないので、実際にはリモートデスクトップでデスクトップにつないでそこのVSCodeで書いちゃってますが。。。)。 ブログ書いたりコード書ける程度の環境は作らないとな。\n来年の抱負 ということで、来年の抱負です。\nフリーランス継続 プログラミング ブッチャー本ちゃんと読む 読んだ本のブログを書く 今年もありがたいことに仕事を継続していただけて、乗り越えられました。 来年も価値を提供できるように頑張っていきます。\nプログラミングは失速気味のでなにかテーマを見つけないとなあ。\nブッチャー本は読み始めます。必ずw\nブログのペースが落ちていたり、本を読むペースが落ちているので、 本を読んで自分のためにもブログを書こうと思います。 書いてないって思ったら叱咤してください。。。\n今年も出かけられませんでしたが、仕事も安定してあり、無事乗り切れました。 人と話をする機会は減っているので雑談したいな、オンラインなどで。 相手をしてやってもいいぞという方はぜひ連絡ください。\nさて、来年(もう年あけちゃったけど)は出かけられるかなぁ。 何はともあれ、今年もよろしくお願いします!\n","date":1640957359,"dir":"post/2021/","id":"104b8ee17a8bf1f7043d236659680493","lang":"ja","lastmod":1640957359,"permalink":"https://blog.johtani.info/blog/2021/12/31/looking-back-2021/","publishdate":"2021-12-31T22:29:19+09:00","summary":"今年も振り返りブログです。録画した紅白をオッかけ再生して気になるアーティストだけ見ながら書ています。 振り返り(2020年に書いた抱負から) ま","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2021)"},{"contents":"2021年もあと少しですが、今年買って良かったものをリストアップしておこうかと思います。 今年買ったといいながら、昨年このネタを書くといいつつ書いてないので、昨年の分も入っているかも? Amazonのアフィリンクを貼っていますが、急いでないものはAliExpressで購入したりもしています。\n象印のポット Amazon | 象印 電気ケトル 1.0L コーヒードリップ用機能付き ホワイト CK-AX10-WA | 象印マホービン(ZOJIRUSHI) いわゆる電気ケトルというやつです。これが来るまでは鍋で湯を沸かしていました。 水を入れてボタンを押し、湯を沸かしている間に他のことができるのはやはり便利です。 また、コーヒーを入れるためのコーヒードリップモードがあるので、ドリップするためにわざわざ湯を他のものに入れたり、 専用のヤカンを使わなくても簡単にドリップができるのがさらに便利で重宝しています。\nウォータードリップコーヒーサーバー Amazon | iwaki(イワキ) コーヒーサーバー SNOWTOP ウォータードリップ ここ数年、冬以外は水出しコーヒーを飲んでいます。 麦茶のポットのような水出しコーヒー用ポットを使っていたのですが、滴下式のほうがえぐみが少ないというのを見かけてウォータードリップのサーバーに変えてみました。 このひとつ前に水のタンクの部分がプラスチックのものを利用していたのですが、ドリップする部分を壊してしまったので、部品を購入することができるこちらに切り替えました。 朝、仕事をする前に豆を挽いて仕込んでおくと、昼にはコーヒーが落ちています。 夏は入れ終わったポットごと冷蔵庫に入れておくと氷を入れなくてもアイスコーヒーが飲めるので気に入っています。\neufyの掃除機 Amazon | Anker Eufy HomeVac H11(ハンディクリーナー) USB充電 仕事に使っている机でプラモデルを作ったり、DIYキーボードの工作をしたりと細かなごみが出る作業を行ないます。 ちょっとごみを吸いたいだけなのに、掃除機を毎回取りに行くのも面倒なので充電式のクリーナーを買ってみました。 仕組みも簡単だし、USBで充電できるのでおすすめです。アタッチメントを利用してキーボードの掃除なんかもしています。\n電動精密ドライバー Amazon | Wowstick 1F\u0026#43; 69in1 電動精密ドライバー ビット56種セット ケース USB充電式 LEDライト付き [並行輸入品] キースイッチを付け替えたり、工作したりでねじの開け閉めを頻繁に行います。 思ったよりも頻度が高くなってきたので、電動の精密ドライバーを試しに使ってみたらすごく楽ができました。 電池の入れ替えなどでもねじの開け閉めは行なうので、すごく役に立っています。 ビットが56種類もついていますが、プラスとマイナス以外はまだ使ってないかも。。。\n磁石のUSBケーブル Amazon | SUNTAIHO マグネット充電ケーブル DIYキーボード、エネループの充電器、上記のドライバーや掃除機など、USBで充電したり、接続するものが結構あります。 毎回ケーブルを差し替えるのも大変なのですが、@ymotongpooに教えてもらった磁石のUSBケーブルがお気に入りです。 先端部分(USB-C、micro)とケーブル部分が別々になっており、また、ケーブルと先端は磁石でくっつく構造なので、充電したい機器に先端部分を刺しておきます。 充電や接続したいときにケーブルを近づけると磁石でくっついてくれるのでケーブルの抜き差しが必要なくなります。 先端部分だけを個別に購入できたので、色々な機器にあらかじめつけてあります。\nMaker hart Just Mixer 5 Amazon | Maker hart Just Mixer 5 ステレオ5入力音声ミキサー/Bluetoothオーディオ入力対応 3台のPC+音楽サーバーとしてラズパイを主に利用しており、通知音などを1つのスピーカーから聞きたいので、ミキサーを導入しました。 5つの入力個別に音量調節できるので打ち合わせの時だけ他の音源を小さくしたりなど重宝しています。 ただ、入力が増えるとノイズが乗っている気もしますが。。。\nリストレスト(アームレスト) Amazon | エレコム リストレスト アームレスト 肘起き 扇形 左右で使える2個セット ブラック MOH-EL01BK 扇形のものを分割キーボードの手間においてリストレストとして使っています。 使用例の写真を見ると肘を置いていますが、手のひらをおくのにちょうどいいです。 これまでいくつかパームレストを試してみましたが、凹凸もなく適度な硬さで気に入っています。\nコンテッサセコンダ Amazon | オカムラ オフィスチェア コンテッサ セコンダ 10月に注文してクリスマスに届きました。部品が不足しているようで年内に届かないかもといわれていたのですが。 2003年くらいからアーロンチェアを使っていたのですが、さすがに買い替えるかということで奮発しました。 アーロンチェアは座面がメッシュなのですが、ももが疲れるのもあり、クッション座面のものにしてみました。 冬寒くないのがいいですねwまだ届いたばかりなので調整しないと。\nKindle paperwhite Amazon | Kindle Paperwhite - 大きくなった6.8インチディスプレイ 防水機能搭載 wifi 8GB 電子書籍リーダー 車の点検などでちょっとした待ち時間があるようなときに新書や小説が読めるようにセールで安くなったタイミングで購入しました。 健康診断で読書がはかどりました。もっと本を読まないとなぁ。\nということで、ここ数年で買って便利なものをまとめてみました。 他にもある気がするけど、とりあえずこの辺で。\n","date":1640784504,"dir":"post/2021/","id":"218e2c36d5945ece02fdc55d6cbcbc38","lang":"ja","lastmod":1640784504,"permalink":"https://blog.johtani.info/blog/2021/12/29/best-buy-2021/","publishdate":"2021-12-29T22:28:24+09:00","summary":"2021年もあと少しですが、今年買って良かったものをリストアップしておこうかと思います。 今年買ったといいながら、昨年このネタを書くといいつつ","tags":["misc"],"title":"2021年かって良かったもの"},{"contents":"Azure Cognitive Searchのスキーマの確認をするときに、Azureのポータルでは次のようにフィールドの一覧として見ることができます。\nただ、実際のインデックス定義はJSON形式でやり取りする形になっています(JSONの例:Create Index | Microsoft Docs)。 上記のスクリーンショットのようにフィールド数が少ない場合はそれほど気にならないのですが、フィールド数が大きくなると一覧で見たくなることがあります。 また、ポータルを自分で確認できない場合にJSONファイルを受け取って確認することもあります。 こういう時は、Excel(CSV)って便利ですよね?\nということで、サクッと確認するときには、次のようなjqコマンドをWSL2上で利用して、CSVに変換して確認しています。\necho \u0026#34;Name\u0026#34;, \u0026#34;Type\u0026#34;, \u0026#34;Searchable\u0026#34;, \u0026#34;Facetable\u0026#34;, \u0026#34;Filterable\u0026#34;, \u0026#34;Retrievable\u0026#34;, \u0026#34;Sortable\u0026#34;, \u0026#34;Analyzer\u0026#34;, \u0026#34;IndexAnalyzer\u0026#34;, \u0026#34;SearchAnalyzer\u0026#34; \u0026gt; index_schema.csv cat index_schema.json | jq -r \u0026#39;.fields[]|[.name, .type, .searchable, .facetable, .filterable, .retrievable, .sortable, .analyzer, .indexAnalyzer, .searchAnalyzer]|@csv\u0026#39; \u0026gt;\u0026gt; index_schema.csv 例えばこんな感じになります(上記のポータルのスクショとは別のスキーマですが。。。)。\nどんなフィールドオプションが利用されているか?などをExcelで開いてフィルターなどを活用してチェックするのには便利かなと。 jqコマンドをもっとうまく使うと、ヘッダ行ももっとスマートに出せるかもしれないんですが。。。\nちなみに、上記のコマンドでは残念ながらEdm.ComplexType(参考: 複合データ型をモデル化する方法 - Azure Cognitive Search | Microsoft Docs)には対応していません。 必要になった時に考えるかな。。。\n","date":1640141671,"dir":"post/2021/","id":"f0fdc140e18514362a4e52376a6fecba","lang":"ja","lastmod":1640141671,"permalink":"https://blog.johtani.info/blog/2021/12/22/azure-search-schema-json2csv/","publishdate":"2021-12-22T11:54:31+09:00","summary":"Azure Cognitive Searchのスキーマの確認をするときに、Azureのポータルでは次のようにフィールドの一覧として見ることができます。 ただ、実際のインデ","tags":["azure search","misc"],"title":"Azure Cognitive SearchのIndex Schema JSONをCSVで見たくなる"},{"contents":"今年もアドベントカレンダーの季節になってしまいました。 今年で2回目となる、pyspa Advent Calendar 2021の投稿です。 昨年に引き続きDIYがらみの投稿です。\nコントローラーラック 3つのコントローラーがあるのですが、結構場所を取ります。 また、それぞれ充電しないといけません。\n充電しつつ、邪魔にならない置き方はできないものか?と思っていたところ次のようなコントローラーラックを見つけました。\nAmazon | 山崎実業(Yamazaki) ゲームコントローラー収納ラック これそのものは場所を取るので購入は見送りましたが、エレクターの棚にワイヤーネットをつけると似たようなものができるのでは?ということで、DIYしてみることにしました。\n材料 材料は以下の通りです。 書いていない材料としてあとは、結束バンドがあります。\nワイヤーネット44×29.5cm オフホワイトB28 | 【公式】DAISO(ダイソー)ネットストア スリム型ネットフック50mm 2本入り | 【公式】DAISO(ダイソー)ネットストア クロームメッキワイヤーフック(2連、U字、2個) | 【公式】DAISO(ダイソー)ネットストア Amazon | マグネット 充電ケーブル SUNTAIHO USBケーブル LEDインジケーター付き Amazon | Anker PowerPort Atom III Slim (PD 充電器 65W 4ポート USB-C) 設置 まずは、2連のワイヤーフックでワイヤーネットをエレクターの棚にぶら下げました。\nそのままでは固定されないので、下のエレクターの棚とワイヤーネットを結束バンドで固定。 これで、コントローラーを置いたり取ったりしてもぐらぐらしません。\n固定したワイヤーネットの表(コントローラーを配置する側)に、ネットフック50mmをコントローラーの数だけ配置しました(上の写真でフックとコントローラーの関係がわかります)。\n前から見るとこのような形です。 裏側に、2連フックを使って、Ankerの充電器を固定し、USBのケーブルをコントローラーの上に来るように配置します(写真ではPS4とPS5のコントローラーの上の部分にぶら下がる形です)。\nコントローラーには磁石の端子をコントローラーに差し込んでおきます。\n磁石のUSBケーブルを利用していることで、コントローラーを取り出すときは少し力を入れて引っ張るだけ、収めるときは、ケーブルに近づけて充電できる状態にした後にフックに載せるだけとなりました。 ケーブルの抜き差しをしなくてもよいのでとても便利。 全体像は次の写真のようになっています。一番上のコントローラーはエネループを利用しているのでケーブルは不要になっています。\n磁石のUSBケーブルをpyspaでとんぷーに教えてもらって思いついたアイデアです。 磁石の端子は色々と使い勝手が良いので、DIYキーボードやテンキー、MX Ergo、Kindleなど色々なところに使っています。\n今年のDIYキーボード キーボードを作ったのは2つですが、改造を色々やってました。 ブログに記載したものはリンクだけにしておきます。\nケーブル自作 自作ケーブルキット – 遊舎工房 ケーブルも自作できるみたいなので作ってみました。 現在はテンキーの配置の問題もあって、メインでは利用はしていませんが工作としては面白かったです。 熱収縮チューブを処理するための道具を持っていなかったので、チューブの固定が甘いのが失敗でした。ドライヤーくらいの熱では足りないので作ろうと思っている方は要注意かと。\nCorne Light v2のBLE+LPME-IO対応 詳細はブログ記事を。Corneはこれ以外に、キースイッチの付け替えも行ないました。ルブしたGateronクリアをハンダでつけなおしました。\nCorne Light v2のBLE+LPME-IO対応 #DIYキーボード Sofle keyboard v2のBLE+LPME-IO対応 詳細はブログ記事を。このブログはSofleで書いています。現在メインに利用しているキーボードです。\nSofle v2を組み立てて、BLE+LPME-IO化してみた #DIYキーボード 10月には電池モジュールを次のものに付け替えました。家で主に使用するのもあり、充電池のほうが使い勝手がよさそうだという判断です。スイッチのON/OFFもしやすくなって満足しています。\n単4電池昇圧モジュール - のぎけす屋 - BOOTH Sofleの電池モジュールをボタン電池から単4電池用に差し替えた。 pic.twitter.com/TUizwr2qmw\n\u0026mdash; Jun Ohtani (@johtani) October 16, 2021 Lunakey Miniの組み立てとBLE+LPME-IO対応 詳細はブログ記事を。Sofleと時々入れ替えて使っています。小指のあたりのずれの大きさ、親指のキーの多さが使い勝手のよいキーボードです。コンパクトなのもあり、こちらは持ち運びにも利用できるかなと考えています。\nLunakey Miniを組み立てて、BLE+LPME-IO化してみた #DIYキーボード Soyuzの組み立て(Numpadキット) Soyuz (黒基板) – 遊舎工房 自宅の作業環境(2021/02)の写真にもありますが、分割したキーボードとは別にテンキーを利用しています。 WindowsのログインでPinコードを入力したり、色々な場面で数字の入力をすることがあるためです。 Soyuzを組み立てる前は素 - Shiro – 遊舎工房を利用していたのですが、これでは「⁺」や「Enter」など、電卓のような利用方法の場合にはキーが足りません。 かゆいところに手が届かないので、きちんとしたNumpadをということでSoyuzを組み立てました。\nShiroよりもだいぶ存在感があります。\nGK21S(Numpad) USB Type C充電器付きの滑らかな交換用キーボードキット (Gk21s/k21),スイッチ,デュアルモードPCB|Keyboards| - AliExpress 最後は独身の日のセールで見つけたNumpadキットです。キットといってもこちらは、基盤からケースまで組み立てが終わっているキットで、キースイッチを差し込んで、キーキャップを付けるだけというものになります。 現在はこれをメインに利用しています。通常のNumpadの上に1列キーが多く、Backspaceなどを割り当てられるのが便利です。 ドライバーソフトも用意されており、キーマップのカスタマイズも可能です(まだそこまでやってないけど)。\nお気に入りキースイッチ Kailh Box Silent ピンク軸 5個 | Kochi Keyboard Input Club Hako スイッチ(10個入り) – 遊舎工房 最後はキースイッチの紹介です。 現時点ではこの2種類を組み合わせるのが私の好みに合っているようです(今のところ)。 Box Silentのピンクをアルファベットのキーに、Input Club HakoのVioletをCtrlやShift、Enterなどのキーに割り当てて使っています(下の写真の左側で、キーキャップをつけている部分がHako Violetになっています)。\nまとめ ということで、pyspa Advent Calendar 2021の8日目の記事でした。 それほど作ったりしてないなと思っていたのですが、記事にしてみると今年も色々とDIYしてたみたいです。 キースイッチやキーキャップも自分の好みが固まってきたので、来年はファームウェアやキーマップ周りをいじっていきたいと思っています。\n","date":1638889200,"dir":"post/2021/","id":"26e44dfd16a2963d4c18e99806c26fd7","lang":"ja","lastmod":1638889200,"permalink":"https://blog.johtani.info/blog/2021/12/08/controller-rack/","publishdate":"2021-12-08T00:00:00+09:00","summary":"今年もアドベントカレンダーの季節になってしまいました。 今年で2回目となる、pyspa Advent Calendar 2021の投稿です。 昨年に引き続きDIYがらみの投稿","tags":["DIYキーボード","misc"],"title":"今年のDIYキーボードとコントローラーラック"},{"contents":"Domain-Specific Pretraining for Vertical Search: Case Study on Biomedical Literatureという論文を読んだので軽くメモを残しておきます。論文自体はリンクから参照してください。\n読んだ理由 Azure Cognitive SearchでSemantic Searchが利用可能になったこともあり、「Semantic Search」に関するMSのリサーチチームが発表している論文をたまたま見つけたためです。 Elasticsearchとニューラルモデルを利用したランカーでのリランクする仕組みがSemantic Searchと似ていたので読んでみました。\nざっくりメモ どんなもの? クリックログなどで関連度を改善できないような場合に、ドメイン固有の言語モデルを利用して検索結果の改善をする方法が提案されているので、バイオメディカル検索で実際に評価してみたという論文です。 特定分野の大量の文書から検索をするときに、ドメイン固有の事前学習した言語モデルを用意して、さらにファインチューニングする方法を評価しています。 言語モデルの生成に利用されたのはBERTになります。\n技術や手法のキモはどこ? 医療分野のデータを利用して評価していますが、ほかのドメインにも一般化できる可能性があることや、実際のシステムを提示している部分が肝になりそうです。\n論文から引用した言語モデルを用いてランキングを行う仕組みを構築する部分の構成です。\n左半分が、ドメイン固有の事前学習についてです。Wikipediaなどを利用したBERTのモデルが公開されたりしていますが、大量のドメイン固有データが用意できるのであれば、ドメイン固有のデータで事前学習することが有効であるという主張です(参考文献。これもMS Researchでした。同じチームなのかな?)。 この論文ではBERTの学習データとして、ドメイン固有のテキストを用いています。 実際にはPubMedBERTを利用しています。\n右半分がドメイン固有のデータで生成された言語モデルを利用して、ドメイン固有のニューラルランカー(検索結果のランキングを行なう仕組み)をファインチューニングする処理です。 MS MARCOと呼ばれるMSが公開している機械学習向けのデータセットのうち、ドメイン固有のサブセットを取り出して利用しているようです。\nこの論文では、L1検索(第1段階の検索)にBM25を利用して、L2検索にここで作成したニューラルランカーを利用し、検索結果を返す仕組みとなっています。 これは、Azure Cognitive SearchのSemantic Searchのシステムに似ています。\nこの論文では、BM25で検索した結果の上位60件の結果がL2のランカーの入力となっています。\n以下の2つが主な論文の成果となっています。\nドメイン固有の事前学習を利用することで、高度な学習コンポーネントなどの追加することなく高い精度が出た。 既存のBM25の検索エンジンと組み合わせてニューラルランカーを使うことで、計算コストを下げつつより良い上位の検索結果を返す仕組みを構築した。 どうやって有効だと検証した? TREC-COVIDデータセットを用いて評価して、TREC-COVIDに参加しているシステムと論文で提案している構成のシステムとの比較をしています。 また、ドメイン固有の事前学習が、一般ドメインなどの事前学習と比較して影響があるかどうかの評価もしています。\n実際にAzure上で構築した仕組みをMicrosoft Biomedical Searchとして公開しているようです。 上記のシステム構成のように、Elasticsearchで検索して、ニューラルランカーはKubernetes上に展開されたGPUで計算をしています。 論文には使用しているマシンの構成や台数なども記載があります。\n実際に構築したシステムをユーザーに利用して体験したもらった結果としては、 複雑な意図を持った長いクエリに対してはPubMedなどの他の検索ツールとしても良い結果が返ってきたことが確認されたとなっています。 ただし、一般的な短いクエリの場合は十分な結果にならない場合があったとのことです。\n議論はある? 実際にほかのドメイン(金融、法律、小売りなど)で適用してもうまくいくかは今後の研究に期待だと思います。 また、ファインチューニングするときに利用できるデータが今回の論文にあるようにMS MARCOのサブセットとして抽出できればよさそうです。\n他に読むべき論文は? TREC-COVIDに参加しているほかのシステムがどのような学習や仕組みが必要なのかを見ることで、どのくらいの手間・コストが軽減しているのかがわかるはずです。\n感想 ということで、読んでみました。 細かなほかの手法については調べていませんが、システム構成としてはAzure Cognitive SearchのSemantic Searchの仕組みと同じだと思われます。 違いは、ドメイン固有の事前学習のモデルではないことでしょうか。 ある程度のドメイン固有のモデルを利用できる仕組みができると、さらにSemantic Searchがうまく使えるようになるのかもしれません(前回書いたブログではWikipediaのデータを利用してみましたが、思ったほど良い感じはしなかったです。。。ファインチューニングの仕組みもないしなぁ)。 また、短いクエリでは芳しくない結果もあったというのは、おそらくニューラルランカーで評価するための情報が少なくなってしまうのだと思います。Semantic Searchに向いているクエリの作り方とかが出てくるのかな?\n","date":1636522396,"dir":"post/2021/","id":"35200cbf0b5b45d7f5f0b343cb18868b","lang":"ja","lastmod":1636522396,"permalink":"https://blog.johtani.info/blog/2021/11/10/reading-ms-biomedical-search-paper/","publishdate":"2021-11-10T14:33:16+09:00","summary":"Domain-Specific Pretraining for Vertical Search: Case Study on Biomedical Literatureという論文を読んだので軽くメモを残しておきます。論文自体はリンクから参照してください。 読んだ理由 Azure Cognitive S","tags":["search","paper"],"title":"Domain-Specific Pretraining for Vertical Search: Case Study on Biomedical Literatureという論文を読んだ"},{"contents":"今年もMICESにも参加してました。 昨年はBerlin Buzzwordsと共同開催でしたが、今年は別開催(別日程)でした。\nMICESは2017年から始まったe-commerceの検索にフォーカスしたカンファレンスです。 ECに関連する話に特化されていますが、話題は多岐にわたっています。色々やることありますねぇ、ECも。\n参加したセッション 参加したセッションの個人メモを今回も残しておきます。 セッション個別のリンクは用意されていないみたいですが、公式サイトにタイムテーブルがあり、セッションのタイトル、概要に加えて、スライドのPDFもリンクがあります。動画が公開されているものもあります。\nDreaming Search ビデオが公開されています。スライドがざっくりしたものなので最初に聞いた時にはしっくりこなかったので、聞き直してのメモです。 GDPRのような話で、個人の情報を自分たちで管理しようと流れがあります。 それぞれのECサイトなどでのユーザーのイベント(何を検索して、何をクリックした)情報はそれぞれのサイトで閉じた情報になっています。このため、自分の興味のある情報が断片化された情報でそれぞれのサイトで管理されてしまい、パーソナライゼーションされるもの(ランキングだったりレコメンドだったり)がいまいちな場合があります。 この個人の情報(ユーザーのイベント)をユーザー自身がハンドリングして、どの情報までをどこまで公開できるようにするというように管理できる仕組みができないか?という話のようでした。実際にそのための仕組み(もっと大きな話の仕様)を検討しているプロジェクトがあり、それに関連して検索という観点で夢を語っているセッションです。\nざっくり私が理解したのをまとめましたが、empathy.coという会社としてはいくつかPoCなども実施されているようでした。 個人の情報の扱い方に関する話は新鮮で面白かったです。 仕組みが出来上がり、各サイトが対応するとより個人が欲しい情報が集まりやすくなるのかなぁ?\nForget Facets, welcome Refinements (TM) Berlin BuzzwordsでいくつかLTをやられていた方によるファセットとその応用(彼らはRefinementsと名前をつけたみたい)についての話でした(ビデオとスライドが公開済み。)。 検索エンジンとファセットの関係の歴史から始まって、Kibanaでの使い方、モバイルや音声検索・チャットボットでのファセットは難しいよね?という話につながります。 ということで、Refinementsとして、ファセットを提示してユーザーに選んでもらうだけでなく状況に応じて、提案するための情報としてファセットを使うといいのでは?という話でした。例えば、チャットボットや音声検索での結果の場合、検索結果数が多くなるとユーザーが望んだものが返せるとは限らないです。その時に、ファセットの情報をもとに絞り込み条件を聞き返すネタに使うのはどうか?というような話でした。オートサジェスト(検索があいまいな時に、追加のキーワードを提案するもの)のような形でブランド名だったり、カテゴリーなどを表示する仕組みです。 実際の実装の話は、彼らが過去にBerlin Buzzwordsなどで話をしているのでそちらが参考になるとのことでした(参考:berlin buzzwords 2019 / Heystack 2019)\nReinforcement learning in search 検索における強化学習の話みたいです。ビデオとスライドが公開されています。ビジネス的に検索のランキングが重要だが、そのランキングをどうやって良くしていくのか?という話です。 ランキングでデフォルトのBM25から始まり、LtRを導入し、A/Bテストなどをしつつ、モデルの変化がどのようにビジネスに影響するかをはかるのが難しくなります。 LtRに対するオンライン機械学習のアプローチについて実際に直面した課題の話などがされている(はず?)です(どうも、実際にCTRなどを用いたところまでは行ってなさそう)。\n多腕バンディットなどの強化学習の話が続いたあたりでギブアップしてしまいました。。。\nBetter Search through Query Understanding - Panel Query Understandingに関するパネルとして3社の人がそれぞれどういった取り組みをしてるか?という話をしたあと質問などに答えていく形式でした。残念ながらビデオはまだ公開されていませんが、スライドが公開されています。QA部分も結構な時間だったのでビデオの公開がされるといいなぁ。\nUnderstanding queries by analysing user interaction / Andrea Schütt (OTTO) OTTOというECサイトでのQuery Understandingの紹介と、LtR導入にまつわる話。 データサイエンスとして最初はQuery Understandingやってたけど、スケールしないのでLtR導入して色々と試行錯誤しているところのようだった。\nQuery Understanding AI search eBayの方の発表。Query Understanding = ユーザーの興味をクエリから類推するという定義から、クエリを分類する、同定するためにどうしているか?という話でっした。 単語の表面的な文字としての近さだけでは、語順が変わると意味が変わるものや、ステミングのせいで同じになってしまうものといった例を紹介しつつ、クエリをベクトルにして表現(コンバージョン、クリックなどの情報を元にプロダクトのベクトルにしてみたり)し似ているかどうか?を判断している話です。\nCase study : Autocomplete Search Suggestions Digitec Galaxusというサイトでのオートコンプリートをもっと使いやすくするためにどんなデータを集めて、どうやって表示しているか?という話でした。 とりあえず入力されたものにヒットしたものを出すような実装だった場合に、サジェストされる量が多く、ノイズも多いので使いにくかったものをどうやって改善して行ったかという処理の流れなどの説明もありました。\nThe need for an open web search in Europe - The approach of the Open Search Foundation and its implications for E-Commerce-Companies Speaker: Alexander Decker / OPEN SEARCH FOUNDATION\nもっとオープンな検索システムを作っていこうという団体の話でした。 AWSが最近1.0をリリースしたやつとは別物です。 Googleでみんな検索しているけど、ブラックボックスなのでバイアスがかかっている。 もっとバイアスフリーなインデックスを提供できると、使いやすくなるよね?みんなでそういうインデックスを作っていかないか?という話でした。 ECとの直接の関係はセッションからは読み取れませんでした。 どうやって、集めるデータの基準(入れるべき、入れるべきではないなど)を作るんだろう?という疑問が残っています。公共的なものやオープンデータについてはあるとよさそうかもなぁ。\n101 hints to improving the customer satisfaction on search engines in the retail industry Speaker: Marion Hemery (Carrefour France) \u0026amp; Lucian Precup (a// \u0026amp; Adelean)\nカルフールのECサイトでの検索に関する顧客満足度の改善についての話です。 どんなものをどうやって図るのか、フィードバックを取るための仕組みは? そこからわかったものをどうやってシステムに優先度をつけながら取り込んでいくのか? というのをどんなものを使っているかという説明を交えながらのセッションです。 スライドが結構細かく書かれているのでスライドを見るだけでもわかりやすいかな。\n“An ounce of prevention is worth a pound of cure”: establishing a gold standard-based evaluation in customer projects Speaker: Bertram Sändig \u0026amp; Cornelia Werk / NEOFONIE\n検索の性能指標(速度ではないほうの性能)をきちんと評価する仕組みが重要だよというセッションです。 検索の仕組みを変更(例ではステミングを導入するはなしをしてました)した場合に、現行システムにどういう影響が出るのか?それをどうやって図るのか、どうやってテストしていくのか?という話です。 ステミングを導入したら、検索にヒットしやすくなったものも出てきたけどその弊害として今までよかった検索の結果にノイズが増え多という話をもとに、検索結果としてこうあってほしいというゴールデンスタンダードをきちんと作って育てていくべきですよという話でした。完ぺきなものなどないので少しずつやっていきましょうと。\nということで、見ていないもの(LTや最後のワークショップ)もありますが、見たものに関してメモを残してみました。\n","date":1626160103,"dir":"post/2021/","id":"10a7f69bd03d2632722300194f01e93d","lang":"ja","lastmod":1626160103,"permalink":"https://blog.johtani.info/blog/2021/07/13/attend-mices-2021/","publishdate":"2021-07-13T16:08:23+09:00","summary":"今年もMICESにも参加してました。 昨年はBerlin Buzzwordsと共同開催でしたが、今年は別開催(別日程)でした。 MICESは201","tags":["conference","berlin buzzwords","MICES"],"title":"今年もMICESにオンライン出張してた"},{"contents":"今年もBerlin Buzzwordsにオンライン出張してました。 今年の開催は6月14日から17日まででした。 どんなカンファレンスなのかは昨年のブログ記事をごらんください。\n今年はHAYSTACKは共同開催で、MICESは別開催でした。 MICESにも参加していたので、また後日にブログ記事を公開する予定です。\n参加したセッション 参加したセッションの個人用のメモを取ってあるので、簡単にまとめておきます。 セッションページに動画やスライドも追加されつつあります。興味のある方はそちらをご覧いただければと。 (今のところYouTubeに上がっているビデオは69本あります。再生リストはこちら) 気になっていたセッションもあるので、ビデオを見てまたメモを公開すると思いますが、まずは第1弾を。 ちなみに、検索をメインに見ています。Berlin Buzzwords自体はオブザバビリティやOSSコミュニティ、データのストリーミングの話などの話題もあるので、この辺りも興味があれば探してみても面白いかもです。\nHow to measure Diversity of Search Results セッションページ: How to measure Diversity of Search Results | Berlin Buzzwords 2021 従来の検索では、クエリに対して精度の高い検索結果を1件または数件返すのはどうするか?というものだったが、最近、あるユースケース(ほかの物の発見を促したいケース)では 検索結果の多様性を高めつつ、精度もある程度確保したいという場合があります。\nざっくりした検索クエリ(例えば自転車)の場合に、自転車だけが1ページ目にある場合よりも自転車とは別に自転車グッズも表示された場合のほうがクリック率やGMV(Gross Merchandice Value?)が上がったという話が紹介されていました。 この時どのくらい混ぜればいいのか?というのを、シャノンのエントロピーを使って、検索結果の多様性を保つための具体的なヒントについて話をされています。 実際にこういう計算をしてやれますねという紹介がされています。\nFrom text search and recommendation to ads and online dating; approximate nearest neighbors in real world applications セッションページ: From text search and recommendation to ads and online dating; approximate nearest neighbors in real world applications | Berlin Buzzwords 2021 Vespa.ai(OSS)の紹介でANNの話でした。通常、ANNを用いた検索の場合に他の検索条件(地理情報、日付など)をANNの結果に対して適用すると、望んでいる数がとれないです。その場合に、Vespaは内部でいい感じの動きをしますよという紹介でした。\n\u0026ldquo;Are You Sure?\u0026quot;: blending product comparisons and recommendations with A.I. セッションページ: \u0026ldquo;Are You Sure?\u0026quot;: blending product comparisons and recommendations with A.I. | Berlin Buzzwords 2021 Amazonの製品ページにある、類似商品との比較一覧のような一覧をどうやって実現するか?という話でした。比較一覧に掲載する商品を選出するパイプラインをこうやれますよね?という話でした。ログ(クリックやカートに入れたかどうかなど)を元にkNNで似ているデータを洗い出し、どの商品、どの項目を比較一覧として選ぶかという流れでした(セッションではもっと詳しい話がされています)。オフライン実験の話までがセッションでされています。\nThe future of Lucene\u0026rsquo;s MMapDirectory: Why use it and what\u0026rsquo;s coming with Java 16 and later? セッションページ: The future of Lucene\u0026rsquo;s MMapDirectory: Why use it and what\u0026rsquo;s coming with Java 16 and later? | Berlin Buzzwords 2021 Apache Lucene PMCのUweさんによるLuceneのMMapDirectoryの話です。 ファイルシステムとJavaに関する歴史と、なぜMMapなのか、現在のMMapの実装の問題点とJDK 16でどうなっているか(どんな感触か)、さらにその先(JDK17)は?という話です。 Luceneでの利用方法からJDKへのフィードバックが行われている話や、そのフィードバックをもとに今後どのようにしていくのか?という話がされています。\nSearch and Sushi; Freshness Counts セッションページ: Search and Sushi; Freshness Counts | Berlin Buzzwords 2021 こちらもVespa.aiの紹介です(今年はスポンサーしてるから多いのかも?)。Yahoo!とVerizon Mediaで利用している話をしたあと、Vespaでのリアルタイムインデキシングに関するアーキテクチャの紹介でした。内部で転置インデックスやそれ以外のデータをどのように保持しているのか?どういったことができるのか?というのをアーキテクチャ、ストレージの観点から紹介しています。\nEncores? - Going beyond matching and ranking of search results セッションページ(動画がまだない): Encores? - Going beyond matching and ranking of search results | Berlin Buzzwords 2021 検索のマッチングやランキング以外のいくつかの機能についての紹介をワークショップ形式で行うセッションです。ファセット、クエリオートコンプリート、スペル訂正、クエリリラクゼーションについて、データとSolrのクエリを基準に説明をしてくれます。\nThe Invasion of Transformers - Boosting Search with Latest NLP セッションページ: The Invasion of Transformers - Boosting Search with Latest NLP | Berlin Buzzwords 2021 deepsetという会社のCTOの方で、自社で作っているOSSのhaystackという製品の紹介です。 最近のGoogleの検索結果にはいろんなもの(問いかけに関する答えそのもの、またそのプレビューやサマリー)が出てきているという話から、Transformersを使って検索ができないかということで自社のOSSの仕組みを紹介しています。\n参考 Google: BERT now used on almost every English query deepset-ai/haystack: End-to-end Python framework for building natural language search interfaces to data. Leverages Transformers and the State-of-the-Art of NLP. Supports DPR, Elasticsearch, Hugging Face’s Hub, and much more! Learning to Judge セッションページ: Learning to Judge | Berlin Buzzwords 2021 otto.deというECサイトでLtRを導入し、そのLtRにどんな特徴を利用しどうやって実験したかというセッションでした。Apache Solrで検索ができていて、これまでは検索の管理を人手で行っていたがスケールしない(扱う商品などは増えているのに)のでLtRを導入し始めたという感じでした。LtRの導入の過程でどういう仮定を置いて、どうモデルを決め、それをどうやってテストしてどう分析したか?という流れでした。\nText categorization with Apache Lucene セッションページ: Text categorization with Apache Lucene | Berlin Buzzwords 2021 LTなので短めです。BBCのデータセットをインデックスに登録し、そのデータをもとにLucene(デモではKibana+Esを利用していた)でテキスト分類を行なう方法について紹介しています。BBCのデータセットは記事(テキスト)とカテゴリ(タグ)というデータです。 このデータが登録されているインデックスに対して、More Like Thisクエリに分類したい文章を与え、ヒットしたデータをもとにAggregationでカテゴリを取得し、上位のカテゴリが分類された結果になるというデモでした。 テキストフィールドにはEdge N-Gramを利用していること、Aggregationのソートの条件はMore Like Thisクエリでのスコアの平均を利用していることというのがこの方法がうまくいくことのようでした(なるほど!)。ただ、日本語でもこれが使えるかな?というのはやってみないとわからないかなぁと(やってないです)。\nとりあえず、メモしておいたのはこの辺でした。 他にもセッション一覧を眺めながら面白そうな話をピックアップしてメモを取っていこうかなぁ?気になるセッション、メモがおかしいなどあればコメントいただければと。\n","date":1625815493,"dir":"post/2021/","id":"59b7b60e6bbf4858d72643d22ad90451","lang":"ja","lastmod":1625815493,"permalink":"https://blog.johtani.info/blog/2021/07/09/berlin-buzzwords-2021-1/","publishdate":"2021-07-09T16:24:53+09:00","summary":"今年もBerlin Buzzwordsにオンライン出張してました。 今年の開催は6月14日から17日まででした。 どんなカンファレンスなのかは昨年","tags":["conference","berlin buzzwords"],"title":"今年もBerlin Buzzwordsにオンライン出張してた"},{"contents":"Azure Cognitive Searchで新機能「Semantic Search(セマンティック検索)」という機能の日本語対応が発表されました。 実際にはPublic Previewという状態ではありますが、どんな機能か気になったので調べてみました。 なお、本ブログは2021年6月時点での内容となります。\n公式ドキュメント 公式ドキュメントでいろいろと説明されています。まずは公式ドキュメントを見ていただくのが良いかなと。最初のドキュメントには10分ちょっとの紹介ビデオもあります。ピックアップしたのは概要、クエリ、レスポンスの構造、紹介ブログになります。ブログ以外は日本語(たぶん機械翻訳?)になっています(新機能の紹介の日本語ページにはまだ記載がありません)。\nSemantic search - Azure Cognitive Search | Microsoft Docs Create a semantic query - Azure Cognitive Search | Microsoft Docs Structure a semantic response - Azure Cognitive Search | Microsoft Docs The science behind semantic search: How AI from Bing is powering Azure Cognitive Search - Microsoft Research 簡単にですがデータを入れて試してみたので、どんな仕組みなのかどういう挙動なのかを紹介します。\nSemantic Searchとは? 言語理解、セマンティック関連性などを提供する機能です。BingとMSリサーチにより開発されて、Azure Cognitive Searchに導入されました。 クエリの書き方を少し変更する必要がありますが、再インデックスや設定変更などは必要ないという仕組みになっています。\n検索クエリからコンテキストを読み取って、検索し、リランクするアルゴリズム(Semantic Ranker) 関連する一節を強調表示(Semantic Caption) クエリに対するセマンティック回答(Semantic Answer) スペルチェック機能 言語によって利用できる機能が異なります。\nSemantic Searchの利点は先ほどの紹介にも書きましたが、インデキシング時に特殊処理をする必要がないことかなと。 すでに登録してあるデータ(制限がありますが)でもすぐに試すことができます。\n仕組み https://docs.microsoft.com/ja-jp/azure/search/media/semantic-search-overview/semantic-query-architecture.png\nスペル修正機能 クエリパース スコアリング 上位50件に対してSemantic Rankerにより再評価(検索ヒットが50件以上の場合でも上位50件のみがリランクの対象) 言語表現モデルを利用 結果の要約として最適な部分をキャプションとして抽出。 クエリが質問形式の場合は一番よさそうな場所を回答として選択 1および4番目の処理が今回新しく使えるSemantic Searchの機能になります。スペルチェックは日本語がまだ対象外なので、4番目の機能について紹介します。\n利用できる環境と制限 冒頭でも書きましたが、Public Previewの段階です。実際に利用するにはリクエストページから申し込みが必要になっています。\n利用リクエスト時に利用するAzure Cognitive Searchのサービス名が必要になるので、あらかじめ起動しておかなければいけません。 また、利用できるリージョンが限定されているのでサービス起動時のリージョンには気を付けてください。\n利用できるリージョン 米国中北部、米国西部、米国西部 2、米国東部 2、北ヨーロッパ、西ヨーロッパ 利用できるTier セマンティック検索はStandardレベル スペルチェックはレベル制限なし 価格(セマンティック検索のみ) 7月初旬までは25万クエリで500ドル Analyzerの制限 Azure Cognitive Searchが提供する言語アナライザーが対象(Custom Analyzerでは利用不可) サービス起動後にプレビュープログラムを申請すると、利用できるようになるとメールが届きます。そこから利用ができるようになります。\n今回は日本語のWikipediaのデータをいれてどんな機能なのかを確認してみました。\nWikipediaのデータを入れて試してみた 日本語のWikipedia(あとで英語も入れました)を一部(10万件程度)登録してSemantic Search(主にRanker)の動きを確認してみました。\nデータの登録には自作ツールを利用。\nJSONデータ生成ツール:https://github.com/johtani/wiki-extractor-rs JSONデータ登録ツール:https://github.com/johtani/wiki-json-loader 日本語Wikipediaの2020年6月のデータ、英語Wikipediaの2021年6月のデータを利用。上記ツールで生成したもののうち約10万件をAzure Cognitive Searchに登録して動作確認をしました(英語のデータでJSONデータ生成ツールでバグがあるのですが修正していません。。。)。 また、クエリの実行にはVisual Studio CodeのREST Client拡張(どんなものかは以前のブログをご覧ください)を使いました。簡単にREST APIを呼び出せるのはすばらしい。\n日本語のWikipedia 日本語のWikipediaのデータを「96,344件」登録し実験しました。 スキーマは次のような形です(説明に必要なものだけ抽出してあります)。自然分が入っているtitle、contents、headingsの3つのフィールドを今回はSemantic Searchの対象にしてみるので、AnalyzerをLuceneベースの日本語Analyzerであるja.luceneを設定しました。\nフィールド名 : タイプ / Analyzer id : Edm.String / keyword categories : Collection(Edm.String) / keyword title : Edm.String / ja.lucene contents : Edm.String / ja.lucene headings : Edm.String / ja.lucene Analyzerに言語Analyzerを設定するくらいで、他の設定は特に必要ありません。\nクエリとデータの確認 デモの動画や説明のサンプルを見たところ英語で「Where was Alan Turing born?」や「What\u0026rsquo;s the capital of France?」のような自然文のクエリが出てきたので、次のようなクエリで試してみました。\nフランスの首都はどこですか? 実際にパリのページがインデックスに存在していることは以下のクエリで確認しました。\nパリ:3047件 POST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;パリ\u0026#34;, \u0026#34;top\u0026#34;: 10, \u0026#34;searchFields\u0026#34;: \u0026#34;title, categories, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id, contents\u0026#34; } ※ここで{{host}}などはREST Client拡張で変数として定義したものです。\nhost : Azure Cognitive Searchのサービス名 index-name : インデックス名 api-key : 接続のためのAPIキー URLパラメータのapi-version=2020-06-30-PreviewがPreview機能を呼び出すための指定になっています。\n3047件の1件目が「パリ」のページで以下のようなWikipediaの文章をセクションごとに文字列としてページ全体を配列に入れてcontentsに登録してあります。\n\u0026#34;パリ(、巴里)は、フランス北部、イル=ド=フランス地域圏にある都市。フランスの首都であり、イル=ド=フランス地域圏の首府である。\\nフランス最大の都市であり、同国の政治、経済、文化などの中心である。ロンドンと共に欧州を代表する世界都市。行政上では、1コミューン単独で県を構成する特別市であり、ルーヴル美術館を含む1区を中心に、時計回りに20の行政区が並ぶ(エスカルゴと形容される)。\u0026#34;, このインデックスに対して「フランスの首都はどこですか?」というクエリを、セマンティック検索のクエリと通常のクエリの2パターンで検索をしてみました。\nこれまでのクエリ(セマンティックではない検索) まずは通常のクエリです。 searchがクエリ文字列、searchFieldsが検索対象フィールドになります。\nPOST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;top\u0026#34;: 100, \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;フランスの首都はどこですか?\u0026#34;, \u0026#34;searchFields\u0026#34;: \u0026#34;title, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id\u0026#34; } クエリを実行するとヒット件数が'13996\u0026rsquo;件で、トップ5件のデータは次のようになりました。\n\u0026#34;@odata.count\u0026#34;: 13996, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 17.059355, \u0026#34;id\u0026#34;: \u0026#34;462\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;首都\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 16.086372, \u0026#34;id\u0026#34;: \u0026#34;21053\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;首都圏\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 15.059893, \u0026#34;id\u0026#34;: \u0026#34;71414\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;どこでもドア\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 14.086605, \u0026#34;id\u0026#34;: \u0026#34;51972\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;首都機能移転\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.996841, \u0026#34;id\u0026#34;: \u0026#34;3877\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;首都の一覧\u0026#34; }, 見るとわかりますが、「首都」「どこ」といった単語を含むデータが上位に入っています。「フランス」を含むデータは8件目と10件目に「フランス植民地帝国」、「ラ・フランス」といったデータが出てきます。\n{ \u0026#34;@search.score\u0026#34;: 12.705561, \u0026#34;id\u0026#34;: \u0026#34;129279\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;フランス植民地帝国\u0026#34; }, ... { \u0026#34;@search.score\u0026#34;: 12.036648, \u0026#34;id\u0026#34;: \u0026#34;3173\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ラ・フランス\u0026#34; }, 残念ながら望んでいる結果にはほど遠いかと。\nどんな検索になっているのでしょうか?まずは、クエリの解釈から。 デフォルトで、Azure Cognitive Searchはデフォルトでは、入力された文字列をtype=simple、mode=anyで検索します(クエリパラメータ参照)。 対象となるフィールドはsearchFieldsで今回は指定してあるので、これらのフィールドに対して、入力された文字列を渡してAnalyzerで単語分割し(今回はsimpleクエリ用の特殊文字が入っていないため文字列として扱われる)、 出てきた単語で(mode=anyだから)OR検索します。 ja.luceneのAnalyzerが出力する単語列がどんなものかは以下のリクエストを実行するとわかります。\nPOST https://{{host}}/indexes/{{index-name}}/analyze?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;analyzer\u0026#34;:\u0026#34;ja.lucene\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;フランスの首都はどこですか?\u0026#34; } 結果は以下の通りです。\n\u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;フランス\u0026#34;, \u0026#34;startOffset\u0026#34;: 0, \u0026#34;endOffset\u0026#34;: 4, \u0026#34;position\u0026#34;: 0 }, { \u0026#34;token\u0026#34;: \u0026#34;首都\u0026#34;, \u0026#34;startOffset\u0026#34;: 5, \u0026#34;endOffset\u0026#34;: 7, \u0026#34;position\u0026#34;: 2 }, { \u0026#34;token\u0026#34;: \u0026#34;どこ\u0026#34;, \u0026#34;startOffset\u0026#34;: 8, \u0026#34;endOffset\u0026#34;: 10, \u0026#34;position\u0026#34;: 4 } ] これで、どのような単語が出てきているかがわかりました。 それぞれのフィールドでどのようなスコアになっているかまではわからないですが、検索結果には上記3つの単語のいずれかがsearchFieldsにヒットすれば出てきます。おそらく、ヒットした単語数が多い、短い文字列のフィールドがより高いスコアになるというような動きになっていると思われます(BM25になってるはず)。\nセマンティック検索 では、セマンティック検索のクエリに変更してみましょう。\nPOST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;top\u0026#34;: 100, \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;フランスの首都はどこですか?\u0026#34;, \u0026#34;searchFields\u0026#34;: \u0026#34;title, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id\u0026#34;, \u0026#34;queryType\u0026#34;: \u0026#34;semantic\u0026#34;, \u0026#34;queryLanguage\u0026#34;: \u0026#34;ja-jp\u0026#34; } queryType、queryLanguageがセマンティック検索のクエリを実行するためのパラメータになります(公式ガイド参照)。 今回は日本語のデータであるため、日本語のモデルを利用するようにqueryLanguageを指定します(許可されていない文字列を渡すとエラーになる)。 この2つを追加するだけです。簡単ですね。\n結果は次のようになります(上位5件抜粋)。\n\u0026#34;@odata.count\u0026#34;: 13996, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 12.036648, \u0026#34;@search.rerankerScore\u0026#34;: 2.3456064984202385, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;ラ・フランス\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;ラ・フランス\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;3173\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ラ・フランス\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 11.144733, \u0026#34;@search.rerankerScore\u0026#34;: 2.3173404783010483, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;ラン (フランス)\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;ラン\u0026lt;/em\u0026gt; (\u0026lt;em\u0026gt;フランス)\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;108094\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ラン (フランス)\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 11.144793, \u0026#34;@search.rerankerScore\u0026#34;: 2.1937477812170982, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;ブレスト (フランス)\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;ブレスト\u0026lt;/em\u0026gt; (\u0026lt;em\u0026gt;フランス)\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;116154\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ブレスト (フランス)\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 10.199907, \u0026#34;@search.rerankerScore\u0026#34;: 2.1590753793716431, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;フランス・ハルス\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;フランス・ハルス\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;81566\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;フランス・ハルス\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 11.273148, \u0026#34;@search.rerankerScore\u0026#34;: 2.1434053033590317, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;バカロレア (フランス)\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;バカロレア\u0026lt;/em\u0026gt; (\u0026lt;em\u0026gt;フランス\u0026lt;/em\u0026gt;)\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;54514\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;バカロレア (フランス)\u0026#34; }, 検索結果数を見ると、通常のクエリと同じ値です。 これは、公式ドキュメントのセマンティック検索に説明があるように、 セマンティック検索が通常のクエリで実行した後の検索結果に対して、上位50件のデータだけに対してsemantic rankerによってスコアを再計算するという仕様のためです(ドキュメントからの推測)。\n実際に検索結果の50件目、51件目は次のようになっていました。50件目までのデータには@search.rerankerScoreというスコア(と@search.captions)が追加されています。 51件目のデータについては、前の通常のクエリの51件目のデータと同じデータでした。\n{ \u0026#34;@search.score\u0026#34;: 10.909212, \u0026#34;@search.rerankerScore\u0026#34;: 0.07321979058906436, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;首都高速埼玉大宮線\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;67667\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;首都高速埼玉大宮線\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 10.049902, \u0026#34;id\u0026#34;: \u0026#34;68569\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;スタッド・ド・フランス\u0026#34; }, 上位5件のデータに戻ります。 これらは、通常のクエリとは異なる結果となりました。 見ると@search.captionsというところにハイライトされた項目が表示されています。 検索クエリをもとにそれっぽい部分がキャプションという形で返ってくる仕組みです。\n結果を見るとわかりますが、残念ながら「パリ」のページは返ってきませんでした。 もともと通常のクエリを実行したときの「326」番目の結果として返ってきているため、セマンティック検索の対象とはならなかったためです。 ただ、「首都」「どこ」といった単語よりも「フランス」に関するドキュメントが通常の検索よりも上位に来ています。 クエリに存在する単語で「フランス」がより重要であると判断されているようです。\nSemantic Rankerに処理させてみる ちなみに、今回登録したデータにはWikipediaのカテゴリも登録してあります。 「ヨーロッパの首都」というカテゴリで絞り込んでから検索してみるとどうなるかもやってみました。 filterのパラメータが絞り込み条件です。\nPOST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;top\u0026#34;: 100, \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;フランスの首都はどこですか?\u0026#34;, \u0026#34;searchFields\u0026#34;: \u0026#34;title, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id\u0026#34;, \u0026#34;queryType\u0026#34;: \u0026#34;semantic\u0026#34;, \u0026#34;queryLanguage\u0026#34;: \u0026#34;ja-jp\u0026#34;, \u0026#34;filter\u0026#34;: \u0026#34;search.ismatch(\u0026#39;ヨーロッパの首都\u0026#39;, \u0026#39;categories\u0026#39;)\u0026#34; } 結果は次の通りです。カテゴリで絞り込みをしているので検索結果数は39件となります。このため、すべてのデータがSemantic Rankerの対象です。 ですが、「パリ」のページは11件目に出てきました。\n\u0026#34;@odata.count\u0026#34;: 39, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 3.8405614, \u0026#34;@search.rerankerScore\u0026#34;: 2.0472740978002548, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;ウィーン\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;9465\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ウィーン\u0026#34; }, ... { \u0026#34;@search.score\u0026#34;: 4.8915977, \u0026#34;@search.rerankerScore\u0026#34;: 1.8480307757854462, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;レイキャヴィーク\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;レイキャヴィーク\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;112253\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;レイキャヴィーク\u0026#34; }, ... { \u0026#34;@search.score\u0026#34;: 7.277628, \u0026#34;@search.rerankerScore\u0026#34;: 1.7982495501637459, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;パリ\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;パリ\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;31\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;パリ\u0026#34; }, キャプションは入力された単語だけではなく、クエリが持っている単語をもとにした何かしらの基準(おそらく言語モデルで近い単語?)で選択されていると思われます。首都というカテゴリーで絞り込んでしまったので、ヒットした文章が似たようなものが多くなったせいか、残念ながらそこまでSemantic Rankerが意図を汲み取るところまでは行きませんでした。\nフランスの歴史 視点を変えてみましょう。質問そのものの答えではなく、クエリの意図に近いものが出てくるかを見てみましょう。 ここまでのクエリでフランスに関するクエリを投げていました。今回のインデックスに「フランスの歴史」で検索すると「30820」件のドキュメントがヒットし、上位にはフランスには関係ない「歴史」のページや「フランス」の文学、都市など「フランスの歴史」とは少し離れた意味のものが上位に来ています。\n\u0026#34;@odata.count\u0026#34;: 30820, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 12.888079, \u0026#34;id\u0026#34;: \u0026#34;17875\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;スコットランドの歴史\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.718105, \u0026#34;id\u0026#34;: \u0026#34;10665\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;世界の歴史\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.701981, \u0026#34;id\u0026#34;: \u0026#34;31397\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ベトナムの歴史\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.579847, \u0026#34;id\u0026#34;: \u0026#34;22433\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;フランス文学\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.524254, \u0026#34;id\u0026#34;: \u0026#34;34667\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;フランスの国旗\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.52136, \u0026#34;id\u0026#34;: \u0026#34;108094\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ラン (フランス)\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.41088, \u0026#34;id\u0026#34;: \u0026#34;20717\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;歴史小説\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.388911, \u0026#34;id\u0026#34;: \u0026#34;56229\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;演劇の歴史\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.343941, \u0026#34;id\u0026#34;: \u0026#34;39669\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;イギリスの歴史\u0026#34; }, このクエリをセマンティッククエリで検索すると次のようになりました。\n\u0026#34;@odata.count\u0026#34;: 30820, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 12.274498, \u0026#34;@search.rerankerScore\u0026#34;: 1.482184374704957, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;自由フランス\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;自由フランス\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;96475\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;自由フランス\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 11.446766, \u0026#34;@search.rerankerScore\u0026#34;: 1.3535655084997416, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;フランスの地域圏\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;フランスの地域圏\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;51845\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;フランスの地域圏\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 10.926437, \u0026#34;@search.rerankerScore\u0026#34;: 1.3261859538033605, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;フランス第一帝政\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;フランス第一帝政\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;57573\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;フランス第一帝政\u0026#34; }, 上位には「フランスの歴史」に関連しそうなタイトルが上がってきています。 また、先ほど「歴史」という単語でヒットして上位に来ていた「スコットランドの歴史」は@search.rerankerScoreの値が低くなっていました(31件目に出現)。\n{ \u0026#34;@search.score\u0026#34;: 12.888079, \u0026#34;@search.rerankerScore\u0026#34;: 0.42768346797674894, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;スコットランドの歴史\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;17875\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;スコットランドの歴史\u0026#34; }, 考察 日本語のWikipediaを約10万件入れたインデックスでセマンティック検索を試してみました。 デモや説明などでクエリが自然文の質問だったこともあり、質問の回答になりそうなページが上に来るかと期待しましたが、期待しすぎました。\nこれは、Azure Cognitive Searchのセマンティック検索の仕組みを考えると納得のいくものです。 説明を読んだ時にも感じたのですが、入力された文字列でまず検索をし、上位50件をセマンティック検索の対象としています。\nですので、そもそもクエリの文章に出てくる単語が含まれたデータだけが対象となります。 このため、クエリに出てこない単語のみで構成されているものは残念ながら対象とできません。 また、上位50件だけがSemantic Rankerの対象となっているため、検索にヒットしたとしても上位に食い込まなければ言語モデルによるランキングの対象にもなりません。 セマンティック検索といっても、残念ながらドキュメントに出てこない単語(似た単語、質問に対するそのものの回答)まで読み取る機能はありません。\nただ、「フランスの歴史」の検索で見たようにそれぞれの単語だけで検索をしていた場合とは異なり、 クエリの意味に沿ったスコアづけにより、通常の検索よりも意図したものに近いデータが出ていることが確認できました。 複数の単語で構成されるクエリの場合に、単語だけでスコアを計算した場合よりもよさそうな結果が上位に出てくることがわかりました。\nただし、重要なのは「上位50件」までしかSemantic Rankerの対象にはならない点です。\n英語のWikipedia セマンティックは英語対応が一番最初にリリースされているので、英語のWikipediaについてもデータを登録してみました。\n英語のWikipediaのデータを「111,649件」登録しました。 スキーマは以下の通り(今回の調査に利用していないものは省略)です。日本語と異なる点はAnalyzerがen.luceneになっていることぐらいです。\nフィールド名 : タイプ / Analyzer id : Edm.String / keyword categories : Collection(Edm.String) / keyword title : Edm.String / en.lucene contents : Edm.String / en.lucene headings : Edm.String / en.lucene クエリとデータの確認 日本語同様に首都に関する質問形式にしてみました。\nWhat\u0026rsquo;s the capital of Italy? 実際にRomeのページがインデックスに存在していることは以下のクエリで確認済みです。\nRome:2302件\nPOST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;Rome\u0026#34;, \u0026#34;top\u0026#34;: 10, \u0026#34;searchFields\u0026#34;: \u0026#34;title, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id, contents\u0026#34; } 以下のようなWikipediaの文章をセクションごとに文字列としてページ全体を配列に入れてcontentsに登録してあります(これも日本語と同じです)。\n\u0026#34;\u0026#34;\\n\\nRome (Italian and Latin: Roma ) is the capital city and a special comune of Italy (named Comune di Roma Capitale), as well as the capital of the Lazio region. The city has been a major human settlement for almost three millennia. With 2,860,009 residents in , it is also the country\u0026#39;s most populated comune...\u0026#34;, このデータ群に対して「What\u0026rsquo;s the capital of Italy?」というクエリを、Semantic Searchのクエリと通常のクエリの2パターンで検索をしてみる。\nこれまでのクエリ(セマンティックではない検索) まずは、Semantic Searchではないクエリです。\nPOST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;top\u0026#34;: 100, \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;What\u0026#39;s the capital of Italy?\u0026#34;, \u0026#34;searchFields\u0026#34;: \u0026#34;title, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id\u0026#34; } ヒット件数は18049件で、トップ5件は次のような形です。\n\u0026#34;@odata.count\u0026#34;: 18049, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 17.870815, \u0026#34;id\u0026#34;: \u0026#34;14532\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Italy\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 16.596167, \u0026#34;id\u0026#34;: \u0026#34;14702\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Economy of Italy\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 16.180624, \u0026#34;id\u0026#34;: \u0026#34;183878\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Louis II of Italy\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 15.917025, \u0026#34;id\u0026#34;: \u0026#34;29665\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;State capitalism\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 15.88901, \u0026#34;id\u0026#34;: \u0026#34;215741\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Capitalization\u0026#34; }, 日本語の場合よりもItalyに関連するものが上位に多く含まれます。 ただ、Rome自体のページは上位50件には出てきていませんでした。 また、capitalとは意味の異なるcapitalizationやcapitalismが上位に来ています。 日本語の場合と同様にクエリがどのように解釈されているのか?も見てみます。\nPOST https://{{host}}/indexes/{{index-name}}/analyze?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;analyzer\u0026#34;:\u0026#34;en.lucene\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;What\u0026#39;s the capital of Italy?\u0026#34; } 結果は以下の通りです。\n\u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;what\u0026#34;, \u0026#34;startOffset\u0026#34;: 0, \u0026#34;endOffset\u0026#34;: 6, \u0026#34;position\u0026#34;: 0 }, { \u0026#34;token\u0026#34;: \u0026#34;capit\u0026#34;, \u0026#34;startOffset\u0026#34;: 11, \u0026#34;endOffset\u0026#34;: 18, \u0026#34;position\u0026#34;: 2 }, { \u0026#34;token\u0026#34;: \u0026#34;itali\u0026#34;, \u0026#34;startOffset\u0026#34;: 22, \u0026#34;endOffset\u0026#34;: 27, \u0026#34;position\u0026#34;: 4 } ] 日本語とあまり変わってはいません。ただ、単語が入力されたものとは少し変わっています。 これは、en.luceneの処理で、stemmingが行われているためだと思われます。たとえば、「capital」の場合、Stemmingにより「capital」「capitalize」などの単語が元になりますが、動詞、名詞などの違いなく検索できるようにするためにこのようなStemmingの処理が行われます。 ということで、これらの単語を含むドキュメントがヒットしています。Italyが一番上に来ているのはItalyという単語が多く含まれるからのようです。\nSemantic Searchクエリ では、Semantic Searchのクエリに変更してみましょう。\nPOST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;top\u0026#34;: 100, \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;What\u0026#39;s the capital of Italy?\u0026#34;, \u0026#34;searchFields\u0026#34;: \u0026#34;title, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id\u0026#34;, \u0026#34;queryType\u0026#34;: \u0026#34;semantic\u0026#34;, \u0026#34;queryLanguage\u0026#34;: \u0026#34;en_us\u0026#34; } queryType、queryLanguageがsemantic searchのクエリを実行するためのパラメータになります(公式ガイド参照)。 今回は英語のデータであるため、英語のモデルを利用するようにqueryLanguageを指定します(許可されていない文字列を渡すとエラーになる)。\n結果は次のようになります(上位5件抜粋)。\n\u0026#34;@odata.count\u0026#34;: 18049, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 17.870815, \u0026#34;@search.rerankerScore\u0026#34;: 1.9688458815217018, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Italy\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;14532\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Italy\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 14.239678, \u0026#34;@search.rerankerScore\u0026#34;: 1.9419755563139915, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Capital city\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;181337\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Capital city\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 10.181764, \u0026#34;@search.rerankerScore\u0026#34;: 1.8902588561177254, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Lepontii\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;325133\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Lepontii\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 10.865718, \u0026#34;@search.rerankerScore\u0026#34;: 1.875102698802948, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;ItalY\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;14482\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ItalY\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 11.689348, \u0026#34;@search.rerankerScore\u0026#34;: 1.8201303631067276, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Savoy\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;27885\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Savoy\u0026#34; }, 日本語で見てきたように、検索結果数を見ると、通常のクエリと同じ値で、残念ながら50件までにRomeは入っていないため、Semantic Rankerによるブーストもかかりませんでした。 ただし、「Capitalization」や「State capitalism」といった別の意味(地理に関するものではない単語)のものが上位に出てこなくなっています。 これは、capitalという単語が地理に関する意味を持っていると判断された結果のように見えます。 Capitalizationの@search.rerankerScoreは上位のスコアに比べて小さいものとなっています。\n{ \u0026#34;@search.score\u0026#34;: 15.88901, \u0026#34;@search.rerankerScore\u0026#34;: 0.93921028636395931, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Capitalization\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;215741\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Capitalization\u0026#34; }, What\u0026rsquo;s the capital of Finland? 上位50件以内(20件目)に「Helsinki」のページが出てくるクエリでセマンティック検索をしてみました。\nPOST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;top\u0026#34;: 100, \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;What\u0026#39;s the captial of Finland?\u0026#34;, \u0026#34;searchFields\u0026#34;: \u0026#34;title, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id\u0026#34;, \u0026#34;queryType\u0026#34;: \u0026#34;semantic\u0026#34;, \u0026#34;queryLanguage\u0026#34;: \u0026#34;en-us\u0026#34; } 結果としては、2件目にHelsinkiが返ってきていたので、Semantic Rankerがによる並び替えがうまくいきました。 (下記の結果は上位3件を抜粋したものです)。\n\u0026#34;@odata.count\u0026#34;: 16673, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 14.026371, \u0026#34;@search.rerankerScore\u0026#34;: 2.42378556355834, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Vanaja (Finland)\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;7132102\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Vanaja (Finland)\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.434971, \u0026#34;@search.rerankerScore\u0026#34;: 2.383675143122673, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Helsinki\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;13696\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Helsinki\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 13.380153, \u0026#34;@search.rerankerScore\u0026#34;: 2.2026549801230431, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Rauma, Finland\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;178635\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Rauma, Finland\u0026#34; }, 考察 今回の英語のクエリではSemantic Rankerがある程度の役割をはたしていそうだということはわかりました。 Capitalがいくつもの意味を持っていることもあり、文章をもとにより意味の近いドキュメントが上位に来たということです。 ただ、英語の場合も基本的には上位50件以内のデータに対して処理が行われるので上位50件以内にデータが入らなければうまくいかないようです。\nまとめ Azure Cognitive Searchの新機能であるセマンティック検索について調べてみました。 まだPublic Previewですが、簡単に使えるような仕組み(データの再登録なし、クエリでパラメータを追加するだけ)が用意されているのは便利でした。 ただ、最初に想像していたもの(私の早とちりもありますが)ほどのセマンティック検索とは行きませんでした。 似たような言葉の意味を持ったものを探してくれたり、答えそのもののページのスコアがすごく高くなるといったものではありませんでした。\n仕組み上、クエリに含まれる単語で検索し、上位50件以内のデータだけが対象になる(残念ながら現時点ではこの件数の変更はできません。)ため、これまでの検索とは劇的に変化するものではないことはわかりました(銀の弾丸はないんですけどね)。\nある程度の挙動をわかっていれば、Wikipediaのようなデータでもそれなりの結果は取得できそうだということはわかりました。\n「言語モデル」でクエリとヒットしたデータをもとにスコア計算をし直しているようですが、この部分がどのようなデータ・クエリだと有効活用できるのか?というのをもう少しいろいろな角度で試してみる必要がある気がします(適材適所が何なのか?)。 あとは、上位50件までが対象なので、それ以上の件数のデータの並びに関してはこれまでと同様の結果となる点は注意しないといけません。 また、今回試していないほかの機能(スペルチェック、Semantic Answerなど)にメリットがあるのかもしれません。\nざっくりですがセマンティック検索について調べてみました。 こんなデータだとどうなの?ここの考え方が間違ってるのでは?などの指摘がありましたら、コメント欄またはTwitter(@johtani)でコメントを頂けたらと。\n","date":1625130583,"dir":"post/2021/","id":"43caef5d41c4e74826e4a8d82088739d","lang":"ja","lastmod":1625130583,"permalink":"https://blog.johtani.info/blog/2021/07/01/semantic-search-in-azure-cognitive-search/","publishdate":"2021-07-01T18:09:43+09:00","summary":"Azure Cognitive Searchで新機能「Semantic Search(セマンティック検索)」という機能の日本語対応が発表されました。 実際にはPublic P","tags":["azure search"],"title":"Azure Cognitive Searchの新機能、Semantic Searchを試してみた"},{"contents":"Sofle v2を長らく使っていましたが、コンパクトなのもやっぱりいいよなぁというときにKochi KeyboardからLunakey Miniが発売していました。 小指のあたりの傾斜が使いやすいかも?ということで、組み立ててみました。\nもちろん購入はKochi Keyboardさんからです(購入はこちらから)。\nLunakey Miniビルドガイド 作者のYoichiroさんが公開しているビルドガイドが詳細まで書かれています。 こちらをまずは参照してください。\nLunakey Mini ビルドガイド (Rev.4以降) ビルドログ(主にツイート) 私の組み立てについては、Twitterでツイートしていたものがありますので、そちらを貼っておきます。 ちなみに、ツイートしていて躓いているときに、作者のYoichiroさんからたびたびコメントをいただきました。 ありがとうございました!!\n間にいくつかコメントを差し込んでいます。\n結局両方のダイオードつけてしまいました。今日はここまで pic.twitter.com/3qLI6EpfXB\n\u0026mdash; Jun Ohtani (@johtani) April 12, 2021 ハンダはつけた pic.twitter.com/ySE9SA3gZn\n\u0026mdash; Jun Ohtani (@johtani) April 13, 2021 コンスルー問題 左手じゃん、T。Tのダイオード浮いてた。右手も一回全部見直すか\n\u0026mdash; Jun Ohtani (@johtani) April 13, 2021 ここで問題が発覚。右手(ツイートではぼけていて、左手と書いています)についてはダイオードが1か所浮いていただけなので、はんだ付けですぐ直りました。 左手側が大問題です。そもそも右手につけたProMicroへの書き込みができませんでした。 キーボードによっては、ダイオードなどを付ける前からまず、リセットボタンを付けて、ProMicroを指して書き込みをする場合もあります。 ただ、その書き込みができない。 (ちなみにこのタイミングでテスターをつけっぱなしにしていたのが発覚し、9V電池切れのため翌日に持ち越した。。。)\nさて、デバッグのお時間です pic.twitter.com/CaEOv4E5Bg\n\u0026mdash; Jun Ohtani (@johtani) April 14, 2021 ただ、ProMicro刺した状態で、リセットボタン、リセットボタンの足をショートさせても書き込みはできず、ProMicroのGndとResetの足のショートでは書き込みができる。\n\u0026mdash; Jun Ohtani (@johtani) April 14, 2021 テスターで調べてみたところ、リセットボタンとProMicroがうまく通電していません。\nだいぶ進んだけど、Eの列がおかしいなぁ。さて、どこの接触だ? pic.twitter.com/5tci12Vk05\n\u0026mdash; Jun Ohtani (@johtani) April 14, 2021 どうも、左手の基盤のProMicroの足の穴がコンスルーとの接触が悪いみたいでした。 コンスルーの足を無理やりまげて(3個のコンスルーの足を折りました。。。)、通電できるようにして解決(結局あとでいくつかの足についてははんだ付けしました)。\n終わった。LEDの予備はんだまでやってからおしまいにしよ\n\u0026mdash; Jun Ohtani (@johtani) April 16, 2021 LED実装 鬼門の表面実装ですが、LEDを1個破損するだけで乗り切りました。ちょっと色はおかしかったですが、これはおそらくProMicroの足のせい。\n一個逆につけてしまい、お亡くなりになりましたが、まぁ、良いかな。まずは右手 pic.twitter.com/zldu6fRsXR\n\u0026mdash; Jun Ohtani (@johtani) April 18, 2021 ソケットの実装x2 ロープロファイル(Kailh choc v1)のキースイッチも試してみたいので、MXと両方のソケットをはんだ付けしました。 両方利用できるのは便利ですね。はんだ付けも楽しいし。\nソケットを片手だけ(両方のソケットつけるのでまだ、1/4) pic.twitter.com/7XFRDx0D0I\n\u0026mdash; Jun Ohtani (@johtani) April 18, 2021 キースイッチ設置 親指以外にはKailh Box Silentのピンク軸(Kochi Keyboardから)、親指にはKailh Input Club Hako Violet(AliExpressで購入したもの。リンクは遊舎工房のもの)をつけました。 どちらもそれほどぶれもないものです。Silent ピンクはリニアで静かでそれほど力がいらないスイッチになっています。 親指はタクタイルで小気味のいい音が気に入っています。Sofleもこのキースイッチになってます。\n残りのソケットつけて、キースイッチも設置して、動確してボトムプレートも装着。残りはキーキャップ。 pic.twitter.com/hGc1TtI6fu\n\u0026mdash; Jun Ohtani (@johtani) April 25, 2021 キーキャップ+キーマップ お試しにXDAのキーキャップをはめてみたのですが、キーの境目がわかりにくく、タイプミスが多かったです。 その後のツイートにあるようにOEMに切り替えています。\nキーマップについては、Lunakey Miniの作者のYoichiroさんが作ったRemapというブラウザベースでキーマップの書き換えができるツールで楽々変更ができました。JISキーまで対応しているのでJISベースでキーマップを作成している私にはうってつけでした。 Remapの利用方法についてはサリチル酸さんのブログが詳しく書いてあります(本当に頭が下がります)。\nRemap使ってキーマップいじったら、すごく楽だった。\n\u0026mdash; Jun Ohtani (@johtani) April 26, 2021 BLE + LPME-IO化 ここまでで、USB接続で動作はしていたのですが、Sofle同様に3台をBluetoothで切り替えながら使いたかったので、 Corne Light v2につけていたBLE+LPME-IO(Corneの実装などは前のブログを参照)を抜き取って、Lunakey Miniに移植してみました。\nBLE ProMicro化は作者の方のブログで行われていたので、LPME-IO対応も何とかなるだろうと。\nBLE+LPMEに変えた。後でブログ書こう pic.twitter.com/mGePN52v6k\n\u0026mdash; Jun Ohtani (@johtani) April 29, 2021 LPME-IOへの対応はCorneとSofleの時に行なったこともあり、なんとなくあたりがついていました。 流れとしては、以下の通りです。\nBLE Micro Pro用の設定ファイルを作成 BLE Micro Proのサイトの「キーボードの設定ファイルを編集する」のコマンドでコンフィグファイルを生成 LPME-IOのジャンパをはんだでブリッジ 1.で生成したコンフィグから、Corne Lightと同じ個所のジャンプをすれば良いとわかったので今回はスキップ TRRSのI2C対応 Corne LightのLPME-IO対応の時と同様にSDAとSCLをTRRSの足にショートカット ただ、今回右手側は、下記ツイートのようにOLEDの足からTRRSの足にショートカットしました。Corneの基盤を見ていた時にこれでも行けそうだな?と思っていたので、試してみた次第です。ちなみに、左手はCorneの時と同じPro Microから長い銅線を引っ張っています(電池基盤があったので、外すのがめんどくさかったため)。 BLE Micro Proにファームウェア書き込み BLE Micro Proのサイトの手順に従います。 設定ファイルには1.で出力されているLPME用のファイルを使用。 といった感じです。キーマップが設定されていないので、Remapで設定しなおしました。 Remapは、キーマップをPDFで出力する機能までついていて、すごくいいですね。サイコー\nあと、足。 pic.twitter.com/W0Wpf5k5SE\n\u0026mdash; Jun Ohtani (@johtani) April 29, 2021 傾斜がつくように奥側に高さを出すためのゴム足を貼り付けました。 あとは、3台のPCにBluetoothで接続すれば終了です。 (AD_WO_Lのキーを利用して追加していくのを毎回忘れる。。。)\n疑問点 ちょっとだけ疑問点がありますが、時間があればそのうち調べるかな。\nRemapはクラウドに設定ファイルをセーブできるけど、json形式で手元にダウンロードしたりはできないのかなぁ? LEDは有線じゃないと点かないみたいだけど、音はどうなんだろう? 音が出せそうなら、Bluetoothの接続切り替えするときに音の出方を変えるとかをやってみたいなぁ。 まとめ ということで、Lunakey Miniを組み立てて、BLE+LPME-IO対応してみました。 はんだ付けはだいぶ慣れてきましたし、今回もトラブルがあったおかげでテスターを利用して、どのあたりがおかしいかという調査をするのも慣れてきました。 あとは、キーの配置の違いを体感して、どれが自分に合ってるかなぁ?というのを試したり仕様と思います。 ロープロファイルも試してみようかな。\nあ。もちろん、このブログは組み立ててBluetoothで接続したLunakey Mini Rev5、Kailh Box Silentピンク軸+Input Club Hako Violetで書きました!!久々に数字列がないので記号入力とかがちょっとバタバタしましたw\n","date":1619709972,"dir":"post/2021/","id":"f4baa43cc7ca712d83b99a794c4e2dbd","lang":"ja","lastmod":1619709972,"permalink":"https://blog.johtani.info/blog/2021/04/30/build-lunakey-mini-ble/","publishdate":"2021-04-30T00:26:12+09:00","summary":"Sofle v2を長らく使っていましたが、コンパクトなのもやっぱりいいよなぁというときにKochi KeyboardからLunakey Miniが発売して","tags":["DIYキーボード","misc"],"title":"Lunakey Miniを組み立てて、BLE+LPME-IO化してみた #DIYキーボード"},{"contents":"みなさんは、スライドの作成には何を使っていますか? Keynote?Powerpoint?Google Slides?\n私は、Macでスライドを作るときは前職ではテンプレートもあったのでKeynoteでしたが、ちょっとしたものはMarkdownベースのDecksetを利用していました(買い切りタイプの有料ソフト)。\nフリーランスになってもこちらを利用していたのですが、Windows環境に切り替えたので使えなくなってしまいました。 一度はGoogle Slidesで作ったのですが(第39回Es勉強会スライド)、既存の資産を流用したくなりどうしたものかと悩んでい(ツイートし)たら。\nMacの頃はDecksetってアプリでMarkdownで書いてたんだけど、Winに移動したのでこのタイミングでGoogle Slidesにでもしようかなと考えてるところ。Markdownでスライド作るのほかになんかあるか探すほうがいいかなぁ?\n\u0026mdash; Jun Ohtani (@johtani) March 18, 2021 僕はこれ使ってますhttps://t.co/sFaAmKZY6V\n\u0026mdash; miyake | ZEN (@kazuyukimiyake) March 18, 2021 ということで、利用してみようかなとなりました。\nMarpとは? Markdownでプレゼンテーションのスライドを作ることができるOSS?になります。\nMarp公式サイト といっても、これ自体を使わなくても、VS Code上でプレビューしたりHTML形式で動作するスライドを吐き出すことが可能です。 なので、VS Code用のプラグインを利用しています。\nサンプル この間利用したスライドはこんな感じのMarkdownになってます。 ---でページを区切りつつ、記述していく形です。\n--- marp: true theme: poster --- \u0026lt;!-- _class: big-center --\u0026gt; # 本当にその検索は\u0026lt;br/\u0026gt;自分が想像している検索に\u0026lt;br/\u0026gt;なってますか? \u0026lt;br/\u0026gt; \u0026lt;br/\u0026gt; \u0026gt; 2021/03 \u0026gt; Jun Ohtani / @johtani --- ![bg right:40% 40%](johtani_face.jpg) # 自己紹介 - フリーランスエンジニア - 検索技術勉強会主催者 - Apache Solr入門(第2版まで)や データ分析基盤構築入門の著者の一人 --- プレビューで見るとこんな感じです。\nプラグイン Marp for VS Code プラグインをインストールするのも簡単ですよね。 マーケットプレイスからインストールすれば完了です。\n機能については上記のページにあるように、プレビューとスライドの出力です。 プレビューでは、Markdownのプレビューみたいな形で、スライドが表示できます。\n先日この機能を利用して作成して、HTMLで出力して利用しました。 PDFとかPPTX出も出せるようなので、今後試してみようかなと。\nDecksetのスライドとの違い ページの区切りなども同じだったので、大筋ではそれほど違いはありませんでした。 ただ、画像周りとスタイルの設定は細かく修正をしました。\n変更した点としては、以下のようなものがあります。\nヘッダ部分の変更 上のサンプルにありますが、marp: trueを含む部分がMarp独自の記述です。 ページごとのちょっとした変更 ページごとにスタイルの変更ができるみたいで(Decksetではできなかったはず?)、タイトルページのスタイルを変えてあります。 画像の指定 画像の読み込み自体は違いはないのですが、画像の配置についての指定方法は カスタムテーマ用CSSの作成 デフォルトではなく、Decksetで用意されているような感じのスタイルに変更してみてます。 カスタムテーマはCSSで設定できるので、CSSファイルを用意して、VS Codeの拡張機能の設定からファイルパスを指定する形です。\nということで、当面はMarpでスライドを作っていくことになるかと思います。 まぁ、ただ、スライドを作るいこと自体が減ってきてはいるのですが。 ほかの配色を試したり、ヘッダフッタとかも試してみるのもいいかもな。\n気が向いたら、CSSをどこかにアップロードするかもです。\n※今回のブログはGateronサイレントクリア軸をルブしてみた、Corne Light v2で最後の数行を書いてみました。 キースイッチだけだとこすれる音が減った気がしてましたが、キーキャップを付けたら少しこすれる音が気になる感じです。\n","date":1617615911,"dir":"post/2021/","id":"f41d4fde94cbd7bbd28808dc080a2019","lang":"ja","lastmod":1617615911,"permalink":"https://blog.johtani.info/blog/2021/04/05/intro-marp/","publishdate":"2021-04-05T18:45:11+09:00","summary":"みなさんは、スライドの作成には何を使っていますか? Keynote?Powerpoint?Google Slides? 私は、Macでスライドを作","tags":["勉強会"],"title":"スライド作成の環境をMarpにしてみた"},{"contents":"新型コロナウィルスの影響もあり、オフラインで集まって勉強会も開催できなくなっています。 検索技術勉強会も、もう1年以上開催できていないです。\nスピーカーの人にオンラインでしゃべってもらうのもありだとは思うのですが、 懇親会とセットでその価値があったかもなぁと思うところもあり、オンラインでの開催に乗り気になれないまま時間がたってしまいました。 (配信周りを調べるのがめんどくさいなぁというのもあったかも(反省))\nそんな中、takuya-aさんと話をしていて、エンジニア同士のゆるいつながりができる場所が欲しいですねぇということに。\nはー、検索技術勉強会、オフラインでできないまま1年以上たってしまったのか。オンライン勉強会とかはスピーカーの人の負担とかもあるし、Discordみたいなオープンな場だけ用意してみるのありかなぁ?ただ、活発に話がされるのかどうかわからんし、ROMな人ばかりだとアレなんだけどなぁ。\n\u0026mdash; Jun Ohtani (@johtani) March 30, 2021 そこからの、このツイートです。 ちらほらと興味のありそうな人が出てきたねという話をしていたら、Slackのワークスペースが出来上がってましたw\n検索技術に関する情報交換を目的とした Slack を立ち上げました!こちらの招待リンクからご参加ください。 https://t.co/Tca70vuMff\n\u0026mdash; takuya-a (@takuya_b) March 31, 2021 ありがとう、takuya-aさん!\nということで、検索周りでわいわいできる場になればいいなぁと。 盛り上がってくれば、オンラインでの勉強会とかもありかもしれないですね! 興味のある方は、上記ツイート内のリンクからご参加下さい!!\n","date":1617200894,"dir":"post/2021/","id":"ce426b7f3190c8a4a47d45ac799e91a4","lang":"ja","lastmod":1617200894,"permalink":"https://blog.johtani.info/blog/2021/03/31/search-tech-jp-slack/","publishdate":"2021-03-31T23:28:14+09:00","summary":"新型コロナウィルスの影響もあり、オフラインで集まって勉強会も開催できなくなっています。 検索技術勉強会も、もう1年以上開催できていないです。 ス","tags":["勉強会"],"title":"検索技術に関する情報交換を目的としたSlackができました!"},{"contents":"Azure Cognitive SearchにはOData式という書式で条件が書ける仕組みがあります。 ODataは検索条件($filter)やソート条件($orderby)、取得する項目名の指定($select)です。\n私は、Luceneの構文に慣れているので、普通のsearchパラメータを利用しようとします。 が、OData式として特殊な書き方がいくつかあるようなのでこちらの利用方法も調べてみました。 その時、N-Gram(よくやるのはN=2)で陥る問題の話もあるのでこちらについても言及します。\nOData式で検索 次のような3件のドキュメント(フィールド名はbodyとします)をN-Gramで登録していたとします。\nミルクティを飲みたいです。 マティーニはカクテルですが、ミルクセーキは? 風呂上がりのミルクは最高です。 この時、OData式でミルクティという単語で検索してみましょう。\n検索条件は$filterで指定します。 フルテキスト検索用に関数が用意されており、こちらに単語を指定します。\n$filter=search.ismatchscoring(\u0026#39;ミルクティ\u0026#39;) こんな感じ。フィールドの指定がない場合、対象のフィールドは検索可能なフィールドすべてが検索対象になります(公式ガイドのクエリパラメータのqueryTypeに説明あり)。\nでは、実行してみましょう。で返ってくるのは?1だけかな?と思う人が多いかもしれません。 が、結果は3件とも帰ってきます。\n問題点は? では問題点はどこでしょう? ismatchscoringのオプションなどを見る前に、転置インデックスを用いた検索エンジンの挙動をおさらいしましょう。 転置インデックスの仕組みを理解することで、なぜそんな挙動になるのか?というのがわかりやすくなります。 おさらいにはElasticsearchをベースに話をしますが、Azure Cognitive Searchでも同じような挙動になります。\n転置インデックスとトークナイザー(アナライザー)の関係(おさらい) 昨年、オンラインで開催されたOSC広島で発表した資料(録画あり)でもざっくりと説明しています。\nView 本当にその検索は自分が想像している検索になってますか? on Notist.\nざっくりですが、おさらいです。\n検索エンジンでは、入力された文章を、ある規則(アナライザー)で単語に分割し、その単語ごとにどのドキュメントに出現したのか?というリストが作られます。 このリストが転置インデックスです。書籍の後ろにある索引を想像するとどんなものかがわかりやすいです。 単語に対してその単語が出てくるページ番号がわかるという仕組みです(下図は本の索引の一例)。\n書籍の索引は著者や編集の方により厳選された単語のみが採用されています。 が、検索エンジンでは文章を単語に区切る機能が存在します。 この「ある規則」で単語を区切る仕組みが「アナライザー(トークナイザー)」と呼ばれる機能です。 例えば英語用のアナライザーに英語の文章が入力されたとき、文章はこのように単語に区切られたもの(単語列)を出力します(下図)。\n今回はNGramの話なので、NGramのAnalyzerを利用してみるとこんな感じになります。\n実際に出来上がる転置インデックスは次のような形になります。 検索の仕組み(おさらい) 出来上がっている転置インデックスに対して検索をする場合、入力文字列(検索条件)に対して、転置インデックス作成時と同様にAnalyzerが動作します。 処理としては、\nクエリのパース フィールドのAnalyzerで処理 転置インデックスを検索 という形です。 例えばこんな感じ。\n同じAnalyzerの処理が入ることで、転置インデックスに採用されているのと同じ単語が出てくるため、検索がきちんとできるということになります。\n英語と日本語(NGram)の違い 英語と日本語の違いは、スペースの意味になります。 英語の場合は、スペースが単語の区切りになりますが、日本語の場合スペースでは区切られていません。\nですので、検索窓に入力された文字列は、英語の場合、クエリのパースの時点で単語に区切られます。そのあとにAnalyzerになるので、基本的には単語単位でAnalyzerの処理が動きます。そのあと、転置インデックスへの検索となります。なので、多くの場合はAnalyzerの出力は1単語です(類義語などを利用していたりする場合は異なりますが)。\n日本語の場合、スペースでは区切られていないので、クエリのパースの時点で入力された文字列がそのままAnalyzerにわたります。 今回はAnalyzer(NGram)が単語に分割し、それをもとに検索処理が実行されます。\nismatchscoringの問題点は?(やっと帰ってきました) さて、回り道をし、簡単ですが転置インデックスやAnalyzerについて説明しました。 では本題です。\n$filter=search.ismatchscoring(\u0026#39;ミルクティ\u0026#39;) このismatchscoring関数ですが、そのほかにも引数の指定が可能で、省略した場合にデフォルトで採用される値がいくつかあります。 公式のドキュメントにパラメータの意味が掲載されています。\n今回は、第4引数のsearchModeの値が問題点です。デフォルトでは、anyが指定されます。 この、anyは検索語(今回はミルクティ)の任意の検索語句が一致する必要があることになります。 「検索語句」?なんでしょう?これが、ここまで回り道をして説明してきた、Analyzerの出力した単語になります。 「ミルクティ」はNGram(N=2)のAnalyzerを通すと、\n「ミル」「ルク」「クテ」「ティ」\nという4つの単語が出力されます。 これが、「検索語句」です。「任意の」とあるので、上記4つの2文字のどれか?が出現すれば検索条件にヒットしたこととなります。\nですので、以下のように(一部のみ色を変えてます)3つの文章にはそれぞれの文字が含まれているため、先ほどの条件では3件の結果が返ってくることになります。\nミルクティを飲みたいです。 マティーニはカクテルですが、ミルクセーキは? 風呂上がりのミルクは最高です。 NGramで一部分の単語だけで一致したものがヒットしてしまうと違和感があるので、allに変更します。\n$filter=search.ismatchscoring(\u0026#39;ミルクティ\u0026#39;, \u0026#39;body\u0026#39;, \u0026#39;simple\u0026#39;, \u0026#39;all\u0026#39;) 今度はどうなるでしょう?\nミルクティを飲みたいです。 マティーニはカクテルですが、ミルクセーキは? 先ほどよりもマシになりました。 3がヒットしなくなっています。3の文章には「ティ」などが出てこないためです。 ただ、感覚的に2番目がヒットするのは少し違和感がありますよね? 確かに4つの単語がすべて出てきていますが、「ミルクティ」とは少し遠いです。\nさらに「ミルクティ」にヒットさせるにはフレーズ検索にする必要があります。 Elastic社のブログの日本語の検索に関する記事でも出てきますが、フレーズで検索することで「ミルクティ」だけにヒットさせることができます。\n「フレーズ検索=語順を保証する検索」となります。 ですので、\n「ミル」「ルク」「クテ」「ティ」\nこの順序で出てきた場合のみ、検索にヒットしたことになります。 OData式でフレーズ検索する場合は、単語をダブルクォート\u0026quot;でくくる必要があります(公式ドキュメントの例に記載あり)。\n$filter=search.ismatchscoring(\u0026#39;\u0026#34;ミルクティ\u0026#34;\u0026#39;, \u0026#39;body\u0026#39;, \u0026#39;simple\u0026#39;, \u0026#39;all\u0026#39;) これで結果は以下の1件だけとなります。\nミルクティを飲みたいです。 これでNGramで部分一致のような挙動で日本語の検索ができるようになりました。\nちなみに、フレーズにした場合は第4引数はanyに変更しても1件だけの検索結果となります。 フレーズ検索には「すべての語が含まれる」、「すべての語が順番に現れる」という2つの条件が含まれるためです。\n$filter=search.ismatchscoring(\u0026#39;\u0026#34;ミルクティ\u0026#34;\u0026#39;, \u0026#39;body\u0026#39;, \u0026#39;simple\u0026#39;, \u0026#39;any\u0026#39;) この例の引数をミルクティを\u0026quot;ミルク\u0026quot; \u0026quot;最高\u0026quot;のような検索条件に変えた場合、「\u0026ldquo;ミルク\u0026rdquo;」「\u0026ldquo;最高\u0026rdquo;」の2つの条件をanyで扱うため、 「\u0026ldquo;ミルク\u0026rdquo;」「\u0026ldquo;最高\u0026rdquo;」のどちらかが出てくれば良い結果となり、3件の結果が返ってきます。 第4引数をallに変更すると、「\u0026ldquo;ミルク\u0026rdquo;」「\u0026ldquo;最高\u0026rdquo;」の両方が出てこなければならないため、3件目のデータのみが返ってきます。\n$filter=search.ismatchscoring(\u0026#39;\u0026#34;ミルクティ\u0026#34; \u0026#34;最高\u0026#34;\u0026#39;, \u0026#39;body\u0026#39;, \u0026#39;simple\u0026#39;, \u0026#39;all\u0026#39;) これは、\n$filter=search.ismatchscoring(\u0026#39;\u0026#34;ミルクティ\u0026#34;\u0026#39;, \u0026#39;body\u0026#39;, \u0026#39;simple\u0026#39;, \u0026#39;any\u0026#39;) and search.ismatchscoring(\u0026#39;\u0026#34;最高\u0026#34;\u0026#39;, \u0026#39;body\u0026#39;, \u0026#39;simple\u0026#39;, \u0026#39;any\u0026#39;) と同じ意味となります。 少し長くはなりますが、後者の書き方をプログラムで書くと思います、私の場合は。 検索窓に入力された単語に必ず\u0026quot;を追加する処理を書くために、画面入力の文字列を一旦パースをすることになるからです。\nまとめ 簡単?にですが、OData式でのフルテキスト検索と、NGramでのフレーズ検索について説明しました。 英語の場合、もともとスペースで区切られているので、フレーズといわれてピンときますが、日本語の場合はAnalyzerの挙動をわかっていないと「?」となるかと思います。 なぜフレーズ検索が必要なのか?というのが少しでもわかっていただければと。 ちなみに、NGramのTokenizerには別の落とし穴もありますが、その話はまた後日にでも。\n参考として日本語関連の検索に関する記事のリンクを残しておきます。\n参考 Elasticsearch日本語でフレーズ検索が必要なわけ NGramも含め、Elasticsearchでの日本語の検索の設定やクエリについては、Elastic社のブログで日本語で書かれた記事が詳しいのでこちらをご覧いただくのがいいです。 ","date":1614756213,"dir":"post/2021/","id":"eced95e5f301a8340e83d81d3c0d5c0d","lang":"ja","lastmod":1614756213,"permalink":"https://blog.johtani.info/blog/2021/03/03/phrase-query-in-japanese/","publishdate":"2021-03-03T16:23:33+09:00","summary":"Azure Cognitive SearchにはOData式という書式で条件が書ける仕組みがあります。 ODataは検索条件($filter)やソート条件($orderb","tags":["azure search","elasticsearch"],"title":"OData式と日本語の検索(NGram)とフレーズ検索"},{"contents":"自宅の環境がいろいろと変わったのですが、書いていなかったので更新版です。 前回のブログ(2020/09)、前々回のブログ(2020/03)はそれぞれリンクをたどってください。\n現状のデスクトップはこんな感じ\nPC 別のブログにまとめましたが、Windowsメインに切り替えました。 ハードの話以外に、Windows OSに切り替えたときにいくつか入れたものもあります。 それは、移行のブログに少しだけ書いてあります。\nひさびさにWindowsに戻ってきていますが、だいぶ慣れました。 まぁ、それほど大したことをやってないというのもあるかもですが。。。\nメインPC以外にこれまでのmacをブラウジング用にサブディスプレイにつなぎ、マウスをLogicool Flowで行き来できるようにし、 キーボードはKVMスイッチで切り替えてやりくりしていました(最新環境はキーボードのところを参照してください)。\nAmazon | サンワダイレクト USB切替器 キーボード・マウス用 KVMスイッチ キーボード いくつかDIYしましたが、今はメインでSofle Keyboard v2を利用しています(Kochi Keyboardさんで購入できます)\nSofle keyboard v2を有線で使っていましたが、最近Bluetooth対応して無線化しました(その時のブログはこちら)。 ですので、PCとの接続の切り替えはキーボード上で特定のキーの組み合わせを押すことで、切り替えられるようになっています。 KVMとは異なり、Bluetoothの接続が切り替わるのにタイムラグがある+どこにつながっているのか?というのがわからないので、想定していないところでキーが入力されていることがあります。 これは、何とかしたいかもなぁと考えてはいるところ。\nマイク&オーディオインターフェース 基本的に自宅でリモート作業をしています(ありがとうございます)。 なので、ミーティングもオンラインです。 となるとやはり、音がいいほうがお客さんにも喜ばれるかなぁと。 2020年3月時点ではSAMSONのGoMicを利用していました。 これもいい音なのですが、大きいマイクでもいいかなと。 あとは、ほかの使い道もあるかも?ということで、オーディオテクニカのマイク(+ポップガード)とフォーカスライトのオーディオインターフェースに変えてみました。 自分は実感ないですが、きっと役に立っていると思いますw\nAmazon | audio-technica サイドアドレス コンデンサーマイクロホン AT2050 | コンデンサ | 楽器 Amazon | AUDIO-TECHNICA AT-PF2 ポップフィルター | マイクアクセサリ | 楽器 Amazon | Focusrite フォーカスライト オーディオインターフェイス 2イン/2アウト 24bit/192kHz Scarlett Solo (3rd Gen) ステッカー付きセット 【国内正規品】 | 楽器・音響機器 | 楽器 ディスプレイ 以前は、MacBookProの16インチで、メインディスプレイの下に2枚目のディスプレイも兼ねて開いて利用していました(前回のブログ参照)。 自作PCに切り替えたので、ディスプレイがなくなってしまうので、同じような大きさのモバイルモニターを利用しています。 今のところは据え置きになっていますが、持ち運べるので、ほかの部屋や外出時にも使えるんではないかなと。 ディスプレイの足などはないので、邪魔にもならず便利ですね。\nAmazon | モバイルモニター モバイルディスプレイ 4K 15.6インチ cocoparスイッチ用モニター 非光沢IPSパネル 薄い 軽量HDRモード/FreeSync対応/ブルーライト機能 3840x2160 UHD/USB Type-C/標準HDMI/mini DP/カバー付3年保証付 | cocopar | ディスプレイ 通販 音楽再生環境 サブディスプレイにサンダーボルトディスプレイを使用していたので、Mac Miniを接続していましたがサンダーボルトディスプレイには退役してもらいました。 それに伴って、Mac Miniも別の場所に移動しました。音楽再生環境にラズパイ4を復活させました。 以前購入したセットについていたケースではファンの音が気になっていたので、ヒートシンク型に変えました。 結構重いですが、冷えてそうです。\nAmazon | Geekworm Raspberry Pi(ラズベリーパイ) 4 B 用アーマー金属ケース パッシブ冷却/シェル熱放散 ラズベリーパイ4 コンピュ ータモデルB適用 (アーマーケース(ファン無し)) | Geekworm | 冷却パーツ・ファン 通販 Webカメラ カメラ自体に変更はないですが、付属品をいくつか。 Webカメラではないカメラもつけてみたいなと思い、モニターアームにカメラを付けられるものを付けてみました。 ただ、おっさんの顔をきれいに映してもなぁという結論に至ったので、Webカメラが乗っかっています。。。 あとは、デスクトップPCになり、カメラのケーブルだけではPCまで届かなくなってしまったのでUSB Type-Cの延長コードを買ってみました。実はこれ2本目ですが。。。 スタンディングデスクの昇降でケーブルに負荷がかかってしまったことがなんどかあり、1本目の延長コードは接触が悪くなってしまいました。。。時々外したりしていて、ケーブルの配置がおかしいときがあるので、気を付けるようにしています。\nAmazon | 長尾製作所 モニターアーム用 VESA カメラ&マイクマウント NB-MV001MH | 長尾製作所 | モニタアーム\u0026amp;スタンド 通販 Amazon | iVANKY USB Type C 延長ケーブル USB 3.1 Gen 2(4K@60Hz/1.0m/オス-メス)10Gbps高速データ転送 3A急速充電 usb-c 変換 Huawei MateBook13, iPad Pro11, Nintendo Switch, MacBook等対応 | IVANKY | USBケーブル 通販 照明 裸の蛍光管だったのですが、リモコンで点灯したり、照度を変えられるようにしたかったので、 パナソニックの照明に変えました。\nAmazon | パナソニック LEDシーリングライト 調光・調色タイプ リモコン付 6畳 3, 699lm HH-CD0620AZ 【Amazon.co.jp限定】 | パナソニック(Panasonic) | ホーム&キッチン 変えたのはよかったのですが、部屋が長細い+Webカメラの位置(自分から見て左にカメラを置いて、部屋の奥への画角?になっている)のせいで、右半分の顔が暗くなる場合がありました。 幸い、右にはスチールラックが組んであるので、そこにつけられる照明を購入して女優ライトみたいな感じで使っています(頻繁ではないですが)\nAmazon|ルミナス メタルラック用 LEDライト 磁石で簡単設置 連結可能 幅60cm 昼白色 LED60R-N|メタルラックパーツ オンライン通販 フットレスト 昨年3月くらいに配置して、座っているときに足を置くのに便利に使っていました。 が、1台だと幅が足りないので最近2つ目を購入して並べて使っています。 片足ずつ載せられるのは便利ですね(基本ガニ股なので。。。)。\nAmazon | サンワダイレクト フットレスト スチール製 角度10° 幅40×奥行30cm 足置き台 100-FR011 | フットレスト | 文房具・オフィス用品 ということで、最近はこんな環境で仕事をしています。 当分これで更新しないんじゃないかなぁ。 (サブディスプレイが左に寄っているので、局面ディスプレイが気になっているところですが。。。)\n","date":1614246182,"dir":"post/2021/","id":"fcb0105fa6b5777a133f247784b9d930","lang":"ja","lastmod":1614246182,"permalink":"https://blog.johtani.info/blog/2021/02/25/update-working-facility/","publishdate":"2021-02-25T18:43:02+09:00","summary":"自宅の環境がいろいろと変わったのですが、書いていなかったので更新版です。 前回のブログ(2020/09)、前々回のブログ(2020/03)はそ","tags":["misc"],"title":"自宅の作業環境(2021/02)"},{"contents":"Azure Cognitive SearchにSuggestやAutocompleteの機能があるのを見つけたので、どんな挙動なのかを調べてログとして残しておきます。\n公式ドキュメント 日本語で公式ドキュメントが公開されています。使い方や流れについてはこちらをまずは見れば使えると思います。\n本ブログでは、ざっくりとした機能の紹介と内部がどんな挙動をしていそうか?、日本語だとどういう感じになるのか?という点を紹介しようと思います。\nどんな機能? 検索窓でよく、キーワードを入力しているときに検索キーワードの候補が表示されることがあります。 このキーワードの候補を表示するための機能が今回紹介するSuggesterと呼ばれる機能です(日本語の公式ドキュメントでは「先行入力エクスペリエンス」)。 Suggesterには、以下の2つの機能が用意されています。\nAutocomplete:キー入力しているときに、入力されている文字列で始まる単語で、検索できるもの(転置インデックスに登録されている単語)をリストで返す機能 Suggestion:入力した文字列で始まるキーワードを含む、元のデータを返す機能 利用方法 Suggesterの機能を利用するにはインデックスに設定を追加する必要があります(新規、既存どちらでも可)。 ただ、既存のインデックスに設定を追加した場合、内部にすでに存在するドキュメント(データ)については、このSuggesterのデータは作られません。 ですので、既存データを再度登録しなおすといった作業が必要となるので注意が必要です。\n本ブログでは、いくつかAzure Cognitive Searchのサンプルのリクエストが出てきます。Visual Studio CodeのREST Client Extensionの書式となります。拡張機能の簡単な紹介は昨年のブログをご覧ください。\n設定編 Suggesterの設定では、主に以下の2つを設定する必要があります。\nname: suggesterの名称。クエリ時に指定します。 sourceFields: 入力データのもととなるフィールド名。 String型のみ指定可能。また、Azureで用意されたアナライザーだけが利用可能です。自分で用意するカスタムアナライザーは利用できないので注意が必要です(制限についてはこちら)。 今回使用するサンプルのインデックス設定は次の通りです。\nインデックス作成のリクエスト(@host、@api-keyはご自身のものに置き換えてください。)\n## 設定 @host = 名前.search.windows.netと記載 @api-key = APIキーを入力 ### Create index with suggester POST https://{{host}}/indexes/?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;name\u0026#34;:\u0026#34;suggester-test\u0026#34;, \u0026#34;fields\u0026#34;:[ { \u0026#34;name\u0026#34;:\u0026#34;id\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;Edm.String\u0026#34;, \u0026#34;key\u0026#34;:true, \u0026#34;searchable\u0026#34;:false }, { \u0026#34;name\u0026#34;:\u0026#34;name\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;Edm.String\u0026#34;, \u0026#34;searchable\u0026#34;:true, \u0026#34;analyzer\u0026#34;:\u0026#34;ngram_analyzer\u0026#34; }, { \u0026#34;name\u0026#34;:\u0026#34;category\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;Edm.String\u0026#34;, \u0026#34;filterable\u0026#34;:true, \u0026#34;facetable\u0026#34;: true } ], \u0026#34;suggesters\u0026#34;: [ { \u0026#34;name\u0026#34;: \u0026#34;name_suggester\u0026#34;, \u0026#34;searchMode\u0026#34;: \u0026#34;analyzingInfixMatching\u0026#34;, \u0026#34;sourceFields\u0026#34;: [ \u0026#34;name\u0026#34; ] } ] } 公式ドキュメントのサンプルでは日本語がないので、日本語のデータも入力しています。\nデータ登録リクエスト\n### Index data POST https://{{host}}/indexes/suggester-test/docs/index?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;value\u0026#34;: [ { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Microsoft Office\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;microsoft\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;2\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Microsoft Azure\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;microsoft\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;3\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;GitHub Enterprise\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;github\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;4\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;GitHub dot com\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;github\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;5\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Bluetooth Mic\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;hardware\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;6\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;東京スカイツリー\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;japanese\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;7\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;東京タワー\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;japanese\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;8\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;東京特許許可局\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;japanese\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;9\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;グランメゾン東京\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;japanese\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;10\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;東京都庁\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;japanese\u0026#34; } ] } 以上が事前準備です。データ登録時に内部でSuggester用のデータを内部で生成しているようです(公式ドキュメント)。\nクエリ編 最初に説明しましたが、Suggesterの中ではAutocompleteとSuggestionという2種類の機能が用意されています。それぞれについて例をもとに説明していきます。\nAutocomplete API 検索窓に入力された文字を元に、前方一致でどのような単語で検索できるか?という候補を表示するための機能です(2単語も対応していますが今回は省略。APIの仕様はこちら)。\nたとえば、micという文字が入力されているところでAutocomplete APIを呼び出す時は、次のようなリクエストです。searchというパラメータに入力値を与えます。suggesterNameはインデックス作成時につけた名前になります。\nPOST https://{{host}}/indexes/suggester-test/docs/autocomplete?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#34;mic\u0026#34;, \u0026#34;suggesterName\u0026#34;: \u0026#34;name_suggester\u0026#34; } レスポンスとして、次のようなJSONが返ってきます。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;value\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;microsoft\u0026#34;, \u0026#34;queryPlusText\u0026#34;: \u0026#34;microsoft\u0026#34; }, { \u0026#34;text\u0026#34;: \u0026#34;mic\u0026#34;, \u0026#34;queryPlusText\u0026#34;: \u0026#34;mic\u0026#34; } ] } サンプルデータとして登録したデータにcategoryというフィールドを入れていました。 Autocompleteは条件を絞り込んで結果を返すこともできます。 filterにODataの書式で条件を書けます。 categoryフィールドにmicrosoftが設定されているデータだけを取得するということができます。\n### Autocomplete with filter POST https://{{host}}/indexes/suggester-test/docs/autocomplete?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#34;mic\u0026#34;, \u0026#34;suggesterName\u0026#34;: \u0026#34;name_suggester\u0026#34;, \u0026#34;filter\u0026#34;: \u0026#34;category eq \u0026#39;microsoft\u0026#39;\u0026#34; } レスポンスはこちら。先ほどとは違い、micというデータは返ってきていません。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;value\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;microsoft\u0026#34;, \u0026#34;queryPlusText\u0026#34;: \u0026#34;microsoft\u0026#34; } ] } 英語の場合、「単語」の単位は字面の通りです。スペースで単語が区切られているのでわかりやすいです。 日本語の場合は普通の人には少し想像しにくいです。 東京という文字を入力してみます。\n### Autocomplete in Japanese POST https://{{host}}/indexes/suggester-test/docs/autocomplete?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#34;東京\u0026#34;, \u0026#34;suggesterName\u0026#34;: \u0026#34;name_suggester\u0026#34; } すると返ってくるのは以下の通り「東京」だけになります。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;value\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;東京\u0026#34;, \u0026#34;queryPlusText\u0026#34;: \u0026#34;東京\u0026#34; } ] } 入っているデータは「東京スカイツリー」、「東京タワー」などです。 普通に考えると、これらがそのまま返ってくると思うかもしれませんが、違います。\nこれは、Suggesterの元となるフィールドのAnalyzerの挙動によります。 今回のインデックスのnameフィールドのanalyzerにはja.luceneです。これは、日本語用のアナライザー(Kuromoji)になります。いわゆる形態素解析器で日本語の文字列を「単語」に分割します。 英語についてはスペース区切りで分割しますが、日本語についてはKuromojiが内部の辞書とアルゴリズムに基づいて単語に分割してくれます。 Azure Cognitive Searchでは、Analyzerの挙動を確認するためのAPIも用意してあるので実行しみると、\n### Autocomplete in Japanese POST https://{{host}}/indexes/suggester-test/analyze?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;text\u0026#34;: \u0026#34;東京スカイツリー\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;ja.lucene\u0026#34; } このような結果が返ってきます。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;東京\u0026#34;, \u0026#34;startOffset\u0026#34;: 0, \u0026#34;endOffset\u0026#34;: 2, \u0026#34;position\u0026#34;: 0 }, { \u0026#34;token\u0026#34;: \u0026#34;スカイ\u0026#34;, \u0026#34;startOffset\u0026#34;: 2, \u0026#34;endOffset\u0026#34;: 5, \u0026#34;position\u0026#34;: 1 }, { \u0026#34;token\u0026#34;: \u0026#34;ツリー\u0026#34;, \u0026#34;startOffset\u0026#34;: 5, \u0026#34;endOffset\u0026#34;: 8, \u0026#34;position\u0026#34;: 2 } ] } ja.luceneのAnalyzerによって、3つの単語に分割されているのがわかります。 Autocomplete APIの実行結果も、このAnalyzerによって分割された単語をもとに、候補となる単語を前方一致で検索して結果を返しているのです。 ですので、「東」と入れても「東京」が返ってくるのがわかります。 一方で、「東京ス」と入力した場合は次のような結果となります。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;value\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;スカイ\u0026#34;, \u0026#34;queryPlusText\u0026#34;: \u0026#34;東京スカイ\u0026#34; } ] } これは、autocompleteModeと呼ばれるパラメータの挙動となります。 デフォルトでは、oneTermという設定で、最後の単語(例の「東京ス」の場合は「東京」「ス」と区切られるので「ス」という文字を単語とみなす)にマッチする単語(例では「スカイ」)が返ってきます。 queryPlusTextについては、入力された文字にtextで返ってきた単語をくっつけたものが取得できます。\n英語であれば、スペースで区切られており、単語が切れているのが簡単にイメージできますが、日本語の場合は少し違和感が出るかと。\nこのように、入力された文字が含まれる「単語」を基本的に返す動作をするのがAutocomplete APIです。\nSuggest API では、もうひとつのSuggest APIはどういったものでしょうか? autocomplete APIに似ていますが、返ってくるデータが登録されたデータそのものになります。\nたとえば、micという文字列を入力とした場合、\nPOST https://{{host}}/indexes/suggester-test/docs/suggest?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#34;mic\u0026#34;, \u0026#34;suggesterName\u0026#34;: \u0026#34;name_suggester\u0026#34; } 次のような結果が返ってきます。Autocompleteの時は単語でしたが、こちらは入力データがそのまま返ってきています。 入力データの中にmicで始まる単語が含まれたものが候補となっています。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.text\u0026#34;: \u0026#34;Bluetooth Mic\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;5\u0026#34; }, { \u0026#34;@search.text\u0026#34;: \u0026#34;Microsoft Office\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;1\u0026#34; }, { \u0026#34;@search.text\u0026#34;: \u0026#34;Microsoft Azure\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;2\u0026#34; } ] } 日本語の場合、Autocompleteとは異なり、その単語を含むものがサジェストされるので、「東京」をsearchに指定すると「東京」を含むデータが出てきます。\n### Suggest in Japanese POST https://{{host}}/indexes/suggester-test/docs/suggest?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#34;東京\u0026#34;, \u0026#34;suggesterName\u0026#34;: \u0026#34;name_suggester\u0026#34; } レスポンスはこちら。単語を含む元の文字列が返ってきます。ここまでは違和感はありません。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.text\u0026#34;: \u0026#34;東京タワー\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;7\u0026#34; }, { \u0026#34;@search.text\u0026#34;: \u0026#34;グランメゾン東京\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;9\u0026#34; }, { \u0026#34;@search.text\u0026#34;: \u0026#34;東京都庁\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;10\u0026#34; }, { \u0026#34;@search.text\u0026#34;: \u0026#34;東京スカイツリー\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;6\u0026#34; }, { \u0026#34;@search.text\u0026#34;: \u0026#34;東京特許許可局\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;8\u0026#34; } ] } では、「東京」「特許」という2つの単語をスペースで区切ったものが入力されたとするとどうでしょう?\n### Suggest in Japanese POST https://{{host}}/indexes/suggester-test/docs/suggest?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#34;東京 特許\u0026#34;, \u0026#34;suggesterName\u0026#34;: \u0026#34;name_suggester\u0026#34; } スペースがありますが、内部処理では形態素解析器が分割した後でこの単語の順番で出てくるものを探しているので、出てくることになります。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.text\u0026#34;: \u0026#34;東京特許許可局\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;8\u0026#34; } ] } なお、このSuggestのAPIは、単語の語順を気を付ける必要があります。 「特許」「東京」と順序を入れ替えたスペース区切りの場合は、\n### Suggest in Japanese POST https://{{host}}/indexes/suggester-test/docs/suggest?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#34;特許 東京\u0026#34;, \u0026#34;suggesterName\u0026#34;: \u0026#34;name_suggester\u0026#34; } 結果は返ってこないです。おそらく内部では、フレーズクエリで、最後の単語だけを前方一致で検索するような仕組みが動いているのだと思われます。 スペースで区切られてはいるが、順序があるので少し違和感を感じるかもしれません。英語だとフレーズの部分のイメージは沸きやすいのですが。\n短い文章のデータ(例:本のタイトルやランドマーク名など)では、このSuggestAPIを利用するとデータそのものが返却されるので、便利かもしれません。\nまとめ ということで、Azure Cognitive SearchのSuggesterの簡単な紹介でした。APIのページにはそのほかのパラメータについても説明があるので、使ってみようと思う方は目を通していただくのがよいかと。\n今回のブログは裏の仕組みがどんな感じなのか?を想像しながらAPIについて調べた形になります。日本語の場合に、少し違和感を覚える人もいそうだろうなということでブログを書いてみました。 今回は書いていませんが日本語でAutocompleteをやりたい場合は、読み仮名でも漢字が表示されるほうがよいという場合もあると思います。 その場合は、用意されている機能では難しいので、独自実装するといった方法になりそうです。 英語や、読みを利用しない場合は、挙動を理解していれば役に立つ場面もありそうです。\n","date":1612515120,"dir":"post/2021/","id":"931b2ebd9bfaeb5dcf1973e724a1f8d0","lang":"ja","lastmod":1612515120,"permalink":"https://blog.johtani.info/blog/2021/02/05/autocomplete-and-suggest-on-azure-search/","publishdate":"2021-02-05T17:52:00+09:00","summary":"Azure Cognitive SearchにSuggestやAutocompleteの機能があるのを見つけたので、どんな挙動なのかを調べてログとして残しておきます。 公","tags":["azure search"],"title":"Azure Cognitive Searchでオートコンプリートやサジェストをしてみる"},{"contents":"オライリー・ジャパンから出ている「コンピュータシステムの理論と実装」を読み始めたのでメモを取ることに。\n原著はオライリーじゃないのかというのが、まず最初の気づきでした。\nNANDからテトリス コンピュータのハードウェアからOS、さらにその上で動くアプリケーションまでを動作させるというのを少しずつやっていくという書籍みたいです。 イントロと1章を読みましたが、1章では論理回路の話でした。\n実際に物理的に作るわけではなく、シミュレーターなどのソフトウェアが用意されており、 そのソフトウェア上で動くものを作っていくことになります。 ソフトウェアのために専用のサイトが用意されて、ダウンロードもできるようになっているので、実際に手を動かしながら理解を進める感じになるのかと。\n目次を見ていただくとわかりますが、すごく幅が広いです。 1年で読み終われるかなぁ?まぁ、のんびりやっていこうかなと。\n用意されているソフトウェアなどで便利だなと思ったのは、どの章からでも興味のある部分から始められるようになっているようです(まだ始めてなくて。。。) 内部ではすべてのパーツがそろえてあるけど、章ごとのプロジェクトでは、個別に自分で実装したものがあればそちらが動くという挙動のようです。\nということで、ちょっとずつやっていこうかなと。 ほんとにテトリス動くのかなぁ?\n","date":1612424444,"dir":"post/2021/","id":"aa61b4543e8a7c67fccabee27a6e99cd","lang":"ja","lastmod":1612424444,"permalink":"https://blog.johtani.info/blog/2021/02/04/reading-elements-of-computing-systems/","publishdate":"2021-02-04T16:40:44+09:00","summary":"オライリー・ジャパンから出ている「コンピュータシステムの理論と実装」を読み始めたのでメモを取ることに。 原著はオライリーじゃないのかというのが","tags":["輪読","Nand2Tetris"],"title":"「コンピュータシステムの理論と実装」を読み始めた #Nand2Tetris"},{"contents":"Corne使ってましたが、数字キーがあるとどうなのかな?というのがやはり気になって。 そこに、Kochi KeyboardさんからSofle Keyboard v2というのが発売されたので組み立ててみました(去年末に)。また、先日Corne Light v2のBLE化に成功したので、Sofle keyboard v2のBLE Pro Micro + LPME-IO化にもチャレンジしてみました。\nSofle keyboard v2 ビルドログ 自分で書くよりもすごくよくできたビルドログがKochi Keyboardさんで公開されているので、そちらを参考にしてください。\nSofle Keyboard v2ビルドガイド すごく詳しく書いてあります。なので、こちらを見ていただければ問題ないかなと。 ただ、自分ではいくつか失敗したので自戒を込めてログを残しておきます。\nOLED用のジャンパをはんだ付けし忘れ 単にビルドログを流し読みしたツケが。。。 Sofleは同じ基盤を左右で利用します。なので、右手と左手で、同じ基盤の表と裏を利用します。 OLED用のジャンパする部分は両面に用意されていますが、はんだでジャンプするのはPro Microが実装される面となります。\n両面にジャンプ用のランドがあるとは気づかないで、左手の裏面をジャンプしてすべて実装し終わってから、OLEDが表示されないことに気づいてしまいました(ビルドログ用にと思って撮った写真に証拠が残ってますねw)。。。\nということで、またはんダッシュ太郎くんのお世話になりました(Pro Microを外してジャンプしました)。本当に有能ですよ彼は。。。\nAmazon | サンハヤト はんだシュッ太郎NEO 45Wタイプ HSK-300 | ハンダゴテパーツ ソケットのはんだ付け甘すぎ あとは、慣れてきたなぁと思っていたところに天罰が。 キースイッチのソケットを付けるの慣れてきたなーと思って、サクサクとつけていたのですが、 いざキースイッチをはめるときにボロボロとはがれていきましたw 半分くらいは外れたんじゃないかな?ちゃんとはんだ付けした後にピンセットなどで軽くいじってみるべきですね。。。\n滑り止め 利用しているキーキャップがOEMプロファイルということもあり、数字キー側を少し高くしたほうが入力しやすいです。そのために、少し大きめのソフトクッションを購入しました。\nAmazon | WAKI ソフトクッションCN-020 クリアータイプ: 産業・研究開発用品 上の左右の角に貼り付けると、がたつきがあったので少しずらして貼り付けて安定させています。 OLEDのプレートの部分を押すと手前が浮き上がってしまいますが、そこにはキーはないので問題ないかと。\nということで、毎回気づきがあって面白いですね。。。\nSofle keyboardのBLE化 Corne LightのBLE化がうまくいったので、もうひとセットのぎけす屋さんから購入しました。 BLE Micro ProやLPME-IO、電池基盤などについては前回のCorneのBLE化の記事を参照してください。\nハードウェア編 Sofle keyboard v2は残念ながらせきごんさんの公式ページの対応キーボード一覧には掲載されていません。 が、Sofle KeyboardのGitHubのページには次のような記載があります。\nSofle is 6×4+5 keys column-staggered split keyboard with encoder support. Based on Lily58, Corne and Helix keyboards.\n基盤の写真のPro Micro周りもCorneに似ています。 ということで、おそらくBLE + LPME-IO化が行けるのでは?と予測して作業に取り掛かりました。\nPCBの確認 Sofle Keyboardの基盤の設計図はGitHub上に公開されています。 この設計図を見る方法をまずは探しました。\n自作キーボードについて探すにはまずはサリチル酸さんのブログ「自作キーボード温泉街の歩き方」です。 回路図なので、設計ノウハウあたりのカテゴリーにあるだろうと探したところ見つかりました。\n(設計者向け)オートルーターを使って睡眠時間を確保しよう 配線のテクニックというブログですが、回路図を書くためのツールKiCadについて記載があります。 このブログにある以下の記事をもとに、KiCadのインストールや使い方をちょっとだけ勉強しました。\nfoostanさんのMeishi Keyboardの開発者向けガイド(JP) KiCadことはじめ KiCadの中の回路図エディタ「Eeschema」でSofle keyboardのPCBのフォルダを開くと回路図が開きます。 実際の基盤になる前に、Pro Microのどの足と何がつながっているのか?などが見て取れます。 前回のCorneのBLE化でLPME-IO対応したときに、学習しましたが、 TRRSの足とPro MicroのSDAとSCLをつなぐことで、LPME-IOを使うことができるようになるというのがわかっています。 それをもとに回路図を見たところ、以下のような記述がありました。\nどうも、JP9とJP10というはんだでジャンプする場所を用意してくれていそうです。 先を見越した設計本当にありがたいですね。\nJP9とJP10のはんだ付け 今ついているPro Microを外し(またはんダッシュ太郎が活躍)、基板を確認したところ対象の個所がありました。下の写真は左手の裏側です。\nこれらをはんだでジャンプします。\n右手は表側にあるので、Pro Microを外した後にジャンプしました。 左手は裏側です。 Corne Lightでは、Pro Microの足から導線を使ってTRRSの足につなぎましたが、今回はすっきり実装できました。 ジャンプした後はBLE Micro Proをはんだ付けします(はんだ付けせずに動作確認しようとしましたが、うまく通電しなくてちゃんと動かなかったです)。\nLPME-IOのジャンパ LPME-IOのGitHubページにあるように、利用するキーボードによって、いくつかはんだでジャンプする必要があります。 これは、BLE Micro Pro用のConfigファイルを見て、対象を決める必要があります。 が、Sofleは事前に用意されたものがありません。\nConfigファイルの生成 用意されていないConfigファイルが、QMKの設定ファイルから生成することができるようななっています(本当に感謝しかないですね)。 手順はBLE Micro Proのドキュメントにありました。\n新しいキーボード用の設定を作成する - QMK用の設定から変換する この変換スクリプトで3種類のconfig(右手用、左手用、LPME-IO用)が生成されます。 私の場合はLPMEを利用するので、lpmeという名前の入ったconfigを利用します。 中を見るとcol以下の記載が以下の通りだったので、8からDをジャンプします。\n\u0026#34;col_pins\u0026#34;:[18, 17, 16, 15, 14, 13, 18, 17, 16, 15, 14, 13], ここまででハードウェア側が終了です。\nファームウェア・設定編 ハードウェアの実装が終わったので、ファームウェアおよびアプリの設定です。\nファームウェアのセットアップ キーボードをUSBで接続し、BLE Micro Pro Web Configuratorのページにアクセスすると、 セットアップ初期画面が出てきます。\n公式ページの「キーボードを選ぶ」を参考にファームウェア、アプリのアップデートを行います。 「設定ファイルの書き込み」のタイミングでupload your ownを選択すると、ファイル選択画面が出てくるので、変換スクリプトで生成したJSONファイルを選択します。 このとき、Mas Storage Classとしてキーボードが認識されている状態だとうまく書き込めなかったので、キーボードのドライブを「取り出し」してからファイルをアップロードしました。\nキーマップの設定 BLE Micro Proのアプリが設定をきちんと認識すれば、あとはWeb Configuratorでキーマップの設定が可能になります。 これまた、残念なことに、BLE化する前のキーマップをJSONファイルで保存してなかったので(泣きそうw)、QMKのkeymap.cのファイルをもとに、ブラウザ上でがんばって設定しましたw また、新しい設定ではBLE関連のキーをマッピングとして追加しています。\nBluetooth接続 あとは、接続確認です。 MacとWin2台と接続するのですが、Win→Mac→Winの順番でBluetoothの接続をやっていたら、なぜか3つ目のWindowsで接続候補に出てくるけど、接続しようとするとタイムアウトをするという現象に遭遇しました。 MacのBluetoothの設定を一旦削除してから、Win→Win→Macの順番でペアリングしたところ問題なく接続できました。ただ、これが本当の対処なのかどうかは不明です。3番目だと接続できなかったWindowsマシンは再起動もしてみたのですがダメでした。この辺よくわかってないなぁ。\nまとめ ということで、Corne Lightに引き続き、Sofle Keyboard v2もBLE+LPME化に成功しました。 導線なども使わずにLPME対応ができたので見た目もすっきりしています。 これで、KVMスイッチだと2台までしか切り替えできなかったのが、3台をひとつのキーボードで操ることができるようになりました。 だいぶ楽になりそうな予感がしています。\nまだ、完ぺきではないので、次のような対応をやっていく予定です。\nロータリーエンコーダー対応:BLE以前はQMKのkeymap.cの中でロータリーエンコーダーの動作を記述していたので、BLE Micro Proでどうやるのかを調べたい。encorder.jsonというファイルがあったのでその辺ではないかな? OLED対応:Corne Lightの時と同様に、OLEDが点かなくなったのでこの辺りを調べたい。 ということで、とりあえずキー入力するのには困らない程度にはできたので、より便利にする方法を時間を見つけて模索する感じになりそうです。 あと、KiCadも面白そうなのでこっちもちょっと触ってみたくなってきたかも?\n","date":1612106122,"dir":"post/2021/","id":"d95522c691013bfe66dd46ded85a98ed","lang":"ja","lastmod":1612106122,"permalink":"https://blog.johtani.info/blog/2021/02/01/apply-ble-to-sofle/","publishdate":"2021-02-01T00:15:22+09:00","summary":"Corne使ってましたが、数字キーがあるとどうなのかな?というのがやはり気になって。 そこに、Kochi KeyboardさんからSofle Keyboard v","tags":["DIYキーボード","misc"],"title":"Sofle v2を組み立てて、BLE+LPME-IO化してみた #DIYキーボード"},{"contents":"メインマシンとMacは下記のサンワサプライのUSB接続のKVMスイッチを使っていますが、もう一台ノートPCがありここに接続しているCorne(初めてのDIYキーボード)が長いUSBケーブルでつながっています。\nAmazon | サンワダイレクト USB切替器 キーボード・マウス用 KVMスイッチ 時々必要になって、デスクにキーボードだけ引っ張ってきて利用するのですが、ケーブルの取り回しがまぁ邪魔で。。。 BLE対応(BLE Micro Pro)をしてみようかなということに。\nBLE + LPME-IO対応 分割キーボードをBLE対応(それぞれにBLE Micro Proを実装)すると、キーボード間のつながりがいまいちになることもあるというのをちらほら見ていたので、BLE Micro Pro + LPME-IOという構成で、 Corneのキーボード同士はTRRSケーブルで接続し、PCとCorne間をBluetoothで接続する構成にしてみました。\nBLE Micro Proについては、公式ドキュメントにいろいろと記載があります。\n材料 ということで、材料は以下の通り。セット販売は売り切れていたので、個別に購入しました。 コンスルーと電池以外は1つずつです。\nBLE Micro Pro(のぎけす屋) x 1 LPME-IO(のぎけす屋) x 1 BLE Micro Pro用電池基盤(遊舎工房) x 1 コンスルー(Kochi Keyboard) x 4 CR1632ボタン電池(近所のスーパー) x 2 実装 まずは、それぞれ組み立てです。\n電池基盤 以下の記事を参考にはんだ付けしました。\nQiita: 自作キーボードビルドログ:その2「ErgoDash」無線化対応 ハードウェア編 - 電池基盤の組み立て・半田付け yfuku docs - Claw44 / 無線接続について 注意点は以下の通りです。\n基盤が軽いので固定が必要(マスキングテープでマットに貼り付けたらましになった) 電池ホルダーが変形しやすい(設置して、足を折るために上から押さえつけたら、本体が曲がってしまった。。。) 部品が細かいので大変(老眼だから?) BLE Micro Proとの接続は参考にしたyfuku docsにある方法(余っていたピンヘッダを1本ずつ使ってはんだ付け)を採用しました。 (パッと見大丈夫そうだったので電池基盤の裏に絶縁テープは貼ってないです貼ってないです)\nBLE Micro Pro(もげ対策) BLE Micro Pro自体はコンスルーをはんだ付けするだけですが、今回はもげ対策として、ダイソーで買ってきたグルーガンで ちょっとだけ補強してみました。 初グルーガンだったので不細工だけど。これ難しいな。\n効き目あればいいけど?\nLPME-IO対応 いくつかのジャンパをはんだでブリッジ まずは、LPME-IOのREADMEのページの導入手順を読み、いくつかのピンをジャンプしました。 せきごんさんのBLE-Micro-Proのリポジトリに、CorneのLPME用コンフィグファイルを見ると、ジャンプするのは20, 19, 18, 17, 16, 15に対応している、F,E,D,C,B,Aの6つです(写真撮り忘れた。。。)。\nTRRSのI2C対応(って言い方であってるのかなぁ?) ジャンプだけでいけないかなぁ?と思いましたがダメでした(USBでつないでみたけど、左手(BLE-Micro-Proがついている側)だけ入力可能です。\nBLE Micro Proの公式サイトにLPME-IOについても記載があります。 実績のあるキーボード一覧にCorne Lightの記載もあったので、試してみようと思ったのが発端です。\nただ、LPME-IOの欄に注意書きが。\n*LPME-IOを使うには改造が必要\nまた、一覧の最初にも記載があります。\nLPME-IOを使うにはキーボードの左右の有線通信がI2Cである必要があります。とくにOLEDに対応しているキーボード等の場合は、I2C用のピンをTRRSジャックに接続する改造を施すことでI2C化できる場合があります。\nまだ、自作キーボードの仕組みをがっつり理解しているわけではない初心者なので、まぁ、ちょっとわからないかなと。。。 BLE Micro Proのはじめにのページを見ると、 Self Made keyboard in JapanのDiscordに専用チャネルがあるようで、過去ログを検索してみました。 検索したところ、Corneの場合Micro ProのSDA(写真の青い線)とSCL(写真の黄色い線)(参考:Corneの基盤の図)をそれぞれ、TRRSの2つのピンに接続する必要がありそうだというコメントがありました。\nCorne Cherry v2の場合は、接続するためのショートカットが用意されていましたが、Corne Light v2だと見当たりませんでした。 ということで、線を使って物理ショートカットしました。ちなみに、ショートカットは両手ともに必要なようです。\nUSB-Cで接続テスト 上記対応が終わって、基板に設置してUSB-Cケーブルで接続したところ、外部ドライブとして見えるようになりました。\nキーマップの書き換えとか 公式ドキュメントのBLE Micro Pro Web Configuratorを使うの手順通りに書き込みを行っていくと、特に問題なく接続できました。 便利すぎですね。キーマップの変更は、これまでのCorneのキーマップJSONファイルからコピペして書き込んだだけです。 (この後、BLE用のキーマップを書き足すためにもう一度変更しますが)\nLPME-IO対応なので、Micro Proは片側しかないので、書き換えも楽々でした。\nBLEで接続テスト 今回の目的だったWindowsにBluetoothで接続できるようにしてみました。 最初はサリチル酸さんの記事を見ていたのですが、キーコードがちょっと変わっているようでした。\nで、よくよく見ると、BLE Micro Pro Web ConfiguratorにBLE関連のキーも用意されているじゃないですか。。。\nBLE関連のキーを割り当てた後は、USBをオフにして、Bluetoothをオン、BTNEWで新しくペアリングするようにすれば接続完了でした。\n課題 これまでと違い、すんなり実装ができましたがまだいくつか気になる点が。\n複数の機器とペアリングして切り替え Macともペアリングしてみようとしたのですが、切り替えがうまくいかないようで。。。 OLEDつけるにはどうするんだろう? 左手側は電池が乗っているのですが、右手側はLPME-IOだけなので、上にOLEDを載せる余裕があります。 なので載せてみましたが点かないですね。ファームウェアを何かしないといけないんじゃないかな?調べないとなぁ。 という感じです。 まだちゃんと長時間使っていないので、他の問題点も出てくるかもしれませんが、まぁとりあえず使ってみてからかな。 うまくいくようなら、メインマシンにBluetoothモジュール追加してみるのもありかと考えているところです。\n調べながら、自分なりに対応してみましたが他にもいい方法とかあれば教えてもらえると助かります。\n","date":1610332951,"dir":"post/2021/","id":"4ad8239a37f641bcd17abeb96106314e","lang":"ja","lastmod":1610332951,"permalink":"https://blog.johtani.info/blog/2021/01/11/apply-ble-and-lpme-to-corne/","publishdate":"2021-01-11T11:42:31+09:00","summary":"メインマシンとMacは下記のサンワサプライのUSB接続のKVMスイッチを使っていますが、もう一台ノートPCがありここに接続しているCorne","tags":["DIYキーボード","misc"],"title":"Corne Light v2のBLE+LPME-IO対応 #DIYキーボード"},{"contents":"振り返りブログにも書きましたが、デスクトップPCを自作(DIY)しました。 組み立てたに使ったパーツのアフィリンクを貼っておきます。\n10月くらいにPC組もうと思って、組み上がったのは11月半ばでした。 最初はもうちょっと小さいPCにしようと思ってたのに気づいたらATXになってました。 パーツの選定の基準は以下のツイートです。影響されやすいなぁ。\nタワーってほど大きくなくていいと思いますが、NZXT H510 ぐらいの大きさは欲しいですね。https://t.co/s1c1fOnPyI\n単純に、スペースがないと組みにくいのと冷えにくい、買ってきたものがやっぱりこれだと入らない、というリスクがかなり減るので。\n\u0026mdash; さぼてん(さぼ福)🌵 (@cactusman) October 9, 2020 今年3台作りました。ノートPC使えない体になります。 pic.twitter.com/8zDmeRwNkS\n\u0026mdash; miyake | ZEN (@kazuyukimiyake) October 9, 2020 白いケースいいなぁという感じで、ケースとCPUクーラーが決まったんで、ググってこちらのHAKKAさんのYouTube見ながら妄想してました。 パーツがなかなか揃わなくて。 そして、PCが光るのどうなの?と思ってたのに、気づいたら光ってました(なぜ?)。\nグラボがない状態(CPU内蔵GPU)で12月頭までは動作してました。\n購入自体はTSUKUMO、ビックカメラオンライン、パソコンSHOPアーク、イートレンドオンラインショップでオンラインで購入しました。\nPCケース Amazon | NZXT H510i White CA-H510I-W1 CS7946 | NZXT | PCバッグ・ケース・スリーブ 電源 Amazon | NZXT E850 デジタル電源ユニット 80 Plus Gold 認証 [ 定格 850W 出力 ] NP-1PM-E850A-JP NP-1PM-E850A-JP SP947 | NZXT | パソコン・周辺機器 通販 マザーボード Amazon | ASRock AMD Ryzen 3000シリーズ CPU(Soket AM4)対応 X570チップセット搭載 ATX マザーボード X570 Steel Legend | ASROCK CPU AMD Ryzen 4750G\nCPUクーラー Amazon | NZXT KRAKEN Z63 簡易水冷CPUクーラー 液晶モニタ搭載 RGB対応 280mm RL-KRZ63-01 FN1441 | NZXT | CPUファン 通販 メモリ Amazon | G.SKILL 128GB(4 x 32GB)Trident Z NeoシリーズDDR4 SDRAM 3200MHz PC4-25600デスクトップメモリモデルF4-3200C16Q-128GTZN | G.Skill | メモリ 通販 SSD Amazon | Seagate FireCuda 520 M.2 1TB PCIe Gen4x4 内蔵SSD M.2 2280 3D TLC ZP1000GM3A002 | SEAGATE グラボ Amazon | GIGABYTE NVIDIA GeForce RTX3080搭載 グラフィックボード GDDR6X 10GB ホワイトモデル【国内正規代理店品】GV-N3080VISION OC-10GD | 日本ギガバイト 拡張カード Amazon | ASRock 拡張インターフェースボード Thunderbolt 3 AIC R2.0 | ASROCK | インターフェースカード 通販 拡張カードは実は差し込んだら最初うまく動かなくてサポートに連絡しました。同じ構成の検証機を用意して解決方法を見つけてもらいました。しかも数日で。サイコーのエクスペリエンスでした!\n日本語でサポートしてもらえてしかも数日で解決してもらった。ASRockのサポートすばらしかったです! https://t.co/8FasCInIqt\n\u0026mdash; Jun Ohtani (@johtani) December 8, 2020 その他 ケースのフロントパネルのUSB-Cポートを使えるようにするために。\nAmazon | Cablecc USB 3.1フロントパネルソケットType-E-マザーボード用USB 3.0 20ピンヘッダーオス拡張アダプター | cablecc | PCアクセサリ・サプライ 通販 最近のPCパーツはUSBでモニタリングできるみたいで、マザボのUSBポートが足りなかったので拡張しました。\nAmazon | マザーボードのUSB 9ピン 増設 内部用4ポートUSB2.0 HUB | ノーブランド品 | USBハブ 通販 白いケースだし、「映え」のために白いケーブルを。\nAmazon | Novonest 電源専用延長スリーブ 補助電源モジュラーケーブル 長さ300mm 6本1セット スリーブガイド24点セット付き 【SC304】 | novonest | 電源ユニット 通販 組み立て中 手元にあったCPUでBiosアップデート(Ryzen 5000シリーズにしたかったから。まだできてないけど)。\n応急処置でBiosアップデートしてる pic.twitter.com/mXf2B5kwqB\n\u0026mdash; Jun Ohtani (@johtani) November 8, 2020 さーて、頑張るぞー pic.twitter.com/HmlGqREjmP\n\u0026mdash; Jun Ohtani (@johtani) November 13, 2020 さて、仮起動実験ですよと pic.twitter.com/5HP3cbs6SH\n\u0026mdash; Jun Ohtani (@johtani) November 13, 2020 きたきたー pic.twitter.com/4sL3ymecEo\n\u0026mdash; Jun Ohtani (@johtani) November 13, 2020 コネクター刺しまくらないと pic.twitter.com/Soye3lS4M9\n\u0026mdash; Jun Ohtani (@johtani) November 13, 2020 完成はこんなかんじ 初期構成\n組み上がったよー pic.twitter.com/sBwpvLsZh3\n\u0026mdash; Jun Ohtani (@johtani) November 14, 2020 グラボデプロイ\n設置完了してこんな感じ。なんかベンチマーク走らせるかなぁ。何がいいだろ pic.twitter.com/aZufAE9fJA\n\u0026mdash; Jun Ohtani (@johtani) December 4, 2020 グラボのおまけも付けてみた。\nまぁ、せっかくついてきたので取り付けてみました(グラボ下の光ってるパネル)。 pic.twitter.com/068IxaV1ps\n\u0026mdash; Jun Ohtani (@johtani) December 4, 2020 とまぁ、こんな感じでした。 メモリは多分使い切れないだろうなぁと思いながら、やってみたかったという感じです。。。\n","date":1609422526,"dir":"post/2020/","id":"64a421c2367372c3199c66a6420faf89","lang":"ja","lastmod":1609422526,"permalink":"https://blog.johtani.info/blog/2020/12/31/diy-pc/","publishdate":"2020-12-31T22:48:46+09:00","summary":"振り返りブログにも書きましたが、デスクトップPCを自作(DIY)しました。 組み立てたに使ったパーツのアフィリンクを貼っておきます。 10月くら","tags":["misc"],"title":"PCもDIYしました"},{"contents":"今年も振り返りブログ書いてます。カタンの航海者版を購入して家族とやってましたが、負けてしまいました。\n振り返り(2019年に書いた抱負から) まずは去年の抱負を元に書きますが、3月以降はコロナウィルスの影響でいろいろと生活が変わってしまいましたね。\n職につく 厳密には達成してないことになるのかな?\n1月末にフリーランスはじめました(仮)という記事を書きましたが、 そのまま、現時点では個人事業主でフリーランスとして4社ほどお手伝いさせていただいています。\nお手伝いしてるお客さんの事例が出てた。直接的に類似画像検索の部分を手伝ってるわけではないんですが、Azure Cognitive Searchの調査とかやってます。 / 「ハッカソン」で社外の知見を積極的に活用! 富士フイルムソフトウエアが実践するサービス開発の理想形 - https://t.co/yDIwYmYDBM\n\u0026mdash; Jun Ohtani (@johtani) June 19, 2020 名前出てた。ZOZOさんの手伝いさせていただいております。 / ZOZOTOWNにおける検索速度改善までの道のり - ZOZO Technologies TECH BLOG - https://t.co/OqaFMYe0TY\n\u0026mdash; Jun Ohtani (@johtani) August 20, 2020 こんな感じです。 コロナウィルスの影響もあり、完全リモートで仕事をさせていただいています。 感謝しかないです。\nブログプラットフォームの移行 昨年の振り返りの時点で目を付けていたHugoへの乗り換えを行いました。 乗り換えについてもまとめてあります。\nOctopressからHugoへ移行中(まだ途中) ブログ移行日記(その1) - Hugoとテーマ ブログ移行日記(その2) - Markdownファイルの変換 ブログ移行日記(その3) - Hugoの設定と微調整(テーマに合わせた) ブログ移行日記(その4) - 検索機能(Algolia)の導入 ブログ移行日記(その5) - Jugemのブログを移行 無事移行できて、特に困ってない感じです。\nプログラミング 昨年よりは書いた気がしています。 まぁ、書きなぐって放置してるのもありますが。。。\n細々としたツールがいくつか。\nfrom-octopress-to-hugo bulk2es-rs azure-search-analyze-client wiki-extractor-rs kuromoji-graphviz-output kuromoji-cli あとは、Linderaという形態素解析も手伝ってみました。 ちょっと後半は忙しくなり、コーディングが減ってるんで、また復活させないと。\nRust再入門 Tantivyは結局触れてないけど、Linderaを手伝えました。あとは、ちょっとしたツール(bulk2es-rs)なども作りました。 知り合いとやっていたRust the bookを読むのも一通り終わりました。 Linderaまわりのリファクタとかを年明けにやろうかな?\n検索の勉強 仕事になりました。というか、しました。 ブッチャー本も買ったんですが、手を付けられてないので、年明けから心機一転、よみ始めようと思います。\n検索技術勉強会の継続 残念ながらだめでした。 年初にスピーカーの方に連絡は入れて履いたのですが、コロナウイルスの影響で 今年はオフラインの勉強会は無理だろうとい事で延期したままです。 オンラインの勉強会もいくつか開催されていましたが、検索技術勉強会は残念ながらモチベーションもわかずのまま今年も終わってしまいました。 単に話を聴くセミナーのようなものよりは、Podcastのような形を取るのがいいのかもなぁとは思っているのですが。。。 だれか、サクッと話したい人いたらやってみませんか?\n振り返り(今年あったできごと) さて、ここからは今年の出来事を。\n自宅環境の改善 Windowsへの移行 キーボードDIY フリーランス ブログ書いたなぁ 3月以降はずーっと自宅で仕事してました。 ということで、自宅の環境がどんどんアップデートされていった1年でした。 最終バージョンは年内に間に合わなくて、年明けに書きますが。。。 途中経過はこんな感じでした。今は更に変わっていますが。\n3月バージョン 9月バージョン 12月バージョンでも書きますが、ずっと自宅で作業だったのもあり、自作PCをやりたくなったので、久々にWindowsに帰ってきました。Ubuntuもチョット検討しましたが、Windowsに今は落ち着いています。自作PCはこんな感じ。 自作PCブログも後で書きますね。\n設置完了してこんな感じ。なんかベンチマーク走らせるかなぁ。何がいいだろ pic.twitter.com/aZufAE9fJA\n\u0026mdash; Jun Ohtani (@johtani) December 4, 2020 Windowsをお試し中 Windowsへの移行(その1) AutoHotKeyで色々と弄っているので、素のWindowsは触れる気がしないけど。。。\n自作つながりで、キーボードもDIYしました。\nDozen0を作成した Corne Light v2を作成した Corne Chocolateを組み立てた Sofle Keyboardも組み立てた(けど、ビルドブログはまだ) 分離キーボードには昨年から興味があったのですが、手を付けていませんでした。 今年は自宅でずっと作業でしたから、これを機会に作ってみました。 既製品(Moonlander)も気になってはいたのですが、DIYキーボードはプラモデル感覚で作れそうだし面白そうだなと。 今年一番ハマったものかもしれないです。 知り合いが始めたKochi Keyboardで最初に発売されたのがCorne Light v2だったので、これが初めての分割キーボードです。 40%キーボードからいきなり入ったので最初はかなり大変でしたが、なれると入力が早くなる気がします。ホームポジションからほぼ動かないのはいいですね。最初は数字列がないのでアホか???と思っていましたが。 今は、Sofle(60%キーボード)がメインになっています。40%から60%に移行すると 数字のキーが遠いなと思ってしまいますねw\nどうなるものかと思いつつ、フリーランスを続けています。 最初に仕事をいただいた富士フイルムソフトウェアさんには非常にお世話になっています(今もお手伝いさせてもらっています、ありがたい)。来年も精進していきます!\n今年はブログを書きました、最後はちょっと息切れしてる感じになってるけど。。。 もっとカジュアルに書くようにしないとなぁ。 年明けにまだ書いてないブログを書いていかないと。「自作PCブログ」「Sofleのビルドブログ」「2020年買ってよかったブログ」とか。\n来年の抱負 ということで、来年の抱負です。\nフリーランス継続? プログラミング 検索の勉強 検索のポッドキャスト? とりあえず今年は乗り切れました。来年も食べていくためにもフリーランスを継続できるように、お手伝いさせて頂いてる各社に 継続してもらえるように精進していきます。色々と勉強させて頂いてるのでほんとうにありがたいです。\nプログラミングは今年の後半はスローダウンしてしまったのでがんばらないと。 検証用のコードやちょっとしたツールを書くほうが多いので、もう少し継続してメンテナンスするようなものも書きたいなぁと。\n検索の勉強はまずはブッチャー本を買ってしまったので、ここからでしょうか。 値段も厚みもすごいので、コツコツ元を取れるようにがんばります。。。\n来年もまだまだ自宅で仕事が続きそうなので、勉強会というよりもポッドキャストみたいなものをやるのがいいのかもなと。 2020年初にやらせていただいた、「検索システム探訪」をポッドキャスト風にやるのもありなのかもなぁ。 興味ある人いたら連絡ください。公開しない雑談とかもありだと思ってるので。\n今年は色々ありましたが、無事に乗り切れました。 気軽にランチなどで遊びに行けない状況ですが、雑談相手になっていいなと思う方、連絡お待ちしています。\nさて、来年はどんなキーボード作るのかなぁ(え?また作るの??)。 今後もよろしくおねがいしまーす!\n","date":1609406004,"dir":"post/2020/","id":"a5b2ee641e10d3e4db8f888217ab9ecc","lang":"ja","lastmod":1609406004,"permalink":"https://blog.johtani.info/blog/2020/12/31/looking-back-2020/","publishdate":"2020-12-31T18:13:24+09:00","summary":"今年も振り返りブログ書いてます。カタンの航海者版を購入して家族とやってましたが、負けてしまいました。 振り返り(2019年に書いた抱負から) ま","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2020)"},{"contents":"Elastic stack (Elasticsearch) Advent Calendar 2020の18日目の記事になります。\n本日の勉強会でLTをしましたが、しゃべり足りなかったんで。 Elasticsearch 7.8でこっそりとリリースされたIndex Template V2について調べたのでどんなものかをまとめてみます。 リリースブログには出てきてない(7.8のEsのページのWhat\u0026rsquo;s newには出てた)ので気づいてない人も多いのではないでしょうか?\nIndex Templateとは? まずはIndex Templateがどんなものかを説明しましょう。\nIndexの設定やマッピングはデフォルト値以外を設定したい場合に、毎回\u0026quot;mappings\u0026quot;や\u0026quot;settings\u0026quot;の設定を指定してIndexを作成するのは手間がかかります。 そこで便利な機能として提供されているのがIndex Templateです。このIndex TemplateはCluster Stateに保管されます。\nIndex Templateを利用するときの流れは以下の通りです。\nIndex Templateの作成 Indexの作成 例えば、3ノード構成のクラスターでインデックスを作成するときに常に\u0026quot;number_of_shards: 3\u0026quot;を設定したいとします。 Index Templateは次のような感じになります。\nPUT _template/blog_num_shards { \u0026#34;index_patterns\u0026#34;: \u0026#34;blog_*\u0026#34;, \u0026#34;settings\u0026#34;: { \u0026#34;index\u0026#34;: { \u0026#34;number_of_shards\u0026#34;: 3 } } } または日本語のシンプルな形態素解析のアナライザーの設定を\u0026quot;jp_\u0026ldquo;という名前でるようできるようにしたい場合には次のような感じになります。\nPUT _template/jp_simple_kuromoji { \u0026#34;index_patterns\u0026#34;: \u0026#34;jp_\u0026#34;, \u0026#34;settings\u0026#34;: { \u0026#34;index\u0026#34;: { \u0026#34;analysis\u0026#34;: { \u0026#34;simple_jp\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;custom\u0026#34;, \u0026#34;tokenizer\u0026#34;: \u0026#34;kuromoji\u0026#34; } } } } } インデックステンプレートの登録が終われば、インデックスを作成するタイミングでIndex Templateが適用されます。 例えば、blog_2020というインデックスを作成すると、number_of_shards: 3のインデックスが作成されます(デフォルトは1)。 jp_blog_2020というインデックスを作成すると、simple_jpというAnalyzerが設定されています。 このように、インデックス名を意識するだけで設定が適用されていくのが利点です。\nちなみに、Index TemplateはIndex作成時に適用されるだけなので、Index Templateを変更してもこれまでのインデックスへは影響はありません。\nこれまでのIndex Templateの問題点 と、Index Templateが便利なのはわかりましたが、ではなぜ今回V2がリリースされたのでしょうか? 先ほどの例を見るとわかりますが、これまでのIndex Templateは部品化が難しいのが問題でした。 Index Templateはそれぞれがインデックスの作成時に適用されます。 が、Index TemplateにIndex Templateを組み込むことはできません。 例えば、先ほどサンプルとして作成したjp_simple_kuromojiのIndex Templateはjp_で始まるインデックスにしか適用できません。\nでは、blog_で始まるインデックスにもkuromojiのシンプルなアナライザーを使いたくなった場合はどうなるでしょう? 残念ながら、jp_simple_kuromojiと同じ設定をblog_num_shardsのテンプレートに追加するか、jp_simple_kuromojiのindex_patternsの部分だけを書き換えた新しいテンプレートを用意するか、jp_simple_kuromojiのindex_patternsにjp_を追加する方法です。 いずれにしてもIndex Templateの継承(複数のテンプレートを1つのインデックスに紐づける)が必要となります。 この時、複数のIndex Templateが適用されるため、適用する順番が出てきます。 この順番をIndex Templateのorderパラメータで指定できます。\nただ、これも問題のもととなっていました。 複数あるIndex Templateのどれがどの順番で適用されるのか?それはインデックスを作成時にようやくわかります。 使いたい側(インデックス)が、使いたいもの(テンプレート)を指定するのではなく、その逆(使いたいものに使いたい側の情報を設定しなくてはならない(index_patternsやorder))になっているのでわかりにくくなっていました。\nということで解決策としてリリースされたのがIndex Template V2です(ちなみに名前にV2とは言ってるわけではなく、現在のIndex Templateの機能がlegacy index templateという名前になり、Deprecatedになっています(まだログには出ない))。\nIndex Template V2 7.8のWhat\u0026rsquo;s newドキュメントではComposable Index Templateと紹介されています。 大きく3つのエンドポイントが提供されます。\nComponent Template 用API テンプレートのコンポーネントという単位で管理するためのAPI。 登録更新、削除、取得が可能 Index Template 用API Index Templateを管理するためのAPI 登録更新、削除、取得が可能 Simulate index template API(Experimental) Index Template Legacy Index Templateとの大きな違いは、\nテンプレートをコンポーネントにできる 1つのインデックスに適用されれるテンプレートは1つだけ という点です。これまでとは挙動が異なるので注意が必要です。\n新しいIndex Templateを利用する際の流れは次のようになります。\nComponent Templateの作成 Index Templateの作成 作成したIndex Templateの挙動を確認 実際にIndex名を指定してIndex Templateの挙動を確認 という形です。では、それぞれの機能を見ていきましょう。\nCoponent Template API テンプレートコンポーネントを管理するためのAPIです。 具体的なAPIごとに説明していきます。\nPUT _component_template コンポーネントを登録、変更するためのAPIです。公式ドキュメントはこちらです。 先ほどのkuromojiのAnalzyerをコンポーネントとして登録してみましょう。\nPUT _component_template/jp_simple_kuromoji { \u0026#34;template\u0026#34;: { \u0026#34;settings\u0026#34;: { \u0026#34;index\u0026#34;: { \u0026#34;analysis\u0026#34;: { \u0026#34;analyzer\u0026#34;: { \u0026#34;simple_jp\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;custom\u0026#34;, \u0026#34;tokenizer\u0026#34;: \u0026#34;kuromoji_tokenizer\u0026#34; } } } } } }, \u0026#34;version\u0026#34;: 1, \u0026#34;_meta\u0026#34;: { \u0026#34;description\u0026#34;: \u0026#34;simpleなKuromoji analyzer\u0026#34; } } 先ほどと特に違いはありません。templateという階層が1段増え、index_patternsがなくなりました。 template部分はIndexに設定するsettings、mappings、aliasesが指定可能です。 ちなみに、\u0026ldquo;template\u0026quot;の中身をそのままIndex作成時に使用した場合にエラーにならない設定である必要があります。 ここは注意が必要です。例えば、component Aでkuromojiのアナライザーの設定をし、component Bでそのアナライザーを使用するフィールドのmappingだけを記述した場合、component Bでエラーが発生します。上記のようなシチュエーションでは、Index Templateで利用するフィールドを定義し、component Aを利用する宣言をすれば問題ありません。\nそのほかに使えるパラメータで便利なものを紹介しておきます。\nクエリパラメータ\ncreate: URLに指定するパラメータ。trueを指定することで、既に存在する場合にエラーを返してくれる。更新も同じAPIなので間違わないようにするために利用すると便利。デフォルトはfalse リクエストボディ\n_meta: テンプレートにメタ情報を付与できる。_metaの中は自由に記述可能。コメントなどを書いておくとあとでわかりやすい GET _component_template コンポーネントを取得するためのAPIです。公式ドキュメントはこちらです。 一覧での取得とリストでの取得が可能です。\n一覧取得サンプル\nGET /_component_template GET /_component_template/* これ以外に、IDを指定して取得することも可能です。\nGET _component_template/jp_simple_kuromoji *を利用して複数取得も可能です。\nGET _component_template/jp* GET _component_template/j*_* DELETE _component_template コンポーネントを削除するためのAPIです。公式ドキュメントはこちらです。 IDを指定してコンポーネントを削除できます。\nDELETE /_component_template/jp_simple_kuromoji ID指定以外に*を利用することも可能ですが気を付けて使用しましょう。\nDELETE /_component_template/jp_* DELETE /_component_template/* ちなみにIndex Templateで利用されているコンポーネントを削除しようとした場合はエラー(ステータスコード400)が返ってきます。 *などを使用して削除しようとした場合は、ひとつでも利用されているものが含まれている場合は削除は実行されずにエラーだけが返ってくるようになっています。\nIndex Template API Index Templateを管理するためのAPIです。 Component Template APIで定義したコンポーネントを利用してテンプレートを作成できます。コンポーネントを利用しないで単体で完結したテンプレートも作成可能です。 具体的なAPIごとに説明していきます。\nPUT _index_template Index Templateを登録・更新するためのAPIです。公式ドキュメントはこちらです。\nこれまでのLegacy Index TemplateのAPIのエンドポイント(_template)ではなく、(_index_template)というエンドポイントになっていることにまず注意してください。 先ほど作成したjp_simple_kuromojiコンポーネントと、追加で作成した3_shardsというコンポーネントを利用して blog_で始まるインデックスに適用できるIndex Templateを作成してみましょう。\nPUT _index_template/blog_template { \u0026#34;index_patterns\u0026#34;: [\u0026#34;blog_*\u0026#34;], \u0026#34;template\u0026#34;: { \u0026#34;mappings\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;hoge\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;simple_jp\u0026#34; } } } }, \u0026#34;priority\u0026#34;: 100, \u0026#34;composed_of\u0026#34;: [\u0026#34;jp_simple_kuromoji\u0026#34;, \u0026#34;3_shards\u0026#34;] } composed_ofというパラメータに利用したいコンポーネントを配列で記述していきます。 Index Templateが適用される時に、ここに記述されている順番でコンポーネントが適用されていきます。 ですので、最後に書いてあるテンプレートが一番強いことになります。 これは例えば、同じ設定値number_of_shardsを2つのコンポーネントが設定している場合に、最後に設定した値がインデックスに採用されるという意味です (公式ドキュメントにサンプルが掲載されています)。 なお、存在しないコンポーネントをcomposed_ofに指定した場合は400エラーが返ってきます。同じコンポーネントを複数重複して指定した場合は特にエラーにはなりませんでした。 composed_ofを指定しなければ、単体で完結したテンプレートを定義可能です。\n次に重要な設定はpriorityです。これまでのテンプレート機能と異なる点で説明しましたが、\n1つのインデックスに適用されれるテンプレートは1つだけ となっています。 この1つを決めるための値がpriorityになります。 インデックス名によってはindex_patternの定義によって、複数のIndex Templateにマッチします。例えばblog_*と*_2020のIndex Templateがあった場合にblog_2020というインデックスを作った場合です。 この時、Elasticsearchはpriorityの大きい値を持ったIndex Templateだけを適用します。 blog_*のIndex Templateのpropertyが10、*_2020のIndex Templateのpropertyが100だった場合、*_2020のテンプレートが適用されます。Legacy Index Templateではorderという似たパラメータがありましたが、こちらは適用する順序を決定するためのものでした。挙動が違うので注意しましょう。\nちなみに、blog_*と*_2020のpropertyがどちらも10というIndex TemplateをPUTしようとした場合、2番目にIndex TemplateをPUTするタイミングでエラーが返ってきます。\nそのほかに使えるパラメータで便利なものはPUT _component_templateと同様にcreateと_metaです。\nGET _index_template Index Templateを取得するためのAPIです。公式ドキュメントはこちらです。 一覧での取得とリストでの取得が可能です。\n一覧取得サンプル\nGET /_index_template GET /_index_template/* これ以外に、IDを指定して取得することも可能です。\nGET _index_template/blog_template *を利用して複数取得も可能です。\nGET _index_template/blog_* GET _index_template/b*_* DELETE _index_template Index Templateを削除するためのAPIです。公式ドキュメントはこちらです。\nIDを指定してコンポーネントを削除できます。\nDELETE /_component_template/jp_simple_kuromoji ID指定以外に*を利用することも可能ですが気を付けて使用しましょう。\nDELETE /_component_template/jp_* DELETE /_component_template/* 最後のサンプルを実行すると、Elasticのツールなどが登録したIndex Template以外はすべて削除されてしまうので本当に気を付けましょう。\nSimulalte API さて、コンポーネントとテンプレートを作成したので確認をしましょう。 Legacy Index Templateでは確認するためには実際にインデックスを作成するしかありませんでしたが、V2ではSimulate APIが用意されています。 このSimulate APIには2つのAPIがあります。\nPOST /_index_template/_simulate/\u0026lt;テンプレート名\u0026gt; POST /_index_template/_simulate_index/\u0026lt;インデックス名\u0026gt; Index Templateの確認のためのAPIとインデックス名を指定したときに出来上がるIndexの設定を確認するためのAPIです。 Indexを実際に作成しなくても確認できるのは便利ですね。\n例えば先ほど作成したblog_templateを試してみましょう。\n_index_template/_simulate API POST _index_template/_simulate/blog_template レスポンスはこんな感じです。\n{ \u0026#34;template\u0026#34; : { \u0026#34;settings\u0026#34; : { \u0026#34;index\u0026#34; : { \u0026#34;analysis\u0026#34; : { \u0026#34;analyzer\u0026#34; : { \u0026#34;simple_jp\u0026#34; : { \u0026#34;filter\u0026#34; : [ \u0026#34;kuromoji_readingform\u0026#34; ], \u0026#34;type\u0026#34; : \u0026#34;custom\u0026#34;, \u0026#34;tokenizer\u0026#34; : \u0026#34;kuromoji_tokenizer\u0026#34; } } }, \u0026#34;number_of_shards\u0026#34; : \u0026#34;3\u0026#34; } }, \u0026#34;mappings\u0026#34; : { \u0026#34;properties\u0026#34; : { \u0026#34;hoge\u0026#34; : { \u0026#34;type\u0026#34; : \u0026#34;text\u0026#34;, \u0026#34;analyzer\u0026#34; : \u0026#34;simple_jp\u0026#34; } } }, \u0026#34;aliases\u0026#34; : { } }, \u0026#34;overlapping\u0026#34; : [ { \u0026#34;name\u0026#34; : \u0026#34;blog_template2\u0026#34;, \u0026#34;index_patterns\u0026#34; : [ \u0026#34;blog_*\u0026#34; ] } ] } templateにコンポーネントがマージされた結果が出力されます。 overlappingはindex_patternsがかぶる可能性があるIndex Templateの情報が出力されます。 サンプル用にblog_template2という、同じindex_patternsでpriorityが低いものを登録してあるためです。 index_patternsが完全に同じではなくとも、重複する可能性があるものはここに出力されます。 例えば、index_patternsがb*という別のIndex Templateを作成してからSimulate APIを実行すると、overlappingにそのIndex Templateも出力されます。\nSimulate Index Template APIのもう一つの機能は登録前のIndex Templateの確認です。 リクエストのURLのテンプレート名をなくし、PUT _index_templateと同じJSONをリクエストボディとして送信した場合、コンポーネントをマージしたテンプレートがどんなものかを確認できます。\nPOST _index_template/_simulate { \u0026#34;index_patterns\u0026#34;: [\u0026#34;blog_*\u0026#34;], \u0026#34;template\u0026#34;: { \u0026#34;mappings\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;hoge\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;simple_jp\u0026#34; } } } }, \u0026#34;priority\u0026#34;: 10, \u0026#34;composed_of\u0026#34;: [\u0026#34;jp_simple_kuromoji\u0026#34;] } このリクエストを送信すると、コンポーネントがマージされた結果が返ってきます。index_patternsがかぶるものがある場合はoverlappingも一緒に返却されます。\n_index_template/_simulate_index API 今度はインデックス名を指定するSimulate APIを試してみましょう。\nPOST _index_template/_simulate_index/blog_2021 これだけです。\n{ \u0026#34;template\u0026#34; : { \u0026#34;settings\u0026#34; : { \u0026#34;index\u0026#34; : { \u0026#34;analysis\u0026#34; : { \u0026#34;analyzer\u0026#34; : { \u0026#34;simple_jp\u0026#34; : { \u0026#34;filter\u0026#34; : [ \u0026#34;kuromoji_readingform\u0026#34; ], \u0026#34;type\u0026#34; : \u0026#34;custom\u0026#34;, \u0026#34;tokenizer\u0026#34; : \u0026#34;kuromoji_tokenizer\u0026#34; } } }, \u0026#34;number_of_shards\u0026#34; : \u0026#34;3\u0026#34; } }, \u0026#34;mappings\u0026#34; : { \u0026#34;properties\u0026#34; : { \u0026#34;hoge\u0026#34; : { \u0026#34;type\u0026#34; : \u0026#34;text\u0026#34;, \u0026#34;analyzer\u0026#34; : \u0026#34;simple_jp\u0026#34; } } }, \u0026#34;aliases\u0026#34; : { } }, \u0026#34;overlapping\u0026#34; : [ { \u0026#34;name\u0026#34; : \u0026#34;fuga\u0026#34;, \u0026#34;index_patterns\u0026#34; : [ \u0026#34;b*\u0026#34; ] }, { \u0026#34;name\u0026#34; : \u0026#34;2021\u0026#34;, \u0026#34;index_patterns\u0026#34; : [ \u0026#34;*_2021\u0026#34; ] } ] } 例で作成したblog_templateが適用されていますが、それ以外にindex_patternsに合致したがpriorityが低くて適用されなかったものがoverlappingに出力されています。 実際に適用されたテンプレートの名前も別途出力してくれるとわかりやすいかもしれないですね。 (*_2021というインデックスパターンのテンプレートを試しに作ってみたのですが、これはバグがありそうです。2021に合致するインデックス名をSimulateしたらoverlappingに合致しないものがたくさん出てきました。バグ報告しとくか)。\nKibana対応 ここまで、Index Template V2のAPIの説明でしたが、Kibanaでの対応についても調べてみました。\nIndex Management(Stack Management機能。Elasticライセンスが必要だが無償の機能) 7.9からKibanaのIndex管理画面でComposable Templateが利用できるようになっています(GitHub Issue)。 画面のスクショを一通り貼っておきます。残念ながら、それぞれのJSONの編集部分では補完などはサポートされていないようでした。 頑張って自分でsettingsやmappingsのJSONを記述していく感じになります。JSONとして正しいかどうかはチェックしてくれます。 Index Templateのウィザードでは、ボタンでコンポーネントを追加したり削除したり、順序を入れ替えたりといった作業が可能になっています。 また、プレビュー表示が可能なので、composed_ofで選択したものが今どのように適用されているか?といったのも確認できるようになっていました。 結構便利に管理できそうです。ちなみにスクショは7.10の画面になります。\nComponent Template周り 一覧表示とウィザード Index Template周り 一覧表示とウィザード Console(Dev Tools。OSSで利用可能) リクエストを実行は可能ですが、自動補完機能は一部のみ対応しているようです(GitHub Issue)。\n対応済みの機能\nDELETE _component_template (ただし、ここまで。存在するコンポーネント名は補完されない) 上記以外はまだ未対応のようです。 プルリクエストチャンスかも?\n参考 Composable Templates · Issue #53101 · elastic/elasticsearch What’s new in 7.8 | Elasticsearch Reference [7.8] | Elastic Index management | Elasticsearch Reference [7.10] | Elastic [Composable template] Create / Edit wizard by sebelga · Pull Request #70220 · elastic/kibana [Console] Support suggesting index templates v2 · Issue #75967 · elastic/kibana まとめ ちょっと長くなってしまいましたが、新しいIndex Templateについての紹介でした。 これまでと違い、複数のテンプレートが適用されない点があるのでそこは注意が必要そうです。 コンポーネントをうまく使えば、管理が簡易化はされそうですね。\n","date":1608216955,"dir":"post/2020/","id":"c6fc88bd57a0e57ddf22e2eb1bef892c","lang":"ja","lastmod":1608216955,"permalink":"https://blog.johtani.info/blog/2020/12/17/index_template_v2/","publishdate":"2020-12-17T23:55:55+09:00","summary":"Elastic stack (Elasticsearch) Advent Calendar 2020の18日目の記事になります。 本日の勉強会でLTをしましたが、しゃべり足りなかったんで。 Elasticsearch 7.8でこっそりとリリースされたI","tags":["elasticsearch"],"title":"Index Template V2"},{"contents":"はじめまして、pyspa。 ということで、pyspa Advent Calendar 2020の4日目(大谷コンビの2号)の投稿になります。 コンビそろってキーボード記事ですね。\n今年はDIYキーボードにはまった(はめられた?)年でした。 もともと分割キーボードには興味があり、自宅で作業するのが基本となったのもあり手を出した次第です。 まだまだ使いこなすところまでは来てないかもしれないですが、組み立てたり、問題点のキリ分けしたり、試行錯誤するのは楽しいなと。\n今回はCorne Chocolateというキーボードを組み立てたのでそちらのビルドログ(かつ今後のための教訓)になります。 LEDを使ったキーボードがどんなものなのか+薄いキーボードも気になるなということで取り組んでみました。 今回もいくつか失敗をしつつ、リカバリーして動くものができました。\nパーツ(材料) 基本のパーツは今回もKochi Keyboardさんから購入しました。\nキット : Corne Chocolate(ベースキット) キースイッチ : Kailh Choc v1 Blue (25gf リニア) 5個 キーキャップ : Kailhロープロ刻印キーキャップ ケーブル類は家に転がっていたケーブルを利用しました。 キースイッチセットもあるのですが、軽いキータッチが好みなので、一番軽いKailh ChocのBlueを試してみたくキースイッチを個別に選択しました。 キーキャップはShiroを作るときに調達していたものを利用した形です。\n今回も公式のビルドガイドにざっと目を通してから着手しました。\n準備 ビルドログにもあるようにPCBがリバーシルブなので、作業中に迷子にならないようにこんな感じで表にマスキングテープで目印をつけておきました。\n今回から耐熱ワーキングマットで作業をすることにしました。机の天板に傷つくの嫌だし。 気兼ねなくはんだできるのでおすすめです。\nhttps://t.co/0qntPD8qIa\n2ヶ月ぐらいにここで買いました!\n\u0026mdash; 西田和史(k.bigwheel) 開発基盤EM (@k_bigwheel) November 11, 2020 ダイオード、OLEDソケット、コンスルー、TRRSソケット、 こちらは前回のCorneとほぼ同様だったのでビルドガイド通りに進めます(写真撮り損ねました。。。) 前回との違いはダイオードの形です。 表面実装するタイプのダイオードなので向きに気を付けつつ、つけていきます。\nビルドガイドに向きやダイオードのつけ方が紹介されています。 拡大鏡とピンセット必須ですね。 前回同様に、ここまででいったんqmk_toolsでファームウェアをインストールして、ピンセットを使いながらキーの認識とOLEDの動作確認を行いました。 今使っているファームウェアがあるのでそれを入れて問題ないかを確認しました。\nLED実装 今回のメインイベントです(そして苦杯をなめたイベントでもあります)。 ビルドガイドにも記載がありますが、信号が流れる順番があるようなので1番から取り付けていきます。 また、ビルドガイドにLEDに関する注意事項もいくつか掲載されています。必ず読みましょう。\nこの1~6までのLEDがすごく大変でした。。。\n表面実装のLED(Underglow LED)で四苦八苦 いくつかのブログを参考にしながら作業を進めました。\nコルネキーボードを作りました ~LED取り付けに四苦八苦記~ | キオクノロンダリング SK6812miniの仕様などについて書いてあります。デバッグするのにすごく役に立ちました。 Corne Chocolateビルドログ - nokの雑記 手書きでどんな感じでやればいいのかを解説してくれています。最終的にはこの方法が一番だったのかも? 自作キーボードキット「Corne Cherry」のレビュー - 自作キーボード温泉街の歩き方 あとで出てきますが、リカバリ方法の参考になりました。 皆さん苦労されてますね、そして私も苦労しました。。。\n試してみた方法、考察は次の通りです。\nLEDチェック用のファームウェアをインストールして1つつけては動作確認 HelixのLEDテスト用ファームウェアをインストールしました。 白光 1C型こて先 失敗した後にリカバリするために購入しました。 LEDのランドなどが2Cよりも面積が小さいので、そのサイズに合わせたこて先のほうがよかったようです。 はんだの温度(温調できるはんだごて必須) 最初は250℃でやっていましたが、なかなかはんだが溶けません。そのせいで焦りも出てきます。 最終的には270度で作業しましたが、温度のせいでLEDが壊れたのはなかった気がします。1Cのこて先だったので無事だったのかもしれません。 フラックスなし あると楽だったのかも?残念ながら試してないです。 予備はんだ手法(だめっぽかった) 基盤のランド4か所に予備はんだをし、はんだを温めつつLEDを乗せる方法 LEDの裏にも予備はんだ どちらも試してみましたが、温めている個所以外のはんだと高さの違いが出てしまい、LEDが浮いてしまいます。4か所を同時に温めることはできないので、すこしずつ調整しているうちにLEDを物理的に壊してしまうことがありました。。。 ちょっとコツが分かったかも? pic.twitter.com/ruwrmEWCAe\n\u0026mdash; Jun Ohtani (@johtani) November 19, 2020 わかった気になっていますが結局失敗しました。。。\n結局最後までこれというコツはわかってない気がします。結局3つか4つのLEDがお亡くなりになりました。 うまくいかなかった原因は、予備はんだで傾きなどができ、それを修正していくうちに基盤やLEDにダメージを与えてしまったのだと思います。\nよく見ると基盤が一部剥がれかけてるのがわかるかなぁと。\nリカバリー 右手側の表面実装の4番と5番が失敗しました。\n4番目(以下のツイート右側画像の上) こちらは、1度付けたLEDをはがすときにはんだを取り除くのが不十分な状態でLEDをはがしたために、基板のランドごとはがれてしまいました。 なのでここはLEDはつかないです。。。 5番目(以下のツイート右側画像の真ん中あたりの黄色い線がつながっているLED) LED自体はつけてありますが、青色しか発光しなくなっています。 4番目が完全に死んでしまったので、無事な3番目のLEDのDINに流れている信号を 5番目のLEDのDINにも流れるようにするために10芯コードでショートカットさせました。 (リカバリ方法は先ほど紹介したブログが非常に参考になりました、先人の知恵ありがたし)。 黒い線も売っていたのですが、自戒も込めて目立つ色にしてみました。\n勉強させていただきました、、、 pic.twitter.com/Zp16fJKziM\n\u0026mdash; Jun Ohtani (@johtani) November 22, 2020 ちなみに、左側のショートカットのコードはつけた後に1か所LEDの向きが違うことに気づき必要なくなっています (上記の基盤が傷ついている画像をよく見ると上下が逆になってるのがわかる人にはわかるかも)。\n片方は導線なくて良くなった。表から見たら向きが違うのに気がついたわ、、、 pic.twitter.com/7TSDMPPxlX\n\u0026mdash; Jun Ohtani (@johtani) November 22, 2020 最終的に2か所おかしいLEDにはなりましたが、幸いにもアンダーグローです。 Kochi Keyboardさんで購入したキットのボトムプレートはFR4なのでほぼ見えません!(負け惜しみ)\nソケット さて、気を取り直してソケットをつけていきます。 Dozen0にて経験済みなのでそれほど手間はかかりませんでした。 LEDの失敗の時に1Cのこて先を購入していたため、ソケットの横の隙間からこて先が差し込めたのが便利でした(LEDでダメージを受けていたのもあり写真撮り忘れ)。\n完成 ということで完成です。デフォルトで赤く光ってます。キーキャップがLEDを透過してくれるタイプだったのがこれまたよかったですね。 作る前は光らなくてもなんて思ってたのに。\nキーマップ(v2) Corne Lightで作業を数週間ほどして、いくつか入力しにくい部分があったのでマッピングを少しだけ変えました。 相変わらず日本語キーボードベースですが、数字のレイヤーにいくつかの記号を使えるように割り当てました。 コーディングをするときに、ライブラリのバージョン(例:7.10.0とか)やIPアドレスを入力していてレイヤー切り替えのためのキーを押したり話したりするのは効率が悪すぎたためです。 数字との組み合わせでよく使いそうな以下のキーを数字のレイヤーに移動しました。\nセミコロン(JP_SCLN) コロン(KC_QUOT) アンダースコア(JP_UNDS) コンマ(KC_COMM) ピリオド(KC_DOT) スラッシュ(KC_SLSH) #include \u0026#34;keymap_jp.h\u0026#34; const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [0] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, JP_MINS, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, JP_SCLN, KC_QUOT, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, MO(1), KC_SPC, KC_ENT, MO(2), KC_RALT //`--------------------------\u0026#39; `--------------------------\u0026#39; ), [1] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LCTL, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_LEFT, KC_DOWN, KC_UP,KC_RIGHT, JP_SCLN, KC_QUOT, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LSFT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, JP_UNDS, XXXXXXX, KC_COMM, KC_DOT, KC_SLSH, XXXXXXX, //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, _______, KC_SPC, KC_ENT, MO(3), KC_RALT\\ //`--------------------------\u0026#39; `--------------------------\u0026#39; ), [2] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. KC_TAB, JP_EXLM, JP_DQUO, JP_HASH, JP_DLR, JP_PERC, JP_AMPR, JP_QUOT, JP_LPRN, JP_RPRN, JP_CIRC, KC_BSPC, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LCTL, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, JP_MINS, JP_EQL, JP_LBRC, JP_RBRC, JP_YEN, JP_AT, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LSFT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, JP_UNDS, JP_PLUS, JP_LCBR, JP_RCBR, JP_PIPE, JP_TILD, //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, MO(3), KC_SPC, KC_ENT, _______, KC_RALT //`--------------------------\u0026#39; `--------------------------\u0026#39; ), [3] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. RESET, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,\\ //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| RGB_TOG, RGB_HUI, RGB_SAI, RGB_VAI, RGB_SPI, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,\\ //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| RGB_MOD, RGB_HUD, RGB_SAD, RGB_VAD, RGB_SPD, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,\\ //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, _______, KC_SPC, KC_ENT, _______, KC_RALT\\ //`--------------------------\u0026#39; `--------------------------\u0026#39; ) }; LEDの色が変えられる!(気づくの遅い) あと、キーマップを変更しているときに4つ目のレイヤーにRGBなどのボタンがあるのに気付いて押してみたら、LEDのパターンや色を変えることができるのに気付きました。 (遅すぎでは。。。)\nキーキャップが白いのもありこんな感じの色にしてみています。\nユニコーンガンダムっぽくなった pic.twitter.com/vHxZkMrYyP\n\u0026mdash; Jun Ohtani (@johtani) November 28, 2020 まとめ ということで、失敗も多々ありましたがキーボードとしてはちゃんと動くできたものができたので安心しました。 今後、状況が落ち着いてきて自宅以外で仕事をするときにはCorne ChocolateをPCと一緒に持ち歩くと思います。 薄くて邪魔にならなくてよさそうです。\n今回もはんだっしゅ太郎大活躍でした。本当に買ってよかった。 LEDがつかないときはちょっと落ち込みましたが、これのおかげで立ち直れたのもありますし。 あとは、試行錯誤しつつLEDとかの理解ができたのも楽しかったです。 キーマップの変更時にLEDの変更などができるのに気づいたのはちょっと遅すぎたので、qmkの仕組みや割り当てられるキーにどんなものがあるのかをもう少し研究したいなと思います。\nさて、次はどんなことを試すかなぁ。\n","date":1607004824,"dir":"post/2020/","id":"a46c601d03a3a26bc418d0096fe83a42","lang":"ja","lastmod":1607004824,"permalink":"https://blog.johtani.info/blog/2020/12/03/build_corne_choc/","publishdate":"2020-12-03T23:13:44+09:00","summary":"はじめまして、pyspa。 ということで、pyspa Advent Calendar 2020の4日目(大谷コンビの2号)の投稿になります。 コンビそろってキーボード記事です","tags":["DIYキーボード","misc"],"title":"Corne Chocolateを組み立てた #DIYキーボード"},{"contents":"前回のブログのまとめに書いたように、セパレートタイプのキーボードであるCorne Light v2を作成したのでそのビルドログです。DIYキーボードとしては2つ目になります。\nまとめで書いていたお店が開店したので、購入してみました。 購入したのはこちらのKOCHI KEYBOARDさんです。 ついこの間オープンしたばっかりのお店です!\nなんで作ったの? スプリット型(セパレートタイプ?どっちが正しいんだろう?)のキーボードに興味があって、KOCHI KEYBOARDさんで買えたのがこれだったというのが大きな理由です。こういうのってタイミングだと思うので。 あとは、組み立てていくのがプラモデルみたいで面白いというのもあります。 基本的にここのところ自宅で仕事をしているので、ノートPCのキーボードにこだわる必要もないなというのも理由ですね。今後も当面は自宅で仕事になると思いますので。\nCorne Light v2 foostanさんが設計された(って言い方であってるのかな?)、3x6のサイズに親指の3キーが配置された分離型のキーボードの一種です。 シリーズ?の名前としてはCorne Keyboardと呼ばれています。 (そういえば、由来は何だろう?自作キーボードがどうやって設計されていくのかという流れがまとめられた作者の方のブログがおもしろいです。) また、基板の設計などがGitHub上でMITライセンスで公開されています。 オープンソースなハードウェアというのも面白いです。\nビルドログ 作者の方がビルドガイドを公開してくれています。ですので、こちらに沿って作業をしていきます。 ちなみに、私は今回Gateronのクリア軸を選択してみました。さらさらと入力できるのが好きなので。 サイレント軸にも興味はあるのですが、今回は実際にスプリット型のキーボードを早く触ってみたいというのが勝ちました。キーキャップについては後述します。 ツイートに都度、写真をアップしていたので組み立ては画像でお楽しみください(時々取り忘れてるけどw)。\nうむ pic.twitter.com/svW9WdzaZv\n\u0026mdash; Jun Ohtani (@johtani) October 21, 2020 刺して曲げる pic.twitter.com/M0jfQJg2k8\n\u0026mdash; Jun Ohtani (@johtani) October 22, 2020 両方できたと。ハンダまでやって今日はおしまいにすっか pic.twitter.com/HgsSrxqpcg\n\u0026mdash; Jun Ohtani (@johtani) October 22, 2020 写真取り忘れたけど、ProMicroつけた pic.twitter.com/RS4z0lqsUZ\n\u0026mdash; Jun Ohtani (@johtani) October 22, 2020 OLEDもついたと。今日はここまで pic.twitter.com/p6Z8MMP0Xz\n\u0026mdash; Jun Ohtani (@johtani) October 22, 2020 ここまでは順調です。\nOLEDがつかない? ビルドガイドに従って、この後キースイッチをつけちゃうと問題の切り分けが難しくなるということで、 ここまでの段階でQMK Toolboxを使ってProMicroにファームウェアを書き込んで、それぞれのキーのソケットの取り付け部をピンセットでショートさせつつ、キーが入力されるかどうかを見ていきます。 QMK Toolboxについてはサリチル酸さんのブログがわかりやすいので参考にさせていただきました(わかりやすい記事をありがとうございます)。 で、ビルドガイドにあるように動いてるかを確認しようとしたのですが。。。\nさて、ファームウェア書き込んだけど、OLEDがつかないな。どっかつながってないのか?\n\u0026mdash; Jun Ohtani (@johtani) October 24, 2020 ビルドガイドのようにはいかず。。。 USBでPCとつないだ状態で、QMK Configuratorをサイトで開いて、キーボード入力テストを開くと、ショートさせたキーがPC側で認識されているかのテストができます。 これで、一通りキーは認識できていそうだというのはピンセットでショートさせながら確認しました。 ただ、OLEDには何も表示されないんです。。。\n前回Dozen0を組み立てた時に、ソケットのはんだ付けが甘かったというのもあったので、 OLEDやソケットのはんだを温めなおしたりしてみて、何度か確認してみたものの特に進展がなしです。 (ちなみにうまくいかないのもあって、ぼけたツイートしたりもしてます。)\nまぁ、OLEDはビルドガイドを見てもオプション扱いなので、それよりも触ってみたい衝動に駆られて、 キースイッチをはんだ付けしていきます。\nちなみに昨晩、OLEDはとりあえず置いといてって感じでキースイッチつけてた。キーキャップはまだない pic.twitter.com/SzLmzNg60Y\n\u0026mdash; Jun Ohtani (@johtani) October 26, 2020 それも終わって、問題点の切り分けに何かできないかな?と思ってやったのがOLED単体でArduinoと接続してみて動くかどうかです。 Qiitaにちょうどいい感じの記事を見つけたのでこれまた参考にさせていただきました(4本のジャンパー線を一人で持ちながら確認するの大変だったw)。\nはんだでの修正にしっぱい で、自分の中での結論として、「OLEDソケットのはんだ付けが怪しい」となりました。 そこで、まずは外してみようかと思ったのが間違いでした。 はんだごてとはんだ吸い取り線で何とか外せるだろうと思っちゃったんですよ。 OLEDピンソケットは足が4本あって、とりあえずとれるところまではんだ吸い取り線で吸い取ってみましたが、 さすがに基盤の穴に流れ込んだはんだまでは吸い取れず、頑張って温めながらソケットを抜こうとがんばって、 ラジオペンチでピンソケットを引っ張りながら引き抜きました。かろうじて引き抜きはできたのですが、ソケットは足が折れてしまいました。\n作者登場(OLED問題の解決) そんなところにCorneの作者の方がツイートを拾ってくれたみたいで以下のような返信を頂きました。\nOLEDが点かないのはファームのせいかもしれません(最近以前のファームで動かない新しいタイプのOLEDモジュールが出回るようになりました)。お手数ですが、https://t.co/vfSBfIeeJX のブランチのものを試して頂けますか?(ただいまPRレビュー中でまだマージされていない状態です)\n\u0026mdash; c7s (@foostan) October 25, 2020 暗闇に光明とはこのことです。 教えていただいたブランチを手元でビルドしてファームウェアを書き込むと、\nすごい、出ました!右側のディスプレイにロゴが。ありがとうございます(左側のOLEDはソケットのはんだ付け直し失敗したのでもうちょっと先になりますが)!\n\u0026mdash; Jun Ohtani (@johtani) October 26, 2020 なんと、ファームウェア書き込んだ瞬間にOLEDが点くじゃないですか。 感謝感激ってやつです。お礼を言うのに便乗してOLEDの問題の切り分けの方法についても聞いてしまいました。\nOLEDリベンジ 片側は無事だったのですが、もう一方は修復が困難になったので救世主を発注します。 自作キーボードの作成に便利なものリストとして、いくつかのブログに上がっていたのですが、必要ないだろうと見送っていたツールです。\nAmazon | サンハヤト はんだシュッ太郎NEO 45Wタイプ HSK-300 | ハンダゴテパーツ 本当にすごく使いやすかったです。 OLEDのピンソケットが修復不可能だったのですが、ProMicro用に付属して余っているピンヘッダがちょうどいい長さでした。 なので、これを4本分切り取り、OLEDモジュールにつけてしまったOLEDヘッダピンを抜き取って、代わりに切り取ったピンヘッダをつかって、OLEDと基盤を直接はんだ付けすれば修復できそうだと判断しました。\nはんだシュッ太郎君を使ってOLEDについてるヘッダピンをまずは除去。 そのあとはこんな感じで繋げました。\n見にくいかもだけど pic.twitter.com/YAHoxjgppN\n\u0026mdash; Jun Ohtani (@johtani) November 5, 2020 取り外しにくくはなったけど、無事両方のOLEDが点くのも確認できました。やったー。\nヤッター、両方のOLEDがついたよー pic.twitter.com/6KLDWvnaEC\n\u0026mdash; Jun Ohtani (@johtani) October 28, 2020 キースイッチがご機嫌斜め キーキャップは別途、AliExpressで発注をかけたのですが、ここまで来たら待ちきれないですよね? ということで、手元にあった上海問屋のキーボードのキーキャップが同じMXキースイッチ用のものだったので移植しました。キーキャップ付けてみないとわかならいものですね、1つだけキースイッチがうまくはまっておらず、斜めについているのがこの時点で判明しました(ボトムプレート付けた後だったので、プレート外してから、はんだで修正)。\nちなみにキーキャップはめてる途中で、一箇所キースイッチが斜めにはんだ付けされちゃってるのを発見して慌てて直しました。 pic.twitter.com/qofHp3o4Pc\n\u0026mdash; Jun Ohtani (@johtani) October 30, 2020 無事使えるようになりました。\nアンスコが打てない&Escどこ? キーキャップ付けたので仮運用ということで、まずはデフォルトのキーマップをもとにどんな感じで入力できるのかを試してみました。 ここにも罠がw ブラウザでQMK Configuratorを開いてデフォルトのキーマップを確認しながら試し打ちをしていたのですが、どうも思ったのと違う動きをしているキーが。\nまずBASEレイヤー(レイヤー0)の右側のシフトと、LOWERレイヤーやRAISEレイヤーのEscです。 入力しているとどうも、右のシフトがEscで、レイヤーを切り替えてもTabのままだなと。 しょうがないので、OLEDが出なくてもいいのでQMK Toolboxでダウンロードしてきたものを利用したら想定通りなのにと。 きちんとqmk_firmwareの構成を理解しないままやってたつけでしたね。 結論としては、OLED用に教えてもらったブランチではキーマップが書き換わっていたようでした。 make crkbd:defautでビルドした時に利用されるkeymap.cがキーマップの定義が書いてあるファイルです。 qmk/qmk_firmwareのリポジトリにあるkeymap.cとfoostanさんにもらったブランチでは差分があったみたいでした。\nおかげで、qmk_firmwareのkeymap.cの仕組みがわかったし結果オーライです。 問題があって調べるとどんな作りになってるかとかちゃんと確認できますしね。 手順通りにやってるだけで問題が起きないと、どんな仕組みになってるのかがわからないので人に聞きまくるしかできなくなっちゃいますしね。\nこれでEsc問題は解決したのですが、アンスコがどうしても入力できません。 自作キーボード以外はすべて日本語配列のキーボードを使用しているのもあり、 日本語配列のキーボードだとどうもキーのマッピングが異なるようだと。\nググって参考にしたのはこの辺でした。\n【QMK】JPキーコードでキーマップを定義する - 天高工房 自作キーボードキット「Corne Cherry」のレビュー - 自作キーボード温泉街の歩き方 そのほかにもVIAのファームなども試したのですが、どれもうまくいかず。 色々ググってみて最終的な解決策はkeymap.cでkeymap_jp.hというファイルが読み込まれていないので、日本語用の設定とかを読み込んでみたつもりがうまく反映されていないという感じでした。\nJISにする場合、keymap_jp.hっていうヘッダファイル読み込んだほうがいいです\n\u0026mdash; Yoshi Yamaguchi (@ymotongpoo) November 3, 2020 今の時点ではこんなキーマップにしてあります。 今後も日本語配列のキーボードをベースに考えていくつもりです。\n#include QMK_KEYBOARD_H #include \u0026#34;keymap_jp.h\u0026#34; const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [0] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, JP_MINS, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, JP_SCLN, KC_QUOT, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, MO(1), KC_SPC, KC_ENT, MO(2), KC_RALT //`--------------------------\u0026#39; `--------------------------\u0026#39; ), [1] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LCTL, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_LEFT, KC_DOWN, KC_UP,KC_RIGHT, XXXXXXX, XXXXXXX, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LSFT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, _______, KC_SPC, KC_ENT, MO(3), KC_RALT\\ //`--------------------------\u0026#39; `--------------------------\u0026#39; ), [2] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. KC_TAB, JP_EXLM, JP_DQUO, JP_HASH, JP_DLR, JP_PERC, JP_AMPR, JP_QUOT, JP_LPRN, JP_RPRN, JP_CIRC, KC_BSPC, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LCTL, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, JP_MINS, JP_EQL, JP_LBRC, JP_RBRC, JP_YEN, JP_AT, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LSFT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, JP_UNDS, JP_PLUS, JP_LCBR, JP_RCBR, JP_PIPE, JP_TILD, //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, MO(3), KC_SPC, KC_ENT, _______, KC_RALT //`--------------------------\u0026#39; `--------------------------\u0026#39; ), [3] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. RESET, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,\\ //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| RGB_TOG, RGB_HUI, RGB_SAI, RGB_VAI, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,\\ //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| RGB_MOD, RGB_HUD, RGB_SAD, RGB_VAD, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,\\ //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, _______, KC_SPC, KC_ENT, _______, KC_RALT\\ //`--------------------------\u0026#39; `--------------------------\u0026#39; ) }; キーキャップが待ちきれなくて この右下のトンガリがちょっと気になる pic.twitter.com/W0A0z67cns\n\u0026mdash; Jun Ohtani (@johtani) October 30, 2020 キーキャップが待ちきれなくて上海問屋のキーキャップを付けてみて、いろいろ試行錯誤してみました。\nあー。上下関係ないのか。だからみんなこんな感じにしてるのか? pic.twitter.com/KTBlPLespr\n\u0026mdash; Jun Ohtani (@johtani) October 30, 2020 どのくらい離すのが良いか実験中 pic.twitter.com/ozK4WyBXY8\n\u0026mdash; Jun Ohtani (@johtani) November 2, 2020 キーキャップもいろいろあるのね 届いた。 pic.twitter.com/jccNW1ZcEM\n\u0026mdash; Jun Ohtani (@johtani) November 2, 2020 もう一個 pic.twitter.com/9y6qat4JiN\n\u0026mdash; Jun Ohtani (@johtani) November 2, 2020 とりあえずセミコロンの位置につけてみた。 pic.twitter.com/TDk5213IHi\n\u0026mdash; Jun Ohtani (@johtani) November 3, 2020 今はこのDSAプロファイルの青いグラデーションのキーキャップを使っています(Dukeはここにはいないですw)。 キーキャップのプロファイルはこれまた、サリチル酸さんのブログがわかりやすく書かれています(ほんとすごいなぁ。)。\n高さ調節 そのまま使っていたのですが、やはりもうちょっと奥側に高さがほしいなと。 ダイソーなどで打っているケーブルクリップがお試しには良さそうだったのでこんな感じで内側がちょっとだけ高くなるような感じにして使っています。\nこうなった。とりあえず仮運用 pic.twitter.com/VkhjawdhLM\n\u0026mdash; Jun Ohtani (@johtani) November 4, 2020 まとめ ということで、駆け足ですがCorne Light v2のビルドログでした。 いきなりフルキーボードから40%キーボードかつ異なる並びにしたので、 混乱しっぱなしですが、いい頭の運動になっているし、なにより作って動かすまでの間に いろいろと調べたり試行錯誤できたのがすごく楽しかったです。\nあとは、スプリット型+Column Staggeredになったので「c」や「b」を間違えまくっていますが、 いい気付きでした。まだまだ記号とかの入力に慣れていないですが、ちょっとずつ身に着けていけたらなと。\nただ、もう次のキーボードをDIYしたい気持ちも出てきているので困っているところです。\n書ききれてないこともあるかと思うので、ここはどうしてるの?これはどうやったの?などあれば、Tweetなりコメントなりを頂けたらなと思います。いやぁ、DIYキーボード楽しいわ。\n","date":1604503527,"dir":"post/2020/","id":"b16bddd1a6d3e5f4136446bebe7ffbc7","lang":"ja","lastmod":1604503527,"permalink":"https://blog.johtani.info/blog/2020/11/05/build-corne-light-v2/","publishdate":"2020-11-05T00:25:27+09:00","summary":"前回のブログのまとめに書いたように、セパレートタイプのキーボードであるCorne Light v2を作成したのでそのビルドログです。DIYキーボードとし","tags":["DIYキーボード","misc"],"title":"Corne Light v2を作成した #DIYキーボード"},{"contents":"ヒゲが不評だったのでいつも通りの長さに切りました。\n前回「Windowsをお試し中」と書きましたが、いくつかソフトをインストールしたりしたので現状を忘れないようにブログに残しておきます(また同じ作業する予定なので)\nインストールしたものたち 今のところインストールしたのはこの辺。 特にコメントしたいものについてこのあと明記します。\nドライバインストール from CD MX Ergoのソフトインストール。接続はコネクター Windowsアップデート Chrome Visual Studio ビルドツール(Lindera用) JetBrains Toolbox IntelliJ CLion Rider Visual Studio Code Slack Teams Google Drive共有 Gitter Divvy for Windows Zoom DeepL Sophos Twitter for Windows Office 365 AutoHotKey WSL2 - Ubuntu Windows Terminal Rustup Git for Windows wsl-ssh-agent PeaZip Speccy Hugo (WSL2のUbuntuにapt-get install hugoした) PowerToys AutoHotKey 前回のブログに書いたように、カーソル系のEmacsショートカットが体に染みついて離れないのです。 そこで、ググって見つけた記事はこちら。 AutoHotKeyというツールが Windowsに常駐して、特定のキー入力の時に、別の操作を実行してくれるツールです。\n見つけた記事にあった、https://github.com/lintaro-jp/gtk-emacs-theme-like.ahkのキーマップをもとに、いくつか変更したものを使用させていただいています。\n書き換えたのは、以下の通りです。\nCtrl+\\でIMEの切り替え(Wnn風) Ctrl+kをEmacsと同じ挙動に(もとにしたキーマップでは、カーソルから行末までが削除されてしまう) Win+sでもファイル保存(Ctrl+sと同じ挙動に。デフォルトではCortanaが起動して邪魔くさいので) すごく快適です。そのうち、もう少し自分が使いやすいようにキーマップを追加していったりするかもしれません。 特に、Macのショートカットがしみついているものについてなどです(仮想デスクトップ切り替えとか?)\nPowerToys Divvyをインストールしたのですが、グローバルショートカットがうまく動かなくていまいちでした(なんでだろ?) そこでググって見つけたのが@ITのPowerToysの記事でした。 PowerToysはMS製のOSSツールで、GitHub上で公開されています。 中には「ColorPicker」、「FancyZones」、「File Explowrer Add-ons」など、複数のツールが入っています。 「FancyZones」です。\nWindowsでは、デフォルトで、アプリにフォーカスしているときにWin+カーソルでウィンドウの配置場所をいくつか(左右どちらかに半分、4分の1(右上、左上など))に配置してくれるAero Snapというものが動いています。が、上半分などデフォルトにない柔軟な配置を設定することができません。 MacではDivvyというツールをいれて、それを実施していたのですが、先ほど書いたようにWindows版はあるものの、なぜかグローバルショートカットが動かず、システムタスクトレイのアイコンをクリックしなければいけませんでした。\nそれを解消してくれるのがFancyZonesです。 FancyZonesの設定項目で、自分で画面上にどのような割り当て領域を作るかを設定できます。さらに、マルチディスプレイ、仮想デスクトップを使っている場合、それぞれのディスプレイかつ仮想デスクトップで個別にレイアウトが設定できるようになります。 レイアウトを設定した後は、Shiftキーを押しながらウィンドウを移動すると、設定した領域が出てきて、あとは、割り当てたい領域にウィンドウを移動するだけでその領域いっぱいにウィンドウをリサイズしてくれます。 また、設定を変えることで、Shiftキーを押さなくてもウィンドウ移動するだけで領域にリサイズすることも可能です。また、Aero Snapの機能をオーバーライドしてWin+カーソルで動作させることも可能になります。\nWSL2 + Windows Terminal 三宅さんからコメントを頂いたので。\nもう少し幅広い感じですかね。あわせて Windows Terminal 使うとわりと快適です。\n\u0026mdash; miyake | ZEN (@kazuyukimiyake) October 15, 2020 なんとなく噂は聞いていましたがということで、MSのドキュメントを見ながらインストールしました。クイックスタートに則って作業するだけで特に問題なくUbuntuまで無事インストールできました。 Windows Terminalも同様です(クイックスタートで入れることになる)。\nGit for Windows + wsl-ssh-agent 少してこずったのがこちらです。 チュートリアルに記述はあったのですが、どちらで作業するのか?などが少しわかりにくかったので。ググって出てきた記事をもとに作用しました。\nRustのプロジェクトファイルをMacから丸ごとコピーしていたのですが、Git for Windowsを入れるまでは、CLion+Rust pluginの環境では、.gitファイルをきちんと認識してくれませんでした(この時WSL2と少し混同してた)。\n無事環境は用意できました。 作業の手順は以下のような感じです。 Macで使用していた.sshのディレクトリを持ってきて作業しました。\nWindows側での作業 Macから.sshディレクトリをc:\\\\Users\\johta\\にコピー Git for Windowsのインストール OpenSSHクライアントの設定 管理者権限でコマンドプロンプトを起動して sc config ssh-agent start=auto sc start ssh-agent [wsl-ssh-agent(https://github.com/rupor-github/wsl-ssh-agent)のインストール ダウンロードして.7zファイルを展開 wsl-ssh-agent-gui.exeとnpiperelay.exeをc:\\\\Users\\johta\\binに移動 c:\\\\Users\\johta\\bin\\wsl-ssh-agent-gui.exeのショートカットをスタートアップに作成 作成したスタートアップのリンク先に -setenv -envname=WSL_AUTH_SOCKを追加 Git BashでOpenSSHを利用するように設定 setx GIT_SSH C:\\\\Windows\\system32\\OpenSSH\\ssh.exe ssh-addで秘密鍵を登録 ssh-add .ssh/id_rsa WSL2のUbuntuでの作業 Ubuntuはgitがすでに入っていたのでインストールはスキップ git config --global user.name \u0026quot;Jun Ohtani\u0026quot; git config --global user.email \u0026quot;メールアドレス\u0026quot; mkdir .ssh .bashrcの最後行にwsl-ssh-agentのWSL2 compatibilityにあるexportからfiまでをコピー。この時、パスを自分のパスに変更すること(私の場合$HOME/winhome/.wslの部分を/mnt/c/Users/johta/binに書き換えました) これで、WSL2側では.sshのファイルを管理しなくても、Windows側のOpenSSHに接続してssh周りの処理をしてくれるようになりました。\nPeaZip wsl-ssh-agentが.7z形式で圧縮されていたので、ダウンロードしました。 とりあえずこれを入れてみたのですが、ほかにお勧めがあれば教えてほしいです。\nSpeccy CPUの温度やスレッドごとのCPU使用率などを見てみたいので入れてみました。 これもとりあえず入れてみた感じなので、ほかにお勧めのソフトがあれば教えてもらえればと。 リソースマネージャーでもスレッドごとのCPU使用率は見れたのですが、温度が見れなかったので。\nHugo + WSL2にあるUbuntuにsudo apt-get install hugoしてインストールしました。\nそこで、VS Code の Remote Extension です。WSL2 から ‘code’ で起動できます😎\n\u0026mdash; Daiyu Hatakeyama@Microsoft, Hack in ChatGPT (@dahatake) October 17, 2020 あとは、畠山さんに教えてもらったVSCodeのRemote - WSLを入れて、 WLSに接続した状態でVSCodeを起動して記事のMarkdownを書くと、VSCodeのターミナルを開くとWSL2に接続してくれて、hugoコマンドが実行できます。\nまとめ とりあえず、ブログが書ける環境ができました。 Mac上にあった各種プロジェクトのディレクトリをコピーして、Rustの開発もできるようになりました。\n今後も環境構築は続いていきます。Javaとか入ってないし。 SDKMan使ってたけど、切り替えどうしよう?とか。\nそういえばSDKMAN!をJDK切替に使ってたけど、結局windows側のパスは通らんので自力インストールになった。scoopがよさげ\n\u0026mdash; きしだൠ(K1S) (@kis) October 17, 2020 IDE系から呼び出すターミナルはWSL2がいいなぁとか。\nhttps://t.co/X4Jj4tih1I\n\u0026mdash; そーだい@初代ALF (@soudai1025) October 17, 2020 ほかにもおすすめなどがあれば教えてください!\n","date":1603029710,"dir":"post/2020/","id":"188c1ee5132a6752dfce5a0235354070","lang":"ja","lastmod":1603029710,"permalink":"https://blog.johtani.info/blog/2020/10/18/restart-windows-no1/","publishdate":"2020-10-18T23:01:50+09:00","summary":"ヒゲが不評だったのでいつも通りの長さに切りました。 前回「Windowsをお試し中」と書きましたが、いくつかソフトをインストールしたりしたので","tags":["misc","windows"],"title":"Windowsへの移行(その1)"},{"contents":"ヒゲが伸びてきて(試しに伸ばしてる)不評を買っている今日このごろです。\n自宅で作業することが多くなってきたので、自作PCでもと思っていますが、OSをどうしようか悩み中。 とりあえず、試しにWindowsにしてみるかということで、10年ぶりくらいにWindowsに帰ってきました (この文章はMacで入力してますが)。\nむかしむかし もともとはWindowsを使っていたのですが、Win7くらいに32bitと64bit混在の時期に、 Xkeymacsを利用するときに少し手間がかかるなぁと思ったのもあり、Macに移行しました。 Macだと自分がよく使うEmacsっぽいショートカットがデフォルトいろんなアプリで使用できる利点があったからです。\nただ、最近、TL上で光るPCとかを見てしまったのもあり、 自作PC(どちらかというとDIYかな?)熱が復活しました。 まだ、OSをWindows、Ubuntuのどちらをメインにしようかな?と悩んでいるところではありますが、まずはWndowsをちょっと試してみるかなと。\nまずは、やりたいことをちょっとリストアップしておこうかなと思います(きっと、先人の知見が集まってくるはず!)。\nどうしてもほしい機能 大学の頃にSunOSやSolarisを使用し、Emacsでメールを読んだしていたせいで、Emacsのショートカット操作が体から抜けない状態です(抜こうとしてないという話もあるが)。 ですので、社会人になってからWindowsを利用していたときはXkeymacsというソフトのお世話になっていました(神アプリでした。まだあるのかな?)。\nショートカット操作とか カーソル移動(必須) 上下左右:Ctrl+n、p、f、b 行頭、行末:Ctrl+a、e 編集 デリートキー:Ctrl+d Ctrl+hがバックスペースだけど使わないな、そういえば カーソルから行末までをカット:Ctrl+k 必須! カーソル移動がホームポジションから移動しなくてもいいのもあって、多用してしまっています。 これ、WindowsとかUbuntuでいい感じにできるのあるのかな? できれば、IMEやブラウザのURLのサジェストなどもこのカーソル移動で移動できると嬉しいです。 (昔はM-%とかで置換などもやってたけど最近はやらないな。)\nデスクトップ操作系 仮想デスクトップ やることごとにデスクトップを切り替えて使うので ウィンドウのリサイズ? DivvyというアプリをmacOSで利用中 自分で登録したサイズ(例:画面右半分)にウィンドウサイズを変更などがショートカットで可能 仮想デスクトップはあると思うけど、ウィンドウのリサイズの便利なツールあるかなぁ?\n利用するアプリ SNS、オンラインミーティング Twitter macOSではTweetDeckと夜フクロウを使用 Slack ネイティブアプリ Gitter ネイティブアプリ Chatwork ブラウザ Teams ネイティブアプリ Zoom ネイティブアプリ Google Meet ブラウザ Discord ネイティブアプリ(最近使ってないな) 色々使ってますが、最悪ブラウザで使う感じかな?\nオンラインストレージ Google Drive 同期アプリ使ってる Dropbox あんまり使ってない 開発系 JetBrainsのIDE Toolbox App IntelliJ CLion + Rust plugin Rider zsh macOSで標準になったから コマンド系 git SDKman ant gradle JDK Rust Hugo Jasper GitHubのIssueとかを見るネイティブアプリ 自分が関連しているIssueとかが楽に見える(メールだと埋もれてしまう) エディタ Visual Studio Code 開発系では?と思われるかもだけど、Markdownエディタとして使ってる Emacs by Homebrew 最近は起動してない その他 カレンダー macOSのカレンダーで複数のGoogleカレンダーを取り込んでる ScanSnap Ubuntuで使えるやつあるのかな? Mac miniにつないであるので、画面共有とかで入れればそれでOK 画面共有 winやubuntuからMac miniとか見えるかな? キーボード共有 macも使うので、KVMスイッチとかかな? マウス共有 MX ErgoのFlowを使うと行き来が簡単にできたので良さそう。 ただし、Ubuntuだとどうなるのか? システム監視系 CPUの温度とかCPU、メモリの使用率とか まとめ とりあえずこんなところです。カーソル移動系が一番重要なので、そのへんから色々とちょっとずつ試していく予定。 ぜひオススメアプリとかあれば教えていただければと。\n","date":1602727442,"dir":"post/2020/","id":"de37d9fae011687eb1eb5a127fcb89e3","lang":"ja","lastmod":1602727442,"permalink":"https://blog.johtani.info/blog/2020/10/15/restart-windows/","publishdate":"2020-10-15T11:04:02+09:00","summary":"ヒゲが伸びてきて(試しに伸ばしてる)不評を買っている今日このごろです。 自宅で作業することが多くなってきたので、自作PCでもと思っていますが、","tags":["misc","windows"],"title":"Windowsをお試し中"},{"contents":"今年の春くらいから、セパレートタイプのキーボードが気になっています。 また、なんか知らないですが、Twitterのタイムラインが自作キーボード(DIYキーボード)で盛り上がってる気がします。 (たぶん、気になってるから余計目についてる)。 これとか。このスライドから、自分がやってるのは「まだ」DIYキーボードだなということで、タイトルに使ってみました。\n#toruby \u0026quot;DIYキーボードは実質Ruby\u0026quot; 本日のスライドです! とちぎでこの話をできてよかった!!!q: https://t.co/RJot71Ngu9\n\u0026mdash; Kakutani Shintaro (@kakutani) September 12, 2020 セパレートタイプのキーボード 今年の夏まではMac Book Pro 16インチのキーボードを利用していました(参考:自宅の作業環境(2020))。 これまで、自宅で作業することよりも、外で仕事をすることが多く、また、外といっても様々な場所(サムライズムだったり、オフィスだったり、カフェだったり)で作業をすることが多かったので、ノートPCのキーボードにしていました。流石にキーボードを持って歩くほどは気にしていなかったので。\nただ、コロナウイルスの影響もあり、ほぼ自宅で作業することとなりました。 となると、前から気になっていたセパレートタイプのキーボードが俄然気になり始めます。 (といいつつ、寄り道してたりしますが)\n気になっていたのはこのあたりなのですが、\nErgodox EZ Moonlander Mark I 流石にいきなり行くにはちょっと気が引けるなぁと(なかなかいいお値段)。 また、自分が日本語キーボードを利用しているというのもちょっとあります。\nキースイッチの感触を知りたくて ただ、日々、楽しそうな自作キーボードの記事や画像が流れてきます。 で、思い出したのが自分の趣味。プラモデルです。色を塗ったりはしないですが、組み立てるのは楽しいなと。 じゃあ、趣味と実益を兼ねればいいのでは?(ほんとか?)となり、作る気になってきました。\nただ、全く知らない世界だし、どんなものなんだろう?と。 市販のキーボードでも、キーの押し具合が色々合ったり、形もまちまちです。 また、このご時世ですので、自宅からあまり出ていないので遊舎工房さんなどに遊びにも行けず。\nそんなところに流れてきたのがキースイッチのテスターでした(世の中誘惑だらけ)。\nスイッチテスター人気スイッチ詰め合わせ 18個セット 「なるほど、これでどんな感触かわかるじゃないか!」と、気づけばポチッと押していました。。。 届いて、「ふむふむ、これがこういう感触なのか。なるほど」ポチポチ押しながら、さらに自作キーボードについて調べていきます。\nいろんな感触なんだなぁ pic.twitter.com/PaGDMIRJiv\n\u0026mdash; Jun Ohtani (@johtani) September 22, 2020 キースイッチのストロークの深さを知りたくて まぁ、当たり前なのですが、先程のキースイッチテスターどこにもつながっていません。 キーボード触ってるとわかりますが、ストロークが違いがあるんですよ。 ただ、これだとわからない。けど知りたい。\nで、ググっているとArduinoを使ってLチカやってる人とか、キー入力させている人がいるじゃないですか。 これでは?そういえば、Arduinoもどきうちにもあるぞ?と。 で、準備をしていたときに見かけてしまったのがこのツイートでした。。。\nhttps://t.co/ALl7OcRVRa 高機能テスターとしてもおすすめ\n\u0026mdash; Kakutani Shintaro (@kakutani) October 4, 2020 やられてしまいました。。。\ndozen0作りました ということで、前置き長かったですが、Dozen0というキーボード(マクロパッド?)を遊舎工房さんから購入して作ってみました。 手順はビルドガイドという形でまとまっています。\n基本的にはこれに沿って作成しました。\nパーツと手順の確認 さてと。 pic.twitter.com/GTBJ7zDleN\n\u0026mdash; Jun Ohtani (@johtani) October 10, 2020 まずは入っているパーツがきちんとあるか確認します。 また、ビルドガイドでどんな作業があるのかをざっと眺めておきます。 まぁ、プラモデルといっしょですよね。\nキットにはキースイッチとキーキャップは含まれていません。これはご注意ください。 私は、キースイッチテスターとして入手していたキースイッチとキーキャップがどんな押し具合なのかを確認したかったので特に問題ありません。\nハンダづけ Amazon | 白光 ダイヤル式温度制御はんだこて FX600 | ハンダゴテ Amazon | 白光 こて先 2C型 T18-C2 | ハンダゴテパーツ Amazon | 白光(HAKKO) セラミックヒーターはんだこて専用こて台 クリーニングスポンジ付き FH300-81 | ハンダゴテパーツ Amazon | goot(グット) 高密度集積基板用 鉛入りはんだ Φ0.6mm スズ60%/鉛40% ヤニ入り SD-60 | ハンダゴテ はんだ付け用に揃えた道具です。「自作キーボード ハンダゴテ」とかでググると出てきたものがこれだったので。 デフォルトのコテ先ではなく、2Cのコテ先に付け替えてから作業を開始しました。\n私の持っていたソケットはCherry MX系なのですが、気が向いたらKailh Chocも試したくなるかも?ということで、 すべてはんだ付けしました。本格的にはんだ付けしたのは大学以来だからもう20年近く経ってますね。 ソケットの足をプリント基板にはんだ付けするのですが、2Cのコテ先が大きくなかなか手こずりました(これがこのあと問題を引き起こしました)。\nソケット、リセットスイッチ、ProMicroをはんだ付けすればはんだの作業は終了です。\npic.twitter.com/jjUo162n54\n\u0026mdash; Jun Ohtani (@johtani) October 10, 2020 pic.twitter.com/p5atvtHfFN\n\u0026mdash; Jun Ohtani (@johtani) October 10, 2020 スイッチの取付と組みたて 試したいキースイッチを選んでトッププレートにつけていきます。\nキーテスターからスイッチとキーキャップ持ってきて完成。動作確認はまだなのでまた、最初に戻るかもだけど、、、 pic.twitter.com/ZmBd3bgOKI\n\u0026mdash; Jun Ohtani (@johtani) October 10, 2020 組み立ても終わり次は実際の動作確認です(ツイートしていますが、予想通りの展開でした)。\nファームウェアの書き込み USBで接続して、ファームウェアの書き込みです。 書き込み手順はビルドガイドにありますが、QMK Toolboxの使い方やQMK Configuratorの使い方は以下のサリチル酸さんのブログがわかりやすかったです。\n(初心者編)自作キーボードにファームウェアを書き込む (初心者編)QMK Configuratorを使ってキーマップを書き換えよう 実際に書き込んで動かしてみると。。。。\nうーん、上半分が死んでる気がするなぁ。\nデフォルトキーマップの書き込みはできたけど、カーソルの上とかバックスペースが入らないw\n\u0026mdash; Jun Ohtani (@johtani) October 10, 2020 とりあえず、もう一回確認してみた。デフォルトのキーマップで、「Cut」「Paste」が強く押さないと入力されない。UpとDeleteは動くようになってた。CopyとBkSpがうんともすんとも言わない。下段のキーは全部動く。https://t.co/zEyINdAK6t\n\u0026mdash; Jun Ohtani (@johtani) October 10, 2020 といった具合に上半分が動作があやしいです。\n再度、はんだ付け ということで、ネジを外して上の段のソケットをはんだで温めてみると、片側だけ温めるとはずれるじゃないですか。 どうやら、うまくソケットの足が基盤にはんだ付けできていなかったようです。 この時、最初に作業したときに2C型のコテ先が大きくて、ソケットの足に入らなかったのを思い出したので、 最初にはんだごてについていたコテ先に戻してから作業をしました。 これだとソケットの足の隙間に入るんです。ということで、挙動のおかしい上段のソケットをすべてつけ直したところ無事動作しました。\n上の段、全体的にソケットがうまくはんだ付けできてなかったみたいだった。今回はMX系のスイッチしかないので、Kailh Chocのソケットの導通は未確認。ざっとブログにまとめるか。\n\u0026mdash; Jun Ohtani (@johtani) October 10, 2020 現在のキーマップ これが今のキーマップです。仕事中のBGMをラズパイ4の音楽プレーヤーで流していますが、 部屋から出るときや、打ち合わせがあるときに音楽の停止、開始などを画面共有経由でやっています。 が、わざわざマウス移動するのもめんどくさいなと。これに使えそうだというのもあったので、Dozen0を購入したというのがあります。 残念ながら、Prev Trackとかがうまく動かないので、ショートカットを調べてキーマップ書き換える予定ですが、非常に便利になりました。\nまとめ ということで、Dozen0を作ってみましたが、楽しかったです。すんなりと行かなかったのがまた良かったです。 試行錯誤して動いたときの喜びが何倍もありました。また、キースイッチの感触も知ることができました。 たぶんGateron Silentクリア軸もしくは赤軸くらいが良さそうだなぁと(こうやって沼へ。。。)。 キーマップの仕組みを調べたり、もっと面白い使い方できないかな?と探りつつ、次のステップに進もうかなと。\n次は本格的なセパレートタイプのキーボードを作る予定です。が、お店のオープンを待ってからということになってます。はやくオープンしないかなぁ!!\nがんばって!!\n\u0026mdash; Jun Ohtani (@johtani) September 29, 2020 ","date":1602428006,"dir":"post/2020/","id":"c377351433a941a927aab543931f6026","lang":"ja","lastmod":1602428006,"permalink":"https://blog.johtani.info/blog/2020/10/11/build-dozen0/","publishdate":"2020-10-11T23:53:26+09:00","summary":"今年の春くらいから、セパレートタイプのキーボードが気になっています。 また、なんか知らないですが、Twitterのタイムラインが自作キーボード","tags":["DIYキーボード","misc"],"title":"Dozen0を作成した #DIYキーボード"},{"contents":" 2020/10/06 11:00くらいにマージされました。\n@minoru_osuka さんが開発を引き継いだLinderaというKuromojiのRustクローンがあります(リポジトリ) 。 最近趣味でRustを勉強しているので、こちらを少し手伝っています。\nRustの勉強仲間である@takuya_bさんや@ikawahaさんと話をしているときに、FST部分をDouble Array Trieに置き換えると速度が向上するのでは?という話が出まして、@takuya_bさんがDouble Array Trieを作るらしいという話になったので、下準備などをしつつ、作ってもらったライブラリyadaを組み込んでみたという話です。\nベンチマークの追加 下準備として、今のLindera(FST実装)がどのくらいの性能なのか?というのを計っておく必要があります。 幸いにも、Linderaのオリジナルの開発者の方が、criterion.rsというライブラリを使ったベンチマークプログラムを作成してくれていました。\nただ、1種類だけだと少し心もとないなというのと、長い文章やパターンを増やしたほうが良さそうだなということで、 ベンチマーク自体をいくつか追加しました(追加したときのPR)。\n種類としては、5種類のベンチマークです。\nシステム辞書のみのTokenizerのコンストラクタ呼び出し カスタム辞書ありのTokenizerのコンストラクタ呼び出し システム辞書のみのTokenizerのtokenize処理の呼び出し カスタム辞書ありのTokenizerのtokenize処理の呼び出し 青空文庫の坊っちゃんのテキストをシステム辞書のみのTokenizerでtokenize 1,2はコンストラクタ部分だけの処理をベンチマークテストする目的で作成しました。 LinderaはTokenizerがtokenize処理するのに利用するデータをいくつか内部で保持しています。 これらはファイルにシリアライズされており、Tokenizerのオブジェクト生成時に読み込みやデシリアライズ処理が発生します。 この部分だけも速度を計測したい目的でコンストラクタだけを切り出しました。\n3,4はTokenizerのメインの処理です。コンストラクタはベンチマークの対象外にしました。 純粋にtokenizeの処理だけを切り出して計測するためです。 カスタム辞書がある場合、ない場合は念の為切り出した形になっています。\n5は長い文章(文章が多いのでバリエーションも増える)を扱いたいために別にしました。\nこれで、一応下準備が完了です。 ちなみに、Criterionは賢くて、前のベンチマークの結果と最新の結果を比較してくれる機能があります。 どんな感じで出てくるかはベンチマーク結果をご覧ください。\nyadaの組み込み ベンチマークの準備をしていたところyadaがリリースされたので、Linderaへの組み込みを検討し始めました。\nというわけで、またダブル配列を書いてしまったので crate として公開しました。フィードバックお待ちしております! https://t.co/As7h0tfmjf\n\u0026mdash; takuya-a (@takuya_b) September 20, 2020 中身の理解 lindera-fstを利用して、prefix searchしている処理があるので、そこで利用しているFSTをyadaに置き換えれば良さそうだと判断して、 処理を読んでいきます。\nTokenizerは、PrefixDictという構造体でlindera-fstを利用している prefixメソッドが入力文字列を元に、FSTを前方一致検索して、ヒットした単語の情報をIteratorとして取り出せる(単語の情報は「入力文字列の先頭からの文字数」と「ヒットした単語のWordEntry構造体」) PrefixDictのfstは辞書(例:ipadic)ごとにlindera-\u0026lt;辞書名\u0026gt;-builderで生成される システム辞書としては、デフォルトではlindera-ipadic-builderでfstを構築している 構築処理はこの辺 という感じです。 また、辞書周りのファイルがそれぞれどんな役割なのか、どんなデータの持ち方をしているのか?といった点を、変更点の調査のついでに書き出してみました。lindera-dictionary/FILES.md。TODOになっている部分も追記が終わっています(PR)\n変更点 実際に変更したプログラムの詳細についてはのPRを見ていただくとして、簡単には以下の点になります。\nRustのバージョンを1.46.0に(おもにREADME.md) yadaが利用している機能に1.46.0で導入された機能があるため lindera-fstをyadaに変更(lindera-core/Cargo.toml, lindera-ipadic-builder/Cargo.toml) 合わせて、dict.fstというファイル名をdict.daに変更 dict.daに関して構築部分と検索部分を変更 FSTではFSTから返ってくる値(入力文字列に出てきた単語に関連する値)はu64だったが、yadaのDoubleArrayがu32しか扱えないため、u32に変更。テストの記述はしていないが、扱うデータ的にu32で問題なさそうだったので。 検索部分:PrefixDict構造体のprefixメソッドでDoubleArrayのprefix_common_searchを使用 DoubleArray自体がprefix_common_searchのメソッドを持っていたので、処理が簡単に置き換え可能だった。FSTはprefixメソッド内で独自で前方一致検索を実装していた。 構築部分:lindera-ipadic-builder/src/lib.rsのbuild_dictとbuild_user_dictのdict.da構築処理 ipadicのCSVファイルを読み込んで、見出し語をキーに、辞書にある単語情報のベクタを値とするBTreeMapを生成し、このBTreeMapに基づいてFSTを構築していた部分をDoubleArray構築処理に置き換えた。 シフト演算などで、実際の値(dict.vals)へのポインタを作っていたのだが、ここの処理を読み解くためにFILES.mdを書き出した。 という感じです。そもそもデータ構造がどうなっているのか?から読み解いて、変更部分を洗い出して変更していった形になります。 取り込み作業中にいくつかyadaに要望(このへん)を上げて、変更を取り込んでもらい、最終的にyadaのバージョン0.3.2で問題なく動きそうだという形になりました。@takuya_bさん、対応ありがとうございました。\nエッジケースバグの発見 作っててよかった、テストケースでした(実際にはベンチマークテストですが)。 取り込み作業中に、Lindera本体のcargo testはすべてOKになるが、ベンチマークを取ろうとしたときに、坊っちゃんの文字列を入力にしたベンチマークが失敗するという事象が発生しました(PRのコメント参照)。 切り分けのために、入力の文章のどこでおかしくなるのか?DoubleArrayのbuildメソッドに渡している値がおかしくないか?などをすこしずつ調べていくと次のバグが判明したという感じです。\n特定のデータ(ipadicの見出し語一覧)をDoubleArrayに入れて、特定の文字列(「は相」)をcommon_prefix_searchにいれたら、 返ってくる情報(0から何バイト目の文字が一覧に存在した)が、不正な値が返ってくるというバグでした。 @takuya_bさんに見てもらいつつ(DoubleArrayの中身わからん。。。)、修正してもらいました。素早い対応ありがとうございます。\nyada 0.3.1 をリリースしています。特定の条件で不正な遷移を許すダブル配列が構築されてしまうバグを修正しています。このエッジケースは @johtani さんが見つけてくださいました。ありがとうございました! https://t.co/CiftZi5GDn\n\u0026mdash; takuya-a (@takuya_b) September 30, 2020 やはり、いろんな文字列入れてテストしてみるの重要ですね。 ということで、ベンチマークだけでなく、テストケースとしても坊っちゃんのファイルを読み込んでトークナイズするようにPRでテストケースを追加しています。\nベンチマーク結果 yadaを利用した変更が終わったので、再度cargo benchを実行して計測です。 計測としては、masterブランチでまずcargo benchを実行し、yadaの実装をしたブランチに切り替えてからcargo benchを実行します。 すると、Criterion? cargo benchが、最終的な結果に前回との差分でどのくらい性能が改善、改悪したかも合わせて出力してくれます。 実行環境と結果は以下のとおりです。\nMacBook Pro 16インチ CPU:Core i7 6コア 2.6GHz メモリ:32GB コンストラクタのベンチマークについては10%ほど性能が悪くなっています。 これは、FSTよりもDoubleArrayTrieのほうがデータが大きくなってしまうためだと思われます。 実際にファイルのサイズは次のようになりました。yada(DoubleArrayTrie)のほうが2倍以上大きいことがわかります。 また、このファイル以外にもLinderaが利用しているデータはありますが、それらは今回変更の対象にはなっていません。 なので、単純にこのファイルの読み込みの処理に時間がかかっているのだと想像できます。\n2147765 / FST / dict.fst 5425152 / yada / dict.da tokenizeのベンチマークについては、11%〜28%の改善が見られました。 文章から、内部に保持している辞書に存在する単語を見つけ出す処理に利用されるのがFST、DoubleArrayTrieです。 今回の変更では、この処理に利用しているデータ構造だけを変更しました。 実際には\nDoubleArrayTrieを用いた単語の検索処理 見つかった単語の持つ値(data.valsのオフセット情報)を元にシフト演算 といった処理が実行されます。シフト演算はu64だったものがu32に変更されたくらいなので、大した処理量ではないかと。 大部分はDoubleArrayTrieを利用したルックアップ処理が速度向上に寄与していると思います。\nまとめ 最近Linderaに加えた変更、作ったPRについて少しブログにまとめてみました。 ちなみに、まだPRの段階でレビュー\u0026amp;リリース待ちという感じです。\n実際には作ってもらったライブラリを組み込んでみたというだけなのですが、速度が向上した結果が見れたのは面白いです。 また、基本的なデータ構造とかアルゴリズムの勉強にもなりました(2次元配列を1次元配列に押し込むとか)。このへんも今後も勉強していきたいです。\n組み込む際に色々と協力していただいた@takuya_bさん、@ikawahaさん、巻き込んでくれた@minoru_osukaさんに改めて感謝いたします。\nRustや形態素解析のプログラムの勉強を兼ねて、今後もなにか改善できる部分がないかなどを見ていこうと思っています。 Rustで形態素解析をしたいという人がどのくらいいるかはわかりませんが、おかしなところや疑問点などあればコメントください。\n","date":1601865378,"dir":"post/2020/","id":"15932a656f7acfac897d27766eadc9e2","lang":"ja","lastmod":1601865378,"permalink":"https://blog.johtani.info/blog/2020/10/05/switch-fst-2-da/","publishdate":"2020-10-05T11:36:18+09:00","summary":"2020/10/06 11:00くらいにマージされました。 @minoru_osuka さんが開発を引き継いだLinderaというKuromojiのRustクローンがあります(リポジトリ)","tags":["Rust","Lindera"],"title":"LinderaのFSTをDoubleArrayTrieに変更した話"},{"contents":"先日は「検索システムを構成するパーツ」ということで検索システムを構成しているパーツについて書いてみました。\n大体、検索がうまくヒットしないといった場合に、問題になるのがコンテンツ自体のデータもしくは、転置インデックスのキーワードだったりします。 そこで今回は、前回のパーツの「データソース・コンテンツ」周りについて少し書いてみようと思います。言葉の定義、それぞれがどんなことをやるのか、とりあえず導入したあとにコンテンツ周りでどんな改善ができるかなどを書いてみます。\n言葉の定義 コンテンツ 実際に検索させたいデータになります。 コンテンツにはWebページ、データベースのレコード(CMSで登録されたデータなど)、ファイルサーバーにある文書(PDF、Word、Excelなど)などになります。\nデータソース コンテンツのマスタデータが保存されている先です。 よくあるデータソースとしては以下のものが考えられます。\nWebサイト - 自社もしくはインターネットに存在しているWebサイトです。 ファイルサーバー - ローカルネットワーク上のファイルサーバーもありますが、最近ではGoogle DriveやDropboxといった外部のWebサービスもあります。 RDB - CMSや自社システムでのデータの保存先です。 クローラー コンテンツをデータソースから収集してくるプログラムのことです。 Webサイトやファイルサーバーからコンテンツを収集して検索エンジンに登録するところまでを担当します。 RDBにあるデータを検索エンジンに登録する場合はクローラーがデータを登録するというよりは、RDBにデータを登録するシステムが検索エンジンに登録する機能を持っていることが多いです。\nデータの収集と登録 収集 クローラーを使用した収集の場合は、サービスの特性とデータソースによって、どの程度の頻度でクロールするのか、クロール対象はどこまでか?といったものを決める必要が出てきます。 これらが決まれば収集ができるかと(他に権限とかもありますが。)。 収集コンテンツは、そのままでは利用しにくかったり、利用できないことがあるので、次はデータの変換を行います。\nデータ変換 コンテンツはそのままの形では検索エンジンには扱いにくいデータ形式である場合があります。\nWebページの場合 Webページの場合、コンテンツにはHTMLタグが入っていたり、JavaScriptなど検索対象にはしたくないデータなどが入っています。これらを除去して、検索させたいものを取り出す必要があります。 また、Titleタグなど、いくつかメタデータとして扱えるものがHTMLで規定されているので、これらを別の項目として取り出して個別に検索できるようにすると便利です。 HTMLをパースしてデータを抜き出す処理ができるライブラリなどがあるので活用します。\nファイル PDFファイルなど、ファイルの場合もメタデータと呼ばれるファイル自体が持っている情報が存在します。作成者、更新日時、ファイル名、パスなどです。 これらも検索時に有効な情報になります。 また、ファイルから文字列を抜き出す処理も必要になります。 それぞれデータフォーマットが異なりますので、そのフォーマットに合わせて文章データを抜き出す処理が必要です。OSSや製品がありますので、それらを利用して、ファイルから文章を抜き出します。\nRDB RDBのデータの場合、データが正規化されています。 検索エンジンでは、非正規化のデータを登録して検索することが基本となるため、まずは非正規化して取り出す必要が出てきます。\n例えば、ジャンルやカテゴリ、各種IDなどが実際のコンテンツのレコードに入っていると思いますが、これらをユーザーが入力したキーワードで検索したい場合などは、IDではなく表示名を取り出して、検索エンジンに登録する必要が出てきます。\nその他 データごとの変換処理について説明しました。 その他に、データのクリーニング処理などと言ったことも必要になってきます。例えば、HTMLのタイトルに必ずサイト名が入っているが、除去したいといった場合や、検索エンジン固有のデータの前処理などもあります。\n登録 最後は検索エンジンへの登録です。 最近の検索エンジンはJSON形式でデータを受け取る場合が多いので、JSONに変換することが多いです。 基本的には各種プログラミング言語のライブラリが用意されているのでこれらを利用するのが基本となります。\n検索したい項目、検索させたい方法などを洗い出し、必要なデータを作成して検索エンジンに登録します。 登録と書いていますが、更新、削除などもここでの対象となります。\nここまでの流れで、データソースからコンテンツを取得し、変換して、検索エンジンへの登録が終わりました。\n検索の改善 検索のログから分析して改善していくのが良いですが、ユーザーからの質問や意見などからも改善すべき点が見えてくると思います。 検索ログでは、次のようなものを元に、検索がうまく行かないものを見つけ出します。\n0件ヒット 0件クリック ヒットしていない検索ワードがある場合、コンテンツに問題がある場合があります。まずはこのあたりをとってみるのが良いかと。 そもそも、入力されたキーワードにマッチするコンテンツを扱っていないこともわかりますし、入力されたキーワードに似た単語を持ったコンテンツなども存在するはずです。 類義語の辞書を用意して、検索にヒットできるようにするといった分析と改善にも利用できます。\nあとは、検索エンジン側の話ですが、形態素解析器などを利用している場合に、意図した区切りになっていないために、うまくキーワードがヒットしないと言ったこともあります。\nコンテンツの理解 実はこれが一番だったりします。 どんなコンテンツを自分たちが扱っているのか?どんなデータがどういった項目でコンテンツに入っているのか?といったところから、 コンテンツのデータを元に検索にヒットさせる方法が改善できます。\nCMSなど人が入力したデータをコンテンツとして扱う場合、入力画面を改良することで、望んでいるデータを入れてもらえたり、不要なデータが入らなくなる可能性があります。 例えば、ECサイトなどで商品の説明文やタイトルにいろいろなキーワードが入っている場合などがあります。むりやりどんなキーワードでもヒットさせたいという入力者の意図もあるのですが、検索しているユーザーにはノイズになることも多いです。適切にカテゴリやジャンル、属性といった項目に分けることでおかしな入力データを減らすことも可能です。\nWebサイトなどをクローリングしたものの場合は、サイトごとに文章の特徴があったり、重複している部分などが合ったりする場合があります。 これらもコンテンツをよく調べることで、不要な情報を除去したりといったことが可能になります。\nまとめ 簡単ですが、検索のデータソースやコンテンツにまつわる話を紹介しました。 もちろんここでは紹介しきれていない項目がいっぱいあります。 また、具体例ではなく概略をざっくりと書いているのでわかりにくい場合もあるかもしれません。 すこしユースケースを絞り込んで書いたほうがわかりやすくなるのかも?\n次はUIとか書くかも?\n不明点とか疑問点、指摘事項などあればコメントしていただければと。 要望などもお待ちしております。\n","date":1600136614,"dir":"post/2020/","id":"b2c4cf0fb96d02d37f03668caaecbc57","lang":"ja","lastmod":1600136614,"permalink":"https://blog.johtani.info/blog/2020/09/15/improve-search-no3/","publishdate":"2020-09-15T11:23:34+09:00","summary":"先日は「検索システムを構成するパーツ」ということで検索システムを構成しているパーツについて書いてみました。 大体、検索がうまくヒットしないとい","tags":["検索"],"title":"検索対象のデータとデータソース(検索システムに関する妄想その3)"},{"contents":"自宅環境に少しアップデートがあったので更新版です。 お客さんのおかげで相変わらず自宅で作業させてもらってるのもあり、昨今のコロナウイルスの影響で出かけることもないので、自室の作業環境が更新されている感じです。 前回のブログはこちらです。 前回のまとめで触れていた2点について更新されています。\nまずは、現状のデスクの上の写真です。\n基本的には前回紹介したものと大きくは変わっていません(?)。 変わったものについて紹介していきます。\nデスク 先程の写真ではちょっとわかりにくいですが、スタンディングデスクになりました。\nタイマーついてるの便利 pic.twitter.com/E9engTIMnM\n\u0026mdash; Jun Ohtani (@johtani) April 30, 2020 Flexispotの天板と足の組み合わせにしました。 前のElectaの天板が明るめの色だったのもあって、メープルの天板です。 組み立てはちょっと大変でした。 足が重たいのと、天板にはネジ穴がなく電動ドライバーもないので、ネジ締めと机を起こすのがちょっと大変です。子供に手伝ってもらいながら組み立て設置をしました。 オンラインミーティングなどのときには基本、立って作業しています。 あとは、デフォルトのタイマー設定のままですが、45分ごとに立ったり座ったりを数回繰り返す感じです。\nAmazon | FLEXISPOT オフィスデスク用天板 スタンディングデスク120×60cm Amazon | FLEXISPOT スタンディングデスク 電動式 昇降デスク メモリー機能付き ブラック EN1B(天板別売り) スタンディングデスクマット フローリングに45分立ちっぱなしだと結構、足の裏がつかれるんですよ。なので、クッション性が高いフロアマットを立ってるときは利用しています。ちょっとめんどくさいのですが、椅子のときは壁に立て掛けて、立つときにマットを敷くようにして使っています。\nちなみに、ウレタン素材なので開封直後はすごい匂いでした。。。 数日は陰干しみたいなのが必要です、ご注意を。 ただ、これを利用してから膝やかかとが痛いことはなくなっています。\nAmazon | 疲労軽減マット スタンディングデスクマット 滑り止め加工 立ち仕事 耐水 耐油 耐菌 (ブラック, 75cm*50cm*2cm) ケーブルトレー スタンディングデスクだとケーブルをぶら下げた状態だと危なそうだなということで、ケーブルトレーも机の下に追加してあります。電源タップを配置して、ディスプレイなどの電源はこちらから取るようにして、ケーブルトレーからは電源タップとスタンディングデスクの電源コードを垂らすという感じです。実際にはLANケーブルも伸びてたりはしますが。。。 また、後で出てくるラズパイ+SSDも最近こちらに移設しました。 最初にチャコールグレーを発注したのですが、配送日が未定になったので、Lサイズのシルバーを発注するという慌てようでした。 結局、今は両方使っています。テーブルタップにラズパイと、結構乗せるものがあるんですよね。見えない場所だし、色が揃ってないのは気にならないかなと。\nAmazon | プラス Garage ワイヤーケーブルトレー Lサイズ 幅63.7cm シルバー Amazon | プラス Garage 配線ケーブルトレー 幅40cm チャコールグレー キーボード+パームレスト 10数年ぶりに外付けキーボードじゃないかな? 少なくともMacに移行してからは、ずっとMac bookのキーボードを使ってました(極稀にMac mini起動後とかにMagic Keyboard使うくらい)。 外出して仕事をすることが多かったのもあり、体をキーボードに合わせる感じでした。\nが、ずっと在宅で仕事をしていますし、ふるさと納税でRealforce(リンクは楽天)がということで、申し込んでみました。2週間ちょっとで到着。 箱が厳重でびっくりしました。\nAmazon | 東プレ REALFORCE SA for Mac ホワイト R2SA-JP3M-WH | Realforce まだ深いキーに慣れつつあると言った感じです。 付属の2mmのキースペーサーでAPCを2.2mmの設定で使用しています。最初は3mm+APC 1.5mmでやっていたのですが、流石にキーが敏感すぎてちょっとキーボードに手をおいたまま考え事をしているだけで「lllllllllll」のようになってしまったので現在の組み合わせに落ち着いています。\nあと、特殊な設定としてはスペースの横のeng/kanaキーを設定でキーロックして使えなくしました。どうも、ご入力の原因になっているようだったので。 日本語の入力切替は、昨日まではCtrl+Spaceを使用していましたが、このブログを書き始めてからCtrl+\\に変更しています。 むかーし、使っていたIME切り替えのショートカットです(知っている人は知っているやつ)。\nマウスは使用しておらず、キーボードの手前にトラックパッドをおいて使っています。パームレストの部分は、サムライズムさんのトラックパッドがきれいに入るmagicTrayPalmです。 Mac book Proと同じような感じでトラックパッドが使えるのがいいですね。 興味がある方は、侍割のリンクをたどってもらうと、初めてサムライズムさんで買い物をする方に限り割引がつくようになってるみたいです(なんと、私もなんか割引になる!)。\nディスプレイアーム 外付けキーボードになったのですが、Mac Book Proの画面も活用したく、さらに上下での配置がやはり目線の移動距離が少ないので気に入っていました。ただ、前回のブログで紹介したアームでは少し高さが足りず。。。 思案しながらAmazonを回遊していたら、同じ会社の新しいアームがあり、調べると高さが取れそうだということで付け替えました。 アーム2本ありますが、今のところ1本だけを使っています。 2本目のアームにカメラを乗せるのもあり?と思いながらまだ試していませんが。玉突き式に前に使っていたアームがサンダーボルトディスプレイ(縦置き)のアームになっています。前にサンダーボルトにつけていたアームは重量オーバーで悲鳴を上げていたので。。。\nAmazon | HUANUO 2画面 アーム デュアル ガススプリング式 スマホ充電器 寝室で利用していた斜めに立てかけるタイプのワイヤレス充電器を作業デスクに持ってきました。 実は部屋に時計がなく、Pixel 3 XLを使っているので、スマホの画面に常に表示されている時計を置き時計の代わりに使えそうだなと (スマホで写真を撮っているので上の画像ではスマホがありませんが)。 結構便利です。ちょっと時間を確認したいときに、メニューバーの時計では流石に小さすぎるのでw\nAmazon | Anker PowerWave 7.5 Stand, Qi ワイヤレス充電器 ミキサー 音声のミキサーです。Yamahaのスピーカーは入力が2系統あるのですが、入力したい音声は3系統あります(ラズパイ4、Mac mini、メインディスプレイ)。2入力を1系統にまとめるプラグを試しに買ってみて、Mac miniとラズパイをまとめてみたのですが、残念ながら切り替わるときに数分無音状態が続くという問題が発生しました。 USB給電できるタイプを購入しました。スライダーとかいらないなと思っていたのですが、電話やミーティング時にBGMの音を下げたりするのに地味に便利だったりします。 ただ、スライダーを動かそうとすると本体も動いてしまっていたので、本体裏に滑り止めを貼ってあります。\nAmazon | Maker hart Just Mixer ステレオ3入力音声ミキサー/電池とUSB電源可能 Webカメラ おっさんの顔がきれいに写っても仕方ないんですが、下からのアングルよりはいいかなぁということと、今後の勉強会で使えそうかな?ということで、購入してみました。 縦でも横でも使える便利なカメラです。また、あんまりないのですが、部屋の中などを写すときにカメラを持ち回せるの便利ですね。 ディスプレイの上に置いてしまうと高さがありすぎるということで、スピーカーの上に乗っけています。仮置きなのですが、このままになるんじゃないかな? 打ち合わせ中は画面共有してることが多いのでオンライン飲み会などで主に活躍してる気も。。。\nAmazon | ロジクール ウェブカメラ フルHD 1080P 60FPS StreamCam C980OW オフホワイト USB-C接続 Mac miniのSSD化 見えないところですが、Mac miniのHDDをSSDに差し替えました。 性能検証用のマシンとしてMac miniを利用し始めたのですが、 計測するたびに速度の差がありすぎるのでおかしいな?と。 よくよく考えてみると、このMac miniはFusion Driveだったんです。。。 開発などで使う分には大容量だし便利だったのですが、負荷計測に利用する場合は挙動をハンドリングできないので、弊害でしかないです。。。 ということで、頑張って差し替えました。想像以上の大手術でした。 「Mac mini HDD 交換」などでググると換装している方たちがいらっしゃいます。興味ある方はググってみてください。\nさて、復路 pic.twitter.com/SwndXPoKqn\n\u0026mdash; Jun Ohtani (@johtani) July 25, 2020 Amazon | シリコンパワー SSD 1TB SATA3 6Gb/s 2.5インチ ラズパイ4 Mac miniの負荷検証マシン化のため+Linuxを触りたかったというのもあり、ラズパイ4を追加しました。 Mac miniは主な使用用途が音楽再生だったのでラズパイ4で肩代わりできるだろう+その他の検証にもラズパイ4が使えそうだと。 現在はUbuntuをインストールして、画面共有で操作しています。\nAmazon | LABISTS Raspberry Pi 4 4B MicroSDHCカード64G まとめ かなり快適になりました。キーボードもうるさくないですし、熱くもありません。マイクのポップガードは意味がなさそうなので外しました。\nまだいくつか気になってるものもあるので、また更新するかもしれません。\n分離式キーボード - 胸を広げた状態でキーを打ったほうがいいのでは?という気がしています。ただ、最近はずっと日本語キーボードを使っているので選択肢が少ないんですよね。。。\nサンダーボルト?USB-C?ドック - MacBook Proのポートがすべて埋まっているし、もう少しケーブルを減らせると幸せになれそうなきが。。。\nモバイルディスプレイ - MacBook Proのディスプレイを使っているのですが、キーボードの上にかぶってるんですよね、結構。。。クラムシェルにしてiPadもしくはモバイルディスプレイに置き換えたほうがスッキリはしそうかなと。ただ、Touch IDが使えなくなったり、クラムシェル状態でMacBook Proの電源を入れられないというはなしなので、あまり意味がなさそうだなというのもあります。\n","date":1599531445,"dir":"post/2020/","id":"d08a3fdc040bbbdd81c9927ce296318c","lang":"ja","lastmod":1599531445,"permalink":"https://blog.johtani.info/blog/2020/09/08/update-working-facility/","publishdate":"2020-09-08T11:17:25+09:00","summary":"自宅環境に少しアップデートがあったので更新版です。 お客さんのおかげで相変わらず自宅で作業させてもらってるのもあり、昨今のコロナウイルスの影響","tags":["misc"],"title":"自宅の作業環境(2020/09)"},{"contents":"Rustで便利なクレートを見つけたので、紹介がてら、自分のメモのためにブログに残しておきます。\nそもそもの問題 Rustで処理を書いていて、なんかちょっと遅いな?どこの処理で時間がかかってるんだろう? ということがありませんか?ありますよね?\nというのを調べるために、最初に思いつくのは自分で計測する方法です。 流石にそれはなぁ、と思ったのでググって出てきた方法を最初は使っていました。\nRustで実行時間計測 3年前の記事ですが、とりあえず計測する分には問題なかったのでこちらの方が書いていたマクロを拝借していました。 が、ちょっと面倒なのが戻り値がある処理などのときに、このマクロを挟むのが結構めんどくさいなと。 また、処理の時間を測りたいのは基本的にはメソッドや関数単位であることが多いです。\nで、さらにググっていて見つけたのが、meteredでした。\nどんなもの? 計測したい部分に#[metric]のようなアノテーションを追加することで計測対象としてくれます。 あとは、計測したものを保存するレジストリという場所を指定するだけです。 処理が終わったタイミングなどで、そのレジストリの内容を出力することで、次の情報を計測することができます。\nHitCount : 実行された回数 ErrorCount : エラーを返した数(Resultを戻り値にしているメソッドが対象) InFlight : 処理中の回数かな? ResponseTime : レスポンスタイム(処理に何秒かかったか) Throughput : スループット(1秒あたり何回呼ばれたか) とりあえず試してみたのは、ResponseTimeとThroughputです。他のメトリクスはまた後日(機会があれば)。 また、metered::metric::Metricトレイトというものが用意されているようで、これを実装した独自のメトリクスも扱うことができるようです。\n使い方 使い方としては次のようになります。\n計測対象となるメソッドがある構造体に、メトリクスを保持するためのレジストリを用意 計測対象にしたい構造体のメソッドに#[measure]を追加(このとき、計測したいものも指定する。) あとは、実行したあとに構造体をダンプするとメトリクスが出力されます。\nレジストリの用意 #[derive(Default, Debug, Serialize)] pub struct NekoParser { metric_reg: NekoParserMetricRegistry, } NekoParserMetricRegistryという型はこのあとのimplのアノテーションで指定する名前になります。 実際にはこの型の構造体を自分で定義する必要はありません。 構造体のderiveでDefaultを指定します。構造体のインスタンス化のときにdefault()メソッドを呼び出して初期化したいためです(おそらくレジストリの初期化をやってくれるのだと思う(要確認))。 レジストリの用意はこれだけです。\nレジストリの指定と計測対象の指定 計測対象側です。少し長いですが、NekoParserのメソッドすべてを掲載しました。 まずは、1行目でレジストリの名前の指定(registry = NekoParserMetricRegistry)、レジストリのフィールド名(registry_expr = self.metric_reg)、レジストリの可視性(visibility = pub(self))を定義します。 2行目では、implブロック全体で計測したいメトリクスを指定しています。今回は、スループットとレスポンスタイムを計測したかったので #measure([ResponseTime, Throughput])]と2種類を指定しています。 メトリクスが2種類のため配列で指定していますが、1種類だけの場合は[]の記号は必要ありません。\nあとは、計測したい各メソッドに#[measure]をつけるだけです。 なお、メソッドごとに#[measure(ErrorCount)]といったかたちで個別にメトリクスを指定することも可能です。 今回はお試しということもあり、すべて#[measure]だけになっています。 アノテーションを付けただけで、メソッド自体を変更はしていません。\n#[metered(registry = NekoParserMetricRegistry, registry_expr = self.metric_reg, visibility = pub(self))] #[measure([ResponseTime, Throughput])] impl NekoParser { #[measure] pub fn load_and_parse_neko(\u0026amp;self) { let file_path = \u0026#34;./data/chap04/neko.txt\u0026#34;; let file = File::open(file_path).unwrap(); let buf = BufReader::new(file); let mut out = File::create(\u0026#34;./data/chap04/neko.txt.lindera.json\u0026#34;).unwrap(); buf.lines().filter_map(|item| item.ok()).for_each(|line| { let tokens = self.tokenize(line.as_str()); self.output_tokens(\u0026amp;tokens, \u0026amp;mut out); }); } #[measure] pub fn output_tokens(\u0026amp;self, tokens: \u0026amp;Vec\u0026lt;Token\u0026gt;, buf: \u0026amp;mut File) { writeln!(buf, \u0026#34;{}\u0026#34;, serde_json::to_string(tokens).unwrap()) .expect(\u0026#34;Error during output json\u0026#34;); } #[measure] pub fn tokenize(\u0026amp;self, line: \u0026amp;str) -\u0026gt; Vec\u0026lt;Token\u0026gt; { let mut tokenizer = lindera::tokenizer::Tokenizer::new(\u0026#34;normal\u0026#34;, \u0026#34;\u0026#34;); let lindera_tokens = tokenizer.tokenize(line); let tokens = lindera_tokens .iter() .map(|lindera_token| { let surface = lindera_token.text.to_string(); let pos = lindera_token.detail[0].to_string(); let pos1 = if pos != \u0026#34;UNK\u0026#34; { lindera_token.detail[1].to_string() } else { String::new() }; let base = if pos != \u0026#34;UNK\u0026#34; { lindera_token.detail[6].to_string() } else { String::new() }; Token { surface, base, pos, pos1, } }) .collect(); return tokens; } } 計測結果の出力 最後は計測結果の出力です。 今回はテストメソッドで実行して結果を出力する処理を書きました。\nlet parser = NekoParser::default();で構造体をインスタンス化します。 あとは、処理をそのまま実行します。\n最後に出力結果をJSON形式の文字列にしてから出力しました。 let serialized ... println!(\u0026quot;{}\u0026quot;, serialized);という形です。 簡単ですね!\n#[cfg(test)] mod tests { use crate::chapter04::answer::NekoParser; use std::path::Path; #[test] fn success_output_tokenlists() { let parser = NekoParser::default(); parser.load_and_parse_neko(); let serialized = serde_json::to_string(\u0026amp;parser).unwrap(); println!(\u0026#34;{}\u0026#34;, serialized); assert!(Path::new(\u0026#34;./data/chap04/neko.txt.lindera.json\u0026#34;).exists()); } } 出力結果 ここまで紹介したものの実行結果は次のような形でした。 レスポンスタイム、スループットともに、最小、最大、99パーセンタイルなどを出力してくれます。 出力はメソッド名ごとにくくられているのでとても便利です。\n{ \u0026#34;metric_reg\u0026#34;: { \u0026#34;load_and_parse_neko\u0026#34;: { \u0026#34;response_time\u0026#34;: { \u0026#34;samples\u0026#34;: 1, \u0026#34;min\u0026#34;: 176128, \u0026#34;max\u0026#34;: 177151, \u0026#34;mean\u0026#34;: 176640.0, \u0026#34;stdev\u0026#34;: 0.0, \u0026#34;90%ile\u0026#34;: 177151, \u0026#34;95%ile\u0026#34;: 177151, \u0026#34;99%ile\u0026#34;: 177151, \u0026#34;99.9%ile\u0026#34;: 177151, \u0026#34;99.99%ile\u0026#34;: 177151 }, \u0026#34;throughput\u0026#34;: { \u0026#34;samples\u0026#34;: 0, \u0026#34;min\u0026#34;: 0, \u0026#34;max\u0026#34;: 0, \u0026#34;mean\u0026#34;: 0.0, \u0026#34;stdev\u0026#34;: 0.0, \u0026#34;90%ile\u0026#34;: 0, \u0026#34;95%ile\u0026#34;: 0, \u0026#34;99%ile\u0026#34;: 0, \u0026#34;99.9%ile\u0026#34;: 0, \u0026#34;99.99%ile\u0026#34;: 0 } }, \u0026#34;output_tokens\u0026#34;: { \u0026#34;response_time\u0026#34;: { \u0026#34;samples\u0026#34;: 9964, \u0026#34;min\u0026#34;: 0, \u0026#34;max\u0026#34;: 143, \u0026#34;mean\u0026#34;: 0.03592934564431955, \u0026#34;stdev\u0026#34;: 1.5152489085107463, \u0026#34;90%ile\u0026#34;: 0, \u0026#34;95%ile\u0026#34;: 0, \u0026#34;99%ile\u0026#34;: 0, \u0026#34;99.9%ile\u0026#34;: 6, \u0026#34;99.99%ile\u0026#34;: 143 }, \u0026#34;throughput\u0026#34;: { \u0026#34;samples\u0026#34;: 174, \u0026#34;min\u0026#34;: 39, \u0026#34;max\u0026#34;: 71, \u0026#34;mean\u0026#34;: 57.103448275862064, \u0026#34;stdev\u0026#34;: 3.8417981983375835, \u0026#34;90%ile\u0026#34;: 60, \u0026#34;95%ile\u0026#34;: 61, \u0026#34;99%ile\u0026#34;: 64, \u0026#34;99.9%ile\u0026#34;: 71, \u0026#34;99.99%ile\u0026#34;: 71 } }, \u0026#34;tokenize\u0026#34;: { \u0026#34;response_time\u0026#34;: { \u0026#34;samples\u0026#34;: 9964, \u0026#34;min\u0026#34;: 12, \u0026#34;max\u0026#34;: 79, \u0026#34;mean\u0026#34;: 16.897230028101177, \u0026#34;stdev\u0026#34;: 2.331145559054724, \u0026#34;90%ile\u0026#34;: 19, \u0026#34;95%ile\u0026#34;: 20, \u0026#34;99%ile\u0026#34;: 24, \u0026#34;99.9%ile\u0026#34;: 46, \u0026#34;99.99%ile\u0026#34;: 79 }, \u0026#34;throughput\u0026#34;: { \u0026#34;samples\u0026#34;: 174, \u0026#34;min\u0026#34;: 39, \u0026#34;max\u0026#34;: 71, \u0026#34;mean\u0026#34;: 57.103448275862064, \u0026#34;stdev\u0026#34;: 3.819293076427424, \u0026#34;90%ile\u0026#34;: 60, \u0026#34;95%ile\u0026#34;: 61, \u0026#34;99%ile\u0026#34;: 64, \u0026#34;99.9%ile\u0026#34;: 71, \u0026#34;99.99%ile\u0026#34;: 71 } } } } 出力内容で気になったのはoutput_tokensとtokenizeのthroughputが全く同じ結果が出ていることです。 なにかバグを踏んでいる気がします。。。(時間を見つけてソースコード読んでみるか。)\n気をつけること meteredの導入時にわかりにくいコンパイルエラーが出たので備忘録として残しておきます。 (下からコンパイルエラーを読んでしまうくせがあったのが問題なのですが。。。) エラーメッセージは次のとおりです。\nerror[E0412]: cannot find type `ResponseTime` in this scope --\u0026gt; src/chapter04/answer.rs:13:12 | 13 | #[measure([ResponseTime, Throughput])] | ^^^^^^^^^^^^ not found in this scope | help: consider importing one of these items | 1 | use metered::ResponseTime; | 1 | use metered::common::ResponseTime; | error[E0283]: type annotations needed --\u0026gt; src/chapter04/answer.rs:12:1 | 12 | #[metered(registry = NekoParserMetricRegistry, /* default = self.metrics */ registry_expr = self.metric_reg)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type | = note: cannot satisfy `_: std::default::Default` = note: required by `std::default::Default::default` = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) 最初のメッセージにはわかりやすく出ていますが、ResponseTimeをuseせずに利用しようとした場合に以下のようなエラーが出ていました。 ターミナル画面が狭かったのでE0283のエラーが目に入り、何を言ってるんだろう?という状態になってしまいました。 スクロールアップしたら、答えが載っているのに。。。\nコード全体 元ネタはNLP100本ノックの第4章です。 コードの全体はGitHubのソースをご覧ください。\nまとめ meteredを簡単ですが紹介してみました。 導入自体も簡単で、想像していたような使い方ができたので満足しています。 ほかにもプロファイラなどはあるのかもしれませんが、まずはこれを使っていこうかと思っています。\nバグらしきものがありそうだったりするので、そのへんは今後調査してみようかと。 まだ、ちょっと試してみただけなので、metered自体のオーバーヘッドや、独自のメトリクスの実装方法、メソッドではなく関数に対して利用する場合にはどうするのか?などいくつか疑問点があるので、今後試してみてまたブログに残しておこうと思います。\n","date":1599487900,"dir":"post/2020/","id":"827de2d7a9d231f6bcb44caf35896c1f","lang":"ja","lastmod":1599487900,"permalink":"https://blog.johtani.info/blog/2020/09/07/intro-metered-rs/","publishdate":"2020-09-07T23:11:40+09:00","summary":"Rustで便利なクレートを見つけたので、紹介がてら、自分のメモのためにブログに残しておきます。 そもそもの問題 Rustで処理を書いていて、なん","tags":["Rust"],"title":"meteredクレートの紹介"},{"contents":"Rustで言語処理100本ノックの第4章です。\n前回はこちら。\n今回は早めに続きをやりました。 「形態素解析」ですしね。\n第4章の概要 吾輩は猫であるの文章が用意されていて、MaCabで形態素解析した結果をファイルに保存したところからが開始となります。\nが、せっかくRustでやっているのでKuromojiのRust版であるLinderaを利用して形態素解析した結果を保存する部分から作成しました。 3章に引き続き、大きな流れのところの説明だけにしておきます。\n形態素解析 もとのneko.txtが文章が1行ごとになっているので、そのまま1行ずつ読みならが、形態素解析していきます。読み込みの部分は3章とあまり変わらないので割愛します。 以下は、形態素解析の処理と形態素解析結果用の構造体です。\n#[derive(Clone, Debug, Serialize, Deserialize)] struct Token { surface: String, base: String, pos: String, pos1: String, } まずは構造体です。今回の問題では、必要な情報は4種類だったのでそれを構造体にしました。\n表層形(surface) 基本形(base) 品詞(pos) 品詞細分類1(pos1) deriveでSerialize、Deserializeを付与しているのは、形態素解析の結果をJSON文字列として保存し、あとのそれぞれの課題で読み出すためにserde_jsonを利用するためです。\nfn tokenize(line: \u0026amp;str) -\u0026gt; Vec\u0026lt;Token\u0026gt; { let mut tokenizer = lindera::tokenizer::Tokenizer::new(\u0026#34;normal\u0026#34;, \u0026#34;\u0026#34;); let lindera_tokens = tokenizer.tokenize(line); let tokens = lindera_tokens .iter() .map(|lindera_token| { let surface = lindera_token.text.to_string(); let pos = lindera_token.detail[0].to_string(); let pos1 = if pos != \u0026#34;UNK\u0026#34; { lindera_token.detail[1].to_string() } else { String::new() }; let base = if pos != \u0026#34;UNK\u0026#34; { lindera_token.detail[6].to_string() } else { String::new() }; Token { surface, base, pos, pos1, } }) .collect(); return tokens; } 次が形態素解析の処理です。 入力に1行分の文章を受け取り、出力として、さきほどの構造体をベクタに入れたものVec\u0026lt;Token\u0026gt;を返します。 内部ではLinderaのTokenizerをnormalモードでインスタンス化してそのtokenizer()メソッドを叩いているだけです。 インスタンス化のときの第2引数は辞書のディレクトリですが、今回はデフォルト辞書(IPADIC)を利用しています。 戻り値はLinderaが用意したToken構造体なので、これを今回作成したToken構造体に詰め替えているだけです。\n注意点としてLinderaはMeCabとは異なり、未知語(辞書に出てこない単語)の処理が実装されていないので、品詞が\u0026quot;UNK\u0026quot;の場合にはその他の情報が取得できないので、空文字を構造体に設定するようにしました。\n結果の保存 形態素解析の結果はJSONで保存しました。 もとのファイルが1文が1行になっていたので、 1行を読み込み、形態素解析し、それをVecで取り出して、1行1配列JSONの形で保存するようにしてあります。\nfn output_tokens(tokens: \u0026amp;Vec\u0026lt;Token\u0026gt;, buf: \u0026amp;mut File) { writeln!(buf, \u0026#34;{}\u0026#34;, serde_json::to_string(tokens).unwrap()).expect(\u0026#34;Error during output json\u0026#34;); } serde_json::to_stringにVec\u0026lt;Token\u0026gt;を渡しているだけですが、構造体にderiveをつけているのでよしなにやってくれます(便利ー)。\nJSONの読み込み処理 1行1JSONの読み込み処理です。 今回も3章のように読み込みながら、各文章ごとの形態素解析結果に対して処理を実施するために、処理を実行するためのtraitをCommandとして用意し、それぞれの問題で形態素解析結果に対して処理を書くような実装にしました。また、設問37で「猫」と共起している単語を処理するという課題があるので、文章に「猫」が入っているものだけを処理できるようにするためのFilterも用意し、これをJSONの読み込み処理のイテレータのfilterにわたすようにしています。 特にフィルタリングが必要ない場合ように、NonFilterを予め実装済みです。\ntrait Command { fn execute(\u0026amp;mut self, tokens: \u0026amp;Vec\u0026lt;Token\u0026gt;); } trait Filter { fn is_target(\u0026amp;self, line: \u0026amp;str) -\u0026gt; bool; } struct NonFilter {} impl Filter for NonFilter { fn is_target(\u0026amp;self, line: \u0026amp;str) -\u0026gt; bool { true } } // ch04-30. 形態素解析結果の読み込み fn load_json\u0026lt;T: Command\u0026gt;(cmd: \u0026amp;mut T) { load_json_with_filter(cmd, \u0026amp;NonFilter {}); } fn load_json_with_filter\u0026lt;T: Command, U: Filter\u0026gt;(cmd: \u0026amp;mut T, filter: \u0026amp;U) { let file = File::open(\u0026#34;./data/chap04/neko.txt.lindera.json\u0026#34;).unwrap(); let buf = BufReader::new(file); buf.lines() .filter_map(|item| item.ok()) .filter(|line| filter.is_target(line)) .for_each(|line| { let tokens = parse_line_json(line.as_str()); cmd.execute(\u0026amp;tokens); }); } output_tokensではserde_json::to_stringを呼び出してましたが、読み込みでは、serde_json::from_strを使うと構造体にしてくれます。\nfn parse_line_json(line: \u0026amp;str) -\u0026gt; Vec\u0026lt;Token\u0026gt; { return serde_json::from_str(line).unwrap(); } あとは、設問ごとにCommandトレイトを実装していく形です。 たとえば、32.の動詞の原形を出力する場合は次のようになります。\nstruct ExtractVerbBase { out: File, } impl Command for ExtractVerbBase { fn execute(\u0026amp;mut self, tokens: \u0026amp;Vec\u0026lt;Token\u0026gt;) { tokens .iter() .filter(|token| token.pos == \u0026#34;動詞\u0026#34;) .for_each(|token| { writeln!(self.out, \u0026#34;{}\u0026#34;, token.base).expect(\u0026#34;Error during writeln\u0026#34;); println!(\u0026#34;{}\u0026#34;, token.base); }) } } 標準出力とは別にファイルにも出力できるようにExtractVerbBaseにoutでファイルを保持しています。\n34. 名詞の連接 「名詞の連接(連続して出現する名詞)を最長一致で抽出せよ.」という課題だったのですが、最初は読み間違えて、名詞の連接の最も長いものだけを出力するようにしてました。。。 やっぱり、出力結果とかのサンプルは用意しといてほしいなぁ。。。\nimpl Command for ExtractMaxConjunctionNoun { fn execute(\u0026amp;mut self, tokens: \u0026amp;Vec\u0026lt;Token\u0026gt;) { let mut nouns = vec![]; // TODO 参照保持でどうにかしたいけどなぁ。 tokens.iter().map(|token| token.clone()).for_each(|token| { if token.pos == \u0026#34;名詞\u0026#34; { nouns.push(token); } else { if nouns.len() \u0026gt; 1 { self.buffer.push(nouns.clone()); } nouns = vec![] } }); } } 名詞の場合に、nounsにバッファリングしつつ、違う品詞が来たら出力するという処理になっています。 cloneを呼び出していますが、これを参照を引き回す感じにできるといいのかもなぁ(結構めんどくさい)。\n36. 頻度上位10語 頻度を数えるのにはBTreeMapを利用しています。 数えながら、Top10を保持する方法がいい気がしたのですが、いい入れ物を見つけられなかったので、数え上げたあとにBTreeMapのIteratorを回しながら、キーバリューのVecをまず生成します。 その生成したVecに値でソートし、その後Iteratorから最初の10件を取得して表示する方法にしました。\nソートして取り出すという処理がついでにかかっています。。。 BinaryHeapがなにか使えそうな気もしたのですが、いい方法が思いつきませんでした。\nfn print_top10(\u0026amp;mut self) { let mut key_values: Vec\u0026lt;(\u0026amp;String, \u0026amp;u32)\u0026gt; = self.terms_count.iter().collect::\u0026lt;Vec\u0026lt;(\u0026amp;String, \u0026amp;u32)\u0026gt;\u0026gt;(); key_values.sort_by(|x, y| y.1.cmp(\u0026amp;x.1)); key_values.iter().take(10).for_each(|(key, value)| { writeln!(\u0026amp;self.out, \u0026#34;{}, {}\u0026#34;, key, value).expect(\u0026#34;Error during writeln\u0026#34;); println!(\u0026#34;{}, {}\u0026#34;, key, value); }); } まとめ 形態素解析結果をちゃんと眺めてはいないですが、処理としてはこんなところかなと。 グラフはめんどくさいのでスキップしてしまいました。。。 Kibana/Esに食わせて見てみるのもありかなぁ?\n次は係り受け解析です。Rustで使えるライブラリとかあるかなぁ?\n","date":1599445027,"dir":"post/2020/","id":"3c5d4d351e0fb9e33e0e8b6d1d43c0f2","lang":"ja","lastmod":1599445027,"permalink":"https://blog.johtani.info/blog/2020/09/07/reboot-nlp100-ch04/","publishdate":"2020-09-07T11:17:07+09:00","summary":"Rustで言語処理100本ノックの第4章です。 前回はこちら。 今回は早めに続きをやりました。 「形態素解析」ですしね。 第4章の概要 吾輩は猫である","tags":["Rust","nlp100"],"title":"第4章終了(言語処理100本ノック2020)"},{"contents":"Rustで言語処理100本ノックの第3章です。\n前回はこちら。\n少し間が空きましたが、再開しました。 間が空いた理由は。。。「正規表現」ですかね。。。 苦手なんです、正規表現。 なので、28はちょっとギブアップしてしまいました。\n第3章の概要 個別に説明はせずに大きな流れのところだけ。 それぞれの問題の解についてはリポジトリを御覧ください(興味ある人いるのかなぁ?)\n第3章はNDJSON(new line delimited JSON)という、 1行に1JSONという形式のデータを格納したファイルがgzipで圧縮された状態で提供されます。 まずは、このJSONファイルからJSONを読み込むのが主な処理になります。\n読み込んだデータに「イギリス」のWikipediaの記事が入っているので、そこから正規表現で必要なデータを抽出します。\n最後の問題が少し特殊で、抜き出した情報の「国旗」のファイル名を元に、MediaWikiのREST APIを叩いて、結果を取得し、その一部の情報を抜き出すというものです。\nJSONの読み込み処理 gzipファイルを読み込んでから、1行ずつ抜き出してVecに入れる処理が次のようになります。 今回のgzipファイルは大した量が入っていないので、全部先に抜き出す処理としてまとめました。 もっと巨大なファイルの場合は個別のJSONに対する処理を buf.lines().map()のmapのなかで実行する形にすると思います。 gzipのファイルを開くのにflate2というクレート(ライブラリ)を利用しました。便利なのは、BufReaderにlines()というメソッドがあるところですかね。\n// https://docs.rs/flate2/1.0.14/flate2/read/struct.GzDecoder.html pub fn extract_ndjson_from_gzip(input_file_name: \u0026amp;str) -\u0026gt; Vec\u0026lt;String\u0026gt; { let f = File::open(input_file_name).expect(\u0026#34;file not found?\u0026#34;); let gz = GzDecoder::new(f); let buf = BufReader::new(gz); let lines: Vec\u0026lt;String\u0026gt; = buf.lines().map(|l| l.unwrap()).collect(); return lines; } こちらは、上記のメソッドで抜き出したVecを元に、記事の情報を抜き出す処理をしています。 JSONをパースして構造体Articleにデシリアライズするために、serdeというライブラリを使用しています。 serde自体は様々なデータ形式(JSON、YAMLなど)をパースするためのフレームワークです。今回はJSONなので、serde_jsonの実装を利用しています。 また、JSON文字列から構造体にデシリアライズするのを簡単にできるように構造体に#[derive(Deserialize)]をつけています。 あとは、let article: Article = serde_json::from_str(json.as_str())という処理を実行すればserde_jsonがJSONをパースして構造体に変換してくれます。形式がわかっているJSONの扱いはこれが楽ですね。変数に型を明記してあるので、型の推論もしてくれてるようです。\n#[derive(Deserialize)] pub struct Article { title: String, text: String, } // ch03-20. JSONデータの読み込み // https://serde.rs/ pub fn load_json(input_file_name: \u0026amp;str, target_title: \u0026amp;str) -\u0026gt; Vec\u0026lt;Article\u0026gt; { let mut results = vec![]; let ndjson = extract_ndjson_from_gzip(input_file_name); for json in ndjson { let article: Article = serde_json::from_str(json.as_str()).expect(\u0026#34;json parse error\u0026#34;); if article.title == target_title { results.push(article); } } return results; } 後続の処理ではパースしたArticleから記事情報を取得して色々と処理をしています。\n正規表現 正規表現用のクレートregexがRustに用意されています。Regex::new(正規表現)で、正規表現をコンパイルし、あとは、この構造体のメソッドを利用して文字列を処理していきます。 問題では、マッチするかどうか、マッチした一部の文字列を抜き出す、不要なタグを削除するといった処理を正規表現で行いました(Rust書くよりも正規表現の書き方とかを調べるのに大半の時間をもっていかれてます。。。)。\npub fn extract_category_lines(article: \u0026amp;Article) -\u0026gt; Vec\u0026lt;String\u0026gt; { let re = Regex::new(r\u0026#34;\\[\\[Category:(.*)\\]\\]\u0026#34;).expect(\u0026#34;syntax error in regex\u0026#34;); let mut lines = vec![]; article.lines_from_text().iter().for_each(|line| { if re.is_match(line) { lines.push(line.to_string()); } }); return lines; } MediaWiki APIリクエスト処理 最後の問題で国旗のファイル名を元にMediaWiki APIを叩いて、URLの文字列を取得しましょうという問題がありました。 ファイル名をREST APIの引数に渡してHTTP経由でリクエストを送信し、返ってくるJSONレスポンスからURLを抜き出すという処理です。\nHTTPのリクエストの送受信にreqwestというクレートを利用しました。 ちょっと長いけど、APIコールしている箇所はこんな形です。\nこの関数にはasyncとついています。非同期処理の関数です。内部で2回ほど(リクエスト送信の結果待ちとレスポンスのパース待ち).awaitがあります。\nclientに.get(URL)やquery(\u0026amp;[])といったメソッドが用意されているので、URLやクエリパラメータを用意してsend()でリクエスト送信します。\nasync fn call_api(file_name: \u0026amp;str) -\u0026gt; Result\u0026lt;String, String\u0026gt; { let client = reqwest::Client::new(); let file_name2 = format!(\u0026#34;File:{}\u0026#34;, file_name); //let mut file_name2 = file_name.to_string().replace(\u0026#34; \u0026#34;, \u0026#34;_\u0026#34;); let query = [ (\u0026#34;action\u0026#34;, \u0026#34;query\u0026#34;), (\u0026#34;format\u0026#34;, \u0026#34;json\u0026#34;), (\u0026#34;prop\u0026#34;, \u0026#34;imageinfo\u0026#34;), (\u0026#34;iiprop\u0026#34;, \u0026#34;url\u0026#34;), (\u0026#34;titles\u0026#34;, file_name2.as_str()), ]; let result = client .get(\u0026#34;https://en.wikipedia.org/w/api.php\u0026#34;) .query(\u0026amp;query) .send() .await; match result { Ok(response) =\u0026gt; match response.status() { StatusCode::OK =\u0026gt; { let body = response.json::\u0026lt;MediaWikiResponse\u0026gt;().await; match body { Ok(obj) =\u0026gt; match obj.get_url() { Some(url) =\u0026gt; Ok(url), None =\u0026gt; Err(String::from(\u0026#34;Cannot get url...\u0026#34;)), }, Err(error) =\u0026gt; Err(error.to_string()), } } _ =\u0026gt; Err(String::from(format!( \u0026#34;Status code is {}.\u0026#34;, response.status() ))), }, Err(error) =\u0026gt; { let error_msg = format!(\u0026#34;Error occurred... {:?}\u0026#34;, error); println!(\u0026#34;{}\u0026#34;, error_msg.as_str()); Err(error_msg) } } } あとは、呼び出し元で非同期の処理を実行するために、tokioというクレートを利用しています。 block_on()でcall_api()の実行をして、結果が返ってくるのを待ち受けています。結果が返ってきて、問題なければ、call_apiの戻り値Result\u0026lt;String, String\u0026gt;の左側のStringの値が取り出され、get_image_urlの戻り値となります。\nfn get_image_url(file_name: \u0026amp;str) -\u0026gt; String { let mut _rt = tokio::runtime::Runtime::new().expect(\u0026#34;Fail initializing runtime\u0026#34;); let task = call_api(file_name); _rt.block_on(task).expect(\u0026#34;Something wrong...\u0026#34;) } 一応、非同期に関して説明してみましたが、合っているのかどうか。。。 クレートの関係などはまだちょっと自身がないです。。。 あとは、エラーの処理の仕方とかももうちょっと勉強したいかな。\nまとめ 一応、3章を終わらせました。だいぶ強引かつ1つスキップしましたが。。。 次は第4章の形態素解析です。\n","date":1599230785,"dir":"post/2020/","id":"eb2a5824e03996c1966bee38866ce349","lang":"ja","lastmod":1599230785,"permalink":"https://blog.johtani.info/blog/2020/09/04/reboot-nlp100-ch03/","publishdate":"2020-09-04T23:46:25+09:00","summary":"Rustで言語処理100本ノックの第3章です。 前回はこちら。 少し間が空きましたが、再開しました。 間が空いた理由は。。。「正規表現」ですかね。","tags":["Rust","nlp100"],"title":"第3章終了(言語処理100本ノック2020)"},{"contents":"負荷を計測するために、数回、Azure Cognitive Searchのクラスターを起動したり、停止したりしてました。 これは、Terraformでやると楽できるのでは?と思ったので、やってみました。 1パーティションのクラスターなので、全然大したことはないのですが、メモを残しておくためにブログに書いておきます。\n基本的にはTerraformの公式ドキュメントにあったものを自分用に変数を抽出しただけです。\nファイルたち 単にクラスターを起動するためだけなので、2種類のファイルだけ作成しました(1個でもいいかも)。\nvariables.tf - 変数用のファイル。いくつかの設定を変数として定義しました。 terraform.tf - Terraform本体のファイル。 variables.tf まずはvariables.tfです(ファイル内の並びは異なりますが。。。)。terraform.tfで利用する5つの変数です。\nresource_group - リソースグループ名。既存とは異なるリソースグループ名にしました(変に壊してもいいので)。 machine_type - 価格レベル(SKU)。公式ドキュメントに設定できる値の一覧があります。今回はWikipediaのデータを登録していたのでそれが入るサイズにしています。 region - 場所(リージョン)。リージョンの一覧はどこにあるんだろう?これを参考にしましたが。 partition_size - パーティションのサイズ(=Elasticsearchでのシャードかな?)です。今回は1つでの性能を計測したかったので1にしてあります。 search_cluster_name - Azure Cognitive Searchのサービス名。search.windows.net名前空間で一意である必要があったので、他の人が使わなそうな名前をつけています。 variable \u0026#34;machine_type\u0026#34; { default = \u0026#34;standard\u0026#34; } variable \u0026#34;region\u0026#34; { default = \u0026#34;East Asia\u0026#34; } variable \u0026#34;resource_group\u0026#34; { default = \u0026#34;johtani-wiki-test\u0026#34; } variable \u0026#34;search_cluster_name\u0026#34; { default = \u0026#34;johtani-wikipedia\u0026#34; } variable \u0026#34;partition_size\u0026#34; { default = 1 } terraform.tf terraform.tfは以下の通り。Terraformの公式ドキュメントにある例にproviderを追加しただけのものになります。\nprovider - プロバイダーの設定。Azureを利用するという宣言です。features {}がないとエラーになります。空でも必ず指定が必要です。認証周りについては、azure-cli経由で認証する方式を採用しました。azure-cliはHomebrewでインストールしています。 azurerm_resource_group - リソースグループの設定。variables.tfのresource_groupとregionを利用しています。必須項目はこの2種類だけです。 azurerm_search_service - Azure Cognitive Searchの設定。partition_count以外は必須項目です。variables.tfとazurerm_resource_groupの設定を利用しています。今回は利用していませんが、レプリカ数なども指定できるようになっています。 # Azureのproviderを指定。 provider \u0026#34;azurerm\u0026#34; { features {} } # リソースグループの設定 resource \u0026#34;azurerm_resource_group\u0026#34; \u0026#34;wiki-test\u0026#34; { name = var.resource_group location = var.region } # Azure Cognitive Searchの設定 resource \u0026#34;azurerm_search_service\u0026#34; \u0026#34;search_service\u0026#34; { name = var.search_cluster_name resource_group_name = azurerm_resource_group.wiki-test.name location = azurerm_resource_group.wiki-test.location sku = var.machine_type partition_count = var.partition_size } 以上がファイルです。ほぼ公式ドキュメントのサンプル通りですねw\nデプロイとか ファイルの準備ができたら実際にデプロイします。 Azureの環境への認証にはAzure CLIを利用して、事前にログインした状態にします。 実際にデプロイするまでの手順は次のようになります。\naz login - Azureの認証。ブラウザが起動してログイン画面が表示されます。無事認証がOKなら、azコマンドでAzure Cloudの情報が取得できます。 terraform init - 初回だけです。Terraformのワーキングディレクトリの初期化処理を実行します。 terraform plan - Terraform \u0026lt; 0.12の場合は実行。最新版だともういらないみたいだ。 terraform apply - 実際にAzure上にクラスターを起動します。Terraformが隠蔽してくれているので、実際にどんなことをやっているかはわかってないですが。 以上で、Azure Cognitive Searchのクラスターが起動します。 すごく簡単です。Webコンソールでチェックすれば、起動していることも確認できます。\nこの状態では、クラスターが起動しただけなので、あとは必要に応じてデータをロードしたり、アプリから検索したりと行ったことが可能になります。 そのへんの話はまた機会があれば。\nDestroy 今回は負荷テスト用にクラスターを起動していましたので、必要なくなれば、クラスターを削除します。Terraformを導入したもう一つの理由がこの簡略化です。 terraform destroyを実行するだけで、Azure Cognitive Searchのクラスターおよび、リソースグループが削除されます。\nまとめ ということで、ほぼ公式ドキュメントのままですが、TerraformでAzure Cognitive Searchのクラスターを起動する方法の紹介でした。 ブログを書いていて、1点気になったのは、ロケーション(リージョン)の一覧はどこにあるんだろう?という点です。azコマンドとかで出てくるのかなぁ?\n","date":1597742807,"dir":"post/2020/","id":"f5effd616a3f8db6193b482caec37912","lang":"ja","lastmod":1597742807,"permalink":"https://blog.johtani.info/blog/2020/08/18/azure-search-with-terraform/","publishdate":"2020-08-18T18:26:47+09:00","summary":"負荷を計測するために、数回、Azure Cognitive Searchのクラスターを起動したり、停止したりしてました。 これは、Terraformでやると楽でき","tags":["azure search"],"title":"TerraformでAzure Cognitive Searchのクラスターを起動"},{"contents":"先日は「システムの特徴と検索機能について」という感じでふんわり書きました。 まぁ、頭の中でぼんやり考えてることを文章にしてみた感じです。 他にもぼんやりしてるものはいくつかあるので今日も書いてみることに。 検索システム?みたいなツイートも見かけたので、検索システムってこんなイメージですというブログを書いてみました。\n検索システム(機能)を構成するパーツ 今回はシステムに組み込まれる検索機能を構成するパーツについて書き出してみようかなと思います。 パーツといってもユーザー、UI、コンテンツなども入れています。\nユーザー 検索UI 検索窓 オートコンプリート 検索結果画面 ファセット ソート ハイライト 詳細画面 レコメンド 検索エンジン コンテンツ 検索ログ クリックログとかも サービス提供者 ざっくり書くとこんな感じです。 システム構成だったり、機能だったり、アクターだったりといろいろなものが混ざってしまっていますが、登場するものはこんなものです。\nざっくりした繋がりの図はこんな感じです。\nそれぞれの役割について見ていきましょう。\nユーザー サイト、システムのユーザーです。 検索UIを経由して望んだコンテンツを探します。 探す目的は、サイトによって異なります。 「何かを購入(ECサイトやオークション)する」だったり、「情報(レシピや社内文書)を見つける」だったりします。 図では「キーワード」と記載しましたが、最近では自然文(文章)を受け付ける検索もあります。\n検索UI サイト、システムが提供するUIです。ユーザーはこのUIにキーワード(質問)を入力し、検索結果を取得します。 UIにはいくつものパーツがさらに存在します。簡単に例を上げると以下のようなものです。\n検索窓 - キーワードを入れるための入力ボックスです。 オートコンプリート(自動補完) - サイトによっては、検索窓に何かを入力すると、キーワードを保管したりサジェストしたりしてくれます。 検索結果画面 - 質問にマッチしたコンテンツの一覧を表示する画面です。一覧以外にもいくつか情報が表示されます。 検索結果一覧 - コンテンツの一覧です。何かしらの基準(日付順や人気順など)によってソートされたものが表示されます。 ファセット - 検索結果が持っている属性(価格帯、カテゴリ、メーカー名など)の一覧で、絞り込み検索のヒントです。 ハイライト - 入力したキーワードがどこにマッチしたかがわかるように、強調表示されたスニペット(情報の一部)が出ます。 検索APIとUIに分かれている場合が多いでしょうか? 処理の流れとしては、検索窓に入力されたキーワードを検索エンジンに問い合わせができるクエリに書き換えてからリクエストを投げます。 あとは、検索エンジンからのレスポンスにある検索結果を表示できる形に変換して表示するのが役割です。 また、検索ログの出力もこの部分で担当することが多いです(もしくは、検索エンジン自体がログ出力の機能を持っている場合もあります)。\n検索エンジン 検索に特化したデータ構造を内部に持っているサーバーもしくはサービスです。 ElasticsearchやApache Solr、Azure Cognitive Searchなどは転置インデックスと呼ばれるデータ構造になっています。 検索エンジンの検索処理に対しての主な役割は次の2つです。\nクエリにマッチするコンテンツの集合を決定する マッチしたコンテンツを特定の条件で並び替える(ランキング) クエリを受け取り、検索結果のリストを返すのが処理の大きな流れです。 その他に、ファセット、ハイライトといった付加的な処理を実行することがあります。\nまた、データ登録(インデキシング/インデクシング)の処理もあります。\n登録するコンテンツを検索に特化したデータ構造にして格納する 転置インデックスの場合は、入力されたデータ(文章)から単語列を作り出して、単語からコンテンツのIDが判別できる形にする処理になります。\nAlgoliaやElastic App SearchのようなSaaSであったり、RDBの機能を利用するといった選択肢もあります。\nデータソース・コンテンツ 実際に提供したいコンテンツになります。 コンテンツが保存されている場所は、サイトによって異なります。\nWebの検索サイト - インターネット上のホームページ ECサイト - データベースに格納されているアイテムのデータ 社内文書検索 - ファイルサーバーやWikiなどのファイル、文書 といった感じです。 実際には、データソースからコンテンツを検索エンジンに登録する場合は、いくつかの処理(いわゆる前処理)が必要になります。 社内文書検索やWebの検索サイトの場合は、データを収集するためのクローラーが必要ですし、 収集したデータから、検索エンジンに登録するデータを加工したり(HTMLタグを除去したり、メタデータ(URL、収集日、タイトル)を付与したり)もします(ETL処理とか言われる)。\n検索ログ 検索を提供するだけであれば、必要ありません。 が、実際に検索がどのような使われ方をしているか?を知るために必要な機能になります。 この検索ログがユーザーのニーズを読み解くための情報になります。 検索ログには次のような情報が入ります。\n検索窓に入力された文字列 入力された文字列でヒットした件数 検索結果を出したタイミングでのログです。他にも実際にヒットしたコンテンツのIDなどをログに残したり、他のユーザーと区別をつけるために、ユーザーのセッションごとにIDを発行してログに残したりもします。\nまた、検索に満足してもらえているかを見るために、実際に検索結果のどのコンテンツに興味をもったのか?という情報も検索ログとして残すことがあります。クリックログなどとも呼ばれます。検索結果のどのドキュメントが実際にクリックされたか(詳細画面に遷移したか)という情報です。1回の検索結果に対してクリックされるごとにログが残ります。 もちろん、結果に満足しない場合は、クリックされずに、キーワードを変えたり、絞り込み条件がクリックされたりします。\nECサイトなどの場合は更に、実際に購入されたかどうかといった情報もユーザーのニーズを読み解くための情報となります。 詳細画面へのクリックログや購入ログについては、検索以外からの流れ(広告やDMだったり、レコメンドだったり)なども考えられます。 これらのログを元に、検索を改善していくことになります。\nサービス提供者 サイト・システムの提供者です。 コンテンツの準備、検索UIにはどんな物が必要なのか、サイト・システムにとって良い検索とはなにか?、検索ログからユーザーのニーズを分析して何を改善していくのか?といったことを考えます。 例としては次のようなことです。\n検索結果に表示するコンテンツとはなにか? コンテンツの持っている項目・属性の何を検索対象とするか? 検索結果の並び順(ランキング)がどんなものがよいのか? 検索UIにはどんなものを表示するのか? 検索機能を作るときの流れ 検索機能を構成するパーツにどんなものがあるかを紹介しました。 実際にシステムに検索機能を追加する場合は、最低限、次のものが必要になります。\n検索UI 検索エンジン(RDB?SaaS?ミドルウェア?) データソース・コンテンツ とりあえずこれらがあれば、検索機能を作ることはできるかと。 ただ、作っただけでは、いいか悪いかの判断がつかないので、どういった使われ方をしているかを知るために検索ログをとったりして、 改善をしていく必要が出てきます。\nまとめ わかってるよそんなことはと言われそうな感じになったかもしれないですが、 検索の機能を構成するパーツについて紹介してみました。 細かなはなしは色々とありますが、大まかにはこのような役割のパーツがあります。\n実際にはこれらのパーツを用意すればよいわけではなく、それぞれで検索を良くしていくためにどんなことを考えていくのか?などが出てきます。そのあたりの話はまた、別のブログで書いていく感じでしょうか。こんな感じで書いてくと、終わらない気がしてきたけど。。。 次はどんなはなしを書くかなぁ。\n","date":1595907282,"dir":"post/2020/","id":"11a61827e80739a6065960eb188d5758","lang":"ja","lastmod":1595907282,"permalink":"https://blog.johtani.info/blog/2020/07/28/improve-search-no2/","publishdate":"2020-07-28T12:34:42+09:00","summary":"先日は「システムの特徴と検索機能について」という感じでふんわり書きました。 まぁ、頭の中でぼんやり考えてることを文章にしてみた感じです。 他にも","tags":["検索"],"title":"検索システムを構成するパーツ(検索システムに関する妄想その2)"},{"contents":"今年の頭からシステムの検索周りを手伝う仕事をフリーランスとしてやっています。 検索の仕組みを知れば知るほど面白くなってきたからという理由になるのかな? LuceneやSolr、Elasticsearchなどを長く触っているというのもあるかと思います。\nということで、検索についていつも考えています。 頭の中でまとまっていない状況ですが、システムにおける検索機能についていくつか頭の中にあることを書き出して、 いろんな方にダメ出しやコメントをもらいたいなと思ったので、色々と書いてみようかと。 思いつきのままに書いているので、はなしがあちこち飛ぶ可能性もありますが、あしからず。\n検索って難しい 「「検索」とは、データの集合から目的のデータを探し出すこと」By Wikipedia\n一言で「検索」といっても、使う人、ユースケースによっていろいろな「検索」があります。 例えば、新しいスマホを買ったときに、スクリーンロックの時間を設定する機能を「検索」したりします。 また、PCで仕事をしているときに、ファイルの中身をある文字列で「検索」したりもします。 TSUTAYAに行って、欲しかった本がおいてあるかどうか店内の端末で「検索」もします。 Rustを書いていて、こんなことをやるライブラリありそうだよな?と思ってGoogleでウェブの検索をしたりもします。\n私が特にそうだと思いますが、なにかあったらまず検索をするという生活をしています。 ただ、このとき、「検索」といっても望んでいる挙動が違ったりするものです。 以下は自分が「検索」しているときに想定していることになります。\nファイル内の検索をしているときはgrep的な検索を想定していることが多い。 書籍の検索をしているときは、特定の項目(著者など)に対してgrep的な検索を想定しているが、名前の読みなどでも検索されることを想定している(漢字覚えてなかったりする。。。)。 Rustを書いているときに機能をGoogleで検索するときは、いい感じに検索してくれることを望んでいる(入力するキーワードが曖昧なことが多々ある。例えば、そのものズバリの名前をしらないときとか) あくまでも私が想像している挙動です。他の人とは違う可能性もあります。 なので、「検索」といってもさまざまな要素があるし、想定しているシーンも異なるので「難しい」なと思っています。 また、そんな「検索」ですが、世の中的にはあって当たり前だと思われていたり、お金や時間がかかるものと思われてなかったりもします。ま、けどそういったことも含めてやればやるほど面白いなと感じている今日このごろです。\n前置きはこのくらいにして、今回はシステムの特徴と検索機能について感じていることを書いてみようと思います。\nシステムの特徴と検索機能 先ほども書きましたが、検索は今やシステムに欠かせない機能となっています。 が、あればいいというものでもないのではないかなと。とりあえず検索できるべきだということで 検索機能を追加しても使いにくいものや、想定している動きをしない場合は使われないものになってしまいます。\nシステムでの検索機能は特に、「情報検索」(Wikipediaはこちら)と呼ばれたりもします。Wikipediaによるとこんな説明です。\n情報検索(じょうほうけんさく)とは、コンピュータを用いて大量のデータ群から目的に合致したものを取り出すこと。検索の対象となるデータには文書や画像、音声、映像、その他さまざまなメディアやその組み合わせとして記録されたデータなどが含まれる。\n「目的」と呼ばれるものは「ユーザーのニーズ」と呼ばれたりもします。 「合致したもの」というのがシステムが返す「検索結果」になります。検索結果は大体の場合、何かしらの順序でソートされていることが多いです。 ざっくり話をすると、「ユーザーのニーズ」を元に「(何かしらの順序でソートされている)検索結果」を返すという処理です。\nただ、この「ユーザーのニーズ」や「何かしらの順序でソートされている検索結果」はシステムの特性、特徴によってぜんぜん違うものになります。検索エンジンを入れただけで解決するものではありません。\nまた、システムは提供する側のニーズもあります。 ECサイトであればより多くのユーザーに購買してもらったり、 コミュニティサイトの場合は利用ユーザーを増やしてコンテンツや広告の収入を増やしたりといったニーズがあります。\nこれらの両方のニーズが検索機能に影響を与えたりもします。\nいくつか例を上げてみましょう。\n書籍の検索の場合 ユーザーのニーズは、「ある本を探す」ことです。そのためにユーザーがクエリを入力します。 クエリは、例にも出しましたがタイトルや著者名の読みだったりします。 検索窓が1つしかないというよりは、著者やタイトル、出版社などそれぞれの項目ごとに検索できるほうが便利だったりしますよね。 検索結果については、完全一致したものが一番最初に出てきてほしいこともあれば、出版年月日の降順で並べたいことなど、 その時々でやりたいことが変わったりもします。\n場合によっては、説明文などでも検索できると嬉しいこともあります。また、システムからは離れますが、図書館や書店で時々、「〇〇について書かれている本ありますか?」といった聞き方をしたりもします。\nまた、書店としては、探している本を見つけてもらうために検索端末などを用意しますが、そ れ以外の本も買ってもらえるといいですよね。 オンラインの書店などでは、検索結果や書籍詳細の画面に関連書籍が出ていることもあります。\n検索とは少し異なり、探索(なにか面白い本とかないかな?というようなニーズ)をしに、書店に行くこともあります。 書店で平積みされた本やポップなどを見て新しい本に興味を持つこともあります。\nオークションサイトやECサイトでの検索の場合 ユーザーのニーズは、「欲しい物を探す」ことです。 ユーザーが入力するクエリは、幅広いものになると思います。製品の型番を入力する人もいれば、 メーカー名や製品名だったり、ジャンルで絞り込んで検索することもあります。\n探されるもの(コンテンツ、アイテム)も多数に渡ります。 検索窓は1つかもしれませんが、検索結果には、絞り込み条件(ファセット)がいくつか並んで、絞り込んでいける仕組みが用意されていることが多いです。\n検索結果のソートは、価格順だったり人気順だったりします。 ただ、オークションサイトの場合は新しいもの順や、終了日時の早い物順だったりします。\nサイト提供者のニーズとしては、より多くのアイテムを購入してもらうこと(売上)です。 また、オークションサイトの場合は、アイテムを提供している人のニーズも影響してくるでしょう。 売りたい人はより多くの人の目に止まってほしいと思うはずなので、 様々な情報を付与していかに目にとまるか?といったことを考えてくると思います。\nまた、様々な商品を扱うECサイトの場合は、さらに色々と大変になってきます。たとえば、「iPhone」で検索されたときに、 iPhoneそのものが上位に来るべきなのか、ケースなどの周辺商品なのかだったりといった問題が出てきます。 商品の提供者が多数に渡る場合は、同一商品でもさまざまなお店から提供されてしまうために、検索結果一覧に多数同じ商品が並んだりもしますよね。\nレシピサイトでの検索の場合 ユーザーのニーズは「レシピを探す」です。が、探し方はユーザーによって様々です。 冷蔵庫にある材料を入力して検索することもあれば、食べたいものが決まっていてそのレシピを検索することもあります。 このとき、重要なのは類義語だったりするでしょう。食材やレシピは同じものでも様々な名前(例:パクチー、コリアンダー、シャンツァイ(香菜)など)を持っていたりします。また、部位や形によっても名前が変わったりもします。\n検索結果は人気順で並ぶことが多いでしょうか? ただ、レシピの提供がユーザーによるものなのか、サイト運営者が提供しているものかによっても変わってくるでしょう。\nサイト提供者のニーズとしては、レシピコミュニティサイトの場合は、ユーザー数の増加や広告の売上などがあるでしょう。 調味料などのメーカーがレシピサイトをやっている場合は、調味料の売上だったりします。この場合は、検索がどの程度売上に寄与しているのか?などを測ることが難しかったりしそうです。\n社内文書検索の場合 ユーザーのニーズは「文書を探す」です。探し方はファイル名であったり、ファイルのなかに出てくる単語だったりします。 社内用語・略語のような特殊な単語で検索されることもあるでしょう。ユーザーによっては、ぼんやりとした「こんな資料を探している」といったふんわりとした検索をしたくなることもあります。\n検索結果の表示順は「それっぽいもの」が上位に出てくることが望まれそうです。 ただ、古い文書が出てきても役に立たないこともあります。新しい文書のほうが役に立つことが多いので、最近作られたものというのも重要な情報になります。ただし、権限によっては見ることができなかったり、そもそも探すこともNGだったりもします。\n社内文書検索の提供者は、素早く検索できるものを提供することで仕事の効率を上げてもらったり、無駄を省くことができることを期待しているでしょう。\n昔からですが、社内の文書は様々な場所に散らばっていることが多いです。顧客管理システム、ファイルサーバー、Wiki、ウェブサイトなどこれらをまとめて検索できるシステムなどが望まれていることも多いです(使われるかはまた別ですが。。。)。\nスマートスピーカーの場合 ちょっと特殊な面白い例かなと思ってます。 音声で検索(というかお願い?)します。 システムとしては、ユーザーのニーズを理解するのに2段階あるのかなと。\n音声認識 認識した文章・キーワードで検索(場合によってはコマンド発行) これだけでも難易度が増します。\nさらに、画面のないスピーカーの場合は、結果は1件だけになります。これって結構難しいことだと思うんです。 画面があれば、検索結果を上位10件などのリストで表示して、あとはユーザーに選んでもらうことができますが、 音声の場合は1件だけしか返せません。 また、レスポンスタイムもシビアなものだと想定されます。ずっとスピーカーに黙っていられると困りますよね? きっと大変なんだろうなぁ(妄想)。\nこのように、検索と言っても、システムごとに要求・想定されるものは変わってきます。\nまとめ 例をいくつか上げましたが、ざっくりしすぎて発散してますかね。。。 想像している部分もあるので、この通りではないと思います。 ただ、システムによって、「検索」といってもシステムの特性上、 さまざまな物事、思惑が絡んでくるというのは想像してもらえたと思います?(思いたい)。\nシステムに検索機能を追加すると言っても、探したいものが何なのか?、探してもらうものはどういったものなのか?、 検索機能を追加することで何を達成したいのか?など考えることは色々あります。 どうやって、検索機能を実装するのか、その検索機能を実装するためにはどんな情報が必要なのか?などの検索機能のコアな部分を考えるだけでなく、提供しているシステム、コンテンツがどんなものかなど、システム全体を考えながら検索機能を考えていく事が検索をより良いものとして行くことだと思います。\nまた、検索されるものも検索する人もシステムが成長するのに合わせて変化していきいます。システム同様、一度作ればおしまいというものではないので、やることはいっぱいあるのかなと。\n次は、検索のパーツについてなにか書こうかなぁ。\nボヤキ もう少しまとめてから書いたほうがいいのかもなぁ。 もしくは、出てくる要素を整理するとか。 ユーザー、コンテンツ、コンテンツ提供者とかで。 ふんわりとしたブログになってしまった。 個別のシステムごとにもっと書けることもありそう。\n","date":1595842134,"dir":"post/2020/","id":"9da845cd31310b8952efd1be1881e651","lang":"ja","lastmod":1595842134,"permalink":"https://blog.johtani.info/blog/2020/07/27/improve-search-no1/","publishdate":"2020-07-27T18:28:54+09:00","summary":"今年の頭からシステムの検索周りを手伝う仕事をフリーランスとしてやっています。 検索の仕組みを知れば知るほど面白くなってきたからという理由になる","tags":["検索"],"title":"システムの特徴と検索機能について(検索システムに関する妄想その1)"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章 Rust the book - 第9章 Rust the book - 第10章 Rust the book - 第13章 14章は飛ばして、15章です(Cargoはまた別途調べればいいかな?と思って)。\n第15章 スマートポインタ たぶん、これを理解すれば、参照とベクタや構造体とかの組み合わせがもう少し効率よく使えるようになるのかなぁ?\nポインタの強い版? 参照カウント方式のスマートポインタ型 - Luceneとかで実装されてた気がするなぁ 複数の所有者!? DerefとDropトレイトを実装している構造体 ヒープのデータを指すBoxを使用する これはコンパイルエラー。let yのタイミングで借用してるので、書き換えでエラーになる。\nfn main() { let mut x = 5; let y = \u0026amp;x; assert_eq!(5, x); assert_eq!(5, *y); x = 6; assert_eq!(6, x); assert_eq!(6, *y); } こっちはOK。\nfn main() { let mut x = 5; // in stack let y = Box::new(x); // in heap assert_eq!(5, x); assert_eq!(5, *y); x = 6; assert_eq!(6, x); assert_eq!(6, *y); } 余談:コンパイラが変なワーニングを出してくれた。\nuse std::ops::Deref; impl\u0026lt;T, Z\u0026gt; Deref for MyBox\u0026lt;T, Z\u0026gt; { type Target = T; fn deref(\u0026amp;self) -\u0026gt; \u0026amp;T { \u0026amp;self.0 } } struct MyBox\u0026lt;T, Z\u0026gt;(T, Z); impl\u0026lt;T, Z\u0026gt; MyBox\u0026lt;T, Z\u0026gt; { fn new(x: T, y: Z) -\u0026gt; MyBox\u0026lt;T, Z\u0026gt; { MyBox(x, y) } } fn main() { let x = 5; let z = \u0026#34;10\u0026#34;; let y = MyBox::new(x, z); assert_eq!(5, x); assert_eq!(5, *y); } Derefトレイトでスマートポインタを普通の参照のように扱う 参照外し型強制 : 日本語ムズカシイネ Derefを自分で実装しないといけない場面がちょっと想像できてない。たぶん、Boxとかの説明に必要なので出てきたって感じなんだろうけど。 Dropトレイトで片付け時にコードを走らせる こっちは、リソース開放とかでいい感じにできそうだってのはわかった。 Dropはどんなときに実装するんだろう?Tantivyだとオブジェクトプールとかで使ってた。 Rcは、参照カウント方式のスマートポインタ これ、ここで作ったConsのリストを追っかけるためのサンプルも書いてほしい。 #[derive(Debug)] enum List { Cons(i32, Rc\u0026lt;List\u0026gt;), Nil, } fn print_typename\u0026lt;T\u0026gt;(_: T) { println!(\u0026#34;{}\u0026#34;, std::any::type_name::\u0026lt;T\u0026gt;()); } use List::{Cons, Nil}; use std::rc::Rc; use std::borrow::Borrow; fn main() { let z = Cons(5, Rc::new(Cons(10, Rc::new(Nil)))); let a = Rc::new(z); let _b = Cons(3, Rc::clone(\u0026amp;a)); let _c = Cons(4, Rc::clone(\u0026amp;a)); match \u0026amp;(*a) { Cons(v1, v2) =\u0026gt; { print_typename(v2); println!(\u0026#34;{}, {:?}\u0026#34;, v1, v2); }, Nil =\u0026gt; println!(\u0026#34;Nil!!\u0026#34;) }; } RefCellと内部可変性パターン 循環参照は、メモリをリークすることもある ","date":1594288778,"dir":"post/2020/","id":"208a8c072ea521c813b86ca7730eb880","lang":"ja","lastmod":1594288778,"permalink":"https://blog.johtani.info/blog/2020/07/09/hap15-rust-the-book/","publishdate":"2020-07-09T18:59:38+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第15章"},{"contents":"6月7日の週に開催されたBerlin Buzzwordsにオンライン出張してました。\nBerlin Buzzwordsとは? ベルリンで開催されている、Big Data、Scarability、Storage and Searchabilityに関するカンファレンスです。 今年はコロナウイルスの影響で、オンラインで開催されました。 また、同時期に検索に関する他のカンファレンス(以下の2つ)もベルリンで毎年開催されているのですが、今年はこれら3つのカンファレンスが1つのチケットで参加できる形で開催されました。\nMICES - MIX-CAMP E-COMMERCE SEARCH HAYSTACK - The Search Relevance Conference! sponsored by OpenSource Connections MICES、HAYSTACKは初参加ですが、検索に関するいくつかのトピックが聞けたので楽しかったです。\n6/7から6/12まで(がんばって)参加したので、その感想などをブログにとどめておきます。\nオンラインってどんな感じで開催されてた? まずは、オンライン開催がどのような感じだったのかをメモしておきます。\n有料のオンラインカンファレンス(事前にチケット購入が必要) 参加者用Slack カンファレンス数日前まではここで連絡とか質問が可能だった(もちろん、メールも来ましたけど)。 基本的なプラットフォームはBrellaのバーチャルイベントプラットフォーム 参加者同士のSNS機能 - 参加者同士の興味によって参加登録時に似たような人ですよとマッチングしたり。ビデオチャット機能もあり。 カンファレンスのスケジュール確認 - セッションのスケジュールの他に、参加者同士でのチャットのスケジュールも可能。一番便利だったのは自分のタイムゾーンも表示してくれること。 ストリームチャネル - セッションが行われている場所への誘導 スピーカー・スポンサーのリスト - スピーカーやスポンサーを探せる機能。スポンサー企業からは参加者も見ることができる セッションはYouTubeライブ ストリーム中だったらちょっと戻ったり、ポーズもできるので、便利だった セッション後の質疑応答にはJitsiというオープンソース!?のビデオカンファレンスの部屋が用意されてた(GitHubで公開されてるのか。https://github.com/jitsi)。 2日目、3日目はLTとかが終わったあとに、オンライン飲み会やってたっぽい(不参加) 主催者側も初めてだとは思うのですが、目立ったトラブルはなかったです。 ちょっとだけ遅れたりしてましたが、それほど影響はなかったです。 オンラインでの開催の一番のネックは、日本だと時差が辛いということです。 ベルリンが開催地なのですが、スピーカーや参加者はアメリカからの方が結構います。 そのため、開始時間が日本の23時といった具合になりました。\n面白かった\u0026amp;気になったセッション いくつか面白かった\u0026amp;もう一度見ないとなと思ったセッションと感想を。\nNatural Language queries at Salesforce scale セッションのページはこちら(2020年7月現在) Salesforceでどのような自然言語のようなクエリに対して書き換え、サジェストのようなことをやっているか?という話です。 Salesforceはテナント(企業)ごとに、データ構造などがカスタマイズ可能なため、 それぞれ個別に入力クエリ(例: new leads in sf)に対して、どういったパーツ(時間?場所?状態?)なのか?、どのフィールドへの条件なのか?といったものをNERのディープラーニングモデルとして捉えて解析しているという話でした。 企業毎にパーソナライズもされていると。実際にはパイプラインの一部でこの処理をやっており、それ以外にも処理はされているという話もありました。評価の話もされています。\nAMA - AI-Powered Search セッションのページはこちら(2020年7月現在) ManningでMEAP(絶賛書いているところ)のAI-Powered Searchの著者2名がAMA形式でいろんな質問に答えていく感じのやつです。 最初は近況報告(Treyさんがカンファレンス直前に転職してた)と、書籍がどんなものかを簡単に紹介したあと、質問に答えていく形式で2時間あります。ディープラーニングのモデルに関する話なども出てきています。 もう一度見たいと思ってたやつなので見ないとな。。。 (パネルっぽいセッションは、ヒントがなにもないので結構辛い)\nAsk Me Anything: Lucene 9 セッションのページはこちら(2020年7月現在) LuceneのPMCメンバーのUweさんが今後のLucene/Solrのいくつかの質問に答える感じのAMAです。 出てきた話(質問の前の)としては、Lucene 8の現状(Bloc-Max WANDとか)や、Java 11対応になるよとかです。 QAでは、SIMDの話、Approximate Nearest Neighborがどんな感じか?などの話でした。\nFrom commercial search to owned search セッションのページはこちら(2020年7月現在) カルフールスペインがECの検索をどのように導入したかという概要レベルの話でした。 モノリシックなものをマイクロサービスでk8s上に載せ替えたという大きなアーキテクチャ以降の話です。 Empathy.coが提供しているものを最終的には使用したみたいだけど、 どんな検索がされているのかといったニーズの調査ができるようになり、検索に絡んだKPIが改善した話でした。 COVID-19に絡んだクエリの変化についてもちょっと話が出てました。\nNeural Search in Practice セッションのページはこちら(2020年7月現在) Zalandoの検索の一部でNIR(Neural IRモデル)を利用してクエリの改善をやって、それをどうやってトレーニングして、テストしたかなどの話。 NIRを利用することで、複数の言語に対して改善が見られたという話だった。 今までは、クエリをいくつかの処理を元に翻訳して、入力された単語がカテゴリーに対するものなのか、スタイルに関するものなのか?などを判別して、クエリの補強?を行っている手法だった。 これに対して、ディープラーニングでクエリに対するクリックデータを元にトレーニングして、どういうクエリに対してどんなアイテムを出すのか?というモデルで検索を改善していた。 ヒット件数が0件だったり少ないものを対象にして上記の処理を入れているらしい。 (ということで、ディープラーニングをしっかり勉強しないといけないみたいなので、どうにかしたい。。。)\nTop 10 Lessons learned in search projects the past 10 years セッションのページはこちら(2020年7月現在) 10年検索プロジェクトをやってきた10個の気づきという感じのセッション。 ごく当たり前のことなんだけど、検索の導入・改善に関して、こういう事あって、何も考えないとこうなっちゃうよね。 だから、こんなことをやるべきだよね?という話です。 たとえば、検索窓はあるけど分析すらしていない状況(レッスン1)だとまずはこういうのやらないとね。とか、 検索クエリの分析・改善ばかりして、コンテンツの分析・改善を怠っていないか?という当たり前の話です。 当たり前なんだけどまとめてくれてるのは、やはりいいなぁと。\nClick logs and insights: Putting the search experts in your audience to work セッションのページはこちら(2020年7月現在) 検索ログとクリックログがあったときに、どういったことに使えるのかを料理のレシピに見立ててデモをするセッションで説明が面白かったです。 「こんなログがあったときに、ログのこの項目とこの項目を材料にすると、こんなのができますね」というのを、Elasticsearchにログを取り込んで、JupyterNotebookでデモをしていました。やはり動くものがあるとわかりやすいですねぇ。\nMixing and Matching: Diversifying Search Results セッションのページはこちら(2020年7月現在) これまたパネルセッションです。 検索結果の多様性に関するディスカッションでした。 これは、ECだからこその課題でもあるのかなと。検索自体は「何かを見つける」ための手段です。 普通に考えた場合は、ピンポイントで探していたものが見つかるのが嬉しいです。 が、例えば、ユーザーが検索した単語そのものが入っているだけのものが見つかるよりも、似たような商品も一緒に出てきてほしいことありますよね?また、ECサイトだと、回遊してほしいというのもあります。ということで、それぞれの方がどんな観点で多様性を考えているのかという話をするディスカッションになっていました。\nThought Vectors, Knowledge Graphs, and Curious Death(?) of Keyword Search セッションのページはこちら(2020年7月現在) AI-Powered Searchの著者の一人、Treyさんのセッション。ベクトルを検索にどうやって使うのか、 ベクトルで表現できるものはどんなものがあるのか?どんな検索エンジンで使えるのか?という話でした。 歴史的な話も交えつつ、検索だとこのへんで使えるんじゃないか?というような話でした。\n録画は? 気になったセッションをいくつか書き出してみました。 ちなみに、全セッションのビデオが公開されています。興味がある方は、ご覧いただければと。\nThe recordings from this year\u0026#39;s Berlin Buzzwords / MICES / Haystack joint event are now online. You can watch them all on our YouTube channel. Thank you once again to all of our wonderful speakers. https://t.co/hTRDmKNdpd\n\u0026mdash; @berlinbuzzwords@floss.social (@berlinbuzzwords) July 6, 2020 感想そして来年は? 楽しかったです。検索に関する話が色々聞けるのはやっぱ楽しいですね。サイトの特性(ECなのか、Wikipediaなのかなど)によっても「良い検索」の定義も変わるので、サービスなどがどんなものか、そしてそれを良くするためには検索はどんなことができるのか?といった話や、技術的な濃い話までいろいろな話を聞けました。 ただ、パネルは英語の聞き取りが辛いですね。。。あと、時差が。日本にいながらにして時差ボケは辛い。。。 オンライン飲み会には流石に参加できませんでした(4時とか5時から始まるし)。\n来年もオンラインで開催されたら間違いなく参加します。 オフラインのみだった場合はどうなるかなぁ。。。\n","date":1594005164,"dir":"post/2020/","id":"e5cb2e5d501d3db2db5d8f14984a66d4","lang":"ja","lastmod":1594005164,"permalink":"https://blog.johtani.info/blog/2020/07/06/attend-berlin-buzzwords/","publishdate":"2020-07-06T12:12:44+09:00","summary":"6月7日の週に開催されたBerlin Buzzwordsにオンライン出張してました。 Berlin Buzzwordsとは? ベルリンで開催されている、Big","tags":["conference","berlin buzzwords"],"title":"Berlin Buzzwordsにオンライン出張してた"},{"contents":"luceneutil - マニアックなツールのセットアップの続きです。 今回も誰得?なブログなので興味ない場合は飛ばしましょう。\n一応、luceneutilのREADMEにあるlocalrun.pyを動かせるところまでいったんですが、そこで一旦本題を思い返してみました。\nKuromojiの性能が落ちてるらしいし、Analyzer系のベンチマーク測ってるグラフに載せたほうがいいよね。\nこれが、そもそも動かしてみようと思った本題です。 READMEに書いてある手順で動いたんですが、よくよく調べてみると、Analyzer系の性能テストをやってるのは、別物っぽいぞと。 なんとなく、「ソフトウェア考古学」っぽくなってきましたね。\nAnalyzerの性能テストやってるのは? Analyzerのパフォーマンステストのグラフに出てきたTokenizerの名前を元にluceneutilのリポジトリを検索してみました。 EgdeNGrams当たりで検索するとヒットしたのが以下のファイルです。\nsrc/main/perf/TestAnalyzerPerf.java src/main/perf/TestAnalyzerPerf4x.java src/python/sumAnalyzerPerf.py 本命はsrc/main/perf/TestAnalyzerPerf.javaっぽいですね。 これを動かしている人はどれかな?ということで、今度はこのファイル名で検索します。\nsrc/python/runAnalyzerPerf.py どうやら、このPythonのファイルが先程のJavaファイルを実行して、性能を計測しているみたいです。 最初に出てきた、sumAnalyzerPerf.pyはrunAnalyzerPerf.pyの実行結果をAnalyzerの計測結果のグラフに追加する処理をしているようだということまでがわかりました。\nKuromojiをTestAnalyzerPerfに追加してみる 動かす対象がわかったので、あとは、やることを追加しましょうと。\nKuromojiの実行をTestAnalyzerPerfに追加 引数を追加して日本語版のWikipediaのファイルも読み込むようにする runAnalyzerPerf.pyに引数の追加とクラスパスの追加 JapaneseAnalyzerはlucene/analysis/kuromojiにビルドされるのでクラスパスを追加 引数に日本語版のWikipediaのファイルを追加 日本語版のWikipediaのデータの用意 こんなものかな?と。\n1と2はそれほど大変ではないので、3をまずはというところから始めてみました。\nWikipediaのXMLから1行1データのTSVファイルに まずは、どんなファイルを想定して動いているのかな?ということで、英語版のファイルがどんなものかを探してみることに。\nTestAnalyzerPerf.javaでは入力ファイルから1行ずつ文字列を読み込んでAnalyzerに処理させているだけというのがわかっています。なので、とりあえず、1行ずつ読めるような形式だと。 次に、runAnalyzerPerf.pyの55行目でenwiki-20130102-lines.txtというものを読み込んでいます。 が、これがよくわからないw\n前回とりあえず動いたときに、src/python/constants.pyにいろんなファイルへのパスとかが記載されていたのを覚えていたので、その当たりから調べてみます。 52行目に約665万件のドキュメントだというような記載があります。 前回のlocalrun.pyのファイルと似たような構造(1行に1記事が埋め込まれたTSVファイル)だろうと判断して、それを作りそうなプログラムを探してみました。 Wikiとかで検索して見つけたのがこのソースたちでした。\nsrc/python/wikiXMLToText.py - それっぽい名前ですよね? 中身を見ると、第1引数のファイル(XML)からpageタグごとにデータを抜き出し、処理をしてからタブ区切りで第2引数のファイルに書き出してます。 src/python/WikipediaExtractor.py - これもそれっぽいですね。 WikipediaExtractory.pyは界隈では有名なhttps://github.com/attardi/wikiextractorみたいです。こっちはなんとなく使い方はわかっています。 src/python/combineWikiFiles.py - これまたそれっぽい。 中身を見ると、1番目のコードで出力したデータに、2番めのコードで出力されたデータを元になにかしら処理をして、引数で与えられたファイルに出力する感じになってます。 ということで、完全に憶測ですが、日本語のWikipediaのXMLファイルを元に次のような流れでファイル作ってみればいいのかな?と。\njawiki-20200620-pages-articles.xml.bz2をwikimediaからダウンロードして、unbzip2で展開 python src/python/wikiXMLToText.py jawiki-20200620-pages-articles.xml jawiki-lines.txtで、1行ごとのデータを作る ちなみに、このプログラムは2箇所ほど修正しました。usernameタグが存在しないpageが出力されなさそうなので、デフォルトでusername: \u0026quot;\u0026quot;みたいなデータをattrってディクショナリに設定しました。 cat jawiki-20200620-pages-articles.xml | python -u src/python/WikipediaExtractor.py -b102400m -o extractedで別途XMLからデータを抽出 python src/python/combineWikiFiles.py jawiki-lines.txt extracted/AA/wiki_00 jawiki-20200620-lines.txtで2と3の出力をかけ合わせる で、まぁ、一応ファイルはできたんですが。。。 前回のブログ記事でセットアップしたときにダウンロードされたファイルはtitle、日付、本文の3つのカラムしかないんですが、上記の手順で作り出したファイルにはいろんなカラムが存在するんですよね(2が出力する項目が結構ある)。。。\n性能テスト用プログラムの書き換え 入力ファイルは出来上がったので、あとは、性能テストを走らせる部分の修正です。 修正部分はプルリク見たほうが明確なので省略で。\n実行してみた で、実行してみました。 せっかくなので、ブランチをbranch_8_5とmasterを対象にしてやってみました。 実際にはsrc/python/runAnalyzerPerf.pyにディレクトリ名やブランチ名が直書きされてたので書き換えつつ実施した結果はこちら。\n他の英語系のAnalyzerと同じグラフに載せてみたのですが、遅いので、下の方に表示されてます。 で、下に凹んだ部分(23 Juneのところ)がbranch_8_5で実行したときの性能値でした。 実際に遅くなってますね。ただ、他のAnalyzerの振れ幅も大きいので、別のグラフにしたほうがわかりやすくなるのかもなぁと思った次第です。\nということで、一応動いたんでプルリク出してみました。 採用されるかなぁ?\n一応誰得ブログはこれでおしまい。 Noriとかもこの感じで対応できるんじゃないかな?\n","date":1593050518,"dir":"post/2020/","id":"bbd2824ff0d5b801bb6f5da3a2a1a888","lang":"ja","lastmod":1593050518,"permalink":"https://blog.johtani.info/blog/2020/06/25/analyzer-perf-test-with-luceneutil/","publishdate":"2020-06-25T11:01:58+09:00","summary":"luceneutil - マニアックなツールのセットアップの続きです。 今回も誰得?なブログなので興味ない場合は飛ばしましょう。 一応、luceneutilのREAD","tags":["lucene"],"title":"luceneutil - Analyzer性能テストへのkuromojiの追加"},{"contents":"LuceneのFSTの修正に関連して、Kuromojiのパフォーマンス問題が出ているようです。 この問題自体はLucene 8.6.0以降で直る予定のようなのです(Elasticsearchへの影響範囲についてはこれが参考になるかな?)。 で、これに関連して、ベンチマーク計らないとねという話が出ていて、 昔から、LuceneのMikeさんがやっているベンチマークのグラフに載せるのがいいよねという話になっていました。 どうも、これについては、Luceneの中にあるbenchmarkというプロジェクトではなく、MikeさんのGitHubリポジトリにあるプログラムで計測しているようです。\nじゃあ、手元でこれどうやって動かすんだろう?ということでやってみたブログになります。 おそらく、99.99%の人は興味ないと思うのでスルーしていただくのがいいと思います。備忘録のために書いてます。\nとりあえずgit clone 公開されているリポジトリはこちらです。\n手順通りに? とりあえず、READMEにセットアップなどのやり方があったんで追っていくことに。 とりあえず動くまでの手順は以下のとおりです。\nディレクトリを決める $LUCENE_BENCH_HOMEが起点になります。名前は何でもいいみたいです。 cd $LUCENE_BENCH_HOME リポジトリをクローン - git clone https://github.com/mikemccand/luceneutil.git utilです。 コレ自体は問題なし。 cd util セットアップスクリプトを実行 - python src/python/setup.py -download ここがすごく時間かかります。6GBのファイルをゆっくりダウンロードしてきますので、一晩置いておきましょう(起きたら終わってた) $LUCENE_BENCH_HOME/dataにenwiki-20120502-lines-1k.txt.lzmaとwikimedium500.tasksいうファイルがダウンロードされている。 ダウンロードした圧縮ファイルを展開 - unlzma enwiki-20120502-lines-1k.txt.lzma macOSにlzmaのコマンド入ってるんですね。知らなかった。 終わったらcd ../で$LUCENE_BENCH_HOMEに戻っておく ベンチマーク対象となるLuceneを用意 - git clone https://github.com/apache/lucene-solr.git READMEにはlucene_candidateとlucene_baselineって名前でって書いてあったのですが、これだと、この後の実行フェーズでエラーになりました。 trunkとpatchというディレクトリにそれぞれ変更しました。localrun.pyを実行したらこのディレクトリ名だったので(相変わらず、自分、行きあたりばったりな対応してるなぁ。。。) とりあえず動くかどうかを確認したかったので、trunkとpatchはどちらもリポジトリをcloneしたものになってます。動いたのを確認したら、タグを指定して比較したいブランチをチェックアウトする予定。 trunkとpatchをビルド - ant jar * localrun.pyを実行 - cd utilそして。。。 5.で記述したディレクトリ以外に1箇所Pythonのコードを書き換えた。 src/python/benchUtil.py内部にhppc-0.8.1.jarのファイルの存在チェックをしているのだが、2020/06/23時点でのLuceneのリポジトリの依存関係だとhppc-0.8.2.jarになっており、ファイルが見つからないエラーが出たため、0.8.2に書き換えた。970行目付近。 改めて実行したら成功した。 まだ途中 とりあえず、実行するところまではできましたが、結果の見方とかちゃんと調べないとなぁ。 いくつかローカルで対応したものについてはあとでGitHubにIssue立てとくべきだな。\nと、動くのを確認したので、日本語周りの準備をしてみてるところです。\n終わったこと\n日本語のWikipediaのデータjawiki-20200620-pages-articles.xml.bz2をダウンロードして展開 試している途中\nWikipediaExtractorでXMLからデータを抽出 - cat ~/tmp/wiki/jawiki-20200620-pages-articles.xml | python -u src/python/WikipediaExtractor.py -b102400m -o extracted これは手順が違うかも???? python src/python/wikiXMLToText.py ~/tmp/wiki/20200620-pages-articles.xml ./hoge.txt これで、title、日付、本文が抜き出せそう? この後にcombineWikiFiles.pyの実行かな? って感じです。 誰得だろうこれ???\n","date":1592917109,"dir":"post/2020/","id":"8a1ea5d5cf843bc5955a94cfcc321e92","lang":"ja","lastmod":1592917109,"permalink":"https://blog.johtani.info/blog/2020/06/23/how-to-use-luceneutil/","publishdate":"2020-06-23T21:58:29+09:00","summary":"LuceneのFSTの修正に関連して、Kuromojiのパフォーマンス問題が出ているようです。 この問題自体はLucene 8.6.0以降で直る","tags":["lucene"],"title":"luceneutil - マニアックなツールのセットアップ"},{"contents":"Azure Cognitive Searchで日本語を扱うときに、形態素解析器を使いたい場合、2種類のAnalyzerが用意されています。今回はこれらの違いがどんなものかを見ていくことにします。\nAnalyzerとは? まずは、その前にAnalyzerとは何者か?というのを少しだけ。 Azure Cognitive Searchは転置インデックスを内部で作成して、検索を行っています。 この、転置インデックスは、「単語」がどのドキュメントに入っているか?を素早く見つけることができるデータ構造となっています。\nAzure Cognitive Searchは、この「単語」を入力された文章から生成するときに、Analyzerというものを利用します。 Analyzerは入力された文章をある規則に則って単語に分割する機能です。 この「ある規則」が、各種言語や用途によって様々に用意されています。 今回はこの中のja.luceneとja.microsoftという2種類のAnalyzerについて違いを見ていきます。\n2種類のAnalyzerの違いはどんなもの? このAnalyzerの挙動を見るためのエンドポイントとしてanalyzeというAPIがあります(詳細は昔のブログを参照)。\nこのAPIを利用して、Wikipediaのいくつかの文章を単語に区切って見て、 ja.microsoftがどんな動きをしているのか想像してみます(残念ながらja.microsoftの仕様?や挙動についてはページが見つからないため)。\nもとの文章と解析結果(一部抜粋) 文章は、手元のElasticsearchに登録したjawikiのデータからランダムに抽出しています。また、自前のツールで生成したWikipediaのデータなので、まだ一部、見苦しい文字列になっています(そっちもなおさないと)。\n1. 砂川(熊本県) thumb|250px|right|上砂川橋より上流方砂川(すながわ)は、熊本県宇城市・八代郡氷川町を流れる二級河川。\nこの文字列から抽出された単語で特徴的なものを一部抜粋しました。\nja.microsoft ja.lucene 250px 250 px 上砂 上, 上砂川 川橋 砂川 橋 宇城 宇 市 城市 二級 二 ^ 級 まず、最初の250pxですが、ja.microsoftでは、pxが単位であると判定しているのか、数値と合わせた単語として抽出されています。この場合、250で検索しても、この文字列はヒットしない形になるので、ノイズが減ることが考えられるかと。\n上砂川橋という文字は、分割の仕方が別れました。 ja.luceneでは、上砂川という単語が地名として辞書に存在するために、このような分割になっています。ja.microsoftのデータは品詞の情報が取れないのですが、上砂、川橋ともに、名詞として辞書に存在しているのではないかなと。ja.luceneには川橋という単語は存在していないようでした。\n宇城市(うきし)については、2005年に合併でできた市のようで、ja.luceneが利用している辞書には存在しない可能性があり、宇城という文字が抽出できてないと思われます。\n最後は二級です。ja.luceneでは、数字と助数詞として分割されています。こちらも何かしらのロジックにより、二級という1単語でヒットできるように数字と単位?が合わせた単語で出てくる仕組みがja.microsoftなのかなと。\n2. UEFA U-18女子選手権2000 UEFA U-18女子選手権2000は第3回目のUEFA U-18女子選手権である。決勝トーナメントは2000年7月27日から8月4日までフランスで行われ、ドイツが初優勝を果たした。\nこの文字列から抽出された単語で特徴的なものを一部抜粋しました。\nja.microsoft ja.lucene u-18, u u 18, nn18 18 第3回目 第 3 回 目 トーナメント, トナメント トーナメント 2000年 2000 年 7月 7 月 27日 27 日 数字を含む単語第3回目や2000年、7月などは、ja.microsoftは先程と同様、数字と単位の組み合わせを1単語として出力しています。\nまた、トーナメントという単語をトナメントという形で、長音を除去した形で出力しています。 今回の文字列ではないですが、この他に、センターをセンターとセンタの2パターンの単語で出力するといったことを行っています。 ja.luceneの場合、単語の最後に長音がある場合だけセンタとして、長音を除去した単語が出力されます。 これは、長音の表記ゆれに対応するためではないかなと。たとえば、インターフェースとインタフェース、インターフェイスのように、人や文章によって、間にでてくる長音を使ったり使わなかったりという表記ゆれに対応するためだと思われます。 その他にも、イプロゥヴェトをイプロゥベトに、ネクストをネキストに、バラエティをバラエチにも変換するなどといった処理をしてくれるようです。カタカナの表記ゆれには強そうですね(これどうやってるんだろう?)。\nja.microsoftでは、nn18というちょっと変わった単語も出てきていました。純粋な数字の場合はnnと入力してくれるようで、数字だけで検索したい場合に利用できるのかな?これはドキュメントに書いておいてほしいかも?\n共通点 ja.lucene、ja.microsoftともに、共通している動作として、「てにをは」といった単語は除去されていました。違いがあるものとしては、「より」(助詞-格助詞-一般)、「されている」(動詞-自立、動詞-接尾、助詞-接続助詞、動詞-非自立)、「ある」(助動詞)といったものはja.microsoftでは除去されずに出てきていました。 ストップワード的に「てにをは」あたりを除去をしている感じでしょうか?\nアルファベットで構成されている単語についても、基本はそのまま出力される挙動のようでした。\nじゃあどっちがいいの? 残念ながらどちらがいいかは、一長一短かなぁと。 ja.luceneに関しては、Luceneの仕組みを利用しているので、Elasticsearchなどを使えば、個別の単語についてより詳細の情報を取得することが可能です(品詞、読みなど)。ja.microsoftについては、残念ながら手の入れようがないので、そういう動きのものだという割り切った使い方になるでしょうか? ただ、長音の除去による表記ゆれなどについては、便利な機能なので、そのあたりの問題に対応したい場合は、ja.microsoftを活用するのも良いかと思います。\n個人的には、より細かい単語としてインデックスに登録できるもののほうが、柔軟な検索には対応できるのではないかなぁと考えています(Kuromojiの辞書をUniDicにするとか?も考えますが、これはAzure Searchではできないですが)。\nまとめ Wikipediaのデータをいくつか使って、ja.microsoftとja.luceneの違いについて、考察してみました。何かの役に立てばと。 他に、これはどんな感じになるの?などありましたら、コメントいただければと。\n","date":1591692240,"dir":"post/2020/","id":"82a115ab8d617e4e96813587fe3a6049","lang":"ja","lastmod":1591692240,"permalink":"https://blog.johtani.info/blog/2020/06/09/difference-analyzers-in-azure-search/","publishdate":"2020-06-09T17:44:00+09:00","summary":"Azure Cognitive Searchで日本語を扱うときに、形態素解析器を使いたい場合、2種類のAnalyzerが用意されています。今回はこれらの違いがどんなもの","tags":["azure search","kuromoji"],"title":"Azure Cognitive Searchでの日本語向けAnalyzerの違い"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章 Rust the book - 第9章 Rust the book - 第10章 11章、12章はちょっと飛ばして、13章です。\n第13章 イテレータ、クロージャです。 12章の話もちょっと出てくるのか。\nクロージャ 基本的に、「変数には値が束縛されている」という固定観念がずっと頭にこびりついたままなので、クロージャに慣れないんだろうなぁ。そろそろこの固定概念をどうにかしないと。\n匿名関数で、変数に保存したり引数に渡せる ちょっと面白い話(ワークアウト)で実際に考えられる手法の説明がいくつか行われる 関数でリファクタリング これが自分がよくやるパターンかなぁ。クロージャになれてないので。。。 クロージャーを変数に束縛 呼び出しは関数みたいな感じ(ここで少し混乱) これだと、結局呼び出されたタイミングが複数回あるよね? -\u0026gt; あはりそうだった ここで、閑話休題で、クロージャの型推論とか注釈の話。 クロージャは狭い文脈だし、外に公開しているものでもないので、戻り値なども定義してなくてもいいよねとのこと。書くことも可能?なので、書いてわかりやすくするのもありなんだろうな。\n推論についてはこれまで通りで、2回異なる型の変数で呼び出すと、2回目で怒られていた。\n遅延評価(クロージャを保持する構造体!?) Fnトレイト トレイトとMatchの組み合わせだからこのへんで説明する形になるのか。 これを真似すれば、いくつか処理を簡素化できるかもしれないなぁ、たしかに。 なければ実行するみたいな処理を書きたいことがよくあるし。Javaだとnullで定義しといて、nullだったらみたいなのがあるから。 Cacherはサンプルだからこの名前でいいけど、自分だと、どんな名前にするかなぁ?\n振る舞いは難しくなるのか。Cacher実装の限界を読むと。\n関数にするとスコープが変わるのでアクセスできなくなると。。。コンパイラが教えてくれるのは便利だな。\n環境から値をキャプチャする3つの方法\n多分この話が一番クロージャに意味がある話なんだと思う。 イテレータ 回しましょう。\n便利。ただ、こういう書き方に自分が慣れてないので、そっちを補正しないとなぁ。 どれがイテレータ?っていうのを判別するのがちょっとむずかしい(慣れの問題かなぁ) イテレータアダプタ便利。どんなのがあるのか?とかがやっとわかってきた。 パフォーマンスに関しては、うーん、どうなんだろう?という感想だった。 ","date":1591259849,"dir":"post/2020/","id":"e74d071363645a588f858b35231128c4","lang":"ja","lastmod":1591259849,"permalink":"https://blog.johtani.info/blog/2020/06/04/chap13-rust-the-book/","publishdate":"2020-06-04T17:37:29+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第13章"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章 Rust the book - 第9章 第10章 ジェネリック、トレイト、ライフタイムです。 手強そう。\nいきなり関数の切り出し方みたいな話が始まって面食らいました。\nジェネリックなデータ型 ジェネリックはJavaにもあるので、それほど理解に苦しむことはなかったです。 また、OptionやResultですでに経験済みでしたし。\nただ、impl\u0026lt;T\u0026gt; Point\u0026lt;T\u0026gt;{、このメソッド定義は少し最初は戸惑いました。 言われてみれば、なるほどなんですけど。\nコンパイル時にコンパイラが単相化を行うことにより、必要最低限なコードを生成してくるというのは理にかなっているなぁと。\nトレイト: 共通の振る舞いを定義する 出だしにもありますが、「インターフェイス」という機能に類似していると考えると割とすんなりと理解が進みました。 ただ、Javaだと、インターフェースはクラスとセットなため、トレイとの実装に関する記述方法は少し戸惑いが。\nデフォルト実装との組み合わせはAbstractに似た処理になるなと考えながら読みすすめました。\n「トレイト境界」という日本語には少し違和感を覚えましたが、線引をして、制限をかけるという理解でいいのかな?\n実際には#[derive()]などで、トレイトを自分で実装する必要がないなどの、便利機能も用意されており、このあたりのコードの追い方がまだ少し慣れていないかもなぁと。便利なんですけど。。。\n少しだけ気になったので、動作確認したのは次の実装です。\nトレイトで宣言されている関数と構造体が独自に実装する関数の名前がかぶるとどうなるのかという実験です。 構造体独自のメソッドが優先される感じになりそう。\npub struct Tweet { pub username: String, pub content: String, pub reply: bool, pub retweet: bool, } pub trait Summary { fn summarize_author(\u0026amp;self) -\u0026gt; String; fn summarize(\u0026amp;self) -\u0026gt; String { // {}さんからもっと読む format!(\u0026#34;(Read more from {}...)\u0026#34;, self.summarize_author()) } } impl Tweet { fn summarize_author(\u0026amp;self) -\u0026gt; String { format!(\u0026#34;hoge {}\u0026#34;, self.username) } fn to_string(\u0026amp;self) -\u0026gt; String { format!(\u0026#34;fuga\u0026#34;) } } impl Summary for Tweet { fn summarize_author(\u0026amp;self) -\u0026gt; String { format!(\u0026#34;@{}\u0026#34;, self.username) } } pub fn summary\u0026lt;T: Summary\u0026gt;(hoge: \u0026amp;T) { println!(\u0026#34;{}\u0026#34;, hoge.summarize_author()); } pub fn main() { let tweet = Tweet { username: String::from(\u0026#34;horse_ebooks\u0026#34;), content: String::from(\u0026#34;of course, as you probably already know, people\u0026#34;), reply: false, retweet: false, }; println!(\u0026#34;{}\u0026#34;, tweet.summarize_author()); summary(\u0026amp;tweet); println!(\u0026#34;{}\u0026#34;, Summary::summarize_author(\u0026amp;tweet)); } ライフタイムで参照を有効化する 言われてみればそうですが、プログラマが色々考えないとまぁ、行けないんですねという感想。\nただ、借用チェッカーが賢くやってくれるおかげで、全てにライフタイム注釈をつけなくて良くなっているというのがわかりました。 逆に言うと、なんとなくRustを書き始めてしまったので、それを知らずに書いたせいで、コンパイラに怒られてても「?」となっていたのかと。。。\n疑問点がいくつかあって、\n通常はどんなライフタイム注釈をみんな書いてるんだろう?'aとかざっくりしすぎてる? 1つのメソッド、関数にライフタイム注釈が大量に出てくるような書き方をした場合は設計がおかしいのでは?って考えたほうがいいのかも? ジェネリックな型とライフタイム引数の順序を入れ替えてみても動くだろ?とおもって入れ替えてみたら怒られた。 あとは、構造体+ジェネリックが絡んできたら少しこんがらがってきそうっという感じです。 まぁ、これから先は実際に書いてみないことにはわからないんだろうなと。\nまとめ 読みました。 実際にはプログラムを書きながら慣れていく感じだろうなぁと。 まだまだ、あれ?ジェネリックってどう書くんだっけ?とか、ライフタイム注釈どうやって付けて、使うときはどうすんだ?みたいになりながら、 出てくるサンプルを少し変えてみてはどうやって動くんだろうこの場合?みたいなことをやってました。 次は、11章、12章を少しだけ自習しつつ、13章に入る予定です(知り合いと一緒に読みすすめてる)。\n","date":1590656815,"dir":"post/2020/","id":"163beeae9620c1a6a46a38aa7ebd9663","lang":"ja","lastmod":1590656815,"permalink":"https://blog.johtani.info/blog/2020/05/28/chap10-rust-the-book/","publishdate":"2020-05-28T18:06:55+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第10章"},{"contents":"今回はAzure Cognitive SearchのSDKを利用したアプリケーションが、実際にAzure Cognitive Searchに対して送信しているリクエストのパラメータとボディをログに保存する方法について紹介します。\n動機 アプリケーションでリクエストを組み立てて、SDK経由で送信していると、最終的にAzure Cognitive Searchに対して送信されているリクエストのパラメータや検索条件などをひと目で見たいことがあります。 アプリケーションでは、ソート条件や、クエリ文字列の組み立てなどの処理は異なる場所で行われたりしますので。\nまた、公式リファレンスでは、機能の説明はRest APIの使い方と組み合わせで説明されることが多いです。\nということで、SDKを利用しているアプリからAzure Searchへ送信されているリクエストをログに保存する方法を調べてみました。\n方法 調べてみるといくつかの手段を取ることができそうだとわかりました。実際に調べて実装する方法を4種類ほど試してみたのでブログに残しておきます。なお、2020年4月時点でのSDKとAzureの仕組みに基づいたブログになります。最新版ではお手軽な方法があるかもしれません。\nDelegatingHandlerを利用する ServiceClientTracingの機能を利用する Azure Application Insightsを活用する Azure Cognitive Searchのコンソールにある診断情報の機能を利用する 1、2はAzure Cognitive SearchのSDKのリファレンスから当たりを付けて見つけた方法です。 3はApplication Insights、4はAzure Cognitive Searchの機能になります。 これらの方法について個別に説明していきます。\n1. DelegatingHandleを利用する まずは、SDKでロギングの機能がないかを調べて見つけた機能がこちらです。 SDKのSearchServiceClientのコンストラクタの引数にDelegatingHandlerというものが渡せることを発見しました。\nこれは、.NET FrameworkのHttpのAPIに存在するクラスで、HTTPのクライアントがHTTPの送受信時に、処理を挟むことができる機能です。フレームワーク側で、LoggingHttpMessaggeHandlerというクラスを用意してくれていましたが、残念ながらこちらは、リクエストとレスポンスのヘッダのみをロギングするクラスでした。 ということで、リクエストボディをログに出力したい場合は独自に拡張してやる必要があります。なお、ロギングにはMicrosoft.Extensions.LoggingのILoggerを使用します。\nまた、Azure Cognitive SearchのSDK側に違う問題点もありました。チュートリアルにあるように、検索するときには、SDKは次のような使い方を想定しています。\n// Create a service and index client. _serviceClient = new SearchServiceClient(searchServiceName, new SearchCredentials(queryApiKey)); _indexClient = _serviceClient.Indexes.GetClient(\u0026#34;hotels\u0026#34;); インデックス用のクライアントを取得するために、GetClient(インデックス名)というメソッドを使用します。このGetClientメソッドのバリエーションとして、DelegatingHandlerを受け取るメソッドがないのです。。。\nということで、DelegationHandlerを活用する方法としては、以下の2つを実装する必要があります。\nCustomなLoggingHttpMessageHandlerクラスを実装 GetClientと同等の処理をDelegatingHandlerを引数にしたものを実装する 以上の2つを実装し、アプリケーション側から2で作成したGetClientを呼び出すことで、リクエストをボディも含めてログ出力することが可能になります。以下は実装例です。\nCustomHttpMessageHandlerクラス。\nusing System; using System.Collections.Generic; using System.Diagnostics; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; namespace AzureSearchSample { public class CustomLoggingHttpMessageHandler : DelegatingHandler { private readonly ILogger _logger; private readonly bool _logContent = false; public CustomLoggingHttpMessageHandler(ILogger logger, bool logContent) { if (logger == null) { throw new ArgumentNullException(nameof(logger)); } this._logger = logger; this._logContent = logContent; } protected override async Task\u0026lt;HttpResponseMessage\u0026gt; SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { if (request == null) { throw new ArgumentNullException(nameof(request)); } await Log.RequestStart(this._logger, request, this._logContent); var stopwatch = new Stopwatch(); HttpResponseMessage response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false); stopwatch.Stop(); await Log.RequestEnd(this._logger, response, stopwatch.Elapsed); return response; } private static class Log { private static class EventIds { public static readonly EventId RequestStart = new EventId(100, \u0026#34;RequestStart\u0026#34;); public static readonly EventId RequestEnd = new EventId(101, \u0026#34;RequestEnd\u0026#34;); } public static async Task RequestStart(ILogger logger, HttpRequestMessage request, bool logContent) { StringBuilder message = new StringBuilder(); message.AppendLine($\u0026#34;Sending HTTP request {request.Method} {request.RequestUri}\u0026#34;); if (logger.IsEnabled(LogLevel.Trace)) { LogHttpHeaders(message, request.Headers); await LogHttpContent(message, request.Content, logContent); logger.Log( LogLevel.Trace, EventIds.RequestStart, message, null, (state, ex) =\u0026gt; state.ToString()); } } public static async Task RequestEnd(ILogger logger, HttpResponseMessage response, TimeSpan duration) { StringBuilder message = new StringBuilder(); message.AppendLine( $\u0026#34;Recieving HTTP response after {duration.TotalMilliseconds}ms - {response.StatusCode}\u0026#34;); if (logger.IsEnabled(LogLevel.Trace)) { LogHttpHeaders(message, response.Headers); await LogHttpContent(message, response.Content, false); logger.Log( LogLevel.Trace, EventIds.RequestEnd, message, null, (state, ex) =\u0026gt; state.ToString() ); } } private static void LogHttpHeaders(StringBuilder message, HttpHeaders headers) { if (headers == null) throw new ArgumentNullException(nameof(headers)); foreach (KeyValuePair\u0026lt;string, IEnumerable\u0026lt;string\u0026gt;\u0026gt; header in headers) { foreach (string value in header.Value) { message.AppendLine($\u0026#34;{header.Key}: {value}\u0026#34;); } } } private static async Task LogHttpContent(StringBuilder message, HttpContent content, bool logContent) { if (content != null) { foreach (KeyValuePair\u0026lt;string,IEnumerable\u0026lt;string\u0026gt;\u0026gt; header in content.Headers) { foreach (string value in header.Value) { message.AppendLine($\u0026#34;{header.Key}: {value}\u0026#34;); } } if (logContent) { string contentBody = await content.ReadAsStringAsync(); message.AppendLine(contentBody); } } } } } } GetClientの実装\nprivate ISearchIndexClient GetClient(string indexName, params DelegatingHandler[] handlers) { var rootHandler = _searchServiceClient.HttpMessageHandlers.OfType\u0026lt;HttpClientHandler\u0026gt;().SingleOrDefault(); var indexClient = new SearchIndexClient(_searchServiceClient.SearchServiceName, indexName, _searchServiceClient.SearchCredentials, rootHandler, handlers) { SearchDnsSuffix = _searchServiceClient.SearchDnsSuffix }; indexClient.HttpClient.Timeout = _searchServiceClient.HttpClient.Timeout; return indexClient; } 出力されるログ例\n2020/04/14 19:17:53.591|TRACE|Sending HTTP request POST https://サービス名.search.windows.net/indexes(\u0026#39;インデックス名\u0026#39;)/docs/search.post.search?api-version=2019-05-06 client-request-id: be02140f-3a07-48cc-b018-d8aa5e819bc3 Accept-Language: en-US Accept: application/json; odata.metadata=none api-key: APIキー User-Agent: FxVersion/4.700.20.11803 User-Agent: OSName/MacOs User-Agent: OSVersion/Darwin.19.4.0.Darwin.Kernel.Version.19.4.0.Wed.Mar.4.22.28.40.PST.2020.root.xnu.6153.101.6.15RELEASE.X86.64 User-Agent: Microsoft.Azure.Search.SearchIndexClient/10.100.19.52907 Content-Type: application/json; charset=utf-8 { \u0026#34;count\u0026#34;: false, \u0026#34;facets\u0026#34;: [], \u0026#34;queryType\u0026#34;: \u0026#34;simple\u0026#34;, \u0026#34;scoringParameters\u0026#34;: [], \u0026#34;search\u0026#34;: \u0026#34;azure\u0026#34;, \u0026#34;searchMode\u0026#34;: \u0026#34;any\u0026#34; } |AzureSearchSample.SearchService|EventId_Id=100, EventId_Name=RequestStart, EventId=RequestStart メリット、デメリット Azure Cognitive Searchの検索の処理だけを対象にリクエストのログを出力することが可能です。また、影響範囲はアプリケーションだけに閉じていますので、デバッグ目的などでログ出力したい場合に、自分だけの手元でログの確認が可能になります。\nデメリットとしては、独自に実装しなければいけない範囲が広いことです。\n2. ServiceClientTracingの機能を利用する Microsoft.Rest.ClientRuntimeというライブラリをAzure Cognitive Searchは利用しています。 このライブラリにServiceClientTracingというクラスが存在します。 なにやら、クライアントの処理のトレースができそうです。\nAzure Cognitive SearchのSDKの実装がGitHubに公開されており、検索リクエストの処理を投げる直前に、このトレースの仕組がONになっていると、ServiceClientTracing.SendRequestメソッドを呼び出していました。\n実際にSendRequestメソッドに送られたものに対して何かしらの処理を行うのは、IServiceClientTracingIntercepterインターフェースを実装したクラスになります。 このインターフェースの実装がLog4Netに存在します。Log4Netを利用している場合は、これを活用すれば楽ができます。\n実際にServiceClientTracingを有効にするには、以下の2行を呼び出すだけです。\nServiceClientTracing.IsEnabled = true; ServiceClientTracing.AddTracingInterceptor(new Log4NetTracingInterceptor()); あとは、Rest.ClientRuntimeがよしなにやってくれます。 1とは異なり、トレースログなので、リクエストのボディについても出力してくれます。\n2020-05-26 19:09:04,058 [1] DEBUG Microsoft.Rest.Tracing.Log4Net.Log4NetTracingInterceptor [(null)] - invocationId: 1 instance: Microsoft.Azure.Search.DocumentsProxyOperations method: SearchPost parameters: {searchRequest=Microsoft.Azure.Search.Models.SearchRequest,clientRequestId=,cancellationToken=System.Threading.CancellationToken} 2020-05-26 19:09:04,164 [1] DEBUG Microsoft.Rest.Tracing.Log4Net.Log4NetTracingInterceptor [(null)] - invocationId: 1 request: Method: POST, RequestUri: \u0026#39;https://サービス名.search.windows.net/indexes(\u0026#39;インデックス名\u0026#39;)/docs/search.post.search?api-version=2019-05-06\u0026#39;, Version: 2.0, Content: System.Net.Http.StringContent, Headers: { client-request-id: 591cb14f-e5c2-4a85-977d-01d1f6431ddc Accept-Language: en-US Accept: application/json; odata.metadata=none api-key: APIキー Content-Type: application/json; charset=utf-8 } Body: { { \u0026#34;count\u0026#34;: false, \u0026#34;facets\u0026#34;: [], \u0026#34;queryType\u0026#34;: \u0026#34;simple\u0026#34;, \u0026#34;scoringParameters\u0026#34;: [], \u0026#34;search\u0026#34;: \u0026#34;azure\u0026#34;, \u0026#34;searchMode\u0026#34;: \u0026#34;any\u0026#34; } } 2020-05-26 19:09:04,459 [Thread Pool Worker] DEBUG Microsoft.Rest.Tracing.Log4Net.Log4NetTracingInterceptor [(null)] - invocationId: 1 response: StatusCode: 200, ReasonPhrase: \u0026#39;OK\u0026#39;, Version: 1.1, Content: System.Net.Http.StreamContent, Headers: { Cache-Control: no-cache Pragma: no-cache request-id: 591cb14f-e5c2-4a85-977d-01d1f6431ddc elapsed-time: 72 OData-Version: 4.0 Preference-Applied: odata.include-annotations=\u0026#34;*\u0026#34; Strict-Transport-Security: max-age=15724800; includeSubDomains Date: Tue, 26 May 2020 10:09:04 GMT Content-Type: application/json; odata.metadata=none Expires: -1 Content-Length: 376 } メリット、デメリット Log4Netを利用しているアプリの場合、2行だけを追加することで実装が完了するのがお手軽な点です。\n難点としては、Rest Client全てにたいしてトレース処理が入ってしまうので、Azure Cognitive Search以外にもRestクライアントを利用しているものが存在した場合、ログの量が増えてしまいます。また、検索以外の処理でもトレースされてしまうのもデメリットになります。\nLog4Net以外のログ機構を使用している場合は、自分でIServiceClientTracingInterceptorを実装する必要も出てきます(参考:StackOverflow)。\n3. Azure Application Insightsを活用する ここから紹介する3と4については、ログの出力先がAzure上になります。\nAzureのApplication Insightsを利用する方法です。 Azure?.NET?のアプリケーションパフォーマンスモニタリングのサービスです。\nApplication Insightsを自分のアプリケーションに設定することで、アプリケーションのパフォーマンス監視に関する情報がAzure上のApplication Insightsリソースに送信されるようになります。\nただ、Application Insightsのデフォルトの機能では、URL程度の情報だけが送信されます(参考:しばやんさんのブログ)\nこちらも拡張機能が用意されており、ITelemetryInitializerのインターフェースを実装したクラスを用意することで、独自の情報をApplication Insightsに出力することが可能となります。詳細についてはしばやんさんのブログを参考にしてもらうのが良いかと。\nHttpリクエストを出力する実装例は次のとおりです。ただ、ちょっとうまく行かないパターンがあったので、コメントアウトとして残してあったりします(なんでだろう?)\nusing System.Collections.Generic; using System.Net.Http; using System.Net.Http.Headers; using Microsoft.ApplicationInsights.Channel; using Microsoft.ApplicationInsights.DataContracts; using Microsoft.ApplicationInsights.Extensibility; namespace AzureSearchWebSample.ApplicationInsights { public class HttpRequestInitializer : ITelemetryInitializer { public void Initialize(ITelemetry telemetry) { if (!(telemetry is DependencyTelemetry dependency)) { return; } HttpRequestMessage requestMessage = null; HttpRequestHeaders requestHeaders; if (dependency.TryGetOperationDetail(\u0026#34;HttpRequest\u0026#34;, out var details) \u0026amp;\u0026amp; details is HttpRequestMessage request) { requestMessage = request; requestHeaders = request.Headers; if (requestMessage.Method == HttpMethod.Post) { string contentBody = requestMessage.Content.ReadAsStringAsync().GetAwaiter().GetResult(); dependency.Properties.Add(\u0026#34;RequestBody\u0026#34;,contentBody); } } else if (dependency.TryGetOperationDetail(\u0026#34;HttpRequestHeaders\u0026#34;, out details) \u0026amp;\u0026amp; details is HttpRequestHeaders headers) { requestHeaders = headers; } else { return; } foreach (KeyValuePair\u0026lt;string,IEnumerable\u0026lt;string\u0026gt;\u0026gt; header in requestHeaders) { foreach (string value in header.Value) { dependency.Properties.Add(header.Key, value); } } //この実装の場合は出力されなかった。なぜ? // if (requestMessage != null \u0026amp;\u0026amp; requestMessage.Method == HttpMethod.Post) // { // string contentBody = requestMessage.Content.ReadAsStringAsync().GetAwaiter().GetResult(); // dependency.Properties.Add(\u0026#34;RequestBody\u0026#34;,contentBody); // } } } } メリット、デメリット すでにApplication Insightsを利用している場合はついでに情報が出力されるので便利です。かつ、常にリクエストログを見れるようにしておく場合はとても便利だと思います。\nApplication Insightsを利用していない場合は、そこから導入しなければならなくなるので、手間が増えるかもしれないです。\n4. Azure Cognitive Searchのコンソールにある診断情報の機能を利用する。 最後はAzure Cognitive Searchの診断ログを有効にする方法です。 ここまで説明してきた方法の中で、一番お手軽な方法です。。。\nこれまでは、リクエストボディを出力する方法を考えていましたが、Azure Cognitive Search側の診断ログを有効にすると、リクエストボディで送信したものが、Azure Cognitive Search側で、クエリパラーメータとして、診断ログに出力されます(診断ログのQuery_s)。\nあとは、Azureのコンソールで当該時間のログを見ればよいだけです。以下は出力されたログの一部です。Description_sにはURLのパスが記載されています。\n診断ログ例(一部)\nDescription_s POST /indexes(\u0026#39;multi-field-test\u0026#39;)/docs/search.post.search Query_s ?api-version=2019-05-06\u0026amp;searchMode=Any\u0026amp;search=azure\u0026amp;queryType=Simple\u0026amp;$count=false メリット、デメリット アプリケーション側に手を入れる必要がなのでお手軽です。 一度設定しておけばコンソール側でログをいつでも見れるので便利です。\nリクエスト量が多くなってしまうと、ログの量も多くなり、費用がかさむ恐れがあります。また、複数の人が触る環境の場合は自分で送信したリクエストがどれだったのか?といった状況に陥る可能性はあります。\nその他は? Azureに対してではないですが、昔似たようなことをやるときにやっていた方法として、ローカルにプロキシサーバーを起動し、そのプロキシサーバー経由でアプリケーションから、Azureに接続することで、リクエストを保存する方法もあります。 ざんねんながら、未調査ですがアプリなどにはそれほど手を入れる必要はないかと思います。\nまとめ ちょっと送信リクエストの内容が見てみたいという話でしたが、いろいろな手段が存在しました。 自分の状況、環境に合わせて手段を選択肢てみるのがいいかと思います。 まずは、簡単な診断ログあたりからでしょうか?\n","date":1590481367,"dir":"post/2020/","id":"36dd94159e3e60076c0c6098086e255f","lang":"ja","lastmod":1590481367,"permalink":"https://blog.johtani.info/blog/2020/05/26/logging-azure-search-request/","publishdate":"2020-05-26T17:22:47+09:00","summary":"今回はAzure Cognitive SearchのSDKを利用したアプリケーションが、実際にAzure Cognitive Searchに対して送信しているリクエストのパラメータ","tags":["azure search",".net"],"title":"Azure Cognitive Searchのリクエストのロギング"},{"contents":"Mircosoft Buildというイベントが今週ありました(MSの方やお客さんに教えてもらった)。\nそこで、Azure Cognitive Searchのセッション(MyBuild - Cognitive Search: The pocket-knife for knowledge mining)があったので、見てみました。 内容がどんなものかをメモっておきます。 最初はCognitive Searchがどんなものよという説明でした。\nビルトインスキルの拡充の話 データソースからデータを取り出し、エンリッチし、検索エンジンに保存するという、パイプラインが組めるようになっています。\nこのパイプラインで利用できる処理のことがスキルと呼ばれています。ここで利用できるビルトインスキルが拡充されますよという話でした。ちょっとだけ抜き出すと以下のとおりです。\nAzure Machine Learning Text translation Brand detection Object detection スキルのリファレンスには載ってるものと載ってないものがあるので、今後追加されてくのかな? Brand detectionがどんなものなんだろう?ってのがちょっと気になりました。どっかにデモとかあるかなぁ?\nスキルセットのための新機能 : Debug Sessionのデモ 上記のスキルを組み合わせてパイプラインを組んで、データソースから取り出したデータをエンリッチしてから、検索エンジンに入れる処理をかけるのですが、その処理のデバッグ用に新しいGUIの機能が追加されてますよという紹介とデモでした。\nTutorial: Use Debug sessions to diagnose, fix, and commit changes to your skillset - Azure Cognitive Search | Microsoft Docs Manage Identityの話 Azure Cognitive Searchにデータを登録するパイプランの最初の段階で、各種データソースにアクセスが必要です。 このアクセス時にコネクションの設定にアカウントキーなども含めてましたが、これをコネクション設定ではなく、専用の管理機能が用意されましたよという話でした。\nSet up a connection to a data source using a managed identity (preview) - Azure Cognitive Search | Microsoft Docs QA Similarityとかの話 BM25になってるよとか SDKの話とか ほかにRelevancyの話 Analyzerをデフォルトのままじゃなくてちゃんと考えて使いましょう(例:各言語用のAnalyzerがいっぱいあるよとか) こんな感じでした。\n","date":1590117041,"dir":"post/2020/","id":"21982f43bc435f22efef22b309a48c66","lang":"ja","lastmod":1590117041,"permalink":"https://blog.johtani.info/blog/2020/05/22/watching-azure-cognirive-search-session-at-ms-build/","publishdate":"2020-05-22T12:10:41+09:00","summary":"Mircosoft Buildというイベントが今週ありました(MSの方やお客さんに教えてもらった)。 そこで、Azure Cognitive Searchのセッション(MyBuil","tags":["azure search"],"title":"Microsoft Build(2020)のAzure Cognirive Searchのセッションを見たのでメモ"},{"contents":"ElasticのWorkplace Searchを触ってみています(その1、その2)が、Elastic Stackの7.7.0がリリースされてしまいました。\n簡単ですが、リリースブログを見ながら気になった点をメモしとこうかと。\n本家のリリースブログ いっぱいあるんですよ、これが。まぁ、内容かぶってるのもあるんですが。\nElastic Stack Elastic Stack 7.7.0をリリース Elasticsearch 7.7.0 released Kibana 7.7.0 released Logstash 7.7.0 released Enterprise Search系 Elastic Enterprise Search 7.7 released, featuring Workplace Search GA | Elastic Blog Elastic App Search updates: Scale your way with new configuration options | Elastic Blog Elastic Workplace Search: 新しい、統合された働き方へ Observability系 Elastic Observability 7.7 released | Elastic Blog\nElastic APM 7.7.0 released with service maps, async profiler, and more | Elastic Blog\nElastic Logs 7.7.0 released with PCF support, MQTT support, and more | Elastic Blog\nElastic Metrics 7.7.0 released with enhanced Prometheus integration and PCF support, | Elastic Blog\nElastic Uptime Monitoring 7.7.0 released with alerting, anomaly detection and more | Elastic Blog\nNew alerting framework released for Observability, Security and the Elastic Stack | Elastic Blog\nIntroducing Elastic Security 7.7.0 | Elastic Blog\n個人的に気になったもの で、全部読んだわけではないのですが、個人的に気になった機能についてメモを残しておきます。 多分に検索によっている可能性がありますが、お気になさらず。 また、ブログとドキュメントを元に気になるところをピックアップしてます。 実際の実装とか動作に関してはまだ未調査の段階です。\nAsync Search - Elasticsearch ElasticsearchのAPIとして非同期に検索できるAPIが実装されました (公式リファレンス)。 大量データを検索が終了してから検索結果を返すのではなく、クエリは実行しつつわかったところまでは都度取得したいという要望だったり、Coldインデックスのように遅いストレージ上にあるデータへの検索でも少しずつ取得できるようにという具合だと思います。ログとか大量に扱う場合にまぁ、ほしいですよね。今回はEsのリリースがメインで、今後はKibanaなどとの連携だったり色々改善していくよという話みたいです(Kibanaの一部の機能は利用しているみたい)。\nライセンスとサブスクリプションのレベル Elastic License Basic 気になるところ(と、予想とか) 仕組みがどうなっているか? Search APIと同等のリクエストパラメータが使える。が、いくつか制約はありそう おそらくTask Manageerで検索してる処理が管理され、レスポンスにはIDが発行されて、そのIDで処理の進み具合を取得する感じ。 Shard単位?Segment単位? 内部的にはShard単位で検索処理を扱ってるので、Shard単位がとりあえず楽そう? Aggsとかも? 対象の模様 Sortは? 有効。ソートのフィールドがインデックス対象だった場合は、そのデータの統計値を使ってShardをソートするっぽい(公式リファレンスのNOTE参照) 関連しそうなGitHubのIssuesとか まだ読んでない\nAsync search · Issue #49091 · elastic/elasticsearch Add a listener to track the progress of a search request locally by jimczi · Pull Request #49471 · elastic/elasticsearch Pre-sort shards based on the max/min value of the primary sort field by jimczi · Pull Request #49092 · elastic/elasticsearch Async search: store intermediate results · Issue #55464 · elastic/elasticsearch Reduced consumption of heap - Elasticsearch ヒープの使用量が7.7で減ってるよというブログも別途ありました。\n元になっているLuceneの実装に関するIssueが「[LUCENE-8635] Lazy loading Lucene FST offheap using mmap - ASF JIRA」です。ヒープ上に展開していたデータをmmapで扱えるようにすることで、ヒープのメモリを削減してる。\nで関連して、これがLuceneで操作できるようになって(「Use reader attributes to control term dict memory useage by s1monw · Pull Request #42838 · elastic/elasticsearch」)、そこからEsに取り込まれたと。\n_idをoff-heapにする話は[ここ](Move the terms index of _id off-heap. by jpountz · Pull Request #52405 · elastic/elasticsearch)にあった。\nこれに関連して、ヒープサイズの推奨について再考が必要かも?というIssue(Reconsider our recommendations for heap size? · Issue #52561 · elastic/elasticsearch)も上がってる。\nPainless Lab - Kibana ほんとにPainless?と言う話はさておき、_script APIでexecuteはできていましたが、やはりもう少し楽に実行したいですよね?ということで画面ができたみたいです。\nシンタックスハイライトとかもできるので、より簡単に使えるようになってますね。 まだ、ベータなので足りないContextとかもあるっぽいけど。\nライセンスとサブスクリプションのレベル Elastic License Basic? まだベータだからか、サブスクリプションのページにはなかった。 公式ドキュメントとGitHubのリポジトリから、Elastic Licenseであることは判明。\n気になるところ(と、予想とか?) 制限事項がどんなものか? 使えるContextがまだ少ない?まだGAではない サジェストがどのくらい効くのか? シンタックスハイライトはあるけど。まだかなぁ? その他Elasticsearch関連 7.7リリースのハイライトが別途用意されています。\n7.7.0 release highlights | Elasticsearch Reference [7.7] | Elastic こっちで気になるのは、ClassificationとかTransformsあたりかなぁ。ML関連の機能で。\nWorkplace Search GA これは別のブログに書くかな。\n気になるところ Betaと何が変わったのか? APIとかどういう形で提供されるのか?そもそも提供されるのか? どんな機能?みたいなのも書く予定です。\nData VisualizerでFilebeatのConfigをサジェスト - Kibana and Filebeat Kibanaの画面からデータをちょっと?(100MB)だけアップロードして、Elasticsearchにサクッとデータ登録できる機能が実はあります。この機能の拡張として、Filebeatの設定だとこんな感じに作れるよ?というのを提示してくれるようになったみたいです。 手元にあるファイルを定期的に読み込むときに、設定を書く下地ができるのは便利じゃないかな?\nライセンスとサブスクリプションのレベル Elastic License Basic Data Visualizerってどんなもの?というのはここにブログがあります。残念ながらKibanaとかの公式リファレンスには使い方のページがないんだよなぁ。\nAPMのサービスマップ - APM and Kibana アプリケーションアーキテクチャのどこでAPMが動作しているか、どこと通信しているかという、APMのエージェントが入っているアプリ間のつながりをKibana上で可視化できる機能っぽいです。まだ、ベータみたいですが、面白そう。Azure Application Insightのアプリケーションマップに似てる気がします。\nライセンスとサブスクリプションのレベル Elastic License Platinum 気になるところ どうやって作ってる(つながりをどうやて判断してる)のか? 分散トレーシングのデータを元に誰がどこと通信してるってのは取れるんじゃなかろうか? Log categorization and contextual examples - Kibana and Elasticsearch 7.6から入ってたっぽいですが、ログの分類をMLの機能を使ってできるものが、LogsのUIとかでさらに使いやすくなった模様。\nライセンスとサブスクリプションのレベル Elastic License Platinum 気になるところ 7.6の機能から追いかけないとなぁ。。。 似たようなログをカテゴリーごとに分析できるようになるので、プラスMLの仕組みでこれまでとは異なる種類のログが出始めたみたいなことが分析できそう。 まとめ 眺めるだけで時間かかりましたが、まぁ、相変わらずいっぱいありますね。 興味のあるところの濃淡が出た感じになりましたが、気になる点をピックアップしてみました。 おかしなところとか、ここはどういう意味?などあればツッコミお願いします。\n","date":1589509037,"dir":"post/2020/","id":"306cecb32320ead508346ad8fed3394d","lang":"ja","lastmod":1589509037,"permalink":"https://blog.johtani.info/blog/2020/05/15/elastic-stack-7_7/","publishdate":"2020-05-15T11:17:17+09:00","summary":"ElasticのWorkplace Searchを触ってみています(その1、その2)が、Elastic Stackの7.7.0がリリースされてし","tags":["elastic stack"],"title":"Elastic Stack 7.7がリリースされた"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章 第9章 エラー処理です。 NLP100とか、いくつかのプログラムを書いていて、なんとなくは扱っていますが、きちんと勉強しないと。\nとりあえず、「Rustには例外は存在しません。」が一番知っておくことかな。\npanic!で回復不能なエラー panic!マクロでスタックを巻き戻して掃除をして終了。 異常終了(panic = 'abort')にもできる。 「RUST_BACKTRACEを0以外の変数にセットして実行」 * Resultで回復可能なエラー expect()は気持ち悪い名前じゃないかなぁ? ここでio::Errorではないものもエラーが発生する場合には panic!すべきかするまいか まとめ 「Rustには例外は存在しない」ので、回復不能か可能かを考えつつ処理を書こうと。\n","date":1589449406,"dir":"post/2020/","id":"1e220a934e16fd941bd804ca03865b60","lang":"ja","lastmod":1589449406,"permalink":"https://blog.johtani.info/blog/2020/05/14/chap9-rust-the-book/","publishdate":"2020-05-14T18:43:26+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第9章"},{"contents":"Rustで言語処理100本ノックの第2章の残りです。\n前回はこちら。\nちなみに、標準入力から受け取る処理は書いてないです。 出力に関してはファイル分割、保存と支持があるもの以外は文字列として取り出すところで終わっています。\n12. 1列目をcol1.txtに,2列目をcol2.txtに保存 pub fn extract_column(input_file_name: \u0026amp;str, num: usize, output_file_name: \u0026amp;str) { let input_f = File::open(input_file_name).expect(\u0026#34;file not found\u0026#34;); let read_buf = BufReader::new(input_f); let mut output_f = OpenOptions::new() .write(true) .create(true) .open(output_file_name) .expect(format!(\u0026#34;can\u0026#39;t open file[{}] with write option\u0026#34;, output_file_name).as_str()); read_buf.lines().for_each(|line| match line { Ok(line) =\u0026gt; { let columns: Vec\u0026lt;_\u0026gt; = line.split(\u0026#39;\\t\u0026#39;).collect(); writeln!(output_f, \u0026#34;{}\u0026#34;, columns[num]); output_f.flush().expect(\u0026#34;Error during flush\u0026#34;); } Err(_) =\u0026gt; panic!(\u0026#34;parse error \u0026#34;), }); } 13で出力結果を利用するので入力として出力ファイル名も受け取るようにしました。 問題としては、1列目と2列目を別々に出力すればいいので、1回の処理で書いても良かったのですが、1回1ファイルの出力という形で実装しました(効率は悪い)。\n改行コードあたりを考えるのがめんどくさかったのでwriteln!マクロでファイルに書き出しています。が、普通にwriteメソッドで改行コードを追加しても良かったのかなと。\nあとは、出力先ファイルが存在しない場合だけopenするようにOpenOptionsを利用してみています。\nflushを呼び出すべきなのかどうか?を調べないとな。。。\n13. col1.txtとcol2.txtをマージ pub fn merge_files(col1_file: \u0026amp;str, col2_file: \u0026amp;str, output_file_name: \u0026amp;str) { let col1_buf = BufReader::new(File::open(col1_file).expect(\u0026#34;file not found\u0026#34;)); let col2_buf = BufReader::new(File::open(col2_file).expect(\u0026#34;file not found\u0026#34;)); let mut output_f = OpenOptions::new() .write(true) .create(true) .open(output_file_name) .expect(format!(\u0026#34;can\u0026#39;t open file[{}] with write option\u0026#34;, output_file_name).as_str()); col1_buf .lines() .zip(col2_buf.lines()) .for_each(|(col1, col2)| { let col1 = col1.expect(\u0026#34;parse error col1\u0026#34;); let col2 = col2.expect(\u0026#34;parse error col2\u0026#34;); writeln!(output_f, \u0026#34;{}\\t{}\u0026#34;, col1, col2); output_f.flush().expect(\u0026#34;Error during flush\u0026#34;); }); } 2つのファイル名を入力として受け取り、タブでくっつけて出力します。 zipを利用することで、2つのイテレーターを同時に回しています。\n14. 先頭からN行を出力 pub fn head(input_file_name: \u0026amp;str, lines: usize) -\u0026gt; String { let buf = BufReader::new(File::open(input_file_name).expect(\u0026#34;file not found\u0026#34;)); let mut head = String::new(); buf.lines().take(lines).for_each(|line| { head.push_str(format!(\u0026#34;{}\\n\u0026#34;, line.expect(\u0026#34;parse error\u0026#34;)).as_str()); }); return head; } イテレーターのメソッドにtakeがあります。 これを利用することで、引数に指定した数のエレメントが取得できるので、これでheadが実現できます。\n15. 末尾のN行を出力 pub fn tail(input_file_name: \u0026amp;str, lines: usize) -\u0026gt; String { let buf = BufReader::new(File::open(input_file_name).expect(\u0026#34;file not found\u0026#34;)); let mut tail = String::new(); let line_count = word_count(input_file_name); buf.lines().skip(line_count - lines).for_each(|line| { tail.push_str(format!(\u0026#34;{}\\n\u0026#34;, line.expect(\u0026#34;parse error\u0026#34;)).as_str()); }); return tail; } tailの場合は少し複雑で、11で作成した行数をカウントするメソッドで総行数を取り出し、そこから引数で指定された行数を引き算した数(=出力しない行数)を、イテレーターのskipメソッドの引数に渡しています。これにより、指定された数のエレメントをスキップしたあとの処理がかけます。\n16. ファイルをN分割する pub fn split_files( input_file_name: \u0026amp;str, num: usize, output_file_prefix: \u0026amp;str, output_file_suffix: \u0026amp;str, ) { let total = word_count(input_file_name) as f64; let lines_in_file = total / num as f64; let lines_in_file = lines_in_file.ceil() as usize; // let buf = BufReader::new(File::open(input_file_name).expect(\u0026#34;file not found\u0026#34;)); let output_files: Vec\u0026lt;File\u0026gt; = create_file_vec(output_file_prefix, num, output_file_suffix); println!(\u0026#34;split file each {} lines.\u0026#34;, lines_in_file); let mut lines = buf.lines(); for mut output_f in output_files { let mut current = 1; while current \u0026lt; lines_in_file + 1 { let line = lines.next(); if let Some(line_rs) = line { if let Ok(line_str) = line_rs { writeln!(output_f, \u0026#34;{}\u0026#34;, line_str); } } current = current + 1; } output_f.flush().expect(\u0026#34;error during flush\u0026#34;); } } fn create_file_vec(output_file_prefix: \u0026amp;str, num: usize, output_file_suffix: \u0026amp;str) -\u0026gt; Vec\u0026lt;File\u0026gt; { let mut files = Vec::with_capacity(num); for i in 0..num { let output_file_name = format!(\u0026#34;{}{}{}\u0026#34;, output_file_prefix, i + 1, output_file_suffix); let output_f = OpenOptions::new() .write(true) .create(true) .open(output_file_name.as_str()) .expect(format!(\u0026#34;can\u0026#39;t open file[{}] with write option\u0026#34;, output_file_name).as_str()); files.push(output_f); } return files; } ちょっと長いですね。\n入力としては、分割するファイル数Nが指定されます。まずは、総行数/Nで各ファイルに保存されるべき行数を計算します。 次に、2つ目の関数をつかって、必要な数のファイルオブジェクトをベクトルとして生成します。\nファイルオブジェクトのベクトルの要素を元にしたfor文を回しつつ、それぞれのファイルに必要な行数を出力している処理になっています。\n総行数がNで割り切れない場合にceilで切り上げした行数にするというちょっとした処理を入れてあります。\n17. 1列目の文字列の異なり pub fn count_uniq_words(input_file_name: \u0026amp;str, col: usize) -\u0026gt; usize { let mut words = HashSet::new(); let buf = BufReader::new(File::open(input_file_name).expect(\u0026#34;file not found\u0026#34;)); buf.lines().for_each(|line| match line { Ok(line_str) =\u0026gt; { let columns: Vec\u0026lt;_\u0026gt; = line_str.split(\u0026#39;\\t\u0026#39;).collect(); words.insert(columns[col].to_string()); } Err(_) =\u0026gt; panic!(\u0026#34;parse error \u0026#34;), }); return words.len(); } HashSetを利用することでユニーク性を担保して、最後はHashSetの数を数え上げれば終了です。\n18. 各行を3コラム目の数値の降順にソート pub fn sort_on_col3(input_file_name: \u0026amp;str) -\u0026gt; String { let mut lines: BTreeSet\u0026lt;Line\u0026gt; = BTreeSet::new(); let buf = BufReader::new(File::open(input_file_name).expect(\u0026#34;file not found\u0026#34;)); buf.lines().for_each(|line| match line { Ok(line_str) =\u0026gt; { let columns: Vec\u0026lt;_\u0026gt; = line_str.split(\u0026#39;\\t\u0026#39;).collect(); let num: u32 = columns[2].parse().expect(\u0026#34;parse error\u0026#34;); let line = Line { line: line_str, num, }; lines.insert(line); } Err(_) =\u0026gt; panic!(\u0026#34;parse error\u0026#34;), }); let mut sorted = String::new(); lines.iter().for_each(|line| { sorted.push_str(format!(\u0026#34;{}\\n\u0026#34;, line.line).as_str()); }); return sorted; } #[derive(Eq)] struct Line { line: String, num: u32, } impl Ord for Line { fn cmp(\u0026amp;self, other: \u0026amp;Self) -\u0026gt; Ordering { let ord = other.num.cmp(\u0026amp;self.num); if let Ordering::Equal = ord { other.line.cmp(\u0026amp;self.line) } else { ord } } } impl PartialOrd for Line { fn partial_cmp(\u0026amp;self, other: \u0026amp;Self) -\u0026gt; Option\u0026lt;Ordering\u0026gt; { Some(self.cmp(other)) } } impl PartialEq for Line { fn eq(\u0026amp;self, other: \u0026amp;Self) -\u0026gt; bool { self.eq(other) } } Lineという、行の文章と第3カラム目の値をもった構造体を作成しました。そこにEq、Ord、PartialOrd、PartialEqを実装し、3カラム目での大小比較できるようにしました。 この構造体をBTeeSetに格納していき、イテレーターで回すことで、ソートされた状態にしてあります。 同一数値の場合は行の降順でソートできるようにOrdを実装してあります。\n19. 各行の1コラム目の文字列の出現頻度を求め,出現頻度の高い順に並べる pub fn sort_on_frequency(input_file_name: \u0026amp;str) -\u0026gt; String { let mut names: HashMap\u0026lt;String, u32\u0026gt; = HashMap::new(); let buf = BufReader::new(File::open(input_file_name).expect(\u0026#34;file not found\u0026#34;)); buf.lines().for_each(|line| match line { Ok(line_str) =\u0026gt; { let columns: Vec\u0026lt;_\u0026gt; = line_str.split(\u0026#39;\\t\u0026#39;).collect(); let name_str = columns[0].to_string(); let count = names.entry(name_str).or_insert(0); *count += 1; } Err(_) =\u0026gt; panic!(\u0026#34;parse error\u0026#34;), }); let mut sorted = String::new(); let mut sorted_names: Vec\u0026lt;(\u0026amp;String, \u0026amp;u32)\u0026gt; = names.iter().collect(); sorted_names.sort_by(|(aname, acount), (bname, bcount)| { let ord = bcount.cmp(acount); if let Ordering::Equal = ord { bname.cmp(aname) } else { ord } }); sorted_names.iter().for_each(|(name, count)| { sorted.push_str(format!(\u0026#34;{} {}\\n\u0026#34;, count, name).as_str()); }); return sorted; } もうすこしうまくできる気がしますが、いったんこれで。 数え上げのためにまずはHashMapに第1カラムの文字列, 個数という組み合わせでデータを入れていきます。 出来上がったHashMapをタプルのベクターに変換し、変換したベクターのsort_byメソッドに比較用の関数を渡すことで個数の降順に並べています。同一個数の場合は文字列の降順になっています。 で、最後に並びかわったベクターのイテレーターを使って出力しておしまいです。 内部的には最悪3回回る感じでしょうか? 最初からベクトルに入れつつソートできる仕組みにするようなのがいいのかなぁ?\nまとめ Unixコマンドの勉強になりましたw あとは、HashMapなどの勉強にもなりました。 最後の方は効率がいまいち良くない気もしてはいますが、とりあえず第3章に進もうかと思います。\n","date":1589253809,"dir":"post/2020/","id":"09155bf417a93847b538ad607f78cca2","lang":"ja","lastmod":1589253809,"permalink":"https://blog.johtani.info/blog/2020/05/12/reboot-nlp100-ch02-12to19/","publishdate":"2020-05-12T12:23:29+09:00","summary":"Rustで言語処理100本ノックの第2章の残りです。 前回はこちら。 ちなみに、標準入力から受け取る処理は書いてないです。 出力に関してはファイル","tags":["Rust","nlp100"],"title":"第2章の12から19まで(言語処理100本ノック2020)"},{"contents":"気づいたら1ヶ月サボってました、ごめんなさい。。。\nRustで言語処理100本ノックの第2章をはじめました。\n前回はこちら。\n確認用のUnixコマンド 確認用のファイルを先に生成して置きました。 これで、Rustでコードを書いて、作成済みの確認ファイルを元にassert_eq!でチェックするという方式を取ろうかと。\nで、コマンド群はこちらです。\nUnix/Linuxコマンド、昔から使っています。が、なにかちょっとした文字列処理やファイル処理をやるときは、Javaのプログラム(最近だとPython)を書くというのが基本になってるので、結構、使ったことの無いコマンドが今回ありました。使ったことがなかったのはこちらです。\nsed tr expand paste cut split sedとかは普通さわってるだろ?って思われそうですね。。。\nで、コマンドをmanで調べつつやりました、macOS上で。 これがまたいくつか罠があったので書き残しておきます(自分が知らないだけかもしれないので、おかしいところがあったらツッコミお願いします。)。\nsedコマンドでのタブの扱い ## sed command for macOS. If using Linux, use \u0026#34;\\t\u0026#34; for tab character cat $INPUT_FILE_NAME | sed -e \u0026#39;s/\t/ /g\u0026#39; \u0026gt; $OUTPUT_DIR/11_sed.txt \\tで行けると思ったのですが、うまく動きませんでした。\u0026lt;tab\u0026gt;みたいな書き方もあると思うのですが、これも駄目で、結局タブ文字をそのまま打ち込みました。。。 これ、めんどくさくないですか??? ちなみに、ターミナルで動作確認して、GitHubにあげてあるシェルファイルにコピペしてたのですが、CLionに貼り付けたらタブ文字がスペースに変換されてしまってて20分くらい悩みました。。。\nsplitコマンドに-nオプションがない LINES=`cat $OUTPUT_DIR/10.txt` SPLIT_LINES=`echo $LINES/$N | bc` split -a 1 -l $SPLIT_LINES $INPUT_FILE_NAME $OUTPUT_DIR/16_ splitコマンドについてググると、-nで指定した数のファイルに分割できるという記事がいくつも出てくるのですが、man splitをターミナル上でやるとそんなオプションがないと。。。 macOSがBSD系だからっぽいです。 ということで、行数を元に、指定した数(N)で行数を割ってから、指定行数ごとにファイルを分割する方式にしました。\nこれらのコマンドの違いはHomebrewとかでインストールするとなくなるのかなぁ?(めんどくさいので確認してないですが。。。)\nってことで、2章のそれぞれの課題の正解ファイルの生成はこれでできたはずです。\n10. 行数のカウント wc -lですね。\n// ch02-10 行数のカウント pub fn word_count(file_name: \u0026amp;str) -\u0026gt; usize { let f = File::open(file_name).expect(\u0026#34;file not found\u0026#34;); let buf = BufReader::new(f); return buf.lines().count(); } ファイルを読み込んで行数を数えます。 文字列として読み込んで改行コードの数を数えるというのもありかな?と思いましたが、RustのBufReaderにlines()という行のイテレータ?が取れることがわかったので、それでカウントを取りました。\n11. タブをスペースに置換 // ch02-11 タブをスペースに置換 pub fn tab_2_space(file_name: \u0026amp;str) -\u0026gt; String { let mut f = File::open(file_name).expect(\u0026#34;file not found\u0026#34;); let mut contents= String::new(); f.read_to_string(\u0026amp;mut contents).expect(\u0026#34;read error\u0026#34;); return contents.replace(\u0026#34;\\t\u0026#34;, \u0026#34; \u0026#34;); } こっちはファイル全体を文字列に読み込んでしまってから、文字列のreplaceで置換するという方式です。 ファイルが大きい場合にこれでいいのか?という問題がある気がしますが、まずはこの実装にしました。 やるとしたら、readメソッドとbufferを用意して、少しずつ読みながら、置換して吐き出す感じでしょうか? ちゃんとした文字コードの区切りで取れるかどうかを気にしないと行けないと思うので、思ったよりはめんどくさくなりそう。\nBufReaderをつかってread_lineのほうがましかも?\nまとめ ということで、サボっていたのを再開しました。 Rustのコードを書く前に、Unixコマンドの処理に結構悩みましたw\nRustのコードとしてはファイル処理なので、今後も役立つ気がしてます。 ということで、頑張っていくぞと。\n","date":1588948640,"dir":"post/2020/","id":"c098c6f0901979bd914ed7a345200f90","lang":"ja","lastmod":1588948640,"permalink":"https://blog.johtani.info/blog/2020/05/08/rebootnlp100-ch02-10to11/","publishdate":"2020-05-08T23:37:20+09:00","summary":"気づいたら1ヶ月サボってました、ごめんなさい。。。 Rustで言語処理100本ノックの第2章をはじめました。 前回はこちら。 確認用のUnixコマ","tags":["Rust","nlp100"],"title":"第2章の10から11まで(言語処理100本ノック2020)"},{"contents":"Rustで言語処理100本ノックのリファクタリングの続き。\n前回はこちら。\nとっくに終わってたのに、ブログ書いてなかった。。。\n08. 暗号文 pub fn cipher(text: \u0026amp;str) -\u0026gt; String { return String::from_iter(text.chars().map(|x| { if x.is_ascii_alphanumeric() \u0026amp;\u0026amp; x.is_lowercase() { let mut b = [0; 4]; x.encode_utf8(\u0026amp;mut b); b[0] = 219 - b[0]; char::from(b[0]) } else { x } })); } Rustの文字列はUTF-8でエンコードされたテキストを保持しているので、文字コード自体は意識していないです。 chars()でUnicodeスカラー値のイテレータが返ってくるので、1文字ずつ扱えるようになります。\nただ、1文字をバイトとして扱うのに手こずりました。 encode_utf8というメソッドを利用して1バイトだけ取り出して、計算するというのをやっています。 文字種の判別のメソッドが用意されているのは便利ですね。\nなんかもうちょっとスマートにできないのかな?と思いつつ動いたのでこれになってます。\n09. Typoglycemia pub fn typoglycemia(text: \u0026amp;str) -\u0026gt; String { return text .split_whitespace() .map(|word| { if word.len() \u0026lt;= 4 { word.to_string() } else { let original = word.chars().collect::\u0026lt;Vec\u0026lt;char\u0026gt;\u0026gt;(); let first = original.get(0).unwrap(); let last = original.last().unwrap(); let mut typo = original[1..original.len() - 1] .iter() .map(|x| x.clone()) .collect::\u0026lt;Vec\u0026lt;char\u0026gt;\u0026gt;(); let mut rng = thread_rng(); typo.shuffle(\u0026amp;mut rng); let mut typo = String::from_iter(typo.iter()); typo.insert(0, first.clone()); typo.push(last.clone()); typo } }) .collect::\u0026lt;Vec\u0026lt;String\u0026gt;\u0026gt;() .join(\u0026#34; \u0026#34;); } 一応、1行で記述できたかな? まずは、スペースで単語ごとに区切った後に、word(単語)の長さによって、処理を分岐し、単語が5文字以上の場合にランダムに並び替えを行うというのをやっています。 文字単位で処理を行うために、chars()で1文字ずつ取り出しています。 最初と最後の文字だけはそのままに、間の文字をランダムにシャッフルするというのをやるのに、もとのwordのスライスからコピーした文字列を作り出してから組み立て直すということをやっています。\nコピーしないでゴニョゴニョする方法ってあるのかなぁ? 思いつかなかったので、結構泥臭い感じの実装になってしまいました。\nまとめ めんどくさいので、コードをGitHubのソースコードからではなく、ブログにコードスニペットとしてコピペしました。Hugoでいい感じにGitHubのコードスニペット表示するのないかなぁ?\nということで、2年越しで1章が終了しました。 2章もやらないとなぁ。\n","date":1588923657,"dir":"post/2020/","id":"2c3270f8797ace2fb37402ea6a09d126","lang":"ja","lastmod":1588923657,"permalink":"https://blog.johtani.info/blog/2020/05/08/reboot-nlp100-finish-ch01/","publishdate":"2020-05-08T16:40:57+09:00","summary":"Rustで言語処理100本ノックのリファクタリングの続き。 前回はこちら。 とっくに終わってたのに、ブログ書いてなかった。。。 08. 暗号文 pub fn cipher(text: \u0026amp;str) -\u0026gt;","tags":["Rust","nlp100"],"title":"第1章の08から09まで(言語処理100本ノック2020)"},{"contents":"前回はWorkplace Searchの概要について書きましたが、今回はインストールと構成要素について説明します。なお、2020/5/7時点での情報を元に本記事は書いていますのでご注意ください。基本的にはインストールと起動方法についての手順を元に書いています。所々に考察を挟んだ形の記事になっていますので、気になるところだけ呼んでいただければと。\n記事一覧 ElasticのWorkplace Searchを触ってみる - その1 インストール インストール方法は公式リファレンスもしくはダウンロードページに記載があります。 現時点ではMacもしくはLinuxが対象でWindowsはまだサポート対象外となっています。\n必要なもの インストールに必要なものは以下になります。\nElasticsearch 7.6.x + Platinum license Elastic CloudのElasticsearch Service もしくは ダウンロードしてローカルで起動 enterprise-search-7.6.0.tar.gz ダウンロードページはこちら Java 8もしくは11 Long Term Supportの対象であるJavaです。2020/5/7時点では8か11 今回はローカルにElasticsearchの7.6.2をインストールしてから試してみます。30日間のトライアルライセンスが有効になっているので、Platinumの機能を試すことができます。\nJavaの8か11が必要になります。Elasticsearchには7.xからJDKが同梱されるようになりましたが、Workplace SearchがJettyを元に動作しているからです(enterprise-search-7.6.0.tar.gzにjettyというフォルダあり)。\nインストール手順 大まかには以下の3つです。\nJava 8もしくは11のインストール 14でも大丈夫でした(ローカルにはSDKMANでインストールした14.0.1が利用された)。 Elasticsearchのインストール(Elastic Cloudの場合はクラスタの起動) 今回はローカルにインストール Workplace Searchのインストール Javaはもともとインストールされていたので、今回は2と3をインストールしました。どちらもローカルで起動するので、2つをダウンロードしてtar.gzファイルを展開するだけになります。\n起動方法と設定 起動方法に起動前の設定の手順も記載があります。 設定しながら起動していきます。\nElasticsearchの起動 既存のElasticsearchのクラスターがあり、Platinumのライセンスが有効になっている場合はこの手順は必要ありません。\nElasticsearchの設定ファイルでSecurity機能をオンに 7.1から基本的なセキュリティ機能はベーシックの機能に含まれています。 Elasticsearchを起動 まずは起動(パスワードなどを設定するために必要) Elasticsearchのパスワードの設定 Elasticsearchでデフォルトで用意されているユーザーのパスワードを設定してします。手順では自動で生成させる方法ですが、独自に設定することも可能です。 Workplace Searchの起動 Elasticsearchが起動したらWorkplace Searchの設定をして起動します。\nEsへの接続設定をconfig/enterprise-search.ymlに指定 Esのパスワード設定時に生成されたelasticというユーザーのパスワードをここで指定。 yamlファイルに記載があるが、${ELASTICSEARCH_PASSWORD:changeme}という記述をした場合に環境変数を読み込める allow_es_settings_modification: trueをconfig/enterprise-search.yml ここに記載があるような変更をWorkplace SearchがEsのクラスターに対して実行する模様。Workplace Search以外でも使用しているElasticsearchクラスターの場合はallow_es_settings_modificationを有効にする代わりに、リンク先にあるような設定を自分で追加する。 secret_management.encryption_keysを複数設定 Encryption Keysのガイドに少し詳しい説明がある。 opensslコマンドとかで作ればいいかな?? 1.と同じような設定をしようとしたがうまくいかなかったので、ファイルにキーを設定する方式にしました(バグ?) 起動するときにデフォルトユーザーパスワードを指定 指定しなければ勝手に生成してコンソールに出力してくれるので、そちらの方がいいかと。 今回は手順通りに指定した。 起動確認のためhttp://localhost:3002にアクセス 起動するとログが流れ、問題がなければ次のようにデフォルトユーザーの情報が出力されます。\n######################################################### *** Default user credentials have been setup. These are only printed once, so please ensure they are recorded. *** username: enterprise_search password: pas...ple ######################################################### そして無事起動に成功したことも出力されます。\n######################################################### Success! Elastic Workplace Search is starting successfully. In a few moments, you\u0026#39;ll be able to login at the following address: * URL: http://localhost:3002 * If this is your first time starting Workplace Search, check the console output above for your user authentication credentials. * Visit the documentation: https://swiftype.com/documentation/enterprise-search Secret session key has been generated. Set the key in your config file to persist user sessions through process restarts: secret_session_key: c23...3 ######################################################### ブラウザで画面にアクセスすると、次のような画面が表示されました。\n起動時のエラー いくつかのパターンも試してどんなエラーが出るのかを見てみました。 おまけですね。\nElasticsearchが見つからないエラー Esを起動しないでWorkplace Searchを起動してみました。\n200秒間アクセスしようと試みて駄目だったらエラーで終了みたいです。\n[2020-05-07T03:48:33.645+00:00][13709][2002][app-server][INFO]: Failed to connect to Elasticsearch backend. Make sure it is running. ... [2020-05-07T03:51:54.038+00:00][13709][2002][app-server][INFO]: Could not connect to Elasticsearch backend after 200s. Terminating... [2020-05-07T03:51:54.039+00:00][13709][2002][app-server][ERROR]: -------------------------------------------------------------------------------- Error: Workplace Search is unable to connect to Elasticsearch. Ensure a healthy Elasticsearch cluster is running at http://127.0.0.1:9200 for user elastic. -------------------------------------------------------------------------------- ElasticsearchのSecurityがオフのときのエラー ちなみにSecurityをオフにしたままWorkplace Searchを起動した場合は以下のようなエラーが出ました。\n[2020-05-07T03:46:53.474+00:00][13567][2002][app-server][ERROR]: -------------------------------------------------------------------------------- Elastic Workplace Search requires Elasticsearch security features to be enabled. Please enable Elasticsearch security features as outlined here: https://www.elastic.co/guide/en/workplace-search/current/workplace-search-install.html -------------------------------------------------------------------------------- 構成要素 ここまでインストールして起動してきました。 では、Workplace Searchがどういったコンポーネントから構成されているかを予測してみましょう(あくまで外から見た予想となります。そのうちElastic社のウェビナーとかイベントで内部の発表とかあるかも?)。\nインストールページの記載から インストールページに最小ハードウェアという記載があり、そこで何が動く可能性があるかというのがわかります。\n起動するものはこんな感じみたいです。\nElasticsearch - 外部でもOK App Server - Workplace SearchのWeb機能 Worker - クローラーとかかな? Filebeat - Workplace Searchのログ収集用 その他プロセス - なんだろ? という具合です。\n設定などからの予想 次は設定項目や起動時のログなどからの予想です。\nWorklpace Search配下のセキュアなデータストア - アクセストークンなどの管理のため JRubyアプリケーション - App ServerはJRuby上で動いているRailsアプリ Filebeatも起動している - Workplace Searchのログ収集のため? Filebeatの接続設定はWorkplace Searchの設定値を利用 では構成要素は? ということで、現時点でわかった構成要素は以下のとおりです。\nElasticsearch Workplace Search App Server - Railsアプリ on JRuby Webアプリとは別に(内部?で)、いくつかのワーカーが存在する 管理画面と検索画面の2種類が存在 Filebeat - ログ収集 といった感じです。 まだ起動したばかりなのでこのくらいでしょうか。ログを見るともう少しわかりそうな気がします。\n基本的には、EsをバックエンドにしたRailsのミドルウェアになります。コネクターや検索画面はすべてWorkplace Searchのミドルウェア経由でアクセスする形になりますので、普通に検索で利用するユーザーにはElasticsearchの存在は見えない作りになっています。\n次は? Getting Startedを元に、どんなアクターがいて、どんな機能が提供されているのか、どんな利用方法なのか?というのを見ていこうと思います。\n","date":1588818770,"dir":"post/2020/","id":"44db1f1fefc97cd28d55d443f2bd2b63","lang":"ja","lastmod":1588818770,"permalink":"https://blog.johtani.info/blog/2020/05/07/install-workplace-search/","publishdate":"2020-05-07T11:32:50+09:00","summary":"前回はWorkplace Searchの概要について書きましたが、今回はインストールと構成要素について説明します。なお、2020/5/7時点で","tags":["elasticsearch","workplace search"],"title":"ElasticのWorkplace Searchを触ってみる - その2 - インストールと起動"},{"contents":"2月のElastic社のブログですが、Enterprise Searchとこれまで呼んでいた製品をWorkplace Searchという製品名に変更し、App Searchなどを含む製品群をEnterprise Searchという名前に変更しました(ちょっとややこしい)。 Workplace Search自体はまだβ版という位置づけですが、ダウンロードして試すことが可能です。\nきちんと触ったことがないので、ちょっと触って見ようかなと思い、何回かに分けてブログを書いてみます。まずは概要とかから。\nWorkplace Searchとは? Elasticsearchをバックエンドに利用するElastic社が提供するアプリケーション(ミドルウェア?)の1つです。\nもともとはSwiftypeという会社が作っていた、Site Search、App Searchと同じような系列で開発されている統合検索の検索エンジンミドルウェアという感じです。 製品ページを見るとわかりますが、様々なデータソースから、データをクロールしてElasticsearchに保存することで、統合された検索を提供することができるようになる製品です。 最近は会社のドキュメントがさまざまな場所(Google Drive、Saleseforce、GitHub、Dropboxなど)に保存されています。 それぞれで検索窓などはありますが、1箇所で検索することで横断的に検索でき、仕事の効率があがりますよね?ということで作られている製品です。\n提供(利用)方法は? 今後の提供方法としては、Elastic Cloudで利用できるSaaS形式のものと、独自に(クラウドのコンピューティングエンジンやオンプレのサーバーなどで)Workplace Searchのアプリを起動する方法(オンプレ版)があります。後者の場合は、Elasticsearchのクラスターを用意する必要があります。なお、後者の場合、Elasticsearchのサブスクリプションのプラチナライセンスが必要になるようです(ダウンロードページに記載あり)\nまだ、β版という位置づけなので、今後どのように変更されるかはわかりませんが、今回は2020年5月1日時点でのベータ版(7.6.0)を元にどんなものかを紹介します。現時点で利用できるのはβ版のオンプレ版で、MacやLinuxで利用可能です。\nダウンロードとインストール ダウンロードページにインストール方法などの記載があります。\nインストールして触って見るところはまた後日。\nライセンス、価格は? まだ不明です。SaaS版の提供はまだです。 オンプレ版については少なくとも、Elasticのサブスクリプションのプラチナが必要になります。こちらは、価格は公開されていません。Elastich社もしくはパートナー企業での問い合わせが必要になります。 (たぶん、ドキュメントレベルのセキュリティとかSSOとかの仕組みがプラチナで提供されているのでそのあたりを使っているのでは?と想像してます。)\n想定できそうな用途は? 社内の文書検索でしょうか。ただ、いわゆる昔ながらのエンタープライズサーチと呼ばれている、社内のファイルサーバーなどの文書検索ではなく、クラウドサービスを複数利用している会社が利用する想定になっています。\n例えば、開発者は社内Wiki(Confluence)で社内文書を書き、Issue管理にはJIRAやGitHubを活用しており、ただ、社内での説明にはGoogle Driveを利用しているといった場合です。こういう場合、あの機能についての説明や資料ってどこだっけ?というので、あちこち探し回ったりしないといけないです。また、営業部門やサポート、マーケティングなどが絡んでくると更に、SalesforceやZendeskといったデータソースも出てきます。 情報が散らばっていて、それらを探し出したりまとめるだけで時間を取られている場合などに便利かもしれません。\n次は? 実際にインストールしてから起動して、どんな感じで使えるのかといったところを見て、どんな機能が提供されているのかを見ていこうと思います。\n","date":1588318144,"dir":"post/2020/","id":"4d71d2a23c85fb7af20e8d1e8b3e0de8","lang":"ja","lastmod":1588318144,"permalink":"https://blog.johtani.info/blog/2020/05/01/intro-workplace-search/","publishdate":"2020-05-01T16:29:04+09:00","summary":"2月のElastic社のブログですが、Enterprise Searchとこれまで呼んでいた製品をWorkplace Searchという製品名に","tags":["elasticsearch","workplace search"],"title":"ElasticのWorkplace Searchを触ってみる - その1"},{"contents":"先日、Elasticsearchでのカスタム辞書の利用方法についてブログを書きました。\n辞書の設定方法について記載しましたが、今回は辞書の更新について書いていなかったので、書いてみようと思います。 ここで「辞書」としているのは、Kuromojiのユーザー辞書、Synonym Graph Token FilterのSynonym辞書(いわゆる類義語辞書)のことになります。サードパーティのAnalyzer等に関する話ではありません。\n辞書更新に関する制限事項 辞書の更新について、大原則と制限事項が存在します。\n大原則(辞書の更新=データも更新) ElasticsearchはAnalyzerが切り出した単語を元に転置インデックスを作成して、検索を行っています(この仕組みに関するスライドはこちらを参照のこと)。 Analyzerが辞書を持っている場合、その辞書を元に単語を切り出して転置インデックスに利用します。 また、検索クエリの単語に対してもこのAnalyzerの辞書が利用されます。\n辞書に新しい単語を追加するということは、その単語に関連するドキュメントも更新しないと行けないということになります。\n例えば、Kuromojiを利用していて、「グランベリーパーク」という単語「グランベリー」「パーク」という単語に分割できるような新しい単語として辞書に追加する場合を考えてみましょう。ユーザーが「グランベリー」で検索しても検索結果として出てきてほしいという場合です。\n辞書に「グランベリーパーク」を登録していない頃に登録されたドキュメントは「グランベリーパーク」という1単語として転置インデックスの見出し語を切り出します(Kuromojiはカタカナの連続している文字列については未知語として1単語にし、「名詞-一般」の品詞を付与)。\n更新前でのドキュメントのAnalyze結果\n「グランベリーパーク」「で」「ショッピング」 もし、辞書に「グランベリーパーク」を「グランベリー」「パーク」から構成される新規の単語として登録しそれを使用した場合、辞書を更新したあとから、「グランベリーパーク」という単語がAnalyzerからは出てこなくなります。\n更新後でのドキュメントのAnalyze結果\n「グランベリー」「パーク」「で」「ショッピング」 ということは、辞書更新以前のドキュメントは「グランベリーパーク」という見出し語に対して登録されているので、辞書更新以前に登録されているドキュメントは検索にヒットしなくなります。\nこのように転置インデックスを利用している検索エンジンでは、単語の区切りが変更されるような辞書の更新があった場合、最低でも影響があるドキュメントについては再登録が必要となるわけです。\nこれが大原則(辞書更新=データも更新)となります。 基本的には辞書の更新を行った場合は、ドキュメントの再インデックス(再登録)が必要となります。\nElasticsearchでの制限事項 Elasticsearchでは、辞書の更新に関して実装上の制限事項が存在しています。 内部的な実装として、ElasticsearchではAnalyzerのインスタンス(正確にはAnalyzerのFactoryのインスタンス)の生成がインデックスに関する内部のインスタンスが生成されたタイミングの1回のみとなっています。\nこのインスタンスの生成時に設定ファイル(辞書を含む)を読み込んでいます。\n言い換えると、辞書(ファイル、インデックス設定に関わらず)の読み込みは、インデックスが作られたタイミングのみということになります。 なおここで言う「インデックスが作られたタイミング」というのは、以下の2パターンです。\nインデックス新規作成時 インデックスオープン時 では、ここから辞書を更新してそれを既存のインデックスに適用する方法について説明しましょう。\n辞書の更新方法(ファイル編) 前回のブログで説明しましたが、Elasticsearch 7.4よりも古いバージョンでは、ファイルでKuromojiのユーザー辞書を設定していました。まずはこちらの方法について説明します。前提として、すでにユーザー辞書を設定したKuromoji Tokenizerがインデックスに設定されているものとします(ユーザー辞書の設定方法については公式リファレンスを御覧ください)。\n辞書ファイルに新規にエントリーを追加しただけでは、設定は読み込まれていません。新規辞書を反映させるためには以下の手順が必要となります。\n更新した辞書ファイルの配布 複数ノードでElasticsearchのクラスターを構成している場合はすべてのノードに更新した辞書ファイルを配布する必要があります。 インデックスのクローズ(公式リファレンス) 設定ファイルを再読込させるために一度インデックスをクローズします。 クローズするので、書き込み、検索などの処理を停止する必要があります。もし停止していない場合はクライアント側ではインデックスがクローズされているという旨のエラーを受け取ります(400で、index_closed_exception)。 インデックスのオープン(公式リファレンス) 設定ファイルを読み込みます。これで、新規追加された単語が読み込まれます。 再インデックス _update_by_queryを利用することで、対象のインデックスのデータを再インデックスすることができます。条件無しでAPIを呼び出すとすべてのデータが再度登録されます。 _sourceがfalseの場合は_update_by_queryは利用できません。元データをもう一度外部からElasticsearchに対して登録する必要があります。 Kibanaでの手順をGistにしてあります。手順はこちらをご覧ください。\n辞書の更新方法(インデックス設定編) ファイルの場合とは少し手順が異なります。 インデックスの設定としてユーザー辞書を登録しているため、ファイルをElasticsearchのクラスターにあるノードに配布する必要がありません。 また、辞書の設定はインデックスの設定に指定してありますが、こちらは動的に設定変更できる項目ではないため、インデックスを先にクローズする必要があります。\nインデックスのクローズ(公式リファレンス) 辞書の設定を更新するにはインデックスをクローズする必要があります。辞書の設定は動的に更新できる項目にはなっていないためです。 オープンしているインデックスで更新しようとした場合はillegal_argument_exceptionでCan't update non dynamic settings...というメッセージが返ってきます。 辞書の更新(公式リファレンス:インデックス設定の更新) user_dictionary_rulesに単語と追加します。 インデックスのオープン(公式リファレンス) 設定ファイルを読み込みます。これで、新規追加された単語が読み込まれます。 再インデックス _update_by_queryを利用することで、対象のインデックスのデータを再インデックスすることができます。条件無しでAPIを呼び出すとすべてのデータが再度登録されます。 _sourceがfalseの場合は_update_by_queryは利用できません。元データをもう一度外部からElasticsearchに対して登録する必要があります。 Kibanaでの手順をGistにしてあります。手順はこちらをご覧ください。\n第3の方法(新規インデックス作成) ここまで、インデックスのクローズ、オープンで既存のインデックスに対して辞書を更新する方法について説明しました。 ただ、残念なことにAmazon Elasticsearch ServiceではElasticsearchが提供しているすべてのAPIが利用できるわけではありません(Amazon ESの利用可能なAPIの一覧はこちら)。 (_closeは駄目だけど_openは呼べるのかな???)\nということで、新規にインデックスを作成して、新しい辞書の設定を反映したインデックスを用意し、そこにデータをコピーもしくは登録するという方法になります(Amazon ESのカスタム辞書のドキュメントに手順がありますね)。\n手順としては以下のとおりです。\n辞書の更新(用意) 新しい単語などを登録した辞書を用意します。 ファイル、インデックス設定どちらでもOKです。 ファイルの場合は、既存のファイル名とは異なるファイル名にしたほうが混乱がなくなります。 新規インデックス作成 1.で作成した辞書を元に新規インデックスを作成します。 新規インデックスにデータコピー _reindex APIを利用するとデータコピーが簡単です。sourceとdestを指定するだけです。 _sourceがfalseの場合は_update_by_queryは利用できません。元データをもう一度外部からElasticsearchに対して登録する必要があります。 アプリケーション側で新規インデックスを利用するように変更 _aliasを使用しておくと切り替えが簡単です(公式リファレンスはこのあたり)。 考慮すべき点としては、サービスを提供しながら行う場合は、3.の_reindexを実行し始めたタイミング以降の登録・更新データの扱いについてでしょうか。\nまとめ 辞書の更新に関する大原則、制限事項、手順などについて説明しました。 辞書の変更は検索に大きく影響がでます。そのあたりをきちんと考慮しながら更新しましょう。 ユーザー辞書、カスタム辞書を扱う際の参考にしていただければと。 他にもユーザー辞書で気をつけないといけないこともありますが、今日はこのあたりで。\n","date":1587951855,"dir":"post/2020/","id":"be2c49ea5816e7daa6d3b3ff45353291","lang":"ja","lastmod":1587951855,"permalink":"https://blog.johtani.info/blog/2020/04/27/note-updating-dictionary/","publishdate":"2020-04-27T10:44:15+09:00","summary":"先日、Elasticsearchでのカスタム辞書の利用方法についてブログを書きました。 辞書の設定方法について記載しましたが、今回は辞書の更新","tags":["elasticsearch"],"title":"辞書の更新についての注意点"},{"contents":"Elasticsearchで日本語を扱うときに、カスタム辞書を使いたいという要望がよくあります。 AWSのElasticsearch Serviceでカスタム辞書ファイルを読み込める機能が発表されたようです。\n実は、Elasticsearchの7.4からファイルを使用しなくても日本語のTokenizerでカスタム辞書を利用することができるようになっています。\nカスタム辞書をインデックスの設定で指定 やり方はドキュメントに記載があります。\nトークナイザーの設定をインデックスの設定に記述しますが、このときに user_dictionary_rulesという設定を利用することでカスタム辞書を指定できます。\nPUT custom_dic_sample { \u0026#34;settings\u0026#34;: { \u0026#34;index\u0026#34;: { \u0026#34;analysis\u0026#34;: { \u0026#34;tokenizer\u0026#34;: { \u0026#34;kuromoji_user_dict\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;kuromoji_tokenizer\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;extended\u0026#34;, \u0026#34;user_dictionary_rules\u0026#34;: [ \u0026#34;グランベリーパーク,グランベリー パーク,グランベリー パーク,カスタム名詞\u0026#34;, \u0026#34;高輪ゲートウェイ,高輪 ゲートウェイ,タカナワ ゲートウェイ,カスタム名詞\u0026#34;] } }, \u0026#34;analyzer\u0026#34;: { \u0026#34;my_analyzer\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;custom\u0026#34;, \u0026#34;tokenizer\u0026#34;: \u0026#34;kuromoji_user_dict\u0026#34; } } } } } } 辞書の内部は\u0026quot;単語,出てきてほしい単語列(スペース区切り),読みの単語列(スペース区切り),品詞名\u0026quot;になります。配列で設定可能で、複数の単語を登録したい場合は、カンマ区切りで登録していきます(上記例では2つの単語を登録しています)。\n_analyzeを利用して設定の確認 実際に上記の設定がうまく動作するかは_analyzeのエンドポイントを利用します。\nGET custom_dic_sample/_analyze { \u0026#34;text\u0026#34;: \u0026#34;グランベリーパークがオープンしました。\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;my_analyzer\u0026#34; } 出力は以下のようになります。\n{ \u0026#34;tokens\u0026#34; : [ { \u0026#34;token\u0026#34; : \u0026#34;グランベリー\u0026#34;, \u0026#34;start_offset\u0026#34; : 0, \u0026#34;end_offset\u0026#34; : 6, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 0 }, { \u0026#34;token\u0026#34; : \u0026#34;パーク\u0026#34;, \u0026#34;start_offset\u0026#34; : 6, \u0026#34;end_offset\u0026#34; : 9, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 1 }, { \u0026#34;token\u0026#34; : \u0026#34;が\u0026#34;, \u0026#34;start_offset\u0026#34; : 9, \u0026#34;end_offset\u0026#34; : 10, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 2 }, { \u0026#34;token\u0026#34; : \u0026#34;オープン\u0026#34;, \u0026#34;start_offset\u0026#34; : 10, \u0026#34;end_offset\u0026#34; : 14, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 3 }, ...(省略) ] } ちなみに、デフォルトのkuromojiを利用した場合は、グランベリーパークが1単語として出力されます。\nGET _analyze { \u0026#34;text\u0026#34;: \u0026#34;グランベリーパークがオープンしました。\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;kuromoji\u0026#34; } ## レスポンス { \u0026#34;tokens\u0026#34; : [ { \u0026#34;token\u0026#34; : \u0026#34;グランベリーパーク\u0026#34;, \u0026#34;start_offset\u0026#34; : 0, \u0026#34;end_offset\u0026#34; : 9, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 0 }, { \u0026#34;token\u0026#34; : \u0026#34;オープン\u0026#34;, \u0026#34;start_offset\u0026#34; : 10, \u0026#34;end_offset\u0026#34; : 14, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 2 } ] } これで、カスタム辞書を使用することでグランベリーで検索された場合に、グランベリーパークもヒットするという仕組みです。\n_analyzeはexplainというパラメータも持っており、こちらを利用することで、単語の品詞情報なども取得できます。これを使うことで、実際に設定がきちんと動作しているかの確認に利用できます。\nGET custom_dic_sample/_analyze { \u0026#34;text\u0026#34;: \u0026#34;グランベリーパークがオープンしました。\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;my_analyzer\u0026#34;, \u0026#34;explain\u0026#34;: true } ## レスポンス(一部のみ) { \u0026#34;detail\u0026#34; : { \u0026#34;custom_analyzer\u0026#34; : true, \u0026#34;charfilters\u0026#34; : [ ], \u0026#34;tokenizer\u0026#34; : { \u0026#34;name\u0026#34; : \u0026#34;kuromoji_user_dict\u0026#34;, \u0026#34;tokens\u0026#34; : [ { \u0026#34;token\u0026#34; : \u0026#34;グランベリー\u0026#34;, \u0026#34;start_offset\u0026#34; : 0, \u0026#34;end_offset\u0026#34; : 6, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 0, \u0026#34;baseForm\u0026#34; : null, \u0026#34;bytes\u0026#34; : \u0026#34;[e3 82 b0 e3 83 a9 e3 83 b3 e3 83 99 e3 83 aa e3 83 bc]\u0026#34;, \u0026#34;inflectionForm\u0026#34; : null, \u0026#34;inflectionForm (en)\u0026#34; : null, \u0026#34;inflectionType\u0026#34; : null, \u0026#34;inflectionType (en)\u0026#34; : null, \u0026#34;partOfSpeech\u0026#34; : \u0026#34;カスタム名詞\u0026#34;, \u0026#34;partOfSpeech (en)\u0026#34; : null, \u0026#34;positionLength\u0026#34; : 1, \u0026#34;pronunciation\u0026#34; : null, \u0026#34;pronunciation (en)\u0026#34; : null, \u0026#34;reading\u0026#34; : \u0026#34;グランベリー\u0026#34;, \u0026#34;reading (en)\u0026#34; : \u0026#34;guramberi\u0026#34;, \u0026#34;termFrequency\u0026#34; : 1 }, { partOfSpeechにカスタム辞書で設定したカスタム名詞が出力されていますね。 _analyzeのAPIはこのように、アナライザーの挙動の確認に非常に便利なので是非活用してみてください。\nKibanaでこのAPIを使うためのプラグインも開発していますので、こちらも合わせて利用してみてください。\n注意点 ちなみに、user_dictionaryとuser_dictionary_rulesを両方指定した場合はエラーとなります。 ファイルをベースにしつつ、追加の設定をするという使い方はできないので、注意しましょう。\nインデックスの設定で書くことにより、バックアップ・リストアは楽になるかな。ただ、クラスターステートに取り込まれるから、あまりにも巨大なカスタム辞書だと心配かなぁ。ファイルの場合はクラスターステートには取り込まれないので、そこは圧迫しない。\n\u0026mdash; Jun Ohtani (@johtani) April 22, 2020 それ以外の注意点については、別途ブログを書きました。 「辞書の更新についての注意点」、こちらも合わせてご覧ください。\nまとめ カスタム辞書をファイルではなくインデックスの設定値として設定する方法を紹介しました。こちらは、Elasticsearch 7.4で導入された機能になります。7.4以降を利用している場合はこちらを利用することも検討してはいかがでしょうか? また、_analyze APIも便利なので合わせて活用してみてください。\n","date":1587519056,"dir":"post/2020/","id":"15357b6978e83daa2d97692c861dc177","lang":"ja","lastmod":1587519056,"permalink":"https://blog.johtani.info/blog/2020/04/22/custom-dictionary-after-7-4/","publishdate":"2020-04-22T10:30:56+09:00","summary":"Elasticsearchで日本語を扱うときに、カスタム辞書を使いたいという要望がよくあります。 AWSのElasticsearch Servi","tags":["elasticsearch"],"title":"Kuromojiのカスタム辞書をインデックスの設定で指定"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 第8章 7章はパッケージなので後回しにして、8章に入ります。 8章はコレクションです。\nベクタ型 ベクタは同じ型の値だけ保持可能。 ジェネリクスで型を指定可能 - Vec\u0026lt;i32\u0026gt;とか。 vec!マクロで初期値とか設定すると便利。 ベクタに値を追加するのはpush。もちろん値が変わるので元のベクタにはmutが必要 ベクタのスコープ(ライフサイクル)は要素に対する参照があるのとないので話が変わってくる メモリの確保などの影響で、ベクタ全体に対して借用の規則が矯正されると。 ベクタの値を読むのはいくつか方法あり getメソッドはOptionを返す \u0026amp;v[2]の添字記法の場合はパニックの可能性あり 走査(唐突に参照外しが出てきた) 単純に値を取り出す場合はfor - in \u0026amp;v Enumをベクタにいれることで、異なる型も保持可能(まぁ、Enumの型では固定されるけど)。 これだけのためにEnumを使うことってあるのかな? トレイとオブジェクトに関する文章はちょっとわかりにくい。。。 説明以外のメソッドなどについてはAPIドキュメント見ましょうと(リンクも張ってくれてると嬉しいなぁと思ったり。まぁ、バージョンとかの絡みがあるから難しいか)。\n文字列型 文字列はUTF-8でエンコードされた文字を扱うための型。\nstrは文字列データへの参照。\nString型は言語のコアではなく、標準ライブラリに入っている文字列型。\n他にもあるのか。。。OsStringとか。。。 文字リテラルはDisplayトレイトを実装していると。\n.to_string() = String::from\nStringはコレクションだから追加とかが可能なのか、なるほど。\npush_strとpush\n+演算子での参照。\n\u0026amp;Stringは\u0026amp;strに型強制(キャスト?)してくれる。してくれる場合としてくれない場合もあるのかな?s2の所有権は奪わない形で扱うのでs2はこのあとも使えていると。 ここでは、s1を変更したあとに所有権がs3に持っていかれてる? format!を使うとどの所有権も奪わないので、これを使うほうが考え方は簡単そう。ただし、効率がいいかはわからん。 添字記法でのアクセスをStringは許容していない\n文字の境界が必ずしも1バイトとは限らないから。 スライスも同様。 基本的には.chars()で文字としてアクセスするのが良い。\n逆にバイト表現を得る方法はどうするんだろう?\nNLP100本ノックではencode_utf8メソッド使ったけど。 ハッシュマップ いろんな呼び方あるよね。Rustではハッシュマップだよ。 ハッシュマップはuseしないと使えない キーは1つの型、値も1つの型 タプルのベクタからcollectで生成。なるほど。 タプルのベクタだと、タプルの中身は同じものであることが言える? -\u0026gt; 言える。エレメント数が異なるとコンパイルエラーになった 所有権周りの話。 これ、ベクタのときに話してほしい感じがした。 値を渡すか参照を渡すかによって話が変わってくる。詳しくは10章 このあたりが自分が混乱していた元だ。 entryとinsertの違い entryの戻り値はEntryというenumでor_insertというメソッドがありそれを使うと存在しない場合だけinsertが呼ばれる。 これ便利だ。毎回existあたりで存在チェックしてた気がする。 or_insertは可変参照\u0026amp;mut Vを返す。 これをlet countで束縛するときに、中身が可変かどうかをcountには指定しないのか。。。 まとめ 一応、大学などで習ってた(はず)ですが、 スタックとヒープを意識して考えないといけないなぁというのを何度か意識させられた感じです。\nあと、これはRustに限らずですが、それぞれがどんな関数を持っているか、どんなメソッドを持っているか、どんなマクロが存在するかなどを探すときにみんなどうしてるんだろう? 人に教えてもらっているのか、APIリファレンスを探すのか、そういったところをみんながどういう感じにプログラミング言語を勉強しているか、業務で書いているのかと言うのが気になりました。\n","date":1587028650,"dir":"post/2020/","id":"f488aa62d39194824861a134567cadb8","lang":"ja","lastmod":1587028650,"permalink":"https://blog.johtani.info/blog/2020/04/16/chap8-rust-the-book/","publishdate":"2020-04-16T18:17:30+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 第8章 7章はパ","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第8章"},{"contents":"Rustで言語処理100本ノックのリファクタリングの続き。\n前回はこちら。\nコードも載せたほうが見やすいかなぁ?\n03. 円周率 2年前はこちら。 どちらかというとJavaっぽい書き方かな? 入れ物を用意して、入力を整形して、それからループを回す感じで書いてました。\n今回は1行で収めてみました。 Rustっぽく、returnを省略してみました。 あとは、Iteratorを組み合わせる感じでやってます。 アルファベットの文字数ということで、is_alphabetic()メソッドでfilterしてます。\n04. 元素記号 2年前はこちら。 エラー処理が多いのと、文字の扱いがちょっと\nここまで同様に極力イテレータを利用するという方針でリファクタリングしました。 あとは、エラー処理を除去してます。 正常系だけのテストなのでスッキリさせました。\nこういった、ストリーム系?の書き方の場合にエラー処理をどう入れるかってところはちょっと悩みどころになるんじゃないかなぁ?と思いつつ、イレギュラーなものは後回しで(あとにやるのかなぁ?)\n05. n-gram 2年前はこちら。 これまでと同じく、入れ物を作ってから処理をしてます。\n同じく、極力イテレータを利用する形で実装しました。 いくつか型の変換が必要なので、.map()を呼び出して詰め替えたりしています。\n06. 集合 2年前はこちら。 独自に実装しています。\nせっかく05で文字n-gramの配列を返す処理を実装しているので、 そちらを呼び出して、Setに入れるという処理に書き換えました。 その後の集合に対する処理については特にリファクタリングしてないです。\nまとめ 2年前にやってたところまでは追いつきました。 07は特にリファクタリングする必要がないので、次は08からの予定です。\nリファクタリングしているときになるのは、速度とかでしょうか。 実装の違いでなにか差が出るのかどうかはちょっと気になるところですが、 今回の目的ではないので、目をつぶって進める予定です。\n","date":1586423695,"dir":"post/2020/","id":"9a687babb0f44db51dc389b75bdaa19d","lang":"ja","lastmod":1586423695,"permalink":"https://blog.johtani.info/blog/2020/04/09/reboot-nlp100-ch01-03to05/","publishdate":"2020-04-09T18:14:55+09:00","summary":"Rustで言語処理100本ノックのリファクタリングの続き。 前回はこちら。 コードも載せたほうが見やすいかなぁ? 03. 円周率 2年前はこちら。 どちらか","tags":["Rust","nlp100"],"title":"第1章の03から06まで(言語処理100本ノック2020)"},{"contents":"今回もツイートから。\n言語処理100本ノックの2020年版を公開しました。最近の自然言語処理の研究動向を反映し、深層ニューラルネットワークに関する問題を追加しました。留学生も一緒に取り組めるように多言語化を進め、その第1弾として英訳を部分公開しています(40番以降は順次公開予定)。 https://t.co/52h362PIQQ\n\u0026mdash; Naoaki Okazaki (@chokkanorg) April 6, 2020 言語処理100本ノックが2020年版になったそうです。 そうです、2年前に初めて、準備運動で止まっていたんです!(衝撃的な続かなさ。。。)\nということで、Rust the bookも読んでいることだし、過去のプログラムをチェックしつつ再開しようかなと。 ということで、いくつかリファクタリングしてみました。\nソースはリポジトリを御覧ください。\n00. 文字列の逆順 2年前の実装では、chars()メソッドで取り出したあとに、collect()でVecにしていたのですが、RustのIteratorトレイトにrev()という便利なメソッドが存在していました。\nということで、これを取り出すと、最初の文字列の逆順で文字を取り出すIteratorが取得できます。 あとは、Stringが実装してくれているfrom_iterに渡せば文字列が出来上がります。\n01. 「パタトクカシーー」 ストリーム処理っぽい書き方に変更しました。 2年前はIteratorを取り出して、詰替していましたが、 enumerate()で添字と文字のタプルのイテレータに変換し、 filterで添字が偶数のときだけフィルタリングして、 mapで対象の文字をまとめたイテレータにします。 で、最後はそれを元に文字列を生成することにしました。 iterを使わないでそのままString::from_iterの引数に渡すことも可能ですね。\n02. 「パトカー」+「タクシー」=「パタトクカシーー」 2年前は2つのIteratorをloopで回して頑張って結合してました。 ではなく、zip()を使って、2つのイテレータを組み合わせる方法に替えてみました。 このとき、2つの文字列が違う文字数の場合の処理として、長い方から取り出した文字をあとに結合する処理を追加で記述しました。 ちょっとスマートな感じになりましたかね?\nzipしたあとに出てきたタプルの文字列を結合するのにformat!マクロを使いましたが、他にいい方法有るかなぁ?\nまとめ とりあえず最初の3つをリファクタリングしてみました。 残りもやりつつ、準備運動以降もがんばるぞと。\n","date":1586338425,"dir":"post/2020/","id":"dc9580308938069159c5afc55b2f3b96","lang":"ja","lastmod":1586338425,"permalink":"https://blog.johtani.info/blog/2020/04/08/reboot-nlp10-with-rust/","publishdate":"2020-04-08T18:33:45+09:00","summary":"今回もツイートから。 言語処理100本ノックの2020年版を公開しました。最近の自然言語処理の研究動向を反映し、深層ニューラルネットワークに関","tags":["Rust","nlp100"],"title":"言語処理100本ノック、再び"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 第6章 Enumです。match式に大活躍\nEnumを定義する 列挙型は取りうる値をすべて列挙できる。これが名前の由来 列挙型と列挙子 2連コロン(::)で列挙子を指定可能 列挙子にデータ(構造体も)が格納可能。 標準ライブラリに実装例あり。 疑問:Write(String)とかはタプルの表現になるのかな? と思ったが、タプルでは1つだけの変数を持つものは定義(正確には定義できるが、内部で普通の変数にもどされてるっぽい)できなかった。 メソッド定義も可能 関連関数もできる? -\u0026gt; できる Optionの紹介 Rustにnullはない。代わりにOptionがある Noneを指定する場合に型が必要。Someの場合はすでに値が入るから推測可能なため。 match制御フロー演算子 アーム -\u0026gt; matchしたときの処理のこと 短い場合は波括弧は不要 returnなしでmatchが書いてあるだけだと、慣れない場合に値を返していることに気づかないかも(実際気づけてないかも) Enumが値を持っているときに、値の束縛がmatch式で可能 すべての列挙子を網羅していないことをコンパイラが検知してくれるのはすごく助かる。 ただし、_を利用していなければだけど if letで簡潔な制御フロー enumで1つのパターンのときに処理をしたい場合に使えるmatchの糖衣構文 elseもかけるよ。 まとめ enumに慣れていないので、値や構造体を持つenumを利用するという想像ができないことがありそうだなぁと読みながら思いました。 それになれると、色々とプログラムがシンプルに書ける部分が多くなりそうかな。\n","date":1586255231,"dir":"post/2020/","id":"4fbdc9c57a37781dc5dd86f470c61d04","lang":"ja","lastmod":1586255231,"permalink":"https://blog.johtani.info/blog/2020/04/07/chap6-rust-the-book/","publishdate":"2020-04-07T19:27:11+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 第6章 Enumです。matc","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第6章"},{"contents":"Kuromoji-CLIの使い方などについては過去のブログを御覧ください。\nKuromojiのCLIコマンドとpicocliとGraalVM GitHubリポジトリ Issueだけ上げていたJSON出力対応をしました。 また、ラティス(後述)の出力対応もしました。\nJSON出力 LinderaがJSON出力に対応してるのでそれを真似しました。 -o jsonで指定していただくと、次のようなJSONが出力されます。\n% echo \u0026#34;春眠暁を覚えず\u0026#34; | build/graal/kuromoji -o json [ { \u0026#34;text\u0026#34;: \u0026#34;春眠\u0026#34;, \u0026#34;detail\u0026#34;: [ \u0026#34;名詞\u0026#34;, \u0026#34;一般\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;春眠\u0026#34;, \u0026#34;シュンミン\u0026#34;, \u0026#34;シュンミン\u0026#34; ] }, { \u0026#34;text\u0026#34;: \u0026#34;暁\u0026#34;, \u0026#34;detail\u0026#34;: [ \u0026#34;名詞\u0026#34;, \u0026#34;一般\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;暁\u0026#34;, \u0026#34;アカツキ\u0026#34;, \u0026#34;アカツキ\u0026#34; ] }, { \u0026#34;text\u0026#34;: \u0026#34;を\u0026#34;, \u0026#34;detail\u0026#34;: [ \u0026#34;助詞\u0026#34;, \u0026#34;格助詞\u0026#34;, \u0026#34;一般\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;を\u0026#34;, \u0026#34;ヲ\u0026#34;, \u0026#34;ヲ\u0026#34; ] }, { \u0026#34;text\u0026#34;: \u0026#34;覚え\u0026#34;, \u0026#34;detail\u0026#34;: [ \u0026#34;動詞\u0026#34;, \u0026#34;自立\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;一段\u0026#34;, \u0026#34;未然形\u0026#34;, \u0026#34;覚える\u0026#34;, \u0026#34;オボエ\u0026#34;, \u0026#34;オボエ\u0026#34; ] }, { \u0026#34;text\u0026#34;: \u0026#34;ず\u0026#34;, \u0026#34;detail\u0026#34;: [ \u0026#34;助動詞\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;特殊・ヌ\u0026#34;, \u0026#34;連用ニ接続\u0026#34;, \u0026#34;ぬ\u0026#34;, \u0026#34;ズ\u0026#34;, \u0026#34;ズ\u0026#34; ] } ] Viterbiラティス出力 Kuromojiが内部でトークンをどのように切り出すかを計算するためのViterbiのラティスです。これをGraphvizというツールのDOTフォーマットのファイルとして出力できるメソッドがデバッグ用ですが、Kuromojiに用意されています。 こちらを呼び出して出力するオプション-v(もしくは--viterbi)を追加しました。 注意点として、このオプションを指定すると、DOTファイルが標準出力に出力され、トークンの結果は標準エラーに出力されます。\necho \u0026#34;春眠暁を覚えず\u0026#34; | build/graal/kuromoji -v \u0026gt; viterbi.dot .dotファイル自体は画像ではないので、Graphvizのdotコマンドにて画像ファイルに変換する必要があります。\ndot -Tpng viterbi.dot -oviterbi.png これで、PNGファイルが出来上がります。出来上がったファイルはこんな感じです。\n画像を見ていただくと、緑色のパスがあるのがわかります。 こちらが、Kuromojiが実際に採用した形態素のリストです。それ以外のパスは不採用だったパスとなります。\nちなみに、macOSで1行で画像表示まで行うにはこんな感じで実行します。 openコマンドでpreviewアプリを指定することで画像が表示できます。 Windowsは。。。わかりません、すみません。\n% echo \u0026#34;春眠暁を覚えず\u0026#34; | build/graal/kuromoji -v -o json | dot -Tpng | open -f -a preview.app まとめ これ以前に複数辞書対応などもしていました。 今回は2つの出力形式を追加してみました。 特にViterbiラティス出力については、内部的にどのようなコスト計算で最終的な結果が出てきているかという理解に役立ちます。想定していない切れ方の場合は、そもそも想定している形態素になっていないか、コスト計算で不採用だったかなどを確認できますので、使ってみると面白いかもです。\n","date":1586143600,"dir":"post/2020/","id":"6fbf7c3d0f4f89e415e89cec28811a94","lang":"ja","lastmod":1586143600,"permalink":"https://blog.johtani.info/blog/2020/04/06/update-kuromoji-cli/","publishdate":"2020-04-06T12:26:40+09:00","summary":"Kuromoji-CLIの使い方などについては過去のブログを御覧ください。 KuromojiのCLIコマンドとpicocliとGraalVM G","tags":["misc"],"title":"KuromojiのCLIコマンドにJSON出力とラティス出力を追加"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた Rust the book - 第4章 第5章 構造体です。勝手知ったるなんとやら?オブジェクト指向的な部分は問題ないかなぁと。\n定義とインスタンス化 structで定義 インスタンスの生成は引数は順不同でOK 構造体のインスタンスを可変にするとフィールドの値も変更可能 特定のフィールドのみ可変にすることは不可能 インスタンス化する関数の最後でreturnなしでインスタンスの返却を暗黙にできる(return書いてほしいな。。。) インスタンス化時にフィールド初期化省略記法が可能(これはちょっと便利?) 構造体更新記法..user1のように、明示的に設定されていない他のフィールドをコピーしてくれる機能あり タプル構造体 タプル構造体!? struct Color(i32, i32, i32); いつ使うんだろう? ユニット様構造体 ユニット様構造体 = フィールドのない構造体。トレイトを実装したいけどインスタンスで持つ値はない場合に利用 ライフタイム 構造体が参照を持つときにライフタイムという話が出てくる。なるほど。 ライフタイム指定子が必要になる -\u0026gt; 10章での話 プログラム例 タプルを引数かぁ。タプルは慣れないので構造体作りそう Debugトレイトと{:?}という書き方 derive(Debug)でデバッグ用のトレイトを自動で実装=継承してくれる {:#?}だとpretty printになる(改行とか入る) この辺の便利なトレイとは付録Cにあるらしい。この辺はやりながら覚えるしかないか。\nメソッド記法 最初の引数は必ずself implは構造体とは別の場所に書く = Javaのクラスとは違う struct Rectangle { width: u32, height: u32, } impl Rectangle { fn area(\u0026amp;self) -\u0026gt; u32 { self.width * self.height } } 参照じゃないselfも使えるらしい。どういうときに使うんだろう? 関連関数 selfなしの関数をimplにかける。Javaのスタティックメソッドみたいな感じ その他 implブロックがあちこちにかける。これはつらいな。。。 2つにわかれたimplブロックに同じメソッドを書いてみたら、CLionのプラグインではエラーを検知してもらえなかった。 cargo buildではきちんとエラーが表示された。 複数のimplブロックが有用になるケースは第10章で見ますが、そこではジェネリック型と、トレイトについて議論します。\n人の構造体に自分のトレイトを適用したりもできる。 実験 スコープとかどうなりそう?って実験もしてみた。\nfn main() { trait Hoge { fn trim(\u0026amp;self); } impl Hoge for String { fn trim(\u0026amp;self) { println!(\u0026#34;hogehoge {}\u0026#34;, \u0026amp;self); } } let c = String::from(\u0026#34;hoge\u0026#34;); c.trim(); println!(\u0026#34;{}\u0026#34;, fuga(\u0026amp;c)); } fn fuga(d: \u0026amp;String) -\u0026gt; \u0026amp;str { d.trim() } 出力はこんな感じ\nhogehoge hoge hoge まとめ 気になったのは以下の点。そのうち分かるようになってくるのかな。\n構造体更新記法はどういったときに使うのを想定して作ったんだろう?とか 可変長引数はマクロじゃないとだめ ","date":1585807758,"dir":"post/2020/","id":"8d9c3760395e8e0eb40e335b22750b68","lang":"ja","lastmod":1585807758,"permalink":"https://blog.johtani.info/blog/2020/04/02/chap5-rust-the-book/","publishdate":"2020-04-02T15:09:18+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた Rust the book - 第4章 第5章 構造体です。勝手知ったるなんとやら?","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第5章"},{"contents":"すもけさんが在宅勤務環境をブログに書いてておもしろそうだな(あと、アフィリンク貼れるな)と思ったので自分の環境も書いてみようかなと。\n私自身は昨今の新型コロナウイルスの影響というのではなく、もう10年以上自宅でも作業ができる環境を整えています。 前前職の頃から家でも仕事をすることがよくあったので。今は、お客さんに恵まれていてリモートができる形で働かせていただいてます。\n机周りはこんな感じです。机はこれも15年以上前から使用しているエレクターの机です。椅子も15年以上前から使っているアーロンチェア(購入時は高いと思ったけど、これだけ使えているので大満足)です。\nメインのPCはMac Book Pro16インチを使っています。それとは別にMac miniがMac bookの後ろに隠れています。こっちはブラウジングや音楽を聞いたりするために使っています。\nまずはディスプレイ周りから。\nディスプレイ周り ディスプレイ Acerの31インチディスプレイです。昨年の夏に購入しました。28インチの4Kディスプレイを探していたのですが、セールか何かで2-3000円の違いでこのサイズが買えたので、このサイズになっちゃいました。Mac Book ProはDisplay port-USB-Cケーブルで接続し、PS4をHDMIで接続しています。 【Amazon.co.jp 限定】Acer モニター ディスプレイ ET322QKwmiipx 31.5インチ マイクの左側に写っているのはAppleのサンダーボルトディスプレイです。縦にしてブラウザやミュージックプレイヤーなどで音楽かけながら仕事をしています。 サブディスプレイって感じです。 Mac Book ProとMac miniの両方を操作するのですが、できれば同じキーボード+トラックパッドがいいなということで、Synergyというソフトを使って、Mac Book Proのキーボードとマウスでネットワーク越しにMac miniを操作しています。ただ、マシンの再起動後などにこのソフトが起動していない場合もあるので、Mac Book Proの右側にMac miniのためのトラックパッドがおいてあります。\nディスプレイアーム ディスプレイはそれぞれディスプレイアームを使っています。写真のようにMac Book Proを下に、外部ディスプレイを上にという上下で作業をしています。 16インチの画面だと普通のディスプレイの足だとメインディスプレイにかぶってしまうので、アームに切り替えました。 最初はグリーンハウスの激安を使っていたのですが、31インチのディスプレイだとアームの高さが足りなかったので、2つ目のガススプリング式のアームを追加で購入しました。ガススプリング式なのに5千円しないので、かなりお得感があります。ただ、ディスプレイは基本的に動かさないので、どちらかというとディスプレイの足の部分を効率良く使うことが目的です。\nAmazon | グリーンハウス 液晶ディスプレイアーム 4軸 クランプ式 Amazon | HUANUO PC モニター アーム 液晶ディスプレイ アーム ガススプリング式 サウンド関連 スピーカー 基本、音楽を聞きながら作業をするので、小型だけどしっかりと音がでるスピーカーを買いました。スタイルもいいし気に入ってます。 入力が2系統あるので、31インチディスプレイのヘッドフォン出力とMac miniのからの出力の2つをつないでいます。 仕事中はMac miniで音楽流しつつ、テレカンやゲームのときはメインディスプレイからの音が出る形です。 Amazon | ヤマハ パワードスピーカー NX-50 マイク 前職がDeveloper Advocateということで、インタビューなどに行くこともあるかも?ということで小さめのも運びができるコンデンサマイクを購入してました。結局それほど持ち運びはしてないのですが、値段の割には音がいいんじゃないかな?一応、無指向と単一指向の2種類を切り替えることが可能です。\nAmazon | SAMSON マイク ポータブル USB コンデンサ Go Mic | コンデンサ | 楽器 マイクスタンド マイクはあったのですが、クリップ式でした。PCのディスプレイにクリップしていると、打鍵音を拾ってしまうので、マイクスタンドを最近導入しました。やすかったです。 前まではヘッドフォンのケーブルに付いているマイクで喋っていたのですが、服によってはマイクに擦れてしまい、ノイズが載っていました。 マイクスタンド+スピーカーでもスピーカーの音をマイクが拾わないので、最近はヘッドフォンを使用しないで気楽に話ができるようになっています。 Amazon | Luling Arts マイクスタンド アーム その他 モニタスタンド Mac Book Proの後ろで見えにくいですが、Mac miniが下に入っていて、上にMac mini用のキーボード、スピーカー、Qiの充電パッドが載せてあります。 Mac miniのキーボードをじゃまにならないように置きたいという目的で購入しました。3次元で空間が利用できるので結構重宝してます。 Amazon | サンワサプライ 机上液晶モニタスタンド(D200・黒) MR-LC303BK 充電関連 スマホ充電用にスピーカーの横においてあります。ただ、スイートスポットを探すのがちょっと大変で、時々充電できてないことがあったりします。。。 Amazon | DesertWest Qi 急速充電ワイヤレス充電器 【Qi認証済み/PSEマーク付き】15W USBでの様々な充電用にはMercariさんのカンファレンスでいただいたAnkerの充電器をおいてあります。Mi Band 4、キーボードなどの充電向けです。 Amazon | Anker PowerPort 6(60W 6ポート USB急速充電器) まとめ 簡単ですが作業環境でした。だいたい満足しています。もうちょっと改善したいなと思っているのは次の点です。\nUSB-Cドック?ハブ?みたいなものがほしい 充電ケーブル、マイク、ディスプレイケーブル、有線LANの4つのケーブルがMac Book Proに刺さっており、ポートが全滅です。出先から帰ったときにつなぐのも少し面倒なので、1つか2つのポートでまとめられるといいなぁと思っています。が、ドック系はいい値段するのでまだ置き換わっていない感じです。 スタンディングデスクが気になる 自宅でずっと座っているのはやはり気になるもので。スタンディングデスクにして時々たって作業したいなぁと思うことがあります。ただ、使ったことがないので、どれがいいのかわからず手を出せない状況です。 ウェブカメラいる? Mac Book Proのカメラでオンラインミーティングなどしています。気にするほどのことではないとは思いますが、メインディスプレイを見ながらしゃべると下からカメラで撮影されている形になります。。。 今のところはこんな形です。なにかの参考になればと。 あと、なにかおすすめのもの(特にスタンディングデスク)があれば教えて下さい!\n","date":1585217511,"dir":"post/2020/","id":"3f431bf71ee866f626daf42bc915fa3f","lang":"ja","lastmod":1585217511,"permalink":"https://blog.johtani.info/blog/2020/03/26/working-facility/","publishdate":"2020-03-26T19:11:51+09:00","summary":"すもけさんが在宅勤務環境をブログに書いてておもしろそうだな(あと、アフィリンク貼れるな)と思ったので自分の環境も書いてみようかなと。 私自身は","tags":["misc"],"title":"自宅の作業環境(2020)"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた 第4章 第4章です。たぶん、これがいちばん大事な概念だと思います、Rustの。 そして、つまみ食いしながらRust書いてましたが、ここがきちんと理解できないまま書いてたってのもあります。。。\n所有権とは? drop関数ってのがあって、明示的に呼ぶことも可能。次のような感じで。2つ目のprintln!はエラーになる。sがもう無いのに借用しようとしてるから。 fn main() { let mut s = String::from(\u0026#34;hello\u0026#34;); s.push_str(\u0026#34;, world!\u0026#34;); println!(\u0026#34;{}\u0026#34;, s); drop(s); println!(\u0026#34;{}\u0026#34;, s); } ムーブ - shallow copyではない。以下の2行目がムーブ。 let s1 = String::from(\u0026#34;hello\u0026#34;); let s2 = s1; println!(\u0026#34;{}, world!\u0026#34;, s1); スタックとヒープの話が絡んでくる。あんまり意識すること無いよなぁ。 スタック = 固定長のデータを入れる場所。ポインタ、数値など ヒープ = 可変長のデータが入る場所。可変の文字列とか。\nクローン - ヒープのデータをコピーすること。 コピー - スタックに収まるデータの場合はクローンが必要なくコピーで事足りる。 CopyトレイととDropトレイとは同居できない。 タプルのコピーはややこしそう 所有権と関数でまた、スタックに入れられるような変数と可変のオブジェクトの違いが出てくる。 takes_ownership(s: String)が参照を受け取れば問題なく、このあとも使える。 戻り値でもムーブが発生 参照と借用 借用 - 関数の引数に参照を取ること 可変な参照\u0026amp;mutは1つ(不変な参照も含めて1つ)しか許さない データの競合を防ぐため。 不変な参照を複数用いるのはOK 実際に変更が実行されるタイミングでエラーと判定される場合もある。 let mut s = String::from(\u0026#34;hello\u0026#34;); { let r1 = \u0026amp;mut s; } // r1はここでスコープを抜けるので、問題なく新しい参照を作ることができる let r2 = \u0026amp;mut s; ダングリング参照はテスト書くときとかにやってるかも。。。 fn dangle() -\u0026gt; \u0026amp;String { // dangleはStringへの参照を返す let s = String::from(\u0026#34;hello\u0026#34;); // sは新しいString \u0026amp;s // String sへの参照を返す } // ここで、sはスコープを抜け、ドロップされる。そのメモリは消される。 // 危険だ スライス型 部分的な参照。開始位置+長さで構成されているっぽい \u0026amp;strの説明がよくわからなかった。 引数としての文字列スライスのテクニックは色々と使いまわせそう。\nまとめ 所有権、これまで特に難しいと思ってたのは、固定長の変数と、可変長の変数の違いを意識してなかったのが原因っぽい。 まぁ、Vecとかがどうなるのかとか、他にもいくつか気になるところはあるので、もうちょっとやらないといけないなと思いました。\n","date":1585210331,"dir":"post/2020/","id":"7fded0345c258eea966c0b5ee1b7c7aa","lang":"ja","lastmod":1585210331,"permalink":"https://blog.johtani.info/blog/2020/03/26/chap4-rust-the-book/","publishdate":"2020-03-26T17:12:11+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた 第4章 第4章です。たぶん、これがいちばん大事な概念だと思","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第4章"},{"contents":"先日、Visual Studio Codeのプラグインを作ってみた(Azure Search Analyze Client)というブログを書きました。 このプラグインを作ってたタイミングで、Elasticの河村さん経由で、Microsoft Open Tech Night #9 w/ ElasticでなにかLTしませんか?という打診がありました。\n仕組み的には似たようなものだし、Elasticsearch用の拡張機能も作れるし、発表のネタにもなるし一石二鳥では?ということで、LTを快諾し、昨日発表してきました。\n資料とか 発表資料やGitHubのリポジトリなどは、以下のとおりです。\n発表資料 : Analyze APIのVS Codeプラグインを作ってみた GitHub Repository : https://github.com/johtani/vs-code-es-analyze-client Visual Studio Code Marketplaceページ 機能 まだ、必要最低限の機能を実装した感じです。\nAnalyze APIのパラメータ入力用のエディタ起動(Elasticsearch Analyze Client: Create Elasticsearch Analyze Request) Esにリクエストを送信して結果の表示 インストールからリクエスト送信して結果が出てくるまでのデモです。\n1点LTのデモのときに話すのを忘れていましたが、.esanalyzeという拡張子のファイルであれば、このプラグインが入力値を見つけ出して、「Analyze text with analyzers」というコマンド送信用のリンクをエディタ画面に表示する機能があります。 ですので、パラメータ入力用のエディタを起動し、値を設定したあとにファイルをhoge.esanalyzeというような名前で保存してもらえれば、後日そのファイルを開くことでリクエストが再送できます。\nAzure Search版との機能の違い 先日のAzure Search向けのクライアントとの違いがいくつかあります。 ElasticsearchのAnalyze APIの方が多機能であるため、プラグインとしても違いがあったほうがいいかなと。\n入力がJSON形式 結果画面に詳細表示切り替えボタンを追加 現時点では対応していませんが、Analyze APIはカスタムのtokenizer、filter、char_filterの設定を入力として受け付けることが可能です。そのときに指定するのはJSON形式でtokenizerなどの設定を記述します。 今後、これらの対応をすることを考えると、入力全体をJSON形式で読み込めるほうがわかりやすいかなということで、入力はJSON形式で入力してもらうことを想定しました。\n結果画面に詳細表示切り替えボタンを追加したのは、2つの理由があります。1つはAzure SearchのAnalyze APIよりもTokenの情報としていくつか他の情報も存在するためです。複数のAnalyzerとの比較をする場合は、単語列だけを比較したいですが、Analyzer個別の詳細情報を見たい場合もあるので、切り替えができたほうがよいかなと。 2つ目の理由はまだ実装していませんが、explainパラメータの出力への対応のためです。 explainパラメータを指定すると、カスタムAnalyzerの場合に、Analyzerの設定にあるchar_filter、tokenizer、token_filterのそれぞれのステップでの単語列の出力が結果として返ってきます。この結果には標準の出力よりもさらに多くのtokenの情報(例えば、kuromojiだと品詞情報、読み、原型など)が追加されてきます。これらの表示を切り替えることができたほうがよいかと。\nこれらは、実はKibanaのプラグインとしてすでに実装済みになっています。 同等の機能は実装できるかなという目論見もあり、そちらに合わせた感じにしてあります。\n今後の対応 現時点では、Analyzer名の指定のみが可能となっています。Kibanaのプラグインと同程度の機能はGitHubのIssueとして登録してみました。\nexplainパラメータ対応 fieldパラメータ対応 custom analyzer対応 その他に、インデックス名やアナライザ名の自動補完みたいな機能があると便利かも?と妄想していたりします(実装が大変かもですが。。。)。Kibanaのプラグインの場合は、Mappingやインデックス名を調べるときに、KibanaのConsoleからチェックすればよかったのですが、このプラグイン単体だとそのあたりの情報の取得に他のツール(Kibanaだったり、REST API Clientだったり)を使わないといけないという問題点はあるかなぁと。\nあとは、結果画面がこのままで本当に見やすいかどうか?なども気になってはいます。\nまとめ まだまだ、作ってみたというレベルのプラグインです。 どのくらいの人に使ってもらえるかもわかりませんが、こんな機能あるといい?など要望があればリクエストいただければと。 Twitterで聞いていただいてもいいですし、GitHubのIssueとして登録していただいても構いません。 そもそもいらないなぁなんて意見でももちろん大歓迎です。フィードバックお待ちしてます!\n","date":1585102205,"dir":"post/2020/","id":"a7f0e85fcad4f5bc5ae5c18c10de4f9e","lang":"ja","lastmod":1585102205,"permalink":"https://blog.johtani.info/blog/2020/03/25/vsc-es-analzye-plugin/","publishdate":"2020-03-25T11:10:05+09:00","summary":"先日、Visual Studio Codeのプラグインを作ってみた(Azure Search Analyze Client)というブログを書きました。 このプラグインを作ってたタイミン","tags":["elasticsearch","visual studio code"],"title":"ElasticsearchのAnalyze APIのVisual Studio Codeのクライアントプラグイン"},{"contents":"自転車本を読み始めましたが、その前にRust the bookを読んだほうが良いかも?と知り合いと話をしていてなったので、先にRust the bookを読み始めてます。 コツコツ読むってのが苦手なので、知り合いと小規模オンライン読書会しながら読むことになりました(基本的になにか書きながら、使い方を調べるので、存在そのものを知らない記述や使用法などがあったりする)。\n日本語版Rust the book Rust the book 基本は日本語版を読んでいます。まずは1章から3章あたり。\n気になった点などを。自分用のメモなので、読みやすさとかは考えてないです(あとで自分が死ぬパターン?)。\n1章 rustfmt便利。\nCLionのRustプラグインでは、保存時にrustfmtするというオプションがある。デフォルトはオフ。\u0026ldquo;Run rustfmt on Save\u0026rdquo; cargoの--binオプション。意識してつけたことなかった=デフォルトだった。\nライブラリにするときは--lib 2章 「変数を値に束縛」という言い回しにまだ慣れない。 「代入」という言い方に慣れているから? ただ、エラーにはassignってあるな。\u0026ldquo;error[E0384]: cannot assign twice to immutable variable x\u0026rdquo; preludeというのがデフォルトで読み込まれる型が存在する場所。 .expect()により、Resultが評価済みになる マクロがまだ慣れない extern crate rand;が最新版だと要らなくなっている。 rand::Rngはgen_rangeのためにuseしている。CLionだとかってにuseを推測して追加してくれた。 matchはswitch文みたいな感じ。けど、defaultが必ず実行されるって感じではないな。 ただし、全て網羅しないと怒られるのが便利。 アームという呼び方が新鮮 単一の式のときは{}が省略できる ブロック{}のときは、終わりにカンマを入力するとrustfmtが除去する(最後の条件かどうかは関係ない)。 シャドーイングは面白い。 よく、hoge_strやhoge_intのような変数を書くので、ありがたい。 ただし、コードを読むときに少し混乱しそう? let ... matchで変数への束縛でmatchが使えるのは便利(これまで知らなかったので、変数宣言して条件つけて束縛する処理書いてた)。 シャドーイング? fn main() { let x = 5; let x = x + 1; let x = x * 2; println!(\u0026#34;The value of x is: {}\u0026#34;, x); } とか\nlet spaces = \u0026#34; \u0026#34;; let spaces = spaces.len(); みたいに、同一変数名を使い回せること。再代入ではない\n3章 constは型注釈が必須 100_000のような記述が便利(Javaもできるって言われてびっくりしたw) タプルの中身を一部だけ書き換え可能。(mutを指定すれば) tup.0 = 20;のような感じで。 配列は固定長でかつ、同一の型のものだけが入る 文末にセミコロンがない場合に四季になるというのはちょっと射にくいので辛いのでは。。。 自分は明示的にreturnを書きたくなる。が、returnだと動かない場合もある。。。 let ... ifのような記述もできる。 (1..4)はRange型 おまけ フィボナッチ数列計算してみろというのがまとめにあったので。こんな感じでいいのかな?\nfn calc_fibonacci(n: usize) -\u0026gt; usize { if n == 0 { return 0; } else if n==1 { return 1; } else { return calc_fibonacci(n-1) + calc_fibonacci(n-2); } } その他 知り合いと読みすすめると、人が不思議に思ったところが、自分が理解が曖昧だったことなどに気づけて便利です。\n","date":1584928642,"dir":"post/2020/","id":"48b5ab9805919736382ffea5a9554c02","lang":"ja","lastmod":1584928642,"permalink":"https://blog.johtani.info/blog/2020/03/23/start-reading-rust-the-book/","publishdate":"2020-03-23T10:57:22+09:00","summary":"自転車本を読み始めましたが、その前にRust the bookを読んだほうが良いかも?と知り合いと話をしていてなったので、先にRust the bookを読","tags":["rust","読書","rust-the-book"],"title":"Rust the Bookを読み始めた"},{"contents":"動機 Azure Cognitive Searchを検索エンジンに使っているお客さんを手伝っています。 そこで、検索の基本的な話をさせていただきました(もともとJJUGナイトセミナーでしゃべる予定だったスライドがベース)。\nで、Elasticsearchなどの転置インデックスを利用している検索エンジンで検索の基本的な動作がどうなっているかを理解するのに、 個人的には一番重要だと思っているのがAnalysis(Analyze)の機能です。 転置インデックスの単語の切り出し方がどうなっているかによって、望んだ単語でうまく検索できているかいないかなどがわかります。\nAzure Cognitive SearchもAnalyze TextというAPIを提供してくれています(内部的にはElasticsearchだし)。 APIはあるのですが、返ってくる結果はJSONです。また、他のAnalyzerの設定との違いなどをみたくなったりもします。 やはり、普段使っているツールなどで簡単にどういう単語が出てくるかがわかるとうれしんじゃないかなぁ?と。\nということで、最初はPythonでちょっとAPI呼び出して、カンマ区切りで出力するものを作ってみたのですが、GUIとかあると便利かなぁという話になりました。 最近、ブログ書いたりするのにVisual Studio Codeを使い始めているので、これなら使いやすいかなと。 ということで、Visual Studio Codeの拡張機能(プラグイン?)としてインストールできるツールを作ってみました。 Azure Cognitive Searchを使っている人向けなので、ニッチなツールですが。。。\n余談 Elastic Stack(Elasticsearch)向けにはKibanaのプラグインでAnalyze APIを可視化するツールを作ってます。 analyze-api-ui-pluginです。Elastic Stack、特にKibanaを必ず利用する方はこちらを使うと便利かもです。\n概要と機能 GitHub リポジトリ Visual Studio Marketplaceのページ Marketplaceに公開しているので、johtaniやAzure Search Analyze Clientなどで検索してもらえれば出てきてインストールができます。\n機能としては、以下の2つです。\nテンプレートから入力値設定用のドキュメントを作成(Untitled-1というドキュメントをエディタに新しく開く) Azure Cognitive SearchのAnalyze Text APIを呼び出して、結果をHTMLのテーブル形式で表示 入力値設定用のドキュメント作成 APIの呼び出しに必要な情報を記入してもらうのに、いくつか案を考えました。\nプラグインの設定に記入してもらう 環境変数とかを読み出す テキストとして保存したファイルを使う 設定や環境変数だと、異なる環境に接続したりするときに、わざわざ設定し直すのがめんどくさいかもと。 で、愛用していたREST API Clientを真似するのが良いかもという結論になり、.analyzeという拡張子のファイルから必要な項目を読み出して、APIを呼び出す形にしてあります。\nCommand Palette(左下の歯車マークもしくは、メニューのViewから開ける)からAzure Search Analyze Client: Create Azure Search Analyze Requestというコマンドを選びます。\nすると、以下のようなファイルがエディタに開きます。\nこれらの項目をまずは埋めていきます。 それぞれの値がどういったものかはGitHubのREADMEを御覧ください。\n入力値エラー(存在チェックしかしていない)がある場合は、ダイアログが表示されます。\n結果表示 値を入力したら、設定値と###の間に表示されているAnalyze text with analyzersというグレーの文字をクリックします。すると、APIにリクエストを送信し、結果が返ってきて、別のパネルとして表示されます。\n複数のAnalyzerを入力値に設定すると、それぞれがどのような区切り方をするかがわかります。 文字の下にある[0:2]は、その単語がもとの文章の何文字目から何文字目までに出現しているかというオフセットの表示になります。\nもし、Analyzer名の設定ミスなどで指定されたAnalyzerがない場合は、結果画面にエラーが表示されるようにしています。\n以上が簡単な機能の説明です。 簡単なと言いつつ、これだけしか機能がありませんが。\nVisual Studio Codeのプラグインの作り方 プラグイン自体の作り方に関してはVisual Studio CodeのGetting Startedがわかりやすかったです。 APIや機能が豊富なので、最初はちょっと戸惑いましたが、サンプルもGitHubで多数公開されています。\nあとは、REST API Clientを参考にさせていただきました。\nGetting Startedを一通り読むことで、なんとなくプラグインの作成からMarketplaceへのリリースまでが完了できました。 (TypeScriptに慣れていないのがあるので、プログラミング自体は手間取りましたが。。。)\n今後の対応? いまのところ、こんなところを考えていますが、こんな機能がほしい、バグが有るなどあれば、GitHubにIssueを上げていただければと(使う人すくないだろうけど)。\nいろいろなエラーに関する対応 Readmeに画像をアップ アイコン作成? 自動補完機能? まとめ Visual Studio Codeの拡張機能を作ってみました。 Yeomanによるプロジェクトテンプレートが用意されているので、とりあえず、Hello worldを作るのは簡単でした。 試行錯誤しつつTypeScriptを書いたので、TypeScriptっぽくないところなどもあるかもですが、誰かの役に立つツールになってくれれば良いなぁと。\n","date":1584582615,"dir":"post/2020/","id":"c9d257aba54475c20b3737ce7c779e55","lang":"ja","lastmod":1584582615,"permalink":"https://blog.johtani.info/blog/2020/03/19/azure-search-analyze-plugin/","publishdate":"2020-03-19T10:50:15+09:00","summary":"動機 Azure Cognitive Searchを検索エンジンに使っているお客さんを手伝っています。 そこで、検索の基本的な話をさせていただきました(もともとJJUGナイ","tags":["azure search","visual studio code"],"title":"Visual Studio Codeのプラグインを作ってみた(Azure Search Analyze Client)"},{"contents":"これまで\n実践Rust入門はじめました 実践Rust入門の3章を読んでるところ 3章終了 3章の終わりまで読み終えた。\nいきなり実践的なプログラムで少し面食らっていたが、ステップを追って所有権周りの話まで来たので、 なんとなくRustのいいところが理解できたような気がする。\nただ、最後のsplit_at_mutが実際には内部でどういう形に変換することによって、コンパイルエラーにならずに、 借用がうまく行っているのかあたりは、まだきちんと理解できていない。\nこれは、どの言語にも言えるんだけど、リファレンスをうまく読み解きながら、 自分がやりたい処理ができるかどうかを考えるのって結構むずかしいなぁと思う。\nbenchmark.rsはコピペして実行しただけなので、またあとで読み返してみるかな。\nということで、ここから先は、基本を勉強する感じで4章から読みつつ、なんかプログラムをまた書いてみるか。\n","date":1583140813,"dir":"post/2020/","id":"6f47cb314fd780c122adb8cc1f44f785","lang":"ja","lastmod":1583140813,"permalink":"https://blog.johtani.info/blog/2020/03/02/finish-bicycle-book-chap3/","publishdate":"2020-03-02T18:20:13+09:00","summary":"これまで 実践Rust入門はじめました 実践Rust入門の3章を読んでるところ 3章終了 3章の終わりまで読み終えた。 いきなり実践的なプログラムで少","tags":["rust","読書"],"title":"実践Rust入門の3章を読み終わった"},{"contents":"Kuromoji-CLI Rust初心者がRust製の日本語形態素解析器の開発を引き継いでみたという記事にありますが、LinderaというRust製の日本語形態素解析が出てきました。KuromojiのRustクローンみたいなものです。 で、作者の人とのチャットの中で、「MeCabみたいなKuromojiのCLIないですかね?誰か知りませんか?」という話になりました。\n自分は普段はKuromojiの確認をするのは、Elasticsearch関連もしくは、Azure Searchなどだったりするので、 当たり前のようにKibanaを立ち上げたり、REST APIを叩いてましたが、たしかにコマンドラインインタフェースあると便利かも? と思い、作ってみるかということに。\npicocli いま、JavaでかんたんなCLI作るとなったら何がおすすめ?\n\u0026mdash; Jun Ohtani (@johtani) February 26, 2020 で、いつものツイートです。で、picocliという返信がありました。 JavaでCLIのプログラムを書くのが簡単になりそうだと。 ドキュメントもしっかりしてます。サンプルも載ってるし。\nAnnotationで、コマンドの説明などパラメータ、オプションなどが記述でき、必須チェックなども可能です。\nまた、オプションの説明文に関しては、テンプレートを用いることで、取りうる値をEnumの値で出力してくれたりといった便利機能まで備わっていました。\nGraalVM また、GRAALVMとPICOCLIでJAVAのネイティブコマンドラインアプリを作ろうというスライドも教えてもらい、ネイティブコマンドまで作れるらしいと。 なんて便利なんでしょう!ってことで、こちらもチャレンジしてみました。 GraalVMがどんなものかはなんとなくは知ってたのですが、何者だろう?とツイートしたところ、これまた返信が。\nっ 資料はかなり古いので現行版と乖離はあるけど概念は変わってないので..https://t.co/KRQjhNdD9f\n\u0026mdash; たむたむ🏫 (@tamtam180) February 26, 2020 本当に、Twitter便利ですね。\nGraalVMがどんなものかもいただいた資料でサクッと理解できました。 ただ、picocliが実はものすごく良くできており、自分でインストールする必要も実はありませんでした。\ngradle-graalというGradleのプラグインと、 Picocli Code Generationを利用することで、 以下のコマンドを実行することで、ネイティブコマンドアプリが作成できました。\ngradle nativeImage build.gradleファイルに記述したのは、以下のような項目です。\npluginの利用 picocli-codegenをannotationProcessorとして呼び出し jarに関する記述(メインクラスと依存するJarを含める設定) ネイティブコマンドの名前とか(gradle-graalの設定) 辞書が読み込めなかった で、native imageを作って実行しましたが、Kuromojiが内包している辞書ファイルが読み込めませんでした。 どうやら、picocli-codegenの自動生成では対応できない、リソース関連設定が必要らしいと。\npicocli-godegenの設定を見ていて見つけたのが、other.resource.patternsというオプションでした。\nkuromoji-cliのbuild.gradleに、その設定を加えたら辞書が読み込めるようになりました。\nこの設定をどうやって書くのか?というのを探すのにちょっと時間がかかりました。Picocli作者のRemko Popmaさんのサンプルリポジトリに設定を利用したbuild.gradleがありました。サンプル本当にありがたいですね。\n完成 出来上がったのは、kuromoji-cliというリポジトリになります。 内部で利用しているのはAtilikaのKuromojiです。LuceneのKuromojiではないのでご注意を(LuceneのKuromojiで最初やってみたのですが、リフレクションなどが多用されてて、Single Imageにするのが手間がかかりそうだった)。 コマンドのポータビリティはそれほど無いと理解してる(あってる?)ので、利用してみたい方は、リポジトリをクローンしてからビルドしてみてください。\n参考資料 kuromoji Picocliドキュメント Getting Started GraalVM / GraalVM超入門 一体何モノなの? GraalVM入門編 / GraalVM for beginners まだ途中? ほかにもあると便利かも?という機能があればIssueやPRを上げてください。 とりあえず、頭にあるのは以下のとおりです。\nJSONの出力はまだ未対応 いろんな辞書をAtilikaのKuromojiはサポートしてるのでそのへんも対応してみる? ","date":1582858179,"dir":"post/2020/","id":"d710a073be2da219a388a150eb7b6b6a","lang":"ja","lastmod":1582858179,"permalink":"https://blog.johtani.info/blog/2020/02/28/kuromoji-cli/","publishdate":"2020-02-28T11:49:39+09:00","summary":"Kuromoji-CLI Rust初心者がRust製の日本語形態素解析器の開発を引き継いでみたという記事にありますが、LinderaというRust製の日本語形態素解","tags":["misc"],"title":"KuromojiのCLIコマンドとpicocliとGraalVM"},{"contents":"これまでのはこちら。読書メモなので、本と合わせて読んでいただくのが良いです。\n実践Rust入門はじめました 3章のクイックツアーを読んでます。 バイトニックソート自体の理解はちょっとおいておいて、読み進めています。 いくつか疑問に思ったことがあったので、またメモを。 まだ、3.5.7の手前ですが。\n疑問点 3.4.1のジェネリクス対応のテストケースの部分で、既存のu32用のテストケースの入力のデータ列にVec\u0026lt;u32\u0026gt;という型注釈をつけるのですが、 追加した文字列の入力データには注釈をここではつけないのはなんでなんだろう?ちなみに、なくても動いた。バージョンの違いとかあるのかしら?\n3.4.6のmatch文\nmatch文の引数?が*orderになっていたが、orderでも実行できた。引数にくるのが参照だから*が付いてるんだとも運だが、なくても動くのはコンパイラがよしなに解釈してくれてるからかな? 便利なツール Rust標準のツールの説明がいくつか3章で紹介されてて便利だったのでメモ。\nrustfmt フォーマッター。デフォルトでフォーマット機能が付いてるの便利ですね。言語として決まってると、プロジェクトごとに悩まなくていいってのがありますし。\nrustfmt ファイル名 という形で使えるみたい。 プロジェクトごとだとcargo fmtのほうが楽そうかな。\n標準ライブラリAPIドキュメントをブラウザで閲覧 rustup doc --std これでデフォルトブラウザでRustの公式ドキュメントが開きます。 しかもローカルファイルだからサクサク。検索バーもついてて便利です。\nエラーのドキュメントを閲覧 rustc --explain 308 コンパイル時にエラーが出たときに、error[E0308]のようにコンソールに出てきます。 ヒントも出てくるのですが、詳細が上記のコマンドで読めるみたいです。\n","date":1582443437,"dir":"post/2020/","id":"71cf83ae0f45e9ede3a3f979b9c74933","lang":"ja","lastmod":1582443437,"permalink":"https://blog.johtani.info/blog/2020/02/23/bicycle-book-chap3/","publishdate":"2020-02-23T16:37:17+09:00","summary":"これまでのはこちら。読書メモなので、本と合わせて読んでいただくのが良いです。 実践Rust入門はじめました 3章のクイックツアーを読んでます。 バ","tags":["rust","読書"],"title":"実践Rust入門の3章を読んでるところ"},{"contents":"もう2020年2月になってしまってますが、2019年に買って便利だったもの良かったものをいくつか記録に残しとこうかなと。\nBRAVIA KJ-55X9500G Amazon | ソニー SONY 49V型 液晶 テレビ ブラビア 4Kチューナー内蔵 テレビをやっと買い替えました。 前に使っていたのはプラズマディスプレイで、10年以上たったもので、パネルの一部が赤い残像が残ってたりしました。 もう流石にいいでしょうということで、買い替えたのがSonyのテレビです。 4Kのチューナーもついているし、アップコンバーターもついているので普通の地上波でもきれいです。 まぁ、10年前のテレビに比べればたくさんいいことがありますよねw\n新しいTV買って一番活躍してるのはYouTubeボタンだったりします。 最近はミュージックビデオがYouTubeにたくさんあるので、King Gnuなどの音楽流したりするのに便利です(テレビなのに)。 今は、プライムビデオボタンがより活用される感じになってきてます(テレビなのにw)。\nSodastream Amazon|スピリット ワンタッチ ホワイト スターターキット ここ数年、炭酸を普段飲んでます。甘いもの飲まないようにって意味でも。。。 で、これを買うまでは、サントリーの天然水スパークリングレモンとかを、箱買いしてました。 が、まぁ、ペットボトルのゴミが半端ないんですよ。場所も取るし。\nソーダストリームのことは知ってたのですが、自分で炭酸の量を考えながら、入れないといけないので避けていました。\nが、今回購入したものは、水の入ったボトルを指して、ボタン一つで3段階の炭酸を入れることができるんです!買って本当に重宝してます。うちでは1Lのボトルを1本追加して、2本で運用してます。 家族はなっちゃんのオレンジとかを炭酸割りしたり、カルピスソーダ作ったりして楽しんでます。 ワンタッチということで、簡単に入れられるので家族も重宝してます。\nNature Remo + Chromecast Amazon | Nature スマートリモコン Nature Remo mini Remo-2W1 Google Home miniがキャンペーンで手に入ったので、ベッドルームの照明やクーラーの操作もできそうなのでNature Remoを導入しました。 Chromecastは余っている液晶モニターにつないで、スマホからキャストできるようにしたり、音楽聞けるようにしてあります。\nNature Remoは温度計などもついているので、部屋の温度に合わせてエアコンのオンオフなども可能で、 暑い夏にとても便利でした。寝る時間にはクーラーが入っているのですんなり寝れたりと。 スマホから電源オンオフできるのも便利ですね。 Chromecastはモニターにつなぎましたが、今は、Google Music Playのプレーヤーになってます。 (最近、家にあるCDを読み込んでGoogle Play Musicにアップしてる)。\nただ、それ以上のことには使えてないので、もうちょっと面白いことしてみないとなぁ。\nモニターアーム Amazon | HUANUO PC モニター アーム 液晶ディスプレイ アーム ガススプリング式 Amazon | グリーンハウス 液晶ディスプレイアーム 4軸 クランプ式 ディスプレイがふるくなってたので、4Kディスプレイに買い替えた(27インチで4万切るとかで安い。。。)んですが、Mac Book Pro 15インチ(今は16インチ)を使っていて、Macの画面がディスプレイにかぶるので モニターアームを買いました。 1つ目がガススプリング式のアームです。なのに、5000円を切ってるんですよ。おそるべし。 2つ目はクランプ式です。アームにしたものの特に動かすことはなく、高さを出したいだけってことがあるので、クランプ式のも使ってます(家ではディスプレイ2枚使ってる)。 コスパ最高です。\nAnker PowerCore 10000 PD Amazon | Anker PowerCore 10000 PD(10000mAh PD対応最小最軽量 大容量 モバイルバッテリー) Pixel 3にしてから、電池の持ちはよくはなってるんですが、もしもの時のためにモバイルバッテリーは話せないですよね。 PD対応なので、Pixel 3に急速充電ができるし、サイズもそれほどじゃまにならないサイズなので便利です。USB-Aもついているので、このあと紹介するイヤホンの充電ケーブルなんかも差し込めて大活躍です。\nサウンドピーツのイヤホン Amazon | SOUNDPEATS(サウンドピーツ) Q35HD ワイヤレス イヤホン 高音質・低遅延 IPX8防水 私が持ってるのはこの前のバージョンで、micro-USBで充電充電するタイプですが、こちらもコスパ最高です。 冬は防寒も兼ねてヘッドフォンをしているのですが、春から秋にかけてはこれまで、優先のイヤホンを使ってました。もしくは、Bluetoothのレシーバーに優先のイヤホンつけてました。電池切れたら、イヤホンさして使う感じで。 が、Pixel 3はイヤホンジャックがありません。ということで、ワイヤレスイヤホンに移行するかということで選んだのがこちらです。 世の中的には、完全ワイヤレスイヤホンが流行っていますが、片方無くなってしまうイメージしかわかなくて。。。 これが壊れても、完全ワイヤレスではなくつながったワイヤレスイヤホンを使うと思います。\nヘッドルーペ Amazon | Tumao ヘッドルーペ ルーペ メガネ LED付拡大鏡 眼鏡の上装着 メガネゴムバンド両用 5レンズ交換調節 プラモデルをちょいちょい作るんですが、もう年ですね。。。細かいところが見にくくて。 ガンダムのRG系のプラモデルだと、1/144なんですよ。小さいんですよ。見えないんですよ。。。\n完成しましたー! pic.twitter.com/S9QTS4kJDI\n\u0026mdash; Jun Ohtani (@johtani) February 16, 2020 ということで、ヘッドルーペ導入してみました。 最初は、卓上に置けるルーペにしてみたんですが、自分がルーペがあるところに動かないといけないの結構つらくて。 これのおかげで、プラモデル作成に問題はなくなりました。老眼とは関係なく、ちょっと猫背になっちゃうのが今は悩みの種ですが。。。こたつで作ってるからなぁ。\nまとめ ということで、いくつかよかったものを紹介してみました。 今年はちゃんと年末に書こう。。。\n","date":1582272302,"dir":"post/2020/","id":"daa3fe935b0be9f31b6b362ad9e0d2d6","lang":"ja","lastmod":1582272302,"permalink":"https://blog.johtani.info/blog/2020/02/21/best-buy-2019/","publishdate":"2020-02-21T17:05:02+09:00","summary":"もう2020年2月になってしまってますが、2019年に買って便利だったもの良かったものをいくつか記録に残しとこうかなと。 BRAVIA KJ-55X9500G Amazon | ソニー SONY 49","tags":["買い物"],"title":"2019年に買ってよかったもの"},{"contents":"ブログ移行日記(その5)です。前回まではこちら\nブログ移行日記(その1) ブログ移行日記(その2) ブログ移行日記(その3) ブログ移行日記(その4) 今回はこれまでとは異なる特殊な話です。\n最初にブログを書き始めたときに利用していたのがJugemのブログでした。 その後、Octopressに移行して、今年、Hugoに移行したという流れです。\nで、よくよく考えると、Jugemのブログも移行できるんじゃないか?となりました。 じゃあ、やってみるかと。なので、今回のブログは自分の備忘録です(興味のない人が大多数じゃないかな)。 一応、Pythonで書いたプログラムはGitHubに上がっています。文字列置換と正規表現のオンパレードです。\nJugemからExport まずは、移行元のデータが取り出せるかどうかを調べたところ、text形式もしくはXML形式でエクスポートが可能でした。\n変換処理が必要なはずなので、XMLでダウンロードします。 独自のXMLですが、記事ごとにXMLのタグ(\u0026lt;entry\u0026gt;)でまとめられているので、処理が楽です。\nXMLをMarkdownに \u0026lt;entry\u0026gt;タグの下に次のような項目が入っているので、抜き出します。\nヘッダ部 title - 記事タイトル author - 著者 category - タグ date - 投稿日付 description : 本文(先頭部分) sequel : 本文(つづき) titleからdateまでをHugoのMarkdownのヘッダ部分として出力します。 日付は形式が違うので合わせるように変換し、 titleは(Jugemより移植)という文字列を追加しました。\nまた、Hugoの個別のコンテンツにするためにそれぞれをMarkdownのファイルに変換しています。 ファイル名は変換後のdateの先頭10文字(yyyy-MM-dd)に-を付け加えて、 タイトルを追加しました。ホントは英語のファイル名にしたかったんですが、ちょっと手抜き。ファイル名に使用できないような文字は-に置換しています。\n本文 本文部分はもう少し複雑です。 まずは、descriptionとsequelから抜き出した文字列を結合します。\nで、内部の文字列に次のようなものがあるので、それぞれMarkdownに変換したりという処理を書いてます。\nHTMLのheadingタグをMarkdown形式に br、hr、del、strongなどのタグもMarkdown形式に aタグの処理 Amazonのアフィリエイトタグの処理 ul、olタグの処理 などです。 アフィリエイトタグは、数行に渡るの複数のHTMLタグで記述されているので、 ASINと商品タイトルだけを抜き出しています。 Hugoでアフィリエイトのリンクを作るために、hugo-amazon-jpという公開されているshortcodeを元に、カスタマイズしたものを使っています。 これ用に、必要なASINとタイトルを別ファイルに出力したりしています。\nまた、いくつか画像を使っている記事があったのですが、これが曲者でした。 XMLに入っているimgタグに画像へのURLがあるのですが、アクセスしても存在しないURL担っています。。。 ブログで公開している画像のファイル名に似たものがXMLに入っていたので、URLを組み直して、ダウンロードするという処理も書いています。\nあとは、昔ちょっと凝った書き方(spanタグで章みたいなことやってた)をしていた部分の処理を加えて完成です。\nまとめ 元のXMLを見たり、抜き出したファイルを見ながら、トライアンドエラーでプログラムを書きました。 なんとなく変換できたなかっていうところで、取り込んで公開しました。 まだ、全部の記事をチェックしてないですが、なんとなく移植できたので一旦これでいいかなと。 昔の記事を見たときにおかしい場所があったら手で治すつもりでいます。\nなんか、もうちょっとうまくプログラムかけた気もしますが、書き捨てのプログラムだと思うのでこんなもんかな。\n1点気になっているところは、コメントの部分です。 ブログにコメントをいただいていたのですが、その部分は移植できてないです。\nOctopresに移植していこうは、Disqusのサービスでコメント部分を提供しています。ここに移植するのも変な話だなぁと思っているので、本文にコメントを取り込む感じかなぁ?\nもともとのJugemのサイトもそのまままだ残してあるので、そのうち気が向いたらで。\n","date":1582254240,"dir":"post/2020/","id":"ef8a399c9679ce4e9710c7c6ecf8bcc7","lang":"ja","lastmod":1582254240,"permalink":"https://blog.johtani.info/blog/2020/02/21/import-jugem-posts/","publishdate":"2020-02-21T12:04:00+09:00","summary":"ブログ移行日記(その5)です。前回まではこちら ブログ移行日記(その1) ブログ移行日記(その2) ブログ移行日記(その3) ブログ移行日記(その4","tags":["hugo","ブログ"],"title":"ブログ移行日記(その5) - Jugemのブログを移行"},{"contents":"お手伝いしているお客さんがAzure Cognitive Searchを利用してます。 検索周り=Azure Cognitive Searchに関する手伝いをする形で入っており、 いくつか触った感触をブログにまとめてみようかと(お客さんからはOKいただいてます)。\nAzure Cognitive Searchとは? 公式サイト 「AIを活用した」クラウド検索サービスと紹介されています。\n昔はAzure Searchと呼ばれていましたが、ここ最近はAzure Cognitive Searchと呼ばれているみたいです(Microsoft Igniteで発表された話がまとまっているページもあります)。 もともと、検索エンジンのSaaSサービス(キーワード検索、あいまい検索、オートサジェスト、スコアリングなどの機能)として作られていた部分に、データの登録パイプラインにCognitive Serviceの便利な機能を簡単に使えるようにしたものというイメージでしょうか。\nバックエンドはElasticsearchのはずです。変わってなければ。 昔、Elastic社主催のユーザーカンファレンスでMSの方が公演された資料が公開されていたりします。 ちなみに質問が多いのでしょうか、Azure Cognitive SearchとElasticsearchの違いはなんですか?というページがよくある質問のページに用意されていました。参考までに。\n今回はちょっとしたインデックスをつくって検索する部分を紹介してみようかと思います (Cognitiveなところは機会があればまた)。\n普通の使い方については、Azureのドキュメントなどを読んで頂く形にします。 ポータルと呼ばれるブラウザ上でAzureのサービスを触ることができる画面が用意されています。 ここで、簡単な操作(インデックス作成、フィールドの追加)\nAPIを使ってインデックス(特にAnalyzer)の設定をしたり、データをいれて、クエリしてみるというところをサクッと紹介しようと思います。\nインデックスの作り方 インデックス作成に関するドキュメントも用意されています。最初はポータル(GUI)でインデックスを作成する方法が紹介されています。 ですが、今回はn-gram(n=2)のAnalyzerを利用したかったので、GUIではなくAPIでインデックスを作成しました。 カスタムアナライザーを利用する場合、REST APIを利用しなければ行けないということになっています。 n-gramのAnalyzerを含むインデックス生成のREST APIは以下のとおりです。こちらを実行することで、インデックスが作成されます(JSONの記述ミスなどがある場合はエラーが返ってきます)。\n@host = \u0026lt;サーチのサービス名\u0026gt;.search.windows.net @api-key = \u0026lt;APIキー\u0026gt; ### POST https://{{host}}/indexes/?api-version=2019-05-06 Content-Type: application/json api-key: {{api-key}} { \u0026#34;name\u0026#34;:\u0026#34;ngram-test\u0026#34;, \u0026#34;fields\u0026#34;:[ { \u0026#34;name\u0026#34;:\u0026#34;id\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;Edm.String\u0026#34;, \u0026#34;key\u0026#34;:true, \u0026#34;searchable\u0026#34;:false }, { \u0026#34;name\u0026#34;:\u0026#34;ngram\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;Edm.String\u0026#34;, \u0026#34;searchable\u0026#34;:true, \u0026#34;analyzer\u0026#34;:\u0026#34;bi_gram_analyzer\u0026#34; } ], \u0026#34;analyzers\u0026#34;:[ { \u0026#34;name\u0026#34;:\u0026#34;bi_gram_analyzer\u0026#34;, \u0026#34;@odata.type\u0026#34;:\u0026#34;#Microsoft.Azure.Search.CustomAnalyzer\u0026#34;, \u0026#34;tokenizer\u0026#34;:\u0026#34;bi_gram_tokenizer\u0026#34;, \u0026#34;tokenFilters\u0026#34;:[ \u0026#34;lowercase\u0026#34; ] } ], \u0026#34;tokenizers\u0026#34;:[ { \u0026#34;name\u0026#34;:\u0026#34;bi_gram_tokenizer\u0026#34;, \u0026#34;@odata.type\u0026#34;:\u0026#34;#Microsoft.Azure.Search.NGramTokenizer\u0026#34;, \u0026#34;minGram\u0026#34;:2, \u0026#34;maxGram\u0026#34;:2 } ] } なんだかどこかで見たことのある記述のようなそうでないような。。。 Analyzerは、charFilters(0以上複数可)、tokenizer(1つ必須)、tokenFilters(0以上複数可)から構成されます。 フィールドで指定するのはAnalyzerなので、まずanalyzersにCustomAnalyzerの設定を行います。 名前はbi_gram_analyzerにしました(好きに付けてください)。 tokenizerにはこのあと設定するtokenizerの名前を設定します。ここでは、bi_gram_tokenizerという名前にしています。 また、大文字小文字を気にせずに検索したいため、tokenFiltersにlowercaseを指定しています。こちらはすでに定義済みのため、定義済みの名前で呼び出すだけで使用できます。\n次が、bi_gram_tokenizerの設定です。 n=2としたいので、tokenizers配下にTokenizerの設定をします。 @odata.type\u0026quot;:\u0026quot;#Microsoft.Azure.Search.NGramTokenizerがTokenizerの名前です(ちょっと独特な名前ですね)。 Tokenizerごとにオプションがあり、NGramTokenizerの場合は、minGram、maxGramがオプションに相当します。 今回は2文字ごとにトークンを出力したいので、minとmaxをそれぞれ2としています。\nこれで、あとは、フィールドでanalyzerという設定にbi_gram_analyzerを指定すればそのフィールドはbi_gram_analyzerを使用してアナライズされるようになります(このへんはElasticsearchといっしょですね)。 フィールドは文字列を扱うので、Edm.Stringというタイプにしてあります。データ型については、フィールドコレクションとフィールド属性というドキュメントを参考に設定しましょう。\n閑話休題 - REST Client Exstension for Visual Studio Code なお、今回のサンプルはREST Clinet Extention for Visual Studio Codeを利用する想定の記述になっています。\nVisual Studio Codeで.restもしくは.httpというファイルに以下のAPIを記述すると、Send RequestというリンクがURLの上部に出てくるような拡張機能です。REST APIにリクエストするときに便利なツールになっています。 変数も使えるので、APIのキーやURLの一部をこのように共通化して、他の環境でも使いやすくできるのは素晴らしいなと。\nアナライザーの挙動の確認 設定したAnalyzerがきちんと機能しているかというのを確認する必要があります。 入力した文字列がきちんと想定している単語として切り出されて、転置インデックスの見出し語に使われるかというのが重要になるからです。\nAzure Cognitive Searchでもアナライザーのテスト用APIが用意されています。 使い方はこちら。 APIの仕様のページもありました。 「アナライザーの挙動はどんな感じ?」という文字列が、作成したインデックスの定義したアナライザーbi_gram_analyzerにより、 どのように分割されるかを確認するAPIの呼び出しは以下のとおりです。\n### POST https://{{host}}/indexes/ngram-test/analyze?api-version=2019-05-06 Content-Type: application/json api-key: {{api-key}} { \u0026#34;analyzer\u0026#34;:\u0026#34;bi_gram_analyzer\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;アナライザーの挙動はどんな感じ?\u0026#34; } レスポンスはこんな形です。ヘッダ部分は省略してあります。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;https://{{host}}.search.windows.net/$metadata#Microsoft.Azure.Search.V2019_05_06.AnalyzeResult\u0026#34;, \u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;アナ\u0026#34;, \u0026#34;startOffset\u0026#34;: 0, \u0026#34;endOffset\u0026#34;: 2, \u0026#34;position\u0026#34;: 0 }, { \u0026#34;token\u0026#34;: \u0026#34;ナラ\u0026#34;, \u0026#34;startOffset\u0026#34;: 1, \u0026#34;endOffset\u0026#34;: 3, \u0026#34;position\u0026#34;: 1 }, { \u0026#34;token\u0026#34;: \u0026#34;ライ\u0026#34;, \u0026#34;startOffset\u0026#34;: 2, \u0026#34;endOffset\u0026#34;: 4, \u0026#34;position\u0026#34;: 2 }, { \u0026#34;token\u0026#34;: \u0026#34;イザ\u0026#34;, \u0026#34;startOffset\u0026#34;: 3, \u0026#34;endOffset\u0026#34;: 5, \u0026#34;position\u0026#34;: 3 }, { \u0026#34;token\u0026#34;: \u0026#34;ザー\u0026#34;, \u0026#34;startOffset\u0026#34;: 4, \u0026#34;endOffset\u0026#34;: 6, \u0026#34;position\u0026#34;: 4 }, { \u0026#34;token\u0026#34;: \u0026#34;ーの\u0026#34;, \u0026#34;startOffset\u0026#34;: 5, \u0026#34;endOffset\u0026#34;: 7, \u0026#34;position\u0026#34;: 5 }, { \u0026#34;token\u0026#34;: \u0026#34;の挙\u0026#34;, \u0026#34;startOffset\u0026#34;: 6, \u0026#34;endOffset\u0026#34;: 8, \u0026#34;position\u0026#34;: 6 }, { \u0026#34;token\u0026#34;: \u0026#34;挙動\u0026#34;, \u0026#34;startOffset\u0026#34;: 7, \u0026#34;endOffset\u0026#34;: 9, \u0026#34;position\u0026#34;: 7 }, { \u0026#34;token\u0026#34;: \u0026#34;動は\u0026#34;, \u0026#34;startOffset\u0026#34;: 8, \u0026#34;endOffset\u0026#34;: 10, \u0026#34;position\u0026#34;: 8 }, { \u0026#34;token\u0026#34;: \u0026#34;はど\u0026#34;, \u0026#34;startOffset\u0026#34;: 9, \u0026#34;endOffset\u0026#34;: 11, \u0026#34;position\u0026#34;: 9 }, { \u0026#34;token\u0026#34;: \u0026#34;どん\u0026#34;, \u0026#34;startOffset\u0026#34;: 10, \u0026#34;endOffset\u0026#34;: 12, \u0026#34;position\u0026#34;: 10 }, { \u0026#34;token\u0026#34;: \u0026#34;んな\u0026#34;, \u0026#34;startOffset\u0026#34;: 11, \u0026#34;endOffset\u0026#34;: 13, \u0026#34;position\u0026#34;: 11 }, { \u0026#34;token\u0026#34;: \u0026#34;な感\u0026#34;, \u0026#34;startOffset\u0026#34;: 12, \u0026#34;endOffset\u0026#34;: 14, \u0026#34;position\u0026#34;: 12 }, { \u0026#34;token\u0026#34;: \u0026#34;感じ\u0026#34;, \u0026#34;startOffset\u0026#34;: 13, \u0026#34;endOffset\u0026#34;: 15, \u0026#34;position\u0026#34;: 13 }, { \u0026#34;token\u0026#34;: \u0026#34;じ?\u0026#34;, \u0026#34;startOffset\u0026#34;: 14, \u0026#34;endOffset\u0026#34;: 16, \u0026#34;position\u0026#34;: 14 } ] } このAzure SearchのAnalyze API、使用できるオプションはすくないですが、ElasticsearchのAnalyze APIと似ています。\nデータの登録の仕方 データ登録もAPIからできます(あたりまえですね)。 APIは1件ずつではなく、バルクで登録できる形で提供されています。\nサンプルとしては、以下のような形です。 @search.actionの部分(searchがあるとわかりにくい気がするけど。。。)が、ドキュメントの登録、更新、削除の命令を書き込むところになります。 今回は単純に登録するだけなので、uploadを指定しました。 ほかにもいくつかアクションが用意されています。用途に合わせて指定する感じになります。 id、ngramはそれぞれフィールド名です。ドキュメントに登録したい値を記述します。\nPOST https://{{host}}/indexes/ngram-test/docs/index?api-version=2019-05-06 Content-Type: application/json api-key: {{api-key}} { \u0026#34;value\u0026#34;: [ { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;ngram\u0026#34;: \u0026#34;新しいAzure Searchの使い方\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;2\u0026#34;, \u0026#34;ngram\u0026#34;: \u0026#34;Elasticsearchの紹介\u0026#34; } ] } 検索クエリ 最後は検索クエリです。 検索クエリはいくつかのオプションがあります。 ざっくりだと、queryTypeがsimpleとfullという2種類が用意されており、ちょっとした検索を作る場合はsimpleで事足りそうという感じです。 入力された単語(スペース区切りで複数扱い)をフィールド(複数可)に対していずれかの単語を含むもしくは、すべての単語を含むという検索に行くというパターンですね。 このときの、「いずれか」か「すべて」の設定がsearchModeというパラメータになります。 anyの場合、Googleの検索と同様に、どれかの単語が入っているドキュメントが対象に、allの場合すべての単語が含まれるドキュメントだけがたいしょうになるといった形です。\nqueryType=fullの場合はLuceneの構文でクエリがかけます。ElasticsearchのQuery String Queryみたいな形です。\n簡単なサンプルは次のような感じです。このサンプル\nPOST https://{{host}}/indexes/multi-field-test/docs/search?api-version=2019-05-06 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#39;ngram:\u0026#34;使い方\u0026#34; ngram:\u0026#34;紹介\u0026#34;\u0026#39;, \u0026#34;queryType\u0026#34;: \u0026#34;full\u0026#34;, \u0026#34;searchMode\u0026#34;: \u0026#34;any\u0026#34; } すこしだけクエリの補足を。 searchに入力された単語をダブルクォートで囲んでいます。これは、「使い方」という文字がbi_gram_analyzerにより「使い」「い方」に 分割されるのですが、必ずこの順序で出現したものだけを検索対象にしたい(フレーズ検索)という意味になります(*bi_*gramなので、「紹介」に関してはダブルクォートは厳密には必要ないです)。\nあと、レスポンスは今回記載していませんが、@search.scoreという項目で、スコアが返ってきます。 デフォルトのスコア計算には何を使ってるんだろう?ドキュメントにはTF-IDFとの記述があるのですが。。。カスタマイズもできそうです。\n少しオモシロイと思ったのは、スキーマ(インデックスの設定)に定義されているが、ドキュメントとしては登録していない項目についても、 Azure Cognitive Searchはドキュメントのフィールドがnullという形で返ってくるようでした。 そもそもフィールドが存在しないドキュメントとフィールドの値がnullのものの違いは無いようです。\n簡単ですが、インデックスの設定、ドキュメントの登録、検索の方法の紹介でした。\nちょっと触った感想 一番売りである、Cognitiveの部分はまだ触っていないです、すみません(こっちが売りな気もするんですが)。 検索エンジンの部分としては、Elasticsearchを知っていると、「あー、そんな感じね」という気持ちになれるサービスです。 個々のAPIやデータの形式は異なるので、きちんとAPIのリファレンスなどを確認しつつという形になりますが、なんとなくこういうAPIなどがありそうだな?と予測しつつ使えるかなと。 内部的にはElasticsearchだと思いますが、独自のAPIでラップされているおかげで、バージョンの違いなどを意識せずに使えるのではないかと思います。\nまた、今回は紹介していませんが、マイクロソフト独自の各言語のアナライザー(日本語も含む)があります。 Luceneのアナライザーとマイクロソフトのアナライザーのどちらも利用できますので、ここの違いを見てみるのも面白そうだなと思いました。 緯度経度を利用した検索、フィルター検索(スコア計算対象にならない)、ファセット、スコア調整の機能なども備えているようです。\nなんにせよ、利用する場合やドキュメントを読む場合に、全文検索の仕組みをなんとなく知っておいたほうが読みやすいんじゃないかなというのが感想です。\nここ数年はElasticsearchがメインでほかはほぼ触っていない状況だったので新しい製品に触れるのは面白いですね。 時間があったら、アナライザーの違いなども調べてみたいなと思います。\n","date":1582080481,"dir":"post/2020/","id":"c3053579ae25e2fb9b967076a06373af","lang":"ja","lastmod":1582080481,"permalink":"https://blog.johtani.info/blog/2020/02/19/research-azure-cognitive-search/","publishdate":"2020-02-19T11:48:01+09:00","summary":"お手伝いしているお客さんがAzure Cognitive Searchを利用してます。 検索周り=Azure Cognitive Searchに関する手伝いをする形で入っており、 いく","tags":["azure search"],"title":"Azure Cognitive Searchでインデックスを作って検索"},{"contents":"また、ツイートから始まるお話です。 まだまだ、検索システムってどんなものかを勉強したいしということで、こんなのをツイートしてました。\n「検索システム探訪」みたいな名前がいいかな? https://t.co/sG7BDdGI9h\n\u0026mdash; Jun Ohtani (@johtani) February 6, 2020 検索について知り合いとお茶をしながら話をしていて、こういう話を聞くの面白いなぁと思ったので。 どんなことを個人的には聞きたいかな?というのをまとめといたほうがいいかと思いブログを書いています。 こんなことも面白そうだよね?\nどんなこと聞きたいかな? いまのところ思いついた内容はこんな感じかな? こんなのも聞くと面白そうだよね?などありましたら、コメント欄に書いてもらえればと。\n利用しているシステム・サービスは? 構成やどこのサービスなのか? 検索ユーザーはどんな人? ユーザーの種類 ユーザーの検索ニーズ 検索対象データはどんなもの? データ件数はどのくらい? 属性、項目がどのくらいあるか? 検索結果として出したいものは? ソートはどんなものがあるの? ランキングで重要なものは? UI/UXはどんな感じ? ハイライト、ソート、ファセット(Aggs) キーワードサジェスト、オートコンプリート 検索システムの監視(オブザバビリティ??) ビジネス的な指標 クエリログ、クリック(ユーザーに関する情報) システムメトリクス 困っていることは? ランキング クエリ 検索システム分析 第1回やりました。 ちなみに、最初のツイートに対して、すぐに返事をくれた方がいました。\nうちでよければご説明します!\n\u0026mdash; Kizashi (令和もRailsエンジニア募集中) (@kizashi1122) February 6, 2020 Twitter本当にありがとうございますという感じです。\nで、早速話を聞かせていただきました。大阪の方だったので、テレカンでやらせていただきました。 移動時間とか気にせずにできるので、テレカン形式いいですよね。\n内容は、非常に面白かったです。 使ってるシステムについて、どんなところで、どのようなように検索エンジンをつかっているのか、 どんなことで困っているのかなどをお聞きすることができました。\n2020/02/13 追記 対応していただいたIngageの永田さんから、内容を公開しても良いという承諾をいただいたので、メモを公開します。\nサービス : Re:lation 問い合わせメールなどのチームで対応する対応 利用している検索エンジン Elasticsearch (AWS Es) ノード数 8 - 3 master + 5 data データ データ数 : 約1億5千万 親子関係 : チケット - メール(=1ドキュメント) - コメント 画面としてはチケットの一覧=aggsでチケットIDの一覧を生成してリスト表示 インデックス数 : 5 = テナントごとに振り分けしてる。 8シャード - スケールアウトした場合も対応できるので。 PostgreSQLにマスターは保存 データの単位はメール。コメントはtextの配列でメールに保存されている。 EsはIDの一覧を返す。ただし、チケットのIDの一覧 機能 ハイライト Esではなく独自実装。 クエリ n-gramでやってる = kuromoji使ってない min=1, max=2 悩み事 EBS上だったものをローカルにしたので速くなった。 期間が長いと、検索結果一覧の表示が遅い aggsが遅いのかな? 検索結果一覧はチケットが持っているメールの日付の降順。結果一覧はチケットの一覧。 詳細検索はDB、左のステータスもファセットも現在はDBから生成 Es使ったほうが早いかも? マルチテナントのつらさ 検索ログ 独自ログはとっていない = アプリのログから判別 今後 アドレス帳検索 お誘いお待ちしております! 今後もこれやっていきたいなぁ。話してもいいよ!という方がいらっしゃいましたら、@johtaniまでDMもしくはメンションをください。お待ちしております!\n","date":1581344427,"dir":"post/2020/","id":"7b080dc43fce482af14de61c6ab819a5","lang":"ja","lastmod":1581344427,"permalink":"https://blog.johtani.info/blog/2020/02/10/explore-search-system/","publishdate":"2020-02-10T23:20:27+09:00","summary":"また、ツイートから始まるお話です。 まだまだ、検索システムってどんなものかを勉強したいしということで、こんなのをツイートしてました。 「検索シス","tags":["検索システム探訪"],"title":"「検索システム探訪」したいな=\u003eやりました"},{"contents":"年末、何種類かのボードゲームを家族で楽しみました。 家族の感想を交えて簡単に紹介しようかと思います。 家族や知人でボードゲームを購入するときの参考に参考にしてもらえたらと。 それぞれのゲームの詳細については、それぞれWikipediaなどのリンクを張っておくので、参考にしていただけたらと。 結構有名なボードゲームが多いのかな?\nカタン Amazon | カタン スタンダード版 | ボードゲーム | おもちゃ 簡単な紹介 プレーヤー数 : 3-4名 (拡張版を追加すると5-6名でもプレイできるみたい) 対象年齢 : 10歳以上 種類 : 対戦型 紹介 : 大航海時代に発見された無人島を複数の入植者たちが開拓していき、もっとも繁栄したプレイヤーが勝利するという内容のボードゲーム(Wikipediaより)。 特徴 : 5種類の資源を元に、道を作ったり、開拓地や都市を作ったり、サイコロを使った運も必要ですが、プレーヤー同士で手持ちの資源を交渉することも可能なゲームです。 感想 最初の配置が重要な気がします。資源の組み合わせによってできることが変わってくるので、何をやりたいかというのを元に考えて配置するのが重要そうです(私はまだうまくできてませんがw)。 プレーヤー同士の交渉も1つの手段なので、会話しながら、自然と交渉術も身についてきそうです。 戦略だけじゃなくサイコロを使った運もあるので、子供と大人が混ざっていても偏った結果にはならないです。 自分の道や町が発展していくのも楽しみの1つです。 お化け屋敷の宝石ハンター Amazon | お化け屋敷の宝石ハンター FBH20 | おもちゃ | おもちゃ 簡単な紹介 プレーヤー数 : 2-4名 対象年齢 : 8歳以上 種類 : 協力型 紹介 : お化け屋敷がおばけでいっぱいになる前に、みんなで協力して8つの宝石をみつけて、屋敷から脱出しよう!(メーカーホームページより)。 特徴 : 対戦ではなくプレーヤーみんなで協力してやるボードゲーム。おばけのフィギュアも可愛いです。サイコロを利用した運もありますが、みんなでどういった戦略で宝石を取り出すかなど会話も進むゲームです。上級編という難しめのルールも用意されているので、ハラハラ・ドキドキしながらプレイできます。 感想 負けて悔しくなったり機嫌が悪くなることがないのがいいですね。 普通のルールだと少し物足りない感じですが、上級編のルールはより、みんなで協力する必要が出てきます。 また、上級編のルールは絶妙な難易度で、もう一度やりたいと思わせるのが良い仕組みです。 ラビリンス Amazon | ラビリンス (Labyrinth) ボードゲーム | ボードゲーム | おもちゃ 簡単な紹介 プレーヤー数 : 1-4名 対象年齢 : 8歳以上 種類 : 対戦型 紹介 : 動く迷路で宝探し!通路が動く不思議な迷路の中に、「宝物」や「奇妙な生き物」が隠されています。プレイヤーはこれらを集めてこなければなりませんが、そのためには、巧みに迷路を動かさなければなりません。(メーカーホームページより)。 特徴 : サイコロがないボードゲームです。先を予測しながら人のじゃまをしつつ、自分に有利に進めていくゲームです。プレーヤー個別に難易度を変えられる仕組みがあります(子供だけに有利なルール設定が可能)。 感想 子供ルールがあるので、1度のゲームで別々の難易度が設定できるのがいいです。左右盲の人には子供ルールとかもありです。 ラビリンスが得意な人は地図を読むのが得意な人だと思います。 頭も使うけど、自分が望んだ道ができた時の快感があります。 モノポリー Amazon | ハズブロ ボードゲーム モノポリー クラシック C1009 正規品 | ボードゲーム | おもちゃ 簡単な紹介 プレーヤー数 : 2-6名 対象年齢 : 8歳以上 種類 : 対戦型 紹介 : プレイヤーは双六の要領で盤上を周回しながら他プレイヤーと盤上の不動産を取引することにより同一グループを揃え、家やホテルを建設することで他のプレイヤーから高額なレンタル料を徴収して自らの資産を増やし、最終的に他のプレイヤーを全て破産させることを目的とする。モノポリーとは英語で「独占」を意味する。(Wikipediaより)。 特徴 : 資本主義とは?みたいなのを体験できるゲーム。すごろく型ですが、ゴールがあるわけではなく、決着がつくまでぐるぐる回る感じです。 感想 資本主義を象徴しているゲーム展開。真剣勝負間違いなしです。 負けると途中退場ってのがちょっとつらいです。。。 カタンとは違った感じの交渉術になります。 コマが色んな種類があってかわいいです。 パンデミック Amazon | パンデミック:新たなる試練 (Pandemic) 日本語版 ボードゲーム | ボードゲーム | おもちゃ 簡単な紹介 プレーヤー数 : 2-4名 対象年齢 : 8歳以上 種類 : 協力型 紹介 : 『パンデミック』(Pandemic)は、プレイヤーが新型ウイルス対策チームの一員となり、協力しあい感染症の世界的流行(パンデミック)に立ち向かうというボードゲームである。(Wikipediaより)。 特徴 : プレーヤーが個別のロール(役割)を持っており、よりみんなで協力をしないとウイルスに打ち勝てない感じです。 感想 ルールが結構複雑で、理解しながらだと少し時間かかりました。 8歳以上になっていますが、少しむずかしい印象でした。 戦略、戦術が問われる形のゲームなのでしっかり理解すると楽しそう。 世界地図上で、ウイルスと戦っていく感じは臨場感があって面白いです。 ナインタイル Amazon | ナインタイル | カードゲーム・トランプ | おもちゃ 簡単な紹介 プレーヤー数 : 2-4名 対象年齢 : 6歳以上 種類 : スピード対戦型 紹介 : 「ナインタイル」の基本ルールは、それぞれの手元にある、9枚のタイルを自由に動かしたりひっくり返したりして、誰よりも早くお題どおりに並べるだけ。(公式サイトより)。 特徴 : ボードゲームというか、カードゲーム。ルールは簡単ですが、記憶力と素早さが重要です。 感想 脳トレに良さそう(子供に勝てませんでした。。。)。 瞬発力+記憶力が重要。 デザインがきれい じゃあ、家族の人気は? ラビリンス、カタン、モノポリーあたりが人気です。 ゲーム性もありますが、デザインとしてもきれいなものが多かったです。\nテレビゲームも面白いですが、ワイワイ喋りながらボードゲームをやるのも楽しかったです。 今回紹介したボードゲームはどれもある程度ルールを理解するところから始めないといけないですが、理解力や説明力なども必要になってくるので色んな楽しみがあるかなと思います。\n","date":1580558694,"dir":"post/2020/","id":"90f9355781403b92e844de8568863ae8","lang":"ja","lastmod":1580558694,"permalink":"https://blog.johtani.info/blog/2020/02/01/intro-board-game/","publishdate":"2020-02-01T21:04:54+09:00","summary":"年末、何種類かのボードゲームを家族で楽しみました。 家族の感想を交えて簡単に紹介しようかと思います。 家族や知人でボードゲームを購入するときの参","tags":["ゲーム"],"title":"ボードゲーム紹介"},{"contents":"実践Rust入門という本を買っていた(去年の7月だ。。。)のですが、積んであったので、時間を作って読み始めようかと。\n実践Rust入門[言語仕様から開発手法まで] | κeen, 河野 達也, 小松 礼人 |本 | 通販 | Amazon 経緯 もともとは、言語処理100本ノックはじめました(Rust)という感じで、触っていたのですが、場当たり的にやってても時間を持っていかれるだけだなということに気づいたのが最初です。\n今年の目標は、覚えられなので、ちょっとずつでもアウトプットしていこうってのもあり、 読書記録をつけつつ、読んでいこうかなぁと。\nどこまで読んだ? 2章の2-2-5までです。 前回、Rustの環境はセットアップしていたのですが、新PCに切り替わったので、rustupからはじめました。\nrustup rustupではデフォルト設定のままではなく、PATH変数の書き換えだけはしない形でインストールを行いました。\nPATH変数は.zshrcファイルで変更したかったためです(rustupコマンドに変更して貰う場合は.profileなどのファイルが変更されそうだったため)。\nインストールが終わったあとに.zshrcに以下の行を追加しました。\n### For Rust env source $HOME/.cargo/env 疑問点 ここまで読んだ疑問点です。\ncargo new helloしたあとにmain.rsに以下のmain()関数が出来上がっている!? fn main() { println!(\u0026#34;Hello, world!\u0026#34;); } 驚きましたが、cargo new hogeってやっても、おなじmain.rsができてました。デフォルトで出来上がるんですね。どんな超能力!?と思ってしまいましたw\ncargo new helloして出来上がったCargo.tomlに著者名が入力されていた。 authors = [\u0026#34;Jun Ohtani \u0026lt;メアド\u0026gt;\u0026#34;] なんで?と思いました。まだ解明してないです。 本を読んでいけばわかるかな?\n予想:gitの設定(~/.gitconfig)に氏名とメアドが設定されているので、これを利用しているのかな? ","date":1580475492,"dir":"post/2020/","id":"7fcfaa8dd34dbd508f19e8ca0fcfda0f","lang":"ja","lastmod":1580475492,"permalink":"https://blog.johtani.info/blog/2020/01/31/start-reading-bicycle-book/","publishdate":"2020-01-31T21:58:12+09:00","summary":"実践Rust入門という本を買っていた(去年の7月だ。。。)のですが、積んであったので、時間を作って読み始めようかと。 実践Rust入門[言語仕","tags":["rust","読書"],"title":"実践Rust入門はじめました"},{"contents":"12月に退職しますブログを書きましたが、その後どうなったのか?という話をしてないなと思ったので、一応現在の状況を書き留めておこううかと。\n結論 実際にはフリーランスとして働き始めてます。検索周りをお手伝いするお仕事を。読解いとこあれば所属するつもりでもいるし。\n\u0026mdash; Jun Ohtani (@johtani) January 27, 2020 フリーランスとして最初の仕事はElasticsearchではなく、Azure Cognitive Searchの支援だったりします。Esで困ってる方の手伝いもしますので、興味ある方はDMください。\n\u0026mdash; Jun Ohtani (@johtani) January 31, 2020 2020年1月24日が、正式なElasticの退職日でした(有給休暇消化してた)。 で、現在のステータスはこのツイートです。\n現在の心境 どこかに就職してガッツリ検索もやりたいし、いろんな会社の検索やElastic Stackに関するお手伝いをするのにも興味があるし、どちらにも興味がある状況です。まぁ、検索に興味が尽きないというのだけは決まってますかね。\n悩んでいるところに、幸いにもAzure Search周りで手伝ってほしいという話が舞い込んできたので、フリーランスとしてお手伝いをさせていただいてます(現時点で、半稼働で、が3月末まで)。\nElastic Stackなどの知見もあるのでのお手伝いをするというのもありかなぁと。お仕事発注してもいいな?という方があれば、TwitterのDMなど、連絡をいただければと。\n現在の状況でした。\n副業ができる会社に就職するのがどっちもできていいのかも?\n","date":1580470659,"dir":"post/2020/","id":"c61a5bda3f1667498626ae52ad0362e0","lang":"ja","lastmod":1580470659,"permalink":"https://blog.johtani.info/blog/2020/01/31/start-freelance/","publishdate":"2020-01-31T20:37:39+09:00","summary":"12月に退職しますブログを書きましたが、その後どうなったのか?という話をしてないなと思ったので、一応現在の状況を書き留めておこううかと。 結論","tags":["転職"],"title":"フリーランスはじめました(仮)"},{"contents":"ブログ移行日記(その4)です。その他の記事はこちら。\nブログ移行日記(その1) ブログ移行日記(その2) ブログ移行日記(その3) ブログ移行日記(その5) 前回までで、なんとなく移行は終わってます。 今回はテーマで使えるようになっているブログの検索機能の導入の話です。\n検索サービスはAlgoliaを利用します。 OctopressのころはElastic社のサービスであるElastic Site Searchの機能を利用して、クローリングしてから検索できるようにしていましたが、Hugoで導入できるモジュール?があったので、今回からこちらに移行しました。\n参考記事 Clean White ThemeのREADME(Algoliaの設定方法) 参考ブログ:hugoで作ったblogにalgoliaで全文検索機能を追加する Algoliaとは? 検索のas-a-serviceをやっている会社です。Wikipediaによると本社はサンフランシスコにあるみたいですね(フランスの会社のイメージでした。起業された方がフランス出身だからかなぁ?)。 クラウドで検索インデックスを保持でき、API経由で検索したり登録したりできる感じのサービスです。内部で使われているのはOSSではない独自の検索エンジンです。\nクラウドで提供されているサービスなのでサクッと検索を使い始めることができるのがいい点ですね。 また、小さな非商用のプロジェクトにフリーで利用できるプランも提供されているようです(2020年1月現在)。\nAlgoliaのサービス登録からインデックス作成 私が利用しているテーマで設定する方法の記載があったので手順の通りにやってみました。 大きく2つの作業(Algolia側とHugo側)が必要です。まずは、Algoliaで必要な作業から。作業の流れだけ記載しておきます。詳細は「Static site search with Hugo + Algolia」の3)を確認してください。\nAlgoliaのサインアップ(すでにアカウントがあれば不要) New Applicationの作成(名前とプランの指定) リージョンの指定 インデックス名の指定 APIキーを確認 です。これで、Algolia側の準備は完了です。\n今回は関係ないですが、Algoliaの管理画面で、利用状況(データ登録などの操作回数、クエリの回数、インデックスに保存されているレコード数)の確認が可能です。 ほかにも有料プランを利用するとAnalyticsなどもできるようです。\nHugo側で必要な設定 今度はHugo側です。Hugoのサイトのディレクトリに移動してからの作業です。\n仕組みとしては、\nHugoのoutput機能でAlgolia向けのJSONファイルを生成する Node.jsのライブラリを使用してAlgoliaに1.で生成したJSONを登録、更新する 検索画面の作成 という流れになります。 ですので、作業としては以下のとおりです。\nOutput出力の設定(すでにテーマ側で設定されているので、特に作業は必要なし) npm環境の構築(Hugoのconfig.tomlと同じディレクトリ階層) Node.jsのインストール(必要であれば) npm環境の初期化 npmでatomic-algoliaのインストール atomic-algolia向けの設定(登録のためのAPI関連の設定) Algolia向けJSONの出力設定 検索関連の設定 content/search/placeholder.mdの作成 検索用のAPIキーなどを設定 npm関連の作業 以下、npm関連の作業です。\nNode.jsのインストール(必要であれば) 割愛します。環境に合わせてインストールしてください。私はnvm経由でインストールしています。 npm環境の初期化 Hugoのディレクトリでnvm initを実行 npmでatomic-algoliaのインストール Hugoのディレクトリでnpm install atomic-algolia --save atomic-algolia向けの設定(登録のためのAPI関連の設定) Hugoのディレクトリに.envファイルを作成し、以下を設定します。 Algolia向けJSONの出力設定 特に変更なし(config.tomlに少し設定があります)。 ALGOLIA_APP_ID=AlgoliaのApplication ID ALGOLIA_ADMIN_KEY=AlgoliaのAdmin API Key ALGOLIA_INDEX_NAME=先程作ったインデックス名 ALGOLIA_INDEX_FILE=public/algolia.json 最後のALGOLIA_INDEX_FILEは固定文字列でいいと思います。 hugoコマンドを実行するとpublicディレクトリ配下にalgolia.jsonというファイルが生成され、Algolia登録用のJSONが出力されています。\n余談 : algolia.jsonの出力の設定は、config.tomlに記載があります。また、JSONファイルのテンプレート自体はthemes/hugo-theme-cleanwhite/layouts/_default/list.algolia.jsonにあります。Algoliaに登録するデータの構造など変更をする場合はこのテンプレートをカスタマイズすれば良さそうです。\n検索関連の設定 実際に検索の画面を表示するために、検索用の画面と、検索用のAPIの設定が必要です。\ncontent/search/placeholder.mdの作成 /search/が検索用のページになります。空のファイルです。実際にはJavaScriptが検索用の窓を表示したりしてくれます(これが必要な理由がまだ不明だなぁ)。 検索用のAPIキーなどを設定 検索のためのAPIキーなどの設定が必要となります。テーマ作者の方のサンプルのconfig.tomlにパラメータは用意されています。 以下の値を設定します。\nalgolia_search = true algolia_appId = \u0026#34;AlgoliaのApplication ID\u0026#34; algolia_indexName = \u0026#34;作成したインデックス名\u0026#34; algolia_apiKey = \u0026#34;AlgoliaのSearch-Only API Key\u0026#34; 以上でAlgolia関連の設定などの作業が終了です。\nAlgoliaへのデータ登録方法 最後に、実際にデータを登録する必要があります。 手順は、以下のとおりです。\nhugoコマンドの実行(htmlと一緒に登録データのalgolia.jsonを生成) npm run algoliaコマンドの実行(atomic-algoliaを利用してAlgoliaにデータを登録) 設定などが問題なければ、Algoliaの管理画面で登録ができているはずです。 実際にブログのデプロイにはdeploy.shというファイルをこちらを元に作成して使っています。このなかで、hugoコマンド実行後にnpm run algoliaを実行するようにしいます。\n今後の課題 Hugoで生成された記事はそれぞれのブログポスト以外に、タグごとのページも生成されています。 こちらも実はAlgoliaのインデックスに登録されていて、タグを入力すると、タグ名のリンクが出てきます。\nこちらはelasticsearchで検索したときの検索結果です。1件目はタグページです。\nこれらのページはAlgoliaに登録しないようにするのが良さそうかな?と考えているところです(考えてるだけ)。\n2020/01/29更新\nlist.algolia.jsonを編集して、記事だけをインデックスするように修正しました。 テーマに存在するlayouts/_default/list.algolia.jsonを、自分のところにコピーし、次のように変更しました。if文を1行追加して、postという種類のものだけを出力するようにしました。\n{{/* Generates a valid Algolia search index */}} {{- $.Scratch.Add \u0026#34;index\u0026#34; slice -}} {{- $section := $.Site.GetPage \u0026#34;section\u0026#34; .Section }} {{- range .Site.AllPages -}} {{- if or (and (.IsDescendant $section) (and (not .Draft) (not .Params.private))) $section.IsHome -}} {{- if (and (eq .Section \u0026#34;post\u0026#34;) (ne .URL \u0026#34;/post/\u0026#34;)) -}} {{- $.Scratch.Add \u0026#34;index\u0026#34; (dict \u0026#34;objectID\u0026#34; .UniqueID \u0026#34;date\u0026#34; .Date.UTC.Unix \u0026#34;description\u0026#34; .Description \u0026#34;dir\u0026#34; .Dir \u0026#34;expirydate\u0026#34; .ExpiryDate.UTC.Unix \u0026#34;fuzzywordcount\u0026#34; .FuzzyWordCount \u0026#34;keywords\u0026#34; .Keywords \u0026#34;kind\u0026#34; .Kind \u0026#34;lang\u0026#34; .Lang \u0026#34;lastmod\u0026#34; .Lastmod.UTC.Unix \u0026#34;permalink\u0026#34; .Permalink \u0026#34;publishdate\u0026#34; .PublishDate \u0026#34;readingtime\u0026#34; .ReadingTime \u0026#34;relpermalink\u0026#34; .RelPermalink \u0026#34;html\u0026#34; .Params.Description \u0026#34;title\u0026#34; .Title \u0026#34;type\u0026#34; .Type \u0026#34;url\u0026#34; .URL \u0026#34;weight\u0026#34; .Weight \u0026#34;wordcount\u0026#34; .WordCount \u0026#34;section\u0026#34; .Section \u0026#34;tags\u0026#34; .Params.Tags \u0026#34;categories\u0026#34; .Params.Categories \u0026#34;author\u0026#34; .Params.authors \u0026#34;content\u0026#34; .Params.Description \u0026#34;excerpt_html\u0026#34; .Params.Description \u0026#34;excerpt_text\u0026#34; .Params.Description \u0026#34;summary\u0026#34; .Summary)}} {{- end -}} {{- end -}} {{- end -}} {{- $.Scratch.Get \u0026#34;index\u0026#34; | jsonify -}} まとめ これで、ブログ内記事検索ができるようになります。 Algoliaは個人の非商用利用の場合、フリープランが用意されているのがありがたいですね。 まだ、Hugoと連携しただけで、Algolia自体でどんな機能があって、どんなことができそうかといったところは調べていませんが、簡単に利用できるのはとても助かります。\nまぁ、個人ブログの検索機能ってそんなに使う人はいないんですが、自分としては便利かなぁと。\n","date":1580186404,"dir":"post/2020/","id":"d9018f459d3c94a91e92b459e152f7e7","lang":"ja","lastmod":1580283604,"permalink":"https://blog.johtani.info/blog/2020/01/28/introduce-algolia/","publishdate":"2020-01-28T13:40:04+09:00","summary":"ブログ移行日記(その4)です。その他の記事はこちら。 ブログ移行日記(その1) ブログ移行日記(その2) ブログ移行日記(その3) ブログ移行日記(","tags":["ブログ"],"title":"ブログ移行日記(その4) - 検索機能(Algolia)の導入"},{"contents":"ブログ移行日記(その3)です。その他の記事はこちら。\nブログ移行日記(その1) ブログ移行日記(その2) ブログ移行日記(その4) ブログ移行日記(その5) 今回は、Hugoの設定とテーマの一部変更した点について記載します。\n設定ファイル(config.toml) Hugoの設定ファイルはconfig.tomlになります。hogo new siteコマンドで生成したディレクトリの中にデフォルトで含まれていますが、こちらではなく、テーマの作者が用意してくれたconfig.tomlを元に変更を加えました。\nちなみにテーマの作者の方が設定とコンテンツを含めたサンプルも公開してくれています。設定やディレクトリの構成はこちらを参考にしました。\n設定ファイルで変更した項目は以下のとおりです。\nサイトのタイトルや説明など 特記することはありません。好きなように変えました。\nbaseurl title SEOTitle description keyword slogan sidebar_about_descrption 画像関連(ヘッダーや著者近影) 画像の置き場はstatic/images/ディレクトリですが、設定ファイルには images/から設定します。\nheader_image : ブログのヘッダー背景 sidebar_avatar : 著者近影 言語周り(特に多言語対応する予定は無いのですが) languageCode = \u0026ldquo;ja\u0026rdquo; defaultContentLanguage = \u0026ldquo;ja\u0026rdquo; オフにした機能、削除した項目 freands = false bookmarks = false 上記の設定変更以外に、[[params.bookmark_link]]や[[params.friend_link]]も削除。\n中国のサービスや、特化した設定など。\nBaidu Analytics関連 Disqus proxy関連 Reward(wechat pay \u0026amp; alipay関連) params.social関連 rss = true twitter linkedin github ほかはすべてコメントアウト。\n外部サービス関連 disqusShortname : Disqusのショートネーム googleAnalytics : Gooogle AnalyticsのトラッキングID algolia関連 : 別のブログ記事として、設定方法などを書きます。 追加した設定(昨日のブログで説明済み) Octopressと同じ形のパーマリンク [permalinks] post = \u0026#34;/blog/:year/:month/:day/:slug\u0026#34; Markdownファイル中のHTMLタグ表示 [markup.goldmark.renderer] unsafe = true 以上が設定ファイル関連です。\nテーマの変更点 テーマそのままでは問題があったり、独自に変更したいという点があったので、いくつか変更をしています。\nフォントの変更 そのままテーマを適用するだけでうまく行けばよかったのですが、フォントの問題が発生しました。テーマの作者の方が中国の方だから?かどうかはわかりませんが、デフォルトのままだと中華フォントになってしまいました。\nあー、中華フォントだな。 pic.twitter.com/OvHpY4LSp1\n\u0026mdash; Jun Ohtani (@johtani) January 16, 2020 config.tomlにcustom_cssという設定があり、こちらで指定したCSSのファイルがテーマのlayouts/partials/head.htmlから読み込まれる仕組みがあるようなので、フォントに関するCSSをこの機能を使用して指定するようにしました。\nconfig.tomlの設定は次のとおりです(リスト)になっているので、複数のファイルに分割して、読み込ませることも可能なのかな?。\ncustom_css = [\u0026#34;css/custom-font.css\u0026#34;] cssファイルについては、static/css/custom-font.cssというファイルを作成し、次のような記載になっています。 フォントの指定と右側サイドバーの自己紹介の部分の文字色を変更するためのものです。\nbody, h1, h2, h3, h4, h5, h6, .navbar-custom { font-family: Helvetica,\u0026#34;Sawarabi Gothic\u0026#34;,Meiryo,\u0026#34;メイリオ\u0026#34;,\u0026#34;Hiragino Kaku Gothic ProN\u0026#34;, \u0026#34;ヒラギノ角ゴ ProN\u0026#34;,YuGothic,\u0026#34;游ゴシック\u0026#34;,Arial,sans-serif; } .sidebar-container { color: #404040; font-size: 14px; } faviconの変更 テーマにfavicon.icoが含まれていたのですが、せっかくなので独自のものに変えてみようかと。 ただ、残念ながら、こちらはパスおよびファイル名がlayouts/partials/head.htmlに直書きされていました。\n画像はimages配下にと思っていたのですが、このパスだけを変更するためにhead.htmlを自分の配下にコピーしてカスタマイズするのもどうかと思った(テーマに変更やバグ修正が入るたびに手動でコピーするのはなぁと思った)ので、static/img/favicon.icoファイルを作成しました。\nテーマよりもHugoのプロジェクトにあるファイルを優先するようなので、ファイルだけをプロジェクトに作成しました。\n記事一覧のテンプレート 記事の一覧で表示される、作成者と作成日時が英語表記でかつ、冗長な感じがしたので、スッキリさせるために、layouts/partials/post_list.htmlをテーマからコピーして、次のように変更しました。\n元の形式は : Posted by author Monday, January 2, 2006 現在の形式 : 2006-01-02 by author 記事のテンプレート 今回採用したテーマでは、記事の先頭に記事のセクションを元に目次を生成してくれるものでした。\n目次をコンテンツから自動で作ってくれるの便利だな。 pic.twitter.com/9bU3sLnUrm\n\u0026mdash; Jun Ohtani (@johtani) January 16, 2020 とても便利です。ただ、表示が「TOC」なんです。 英語でしかも「ToC」という表記ならまだ気にならなかったかもですが、大文字だと流石に気になったので、プロジェクトのlayouts/_default/single.htmlにコピーして「目次」という日本語に書き換えました。 このHTMLにテーマで修正が入った場合はどうしようかなぁ。。。というのが目下の悩みです。。。\nArchetypeテンプレートの追加 最後は新規記事を書くときに生成されるMarkdownのメタデータの追加です。 HugoにはArchetypesというのが存在します。\nHugoではhugo new 記事としたときに、記事の種類(content/ディレクトリ名=記事のタイプ)によって、作成するmarkdownファイルをテンプレートから生成する機能があります。この生成時に使われるのがarchetypesというディレクトリにあるファイルです。\n私のブログサイトでは、今のところcontent/postというブログの記事だけを書く予定ですので、archetypes/post.mdというファイルを作って以下のようなメタデータをhugo newしたときに自動で生成するようにしました(テーマにあったpost.mdファイルの代わり)。\n--- layout: post title: \u0026#34;{{ replace .Name \u0026#34;-\u0026#34; \u0026#34; \u0026#34; | title }}\u0026#34; slug: \u0026#34;{{ substr .Name 11 }}\u0026#34; author: johtani date: {{ .Date }} comments: true tags: [] draft: true --- タイトルはファイル名のハイフンを空白に変換したもの(実際にはファイル名は英語にしているので、使いませんが。。。) slugはファイル名の先頭からYYYY-MM-DD-という11文字を除いたもの。これは、OctopressのURLに合わせるために使用するURLの一部の文字列です。 author: johtani : 著者は私だけだから固定文字列 comments: true : ブログ記事にはDisqusのコメント機能を利用 tags: [] : 各内容によってタグを付けるが、生成時には空 draft: true : 明示的にこの行を消すまではドラフト記事としたいため という感じです。ほかにどのよなメタデータがあるのかまではまだ調べていないので、今後また適宜変更していくと思います。\nまとめ Hugoの設定や、テーマそのままではなく独自の変更を加えた部分を思い出して書き出してみました。\nこれで、Algoliaに関する部分以外はだいたい思い出して書いたと思います。 次は、Algoliaの使い方と設定について書き残す予定です。\n","date":1579853081,"dir":"post/2020/","id":"99c9c80a6532e4ea3b535c5a92d07a25","lang":"ja","lastmod":1579853081,"permalink":"https://blog.johtani.info/blog/2020/01/24/setting-hugo/","publishdate":"2020-01-24T17:04:41+09:00","summary":"ブログ移行日記(その3)です。その他の記事はこちら。 ブログ移行日記(その1) ブログ移行日記(その2) ブログ移行日記(その4) ブログ移行日記(","tags":["ブログ"],"title":"ブログ移行日記(その3) - Hugoの設定と微調整(テーマに合わせた)"},{"contents":"その他の記事はこちら\nブログ移行日記(その1) ブログ移行日記(その3) ブログ移行日記(その4) ブログ移行日記(その5) ブログ移行日記(その2)です。前回はHugoとは?というのと、自分が選んだテーマについて記載しました。 本家の手順などを参考にすると、Hugoにテーマを適用し、でHTMLを生成して、表示するところまでできるはずです。\n今回は、OctopressのmarkdownファイルをHugo用に変換する方法について紹介します。お手製ですが、Pythonスクリプトを作ったので、そちらも合わせて簡単に紹介する予定です。\n参考ブログ 「Octopress Hugo 移行」でググるといくつか出てきます。先人の知恵ありがたいですね。 ということで、私はこちらの2つのブログを参考にさせていただきました。ありがとうございます。\nOctopress から Hugo へ移行した - iriya-ufo\u0026rsquo;s blog OctopressからHugoへ移行する方法 | gam0022.net 画像のコピー 画像はそのまま上記参考ブログを元にsource/imagesからstatic/imagesにコピーしました。特にディレクトリ構造の変更とかもしませんでした。\nコンテンツのコピー こちらは、コピーのタイミングでいくつか変換などの処理を行いました。 ファイルの変換にはPythonのスクリプトを書きました。 自分向けの移行ツールなんで、ディレクトリ名とか引数にすらしてないです。。。\n参考ブログと同様の変換\nメタデータの日付変換 categoriesをtagsに変換 画像タグの変換 タイトル、画像のサイズなどに合わせていくつか分岐があります。 参考ブログとは異なる変換、変更\nコードブロックは無変換 0.60.0からCode Fencesに対応したみたいなので不要でした。 ディレクトリ構造の変更 ファイルを年ごとのディレクトリに格納(これまでは、全てのファイルが同一ディレクトリにあった) 拡張子の変更 (.markdown -\u0026gt; .md) メタデータにauthorの追加(自分しか書かないんですけどね) URLをOctopressに合わせる Google検索からの流入もあり、これまでのURLに変更はかけたくないなと。 こちらも参考ブログに記載があるので、そのまま参考にさせていただきました。\nslugについては、移行ツールでファイル名を元に追加する処理を書きました。\nHTMLを含んだMarkdownの対応 TweetやAmazonのアフィリエイトのリンクがHTMLタグでいくつかの記事に含まれており、デフォルトの設定だと表示されません。 config.tomlファイルに以下の設定を追記することで、出力されるようになりました。\n[markup.goldmark.renderer] unsafe = true 名前がunsafeなので、ちょっと気になりますが。。。 すべての記事を表示してチェックしてみたわけではないので、おかしな記事を見つけた方は連絡をいただけると助かります。\nまとめ OctopressのファイルをHugo用にコピーや変換した方法を思い出しながら書いてみました。基本的には参考ブログに上げた2つのブログを真似したものになります。\n次は、利用したテーマのサンプル設定を元に、自分用に変更した点などについて書き残しておこうかな?\n","date":1579775514,"dir":"post/2020/","id":"018b365b00dd3a6ad17c813d21590549","lang":"ja","lastmod":1579775514,"permalink":"https://blog.johtani.info/blog/2020/01/23/convert-md-from-octopress-to-hugo/","publishdate":"2020-01-23T19:31:54+09:00","summary":"その他の記事はこちら ブログ移行日記(その1) ブログ移行日記(その3) ブログ移行日記(その4) ブログ移行日記(その5) ブログ移行日記(その2)","tags":["ブログ"],"title":"ブログ移行日記(その2) - Markdownファイルの変換"},{"contents":"その他の記事はこちら\nブログ移行日記(その2) ブログ移行日記(その3) ブログ移行日記(その4) ブログ移行日記(その5) 起因 いつものツイートから始まる私の行動です。\n(もしかしたら前に一度おすすめしたかもですが) Goのtemplate構文に拒絶反応がなければHugo割と良いですよ〜。\n\u0026mdash; Nobuyuki Kubota (@nobu_k) October 10, 2019 ってことで、Hugo勧められたし、テーマが豊富だしということで、乗り換えた次第です。\n(元)同僚に教えてもらった記事を見てる。Gatsbyも気になるんだけど、デザインセンスないし、テーマが豊富なのがいいなぁ。/ Comparison of Gatsby vs Jekyll vs Hugo | GatsbyJS - https://t.co/yUbKiBmtMS\n\u0026mdash; Jun Ohtani (@johtani) January 9, 2020 一応Gatsbyのサイトにあった比較も見たのですが、テーマの豊富さが勝ちました。デザインを自分でやれるほどではないので。\n理由 乗り換えるに至ったのは主に2つの理由です。\nOctopressが更新されていない ページが増えてきてサイトの生成に時間がかかる 前に使っていたOctopressもJekyllというものがベースになっていました。 Jekyllは今でも更新があるのですが、Octopressが更新されなくなってしまったのと、Rubyがベースになっているため?なのかはわかりませんが、 ブログのページ数が増えてきて、サイトのビルドに時間がかかってくるようになりました。\n結果 まだ、改良点があるかもですが、とりあえず公開できる感じになったと思ったんで切り替えました。\n前のブログはこんな感じで、\n移行後はこんな感じです。\nHugoとは? 公式サイト こちらにあるように、Go言語で実装されているウェブサイト構築フレームワークです。 Go言語で実装されているのもあり、インストールが簡単でした。 Macを使っていますが、Homebrewでインストールができてしまいます。 他の方法もあるようでしたが、Emacsをインストールするのにbrewを入れているので、brewでインストールしました。\n使い方は色んな人が書いてるし、公式ドキュメントを見ていただけばいいかな。\nテーマとは? Hugoのサイトにテーマの一覧があります。 一応、個人のブログなので、それなりにデザインを入れつつ、他の人と違う感じにしたいなと。 テーマ一覧をざっと眺めて良さそうなのをピックアップしたら、最終的にこちらのテーマになりました。\nClean White それなりに更新されてますし、DisqusとSearch(Algolia)が使えるのでこのテーマに決めました。 テーマのインストール方法などはGitHubのREADMEの「Quick Start」に記載があります。\n私は、Hugo自体の設定などをGitHubで管理したかったので、git submoduleを利用して、次のような構成になりました。\nhugo - main repository ├── archetypes ├── content ├── data ├── layouts ├── public - github.com/johtani/johtani.github.io ├── resources ├── static └── themes └── hugo-theme-cleanwhite - github.com/zhaohuabing/hugo-theme-cleanwhite.git hugo : hugo new siteコマンドで作成されたディレクトリです。このディレクトリでまずgit initしました(このリポジトリはプライベートで管理してます)。 themes/hugo-theme-cleanwhite : テーマのQuick Startにあるgit submodule addコマンドでサブモジュールとしてテーマをインストールしました。 public : hugoが生成するHTMLのトップのディレクトリがこちらです。私はGitHub pagesを利用してブログを公開しているので、git submodule addでjohtani.github.ioをサブモジュールにしました。 Hugoで生成したHTMLなどをGitHub pagesで公開するときの手順などはHugoのドキュメントに記載がありました。\nまとめ Hugoに移行した理由や、Hugoとテーマの簡単な紹介でした。 テーマが豊富なのはデザイン力(りょく)がない身としてはありがたいですよね。 次はOctopressのmarkdownファイルをHugo用に変換したり、それに関する設定周りの話を書く予定です。\n","date":1579659814,"dir":"post/2020/","id":"a65bd31d4c3dab0a41712823a5d6002b","lang":"ja","lastmod":1579659814,"permalink":"https://blog.johtani.info/blog/2020/01/22/intro-hugo-and-theme/","publishdate":"2020-01-22T11:23:34+09:00","summary":"その他の記事はこちら ブログ移行日記(その2) ブログ移行日記(その3) ブログ移行日記(その4) ブログ移行日記(その5) 起因 いつものツイートから","tags":["ブログ"],"title":"ブログ移行日記(その1) - Hugoとテーマ"},{"contents":"5年くらい、Octopressを使用していましたが、更新されなくなっているのと、コンテンツの生成に時間がかかることもあり、 ほかのプラットフォームを使用するように変更しました。\nとりあえず、今回の移行で参考にした記事とかURLをリストアップしてみました。 詳細についてはまた明日以降で。\n参考記事 移行関連 : https://iriya-ufo.net/blog/2018/12/27/octopress-to-hugo/#github-pages- 移行関連 : https://gam0022.net/blog/2016/09/25/migrated-from-octopress-to-hugo/ Hugo自体の日本語紹介記事 : https://knowledge.sakura.ad.jp/22908/ Hugo概要 https://gohugo.io/ テーマ 一覧 : https://themes.gohugo.io/ 利用したテーマ : https://github.com/zhaohuabing/hugo-theme-cleanwhite データ移行 作ったスクリプト : https://github.com/johtani/from-octopress-to-hugo favicon 作ったサイト : http://emblemmatic.org/markmaker/#/ Algoliaセッティング 参考 : https://blog.uni-3.app/2019/01/02/hugo-algolia-search/ GitHub Pagesでの運用 https://gohugo.io/hosting-and-deployment/hosting-on-github/#types-of-github-pages 残タスク Amazonのアフィリンクをきれいに表示するlayoutか何かを用意する? ","date":1579166617,"dir":"post/2020/","id":"3c299a4d77be8b4f886ce9fcd23a2561","lang":"ja","lastmod":1579166617,"permalink":"https://blog.johtani.info/blog/2020/01/16/moving-to-hugo/","publishdate":"2020-01-16T18:23:37+09:00","summary":"5年くらい、Octopressを使用していましたが、更新されなくなっているのと、コンテンツの生成に時間がかかることもあり、 ほかのプラットフォ","tags":["hugo","ブログ","octopress"],"title":"OctopressからHugoへ移行中(まだ途中)"},{"contents":"今年も振り返りブログ書いてます。Sasukeがついてる。\n振り返り(2018年に書いた抱負から) まずは去年の抱負を元に。\nTOEIC 受けました。\nお。TOEICの点上がってた(まだまだだけど。。。)\n\u0026mdash; Jun Ohtani (@johtani) October 21, 2019 無事、上がってました。テストの点数を上げるのが目的ではなく、今の実力が どんな感じかというのを確認するために受けました。 前回までが低かったのもあるんですが。 また、数年後に受けてみるのかな?\nCfP見つけて応募 \u0026amp; いろんな場所に顔を出す 色んな所には顔を出しました。 CfPはそれほど出せていなく、とちぎRubyとDevRelJPで喋った程度かと。 12月に最終出社日を迎えたので、今後は顔を出したりCfP見つけて応募も、 一旦休憩に入る予定です。\nもっとブログ! 12月に入ってから、一気に増えてますねw Elasticでは結局それほどかけなかったなぁ。\nRustの継続 こっちは、書籍も買ったのに手がついてないです。 来年に書籍を読みながら再入門する予定です。\n開発の継続 一応ほそぼそと続けてますが、メンテナンスですね。 Analyzer向けのKibanaのプラグインのバージョンアップにだけ対応していたり。 年初にReact化には着手しました。 あとは、Luceneにちょっとしたパッチ(Lukeの画面とKuromojiのUniDic対応)を送った感じかな。もっとLucene周りやりたいかな。\n日本でエンジニア獲得! トレーナーやエンジニアが入社してくれました! が、私が退職してしまいますが。。。 私自体が次のステップに移らないとなぁと。 Elasticに興味がある人いたら、中の人を紹介できるので声をかけてください!\n振り返り(今年あったできごと) さて、ここからは今年の出来事を。\n検索技術勉強会発足 勉強会運営座談会 初フロリダ 初カナダ\u0026amp;初ナイアガラの滝 退職(予定) 検索技術勉強会ってのをはじめました(はじめましたブログはこちら)。 やっぱり検索の話を聞いたり考えたりするのが好きなので、もっといろんな話を聞く機会がほしいなぁと。ツイートすると何人かの知り合いが手を上げてくれたので、初めて見たのが2月でした。 所属会社もあったので、自分が全面に出ない形で運営に協力するという形式でやっています。なんだかんだでもう4回も開催できています。スピーカーへの声掛けなど、複数人で運営するとそのあたりが多様性が出るし、楽になるのですごくいいなぁと。 来年も2月か3月にやりたいねと話をしているところです。興味のある方は、ぜひスピーカーを!\nで、その流れで、他の勉強会の運営ってみんなどうしてるんだろう? という疑問も出てきたので、勉強会運営座談会なるものもやってみました。少人数で集まって、勉強会の運営ってどんなやり方してます?どんなことに困ってます?みたいなのを共有してみました。 自分自身がそれほど、ほかの勉強会の運営に顔を出してたわけでもなく、やり方をみんなはどうやって共有してるのかなぁ?というのが気になったので。 思った以上に属人化してるのかもなぁというのが感想でした。 ドタバタしてたので、あれからやってませんが、共有する勉強会みたいなのも面白いのかも?\n今年も2回ほどElasticの社内イベントで海外に行かせてもらいました。 5月にフロリダと11月にトロントでした。 フロリダでは、NASAにも行けたし、トロントでは足を伸ばしてナイアガラの滝を見に行くなどもしてみました。こういう機会が定期的にあるのは、いいですよねぇ。\n最後は、退職イベントですね。5年5ヶ月勤めたElasticでの仕事が、12/6で最終出社日でした。実際の退職日は1/24となっています(現在有給休暇消化中)。長かったような、短かったような。日本で1人目で入社してさまざまなことをやらせてもらい、本当に色んな経験ができました。英語も上達したし。 ただ、外にいることでできることがありそうだなと感じたこともあってのこの決断でした。\n最終出社日以降、色んな人とランチさせてもらったりしています。 次に何をやろうかな?ってのんびり考えながら休んでいるところなので。 やっぱり、検索周りのことをやりたいなぁというのが念頭にあるので、そのあたりで模索中という感じです。 が、せっかくの機会なので、少しのんびりしようかなとも思ってます。 なので、プラモデルの作成や配達業(デス・ストランディング)をやってみたり、16インチMacbookのセットアップしながらブログ書いたりしています。 年明けに入ったら、プログラミングもちょっとやりたいな。\nあとこの場を借りて、ブログの欲しい物リストのものを送っていただいた皆様に感謝を述べさせていただきます。本当にありがとうございました!この感謝はまた何かの機会にでも!\n来年の抱負 ということで、来年の抱負です。\n職につく ブログプラットフォームの移行 プログラミング Rust再入門 検索の勉強 検索技術勉強会の継続 まぁ、まずは職につかないとですね。どこかに在籍しつつ、副業で検索周りのこととかやるのもありかもなぁと考えたりしています(プラモデルつくりながらw)。\nブログのプラットフォームをOctopressからHugoあたりに移行しようかなと思ってます。Octopress自体がもう開発がされてないようですし。Hugoだとテンプレート?テーマ?がそれなりにありそうなので良さそうかなぁと。移行プログラムも書かないとかな。新しいものを調べるのって楽しいですよね。\nプログラミングも復活させたいなと。どうしてもこれまでは、しゃべるのをメインにしていたので、後回しにしてしまっていたのもあります。まぁ、向いてないのかもと思ったりもしますが、下手の横好きなりに少しずつでも何かを改善したり作ったりしたいなと。 勉強会の運営周りですこし楽をするためのプログラム書いたりもしているので、この辺もブログに書こうかな?\nRustはTantivyというプロダクトも出てきているし、勉強しようと思って、自転車本を買いつつ、Kindleの肥やしにしているので、手を動かそうとおもいます。 ブログ書いてサボった場合の可視化しないとなw\n検索の勉強もやりたいなと。これまではElasticsearchに注力していましたが、ほかのプロダクトやサービスも調べてみたいなと。教えを請いに皆さんのところにお邪魔するかもしれないので、そのときは優しくしてください。\n今年始めた検索技術勉強会を今後も継続できるようにしたいなと。 で、運営周りを楽にできるような仕組みをもう少し導入できればなぁと考えていきたいなと思います。\nさて、嵐の曲も始まったし終わりです。\n今年も様々な方々に助けていただきました。また、最終出社日以降にランチを一緒にさせていただいたり、遊びに行かせていただいたりとありがとうございました。年明けもひましてるので、ぜひランチしましょうw\n来年はなにやってるんだろうなぁ? 今後も皆さんよろしくおねがいします!!\n","date":1577764743,"dir":"post/2019/","id":"35aa9e09db936aee7ec407c431816573","lang":"ja","lastmod":1577764743,"permalink":"https://blog.johtani.info/blog/2019/12/31/looking-back-2019/","publishdate":"2019-12-31T12:59:03+09:00","summary":"今年も振り返りブログ書いてます。Sasukeがついてる。 振り返り(2018年に書いた抱負から) まずは去年の抱負を元に。 TOEIC 受けました。 お。TO","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2019)"},{"contents":"このブログ書こうと思って、これまでMacのセットアップしてたんだった。。。\n普段、macOSの標準ターミナルを使ってます。 で、ターミナルを使うシーンは次のような感じです。\nブログのデプロイ(参考:Octopress環境のDockerイメージ化) ElasticsearchとKibanaの動作確認 Elasticsearchの起動用ターミナル Kibanaの起動用ターミナル プラグインの開発(elasticsearch-ingest-csv と analyze_api_ui) elasticsearchのリポジトリ kibanaのリポジトリ ingest-csvのリポジトリ analyze_api_uiのリポジトリ 上記のように1.以外については複数のターミナルをそれぞれのディレクトリで起動して使っています。 これらの3つのパターンのときに、毎回ターミナル(シーンによっては複数のウィンドウ)を開いて、ディレクトリに移動って大変だなと。\nウィンドウグループって? そこで、ターミナルに便利な機能がないのかな?と思い、メニューを見ていたところ「ウィンドウグループ」というのがあったので調べて、現在の使い方に至っています。\nウィンドウグループの使い方の説明はこちらです。\n使い方にあるようにウィンドウの場所、設定、タブなどを保存できます。 そして、「ウィンドウグループを開く」というメニューから保存しておいたグループを開くと、簡単に作業環境が再現可能になります。\n開くときのメニューはこんな感じです。\n作り方 ウィンドウグループの使い方に載ってます。 まずは、保存したいターミナルを開いて、開いたときに移動していたいディレクトリに移動します。 複数のタブやウィンドウを開いた状態にしたい場合は、複数ターミナルを起動して、それぞれ移動したいディレクトリに移動しておきます。\nグループとしてまとめたいウィンドウが起動できたら、あとは、「ウィンドウ」メニューの「ウィンドウをグループとして保存」を選択します。\nこれだけです。あとは、使いたくなったときに開くだけです。 簡単ですよね?\n作るときの注意点としては、複数のウィンドウグループを作りたいときは、 それぞれグループごとに作成しては、個別にやる必要があります。 現在開いているターミナルのうち、あれとこれをウィンドウにしたいというやり方はできないので、そこだけ注意点です。 環境ごとにプロファイル(バックグラウンドの色やテーマ)を覚えさせることができるので、1.のシーンだとIceberg、2.のシーンではBasic、3.のシーンではHomevrewで設定していたりします。 (ただ、Preztoのテーマをagnosterにしてしまったので、Basicだとプロンプトが見にくくてしょうがないのですが。。。)\n設定はどんな感じ?? ウィンドウグループの管理については、ターミナルの「環境設定」に管理用の画面があります。\nこの画面でいらないグループを削除したり、設定のエクスポート/インポートも可能です。\n私の使い方 3つの利用シーンは説明しました。 すべてのウィンドウグループを変更するたびにインポート/エクスポートしてます。 上記1.と3.のユースケースはほぼ変更がないので、エクスポートしたものを移植用に管理していますが、2.のユースケースについては、頻繁に更新しています(ElasticsearchとKibanaのバージョンをアップしないといけないので)。\nこのとき、MacのGUIで毎回設定をしているわけではありません。 エクスポートしたファイルは、.terminalという名のXMLファイルになっています。\nその中に、次のようなパスが記述されています。このバージョン番号の部分をアップデートのたびにemacsなどで変更し、ターミナルの管理画面で、削除してからインポートし直すだけで、バージョンアップに対応している感じです。\n\u0026lt;key\u0026gt;Tab Working Directory URL\u0026lt;/key\u0026gt; \u0026lt;string\u0026gt;file://johtani-mac-15.local/Users/johtani/tmp/elastic_stack/v7.5/elasticsearch-7.5.1/\u0026lt;/string\u0026gt; \u0026lt;key\u0026gt;Tab Working Directory URL String\u0026lt;/key\u0026gt; \u0026lt;string\u0026gt;file://johtani-mac-15.local/Users/johtani/tmp/elastic_stack/v7.5/elasticsearch-7.5.1\u0026lt;/string\u0026gt; まとめ ということで、標準ターミナルのウィンドウグループを使うと、よく開くディレクトリやウィンドウ、タブを覚えて置かせることができるので、それぞれの環境向けのターミナルを、好きなときに開くことができるようになります。 私は、ウィンドウは1つで複数のタブをウィンドウグループという形で覚えさせておくことで、各シーンの切り替え、もしくは併用を閉じたり開いたりを簡単にできるようにしています。\n他のターミナルソフトを使うと似たようなことが簡単にできたりするのかな? みなさんがどうやってこのような作業やってるのかな?ってのはちょっと気になるところです。\n余談(いつものようにツイートとその反応) ちなみに、みんなどんなターミナル環境なんだろう?と思いツイートしてみた結果はこちらです。 (コメントRTってうまいことひろえないのかなぁ?)\nMac標準のターミナル使ってる人ってどのくらいいるんだろ?iTermとか入れてるのかな?tmuxとか?\n\u0026mdash; Jun Ohtani (@johtani) December 11, 2019 Iterm2使ってtmux使って今はIterm2だなー\ncommand2回押すだけでターミナル出すくせが抜けん https://t.co/P8o4M1HSoj\n\u0026mdash; GO☆ | TAFDATA (@_gogoponz) December 11, 2019 Alacritty + tmux やなー。標準はもう使ってない。 https://t.co/HI7hPCg3uo\n\u0026mdash; Ryo HIGASHIGAWA (@biwakonbu) December 11, 2019 標準です https://t.co/W27e2pcq3j\n\u0026mdash; shin higuchi @Acroquest (@shin0higuchi) December 11, 2019 Macを買って以来、ずっと結局標準ターミナル以外使っていない感じ。珍しかったのか。。 https://t.co/Zjz32SgjC6\n\u0026mdash; Kazuhiro Hara™ (@kara_d) December 11, 2019 ","date":1577063679,"dir":"post/2019/","id":"1a1a8cc0040b356d06eacd22e0526476","lang":"ja","lastmod":1577063679,"permalink":"https://blog.johtani.info/blog/2019/12/23/whats-window-group-of-terminal/","publishdate":"2019-12-23T10:14:39+09:00","summary":"このブログ書こうと思って、これまでMacのセットアップしてたんだった。。。 普段、macOSの標準ターミナルを使ってます。 で、ターミナルを使う","tags":["misc"],"title":"macOS標準のターミナルのウィンドウグループが便利"},{"contents":"ドットファイル系(.emacsとか)をこれまでは、PCを引っ越すたびにコピーしてたんですが、いいかげん、GitHubとかで管理したいなと。\nで、ツイートしたところ(こればっかりだなw)、homeshick(homesick)が便利だよとの情報を得たので使ってみました。\nhomesick、正確にいうとhomeshickを使ってます。悪くないです\n\u0026mdash; 🤓k.bigwheel🤓 (@k_bigwheel) December 10, 2019 使い方とか 実物はGitHubで公開されていました。\nhttps://github.com/andsens/homeshick\n何者かというと、ホームディレクトリにあるドットファイル(.zshrcなど)をgitコマンドで管理するのを楽にしてくれるシェルの関数群みたいです。 インストールは至ってかんたんで、git cloneで持ってくるだけです。homeshickのリポジトリのREADMEに記載があります。\n使い方はTutorialsにあります。\nhomeshick generate ほげほげで管理する単位(castle)を作ります。ほげほげが名称です。今回私はdotfilesにしました。 homeshick track ほげほげ .zshrcで管理したいファイルを指定します。すると、homeshickが対象のファイル(ここでは.zshrc)をcastleの保存先ディレクトリにコピーしてから、シンボリックリンクをホームディレクトリ上に作ってくれます。 homeshick cd ほげほげで、castleの実際のディレクトリに移動します。実態は.homeshick/repos/ほげほげです。 git remoteコマンドでcastleとGitHubの関連をつけて、あとは、普通にgitコマンドでコミットしたりすればOKです。 すごく簡単に導入できました。あとは、実際にtrackしたいファイルを追加していく感じです。 現状は、.zshrc、.gitconfigあたりを管理しています。 ついでに、homebrewでインストールしたものもbrew bundle dumpで出力して、homeshickで管理することで、brewでインストールしたものの管理もできそう(参考)。\nってことで、至極かんたんでした。すばらしい。\n参考 homeshick Tutorials Qiita : homeshickを使ったdotfilesの管理 ","date":1576624266,"dir":"post/2019/","id":"80c8fca02ebfecc7a931dad1ec38466e","lang":"ja","lastmod":1576624266,"permalink":"https://blog.johtani.info/blog/2019/12/18/introduce-homeshick/","publishdate":"2019-12-18T08:11:06+09:00","summary":"ドットファイル系(.emacsとか)をこれまでは、PCを引っ越すたびにコピーしてたんですが、いいかげん、GitHubとかで管理したいなと。 で","tags":["misc"],"title":"homeshick導入"},{"contents":"Macbook Proが新しくなり、OSがCatalinaになっちゃいました。 これまで使ってた、.bash_profileをコピーしてターミナルを立ち上げたところ、 なんか色々と設定が動いてないな?と思ったら、zshがデフォルトに切り替わってました。\nということで、デフォルト変わったし、時間あるしzshってどんな感じなのか調べてみようと。\n準備前(ツイート) で、ツイートをしたところ、海外の方?より返信が来ました。\nI have a series of posts explaining the transition: https://t.co/dz8QNjxxGf\n\u0026mdash; Scripting OS X (@scriptingosx) December 10, 2019 おもしろそうなので、ざっくりと読んでみました。zshを利用されているTwitterの知り合いの何人かからはzsh + oh-my-zshがいいよとコメント頂いてたんですが、\nMoving to zsh Catalinaからzshがデフォルトになるからと、手元の環境を変更するための話をブログにまとめてくれてます。\nMoving to zsh\nサラッと読んだので、いくつか抜粋すると\nbashでいくつか今設定しているものがあるのでその説明 alias - ファイルをそれぞれの拡張子ごとにアプリを切り替えてる(openコマンドの利用例があって参考になりました)。 functions - manコマンドのときに新しいWindowひらいたりとか shell settings - 大文字小文字関係なくファイル名をTabで候補を表示したり、historyをターミナル個別ではなく共有できるような設定にしたり prompt - 現在のディレクトリがどこかとか表示したり zshの設定ファイル群の説明 shellオプションの抜粋 といった感じでした(途中で読むのやめましたが。。。)\n面白かったのは、Suffix Aliasesです。 ファイル名だけをターミナルで指定すると、拡張子に応じて起動するコマンドを切り替えたりできると(結局まだ採用はしてないですがw)\n結局? 結局、上記ブログを読んでいろんなオプションあるんだなぁ。と思ったのですが、手っ取り早く試すためにPreztoをインストールしました。 以下のような構成になってます。\nなるほど、これがzsh + prezto + powerline fontか。前までgit-promptを拾ってきてbashに組み込んでたけど、ブランチ表示されるし便利だな。 pic.twitter.com/Z2ArBgRZey\n\u0026mdash; Jun Ohtani (@johtani) December 12, 2019 Mac標準ターミナル Iceberg プロファイル Powerline font Prezto agnoster theme - prompt agnoster or ~/.zpreztorc の変更 .zshrcにいくつかaliasなどを追加。参考:gist Preztoのデフォルトでlessなどからエディタを立ち上げるとnanoが起動したので、vimに変更 Preztoが作る設定と自分の設定を混ぜたくなかったので、.zshrcでinit.zshを呼び出し になりました。フォントサイズだけはちょっと大きくしました(老眼ェ。。。) ターミナルの参考にさせていただいたブログは「preztoでzsh構築した時のメモ 」です。\nターミナルソフト(余談?) terminalも人によっては、色んなものを使ってたなと思いツイートしました。 結構みなさん標準のterminalを使ってるみたいでした。ただ、私が聞いたこともないターミナルソフトもちらほらあったので、色々あるんだなぁと。\nMac標準のターミナル使ってる人ってどのくらいいるんだろ?iTermとか入れてるのかな?tmuxとか?\n\u0026mdash; Jun Ohtani (@johtani) December 11, 2019 ","date":1576542903,"dir":"post/2019/","id":"f3ef819656f68b87a91c53afbd441fec","lang":"ja","lastmod":1576542903,"permalink":"https://blog.johtani.info/blog/2019/12/17/move-to-zsh/","publishdate":"2019-12-17T09:35:03+09:00","summary":"Macbook Proが新しくなり、OSがCatalinaになっちゃいました。 これまで使ってた、.bash_profileをコピーしてターミナルを立ち上げ","tags":["misc"],"title":"zshへの移行"},{"contents":"最近使っていたPCが手元からなくなったので、16インチ Macbook Proをセットアップしているところです。 で、時間もあるのでこれまでほったらかしてきた、このブログの環境をちょっと変更しようかなと。\nまずは、変更するにしても、Octopressのブログの環境自体は必要です。 実際に、移行する前のこの記事自体も書いているわけですし。\nただ、今後なくなる環境をローカル環境にセットアップするのもどうかと思い、Docker環境にしてみました。\n参考 \u0026ldquo;Octopress Docker image\u0026quot;でググって出てきたサイトを参考にしました。\n参考ブログ:Octopress in a Docker Container\nセットアップからDockerイメージのビルドまで Docker for Mac自体もインストールしていなかったので、インストールしておきます。 参考ブログの方がGitHubのリポジトリにDockerfileをアップしてくれているので、手順に従い、cloneします。 cloneしたDockerfileの3行目にENV LC_ALL C.UTF-8を追加します(UTF-8でブログを書いており、previewした場合にエラーが出たため) 参考ブログにある「Build the docker image」の手順に従い、Gemfile、.gitconfigをコピーしてイメージをビルドします。 参考ブログの「Rakefile」にあるように、自分のoctopress/RakefileのProcess.spawn(...)にアドレスを追加します(Dockerコンテナの外からアクセスできるように) 自分のoctopressにあるGemfile.lockを削除しました(ビルドしたイメージにはいるGemと一部バージョンが異なる記載のものがあったため) ここまでで、\nDocker run 実際にコンテナを実行するためのスクリプトを書きました(書いたと言っても参考ブログにある起動コマンドを叩いてるだけですが。。。)\nlaunch-octopress-docker.shというファイル名で以下のコマンドを実行してるだけです。\n!/bin/sh docker run -p 4000:4000 --rm --volume /Users/johtani/projects/blog/octopress:/octopress --volume /Users/johtani/.ssh:/home/blogger/.ssh -ti blog/octopress /bin/bash このシェルを起動すると、Dockerコンテナにbashで接続し、/octopressディレクトリにログインしています。 あとは、いつものようにrake new_post[\u0026quot;....\u0026quot;]で新規記事のテンプレートを作成したりすればOKです。\nrake generate; rake previewと実行してからローカルのブラウザでhttp://localhost:4000に接続すればプレビューも可能。\nということで、このDockerファイルとかを持っておけば、他の環境でもかんたんにOctopressの環境が再現できそうです。 先人の知恵有り難し。 これで、クリーンなまま他のブログ環境に移行できそう。\n追記(2019/12/17) Docker環境でいくつか問題があったので、追記しておきます。\nDocker for Macが再起動しない Docker for MacがCatalina環境だと問題があるみたいでした。 CPUの数やメモリの数を変更してDockerを再起動したところ、ずっとStartingのまま。\n解決方法としては、launchctlの設定に$PATHを追加するみたい。これで、問題なく起動するようになった気がする\nsshの設定ファイルの問題 .ssh/configにMacのKeyChainを利用する設定を記載してるんですが、Ubuntu上だとこの設定のせいで、エラーが出てしまいます。 IgnoreUnknownという設定で、知らないオプションがあったら無視するという設定になる模様。ということで、Dockerコンテナ上でrake deployのときにエラーが出てたのが解消できました。\n","date":1576458061,"dir":"post/2019/","id":"1abc586d67f0b6c05fd5e60f25492340","lang":"ja","lastmod":1576458061,"permalink":"https://blog.johtani.info/blog/2019/12/16/dockernize-octopress/","publishdate":"2019-12-16T10:01:01+09:00","summary":"最近使っていたPCが手元からなくなったので、16インチ Macbook Proをセットアップしているところです。 で、時間もあるのでこれまでほったらかしてきた","tags":["octopress"],"title":"Octopress環境のDockerイメージ化"},{"contents":"本日、Elasticでの最終出社日でした。実際の退職日はまだ先ですが、有休消化という感じです。\n思い返せばもう5年と5ヶ月も前ですが、Elastic(当時はElasticsearchって社名だった)に参加しました。\n社名も変わりましたし、プロダクトの数も増えたし、IPOもしました。 初の外資+スタートアップということもあり、ものすごくエキサイティングな5年半でした。 Elasticを離れはしますが、検索自体にはまだまだ興味があるので、LuceneやElasticsearchになにかしら関わる感じのことをする予定です。 検索技術勉強会も今後もやっていきますし。\nただ、激動の5年半だったので、退職日までちょっとゆっくりしようと思っています。 次にどんなことをするのかはまた、別の機会にでも。\nおまけ ということで、まぁお約束です。\nほしい物リストはこちら\n","date":1575615090,"dir":"post/2019/","id":"1bbf2ef67f096960e13d8578fa544536","lang":"ja","lastmod":1575615090,"permalink":"https://blog.johtani.info/blog/2019/12/06/leaving-elastic/","publishdate":"2019-12-06T15:51:30+09:00","summary":"本日、Elasticでの最終出社日でした。実際の退職日はまだ先ですが、有休消化という感じです。 思い返せばもう5年と5ヶ月も前ですが、Elas","tags":["転職"],"title":"退職します"},{"contents":"これは、情報検索・検索エンジン Advent Calendar 2019 の 4 日目の記事です。\n1日目から、質の高いエントリーが続いていましたが、一旦休憩して頂く感じの記事になってます。気軽に読んでくださいw。Advent Calendarつくらないの?と煽ったのもあり、穴を埋めようかなと。 発端 ちょっと先ですがこういうのやります。実装寄りの話やOSS開発に興味がある方,きてください~ / Lucene 版 #Kuromoji のコードを読む会(辞書ビルダー編) https://t.co/NgEmUohoPo #kuromoji\n\u0026mdash; Tomoko Uchida (@moco_beta) September 6, 2019 「Lucene 版 #Kuromoji のコードを読む会(辞書ビルダー編)」という勉強会があり、参加したところ、UniDicの辞書のビルドがコケるという話を聞いたんで、ちょっとやってみるかと。\nちなみに、Kuromojiとは、Apache Luceneに入っている、日本語向けの形態素解析ライブラリです。IPAdicの辞書を内包しており、SolrやElasticsearchといった、Apache Luceneを利用している検索エンジンで手軽に使える形態素解析ライブラリになっています。が、対応している辞書がデフォルトだとIPAdicなのです。\n問題点 LUCENE-4056というIssueが上がっています。\nbuild.xmlには記載はないけど、辞書のビルダーは対応していそうな雰囲気を醸し出しているので、試してみたというのが発端?かと。で、実際に動かしてみると動かない点がありましたと。\nまた、Issueの会話で出ていたUniDicの辞書のライセンスの話もありました。 ただ、UniDicがライセンスを変更したので、このあたりはクリアできそうかなと。\nパッチ ということで、動かしてみていくつか修正してパッチを作りました。\nhttps://github.com/apache/lucene-solr/pull/935\n最近のLuceneはGitHubでプルリク遅れるのが便利ですね。 そんなに大したことはやってないです。以下の点が問題だったので直しています。\nIPAdicとUniDicで語彙定義ファイルのCSVの形式(カラムの数)が異なる unk.defのカラム数も異なる あとは、辞書のダウンロードの部分やbuild.xmlでの処理を追加した形です。 このプルリクを適用したlucene-solrのソースディレクトリを持ってきて、手元でjarをビルドすれば普通はIPAdicの辞書を内包したkuromojiのjarファイルが出来上がります。\nlucene/analysis/kuromoji/build.xmlファイルを、このGistにあるように変更して、ant build-dictとやれば辞書のビルドが可能です。 また、cd lucene/;ant jarとすれば、UniDicの辞書を内包したjarファイルもビルドできます(lucene/build/analysis/kuromojiの下にjarファイルができあがります)。\n確認? 一応、パッチは動くのですが、パッチ自体はUniDicの辞書をビルドする仕組みはオフのままです。なので、テストをどうやろう?というところでやなんで止まっています。。。\nただ、実際に作ったパッチできちんとIPAdicとUniDicがそれぞれビルドできているかの確認はしないとなと。\nということで、2つのjarファイルを読み込んで、それぞれトークナイズして、その出力を表示するツールを作ってみました。\n上記パッチを適用したlucene-solrのソースを持ってきて、IPAdicの辞書を内包したkuromojiのjarファイルと、UniDicの辞書を内包したjarファイルを用意し、ツールの支持に従って、ファイルをディレクトリに配置して、実行すれば以下のような出力がされるようになっています(とりあえず作ったものなので、Javaファイルにトークナイズしたいテキストを書かないといけないのですが)。\nたとえば、「自転車と自動車の違いはなんでしょう?」という文字列を入力すると、以下のような出力になりました。\n+++ ipadic ++++++++++++++ token[0] is [自転車] token[1] is [と] token[2] is [自動車] token[3] is [の] token[4] is [違い] token[5] is [は] token[6] is [なん] token[7] is [でしょ] token[8] is [う] +++ unidic ++++++++++++++ token[0] is [自転] token[1] is [車] token[2] is [と] token[3] is [自動] token[4] is [車] token[5] is [の] token[6] is [違い] token[7] is [は] token[8] is [なん] token[9] is [でしょう] UniDicは[短単位]で語彙が扱われるため、「自転車」や「自動車」がそれぞれ「自転」「車」、「自動」「車」という形でトークナイズされていることがわかります。\nどちらがより便利なのか?というのは用途によっても変わってくるかと思いますが、検索の転置インデックスとしては、より短い単語で区切られている方が、より多くの文書にヒットする可能性が高くなるので、便利な可能性が高いです。\nまとめ ということで、パッチを作ってみたものの、まだ取り込まれていない状況です。 着地点をどうするかって話かなと思っています。興味があれば遊んでみていただければと。\n将来的には、辞書をjarから切り離して別のディレクトリやjarとして使えるようにしようというIssueも作られています。こちらがすすめば、UniDicだけでなく、その他の辞書を切り替えながら使えるようになる日が来るのではないでしょうか?\n","date":1575385200,"dir":"post/2019/","id":"c2d39f2f7fe6cb69fc8efb6c5495c932","lang":"ja","lastmod":1575385200,"permalink":"https://blog.johtani.info/blog/2019/12/04/about-lucene-4056/","publishdate":"2019-12-04T00:00:00+09:00","summary":"これは、情報検索・検索エンジン Advent Calendar 2019 の 4 日目の記事です。 1日目から、質の高いエントリーが続いていましたが、一旦休憩して頂く感じの記事になって","tags":["Lucene"],"title":"Apache LuceneのKuromojiのUniDicビルド対応パッチについて"},{"contents":"Elastic stack (Elasticsearch) Advent Calendar 2019の1日目の記事になります。\nまだ、1ヶ月を残してますが、簡単に今年起こったことを振り返ってみようと思います。毎年恒例ですね、ここ数年。\nElastic Stack 6.6.0リリース(1月) リリース記事はこちら\nElastic APMが6.6のリリースと同時にElastic CloudでAPM Serverが無料で利用できるようになったのが地味に便利でした。APMのデモをやるために、それまでは手元にAPM Serverの起動が必要だったので。。。\nユーザーの方たちにはIndex Lifecycle Management(インデックスライフサイクル管理:ILM)がリリースされたのが便利だったと思います。 まだ、ベータでしたが、インデックスの世代管理を格段に便利にしてくれるツールになり、現在では必須アイテムとなっています。 もう一つ、地味に便利なのは、KibanaからElasticsearchへの接続を複数指定できるようになった点かと思います。\nElatic Common Schemaのベータリリース(2月) リリース記事はこちら\nElastic Stackではメトリック、APM、ログなど、様々なデータを一元的に可視化することができるという利点があります。ただ、一元的にデータを可視化、検索するためには異なるデータセットに統一されたフィールド名が欠かせません。そのための手段としてElasticが公開したのがElastic Common Schemaです。 各種データの項目名、型などを共通化する仕様をGitHub上で公開しています。最近のBeatsのモジュールはこのElastic Common Schemaに則ってデータが定義されるようになってきています。これにより、ログからメトリックへ、APMからログデータへというシームレスな移動ができるようになっています。\nElastic Stack 6.7.0リリース(3月) リリース記事はこちら\nElastic MapsやUptimeといった、これまでの可視化とは異なる便利なアプリが増え始めました。Mapsでは地図の表現が格段にアップしたので、コレまで以上に地理情報と合わせた可視化が楽しくなりました。\nもちろん、基本的に必要な技術が着実にGAされていくのもElastic Stackの素晴らしい点です。\nIndex Lifecycle Management(ILM)がGA Cross Cluster Replication(CCR)がGA CanvasがGA Logs \u0026amp; Infra UIがGA Elastic Stack 7.0.0リリース(4月) リリース記事はこちら\nメジャーバージョンのリリースです。 KibanaのUIが刷新されたり、Elasticsearchのクラスター管理の機能が新規に構築されたり、様々な改善がこのリリースでも入っています。また、メジャーバージョンのリリースのタイミングが、さまざまな大きな仕様の変更や改善が入るタイミングでもあります。これまで以上にパフォーマンスが改善(Top-Nクエリ高速化など)されたり、新しい機能の追加(ナノ秒のサポート)されたりしました。\nElasticsearchのセキュリティの主要な機能が無料に(5月) リリース記事はこちら\n6.8.0および7.1.0のリリースはこの機能の無償提供となりました。 結構衝撃的な話だったのではないかなぁと。これ以前は有償の機能だったセキュリティの以下の機能をElastic License配下で無料で提供する形に変わりました。まだ、ご存知でない方は、データの安全のためにもセキュリティ機能を利用することをおすすめします。\nTLSによる通信暗号化 ユーザー作成と管理にファイルおよびネイティブのレルム認証を使用可能 クラスターAPIとインデックスに対するユーザーアクセスの管理にロールベースのアクセス制御を使用可能、またSpaces機能でKibanaのマルチテナンシーの安全性を向上 Elastic{ON}19開催(5月) 今年も東京で開催しました。ビデオなどはこちらで公開されています。 https://www.elastic.co/elasticon/tour/2019/tokyo\n今回も偉そうにElatic Stackの新しくなった点を紹介するなどしてました。。。\nElastic Stack 7.2.0リリース(6月) リリース記事はこちら\nElastic SIEMがベータリリースされたのがこのタイミングです。 2月の発表したElastic Common Schemaをフルに活用していると言ってもいいのがこの機能になります。まだ今後もどんどん改善が入るであろうきのうになります。\nまた、Elasticsearchをバックエンドにした検索ミドルウェアとして利用いただけるElastic App Searchのセルフマネージド版もこのタイミングでリリースされています。\nさらに、このリリースの直前にはElastic Cloud on Kuberunetes(ECK)というものベータリリースされました。少しわかりにくいかもですが、ElasticsearchやKibanaをKubernetesのOperatorとして利用できるようになっています。こちらもElastic Licenseでリリースされているのでk8s上でKibanaやEsを管理しようとしている方は触ってみると面白いかもです。\nElastic Cloud Elasticsearch ServiceがGCP日本で利用可能に(7月) リリース記事はこちら\nElastic Cloudもプラットフォームが拡大した年でした。 Google Cloud Platformの東京リージョンを選択できるようになりました。さらなる統合(支払いをGCP経由にまとめたり、GCPのコンソールから利用できたりなど)も進んでいます。\nElastic Stack 7.3.0リリース(8月) リリース記事はこちら\nデータフレームと呼ばれるデータ取り込み時のピボット機能が導入されました。また、MapsのGAリリース、Elastic APMの.NETエージェント正式リリースなど、細かいですが様々なものがリリースされています。\nElastic Cloud Elasticsearch ServiceがAzureで利用可能に(9月) リリース記事はこちら\nMicrosoft Azureへのデプロイも可能になりました。残念ながらまだ日本リージョンには来ていないですが、今後出てくるはずです!さまざまなクラウドベンダーのサポートにより、より多くの人に使っていただけるようになるのかと。\nElastic Stack 7.4.0リリース(10月) リリース記事はこちら\nもう7.4.2まで出ていますが、いい感じの間隔で7.0、7.2、7.3と来ていますね。 7.4では、スナップショットリストアがKibanaから簡単に行えるようになりました。これまではKibanaのConsoleでJSONを見ながら管理されていたかもですが、GUIにより今どんなスナップショットがあるのか、どれをリストアするのかといった操作が簡単にできるようになっています。\nKibanaについてはPKI認証のサポートなども始まり、様々な認証方式でより便利にKibanaが使えるようになっています。\n12月? 12月ですし、Elasticsearch勉強会では「LT&忘年会」ということで、懇親会がメインの勉強会として12/6に開催します。悪路クエストの緑川さん、吉岡さんに主体となっていただき、マイクロソフトさんを会場に借りて開催予定です。興味のある方はぜひご参加ください。 LTもおまちしています!\nまとめ 駆け足でしたが今年を振り返ってみました。 今年も色々ありました。残すところあと1ヶ月です!\nさて、Elastic Stack Advent Calendar 2019は今日から25日まで続きます。今年はその2もできています!こらからの記事を楽しみにしています! 本日はその2で[kaibadash@github]さんが「5分でできるElastic stack環境構築」というのを書いてくれてるはずです!\nということで、次はKunihikoKidoさんの「 Elastic Cloud を使うようになって設計方針やら変わったことについて書きます。」になります。お楽しみに!\n","date":1575126000,"dir":"post/2019/","id":"78da47d61c91c82809a3c97a791d26d2","lang":"ja","lastmod":1575126000,"permalink":"https://blog.johtani.info/blog/2019/12/01/whats-happen-at-elastic-in-2019/","publishdate":"2019-12-01T00:00:00+09:00","summary":"Elastic stack (Elasticsearch) Advent Calendar 2019の1日目の記事になります。 まだ、1ヶ月を残してますが、簡単に今年起こったことを振り返ってみようと思います。毎年恒例ですね、","tags":["elasticsearch"],"title":"2019年のElastic StackとElastic"},{"contents":"Bonfire Data \u0026amp; Science #1にブログ枠で参加してきました。 ということで、メモです。\n日時 : 2019/10/25 19:00 - 21:30 場所 : Yahoo! Japan サイト : https://yj-meetup.connpass.com/event/148121/ ハッシュタグ: #yjbonfire 概要 Data \u0026amp; Scienceとは? データとサイエンスに関わる人達の情報共有のための勉強会/交流会\nサイトから引用です。\n第1回のテーマは「画像検索」です! 最近EC系のサイトで類似画像検索が出来るようになったけどどうやってるの? 画像検索のモデルってどうしてるの? 画像検索のインフラはどうしてるの? 私たちの会社でも画像検索を用いたサービスを構築できるだろうか? こういった疑問に答えたり、いま抱えている悩みを解決するヒントを得る場になればと思っています。 今回は、画像検索を行なっているヤフー, メルカリ, ZOZOテクノロジーズの3社に事例と基盤技術について登壇いただきます。 QAはこちら。https://app.sli.do/event/w3wayjmv/live/questions\nMercari画像検索について(仮) 発表者:荒瀬晃介(株式会社メルカリ / AIエンジニアリングチーム)\nAIエンジニアチーム\n写真検索プロジェクトのTech Lead\niOSのみで提供の写真検索\nシステムオーバービュー\nMobileNet v2で特徴抽出 ANNのインデックスを使ってDBに入れる 論文も発表済み(3本)\n今日の発表はこの内の2本を元に話をします。 C2Cでの問題点 商品は床やテーブル上で撮影 クエリは着用(着ている)画像が使われやすい。 人が写ってる写真が結果に多いと業者が出展しているように見えてしまう。 提案手法 人が写ってるものから人の代表ベクトルを抜き取る (クエリ時にのみ処理を実施しているので変更が容易) 特徴変換ベクトル トップスなど、分類ごとに学習させてからベクトルを構成 なんでMobileNet v2? エッジデバイスでの処理を見据えて選択 インフラ Docker + k8s\nCRDを使ってる?\ntraining\nコンテナベースパイプライン いくつかのバッチ処理を工程ごとにパイプライン化 バッチ実行情報をカスタムリソースとしている=再実行が簡単(復旧作業が容易) 画像を扱う=ダウンロードが時間がかかる -\u0026gt; 復旧しやすいようにPVにある程度キャッシュさせている Serving\u0026hellip;\nGCP側 なぜ2つに別れてるんだろう?実際のサービスも2つに分かれてたりするんだろうか?\n将来の展望 Realtime Image Search カメラでものを写している状態でそれが何かを検索できる。 物体検出+特徴抽出をエッジで行うためできる エッジの性能により違いが出てきたりするっぽい QA Q: 業者が想定されると、購入意欲を下げるというのは実験した結果?それとも想像? A: 実験はしていないが、e-commerceにおいての研究がある Q: どういう理由でマルチクラウドにしたんでしょう? A: 画像のマスターがAWS。メルカリのマイクロサービスはGKEなので、サービング環境がGCP Q: 画像の内、服のエリアが大部分で体の面積が少ない場合と、メガネや帽子のように、アイテムの方の面積が少ない場合で、トレーニングに必要なデータ数は変わりましたか? A: カテゴリによる性質の違うはある。ので、改善は必要。 ZOZO画像検索について(仮) 発表者:平田拓也(株式会社ZOZO / AIエンジニアリングチーム)\n(聞き逃した。。。)\nWEAR\nマルチサイズ\nチーム構成 研究所+ML Opsチーム 使用しているアルゴリズム 物体検出アルゴリズム 特徴量抽出アルゴリズム 近似最近傍探索(approximate nearest neighbor, ANN) インフラ GCPを採用。 BigQuery上にデータ基盤がある Managed GPUが必要 なんでk8s? コンテナ Cloud Runがなかった アーキテクチャ マイクロサービス化されている Google Cloud Next 2019 Tokyoでsonotsさんの発表があるよ 監視項目 CPUなどは見ていない レスポンスタイムとステータス監視 リクエスト数 APM 使ってるものStackdriver + Datadog + Sentry Warningが30分で続けたら通知などができるのがStackdriver 画像検索の改善のためにやっていること 課題 レイテンシーが大きい 推論が大変? 急激なトラフィックの増加に対応できない GPUのスケールアウトが問題 -\u0026gt; 先行投資が必要 流れ キャッシュありなし 物体検出 (GPU) 特徴量抽出 (GPU) 近似最近傍探索 DBから取得 2と3が問題\n2と3を特徴量DBという形でデータが登録された時点で特徴量などを計算してしまうことでGPUへの依存をなくした。 Apache AirFlowが便利? Cloud ComposerとApache AirFlow Cloud Composerに関するいくつかのTipsがありました。\nQA Q: 推論をCPUでやったらどれぐらい遅いんだろう A: GPUインスタンス代金 \u0026lt; それと同等の速度を出すためのCPUインスタンス代金 Q: k8sスケールアウト時のリソース割当を最適化する為、resource limit / request標準化 or 時系列分析などから自動調整するなどはされていますか? A: \u0026hellip;聞き逃した Q: (TCOを考慮したクラスタ構成) Cloud Composerの値段が高いようなパプリッククラウド利用の課題対策としてプライベートクラウドとのハイブリッド構成にされているのでしょうか?もしハイブリッド構成でしたら、パブリック or クラウドを切り分ける基準はございますか。 A: GKEオンリー Q: cloud composerでairflowを使う辛い点は? A: 不安定さ。。。 Yahoo!ショッピングにおける画像検索(仮) 発表者:佐藤 純一(ヤフー株式会社) 商品検索APIの開発とか検索エンジンの保守とか 類似画像検索システムの開発が直近の仕事 類似画像検索 ヤフーショッピング 3億の商品 ファッション系はビジュアルが重要=言語による表現が難しい iOSとAndroid Androidだとカメラで撮影してから検索みたいなことも可能 システム概要 物体検出 ノイズ除去 特徴抽出 インデックス(NGT) -\u0026gt; https://github.com/yahoojapan/NGT 1000万件を超える 検索 アプリの画像をAPIに投げてベクトルから、近いものn件を取得 ベクトル化/インデックス更新 GPUマシン Kafka使ってる クラウドストレージに日次?バックアップみたいに保存 差分更新の仕組みがある メンズとレディースは分けている 絞り込み検索のために分離(インデックスのメタデータとしてタグがある) システム構成 Python Kafka TensolflowServing 可視化?監視?はGrafana+Prometheus 開発を通しての学び 自動デプロイとかテスト 検索精度の確認ツールを作る コレ重要だよね。何が変更してるかとか、何が正しいかってのが必要だし。。。 復旧可能、早期復旧の仕組みを容易 今後の方針 対象商品の拡大 物体検出特徴抽出モデルの性能改善 NGTの検索システムをValdに移行 Vald k8s上で動作、分散検索、分散インデキシングなどの機能を提供予定 QA Q: iOS(既存の画像)とAndroid(カメラで撮る)で画像検索の方式が違うのはなぜ? A: アプリの違い Q: 1枚の写真に沢山写っている中で、対象の商品をどう識別しているんでしょう。靴もトップスもボトムスも写っていたら、かなり難しそう A: Yahooブラウザの場合は1番大きな領域のものを選択。Yahoo shoppingだと選択可能 NGTについて(仮) 発表者:岩崎 雅二郎(ヤフー株式会社) 類似画像検索を20年くらいやってる 近傍検索ライブラリ https://github.com/yahoojapan/NGT\n高次元ベクトルの近傍検索 ツリーとグラフによるインデックス 近傍検索とは?\n距離空間上でのクエリの近傍のオブジェクトを取得 k最近傍検索(通常はこっち) 範囲検索(あんまり使われない) NGTの特徴\n世界トップレベルの高速高精度な近似近傍検索 OSS 追加削除が可能(削除がとくに難しいらしい) 多様な利用形態(Python、C++、C、Go、コマンドライン) サーバ版NGT(ngtd、vald)を提供 共有メモリ版でメモリサイズ以上のデータ登録可能 量子化版NGT(NGTQ)により。。。 ANNベンチマークによりテスト\n実行環境が決められているらしい。誰が実行しても比較可能 グラフベースの検索の仕組みのほうが性能がいいというのがベンチマーク結果からわかる なんではやいの? インデックス生成 ツリー(グラフの探索起点の取得に利用する。DVP-tree) グラフ(ANNG) ノードを逐次追加しつつ、近傍ノードを検索してから接続するというのを繰り返している 検索 ツリーから絞り込みつつ、グラフを検索する ANNGに課題があるのでONNG(Optimized Nearest Neighbors Graph)に ノード単位の次数(入出)を最適化 データセットによって有効な次数が違う。。。 NGTを利用した深層学習で。。。 Yahoo!ラボ FavNavi 特徴量の構成(低次特徴量(300次元)、カテゴリ特徴量(128次元)、領域アスペクト比(1次元)) 個別の特徴量だけだとイマイチな結果になるが、組み合わせるといい感じになる モデル性西洋学習データ スライドがあればいいなぁ(表書くの大変だし。。。)\nQA Q: 実際のお客さまの利用を考えると、近似近隣の密度が異なるので、近いものばかりの検索結果や遠いものも含んでしまった検索結果が出ると思うのですが、遠いものが含まれてしまうと、閾値でフィルタしたりするのでしょうか? A: NGTは近いものしかないので、外れ値ってなんでしょう。。。 検索のフィルタリングをある程度している(カテゴリとか)。 まとめ 慣れない分野の話を聞きながらざっとメモを取ったものなので役に立つかはわかりませんが。。。\nアルゴリズムとかまでは得意ではないんですが、画像「検索」ということで参加してみました。 実際に画像検索の仕組みがどんな感じでできているのか、どんな技術がつかわれているのか?ってのがわかったのは 面白かったです。確かに検索のためのキーワードって出てこないことあるしなぁと。 あー、こんなかばんほしいとか、これなんだろ?みたいなのあるからなぁ。\n","date":1572000002,"dir":"post/2019/","id":"11b3a28b536f34d3606427f835bd3ddf","lang":"ja","lastmod":1572000002,"permalink":"https://blog.johtani.info/blog/2019/10/25/bonefire-01/","publishdate":"2019-10-25T19:40:02+09:00","summary":"Bonfire Data \u0026amp; Science #1にブログ枠で参加してきました。 ということで、メモです。 日時 : 2019/10/25 19:00 - 21:30 場所 : Yahoo! Japan サイト : https://yj-meetup.connpass.com/event/148121/ ハッシュタグ: #yjbonfire 概要 Data \u0026amp; Scienceと","tags":["勉強会"],"title":"Bonfire Data \u0026 Science #1に参加しました"},{"contents":"この間のElasticsearch勉強会でAcroquest Technologyの人たちが技術書展7で販売されていた書籍を頂いてしまいました。なので、軽く読んでの感想と宣伝です(これ、電子版とかで買えないのかな?)。\nElasticのパートナーとしても活躍していただいてますが、こういう感じでさまざまなところでElastic Stackを広めていただいていて感謝しかありません。\n章立てとしては以下の通りです。\nElasticsearchでエンタープライズサーチを実現する 同僚が作成、メンテナンスしているFSCrawlerを使った例も書かれています。ローカルのファイル(PDFやJSONとか)をサクッとElasticsearchにインストールしたりするのには便利です。 Kibana Canvasによる柔軟な可視化 Canvasについてどんなものなのか?というのとelasticcofeeというサンプルを元に、その変更の仕方などが説明されています。 Elastic APMによるアプリケーションパフォーマンス監視 Go AgentとAPM自体の使い方の説明です。最近強化されている他の機能との連携(AlertingやMachine Learning)についても触れてくれています。 Kubernetesクラスタのメトリクス・ログ・性能情報の可視化 Azure上でAzure Kubernetes Serviceの上で動いているアプリなどをBeats、APMでデータを取りつつ、他のAzure上にAzure Marketplaceのテンプレートを用いて起動したElasticsearchとKibanaの環境を用いて可視化する方法が説明されています。 ということで、薄い本ですが、手順をおって説明されていたり、7.3と新しいバージョンで書かれているのですばらしいなぁと。 前作の「Elasticsearch NEXT STEP」に引き続きインプレスさんから出たりするのかなぁ?\nちなみに、Elastic APMのRubyに関して興味がある方は、私が前に発表したときの資料がありますので、こちらを参考にしてみてください。\n","date":1570690589,"dir":"post/2019/","id":"d8041ae308961666b15aa1e57b0f9f35","lang":"ja","lastmod":1570690589,"permalink":"https://blog.johtani.info/blog/2019/10/10/review-es-next-step-2/","publishdate":"2019-10-10T15:56:29+09:00","summary":"この間のElasticsearch勉強会でAcroquest Technologyの人たちが技術書展7で販売されていた書籍を頂いてしまいました","tags":["書籍"],"title":"Elasticsearch NEXT STEP 2を頂きました"},{"contents":"Twitterで「Meetup.comに切り替えたらー」みたいな話があったので、 受付用アプリとかなくてという話になったので、普段Elasticsearch勉強会で使用している QRコード生成の仕組みを紹介してみようかと。\nHTMLだけで済むようにQRコードを生成するjquery.qrcode.min.jsってのを使用してます。\nHTMLコードはこちら。\n仕組み 1枚だけのHTMLを生成 MeetupのOAuth2の仕組みを利用(consumer keyを発行する必要あり。) Meetup APIを利用してユーザー情報取得 取得したユーザー情報をGoogle Formに埋め込んだ形で表示するURLを組み立てる 組み立てたURLをQRコードにしてHTMLに表示 受付で、QRコードリーダーを使って、QRコードを読み込むとGoogle Formが開くので、「送信」ボタンを押す 1. HTMLの作成 QRコードを表示するためのHTMLを作成します。Gistに貼り付けてあるので、参考にしてもらえれば。 いくつか埋め込まないといけないものがあるので、個別にそれは説明します。\n2. Google Formの準備 Elasticsearch勉強会では、出席者の情報として、IDと氏名をリストとして保存しています。 目的としては、何人実際に参加したかを計測するのが目的です。 ですので、参加者リストのGoogle Formを作成します。 で、作成した後に、プレビューを表示する。こんな感じ。\nこの時のプレビューのURLをQRコードのURLとして使いたいので、このURLをQRコード表示のHTMLに埋め込みます。\nfunction createGoogleFormURL(data) { var obj = { \u0026#34;entry.1744035444\u0026#34; : data.id, \u0026#34;entry.2031666715\u0026#34; : data.name }; return \u0026#34;https://docs.google.com/forms/d/e/\u0026lt;GOOGLE_FORM_ID\u0026gt;/viewform?\u0026#34; + $.param(obj); } ここら辺です。 returnに書いてあるhttpsで始まる文字列をまず、先ほどのURLで置き換えます。 次に、プレビューのHTMLの中から\u0026lt;input\u0026gt;タグを探して、nameの値を抜き出します。 それをobjのキーに利用します。entry.で始まる文字列が該当します。\nこれで、このURLをQRコードにすれば、値(ここだとIDと氏名)が埋め込まれた形のGoogle Formがスマホのブラウザで起動します。\n3. Meetup APIの準備 MeetupのAPIを利用できるようにします。Meetup.comにログインするとみれるAPIのページがあります。 https://secure.meetup.com/meetup_api\nまず、OAuthを利用するためのConsumer Keyを発行します。\nメニューのOAuth Consumersをクリックして、\n\u0026ldquo;Create New Consumer\u0026quot;をクリックします。 すると、次のような画面が開きます。\nConsumer nameとRedirect URIが重要です。\nConsumer nameはユーザーがMeetup経由で認証するときに、その認証画面で表示される名前になります。 わかりやすい名前を表示してあげると良いかと。\nRedirect URIが一番重要です。実際にOAuthで認証が通った後に表示するHTMLを提供しているURLを指定します。 Elasticsearch勉強会の場合は、私のドメインにwwwをつけた\u0026quot;https://www.johtani.info\u0026quot;を指定しています。 実際にQRコード表示用のHTMLを配置するHTTPサーバーのトップのURLを指定します。 (ちなみに、私のウェブサーバーはS3で運用してます。ですので、HTMLをS3のバケットにアップロードしてあるだけです)\n必須項目を入力したあと、最下部にあるRegister Consumerボタンを押せばキーが生成されます。 生成されたキーがOAuth2のURLのパラメータに必要になります。\nこれで、リダイレクトの準備が整いました。\nOAuth2のURLには、Implicit Flowを利用します。 これで、リダイレクト先のHTMLにトークンがわたるので、Meetup APIにこのトークンが使えるようになります。\n認証用のURLはこちらです。このURLを参加者宛のメールに入れて毎回送信しています。\nhttps://secure.meetup.com/ja-JP/oauth2/authorize?response_type=token\u0026amp;redirect_uri=\u0026lt;QRコード表示HTMLのURL\u0026gt;\u0026amp;client_id=\u0026lt;コンシューマーキー\u0026gt; 参加者はこのリンクをクリックすることで、次のような画面が出てきます。 ログインしていない場合はLog in画面が表示され、まずはログインを促されます。\nで、Allowをクリックすれば、redirect_uriに指定されているページが表示されるわけです。\nQRコード表示用のHTMLでは、次のAPIを使用して、ログインしているユーザーの情報を取得してきています。\nfunction getMemberId() { $.getJSON(\u0026#39;https://api.meetup.com/2/member/self/?only=id,name\u0026amp;access_token=\u0026#39;+ getToken(), displayQRCode); } ここで取れた値が、先ほどの「2. Google Formの準備」で説明したコードのdataの部分に渡ってくるわけです。\nfunction createGoogleFormURL(data) { var obj = { \u0026#34;entry.1744035444\u0026#34; : data.id, \u0026#34;entry.2031666715\u0026#34; : data.name }; return \u0026#34;https://docs.google.com/forms/d/e/\u0026lt;GOOGLE_FORM_ID\u0026gt;/viewform?\u0026#34; + $.param(obj); } 4. QRコードの表示 あとは、jquery.qrcode.min.jsを使用してURLを表示するだけです。\nfunction displayQRCode(data) { $(\u0026#39;#qrcode\u0026#39;).qrcode({width: 128,height: 128, text:createGoogleFormURL(data)}); } サイズとURLを指定するだけですね。\nまとめ あとは、受付で、参加者の方が表示してくれたQRコードをスマホのQRコードリーダーやカメラで読み込めばGoogle Formが開いて必要な情報は入っているので、「送信ボタン」を押せば参加者リストが出来上がっていくという形になります。\n毎回勉強会の前日に、前回のGoogle Formを「コピー」してから、各回の勉強会の登録者フォームを作成しています。 コピーすることにより、Google Formの\u0026lt;input\u0026gt;タグに使用されるnameもそのままコピーされるので、 QRコード生成用のHTMLを書き換える部分の手間が減る形になっています(気づくまで数回かかったw)。\nですので、QRコードのHTMLの中身としては、「勉強会のページへのリンク」、「Google Formへのリンク」の2つを書き換えてから毎回アップロードしているだけとなっています。\nこのやり方が、スマートかどうかはわからないですが、受付アプリがない中、Meetup.comから取得した参加者リストのExcelやプリントアウトしたリストを元に参加者をチェックするよりは、手間が省けてるんじゃないかなぁと。\n残念ながら、QRコードの存在を知らないでそのまま勉強会にくる人がいるので、受付で最低一人はMeetup.comの参加者リストから、 名前を検索してチェックするという作業もやってもらってます。 QRコードを持ってきた方がすんなり受付を通過できるようになってますので、ぜひQRコードを持って勉強会にきてもらえればと。\n","date":1560939044,"dir":"post/2019/","id":"d96f80f23543850a2ee9fff8cd2cc53f","lang":"ja","lastmod":1560939044,"permalink":"https://blog.johtani.info/blog/2019/06/19/qr-code-with-meetup-dot-com/","publishdate":"2019-06-19T19:10:44+09:00","summary":"Twitterで「Meetup.comに切り替えたらー」みたいな話があったので、 受付用アプリとかなくてという話になったので、普段Elasti","tags":["勉強会"],"title":"勉強会の受付自作?アプリ?HTMLについて"},{"contents":"Elasticsearch勉強会や検索技術勉強会やってるんだけど、独学で勉強会やってるなーと思い、みんなはどうやってるんだろうとツイートしてみたところ。\nあー、勉強会運営座談会したい。\n\u0026mdash; Jun Ohtani (@johtani) 2019年4月2日 面白そう\n\u0026mdash; 機械の体を手に入れるのよ鉄郎 (@tetsuroito) 2019年4月2日 やってみるか。\n\u0026mdash; Jun Ohtani (@johtani) 2019年4月2日 やりましょう\n\u0026mdash; 機械の体を手に入れるのよ鉄郎 (@tetsuroito) 2019年4月2日 ってことで、何人か釣れたので、勉強会運営座談会をやってみました。 会場提供していただいた、Classiさんありがとうございました!\n参加してくれた人たちはまぁ、勉強会のサイトを見ていただければなんとなくわかるかなと。 自己紹介とどんな勉強会、読書会運営してますってとこから始めて、次のようなトピックについてピザ食いながら3時間くらい話しました。\nスピーカーの募集方法 運営側から声かけてる?それとも公募してる? 登壇時間とかどうしてる? スピーカーになってもらうためになんかやってる? スケジュール管理 会場探し、スピーカー探し、イベントページ作るタイミングは? 複数拠点開催したことある? ハンズオンとかはどうしてる? 土日開催?平日開催? アンケートとってますか? 使用してるイベントサイトは? ドタキャン対応どうしてる?出欠とったりしてる?懇親会の規模とかどうやって見積もってる? 運営費用関連はどうしてる? グッズとか、ツールとか、スピーカーへの謝礼とか 運営って複数でやってる? その時のツールは? 運営メンバーにはどうやってなってもらう? 録画配信とかまで手が回る? 会場探すの大変じゃない? 会場の部屋の使い方はどうしてる? 行動規範とかどうしてる? 読書会の場合に人が減ってったりしない? まぁ、こんな感じです。色々話してメモしてたんですが、まぁトピックくらいで。\nそもそもは、勉強会の運営って本業ではない(はずな)ので、いかに楽をしつつうまく運営できるかってのを知りたいのと、 他の人どうやってるかってのからアイデアもらえるといいなーと思ったんでやってみました。 他のツールがどんなものかとか知れたし、あー、そういうやり方すればいいのねーみたいなのも知れたので、次回以降の勉強会に活かせればなーと。 自分がやってるやり方とかもブログ書くといいのかなぁ?\n残念です!次回もやるかもしれないので、 @johtani さんに期待してください!\n\u0026mdash; 機械の体を手に入れるのよ鉄郎 (@tetsuroito) 2019年4月25日 次回やるのかなぁ?興味ある人いるのかなぁ?\n","date":1556204526,"dir":"post/2019/","id":"538e38fbc3f78cd61e1841d8141ddcc1","lang":"ja","lastmod":1556204526,"permalink":"https://blog.johtani.info/blog/2019/04/26/meetup-organizer-drinkup/","publishdate":"2019-04-26T00:02:06+09:00","summary":"Elasticsearch勉強会や検索技術勉強会やってるんだけど、独学で勉強会やってるなーと思い、みんなはどうやってるんだろうとツイートして","tags":["勉強会"],"title":"勉強会運営座談会ってのをやってみた"},{"contents":"どーも、johtaniです。\nSearch Engineering Tech Talkという勉強会に運営として参加して、第1回の勉強会を開始しました。 本日(2/26)は第1回目だったので、ブログを残しておこうかと。\n勉強会自体の資料については第1回の勉強会のページにあるし、勉強会の感想とかブログはツイートやみんながブログを書いてくれると思うので、勉強会開催の経緯などについてブログを残しておこうかと。\nなんで始めたの? 私自身が古くはFAST Searchに始まり、何か縁があって、 検索のシステムに長く携わってきたこと(Apache Solrの本書いたり、Elasticsearch勉強会始めたり)もあり、 検索が面白いなと日々思ってます(思ってるだけかもしれないが)。\nで、これまでElasticsearch勉強会をやっているのですが、検索エンジン固有の話ではない、 いわゆる検索の共通の課題というのがあるなぁと。 そういう課題やノウハウって、製品に限らず共有できれば面白いことがもっとできるんじゃないだろうか? と感じることが多々ありまして。 オープンソースのコミュニティをソースコードをベースではなく、共通の課題・話題を中心としたコミュニティが あってもいいんじゃないかなぁと。\nまぁ、要は、私がみんなの検索で困ってることとか、どうやって検索システム考えてるのかが聞きたかったわけですよ。\nということで、一人でやっても面白くないので、興味ありそうな人を募ってやってみようということを始めたのが2018年12月くらいです。\n運営とかどうしてるの? まずは、共同主催者(コアメンバー)を募集してみようということで、Googleフォーム作って、 興味ありそうな人がいる場所に投稿してみました。(TwitterとかFBとか) で集まったのが今回紹介したメンバー(スライド参照)です。 ユーザー企業の人もいれば、私みたいな検索エンジンの人もいるので面白い感じにできたかなぁと。 で、スピーカーを運営や知り合いに声をかけて第1回をやってみたという感じです。\n今後どうするの? 残念ながら次回はまだ未定です。 2ヶ月に1回くらいのペースで開催できればなーと思ってますが、スピーカーが集まるかなどによるかなぁと。 ということで、勉強会のグループのページにスピーカー応募フォームのリンクがありますので、スピーカーに興味がある方は入力していただければと。\nもちろん第2回はやりたいので、勉強会のページからの連絡をお待ちください!!\n","date":1551191880,"dir":"post/2019/","id":"b27bdabd8e1a6b7dc06886867331ceb3","lang":"ja","lastmod":1551191880,"permalink":"https://blog.johtani.info/blog/2019/02/26/start-search-engineering-tech-talk/","publishdate":"2019-02-26T23:38:00+09:00","summary":"どーも、johtaniです。 Search Engineering Tech Talkという勉強会に運営として参加して、第1回の勉強会を開始しました。 本日(2/26)は第1回目だったの","tags":["勉強会","検索"],"title":"Search Engineering Tech Talk(検索技術勉強会)の運営として参加して始めてみました。"},{"contents":"今年も振り返りブログをかけてます。よかったw\n振り返り(2017年に書いた抱負から) まずは去年の抱負を元に。\nもっと英語の継続&TOEIC まぁ、継続してます。英会話も続けてますし、海外TVドラマや映画見てます。 ただ、昨年書いたTOEICはイベントが被りまくってて受けれてないです。。。 来年は受けれればいいが。 ちなみに見たドラマはこの辺。あんまり見てないなぁ。 「はじまりのうた」は飛行機の中で見たんですが、よかったです。 最近は音楽系の映画が好きなのかなぁ。グレーテストマンショー(ミュージカル風)とかもハマったし。\nGame of Thrones はじまりのうた BEGIN AGAIN (映画) 24 シーズン4まで 今は、ボキャブラリのなさに苦しんでる感じです。キクタンとかするべきなのかもなぁ。 基本勉強が下手だからなー。\n継続的にイベントに登壇 & CfPもっと出すぞ! OSCには出てました。あとは、いくつかに呼ばれて出たりでしょうか。 CfPはJJUGしか出せてない気がするんで、もっと出さないとですね。。。 春のJJUGでは20分で短すぎた「オープンソースとビジネスモデル」の話(同僚のネタ)が 今年面白かった内容かなぁと。 もっと話を作るのをうまくしないとだろうなぁ。 ユースケースが増えてるんで、もっといろんなところに出ていかないとなぁと。 ブースの出し方とかもちょっと考えないといけないかもなーと思ってたり。 マンネリになってきてる気がするんで、なんか取り入れないとなぁ。\nもっとブログ! 出だしはよかったんですが、途中でRustネタのブログも止まってしまいましたね。。。 業務が忙しくなったのを言い訳にして時間が取れなくなってるんで、 もっと習慣つけないとなぁ。\n雑誌やWeb系雑誌で記事を。 できてないです。。。どうすっかなぁ。 重い腰上げないのが問題なんですけどね。。。 自社のウェビナーとかはそこそこやってましたが。\nコミュニティを別の方法で盛り上げ フォーラムは皆さんのおかげで盛り上がってきてる気がしてます。 別の方法ではなく、勉強会を9月から毎月開催にして、ユースケースごとに切り替えてみました。 あとは、スピーカー登録用のフォームの用意とかして、継続的に楽にスピーカーの人たちが見つけられるようにと。 私は「全然」関わってないんですが、技術書典でいろんな方に書籍を書いていただきました。 また、Elasticloverという毎週いろんな記事をまとめていただけ助かりました。 少しでも感謝をということで、コミュニティランチというイベントで、フォーラムで回答していただいてる方や、書籍を出していただいた方を招いてCEOのShayとランチするというイベントもやってみました。 少しは盛り上げられたかなぁ。 次は、ハッカソンみたいなのとかやってみるのもありなのかなぁ?(サポートしきれない気がするんだよなぁ)\nElasticsearchなど検索系の開発にも参加 開発。。。 Analyzer向けのKibanaのプラグインの開発は継続してますが、あんまり開発してないですねぇ(GitHubの草をみながら)。 ちょっとしたPRはやったりしてますが、もっとやりたい。。。 とりあえず、来年しょっぱなは、検索系じゃないですが、KibanaのプラグインのReact化をやらないとなぁと。\n振り返り(今年あったできごと) さて、反省が多かったですが、ここからは今年の出来事を。\n初スノーシュー in US オフィス引越し パリで料理w K8sとde:code QNAPとか IPO! 初のオンライン登壇 初アイルランド! Pixel3 XL 今年も初モノがちらほら。\nアメリカでスノーシューやりました。昨年は釣りでしたが、今年はスノーシューでした。 スノーシューはすごくよかったんですが、サンフランシスコから社内ミーティングのある場所までの 移動に10時間バスに缶詰という変な初モノもありました。。。 スノーリゾートのある山の上にバスで移動だったんですが、前日までの天候の生でチェーン規制が出てしまい、登りかけた山を降りて、違う経路で登り直すという長旅でした。。。 途中からずっとゲームオブスローンズみてました。。。\nオフィスが引っ越しました。人数が増えてきたのもあり、銀座のWeWorkに引っ越しました(私はあんまり行かなかったりしますがw)。 ただ、すでに手狭になってきて、来年はまた引っ越してるかもなぁ。 今年の終わりで日本のメンバーが22名に増えました!すごい!4年半前の22倍!\nパリで料理もしましたwセールスのキックオフミーティングがパリで開催され、なぜか参加してきました。 そこで、DevRelチームのミーティング&ディナーがあったんですが、ディナーがアクティビティ付きで、チームのみんなとパリで料理やカクテル作ってきました。 まさか、パリで手巻き寿司作るとは思わなかった(怖くて食べてないですw)\n今年はイベントが連続することが多かったです。パリから帰ってすぐにde:codeでMSの川崎さんと登壇したりしました。Kubernetesを触る機会ができたんでよかったですが、時差ボケは辛かったw今年は他にもカンファレンス直後にトレーニングだったりと、夏に喉やられちゃいました。喉に負担をかけない話し方の練習すべきなんだろうなぁ。\n自宅の環境もちょっと整えました。10年前から使ってた、TeraStationをQNAPに刷新。快適に検索できるわ、クラウドにバックアップとれるわで、すごく快適です。 あとは、自室のディスプレイをディスプレイアームにつけたり、壊れたモニタースピーカーをYamahaのパワードスピーカーに買い替えたりと。 ちょこちょこ自宅で作業したりするんで、快適です。\n今年はめでたいことに会社がIPOしました。ニューヨーク証券取引所で株式公開しました。 転職して4年、初体験なんで何がどうってのはいまいち実感わかないんですが、順調にきてるのは嬉しい限りです。今後も頑張りますよ!\n自社のウェビナーでは、オンライン登壇してたんですが、インフラ勉強会でオンライン登壇させていただきました。 Elastic Stackの入門的な話をさせていただいたので、興味があればみていただければと。 こういうのにはマイクが非常に重要だなというのが結論です。ウェビナーで使ってるShureのマイクで話したので聞き取りやすかったです。 来年はもっと手軽にちょっとしたウェビナーとかポッドキャストやろうかな、ということで、持ち運び用にSAM SONGo Micを購入してみたのでどっかで試してみたいなー。\nアイルランド(ダブリン)にも行きました。これまた、社内のミーティングなんですけどね。半年に1度エンジニアが集まる社内イベントがあるので、いろんなところに旅をさせてもらっていて、すごく楽しいです。 みんなにも会えるし。ただ、アイルランドの英語はきつかった。。。\n最後はPixel3です。SonyのXperiaをここ数年は使ってたんですが、電池の持ちなどが悪くなったんで、気になってたPixel3に変えました。すごくいい。いらないものが入ってないのもいい。あとカメラがすごくいい。他の機能をまだちゃんと調べてないんで、誰か便利機能知ってたら教えてくださいw\nとまぁ、こんな感じでした。\n来年の抱負 最後は来年の抱負を。\nTOEIC CfP見つけて応募 \u0026amp; いろんな場所に顔を出す もっとブログ! Rustの継続 開発の継続 日本でエンジニア獲得! まぁ、英語ですね。これは地道にやるしかないんだろうなと思いつつ、コツコツが苦手でw とりあえず、今年はどこかでTOEIC受けないとな。\nいつも行かないけど、弊社プロダクトに関係のあるカンファレンスのCfPを見つけ出して、 応募しまくって、少しでもしゃべらないとなぁ。喋れなくても、Elasticsearchがらみで登壇していただいてる方がいるカンファレンスには顔を出していきたいなぁと。 登壇される方いたら、ぜひ連絡ください!あとは、CfPのサイトを探す仕組みを作らないとなぁ。 検索サイト作るかなぁ。 あとは、カンファレンスではなく、いろんな会社に遊びにいきたいと思ってます。 入門的な話をしてほしいような方、こんな使い方してますっていう話をしていただける方、大募集です。 これもGoogle Formでも作ってみるか。\nブログなぁ。小さな習慣を読んだのに、習慣化できてないので、なんとかしないとという意味で。。。が、頑張ります。。。\nRustの継続&開発の継続もですね。Java歴が長いので、他の言語を勉強しようと思ってRustやってますがなかなか身についてないというか、時間を取れてない。これもコツコツやらないとなー 検索関連の開発もちょっとずつやりたいなと思ってるんで、LukeへContributeしようかな。\n切実なんですが、日本に弊社のエンジニアを増やしたいなと。特に人前で喋ってもらえる人が増えると助かるんです。弊社最近、ユースケースが増えてきてて、追いつかなくてwダレカタスケテーw\nさーて、そろそろ紅白のサザンが始まるんで終わりです。\n今年も様々な方々に様々な面で助けていただきました。本当にお世話になりました。 この場を借りてお礼申し上げます。\n来年ももちろん、助けてもらうんで、よろしくお願いいたします! あと、話聞きたい方、声かけてくださーい。\n","date":1546240485,"dir":"post/2018/","id":"6c226ee1519fbf910197cc1d5c5a5756","lang":"ja","lastmod":1546240485,"permalink":"https://blog.johtani.info/blog/2018/12/31/looking-back-2018/","publishdate":"2018-12-31T16:14:45+09:00","summary":"今年も振り返りブログをかけてます。よかったw 振り返り(2017年に書いた抱負から) まずは去年の抱負を元に。 もっと英語の継続&TOEIC まぁ、","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2018)"},{"contents":"Elastic stack (Elasticsearch) Advent Calendar 2018の25日目の記事になります。 今年最後のAdvent Calendarです!来年も忘れてなければやるはず!\n今日は、すでにalpha2までリリースされた7系でどんな変更が入るのかをちょっとだけ紹介します。 ほんとにちょっとだけですよ。\nKibanaのk7 design (kibana) Kibanaの新デザインです。K7って呼ぶのかな?\nまだ、メニューと一部が実装されているだけですが、7.0.0でガラッと変わりそうです。 そのほかの画面のIssueはこちらです。 \u0026ldquo;k7\u0026quot;で検索しただけですが。メタIssueが見つからなかったんで。例えば、こんな感じでアプリとかのスイッチとかがこんな感じになるよというデザイン案が観れたりします。\nZen2 (elasticsearch) Elasticsearchの新しいクラスター管理機構アルゴリズムになります。 Zenと呼ばれる独自実装のものを6系までは使っていましたが、7系向けに変更がかかりました。 実際には、Nodeを探す仕組み、Masterの選出アルゴリズム、クラスター状態の管理などを行います。 上記のリンクにあるようにドキュメントも詳しくなりました。 信頼性をさらに向上し、設定ミスを起こしにくくして、より使いやすくという目的で様々な変更が加えられています。 これが、メタIssueかな? アルゴリズムの変更や、クラスターの状態の管理の方法などの変更に関するIssueやPRにリンクが貼ってあります。\n新しいデータタイプ (elasticsearch) Feature/Feature vector datatype ドキュメントはこちらとこちら\nfeature queryと合わせて使用するためのフィールドで、しかもクエリのスコア計算「のみ」に使用するフィールドになります。 検索条件やソート、Aggregationの対象ではなく、クエリのスコアに影響させたい値を入れておくためのフィールドです。 6から追加された機能の「track_total_hits」をfalseにした時と合わせると、function_scoreなどで計算をしていた場合よりも、検索性能が上がるという利点まであります。 ちなみに、「track_total_hits」は検索ヒット数を計算しないで、上位のデータを取得する時にクエリを早くするといったことができる機能になります。 Index Sortingと組み合わせることで威力が発揮できる仕組みになるはずです。\nFilebeat supports NetFlow (beats) NetFlowが入力として追加されます。 Filebeatと言いつつ、File以外の入力が徐々に増えてきてますね(UDPやTCPにも対応しましたし)。 ネットワーク機器などの監視を行う方などにはさらに便利になってくるのではないでしょうか? (私はこの辺りは不得手なので、誰か使ってみてもらえればと!)\nまとめ まだ、序の口って感じですが、今年はこの辺で。7系ではここであげた以外にも様々な機能が追加されています(もしくは予定です)。 Elasticのドキュメントの良いところは、masterブランチのドキュメントも公開されていることです。 ドキュメントのバージョンを7.0.0-alpha2にすれば、masterブランチで追加されたページが見れるので、 興味のある方は眺めてみていただければと。物によって、リリースノートが書かれていなかったりするので注意は必要ですが。\n今年もあと数日になりましたが、Advent Calendarへの参加ありがとうございました! 来年ももちろんやりますので、年始からネタを考えてくださいね。\n来年一発目は、第28回Elasticsearch勉強会 - 6.5機能紹介 -になります。ウェビナーでも紹介しましたが、6.5で入った様々な新機能をデモありで紹介する予定です。 興味のある方はぜひご参加ください。\nでは、来年もよろしくお願いいたします。\n","date":1545663601,"dir":"post/2018/","id":"ee62cb0b9a97f990df1ed0266a7027e2","lang":"ja","lastmod":1545663601,"permalink":"https://blog.johtani.info/blog/2018/12/25/whats-new-in-elastic-stack-7/","publishdate":"2018-12-25T00:00:01+09:00","summary":"Elastic stack (Elasticsearch) Advent Calendar 2018の25日目の記事になります。 今年最後のAdvent Calendarです!来年も忘れてなければやるはず! 今日は、すでにalp","tags":["elasticsearch"],"title":"Elastic Stack 7.0で入ってくる新機能をちょっと紹介"},{"contents":"Elastic stack (Elasticsearch) Advent Calendar 2018の1日目の記事になります。\nちょっと遅れちゃいました。。。 まだ、1ヶ月を残してますが、簡単に今年起こったことを振り返ってみようと思います。毎年恒例ですね、ここ数年。\nElastic Stack 6.2.0リリース(2月) リリース記事はこちら\nAPMがGAリリースされ、Beats monitoring UIも追加されました。Stackとしての統一度がちょっとずつ上がってきた感じですね。 Kibanaのホーム画面(左メニューのKibanaアイコンをクリックした時)にデータ登録のチュートリアル的な画面が追加されています。 特にBeatsを利用する時の流れが簡単にわかるのがいい感じです。Metricsなどはローカルでちょっと試すのにも簡単な流れですので、ぜひ一度やってみてもらいたいなと。 個人的にはtermsを使ったパイチャートで、その他の数値がどのくらいあるかといった表示ができるようになって、やっと帰ってきた!(Kibana 3の頃にはあった機能)という印象でした。\nElastic{ON}18開催(2月) 第4回目のユーザーカンファレンスがSFで開催されました。 今年のキーノートが今年最大のニュースですね。 X-Packのコードの公開が発表されたのがこの時でした。 個人的に今後もオープンソースに携わっていきたいと思いながら日々働いていますが、 Elasticのオープンソースへのこだわりと、シンプルな考え方を再確認して素晴らしい会社で働けてるなーと。 商用のソースコードを公開してユーザーや顧客の皆さんとより良いものを作っていきたいという形ですので、今後もよろしくお願いします! キーノートの動画はこちらからご覧いただけます。\nそのほかにも次のような発表が行われました。\nSQL for elasticsearch Canvas Elastic App Search(旧Swiftype) Elastic Stack 6.3.0リリース(6月) リリース記事はこちら\n2月末のElastic{ON}で発表されたX-Packのコードの公開にはやはり時間がかかりました。 有償コードのリポジトリとの統合やライセンスの変更、テスト環境などなど、色々大変だったみたいです。 ようやく公開され、ベーシックのライセンスの扱いなども変わり、より使いやすくなったのがこのタイミングです。\nX-Packをプラグインとしてのインストールが不要に ベーシックライセンスがデフォルトでONに。6.3から登録などが不要に。 Apache 2.0ライセンスの部分のみのディストリビューションも別途ダウンロードできるようになどなど 日本でもリリースウェビナーをやりました。ご覧いただけましたかね?\nElastic Cloud Elasticsearch Serviceがより使いやすく(8月) リリース記事はこちら\nこれまでは、メモリとストレージの比率だけしか指定できなかったのですが、 このリリースで様々なユースケースに応じた組み合わせが可能になりました。 CPUやメモリリソースよりもストレージを大きくしたりなどです。 専用マスターノードを追加できたり、待望の機械学習(Machine Learning)が提供されたりと色々と変更があり使いやすくなったかと。 昔からよく聞かれる、Kuromojiなどのカスタム辞書を登録する機能もあるので、Elastic Cloud便利です。 ご存知ない方は、14日間のトライアルもありますので試していただければと!\nElastic Stack 6.4.0リリース(8月) リリース記事はこちら\nフィールドエイリアスや韓国語のアナライザーがElasticsearchに追加されました。 Kibanaはデザインがここからさらに少しずつ変更が入ってたりします。 Elastic UIフレームワークと呼ばれるデザイン用のライブラリが、ElasticのプロダクトのUIに取り込まれていってる感じです。統一感が取れてきてますよね。私が開発しているAnalyze UIのプラグインにも取り込みました。 あとは、マイクロソフトのde:codeで話をさせていただいた、Logstash向けのAzure Moduleがリリースされたのもこのバージョンでした。AzureのEvent Hubからデータを取り込んで、SQLデータベースのモニタリングや、ユーザーの認証などをとってKibanaで可視化するものです。\nもっとも気に入っているのはサンプルデータの登録が簡単になったことです。これまでは、KibanaとElasticsearchを用意した後に、データを入れるためにFilebeatなどを使ってから、ようやくKibanaで遊べるという形でした。 6.4からは、ElasticsearchとKibanaを立ち上げて、Kibanaのホーム画面の「Sample Data」のリンクを押した後に、「Sample flght data」の「Add」ボタンを押せばKibanaからデータが登録されます(サンプルデータについてはこちら)。とりあえず触ってみたいという方への敷居がさらに下がったのではないかなぁと。\nElastic認定エンジニア第1号(8月) ブログ記事はこちら\n認定制度も始まりました。Elasticsearchの知識、経験を問われるテストを受けていただき、合格すると認定されるというやつです。 なんと、社外で世界初の認定エンジニアがアクロクエストの吉岡さんでした(上記ブログ参照)。 私もトレーナーやってるのもあり、慌てて認定をとったりしましたw。 認定テストは筆記ではなく、実際に作業をするテストなので実践的です。 トレーニングの受講が必須ではないのも面白いなぁと思いました。 トレーニングや認定エンジニアに興味がある方は、Elasticのトレーニングのサイトをご覧ください。 1月末にはまた、日本語でElasticsearchのトレーニングも開催されます!\nElastic Cloud Enterprise 2.0リリース(9月) リリース記事はこちら\nElastic Cloud Enterpriseをご存知ない方もいらっしゃるかもしれません。 Elastic Cloudの裏側で利用しているクラスターの起動などの仕組みを製品として提供しているのがこちらになります。 Elastic Cloudで機械学習や様々な構成ができるようになったものがリリースされたのがこの2.0です。 複数のElasticsearchクラスターを管理したい場合には、こちらが便利なツールになってるんじゃないかなぁと。 部署ごとにクラスターを提供するといったことが可能になるので、乱立する前に利用するのも便利かなーと。\nニューヨーク証券取引所で株式を公開(10月) ブログ記事\n日本語でブログ(10月) Elasticsearchの運用に関する典型的な4つの誤解というブログを書きました。4年も働いてるのに、会社のブログに翻訳以外で書いたことなかったので。。。 Twitterや勉強会、ブログ記事などで見かけるよくある誤解に関する記事を書いてみました。 Elasticは英語のブログも活発に書かれているのですが、今後もこのような形で日本語でのブログも頑張りますので、 読んでみたいものなどあればコメントいただければと。\nまぁ、弊社の大輪は色々書いてるんで、私がもっと頑張れって話ですかね。。。\nElastic Stack 6.5.0リリース(11月) リリース記事はこちら\n昨日(11/30)のウェビナーでも話をさせていただきましたが、Elastic Stack 6.5は「本当にマイナーリリース???」と思うほど盛りだくさんの機能がリリースされました。\nインフラUI、ログUI Elastic APMの分散トレーシング対応 Java \u0026amp; Go APM Agent GAリリース Cross Cluster Replication ODBCドライバー Kibana Canvas Kibana Spaces Data Visualizer for files Functionbeat LogstashのApp Search output リストアップしただけでもこれです。45分のウェビナーでは伝えきれてないなぁとも思ってますので、何か検討しようと思います!\nElasticsearch勉強会(3月から12月) Elasticsearch勉強会ページ\n今年は、6回の勉強会を開催(1つは12月19日開催)しました。 9月からは、ユースケースなど、もっと参加者の皆さんの興味があることにフォーカスしながら開催をしてみ始めました。 参加しやすくなってればいいのですが。。。 そろそろまたアンケートをとったりして、参加しやすいか、どんな改善がしてほしいかなどを聞きたいなと思っています。\n12月はもっと皆さんと喋りたいなということで、スピーカーなしの「LT\u0026amp;忘年会」にしてみました。 私やElasticのものも参加するので、ぜひ色々聞いたり、他のコミュニティの方達の使い方を聞き出して、 新しい発見をしていただければなーと思います。LTでスピーカーの練習をするってものありですよ!(まだ誰も応募してくれてない。。。) 発表することで、フィードバックがもらえて、自分の使い方に自信が持てたり、その他の視点を得ることができると思いますので、 ぜひ発表してみていただければと。\n12月のjohtani出没イベント 12月は以下のイベントにブースを出してます。イベントに参加される方ははぜひブースにお立ち寄りください!!\n12/4-5 : Japan Container Days - 東京 12/8 : OSC福岡 - 福岡 12/15 : JJUG CCC 2018 Fall - 東京 12/19 : 第27回Elasticsearch勉強会 - 東京 なんか、忙しそうだな。。。\nまとめ 駆け足でしたが今年を振り返ってみました。 今年も色々ありましたが、今後もよろしくお願いいたします。\nさて、Elastic Stack Advent Calendar 2018は今日から25日まで続きます。こらからの記事を楽しみにしています!\nということで、次はkaibadash@githubさんの「ぼくの考えた最強のElasticsearch index設定を最強にわかりやすく書くぞ!!!」になります。お楽しみに!\n","date":1543628918,"dir":"post/2018/","id":"ba45ddd3042dad59a12e5937644f7246","lang":"ja","lastmod":1543628918,"permalink":"https://blog.johtani.info/blog/2018/12/01/whats-happen-at-elastic-in-2018/","publishdate":"2018-12-01T10:48:38+09:00","summary":"Elastic stack (Elasticsearch) Advent Calendar 2018の1日目の記事になります。 ちょっと遅れちゃいました。。。 まだ、1ヶ月を残してますが、簡単に今年起こったことを振り返ってみよ","tags":["elasticsearch"],"title":"2018年のElastic StackとElastic"},{"contents":"(転職する少し前までパスポートすら持ってなかったのに)今の会社に転職してから、半年に1度の割合で海外への出張が発生する生活を送っています。 4年目になりますが、今回いくつか新しいガジェット?アイテム?を出張用に導入したので感想を書いておこうかなと。\nとりあえず、以下の4つです。\nFelimoa ネック ピロー これまでは、無印で購入した「フィットするネックピロー」を使ってました。 特に使ってる間は問題ないのですが、どうしてもかさばります。。。 そんな時、FBで見かけたのがこちら。\n厚みがないので、持ち運びが便利でした(商品紹介の中にありますが、リュックにつけると邪魔にならない)。 飛行機の中で使うので、それほど暑くない場所なので、ムレる感じでもなく。 ただ、ヘッドフォン+真横にフレームがくる形になるとヘッドフォンに干渉するので、 私はフレームを顎の下の方に寄せた形で使ってました。 軽さと場所を取らないのがよかったです。\nノイズキャンセリングヘッドフォン これまでは、SONYのNW-A847という ノイズキャンセリング機能付きのウォークマン+アクセサリーで外部入力を取り込む形で、飛行機で映画を見ていました。 これ自体が8年前の製品ですね。。。 これとは別に、冬の寒い時期は防寒も兼ねてヘッドフォンを使用しています。 MDR-10Rを使ってたんですが、昨年こんな感じになりまして。。。\n応急処置 pic.twitter.com/uDErZWpPVC\n\u0026mdash; Jun Ohtani (@johtani) 2017年11月10日 で、ヘッドフォンの買い替えを検討してたんです。 そこへ飛び込んできたのがSonyの新しいノイズキャンセリングヘッドフォンでしたと。\nせっかく買い換えるし、今度はいいものを長くということでフライト前日に購入してしまいました。 結論としては高いけど買ってよかったと。よかった点はこんな感じです。\n軽い イヤーパッドが耳を抑えることがないので長時間でも気にならない 人の声だけノイズキャンセリングをオフにする(騒音などはキャンセルしてくれる) バッテリーが長時間 ヘッドフォンを外さないでも案内を聞くことができる「クイックアテンションモード」 などなど。行きのフライトで5時間も遅れが出ましたが、空港、飛行機内で非常に快適に過ごせました。 大事に使おう。。。\ncw-x 知り合いがFBにアップしてて、立ちっぱなしの仕事だったり、長時間のフライトでも足が疲れないという噂を聞いて購入しました。\n長時間のフライトの後に、ホテルで1泊しても足の疲れって結構残ってるんです。 今回、12時間のフライトでズボンの下に履いて行きましたが、足の疲れがほぼありませんでした。 デブになりつつあり、足太くなって来てるので、履くのはちょっと苦労しますが。。。もともときつめに作ってるんじゃないかなぁ(希望的観測)。 帰りも使用しましたが、帰りはフライト前に1万歩ほどダブリンの街中を歩き回ってたので、流石に疲れが出てます。。。 今度は、カンファレンスのブースなどで立つことが多いシーンでも使ってみて、疲れがどうなるかを試してみようと思います。\n携帯ウォシュレット 初めて購入しました。海外のホテルで1週間とか連泊するんですが、トイレットペーパーがやはり硬めなのが気になって。。。\n世界に誇る日本の技術の一つだと確信してますw ドイツに長期出張してた友人が便利だよと言ってたので、思い切って購入して持って行きました。 硬めのトイレットペーパーも気にならなくなるのでとても幸せな気分ですw\nまとめ とりあえず、今回はこんな感じです。 総じて導入してよかったなという感じでした。 他にもおすすめ出張グッズとかあればコメントいただけると嬉しいです。\n普段使ってるものとか、どういうものを持っていってるとか興味ある人いるかなぁ? ではでは。\n","date":1539794095,"dir":"post/2018/","id":"3fd9052870778e14ab4a5acbc8c24af4","lang":"ja","lastmod":1539794095,"permalink":"https://blog.johtani.info/blog/2018/10/18/items-for-long-businesstrip/","publishdate":"2018-10-18T01:34:55+09:00","summary":"(転職する少し前までパスポートすら持ってなかったのに)今の会社に転職してから、半年に1度の割合で海外への出張が発生する生活を送っています。 4","tags":["misc"],"title":"新規導入した長期出張用のアイテムをいくつか紹介"},{"contents":"毎月開催の2回目になります。 今回は日経さんの会場をお借りしての開催となりました。\n前回から、スピーカーの募集をhttp://bit.ly/SpeakerElasticTokyoMeetup で行なっております。 ぜひ皆さんのノウハウを共有していただけると助かります。 また、次回もすでにスケジュール済みです。次回は「ログ/メトリック分析」回になります。\n以下は、個人的なメモになります。\nメディアコンテンツ向け記事検索DBとして使うElasticsearch / Future Architect 株式会社 村田 靖拓さん (twitter: @famipapamart) メディア記事コンテンツ検索 全ての情報が1indexに入っているようにすること。 typeは少し悩んだ。 範囲検索にはならない場合がある。(文字列で登録してWildcard検索できるようにした) kuromojiで基本対応 異体字についてはchar filterでマッピング 細かな設定とかもスライドにて公開予定。 基本的なプラグインだけで対応した Dynamic Field mappingを有効にしたまま対応 パフォーマンス検証 初回のインデックスのロードはこの辺かなぁ?。 自力でQueryのoffset-limitを構築するのかぁ。 ソート条件が固定らしいのでできる方法 minne での検索運用(仮) / @_shiro16 さん ハンドメイドなものをマーケットプレイスがminne SolrからElasticsearchに切り替えた話 2016/02以降はEs 昔は、DBからSolrへ同期 Es版ではDBからの同期ではなく、Workerに対してリクエストを入れる 現状は独自にEC2で運用中 ユーザーが求めているものがきちんとでているかを計測している 行動ログはどんな感じ? TDにログを入れて、CTRとかを計算してre:dashで可視化 A/Bテストも実施 指標はキャンペーンなどが実施されている場合にブレる場合もある トレンドをログから知ることができる Function Scoreでスコアを変更してる 季節的な単語でスコアを変更したりする ドリンクの対応などをして聴けてないところが。。。 query_stringのはなし / 加藤遼さん (日本経済新聞社) 電池が切れそう+ピザとかの手配をしていたらメモが取れず。\n苦労が滲み出る感じのセッションでした。 query_string queryが実際にどんなクエリになっているかの説明を交えて説明してもらえたのはすごくよかったんじゃないかと。 まとめ 検索は話してくれる人が多いし話題に事欠かないなぁという印象でした。 今回も、スピーカーの皆さん、会場提供をしていただいた日経さんありがとうございました。\n他のユースケースのスピーカーも募集してます。ぜひMeetup.comの概要に記載してあるリンクからスピーカーの応募をお願いします!\n","date":1539765230,"dir":"post/2018/","id":"d3fa23c9066f943f10e8883de9340dea","lang":"ja","lastmod":1539765230,"permalink":"https://blog.johtani.info/blog/2018/10/17/26th-elasticsearch-tokyo-meetup/","publishdate":"2018-10-17T17:33:50+09:00","summary":"毎月開催の2回目になります。 今回は日経さんの会場をお借りしての開催となりました。 前回から、スピーカーの募集をhttp://bit.ly/Sp","tags":["elasticsearch","勉強会"],"title":"第25回Elasticsearch勉強会を開催しました。"},{"contents":"7/25にJJUGナイトセミナーでElastic Stackの紹介とAPMのJava Agentの紹介をしたので、補足のブログです。 (久々に書くな。。。)\nスライドとサンプルアプリのリポジトリはこちら。\nスライド:https://speakerdeck.com/johtani/intro-elastic-stack-and-elastic-apm-java リポジトリ:https://github.com/johtani/apm-beats-kubernetes-demo/tree/master サンプルアプリ 勉強会の頭でサンプルアプリへのアクセス用QRコードを用意して質問してもらう感じにしました。\nアプリ自体が質問の受付と、そこにある質問に対して聞きたいかどうかのVoteができる仕組みになっています。 セッション最後にこの画面をみながら答えました。 手を挙げていただくよりも、匿名(名前入れるようになってますが、実名である必要はない)で登録できるし、 みんなが聞きたいかどうかもわかるので便利だなぁと。\n元は、Elastic{ON} 2018であった「Docker \u0026amp; Kubernetes Log Collection and Monitoring with Beats and Elasticsearch」のサンプルアプリです。 これをSpring Bootに移植して、ちょっとだけサンプルコードを追加したものになります。\n構成とかの補足 スライド、GitHubのリポジトリのREADMEにある図は、k8s上のサンプルアプリケーションの構成だけでした。 ElasticsearchとKibanaを含めた図はこんな感じです。\nk8s上の各種Beats、APM Serverは一旦Elastic CLoud Elasticsearch Service(AWS Tokyoリージョンにデプロイ)に対してデータを投げます。 で、KibanaはGKE(k8s on GCP)で動かして、実際に勉強会ではkubectl proxyで接続してから表示していました。 この構成にしている理由は次の理由です。\nElastic CloudのElasticsearchクラスターにデータを投げている理由 クラスターの起動が簡単。 データを永続化したい。k8sのアプリは必要がなくなったらデータを削除したいから。 k8sのdeploymentを書く手間を省く 普段使ってるので。。。 KibanaをGKEで動かした理由 Elastic Cloudでは*「現時点(7/29現在)」*で、KibanaでAPM専用のUIを起動できない ローカルである必要はない といったところです。 Elastic Cloudのインスタンスを起動したままにしておけば、デモをしなくても、このタイミングのログ、メトリクスを 再利用して話をすることも可能です。\nまとめ ということで、簡単ですが、構成の補足でした。 勉強会では告知したのですが、今後の勉強会はトピックスごとでやりたいなと。ということで、どんなトピックスに興味があるのか、スピーカーの応募にはどんなツールが話しやすいかなどといったことのアンケートを集めております。ぜひご協力ください! また、アンケート、このブログに関する質問がある場合は、@johtani、もしくはブログへのコメントでお願い致します。\n今後の勉強会のやり方などについてアンケートを実施中です。https://t.co/XU15CHro0n 皆さん是非ご協力ください。ここにない項目については返信をお願いします。 #elasticsearchjp\n\u0026mdash; Jun Ohtani (@johtani) 2018年7月23日 ","date":1532843130,"dir":"post/2018/","id":"10ae016e19fff6ae9cfaeb8534fa47f9","lang":"ja","lastmod":1532843130,"permalink":"https://blog.johtani.info/blog/2018/07/29/apm-java-at-jjug/","publishdate":"2018-07-29T14:45:30+09:00","summary":"7/25にJJUGナイトセミナーでElastic Stackの紹介とAPMのJava Agentの紹介をしたので、補足のブログです。 (久々に書く","tags":["勉強会"],"title":"JJUGナイトセミナーで話しました"},{"contents":"第2回から少し間が空いてしまいましたが、templateで作成したプラグインのディレクトリ構成とどういう流れでデータがやり取りされるかについてみていきます。 (2018/02月時点で作成したディレクトリ構成にしたがって説明します) ちなみに、JavaScriptの優れた開発者ではないので、誤解している点や、効率の悪い書き方などがあるかもしれません。見つけた場合は、連絡をいただければと思います。\nでは、まずは作成したディレクトリ構成についてみていきましょう。\nディレクトリ構成 simple-sample-kibana-pluginがプラグインのプロジェクトのトップディレクトリになります。このディレクトリに次のような構成でサブディレクトリが存在します(なお、画像はIntelliJに取り込んだ後のディレクトリになっているので、.imlなど、不要なファイル/ディレクトリが存在しています)。\n主要なディレクトリ、ファイルについて簡単に一覧で説明します(順不同)。\nファイル/ディレクトリ名 説明 index.js プラグインの本体。Kibanaはこのファイルのオブジェクトを読み込みプラグインを起動。設定などの読み込みもこちら。 package.json npm/yarnのパッケージに関する情報を定義するファイル README.md README。プラグインの説明などを記載する。インストール方法なども記載すると便利 public ブラウザ側に配布されるプログラムや画像一式 public/less/main.less LESS用のファイル。アプリ固有のスタイルなどを記載 public/app.js ブラウザ側で読み込まれるプラグインのモジュールなど。 public/template/index.html HTMLのテンプレート。ブラウザ上での描画に利用 server/routes Kibanaサーバー側で動作するプラグイン。hapi.jsを利用してREST APIを実装する 重要なファイルについて少しだけ説明します。\npackage.json npmやyarnでビルドなどをするときに使用するパッケージ情報を記載するためのファイルです。 プラグインの名前、バージョン、説明などを記載します。 Kibanaのバージョンについてもこちらで管理します。この情報を また、ライブラリなどの依存関係についてもこちらで記載しています。 以下、抜粋。\n{ \u0026#34;name\u0026#34;: \u0026#34;simple-sample-kibana-plugin\u0026#34;, \u0026#34;version\u0026#34;: \u0026#34;0.0.0\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Sample plugin for explaining how to make kibana app\u0026#34;, \u0026#34;main\u0026#34;: \u0026#34;index.js\u0026#34;, \u0026#34;kibana\u0026#34;: { \u0026#34;version\u0026#34;: \u0026#34;6.2.1\u0026#34;, \u0026#34;templateVersion\u0026#34;: \u0026#34;7.2.4\u0026#34; }, \u0026#34;scripts\u0026#34;: { \u0026#34;lint\u0026#34;: \u0026#34;eslint **/*.js\u0026#34;, ... }, \u0026#34;devDependencies\u0026#34;: { \u0026#34;@elastic/eslint-config-kibana\u0026#34;: \u0026#34;^0.14.0\u0026#34;, \u0026#34;@elastic/eslint-import-resolver-kibana\u0026#34;: \u0026#34;^0.9.0\u0026#34;, \u0026#34;@elastic/plugin-helpers\u0026#34;: \u0026#34;^7.1.3\u0026#34;, ... \u0026#34;expect.js\u0026#34;: \u0026#34;^0.3.1\u0026#34; } } ちなみに私は、versionなどをリリースするたびに変更しています。\nindex.js 最初にKibanaに読み込まれるオブジェクトになります。 Kibanaのアプリの名前や、必要なモジュールなどを記載します。\nまた、kibana.ymlから設定など読み込む処理なども書くことができます。\n2行目のexampleRouteはサーバー側のAPIとして利用するhapi.js用のファイルのパスになります。\nuiExportsはこのアプリの画面に関する設定などの記載になります。 appの部分が実際にアプリの情報で、 mainがあとで説明するこのプラグインのUIのためのJavaScriptファイル(public/app.js)になります。mainですので、最初に読み込まれる処理が記載されているものを指定します。app.jsというファイル名を変更する場合は、こちらのappの部分を変更したファイルに合わせましょう。\nconfig(Joi)の関数が設定ファイルの読み込みなどの処理を記載する場所です。\ninit(server, options)の関数が初期化処理を記載する場所になります。 このサンプルアプリでは、2行目のimportで読み込んだhapi.js用のファイルの関数を呼び出しています。引数で渡しているserverがhapi.jsのserverオブジェクトになります。 routeメソッドを使用して作成しているプラグイン用のREST APIを追加しています。\nimport { resolve } from \u0026#39;path\u0026#39;; import exampleRoute from \u0026#39;./server/routes/example\u0026#39;; export default function (kibana) { return new kibana.Plugin({ require: [\u0026#39;elasticsearch\u0026#39;], name: \u0026#39;simple-sample-kibana-plugin\u0026#39;, uiExports: { app: { title: \u0026#39;Simple Sample Kibana Plugin\u0026#39;, description: \u0026#39;Sample plugin for explaining how to make kibana app\u0026#39;, main: \u0026#39;plugins/simple-sample-kibana-plugin/app\u0026#39; }, ... }, config(Joi) { return Joi.object({ enabled: Joi.boolean().default(true), }).default(); }, init(server, options) { // Add server routes and initialize the plugin here exampleRoute(server); } }); }; public/app.js 画面用のモジュールです。 uiRoutesという機能を使用して、アプリの呼び出しURLを定義します。テンプレートで作成したばかりの場合は、/というURLが追加されるのみです。\n実際に画面を表示する際に動くコントローラーの部分はその下の uiModules.controllerに指定してあるfunctionが画面描画の 処理を書く部分になります。 templateで作成したプラグインでは、\u0026ldquo;title\u0026quot;など表示に必要なデータを$scopeというオブジェクトに詰め込んでいます。 これはAngularJS(1系)でのモデルオブジェクトになります。\nimport moment from \u0026#39;moment\u0026#39;; import { uiModules } from \u0026#39;ui/modules\u0026#39;; import uiRoutes from \u0026#39;ui/routes\u0026#39;; import \u0026#39;ui/autoload/styles\u0026#39;; import \u0026#39;./less/main.less\u0026#39;; import template from \u0026#39;./templates/index.html\u0026#39;; uiRoutes.enable(); uiRoutes .when(\u0026#39;/\u0026#39;, { template, resolve: { ... } }); uiModules .get(\u0026#39;app/simple-sample-kibana-plugin\u0026#39;, []) .controller(\u0026#39;simpleSampleKibanaPluginHelloWorld\u0026#39;, function ($scope, $route, $interval) { $scope.title = \u0026#39;Simple Sample Kibana Plugin\u0026#39;; $scope.description = \u0026#39;Sample plugin for explaining how to make kibana app\u0026#39;; ... $scope.$watch(\u0026#39;$destroy\u0026#39;, unsubscribe); }); server/routes/example.js hapi.jsというNode.jsのためのサーバーフレームワークです。 このフレームワークをKibanaは使っており、Kibanaのサーバーとブラウザとのやり取りに使用するREST APIを記述するために使用しています。 例えば、Elasticsearchとのやり取りを実際に行うAPIなどをこのREST API内部で記述します。\nexport default function (server) { server.route({ path: \u0026#39;/api/simple-sample-kibana-plugin/example\u0026#39;, method: \u0026#39;GET\u0026#39;, handler(req, reply) { reply({ time: (new Date()).toISOString() }); } }); } pathの部分がブラウザ側からアクセスするURLになります。 実際にElasticsearchとやり取りする処理の書き方については、次回の記事で説明します。\nアーキテクチャ(簡易版) ざっくりですが、ファイルやディレクトリについて説明しました。 簡単なデータのやり取りについての流れを説明します。\nKibana自体はNode.jsで実装されサーバーとして動作していますが、ブラウザでアクセスすることで画面を描画しています。 簡単なコンポーネントを並べるとデータのやり取りはこのような形です。\nすごく簡易で大雑把な絵ですが。。。\n実際のプラグインとしては大きく、2つの処理があります。\nブラウザ上の処理 クリックなどのイベント処理 HTMLなどのレンダリング処理 Kibanaサーバー上の処理(Elasticsearchなどとの通信が必要な場合) 外部との通信処理 ブラウザ上では重い処理 絵に記載しましたが、ブラウザ上の処理についてはAngularJSが主なフレームワークで、サーバー上の処理についてはhapi.jsがフレームワークとなっています。\nまとめ ということで、今回はディレクトリ構造とファイルの説明、どういったフレームワークが使われ、データのやり取りがどのように行われているか説明しました。\n次回からは、実際に私が作成したAnalyze UIを元にElasticsearchとのデータのやり取りなどについて紹介していきます。\n","date":1524205801,"dir":"post/2018/","id":"04d818cbaac08b2915db15e0bffdcb5b","lang":"ja","lastmod":1524205801,"permalink":"https://blog.johtani.info/blog/2018/04/20/directory-layout-and-architecture/","publishdate":"2018-04-20T15:30:01+09:00","summary":"第2回から少し間が空いてしまいましたが、templateで作成したプラグインのディレクトリ構成とどういう流れでデータがやり取りされるかについ","tags":["Kibana","plugin"],"title":"Analyze UIとKibanaのプラグインの作成方法(第3回)"},{"contents":"#MANABIYA のブースでセッション時間の合間はお客さん少ないので、ブログを書いてみたり。 ここ数年、スポンサーとして色々なカンファレンスに参加してるんですが、それについてちょっと気なることがあったので。\nスポンサー情報ってどうやって探してます? 職業柄、カンファレンスにCfP出してセッションしてみたり(落ちること多いけど)、スポンサーとしてブースを出したりしています。\nで、疑問があるんですが、みなさんどうやってカンファレンスの情報をゲットしてます?\n数年やって来て、検索したりして見つけてスポンサーした結果、 これまでスポンサーしていたので、情報が流れてくるという感じになりました。 それ以外だと、@yusuke さんに教えてもらったりと言うのがあったんですが。。。\n自分が知らない、自分のTwitterで流れてこないという情報をどうやったら集められるかな?と言うのが今の課題になってます。 と言うことで、ブログを書いてみました。\nカンファレンスを検索できるサイトとか便利? で、私の会社は検索エンジンの会社なんで、検索できると便利では?と考えるんです。\nCfPの応募期間で絞り込みできたり、場所で検索できたり、スポンサー情報を取得する方法が載ってたりすると便利なのではないかなと。 便利に思うのが自分だけでは?と言うのがあるんですが。。。\nあると嬉しい人、データを掲載したいなと言う人いますでしょうか? Google Formなどで入力してもらえるようにして何か作るのもありかなぁと考えているところです。 それとも、スポンサーを募っているカンファレンスのスタッフや企業の人は、こういう情報は特定の人にだけ知ってもらったりしたいでしょうか?\n自分だけではわからないことが多いので、懸念事項や、それダメでしょ? あると便利!などのフィードバックをいただけると助かります。\nそれ以外に、カンファレンス自体の場所、開催日程、サイトへのURLなどが検索できると便利だったりするかも?というのもあります。\nとりあえず、自分が知ってるものだけ、個人的に検索できるようにしたりするのがいいかなぁ。。。 コメントお待ちしてます!\n","date":1521867012,"dir":"post/2018/","id":"8cc6b19cd410e638f4beaf1642f4f52a","lang":"ja","lastmod":1521867012,"permalink":"https://blog.johtani.info/blog/2018/03/24/how-to-find-conferences/","publishdate":"2018-03-24T13:50:12+09:00","summary":"#MANABIYA のブースでセッション時間の合間はお客さん少ないので、ブログを書いてみたり。 ここ数年、スポンサーとして色々なカンファレンスに参加してるんです","tags":["カンファレンス","スポンサー"],"title":"カンファレンス情報の探し方(CfP、スポンサー応募、開催期間など)?"},{"contents":"Rustで言語処理100本ノックの続きで、05と06です。\n05. n-gram 問題はこちら。\nみんな大好きn-gramです。単語と文字があるので、それぞれ別関数として実装しました。問題はbi-gramとn=2だったのですが、一応、nを引数に取る形にして実装しました。\nまずは、単語です。\n前に実装した時は、自分で頑張って、先頭から数えたりしてたんですが、Rustにはwindows(n)という便利なメソッドがsliceにあり、これを利用したらこんな簡単になりました。 sliceは特定のシーケンス(配列)に対してある特定のサイズのViewを作ってくれます(説明あってる?)。 ということで、文字列から、単語の配列(スペース区切りで単語にしている)を作り出して、windows(n)メソッドを通すと、 nで指定した数字の個数だけの単語の配列を先頭から、1単語ずつずらして作ってくれます。まさに、n-gram! 戻り値は配列の配列です。 1点だけ疑問点があるのは、「空白で区切ったものが単語」という考え方で良いかどうか?という点です。特に問題文にはそれが明示されていなかったので、このような前提を置いてあります。\ninvalid_n(text, n)はnの値や入力された文字列をチェックする関数です。入力チェックですね。nが1よりも小さい場合、入力文字列が空文字の場合は、warningでメッセージを出して、空の配列を返す仕組みになっています。\n次は、文字です。\n単語とほぼ一緒ですが、入力文字列を、1文字ずつの配列にしているところが異なります。 また、windowsメソッドで取り出された、1文字ずつのn個の配列を文字列に修正してから、結果の配列に入れています。 ここでも疑問は空白をどう扱うか?になります。 現時点では、空白も1文字とカウントして扱うことにしてあります。 どっちがいいのかなぁ?\n06. 集合 問題はこちら。\nまずは、文字n-gramで出てきた文字列をSetに入れる関数から。\nn-gramの問題で実装した文字n-gramの関数の戻り値を配列ではなく、BTreeSetに変えたものになります。比較などがしやすいように?と思い、BTreeSetを利用していますが、実装としてはHashSetでも問題ないかと。 この関数の集合(Set)を元に、和集合、積集合、差集合を求める関数を実装しました。\nSetのメソッドとして、それぞれ、union=和集合、intersection=積集合、difference=差集合のメソッドが用意されているので、特に困ることはなかったです。 差集合については、1-2と2-1で結果が異なるはずなので、それぞれをテストケース、main.rsで出力するようにしてあります。\n所感 今回は、Rustがすでに実装してくれているメソッドがあったので楽ができました。 やりたいことに相当するメソッドがあるかどうかを調べるためにリファレンスを探さないといけないのがちょっと苦労しましたが。。。 ということで、今日はこの辺りまで。\n","date":1521549285,"dir":"post/2018/","id":"d791eaca9375ca1b36a987af22ee71dd","lang":"ja","lastmod":1521549285,"permalink":"https://blog.johtani.info/blog/2018/03/20/nlp100-ch01-05to06/","publishdate":"2018-03-20T21:34:45+09:00","summary":"Rustで言語処理100本ノックの続きで、05と06です。 05. n-gram 問題はこちら。 みんな大好きn-gramです。単語と文字があるので、それぞれ別関","tags":["Rust","nlp100"],"title":"第1章の05から06までやってみた(言語処理100本ノック)"},{"contents":"Rustで言語処理100本ノックの続きで、03と04です。\n03. 円周率 問題はこちら。\n入力文字列を.split_whitespace()で分割しておいて、単語ごとのベクタを作り出し、そこに対して文字を数えました。「アルファベットの」という注意書きがあるので\u0026quot;,\u0026ldquo;や\u0026rdquo;.\u0026ldquo;は含めずに数えるのかなということで、 charの.is_alphabetic()でA-zまでの判定をしつつ、文字のベクタを作ってから、そのベクタの長さを詰め込むという感じでやりました。\nこれ、ひょっとして、collectでベクタにしなくても、i32とかの変数でカウントするとベクタ作らなくてもいいなじゃにか?というのに書きながら気づいた。。。 必要じゃないオブジェクトを作ってるよなぁ。\n.filter().mapとかかな?この辺りの操作がイマイチ苦手。Javaでもまだ馴染めてないところなんだよなぁ。頭固すぎ。\n04. 元素記号 問題はこちら。\n大作ですね。何だろう、大作。。。 最終的に連想配列(辞書型もしくはマップ型)」ということだったので、BTreeMapに詰め込んでます。 HashMapでもいいんですが、文字列で出力した時にキーが並んで見やすいからという理由で、BTreeMap使いました。それ以上の理由はないです。普通にやるなら、HashMapかな?\n入力として、1文字だけの出力をする場所(インデックス番号)の配列を受け取ってます。1点だけ、チェックしていない、けど入力値の想定をしていて、idx_one_symbolsがソートされていて、小さいものから順番に出てくるものとしてます。関数作って、チェックすべきかな?\nで、指定された場所の最後のものが入力文字列よりも大きいかどうかというチェックもしています。(あー、テストケース書いてないな)この辺りのせいでちょっと長めになってます。\n単語の配列を作るのは03の時と同じやり方です。 回しかたがちょっと違って、.iter().enumerate()で回して、添字と値をタプル?でとりだしてます。添字を見ながら1文字取り出すのか、2文字取り出すのかの判断が必要だからです。あとは一緒ですね。1文字取り出すときは、.first()を使って見ました。 実は、2文字取り出す時と、1文字の時と同じロジック使った方が共通化できて、短くなった???\nということで、こんな感じでした。いつものようにツッコミお待ちしてます。\n所感 問題それぞれについてではなく、 やってて思ったのですが、問題に対して想定される結果が記載されていると嬉しいなと思いました。 ロジックについては、各自実装者に寄ったり、言語によって違いが出たりするし、議論するベースになっていいかなと思うんですが、 問題で想定されている結果(出力)があると、自分の実装にケアが足りないところがないのか?とか、ケアしなくていい点とかがわかるのかもなぁと。 ユニットテスト相当のものがあると楽かなぁと。\nこのケースどうするんだろ?みたいなのが、ところどころコメントに残ったりしてます。 出題の意図としては、その部分も議論の対象ということなのかな?\n","date":1519032848,"dir":"post/2018/","id":"e6684944c37dbdd4c08d978af9e47bed","lang":"ja","lastmod":1519032848,"permalink":"https://blog.johtani.info/blog/2018/02/19/nlp100-ch01-03to04/","publishdate":"2018-02-19T18:34:08+09:00","summary":"Rustで言語処理100本ノックの続きで、03と04です。 03. 円周率 問題はこちら。 入力文字列を.split_whitespace()で分割して","tags":["Rust","nlp100"],"title":"第1章の03から04までやってみた(言語処理100本ノック)"},{"contents":"「鉄は熱いうちに打て」ということで、言語処理100本ノックの第1章の00から02を実装してみました。\nさて、これが効率がいいのかどうかはさておき。\n00. 文字列の逆順 問題はこちら。\n最初、Vecのreverse()で逆順にして0からlen()まで回してたんですが、pop()がいい感じに後ろから取れることがわかったんで、切り替えました。 シンプルかな?\n01. 「パタトクカシーー」 問題はこちら。\n1文字ずつ取り出して、インデックスの番号が2で割ってあまりが0なら文字列に追加していくってのでやってみました。 (ブログ書いてるところで、i in 0..char_array.len()じゃなくて、(i, x) in char_array.iter().enumerate()に切り替えました。) matchとか使って綺麗に書けたりするのかなぁ?\n02. 「パトカー」+「タクシー」=「パタトクカシーー」 問題はこちら。\nだいぶ思考錯誤してる感じがソースに現れてます。 とりあえず、両方の文字列をcharsの配列にして個々のイテレータを回しながら、next()の戻り値があれば追加していく感じにして、 終了条件が両方Noneを通ったらにしてるけど、、、 なんか、もっと綺麗にできないのかなぁ。。。 next()のタプル返す関数作って、とかでなんかできたりするかなぁ?\ngist-it 関係ないですが、GitHubのコードを貼り付けるのに便利なサービスがあるみたいです。\nhttp://gist-it.appspot.com\nこれほんと便利だな。行数指定もできるし。 説明するのが簡単だ。\nとりあえず、今日はこの辺まで。なんか、いい知恵あれば教えてください!\n","date":1518699541,"dir":"post/2018/","id":"bbe1deec11d459bdb348051b970abdaf","lang":"ja","lastmod":1518699541,"permalink":"https://blog.johtani.info/blog/2018/02/15/nlp100-ch01-00to02/","publishdate":"2018-02-15T21:59:01+09:00","summary":"「鉄は熱いうちに打て」ということで、言語処理100本ノックの第1章の00から02を実装してみました。 さて、これが効率がいいのかどうかはさてお","tags":["Rust","nlp100"],"title":"第1章の00から02までやってみた(言語処理100本ノック)"},{"contents":"ども。新しいもの始めないと頭が退化する。。。ということで、こちら( happy new year and new language - katsyoshiのめもみたいなもの)のブログに触発されて、言語処理100本ノックをはじめてみました。\n言語処理100本ノックとは、自然言語処理になるのかな、東北大学の研究室の先生が公開している言語処理に関する実践的な課題をベースにプログラミングなどのスキルを学んでいくための問題集です。 元々はPythonを対象とされているようですが、Rustでやってみようかと。 まぁ、先ほどあげたブログの二番煎じです。。。 ちなみに、インスパイアされた元のブログの方はRust book 2nd editionを読み終えたらしいですが、私はかじった程度です(ダメかも?)。\nNLPもRustもかじった程度なので、苦戦しそうですが、ちょっとずつやっていこうかなと。 ということで、準備運動の第1章から始めようかと。 GitHubにちょっとずつあげていく予定です。 https://github.com/johtani/nlp100-rust\nまぁ、まずは宣言のブログを書いてみただけです。 続いてなかったら、叱咤激励してください。叱咤だけかも?\n","date":1518605551,"dir":"post/2018/","id":"a673b3829e62477e01abc75465416b86","lang":"ja","lastmod":1518605551,"permalink":"https://blog.johtani.info/blog/2018/02/14/start-nlp100-with-rust/","publishdate":"2018-02-14T19:52:31+09:00","summary":"ども。新しいもの始めないと頭が退化する。。。ということで、こちら( happy new year and new language - katsyoshiのめもみたいなもの)のブログに触発されて、","tags":["Rust","nlp100"],"title":"言語処理100本ノックはじめました(Rust)"},{"contents":"第1回では、Analyze UIというプラグインの紹介をしました、ごく簡単にですが。\n第2回では、Kibanaのプラグインの作成方法を順を追って見ていこうと思います。今回は、プラグインのプロジェクトの作り方を説明します。 どんなファイルがあるのかなどについては第3回で説明します(2018/02月現在の方法になります。残念ながら、Kibanaのプラグイン作成自体はまだExperimentalな話になっていますので、変更がある可能性があります)。\n実はそれほど難しいというわけではありません。Kibanaのプラグインを作成するためのテンプレートが用意されています。template-kiban-pluginです。 テンプレートのリポジトリのREADMEに作業手順の記載があります。\nKibanaのリポジトリをClone、Checkout Node.jsの環境を用意する Kibanaを起動できるようにする SAOのインストール テンプレートによるプロジェクトファイルの生成 順を追って説明します。 PLUGIN_DEV_DIRというディレクトリ配下で作業をしている想定になります。\n1. KibanaのリポジトリをClone、Checkout 開発環境として、Kibanaが必要です。Kibanaのプラグインを作るので。 手順などはKibanaのCONTRIBUTING.mdに記載があります。 ということで、まずはKibanaのリポジトリをCloneします。\ncd PLUGIN_DEV_DIR git clone git@github.com:elastic/kibana.git このままだと、masterブランチなので、開発したい対象のKibanaのバージョンのブランチもしくはタグをcloneします。今回は6.2.1向けということで、次のようになります。\ngit checkout v6.2.1 これで、ソースが6.2.1向けになりました。\n2. Node.jsの環境を用意する Node.jsをインストールします。 Kibanaのリポジトリに.node-versionというファイルがあります。 こちらにNode.jsのバージョンが記載されています。 Kibanaが使用しているNode.jsを利用できるようにします。ローカルではnvm利用してインストールしました。後から、切り替えが可能だからです。 nvm自体のインストールについてはnvmのサイトをご覧ください。 nvmがインストールできたら、次のコマンドで、Kibanaが使用しているバージョンをインストールします。\ncd kibana nvm install \u0026#34;$(cat .node-version)\u0026#34; すでにnvmを利用している場合などは、Kibana起動時にKibanaのバージョンに合わせたNode.jsに切り替えるようにしてください。\n3. Kibanaを起動できるようにする Kibanaではyarnというjavascript向けのパッケージマネージャーを利用して起動やビルドなどを行います。まずはyarnをインストールします。最近npmからyarnに切り替えたようです。 私はMacだったので、brewでインストールしました。 インストールできたら、次のコマンドを実行します。\nyarn これにより、package.jsonから必要なライブラリなどをダウンロードして来てくれます。 問題なければ「✨ Done in 439.30s.」というような表示がされます(結構時間かかりますね)。 では、Kibanaを起動できるか確認してみましょう。 さらに、Elasticsearchも起動してみます。 Kibanaのpackage.jsonの中にはElasticsearchを起動するためのスクリプトも用意されています。実際にはgruntを利用してタスクを実行しているようです。Elasticsearchの起動にはJavaが必要になります。 今回は6.2.1なので、JDK 8以降がインストールされている必要があります。 こちらはインストールされているものとします。\nyarn elasticsearch で起動できます。\n\u0026gt;\u0026gt; Started 1 Elasticsearch nodes. という表示が出てればOKです。 次にKibanaです。別のTerminalを起動して、以下のコマンドで起動できます。\nyarn start これだけです。\nserver log [06:58:56.930] [info][listening] Server running at http://localhost:5603 この辺りが出てればKibanaのServerは起動済みです。また、Elasticsearchに接続できていれば、次のログが出ているはずです。\nserver log [07:02:18.010] [info][status][plugin:elasticsearch@6.2.1] Status changed from red to green - Ready Elasticsearch接続用のKibanaのプラグインの状態になります。 これで、Kibanaの環境が整ったことが確認できました。 もちろん、Elasticsearchに関しては、yarnで起動せずに、tar.gzなどでダウンロードして来たElasticsearchを起動しておき、アクセスするといったことも可能です。プラグインなどをElasticsearchにもいれてテストしたい場合などはそちらの方が便利かもしれません。\n4. SAOのインストール では、一度、ElasticsearchとKibanaを停止しましょう。フォワグラウンドで起動しているので、それぞれのTerminalでCtrl+Cで停止できます。 Kibanaのプラグイン作成むけに、テンプレートが作られています。sao.jsというGitHubのリポジトリやnpmのパッケージをテンプレートとして使うことができるツールを利用してプラグインのプロジェクト(リポジトリ)を作成します。 実際にテンプレートとなるリポジトリはtemplate-kibana-pluginになります。 まずはSaoのインストールです。\nnpm install -g sao プラグインのテンプレートのページには上記のようにnpmを利用したインストール方法になっていますが、次のようにyarnでも可能です。\nyarn global add sao これで、saoがインストールできました。\n5. テンプレートによるプロジェクトファイルの生成 あとは、テンプレートを元にプロジェクトを作成します。 PLUGIN_DEV_DIRディレクトリ配下に、kibanaと同じ階層で作成するプラグイン用のディレクトリを作成します。\nmkdir simple-sample-kibana-plugin 以下のような構成になります。\nkibana simple-sample-kibana-plugin 次にテンプレートを適用していきます。\ncd simple-sample-kibana-plugin sao kibana-plugin@7.2.4 2行目がsaoを利用してプロジェクトを作成しているコマンドになります。 すると、次のような質問が出て来ます。 これらに答えるとプロジェクトに必要なファイル(package.jsonやREADME.mdなど)に入力した情報を適用したものを作ってくれます。\n? Name of your plugin? ? Provide a short description ? What Kibana version are you targeting? ? Should an app component be generated? ? Should translation files be generated? ? Should an hack component be generated? ? Should a server API be generated? 実際に答えた内容はこちら。\n? Name of your plugin? simple-sample-kibana-plugin ? Provide a short description Sample plugin for explaining how to make kibana app ? What Kibana version are you targeting? 6.2.1 ? Should an app component be generated? Yes ? Should translation files be generated? Yes ? Should an hack component be generated? Yes ? Should a server API be generated? Yes プラグインの名前などは、ディレクトリ名と同じものを入力補完してくれているので、そのままEnterでもOKです。 Descriptionについてはわかりやすいものを入力しましょう。 バージョンは、先ほどのKibanaのリポジトリに合わせて、6.2.1にしてあります。 あとは、作るプラグインの種類に応じて、必要なコンポーネントを作るかどうかの質問にYes/Noで答えます。 今回はサンプルの説明ということもあるので、全てYesで答えました。 ちなみに、私が実際に作成したanalyze-api-ui-pluginでは、appとtranslationとserverの3つを作成しました。 ただし、translationについては現在はテンプレートで作成したままのファイルが入っており、実際には利用してないです。\n完了したら、プラグインのサンプル入りのプロジェクトが完成です。 もう一度、Elasticsearchを立ち上げて、プラグインのプロジェクトからKibanaを起動してアクセスしてみます。まずは、PLUGIN_DEV_DIR/kibanaディレクトリの下で、Elasticsearchを起動します。\nyarn elasticsearch 次に、PLUGIN_DEV_DIR/simple-sample-kibana-pluginディレクトリの下で、以下のコマンドを実行し、プラグインが入った状態のKibanaを起動します。\nyarn start 問題なく起動すれば、ブラウザでアクセスすると次のような画面が表示されるはずです。\n左側にメニューが1つ増えています。 クリックすると、上記画像のような画面が表示されるはずです。\nこれで、カスタムプラグインの開発ができる環境ができました! 次回は、プロジェクトのディレクトリ構成や、どんなツールが内部で使用されてデータのやり取りが行われているかについて説明します。お楽しみに。\n","date":1518167857,"dir":"post/2018/","id":"7b6cb59a177abe9767fd22da5a03b1e6","lang":"ja","lastmod":1518167857,"permalink":"https://blog.johtani.info/blog/2018/02/09/getting-started-template-kibana-plugin/","publishdate":"2018-02-09T18:17:37+09:00","summary":"第1回では、Analyze UIというプラグインの紹介をしました、ごく簡単にですが。 第2回では、Kibanaのプラグインの作成方法を順を追って","tags":["Kibana","plugin"],"title":"Analyze UIとKibanaのプラグインの作成方法(第2回)"},{"contents":"あけましておめでとうございます。今年はサボりがちだったブログをちょっとずつ復活させようかと。 ということで、第1弾として、昨年少し作っていたKibanaのプラグインを何度かに分けて紹介したいと思います。\n今回はAnalyze UIというプラグインの紹介です。\n今回はインストール方法と簡単な機能紹介です。 細かな紹介は個別にやりたいと思います。\nAnalyze UI pluginとは? Elasticsearchの_analyzeというAPI\u0002(個人的に好きなAPIです)をご存知でしょうか?\nElasticsearchは全文検索エンジンで、データの検索には転置インデックスというものを使用します。 Elasticsearchにデータを登録する際に、text型のデータの場合、この転置インデックスのキーとなる単語を決める処理のことをAnalysisと呼びます(Analysisの詳細については割愛します。後日説明するかも?)。 このAnalysisの処理が、入力されたデータの文字列に対してどのように行われて、結果としてどんな単語がキーとして用いられているかを確認できる機能が_analyze APIです。検索で単語がうまくヒットしないな?とか、なんで、こんなので検索結果に出てくるんだ?といった場合、このAPIを利用すると、どのような単語で転置インデックスが作られているかがわかるので、検索にヒットしない/する理由を見つけることができます。\nElasticsearchの便利な点はRESTfulなAPI+JSONでやりとりができる点なのですが、_analyze APIの結果をJSONで受け取っても、見るのにちょっと苦労します。。。こんな感じ。\nリクエスト:\nPOST _analyze { \u0026#34;analyzer\u0026#34;: \u0026#34;kuromoji\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;今年はブログをいっぱい書きますよ!\u0026#34; } レスポンス:\n{ \u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;今年\u0026#34;, \u0026#34;start_offset\u0026#34;: 0, \u0026#34;end_offset\u0026#34;: 2, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 0 }, { \u0026#34;token\u0026#34;: \u0026#34;ブログ\u0026#34;, \u0026#34;start_offset\u0026#34;: 3, \u0026#34;end_offset\u0026#34;: 6, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 2 }, { \u0026#34;token\u0026#34;: \u0026#34;いっぱい\u0026#34;, \u0026#34;start_offset\u0026#34;: 7, \u0026#34;end_offset\u0026#34;: 11, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 4 }, { \u0026#34;token\u0026#34;: \u0026#34;書く\u0026#34;, \u0026#34;start_offset\u0026#34;: 11, \u0026#34;end_offset\u0026#34;: 13, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 5 } ] } このくらいの量であればまだなんとかなりますが、文章が長くなると辛いですよね。\nということで、GUIがあると便利だろうなぁと。で、作ってみましたというのが今日紹介するKibana用のAnalyze UIプラグインです。 こんな感じで、Kibanaのアプリの一部として動作しブラウザ上で、入力テキストの文字列がどのようにanalyzeされて、単語になるかがわかります。\n(先ほどのAPIのサンプルと同じものを画面で入力した結果になります)。\nインストール方法 現時点の最新版Kibana(6.1.2)に対応しています。 Kibanaのディレクトリでkibana-pluginコマンドを利用してインストールします。\n./bin/kibana-plugin install https://github.com/johtani/analyze-api-ui-plugin/releases/download/6.1.2/analyze-api-ui-plugin-6.1.2.zip これだけです。 で、Kibanaを起動していただくと、左のメニューに「Analyze UI」という項目が増えています。\nクリックすると、Analyze UIが表示されます。\n初期画面は入力された文字を特定のAnalyzerで処理した場合の結果を見るための画面です。綱目の説明は画像をご覧ください。\n先ほどのJSONよりは見やすくなったかと思います。 そのほかにもいくつか画面や機能があるのですが、今日はこの辺りで。 「_analyze API便利なんだけど、JSONは。。。」とか「検索うまくできないなぁなんでだろう?」と思っている方は、ぜひ試して見ていただければと。 問題点などありましたら、GitHubのIssueを登録してください。\n","date":1516343806,"dir":"post/2018/","id":"4afcb20d4d95bcd1bde3aa6b7f552660","lang":"ja","lastmod":1516343806,"permalink":"https://blog.johtani.info/blog/2018/01/19/how-to-make-kibana-plugin-example-analysis-ui/","publishdate":"2018-01-19T15:36:46+09:00","summary":"あけましておめでとうございます。今年はサボりがちだったブログをちょっとずつ復活させようかと。 ということで、第1弾として、昨年少し作っていたK","tags":["Kibana","plugin"],"title":"Analyze UIとKibanaのプラグインの作成方法(第1回)"},{"contents":"今年は紅白を見ながら書いてます。 今年はいろんなところに出張に行ったなぁ。\n振り返り(2016年に書いた抱負から) まずは去年の抱負を元に。\nもちろん英語の継続 もちろん継続してます。英会話しながら海外TVドラマや映画を見てます。 ちょっとずつ英語字幕でも見ようとしてますが、まだまだだなぁ。 あと、TOEICを受けてないんで、それは受けないと。 見たドラマはこの辺です。\nER ウォーキング・デッド Agent of Shield SUITS Mr.Robot(いまいち話の展開についていけなかった) 継続的にイベントに登壇 OSCに今年もブース出してセッション持ってました。 勉強会ももちろんやりました。 あと、外部のカンファレンス(FOSS4G、BigData Analytics、db tech showcaseなど)や 勉強会(monitoring勉強会やCA.ioなど)にも登壇させていただきました。 もっと外部から読んでいただいたり、CfPに応募して通過できるようにしないとなぁ。\nもっと開発&ブログ ブログはすみません。。。来年頑張ります。。。 ブログの代わりに書籍を出せました。データ分析基盤系の書籍になるので、興味のある方はのぞいて見ていただければ。\n開発はちょっとやってます。今年後半はKibanaのプラグインとかをちょっと書いてました。 Ingest-CSVもちょこちょこバージョンアップに追従してたりします。\nサポートエンジニア獲得! 獲得しました!(自分の成果かどうかはわかりませんが。。。) 今は3名体制でサポートしてもらってます。おかげさまでだいぶサポートする機会が減ってきました。 開発は世界各地どこでも募集中だったりしますので、ぜひ連絡いただければと。\n個人的な検索勉強会の再開 再開しました。検索エンジン自作入門を知人と隔週くらいで読んでます。読んでるだけではあれなんで、実装もしてたり。全然違う言語でトライして見ようと思ったのでRustで書き始めてます。まずは、単純なところからと思ったんですが、 Rustの書き方の違いにだいぶ戸惑ってます。。。\n振り返り(今年あったできごと) ここからは今年の出来事を。\n初アメリカで釣り Nintendo Switch! 初Japanチームオフサイト チーム変更 初Berlin Buzzword! 母校(大学)訪問 Kibanaプラグイン開発 今年も初モノがちらほらとありますね。 今年もカレンダー振り返ってたら「え?これ今年だったの?」ってのがちらほらありました。。。\nアメリカで釣りやりました。自社のカンファレンスElastic{ON}のあとに、エンジニアが集まるミーティングがあるんですが、そこで1日Fun Dayがあって、そこで釣りをやりました。 魚群探知機とかで魚探すんですね、最近のは。2、3匹釣ったので非常に楽しかったです。 来年はスノーシューにチャレンジする予定。\nNintendo Switch買って、ゼルダやりました。今はイカやってます。 イカ欲はちょっと減ってるかもなぁ、1に比べると。 あとは、子供に買ったマリオやったりしてるかな。\nここ10年くらい行きたいと思っていたカンファレンス、Berlin Buzzwordに行ってきました! これが今年一番嬉しかった出来事です。Luceneコミッターの方々にも会えたし。特にPoliceman JenkinsのUweさんに会えたのが本当に感激でした。。。 来年も行けるといいなぁ。。。\n今年も出張が多めだったのであちこち飛び回ってたなぁ。 そんな飛び回っている中で、故郷である広島(出身地?)に出張で行ったので、母校に顔を出してきました。 変わってなかった。。。自分が一期生なので、自分が入学した時はまだクレーンとか立ってるような新校舎だったんだけど、それが20年くらい経て、だいぶ古くなってました。。。 広島市内は港近くに高速道路とか出ててだいぶ様変わりしてました。 ただ、小学校も高校も変わってなかったなぁ。久々に高校の同級生にも会えたし。 また、機会があればぜひ行きたいなと。帰省する場所ではなくなったので、行く機会がないんですよね。。。\n開発もちょっとやってます。Kibanaのプラグインに挑戦して見てます。 いまだにJavaScriptは苦手なんですが。。。 ちょっとずつ改良して、ひょっとすると本体とかに取り込めるかな? あとは、今年始めたRustをちょっとずつ継続して行きたいなと。\n来年の抱負 最後は来年の抱負を。\nもっと英語の継続&TOEIC 継続的にイベントに登壇 CfPもっと出すぞ! もっとブログ! 雑誌やWeb系雑誌で記事を。 コミュニティを別の方法で盛り上げ Elasticsearchなど検索系の開発にも参加 英語はもちろんですね。今年は12月の自社イベントに合わせて多くのAPJチームの人が来て、 チームで会話できたし、もっと英語やらないとなぁと。前よりもちょっとは喋れるようになった気がしてます(気がしてるだけで、喋れてるかどうかは不明)。あとは、TOEIC受けて、実力チェックしてみないとなぁ。\nイベント登壇はまぁ、DevRelですから、一応。 来年もとりあえず、3月までは毎月どこかでブース出してます。 Ask Me Anything的なブースの出し方を今年はしてみようかなと思ってるので、 ちょっと使い始めたけど、この辺よくわからないと思ってる方、ぜひ質問しに来てください。 ブース出すだけじゃなくて、スピーカーとしていろんな場所で喋れるようにしないとなぁと。 もっと幅広く知ってもらえるように雑誌とかで連載できるようにしたいなぁと思ってます。 また、日本語の入り口の情報を増やすためにブログも書かないとなぁ。\n勉強会も継続しますが、別の方法でも盛り上げて行きたいなぁと。 勉強会はどうしても聞く人が多くて、ユーザーの間での交流や情報交換とまでは行ってない気がするし、discuss.elastic.coというフォーラムで質問は増えて来てるけど、もう少し交流しやすい場があると使ってもらえるかなぁ?と思っていたり。 何かおすすめとかあれば、連絡ください。 meetup.comの勉強会のページにも掲示板はついてるんだけど交流しにくそうだし。\n来年は自分が最も興味のある検索系の開発にも参加したいなぁと。 Elasticsearchをちょっとずつ時間見つけてやってたりはしますが、もう少し首を突っ込んで行きたいなぁと。Swiftypeもジョインしたし。もっと検索やって行きたい気持ちが強いので。\nさて、ということで、今年もあと1時間なくなりました。 今年も様々な面で色々な方々に助けていただけました。本当にお世話になりました。 この場を借りてお礼申し上げます。\n来年ももちろん、色々な方に助けてもらうと思いますが、よろしくお願いいたします!\n","date":1514723443,"dir":"post/2017/","id":"7c21b70f9e9c782c1f5153268e0cc1c1","lang":"ja","lastmod":1514723443,"permalink":"https://blog.johtani.info/blog/2017/12/31/looking-back-2017/","publishdate":"2017-12-31T21:30:43+09:00","summary":"今年は紅白を見ながら書いてます。 今年はいろんなところに出張に行ったなぁ。 振り返り(2016年に書いた抱負から) まずは去年の抱負を元に。 もちろ","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2017)"},{"contents":"Merry Christmas! Elastic Stack Advent Calendar 2017の24日目の記事になります。\nちょっとですが、2018年のElasticについて書いてみようかと思います。\nイベント いくつか出展が決まっているイベントがあるのでまずは宣伝を。\nOSC Osaka 2018 まずは、1月25日、26日にOSC Osaka 2018に出展し、話をします。参加者がいそうであれば、25日や26日の夜に勉強会もありかなぁと思っています。 セッションでは入門的な話をする予定です。ブースにいますので、色々質問がある関西の方はぜひご参加ください。\nDeveloper Summit 2018 2月15日、16日はDeveloper Summit 2018に出展します。 こちらでもブースにいますので、AMA(Ask Me Anything)的に使っていただくのもいいかなと。 デブサミに参加される方はぜひお立ち寄りください。\nManabiya 3月23日、24日はManabiyaに出展します。 こちらでもAMAのつもりでブースを出す予定です。質問がある方はぜひお立ち寄りください。 こちらのイベントは初めての開催になるようなので、どんなイベントになるか楽しみにしています。\nイベント回りはこの辺りで。 また、1月末に勉強会を予定しています。決まり次第またMeetup.comの方々にメールを出す予定です。\nElastic Stackの2018年は? Canvas! 昨年のElastic{ON}でみなさんをCanvasがリリースされるかなぁと。 現在、みなさんにテストしてもらえるようにcanvas.elastic.coというサイトを公開中で、実際にインストールして試すことができるようになっています。 ぜひ、触って、全く新しいUIを体験して見てください。\nSQL? こちらも昨年のElastic{ON}でみなさんから反響があったものです。 もう直ぐでてくるのではないかなぁと。\nその他は? いくつか面白そうで、取り込み済みのものをピックアップしておきます。\nAdd ranking evaluation API 検索クエリなどに対して検索結果のランクのクオリティを評価するためのAPIの追加(7.0予定) JDK9サポート? 6.2でサポートされそうです。が、LTSのJDK8が推奨のままの予定です。 High-level REST ClientでいくつかAPIが追加 https://github.com/elastic/elasticsearch/pull/27574、https://github.com/elastic/elasticsearch/pull/27351 APM正式リリース? ベータ版がリリースされているので、秒読み段階? ということで より詳しく知りたい方は、サンフランシスコで開催されるElastic{ON} 2018に参加するのが一番です!(ステマ) 私も参加予定ですので、ぜひ、現地でお会いし、色々な情報をゲットしましょう。\n明日で、今年のAdvent Calendarも最後です。micci184さんの記事を楽しみにしましょう!\n","date":1514124616,"dir":"post/2017/","id":"f3a9b931b7f552a4f9dfa61ce4f39f0e","lang":"ja","lastmod":1514124616,"permalink":"https://blog.johtani.info/blog/2017/12/24/elastic-2018/","publishdate":"2017-12-24T23:10:16+09:00","summary":"Merry Christmas! Elastic Stack Advent Calendar 2017の24日目の記事になります。 ちょっとですが、2018年のElasticについて書いてみようかと思います。 イベント いくつか","tags":["elasticsearch"],"title":"2018年のElasticは?"},{"contents":"Elastic stack (Elasticsearch) Advent Calendar 2017の1日目の記事になります。\nまだ、1ヶ月を残していますが、簡単に今年起こったことを振り返ってみようかと思います。思った以上に色々ありましたね。。。\nElastic Stack 5.2.0リリース (1月) リリース記事はこちら\nHeatmapがKibanaで追加されたり、Heartbeatがベータですが追加されました。 個人的には、Terms aggregationのFiltering Valuesによるパーティションが便利になったと思います。Terms Aggsでページングに似たことができるようになりました。\nElastic{ON}17開催 (3月) 第3回目のユーザカンファレンスが開催されました。 バレーダンサーの踊りから始まったキーノート、様々なユーザ企業によるユースケース発表などいろいろありました。 セッションはこちらのサイトからから録画を見ることができます。 SQL for ElasticsearchやAwardが目を引いたと思います。SQL対応まだ出てきていないですが、もうすぐじゃないかと!\nElastic Stack 5.3.0リリース (3月) リリース記事はこちら\nFilebeat moduleが導入され、ログファイルを取り込んでKibanaで可視化するまでの手順がより簡単になりました。Elasticの目指しているものの一つに、シンプルな使い方、簡単にはじめられることといったものがあります。KibanaのTimepickerもより便利になったのも、このバージョンからです。\nShayがCEOに (5月) 2月にすでに発表されていましたが、Elasticsearchの生みの親のShay BanonがCEOに正式に就任しました。CEOになってさらに、精力的に様々なことをやっていて、本当にすごいなと思います。\nElastic Stack 5.4.0、6.0.0-alpha1リリース (5月) 5.4.0リリース記事はこちら、6.0.0-alpha1リリース記事はこちら\n5.4.0は節目になるリリースでした。Machine Learningがベータリリースとして、X-Packに追加されましたし、ElasticsearchではCross Cluster Searchの改善が進みました。LogstashではPersistent QueueがGAになりましたし、KibanaにはTime Series Visual BuilderやEvent Contextなどが追加されますます使いやすくなりました。\nまた、6.0.0のalpha版も同時にリリースされ、様々な方からのフィードバックが集まり始めました。\nElastic Cloud Enterprise GAリリース (5月) Elastic Cloudのバックエンドの技術を製品に採用したものになります。 多くのElasticsearchクラスタを管理しないといけない方には朗報でした。\nOpbeatがJoin (6月) Opbeatチームがジョインしたのが6月です。Elastic StackがAPM\u0002(Application Performance Monitoring)でも活躍することになりそうです。APMの仕組みとしては、APM Agentをアプリ側に配置し、APM Serverへデータを送信し、Elasticsearchに保存、Kibanaで可視化するという流れになります。\nElastic Stack 5.5.0リリース (7月) リリース記事はこちら\nMachime LearningがGAリリースになったのが5.5.0です。色々な方から質問を受けました。それ以外にも、ElasticsearchのWindows MSI InstallerやKibanaのFilter editorなどが追加されました。Filter editorはこれまで検索条件を記述するのが難しいと感じていたKibanaユーザにとても喜んでもらえたものじゃないかなと。 GrokDebuggerが導入されたのもこのタイミングです。\nElastic Stack 5.6.0リリース (9月) リリース記事はこちら\n5系最後のマイナーリリースであり、6へのアップグレードが楽になる様々な仕組みが用意されたのがこのバージョンです。ElasticsearchのJava High level REST clientが導入されたのもこのバージョンです。本当に様々な機能が次のメジャーバージョンとの互換性のために組み込まれています。。。\nElastic Cloud on GCP (9月) リリース記事はこちら\nこれまで、AWS上のみで展開していたElastic CloudがGCP上でも展開されることになりました。残念ながら、日本リージョンはまだありませんが、問い合わせなどが増えれば今後サポートされる可能性が高くなると思います!\nElastic APM alpha (9月) リリース記事はこちら\nOpbeatチームによりElastic StackのAPMがAlphaですがリリースされました。APMがOpen Sourceで利用できるんです!Agentがもっと増えてくると色々なことに使えるようになると思います。ぜひAgentを作成してみてください!\nElastic Stack 6.0.0リリース (11月) リリース記事はこちら\n待ちに待った6.0.0のリリースです。新機能については本日(12/1)の昼に行われるウェビナーをご覧ください!\nSwiftypeがJoin (11月) ニュースリリースはこちら\nSwiftypeと呼ばれる検索のSaaSを提供している会社がジョインしました。 個人的には今年一番嬉しいニュースです。やはり、検索が好きなので。 簡単にSite Searchを構築できる仕組みは非常に面白いものです。 興味のある方は、ぜひ触ってみてください。日本語固有の機能などはまだないので、今後関わっていければなーと。\nElastic{ON} Tour Tokyo開催 (12月) まだ開催前ですが、今年も東京で1dayイベントを開催します。 残念ながら、もうSold outなので、キャンセル待ちになってしまっているみたいですが。私もスピーカーとして喋りますし、AMAブースにも立っています。 参加される方はぜひ声をかけていただければと思います。\nOSC 2017.Enterprise (12月) オープンソースカンファレンスで今年も様々な都市に出張しました。 今年の締めくくりということで、12/8に渋谷で開催されるカンファレンスに出展します。時間のある方は、ぜひブースに遊びに来てください。入門者向けのセッションもあるので、こちらもお待ちしております。\nまとめ 超駆け足ですが、今年を振り返ってみました。 今年もいろんなことがありました。書くのが大変だったw。 OSCなどイベントで声をかけていただいた皆様、ありがとうございました。\nさて、Elastic Stack Advent Calendar 2017は始まったばかりです。これからの記事を楽しみにしています!\nということで、 次はaeroastroさんの「Elasticsearchのインデックスを本当の意味で無停止再構築する方法」(Advent Calendarのページはこちら)になります、お楽しみに!\n","date":1512054000,"dir":"post/2017/","id":"fa0486610d8a02cea245c13c85b6de27","lang":"ja","lastmod":1512054000,"permalink":"https://blog.johtani.info/blog/2017/12/01/whats-happen-at-elastic-in-2017/","publishdate":"2017-12-01T00:00:00+09:00","summary":"Elastic stack (Elasticsearch) Advent Calendar 2017の1日目の記事になります。 まだ、1ヶ月を残していますが、簡単に今年起こったことを振り返ってみようかと思います。思った以上に","tags":["elasticsearch"],"title":"2017年のElastic StackとElastic"},{"contents":"Swiftypeでサイト内検索? プレスリリース:Elasticがサイト内検索サービス最大手のSwiftypeを買収が出ましたが、SwiftypeチームがElasticにジョインしました!\n自分のブログ検索に導入してみる? SwiftypeはSite Searchをサービスとして提供しています。 実際に指定したサイトのデータをクロールして、インデキシングし、検索できるようになります。 ものは試しということで、自分のブログを登録してみました。検索窓はつけてないですが。 14日間のFree trialがあるのでそちらで試してみましょう。 検索窓はデモとか作れたらかな。\nということで、Free trialへ まずはユーザ登録です。Googleのアカウントと連携するか、Swiftypeにメルアドを登録するかが選択できます。 登録できたら、次にどちらのプロダクトを使うかという選択画面が出てきます。 今回はサイト検索して見たいので、「Site Search」の「START FREE TRIAL」をクリックします。\nEngineの指定 Web Crawlerを利用するか、独自にSwiftypeのAPIを利用してデータを登録するかを選択します。\n今回は、お手軽な方のCrawlerを選択します。 すると次に、クロールしたいURLの指定画面が出てきます。\n今回は自分のブログなので、\u0026lsquo;http://blog.johtani.info\u0026rsquo;を指定します。\nで少し待つと、URLのチェック(存在チェックとか、接続チェックとか)が終わり、今回作成するEngineに名前をつける画面が出てきます。 「My Blog search」という名前にしてみました。\nsitemapがあるかどうかをCrawlerがチェックしています。 私のBlogはOctopressでできていて、sitemap.xmlも作ってくれているので、これを元にCrawlerはクロールをしてくれます。そのほかにもRSSやAtomサポートもあるみたいですね。 「COMPLETE SETUP」を押すと、Engineの管理画面が出てきます。\n「CRAWLING」という表示が出ています。クロールしている最中です。これが終われば、「PREVIEW」に代わり、検索できる準備ができたことになります。 実際にPREVIEWして見ると、次のような検索ができるようになります。\nそのほかにはWeightの調整画面などもありますね。フィールド毎に重み付けを変えて見たりもできます。\n日本語独自のAnalyzerなどはまだないので、そのあたりができてくるともっと便利になりそうです。 とりあえず、気になる方は触って見てはいかがでしょうか? 個人的は検索に関するサービスが出てきたのですごく楽しみにしています!\n","date":1510280089,"dir":"post/2017/","id":"c20d71627e66a044b21780f56f2f9504","lang":"ja","lastmod":1510280089,"permalink":"https://blog.johtani.info/blog/2017/11/10/welcome-swiftype/","publishdate":"2017-11-10T11:14:49+09:00","summary":"Swiftypeでサイト内検索? プレスリリース:Elasticがサイト内検索サービス最大手のSwiftypeを買収が出ましたが、Swifty","tags":null,"title":"Swiftypeがジョインしたので触ってみました"},{"contents":"久々に執筆しました。といっても、以前の書籍の更新版です。 まぁ、更新版といっても、私以外の方々は結構な量を書き直しor新規書き起こしされてますが。。。\nということで、みなさん「買って」から感想をいただけるとうれしいです!\u0002(以下の画像でAmazonにジャンプできます!Kindle版も発売中です。)\n今回もElasticsearchの章を担当しました。 5.4ベースで書きましたが、ちょっとずつ6でどう変わるかなども記載してあります。 また、付録ではLogstashやBeatsにもちょっと触れています。 また、自分が一番好きなKibanaの機能であるDev ToolsのConsoleについても記載してあります。こちらも合わせて目を通していただければと。\nみなさんのフィードバック(ツイート、ブログ、Amazonのコメントなどなど)をお待ちしております!\n","date":1505955750,"dir":"post/2017/","id":"4f88f3eebe44285ded812939553ef94c","lang":"ja","lastmod":1505955750,"permalink":"https://blog.johtani.info/blog/2017/09/21/release-intro-logging-analysis-system/","publishdate":"2017-09-21T10:02:30+09:00","summary":"久々に執筆しました。といっても、以前の書籍の更新版です。 まぁ、更新版といっても、私以外の方々は結構な量を書き直しor新規書き起こしされてます","tags":["elasticsearch","kibana","本"],"title":"データ分析基盤構築入門 を一部執筆しました。"},{"contents":"久々のブログ。 Elasticsearch勉強会を主催してますが、 プロダクトを超えて、検索で共通してある課題とか、悩みとか、あるかなぁと。 その辺りを話す場所を考えてみるのいいかもと思い、検索座談会ってのを5人でやってみた。\nとりあえず、初めてなので、5名ほどで。プロダクトはかぶってない感じでした。\n話した議題はこの辺り。 形態素解析の辞書は何を使ってる?有償のもの? そもそも形態素解析? 辞書の更新とかは? シノニムってどうしてる? サジェストとかのデータはどう作ってる?どうしてる? 検索ログとかから作ってる? 検索結果のランキングって検索結果だけで決めるの? 検索漏れとかキーワードのミスマッチとかどうしてる? 今後話したい内容はこの辺かな? 緯度経度系の検索 画像検索、音声検索 検索のキーワードの調査とかしてる人とかいるかな? どんな機能が欲しい? 前処理としてはどんなことをしてる? このあとどうしていくかはまだ考え中。知り合いを捕まえて、どんなことしてるかを聞きにいくのもいいし、議題みたいなことを決めて、それを話してくれそうな人にコンタクトして議論するのもありかなぁ。 普通の勉強会みたいなのにするかもしれないし。 とりあえず、どのくらい興味を持ってる人がいるのかがわからないので。。。\nもちろん、Elasticsearch勉強会は別でやっていきますよ。\n","date":1495639453,"dir":"post/2017/","id":"29b4c2b5adcd80ced1612128b3ca95a9","lang":"ja","lastmod":1495639453,"permalink":"https://blog.johtani.info/blog/2017/05/25/search-meetup/","publishdate":"2017-05-25T00:24:13+09:00","summary":"久々のブログ。 Elasticsearch勉強会を主催してますが、 プロダクトを超えて、検索で共通してある課題とか、悩みとか、あるかなぁと。 その","tags":["勉強会"],"title":"検索座談会ってのをやってみた"},{"contents":"今年はRioのプレイバック\u000e見ながら書いてます。 今年はなんか長い一年だった気が。\n振り返り(2015年に書いた抱負から) まずは去年の抱負を元に。\n英語の継続 継続してます。まぁ当たり前ですが。もう少し話す機会増やさないとだなぁと思いつつ。英会話しながら、海外TVドラマ見ながら。 見たドラマはこの辺かな?\nER SUITS メンタリスト Numb3rs エレメンタリー Agent of Shield あと、映画も見てます。とりあえず、耳を慣らすために字幕ありで見てるので、 英語だけでとは行きませんが。。。 そろそろ同じ映画を英語字幕で見るとかしたほうがいいのかもなぁ。\nもっとElasticsearchの開発に参加 一応参加してます。ちょっとずつですが。 イベントが重なるとできなくなるので、小さなPRとかを細々とって感じですが。。。\n人員の倍増? 倍増したかな?現時点で日本は8名になりました。そのうち1人は完全リモートです。 来年も倍増とは行かないだろうなぁ。取り急ぎ、サポートエンジニアが足りてないのでそこを埋めないと。。。\n日本語情報発信 これはちょっと足踏みしてるかも。ブログの翻訳とかはやってるんですが、もう少しなんとかしないとなぁ。ブログも書かないと。。。\nSplatoon S+? なりました!とりあえずS+とSを行ったり来たりしてる感じです。 メインはノヴァネオですが、Sに落ちたら違う武器でS+に上がるまでチャレンジするってのをやってます。わかば、バケスロソーダ、プライム、ワサビくらいはやったかな? そろそろまた違う武器かなぁ。S+99は無理そうなんで。。。\n振り返り(今年あったできごと) その他の今年の出来事。\n初香港 初プラハ OSCなど、東京以外でのカンファレンス参加 厄年 東京オフィス! BBLとかトレーニング lucene-gosenをちょっとメンテ Podcastデビュー? 初モノ今年も多いかな。 今年は、昨年よりは長く感じた一年でした。 月1くらいで出張してたのもあるのかなぁ? 香港、プラハはもちろん会社のイベントです。 香港はジャッキーチェンの映画を彷彿とさせるところがちょくちょくあって面白かったです。 ビルとかの補修の足場が竹竿とか。 プラハも面白かったです。やっぱりヨーロッパの古い町は歴史のある建物が多くて楽しいです。\nOSCなどのイベントも色々行きました。福岡、名古屋、大阪、京都、札幌と回りました。 それとは別に大阪、福岡も行ったかな。 来年は沖縄と広島に行きたいなぁ。。。 出張のついで?じゃないですが、御朱印集めし始めました。神社仏閣もいいですよねぇ。\n厄年はきつかった。。。たまたまだとは思うけど、お祓いに行ったのが効いたのかなぁ。後半は特に問題なかったかな。腕時計無くしたと思ったら見つかったりしたし。\n弊社東京オフィスができました。(あんまり行ってないけど) ときどきアクロクエストさんがセミナーを開いたりしてます。 昨年のTour Tokyo後のMeetupでもイベントスペースを使って、Drinkup(勉強会の懇親会だけバージョン)もやりました。 今後もちょこちょことイベントをやってみようかな?\nBBLも始めました。あまりきちんと宣伝してないからそれほど依頼は来てないですが。 あとは、今年も2回日本語でトレーニングしました。 前回はほぼ満席にまでなりました。 来年も頑張りたいかな。ショートカットするためにもいいと思うんで、トレーニングを受けて欲しいんです。。。\nlucene-gosenのメンテもしました。 といってもプログラムではなく、ビルドシステムをAntからGradleに変更したんですが。 来年もちょっとずつ触りたいな。機能面で拡充するかはわからないですが。。。\nPodcastにもデビューさせていただきました。 wyukawaさんのPodcastです。「johtaniさんとElasticsearchについて話しました」楽しかったです。 また出たいなぁというか、喋るの面白かった!\n来年の抱負 もちろん英語の継続 継続的にイベントに登壇 もっと開発&ブログ サポートエンジニア獲得! 個人的な検索勉強会の再開 英語はまぁ、当たり前ですね。会社の人つかまえてもっと喋る時間増やさないとだな。\n来年もいろんなカンファレンスなどに出てブース出したり、セッション持ったりして もっともっと広めていかないとなぁ。 あとは、勉強会とMeetupもやっていかないと。入門編と上級編みたいに分けてみるのもありかなぁと考えて見たり。 スピーカー、ご意見募集しております。\n開発に時間をさくための時間の活用をしていかないとなぁと。 どうも時間の使い方がまだ上手くないので。ブログも一緒ですね。。。 月1くらいのペースではかきたいな。。。 ブログもそうだけど書籍もかな???? あと、外資系の他の会社の人ともまた飲みたいなー。\n開発の時間を確保という面ではサポートエンジニアも募集中です。 最近、クライアントが増えて来てチケットが増えて来てるんで、サポートしたりもしてるんです。。。 自分の時間を増やすためにもサポートエンジニアを確保しないと。誰かいい人いないかなぁ。\n個人的にやってた勉強会を忙しいって言って中断してるので、再開しないと。。。\nということで、今年もあと數十分になってしまいました。 今年も色々な方に助けていただけました。お世話になりました。 この場を借りてお礼申し上げます。\n来年もいろんな方々に助けてもらうと思いますが、よろしくお願いいたします。\n","date":1483190534,"dir":"post/2016/","id":"16f1046144ad9ee7bb96214ba7ae7516","lang":"ja","lastmod":1483190534,"permalink":"https://blog.johtani.info/blog/2016/12/31/looking-back-2016/","publishdate":"2016-12-31T22:22:14+09:00","summary":"今年はRioのプレイバック\u000e見ながら書いてます。 今年はなんか長い一年だった気が。 振り返り(2015年に書いた抱負から) まずは去年の抱負を元に","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2016)"},{"contents":"Merry Christmas! Elastic stack Advent Calendar 2016 最終日の記事になります。\n簡単に今年の変遷を振り返ってみます。\nElasticsearch 2.2 (2月) Elasticsearch 2.2.0、2.1.2、1.7.5リリース クエリプロファイラやGeo系の性能改善などが取り込まれました。 また、同時期にリリースされたKibana 4.4ではColor pickerやShare用のURLの短縮化機能なども追加されました。\n第2回目のユーザカンファレンス、Elastic{ON}開催(2月) サンフランシスコで、弊社第2回目のカンファレンスが開催されました。 2015年の会場よりも大きくなり、多数の方に参加いただきました。 ここで、以下の発表がありました。\nElastic StackとX-Packの紹介 これまで、ELK stackと呼ばれて意味明日が、Beatsチームの参加により、ELKだけではなくなったこともあり、Elastic Stackと呼び名を変える事になりました。 また、Marvel、Shield、Watcherなどの商用の拡張機能についても、 単体の名称ではなく、X(Extension)-Packと1つの名前になる事に。 詳細については公式のブログをご覧ください。\nElastic CloudとElastic Cloud Enterpriseの発表 2015年にElasticにジョインし、 これまでFound.no(Found)と呼ばれていた弊社のElasticsearch as a ServiceがElastic Cloudと名称変更しました。 また、Elastic Cloudで培っているノウハウを詰め込んだElastic Cloud Enterpriseも発表しました。実際に利用可能になるまでには まだもう少しかかってしまいますが、アルファ版が公開されていますので、興味のある方は触ってみてください。\nElastic{ON}2016で撮影された、「Elasticsearchがないあなたの人生はどうなりますか?」 といった面白い動画も公開されています。\nElasticsearch 2.3リリース(3月) Elasticsearch 2.3.0および2.2.2をリリース Reindex APIが登場し、Mappingの変更やShard数の変更など、色々とデータの更新などがやりやすくなりました。 また、Task Managementの機能も追加され、長時間かかる処理を間違った場合などの対処が楽になりました。 個人的には、Deprecation Loggingの機能が導入されたことが嬉しいこととなります。次期メジャーバージョンで廃止される機能についてログに出力されるようになりました。 実際に運用されているアプリで利用している機能が今後なくなるかどうかをログを見るとわかるという仕組みです。\nRally登場(4月) Rally登場:Elasticsearchのベンチマークツール Elasticsearchのベンチマークツールがリリースされました。 定期的にElasticsearchの性能を計測することは問題点を見つける事に役に立ちます。そういった手助けをしてくれるツールが公開されることは非常に便利なことかと。\nElastic Stack 5 alpha1 リリース(4月) Elastic Stack 5.0.0 alpha 1 リリース Ingest NodeやLucene 6、新しいKibanaのUIなど多くのものが詰まっていました。ここから多くのユーザにテストしてもらい、5.0の正式リリースを迎えることができました。\nElasticsearch 2.4.0リリース(8月) 2.xの最後のマイナーバージョンリリースです。 Reportingなどの追加とドットつきフィールド名の復活がありました。\nElastic Stack 5.0.0 beta1 リリース(9月) Elastic Stack Release - 5.0.0-beta1 ついにベータです。Painlessがスクリプトのデフォルトになったり、TimelionがKibanaに取り込まれるなど、正式リリースまであと少し!\nPrelertチームジョイン(9月) Welcome Prelert to the Elastic Team Machine Learningエンジンを開発し、Elasticsearch,Kibanaとの組み合わせの製品をリリースしていたPrelertという会社がジョインしました。 Elasticsearchに保存された多くのデータをより活用していただくことができるかと思います。 Elastic{ON} Tour 2016 Tokyoで弊社SAの大輪の発表も人気があるものでした。まだベータ段階ですが、利用して見ることも可能です。 ビデオなどが公開されたらまたツイートしようと思います。\nElastic{ON} Tour Tokyo 2016開催(12月) 今年で2回目のTokyoローカルの1日イベントでした。 ブログは「まだ」書いてませんが、、、今回も盛りだくさんのイベントになりました。 早朝のトレーニング(ハンズオンではない)にも80名近くの方に参加していただけましたし、私はKibanaのキーノート+デモという大役をもらいましたし、ちょっと大変でした。 今年もAMA(Ask Me Anything)ブースが大盛況でした。 色々な方から、弊社のサポート、開発者が色々な質問を受け、それに答えるという形です。楽しんでいただけたかと思います。 来年もぜひ開催したいなと思っています。\nまた、Elastic{ON}17のセッションもいくつか発表されています。 ぜひ、サンフランシスコで行われる本場のカンファレンスにもご参加ください!\n来年は? 1月後半か2月にElasticsearch勉強会を検討しようと思っています。スピーカーに興味のある方は連絡いただければと。\n会社としては、Elastic{ON}2017が3月にまた開催されます。これで3回目となります。もちろん私も参加予定なので、参加される方は、現地で会いましょう!\nそのほかにもBIG DATA ANALYTICS TOKYOやオープンソースカンファレンス(大阪)、デブサミといったカンファレンスに参加(登壇・ブースなど)予定です。 参加される方は、ぜひブースまでお越しください。\nでは、また来年のAdvent Calendarでお会いしましょう!\n","date":1482591830,"dir":"post/2016/","id":"002d980d74d19b43ff4e2446665e2fe5","lang":"ja","lastmod":1482591830,"permalink":"https://blog.johtani.info/blog/2016/12/25/elasticsearch-6-features/","publishdate":"2016-12-25T00:03:50+09:00","summary":"Merry Christmas! Elastic stack Advent Calendar 2016 最終日の記事になります。 簡単に今年の変遷を振り返ってみます。 Elasticsearch 2.2 (2月) Elasticsearch 2.2.0、2.1.2、1.7.5リリース クエリプロ","tags":["elasticsearch"],"title":"2016年のElastic Stack"},{"contents":"Elastic stack Advent Calendar 1日目の記事になります。\nElasticsearch 5.0が10月末にリリースされました。 リリースのブログでいくつか紹介されているのですが、そこでは紹介されていない機能について2、3紹介しようと思います。\nその前に、5.0、あれ?その前は2.xじゃなかったっけ??と困惑されている方もいるかと思うので、簡単に5となった経緯の紹介をしようかと。\nバージョン番号 なぜ2から5に飛んだのかという話ですが、このスライドがその紹介になっています。\nhttps://speakerdeck.com/johtani/elastic-stack-5-dot-0-alpha1-alpha5?slide=5\nElastic{ON} 2016のキーノートでも紹介がありましたが、KibanaやLogstashとElasticsearchを組み合わせて使うときにバージョンのミスマッチで動かないというユーザの声が上がっていました。 2.xのリリースから、同じ日にKibana、Logstash、Beatsもリリースするようになったのですが、 やはり、バージョン番号が異なるため、ミスマッチで動かないというユーザが時々いました。\nElastic Stackという名称にもなったため、バージョン番号をそろえようという事になり、 Elasticsearch、Kibana、Logstash、Beats全てが5.0.0としてリリースされ、 今後は同じバージョン番号になります。\nちなみに、「5」になった理由はKibanaのメジャーバージョンが「4」だったためです。\nさて、では、いくつか機能の紹介を。\nReindex from remote cluster Reindexが2.3から導入されました。データの再登録ができるようになり、マッピングの変更や Shardの数の変更などが柔軟に行えるようになりました。 便利でしたが、あくまでも同一のクラスタでデータを登録し直す形でした。\n5.0からはこの機能に加えて、異なるクラスタからデータを取得してReindexを行うことができるようになりました。 こんな形になります。\nPOST _reindex { \u0026#34;source\u0026#34;: { \u0026#34;remote\u0026#34;: { \u0026#34;host\u0026#34;: \u0026#34;http://otherhost:9200\u0026#34;, \u0026#34;username\u0026#34;: \u0026#34;user\u0026#34;, \u0026#34;password\u0026#34;: \u0026#34;pass\u0026#34; }, \u0026#34;index\u0026#34;: \u0026#34;source\u0026#34;, \u0026#34;query\u0026#34;: { \u0026#34;match\u0026#34;: { \u0026#34;test\u0026#34;: \u0026#34;data\u0026#34; } } }, \u0026#34;dest\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;dest\u0026#34; } } usernameとpasswordはリモートのクラスタに認証の気候が存在する場合に利用できるオプションです。 また、ReindexのAPIはクエリを使用して、必要なデータだけを取得することが可能です。 この機能により、1.xや2.xのクラスタからデータを移行することが可能になります。\nCustom analyzer test using Analyze API もう一つ、ちょっとだけ便利な機能を紹介します。 独自にAnalyzerを定義(TokenizerとToken Filterなどを個別に設定)して、その挙動を確認するとき、2.xまでは、インデックスを作成してそのインデックスに対して_analyze APIを呼び出す必要がありました。\n5.xからは_analyze APIの読み出しのパラメータで指定できるようになりました。 こんな感じです。ここでは、lowercaseフィルタのあとに、{...}でstopフィルタを パラメータの中で、指定しています。\ncurl -XGET \u0026#39;localhost:9200/_analyze\u0026#39; -d \u0026#39; { \u0026#34;tokenizer\u0026#34; : \u0026#34;whitespace\u0026#34;, \u0026#34;filter\u0026#34; : [\u0026#34;lowercase\u0026#34;, {\u0026#34;type\u0026#34;: \u0026#34;stop\u0026#34;, \u0026#34;stopwords\u0026#34;: [\u0026#34;a\u0026#34;, \u0026#34;is\u0026#34;, \u0026#34;this\u0026#34;]}], \u0026#34;text\u0026#34; : \u0026#34;this is a test\u0026#34; }\u0026#39; ちょっとだけですが、Analyzerなどを試すのが楽になるのではないでしょうか?\nということで、以上が1日目の記事でした。 Logstashなど、他の5.0.0に関する記事もAdvent Calendarに空きがあるようなので、個別にかこうかなと思います。お楽しみに!\n","date":1480581270,"dir":"post/2016/","id":"550becdd08d00fb1e7fd00c2adc3d3d6","lang":"ja","lastmod":1480581270,"permalink":"https://blog.johtani.info/blog/2016/12/01/elasticsearch-5-dot-0-highlight/","publishdate":"2016-12-01T17:34:30+09:00","summary":"Elastic stack Advent Calendar 1日目の記事になります。 Elasticsearch 5.0が10月末にリリースされました。 リリースのブログでいくつか紹介されているのですが、そこでは紹介されて","tags":["elasticsearch"],"title":"Elasticsearch 5.0の便利機能紹介?"},{"contents":"久しぶりに、技術的なブログ書いてます。\nIngest Processorのプラグインを作ってみたくなったので、書いてみました。 ただ書いてみるんじゃ3番煎じになりそうなので、cookiecutterを使ってみました。\nと言っても、同僚のAlexがcookiecutter-elasticsearch-ingest-processorと言うテンプレートを作ってくれているのを使っただけですが。(https://discuss.elastic.co に投稿された記事で、使い方がアニメgifで説明されててわかりやすいです)\ncookiecutterとは、コマンドラインで質問に答えると、テンプレートからプロジェクトが生成できるツールです。 Elasticでは、カスタムBeatを作る時に利用する例がいつかの日本語ブログや発表資料で話題になっていました。 これのIngest Processorのプラグインバージョンです。\n今回は、NEologdも使ってみたかったので、Lucene Kuromoji for NEologdを利用して 指定した品詞の単語だけを抽出するProcessorを作ってみました。\nGitHubのプロジェクト:https://github.com/johtani/elasticsearch-ingest-kuromoji-pos-extract\nCookiecutterの使い方 Cookiecutterのインストールはサイトをご覧ください。\ncookiecutter gh:spinscale/cookiecutter-elasticsearch-ingest-processor あとは、出てくる以下の項目を指定するだけです。\nprocessor_type : Ingest Processorのタイプ名です。kuromoji_part_of_speech_extractとしました。(Alexのだと_を使うとちょっと問題があるので後述) description : readme.mdに利用されます。 developer_name : 名前を記載。Javaのファイルのヘッダに利用 elasticsearch_version : デフォルトで5.0.0-alpha4が指定されているので、特に指定せず 以上の質問に答えたら、プロジェクトのディレクトリ構造が出来上がってます。 プロジェクトのビルドなどにはGradleを利用します。\nプロジェクトのIntelliJ IDEA用のファイルを生成 build.gradleファイルでGradleのideaプラグインがapplyされているので、以下のコマンドを叩けばIntelliJ IDEAのプロジェクトファイル(?)が生成され、IntelliJで開けばすぐに開発ができる状態にできます。\ngradle idea コーディング あとは、必要処理をコーディングします。 実際にコーディングするクラスはorg.elasticsearch.plugin.ingest.kuromoji_part_of_speech_extractのパッケージにある以下の2つです。(パッケージ名にはprocessor_typeの名前が指定されている)\nIngestKuromojiPartOfSpeechExtractPlugin KuromojiPartOfSpeechExtractProcessor IngestKuromojiPartOfSpeechExtractPlugin Pluginというクラスは、プラグインをNodeのModuleとして登録する処理を書くクラスとなります。 生成してすぐは、次のような形になっています。(※importやクラス定義の部分は省略しています。)\n... public static final Setting\u0026lt;String\u0026gt; YOUR_SETTING = new Setting\u0026lt;\u0026gt;(\u0026#34;ingest.kuromoji_part_of_speech_extract.setting\u0026#34;, \u0026#34;foo\u0026#34;, (value) -\u0026gt; value, Setting.Property.NodeScope); @Override public List\u0026lt;Setting\u0026lt;?\u0026gt;\u0026gt; getSettings() { return Arrays.asList(YOUR_SETTING); } public void onModule(NodeModule nodeModule) throws IOException { nodeModule.registerProcessor(KuromojiPartOfSpeechExtractProcessor.TYPE, (registry) -\u0026gt; new KuromojiPartOfSpeechExtractProcessor.Factory()); } ... YOUR_SETTINGプロパティとgetSettings()メソッドはelasticsearch.ymlで指定したい設定を記述する場合の例になります。今回は特に必要ないので両方削除しました。 最終系はGitHubのコードをご覧ください。\nKuromojiPartOfSpeechExtractProcessor Processorは実際にIngest Nodeで行う処理を書くところです。\npublic static final String TYPE = \u0026#34;kuromoji_part_of_speech_extract\u0026#34;; private final String field; private final String targetField; public KuromojiPartOfSpeechExtractProcessor(String tag, String field, String targetField) throws IOException { super(tag); this.field = field; this.targetField = targetField; } @Override public void execute(IngestDocument ingestDocument) throws Exception { String content = ingestDocument.getFieldValue(field, String.class); // TODO implement me! ingestDocument.setFieldValue(targetField, content); } @Override public String getType() { return TYPE; } public static final class Factory extends AbstractProcessorFactory\u0026lt;KuromojiPartOfSpeechExtractProcessor\u0026gt; { @Override public KuromojiPartOfSpeechExtractProcessor doCreate(String processorTag, Map\u0026lt;String, Object\u0026gt; config) throws Exception { String field = readStringProperty(TYPE, processorTag, config, \u0026#34;field\u0026#34;); String targetField = readStringProperty(TYPE, processorTag, config, \u0026#34;target_field\u0026#34;, \u0026#34;default_field_name\u0026#34;); return new KuromojiPartOfSpeechExtractProcessor(processorTag, field, targetField); } } TYPEがIngest APIのPipelineでProcessorを指定するときに使う名前になります。ここは、cookiecutterの時にprocessor_typeに入力した文字列になっています。 kuromoji_part_of_speech_extractだと長いので、kuromoji_pos_extractに変えました。\nexecute()メソッドに// TODO implement me!とあります。 この部分に実際の処理を記述していきます。\nあとは、FactoryクラスでIngest APIで指定された設定項目を読み込みます。 今回作成したelasticsearch-ingest-kuromoji-pos-extractでは品詞を指定する必要があるので、pos_tagsを指定できるように処理を追加しました。\n私が実装したものの説明をするとちょっと長くなりそうなので、GitHubのコードをご覧ください。\nテストのコーディング テストのクラスもテンプレートで生成されています。\nKuromojiPartOfSpeechExtractProcessorTests KuromojiPartOfSpeechExtractRestIT KuromojiPartOfSpeechExtractProcessorTests Processorクラスのテストになります。生成直後は次のような感じです。\npublic void testThatProcessorWorks() throws Exception { Map\u0026lt;String, Object\u0026gt; document = new HashMap\u0026lt;\u0026gt;(); document.put(\u0026#34;source_field\u0026#34;, \u0026#34;fancy source field content\u0026#34;); IngestDocument ingestDocument = RandomDocumentPicks.randomIngestDocument(random(), document); KuromojiPartOfSpeechExtractProcessor processor = new KuromojiPartOfSpeechExtractProcessor(randomAsciiOfLength(10), \u0026#34;source_field\u0026#34;, \u0026#34;target_field\u0026#34;); processor.execute(ingestDocument); Map\u0026lt;String, Object\u0026gt; data = ingestDocument.getSourceAndMetadata(); assertThat(data, hasKey(\u0026#34;target_field\u0026#34;)); assertThat(data.get(\u0026#34;target_field\u0026#34;), is(\u0026#34;fancy source field content\u0026#34;)); // TODO add fancy assertions here } テストメソッドも実装されていますが、パラメータの追加の設定処理やアサーションが書かれてません。 実装に合わせて、アサーションや設定処理を追加しましょう。\nKuromojiPartOfSpeechExtractRestIT こちらはIntegration Testになります。 実際にElasticsearchに対して外部からAPIを叩くような感じです。 APIを叩くときに利用するJSONの設定やアサーションはsrc/test/resourcesにyamlファイルがあります。\n10_basic.yaml 20_kuromoji_part_of_speech_extract_processor.yaml 10_basic.yamlはプラグインがインストールされているかの確認のテストです。特に変更する必要はないです。\n20_kuromoji_part_of_speech_extract_processor.yamlは実際にコーディングしたProcessorが動くかどうかのテストです。\nテストの内容については、GitHubのコードをご覧ください。\nテストの実行とZipの生成 テストの実行とZipの生成は次のコマンドを実行すればOKです。\ngradle check テストに問題があった場合は、コケますし、問題なければSUCCESSと表示が出ます。 成功した場合はbuild/distributions/というディレクトリにzipファイルができています。 これをElasticsearchのpluginコマンドでインストールすれば動きます。\nbin/plugin install file:///path/to/elasticsearch-ingest-kuromoji-pos-extract/build/distribution/ingest-kuromoji_part_of_speech_extract-0.0.1-SNAPSHOT.zip kuromoji_pos_extractの利用方法 Ingest APIには便利なSimulate Pipeline APIがあります。\nということで、mecab-ipadic-NEologdにあったサンプルの文章を使って、使い方の説明です。\nPOST _ingest/pipeline/_simulate { \u0026#34;pipeline\u0026#34; : { \u0026#34;description\u0026#34; : \u0026#34;kuromoji neologd extract test\u0026#34;, \u0026#34;processors\u0026#34; : [ { \u0026#34;kuromoji_pos_extract\u0026#34; : { \u0026#34;field\u0026#34; : \u0026#34;body\u0026#34;, \u0026#34;target_field\u0026#34; : \u0026#34;noun_field\u0026#34;, \u0026#34;pos_tags\u0026#34; : [ \u0026#34;名詞-固有名詞-組織\u0026#34;, \u0026#34;名詞-固有名詞-一般\u0026#34;, \u0026#34;名詞-固有名詞-人名-一般\u0026#34;, \u0026#34;名詞-固有名詞-地域-一般\u0026#34;, \u0026#34;名詞-固有名詞-地域-国\u0026#34; ] } } ] }, \u0026#34;docs\u0026#34; : [ { \u0026#34;_index\u0026#34;: \u0026#34;index\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;type\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;id\u0026#34;, \u0026#34;_source\u0026#34;: { \u0026#34;body\u0026#34; : \u0026#34;10日放送の「中居正広のミになる図書館」(テレビ朝日系)で、SMAPの中居正広が、篠原信一の過去の勘違いを明かす一幕があった。\u0026#34; } } ] } 結果はこちら。\n{ \u0026#34;docs\u0026#34;: [ { \u0026#34;doc\u0026#34;: { \u0026#34;_index\u0026#34;: \u0026#34;index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;id\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;type\u0026#34;, \u0026#34;_source\u0026#34;: { \u0026#34;noun_field\u0026#34;: [ \u0026#34;10日\u0026#34;, \u0026#34;中居正広のミになる図書館\u0026#34;, \u0026#34;テレビ朝日\u0026#34;, \u0026#34;SMAP\u0026#34;, \u0026#34;中居正広\u0026#34;, \u0026#34;篠原信一\u0026#34; ], \u0026#34;body\u0026#34;: \u0026#34;10日放送の「中居正広のミになる図書館」(テレビ朝日系)で、SMAPの中居正広が、篠原信一の過去の勘違いを明かす一幕があった。\u0026#34; }, \u0026#34;_ingest\u0026#34;: { \u0026#34;timestamp\u0026#34;: \u0026#34;2016-07-22T06:18:49.007+0000\u0026#34; } } } ] } noun_fieldに固有名詞の単語が抜き出せているのがわかるかと思います。\nAlexのテンプレートで困った点 テンプレートは便利だったのですが、processor_typeに_を使用したタイプ名を指定すると次のような問題(?)が発生しました。\nクラス名がKuromoji_part_of_speech_extractProcessorとなってしまう 深刻な問題ではないのですが、JavaだとCamel Caseが普通なのでちょっと気になって。 ということで、プルリク作って出してみました。まだ取り込まれてないかな。\n取り込み前に使いたい方は以下のコマンドを実行してください。 processor_class_nameという項目が増えています。 デフォルトだとprocessor_typeの_の部分を取り除きつつCamel Caseにしたものが入ります。\ncookiecutter gh:johtani/cookiecutter-elasticsearch-ingest-processor まとめ ということで、とりあえず作ってみましたというものになります。 特徴的な単語(固有名詞だけ)を抜き出して、別のフィールドにできるので、タグみたいなものをこれを使って前処理で作れるようになるかなぁと。\n参考ブログ(元ネタ?) インスパイア元となったブログです。\nUser Agentを解析するIngest Pluginを書いてみた Elasticsearch 5.0.0のIngest Node用プラグインを書いた話 ","date":1469161616,"dir":"post/2016/","id":"a62186ea292d6db03a087bd5dfcc3f1e","lang":"ja","lastmod":1469161616,"permalink":"https://blog.johtani.info/blog/2016/07/22/making-ingest-processor-plugin-with-cookiecutter/","publishdate":"2016-07-22T13:26:56+09:00","summary":"久しぶりに、技術的なブログ書いてます。 Ingest Processorのプラグインを作ってみたくなったので、書いてみました。 ただ書いてみるんじゃ3番煎じ","tags":["elasticsearch","plugin"],"title":"Lucene Kuromoji for NEologdで指定した品詞の単語を抜き出すIngest Pluginを書いてみた #elasticsearchjp"},{"contents":"なんか、今年はよく物が壊れる、厄年だからかなぁ?\nということで、記念に何が壊れたかをブログに残しておこうかと。\n腕時計(壊れてないかな) 電波腕時計を使ってたんだけど、電池がへたってたのでオーバーホールしてもらった。 Moto 360(壊れたというか。。。) 何度かバージョンアップしてるんだけど、数ヶ月前から、ちょっと触っただけで電源が落ちる現象が。ファームウェアのせいかAndroid Wearのバージョンアップのせいかわからないけど。。。挙げ句の果てに、電源を入れるために充電器にセットしないといけないと言う酷い仕様。。。 自転車前輪 自転車で車道を横切る側溝の蓋の間に前輪がはまってすっ転んでしまい、タイヤのスポークがちょっと曲がってしまう ジーンズその1 自転車で転んだ時に、膝とかこすって破れる ジーンズその2 福岡出張中に雨で滑って派手に転んで、膝に大きな穴が。。。 リュック あー、怪しいなと思ってたんだけど、やっぱりこわれた、、、 pic.twitter.com/CD2Y7t6AOD\n\u0026mdash; Jun Ohtani (@johtani) 2016年6月16日 怪しいとは思ってたんだけど。。。 ということで、リュックを新調しつつ修理に出してるところ。 5. Xperia Z3 * 先週金曜日にカメラのレンズが結露してるなぁと思ったら、電源が入らなくなった。補償サービスに入ってたんで、新しいZ3を次の日に送付してもらい復旧。いろいろなアプリがログインしないといけないのでかなり大変だった。。。\nまだ、半年残ってるので他にも壊れるのかなぁ。。。 お祓いしてもらったので、何もなければいいんだけど。\nということで、なんとなく欲しいものリストを貼っておきますね。\n","date":1467251858,"dir":"post/2016/","id":"167e2a6833d49ce198cb3b88f521991e","lang":"ja","lastmod":1467251858,"permalink":"https://blog.johtani.info/blog/2016/06/30/broken-something-in-this-year/","publishdate":"2016-06-30T10:57:38+09:00","summary":"なんか、今年はよく物が壊れる、厄年だからかなぁ? ということで、記念に何が壊れたかをブログに残しておこうかと。 腕時計(壊れてないかな) 電波腕時","tags":["misc"],"title":"よく物が壊れる年"},{"contents":"第16回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 今回は、司会だけに注力してみました()。\nチェックイン数など チェックインした人:141名 キャンセルしなかった人:67名 でした。\n今回は、参加希望者が多くて、当日にも100名近いキャンセル待ちの方がいたので、 240名まで、参加者枠を増枠(会場キャパ190名程度)して対応しました。 まぁ、読み通り、1/3の方はキャンセルしない形でした。 天気も良く電車の遅延などもなさそうだったので、ちょっとドキドキしてたのですが。\n以下は簡単なメモです。\n「LogstashとElasticsearchで作るEnterprise Search Platform」/ Elastic Kosho Owa スライド:https://speakerdeck.com/kosho/enabling-enterprise-search-platform-with-elastic-stack\n使ってるLogstashの設定ファイルを elastic-japan at elastic dot co に送るとTシャツがもらえるらしい。 Logstashのfilter-rubyはここで、evalしてcallしてるから、特にforkとかしてないかと。 「企業・業界情報プラットフォームSPEEDAにおけるElasticsearchの活用」 / 株式会社ユーザベース 北内 啓さん スライド:http://www.slideshare.net/tau3000/speedaelasticsearch-63510388\nアルゴリズム関連の開発担当 企業データをいろんな軸で検索したい データ数が約70億レコードになりそう(通貨 x MySQL) 300万企業データ+Nestedとかで持ってる。 11万フィールド??? 10台の物理サーバに24仮想マシン 企業名の検索 recall重視 NewsPicksの検索機能 「日本 化粧品 売上高」業界のデータとかも観れるのかな?有料会員向け機能 登録済みキーワードかどうかをRDB+Esに検索して、ID化するっぽい ID(Analyze必要ない)検索だから、termクエリだった、サンプルが。 ノードの役割分担 更新はMasterNode経由でDataNodeへ。 検索はClientNode経由でDataNodeへ。 1.xかぁ。。。 「Elasticsearchベースの全文検索システムFess」 / 株式会社エヌツーエスエム 菅谷信介さん スライド:http://www.slideshare.net/shinsuke/elasticsearchfess\n10.xからSolrをやめてElasticsearchへ。 日本語検索 bigram+形態素(1文字検索とかに対応するため) NeologDに対応したkuromojiを利用 DBFluteをESFluteとしてEs対応 KOPFを組み込んで使ってる configをREST API経由で更新できるプラグインあり LT 「ElasticsearchとGCPのネットワークでハマった話」 株式会社サイバーエージェント 平田大地 さん @daichild スライド:https://speakerdeck.com/daic_h/gcpfalsenetutowakudehamatutahua\nhhkb2 2刀流! networkのKeep-alive周りで困ったよというお話。 後で聞いたけど、GCE Cloud Pluginは使ってるそうです。 06/28 17:00追記\nPingを定期的に実行させることで回避も出来るようです。 transport.ping_scheduleに時間を指定します。通常のNode(Transport以外)は\u0026rsquo;-1\u0026rsquo;が指定してあり、動作してません。 「スクリプトフィールドで作るランキングみたいな何か」iwag さん スライド:https://speakerdeck.com/iwag/elasticsearch-dezuo-rurankingu\n1.xかぁ。。。 あとは、function_scoreとかも面白いですよ! その他、感想などのブログ 第16回elasticsearch勉強会に参加してきた 第16回Elasticsearch勉強会に参加してきた まとめ+宣伝? 1.xがまだまだいますねぇ、早く2.xにアップしましょう!(5.0ももう直ぐだし)。懇親会でも色々と話しましたが、https://discuss.elastic.co というフォーラムあるので、ぜひ活用してください。\n次回は8月末か9月頭かでしょうか。 7月末にOSC京都に出没するので、京都で勉強会やりたいと思ってます! 会場とかスピーカーとか興味ある人連絡ください。\n東京の勉強会のスピーカーも随時募集中ですので、連絡ください。\n","date":1467089755,"dir":"post/2016/","id":"993e58f132740b464ecf06ee289dc7b2","lang":"ja","lastmod":1467089755,"permalink":"https://blog.johtani.info/blog/2016/06/28/16th-elasticsearch-meetup/","publishdate":"2016-06-28T13:55:55+09:00","summary":"第16回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズ","tags":["elasticsearch","勉強会"],"title":"第16回Elasticsearch勉強会を開催しました。 #elasticsearchjp"},{"contents":"第15回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 今回は、Elastic{on} 2016開催直後ということで、大半はElastic{on}に関する話でした。\nチェックイン数など チェックインした人:114名 キャンセルしなかった人:62名 でした。 今回は、少しおそめで1時間前にキャンセル待ちがいない状態にしました。 まぁ、いつもの感じでしょうか。数値も安定してきた感じですかね。\n\u0026ldquo;Elasticsearchと機械学習を実際に連携させる\u0026rdquo; / Preferred Networks America, Inc. CTO 久保田展行(Kubota Nobuyuki) さん スライド:Elasticsearchと機械学習を実際に連携させる\n前回の続きの話で、今回が本題でした。\n勉強会直前に発表されたSensorBeeをElasticsearchと一緒に使うとどんなことができるかというお話です。 まぁ、前処理重要ですよねというのが、いつものことですが、印象的でした。 いつものようにわかりやすい説明だったので、使ってブログを書いて欲しいなと。\n発表の中で、説明に出てきたデモとか。\nCES2016でロボットカーのデモを展示してきました \u0026ldquo;Elastic{ON} 2016レポート\u0026rdquo; / Elastic Jun Ohtani スライド:elastic{on} 2016 レポート\n写真多めで、キーノートをメインに話をしました。\n簡単なまとめとしては\nプロダクトロゴができました。ロゴ画像などはこちら 次のメインバージョンは全て5.0。(5.0に関する通知が欲しい人はこちらで登録できます) elastic{on} 2016のビデオなどはこちら BBL始めます。連絡ください \u0026ldquo;Elastic{ON}の過ごし方\u0026rdquo; / クラスメソッド株式会社 藤本 真司 さん スライド:Elastic{ON}の過ごし方\n印象に残ったのは\n「自他共に認めるブログの会社」 4/12にSAPさんに会場を借りてElastic&クラスメソッドでイベントやります。 やっぱりご飯が美味しいんですねぇ。 早速ブログが書かれてました。\n\u0026ldquo;Elastic{ON} 2016 見るべきセッション資料 7選\u0026rdquo; / Acroquest Technology株式会社 谷本 心 さん スライド:Elastic{ON} 2016 見るべきセッション資料 7選 #elasticsearchjp\n印象に残ったのは\n東京でハンズオンやる会場提供者募集中! Ingest Node(参考:Ingest Nodeのドキュメントは公開中。) Reindex API(参考:Backport reindex to 2.x ) その他、感想などのブログ 第15回elasticsearch勉強会にLTで登壇しました #elasticsearch #elasticsearchjp 第15回elasticsearch勉強会に参加してきました #elasticsearch #elasticsearchjp まとめ+宣伝 来年のElastic{ON}に参加したいと思っていただけたらよかったなと。\n4/12にクラスメソッドさんとイベントを行います。また、ツイートすると思います。\n次回はいつも通りだと5月中旬になるかと思います(大丈夫かな?OSC 2016 Nagoyaでしゃべったり、ブース出したりとかするけど)。 5末に名古屋に出没します。名古屋で勉強会できればやりたいと思ってます。会場とかスピーカーとか興味がある方は連絡ください。\n","date":1458186180,"dir":"post/2016/","id":"c56a76ef8f604a8d87be2a32b1f81fac","lang":"ja","lastmod":1458186180,"permalink":"https://blog.johtani.info/blog/2016/03/17/15th-elasticsearch-jp/","publishdate":"2016-03-17T12:43:00+09:00","summary":"第15回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズ","tags":["elasticsearch","勉強会"],"title":"第15回Elasticsearch勉強会を開催しました。 #elasticsearchjp"},{"contents":"久々のポスト。。。\n久々に、技術書読んでます。「自然言語処理の基本と技術」という本です。\n監修の方のツイートを見て気になったので、買ってみました。 書籍のサイトの説明はこんな感じでした。\n本書は、この未来に不可欠となるに違いない自然言語処理の、技術的、ビジネス的基礎知識をくまなくコンパクトに図解した一冊です。 著者陣もそれぞれの分野の第一線で活躍するエキスパート揃い!\n確かに著者陣がすごいです。\nまだ、「はじめに」と自分に関係のある「情報検索」の章を流し読みしただけなんですが、次のような特徴がある本です。\n平易な単語で説明してある(難しい専門用語が少ない) 数式が出てこない(多分。少なくとも読んだ部分では見てない) 説明には例と図解がある 情報検索の章で言うと、全文検索でよく使われる転置インデックス(索引という単語が使われてる)がなぜ必要なのか、どういう感じで作られるのか、 転置インデックスに利用する索引の単語をどうやって作るのか(文字N-Gramや形態素解析)、単語の正規化(ステミングやストップワード)などの説明が 本当にわかりやすく書かれています。 スコアリングについても触れられています。\nElasticsearchも転置インデックスを用いた検索を行っており、 MappingでAnalyzerの指定をしている理由などの理解に役に立つと思います。\n全文検索システムがどのように検索を処理しているかをざっくり理解するのにはもってこいじゃないかと。 1点残念だなと思ったのは、書籍に「索引」がありませんでした(本の索引を思い浮かべてくださいっていう説明あったんだけど)。。。 Kindle版を購入すれば「検索」できるのかな?\nということで、まだ、流し読みしただけなんですが、「すごく」オススメです。 購入はこちらから!\n","date":1457962452,"dir":"post/2016/","id":"3fc7462a83fa55885067fee629287e8a","lang":"ja","lastmod":1457962452,"permalink":"https://blog.johtani.info/blog/2016/03/14/review-basics-and-tech-of-nlp/","publishdate":"2016-03-14T22:34:12+09:00","summary":"久々のポスト。。。 久々に、技術書読んでます。「自然言語処理の基本と技術」という本です。 監修の方のツイートを見て気になったので、買ってみました","tags":["本"],"title":"「自然言語処理の基本と技術」を読んでる"},{"contents":"あけましておめでとうございます、johtaniです。\n第14回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 今年もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\nチェックイン数など チェックインした人:122名 キャンセルしなかった人:58名 でした。 今回も当日の昼の時点でキャンセル待ちがない状態にしていました。 いくつか電車が止まっていたという話を聞いていたので、開始を5分遅らせ、 受付は45分くらいまで開けておくという対応をしてもらいました。\n\u0026ldquo;ココが辛いよelasticsearch\u0026rdquo; / 株式会社リクルートテクノロジー @tatakaba さん スライド:ココが辛いよelasticsearch\n実際にいくつかのサービスで運用されている内容とどういった機能を利用しているか、 どういったものを独自に作っているかという話をしていただきました。\n独自PluginでA/Bテストしてる Snapshotの活用 Index作成は環境に合わせて行っている。 バージョンは混在 PusnaRSのバージョンアップの話。 2つのバージョンのクラスタを用意してリアルタイムに切り替え。 Elasticsearchの活用 QueryのRewrite: SolrのリクエストをEsで受け付けたり。 辛い話。 バージョンアップが辛い Riverなくなるのつらい データずれるのつらい 補足:\nバージョンアップについて 1.x系から2.x系にアップされるのであれば、こちらを必ず試してください。\nhttps://github.com/elastic/elasticsearch-migration\n「.」が使えなくなるという話は、Solrとの大きな違いになるのかもなぁと。 ネスト構造のデータの表記を「.」で行うというのを厳密に行えるように、 「.」を使えなくしたというのがあるかと。\nRiverについて Riverがなくなった理由については、https://www.elastic.co/blog/deprecating-rivers で記載があります。 便利なのですが、負荷が偏ったり、スケールしないとかいう問題点があるかなと。\n良いサンプルとしては、JDBC Riverなどは、Javaのプログラムとして起動できるように変更されていたりします。\nhttps://github.com/jprante/elasticsearch-jdbc/wiki/jdbc-plugin-feeder-mode-as-an-alternative-to-the-deprecated-elasticsearch-river-api\n(個人的 には、SolrのDIHもRiverもあんまり好きではなかったです。データの変換処理と、ロード処理は別々にしたい人だったので。)\nデータのズレなど 耐障害性とか信頼性に関しては、どういった問題点があるのか、どういった対応をしているのかというのがまとめられたページが用意されています。\nhttps://www.elastic.co/guide/en/elasticsearch/resiliency/current/index.html\n「機械学習を利用したちょっとリッチな検索」 / Preferred Networks America, Inc. CTO 久保田展行(Kubota Nobuyuki) さん スライド:機械学習を利用したちょっとリッチな検索\n来日していただき、機械学習と検索の話をしてもらいました。 本編は次回の発表かもw\n機械学習を元に、検索対象の情報を元の情報から増やしてあげる。 増えた情報を検索できるようにする 今日のゴール: 機械学習とはどういうものか? データの集め方とか、アノテーションとか 学習の方法(ツールやライブラリに依存) Esでの活用方法 オフラインで学習させて、情報を付与した後に、Elasticsearchに入れる Jubatus+fluentdで ChainerサポートのOSSのツールを公開予定 「ここからが本当の地獄だ。。。」ってのが聴きたいw\n「Lucene Query 再考 - Domain Specific Query 実装 -」 / Supership株式会社 インフラ事業開発本部検索グループ 大川真吾 さん スライド:Lucene Query 再考 - Domain Specific Query 実装 -\nLuceneのクエリに関する話と、クエリパーサーに関する話でした。 こういった濃い話も勉強会でしてもらえると、色々な参加者に楽しんでいただけるかなぁと。 次回も続きを話してもらう予定です。\n補足:\n参考までにですが、Elasticsearchに入門したての人向けに、 Analyzerとか転置インデックスとかの話をした時のスライドになります。 https://speakerdeck.com/johtani/lucenetori-ben-yu-falsejian-suo\nLT: Fluentd meets Beats / @repeatedly さん スライド:http://www.slideshare.net/repeatedly/fluentpluginbeats-at-elasticsearch-meetup-14\n参考Qiita:http://qiita.com/repeatedly/items/77af41788f0b3ccdefd2\nBeatsの説明をTDの人からしてもらうなどw FluentdにBeatsからのデータを流し込めるようにしたプラグインが出たという話でした。\nfilebeatの性能の件は社内で聞いてみようかと。\nElasticsearchインデクシングのパフォーマンスを測ってみた / 日本IBM 黒澤亮二さん スライド:Elasticsearchインデクシングのパフォーマンスを測ってみた\n参考Qiita:http://qiita.com/rjkuro/items/e79eec7ffb0511b7c678\n細かな性能測定の結果を駆け足で話してもらいました。 皆さんもこの指標をもとに、手元の環境を計測してみたりしてみてもらえればと。\nあとは、2.x系になってるので、同じ方法で計測してもらってまた 発表してもらえると嬉しいなー(棒)\nその他、感想などのブログ Elasticsearch勉強会 第14回フィードバック まとめ+宣伝 久々に(初めてかな?)、ゲストがいないのに自分が喋りませんでした。 次回は3月中旬を予定してます。 次回は、Elastic{ON}16の報告をする予定です。いろいろと発表あるだろうし。\nあと、今月末の1/29にオープンソースカンファレンス 2016.enterprise@Osakaにブース出展します。 セミナー枠でも弊社OSSプロダクトの概要を話しする予定です。 関西の方は、ぜひ参加していただければと。ブースでお待ちしております。\nまた、スピーカーや場所が用意できたら、出張勉強会もまたやりたいなと思っています。 興味ある方は、連絡ください!\n","date":1452220496,"dir":"post/2016/","id":"4b0a768585da8f9f8f8db1ca409e7ebd","lang":"ja","lastmod":1452220496,"permalink":"https://blog.johtani.info/blog/2016/01/08/14th-elasticcsearch-jp/","publishdate":"2016-01-08T11:34:56+09:00","summary":"あけましておめでとうございます、johtaniです。 第14回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆","tags":["elasticsearch","勉強会"],"title":"第14回Elasticsearch勉強会を開催しました。 #elasticsearchjp"},{"contents":"今年は紅白見ながら書いてます。 早い一年だったなぁ。\n振り返り(2014年に書いた抱負から) まずは去年の抱負を元に振り返りをば。\n英語の継続 海外のイベントへの参加 多岐にわたるイベントでのスピーカー 日本の人員の倍増!? Elasticsearchに関する日本語の情報発信 Elasticsearch座談会みたいなものの開催 英語はまぁ、継続してます。亀の歩みですが。。。\n海外のイベントへの参加は、自社のイベントだけでした。来年のElastic{ON}ももちろん参加です。来年こそBerlin Buzzwords行きたいな。。。\n多岐にわたるイベントとまではいってないですかね。。。来年はOSC(大阪や東京)に出没予定です。参加される方は、声をかけていただければと。\n人員は倍増しました!営業の方が参画されたのがかなり助かってます。 今現在で4名です!来年も倍増できるかなぁ?\n日本語の情報発信はリリースブログの翻訳が多めでした。来年は独自コンテンツも増やさないとなぁ。 あとやっぱ書籍かなぁ。。。座談会は来年の課題に。。。\n振り返り(今年あったできごと) その他の今年の出来事。\n初渡米 初バルセロナ 東京以外で勉強会 初自社イベント(日本で) 初トレーナー 不惑 今年も初モノ多いですね。今年も楽しい一年でした。 自社イベントでアメリカやバルセロナなどに行きました。40年近く、海外に行ったことないせいか、海外に行って経験することが面白いです。\n東京以外での勉強会もやりました。名古屋、大阪、京都、北海道と。 来年もOSCで訪れた場所で勉強会を開催したいなぁと。\n自社のイベント(Elastic{ON} Tour Tokyo)も東京でやりました。 どうなることかと思っていましたが、朝から大勢の方に来ていただけてホッとしました。 自分のトークがどうだったのかという反応も気になりますが。。。 せっかくShayたちが来ていたので、もっとブースに話しに来てもらえるともっと嬉しかったかもなぁと。\nTour Tokyoを挟んで自社の公式トレーニングのトレーナーもやりました。 日本で3回目にして、初の日本語でのトレーニングでした。前の2回は逐次通訳だったんですが。 トレーニングって大変だなぁと思ったのと、やはり日本語でトレーニングを受けられるとだいぶ違うだろうなという実感がありました。 来年もできればいいなと。トレーニング自体があったことを知らない人もいたのかなぁ?\n来年の抱負 英語の継続 もっとElasticsearchの開発に参加 人員の倍増? 日本語情報発信 Splatoon S+? 英語あいかわらず出来てないので、頑張らないと。 もっと喋ったりしないとなんだろうなぁ。\n来年は開発をもっとやりたいなと。 来年1月にはセールスのエンジニアが加入するので、開発にもっと時間を割きたいなと。\n人員は倍増できるように頑張りたいです。少なくとも、2人が1月に入ることは決まってるんで、後二人!\nブログももっと書かないとですね。新機能とかこんな使い方できるよとか。 どんな記事が欲しいかとかコメントもらえると楽なので、突っ込みくださいw\n最後は、完全に私用ですね。Splatoonにはまってますw SとA+を行ったり来たりで。。。\nということで、今年はあと、数時間ですが、色々とお世話になりました。 この場を借りてお礼申し上げます。\n来年も、いろんな方に絡んでいくとは思いますが、よろしくお願いいたします。\n","date":1451565182,"dir":"post/2015/","id":"c54909ecf4fb3e9afeea36200fe95dce","lang":"ja","lastmod":1451565182,"permalink":"https://blog.johtani.info/blog/2015/12/31/looking-back-2015/","publishdate":"2015-12-31T21:33:02+09:00","summary":"今年は紅白見ながら書いてます。 早い一年だったなぁ。 振り返り(2014年に書いた抱負から) まずは去年の抱負を元に振り返りをば。 英語の継続 海外の","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2015)"},{"contents":"今年最後のAdvent Calendarとなります。\nこの記事はElasticsearch Advent Calendar 2015の最終日のエントリです。\n簡単に今年の変遷を、Elasticsearchをベースに振り返ってみようかと思います。\nKibana 4リリース(2月) Kibana 4(日本語訳) いきなり、Elasticsearchではない話題ですが。 AggregationベースのKibanaがリリースされました。 画面が黒くないというので、話題になりましたw 12月末時点では、4.3.1になっています。 Sub Aggregationによる強力なグラフ表示や異なるインデックスに対するグラフを 一つのダッシュボードに表示できるといったことができるようになりました。\nセキュリティ向けプラグインShieldのリリース(2月) セキュリティ向けプラグインShieldのリリース(日本語訳) 商用向けのプラグインの第2弾です。 セキュリティ強化のためのプラグインで、いろいろなところで引き合いがあったりします。\n初のユーザカンファレンス、Elastic{ON}開催(3月) #elasticon に参加中 サンフランシスコで、弊社初のカンファレンスが開催されました。(来年(2016年)もサンフランシスコで開催されます。) また、ここで、以下の2点の発表がありました。\nロゴ及びドメイン名などの変更 Foundのジョイン 約1300名が参加する大イベントでした。 初の渡米で楽しんできましたが、ドメインの切り替えなどは大変でした。。。 まだ、ロゴを変えて1年経ってないということが実感できてないです。\nFoundのジョインはまだまだ、日本で知名度が出てないかもなぁと。 もっと広めないと。 利点としては以下の通りです。\n新バージョンがすぐに利用可能に。また、バージョンアップも画面で指定可能 公式プラグイン+その他いくつかのプラグインが利用可能 Elasticsearch 1.5 リリース(4月) Elasticsearch 1.5.0リリース(日本語訳) 主に、resiliencyに関する改良になります。 毎リリースで信頼性向上につながる改良が含まれる形になっています。 このリリースの近くで初の東京の外での勉強会を名古屋で開催したりもしました。\ndiscuss.elastic.coをオープン(5月) https://discuss.elastic.co これまでは、Google Groupsを使っていましたが、Elasticが提供しているプロダクトが 別々のグループであったために、プロダクトにまたがった質問がやりにくかったり、検索がしにくかったりという問題点がありました。 今では、過去のGoogle Groupsのデータも移行されているので、是非参加して、質問・回答してみてください。 日本語でやりとりできるカテゴリもあるので、どんどん、やりとりしていただければ。\nElasticsearch 1.6 リリース(6月) Elasticsearch 1.6.0リリース(日本語訳) 2.0に向けたUpgrade APIが含まれるなど、次期リリースに向けた準備が整いつつあるリリースでした。 他にもsynced flushの取り込みやレスポンスのJSONのフィルタリングなど細かな改善も取り込まれています。\nFound PremiumとStandardリリース(7月) さらに進化したFound(日本語訳) Foundに弊社のサポートチームがサポートできるプレミアムが追加されました。 これにより、商用プラグインとして提供しているShieldが(現在はWatcherも)利用できるなど、 より便利になりました。また、Kibana 4も無料で提供されていたりします。\n小さなサイズのものですと、無料で試していただけるものもあるので、試してみてもらえればと。\nElasticsearch 1.7 リリース(7月) Elasticsearch 1.7.0 および 1.6.1リリース(日本語訳) 1.x系、最後のリリースでした。 小さい改善ですが、セキュリティフィックス、クラスタの安定化に寄与する機能改善が含まれています。\nこのリリース直前に大阪、京都で勉強会も開催してみました。\nElasticsearch 2.0.0-beta1 リリース(8月) Elasticsearch 2.0.0-beta1リリース(日本語訳) 待ちに待った、Lucene 5ベースのElasticsearchの登場でした。 doc_valuesがデフォルトになったり、エラーが構造化されて見やすくなったり、 Pipeline Aggregationが導入されたりしています。 また、問題点の洗い出しも兼ねて、ベータリリースとして、本リリースまでに多くのIssueをあげていただきました。\nElasticsearch 2.0.0 リリース(10月) 2.0の本リリースです。リリースまでに、beta1、2及び、rc1がリリースされました。\n追加された機能や目玉の改善については「Elasticsearch 2.0の紹介」のスライドを参考にしていただければと。\nまた、Elasticsearch 2.0のリリースに合わせて、商用プラグインやLogstash、Kibanaの新しいバージョンがリリースされました。 Kibanaなどは、プラットフォームとしての機能を備え、SenseやTimelionと言ったプラグインアプリもリリースされています。\nLogstash 2.0.0リリース(日本語訳) Kibana 4.2.0リリース(日本語訳) Senseの歴史 - Sense 2.0.0-beta1の紹介(日本語訳) Shield、Watcher、Marvel 2.0.0 GAリリース(日本語訳) Elasticsearch 2.1.0 リリース(11月) Elasticsearch 2.1.0 and 2.0.1 released Beats 1.0.0のリリース(11月) The Beats 1.0.0 Go言語で書かれた軽量データシッパーになります。 パケットをキャプチャしてElasticsearchに送るPacketbeat、 topコマンドで取れるデータなどをTopbeat、 ログファイルなどを取り込み配送するFilebeatがリリースされました。\nlibbeatと呼ばれる、 ベースとなるライブラリを元にしたプロダクトで、Logstashのエージェントのような使い方もできるようになっています。\nGo言語に興味のある方などは、調べてみてはいかがでしょう?\n来年は? 日本では、1/7に第14回Elasticsearch勉強会を開催します。 すでに、38名のキャンセル待ちとなっていますが、おそらく、年明けにキャンセルがそこそこ出ると思うので、まだ間に合うんじゃないかなぁと。\n会社としては、Elastic{ON}16が控えています。参加される方は、ぜひ現地で声をかけてください!!\nその他にもイベント、オープンソースカンファレンス(まずは、大阪、東京)などに出没する予定ですので、こちらも参加していただければと。\nでは、また来年のAdvent Calendarでお会いしましょう!\n","date":1451017794,"dir":"post/2015/","id":"d819cea5197e9b8673d6c0b16659a5ea","lang":"ja","lastmod":1451017794,"permalink":"https://blog.johtani.info/blog/2015/12/25/about-elasticsearch-in-2015/","publishdate":"2015-12-25T13:29:54+09:00","summary":"今年最後のAdvent Calendarとなります。 この記事はElasticsearch Advent Calendar 2015の最終日のエントリです。 簡単に今年の変遷を","tags":["elasticsearch"],"title":"2015年のElasticsearch"},{"contents":"こんにちは、@johtaniです。\n早いもので、師走です。今年もあと少しとなりました(今月が一番忙しかったりしますが。。。)。 ということで、Advent Calendarの季節が始まりました。\nこの記事はElasticsearch Advent Calendar 2015の1日目のエントリです。\n今日は、最近公開されたTimelionの紹介をしたいと思います。\nTimelion? 11/12に公開されたばかりのアプリになります。(公式のブログはこちら。ブログでは動画による説明もあり)\nKibanaにプラグインとしてインストールすることで使用することができるようになるアプリです。 Timelionと書いて「Timeline」と読むようです。 Kibanaとは異なるグラフ描画のプラグインになっています。\nKibana 4.2からプラットフォーム化 Kibana 4.2から、Kibanaにプラグイン機構が導入されました。 Kibanaとしての機能以外にも、プラグインとして、アプリを追加できるようになっています。 Timelionもその一つです。\nインストール Timelionを試してみるには、ElasticsearchとKibanaが必要になります。(こちらは、すでにインストールされているとして。。。)\nKibanaのコマンドを利用して、プラグインをインストールします。\nbin/kibana plugin -i kibana/timelion インストールしたら、Kibanaにアクセスして、Timelionを呼び出します。\nTimelionへアクセス ブラウザでlocalhost:5601にアクセスすると、Kibanaが出てきます。 Kibanaのプラグイン選択のアイコンをクリックし、Timelionのアイコンをクリックします。\nすると、初期画面はこんな感じです。 直近15分のElasticsearchに入っているデータがが全部出てきます。 チュートリアルも出てきてます(初回起動時に出たはず)\nKibanaでの検索窓の部分に関数を指定していくことで、グラフが描画できるツールになっています。\nサンプル:気温データを可視化 百聞は一見に如かずということで、 気象庁のデータを使って、 ちょっとしたグラフを書いてみました。 1年間の気温の推移と日照時間になります。\n上のグラフが那覇、下グラフが札幌の気温のグラフになります。\n赤いライン:最高気温 青いライン:最低気温 黄色い棒グラフ:日照時間 最低気温と日照時間はグラフは次のような式で描画しています。\n青いラインの最低気温 気温のグラフになります。\n.es(index=\u0026#39;tenki2\u0026#39;, q=\u0026#39;city:naha\u0026#39;, metric=\u0026#39;avg:temperature_min\u0026#39;).label(\u0026#39;min\u0026#39;), .es()がelasticsearchに対するデータ取得の関数です。 引数は次のような意味になります。\nindex:対象とするインデックス名 q:検索クエリ。ここでは、cityというフィールドにnahaで検索。 metric:描画対象となっているデータの入ったフィールド。temperature_minというフィールドの1日毎の平均値を取得 最低気温と最高気温は別々のフィールドに格納してあります。最高気温の場合は(temperature_max)を指定します。\n.label(min)で、グラフの凡例の指定です。 残念ながら、日本語の指定は現時点(2015年12月01日時点)ではうまくいかなかったです。(https://github.com/elastic/timelion/issues/17)\nデフォルトでは、線グラフが選択されているので、グラフの種類は特に指定はしていません。 明確に指定する場合はlines()を指定します。\n黄色い棒グラフの日照時間 .es(index=\u0026#39;tenki2\u0026#39;, q=\u0026#39;city:naha\u0026#39;, metric=\u0026#39;avg:sunlight\u0026#39;).label(sunlight).bars() .es()に関しては最低気温のグラフとほぼ一緒です。異なるのは、metricの取得対象のフィールド名です。\n.label()で凡例を指定しています。先程と同様です。\n最後に、棒グラフにしたいため、.bars()を指定しています。\nその他に用意されている関数について知りたい場合は、Timelionのヘルプを表示すると説明が出てきます。 cusum()のような値を累積して表示するような関数も用意されています。\nまとめ Kibanaとは少し違うアプローチで時系列データを描画するためのツールとなっています。 線グラフと棒グラフを一つのグラフに描画したりもできますし、 累積のグラフなんかも描画できるようになっています。\n実験的なプロジェクトである、Timelionの紹介でした。 ここでのノウハウがkibanaにフィードバックされると色々と面白いことになるんじゃないかなと。\nということで、 明日は、zoetroさんの「Kibanaのプラグインの話」になります。 お楽しみに!\n","date":1448936891,"dir":"post/2015/","id":"1b56132638912a1ca54fcf7cd38b8e23","lang":"ja","lastmod":1448936891,"permalink":"https://blog.johtani.info/blog/2015/12/01/introduction-timelion/","publishdate":"2015-12-01T11:28:11+09:00","summary":"こんにちは、@johtaniです。 早いもので、師走です。今年もあと少しとなりました(今月が一番忙しかったりしますが。。。)。 ということで、A","tags":["kibana","timelion"],"title":"Timelionの紹介 - Elasticsearch Advent Calendar 2015 1日目"},{"contents":"第13回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 来年もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\n7月同様、サムライズムの@yusukeさんに テキスト翻訳していただき、大変助かりました。\nチェックイン数など チェックインした人:100名 キャンセルしなかった人:36名 でした。 今回は当日の時点でキャンセル待ちがない状態にしていました。 雨もあって、これなかった人もいるのでしょうか。\n\u0026ldquo;Beyond the basics with Elasticsearch\u0026rdquo; / Honza Král / Elastic スライド:https://speakerdeck.com/elasticsearch/beyond-the-basics-with-elasticsearch\n参考ビデオ(別のカンファレンスで話した時のビデオ):https://www.youtube.com/watch?v=yIixWzjTNog\nPycon HKでアジアに来ていたHonzaに、ついでに日本で話をしてもらうという企画で、 前回から1カ月足らずでの開催となりました。 Elasticsearchの基本的な検索機能とは別の機能に関して少し話をしてもらった感じです。 PercolatorとAggregationの話でした。\n詳しくはビデオやスライドを見てもらうのがいいかなと。\n\u0026ldquo;How did we use Found.no for our services?\u0026rdquo; / 株式会社アイリッジ Takuya Noguchi さん @tn961ir スライド:未定\nFoundユーザー。1.7までの話。 社内で独自にクラスタを構築していたが、managed serviceを利用したいと思っていた。 Found用のACLがShieldに マルチバイトのインデックス名とかも使いたいが、Nginxとの連携でちょっと。。。 セキュリティ関連の話も。Securityに関する報告はこういうものも用意されてるので、こちらに相談してもらうのがいいかも。https://www.elastic.co/community/security 要望がいくつか。 \u0026ldquo;ログ収集の仕組みを再考しよう! あとマウンテンビューに行ってきました。\u0026rdquo; / Acroquest Technology株式会社 谷本 心さん @cero_t スライド:http://www.slideshare.net/shintanimoto/lets-reconsider-about-collecting-logs-plus-visiting-elasticmoutain-view\nログの小話から始まり、ログに関する考え方とかを披露してもらいました。 さらに踏み込んだログの活用の方法の話になるかと思いきや、 思いっきり話が飛んで、マウンテンビューのElasticオフィスに遊びに行った写真が出てきましたw\n写真の後は、弊社のTanya(来月のElastic{ON} Tour Tokyoで来日予定)から 聞いた弊社製品に関する話をしていただきました。 きっと、Beatsに関して次は話してくれるんだろうなぁ(棒)。 流れ的には、来年の2月にサンフランシスコで開催されるElastic{ON}16につながりそうだったので、ここで宣伝しときますね。 今年3月に開催されたイベントには残念ながら日本の方はいなかったので、次回は日本の方がいると嬉しいなぁと。\nLT \u0026ldquo;「Elasticsearch を使った単語共起頻度の計算」\u0026rdquo; / 株式会社はてな id:takuya-a さん スライド:未定\n一風変わったElasticsearchの使い方的な話でした。 検索用にデータを登録してあるElasticsearchから単語の頻度情報を抜き出して、 別のインデックスに登録するという感じでしょうか。 こういうのが、実は、Elasticsearchに機能としてあると便利だったりするのかもなぁと思ってみたり。\nLTよりはちょっと長かったですかねw\nその他、感想などのブログ elasticsearch勉強会 まとめ+宣伝 今回も@yusukeさんのテキスト翻訳に助けていただきました。ほんとありがとうございます。 今年の勉強会はこれがラストになります。 来月は、トレーニングとElastic{ON} Tour Tokyoがあるので忙しくなりそうですが、 参加予定の方は楽しみにしていてください!\nOperations : http://training.elastic.co/class/Operations/Japan/Dec Developer : http://training.elastic.co/class/Developer/Japan/Dec ","date":1447143778,"dir":"post/2015/","id":"2ea86ae5093670df1d4502ea82efa1ac","lang":"ja","lastmod":1447143778,"permalink":"https://blog.johtani.info/blog/2015/11/10/13th-elasticsearch-jp/","publishdate":"2015-11-10T17:22:58+09:00","summary":"第13回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズ","tags":["elasticsearch","勉強会"],"title":"第13回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:The Story of Sense - Announcing Sense 2.0.0-beta1\n誕生 よくある良いプロジェクト同様、Senseもビールを飲みながら考えつきました。 Amstelでの手漕ぎボートのセッションの後で。 友人のJasperと私はJasperの会社で毎年行われる ハッカソンについて話をしていました。 このハッカソンはどのようなアイデアでどんなチームで行うかを聞き取りされる、厳密なハッカソンです。 その時、私とJasperはChromeブラウザに別のヒストリーを表示するという作業をやるとAnne Velingに話をしていました。\nJasperと私はElasticsearchのユーザでしたが、リッチなREST APIにリクエストを送信するための 便利なツールがないと知っていました。 恥ずべきことに、cURLコマンドを利用するターミナルがその時の一番良いツールでした。 皆さん、ターミナルでボディつきのリクエストをサブミットするのがどのくらい不便かというのをわかるために、 5秒ほどターミナルで実行してみてください。 タイプミスのような単純なことでさえ、すべてのコマンドを再タイプしなければならなかったり、 複数行サポートのターミナルと戦ったりです。 ウェブベースのJSONエディタを見つけ出して、それをベースにすることが必要でした。\n終わりなきウィークエンド リサーチをして、Anneに電話しました。 私は彼に、History Pageのプロジェクトにもコミットするが、 Elasticsearchユーザなので、便利なコンソールを開発する時間も欲しいという話をしました。 私たちは、Aceオンラインエディタを利用して、 自動でAPIを認識するナレッジベースを構築し、 コンテキストに沿ったサジェストを大なうようにしました。 Anneはすぐに、それが素晴らしいと同意してくれました。 しかし、彼は、ハッカソンの基本的なルール(週末にそれが終わる必要がある)に違反しているので、 そのアイデアを却下するしかありませんでした。 確かに、私たちが提案していたものは行えませんでした。 最後に、私たちは、ChromeのHistory Pageの素晴らしい置き換えについて実装しました。\nそれでも、私はチャレンジし、それが終わるであろうことを終わるであろうことを証明しなければなりませんでした。 次の週末(といくつかの終業後 :))に、私はそれを作りました。 Senseの誕生です。 それは、まだバグだらけでしたが、動きました。 これを見せるとみんな興奮しました。\n初期 Knowledge Baseの拡張とバグのフィックスで数日を過ごしました。 Senseは広まり始め、ずっと古いバグのあるバージョンを利用しないといけないのかと私は恐れました。 SenseをChromeのExtentionとしてリリースすることを決め、リリースすると自動的に更新されるようにしました。 History Panelのような機能を一つづつ追加するようにしました。\nElasticにジョインしてから、会社の人たちがSenseを使用しているということを聞き、とても幸せでした。 特に、Clintと話をしたときのことを覚えています。 彼は、\u0026ldquo;You know what Sense should do? It should use this format and allow you to have multiple requests in the editor\u0026rdquo; 「Senseになにをすべきかわかる?フォーマットを使うべきだし、エディタで複数のリクエストを持つようにするべきだ」 と言いました。 もちろん、その他のチャレンジも行いました。これは、簡単なものではなく、Aceの詳細を知る必要がありました。 それは新しいAceモード(Aceによって利用されているハイライティングロジック)です。 これは、Senseのサジェストエンジンに密に統合されました。\n次のものが古いSenseのスクリーンショットです。\n画像あり。Figure 1. Sense 0.7 ※画像に関しては原文をご覧ください。\nAPIのURLを入力すると、JSONのボディが入力されます。 うまく切り離すことができ、AceのスタンダードJSONモードを使っていました。 しかし、ここで、次のようなフォーマットをどうやってサポートするか考える必要がありました。\nGET _cluster/health POST index/_settings { \u0026#34;index\u0026#34;: { \u0026#34;number_of_replicas\u0026#34;: 3 } } これは、Aceが3つの異なるものをどうやってパースするかを知る必要があるということです。 HTTPメソッドとURLとJSONボディです。 また、困ったことに、前に説明した前に説明した通り、明らかに別々にはならないものでした。 JSONボディが完全であることを知る唯一の方法はかっこを数えることです。 それは、いくつかの作業とAceのカスタマイズが必要でしたが、それらを切り離すことができました。 そして、Senseのシンタックスが生まれたのです(Thanks Clint!)\nMarvel時代 就業時間中、私の優先すべき仕事はMarvelの開発になりました。 これは、Elasticsearchのための管理と監視のためのソリューションです。 (side note: Marvelは生まれ変わっています。(\u0026quot;Shield, Watcher, and Marvel 2.0.0 GA Released\u0026quot;)) Marvelは開発環境ではフリーなので、MarvelにSenseを組み込むことにしました。 これにより、Senseの開発が日中も行えるようになり、多くのユーザに利用され始めました。 また、Senseは実際に真のJavaScript開発者によって開発されました。 彼は、コードをクリーンにし、ブラウザにおける最新の技術を私に教えてくれました。\nこの期間のSenseは数回書き換えられています。 最も顕著なものは、個別のURLとJSONのサジェストエンジンを書き換えて、 1つのサジェストエンジンにしこれらのコンテキストで動作するようにし、さらに3つ目のコンテキスト(URLパラメータ)を追加したことです。\n新しいエンジンはまた、複数のサジェストコンテキストをメンテナンスするのが簡単になりました。 例えば、_search APIのソートパラメータを考えます。\nGET _search { \u0026#34;sort\u0026#34;: [ \u0026#34;timestamp\u0026#34;: \u0026#34;desc\u0026#34;, \u0026#34;price\u0026#34;: { \u0026#34;order\u0026#34;: \u0026#34;desc\u0026#34;. \u0026#34;missing\u0026#34;: \u0026#34;last\u0026#34; }, \u0026#34;nested_filter\u0026#34;: { \u0026#34;term\u0026#34;: { ... }}, \u0026#34;_score\u0026#34; ] } ユーザがどこにいるかによって、Senseは単純な値(_scoreのような)か、 複雑な構造(orderとmissingのような)やフィルタ(nested_filterのような)も サジェストする必要があります。 これらのサジェストのパスが一度に処理され、無関係なものは除外されます。\nSense 2.0の紹介! Marvel 1.xはKibana 3.0をベースにしていました。 これは、データの探索やダッシュボードツールとして素晴らしいものでした。 しかし、Kibanaチームはさらに素晴らしいものを出しました。 Kibana 4.xはElasticsearchをバックエンドとするUIアプリを簡単に構築することができる プラットフォームとして設計されています。 実際に、Marvel 2.0はKibanaの プラットフォームで利用できる最初のアプリです。\nSenseの話に戻します。 ElasticsearchのAPIとやりとりする一般的なコンソールです。 これをKibanaのアプリぴったりだと気付きました。 ということで、Sense 2.0をKibanaアプリとしてオープンソースで公開しました。 開発及び本番環境で利用してください。\nFigure 2. Screenshot Sense 2.0 ※画像に関しては原文をご覧ください。\nリリースのハイライト Sense 2.0の新しい機能をここで簡単に紹介します。 (すべての変更点についてはこちらをご覧ください。)\nElasticsearch 2.0 SenseのナレッジベースをElasticsearch 2.0サポートに更新しました。 新しいPipeline aggregationにも対応しています。\n複数リクエストの実行 テストやいくつかの一連のコマンドを繰り返し実行したい時があるでしょう。 その時に、それら全てをSenseに記述し、 実行したいリクエストを選択状態にしてElasticsearchにリクエストできます。\nFigure 3. Submit multiple requests ※画像に関しては原文をご覧ください。\nSenseは、Elasticsearchにリクエストを一つずつ送信し、それぞれの出力結果を右のパネルに表示します。 これは、問題のデバッグや複数のシナリオでのクエリの組み合わせの実行に非常に便利です。\n複数リクエストのコピーペースト 複数リクストを選択し、フォーマットしたり、cURLのコマンドとしてコピーすることも可能です。\nFigure 4. Copy multiple requests as cURL ※画像に関しては原文をご覧ください。\n# Delete all data in the `website` index curl -XDELETE \u0026#34;http://localhost:9200/website\u0026#34; # Create a document with ID 123 curl -XPUT \u0026#34;http://localhost:9200/website/blog/123\u0026#34; -d\u0026#39; { \u0026#34;title\u0026#34;: \u0026#34;My first blog entry\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;Just trying this out...\u0026#34;, \u0026#34;date\u0026#34;: \u0026#34;2014/01/01\u0026#34; }\u0026#39; もちろん、複数のcURLコマンドをコピーしてSenseにペースとすると、Senseはそれらをパースしてくれます。\nまとめ Sense 2.0.0のベータリリースです。 実際に多くの作業が終わった認識です。すぐにGAが出るでしょう。\nSense 2.0を知り、試していただくために、新しいドキュメントを参考にしてください。 バグやリクエストがある場合は、フォーラムやGitHubのIssueに登録をお願いします。\n","date":1446195306,"dir":"post/2015/","id":"5912529cfd6ce14c5ede5c6c83dae7e8","lang":"ja","lastmod":1446195306,"permalink":"https://blog.johtani.info/blog/2015/10/30/sense-2-0-0-beta1-ja/","publishdate":"2015-10-30T17:55:06+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:The Story of Sense - Announcing Sense 2.0.0-beta1 誕生 よくある良いプロジェクト同様、Senseもビールを飲みながら考","tags":["elasticsearch","sense"],"title":"Senseの歴史 - Sense 2.0.0-beta1の紹介(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Shield, Watcher, and Marvel 2.0.0 GA Released\n本日(10/28)Shield、WatcherおよびMarvel 2.0をリリースしました。 これが、Elasticsearch 2.0に対応したこれらのプラグインの最初のリリースです。\nElasticsearch 2.0対応のほかに、ShieldとWatcher 2.0は、 セキュリティとアラートを拡張するいくつかの新しい素敵な機能も備えています。\nShield 拡張可能なレルム - Sheild 1.xはユーザ認証のコア的なものを定義するのにフォーカスし 3つの認証メカニズム(esusers、LDAP/AD、PKI)を提供しました。 これらを提供することで、多くのユーザおよびユースケースをカバー出来ましたが、 追加の認証メカニズムを統合する必要があることもわかっていました。 ということで、Shieldのレルムベースの認証システムをユーザが利用、拡張できるようにオープンにし、 ユーザ認証を扱うためのレルム実装をプラグインとして拡張できるようにしました。 特定もしくはプロプライエタリな認証メカニズムが必要なユーザもShieldの強力な セキュリティ機能(ロールベースの認証、セキュアな通信など)をフルに活用できるようになりました。 カスタムレルムの詳細については、こちらをご覧ください。\nフィールドとドキュメントのACL - Shield 2.0はフィールドとドキュメントレベルのアクセス制御機能を提供します。 これは、ロールごとにアクセス可能なフィールドやドキュメントを定義できます。 この新しい機能は、設定の変更するよりも便利です。 このアクセス制御はElasticsearchのLuceneインデックスという最も低レベルで実装されています。 その結果として、このメンテナンスがより簡単であるだけでなく、より良くなっています。 詳細についてはこちらをご覧ください。\nユーザなりすまし - Shield 2.0で、ユーザなりすましの機能が実装されました。 これは、ユーザ(適切なパーミッションを持った)が、他のユーザになることができ、 それらのユーザのためにリクエストを実行できます。 これは、Elasticsearch上に構築されたアプリケーションがすでにユーザ認証を行いますが、 認可はElasticsearchサイドで行う必要があるような場合に有用です。 このシナリオで、アプリケーションの\u0026quot;main\u0026quot;ユーザを設定でき、正しくなりすましを割り当て、 ElasticsearchにアプリケーションユーザとしてリクエストをElasticsearchに実行させることができます。 詳細については、こちらをご覧ください。\nWatcher SlackとHipChatインテグレーション - SlackとHipChatはチーム/グループコラボレーションツールです。 これらは、急速に主流になり、組織の主な内部コミュニケーションハブとなっています。 Watcher 2.0はチャンネル/ルームやユーザにこれらのコミュニケーションチャネル経由で、Watchの通知を行うことができるアクションを 実装しました。 slackやhipchatアクションについてはドキュメントをご覧ください。\nArray Compare Condition - 新しいconditionはタイムシリーズのデータのスパイクを検知するのを簡単にします。 compare conditionは1.xで導入されましたが、このコンディションはElasticsearchのダイナミックスクリプト機能を有効にする必要がアンク使えます。 詳細についてはarray_compare conditionをご覧ください。\nWatchの有効・無効化 - ユーザからの多かったリクエストとして、Watchの無効化がありました。 1.xには、登録済みのWatchを無効にする機能がありませんでした。 これは、Watchを消すか、Watchのトリガーを変更することで回避していました。 これは、全体としてはWatchを管理するのを難しくする回避方法でしかありません。 2.0では、APIを呼び出すだけで、Watchの変更をすることなく、簡単にWatchの有効化・無効化が可能になりました。 これは1.0からあるべき基本的な機能でしたが、ついにこの問題を解決しました。 詳細はこちらをご覧ください。\nMarvel Marvel 2.0を紹介するのに興奮しています。 Kibana 4をベースとした、再設計されたUIを持っています。 Marvel 1.xで学んだ多くのことを導入し、より使いやすく監視しやすいUIになっています。 ShieldとWatcherと同様に、最初のMarvelのリリースは将来的な成長の基盤となり Elasticsearch2.0を効率的に管理するための主要なメトリックにフォーカスしています。\n画像あり。 ※画像に関しては原文をご覧ください。\n再設計により、インタフェースを6ページに減らしています。\nCluster list 画像あり。 ※画像に関しては原文をご覧ください。\nユーザやカスタマーの多くは複数のクラスタを利用しています。 新しいMarvelはそれらを集中的にモニタリングする一つのクラスタからそれらを簡単に監視できます。 各クラスタのデータ送信先をこのモニタリングクラスタにするだけです。\nCluster Overview 画像あり。 ※画像に関しては原文をご覧ください。\nクラスタオーバービューはある一つのクラスタの主要な性能メトリックを見ることができ、 素早くスパイクを発見できます。 このページはまた、アクティブなシャードのリカバリやリロケーションも見ることができます。\nIndices List 画像あり。 ※画像に関しては原文をご覧ください。\nインデックスのリストにはクラスタにあるすべてのインデックスとその属性が表示されます。 テーブルはライブでアップデートされ、フィルタリングやソートも可能です。 一番大きなインデックスは?といったことも調べられます。\nIndex Detail 画像あり。 ※画像に関しては原文をご覧ください。\nインデックス詳細ページはインデックスの主な性能メトリックを見ることができ、シャードの配置についても表示します。\nNodes List 画像あり。 ※画像に関しては原文をご覧ください。\nノードリストはクラスタにあるノードとその主な性能メトリックを見ることができます。 テーブルはライブでアップデートされ、フィルタリングも可能です。 高いCPU利用率やディスクの残り容量なども簡単にわかるようになっています。\nNode Detail 画像あり。 ※画像に関しては原文をご覧ください。\nノード詳細ページは個別のノードに関する主な性能メトリックを見ることができ、ノードにあるシャードのリストも見ることができます。\n新しいMarvelはKibana 4の上に構築されたので、管理方法が変わっています。 Marvelのインストールは2つのステップがあります。 marvel-agentとmarvel user interfaceです。\nMarvel Agent marvel-agentはElasticsearchクラスタにプラグインとしてインストールします。 主なパフォーマンス情報を取得し、ローカルもしくは分離されたモニタリングクラスタにデータを保存・送信します。\nMarvel User Interface Marvel UIはKibanaのプラグインとしてインストールします。 これは、Kibana 4.2の新しいプラグインインフラを利用し、 Marvel Appとして、Kibanaのインタフェースとは個別に提供されます。 Kibanaのアプリの切り替えは次の画像の通りです。\n画像あり。 ※画像に関しては原文をご覧ください。\n2.0リリースは私たちのプロダクトの大きな一歩です。またユーザの意見を常にお待ちしています。 ぜひ、Webフォーラム(https://discuss.elastic.co)やメール(info@elastic.co)でご意見を。\n","date":1446189691,"dir":"post/2015/","id":"15700442e957951307bbcec5fff8643d","lang":"ja","lastmod":1446189691,"permalink":"https://blog.johtani.info/blog/2015/10/30/shield-watcher-and-marvel-2-0-ga-released-ja/","publishdate":"2015-10-30T16:21:31+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Shield, Watcher, and Marvel 2.0.0 GA Released 本日(10/28)Shield、WatcherおよびMarv","tags":["elasticsearch","shield","watcher","marvel"],"title":"Shield、Watcher、Marvel 2.0.0 GAリリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 2.0.0 GA released\nElasticsearch 1.0.0のリリース以降、 477のコミッター2,799のpull requestがあった、 **Elasticsearch 2.0.0 GA(Lucene 5.2.1ベース)**をリリースしました。\nそれだけでなく、Shield(セキュリティプラグイン)とWatcher(アラーティングプラグイン)、 新しくなったMarvel(モニタリングプラグイン)(プロダクション環境でフリー!)、 また、新しくオープンソースとなったSense editorの2.0.0もリリースしました。\nElasticsearch 2.0.0のダウンロードはこちらから。 また、2.0.0での重要な変更点についてはこちらをご覧ください。 全ての変更点については、次をご覧ください。\nChanges list for Elasticsearch 2.0.0 Changes list for Elasticsearch 2.0.0-rc1 Changes list for Elasticsearch 2.0.0-beta2 Changes list for Elasticsearch 2.0.0-beta1 商用プラグインについてはこちらです。\nShield 2.0.0 change logs Watcher 2.0.0 change logs Elasticsearchの新機能 Elasticsearch 2.0.0には素晴らしい新機能があります。\nPipeline Aggregations Aggregationsで導関数や移動平均のような他のAggregationの結果に対する計算が可能となります。 この機能はクライアントサイドで実装しなければなりませんでしたが、 Elasticsearchに計算させることで、より強力な解析のクエリを簡単に組み立て、クライアントのコードを簡略化できます。 これは、予測解析や予測解析や例外検知といった可能性をもたらします。 Pipeline Aggregationについては次をご覧ください。\nOut of this world aggregations. Staying in Control with Moving Averages - Part 1. Staying in Control with Moving Averages - Part 2. Query/Filter merging フィルタはもうありません。 全てのフィルタ条件はクエリとなりました。 クエリコンテキストで使用した場合、関連度のスコアに影響し、フィルタコンテキストで使用した場合、 これまでのフィルタのように、ヒットしなかったドキュメントを除外するだけとなります。 この変更はクエリの実行時に自動的に最も効率的な順序で実行するように最適化されることを意味します。 例えば、遅いクエリ(フレーズやgeo)の最初の実行は速い近似フェーズで実行され、 それから、遅い正確なフェーズで結果を修正します。 フィルタコンテキストでは、直近でよく使われた条件が自動的にキャッシュされます。 詳細については、\u0026quot;Better query execution coming to Elasticsearch 2.0\u0026ldquo;をご覧ください。\n設定可能な圧縮率 _sourceのようなStored fieldsは高速なLZ4(デフォルト)で圧縮するか、インデックスサイズを小さくできるDEFLATE で圧縮できます。 これは、特にロギングのケースで便利です。 古いインデックスをオプティマイズする前にbest_compressionに変更することができます。 詳細については\u0026rdquo;Store compression in Lucene and Elasticsearch\u0026ldquo;をご覧ください。\n堅牢に 新しいElasticsearchはJava Security Managerの元で実行されます。 これは、セキュリティの観点で大きな前進です。 Seciruty ManagerはElastcsearchにより制限をかけ、ハッカーによりシステムに対して何でもできるようなものを制限します。 Elasticsearchはまた、インデキシングの観点でも堅牢になっています。\nドキュメントはインデキシングリクエストに答える前に、耐久性のためにディスクにfsyncされます。 すべてのファイルはチェックサムにより、早期に障害を検知します。 すべてのファイルはどんなファイルへの書き込みもアトミックです 最後に、システム管理者から要請の多かった変更として、 設定されて居ないノードがパブリックなネットワークから参加しないようになりました。 Elasticsearchはデフォルトではローカルホストのみにバインドします。マルチキャストは無くなりました。(プラグインとして残っています。)\nパフォーマンスと信頼性 上記以外にも細かな修正がElasticsearchとLuceneにはあります。 より安定し、信頼性をあげ、簡単に設定できるようにするものです。例えば、次のようなものです。\nヒープの使用率の低減(doc valuesがデフォルト、マージ時のメモリ使用率の削減、 roaring bitsetsによるフィルタキャッシュ) 構造化され読みやすくなった例外 設定の代わりに、フィードバックループを使用した自動調整 安全で明確で信頼性のあるタイプマッピングの大きな修正 クラスタ状態の差分変更による伝搬の高速化および、大きなクラスタでのより安定的に normsの圧縮の改善。これまではヒープスペースを大きく利用していた。 マージの自動的な調整(不可解な設定の微調整が必要ない) より詳細なLuceneのメモリリポート 最適化されたクエリ実行を活用するためにParent/childを書き換え コアプラグイン 公式にサポートされたコアプラグインはElasticsearchと同じバージョン番号で同じタイミングでリリースされます。 インストールするプラグインとElasticsearchの複雑なバージョンの対応表に悩まされる必要はもうありません。 コアプラグインのインストールは次のように簡略化されています。\nbin/plugin install analysis-icu ShieldとWatcherの新機能 商用プラグインも新しい機能をリリースしました。\nShield フィールドおよびドキュメントレベルのアクセス制御 ユーザのなりすまし カスタム拡張可能な認証レルム Watcher 個別のWatchを有効/無効に SlackやHipChatへの通知 これらの詳細については“Shield, Watcher, and Marvel 2.0.0 GA Released”をご覧ください。\nコアプラグイン同様、商用プラグインもElasticsearchのバージョンと同じものが同時にリリースされます。 インストールは次の通りです。\nbin/plugin install license bin/plugin install shield bin/plugin install watcher Marvel 2.0.0はプロダクションでの利用もフリーに Marvelモニタリングプラグインはカスタマに非常に価値のあるもので、 ユーザの発展とともに問題を診断したり見つけたりするのに役に立ってきました。 私たちは、何を改善でき、Mαrvelを一から書き直すことで、いろいろとわかったことがあります。\nMarvel UIを新しいKibanaプラットフォーム上に構築 ダッシュボードにはより簡単に問題を発見するために、最も重要なメトリックを可視化 1つのインストールで、複数のクラスタのモニタリングをサポート(商用サポート対象) 一番良い点はMarvelがすべてのElasticsearchユーザに対してプロダクション環境でフリーになったことです! ライセンスが必要ですが、課金の必要はありません。 もし、マルチクラスタモニタリングサポートが必要な場合、それは商用サポート対象となります。\n詳細に関しては“Shield, Watcher, and Marvel 2.0.0 GA Released”をご覧ください。\nSense editorがオープンソースに Sense(ブラウザベースのElasticsearchリクエストとDSL向けのエディタ)を Kibanaプラットフォームのアプリとして、オープンソースにしました。 また、このリリースで新しい機能が追加されています。\n複数のcURLリクエストをペースとすると、Sense表記に変更 複数のSenseリクエストをcURL表記にしてコピー 複数のリクエストを一度に実行可能 Elasticsearch 2.0サポートとなった自動補完機能 SenseはKibanaのアプリとして次のようにインストールします。\n./bin/kibana plugin --install elastic/sense Senseの詳細については、\u0026quot;The Story of Sense - Announcing Sense 2.0.0-beta1\u0026ldquo;をご覧ください。\nElasticsearch Migration Plugin Elasticsearch Migration PluginはElasticsearch 1.xから2.0にアップグレードする時の良い出発点となります。 1.xのElasticsearchクラスタにサイトプラグインとしてインストールすると、 アップグレードする前に解決すべき問題があるかどうかを検知してくれます。 (例えば、Lucene 3のような古いインデックスや、2.0.0にした場合に動作しない問題のある マッピング(The Great Mapping Refactoring)のような問題)\nプラグインに関してElasticsearch Migration repositoryをご覧ください。\nまとめ ぜひ、Elasticsearch 2.0.0をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)やWebフォーラムなどで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1446103243,"dir":"post/2015/","id":"018e32a8010960eb17e368a6fdd5a51b","lang":"ja","lastmod":1446103243,"permalink":"https://blog.johtani.info/blog/2015/10/29/elasticsearch-2-0-0-released-ja/","publishdate":"2015-10-29T16:20:43+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 2.0.0 GA released Elasticsearch 1.0.0のリリース以降、 477のコミッター2,79","tags":["elasticsearch"],"title":"Elasticsearch 2.0.0リリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Kibana 4.2.0 released\nElasticsearch 2.0 + Kibana 4.2 = 💚 Elasticsearch 2.0サポートのKibanaの最初のリリースです。 これが何を意味するでしょう? 速さ、安定さ、新しい機能。 試してみたい方は、いますぐダウンロードしてください。 そうでない方は、Kibana 4.2の楽しい機能について読んでみてください。\n暗黒面は怖い? そんなことありません。 私たちは常にチャートチャートとダッシュボードを組み立てている組み立てている間は明るいバックグラウンドを使うことを推奨してきましたが、 時々、巨大なスクリーンで暗い部屋で誰も明るい画面から目を背けないようにしたいでしょう。 その影響を小さくするためにダークモードを導入しました。 あなたは、NOCや天文台、その他の暗い場所でKibanaのダッシュボードを楽しむことができます。\n画像あり。 ※画像に関しては原文をご覧ください。\n地図のカスタマイズ Kibanaの地図は素晴らしいですが、もっと多くのオプションが望まれていると聞きました。 もし地図に関して知識があるなら、Kibana 4.2のWMSバックグラウンド地図サポートを試してみてください。 WMSは非常に強力で、US Geological Surveyを含む多くの無料サービスがあります。 http://viewer.nationalmap.gov/example/services/serviceList.html\n画像あり。 ※画像に関しては原文をご覧ください。\nシナリオは? 何かおかしい時、何が起こっているかを正しく知ってもらいたいので、Kibanaがそのタイミングで注目したいコンポーネントがあるなら、 どのように動いているかという概要を知るためのサーバステータスページを作りました。 もちろん、全てがOKであるというのを知りたいだけの場合でも、settingメニューのStatusタブからいつでも呼び出せます。\n画像あり。 ※画像に関しては原文をご覧ください。\n全てにおいて速く ブラウザリフレッシュはKibana 4.2の新しいコードビルディングシステムのおかげで、さらに早くなりました。 また、メモリを覚えてます?Pepperidge FarmKibanaが覚えています。 Kibana 4.2は小さな小さな小さなメモリフットプリントを管理している間、長い長い長い時間実行されているダッシュボードを見ることができるような 大きなメモリのクリーンアップも含んでいます。\nもっとありますが。。。 小さな微調整がいくつもあります。また、今後紹介する本当に刺激的なものの基礎を気づき上げてきました。 これからもElasticのブログ、Twitter、KibanaのGitHubリポジトリに注目し、モンスタートラックアナリティクスの瞬間に立ち会ってください。\n","date":1446103219,"dir":"post/2015/","id":"e159a35d1b9a46e03072a3d54780edcb","lang":"ja","lastmod":1446103219,"permalink":"https://blog.johtani.info/blog/2015/10/29/kibana-4-2-0-ja/","publishdate":"2015-10-29T16:20:19+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Kibana 4.2.0 released Elasticsearch 2.0 + Kibana 4.2 = 💚 Elasticsearch 2.0サポートのKibanaの最初のリリースです。 これ","tags":["elastic","kibana"],"title":"Kibana 4.2.0リリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Logstash 2.0.0 released\nLogstash 2.0.0が本日(10/28)リリースされました。 このリリースは いくつかの設定に関する重要な変更があります。 詳細については、changelogまたは、新しいbreaking changesドキュメントをご覧下さい。\nこれまでの2.0.0直前のリリースに関する変更点はこちらをご覧ください。\nbeta1 beta2 beta3 RC ここでは、2.0の主な変更点の概要を説明します。\nElasticsearch 2.0との互換性 多くの機能および改善を含んだElasticsearch 2.0がリリースされました。 Logstash 2.0はこのリリースに対応しています。 Logstashのこれまでのリリースでは、デフォルトで、Javaの node clientをElasticsearchとの通信として 使用してきました。 2.0では、HTTPクライアントがデフォルトになります。 これにより、シームレスにユーザのデータを取り込み、付加価値をつけ、Elasticsearchに保存して解析することができます。\nHTTPは他のプロトコル(nodeやtransport)同等の機能を持っていますが、 単一のクライアントに接続する時に、少しだけ遅いですが、管理や動作がより簡単です。 HTTPプロトコルを使うことで、Elasticsearchのバージョンのアップグレードが、Logstashのアップグレードすることなく 行うことができます。 デフォルトをHTTPに変更したさらに詳しい情報についてはbeta1のブログをご覧ください。\n他のプロトコル(nodeとtransport)もサポートしますが、これらを利用する場合には、 プラグインを別途インストールする必要があります。\nbin/plugin install --version 2.0.0 logstash-output-elasticsearch_java 互換性のマトリックス LogstashとElasticsearchのバージョンの互換性は次のようになります。\n画像あり。 ※画像に関しては原文をご覧ください。 #Image https://www.elastic.co/assets/bltde5b69e2164aa82f%2Fcompat_matrix.png\nShield 2.0との互換性 このリリースはShield 2.0リリースにも対応しています。 HTTPプロトコルで、追加のプラグインは必要ありません。 こちらのドキュメントをご覧ください。 transportプロトコルでは、Shield 2.0対応のプラグインを個別にインストールする必要があります。\nbin/plugin install --version 2.0.0 logstash-output-elasticsearch_java_shield パフォーマンスの改善 このリリースはまた、多くの部分のパフォーマンスの改善を含んでおり、Logstashを利用してデータをより早く処理することができます。 いくつかをここで説明します。\nUserAgentとGeoIPフィルタ:これらのフィルタで、LRUキャッシュを追加して改善しています。 これにより、IPとユーザエージェントがまとまって現れるというWebリクエストの特性を用いています。 ユーザエージェントフィルタのケースでは、サンプルデータセットにおいて3.7倍ほど早くなりました。 GeoIPでは、1.69倍早くなっています。\nJSONプロセシング:LogstashでJSONのsiriaraizu/でシリアライズに利用しているJrJacksonを新しいバージョンにしました。 これにより、JSONの処理が改善されています。\nフィルタワーカーのより良い値をデフォルトに:以前のリリースでは、filter_workersの設定は1がデフォルトでした。 これは、フィルタの処理を行うワーカーが1つであるという意味です。 filter_workersの設定のデフォルト値はCPUコア数の半分の値を設定します。フィルタ実行の並列性が上がります。 ですので、複雑なgrokパターンやuseragentフィルタの処理がにとっては重要です。\nFilebeat Support Filebeatのベータバージョンを先日リリースしました。 これは、Logstash Forwarderの次期バージョンです。 Filebeatはファイルベースのログをさらに処理するためにLogstashに送るためのエージェントです。 2.0.0はlogstash-input-beatsプラグインを使えばFilebeat 1.0.0-beta4とすぐに動作します。\nシャットダウン操作 これまでのLogstashでは、シャットダウンが開始した時に、例外の機構でシャットダウンが開始したことを プラグインに通知していました。 この処理はサードパーティのコードを使ったプラグインで問題を起こしていました。 Logstashはどの例外を処理するか知らないため、予期しない動作をしていました。 これを修正するためにAPI呼び出し(例えばstop)を各プラグインにシャットダウンのイベントを通知し、 プラグイン自身がきちんと停止するようにしました。 これは、200以上のプラグインに新しいAPIを利用するように修正しないといけないことを意味しました。 しかし、Logstashの停止についてはまだ完全にはフィックスしていません。 とちゅうでおわっているoutputがシャットダウンを遅らせる可能性があるからです。 2.0でAPIの破壊的な変更は適切なリリースでの変更を繰り返すことができる出発点です。\nプラグインの開発者へ:もし、Logstash 1.5のプラグインを開発しているなら、 シャットダウンに関する新しいAPIのリストに関するbreaking changesのドキュメントに助言をください。 また、example inputリポジトリにて、新しいシャットダウンメカニズムの使い方のサンプルコードを提供しています。\nドキュメント 2.0に更新されたドキュメントはこちらです。設定の変更についてもこちらをご覧ください。\n2.0へのアップデート 2.0へアップデートする前に、アップデートガイドもご覧ください。\nフィードバック 2.0のリリースできたことに、多くのコントリビューター、ユーザに感謝しています。 このリリースに含まれている多くのパッチと全てのプレリリースのテストにも感謝しています。 将来の修正やリリースなどについてはロードマップをご覧ください。 2.0は今日リリースされました。 ご意見ご感想はWebフォーラムで!\n","date":1446103197,"dir":"post/2015/","id":"cc64c2fcdecdb505b3797e1aaaa59adc","lang":"ja","lastmod":1446103197,"permalink":"https://blog.johtani.info/blog/2015/10/29/logstash-2-0-0-released-ja/","publishdate":"2015-10-29T16:19:57+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Logstash 2.0.0 released Logstash 2.0.0が本日(10/28)リリースされました。 このリリースは","tags":["elastic","logstash"],"title":"Logstash 2.0.0リリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Relase, we have ※画像に関しては原文をご覧ください。\nElasticにとって大きな1日(社内では「release bonanza」と呼んでいる)です。 多くの主要なプロダクトを新たにリリースしました。 そして、本日、それらを一緒に利用する時にそれらを一緒に利用する時にユーザの体験についてまとめてみました。\n次の通りです。\nElasticsearch 2.0リリース。 大きなマイルストーン、チームによる改善、そして、コミュニティからの素晴らしい貢献。 Pipeline Aggsと呼ばれる新しいタイプのaggregations、 クエリとフィルタのコンセプトを統合することにより簡素化されたクエリDSL、 better compressionオプション、 JavaのSecurity Managerを有効にすることによる強化されたセキュリティ、 FSの挙動に関する強化(fsync、checksum、atmicなリネーム)、 パフォーマンス、マッピングの挙動の一貫性などなどです。 また、我々のチームによる改善も含まれているLucene 5ベースにアップグレードしています。\nKibana 4.2リリース。 Elasticsearch 2.0対応、ダークテーマ、カスタマイズ可能な地図、多くの改善。 Kibana 4.2の多くに作業については外部プラグインサポートといった、内蔵に関するものでした。 この後の説明に続きます。\nMarvel 2.0リリース。 Elasticsearch 2.0対応、合理化されたメトリックス、簡素化されたUI、 多くはKibanaプラグイン(Kibanaプラットフォーム上に構築)としての書き換えです。 このKibana拡張の最初の努力は、Kibanaのプラグインをどうやって書くか、 Kibanaユーザに公式に何をする必要があるかといったものを特定するのに役立ちました。 おっと、忘れるところでした、Marvelを全てのユーザにフリーで使えるようにしました。 マルチクラスタサポートについては有償となります。\nSense 2.0リリース。 2つ目のKibanaプラグインがこれです。 SenseをKibanaプラグインとして書き換えました。 Elasticsearch 2.0サポート、複数リクエストの実行、 curlへのコピーなどです。 おっと、忘れるところでした。オープンソースとすることにしました!\nShield + Watcher 2.0リリース。ElasticsearchのためのセキュリティプラグインであるShieldと、アラート管理のためのプラグインであるWatcherにも 多くの結果が入っています。 最も要求のあった機能である、フィールドお呼びドキュメントレベルでのセキュリティについて、Luceneに落とし込んで実装しました。 また、セキュリティの操作についてプラガブルに実装できるように変更しました。 Watcherは監視の無効化、SlackやHipChatへの通知(bot ops向け)が可能です。\nLogstash 2.0リリース。 Elasticsearch 2.0のサポート、クリーンな停止、全面的なパフォーマンス改善、Beatsサポート。\nご覧の通り、すべてのプロダクトに関する大きな結果です。 チーム間およびFoundの開発者との間での密な連携に感謝します。 これらが私たちが公式にElasticsearch / KibanaをホストしているFoundで 利用可能です。\nひゅう、息切れしました。 チームがしてきたことは、感動的で、謙虚で、刺激的です! Elasticが会社として、全てのユーザ、コントリビュータがどのように私たちの大きなミッションに対する結果をもたらしたかという素晴らしい良い例です。 ユーザに愛され、楽しまれ、成功に導き、革新させる製品を是非ご利用ください。ありがとうございます。\n\u0026ldquo;A Lion, in Africa?\u0026rdquo; - まだまだ終わりではありません。この文言で終わりにしますが、すぐに(本当にすぐに)戻ってきます。;)\n","date":1446095939,"dir":"post/2015/","id":"4cc08ca51ecf0f963035f039de6194c5","lang":"ja","lastmod":1446095939,"permalink":"https://blog.johtani.info/blog/2015/10/29/release-we-have-ja/","publishdate":"2015-10-29T14:18:59+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Relase, we have ※画像に関しては原文をご覧ください。 Elasticにとって大きな1日","tags":["elasticsearch","kibana","logstash"],"title":"Release, we have(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 2.0.0-beta2 released\n本日(9/17)、Lucene 5.2.1ベースのElasticsearch 2.0.0-beta2をリリースしました。 本リリースが2.0.0のRCの前の最後のベータリリースになります。\n注意事項 本リリースはベータリリースであり、テストを目的としたものとなります。 Elasticsearch 2.0.0-beta2はElasticsearch 2.0.0-beta1と互換がありません。 また、Elasticsearch 2.0.0 GAと互換性があるかどうかの保証はありません。\n本番環境には利用しないでください。\nElasticsearch 2.0.0-beta2のダウンロードおよび、すべての変更についてはリンクをごらんください。\n2.0.0-beta1をテストし、問題点を報告していただいた皆様、ありがとうございます。 2.0.0-beta1のあとのElasticsearchのコアの部分の修正のほとんどはバグフィックスになりますが、 geo_shapeフィールドのpoints_only最適化のようなちょっとした改善も含んでいます。\nまた、本リリースでは、商用プラグインの重要な新機能もあります。 こちらについてはShield and Watcher 2.0.0-beta2 releasedをごらんください。 簡単な紹介は次の通りです。\nShieldの新機能 ドキュメントおよびフィールドレベルのセキュリティ Shieldは、クエリを利用したインデックスにあるドキュメントへのアクセスを制御するためのロールを定義できるようになりました。 また、ドキュメントにある特定のフィールドに関するアクセス制限も可能です。 フィルタされたエイリアスのような形ではなく、ドキュメントを検索したり、IDで取得したりする場合にこれらの制限が利用できます。 詳細はField- and Document-level Securityをごらんください\nユーザなりすまし 特定のユーザーに他のユーザーに扮して、彼らのためにリクエストを実行する能力を与えることが、現在できます。 これは、認証がアプリケーションによって実行される場合に便利です。 そして、それは、ユーザの許可レベルを考慮するようにElasticsearchにリクエストします。 詳細はSubmitting Requests for Other Usersをごらんください。\nプラガブルな認証レルム このリリースで、サードパーティの拡張のための認証レルムのインフラを公開しました。 もし、特定の認証要求があり、Shieldがサポートしていない(が、内部の認証管理システムを使いたいような)場合、 これらの要求に見合う新しい認証レルムを利用するプラグインを作成可能です。 詳細はCustom Realmsをごらんください。\nWatcherの新機能 監視の一時 新しく、active / inactive の状態がwatchに追加されました。 これらは、Watchを中断したり、要求に応じて再開させたりできます。 詳しくは、Active Stateをごらんください。\nチャットのための新しいアクション slackとhipchatアクションが追加されました。 これは、Watcherが通知を、SlackやHipchatのユーザに直接送ったり、 チームのチャットルームに送ったりすることが出来るようにします。 詳細については、Slack actionおよび、Hipchat actionをごらんください。\n2.0に関するこれまでのブログ記事 これまでのリリースについての情報はこれらのブログ記事をごらんください。\n\u0008* Elasticsearch 2.0.0.beta1 released\nElasticsearch 2.0.0.beta1 coming soon! The Great Mapping Refactoring Store compression in Lucene and Elasticsearch Better query execution coming to Elasticsearch 2.0 Out of this world aggregations Staying in Control with Moving Averages - Part 1 Staying in Control with Moving Averages - Part 2 The Delete by Query API Is now a plugin Elasticsearch unplugged - Networking changes in 2.0 また、Elasticsearch 2.0.0-beta2のドキュメントや2.0のbreaking changesのリストもごらんください。\nElsticsearch Migration Plugin Elasticsearch Migration Pluginは、既存のインデックスをアップグレードする 必要があるか、他に必要な行動がないかについて、Elasticsearch 2.0.0-beta2を試す前に確認する助けとなります。 Lucene 3のような古いインデックスや、2.0.0にした場合に動作しない問題のある マッピングのような問題を発見できます。\nプラグインの動作に関しては[Elasticsearch Migration repository](Elasticsearch Migration repository)をごらんください。\nテストしましょう! Elasticsearch 2.0.0 GAをすぐにリリースできるようにより多くのベータテスターをお待ちしています。\nぜひ、Elasticsearch 2.0.0-beta2をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)やWebフォーラムなどで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1442565101,"dir":"post/2015/","id":"4b227d61f33182579cd3edd0ac6c7c44","lang":"ja","lastmod":1442565101,"permalink":"https://blog.johtani.info/blog/2015/09/18/elasticsearch-2-0-0-beta2-released-ja/","publishdate":"2015-09-18T17:31:41+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 2.0.0-beta2 released 本日(9/17)、Lucene 5.2.1ベースのElas","tags":["elasticsearch"],"title":"Elasticsearch 2.0.0-beta2リリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch unplugged - Networking changes in 2.0\nElasticsearchをローカルのマシンで起動します。 そして、昨日試したデータを削除するためにDELETE *を実行します。 すると、悲しそうな叫びを同僚が発していることに気づき、なぜそんなことになっているのか不思議に思うでしょう。。。\nElasticsearchはいつも、親しみやすいものでした。 複数ノードのクラスタがどのように機能するのかをテストするには、 ローカルのマシンでいくつかのElasticsearchのインスタンスを起動するだけでした。 起動したインスタンスはマルチキャストを利用して自動的にお互いを見つけて、1つのクラスタになり、負荷を共有し始めます。 しかし、これは親しみやすすぎました。 カンファレンスなどで、ローカルのマシンでElasticsearchを起動してみてください。 すると100ノードのクラスタに参加しているのがすぐにわかるでしょう。\nもうすぐリリースされる、2.0.0-beta1では、Elasticsearchが通信先を選択するネットワークの機能に関する変更があります。 ただし、これまで通り、簡単に開発者が経験できる機能も残っています。\nlocalhostへのバインド 以前、Elasticsearchはデフォルトで、利用可能なネットワークインタフェース全てにバインドしていました。 そこから、一番適したインタフェースをpublish_hostとして選択しようとします。 このアドレスはElasticsearchがクラスタの他のノードとやりとりするためのアドレスです。\nElasticsearch 2.0では、デフォルトでは、localhostにのみバインドします。 127.0.0.1(IPv4)と[::1](IPv6)の両方にバインドしようとします。 また、どちらかのみの環境でも動作します。 この変更は、特に指定がない限り、Elasticsearchがネットワーク上の他のノードと接続しません。 本番環境に移行する場合は、network.hostパラメータを使って設定しましょう。 設定は、elasticsearch.ymlに記述するか、コマンドラインで指定します。\nbin/elasticsearch --network.host 192.168.1.5 bin/elasticsearch --network.host _non_loopback_ network.hostの全てのオプションについては、network settingsのドキュメントをごらんください。\nマルチキャストは廃止 Elasticsearch 1.xはネットワークの他のノードに接続・探索するためにマルチキャストを使用しました。 マルチキャストは魔法のような挙動です。。。 残念ながら、マルチキャストのサポートは良くも悪くもあります。 Linuxはローカルホストでマルチキャストの待ち受けをしていません。 OS/Xは構成されたアドレスの全てのインタフェースにマルチキャストで配信できます。 また、ネットワークによってはマルチキャストはデフォルトでは使用できなくなっています。\nElasticsearch 2.0は異なるアプローチを採用しました。 マルチキャストを廃止します(ただし、新たにプラグインとして提供します)。 代わりに、ローカルホストでは、Elasticsearchはtransport.tcp.portで指定されている範囲(デフォルトは9300-9400)の最初の5ポートに対してユニキャストを使用できるようにします。\nこれは、開発者のための、設定することなく自動的にクラスタを組むという機能を残しています。 しかし、本番に移行するときは、unicast hostsで次のようにリストを指定する必要があります。\ndiscovery.zen.ping.unicast.hosts: [ 192.168.1.2, 192.168.1.3 ] unicast hostsとしてクラスタにあるノードの全てのリストを指定する必要はありません。 少なくとも、マスタノードとして選出されるべきものを指定します。 巨大なクラスタでは、3つの専用のマスタノードを持っており、この3つをunicast hostsとして設定することを推奨しています。\nこれにより、開発の知識・経験が、私たちの推奨する本番でのネットワーク設定に、より近いものとなります。\nノード情報の変更 最後に、inet[/127.0.0.1:9200]といったシンタックスを廃止します。 これは、Elasticsearchがnodes-info APIなどで、使用していたIPアドレスのためのシンタックスです。 今は、RFCに準拠した形で表示します。 127.0.0.1:9200(IPv4)や[::1]:9200(IPv6)のようにです。\n質問がある場合は、ElasticsearchのWebフォーラムで質問してください。ベータはもうすぐです!(翻訳した時点で、すでにベータリリースされています。)\n","date":1440730890,"dir":"post/2015/","id":"0de0edbf2a506143c1739b12e94c0ef9","lang":"ja","lastmod":1440730890,"permalink":"https://blog.johtani.info/blog/2015/08/28/elasticsearch-unplugged-ja/","publishdate":"2015-08-28T12:01:30+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch unplugged - Networking changes in 2.0 Elasticsearchをローカルのマシンで起","tags":["elasticsearch"],"title":"Elasticsearch unplugged - 2.0におけるネットワークの変更(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 2.0.0-beta1 released\n本日(8/26)、Lucene 5.2.1ベースのElasticsearch 2.0.0-beta1をリリースしました。 本リリースは469名のコミッターからの2,500以上ものpull requestを含んでいます。 pull requestのうち、約850が2.0のための新規のものとなります。\n注意事項 本リリースはベータリリースであり、テストを目的としたものとなります。 Elasticsearch 2.0.0-beta1は Elasticsearch 2.0.0 GAと互換性があるかどうかの保証はありません。\n本番環境には利用しないでください。\nElasticsearch 2.0.0-beta1のダウンロードおよび、すべての変更についてはリンクをごらんください。\nElasticsearch 2.0.0-beta1には次の新しい変更が含まれています。\nPipeline Aggregations:これは、他のaggregationsの結果に対するAggregationを実行できます(導関数、移動平均、Holt Winter予測アルゴリズムなども含む) ディスクやファイルシステムキャッシュにより適したより良いデータの圧縮 doc-valuesがデフォルトになったこと、マージ実行時のメモリ使用量の低減、フィルターキャッシュのためのroaring bitsetsなどにより、ヒープの使用率がより効率的に。 構造化された例外 最適化されたクエリ実行順序、フィルタの自動キャッシュ、より高速なクエリに書き換えられたparent-child 設定の代わりに、フィードバックループを使用した自動調整 トランザクションログへの書き込みがデフォルトで、アトミックでかつ冗長に 安全で明確で信頼性のあるタイプマッピング デフォルトでローカルホストでのみクラスタを構成 クラスタ状態の差分によりより高速に変更を伝搬 上記の変更以外にも、多くのElasticsearchおよびLuceneに対する継続的な変更が含まれています。 これらは、Elasticsearch 2.0をより安全に、より簡単に、より良いものにしています。 本リリースに関するより詳しい情報が次のブログにあるので、参考にしてください。\nElasticsearch 2.0.0.beta1 coming soon! The Great Mapping Refactoring Store compression in Lucene and Elasticsearch Better query execution coming to Elasticsearch 2.0 Out of this world aggregations Staying in Control with Moving Averages - Part 1 Staying in Control with Moving Averages - Part 2 The Delete by Query API Is now a plugin Elasticsearch unplugged - Networking changes in 2.0 また、Elasticsearch 2.0.0-beta1のドキュメントも参考になります。 特に、2.0での重大な変更点については必ずごらんください。\nCore plugins コアプラグインの開発の方法を変更しました。 公式にサポートしているプラグインは、現在elasticsearchのリポジトリに含まれています。 これにより、コアと一緒にテストされ、Elasticsearchと同じタイミングでリリースされます。 コアプラグインはElasticsearchと同じバージョン番号隣ます。 インストールは次のようになります。\nsudo bin/plugin install analysis-icu プラグインの新しいドキュメントは私たちのWebサイトのGuideにあります。\nCommercial plugins 私たちの商用プラグインもElasticsearchと同じバージョン番号となり、Elasticsearchと一緒にリリースされます。 ShieldやWatcherはすでに2.0.0-beta1が利用可能です。 インストールのコマンドはは次のようになります。\nsudo bin/plugin install license sudo bin/plugin install shield sudo bin/plugin install watcher MarvelおよびSenseに関する新しい情報もありますが、もう少しお待ちください。\n2.0.0-beta1の商用プラグインに関するドキュメントは次のリンクからごらんください。\nShield 2.0.0-beta1 Watcher 2.0.0-beta1 Elasticsearch Migration plugin Elasticsearch 2.0.0-beta1を試す前に、 既存のインデックスのアップグレードするためになにか行う必要があるかどうかを確認するためのElasticsearch Migration Pluginもリリースしました。 2.0.0では機能しない、問題のあるマッピングなどを見つけるために便利なプラグインです。\nこのプラグインの利用方法についてはElasticsearch Migration repositoryをごらんください。\n既知の問題 同じインデックスの異なるタイプに、同じ名前のipタイプのフィールドを追加した時に、問題があることがわかっています。 この問題は次のリリースでフィックスされます。詳細は#13112をごらんください。\nテストしましょう! Elasticsearch 2.0.0 GAをすぐにリリースできるようにより多くのベータテスターをお待ちしています。\nぜひ、Elasticsearch 2.0.0-beta1をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)やWebフォーラムなどで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1440638952,"dir":"post/2015/","id":"744554499cb7880086fbd9b1f080e7e1","lang":"ja","lastmod":1440638952,"permalink":"https://blog.johtani.info/blog/2015/08/27/elasticsearch-2-0-0-beta1-released-ja/","publishdate":"2015-08-27T10:29:12+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 2.0.0-beta1 released 本日(8/26)、Lucene 5.2.1ベースのElas","tags":["elasticsearch"],"title":"Elasticsearch 2.0.0-beta1リリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:The Delete by Query API Is now a plugin\nElasticsearchの2.0.0-beta1では、これまであった Delete by Query APIが削除され、 新しく Delete by Query pluginに置き換えられています。\nもし、Delete by Query を利用する場合、2.0にアップグレードしたあとは、プラグインをインストールし、ドキュメントに従ってください。\nbin/plugin install delete-by-query なぜプラグインに? ElasticsearchのコアなAPIの品質を保つためであり、以前のDelete by Queryの実装は簡単にはフィックスできない大きな問題がありました。\n各リクエストのあとに、refreshを実行します。これは、削除されたデータが想定外に検索に出てこないようにするためです。\nまた、セグメントが大量にでき、マージが大量に発生し、ヒープが大量に消費されてインデキシングが劇的にスローダウンし、クラスタの複数のノードがクラッシュしてしまう状況も引き起こしました。 このクエリは、プライマリ、レプリカの両方で実行されるため、ことなるドキュメントを削除し、矛盾したレプリカ(データの破損)を引き起こしました。 アップグレードが不安定になります。これは、Delete by Queryリクエストがトランザクションログの中にクエリとして残るためです。そのため、アップグレードのあとに正確にパースされなかったり正確に実行されないかもしれません。例えば、インデックスエイリアスに対するリクエストで、それが削除された後の場合にこのようなバグが発生します。 対照的に、新しいプラグインは、安全な実装です。 scanとscrollリクエストでクエリにマッチしたIDを見つけ、そのIDを使って、bulk indexing APIで削除します。\nこの実装は、遅い必要があります。特に、クエリが多くのドキュメントを削除する場合です。 もし、多くのドキュメントをこのAPIを利用して削除する場合、アプリケーションをテストしてください。 そして、代わりにインデックス全体を消すようなアプローチに切り替えることができないか検討してください。\nDelete by Query pluginのドキュメントに、新しい実装についての違いなどのより詳しい説明があります。\nElasticsearch coreを最小限に プラグインに切り替えることは、簡単な決断ではありませんでした。 多くのユーザは問題なく、Delete by Queryを利用していました。 しかし、危険が常にそこにあり、些細とは言い切れない数のユーザが上記のような深刻な問題に遭遇していました。\nさらに、Elsticsearchのコアは信頼できるものでなければなりません。 他のコアAPIを利用して実装できる機能は、コアに含みません。特に、それがバグを含んでいる場合。 コアのすべての機能は強固であるべきで、Delete by Queryは人気があり、高性能ですが、そうではありませんでした。\n必要に応じて、このような難しいトレードオフの末、信頼性と品質を選びます。\nマッピングの削除の廃止 タイプのマッピングを削除する機能も2.0で廃止されます。 これは、同じフィールド名を、異なるフィールドのタイプで再利用した場合に、インデックスの破損を引き起こす可能性があるためです。\nしかし、Match All Queryで、Delete by Queryプラグインに対してタイプを指定することで、タイプのすべてのドキュメントを削除することはできます。 または、1つのインデックスに異なるタイプを複数含める代わりに、個別のインデックスに分割するようなアプローチに変更することを検討してください。\n","date":1440044644,"dir":"post/2015/","id":"5a9e950f4ac186925e5de978c5f72062","lang":"ja","lastmod":1440044644,"permalink":"https://blog.johtani.info/blog/2015/08/20/core-delete-by-query-is-a-plugin-ja/","publishdate":"2015-08-20T13:24:04+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:The Delete by Query API Is now a plugin Elasticsearchの2.0.0-beta1では、これまで","tags":["elasticsearch"],"title":"Delete by Query APIはプラグインへ(日本語訳)"},{"contents":"第11回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズさん、そして、Shayありがとうございました! 次回もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\n今回は、CTOのShayが来日していたので、英語でいろいろと喋ってもらいました。 4月同様、サムライズムの@yusukeさんに テキスト翻訳していただき、大変助かりました。 今回はQAベースのトークだったのでちょっときつかったですね、申し訳ない。。。\nチェックイン数など チェックインした人:141名 キャンセルしなかった人:51名 でした。 今回はあらかじめ220名(全員が来たらキャパオーバー)としていたので、キャンセル待ちの人は 当日の午後にはいなくなっていた状態です。まぁ、こんなもんかな。結構入りましたね。ありがたいです。\nLT 今回は、少し趣向を変えて、4社の方達にLTをしていただきました。 Shayが来日しているのもあり、事前に英語でスライドを作っていただけると助かりますとお願いさせていただきました。 英語でスライドを作っていただいていたので、伝わりやすくて助かりました、スピーカーの方々ありがとうございました!\n(海外のユーザにもリンクを紹介しやすいので、英語でスライド作ってもらえるといろいろと知ってもらえるのかも。)\nElasticsearch and Recruit Technologies Co., Ltd. / 株式会社リクルートテクノロジーズ 守谷 純之介さん スライド:未定\nN-Gramと形態素のハイブリッドの話などをしていただきました。 @ITで連載もされてますね。ありがとうございます。\nリクルート全社検索基盤のアーキテクチャ、採用技術、開発体制はどうなっているのか (1/2) ElasticsearchとKuromojiを使った形態素解析とN-Gramによる検索の適合率と再現率の向上 (1/3) Shayからは、elasticsearch-hadoopがあるから検討してねと質問(お願い?)がありましたw。\nElasticsearch as a DMP / 株式会社インティメート・マージャー 松田和樹さん @mats116 スライド:Elasticsearch as a DMP\nいくつかのデータソースからAEROSPIKE経由でelasticsearchにデータを登録しているようです。 Data Management Platformのエンジンの一部として、elasticsearchを利用しているようです。\nShayからの質問:「どの機能を使って関心のある単語を抽出していますか?」\n回答:「Significant Term Aggregation」です。\nShay:「おぉ、チェックしてみますw」。\nReal-time social big data analytics using elasticsearch / 株式会社ホットリンク宮田洋毅さん @kakka_jp スライド:未定\nソーシャルメディアのデータを解析するのにelasticsearchにデータを入れて解析。 時間軸での解析やテキストマイニングなんかをしているみたいでした。 いろいろと独自のプラグインを作ってるようです。(興味あるなぁ)\nShayからの質問:「ノード数は?」「30ノードで30シャード」\nElasticsearch in Hatena Bookmark / 株式会社はてな id:skozawa スライド:Elasticsearch in Hatena Bookmark\nはてなブックマークの検索の歴史(MySQL -\u0026gt; Sedue -\u0026gt; Solr -\u0026gt; Elasticsearch) はてなブックマークの検索(ユーザが利用)と社内利用と、ログ解析で利用してる Shayからの質問:「昨年会いましたよね?今はクラスタのサイズはどのくらいのサイズですか?」「メインクラスタは9データノード」\nOpen QA with Shay 思い出せるものだけ。。。(あとで追記します)\nElasticsearch 2.0の話 Pipeline Aggregationとか。 Spark Streaming対応してる? まだ検討中 elasticsearch-hadoopってどんなもの?HDFSにインデックス作ったりするの? いえ、Hadoopの入出力先としてelasticsearchが使える感じ 個人的にAWSのCloudSearchとAWSでElasticsearchはどっちがいい? 時系列データはCloudSearchだと難しいだろうし、AWS上ならfound.noがあるよ! PostgreSQLみたいに信頼性の高いデータストアを目指してる(まだ、プライマリデータストアには使わないで) その他、感想などのブログ Elasticsearch勉強会でLTしてきました | Intimate Merger Engineer Blog 『第11回elasticsearch勉強会』のまとめ #elasticsearchjp \u0008* [Elasticsearch] 第11回 Elasticsearch 勉強会へ参加してきた - 雑文発散(2015-07-28) 第11回 Elasticsearch 勉強会に参加したら英語力に危機感を覚えて最高だった まとめ 今回はShayが来日したので特別バージョンでした。 もっと英語を翻訳するサポートしないとですね、反省してます。。。ぜんぜん流暢じゃないしw\n次回は9月に開催予定ですが、12月にまたShayが再度来日する予定です。 丸1日のイベントを検討中で、Shay以外にも開発者が来日すると思います。 どんな話が聞きたい、どんな人と話をしたいなどあれば、コメントいただければ(対応できるかは。。。)\n勉強会のスピーカーは随時募集中ですので、コメント、メール、ツイートなど、コンタクトしていただければと思います。 よろしくお願いいたします。\n","date":1438321313,"dir":"post/2015/","id":"73b8194ad8fce0cabb01cd21d5e18500","lang":"ja","lastmod":1438321313,"permalink":"https://blog.johtani.info/blog/2015/07/31/11th-elasticsearch-jp/","publishdate":"2015-07-31T14:41:53+09:00","summary":"第11回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズ","tags":["elasticsearch","勉強会"],"title":"第11回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 1.7.1 and 1.6.2 released\n本日(7/29)、Lucene 4.10.4ベースのElasticsearch 1.7.1およびElasticsearch 1.6.2 のバグフィックス版をリリースしました。 これらのリリースは稀ですが、データの欠損が発生する重要なバグのフィックスを含んでいます。 すべてのユーザにアップグレードを推奨します。\nダウンロードおよびすべての変更については次のリンクをごらんください。\n最新安定版:Elasticsearch 1.7.1 1.6系バグフィックス:Elasticsearch 1.6.2 問題のバグ(#12487)は、 同時に複数のノードが故障またはリスタートをした場合の非常にまれな状況で、 シャードのすべてのコピーがクラスタから削除されてしまう状況を発生させます。 このバグは1.5.0から含まれています。\nこのリリースはまた、IPv4アドレスのCIDRマスクのバグのフィックス、 Shieldユーザがmore-like-this APIを利用できないバグのフィックスなど、 いくつかの変更も含んでいます(詳細は更新リストをごらんください)。\nぜひ、Elasticsearch 1.7.1をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1438173353,"dir":"post/2015/","id":"100c0a69bea7f02a0f4540ecaa37d0e3","lang":"ja","lastmod":1438173353,"permalink":"https://blog.johtani.info/blog/2015/07/29/elasticsearch-1-7-1-and-1-6-2-released-ja/","publishdate":"2015-07-29T21:35:53+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 1.7.1 and 1.6.2 released 本日(7/29)、Lucene 4.10.4ベースのE","tags":["elasticsearch"],"title":"Elasticsearch 1.7.1 および 1.6.2リリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 1.7.0 and 1.6.1 released\n本日(7/16)、Lucene 4.10.4ベースのElasticsearch 1.7.0およびElasticsearch 1.6.1 のバグフィックス版をリリースしました。 これらのリリースはセキュリティフィックスを含んでおり、すべてのユーザにアップグレードを推奨します。\nダウンロードおよびすべての変更については次のリンクをごらんください。\n最新安定版:Elasticsearch 1.7.0 1.6系バグフィックス:Elasticsearch 1.6.1 1.7.0が1.x系の最後のリリースとなります。 今後の新機能については、Elasticsearch 2.0以降で取り込まれる予定です。\nElasticsearch 1.7.0は小さなリリースですが、2つの重要なセキュリティフィックスと クラスタの安定化とリカバリに関する2つの重要な機能を含んでいます。\nセキュリティフィックス シャードアロケーションを遅らせる インデックスリカバリの優先度 セキュリティフィックス Elasticsearch 1.6.1 と 1.7.0 は次の2つのセキュリティフィックスを含んでいます。\nリモートコード実行の脆弱性 Elasticsearch 1.6.1より前のバージョンには、transport protocol(ノードとJavaクライアント間での通信に利用)により、 リモートでコードが実行される脆弱性があります。 これは、CVE-2015-3253でのGroovyに関係しています。\nGroovyのダイナミックスクリプティングがオフでも脆弱性があります。 アップグレードをしないユーザは、transport protocol のポート(デフォルトで9300)信頼したエージェントからのみの アクセスに限定することで、脆弱性から保護できます。\nこの問題をCVE-2015-5377としました。\nディレクトリ探索の脆弱性 Elasticsearch 1.0.0から1.6.0までのバージョンで、ElasticsearchのJVMプロセスによって読み込みが可能なファイルを 取得することができるディレクトリ探索攻撃の脆弱性があります。 アップグレードをしないユーザは、信頼できない場所からのSnapshot-Restore APIの呼び出しを防ぐためにファイアウォール、リバースプロキシやShieldを使用することができます。\nこの問題をCVE-2015-5531としました。\nシャードアロケーションを遅らせる Elasticsearch 1.6.0でSynced Flushingが導入されました。 これは、ノードのリスタート時に、更新が止まっているシャードのリカバリを劇的にスピードアップします。 しかし、この変更は、シャードの配置を無効にしている環境でのみうまく実行されます。 ノードが一時的にクラスタから外れている場合や予期せぬリブートの場合には役に立ちません。\nこのシナリオとは次のようなものです。\nノードの想定外のシャットダウン マスタがたのノードにシャードを再配置 各シャードが新しい場所にネットワーク越しにコピー その間に、外れていたノードが再度クラスタにジョイン マスタは新しいノードにシャードを再配置。新しいノードに存在する既存のシャードが全く再利用されない可能性がある ノードレベルとクラスタレベルの両方の並列的なリカバリを抑制しても、 この\u0026quot;シャードシャッフル\u0026quot;がクラスタに対して負荷をかける可能性があります。 これは、外れたノードが再度ジョインするのを単に待つことにより防げるかもしれません。\n待ちましょう! Elasticsearch 1.7.0はindex.unassigned.node_left.delayed_timeout設定を追加しました。デフォルトでは1分です。 これは、ノードがクラスタから外れたとき、ほかのノードにこれらのノードを再配置するまでマスタが1分待つということです。 ノードがこの1分の間に復帰した場合、マスタはローカルにあるシャードを再度配置します。\nなぜ1分? ノードがシャットダウンし、リスタートし、復帰するために十分な時間が1分だからです。 しかし、ノードが復帰しない場合にはまだ再配置が発生することを意味します。 デフォルト値を決定するのは難しいです。 この設定をどのくらいに減らすか、増やすかを決める必要があるかもしれません。\nこのデフォルト値は、config/elasticsearch.ymlファイルに設定できますが、インデックス設定の更新APIを使って設定することも可能です。\nこのデフォルトに関する知見をぜひフィードバックしてください。\nインデックスリカバリの優先度 1.7.0の2つ目の重要な機構はフルクラスタリスタートのような後に、 どの順番でインデックスをリカバリするかという優先度をつけることができるという機能です。\n電源故障による、ロギング用のクラスタのダウンを想像してください。 クラスタが普及した場合、500個のインデックスをリカバリするような場合、499個のインデックスのデータは古く、 500番目のインデックスが重要です。 もっとも最近作成されたインデックスがリカバリされるまで、インデキシングを待つというようなことはできません。\nこれまでは、インデックスはランダムな順序でリカバリされ、重要なインデックスがリカバリされるまで待つしかありませんでした。 1.7.0では、インデックスは優先度の順番でリカバリされます。 この優先度は次のプロパティで指定できます。\nindex.priority設定(大きな値が優先度が高い) インデックス作成日(新しいものが優先度が高い) インデックス名 既存のクラスタについて特に変更せずとも、最も最近作成されたインデックスが古いものよりも復旧されます。 古いインデックスの優先度を上げるためには、index.priority設定に0よりも大きな値を設定します。\nPUT important_index/_settings { \u0026#34;index.priority\u0026#34;: 5 } この設定は、存在するインデックスに対して更新できます。リカバリ中にもです。\nまとめ ぜひ、Elasticsearch 1.7.0をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1437546817,"dir":"post/2015/","id":"809925e891b0456231c374b09cbe4a90","lang":"ja","lastmod":1437546817,"permalink":"https://blog.johtani.info/blog/2015/07/22/elasticsearch-1-7-0-and-1-6-1-released-ja/","publishdate":"2015-07-22T15:33:37+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 1.7.0 and 1.6.1 released 本日(7/16)、Lucene 4.10.4ベースのE","tags":["elasticsearch"],"title":"Elasticsearch 1.7.0 および 1.6.1リリース(日本語訳)"},{"contents":"東京以外での勉強会の第2弾として、関西で勉強会を開催してきました。\nElasticsearch勉強会 in 大阪 Elasticsearch勉強会 in 京都 会場提供をしていただいた、Yahoo!大阪、はてなのみなさん、ご協力ありがとうございました!\nここからはいつものメモです。 ちなみに、大阪の勉強会に、@takuya_aさんと@5kozawaさんの両名にお越しいただき話をしていただきました。 なので、勉強会の内容はほぼ同一になります。\nIntroduction Elastic @johtani スライド:Introduction Elasticsearch\n初めての関西での勉強会ということで、ElasticsearchのOSSおよび商用プラグインの紹介をしてきました。 もちろん、Kibanaのデモもちょっとだけ。スプラトゥーンに関するデータをKibanaでちょっとだけ。 突貫でデータをかき集めたのでもう少し改良しないとですが。\nElasticsearch での類似文書検索と More Like This API 詳解 / 株式会社はてな id:takuya-a スライド:Elasticsearch での類似文書検索と More Like This Query API 詳解\nElasticsearchのMore Like Thisのソースコードリーディングみたいな感じで、 内部でどうやって処理されているかの説明を詳しくしてもらいました。\n前のはてなエンジニアセミナーで話をされていた検索精度の件に絡んだ内容になっているかと。 (大阪で発表してもらった時より京都での発表が分かりやすくなってました。1日で改善されたのすごい!) MoreLikeThisだとチューニングつらいので、自分で作るためにTermVectorAPIでやってみたという流れかと。\n以下は発表後に出てきた質問のいくつかです。\nQ:MoreLikeThisに対してTermVectorで柔軟にできる? A:TermVectorのAPIで統計情報が取れるので、それを使うことでさらなるデータの更新ができる。\nQ:TFとかの統計情報が必要なら、すべてインデックスをしたあとじゃないとちゃんとした値はとれないのでは? A:TermVectorで取得したものをどうやって使うか\nQ:TermVectorAPi\u0026hellip;聞こえなかった A:。。。\nElasticsearchを用いたはてなブックマークのトピック生成 / 株式会社はてな id:skozawa スライド:Elasticsearchを用いたはてなブックマークのトピック生成\nSignificant Terms Aggregationを活用してる話。 トピックページの生成のために、Significant Terms Aggregationをどうやって利用しているかなどのお話でした。\nトピックの集合の重複だったり、精度の判定方法とかいろいろ詳しく説明していただきました。\nQ:2011年と12年で11年の方が多いのは? A:ブックマークの件数に比例\nQ:Significant terms aggsのsizeはいくつをつかってますか? A:20を指定してます。\nQ:Yahooとかニュースをストップワードとしてますが、Yahoo自体のニュースに関してはどーしてるんですか? A:本文とタイトルから別々に作っていて、タイトルからは弾かれますが、本文から作った時に出てきます。\nはてなブックマークにおける Elasticsearch の運用まわりの話 / 株式会社はてな id:hagihala スライド:未定(おそらく公開される)\n体調が回復しきっていない中の発表ありがとうございました。 大幅に修正された資料が出てくるかなと。(ツイートできない数値がちらほらあったので)\nElasticsearchのクラスタの構成、どういった点で困ってたのでどういう調べ方をしたのか、どういった対処をしたのか。 どのあたりが次の課題かなどの話もありました。\n感想・反省点など 大阪、京都ともに30名弱の方の参加をしていただきました。ありがとうございました。 反省点としては、ハッシュタグを告知し忘れてました。。。\n勉強会はやはり、東京が異常に活発で、大阪や京都はまだそれほどでもないのかなぁとも。 大阪はエンジニアの人や会社も多い気がするんですが。私の告知の仕方もあるかもなぁと。 次回があれば、大阪での事例も聞きたいので、スピーカーをもっと探さないとなと。\n関連ブログなど 見つけたら、リンク追加していきます。\nElasticsearch勉強会 in 大阪/京都で発表しました \u0008* 「Elasticsearch での類似文書検索と More Like This Query API 詳解」というタイトルで発表しました その他(余談) 大阪のYahoo!さんは立地条件(梅田のすぐそば)がよく、\n夜景も綺麗でした。大阪城とかも見えてました。(夜景じゃないけど。。。)\n京都は祇園祭の真っ最中。\n水曜日はお休みをいただいて、観光してました。ちょっと日焼けが。。。 おかげで、リフレッシュできました。三十三間堂とか良かった:)\nあまり、関西に縁がない(大阪15年ぶり、京都10年ぶり)ので、 もっとユーザが増えて勉強会の機運が高まると嬉しいなと。:)\n","date":1437010857,"dir":"post/2015/","id":"dd6c32a722dc815273cd9ed8cd6c671b","lang":"ja","lastmod":1437010857,"permalink":"https://blog.johtani.info/blog/2015/07/16/kansai-1st-elasticsearch-jp/","publishdate":"2015-07-16T10:40:57+09:00","summary":"東京以外での勉強会の第2弾として、関西で勉強会を開催してきました。 Elasticsearch勉強会 in 大阪 Elasticsearch勉強会 in 京","tags":["勉強会","elasticsearch"],"title":"大阪と京都でElasticsearch勉強会を開催しました。 #elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:The Great Mapping Refactoring\nElasticsearchのユーザの悩みの最も大きなものの一つは、 タイプとフィールドのマッピングに関する多義性です。 この多義性は、インデックス時の例外やクエリ時の例外、 正しくない結果、リクエストからリクエストへ変化する結果、 また、インデックスの故障やデータのロスを結果として引き起こします。\nElasticsearchをより強固で予測可能な振る舞いをするようにする作業において、 フィールドやタイプのマッピングをより厳格でより信頼性を高くするかといったことに 多くの変更を費やしました。 多くのケースで、Elasticsearch v2.0で新しいインデックスを作るときにのみ、 新しいルールを強制し、これまでのインデックスに関しては後方互換性を保つようにします。\nしかし、幾つかのケースでは、先ほど説明したようなフィールドマッピングの コンフリクトなどが存在するため、それらを利用できないです。\nコンフリクトしたフィールドのマッピングをもつインデックスはElasticsearch v2.0にはアップグレードできません。\nもし、これらのインデックスのデータが必要ない場合は、インデックスを消せばいいです。 そうでない場合はマッピングを正しくして再度インデックスする必要があるでしょう。\nマッピングを正しく変更することは、私たちが簡単に決めることではありません。 ここからは、現在ある問題点と、私たちがどのように実装して解決したかについて説明します。\nフィールドマッピングのコンフリクト あいまいなフィールドのルックアップ タイプのメタフィールド アナライザ設定 index_nameとpath 同期的なマッピングの更新 マッピングの削除 2.0のための準備 フィールドマッピングのコンフリクト これまで、わたしたちはドキュメントのタイプは「データベースのテーブルのようなもの」と説明していました。 タイプの目的を説明する簡単な方法だったからです。 しかし、残念なことにこれは、真実ではありません。 「同じ」インデックスの「異なるタイプ」にある同じ名前のフィールドは、 内部的に、Luceneのフィールド名が同じものになります。\nもしerrorフィールドとして、ドキュメントタイプがapacheのものには数値(integer)を、 ドキュメントタイプがnginxのものには文字列(string)を割り当てた場合、 Elasticsearchは同じLuceneのフィールドに数値と文字列のデータをもつことになります。 このフィールドに対して、検索やaggregationを行う場合、おかしな結果を受け取るか、例外が帰ってくるか、 インデックスが破損することになります。\nこの問題を解決するために、まず、ドキュメントタイプの名前をフィールドの名前の前に追加することを考えました。 各フィールドは完全に別のものとなります。 このアプローチの利点はドキュメントタイプが実際のテーブルのようになることです。\nしかし、この方法には多くの欠点があります。\nフィールドは常に、他のタイプとは異なるものであると区別するためもしくは、複数のタイプに同じフィールドのクエリのためにワイルドカードをつけた場合、 ドキュメントタイプを前につける必要があります。 複数のドキュメントタイプに対して同じフィールド名で検索する場合、クエリを個別に発行しなければならなく遅くなります。 多くの検索で、既存の多くのクエリを壊してしまうために、単純なmatchやtermクエリの代わりに、multi-fieldクエリを使う必要があります。 圧縮の効率の悪さから、ヒープ利用量、ディスク使用量、I/Oなどが、増加します。 複数のドキュメントタイプに対するaggregationは、global ordinalの利点を利用できなくなるために、遅くなり、メモリの使用量も増えます。 解決方法 最終的に、同じインデックスの同じ名前を持つ全てのフィールドは、同じマッピングを持つ必要があるというルールを採用することに決めました。 ただ、copy_toやenabledのようなパラメータはタイプごとに指定することができるようになっています。 これにより、データの破損、クエリ時の例外そして、おかしな結果が発生する問題を防ぎます。 クエリとaggregationは現在でも高速なままで、圧縮率を最大化し、ヒープ使用量やディスク使用率の低減させます。\nこの解決方法の欠点は、個別のテーブルとしてタイプを扱いたいユーザが彼らの考え方を変える必要があるということです。 これは、思ったよりも問題ではありません。 実際には、多くのフィールド名はデータの明確なタイプを表現しています。 created_dateは常に、日付ですし、number_of_hitsフィールドはいつも数値です。 フィールドマッピングがコンフリクトしているユーザはデータを失ったり、おかしなデータを受け取ったり、データを欠損させています。 ベストプラクティスにユーザが従っているかどうかによらず、インデックス時に正しい振る舞いを強制することが現在の違いです。\nユーザの多くがコンフリクトしていないフィールドマッピングをもっていれば、 コンフリクトが起きた場合、技術がこれらのシチュエーションを扱うことが可能になると思いませんか? そこにはいくつかの解決方法があります。\nタイプの代わりにインデックスを別々に 最も簡単な解決方法です。インデックスを別々のインデックスとし、実際のデータベーステーブルのようにします。 インデックスをまたいだ検索はタイプをまたいだ検索のように動作しますし、 ソートやaggregationも同じデータタイプへのクエリのように動作します。これまでと同じ制限です。\nコンフリクトしたフィールドの名前の変更 コンフリクトがごくわずかな場合、(Logstashやアプリケーションで使っているものも一緒に)よりわかりやすいフィールド名に変更することで解決できます。 例えば、2つのerrorフィールドがあった場合に、error_codeとerror_messageに変更します。\ncopy_toもしくはmulti-fieldsを利用 異なるドキュメントタイプのフィールドは別々のcopy_toを設定できます。 元のerrorフィールドはindexの設定にnoが設定してあり、全てのドキュメントタイプで無効化されていますが、 特定のタイプだけ、errorフィールドの値を数値のerror_codeフィールドにコピーすることができます。\nPUT my_index/_mapping/mapping_one { \u0026#34;properties\u0026#34;: { \u0026#34;error\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;no\u0026#34;, \u0026#34;copy_to\u0026#34;: \u0026#34;error_code\u0026#34; }, \u0026#34;error_code\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34; } } } 他のタイプでは文字列のerror_messageにコピーします。\nPUT my_index/_mapping/mapping_two { \u0026#34;properties\u0026#34;: { \u0026#34;error\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;no\u0026#34;, \u0026#34;copy_to\u0026#34;: \u0026#34;error_message\u0026#34; }, \u0026#34;error_message\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } } 同様の解決方法としてmulti-fieldも使えます。\n各データタイプに対してネストしたフィールドに ときどき、Elasticsearchに送ったドキュメントやドキュメントがもっているフィールドを制御できない場合があります。 部分的なコンフリクトに加え、闇雲に、ユーザが送ってきたフィールドを受け入れると、マッピングが肥大化します。 タイムスタンプやIPアドレスをフィールド名に使うようなドキュメントがあると考えてください。\nnested フィールドにすることで、str_val、int_val、date_valというような各データタイプを利用できます。\nこのアプローチによって、次のドキュメントは\n{ \u0026#34;message\u0026#34;: \u0026#34;some string\u0026#34;, \u0026#34;count\u0026#34;: 1, \u0026#34;date\u0026#34;: \u0026#34;2015-06-01\u0026#34; } アプリケーションによって、次のようにフォーマットしなおす必要があります。\n{ \u0026#34;data\u0026#34;: [ {\u0026#34;key\u0026#34;: \u0026#34;message\u0026#34;, \u0026#34;str_val\u0026#34;: \u0026#34;some_string\u0026#34; }, {\u0026#34;key\u0026#34;: \u0026#34;count\u0026#34;, \u0026#34;int_val\u0026#34;: 1 }, {\u0026#34;key\u0026#34;: \u0026#34;date\u0026#34;, \u0026#34;date_val\u0026#34;: \u0026#34;2015-06-01\u0026#34; } ] } この解決方法は、アプリケーションサイドでより多くの作業が必要ですが、コンフリクトの問題とマッピングの肥大化の問題を同時に解決します。\nあいまいなフィールドのルックアップ 現在、フィールドの指定には\u0026quot;short name\u0026quot;、フルパス、ドキュメントタイプを前につけたフルパスが利用できます。 これらのオプションがあいまいさをもたらしています。 サンプルとして次のマッピングをご覧ください。\n{ \u0026#34;mappings\u0026#34;: { \u0026#34;user\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;title\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, \u0026#34;blog\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;title\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;user\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;fields\u0026#34;: { \u0026#34;title\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } } } } } } titleはuser.title、blog.title、blog.user.titleのどれでしょう? user.titleはuser.titleまたはblog.user.titleのどちらでしょう? 答えは「場合によります。」です。Elasticsearchが最初に見つけたものになります。 フィールドはリクエストごとに変わるため、各ノードでマッピングがどのようにシリアライズされたかに依存します。\n2.0では、フィールドを指定する時に、ドキュメントタイプを除いたフルパス名を使用するべきでしょう。\nuser.titleは、blogタイプのuser.titleを意味します。 titleは、userとblogタイプのtitleフィールドを意味します。 *titleはuser.titleとtitleフィールドの両方にマッチします。 userタイプのtitleフィールドとblogタイプのtitleの違いはどのように指定するのでしょう?\n指定できません。フィールドマッピングのコンフリクトで説明した変更により、 titleフィールドは両方のタイプで同じフィールドになります。 本質的にtitleと呼ばれる1つのフィールドになります。\nuser.やblog.のようなタイプのプレフィックスはタイプを指定することによるフィルタリングで効果があります。 クエリのblog.titleフィールドはblogタイプのドキュメントだけを検索し、userタイプのドキュメントを検索しません。 このシンタックスは誤解を招きやすいです。なぜなら、いつでも動作するわけではないからです。 aggregationやsuggestionはすべてのタイプに関する結果を含みます。 この利用のため、上記の例のあいまいさがあるので、タイプのプレフィックスはサポートしません。\n重要 short nameやタイププレフィックスを利用したpercolatorは更新する必要があります。\nタイプのメタフィールド すべてのタイプはメタフィールドを持っています。_id、_index、_routing、_parent、_timestampなどです。 これらのほとんどはindex、store、pathのような幾つかの設定をサポートしています。 これらの設定について次のようにシンプルにしました。\n_idと_typeは変更不可 _indexは、ドキュメントのもつインデックスを保存するためにenabled _routingはrequiredのみを指定 _sizeはenabledのみ _timestampはデフォルトで保存される _boostと_analyzerは廃止。古いインデックスのものは無視される ドキュメントのフィールドから_idと_routingと_timestampの値を抽出することができました。 この機能は廃止されます。これは、ドキュメントのパースとコンフリクトを起こすためです。 代わりに、これらの値はURLもしくはquery stringで指定可能です。\n_boostと_analyzerフィールドは例外で、すでにあるメタフィールドの設定は古いインデックスのものが採用されます。\nアナライザ設定 これまで、indexとsearchのアナライザがインデックス、タイプ、フィールド、ドキュメント(_analyzerフィールドで)の それぞれのレベルで指定可能でした。 同じフィールドに対して異なるanalysis chainの組み合わせができることにより、おかしな関連度を引き起こしていました。 フィールドマッピングのコンフリクトを解消することに加え、アナライザの設定も簡略化します。\nAnalyzedな文字列フィールドは、analyzer設定とsearch_analyzer設定(analyzer設定の値をデフォルトとする)を指定できます。index_analyzer設定はanalyzerとなります。 複数のタイプで同じ名前のフィールドがある場合、フィールドはすべて、同じアナライザの設定を持たなければなりません。 タイプレベルのデフォルト設定のanalyzer、index_analyzer、search_analyzer設定は廃止されます。 デフォルトアナライザはインデックスごとにインデックスのanalysis設定で設定します。これらはdefaultもしくはdefault_searchという名前で設定します。 ドキュメントごとの_analyzerフィールドはサポートしません。既存のインデックスのものは無視されます。 index_nameとpath index_nameとpath設定は(Elasticsearch v1.0.0から利用できる)copy_toによって置き換わりました。 既存のインデックスについてはこれらは機能しますが、新しいインデックスでは指定できません。\n同期的なマッピングの更新 現在、これまで存在していないフィールドを含むドキュメントをインデキシングするとき、 フィールドはローカルのマッピングに追加され、それから、マスターに変更(新しいマッピングをすべてのシャードに適用する更新)が送信されていました。 同時に2つのシャードに同じフィールドを追加することができます。 また、そのとき、異なる2つのマッピングがある可能性があります。 1つはdoubleでもう1つはlongだったり、stringとdateだったりと。\nこのような場合、マスターに最初に届いたマッピングが採用されます。 しかし、「負けた」マッピングをもつシャードでは、すでに異なるデータのタイプを利用しているため、 これを利用し続けます。 そのご、ノードをリスタートしたときに、シャードが別のノードに移動し、マスターにあるマッピングを適用します。 このとき、インデックスが破損したりデータを失ったりします。\nこれを防ぐために、シャードはインデキシングを続ける前に、新しいマッピングがマスターによって採用されるかどうかを待つようになりました。 これはすべてのマッピングが安全に更新されます。 新しいフィールドをもっているドキュメントをインデキシングすると、前よりも処理が遅くなるでしょう。 受け入れられることを待つ必要があるためです。 しかし、クラスタの状態の更新処理のスピードが次の2つの新しい機能によって大きく改善されています。\nクラスタ状態の差分:可能であれば、クラスタの状態の変更はクラスタ状態全体の変更ではなく、部分的なものとする。 シャードへのリクエストの非同期化:シャードアロケーション処理中に、マスタノードは、 割り当てられていないシャードのコピーの日付が最新のものを持っているかを見つけるために、リクエストをデータノードに対して送信します。 ここで、クラスタ状態を変更する呼び出しがブロッキングで行われていました。v1.6.0から、このリクエストはバックグラウンドで非同期で実行されます。 これにより、マッピング更新のようなペンディングタスクをより早く処理できるようになります。 マッピングの削除 (そのタイプのドキュメントがある場合)タイプマッピングを削除できないようにします。 マッピングを削除した後に、削除されたフィールドの情報は、Luceneレベルでは存在し続け、 もし、後から同じ名前のフィールドが追加されたときにインデックスの破損を引き起こします。 そのようなマッピングは残しておくか、新しいインデックスに再インデックスすることができます。\n2.0のための準備 マッピングがコンフリクトしているかどうかを決めることは、手動で行うには慎重に行う必要があります。 私たちは、Elasticsearch Migration Pluginを提供します。 これは、2.0で非推奨になったり廃止された機能を利用しているかどうかを見つけるために役に立つでしょう。\nもし、コンフリクトしたマッピングを持っている場合、 正しいマッピングを持つ新しいインデックスにデータを再インデックスするか、 必要ないなら削除します。 これらのコンフリクトを解決しない限り2.0にはアップグレードできないでしょう。\n","date":1436346691,"dir":"post/2015/","id":"ee4ff9e4e8a1948795e26af2f3f8a30f","lang":"ja","lastmod":1436346691,"permalink":"https://blog.johtani.info/blog/2015/07/08/great-mapping-refactoring-ja/","publishdate":"2015-07-08T18:11:31+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:The Great Mapping Refactoring Elasticsearchのユーザの悩みの最も大きなものの一つは、 タイプと","tags":["elasticsearch"],"title":"Mappingのすばらしいリファクタリング(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 2.0.0.beta1 coming soon!\nElasticsearch 2.0.0.beta1のリリースの準備をしています。 これは、Lucene 5.2.1に含まれる多くの改善が利用できるようになります。 このリリースに関するいくつかの機能は次のようなものです。\nPipeline Aggregations 差分や移動平均、他のAggregationsの結果に対する series arithmeticのようなaggregationが利用可能になります。 この機能は、これまでは、クライアントサイドで実行する必要がありました。 しかし、この計算をより強力な解析クエリを構築してElasticsearchで 実行することができるようになります。 クライアントのコードをより簡潔にすることができます。 これにより、予測解析や異常検知のようなことができるようになります。\nQuery/Filter merging Filterはなくなります。全てのフィルタは、クエリになります。 クエリコンテキストで利用されると、効率的に関連度スコアを計算し、 フィルタコンテキストで利用されると、単に、 マッチしていないドキュメントを除外する(今のフィルタのようなもの)だけです この変更は、クエリ実行が自動的に、より効率的な順番で実行されるように 最適化されることを意味します。 例えば、フレーズやgeoクエリのような遅いクエリは まず、近似フェーズを実行し、それから、より遅い実際のフェーズが 結果に対して行われます。 フィルタコンテキストにおいて、頻繁に利用される条件は自動的にキャッシュされます。\nConfigurable store compression index.codec設定により、高速化のためのLZ4圧縮(default)か インデックスサイズを小さくするためのDEFLATE(best_compression)を 選択できます。これは、ロギングでとくに役に立ちます。 これにより、古いインデックスオプティマイズする前にbest_compressionに 変更できます。\nこれらに関するブログ記事がすぐに公開されるでしょう。\nPerformance and resilience 以降では、新しいメジャーリリースに関して簡単に紹介します。 2.0の変更の多くは内部の機能に関するものであり、 直接ユーザに関連するわけではないからです。\n新しいメジャーバージョンのテーマは、パフォーマンス、安定性、 堅牢性、予測可能性、そして使い勝手の良さです。\n物事が予測した通りに動作する 何か問題があった場合に、Elasticsearchから役立つフィードバックがある ローレベルの設定を扱う必要はなく、Elasticsearchが良い設定を決定する これらに加え、データがより安全に これらの目標は完全ではありません。 まだ、多くの改善があります。しかし、2.xブランチで、 すでに500コミットを超える大きな改善が実施されています。\non-diskの doc valuesをデフォルトで利用(これまではfielddata)。 ヒープ使用量を減らして、スケーラビリティを向上 セグメントマージ処理中のメモリ使用量の削減 normsの圧縮率の改善。ヒープスペースを利用している大きな処理のひとつだったため。 全てのリクエストの後に、transaction logをfsyncすることで、デフォルトで耐久性を向上 全てのファイル変更をアトミックに(部分的なファイルの書き出しはなし) マージを自動で制限 フレーズクエリやスパンクエリを高速化 フィルタキャッシュをより効率化するための圧縮されたビットセット クラスタ状態の差分更新 構造化されたJSON形式の例外 よりきめ細かいLuceneのメモリレポート デフォルトではlocalhostにのみバインド。開発のノードが他のクラスタにジョインするのを防ぐ parent/childのクエリ実行最適化のためにリライト Java Security Managerで必要最小限なパーミッションで実行 全てのコアなプラグインをelasticsearchリポジトリに移行し、Elasticsearchのバージョンに同期してリリースされる予定 アップグレード前に メジャーバージョンのアップグレードは問題のあるものを一掃する機会を与えてくれます。 できる限り、これらの変更をアップグレードするために、簡単な方法を提供しようとしています。 しかし、Elasticsearch 2.0にアップグレードする前に、必要な処理が2つあります。\n1つ目は、フィールドとタイプマッピングに関することです。 mapping APIは、現在、それほど厳密ではありません。 内蔵された保護機構を提供する代わりに、ユーザがベストプラクティスを知っていると信頼していました。 2.0では、mappingはより厳密で安全ですが、いくつかの変更では、後方互換性を保っていません。 詳細についてはThe Great Mapping Recatoringをごらんください。\n2つ目はElasticsearch 0.20以前のユーザに関する変更です。 これは、Lucene 3.xを使っています。 Elasticsearch 2.xはLucene 5をベースにしています。 Lucene 5はLucene 4.xによって作成されたインデックスの読み込みはサポートしていますが、 Lucene 3.xに関してはサポートしていません。\nElasticsearch 0.20以前のバージョンによって生成されたインデックスを持っている場合、 Elasticsearch 2.xのクラスタをスタートすることはできません。 これらの古いインデックスを削除するか、Elaticsearch 1.6.0以上に含まれている upgrade APIを使用してアップグレードする必要があります。\nupgrade APIの実行は2つのジョブを実行します。\n古いLuceneフォーマットのセグメントを最新のフォーマットで書き換えます Elasticsearch 2.xによって読み込めるようという印をインデックスに追加します 全てのセグメントを最新バージョンにアップグレードするのも良い案ですが、 アップグレード前に必要な処理を最小限に抑えることも可能です。 (Lucene 3.xのセグメントだけをアップグレード) その場合は、only_ancient_segmentsパラメータを指定します。\nElasticsearch Migration Plugin Elasticsearch 2.0 に移行する前に、インデックスがアップグレードが必要なのか、 ほかになにかするべきことがあるのかをチェックする助けになる Elasticsearch Migration Pluginをリリースしました。\nまず、プラグインをインストールします\n./bin/plugin -i elastic/elasticsearch-migration プラグインのインストール後はノードのリスタートは必要ありません。\n以下のリンクをブラウザで開きます。\nhttp://localhost:9200/_plugin/migration\n(localhost:9200はインストールしたホスト名に変更してください。)\nMigration pluginに関してバグやご意見がある場合は、GitHubのIssueにお願いします。\n","date":1436250300,"dir":"post/2015/","id":"f887e1aabf801e351bfb39698f208af1","lang":"ja","lastmod":1436250300,"permalink":"https://blog.johtani.info/blog/2015/07/07/elasticsearch-2-dot-0-0-dot-beta1-coming-soon-ja/","publishdate":"2015-07-07T15:25:00+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 2.0.0.beta1 coming soon! Elasticsearch 2.0.0.beta1のリリースの準備をしています。","tags":["elasticsearch"],"title":"Elasticsearch 2.0.0.beta1リリース間近(日本語訳)"},{"contents":"4ヶ月前に、Found joined our team at Elasticをアナウンスしました。 Foundの素晴らしいチームと一緒に仕事をしていますが、彼らによって、より素晴らしい hosted Elasticsearchを提供することになりました。\n私たちがともに密接に働くことにより、本日(2015/7/1)、 新しい2つのFoundを提供することになりました。 Found StandardはこれまでのFoundの機能に加え、さらに低価格を提供します。 Found Premiumは、SLAサポートと、ShieldやWatcherを将来Found上で提供します。\nFound Standard Foundは素晴らしいです。専用のElasticsearchクラスタ、簡単なスケール、 ビルトインのセキュリティそして、時間単位での課金などを持っています。 私たちは、hosted Elasticsearchを探している方に、 Foundが適したソリューションであると思っていますし、 すべての方に利用できて手頃な価格であるということを確信したいと思っています。\n本日(2015/07/01)からFoundの価格をかなり低価格にし、 月額50ドル以下でhosted Elasticsearchを簡単に試してもらえるようにしました。\n価格を下げることは正しい重要なステップですが、 Foundを利用している全ての人に、より良い経験を持っていただきたいと考えています。 低価格化と一緒に、free backupsとbuilt in SSDもFoundで提供を始めることになります。\nFoundの重要な特徴の一つが、高可用性のために、クラスタをいくつのデータセンターに持つかを 選択できることです。 データは重要です。これが正しい選択でユーザの助けになると考えています。 これにより、私たちの価格は、複数のデータセンターにより安価に配置することができます。\nまた、KibanaもElasticsearchのデータを可視化する素晴らしい方法だと考えています。 Kibana 4が最新バージョンですが、 これは、サーバサイドコンポーネントを持っています。 これは、サービスとしてこれを提供するために、追加の料金がかかることを意味します。 Foundチームが築いた素晴らしい基盤とKibanaチームの努力により、 hosted Elasticsearchクラスタで無料のKibana 4を7月15日より提供することになりました。\nFound Premium また、私たちは、オープンソースプロダクトに関してサブスクリプションを提供していますが、 Found Standardに対しても提供することになりました。 これが、Found Premiumです。\nフォーラムベースのサポートよりもSLAベースのサポートを望んでいる場合、 プロダクトを開発しているチームからのサポートを受けることができるオプションを 提供し始めました。 クリティカルなイベントを持っていたり、私たちのプロダクトに関する 問題を予測するためのベストなヘルプやガイダンス、アドバイスを探しているような場合にサポートします。\nさらに近い将来、サブスクリプションの一部として、Shield(Elasticasearchのセキュリティプラグイン)やWatcher(アラーティングプラグイン)が利用できるようになります。\n私たちのチームがともに働き、多くのことを可能にし、すばらしい仕事をユーザに提供したかを 将来も楽しみです。 私は非常に誇りに思っていますし、気に入っていただけたらと思っています。 ぜひ、7/15のWebnarに参加してくわしい話を聞いていただき、疑問を解消してください。\n","date":1436250000,"dir":"post/2015/","id":"9cc2a0b6c8be1405cddcdeb4487c59fe","lang":"ja","lastmod":1436250000,"permalink":"https://blog.johtani.info/blog/2015/07/07/we-just-made-found-more-awesome-ja/","publishdate":"2015-07-07T15:20:00+09:00","summary":"4ヶ月前に、Found joined our team at Elasticをアナウンスしました。 Foundの素晴らしいチームと一緒に仕事をしていますが、彼らによって、より","tags":["elasticsearch","found.no"],"title":"さらに進化したFound(日本語訳)"},{"contents":"JustTechTalk#02 形態素解析のあれやこれや@ジャストシステム\nに参加してきました。 ジャストシステムさんの形態素解析器JMATの話とKagome、Janome、Kuromoji.js、ssslaの開発者の パネルディスカッションでした。\nということで、いつものメモです。\nジャストシステムの形態素解析その2(機械学習編) JMATの話\n前回は辞書の話 今回は学習の話 教師あり/教師なし\nJMATは教師あり 教師なしは研究段階 ラティス構造を辞書ベースで構築して、コストの総和が最小の経路を求める\n連接、単語生成とか。 学習は3フェーズ\nベース、能動、部分アノテーション ベース 300万文のコーパスから1万文のみを利用(なぜ?今から説明) 64GBマシン買ってみたけど、複数実験するには追いつかない オンライン学習がメジャーでない時代に作り始めたので、つかってない CRF学習器を改善 結果として50万文くらいで精度が良くなる 辞書チームからNGがでて、方向転換 方向転換した結果が3つのフェーズらしい ピタジョブに採用? 疑問 \u0008* JMATって、Webの検索の前処理とか分類とかに主に利用するのかな?\nATOKでもこのノウハウって利用してるんかな? 辞書もあるらしいけど、辞書更新されると学習器のデータとかどーなるんだろ? 形態素解析器の実装言語Talkについて kuromoji.jsの@takuya_aさん\nTyped Arrayサポートが高速にできてる理由でもあるらしい Kagomeの@ikawahaさん\nGoはいろいろないらしい Janomeの@moco_betaさん\nsssla(茶筌のRuby clone)\nなんで作ったの?\n形態素解析のライブラリ「解析部分」はNLPのHelloWorldだから なんで、その言語?\nPython 3系は文字列とバイト配列の扱いがすごく楽! その言語で困った点は?\nGoだと、辞書を内包するのが大変 JSは苦労したところしかない(1hくらいしゃべれるぞ!)。基本的なデータ構造とかもない Pythonはパフォーマンスを考えないと Ruby(1.6だったので)もパフォーマンスが その言語を開発するときに必須のものは?\nGoはとくにない。エディタはどれでもOK browserifyが便利 \u0008* ほかの人たちの言語をdisってください * JSは論外。Pythonのコードフォーマッターが揺れるのが。。。Rubyはバージョンが。。。 * Goはブラウザで動かない。Pythonもブラウザで動かない。Rubyも(ry * ほかのは触ったことないので。。。 * Pythonは2.xか3.xか決めてくれ!\nなんで、Kuromojiベースなの? Java読みやすいから。 MeCabとKuromojiの違いは? 未知語の処理が結構違う 感想 きれいなロビーで良かったのですが、マイクがあると嬉しかったかもしれません。 前回の辞書の話も聞いてみたかったかも。\n","date":1436147341,"dir":"post/2015/","id":"18b7998a871950ebc36c415a53630477","lang":"ja","lastmod":1436147341,"permalink":"https://blog.johtani.info/blog/2015/07/06/attend-justsystem-techtalk-no2/","publishdate":"2015-07-06T10:49:01+09:00","summary":"JustTechTalk#02 形態素解析のあれやこれや@ジャストシステム に参加してきました。 ジャストシステムさんの形態素解析器JMATの話とKagome、Janome、","tags":["勉強会"],"title":"JustTechTalk#02 形態素解析のあれやこれや@ジャストシステムに参加しました。"},{"contents":"ひさびさに、勉強会メモ。 Hatena Engineer Seminar #5 @ Tokyoに当選したので行ってきました。\nいつもは近寄らないオシャレな街をドキドキしながら行ってきました。\nということで、簡単なメモです。\nはてなブックマーク全文検索の精度改善 id:takuya-a 問題:検索精度がよくない 京都で検索 → 「ポーランドの京都」「京都大学のまるまる教授」のようなもんがヒット 京都っぽいエントリが出て欲しい。 京都っぽい??? 問題点をブレイクダウン 課題 クエリ考えるの大変だよね 順序が新着順なのが辛い 適合率と再現率の両立 そして(ドラムロール)、できました!(さすが)\nアイデア:はてブのタグを利用する。 関連キーワードを抽出して、クエリ拡張する。\n関連キーワードとは? タグ検索する 検索にヒットしたTerm Vectorsを取得 特徴語をTop25件取得 もっともスコアが高いタームを特徴語とする 英語のストップワードとかが問題点となってたり。 →Dynamic stop word listというのを利用して排除(IDF、RIDF、Gain) 今後の課題 再現率の向上 解析用のフィールド・辞書を追加(精度向上や解析ミスなど) トークに出てきた機能など トークに出てきたElasticsearchの機能については、こんなツイートをしてたので、参考にしてもらえれば。\nこれのkuromoji_stemmerを使ってるっぽい? #hatenatech / elastic/elasticsearch-analysis-kuromoji - https://t.co/3F2sBYXLPH\n\u0026mdash; Jun Ohtani (@johtani) 2015, 6月 16 #hatenatech Term Vectors APIのドキュメントはこちら - https://t.co/HhBmTDr46i\n\u0026mdash; Jun Ohtani (@johtani) 2015, 6月 16 #hatenatech min_score - https://t.co/Sc0exzJRC1\n\u0026mdash; Jun Ohtani (@johtani) 2015, 6月 16 個人的な疑問 Q:クエリにヒットするタグがそもそもなかったら?\nはてなブックマークに基づく関連記事レコメンドエンジンの開発 id:skozawa 課題:一部のエントリに対して関連記事が出ない タグがない記事について関連エントリが出ない=既存はタグを利用している 例:レシピで考える\n現行システム ユーザがつけたタグ情報を利用してMoreLikeThisで計算 新規システム 類似記事検索 特徴語の抽出 特徴語を分類 関連記事検索 関連記事をスコアリング 個人的な疑問 Q:毎回計算してるのかな?記事登録とかされたタイミングでやってるのかな? Q:Termの精度などどうなんだろ?\n『BrandSafe はてな』のアドベリフィケーションのしくみ id:tarao BrandSafeはてな:とか。 広告の配信先をフィルタリング\n複数の素朴なフィルタの組み合わせ→AdaBoost\n個人的な疑問 Q:海外とかもいけるのかな?\nまとめと感想 ということで、簡単なメモでした。ピザごちそうさまでした! 聞いてて少し思ったのは、データ量があるサイトだからうまくいく手法だというのもあるんだろうなというところでした。 あとは、クエリを暗に改善するのとは別に、サジェスト的に表示するのにも使えたりするかも?と思ってみたり。 できるかどうかはわからないですが。。。\nElasticsearchをいろいろと活用してもらってるのがわかって、楽しい勉強会でした。 もっともっといろんなところで宣伝してくださいw\n今日の勉強会を聞いて、俄然、京都・大阪でElasticsearch勉強会を開催したい気になってきました。 特に大阪に知り合いがいないので、だれか紹介してもらえると嬉しいです。 お待ちしてます。\n","date":1434468093,"dir":"post/2015/","id":"ddab6357ff522c0c956ebd7669e83454","lang":"ja","lastmod":1434468093,"permalink":"https://blog.johtani.info/blog/2015/06/17/attend-hatena-engineer-seminar-5/","publishdate":"2015-06-17T00:21:33+09:00","summary":"ひさびさに、勉強会メモ。 Hatena Engineer Seminar #5 @ Tokyoに当選したので行ってきました。 いつもは近寄らないオシャレな街をドキドキしながら行ってきました。 と","tags":["勉強会"],"title":"Hatena Engineer Seminar #5 @ Tokyoに参加しました。 #hatenatech"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 1.6.0 released\n本日(6/9)、Lucene 4.10.4ベースのElasticsearch 1.6.0をリリースしました。 このリリースはElasticsearchの最新の安定バージョンとなります。 また、素晴らしい新機能がいくつか追加されています。\nsynced flushによるリスタートの高速化 \u0008* シャード配置は保留中のタスクをブロックしない レスポンスボディのJSONのフィルタリング 共有ファイルシステムリポジトリに対するセキュリティフィックス 古いインデックスのためのUpgrade API Kibanaユーザのためのハイライトの強化 Windowsユーザのためのmlockall より詳細なスクリプト設定 すべての変更リストとダウンロードはこちらをごらんください。\nsynced flushによるリスタートの高速化 1.6.0より前のバージョンでは、メンテナンスやローリングアップグレード時の ノードの再起動で、必要であるかどうかに関わらず、多くの場合、 ノードのすべてのシャードのすべてのデータを再度コピーする必要がありました。 この新しいsynced flush機能により、 sync-flushされたインデックスに対して、既存のデータを再利用し、 より早くクラスタを正常な状態にすることができるようにします。\nここで、この変更以前にどのように動いていたかを説明します。 すでにあるレプリカシャードは、ノードがリスタートした後に、 プライマリから復元するときに、 最初のステップはプライマリにあるセグメントとレプリカにあるセグメントを 比較することです。そして、セグメントに違いがあった場合にコピーされます。 問題は、セグメントプライマリのセグメントのマージと レプリカのセグメントのマージが別々に起こっており、 各シャードのセグメントが完全に異なるが、 それらが同じデータを持っているという点です。\n新しいsynced-flush機能では、sync_idがプライマリと レプリカシャードに、シャードのコンテンツが同一であるという判別するために、 書き込まれます。これは、リカバリがセグメントの比較のステップを スキップできることを意味します。 リカバリのスピードを高速にします。\nsynced flushはアイドル状態のインデックスで自動的に実行されます。 直前の5分間でデータが登録、更新削除されていないインデックスに対してです。 これは、ロギングのユースケースで特に役に立ちます。 機能のインデックスはインデキシングがストップしたあとの5分で自動的に syncされるでしょう。\nノードのリスタートやクラスタのリスタートが必要で、 自動的に発生するsyncを待てない場合は次のようなことが可能です。\nインデキシングを停止(実行中のリクエストが停止するのも待つ) シャードのアロケーションを停止 synced-flushリクエストの発行 ノードのリスタート シャードのアロケーションの再開 クラスタの状態がグリーンになるまで待つ インデキシングの再開 NOTE: \u0026ldquo;シャードのアロケーションを停止\u0026quot;のステップが必要です。 これがない場合、Elasticsearchはノードの再起動が始まると、 異なるノードにシャードの再配置を始めます。 これは、新しいノードにシャードデータの全てをコピーする必要があります。\nドキュメントのインデキシング、更新、削除のあとに最初のフラッシュが 発生したときに、 シャードのsync_idが自動的に無効化されます。 詳細については#11336と#11179をごらんください。\nシャード配置は保留中のタスクをブロックしない 多数のノードやインデックスを持っているユーザは クラスタ全体のリスタートのあとのシャードのリカバリで、 長い間、リカバリが止まって見えることに気づいたかもしれません。 これらのリカバリが止まって見える間は、クラスタ設定の更新のような軽微なアクションでさえ、 例外が発生したり、その設定が反映されるまでに長時間かかるといったことが起きていました。 この問題の兆候は保留中のタスクのキューが大きくなることです。\nこれらの遅延の原因はシャードの配置のプロセスにあります。 配置されるべきシャードのコピーを 持っているのがどのノードかを全てのデータノードに聞きます。 多くのシャードや遅いディスクを持ったデータノードは 反応するのに時間がかかります。 特に、シャードのリカバリがすでにI/Oを利用しているような時です。 このバージョン以前のものは、シャード情報のためのリクエストを 同期的に処理していました。 クラスタ状態の更新はアロケーションプロセスを続けるために 必要な情報を待っている間、ブロックされます。\n#11262での変更は この情報のためのリクエストを非同期にします。 クラスタ状態の更新はこのタスクによってブロックされません。 これは、保留中のタスクがより早く処理でき、 クラスタが変更に対してより早く反応できます。 処理中のshard infoリクエストの数は number_of_in_flight_fetchキーとしてcluster-health APIで取得できます。\nさらに、シャードがある理由で復旧に失敗すると、 クラスタは、シャードのリカバリが成功するまで、同じノードに対して シャードをアロケーションしないようにします。\nレスポンスボディのJSONのフィルタリング Elasticsearchは全ての情報を返します。 例えば、検索リクエストは_index、_type、_id、 _score、_sourceを返します。 しかし、全ての情報が必要でない場合があります。 また、これらのデータを遅いネットワークで転送することは 遅延の原因となります。\nユーザはこの検索メタデータを無効にするための特殊な設定を 行ったり、他のAPIのレスポンスのフォーマットを コントロールするための設定があります。 #10980の変更で、任意のレスポンスボディのJSONに対して、 必要な要素だけを取得する機能が追加されました。 filter_pathパラメータを使用します。\n例えば、検索リクエストからはtotal数と、各要素のhitsの配列を欲しい場合、 次のように指定します。\nGET _search?filter_path=hits.total,hits.hits nodes-info APIから各ノードのhttp_addressだけを取得したい場合は、 ノード名の部分にワイルドカード(*)を使用します。\nGET _nodes?filter_path=nodes.*.http_address 単一の*がJSON階層の1つの階層に対しての ワイルドカードとして機能します。 2つの**は複数階層に対してとなります。 複数のフィルタはカンマ区切りで指定可能です。 詳細についてResponse filteringをごらんください。\n共有ファイルシステムリポジトリに対するセキュリティフィックス 本リリースはsnapshot-restoreで使われる 共有ファイルシステムリポジトリに関するセキュリティ強化の変更が含まれます。 現在、Elasticsearchのユーザは、Elasticsearchプロセスによって書き込み可能 任意のディレクトリに.snapshotファイルを書き込むことができます。 #11284の変更で、リポジトリのために使用できるディレクトリを 強制的に指定できるようになりました。 適切なディレクトリがconfig/elasticsearch.yml設定ファイルの path.repoに指定される必要があります。\n次のように設定されたElasticsearchインスタンスはこのセキュリティ問題に対して影響を受けにくいです。\nrootではなくelasticsearchユーザとしてElasticsearchを実行 elasticsearchユーザがdataディレクトリに対してのみ 書き込み権限を持っていて、共有ファイルシステムリポジトリに対しても利用できる ファイアウォールやプロキシ、Shieldを使って、snapshot APIの実行を任意のユーザから実行されるのを防いでいる この問題をCVE-2015-4165としています。\n古いインデックスのためのUpgrade API Elasticsearch 2.0以降では、 Lucene 5ベースとなり、Lucene 3 (Elasticsearchのバージョンでは0.90以前) によって書き出されたセグメントを含んだインデックスを読み込むことが できなくなります。 これらの「古いインデックス」はLucene 4にアップグレードする必要があり、 2.0-compatibleとして印をつける必要があります。 そうしなければ、Elasticsearch 2.0に以降できないでしょう。\nupgrade APIは 、最新のLuceneフォーマットにインデックスにある全てのセグメントを アップグレードするためにすでに利用できます。 また、最新のフォーマットは性能向上やバグフィックスといった利点もあります。 さらに、2.0-compatibleとして古いインデックスをマークする設定も 書き込むことができます。 さらに、upgrade_only_ancient_segmentsオプションが Lucene 3のセグメントだけをアップグレードするために利用でき、 移行前の必要な処理を減らすことができます。\nKibanaユーザのためのハイライトの強化 KibanaユーザはElasticsearchのハイライトについて2つの点で問題を見つけていました。\nワイルドカードでフィールド名を指定した場合に、ハイライトに適さないフィールドも帰ってくる(日付や数値のフィールドなど) 古いインデックスが非常に大きなターム(\u0026gt; 32kB)を含んでいて、ハイライトが失敗する。 最近のバージョンでは、これらの大きなタームはインデックス時に除去される #11364の変更で これらの問題が修正されました。 ワイルドカードを利用したフィールド名では、stringフィールドのみを返し、非常に長いタームによる例外は無視するようになります。\nWindowsユーザのためのmlockall 速いGCはノードの安定性と性能について重要です。 小さなバイトのヒープでさえ、ディスクにスワップすることを許可してしまうと、GCに対して大きな影響が出てしまいます。 ですので、これらのコストは排除されるべきです。\nLinuxユーザはbootstrap.mloclall設定による恩恵を受けています。 これは、RAMにJVMのヒープを起動時にロックします。 #10887では、同様の機能をWindowsユーザにも提供します。\nより詳細なスクリプト設定 Scriptsはリクエストにインラインで指定できます。 .scriptsインデックスにインデックスもでき、config/ディレクトリ配下にファイルとして保存もできます。 これまでは、インラインかインデックスされたスクリプトの両方を同時に有効無効にすることが選択できましたが、 .scriptsインデックスをプロキシやShieldで保護することもできました。\n#10116で追加されたより詳細なスクリプトの設定で、インラインか、インデックスされたものか、ファイル化を個別に言語ごとに設定できるようになりました。 また、例えば、search APIではスクリプトを許可するが、update APIでは許可しないといったような設定も可能です。\n最後に ぜひ、Elasticsearch 1.6.0を試してみてください。 そして、感想をTwitter(@elastic)やWebフォーラムなどで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1433910662,"dir":"post/2015/","id":"55188a318c5998989255253e15ccc1f6","lang":"ja","lastmod":1433910662,"permalink":"https://blog.johtani.info/blog/2015/06/10/elasticsearch-1-6-0-released-ja/","publishdate":"2015-06-10T13:31:02+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 1.6.0 released 本日(6/9)、Lucene 4.10.4ベースのElas","tags":["elasticsearch"],"title":"Elasticsearch 1.6.0リリース(日本語訳)"},{"contents":"第10回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 次回もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\n今回も新規の方が結構いたような気がしました。 最終的に、124人がアプリでチェックインした形になりました。 直前にキャンセル待ちから繰り上がると来れない人がいますよねぇ。 多少キャパシティオーバーするくらいの人数で募集するのがいいのでしょうか。 あと、カードが2枚不明で。。。心あたりある人いないでしょうか?\nさて、いつもの通り簡単なメモです。\nElastic{ON}報告+有償プラグインの紹介 Elastic Jun Ohtani @johtani スライド:elastic{ON}報告と商用プラグインの紹介\n少し時間が経ってしまいましたが、弊社初のカンファレンスelastic{ON}の紹介をしました。 約1300名の方に参加していただいたカンファレンスで、非常に盛り上がりました。 Microsoft、GitHubなど、いろいろな会社の方が話をしたり、弊社のエンジニアが濃い話をしたりと。 今回は、日本の方はいなかったですが、次回は日本からも参加してもらえると嬉しいです!\nあとは、5月に弊社にも日本の営業の人が入社したので、有償プラグインについて簡単ですが説明をしました。 プラグインなどに興味があるかたがいらっしゃいましたら、Twitterなどで連絡いただければと。 もちろん、弊社サイトからの問い合わせでも大丈夫です。\nカンファレンスの資料やビデオが弊社サイトで公開されています。 ぜひ一度見ていただければと。\nAWSで実現するelasticsearchの大規模運用 株式会社インティメート・マージャー 松田和樹さん @mats116 スライド:第10回elasticsearch勉強会 公開用資料\nパブリックDMPのサービスの裏側でElasticsearchを利用しているというお話でした。 AWS Auto Scalingに詳しくないので、勉強しないといけないんですが、 リバランスがどのくらいの頻度で発生するのかはちょっと気になります。\nSSDを利用したり、doc valuesを利用したりと、性能を気にしながら利用されている点、負荷試験を行って検証されていたりと、 参考になる話でした。 今回はインフラ側の話に寄っていたので、今度はアプリ側でどんな使い方をしているかといった話を聞いてみたいですね!\nSpark in small or middle scale data processing with Elasticsearch 株式会社ビズリーチ 島本 多可子さん @chibochibo03 スライド:Spark in small or middle scale data processing with Elasticsearch\nScalaとSparkとElasticsearchで検索サービスを作っている話でした。 サービスのアーキテクチャの選別についての説明を順を追って説明していただきました。 失敗と言われていたアーキテクチャを見た時に、「あー、それは。。。」と思っていたら、 思った通りの改善案のアーキテクチャが出てきたので少しホッとしましたw\nJSONのクエリが辛いという話がありましたが、validate APIなどを利用してもらって、事前にチェックをしてもらうと 少しは改善できるかもなぁと。\nSparkをぼんやりとしかわかってないので、もう一度話を聴きたいなぁと思ったので、 押しかけて話を聴きたいと思います。\n話の中で出てきた自作のScalaのElasticsearchクライアントがHTTPのクライアントになった理由が知りたかったです。\nLT Elasticsearchのサジェスト機能を使った話 株式会社アイスタイル 渡邊 紘太朗さん @ktaro_w スライド:Elasticsearchのサジェスト機能を使った話\nぴったり5分でしたwまだ2年目なのにこんなにうまく話をしていただけるとは。。。\nGatling便利そうですね。サーバが1台しかないので、単一インデックスの方が性能が出るだろうなと。 Elasticsearchは1インデックスに対してデフォルトだと5シャードで、シャード単位でLuceneのインデックスが作成されます。 この話で行くと、18インデックスを作ると、かなりの数のファイルI/Oが発生するので、いろいろなインデックスに検索をすると キツいだろうなと。\nサジェストについての日本語の資料が少ないという事だったので、ブログを書いてもらえると嬉しいですw\nElasticsearchで作る形態素解析サーバ 株式会社エヌツーエスエム 菅谷信介さん スライド:Elasticsearchで作る形態素解析サーバ\nいつも発表ありがとうございます。私以外の最多発表者じゃないかという話でした。 今回はElasticsearchを形態素解析サーバにしてしまおうという話で、ちょっと面白い話でした。 Elasticsearch以外の場所で形態素解析したい場合には手軽に使えるかもしれないですし、Elasticsearchと同じ解析結果を別の場所で欲しい場合にも便利かも。\nextended analyze APIの紹介までしていただいて。。。\nちなみに、今は、extended analyze プラグインも指定したAttributeの情報だけ返せるようになってたり、 マルチバリューへの対応もしていたりします。 そのうち本家のanalyze APIに機能を取り込む予定です。(早くしないと)\n開発効率UP! Elasticsearch Client Tool 作ってみた ナレッジワークス株式会社 木戸国彦さん @9215 スライド:開発効率アップ!Elasticsearch Client Tool 作ってみた\nHello Elasticsearch!にはお世話になっている人が多いんじゃないかなと。 今回はSublime Textのプラグインのお話でした。(すみません、Sublime Text使ってなくて。。。) AtomとかIntellijのプラグインもあるとうれしいなー\n変わり種プラグインの作り方 日本IBM 黒澤亮二さん スライド:変わり種プラグインの作り方\nElasticsearchの拡張ポイントの話と、簡単なプラグインの作り方と少しElasticsearch内部の話をしていただきました。 Foundの資料が上がってました。さすが。あそこのブログは面白い話が多いんですよね。 社内で実際に使われてる話とかも聞いてみたい!\nその他、感想などのブログ 第10回 Elasticsearch 勉強会へ参加してきた昨日の話 第10回elasticsearch勉強会 #elasticsearch #elasticsearchjp 第10回elasticsearch勉強会に行ってきました elasticsearch勉強会に登壇してきました まとめ 懇親会で24Fに移動していただくということで、少し手間をかけてしまいました、すみませんでした。 今回も初参加の方がそこそこいたんじゃないかなと。 あとは、AWSサミットがあるために上京してて参加しましたという方もいらっしゃいました。 大きなカンファレンスの期間の前後に行うとこんなメリットもあるんですね、今後の参考にしたいと思います。 次回は7/27を予定しています。CTOのShayが来日予定です!\nあと、東京以外の勉強会も検討しつつあります。興味のある方はコメントやTwitterで反応をいただけると嬉しいです。\nスピーカーは随時募集中ですので、コメント、メール、ツイートなど、コンタクトしていただければと思います。 よろしくお願いいたします。\n","date":1433225196,"dir":"post/2015/","id":"75d9268739fe7787ac02d389ac605feb","lang":"ja","lastmod":1433225196,"permalink":"https://blog.johtani.info/blog/2015/06/02/10th-elasticsearch-jp/","publishdate":"2015-06-02T15:06:36+09:00","summary":"第10回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさ","tags":["elasticsearch","勉強会"],"title":"第10回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Reindex Elasticsearch With Logstash\nThanks David!\nマッピングを変更したり、インデックスの設定を変更したり、あるサーバから他のサーバや、 あるクラスタから他のクラスタ(例えば複数のデータセンターのような場合)にデータを再インデックスしたくなることがあるでしょう。\n後者のような場合はSnapshotやRestoreの機能を利用することもできますが、インデックスの設定を変更をしたい場合は その他の方法が必要になります。\nLogstash 1.5.0で、 elasticsearch inputとelasticsearch outputを使うことで、とても簡単に再インデックスができます。\nではやってみましょう。\n古いクラスタ elasticsearch 1.5.2 はすでにダウンロード済みとして、localhost:9200でoldという名前のクラスタを起動します。\nbin/elasticsearch --cluster.name=old クラスタにpersonという名前のインデックスが存在します。 これは、5シャードで、100万件のドキュメントを持っています。\n新しいクラスタ 次に新しいクラスタを起動します。 localhost:9201でnewという名前のクラスタを起動します。\nbin/elasticsearch --cluster.name=new こちらは、空です。\ncurl -XGET \u0026#34;http://localhost:9201/person\u0026#34; { \u0026#34;error\u0026#34;: \u0026#34;IndexMissingException[[person] missing]\u0026#34;, \u0026#34;status\u0026#34;: 404 } Logstashのインストール 次に、Logstash 1.5.0をダウンロードして、インストールします。\nwget http://download.elastic.co/logstash/logstash/logstash-1.5.0.tar.gz tar xzf logstash-1.5.0.tar.gz cd logstash-1.5.0 logstashの設定ファイルlogstash.confを次のように設定します。\ninput { # We read from the \u0026#34;old\u0026#34; cluster elasticsearch { hosts =\u0026gt; [ \u0026#34;localhost\u0026#34; ] port =\u0026gt; \u0026#34;9200\u0026#34; index =\u0026gt; \u0026#34;person\u0026#34; size =\u0026gt; 500 scroll =\u0026gt; \u0026#34;5m\u0026#34; docinfo =\u0026gt; true } } output { # We write to the \u0026#34;new\u0026#34; cluster elasticsearch { host =\u0026gt; \u0026#34;localhost\u0026#34; port =\u0026gt; \u0026#34;9201\u0026#34; protocol =\u0026gt; \u0026#34;http\u0026#34; index =\u0026gt; \u0026#34;%{[@metadata][_index]}\u0026#34; index_type =\u0026gt; \u0026#34;%{[@metadata][_type]}\u0026#34; document_id =\u0026gt; \u0026#34;%{[@metadata][_id]}\u0026#34; } # We print dots to see it in action stdout { codec =\u0026gt; \u0026#34;dots\u0026#34; } } 実行と修正 実行します。\nbin/logstash -f logstash.conf ドキュメントのチェックと修正 何が起きたでしょう?\ncurl -XGET \u0026#34;http://localhost:9200/person/person/AU1wqyQWZJKU8OibfxgH\u0026#34; { \u0026#34;_index\u0026#34;: \u0026#34;person\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;person\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;AU1wqyQWZJKU8OibfxgH\u0026#34;, \u0026#34;_version\u0026#34;: 1, \u0026#34;found\u0026#34;: true, \u0026#34;_source\u0026#34;: { \u0026#34;name\u0026#34;: \u0026#34;Tali Elyne\u0026#34;, \u0026#34;dateOfBirth\u0026#34;: \u0026#34;1955-05-03\u0026#34;, \u0026#34;gender\u0026#34;: \u0026#34;female\u0026#34;, \u0026#34;children\u0026#34;: 2, \u0026#34;marketing\u0026#34;: { \u0026#34;cars\u0026#34;: null, \u0026#34;shoes\u0026#34;: null, \u0026#34;toys\u0026#34;: null, \u0026#34;fashion\u0026#34;: null, \u0026#34;music\u0026#34;: null, \u0026#34;garden\u0026#34;: null, \u0026#34;electronic\u0026#34;: null, \u0026#34;hifi\u0026#34;: null, \u0026#34;food\u0026#34;: 846 }, \u0026#34;address\u0026#34;: { \u0026#34;country\u0026#34;: \u0026#34;Germany\u0026#34;, \u0026#34;zipcode\u0026#34;: \u0026#34;0099\u0026#34;, \u0026#34;city\u0026#34;: \u0026#34;Bonn\u0026#34;, \u0026#34;countrycode\u0026#34;: \u0026#34;DE\u0026#34;, \u0026#34;location\u0026#34;: [ 7.075943707068682, 50.72883500730124 ] } } } もう一方のクラスタと比較してみましょう。\ncurl -XGET \u0026#34;http://localhost:9201/person/person/AU1wqyQWZJKU8OibfxgH\u0026#34; { \u0026#34;_index\u0026#34;: \u0026#34;person\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;person\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;AU1wqyQWZJKU8OibfxgH\u0026#34;, \u0026#34;_version\u0026#34;: 1, \u0026#34;found\u0026#34;: true, \u0026#34;_source\u0026#34;: { \u0026#34;name\u0026#34;: \u0026#34;Tali Elyne\u0026#34;, \u0026#34;dateOfBirth\u0026#34;: \u0026#34;1955-05-03\u0026#34;, \u0026#34;gender\u0026#34;: \u0026#34;female\u0026#34;, \u0026#34;children\u0026#34;: 2, \u0026#34;marketing\u0026#34;: { \u0026#34;cars\u0026#34;: null, \u0026#34;shoes\u0026#34;: null, \u0026#34;toys\u0026#34;: null, \u0026#34;fashion\u0026#34;: null, \u0026#34;music\u0026#34;: null, \u0026#34;garden\u0026#34;: null, \u0026#34;electronic\u0026#34;: null, \u0026#34;hifi\u0026#34;: null, \u0026#34;food\u0026#34;: 846 }, \u0026#34;address\u0026#34;: { \u0026#34;country\u0026#34;: \u0026#34;Germany\u0026#34;, \u0026#34;zipcode\u0026#34;: \u0026#34;0099\u0026#34;, \u0026#34;city\u0026#34;: \u0026#34;Bonn\u0026#34;, \u0026#34;countrycode\u0026#34;: \u0026#34;DE\u0026#34;, \u0026#34;location\u0026#34;: [ 7.075943707068682, 50.72883500730124 ] }, \u0026#34;@version\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;@timestamp\u0026#34;: \u0026#34;2015-05-20T09:53:44.089Z\u0026#34; } } Logstashは@versionと@timestampフィールドを追加してしました。 これらを除去したいので、Mutate filter pluginのremove_fieldを使います。\nfilter { mutate { remove_field =\u0026gt; [ \u0026#34;@timestamp\u0026#34;, \u0026#34;@version\u0026#34; ] } } マッピングのチェックと修正 実際に、logstashは_sourceフィールドを既存のドキュメントから読み込み、 それらを新しいクラスタに直接投入しています。 しかし、logstashはマッピングについてはケアしていません。\n古いマッピングと新しいマッピングを比較するために、マッピングを取得してみましょう。\ncurl -XGET \u0026#34;http://localhost:9200/person/person/_mapping\u0026#34; { \u0026#34;person\u0026#34;: { \u0026#34;mappings\u0026#34;: { \u0026#34;person\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;address\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;city\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;country\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;countrycode\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;location\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;geo_point\u0026#34; }, \u0026#34;zipcode\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, \u0026#34;children\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;dateOfBirth\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;date\u0026#34;, \u0026#34;format\u0026#34;: \u0026#34;dateOptionalTime\u0026#34; }, \u0026#34;gender\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;marketing\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;cars\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;electronic\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;fashion\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;food\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;garden\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;hifi\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;music\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;shoes\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;toys\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; } } }, \u0026#34;name\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } } } } } curl -XGET \u0026#34;http://localhost:9201/person/person/_mapping\u0026#34; { \u0026#34;person\u0026#34;: { \u0026#34;mappings\u0026#34;: { \u0026#34;person\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;address\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;city\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;country\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;countrycode\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;location\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;double\u0026#34; }, \u0026#34;zipcode\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, \u0026#34;children\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;dateOfBirth\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;date\u0026#34;, \u0026#34;format\u0026#34;: \u0026#34;dateOptionalTime\u0026#34; }, \u0026#34;gender\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;marketing\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;cars\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;electronic\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;fashion\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;food\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;garden\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;hifi\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;music\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;shoes\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;toys\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; } } }, \u0026#34;name\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } } } } } これにより、いくつかの相違を発見できます。\n\u0026#34;location\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;geo_point\u0026#34; } \u0026#34;location\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;double\u0026#34; } データをインデックスする「前」に、実際に利用したいマッピングでインデックスを作成しておくことで、 この問題に対処できます。 この時点で、オリジナルのマッピングを望んだ形に変更することができます。例えば、アナライザを変更したりです。 また、インデックスの設定を新しく定義することもできます。 デフォルトでは、Elasticsearchは5つのシャードと各シャードに対して1つのレプリカを作成します。 しかし、この時点でもう一度変更することが可能です。\ncurl -XDELETE \u0026#34;http://localhost:9201/person\u0026#34; curl -XPUT \u0026#34;http://localhost:9201/person\u0026#34; -d\u0026#39; { \u0026#34;settings\u0026#34;: { \u0026#34;number_of_shards\u0026#34;: 1, \u0026#34;number_of_replicas\u0026#34;: 0 } }\u0026#39; curl -XPUT \u0026#34;http://localhost:9201/person/person/_mapping\u0026#34; -d\u0026#39; { \u0026#34;person\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;address\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;city\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;country\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;countrycode\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;location\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;geo_point\u0026#34; }, \u0026#34;zipcode\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, \u0026#34;children\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;dateOfBirth\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;date\u0026#34;, \u0026#34;format\u0026#34;: \u0026#34;dateOptionalTime\u0026#34; }, \u0026#34;gender\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;marketing\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;cars\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;electronic\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;fashion\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;food\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;garden\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;hifi\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;music\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;shoes\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;toys\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; } } }, \u0026#34;name\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } } }\u0026#39; さて、もう一度再インデックスしましょう!\nbin/logstash -f logstash.conf インデックスやタイプ名の変更 もちろん、インデックス名やタイプ名、IDを変更したい場合も変更が可能です!:)\nelasticsearch { host =\u0026gt; \u0026#34;localhost\u0026#34; port =\u0026gt; \u0026#34;9201\u0026#34; protocol =\u0026gt; \u0026#34;http\u0026#34; index =\u0026gt; \u0026#34;europe_people\u0026#34; index_type =\u0026gt; \u0026#34;someone\u0026#34; document_id =\u0026gt; \u0026#34;%{[@metadata][_id]}\u0026#34; } ","date":1432624090,"dir":"post/2015/","id":"23a22d1411afb787810d68210e6fad4f","lang":"ja","lastmod":1432624090,"permalink":"https://blog.johtani.info/blog/2015/05/26/reindex-elasticsearch-with-logstash-ja/","publishdate":"2015-05-26T16:08:10+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Reindex Elasticsearch With Logstash Thanks David! マッピングを変更したり、インデックスの設定を変更したり、あるサ","tags":["logstash","elasticsearch"],"title":"Logstashを使ったElasticsearchの再インデックス(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Join the Conversation: Discuss.Elastic.Co\n3つのOSSプロジェクトの開発をスケールアップし始め、 コミュニティサポートのために必要なやりとりに対してメーリングリストでは難しいということがわかってきました。 私たちは複数のメーリングリストを持っています。Elasticsearch、Logstash、そして英語以外の様々な言語のメーリングリストです。 このような状況では、あたらしい人たちはどこで質問をするのが良いのか混乱します。\nまた、メーリングリストの流量が増え、「参考になる話題」を見つけるのが難しくなってきました。 様々なユーザに採用してもらい、様々なユースケースが出てくることで、様々な質問が出てきています。 汎用的なメーリングリストではノイズの中から望んだ情報を見つけるのは難しいです。 また、ユーザ全てがメーリングリスト満足しているわけではありません。\nElasticは、ユーザの問題を解くことが大好きです。 コミュニティのメンバー皆さんに気に入っていただけるであろうソリューションを見つけ、フォーラムを https://discuss.elastic.co に移すことにしました。 ぜひ参加して、この新しいツールについてのご意見を聞かせてください。\nメーリングリストは好きだけど、ウェブフォーラムは苦手?問題ありません。 フォーラムにユーザプロファイル(GitHub、Facebook、Twitter、Google Appsのアカウントと連携するか、emailアドレスを利用すれば簡単に作れます)を作り、 email通知の設定をすればOKです。 これで、emailでのやりとりができるようになります。\n利用して、議論を楽しんでください。 もちろん、改善案などにかんするご意見もお待ちしています!\n","date":1432197903,"dir":"post/2015/","id":"615db1a24f36d19a8eaf18d4dceed6b2","lang":"ja","lastmod":1432197903,"permalink":"https://blog.johtani.info/blog/2015/05/21/join-the-conversation-ja/","publishdate":"2015-05-21T17:45:03+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Join the Conversation: Discuss.Elastic.Co 3つのOSSプロジェクトの開発をスケールアップし始め、 コミュニティサポー","tags":null,"title":"discuss.elastic.co にぜひ参加を"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 1.5.2 Released\n本日(4/27)、Lucene 4.10.4ベースのElasticsearch 1.5.1およびElasticsearch 1.4.5 をセキュリティバグフィックス版をリリースしました。 ダウンロードおよびすべての変更については次のリンクをごらんください。\n最新安定版:Elasticsearch 1.5.2 1.4系バグフィックス:Elasticsearch 1.4.5 本リリースはディレクトリトラバーサルの脆弱性のフィックスです。すべてのユーザにアップグレードを勧めます。\n過去のリリースに関するブログは以下のリンクを参照してください。\n1.5:1.4.1, 1.5.0 1.4:1.4.4,1.4.3, 1.4.2,1.4.1, 1.4.0, 1.4.0.Beta1 すべての1.5.2および1.4.5の変更についてはリンクをごらんください。以下では、セキュリティの問題について紹介します。\nディレクトリトラバーサル脆弱性の発見 1.5.2および1.4.5以前の全バージョンのElasticsearchで、ディレクトリトラバーサル攻撃に対する脆弱性がみつかりました。 攻撃者はElasticsearchを実行しているサーバからファイルを取得することができます。 この脆弱性はインストールしたばかりのElasticsearchには存在しません。 この脆弱性は\u0026quot;site plugin\u0026quot;がインストールされると露呈します。 ElasticのMarvelプラグインおよびコミュニティサポートの多くのプラグイン(例:Kopf、BigDesk、Head)がsite pluginです。 Elastic Shield、Licensing、Cloud-AWS、Cloud-GCE、Cloud-Azure、analysis pluginおよびriverプラグインはsite pluginではありません。\nこの問題をCVE-2015-3337としました。\nバージョン1.5.2と1.4.5はこの脆弱性に対して対策済みで、私たちはすべてのユーザにアップグレードを勧めています。\nアップグレードを望まないユーザはいくつかの方法でこの脆弱性に対して対応可能ですが、これらの方法はsite pluginを動作させなくします。\nsite pluginをインストールしているノードのelasticsearch.ymlのhttp.disable_sitesをtrueに設定し、Elasticsearchのノードを再起動 ファイアウォールもしくはプロキシを利用して、/_pluginへのHTTPリクエストをブロック すべてのsite pluginをすべてのElasticsearchノードからアンインストール この問題を報告していただいた、DocuSignのJohn Heasmanに感謝いたします。\n他の変更について インデックスされたスクリプトおよびテンプレートを上書きもしくは削除時に、キャッシュからも完全に削除する。 geo-shapeの多数のフィックス(distance_error_pctを利用した場合の、重要なprecisionに関するフィックスを含む) インデックステンプレートのデフォルトマッピングがバルクインデキシング中にも考慮するように修正 Shadowレプリカがファイルシステムの遅延に対する対障害性を向上し、プライマリシャードのよりスムーズなリロケーションをサポート geo-contextsをcompletion suggesterで使用した場合のマッピングのリフレッシュループを改善 いくつかの重要な変更がv1.4.5にバックポートされています。\n大きなシャードのリカバリを早くするためのシャードリカバリ中のマージを可能に \u0008* truncated translogsの操作をグレースフルに マージが遅くなる場合に、delete-by-queryを減速 ぜひ、Elasticsearch 1.5.2をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1430201648,"dir":"post/2015/","id":"8d7caf84b3a51cca27291c1f7cfc2d40","lang":"ja","lastmod":1430201648,"permalink":"https://blog.johtani.info/blog/2015/04/28/elasticsearch-1-5-2-and-1-4-5-released-ja/","publishdate":"2015-04-28T15:14:08+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 1.5.2 Released 本日(4/27)、Lucene 4.10.4ベースのEla","tags":["elasticsearch"],"title":"Elasticsearch 1.5.2 および 1.4.5リリース(日本語訳)"},{"contents":"第9回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 次回もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\n今回はトレーニングで来日していたIgorとNathanによる特別公演でした。 昨年同様、サムライズムの@yusukeさんに テキスト翻訳していただき、大変助かりました。ほんとうにすごかった。。。\nチェックイン数など 今回はチェックインした人:119名 キャンセルしなかった人:45名 でした。今回はキャンセル待ちのまま当日を迎えた人もいなかったので良かったかなと。 今回から懇親会ページを別にしてみました。本編の勉強会に参加登録していた方には何度かメールを出していたので、 見つけていなかった人は以内とは思うのですが、勉強会のページと間違える人がいたらしいという話を聞きました。 Doorkeeperで1イベントで複数のチケットにそれぞれの参加者数を設定できるようになると嬉しいかもなぁ。\nさて、いつもの通り簡単なメモです。 本当に簡単にですが。\nResiliency in Elasticsearch and Lucene / Igor Motov スライド:https://speakerdeck.com/elastic/resiliency-in-elasticsearch-and-lucene\n※上記スライドは少し古いバージョンです。公開されたら差し替える予定です。\nサンフランシスコで行われたElastic{ON}(弊社初のカンファレンス)で行われたセッションの 改良版といったところでしょうか。 話の中で登場した機能などのリンクをざっとアップしておきます。\nFielddata Doc Values Resiliency Status Kibana4: What\u0026rsquo;s New ? / Nathan Zamecnik スライド:未定\nKibana4の紹介をデモを交えてという感じでした。 こちらは、スライドよりもデモを見てもらうのが一番いいのですが。。。\nいくつかQAがあったので補足を。ちなみに、Issueのラベルに実装される予定のバージョンが付与されてたりします。\nQ:グラフをPDFでエクスポートとかできますか? A:4.3.0で実装される予定です。関連Issueはこちら。https://github.com/elastic/kibana/issues/509 Q:巨大な数値の場合にKB、MBなどといった表示は可能ですか? A:4.1.0で実装される予定です。関連Issueはこちら。https://github.com/elastic/kibana/issues/1543 Q:地図のズームを固定することはできますか? A:4.1.0で実装される予定です。関連Issueはこちら。https://github.com/elastic/kibana/issues/1442 その他、感想などのブログ [Elasticsearch] 第9回 Elasticsearch 勉強会へ参加してきた まとめ 今回は特別バージョンでした。かなり詳しい話だったので面白かったと思います。 Kibanaはデモを見ていただけましたし。また、海外から人を呼べるといいなぁ。\n次回は6月ごろをめどに計画しようかと。 スピーカーは随時募集中ですので、コメント、メール、ツイートなど、コンタクトしていただければと思います。 よろしくお願いいたします。\n","date":1429249314,"dir":"post/2015/","id":"7249710187cc2d983709e044dbc78d9d","lang":"ja","lastmod":1429249314,"permalink":"https://blog.johtani.info/blog/2015/04/17/9th-elasticsearch-jp/","publishdate":"2015-04-17T14:41:54+09:00","summary":"第9回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん","tags":["elasticsearch","勉強会"],"title":"第9回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 1.5.1 Released\n本日(4/9)、Lucene 4.10.4ベースのElasticsearch 1.5.1 をリリースしました。 このリリースはElasticsearchの最新の安定バージョンとなります。\nすべての変更についてはdownload Elasticsearch 1.5.1 hereをごらんください。\n本リリースはシャードを新しいノードに配置するスピードを改善するためのバグフィックスを含んでいます。 シャードのリカバリーの最初のフェーズで、コピー元のノードからコピー先のノードへすべてのセグメントをコピーします。 このフェーズ中には登録、更新削除のリクエストはトランザクションログに記録され、リカバリが終了したあとに コピー先のノードでトランザクションログが再生されます。 シャードが大きい場合、トランザクションログに多数のイベントがたまってしまいます。\n以前では、新しいセグメントのマージはリカバリ中のコピー先のノードでは、実行できませんでした。 大きなトランザクションログは結果として、小さな新しいセグメントを多く生成し、リカバリのスピードに非常に影響を与えます。 Issue #10463は リカバリ中のコピー先のシャードのマージを可能にする変更です。\nその他の注目すべきバグフィックスは次のものになります。\n多くの削除によりバージョンマップがいっぱいになった場合にrefreshを実行するように変更(#10312) 多数のスナップショットを含んだリポジトリの管理の改善(#10366) 実験的な機能であるinner hitsのバグフィックス(#10388, #10353, #10309, #10235) 最後に、Riverが非推奨となりました、まだ見ていない場合は記事をご覧ください。\nぜひ、Elasticsearch 1.5.1をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1428892471,"dir":"post/2015/","id":"563864a949924c505985a168191dcb84","lang":"ja","lastmod":1428892471,"permalink":"https://blog.johtani.info/blog/2015/04/13/elasticsearch-1-5-1-released-ja/","publishdate":"2015-04-13T11:34:31+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 1.5.1 Released 本日(4/9)、Lucene 4.10.4ベースのElas","tags":["elasticsearch"],"title":"Elasticsearch 1.5.1リリース(日本語訳)"},{"contents":"Elasticsearch勉強会 in 名古屋を開催しました。 初の東京以外での勉強会です。 企画、セッションなどお手伝いいただいた@smogamiさん、@mzpさんありがとうございました!\nElasticsearch/ELK stack紹介 @johtani スライド:Introduction Elasticsearch\n初回(次回があるかはわかりませんが。。。)ということもあり、Elasticsearchの説明を行いました。 あと、LogstashとKibanaも。 Kibanaについては、手元の環境でいつものアクセスログのデモやなどを行いました。 また、LTの後に時間があったので、前回の勉強会で利用したチェックリストの説明なども。\nスタンドファームにおけるElasticsearch導入事例 @mzp さん スライド:後日アップ?\n\u0008* 使ってるのはKibana3\nアクセスログが保存されてたけど、活用できてなかった。 Fluentd、Elasticsearch、Kibanaをいれて、可視化してみた。 普通にログ検索が簡単にできて嬉しい システムのレスポンスの性能値などを可視化できるようにして性能改善中 Kibanaでログ分析を1年続けてみたら業務システムの保守と運用が捗った(仮) @smogami さん スライド:「Kibanaでログ分析を1年続けてみたら業務システムの保守と運用が捗った」\n名古屋でJavaの勉強会を主催してみたり(最近できてないけど) 導入するのになかなか大変だった(ファイアウォールだったりが)。。。 Kibanaを使ってどんなことをしてるのか?\n既存システムなどの機能の実行回数やレスポンス時間の推移 曜日ごとにもチェック どの機能がよく使われるのか? 対象となっているシステムはJavaのシステム。 QA\nQ:ログの出力は新規に追加したのか? A : ログの出力自体はLog4Jの設定を変更しただけ。もともと、各メソッドの開始と終了にそれぞれ時間が出力される仕組みがある。\nログの読み込み自体は自作ツールを利用。 飛び込みLT @dabits さん スライド:未定\nKibanaの使い道\nKPIツール エゴサーチツール - Twitterや2chなどのデータを解析ソーシャル分析みたいな感じ? \u0008* ダッシュボードを用意してあげる場合もあるが、触っていろんな機能を試す人も。 感想・反省点など 30名弱の方に参加していただきました。ありがとうございました。 東京の勉強会でもそうですが、半分くらいが検索、半分くらいがログ解析関連に興味がある感じでした。 飛び込みLTもしていただけましたし。会場内限定の話もいくつか。\n場所 場所が少しわかりにくかったかなと。。。建物の入り口に看板がないので、1名に看板役として立っていただきました。 ただ、設備は充実していましたし、室内も綺麗でよかったです。\n懇親会 11名(+私)でした。美味しい手羽先などをいただきながら、Elasticsearch以外のことでも盛り上がりましたw。 また、名古屋の観光名所なども教えてもらったりと有意義な時間でしたw。\nということで、少しでもElasticsearch、Kibana、Logstashなどのユーザが増えてくれればうれしいかなと。 私抜きでも勉強会はできると思うので、今後も開いてもらえるとうれしいかぎりです。 初めての東京以外での勉強会でどんな感じの方が利用しているのか、興味があるのかといったことも知ることができました。\n関連ブログなど Kibana4活用事例を話しました その他(余談) コンパルという喫茶店のアイスコーヒー。ちょっと新鮮な体験でした。 あとは、日曜日に観光場所として教えてもらった、トヨタ産業技術記念館にも行ってみました。 一人だったけど、非常に楽しめました。実演とかあって、わかりやすいし。 トヨタが自動織機の会社が始まりだってのは知らなかった。\n","date":1428108439,"dir":"post/2015/","id":"24357fe145c869ec82fdfc8134a1a6d1","lang":"ja","lastmod":1428108439,"permalink":"https://blog.johtani.info/blog/2015/04/04/elasticsearch-study-session-at-nagoya/","publishdate":"2015-04-04T09:47:19+09:00","summary":"Elasticsearch勉強会 in 名古屋を開催しました。 初の東京以外での勉強会です。 企画、セッションなどお手伝いいただいた@smogamiさ","tags":["elasticsearch","勉強会"],"title":"Elasticsearch勉強会 in 名古屋を開催しました。#elasticsearch #elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 1.5.0 Released\n本日(3/23)、Lucene 4.10.4ベースのElasticsearch 1.5.0 をリリースしました。 このリリースはElasticsearchの最新の安定バージョンとなります。 多くのresiliency(復元性、弾力性) enhancementとバグフィックスを含んでおり、 すべてのユーザにアップグレードを推奨しています。\nすべての変更についてはdownload Elasticsearch 1.5.0 hereをごらんください。\n460PRという大量の変更を含む本リリースは、Elasticsearchをよりresilient(弾力のあるもの)にするために 費やされています。\nInner hits 本リリースで追加された、Elasticsearchに最もリクエストされたものの一つがinner hitsです。 これは、has_childもしくはnestedクエリにマッチした子のドキュメントを、各親ドキュメントと一緒に返すことができます。\n例えば、blogという親ドキュメントとcommentという子ドキュメントを持っているとします。 この時、\u0026ldquo;full text search\u0026quot;というコメントを持ったブログ記事を検索したいとします。\nGET /my_index/blog/_search { \u0026#34;query\u0026#34;: { \u0026#34;has_child\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;comment\u0026#34;, \u0026#34;score_mode\u0026#34;: \u0026#34;sum\u0026#34;, \u0026#34;query\u0026#34;: { \u0026#34;match\u0026#34;: { \u0026#34;body\u0026#34;: \u0026#34;full text search\u0026#34; } } } } } 上記のリクエストは、親のblogドキュメントを返します。 しかし、どのコメントが関係しているのかはわかりません。 関連しているコメントを検索して親ごとにグルーピングするために、 少し手間のかかる2回目のクエリを実行する必要があります。\nInner hitsがこれを変えてくれます。 inner_hitsパラメータを次のように、上記のクエリに追加するだけです!\nGET /my_index/blog/_search { \u0026#34;query\u0026#34;: { \u0026#34;has_child\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;comment\u0026#34;, \u0026#34;score_mode\u0026#34;: \u0026#34;sum\u0026#34;, \u0026#34;query\u0026#34;: { \u0026#34;match\u0026#34;: { \u0026#34;body\u0026#34;: \u0026#34;full text search\u0026#34; } }, \u0026#34;inner_hits\u0026#34;: {} } } } 検索結果の各blog記事に、inner_hitsという項目があり、そこに検索にヒットしたコメントの 上位3件(デフォルト値)が返ってきます。\n... \u0026#34;hits\u0026#34;: [ { \u0026#34;_index\u0026#34;: \u0026#34;my_index\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;blog\u0026#34;, \u0026#34;_id\u0026#34;: 1, \u0026#34;_score\u0026#34;: 3.68, \u0026#34;_source\u0026#34;: { ... }, \u0026#34;inner_hits\u0026#34;: { \u0026#34;comment\u0026#34;: { \u0026#34;total\u0026#34;: 16, \u0026#34;hits\u0026#34;: [ { \u0026#34;_type\u0026#34;: \u0026#34;comment\u0026#34;, \u0026#34;_id\u0026#34;: 5, \u0026#34;_score\u0026#34;: 2.79, \u0026#34;_source\u0026#34;: { \u0026#34;body\u0026#34;: \u0026#34;Full text search is the bomb\u0026#34; } }, { ... }, { ... } ] } } } ] ... inner_hits部分は、第2の検索リクエストに似ています。 sizeやfromパラメータを含めるくことで、挙動をカスタマイズできます。 また、検索から想像するであろう、ページネーション、ソート、ハイライト、_sourceフィルタリングなどといった機能もサポートします。\nInner hitsはparent-childおよび、nestedドキュメントをサポートします。 この機能は、現時点ではexperimentalラベルが付与されています。 このラベルは、この機能が将来変更されたり、削除されたりする可能性があるかもしれないことを意味します。 詳細については、Inner Hits documentationをごらんください。\nShadow replicas Elasticsearchはそれ自身の冗長性に常に気をつけています。 それは、レプリカシャード(各プライマリシャードの冗長なコピー)を持っています。 これは、プライマリシャードを失った時に、データをロスしないようにするためのものです。 レプリカシャードはまた、検索のスループットをスケールアウトするためにも利用できます。 多くのレプリカ(ノードを伴うことで。)はスループットを増加させます。\nしかし、ユーザによってはElsticsearchを分散ファイルシステム上でホスティングしており、すでに、 ファイルシステムがレプリケーションと冗長性を担当しています。 ファイルシステムが同じことしているので、各シャードのコピーを複数持つことはあまり意味がありません。\nShadowレプリカはノードを追加することによる検索スループットをスケールアウトすることが、 余分なストレージやインデキシングのコストを払うことなく、可能になります。 代わりに、各シャドーレプリカはプライマリシャードを持っている共有ファイルシステムにread-onlyでアクセスします。 Shadowレプリカは定期的にファイルシステムのビューをリフレッシュし、プライマリシャードのどんな変更も検知するでしょう。\nプライマリシャードが失敗したら、Shadowレプリカがプライマリに昇格し、 失敗したプライマリによって書き込まれたトランザクションログを読み込みリプレイできます。\nこの機能はexperimentalマークが付いています。詳細についてはShadow Replicas documentationをごらんください。\nResiliency improvements Elasticsearch 1.1 から 1.3では、インデックスのすべてのファイルのチェックサムを追加し、 それらのファイルが壊れているかどうかをチェックするために利用することにフォーカスしました。 1.4では、Zen discoveryと分散モデルについて大きな改良を加えました。\nこれらの変更にともなう、より詳細な統計情報やより詳細なロギングがElasticsearchやLuceneの以前のバージョンに存在した 未知の問題を明るみに出しました。 Elasticsearch 1.5.0では、これらの問題の多くに対処しています。\nElasticsearchとLuceneの以前のバージョンにあるバグがインデックスの故障を引き起こしていました。\nチェックサムコードのおかげで、これらを発見できました。現在は、Elasticsearchの起動時に自動的にLucene3.x\n(Elasticsearch 0.20.x以前)が作成したセグメントを検知して、シャードをオープンする前に、新しいフォーマットを使って、 新しいコミットポイントを書き出します。(#9899)\n1.3.xもしくは以前のバージョンからローリングアップグレードは、ローカルのシャードデータを再利用しようとせずに、\nシャード全体をコピーしようとします。1.3.2と以前のバージョンが実行されているノードからローリングアップグレードすることは 圧縮をオフにしない限りできなくなりました。(#9925)\n1.3.xやそれ以前のバージョンからアップグレードする場合、ローリングアップデートする代わりにクラスタの再起動を考えたほうがいいかもしれません。\n非同期環境は予測することが難しいです。時に、最も予測していないことが起きるからです。\nシャード配置、リカバリ、削除のコードの多くが単純化され、状態変更をよりアトミックで決定的にするための変更によりリファクタリングされました。\n(#8720, #9799, #9784, #9801, #9083, #8579, #8436, #8092, #9902, #6644, #8350, #9770, #9616, #9439, #8350, #8494)\n同様に、変更はクラスタ状態の更新が常に前進するということを確実にしました。更新の受け取り順序が順不同であったり、\nマスターだったノードからの更新を受け取った場合に混乱させていました。 (#9632, #9541, #9503)\nチェックサムとチェックサムのバリデーションの強化(#8723,\n#8599, #8587, #8407, #8010, #8018)\ndisk threshold allocation deciderを速く(#8803)、賢く(#7785)、自動化(#8270)\nauto-generated IDの利用時のインデキシングのスピードアップのためのに追加された最適化を除去。\nたまにドキュメントを重複して登録するため(#7729)\nDownload now ぜひ、Elasticsearch 1.5.0をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1427859496,"dir":"post/2015/","id":"19ecbaa5e12f7a9ebcff703c79534a52","lang":"ja","lastmod":1427859496,"permalink":"https://blog.johtani.info/blog/2015/04/01/elasticsearch-1-5-0-released-ja/","publishdate":"2015-04-01T12:38:16+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 1.5.0 Released 本日(3/23)、Lucene 4.10.4ベースのEla","tags":["elasticsearch"],"title":"Elasticsearch 1.5.0リリース(日本語訳)"},{"contents":"サンフランシスコからこんにちは。\n今、私は、弊社初のユーザカンファレンスelastic{ON}に 参加するために、初のアメリカ出張中です。 初のユーザカンファレンスですが、世界各国から約1300人!の登録がありました。\n本日が初日(Welcome Receptionが昨晩開催されましたが)です。 初日のキーノートで重要な発表が2つありました。\nブランド名の変更(Elastic: For - You Know, More Than Search) Found.noの加入(Welcome Found) です。\n昨日までは、elasticsearchでした。 本日からは、elasticになります。 ブランド名の変更と同時にサイト、ロゴなども変更されました。\nもう一つのビッグニュースがFoundの加入です。 found.noはElasticsearchをクラウドサービスとして提供している会社です。 彼らがジョインすることで、elasticsearchをより気軽に利用できるような環境ができてきます。\nKeynoteでの驚きのニュースこれらでした。 もちろん、このカンファレンスはそれだけには止まりません。\nNetflixやGitHub、Verison Mobile、WikimediaといったElasticsearch,ELKスタックのユーザの話や、 弊社の人たちによる今後のロードマップや私たちの考え方など多岐にわたる話を聞くことができます。\nこのような機会を今後も提供できるような会社になれるよう、頑張っていきたいなと思っています。\nちなみに、弊社のカンファレンスは私がこれまで経験したことのないカンファレンスになっています。 DJや各種ゲーム(ビリヤードとかパックマンとか)が楽しめるようなパーティが 懇親会として開催されたり、スポンサーブースでウェルカムレセプションが行われたりと、 面白い取り組みにあふれています。 次回開催されることがあれば、ぜひ日本の方達にも参加してもらえたらうれしいなと。\n","date":1426059991,"dir":"post/2015/","id":"ced9df0d8c8ed14de91c509b31b4c4ae","lang":"ja","lastmod":1426059991,"permalink":"https://blog.johtani.info/blog/2015/03/11/attend-elasticon/","publishdate":"2015-03-11T16:46:31+09:00","summary":"サンフランシスコからこんにちは。 今、私は、弊社初のユーザカンファレンスelastic{ON}に 参加するために、初のアメリカ出張中です。 初のユ","tags":["elastic","elasticon"],"title":"#elasticon に参加中"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:you know, for security: shield goes ga\n1/27にShield 1.0 をリリースしました。 Elasticsearch向けの私たちのセキュリティプラグインの最初のリリースです。 11月にShieldについてアナウンスしてから、Elsaticsearchのためのセキュリティの機能は、 一般的に望まれているものから始まり、具体的な考えと実行できる計画へと変遷し、それが、いま現実となりました。\n十分にセキュアな環境に、Elasticsearchクラスタをセキュアな状態でデプロイできるようにするため、 私たちは継続的にカスタマーやユーザーからのリクエストを受け取り、統合されたソリューションになるようにしてきました。\n私たちは、そのようなプロダクトがどうあるべきか調査することから始め、 カスタマーとユーザが必要とするセキュリティとはどんなものかを理解するために多くの時間を費やしました。 その結果がShieldです。 Shieldは、ElasticsearchクラスタをセキュアにするElasticsearchの有償プラグインです。 私たちは、ShieldをDev、Gold、Platinumサブスクリプションの一部として、追加料金なしで提供します。\n最初のリリースでは、基本的な機能と基盤にフォーカスしています。 Elasticsearch自身に対しても、セキュリティに対して準備してきました。 拡張性の側面だけでなく、Elasticsearchにあるデータフローについても再考してきました。 Elasticsearchクラスタをセキュアにする場合に、具体的な価値を即座に届けるだけでなく、素早く拡張できるようにも開発しました。\n機能 Shield 1.0は次の5つにフォーカスしています。\n認証(Authentication) 認可(Authorization) 暗号化通信とノードの認可(Encrypted Communication \u0026amp; Node Authentication) IPフィルタリング 監査証跡(Audit Trail) 認証(Authentication) セキュリティの大部分はアイデンティティについてです(例えば、だれがこのAPIを呼び出したのか?システムに何のサービスが接続するか?など) サービスのライフタイムのある時点で、サブジェクト(例えばユーザー)を現在実行中のサブプロセスなどに結びつけることです。 この関係性を持つためには、サブプロセスを実行する前にユーザの身元を確認するように命じます。 ユーザの身元の確認のプロセスをAuthenticationと呼び、ElasticsearchのすべてのAPIコールでそれが実行されます。\n認証の手法は多くの異なるものがあります。 それぞれの手法は、ユーザが認証されたという資格(Authentication Token)を、それぞれのタイプで提供するようにユーザに要求します。 Shield 1.0ではシンプルに、必要なauthentication tokenをユーザ/パスワードペアとしています。 (これは、Shieldの認証基盤が簡単に拡張でき、将来は異なるauthentication tokenもサポートできることを意味します。)\nユーザの資格を受け取ることだけでは不十分で、次に、それらをチェックする必要があります。 Shieldでは、これはレルムの責務です。 レルムは認証プロバイダ/サービスとしてみることができます。 妥当なユーザであると判断/解決されたか、 authentication tokenが適切な資格を持っていない/単に知らないユーザであるということで、拒否されたかです。 Shieldの認証メカニズムでは、複数のレルムを設定でき、さらに、あるレルムの戻り値を扱う他のレルム、というようなchainとすることもできます。 Shield 1.0は3つのレルムをサポートします。\nesusers - Elasticsearchによって管理されるファイルベースのレルムです。 これは、ファイルにユーザを定義することができます。(Apacheサーバのhtpasswdファイルのようなもの) このレルムは外部への依存はなく、Shieldをインストールすれば、デフォルトで使用できます。 このレルムは配置が簡単で、マルチテナントなElasticsearchクラスタに対して使用できます。 マルチテナントなElasticsearchクラスタとは、クラスタを複数のアプリでシェアすることをテナントと言います。 また、すべてのユーザがパスワードを忘れてしまうような\u0026quot;emergency\u0026quot;な代替レルムも対応可能です。 (誰もシステムに入れないような状況のことです) LDAP - 外部のLDAPサーバでユーザを認証するレルムです。 このレルムは組織のLDAPサーバで管理/保存されているユーザをすでに持っている組織を対象としています。 Active Directory - LDAPのタイプの1つで、Active Directoryに対する設定になります。 レルムはelasticsearch.yml設定ファイルで、次のように設定可能です。\nshield.authc realms:\nesuser: type: esusers order: 0 ldap: type: ldap order: 1 url: ldaps://url/to/ldap1/server ldap_fallback: type: ldap order: 2 url: ldaps://url/to/ldap2/server 上記のようにrealmsが一つのチェインとして参照されます。 レルムごとに、設定された順序で、それらは参照されます。\nNOTE : Shieldには、esusersファイルに保存されたユーザを管理するためのコマンドラインツールもあります。\n認可(authorization) 認可(Authorization)は保護されたリソースにアクセスするユーザを許可するか拒否するかということです。 モダンなシステムは、ユーザのパーミッションのために、ロールベースのアクセスコントロール(RBAC)モデルを利用します。 このモデルでは、各ユーザはロールの集合に関連していて、それぞれのロールには、パーミッションの集合が定義されています。 これは、洗練された設定で、パーミッションを機能的なグループで共有させることができます。 例えば、次のようなロールを定義したとします。\nemployee - すべての従業員は部門をまたいだ会社のデータへアクセスできます(例えば、コンタクトやディレクトリ情報など) sales - すべての営業職は営業データにアクセスできる(例えば、流通ルート、ルート、顧客) finace - すべての財務の従業員は財務データにアクセスできる(例えば、予算、経費、伝票) 財務部門のAnnは従業員と財務のロールを持っており、会社のディレクトリと財務データにアクセスでできます。\n認可プロセスはユーザがリクエストに関連したユーザが必要で、このプロセスのために、認証フェーズの後に直接実行されます。\nShieldは2つのタイプのリソースを定義します。クラスタとインデックスです。 これらは、すべてのAPIコールで保護されます。 さらに、それらに関連したパーミッションとロールも定義できます。 一度定義をすると、ロールはユーザもしくはLDAP/ADのグループに関係します。 ロールはroles.yml設定ファイルで定義されます。 設定のサンプルは次のようになります。\nadmin: cluster: all indices: \u0026#39;*\u0026#39; : all monitor: cluster: monitor indices: \u0026#39;*\u0026#39;: monitor employee: indices: \u0026#39;company_directory\u0026#39; : read sales: indices: \u0026#39;opportunities\u0026#39; : read, write \u0026#39;accounts\u0026#39; : read, write finance: indices: \u0026#39;expenses\u0026#39; : read, write \u0026#39;purchases\u0026#39; : read, write 上記のサンプルで、次の5つのロールを定義しています。\nadmin - 管理者のロールで、すべてのクラスターレベルの操作とすべてのインデックスに対してすべてのインデックスレベルの操作を実行可能です。 (¥*インデックスはすべてのインデックスにマッチするワイルドカード) monitor - システム/クラスタのモニタリングのためのロール。このロールのユーザはすべてのクラスタとインデックスレベルの情報の読み取りの APIにアクセス可能だが、インデックスのデータへの読み書きや設定の更新は不能 employee - compnay_directoryにあるすべてのデータへの読み取りアクセスを与えられたロール。このロールはクラスタレベルへのアクセスやデータの書き込みアクセスは持っていない (特にcompany。洗濯されたグループの人々はcompanyディレクトリの更新は可能だが、employeeは読み取りのみが可能) sales - opportunitiesとaccountsインデックスの読み書きができるロール finance - expensesとpurchasesの両方に読み書きができるロール 上記のサンプルで定義されているallとreadとwriteとして名前がつけられた権限です。 これらは、予約語で、Elasticsearchのローレベルのアクションを複数含んだ権限です。 (writeはindex, delete, delete_by_query, bulk, updateの操作を含んでいます。) 多くのケースで、これらのハイレベルの名前が付けられた権限で十分ですが、特定のロールに特定のアクションを明示的に指定することもできます。 次のようになります。\nhr: indices: \u0026#39;company_directory\u0026#39; : indices:data/write/index, indices:data/write/update ここまで説明した認可のレルムは、各ユーザに関連するロールを識別するためのものです。 内部のesuserレルムでは、提供されるesuserコマンドラインツールを使ってロールはユーザに割り当てたり変更したりもできます。 LDAPやActive Directoryでは、LDAP/ADグループにShieldのロールを割り当てることができます。\n認証と認可の両方を用いることで、ユーザリクエストに対して、ユーザごとに許可/不許可をすることができます。\n暗号化通信 認可はElasticsearchのデータを機能的な観点(許可されたユーザだけが操作を可能にする)で保護しますが、 クライアントからElasticsearchクラスタへ、もしくはクラスタのノード間では暗号化されていないデータを送るためまだ危険があります。 第三者が登頂したり、オンザフライでデータを書き換えたりといった可能性やクラスタを壊すことができます。\nShield 1.0はElasticsearchのすべての通信チャネルをセキュアにすることができます。 クラスタ内のノード間のチャネルやクライアントに公開されているチャネルです。 これは、SSL/TLS通信を導入して実現します。\nShieldで使えるSSLはElasticsearchのtransportサービスをSSL/TLSで通信できるものに置き換えます。 これは、ノード間通信チャネルと、HTTP transport(REST APIを提供するもの)のそれぞれに設定可能です。\nShieldのSSL/TLSは、スタンダードなJavaのものとkeystoreとtruststoreを基本にしたものが利用可能です。 SSL/TLSを設定すると、各ノードのキーストアに証明書をインポートする必要があります。 CAがサインした証明書を使うことも、CAが信頼したものとして許可許諾されたものを使うことが可能です。 これは、信頼されたすべてのCAとして知られているtrust storeが必要です。 新しいノードをクラスタに追加するときに、すべての必要な少なくとも一つの信頼されたCAから発行されてサインされたものが必要になります。 クラスタで個別のノードがすべてのkeystore/truststoreを更新する必要性なしに。??\n通信チャネルを安全にする方法やSSL/TLS設定をどのように行うかはShieldのドキュメントをご覧ください。\nノード間認証 強く推奨しますが、許可されたノードだけがクラスタに接続できるようにするために、ノードの認証をSSL transportに設定することができます。 これは、shield.transport.client.authにtrueを設定することで可能です。 設定した場合、ノード間でSSLハンドシェイクが行われ、接続されたノードが接続に来たノードのクライアント認証を要求しチェックします。 もし、チェックに失敗した場合は、SSLシェイクハンドが失敗し接続が拒否されます。\nSSLクライアント認証 transportレベルでノード認証が必要なようなら、次のような疑問がわくでしょう。 Elasticsearchはクラスタに接続するTransportクライアントを使うときはどのように振る舞うのか? Transportクライアントはクラスタの他のノードと同じチャネルを使うため、コネクションを確立するときに、ノードが他のノードと異なるかどうかを見極めることはできません。\nこの時、もっとも単純な解決は、Transportクライアントも同様に許可を与えることです。 それは、認証を解決するときに、他の問題(潜在的な悪意)を引き起こします。 Transportクライアントが他のクラスタのノードを偽装しようとすることです。これは望んでいません。\n幸いなことに、良い解決方法があります。 トランスポートプロファイルです。 Elasticsearch 1.4で導入されたトランスポートプロファイルは、トランスポートレイヤー(異なるホスト/ポートにバインドされる)のために複数のネットワークチャネルを設定することができます。 Shieldはこのサポートを、プロファイルごとに異なるSSL設定をできるように拡張します。 また、ノードのタイプとクライアントプロファイルタイプの間に明確な違いを設定することも可能です。 これを用いると、2つのプロファイルを設定できるようになります。 ひとつは、クライアントのためのもので、もうひとつはクラスタのノードのためのものです。 これにより、クライアントのための認証の問題が必要なくなり、Shieldはクライアントプロファイルをもった限定されたクライアントからのリクエストを保証します。\nIPフィルタリング これは、厳密には、認証カテゴリではありませんが関係しています。 Shieldはそれ自身がIPフィルタリングのメカニズムを持っています。 これは、許可/不許可のIPのリストを設定することができます。 これらのフィルタリングのルールは複数のレベルで設定可能です。 transportチャネル、transportプロファイルレベル、そして、HTTPチャネルです。 次の設定は、それらの設定のサンプルです。(設定ファイルはelasticsearch.ymlになります)\nshield: transport.filter: allow: - \u0026#39;127.0.0.1\u0026#39; - \u0026#39;2001:0db8:1234:0000:0000:8a2e:0370:73 deny: - \u0026#39;10.0.0.0/8\u0026#39; - \u0026#39;2001:0db8:1234::/48\u0026#39; - \u0026#39;*.google.com\u0026#39; http.filter: allow: [ \u0026#39;10.0.0.0/8\u0026#39; ] deny: [ \u0026#39;127.0.0.1\u0026#39; ] transport.profiles: client: shield.filter.deny: [ \u0026#39;_all\u0026#39; ] このように、IPv4とIPv6、CIDR、ホスト名、ワイルドカードが利用できます。 また、この機能はホストOSのIPテーブルに設定することで追加できるが、Shieldにそれを保持し、それらの設定を単純化し、 デプロイの全体から除去できることにも注意してください(詳細はドキュメントのIPフィルタリングをご覧ください)。\n監査証跡(Audit Trail) セキュアなシステムの必須機能の一つで、監査硝石により、Elasticsearchに発生した重要なイベントをトラッキングすることが可能です。 これらのイベントを保存することは、Elasticsearchクラスタの重要なアクティビティの証拠を提供でき、 不審な/悪意のある可能性のあるイベントを追跡するときの診断ツールにもなります。\nShield 1.0.0で、監査証跡は監査/アクセスlogを一般的なElasticsearchのログとは個別に保存します。 それらは、構造化されているため、読んだりパースするのが容易で、イベントのタイプも分類されています。 また、情報のレベルを設定することができ、各イベントをlogレベルの設定で書き出すことができます。 以下が、イベントのリストです。\nanonymous_access_denied - 認証トークンがないユーザからのリクエストがあった時のログ authentication_failed - リクエストされたユーザの認証に失敗した時のログ access_denied - 認証されたユーザが許可されていない操作を実行した時のログ access_granted - 認証されたユーザが許可された操作を実行した時のログ tampered_request - 不正に書き換えられたリクエストが到着したのを検知した時のログ connection_granted - ノードもしくはtransportクライアントがIPフィルタのルールにパスした時のログ connection_denied - ノードもしくはtransportクライアントがIPフィルタリングルールの制限により却下された時のログ Shieldの監査証跡についてより詳しく知りたい方は、ドキュメントをごらんください。\n次のバージョンでは? ここまで紹介したように、これはまだ始まりにすぎません。 Shieldに追加される多くの機能があり、しっかりとした基盤を構築したところです。 Shieldの次のバージョンでは、以下の機能の追加にフォーカスするでしょう。(これらだけに限ったわけではありません。)\nAPIによる設定、管理 より拡張され、柔軟なLDAP/Active Directoryサポート レルムタイプの追加(kerberos、anonymous、certificatesなどなど) セッションベースの認証 ShieldはElasticsearch社の2番目の(Marvelに続く)商用プロダクトです。 ダウンロードして開発環境で評価してください。 インストールは他のプラグインと同様の方法です(インストール方法についての詳細はこちら)。 一度インストールすると、30日の試用ライセンスが始まります。 もし、さらに時間が必要な場合は、sales@elasticsearch.comまで連絡してください。\n私たちのすべてのプロダクトについてフィードバックをお待ちしています。 Shieldの商用利用、機能、ロードマップ、その他のセキュリティに関するトピックなど、質問がありましたら、 サイトからご連絡ください。\n","date":1425030596,"dir":"post/2015/","id":"cb13b64d0127c13bb466c4d4677a7b8a","lang":"ja","lastmod":1425030596,"permalink":"https://blog.johtani.info/blog/2015/02/27/you-know-for-security-shield-goes-ga-ja/","publishdate":"2015-02-27T18:49:56+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:you know, for security: shield goes ga 1/27にShield 1.0 をリリースしました。 Elasticsearc","tags":["elasticsearch","shield"],"title":"セキュリティ向けプラグインShieldのリリース(日本語訳)"},{"contents":"4月13日から3日間、ElasticsearchのCoreトレーニングが東京で開催されます。 Early Birdということで、3/14までに申し込みすると割引があります。 興味のある方は、見ていただければと。\nまた、4/15にElasticsearch勉強会を開催します。 トレーニングに弊社のエンジニアが来日しますので、なにか話をしてもらう予定です。\n募集は後日、Elasticsearch勉強会のDoorkeeperで行います。 興味のある方は、登録しておいていただければと。\nトレーニングや勉強会でお待ちしております。\n","date":1425024629,"dir":"post/2015/","id":"f2cbe07bf2ff16d5a5860b4d6edbc5e8","lang":"ja","lastmod":1425024629,"permalink":"https://blog.johtani.info/blog/2015/02/27/2nd-tokyo-training/","publishdate":"2015-02-27T17:10:29+09:00","summary":"4月13日から3日間、ElasticsearchのCoreトレーニングが東京で開催されます。 Early Birdということで、3/14までに申し込みす","tags":["elasticsearch"],"title":"Elasticsearch Coreトレーニング開催"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:kibana 4. literally.\nKibana 4は現在、文字通り、抽象的に、概念的に、精神的に、そしてとても楽しく、プロダクションレディになりました。 1週間前に準備はできていましたが、満足できるものであるという確信を得たいと思っていました。 そして、Kibana 4.0.0 GAをリリースしました。 次のものはサンプルのスクリーンショットと前日譚です。 これらに興奮してしまった方のために、2ステップのプランを用意しました。\nダウンロードする:Kibana 4 downloadsページからダウンロードします。 理解する:Kibana 4 docsページを読んで理解します。 Tip : もし、まだ、あなたのクラスタがElasticsearch 1.4.4でない場合は、アップグレードする必要があります。\nTip2 : Kibana 4 RC1からアップグレードする場合は、configを移行する必要があります。こちらのgistを参照\n前日譚 - the back story Kibanaはすでに問題解決のためのツールになっています。 なぜ、毎晩2時に呼び出されるんでしょう? そのコードがプロダクションに入ったのはいつですか? その結果、何を壊しました? 私たちはそれらを解決しました。 世界的に、長い間、だれも夜中の2時に呼び出されませんでした。知ってます?。\n*しかし、ここには落とし穴があります。*答えが簡単になれば、問題が難しくなります。 楽な勝利は簡単でした。では、難しい問題(深さが3層の問題)を解きましょう。 複数の要素、複数のフィールドそして、複数のデータソースを分析する必要がある問題を解きましょう。 Kibana 4は少ない時間と労力で最も難しい問題を解決してくれます。\nKibana 3で学んだことをKibana 4に取り込みました。 なぜ10億のデータを持っているのに、地図には1000個しかプロットできないのでしょう? 1つのチャートに1つのフィールドなんでしょう? なぜ、1つのパネルに1つのチャートなんでしょう? なぜ、1つのダッシュボードに1つのインデックスなんでしょう? 5つのシナリオを用意し、2つのフィールドにまたがったデータを比較し、 1つのダッシュボードに3つのインデックスのデータを表示してみましょう。 さぁ、やりましょう。終わったらアイスクリーム(トッピング付きの)を取りに行きましょう。\nthe plot アイスクリームのように、問題には多くの種類があります。 そのために、Kibanaをナポリ風アイスクリーム(3色アイス)のように分割しました。 嫌いな種類は除いて。 もし、あなたがKibanaのユーザ歴が長い場合、最初のタブのDiscoverがホームであることが正しく感じるでしょう。 これにより、短時間で、検索し、レコードを見つけ、簡単な問題を解決できます。 簡単な問題とは、すべてを物語る1行のデータを見つけることによって解決する問題です。\n物事が簡単な検索で説明できるものよりも複雑になった時、チャートとグラフで魔法を作る時間です。 Visualizeタブを開き、Elasticsearchのaggregationの力を利用してデータを解析しましょう。 Visualizeは複数の次元の性質のデータを見せ、今まで尋ねたことがないような質問に対して素早く回答するチャートやテーブル、 地図を作成できます。 あなたが最初に尋ねる質問は「先週サイトが遅かったのはなぜ?」でした。 しかし、データによって明らかにされた質問は「なぜ、クリスマスに東京からの平均ファイルサイズリクエストがスパイクしたのか?」です。\n最後に、Dashboardでこれらを1つにします。\n大きなスクリーンに配置して、こう言います。 「あなたの答えはこのリンクにあります。また、Wikiに埋め込んで、データをCSVにエクスポートしてメールしました。 アイスクリームを食べた後に、自叙伝の第1章を書きました。もっとアイスを持ってきてください。かき混ぜますから。」\nそれぞれのタブで見てきた詳細については、Kibana 4 Beta 1 : Releasedをごらんください。\nto be continued\u0026hellip; 居眠りをする時間はあります?いいえ、Kibana 4.1についてすでに作業中で、将来の大きなプランを持っています。 多くの労力はKibana 4の土台の安定と実用性を構築することに使われました。 また、Elasticsearchアプリケーションの将来を構築するプラットフォームを作りました。 すべてのものは拡張できるように設計されています。 例えば、可視化はより良くなるように構築されています。 オープンソースは私たちのGitHubアカウント以上のものです。 それは、新しく素晴らしいものを誰もが作ることができる構造を作ることが私たちの約束です。\nKibanaでグラフなどを構築したり、Elasticsearchを利用したアプリケーションを作成するために、 私たち開発者のブログを参考にしてください。 ちょっと見てみたいですか? Elastic{ON}15のSpencer Algerのトークをチェックしてください。\nあなた方なしでは、私たちはここにはいないですし、あなた方の助けがなければ何もできません。 ぜひ、GitHubでのissueや提案、貢献をお待ちしています。 もしくは、IRCでFreenodeの#kibanaに参加してください。\nextra credit Kibana 4のすべての話に興味がありますか?私たちのKibana 4ベータに関する過去のブログをチェックしてください。\nKibana 4 Beta 1: Released Kibana 4 Beta 2: Get it now Kibana 4 Beta 3: Now more filtery Kibana 4 RC1: Freshly baked 最後に、Kibanaの利用に関する話をお持ちなら、ぜひ聞かせてください。 stories at elasticsearch dot comもしくは@elasticsearchに連絡をください。 あなたの話を世界にどのようにシェアしているかごらんください。\n","date":1424408752,"dir":"post/2015/","id":"eee039f49a5b570599cf459c55c649f3","lang":"ja","lastmod":1424408752,"permalink":"https://blog.johtani.info/blog/2015/02/20/kibana-4-literally-ja/","publishdate":"2015-02-20T14:05:52+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:kibana 4. literally. Kibana 4は現在、文字通り、抽象的に、概念的に、精神的に、そしてとても楽しく","tags":["elasticsearch","kibana4"],"title":"Kibana 4(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:elasticsearch 1.4.4 and 1.3.9 released\n本日(2/20)、Elasticsearch 1.4.4とElasticsearch 1.3.9をリリースしました。 これはバグフィックスリリースとなります。 主に、Lucene expression scriptsを使う場合のRPMとDEBパッケージの パッケージング問題のフィックスをしたものです。 1.4.4のダウンロードこちらのリンクからアクセスできます。\nfixes 1.4.3のRPMおよびDEBパッケージにはAntlrとASMの依存関係の不足がありました。 この依存はElasticsearchでLucene expression scriptsを利用する場合に必要になります。 Groovyに関する1.4.3の変更により、多くのユーザがLucene explression scriptsを利用することが予想されるため、すぐに、1.4.4をリリースしました。\nまた、このリリースには、クラスタの保留タスクに関するいくつかのバグフィックスも含まれています。 さらに、date histogramで負のインターバルの場合にOutOfMemoryErrorを引き起こすバグも 修正されています。\nすべての変更については1.4.4のリリースノートおよび1.3.9のリリースノートをごらんください。\nフィードバック 私たちはフィードバックをお待ちしています。 Twitter(@elasticsearch)もしくはGitHub issues pageで教えてください。\n","date":1424408734,"dir":"post/2015/","id":"ddd3e6f6e298d3884abc4d888a043664","lang":"ja","lastmod":1424408734,"permalink":"https://blog.johtani.info/blog/2015/02/20/elasticsearch-1-4-4-and-1-3-9-released-ja/","publishdate":"2015-02-20T14:05:34+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:elasticsearch 1.4.4 and 1.3.9 released 本日(2/20)、Elasticsearch 1.4.","tags":["elasticsearch"],"title":"Elasticsearch 1.4.4および1.3.9リリース(日本語訳)"},{"contents":"来る、4月4日の土曜日の午後に名古屋でElasticsearch勉強会を開催予定です。 「初」の東京以外の勉強会です。\nTwitterでこのようなツイートを見かけまして。\n名古屋でElasticsearchの勉強会やりたい機運(今のところ2人)。\n\u0026mdash; mogami (@smogami) 2015, 2月 4 これは!ということで、名古屋で勉強会をやろうかと思います。30名程度の場所を借りて実施予定です。 募集はいつもの、elasticsearch勉強会のDoorkeeperで行う予定です。 ページの準備まで少々待ちください。(おそらく、3月中旬くらい) 私自身はElasticsearchやELKについて話をしようと思っています。そのほかに、2,3名のスピーカーの方を予定しています。 LTなど興味がある人がいたら、連絡ください。\nこれを機に(?)他の場所でも勉強会を開催したいと考えています。 ニーズがどのくらいありそうなのかが、まだよくわかっていませんが、関西などでニーズがあるんじゃないかと期待していたり。\n興味のある方は、コメント欄、Twitterなどでコンタクトしてもらえればと。 (連絡来るとうれしいなぁ。)\n","date":1424240573,"dir":"post/2015/","id":"5b97ead91c0dd0bad57b4f43a89149a2","lang":"ja","lastmod":1424240573,"permalink":"https://blog.johtani.info/blog/2015/02/18/preparing-elasticsearch-meetup-in-nagoya/","publishdate":"2015-02-18T15:22:53+09:00","summary":"来る、4月4日の土曜日の午後に名古屋でElasticsearch勉強会を開催予定です。 「初」の東京以外の勉強会です。 Twitterでこのよう","tags":["elasticsearch","勉強会"],"title":"名古屋でElasticsearch勉強会を開催します"},{"contents":"第8回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 次回もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\n今回は出足が好調で、早々に180人の枠を超えるという嬉しい事態でしたが、 キャンセル待ちが残っているにもかからわらず、来られていない方が67名もいるということで、キャンセル待ちの方には申し訳なかったです。 もうすこし、キャンセルをしてもらえると嬉しいんですが。。。 今回はメールを当日に1度しか打ってないからかなぁ。\nさて、いつもの通り簡単なメモです。 本当に簡単にですが。\n「Elasticsearch導入チェックリスト?」 Elasticsearch株式会社 Jun Ohtani @johtani スライド:Elasticsearch導入チェックリスト?\nElasticsearchを開発環境や本番に導入する前に気にかけて欲しいことについて発表しました。 元ネタはelasticsearch pre-flight checklistです。 少々古いのですが、私が今回話した内容以外にもモニタリングなどについての話も盛り込まれています。 時間がある方は、見ていただければと。\n「Elasticsearch クエリとスキーマ定義のすごい細かい話」株式会社ドワンゴ 藤堂淳也 さん スライド:Elasticsearch クエリとスキーマ定義のすごい細かい話\nフィールドのチェックを別途インデキシングするアプリで行っている。利用できるものだけElasticsearchに投げる 実際に本番環境で利用しているマッピングに対してフィールドを追加する手順について 「これもドキュメントに書いてあるんですが」という感じでドキュメントに色々書いてあるので読みましょうというありがたい発表でした。 実際に試行錯誤したり検証するときに行ったことを喋ってもらえたので、どういった点を気にしながら運用、設計するかというのがわかりやすかったです。\n「ElasticsearchとKibanaで実現する、30億req/dayのリアルタイム分析」株式会社サイバーエージェント 山田直行さん @satully スライド:ElasticsearchとKibanaで実現する、30億req/dayのリアルタイム分析\n会場が21時までしか抑えられていないという失態で、ドタバタしてて前半は聞けてないです。。。\n前回の発表では30日分Elasticsearchに入れていたが、今は3日分のみ保存 レポートなどにはRedshift+Tableauを利用 Kibana3をメインに使っているが、Kibana4も検討予定? QA\nQ:なぜ、ELBを挟んでいるのか? A:特に考えておいているわけではない。 Q:インデックスの構成は? A:1日に2つのインデックス。Bitされたもの、入札されないもの Q:searchのnodeをやめたのは? A:前回発表した勉強会での懇親会で話を聞いたり、他の方と話を聞いて、不要と判断したため 「はてなのメディア面を支えるElasticsearch」株式会社はてな 山家雄介さん @yanbe スライド:未定。おそらく、開発者ブログに公開されるかと。\n\u0008* アドテク系にもやってるらしい。BrandSafeはてな\nはてなブックマークのデータを魅せ方を変える機能などで大活躍。B!KUMAとか その日の話題の見出し自動生成機能。Significant Terms Aggregationsを利用。 こちらの「自然言語処理技術を用いたはてなブックマークの新機能「トピック」をベータリリースしました」エントリに関係あるのかな? 記事の魅せ方を検索できる管理画面ではElasticsearchのクエリDSLを活用されているとのことでした。 検索専門の人でなくても検索式を簡単にくみたてられる画面を用意して、ElasticsearchのクエリDSLに変換するようにしていると。 確かに、クエリをそのまま組み立ててもらうよりも利用しやすい画面がある方がいいですよね。バックエンドはJSとPerlのライブラリとのことでした。\nその他、感想などのブログ 2015-02-13 第8回 elasticsearch 勉強会 @ 丸の内 リクルート 41Fアカデミーホール [Elasticsearch] 第8回 elasticsearch 勉強会へ参加してきた 第8回elasticsearch勉強会 #elasticsearch #elasticsearchjp 第8回 Elasticsearch 勉強会に行ってきた #elasticsearch #elasticsearchjp 勉強会メモ - 第8回elasticsearch勉強会 まとめ 今回も検索からログまでいろんな話になったので、面白かったかと。 参加された方は新しい方が多かったんじゃないかなぁと。(集計結果で見れないのかな、Doorkeeper)。\n今回は、みなさんに21時に41Fから33Fへ移動していただくという大失態があったので、大変申し訳なかったです。 次回(4月中旬)は、このようなことがないように気をつけますので、今後もよろしくお願いいたします。\nあと、東京以外の勉強会も検討しつつあります。興味のある方はコメントやTwitterで反応をいただけると嬉しいです。\nスピーカーは随時募集中ですので、コメント、メール、ツイートなど、コンタクトしていただければと思います。 よろしくお願いいたします。\n","date":1424066543,"dir":"post/2015/","id":"997acc135d01b54f7de77a432fb9133f","lang":"ja","lastmod":1424066543,"permalink":"https://blog.johtani.info/blog/2015/02/16/8th-elasticsearch-jp/","publishdate":"2015-02-16T15:02:23+09:00","summary":"第8回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん","tags":["elasticsearch","勉強会"],"title":"第8回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:running groovy scripts without dynamic scripting\nElasticsearch1.3.8と1.4.3のリリースにより、デフォルトで、リクエストに含まれるGroovyスクリプトや インデックスに保存されたスクリプトを動的に実行する機能をオフにしました。 しかし、Groovyはまだデフォルトのスクリプト言語です。 本ブログ記事では、少しだけダイナミックだが、サンドボックスではない言語のためのスクリプトを どのように使い続けるかを説明します。\n本ブログ記事は、それが何を意味し、さらに重要なのは、安全に重要なタスクを実行させるためにスクリプトを どのように使用し続けるかを理解する助けとなるはずです。\nダイナミックスクリプトとは? Elasticsearchに詳しくない方のために、Elasticsearchでは、 さまざまなリクエストの一部としてスクリプトを送信することができます。 search、aggregation、update、upsert、delete by queryなどです。 あなたのユースケースのために、通常の動作よりも拡張した動作をさせるためにスクリプトを追加できます。\n例えば、以下のリクエストは、ダイナミックスクリプトを含んでいます。 field1とfield2 + shiftが同じ値を持っている時だけドキュメントを返します。\nGET /_search { \u0026#34;query\u0026#34;:{ \u0026#34;filtered\u0026#34;:{ \u0026#34;filter\u0026#34;:{ \u0026#34;script\u0026#34;:{ \u0026#34;script\u0026#34;:\u0026#34;doc[\u0026#39;field1\u0026#39;].value == (doc[\u0026#39;field2\u0026#39;].value + shift)\u0026#34;, \u0026#34;lang\u0026#34;:\u0026#34;groovy\u0026#34;, \u0026#34;params\u0026#34;:{ \u0026#34;shift\u0026#34;:3 } } } } } } 言語を変えることもできます。 それは、当然、シンタックスが変わったり、制限が追加(例えば、Groovyスクリプトの代わりにLucene Expressionsに変更)されることもあります。 langパラメータによって言語を指定できます。\nなぜそれはダイナミック? 上記の例はダイナミックスクリプトです。 それは、実際のスクリプトの部分はサーバサイドで動的に解釈されコンパイルされる必要があるからです。 ダイナミックスクリプトはElasticsearchのAPIによってデータノードに送信されます。 これは、インデックスされたスクリプト(indexed script)も含みます。\n言い換えると、もし、スクリプトがデータノード全てに保存されていなければ、 それは、ダイナミックスクリプトとして扱われます。\ndynamic scriptingをオフにするとどうなるか? 最新のリリースでの変更により、Groovyのdynaic scriptingはデフォルトでオフになりました。 先ほどのスクリプトについても同様で、もし、先ほどのリクエストを実行すると、次のようなエラーが発生します。 (一部省略してあります。)\n{ \u0026#34;error\u0026#34;:\u0026#34;SearchPhaseExecutionException[Failed to execute phase [query], all shards failed; shardFailures {[8FJ02MofSnqVvOQ10BXxhQ][test][0]: SearchParseException[[test][0]: from[-1],size[-1]: Parse Failure [Failed to parse source [{...}]]]; nested: ScriptException[dynamic scripting for [groovy] disabled]...\u0026#34;, \u0026#34;status\u0026#34;:400 } エラーメッセージの重要な箇所は「ScriptException[dynamic scripting for [groovy] disabled]」です。\nスクリプティングを使い続けるには? Elasticsearchでスクリプトを実行するには3つの方法があります。 2つのダイナミックな方法は、リクエストごとのスクリプト(上述)かインデックスされた スクリプト(indexed script)を使う方法です。 インデックスされたスクリプトを使うことは、Elasticsearch自身にGroovyスクリプトを保管することで 利用で、それらを要求に応じて利用することです。 (これは、実際には十分機能しますが、これではまだ、信頼できないユーザに対して彼らのスクリプトを実行できます) RDBのように保存されたプロシージャとして同じ方法で実行させるものと同様です。 前もって、スクリプトを記述しておき、リクエストの一部として後から、名前で呼び出して実行可能です。\nGET /_search { \u0026#34;query\u0026#34;:{ \u0026#34;filtered\u0026#34;:{ \u0026#34;filter\u0026#34;:{ \u0026#34;script\u0026#34;:{ \u0026#34;script_id\u0026#34;:\u0026#34;your_custom_script\u0026#34;, \u0026#34;lang\u0026#34;:\u0026#34;groovy\u0026#34;, \u0026#34;params\u0026#34;:{ \u0026#34;shift\u0026#34;:3 } } } } } } あまり変わっていないことに気づくでしょう。 scriptの部分が、前もって記述されたスクリプトの名前script_idに変更されただけです。\nElasticsearchにスクリプトを提供するダイナミックではない方法はインデックスに保存する代わりに、 ディスクにファイルとしてスクリプトを保存することです。 そうすることで、各スクリプトを設定として保存します。 これは、どのようなスクリプト言語に対してもダイナミックスクリプティングをオフにしたまま、 サンドボックス化されないスクリプトを使い続けることができる方法です。\n最初のサンプルで、Groovyスクリプトはdoc['field1'].value == doc['field2'].value + shiftでした。 これを、.groovy拡張子を持ったファイルとして書き出すことができます。\ndoc[\u0026#39;field1\u0026#39;].value == (doc[\u0026#39;field2\u0026#39;].value + shift) もし、このファイルにyour_custom_script.groovyちう名前をつけて、 Elasticsearchのすべてのデータノードのconfig/scriptsディレクトリに保存すると、 Elasticsearchは60秒(elasticsearch.ymlのwatcher.intervalで変更可能)でこのスクリプトを認識し、今後のリクエストに利用できるようにプリコンパイルするでしょう。 そのファイルはElasticsearch実行ユーザによって読み込みができる必要があります。 これをディスクに書き込んだ後、あなたの設定ディレクトリは次のようになっています。\nconfig/ elasticsearch.yml logging.yml scripts/ your_custom_script.groovy これは、各リクエストやインデックスされたスクリプトをスクリプトとして動的に送信しませんが、 信頼された環境にスクリプトを追加することでダイナミックスクリプトとなることを許します。\nディスクに書かれたスクリプトを使用する スクリプトは、ロードされたスクリプトになるまでは、利用できません。 ログファイルに次のようなログが表示されるまではです。\n[2015-02-11 11:14:47,066][INFO ][script ] [Sergei Kravinoff] compiling script file [/path/to/elasticsearch-1.4.3/config/scripts/your_custom_script.groovy] すべてのElasticsearchのデータノードでスクリプトが読み込まれたら、 それを利用することができます。 利用するために、file(script_idではありません!)としてスクリプト名を指定します。\nGET /_search { \u0026#34;query\u0026#34;:{ \u0026#34;filtered\u0026#34;:{ \u0026#34;filter\u0026#34;:{ \u0026#34;script\u0026#34;:{ \u0026#34;file\u0026#34;:\u0026#34;your_custom_script\u0026#34;, \u0026#34;lang\u0026#34;:\u0026#34;groovy\u0026#34;, \u0026#34;params\u0026#34;:{ \u0026#34;shift\u0026#34;:3 } } } } } } Note:langは必須ではありません。Groovyがデフォルトの言語のためです。 もし、違うスクリプト言語を使いたい、もしくは、デフォルトの言語を(例えば、Lucene Expressionsへ) 変更したい場合、言語が正しいスクリプトを見つけるために提供されている必要があります。 一番良い方法は、アプリケーションがlangパラメータを含んでいることを勧めます。 これは、将来、デフォルトのスクリプト言語が変更されても、問題ないからです。\n質問? もし、質問があれば、遠慮なくTwitter(@elasticsearch)で教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1423721589,"dir":"post/2015/","id":"1fed22e99b0e11a50eb7b92cb1644e8a","lang":"ja","lastmod":1423721589,"permalink":"https://blog.johtani.info/blog/2015/02/12/running-groovy-scripts-without-dynamic-scripting-ja/","publishdate":"2015-02-12T15:13:09+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:running groovy scripts without dynamic scripting Elasticsearch1.3.8と1.4.3のリリースによ","tags":["elasticsearch"],"title":"Groovyスクリプトをダイナミックスクリプトなしで実行(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:elasticsearch 1.4.3 and 1.3.8 released\n本日、Lucene 4.10.3をベースにしたElasticsearch 1.4.3と、セキュリティとバグフィックスリリースである、Elasticsearch 1.3.8をリリースしました。 ダウンロードおよび変更リストはそれぞれ次のリンクからアクセスできます。\n最新ステーブルリリース:Elasticsearch 1.4.3 1.3.x系バグフィックス:Elasticsearch 1.3.8 過去のリリースに関するブログ(公式)はこちら。\n1.4:1.4.2, 1.4.1, 1.4.0, 1.4.0.Beta1 1.3:1.3.7, 1.3.6, 1.3.5, 1.3.4, 1.3.3, 1.3.2, 1.3.1, 1.3.0. すべての変更については1.4.3のリリースノートおよび1.3.8のリリースノートをごらんください。 以下では、セキュリティの問題について紹介します。\ngroovy scripting の脆弱性 Elasticsearchのバージョン1.3.0から1.3.7および1.4.0から1.4.2で、Groovyスクリプトエンジンに脆弱性が発見されました。 脆弱性は、攻撃者がGroovyスクリプトをサンドボックスを避けて構築でき、 ElasticsearchのJava VMを実行しているユーザとしてシェルコマンドを実行できます。\nこの問題をCVE-2015-1427として報告済みです。\nバージョン1.3.8と1.4.3では、デフォルトで、Groovyに対してのサンドボックスをオフにしました。 結果として、ダイナミックスクリプトの実行はGroovyに対してもオフとなります。\nもし、脆弱性のあるバージョンで実行している場合、v1.3.8かv1.4.3にアップグレードするか、ダイナミックなGroovyスクリプトをクラスタの すべてのノードに対して次の設定を追加することで、オフにします。\nscript.groovy.sandbox.enabled: false これは、Groovyのサンドボックスをオフにし、リクエストの一部としてインラインで受け付けるダイナミックなGroovyスクリプトや 特殊な.scriptsインデックスに保存されているスクリプトを実行しません。\nそれまでは、各データノードのconfig/scriptsディレクトリにファイルとして保存されたGroovyスクリプトは まだ、利用可能です。詳細の情報についてはRunning scripts without dynamic scriptingをごらんください。\nfuture scripting plans 安全なダイナミックスクリプティング言語としてGroovyを失うことは、Elasticsearchにとって痛手です。 update APIやsearch APIやaggregationsフレームワークの一部としてScriptを使います。 それらは、静的なAPIでは簡単に表現できない、カスタムなトリックをユーザに実行できるようにします。\n残念ながら、Groovyチームとこの問題を議論した後、Groovy言語もサンドボックスによってきちんと保護されている というにはあまりにもダイナミックであるという結論に達しました。 Groovyは、デフォルトでは利用できなくなります。 利用可能なダイナミックスクリプト言語としてはLucene Expressions言語のみとなります。 Expressionsははやいですが、それらは非常に限定されています。数値のフィールドでのみ実行可能で、ループをサポートしていません。\nより強力で(しかし安全な)ミニ言語になるようにExpressionsを拡張することを調査しています。 これは、Scriptユーザが現在持っている最も一般的なユースケースを少なくとも助けるでしょう。 この拡張は長期間のプロジェクトであり、進化には時間がかかるでしょう。\nぜひ、Elasticsearch 1.4.3をダウンロードして、試してみてください。 そして、感想をTwitter(@elasticsearch)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1423712393,"dir":"post/2015/","id":"5badf61ecb9cfadd7d6af58712fa5f6f","lang":"ja","lastmod":1423712393,"permalink":"https://blog.johtani.info/blog/2015/02/12/elasticsearch-1-4-3-and-1-3-8-released-ja/","publishdate":"2015-02-12T12:39:53+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:elasticsearch 1.4.3 and 1.3.8 released 本日、Lucene 4.10.3をベースにしたElas","tags":["elasticsearch"],"title":"Elasticsearch 1.4.3および1.3.8リリース(日本語訳)"},{"contents":"今年もCROSS参加しました。そして、話もしてきました。 今年は横浜の大さん橋でした。横浜はあんまりこないので、乗り換えでおたおたしてしまいましたが。。。\nなかなかいい景色でした。(寒いけど) 「おおさんばし」って読むんですね。「だいさんばし」だと思ってた。。。\n以下はいつもの、自分用メモです。\n俺はどうしてそのデータストアを選択したのか 〜銀河と小宇宙を語る会〜 http://2015.cross-party.com/program/c1\n遅れて入ったので、ちゃんと聴けてないです。\n最近注目しているデータストアは? Postgresql。JSON型が気になってる。 AiroSpike。データ型のあるデータストアが気になってる。 MongoDB。JSON使いたいなら、これじゃないの? AWSのAurora。インスタンスタイプを選ばなくていい(選ばないといけないらしい)とか、勝手にスケールしてくれるし、MySQL互換。 今こそ語るエンジニアの幸せな未来 http://2015.cross-party.com/program/x3\n「無職初日です。」 Web系の人?とか質問されて、自分が何系かいつもわからなくなるなぁ。 「働きがいは会社が提供するのか、個人が見つけるのか?」 個人かなぁ。会社がなにをやってるかにもよる気がするかなぁ。 「辞めると伝えると、やりたいようにやれって言われるw」 リモートできるかできないか。 「働きがい」というキーワードが出てると普通は怪しい会社w 今は、働きやすさを高くしないと人が雇えなくなってきている。 欧米のミドルウェアだと、35歳定年説はない。→日本でもそうじゃないですか? 漫然と進んでるとダメ。→そりゃそうだ。 全文検索エンジン群雄割拠〜あなたが使うべきはどれだ!〜 http://2015.cross-party.com/program/c4\nスライド:https://speakerdeck.com/johtani/elasticsearchfalseshao-jie-tote-zheng-cross-2015\n楽しんでいただけましたでしょうか? ちょっと話が長くなってしまい、あとの方の時間が少なかった気がしますが。。。\nKibanaのバックエンドとして認識されている人もいたので、検索エンジンですよというのをアピールするいい機会になったので良かったです。 もちろん、Kibanaとの組み合わせも面白いので、少しでも興味をもっていただき、触っていただけたらなぁと。\n話をする機会を用意していただいた、やまかつさん、その他のスピーカーのみなさん、ありがとうございました!。\nElasticsearchに関して何か興味質問などありましたら、気軽にコンタクトしてください。Twitterとかブログコメントなどで。\nプレモルタイム以降 プレモルの写真撮るの忘れてました。。。重要なのに。。。\n美味しくプレモルをいただきながら、何人かの方に声をかけていただき、話をすることができました。 こういう時間がとってあるのがいいですよね。 色々なところでElasticsearchを使っていただいているようで、うれしい限りです。 DMMの方とも話ができたし。\nまとめ 今年はプレモルを飲みに行くだけかなぁと思っていたのですが、話をする人になってました。(おかしいなぁ) 来年もあれば、きっと参加するかなぁと。ではまた来年!\n夜景きれいですね。(端っこに写ってる船は飛鳥IIでした。)\n","date":1422500368,"dir":"post/2015/","id":"fe6ba10cc6c9509b4b22e9d59e029775","lang":"ja","lastmod":1422500368,"permalink":"https://blog.johtani.info/blog/2015/01/29/talk-at-cross2015/","publishdate":"2015-01-29T11:59:28+09:00","summary":"今年もCROSS参加しました。そして、話もしてきました。 今年は横浜の大さん橋でした。横浜はあんまりこないので、乗り換えでおたおたしてしまいま","tags":["勉強会","elasticsearch"],"title":"CROSS 2015で話をしてきました #cross2015"},{"contents":"今年は大晦日になってしまいました。しかも、ちょっと飲んでたり。。。 第9流しながら書いてます。\n振り返り(2013年に書いた抱負から) まずは昨年書いた抱負からの振り返りです。\nElasticsearch勉強会の継続、Solr勉強会の継続+ミックスした検索勉強会の開催 IDEAのさらなる活用 もっと開発(プラグインとか) AWSをもう少し活用 海外のイベントに行ってみたい 読書と英語を継続 AWS活用できてないです、、、 ミックスした勉強会は、ドタバタしててできませんでした。\nIDEAはさらなる活用までいってるかは不明ですが、最近は隣にとても詳しい人が座っているので色々と教えてもらってます。 開発については、ちょっとずつですが、PR書いたりしてます。\n振り返り(今年あったできごと) 初海外(ベルリンとアムステルダム) Elasticsearchに転職 初献本? Elasticsearch勉強会の定期開催 ElasticSearch Serverの翻訳 サーバ/インフラエンジニア養成読本の執筆 勉強会以外でもスピーカー 英語の継続(切実) 初ものが多かったです。 初の海外の会社、初の海外旅行(仕事)、初の献本(著者の人から、多分、初)、初の翻訳本、初のムック本執筆などなど。\n初の海外でした。なのに、夏には海外の会社に転職してみてるとか、ちょっと自分でも信じられません。 ベルリンでは、海外の勉強会にも参加できて非常に有意義でした。 ヨーロッパの街並みは、日本では経験できない雰囲気で、向こうの方には普通の街並みも自分にはとても新鮮でした。\n転職自体は2回目ですが、海外の会社というのは初めてです。日々、英語\u0008の勉強になりますし、いろんな刺激を受けています。 英語の勉強自体も継続中です。英語力が不足しているのは自覚してるので、少しでも英語に触れるようにDLifeで海外ドラマを録画して、通勤時間帯にみるなどを試みてます。\n書籍には、昨年につづき関わることができました。来年も何かしらの書籍に関われることができればなと。 (\u0008気になる人は以下のリンクから。。。)\n分かりきったことですが、Elasticsearchな1年でした。 転職してあっという間の半年です。まだまだやりたいことがいっぱいあるので、来年もバランスよく頑張らないと。\n来年の抱負 英語の継続 海外のイベントへの参加 多岐にわたるイベントでのスピーカー 日本の人員の倍増!? Elasticsearchに関する日本語の情報発信 Elasticsearch座談会みたいなものの開催 英語の継続については書くまでもないですね。 海外のイベントへの参加もかなぁ。3月にサンフランシスコに行くとは思います。 そのほかには、今度こそBerlin Buzzwordsに行きたいです。\nElasticsearch勉強会以外のイベントでもElasticsearchを広めるべく色々なところでスピーカーをしたいなと思っています。 検索、ログ解析で少しは知名度が上がってきていますが、別の言語のコミュニティやイベントでは、まだまだ、elasticsearch自体を知らない人もいると思います。まずは知ってもらうところからかなと。\n日本の人員の倍増については、今年も達成してます(一人が二人になりましたw)。 来年も倍増できればうれしいなと。同じ母国語の同僚がいるのはやっぱりうれしいし、心強いですから。\n来年は(も)、日本語での情報をどんどん発信していきます。サイトやガイドなども 日本語にしたいなと。 あとは、これまで、勉強会でスピーカーをしていただいた人だけを集めた座談会のようなものも開催したいなと考えています。 私自身も色々と聞きたいことがありますし。 そのほかにも色々と要望をお待ちしています。Twitterやブログのコメント欄などで気軽にコンタクトしていただければと。\n最後は、いつものようにですが、来年も勉強会やいろんなイベントに参加する予定です。 ブログも週1程度で書く努力しないとなぁ。 こんな話を書いてくださいとかのリクエストもお待ちしています。\n今年はあと、数時間ですが、色々とお世話になりました。 この場を借りてお礼申し上げます。\n来年も、いろんな方に絡んでいくとは思いますが、よろしくお願いいたします。\n","date":1420026086,"dir":"post/2014/","id":"b36abffbe5d6a0de73a9968604a1a3f9","lang":"ja","lastmod":1420026086,"permalink":"https://blog.johtani.info/blog/2014/12/31/looking-back-2014/","publishdate":"2014-12-31T20:41:26+09:00","summary":"今年は大晦日になってしまいました。しかも、ちょっと飲んでたり。。。 第9流しながら書いてます。 振り返り(2013年に書いた抱負から) まずは昨年","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2014)"},{"contents":"この記事はElasticsearch Advent Calndar 2014の25日目のエントリです。\nあっという間に最終日です。来年につなげるという意味で、Elasticsearchの2系のIssueをいくつかピックアップして紹介してみます。\n現在、ElasticsearchのGitHubリポジトリは、大きく3つのブランチで作業しています。 master、1.x、1.4です。masterと1.xの大きな違いとしては、masterはLuceneの5.x系を採用している点です。\nなお、これから紹介するIssueは現在、確定していない項目も含んでいます。実際に2.0がリリースされるタイミングでは 採用されない場合もあります。\nUpgrade master to lucene 5.0 snapshot #8347 (closed) https://github.com/elasticsearch/elasticsearch/pull/8347\n先ほど書きましたが、Luceneの5に対応するためのPRです。 Lucene 5に関してはLuceneのコミッターのMikeさんのブログ記事も参考になります。\nLucene 5に変更することで、BitSetに関する改善が多く含まれることになります。 メモリの利用量、圧縮などの改善が多く含まれています。 もう1点大事な点としては、Lucene 5系ではLucene 3系のインデックスを読み込むことができなくなる点です。 Luceneの下位互換の範囲は1つ前のメジャーバージョン(5.x系の場合は4.xまでが対象)となっています。\nFilter cache: add a _cache: auto option and make it the default.(closed) https://github.com/elasticsearch/elasticsearch/pull/8573\nFilter cacheは、trueもしくはfalseの設定が利用できますが、filterの種類にも依存します。 その辺りの条件を加味しつつ、よしなにCacheをコントロールしてくれます。\nRemove and/or/not in favour of bool filter #8960(open / discuss) https://github.com/elasticsearch/elasticsearch/issues/8960\n似ているが少し異なるand、or、notフィルタとboolフィルタが存在しています。 これらをわかりやすくするために、boolフィルタに統一しましょうという話し合いをしています。\nInput validation #9059(open / discuss) https://github.com/elasticsearch/elasticsearch/issues/9059\n色々な入力に関するチェックを追加しようというIssueです。 たとえば、ディレクトリ名やファイル名、URLのパスやクエリストリング、フィールドのパスやスクリプトなどです。 Validationがあると、変な設定をして頭をかかえることもなくなるかなぁと。\nRefactor analysis framework #8961(open) https://github.com/elasticsearch/elasticsearch/issues/8961\n新しくAnalyzerを作った場合に、色々な場所に登録必要があったりします。インデックスレベルとノードレベルです。(Kuromojiプラグインなどが参考になります。) また、インデックスごとにカスタムのAnalyzerを設定するので、1つのノードに同じAnalyzerを何度も設定しないといけません。 よりシンプルにするために、Analyzerをノード単位で設定しようという提案です。\nRemove possibility for conflicting field definitions and ambiguous field resolution #8870(open) https://github.com/elasticsearch/elasticsearch/issues/8870\n同じインデックスに、異なるtypeで、同じフィールド名があった場合、いろいろと良くないことがあったりします。 たとえば、フィールドのタイプがintegerとstringと異なる場合に、インデックスレベルで検索を行うとうまく検索できなかったりと。 この問題を解消するために、より明確にしようというIssueです。 たとえば、フィールド名を指定するためには、フルパスで記述をするだとか、フィールドマッピングに関してはインデックスレベルで内部で保持をするなど。\nValidation of mappings request to reject unsupported fields #7205(closed) https://github.com/elasticsearch/elasticsearch/issues/7205\n1.xでも取り込まれますが、嬉しい機能なので紹介します。 これまでは、mappingsでスペルミスをした場合(たとえば、field設定で\u0026quot;indexx\u0026quot;といったミス)には、その項目は単に無視されるだけでした。 これが、v1.xでは、エラーに\nまとめ ということで、簡単ですが、v2.0.0に向けたIssueをピックアップして紹介してみました。 上記以外にも多くの改善、提案が2.0に向けて行われています。 興味のある方は、v2.0.0ラベルでIssueを検索してみてはいかがでしょうか?\n今年もあとわずかとなりました。 今年の2月にElasticsearchの1.0がリリースされ、あっという間に1.4なりました。まだまだ改善しています。\n来年もElasticsearchに興味をもっていただければ嬉しいです。 Elasticsearch初のユーザカンファレンスのサイトもオープンしました。 Elasticsearchに関するいろいろな話が聞ける機会だと思います。登録をお待ちしています。\n","date":1419490380,"dir":"post/2014/","id":"cb9649eca3dfbd356527ffc88f1dcb94","lang":"ja","lastmod":1419490380,"permalink":"https://blog.johtani.info/blog/2014/12/25/pickup-elasticsearch-2-0-0-labels/","publishdate":"2014-12-25T15:53:00+09:00","summary":"この記事はElasticsearch Advent Calndar 2014の25日目のエントリです。 あっという間に最終日です。来年につなげるという意味で、Elasti","tags":["elasticsearch"],"title":"Elasticsearch 2.0系のIssueの紹介"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:marvel 1.3.0 released\n12/17に、Elasticsearch Marvel 1.3.0をリリースしました。 Marvelの以前のリリースから、Elasticsearchでは様々なことがありました(Elasticsearch 1.4のリリースなど)。 このバージョンでは、モニタリングにクエリキャッシュや新しいcircuit breakerなどのような機能を追加してあります。 Senseのナレッジベースは最新のAPIを含むものに拡張されています。 また、Shieldのリリースに向けた準備として、HTTPsのサポートも追加しました。\nアップグレードのために、Elasticsearchの全てのノードに最新版のMarvelプラグインをインストールする必要があります。 また、他のJavaプラグインと同様に、Marvelの新バージョンを有効にするために、各ノードを(1台ずつ)リスタートする必要があるでしょう。 アップグレードプロセスについての詳細は、Marvelドキュメントをごらんください。\nまとめとして、ここに本リリースに関する改善点をいかにリストアップしておきます。\nagent 追加: httpsのサポート デフォルトのMarvelの設定(以前は常に9200)ではなく、ローカルノードのポートを自動的に検出 改善: marvelインデックステンプレートに関するエラーチェックと耐障害性(それに対するチェックと追加時のチェック) エラーログに関するくり返しの抑制 URLパラメータによるインデックス名を指定する_bulk exportコマンド。これは、rest.action.multi.allow_explicit_indexがfalseに設定されているときに有用 修正: ES 1.4.0のtribe nodeがMarvelのインストール時に初期化されない問題 削除: UIで表示されないoptional shard level statsを除去 monitoring ui 追加: ES 1.4.0で導入された新しいcircuit breakerを追加 circuit breakerのlimitをグラフにプロット QueryCacheのグラフを追加 index throttlingのグラフの追加 Index writerとバージョンのmapのメモリ使用量のグラフの追加 修正: Network Transport Bytes Receivedグラフに実際の送信量を表示 Node Statsダッシュボードでいくつかのスレッドプールの不足 sense 追加:\nmappingsをインデックスでオートコンプリートするしないの設定を可能に Cluster Reroute API Search APIのQuery Cacheパラメータ Analyze API Validate Query API Put Percolator API cluster.routing.allocation.*設定 Function Scoreクエリのweightパラメータ Flush API Terms Aggregationのshow_term_doc_count_errorパラメータ Update API _geo_distanceソートオプション Significant Terms aggregationを1.4.0にアップデート Mapping APIにメタデータフィールドを追加 Get Index API Scripted Metric Aggregation simple_query_stringクエリ More Like Thisクエリを1.4.0にアップデート has_childクエリ/フィルタのmin_childrenとmax_childrenオプション terms aggs/significant terms aggsのヒントオプション Mappings APIのtransform インデックスされたscriptとtemplate \u0008* Geo Bounds aggregation Top Hits aggregation Terms aggregationのcollect_modeオプション Percentiles Rank aggregation Disk Threshold Allocator設定 修正:\nURLオートコンプリートの挙動(プロトコルとホストのような組み合わせ) nested typeマッピングのinclude_in_parentとinclude_in_rootの不足 Rangeフィルタでのgt、gte、lt、lte Existsフィルタのオートコンプリート Snapshot、Restore APIのリポジトリ設定の時オートコンプリートの失敗 いつものように、Elasticsearch Marvelを改善するために、フィードバックをお待ちしています。 ElasticsearchユーザMLやTwitterに質問や意見お送りください。\n","date":1418890008,"dir":"post/2014/","id":"7dea465ad52758b10cbceb08c81d1760","lang":"ja","lastmod":1418890008,"permalink":"https://blog.johtani.info/blog/2014/12/18/marvel-1-3-0-released-ja/","publishdate":"2014-12-18T17:06:48+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:marvel 1.3.0 released 12/17に、Elasticsearch Marvel 1.3.0をリリースしました","tags":["elasticsearch","marvel"],"title":"Marvel 1.3.0リリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:elasticsearch 1.4.3 and 1.3.8 released\n本日、Lucene 4.10.3をベースにしたElasticsearch 1.4.3と、セキュリティフィックスとバグフィックスリリースである、Elasticsearch 1.3.8をリリースしました。 ダウンロードおよび変更リストはそれぞれ次のリンクからアクセスできます。\n最新ステーブルリリース:Elasticsearch 1.4.3 1.3.x系バグフィックス:Elasticsearch 1.3.8 過去のリリースに関するブログ(公式)はこちら。\n1.4:1.4.1, 1.4.0, 1.4.0.Beta1 1.3:1.3.6, 1.3.5, 1.3.4, 1.3.3, 1.3.2, 1.3.1, 1.3.0. すべての変更については1.4.2のリリースノートおよび1.3.7のリリースノートをごらんください。 以下では、重要な変更について紹介します。\nbug fixes Elasticsearchに対して広範囲にわたってランダムなテストを行っています。以下の問題を見つけ、修正するのに役立っています。\nプライマリシャードを持つnodeがレプリカシャードをプライマリから復旧している間に、リスタートした場合に、プライマリ上のトランザクションログが削除されデータをロスする(#8917) scriptインデックスが普及した場合に、ScriptService全体がデッドロック(#8901) Index Writerのロックを強制的に解放することによるシャードの破損(#8892) パフォーマンス改善 複雑な設定をもつ大きめのクラスタをもつユーザは、小さなスケールではわからない性能ボトルネックに直面します。 彼らの報告が次の改善をもたらす助けとなりました。\n使用可能なディスク空間に基づいてシャードの配置を決定する、disk allocation deciderの速度改善とクラスタリスタート後のリカバリ速度の改善(#8803) 以前よりも高速な共有ファイルシステムでのSnapshot生成(#8749) 不要なクラスタ状態変更の削減とそれによるネットワークトラフィックの削減およびリカバリの速度向上(#8933, #8413) index stats APIはシャードリカバリによるブロックしない(#8910) 試してみてください。 ぜひ、Elasticsearch 1.4.2をダウンロードして、試してみてください。 そして、感想をTwitter(@elasticsearch)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1418880374,"dir":"post/2014/","id":"bce2fa6458f39a75e2713f3d687271a1","lang":"ja","lastmod":1418880374,"permalink":"https://blog.johtani.info/blog/2014/12/18/elasticsearch-1-4-2-released-ja/","publishdate":"2014-12-18T14:26:14+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:elasticsearch 1.4.3 and 1.3.8 released 本日、Lucene 4.10.3をベースにしたElas","tags":["elasticsearch"],"title":"Elasticsearch 1.4.2および1.3.7リリース(日本語訳)"},{"contents":"「【東京】JJUG ナイト・セミナー「機械学習・自然言語処理特集!」12/17(水)開催」でLuceneの話をしてきました。 本当にごく簡単な入門です。 Luceneをさわるきっかけにしてもらえたら嬉しいです。\nそのほかにも面白い話が聞けましたので、簡単ですがメモを。\nJJUGの2014年振り返り だいたい、毎月ナイトセミナーかCCCを開催 イベント系に、のべ3100名が参加 Java でカジュアルにはじめる機械学習 小宮 篤史さん(スマートニュース株式会社) スライド:#JJUG - Java でカジュアルにはじめる機械学習\nブログ:#JJUG ナイトセミナー「機械学習・自然言語処理特集!」で Java でカジュアルに機械学習する話をしてきました\nガチの人は寝ててください。 機械学習でできること 分類・識別 予測・回帰 パターンマイニング・アソシエーションルール クラスタリング 上2つは教師あり学習/下2つは教師なし学習 データとしては、日構造では扱えないので、「特徴量」を抽出して「特徴ベクトル」を作って、処理をするのが機械学習 得られた結果の正しさの測定などなど\n機械学習の実装は辛いので、車輪の再発明をやめましょう! \u0008Javaで使える機械学習\nWeka:とりあえず使ってみるならこれ? MLlib:Sparkで使われてる Mahout:オワコン? SAMOA:Stormの上で利用できる Jubatus:Javaクライアントあり。 h2o:Deep learningをJavaでやるなら、これ。 ほかにもあったけど、スライド見ていただければ。 機械学習をはじめるのに使えるデータセット\nUCI Machine learning repository\nIris(アヤメデータ)は機械学習界のHello world Wekaを使ったサンプルコード\nSpark/MLlibではじめるスケーラブルな機械学習 猿田 浩輔さん(株式会社エヌ・ティ・ティ・データ) スライド:(後日、リンクがあれば更新予定)\n\u0008* Spark+MLlibを語る上で外せない話題\nHadoopとの違い?\nまずはHadoopの話\nHadoopによるK-meansのデモ\nHadoopの問題点に対するSparkの解決策\nSpark 1.0系からJava8で書ける\nQA:\nQ: データをキャッシュできるという話でしたが、キャッシュするということは、ジョブが途中で失敗した場合は最初からやり直しになるのでしょうか? A: キャッシュしたデータが残っている場合は、途中から再開出来ます。キャッシュしたデータを持ったマシンがこけたら、最初からやり直しです。\nLuceneと日本語の検索 自分 スライド:Luceneと日本語の検索 サンプルのリポジトリ:jjug-example\n自然言語処理にからめて何か話をしてくださいと話を受けていたのですが、自然言語処理については「形態素解析」くらいしか出てこなかったですけど。。。 Luceneがどんなものかを超概要で話をしてみました。少しでもLuceneがどんなものかをわかってもらえたら嬉しいです。\nもっと詳しく知りたい方は、スライドにある参考資料などを見ていただければと。\nJavaで書くのもいいんですが、もっと簡単に検索したい場合はElasticsearchを使うのが便利ですよ!で締めくくりたかったのですが、発表では失敗してしまいました。。。 Elasticsearchの起動からデータ登録、検索まではこちらのスライドを見ていただければ簡単さがわかると思います。\nまた、Kuromojiを利用した時に、Tokenizerなどが出力するTokenの品詞情報を見たい場合に便利なElasticsearch用プラグインも作っています。 こちらも、Elasticsearchと一緒に使ってみてください。\nまとめ 機械学習に関していろんなツールがあるのだなぁと。 懇親会でもちょっと話しましたが、アルゴリズムの選定とか、アルゴリズムに適したデータの作成など、前処理のノウハウとかが大変そうだなぁといつも思います。 機械学習はいつもぼやーっとしか理解してないので。。。\nJJUGさんはYouTubeの動画もあるようなので、過去の面白そうなセミナーも合わせてみてみると面白いと思います。\n毎度のことですが、なんでも良いので、発表した後のフィードバックをいただけるとうれしいです。 今後の励みや改善につながるので。\n","date":1418809314,"dir":"post/2014/","id":"e5390751969ab21df280b7591854b89f","lang":"ja","lastmod":1418809314,"permalink":"https://blog.johtani.info/blog/2014/12/17/jjug-night-seminar-dec-2014/","publishdate":"2014-12-17T18:41:54+09:00","summary":"「【東京】JJUG ナイト・セミナー「機械学習・自然言語処理特集!」12/17(水)開催」でLuceneの話をしてきました。 本当にごく簡単な入","tags":["elasticsearch","jjug"],"title":"JJUG ナイトセミナーでLuceneの簡単な紹介をしてきました。#JJUG"},{"contents":"たまには、他愛のないブログを。\n仕事しながら、コーヒーを飲んでます。\n最近は、サムライズムさんのオフィスに入り浸って仕事してます。 オフィスには、コーヒーミル付きのコーヒーメーカーがあるんです。\n↓こんな感じ(現物は違うけど)\nで、近所のコーヒー問屋で豆を買ってきてます。 そこのマスターに、いつもサジェストされるんです。\n「この豆は、日が経つにつれて、細かく挽いて飲んでください。」\n「この豆は、細かめに挽いて飲むのがオススメです。」\nなどなど。 オススメされるんですが、全自動のコーヒーメーカーは残念ながらここまでやってくれません。\nということで、手動のミルを買ってみました。家でも使えるし。\nちょっと考え事しながらとか、頭の切り替えに、ミルを回すのもいいかなと。 気持ち、美味しいコーヒーな気がします(気のせいかも)\n","date":1418698892,"dir":"post/2014/","id":"05330c3703d0e2c96cfe657ab33f130c","lang":"ja","lastmod":1418698892,"permalink":"https://blog.johtani.info/blog/2014/12/16/a-coffee-break/","publishdate":"2014-12-16T12:01:32+09:00","summary":"たまには、他愛のないブログを。 仕事しながら、コーヒーを飲んでます。 最近は、サムライズムさんのオフィスに入り浸って仕事してます。 オフィスには、","tags":["misc","coffee"],"title":"コーヒーブレイク"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:exciting logstash plugin ecosystem changes\nLogstash 1.5.0 Beta 1(お試しはこちら)のリリースで、 プラグインのインストール、管理、公開の方法を変更しています。 ユーザやコミュニティからフィードバックをもらいました。 その目的は、プラグインの利用や開発をより簡単にすることです。 このプロジェクトは始まったばかりです。プラグインのコミュニティを探し、 共有するためのワンストップソリューションを提供するこのアイデアを改善していく予定です。 このブログで、この決定を行った理由を説明し、新しいワークフローをと今後のロードマップを説明します。\nプラグインがあります! Logstashは、プラグイン(input、filter、output、codec)が豊富にあります。 これらは、Elasticsearchにより開発されたものと、コミュニティからコントリビュートされたものです。 Logstashの主な特長の1つは、これらのプラグインの有効性と動作を拡張するプラグインを追加するのが簡単なことです。 現在、165以上のプラグインがエコシステムにあり、これらは、2つのプロジェクトに分かれています。\nlogstash-coreは最もよく使われるプラグインで、Logstashにデフォルトで含まれます logstash-contribはコミュニティにより開発されたプラグインを含み、別途ダウンロードできます 新プラグインエコシステムの変更 1.5.0では、全てのプラグインは、Logstashコアから分離され、rubygemsを使って個別にパッケージングされます。 rubygemsを選択したのは、依存関係のあるライブラリの配布とパッケージングがパワフルで一般的なものだからです。 さらに、rubygems.orgプラットフォームは配布や探索に影響があります。 また、Logstashにプラグインをインストール、アップデート、削除するのが簡単な基盤も追加しました。 contribプロジェクトは徐々に終了します。全てのプラグインは個別のプロジェクトになります。\nプラグインエコシステム変更の理由 多数のプラグインをもっていると、配布と公開に関して難題が出てきます。 私たちが変更するに至った理由は次のようなものです。\n現在は、プラグインの更新に伴い、Logstashの新バージョンのリリースが必要 開発者は、Logstashのリリース間隔とは別に、新バージョンをリリースをしたい プラグイン開発者は、外部依存を記述できるようにしたい Logstashコアの配布パッケージのダウンロードサイズを小さくし、ユーザは必要なプラグインのみインストール logstash-contribを1つのリポジトリとして管理するのは難しい 詳細: ソースコードの場所 Logstashのソースコードは、今後も現在のGitHubのリポジトリのままです。 しかし、プラグインに関するコードやテストコードは含まなくなります。 この分離により、個別のプラグインの改善と同様にコアの改善に集中できます。 これにより、Logstashプロジェクトの全体の品質も向上します。\n全プラグインのソースコードは、新しいGitHub organization、logstash-pluginsにて管理します。 各プラグインは個別のリポジトリとして、ここに配置されます。 一見すると、これはメンテナンスが難しくなるように思えます。しかし、テスト、Issue、依存関係を明確にすることができます。 私たちの目的は、テスト、ドキュメント、gemの公開の自動化であり、これを簡単にするためのツールを追加します。\nしかし、プラグインの開発者はプラグインのソースコードソースコードをlogstash-pluginsに置く必要はありません。 ー コミュニティで利用可能にするために、rubygems.orgでそれを公開するだけで良いです。\nワークフロー ここで、新プラグインエコシステムのやりとり/ワークフローについて、いくつかの観点から説明します。\nlogstashユーザ: ユーザは、これまでのリリース同様にLogstashのバイナリをダウンロードします。 Logstash 1.5.0は、1.4.2でパッケージされていたプラグインと同等のものが含まれています。 新しいシステムに簡単に移行できるようにです。 そして、ユーザは、最初のデプロイの後に、Logstashプラグインのをインストール、アップグレードできるようになります。\n$LS_HOME/bin/pluginスクリプトがプラグイン操作に関連するコマンドになります。\nプラグインのインストール プラグインのほとんどはgemとしてrubygems.orgにアップロードされます。 例えば、もしユーザがApache Kafka outputプラグインをインストールする場合、次のコマンドを実行します。\nbin/plugin install logstash-output-kafka または、ファイルをダウンロード済みの場合は次のコマンドとなります。\nbin/plugin install /path/to/logstash-output-kafka-1.0.0.gem プラグインの削除 bin/plugin uninstall logstash-output-kafka 1つまた全プラグインのアップデート bin/plugin update bin/plugin update logstash-output-kafka プラグインのリストアップ bin/plugin list bin/plugin list elasticsearch ( List all plugins containing a name ) bin/plugin list --group output ( list all outputs ) ドキュメント プラグインが個別に管理されても、全プラグインのドキュメントは1カ所です。\nlogstash plugin開発者: プラグイン開発者と作者は、Logstashエコシステムのためにプラグインを公開することができます。 プラグインは、gemやJavaライブラリの依存関係を宣言できます。 より重要なのは、Logstashのリリース間隔に関係なく、プラグインの改善版をリリースできます。\nRubygemsテクノロジはパッケージングシステム、依存関係管理、ホスティングのために選択されてきました。 Rubyのgemを公開することに慣れている開発者は、Logstashプラグインを簡単に公開することができます。 Elasticsearchはこれらの機能に関して開発者を支援するために、ツールを提供、メンテナンスします。\n開発およびローカルでのテスト JRuby 1.7.16がプラグインを開発するための唯一の前提条件です。 プラグインにパッチを提供するのは以前と同様です。 例えば、logstash-output-kafkaにパッチを送るのは次のようになります。\ngit clone https://github.com/logstash-plugins/logstash-output-kafka.git 変更 プラグインをローカルでテスト bundle install bundle exec rspec Logstashの他のバージョンもしくはローカルでテストする場合、Gemfileを編集し、 次のように別のロケーションを加えます。gem \u0026quot;logstash\u0026quot;, :github =\u0026gt; \u0026quot;elasticsearch/logstash\u0026quot;, :ref =\u0026gt; \u0026quot;master\u0026quot; 新しいPull Requestをlogstash-output-kafkaに対して作成 コミュニティでコードレビューを受け、Elasticsearchがパッチを受け入れ バージョン バージョン情報は、それぞれのプラグインの.gemspecで管理します。 例えば、Apache Kafka outputのgemspecはこちらです。 バージョニングはsemantic versioningのルールに従い、 Logstashのバージョニングとは別に、プラグインの開発者によって管理されます。 Logstash 1.5.0がリリースされると、マイルストーン1のプラグインはバージョン1.0.0となり、マイルストーン2のプラグインはバージョン2.0.0となるでしょう。\n公開 開発者が変更を加えプラグインを公開したいと思った時、.gemspecのバージョン番号を変更します。 全テストが成功した時、Elasticsearchはrubygems.orgにプラグインを手動で公開します。 もし、テストが失敗した場合、プラグインは公開されません。 長期的には、プラグインの公開の自動化を行いたいと思っています。 この変更は新しいため、公開の自動化を提供する前に、自動化についてより理解し、プラグインのテスト基盤を改良したいと思っています。\nIssue Issueは、各プラグインのGitHubリポジトリに対してオープンなければなりません。 Logstashコアのリポジトリは、コアのパイプラインや共通的な機能に関連するIssueについて扱います。\nドキュメント プラグインのドキュメントはソースコード自体から生成されます。 それぞれのプラグインのドキュメントは、そのプラグインのリポジトリに含まれます。 Elasticsearchは elasticsearch.org/guideに全てのプラグインのドキュメントを集め生成できる基盤を提供します。\n移行 全ての新しいpull requestとissueはlogstash-plugin organisation配下にある各プラグインのリポジトリに対してオープンする必要があります。\nすでにあるPRはどうすれば良いですか? 気にしないでください。すでにあるpull requestは開発者によって移行する必要はありません。 LogstashチームがLogstashコアリポジトリに対してのPRを、個別の関連するプラグインのリポジトリに対してマージします。\ngit clone … # clone the specific plugin repo # now apply the patch curl -s https://github.com/elasticsearch/logstash/pull/XXXX | git am --3way git push Note:このプロセスはすでにあるPRに対してgit historyを管理します\nGitHub Issue 現在、LogstashリポジトリにオープンされているIssueは、それぞれのプラグインのリポジトリに移行します。 Logstashチームがgithub.com APIを利用してこの処理を自動的に行います。 安心してください。私たちが個別のプラグインに対する既存のIssueを移行します。\n今後のロードマップ これは、最初のステップであり、これらの変更は、ユーザや開発者に対してエコシステムをよりよくするために、 しっかりとした基盤を提供します。\n短期的には、開発者のためにpull requestのフィードバックでテスト自動化を提供する基盤を追加していきます。 プラグインリポジトリのブートストラップや管理のためのツールも提供していきます。\n長期的には、すべてのLogstashプラグインを探し、公開するためのコミュニティポータルを提供したいと思っています。 このアイデアは、Puppet ForgeやAWS marketplaceのようなものです。\nLogstash 1.5.0 Beta 1をリリースし、これは新しいエコシステムを提供します。 ぜひ、試していただき、これらの変更に関して感じたことを教えてください。 あなたのフィードバック(TwitterもしくはGitHub)はとても貴重です!\n","date":1418486440,"dir":"post/2014/","id":"4a3c42c9c5ac29db268010bbebf4f579","lang":"ja","lastmod":1418486440,"permalink":"https://blog.johtani.info/blog/2014/12/14/plugin-ecosystem-changes/","publishdate":"2014-12-14T01:00:40+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:exciting logstash plugin ecosystem changes Logstash 1.5.0 Beta 1(お試しはこちら)のリリースで、 プラグインのインストー","tags":["logstash"],"title":"Logstashプラグインのエコシステムの変更(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:logstash 1.5.0.beta1 released\nLogstash 1.5.0 Beta1をリリースしました。こちらのページからダウンロードできます。\nNote: ベータリリースです。本番環境では使用しないでください。\n1.5.0の主な変更点は? 1.5.0の主なテーマはプラグイン管理、パフォーマンス改善、Apache Kafkaインテグレーションです。Logstashの主な特徴の1つは プラグインを利用できることであり、パイプラインの動作を拡張するためにプラグインを追加するのが簡単なことです。 このリリースで、プラグインの開発、管理、公開がより簡単になります。 また、Logstashの速度をより良くしたため、より多くのデータを短時間に処理することができます。 興味ありませんか?では、詳細を見ていきましょう。\nplugin ecosystemの変更 Logstashは165ものプラグイン(inputs、filters、outputs、codecs)を持っており、 これらはElasticsearchとコミュニティからのコントリビュートで開発されています。 多くのプラグインを管理することは、使いやすさと素早さの間のトレードオフがあります。 Logstashの全てのプラグインをまとめることは使いやすさがある一方、プラグインの更新を取り込むために Logstashの新しいリリースを待ってもらうことになります。 Logstashからプラグインを分離して個別に配布する場合、更新は簡単になりますが、使いやすさ(特に新しいユーザに)に影響が出ます。\n私たちは、プロジェクトを前進させるために、これらのバランスをとることを考えました。 これまで、全ての利用可能なプラグインは’core’と\u0026rsquo;contrib\u0026rsquo;の2つに分割していました。 \u0026lsquo;core\u0026rsquo;にあるよく使われるプラグインは、Logstashに含めていました。 コミュニティによりコントリビュートされたプラグインは\u0026rsquo;contrib\u0026rsquo;パッケージとして分離して配布していました。 1.5.0のリリースで、ユーザに対してより良いプラグイン管理をできるように変更しました。 全てのプラグインは、それ自身によるパッケージに移行しました。 パッケージングフレームワークとしてrubygemsを使い、rubygem.org経由でこれらのプラグインを配布、公開します。 また、Logstashにプラグインのインストール、更新、削除を簡単にするための構造も追加しました。\n例えば、S3 output pluginをインストールするには、以下のコマンドを実行します。\n$LS_HOME/bin/plugin install logstash-output-s3 それだけです!Logstashがgemと依存するgemをrubygems.orgからダウンロードし、インストールします。 あなたは、S3にデータを送ることができるようになります。\nダウンロード可能なLogstashリリースはプラグインをまだ多く含んでいますが、 いつでも、個別にプラグインをアップグレードし、インストールすることができます。 プラグインエコシステムの変更に関する詳細のブログ記事をお待ち下さい。\nパフォーマンス改善 Logstash 1.5.0はより高速になっています。パフォーマンスが改善された2カ所について説明します。\ngrok filter Grok filterはLogstashで、構造化データを抽出するためにパターンを記述するのに使われます。 本リリースで、人気のある幾つかのパターンのgrok filterのスループットを100%に改善しました。 言い換えると、grok filterを使うときに、Logstashを通してより多くのデータを処理することができます。\n私たちのベンチマークテストで、1.5.0と1.4.2のスループットの比較をしました。 利用したデータは690万件のApache Webアクセスlogで、COMBINEDAPACHELOGのgrok patternです。 1.5.0で、スループットは34,000 event per sec(eps)から50,000 epsに増加しました。 両方のテストを8コアのマシンでLogstashで8つのワーカーを実行しました。 これらのテストで、一つのgrok filterを実行し、 stdinとstdoutを使ったパイプラインでイベントのスループットを計測しました。 全体的なパフォーマンスは、様々なハードウェアやLogstashのコンフィグによって変化することに注意してください。\njson serialization / deserialization JSONのシリアライズ/でシリアライズをJrJacksonライブラリを利用して実装しました。 これにより、100%以上のスループットの改善がありました。 先ほど説明したパフォーマンステストにおいて、1.3KBのサイズの500,00 JSONイベントを送信し、 16,000 epsから30,000 epsにスループットが改善しました。 45,000サイズのイベントで、850 epsから3500 epsにスループットが増加しました。 すばらしいです。\napache kafka integration いまでは、Apache Kafkaが大規模スケールデータ処理システムでよく利用されます。 Logstashの配備のスケーリングにおいて、Kafkaもまた、shippingインスタンスとindexingインスタンス間の データを保存するための中間メッセージバッファとして使うことができます。\n1.5.0で、Logstash Kafkaのinputとoutputのプラグインのビルトインサポートを追加しました。 これは、Joseph Lawsonによって最初に開発されました。 私たちは、これらのプラグインにインテグレーションテストとドキュメントを追加することにより改良し、 新しいKafkaの機能を開発し続けます。 また、Apache Avro codecを追加することで、Kafkaに保存されたイベントを 簡単に取得でき、ELKスタックを使ってそれらを解析できるようにしました。\nKafka inputを追加するのは次のコマンドです。\n$LS_HOME/bin/plugin install logstash-input-kafka Kafka outputは次のコマンドです。\n$LS_HOME/bin/plugin install logstash-output-kafka セキュリティに関する改善 認証と経路暗号化のサポートを追加し、Elasticsearchのoutput、input、filterのセキュリティを改良しました。 例えば、HTTPプロトコルでSSL/TLSにより暗号化を有効にでき、 HTTPベーシック認証をユーザ名とパスワードをリクエストに与えることで設定できます。 これらの機能は、時期にリリースされるElasticsearch ShieldセキュリティプロダクトとLogstashを統合できます。\nドキュメント これまで、Logstashのドキュメントは[logstash.net])(http://logstash.net/)に置いてあり、 他のELKスタックと一緒に動かす時に、情報を探すのが厄介でした。 1.5.0および、今後のバージョンのドキュメントはelasticsearch.orgのLogstash Guideに移行します。 この移行でelasticsearch.org/guideにELKスタックを利用、 学習するためにドキュメントが1つになりました。 このベータリリースのイテレーションで、私たちはプレゼンテーションとドキュメントの品質を改善することに活発に取り組んでいきます。 (過去のLogstashのドキュメントの全てはいままでのlogstash.netで引き続き公開していく予定です。)\nバグフィックスと改善 ここまでの新しい機能に加えて、Logstash 1.5.0では、多くのバグフィックスと多くの機能改善があります。 ここで、これらのいくつかを紹介します。\n出力しない\u0026rsquo;metadata\u0026rsquo;をイベントに格納可能に。これは、例えば、date filterに使う中間フィールドのために必要。(#1834, #LOGSTASH-1798) HTTPを利用しているときのファイルデスクリプタリークの修正。Logstashがストールするのを防ぎ、OOMエラーからクラッシュするケースも防ぎます。(#1604) Twitter input:full_tweetオプションの追加、Twitter rate limitingエラーのハンドリング(#1471) イベントを生成するfilter(multiline、clone、split、metrics)により、 後続の条件文にこれらのイベントを正しく伝搬(#1431) Elasticsearch output:Logstashはデフォルトでmessage.rawフィールドを作成しない。messageフィールドはElasticsearch によりnot_analyzedでマルチフィールドとして追加される。マルチフィールドはディスクスペースが2倍必要だが、利点がない。 bin/logstashの複数のサブコマンドを除去(#1797) これらの機能、改善、バグフィックスについては、Logstash 1.5.0.Beta1 のchangelogをごらんください。\n試してみてください! ぜひ、Logstash 1.5.0 Beta 1をダウンロードして試してみてください。 そして、感想をTwitter(@elasticsearch)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1418372246,"dir":"post/2014/","id":"1bc36080b2493aab78c26e4f2152542c","lang":"ja","lastmod":1418372246,"permalink":"https://blog.johtani.info/blog/2014/12/12/logstash-1-5-0-beta1-released-ja/","publishdate":"2014-12-12T17:17:26+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:logstash 1.5.0.beta1 released Logstash 1.5.0 Beta1をリリースしました。こちらのページからダウンロードで","tags":["logstash"],"title":"Logstash 1.5.0 Beta1リリース(日本語訳)"},{"contents":"早いもので、師走です。今年もあと少しとなりました。ということで、Advent Calendarの季節が始まりました。\nこの記事はElasticsearch Advent Calndar 2014の1日目のエントリです。\n1日目ということで、簡単に今年の変遷を振り返りつつ、今年導入された新機能についてピックアップしてみようかと思います。\n1.0リリース(Lucene 4.6.0) 今年一番の目玉と思いますが、1月にRCが公開されて、1.0.0が2月にリリースされました。 (ElasticSearch Serverの翻訳が昨年末に終わってレビューをしていた段階での発表だったので個人的にはきついタイミングでした) 1.0の主な変更点はこちら。\nElasticsearch(Sが小文字に) 1.0からSが小文字になりました。(#4634) 0.90以前のバージョンについては、Sが大文字になっています。 ややこしいですが、今年の3月に出版された黒いElasticSearch Server日本語版は原著が0.20で日本語版にするタイミングで0.90に対応しました。 このため、こちらの書籍のタイトルはSが大文字となっています。 (なお、原著の2nd Editionは小文字になっています)\nSnapshot/Restoreの導入とGatewayの廃止 0.90以前のバージョンでは、gatewayというモジュールで、S3などにインデックスのメタデータなどを保存する機能がありました。 この機能は、0.20からlocal以外はdeprecatedとなりました。\nインデックスのバックアップ、リストアのために、1.0で実装されたのがSnapshot/Restoreです。 Snapshot/Restoreでは、インデックスごと、もしくはクラスタ全体をリモートにあるリポジトリにスナップショットを取ることが可能となりました。 初期リリースの段階では、共有ファイルシステムのみでしたが、現在は、S3やHDFSなどに保存が可能となっています。\nAggregation Facetをより強力にしたものです。Facetでは、指定したフィールドの集計のみでした。 データの解析などを行うには、独自で集計する必要がありました。 この機能をより柔軟に行えるように実装したのがAggregationです。\nたとえば、アクセスログを日毎に集計し、さらに日毎の集計に対して国別の集計やユーザエージェントごとの集計をさらに行うといった感じです。 Facetの場合は、日毎の検索結果に対して個別に集計するのみでしたが、Aggregationを使うことで、1週間の検索結果に対して、 日毎に国別の集計を行うといったことが可能になっっています。\ncat API \u0026ldquo;=^.^=\u0026ldquo;猫が出てくるAPIです。(違う)\nElasticsearchでは、クラスタの状態などが全てREST APIで取得でき、JSONで結果が帰ってきていました。 JSONはプログラムなどで処理を行う場合は便利ですが、コンソールで確認したり、管理系のツールでメールで通知する場合などは見にくいことがあります。 これを解消したのが_cat APIです。(公式の紹介ブログはこちら)\nCircuit Breaker OOMが発生しそうなfielddataの読み込みを検知して、事前に防ぐ機構になります。 初期段階ではFielddataに対してのものから実装されました。\n1.1リリース(Lucene 4.6.1) 3月にリリースされました。Elasticsearchはまだまだ発展しているため、リリースのサイクルが短いのが特徴です。\n1.x系では、Rolling Upgradeが導入されました。このため、クラスタ全体を停止することなく、クラスタのアップグレードが可能になりました。\nsearch templates 検索クエリをテンプレートとして登録することができるsearch templatesです。 JSONでクエリを記述できるのは便利ですが、毎回組み立てるのは大変かもしれません。 特に、固定のクエリをプログラムから利用するような場合などです。 テンプレートとして登録しておくことで、検索時に値を埋め込むだけで検索ができるようになりました。\nAggregationの強化 Aggregationの種類が増えました。\ncardinality:ユニークユーザ数の集計などが行えるaggregationです。HyperLogLog++アルゴリズムを利用した実装になっています。 significant_terms:単語の数による集計ではなく、コレクション全体に対する単語の頻度と、検索結果に対する単語の頻度を計算することで、重要度を計ることができます。 percentiles:パーセンタイル値を計算できます。 1.2リリース(Lucene 4.8系) Java 7必須 利用しているLuceneがJava 7必須となったためです。また、Java 6のEOLも切れてますし。\ndynamic scriptingがデフォルトオフ 採用していたMVELがサンドボックス化に対応していないため、危険を回避するためにオフとなりました。\nインデキシングとマージング インデキシングとマージ処理に関するさまざまな改善。\nflushのthreasholdを操作回数ではなく、サイズや時間によるものに変更 デフォルトをConcurrentMergeSchedulerに変更 1.3リリース(Lucene 4.9.0系) セキュリティ関連 JSONPのデフォルトオフ MVELの非推奨化(1.4で削除)+script.disable_dynamicのデフォルト値がsandbox aggregationの強化 top hits:Field Collapsing/combiningと呼ばれる機能です。たとえば、いくつかのサイトのHTMLを収集して検索機能を提供する場合に、ドメインごとに1件ずつ検索結果に出したい場合などに利用できる機能です。 その他にも以下のaggregationが追加されています。\npercentile ranks geo bounds mappingのtransform Mappingにtransform機能が追加されました。 mappingにドキュメントの値を元に、インデキシング時に変換処理を記述できます。 たとえば、特定のフィールドにある値がある場合にだけ、あるフィールドに値を入れるなどといったことが可能になります。\nディスク関連 disk based shard allocation deciderが導入されました。ノードのディスクの使用率を元に、シャードを配置しても良いかといった決定を行う機構です。 チェックサムによるファイルのチェック(Lucene4.9で導入されたコードへの切り替え) 1.4リリース(Lucene 4.10系) ベータ版が出されるほど、多くの改善が入っています。\nresiliency メモリ使用量の低下によるノードの安定性向上 DocValues、リクエストごとのcircuit breakerなど discoveryアルゴリズムの改善によるクラスタの安定性向上 チェックサムの導入による破損したデータの検知 セキュリティ関連 CORSをデフォルト無効 Groovyがデフォルトのスクリプト言語に。 Aggregationの強化 以下のaggregationが追加されています。\nfilter、children、scripted_metric Upgrade API インデックスを最新のバージョンのものにアップグレードするためのAPIです。 Luceneは下位互換を保ってくれているため、古いバージョンのインデックスも読み込むことが可能です。 ただ、最新バージョンで使える機能が制限されていたりということもあります。 クラスタにあるインデックスをアップグレードするのにかかる時間や必要かどうかといったことを取得できる仕組みも提供します。\nまた、Lucene自体は、1つ前のメジャーバージョン(4.x系だと3.x系まで)までの互換性は提供していますが、 2つ前のメジャーバージョンの互換性がなくなります。 Luceneも5.x系のブランチが作成されており、5系のリリースにより、3系との互換性がなくなります。 5系のリリースに対応する場合にも、こちらのAPIが助けになるかと。\n1.4.1 11\u0008/27に1.4.1がリリースされました。 シャードの配置やparent/child、nestedドキュメントの改善などが行われています。\nまとめ ということで、駆け足で、1月から11月までのElasticsearchの流れを追ってみました。 1.0で大きな機能追加、改善が行われ、その後も活発に開発が行われています。 要望などがあれば、MLで聞いてみたりやGitHubに登録するなどを行っていただければと。\nあと、今年から来年にかけての大きなイベントとして、 Elasticsearch初のユーザカンファレンスのサイトがオープンしました。 Elasticsearchに関するいろいろな話が聞ける機会だと思うので、興味のある方は見ていただければと。\nでは、また次のAdvent Calendarで!(最終日の予定ですが、空きがあるのでなにか書くかも)\n","date":1417424748,"dir":"post/2014/","id":"2de582c67fca31500621ecd6d3917a07","lang":"ja","lastmod":1417424748,"permalink":"https://blog.johtani.info/blog/2014/12/01/about-elasticsearch-in-2014/","publishdate":"2014-12-01T18:05:48+09:00","summary":"早いもので、師走です。今年もあと少しとなりました。ということで、Advent Calendarの季節が始まりました。 この記事はElastics","tags":["elasticsearch"],"title":"2014年のElasticsearch"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:elasticsearch 1.4.1 and 1.3.6 released\n本日、Lucene 4.10.2をベースにしたElasticsearch 1.4.1と、バグフィックスリリースである、Elasticsearch 1.3.6をリリースしました。 ダウンロードおよび変更リストはそれぞれ次のリンクからアクセスできます。\n最新ステーブルリリース:Elasticsearch 1.4.1 1.3.x系バグフィックス:Elasticsearch 1.3.6 過去のリリースに関するブログ(公式)はこちら。\n1.4:1.4.0, 1.4.0.Beta1 1.3:1.3.5, 1.3.4, 1.3.3, 1.3.2, 1.3.1, 1.3.0. すべての変更については1.4.1のリリースノートおよび1.3.6のリリースノートをごらんください。 以下では、重要な変更について紹介します。\nshard allocation Elasticsearch 1.3.0で、disk based shard allocationが デフォルトで有効になっています。 もし、ノードのディスクの使用量がlawで指定された値(85%)を超えた場合、ノードにはシャードが配置されません。 また、highで指定された値(90%)を超えた場合、シャードを他のノードへ移動します。\nElasticsearch 1.4.1では、disk based shard allocationに3つの改良が追加されました。\nディスク使用量のチェックはシャードがクラスタに配置されるタイミングでのみ実施していた。現在は60秒ごとに使用量をチェック。(#8270) ディスクフルメッセージはDEBUGレベルでログに出力されていました。なぜ、新しいシャードが配置されないのかを説明するのが困難でした。現在はWARNレベルで30秒ごとにログに出力されます。(#8382) 以前は、シャードをもう一つのノードへ動かすべきかどうか決めるとき、allocation deciderはノードにあるシャードのサイズを考慮するだけでした。現在は、動かされるシャードのサイズも考慮します。これにより、必要最小限のシャードの移動量となります。(#8569) parent/child and nested documents Elasticsearch 1.4.0で、parent/childとnestedドキュメントに対して(新しいセグメントを開くときに)固定長ビットセットフィルタを構築しキャッシュしました。クエリ、フィルタおよびAggregationを常に速くするためにです。 多くのnestedフィールドを持つユーザにとっては、以前のバージョンよりもヒープの使用量が大きくなってしまいました。\nnested aggregationによって処理されるドキュメントの順序を変更すること(#8454)によって、固定長ビットセットフィルタが子のドキュメントに対して必要でなくなりました。 現在は、親のドキュメント(つまり、nestedではないドキュメント)を表すフィルタのみをキャッシュしています。これにより必要なキャッシュ空間のサイズを減少しました。(#8414、#8440)\ndate ranges 2つの日付範囲に関する問題がこのリリースで修正されました。 1つ目は、日付を丸めるかというものです。例えば、timestampフィールドに1秒の解像度の値があるとします。 {\u0026quot;lt\u0026quot;: \u0026quot;2014/11/26||/d\u0026quot;}というrangeフィルタは2014/11/26 00:00:00未満のタイムスタンプのデータを結果として返しました。 しかし、ltをlteに変更した場合、2014/11/27 00:00:00以外の値も含めたいです。\n以前は、lteは2014/11/27 00:00:00のタイムスタンプも含めてしまっていました。現在は、想定通りの動作をします。(#8556)\n2つ目のバグは日付の範囲条件にnow()を利用したaliasとpercolatorフィルタです。 now()の値を、フィルタが作成したタイミングで決定していました。フィルタが実行されるたびに更新せずにです。 #8534で、now()はaliasとpercolatorで想定通りの動作をします。\n試してみてください。 ぜひ、Elasticsearch 1.4.1をダウンロードして、試してみてください。 そして、感想をTwitter(@elasticsearch)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1417056212,"dir":"post/2014/","id":"0a8183ced0e9e3e895b41286e54e8e4d","lang":"ja","lastmod":1417056212,"permalink":"https://blog.johtani.info/blog/2014/11/27/elasticsearch-1-4-1-released-ja/","publishdate":"2014-11-27T11:43:32+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:elasticsearch 1.4.1 and 1.3.6 released 本日、Lucene 4.10.2をベースにしたElas","tags":["elasticsearch"],"title":"Elasticsearch 1.4.1および1.3.6リリース(日本語訳)"},{"contents":"前回の「Logstashを利用したApacheアクセスログのインポート」の続きです。 前回の記事では、Logstashの設定ファイルについて説明しました。 今回は「Elasticsearchに設定するインデックステンプレート」について説明します。\nテンプレートの設定 Elasticsearchでは、登録するデータの特性に合わせてMappingを定義する方がデータを効率良く扱うことができる場合があります。 この場合、通常ですと、インデックス作成時にMappingを指定します。\nただ、今回は、インデックス名に「年」を含める形で指定してあります。 「年」はLogstashで処理したデータによって決まります。このため、あらかじめMappingを指定してインデックスを作成するのは難しいです。\nこのような場合に便利な機能として、「インデックステンプレート」があります。\nインデックステンプレートとは 実際のテンプレートの説明に入る前に、少しだけ説明を。 インデックステンプレートとは、インデックスが作成されるタイミングで自動的に適用される設定をテンプレートとして登録できる機能のことです。 実際にテンプレートが適用されるかどうかは、インデックス名で判断されます。\n例えば、大して重要でもなく、データ量も少ないインデックス用のテンプレートとして、シャード数が1、レプリカ数が0、\u0026quot;_source\u0026quot;を保存しない設定のテンプレートを登録する場合、 次のようになります。\ncurl -XPUT localhost:9200/_template/template_1 -d \u0026#39; { \u0026#34;template\u0026#34; : \u0026#34;te*\u0026#34;, \u0026#34;settings\u0026#34; : { \u0026#34;number_of_shards\u0026#34; : 1, \u0026#34;number_of_replicas\u0026#34; : 0 }, \u0026#34;mappings\u0026#34; : { \u0026#34;type1\u0026#34; : { \u0026#34;_source\u0026#34; : { \u0026#34;enabled\u0026#34; : false } } } } \u0026#39; _templateがインデックステンプレートを登録するためのエンドポイントです。 template_1がこのテンプレートのIDです。削除などについては、このIDを利用します。\nそして、重要なのは、\u0026quot;template\u0026ldquo;の設定です。 \u0026ldquo;template\u0026ldquo;には、このテンプレートが適用されるべきインデックス名を記載します。 上記サンプルではte*となっているため、teで始まる名前のインデックスを作成した場合にテンプレートにある設定が適用されます。\n今回利用するテンプレート 私がJJUG CCCや第7回Elasticsearch勉強会のKibana4のデモで利用したインデックスのテンプレートは次のものになります。 \u0026ldquo;template\u0026ldquo;には、前回の記事で紹介したoutput/elasticsearchの設定 に合致するnew_demo_access_log-*を指定しています。\ncurl -XPUT localhost:9200/_template/new_access_log_for_demo -d \u0026#39; { \u0026#34;template\u0026#34;: \u0026#34;new_demo_access_log-*\u0026#34;, \u0026#34;settings\u0026#34;: { \u0026#34;number_of_shards\u0026#34;: \u0026#34;2\u0026#34;, \u0026#34;number_of_replicas\u0026#34;: \u0026#34;0\u0026#34; }, \u0026#34;mappings\u0026#34;: { \u0026#34;_default_\u0026#34;: { \u0026#34;dynamic_templates\u0026#34;: [ { \u0026#34;string_template\u0026#34;: { \u0026#34;mapping\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;match_mapping_type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;match\u0026#34;: \u0026#34;*\u0026#34; } } ], \u0026#34;properties\u0026#34;: { \u0026#34;path\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;multi_field\u0026#34;, \u0026#34;fields\u0026#34;: { \u0026#34;no_analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, \u0026#34;referer\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;multi_field\u0026#34;, \u0026#34;fields\u0026#34;: { \u0026#34;no_analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, \u0026#34;agent\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;multi_field\u0026#34;, \u0026#34;fields\u0026#34;: { \u0026#34;no_analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, \u0026#34;geoip\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;location\u0026#34;: { \u0026#34;geohash\u0026#34;: true, \u0026#34;geohash_precision\u0026#34;: 10, \u0026#34;type\u0026#34;: \u0026#34;geo_point\u0026#34;, \u0026#34;lat_lon\u0026#34;: true, \u0026#34;geohash_prefix\u0026#34;: true } } }, \u0026#34;response\u0026#34;: { \u0026#34;copy_to\u0026#34;: \u0026#34;response_int\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;bytes\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;response_int\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34; } } } } } \u0026#39; settings設定 デモ用であり、手元で2台のノードを起動するということもあり、number_of_shardsに2を、number_of_replicasに0を指定してあります。\nmappings設定 インデックスのタイプ Mappingsの指定は通常、特定のタイプを指定します。 今回のデモでは、1種類しかないのですが、タイプ名を特に意識しないために、_default_を使用しました。 この場合、任意のタイプに適用されることとなります。 タイプを指定してMappingの設定を行う場合は_default_の部分に特定のタイプ名を記入します。\n\u0026#34;mappings\u0026#34;: { \u0026#34;_default_\u0026#34;: { ... ダイナミックテンプレート 次はダイナミックテンプレートです。 インデックステンプレートはインデックスの設定をテンプレート化しました。ダイナミックテンプレートはフィールドに対してテンプレートを設定できます。\n以下のダイナミックテンプレートでは、stringタイプのフィールドのデフォルト設定を変更しています。 通常、stringタイプのフィールドはanalyzedとなりますが、not_analyzedに変更してあります。 詳しく検索したいフィールドの方が少ないためです。\n... \u0026#34;dynamic_templates\u0026#34;: [ { \u0026#34;string_template\u0026#34;: { \u0026#34;mapping\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;match_mapping_type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;match\u0026#34;: \u0026#34;*\u0026#34; } } ], ... multi_field指定 検索もしたいし、Terms Aggregationでも利用したいフィールドについては、multi_fieldを利用して、 analyzedとnot_analyzedの2種類のフィールドを用意しています。 multi_field設定を用いることで、1つのJSONのデータから、異なる形のフィールドを用意することが可能です。\n今回のテンプレートでは、path、referer、agentにmulti_fieldを指定しました。\n... \u0026#34;path\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;multi_field\u0026#34;, \u0026#34;fields\u0026#34;: { \u0026#34;no_analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, ... 例えば、上記の設定の場合、入力のJSONはpathというデータのみですが、インデックス上にはpath.no_analyzedと path.analyzedというフィールドができあがります。 実際に検索する場合は、path.analyzed:検索したい文字列という形で検索をすることで、いわゆる部分一致のような検索が可能です。 また、完全一致をしたい場合はpath.no_analyzed:検索したい文字列という指定になります。 用途を考えると、requestも指定したほうが良いかもしれません。\ngeoip Logstashでgeoipデータを付与していました。 このgeoipのデータをKibana4で利用するために、geoデータとして登録する必要があります。\n\u0026#34;geoip\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;location\u0026#34;: { \u0026#34;geohash\u0026#34;: true, \u0026#34;geohash_precision\u0026#34;: 10, \u0026#34;type\u0026#34;: \u0026#34;geo_point\u0026#34;, \u0026#34;lat_lon\u0026#34;: true, \u0026#34;geohash_prefix\u0026#34;: true } } }, 上記の設定がgeoデータの指定です。 typeにobjectが指定してありますが、これは、geoipのデータがネストしているためです。 geoipオブジェクトのうち、緯度経度のデータはlocationに入っているため、こちらに緯度経度関係の設定を指定します。\n\u0026quot;type\u0026quot;: \u0026quot;geo_point\u0026quot;:geo_pointタイプであることを指定 \u0026quot;geohash\u0026quot;: true:緯度経度のデータをもとに、geohashの値もインデックス \u0026quot;geohash_precision\u0026quot;: 10:geohashの精度の指定 \u0026quot;lat_lon\u0026quot;: true:緯度経度を個別の.lat、.lonというフィールドにもインデックス \u0026quot;geohash_prefix\u0026quot;: true:該当するgeohashのみでなく、その親にあたるgeohashについてもインデックスする response、response_int、bytes 最後は、response、response_int、bytesです。\nresponseには、HTTPステータスコードが入ります。 文字列としても扱いたいですが、integerとして、Renge Aggregationなどを行いたいので、 response_intというフィールドにも値を入れています。 multi_fieldでも可能ですが、ここでは、copy_toを利用しました。 copy_toを用いることで、異なるフィールドに値をコピーすることができます。\nbytesについては、longで扱いたいとういう理由だけです。\n\u0026#34;response\u0026#34;: { \u0026#34;copy_to\u0026#34;: \u0026#34;response_int\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;bytes\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;response_int\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34; } まとめ 今回はデモに利用したインデックスてプレートについて説明しました。 前回の、Logstashの設定とこのインデックステンプレートを用いることで、Kibanaで解析するデータの準備ができます。 実際の操作などについては、また次回の記事で説明しようかと思います。\n不明な点、誤植などありましたら、コメント欄へお願いします。\n","date":1416900346,"dir":"post/2014/","id":"4d8f5e581eee602c7fd21da8eb68df9a","lang":"ja","lastmod":1416900346,"permalink":"https://blog.johtani.info/blog/2014/11/25/import-apache-accesslog-using-logstash-2/","publishdate":"2014-11-25T16:25:46+09:00","summary":"前回の「Logstashを利用したApacheアクセスログのインポート」の続きです。 前回の記事では、Logstashの設定ファイルについて説","tags":["logstash","kibana","elasticsearch"],"title":"インデックステンプレートとLogstash"},{"contents":"JJUG CCCや第7回Elasticsearch勉強会のKibana4のデモにアクセスログを利用しました。\nただ、セッションでは、どうやってElasticsearchに投入したのかという詳しい話をしていませんでした。 本記事では、データ取り込み時に利用したLogstashの設定ファイルについて説明します。\nLogstashの設定の説明に入る前に、全体の流れを。 「ApacheアクセスログをKibana4により可視化」です。\n材料の準備 「ApacheアクセスログをKibana4により可視化」に必要な材料は次の通りです。 (今回は起動するところまでいかないので、実際に必要なのは次回以降になります。)\nJava 7(u55以上を1つ) Logstash 1.4.2(1つ) Elasticsearch 1.4.0(1つ) Kibana4 Beta2(1つ) Apacheのアクセスログ(適量) Apacheのアクセスログ以外は、公式サイトからダウンロードできます。 それぞれをダウンロードして、起動できるようにしておきましょう。\n※1台のマシン上で行う場合は、アクセスログの量を少なめにするなどの対策をとりましょう。 ※今回は、1台のマシン(Mac)上で、VMなどを利用せず、それぞれ直接起動するものとします。\n可視化の手順と流れ 可視化の流れとしては、\nLogstashでファイルを読み込み、各種処理(パースしたり、情報を追加したり、切り出したり) Elasticsearchに保存 Kibanaでグラフを作ったり、検索してみたり です。\n今回は、1のLogstashでファイルを読み込んだりする設定ファイルの説明です。\nLogstashの設定 Logstashの基本 まずは、Logstashの設定ですが、簡単にLogstashの説明を。 Logstashは大きく3つのパーツに分かれています。\ninput:データの入力処理 filter:inputで読み込んだデータに対する操作など output:データの出力処理 inputでデータを読み込み(複数可)、filterでデータに対して各種処理を行い、outputでデータを指定されたところに出力(複数可)します。\nアクセスログの読み込み設定 アクセスログの読み込み処理は大まかに次のようなものとなります。\nアクセスログを読み込む(input/file) 読み取ったアクセスログを各フィールド(IPアドレス、ユーザエージェントなど)に分割(filter/grok) 日付のパース(filter/date) クライアントIPアドレスにgeoipの情報を付加(filter/geoip) リクエストのパスの第1階層の抽出(filter/grok) ユーザエージェントのパース(filter/useragent) Elasticsearchへの出力(output/elasticsearch) 設定ファイルは次のようなものになります。\ninput { file { path =\u0026gt; \u0026#34;/Users/johtani/demo_access_log/*/*.log\u0026#34; start_position =\u0026gt; \u0026#34;beginning\u0026#34; } } filter { grok { match =\u0026gt; { \u0026#34;message\u0026#34; =\u0026gt; \u0026#34;%{COMBINEDAPACHELOG}\u0026#34; } break_on_match =\u0026gt; false tag_on_failure =\u0026gt; [\u0026#34;_message_parse_failure\u0026#34;] } date { match =\u0026gt; [\u0026#34;timestamp\u0026#34;, \u0026#34;dd/MMM/YYYY:HH:mm:ss Z\u0026#34;] locale =\u0026gt; en } geoip { source =\u0026gt; [\u0026#34;clientip\u0026#34;] } grok { match =\u0026gt; { \u0026#34;request\u0026#34; =\u0026gt; \u0026#34;^/%{WORD:first_path}/%{GREEDYDATA}$\u0026#34; } tag_on_failure =\u0026gt; [\u0026#34;_request_parse_failure\u0026#34;] } useragent { source =\u0026gt; \u0026#34;agent\u0026#34; target =\u0026gt; \u0026#34;useragent\u0026#34; } } output { elasticsearch { host =\u0026gt; \u0026#34;localhost\u0026#34; index =\u0026gt; \u0026#34;new_demo_access_log-%{year}\u0026#34; cluster =\u0026gt; \u0026#34;demo_cluster\u0026#34; protocol =\u0026gt; \u0026#34;http\u0026#34; } } 1. アクセスログを読み込む(input/file) inputのfileモジュール(a)を使用してアクセスログのファイルを読み込みます。 pathでアクセスログのファイルのパスを指定します。 今回利用したアクセスログはdemo_access_log/2010/access20100201.logといった日毎のファイルに分割されていたため、 *を利用してファイルのパスを指定しました。 また、今回は既存のファイルの読み込みだけのため、start_positionにbeginningを指定してあります。 デフォルトではendが指定されるため、Logstashを起動後に追記されたログから対象になってしまうためです。 その他の設定については、公式ガイドをご覧ください。\ninput { file { # a path =\u0026gt; \u0026#34;/Users/johtani/demo_access_log/*/*.log\u0026#34; # b start_position =\u0026gt; \u0026#34;beginning\u0026#34; # c } } Logstashでは、ファイルをどこまで読み込んだかという情報を保持するために、sincedbを利用しています。 設定変更後に同じファイルを最初から読み込みたい場合などは、こちらのファイルを一旦削除するなどの対応が必要です。\nちなみに、読み込んだデータは次のようなJSONになっています。\n{ \u0026#34;message\u0026#34;: \u0026#34;読み込んだアクセスログ\u0026#34;, \u0026#34;@version\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;@timestamp\u0026#34;:\u0026#34;2014-11-21T06:16:21.644Z\u0026#34;, \u0026#34;host\u0026#34;:\u0026#34;jupiter.local\u0026#34;, \u0026#34;path\u0026#34;:\u0026#34;/Users/johtani/demo_access_log/2010/access20100201.log\u0026#34;} } 特に指定がない場合は、messageに読み込んだデータが入ってきます。 @timestampがLogstashが読み込んだ時刻、hostはLogstashが動作しているホスト名です。 pathはfileモジュールが読み込んだファイルのパスを設定しています。 この後の処理で、どこの項目に対して処理を行うかといったことが重要になるので、\n2. 読み取ったアクセスログを各フィールド(IPアドレス、ユーザエージェントなど)に分割(filter/grok) 2.〜6.の処理は、inputで読み込んだ1アクセスログに対する処理となります。\nここでは、grokフィルタを使用して Apacheのアクセスログを各フィールドに分割します。 Logastashでは、簡単に使えるようにいくつかのパターンが用意されています。 Apacheのログのために、COMBINEDAPACHELOGというのが用意されています。 今回はこちらを使用しています。その他にも日付などパターンが用意されているので、試してみてください。\nmessageにアクセスログが入っているので、こちらの項目に対してCOMBINEDAPACHELOGのパターンを matchで適用してフィールドに抜き出します。 tag_on_failureは、matchでパースに失敗した場合に、tagというフィールドに指定した文字列を出力する機能になります。 デフォルトだと_grokparsefailureが付与されますが、ここでは、どの処理で失敗したがを判別するために文字列を変更しています。\nfilter { grok { match =\u0026gt; { \u0026#34;message\u0026#34; =\u0026gt; \u0026#34;%{COMBINEDAPACHELOG}\u0026#34; } break_on_match =\u0026gt; false tag_on_failure =\u0026gt; [\u0026#34;_message_parse_failure\u0026#34;] } ... clientip、ident、auth、timestamp、verb、request、httpversion、response、bytes、referrer、agentがgrokフィルタにより抜き出された項目です。\n{ \u0026#34;message\u0026#34;:\u0026#34;アクセスログ\u0026#34;, \u0026#34;@version\u0026#34;:\u0026#34;1\u0026#34;, \u0026#34;@timestamp\u0026#34;:\u0026#34;2014-11-21T07:20:54.387Z\u0026#34;, \u0026#34;host\u0026#34;:\u0026#34;jupiter.local\u0026#34;, \u0026#34;path\u0026#34;:\u0026#34;/Users/johtani/demo_access_log/2010/access20100201.log\u0026#34;, \u0026#34;clientip\u0026#34;:\u0026#34;クライアントのIPアドレス\u0026#34;, \u0026#34;ident\u0026#34;:\u0026#34;-\u0026#34;, \u0026#34;auth\u0026#34;:\u0026#34;-\u0026#34;, \u0026#34;timestamp\u0026#34;:\u0026#34;01/Feb/2010:00:00:26 +0900\u0026#34;, \u0026#34;verb\u0026#34;:\u0026#34;GET\u0026#34;, \u0026#34;request\u0026#34;:\u0026#34;/images/favicon.ico\u0026#34;, \u0026#34;httpversion\u0026#34;:\u0026#34;1.1\u0026#34;, \u0026#34;response\u0026#34;:\u0026#34;200\u0026#34;, \u0026#34;bytes\u0026#34;:\u0026#34;318\u0026#34;, \u0026#34;referrer\u0026#34;:\u0026#34;\\\u0026#34;-\\\u0026#34;\u0026#34;, \u0026#34;agent\u0026#34;:\u0026#34;\\\u0026#34;Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)\\\u0026#34;\u0026#34; } 3. 日付のパース(filter/date) Logstashは特に指定がない場合、inputでデータを取り出した日付が@timestampとなります。 そして、このフィールドが特に指定がない場合は、Elasticsearchのデータの日付となり、Kibanaで利用する日付となります。\nリアルタイムにアクセスログを読み込む場合は、読み込んだ日時でもほぼ問題はありませんが、過去データの場合はそうもいきません。 そこで、dateフィルタを使用して、@timestampの値を書き換えます。\ndate { match =\u0026gt; [\u0026#34;timestamp\u0026#34;, \u0026#34;dd/MMM/YYYY:HH:mm:ss Z\u0026#34;] locale =\u0026gt; en } 上記では、timestampという項目に対してdd/MMM/YYYY:HH:mm:ss Zという日付パターンの場合に値を書き換える設定となります。 なお、日付の月の部分がFebとなっているため、localeにenを指定しています。Logstashが動作するマシンのlocaleがjaなどの場合にパースに失敗するためです。\n4. クライアントIPアドレスにgeoipの情報を付加(filter/geoip) どの国からのアクセスかなどを判別したいので、IPアドレスを元にgeoipを利用してより詳細な情報を付与します。 Logstashでもこの機能が用意されており、簡単に利用ができます。\ngeoip { source =\u0026gt; [\u0026#34;clientip\u0026#34;] } これだけです。対象とするIPアドレスのフィールドを指定しているだけです。 geoipというフィールドが追加され、次のような情報が付与されます。 国名、緯度経度、タイムゾーンなどです。\n{ ... \u0026#34;geoip\u0026#34;: { \u0026#34;ip\u0026#34;: \u0026#34;IPアドレス\u0026#34;, \u0026#34;country_code2\u0026#34;: \u0026#34;JP\u0026#34;, \u0026#34;country_code3\u0026#34;: \u0026#34;JPN\u0026#34;, \u0026#34;country_name\u0026#34;: \u0026#34;Japan\u0026#34;, \u0026#34;continent_code\u0026#34;: \u0026#34;AS\u0026#34;, \u0026#34;latitude\u0026#34;: 36, \u0026#34;longitude\u0026#34;: 138, \u0026#34;timezone\u0026#34;: \u0026#34;Asia/Tokyo\u0026#34;, \u0026#34;location\u0026#34;: [ 138, 36 ] } ... } 5. リクエストのパスの第1階層の抽出(filter/grok) リクエストされたURLはrequestフィールドにありますが、個別のURLだと、大まかな集計が大変です。 もちろん、クエリで処理することもできますが、Logstashで処理するついでに、第1階層のディレクトリ名を抽出しておくことで、 検索や集計を行いやすくしておきます。\ngrok { match =\u0026gt; { \u0026#34;request\u0026#34; =\u0026gt; \u0026#34;^/%{WORD:first_path}/%{GREEDYDATA}$\u0026#34; } tag_on_failure =\u0026gt; [\u0026#34;_request_parse_failure\u0026#34;] } また、grokフィルタの登場です。 今回は、WORD:first_pathという記述方法で、WORDパターンにマッチした文字列をfirst_pathというフィールドに展開する指定をしています。\n例えば、サイトのスクリプトなどがscriptsというディレクトリにある場合は、first_pathの値を利用して、 後続のフィルタでログデータを出力しないといった処理にも使えます。\n6. ユーザエージェントのパース(filter/useragent) Logstashではユーザエージェントの文字列から、いくつかの情報を付与するフィルタも用意されています。 useragentフィルタです。\nuseragent { source =\u0026gt; \u0026#34;agent\u0026#34; target =\u0026gt; \u0026#34;useragent\u0026#34; } agentというフィールドにユーザエージェントの文字列があるので、このフィールドに対してフィルタを適用します。 元の文字列も取っておきたいので、useragentという別のフィールドに出力するように指定してあります。\n\u0026#34;useragent\u0026#34;: { \u0026#34;name\u0026#34;: \u0026#34;Firefox\u0026#34;, \u0026#34;os\u0026#34;: \u0026#34;Windows XP\u0026#34;, \u0026#34;os_name\u0026#34;: \u0026#34;Windows XP\u0026#34;, \u0026#34;device\u0026#34;: \u0026#34;Other\u0026#34;, \u0026#34;major\u0026#34;: \u0026#34;17\u0026#34;, \u0026#34;minor\u0026#34;: \u0026#34;0\u0026#34; }, このように、OS名やバージョン名などが抽出できます。\n7. Elasticsearchへの出力(output/elasticsearch) 最後は、Elasticsearchへのデータの出力設定です。\nindexにて、出力するindex名を指定してあります。 また、年毎のインデックス名にするために%{year}を利用しています。 sprintf formatです。\nelasticsearch { host =\u0026gt; \u0026#34;localhost\u0026#34; index =\u0026gt; \u0026#34;new_demo_access_log-%{year}\u0026#34; cluster =\u0026gt; \u0026#34;demo_cluster\u0026#34; protocol =\u0026gt; \u0026#34;http\u0026#34; } まとめ ということで、今回はアクセスログをLogstashにて読み込む時の設定について説明してきました。 次回は、実際にLogstashを起動してElasticsearchにデータを登録するところまでを説明します。\nJJUG CCCや勉強会のデモに用いたデータは、 Elasticsearchにデータを登録する前にテンプレートも設定してありました。こちらについても、次回説明しようと思います。\n不明な点、誤植などありましたら、コメント欄へお願いします。\n","date":1416558639,"dir":"post/2014/","id":"937a597a8b399fd32caba88a3c1c7bc4","lang":"ja","lastmod":1416558639,"permalink":"https://blog.johtani.info/blog/2014/11/21/import-apache-accesslog-using-logstash/","publishdate":"2014-11-21T17:30:39+09:00","summary":"JJUG CCCや第7回Elasticsearch勉強会のKibana4のデモにアクセスログを利用しました。 ただ、セッションでは、どうやってElas","tags":["logstash","kibana","elasticsearch"],"title":"Logstashを利用したApacheアクセスログのインポート"},{"contents":"第7回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 次回もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\n昨日も紹介しましたが、Elasticsearch Advent Calendar 2014を用意してみました。まだ、空きがありますので、登録お待ちしております!\n今回は出足が好調で、早々に180人の枠を超えるという嬉しい事態でした。 最終的な参加人数は130名程度で、懇親会参加者が50名弱といったところです。\n「Kibana4」 Elasticsearch Inc. Jun Ohtani @johtani スライド:Kibana4\nということで、Kibana4の紹介と、Kibana4のBeta2を利用したデモを行いました。 デモの開始のところで少し環境がうまく動いてなくて手間取ってしまいましたが。。。\n発表で1点だけ修正があります。JRubyを選択しているのがElasticsearchのライブラリを使用するためという説明をしましたが、 こちらは、Logstashに関する話でした。Kibana4は現時点では、ElasticsearchへのProxyとしての動作が主なものとなります。Rubyでも動作可能です。 bin/kibanaについてはJavaを使った起動になります。 参考:https://github.com/elasticsearch/kibana/tree/master/src/server\n発表でも主張しましたが、ダウンロードして、Elasticsearchを用意すれば簡単に動作させることが可能です。 ぜひ、ローカルで試して見てもらえればと思います。 今回のデモのデータを入れるのに利用したLogstashの設定などについては、ブログで記事を書こうと思います。\nniconicoの検索を支えるElasticsearch 株式会社ドワンゴ 伊藤 祥 さん スライド:niconicoの検索を支えるElasticsearch\nリアルタイム検索の実現、新しい検索への対応 検索のアーキテクチャとか。 Capistranoでデプロイとかを管理 1.4.1が出たら、クラスタを更新予定 ということで、実際に導入した話から、現在の運用の仕方、クラスタのアップグレードなど多岐にわたる内容でおもしろかったです。 遭遇した問題点とかもあったので。 Marvel便利なのでぜひ導入を検討してもらえればw\nElasticsearch at CrowdWorks\u2028株式会社クラウドワークス 九岡 佑介 さん @mumoshu スライド:Elasticsearch at CrowdWorks\n会社の紹介 仕事が検索対象 検索時間が1桁減少! Graceful Degradationで失敗したら、InnoDB FTSで代替:Gracefully found.noのサービスを利用 elasticsearch-modelの拡張を作成してOSSとして公開:elasticsearch-model-extensions Gracefullyで切り替えとかは面白いなと思いました。 検索での利用の話でしたが、他のシーンでも使えそうですよね。 日本にFoundユーザがいるのも初めて知りました。 彼らの開発者ブログも質の良い情報が載っているので、参考になりますよね。\n次は、どんなMappingで運用しているのかとか、どういった工夫をしているかといった点を詳しく聞きたいなと思いました。 またお待ちしております。\n1分で作るElasticsearchプラグイン 株式会社エヌツーエスエム 菅谷 信介 さん スライド:Elasticsearchプラグインの作り方\n\u0008\u0008* プラグインの作り方とか。\n十数個のプラグインの紹介。プラグインはこちらで公開中。https://github.com/codelibs/ 実際に、業務で必要なものから作成 まだまだ作りたいものがある コミュニティ還元できるものはPR送ってもらえるとうれしいです。 前よりは体制も増えてるので、PRも目にとまるようになってるはずです。\nあとは、使ってみたいと思う方も多数いると思うので、ぜひ、OSSなので、貢献しましょう! フィードバックがあるだけで、OSS活動やってるものにとってはやる気につながると思いますし。\nLT:GISとして活用するElasticsearch\u2028船戸 隆さん スライド:GISとして活用するElasticsearch\u2028java-jaからIngressの青(Registance)の勧誘に来られた方w APIをハックして、情報を取得し、Kibanaで可視化 残念ながら、APIが変更されて見れなくなったらしい。 Ingress実際にやったことはないのですが、おもしろそうでした。 発表される方の会社の採用紹介ではなく、Ingressの勧誘をされるとは想定外でしたw\n興味のあるデータをKibanaで可視化するのも面白い例だと思うので、活用してもらえればと思います。\nその他、感想などのブログ 適当に見つけたブログを列挙してあります。これもあるよ!などあれば、教えてください。\n勉強会メモ - 第7回elasticsearch勉強会 第7回elasticsearch勉強会 #elasticsearch #elasticsearchjp まとめ JJUGの時とは違い、Elasticsearch勉強会ではさすがに、企業としてのElasticsearchの知名度が高かったのはありがたいことでした。 自分の発表のために始めた勉強会でもありますが、まだまだ、発表するときは緊張しますし、分かりにくいんじゃないかなぁと思うことも多々あります。 この辺がわかりにくかった、この辺をもっと知りたいなど、フィードバックをお待ちしております。\n冒頭にも書きましたが、Elasticsearch Advent Calendar 2014の登録をお待ちしております。どんなことでも歓迎なので、Elasticsearch、Kibana、Logstashなどについて書いてもらえるとうれしいです。\n次回ももちろん2ヶ月後くらいに行います。 スピーカー募集中ですので、コメント、メール、ツイートなど、コンタクトしていただければと思います。 よろしくお願いいたします。\n","date":1416363547,"dir":"post/2014/","id":"2a8412aa50d07330f1298f0243fa79d3","lang":"ja","lastmod":1416363547,"permalink":"https://blog.johtani.info/blog/2014/11/19/hold-on-7th-elasticsearch-jp/","publishdate":"2014-11-19T11:19:07+09:00","summary":"第7回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん","tags":["elasticsearch","勉強会"],"title":"第7回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:elasticsearch-1.4.0 and 1.3.5 released\n本日、Lucene 4.10.2をベースにしたElasticsearch 1.4.0と、バグフィックスリリースである、Elasticsearch 1.3.5をリリースしました。 ダウンロードおよび変更リストはそれぞれ次のリンクからアクセスできます。\n最新ステーブルリリース:Elasticsearch 1.4.0 1.3.x系バグフィックス:Elasticsearch 1.3.5 1.3ブランチに関する過去のリリースについてのブログは次のとおりです:1.3.4, 1.3.3, 1.3.2, 1.3.1, 1.3.0.\nBeta1リリースでも言及しましたが、1.4.0の主なテーマは*resiliency(復元性、弾力性)*です。 Elasticsearchをより安定し信頼性のあるものにし、メモリ管理を改善し、ディスカバリアルゴリズムを改善し、破損したデータの検知を改善しました。 Beta1リリースからのハイライトも含んでいます。\nDoc values (インデックス時にディスクに保存されるfielddata)がヒープ利用率を激減 Request circuit breaker: メモリを消費しすぎる検索リクエストの中断 Bloom filterのデフォルト無効、高速なインデキシングのためにもはや必要とされないため。 ノードディスカバリ、シャードリカバリの数多くのバグフィックス及び改善 データ破損の早期検知のためのチェックサムのさらなる利用 GroovyをMVELの代わりにデフォルトスクリプト言語に CORSをデフォルト無効に。XSS攻撃防止の為。 クエリキャッシュ、変更されていないシャードからすぐにaggregation結果を返す 新しいAggregation:filter(ドキュメント)、children(ドキュメント)、scripted_metric(ドキュメント) 新しいGET /indexAPI。インデックスのsettings、mappings、warmers、aliasesを1回のリクエストで返却(ドキュメント) 自動付与ドキュメントIDのためのFlake ID。プライマリキーの探索パフォーマンスの改善。 ドキュメントに変更のない更新によるドキュメントの再インデックスの防止 function_scoreクエリの関数でweightパラメータによる個別の改善を可能に。(ドキュメント) 詳細については1.4.0.Beta1のブログ(英語)(日本語訳)をご覧ください。\nBeta1以降の1.4.0の変更の全てについては、1.4.0 release notesでご覧いただけます。 以下では、2つの主な変更について紹介します。\nHTTP Pipelining HTTP pipeliningは複数のリクエストを1回のコネクションで、関連するレスポンスを待つことなく送信することができます。 そして、レスポンスは、受け取ったリクエストと同じ順序で返却されます。 HTTP/1.1の仕様で、pipeliningのサポートが必要です。ElasticsearchはHTTP/1.1であるとしてきましたが、pipeliningはサポートしていませんでした。この問題は.NETユーザで問題を引き起こしました。\n現在、HTTP pipeliningは公式にサポート済みで、デフォルトで利用できます。#8299をご覧ください。\nUpgrade API Luceneのすべてのリリースではバグフィックスや最適化が提供されます。しかし、多くのユーザは古いバージョンのLuceneで作成されたインデックスを持っており、より最新の改善による利点を利用できないことがあります。 新しいupgradeAPIは、あなたのインデックスすべてもしくは一部を最新のLuceneフォーマットに透過的にアップグレードできます。\nGET _upgradeリクエストは、インデックスのアップグレードが必要かどうかを提示し、アップグレードに必要なセグメントのサイズをリポートすることによって、どのくらいの時間が必要かの目安を提供します。 POST _upgradeコマンドはバックグラウンドでインデックスを最新のLuceneフォーマットに書き換えます。\nより詳しい情報はupgradeAPIドキュメントをご覧ください。\n試してみてください。 Beta1リリースを利用し、経験・体験を報告していただいたベータテスターの方々に感謝します。 1.4.0がこれまでの最高のリリースになると確信しています。 ぜひ、Elasticsearch 1.4.0をダウンロードして、試してみてください。 そして、感想をTwitter(@elasticsearch)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1415205033,"dir":"post/2014/","id":"d266a2023c67b7a20c3bd01055b223bc","lang":"ja","lastmod":1415205033,"permalink":"https://blog.johtani.info/blog/2014/11/06/elasticsearch-1-4-0-ja/","publishdate":"2014-11-06T01:30:33+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:elasticsearch-1.4.0 and 1.3.5 released 本日、Lucene 4.10.2をベースにし","tags":["elasticsearch"],"title":"Elasticsearch 1.4.0および1.3.5リリース(日本語訳)"},{"contents":"久しぶりに翻訳ではないブログを。書こうと思いながらかけてなかったので。。。\n今回はvalidate APIの紹介です。\n背景 ElasticsearchのクエリはQuery DSLというJSONで クエリを定義できるものを提供しています。 これは、様々なクエリ、フィルタを定義するために必要です。\n自分の望んでいる条件を記述するために、JSONのネストと格闘することも必要となります。。。 また、クエリ、フィルタには様々なパラメータが用意されています。 これらのパラメータをすべて覚えるのは無理でしょうし、タイプミスなどもありますよね。 タイプミスやカッコのミスマッチなどで格闘して1時間が経過してしまったなどもあると思います。\nそんな時に便利なAPIとして用意されているのがvalidate APIです。\n利用方法 APIが用意されています。\nhttp://ホスト名:ポート番号/インデックス名/タイプ名/_validate/query インデックス名やタイプ名は省略可能ですが、マッピングが異なると思うので、タイプ名まで指定するほうが良いと思います。 上記のAPIに対してクエリを送信するだけです。\nクエリの確認 たとえば、こちらのGistにあるようなマッピングのインデックスに対して 検索クエリを組み立てていて、エラーが出るとします。 ※このクエリはmatch_allのところをmatch_alと、lが1文字足りないクエリになっています。\n検索クエリのリクエスト(エラーあり)\nGET pref_aggs/_search { \u0026#34;query\u0026#34;: { \u0026#34;match_al\u0026#34;: {} } } 実行結果のレスポンス\n{ \u0026#34;error\u0026#34;: \u0026#34;SearchPhaseExecutionException[Failed to execute phase [query], all shards failed; shardFailures {[rwkb01chTZq2V7FD0Tlwrw][pref_aggs][0]: SearchParseException[[pref_aggs][0]: from[-1],size[-1]: Parse Failure [Failed to parse source [{\\n \\\u0026#34;query\\\u0026#34;: {\\n \\\u0026#34;match_al\\\u0026#34;: { }\\n }\\n}\\n]]]; nested: QueryParsingException[[pref_aggs] No query registered for [match_al]]; }{[rwkb01chTZq2V7FD0Tlwrw][pref_aggs][1]: SearchParseException[[pref_aggs][1]: from[-1],size[-1]: Parse Failure [Failed to parse source [{\\n \\\u0026#34;query\\\u0026#34;: {\\n \\\u0026#34;match_al\\\u0026#34;: { }\\n }\\n}\\n]]]; nested: QueryParsingException[[pref_aggs] No query registered for [match_al]]; }]\u0026#34;, \u0026#34;status\u0026#34;: 400 } とこんなかんじで、エラーが帰っては来るのですが、非常に読みづらいです。\nそこで、validate APIを利用します。 リクエスト先を/_searchから/_validate/queryに変更します。\nvalidate API\nGET pref_aggs/_validate/query { \u0026#34;query\u0026#34;: { \u0026#34;match_al\u0026#34;: {} } } validate APIのレスポンス\n{ \u0026#34;valid\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;failed\u0026#34;: 0 } } すると、非常にシンプルな結果が返ってきます。 \u0026quot;valid\u0026quot;: falseとなっているため、クエリに問題があることがわかります。\nエラーの詳細 問題がある事自体はわかりましたが、エラーの内容も知りたいですよね? その場合は、explainというパラメータを追加します。 (正しくはexplain=trueを追加しますが、=trueを省略可能です。)\nvalidate API(explainあり、クエリ自体は省略)\nGET pref_aggs/_validate/query?explain {...} validate APIのレスポンス\n{ \u0026#34;valid\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;explanations\u0026#34;: [ { \u0026#34;index\u0026#34;: \u0026#34;pref_aggs\u0026#34;, \u0026#34;valid\u0026#34;: false, \u0026#34;error\u0026#34;: \u0026#34;org.elasticsearch.index.query.QueryParsingException: [pref_aggs] No query registered for [match_al]\u0026#34; } ] } explanationsという項目が追加されました。 ここにerrorという項目として、エラーの詳細が返ってきます。_searchの時よりも見やすいですね。 今回のエラーは、match_allが正しいクエリですの、match_alというクエリは登録されていないというエラーでした。 では、クエリを修正して実行しましょう。\nvalidate API(エラー無し)\nGET pref_aggs/_validate/query?explain { \u0026#34;query\u0026#34;: { \u0026#34;match_all\u0026#34;: {} } } validate APIのレスポンス\n{ \u0026#34;valid\u0026#34;: true, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;explanations\u0026#34;: [ { \u0026#34;index\u0026#34;: \u0026#34;pref_aggs\u0026#34;, \u0026#34;valid\u0026#34;: true, \u0026#34;explanation\u0026#34;: \u0026#34;ConstantScore(*:*)\u0026#34; } ] } 今度はクエリに問題はありません。\u0026quot;valid\u0026quot;: trueです。 そして、explanationsの項目には、errorの代わりにexplanationという項目が返ってきました。 これが、実際にElasticsearch内部で実行されるクエリになります。\n実際のクエリに利用される単語の確認 この機能はこの他に、クエリの解析にも利用できます。 思ったとおりに検索にヒットしない場合があって、困ったことはないですか? フィールドに指定されたアナライザによっては、単語を変形したりするものが存在します。\nサンプルマッピング\nPUT /validate_sample { \u0026#34;mappings\u0026#34;: { \u0026#34;several_analyzer\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;title\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;body_ja\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;kuromoji\u0026#34;}, \u0026#34;body_en\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;english\u0026#34;} } } } } 例えば、このようにkuromoji、english、デフォルト(standard)アナライザを利用したマッピングがあるとします。 このフィールドに対してpowerfulという単語で検索したとします。\nvalidate API\nGET /validate_sample/_validate/query?explain { \u0026#34;query\u0026#34;: { \u0026#34;multi_match\u0026#34;: { \u0026#34;fields\u0026#34;: [\u0026#34;body_en\u0026#34;,\u0026#34;body_ja\u0026#34;,\u0026#34;title\u0026#34;], \u0026#34;query\u0026#34;: \u0026#34;powerful\u0026#34; } } } この場合、レスポンスは次のとおりです。\nvalidate APIのレスポンス\n{ \u0026#34;valid\u0026#34;: true, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;explanations\u0026#34;: [ { \u0026#34;index\u0026#34;: \u0026#34;validate_sample\u0026#34;, \u0026#34;valid\u0026#34;: true, \u0026#34;explanation\u0026#34;: \u0026#34;(title:powerful | body_en:power | body_ja:powerful)\u0026#34; } ] } title、body_jaについては入力された単語がそのままクエリとして利用されています。 body_enについては、powerという単語に変換されて実行されています。 これは、englishアナライザがステミングを行った結果がクエリとして利用されるという意味です。 また、powerfulを秋葉原といった日本語に変更して実行すると次のようになります。 日本語はstandardアナライザなどでは、1文字ずつ区切られてしまうことがわかります。\nvalidate APIのレスポンス\n{ \u0026#34;valid\u0026#34;: true, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;explanations\u0026#34;: [ { \u0026#34;index\u0026#34;: \u0026#34;validate_sample\u0026#34;, \u0026#34;valid\u0026#34;: true, \u0026#34;explanation\u0026#34;: \u0026#34;((title:秋 title:葉 title:原) | (body_en:秋 body_en:葉 body_en:原) | ((body_ja:秋葉 body_ja:秋葉原) body_ja:原))\u0026#34; } ] } このように、クエリの単語がどのような単語に変換されてクエリに利用されているかなども知ることが可能です。\nまた、クエリを組み立てて、ヒットするはずが、0件となってしまうという場合にも、どのようなクエリが組み立てられているかを確認するという点で、 validate APIが役立ちます。 検索がヒットするが、望んだクエリになっていないのでは?という場合は_search APIのexplainパラメータを 利用すれば、クエリの構成がわかるのですが、検索結果が0件の場合はクエリの構成は表示されません。\n解決できない問題は? 便利なvalidate APIですが、以下の問題に対しては残念ながら確認できません。\nquery以外の項目のvalidate不可 たとえば、_search APIのsizeなどの項目についてはチェックできないです。 存在しないフィールドの指定 上記validate_sampleのマッピングの例でクエリにbody_engという存在しないフィールドを指定してもエラーとはなりません。 まとめ 書いたクエリがうまく動かない、JSONのタグがおかしいといった場合は、 まずはこのvalidate APIで確認してみるのがオススメです。\n","date":1414402951,"dir":"post/2014/","id":"bc2709406a9bb19e8d83a78f81e36244","lang":"ja","lastmod":1414402951,"permalink":"https://blog.johtani.info/blog/2014/10/27/how-to-use-validate-api/","publishdate":"2014-10-27T18:42:31+09:00","summary":"久しぶりに翻訳ではないブログを。書こうと思いながらかけてなかったので。。。 今回はvalidate APIの紹介です。 背景 Elasticsear","tags":["elasticsearch"],"title":"validate APIの利用"},{"contents":"Elasticsearch 1.4.0.Beta1がリリースされました。\n個人でelasticsearch-extended-analyzeというプラグインを開発してます。 こちらも1.4.0.Beta1に対応するべく作業をしてて、少し戸惑ったことがあったので、メモをば。\nここ最近はプラグインのバージョン番号をElasticsearchのバージョン番号と同じものを利用していました。 (プラグインの機能追加をサボってる??) その時に、1.4.0.Beta1という番号を指定したのですが、意味不明なエラーに悩まされてしまいまして。\nプラグインのリリースでは、以下のコマンドを実行します。\n$ mvn release:prepare $ mvn release:perform 最初のコマンド(prepare)で、パッケージングを実施し、Githubにリリースタグを打ったバージョンがpushされます。 次のコマンド(perform)で、パッケージングされたzipファイルがsonatypeのサイトに公開するためにアップロードされます。\n1.4.0.Beta1というバージョン文字列を利用した場合、prepareは問題なく実行できたのですが、 performで以下の様なエラーが返ってきました。\nReturn code is: 401, ReasonPhrase: Unauthorized. バージョン番号が1.3.0では特に問題はなかったのですが、、、 結局、バージョン番号を1.4.0-beta1に変更すると問題なくリリースが完了しました。\nmike_neckさんと話をしていて、Semantic Versioningに関係しているのかなぁという話にはなったのですが、 詳しく調べていません。。。\nそのうち調べようかなぁ。。。。\n","date":1413354368,"dir":"post/2014/","id":"998eda745d07fd8608f251138384a0b9","lang":"ja","lastmod":1413354368,"permalink":"https://blog.johtani.info/blog/2014/10/15/versioning-of-sonatype/","publishdate":"2014-10-15T15:26:08+09:00","summary":"Elasticsearch 1.4.0.Beta1がリリースされました。 個人でelasticsearch-extended-analyzeというプラグインを開発してま","tags":["Elasticsearch","plugin","sonatype"],"title":"Sonatypeのバージョン番号で困ったので"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:elasticsearch 1.4.0.beta1 released\n本日、Lucene 4.10.1をベースにした、Elasticsearch 1.4.0.Beta1をリリースしました。 Elasticsearch 1.4.0.Beta1からダウンロードできます。 また、すべての変更点に関してもこちらをご覧ください。\n1.4.0のテーマは*resiliency(復元性、弾力性)*です。 resiliencyとはElasticsearchをより安定し信頼性のあるものにすることを意味します。 すべての機能が正常に機能している場合は信頼することは簡単です。 予想外のことが発生した時に難しくなります:ノードでout of memoryの発生、スローGCや重いI/O、ネットワーク障害、不安定なデータの送信によるノードのパフォーマンス低下など。\n本ベータリリースは、resiliencyの主な3つの改善を含んでいます。\nメモリ使用量の低下によるノードの安定性向上 discoveryアルゴリズムの改善によるクラスタの安定性向上 チェックサムの導入による破損したデータの検知 分散システムは複雑です。 決して想像できないような状況をシミュレーションするために、ランダムなシナリオを作成する広範囲なテストスイートを持っています。 しかし、無数のエッジケース(特殊なケース)があることも認識しています。 1.4.0.Beta1はこれまで私たちが行ってきた改善のすべてを含んでいます。 これらの変更を実際にテストしていただき、何か問題があった場合は私たちに教えてください。\nメモリ管理 ヒープ空間は限られたリソースです。 上限を32GBとし、利用可能なRAMの50%をヒープの上限にすることを推奨します。 この上限を超えた場合、JVMは圧縮したポインタを使用することができず、GCが非常に遅くなります。 ノードの不安定性の主な原因は遅いGCです。それは、次のようなことから発生します。\nメモリプレッシャー スワップ(参照:memory settings) 非常に大きなヒープ 本リリースは、メモリ管理の改善し、(結果として)ノードの安定性を改善するいくつかの変更を含んでいます。\ndoc values メモリの利用の最も大きなものの1つはfielddataです aggregation、ソート、スクリプトがフィールドの値に素早くアクセスするために、フィールドの値をメモリにロードして保持します。 ヒープは貴重なため、1ビットも無駄にしないためにメモリ内のデータは高度な圧縮と最適化を行っています。 これは、ヒープスペース以上のデータをもつまでは、非常によく動作します。 これは、多くのノードを追加することによって常に解決できる問題です。 しかし、CPUやI/Oが限界に達してしまうずっと前に、ヒープ空間の容量に到達します。\n最近のリリースは、doc valuesによるサポートがあります。 基本的に、doc valuesはin-memory fielddataと同じ機能を提供します。 doc valuesの提供する利点は、それらが、非常に少量のヒープ空間しか使用しない点です。 doc valuesはメモリからではなく、ディスクから読み込まれます。 ディスクアクセスは遅いですが、doc valuesはカーネルのファイルシステムキャッシュの利点を得られます。 ファイルシステムキャッシュはJVMヒープとはことなり、32GBの制限による束縛がありません。 ヒープからファイルシステムキャッシュにfielddataを移行することによって、より小さなヒープを使うことができます。これは、GCがより早くなり、ノードが更に安定することを意味します。\n本リリースより前は、doc valuesはin-memory fielddataよりもかなり遅かったです。 本リリースに含まれる変更は、パフォーマンスをかなり向上させ、in-memory fielddataとほぼ同じくらいの速度になっています。\nin-memory fielddataの代わりにdoc valuesを利用するために必要なことは、次のように新しいフィールドをマッピングすることです。\nPUT /my_index { \u0026#34;mappings\u0026#34;: { \u0026#34;my_type\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;timestamp\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;date\u0026#34;, \u0026#34;doc_values\u0026#34;: true } } } } } このマッピングで、このフィールドに対するfielddataの利用は、メモリにフィールドをロードする代わりに、自動的にディスクからdoc valuesを利用します。 *注意:*現時点で、doc valuesはanalyzedなstringフィールドはサポートしていません。\nrequest circuit breaker fielddata circuit breakerはfielddataによって利用されるメモリの上限を制限するために追加され、OOMEの最も大きな原因の1つを防ぎました。 そして、リクエストレベルのcircuit-breakerを提供するために、コンセプトを拡張しました。 これは、単一のリクエストによって使用されるメモリの上限を制限します。\nbloom filters Bloom filters はインデキシング(前のバージョンのドキュメントが存在するかどうかのチェックのため)や、 IDによるドキュメントの検索(ドキュメントを含むセグメントがどれかを決定するため)に関する重要な性能最適化を提供しました。 しかし、もちろんそれらはコスト(メモリ)を必要とします。 現在の改善は、bloom filterの必要性を取り除きました。 現在では、Elasticsearchはまだ、インデックス時にそれらを構築します(実世界の経験がテストシナリオにそぐわない場合に備えて)。 しかし、デフォルトではメモリにはロードされません。 すべてが予定通りに運べば、将来のバージョンで完全にこれらは除去します。\nクラスタの安定性 クラスタの安定性向上のために私たちができる最も大きなことは、ノードの安定性の向上です。 もし、ノードが安定しておりタイミングよく反応すれば、クラスタが不安定になる可能性が大いに減少します。 私たちは不完全な世界に住んでいます。- 物事は予想外にうまく行きません。クラスタはデータを失うことなくこのような状況から回復できる必要があります。\n私たちは、improve_zenブランチ上で、Elasticsearchの障害からの復旧するための能力の向上に数ヶ月費やしてきました。 まず、複雑なネットワークレベルの障害を繰り返すためのテストを追加しました。 次に、各テストのための修正を追加しました。 そこには、より多くの行うことが存在します。しかし、私たちは、issue #2488(\u0026ldquo;分割が交差している場合、minimum_master_nodesはsplit-brainを防げない\u0026rdquo;)に含まれる、ユーザが経験してきた大部分の問題を私たちは解決しました。\n私たちはクラスタのresiliencyを非常に真剣に取り組んでいます。 私たちは、Elasticsearchが何ができるか、その上で何が弱点であるかを理解してほしいと思っています。 これを考慮して、私たちはResiliency Status Documentを作成しました。 このドキュメントは、私たち(または私たちユーザ)が遭遇したresiliencyの問題の、何が修正済みで、何が修正されないまま残っているかを記録します。 このドキュメントを慎重に読み、あなたのデータを保護するために適切な方法を選択してください。\nデータ破損の検知 ネットワークをまたいだシャードリカバリのチェックサムは、圧縮ライブラリのバグを発見する助けとなりました。 それは、バージョン1.3.2で修正済みです。 それ以来、私たちはElasticsearchのいたるところにチェックサムとチェックサムの確認を追加しました。\nマージ中に、あるセグメント内すべてのチェックサムの確認(#7360) インデックス再オープン時に、あるセグメント内の最も小さなファイルの完全な確認と、より大きなファイルの軽量な打ち切りチェック(LUCENE-5842) トランザクションログからイベントを再生するとき、各イベントはチェックサムを確認される(#6554) シャードのリカバリ中もしくは、スナップショットからのリストア中にElasticsearchはローカルファイルとリモートのコピーが同一であるか確認する必要がある。ファイルの長さとチェックサムのみを使うのは不十分であることが確認された。このため、現在はセグメントのすべてのファイルの同一性を確認(#7159) その他のハイライト Elasticsearch 1.4.0.Beta1のchangelogに本リリースの多くの機能、改善、バグフィックスについて読むことができます。 ここでは、特筆すべきいくつかの変更について述べます。\ngroovyによるmvelの置き換え Groovyは現在、デフォルトのscripting languageです。 以前のデフォルトはMVELで、古くなってきており、サンドボックス内で実行できないという事実は、セキュリティ問題でした。 Groovyはサンドボックスであり(それは、ボックスの外へは許可が必要)、メンテナンスされており、速いです! 詳しくはscriptingについてのブログ記事をご覧ください。\nデフォルトでcorsはオフ Elasticsearchのデフォルト設定はクロスサイトスクリプティングに対して脆弱でした。 私たちはデフォルトでCORSをオフにすることで修正しました。 Elasticsearchにインストールされたサイトプラグインはこれまで同様に機能します。 しかし、CORSを再度オンにすることがない限り、外部のウェブサイトがリモートのクラスタにアクセスすることはできません。 ウェブサイトがあなたのクラスタにアクセス可能に制御できるように、さらにCORS settingsを追加しました。 詳しくはsecurity pageをご覧ください。\nクエリキャッシュ 新しい試験的なshardレベルのクエリキャッシュは、静的なインデックスのアグリゲーションをほとんど即座に反応できます。 ウエブサイトのアクセスの日毎のページビュー数を見るダッシュボードを持っていると想像してみてください。 これらの数値は古いインデックスでは変更がありません。しかし、アグリゲーションはダッシュボードのリフレッシュのたびに再計算されます。 新しいクエリキャッシュを利用すると、シャードのデータが変更されない限り、アグリゲーションの結果はキャッシュから直接返却されます。 キャッシュから古い結果を決して取得することはありません。それは、常に、キャッシュされていないリクエストと同じ結果を返します。\n新しいaggregations 3つの新しいaggregationsがあります。\nfilters\nこれはfilter aggregationの拡張です。複数のバケットを定義し、バケット毎に異なるフィルタを利用できます。 children\nnestedアグリゲーションの親子版。children aggは親のドキュメントに属する子のドキュメントを集計できる scripted_metric\nこのaggregationは、データによって計算されたメトリックを完全にコントロールできます。これは、初期化フェーズ、ドキュメント収集フェーズ、shardレベル結合フェーズ、global reduceフェーズを提供します。 get /index api 以前、ある1つのインデックスのaliases、mappings、settings、warmersを取得出来ました。しかし、それらを個別にです。 get-index API はこれらのすべてもしくは一部を、複数もしくはひとつのインデックスに対して一緒に取得できます。 これは、既存のインデックスと同一もしくはほぼ同一であるインデックスを作成したいときに非常に役に立ちます。\n登録と更新 ドキュメントの登録と更新にいくつかの改善があります。\n現在、ドキュメントIDの自動生成のためにFlake IDを使用しています。これは、プライマリキー探索時に素晴らしい性能向上を提供します。 detect_noopにtrueを設定すると、ドキュメントに変更を与えない更新が軽量になります。この設定を有効にすると、_sourceフィールドのコンテンツを変更する更新リクエストだけ、ドキュメントの新しいバージョンを書き込みます。 更新はスクリプトから完全に操作できます。以前は、スクリプトはドキュメントがすでに存在しているときだけ実行可能で、それ以外は、upsertドキュメントで登録しました。script_upsertパラメータでスクリプトから直接ドキュメントの作成が操作できます。 function score すでに非常に便利なfunction_scoreクエリが、新しくweightパラメータをサポートします。 これは、それぞれの指定された関数の影響をチューニングするのに使われます。 これは、人気度よりも更新日時により重みをかけたり、地理情報よりも価格により重みをかけるといったことを可能にします。 また、random_score機能はセグメントマージによる影響を受けません。これにより、より一貫した順序が提供されます。\n試してみてください。 ぜひ、Elasticsearch 1.4.0.Beta1をダウンロードして、試してみてください。 そして、感想をTwitter(@elasticsearch)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1412244840,"dir":"post/2014/","id":"853cac0f2d1f90b7c986e7d1dcdbbfde","lang":"ja","lastmod":1412244840,"permalink":"https://blog.johtani.info/blog/2014/10/02/elasticsearch-1-4-0-beta-released-ja/","publishdate":"2014-10-02T19:14:00+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:elasticsearch 1.4.0.beta1 released 本日、Lucene 4.10.1をベースにした、Elast","tags":["Elasticsearch"],"title":"elasticsearch 1.4.0.Beta1のリリース"},{"contents":"第6回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 次回もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。 今回は、スタッフが私を含めて3,4名ということで、ドタバタしてしまってスミマセンでした。\n今回はキャンセルが多く、最終的には90人弱の参加となりましたが、今回も多数の方にお集まりいただきありがとうございました。 同じ日に他の勉強会もあった影響でしょうか?\n「Aggregationあれこれ」Elasticsearch Inc. Jun Ohtani @johtani スライド:Aggregationあれこれ\nちょっと長かったですかね。。。 Aggregationの概要、内部動作、種類などを簡単に紹介してみました。 個々のAggregationもいろいろなオプションなどがあるので、色々と試してみていただければと思います。 アニメーション入りのスライドになってましたが、UpしてあるスライドはPDF版になります。 「秒間3万の広告配信ログをElasticSearchでリアルタイム集計してきた戦いの記録」 株式会社サイバーエージェント 山田直行さん @satully スライド:秒間3万の広告配信ログをElasticSearchでリアルタイム集計してきた戦いの記録\nディスプレイ広告配信DSPの話 システム: Fluentd、S3、Elasticsearch、Redis、MySQL 7月に秒間3万〜4万のリクエストをさばいている。 なぜElasticsearchを選んだのか、今の構成など 実際に苦労された点なども交えて話していただき面白かったです。 7月時点のお話ということで、現時点ではまた違う構成っぽかったので、また話を聞きたいなぁ。 「Elasticsearch 日本語スキーマレス環境構築と、ついでに多言語対応」ナレッジワークス株式会社 木戸国彦さん @9215 スライド:Elasticsearch 日本語スキーマレス環境構築と、ついでに多言語対応\nDynamic TemplateやIndex Templateの説明 日本語や多言語化するときのMappingのサンプルになりそうなものがゴロゴロ紹介されてました。 いくつかの例があって、後で見直したいなと。 途中で出てきた、fielddata(インデックスに入っている単語区切りのデータ)を見るのに使ってたクエリはfield data fieldsだったかな。 「elasticsearchソースコードを読みはじめてみた」@furandon_pig さん スライド:elasticsearchソースコードを読みはじめてみた\nリクエストを受けて検索してる部分から読むといいって言われたらしいが、起動スクリプトから読み始めてみた。 時間かかりそうw ただ、人がどんな感じでソースを読んだり理解してるかがわかりやすかったので面白かったです。 定期的に続きを聞いてみたいです。 LT 「reroute APIを使用してシャード配置を制御する」 株式会社富士通ソフトウェアテクノロジーズ 滝田聖己さん @pisatoshi スライド:reroute APIを使用してシャード配置を制御する\nシャードの再配置が自動で行われるので、それをオフにしないと、せっかく移動しても無駄になることがというあるあるネタ Bonsaiロゴを作成するLT 実際にいくら掛かったのかが知りたかった。 「検索のダウンタイム0でバックアップからIndexをリストアする方法」株式会社ドワンゴモバイル 西田和史さん スライド:検索のダウンタイム0でバックアップからIndexをリストアする方法\n擬似無停止のやりかた。 aliasを活用して、かつ、Restoreで再構築するという方法。 aliasまで一緒にリストアされるので注意が必要っていうのは、実際にやってみたからわかることという感じですね。 その他、感想などのブログ 適当に見つけたブログを列挙してあります。これもあるよ!などあれば、教えてください。\n第6回elasticsearch勉強会に行ってきましたのでそのメモ elasticsearch 勉強会 第6回 まとめ 今回も、ためになる話がいっぱい聞けたかなと。 個人的な印象としては、いつものメンバーよりも新しい方が多かった印象です。 また、ほとんどの方が、Elasticsearchをご存知でした。 そこそこ知名度は上がってきているようで嬉しい限りです。(東京以外での知名度なども知りたいかなと。)\nあと、懇親会の部屋の案内が遅くなってしまってスミマセンでした。 さすがにスタッフ3名はきつかったです。。。\n19時半開始にしてみましたが、懇親会の時間がやはり短めになってしまうなぁという印象でした。\n次回ももちろん2ヶ月後くらいに行います。 スピーカー募集中ですので、コメント、メール、ツイートなど、コンタクトしていただければと思います。 よろしくお願いいたします。\n","date":1410927720,"dir":"post/2014/","id":"4616fbea6a6dbc1074bc3f1016bbc73b","lang":"ja","lastmod":1410927720,"permalink":"https://blog.johtani.info/blog/2014/09/17/hold-on-6th-elasticsearch-jp/","publishdate":"2014-09-17T13:22:00+09:00","summary":"第6回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん","tags":["elasticsearch","勉強会"],"title":"第6回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"先日2014年9月9日(火)に『サーバ/インフラエンジニア養成読本 ログ収集〜可視化編』 出版記念!執筆者が語る大講演会!で、 「elasticsearch.もうちょっと入門」というタイトルで発表してきました。 会場のGMOのみなさま、Treasure Data、技術評論社のみなさま、どうもありがとうございました。\n書籍に興味のある方は、右のリンクから購入してもらえるとうれしいです。Kindle版も用意されています。\n提供のTDの方に目をつぶってもらいながらLogstashについての発表となってしまいましたが、楽しんでいただけたかなぁと。 書籍では主にKibana3をメインにしたElasticsearchの使い方だったので、それ以外の機能ということで、Aggregationについて説明してみました。\nそのあとは、おそらく初めてですが、パネルディスカッションにも参加しました。 @naoya_itoさんをモデレーターに、rebuild.fm風に進めていただき、話しやすかったかなと。 (少なくとも私は楽しめました!) ただ、私だけバックグラウンドが少し異なることもあり、話をうまく繋げられなかったかもと気にしていたりもしますが。。。\nパネルディスカッションでもありましたが、エンジニアが「趣味」で入れて試してみるのにはもってこいのツール群だと思います。 ちょっと入れてみて、可視化をしてみるといろいろと発見があると思います。 何かを発見するためにもまず試してみるのが何事も重要かなと最近思ってるのもあるので、気軽に試してみてもらえればと。\n不明点などあれば、著者陣に気軽に聞いていただけると良いかと思います(いいですよね、みなさんw)。 Fluentd(もちろん、Logstashも)、Elasticsearch、Kibanaを利用して、データについて試行錯誤してもらって、 システムやビジネスに必要なものを探索して見てください。\n参考 他の方々のブログをメモとして。\nサービス改善とログデータ解析について発表してきました Kibanaではじめるダッシュボードについて発表してきました #gihyo_efk Fluentdのお勧めシステム構成パターンについて発表しました ","date":1410841260,"dir":"post/2014/","id":"f15702ae9e55bad42182cf18724d1863","lang":"ja","lastmod":1410841260,"permalink":"https://blog.johtani.info/blog/2014/09/16/book-publication-event/","publishdate":"2014-09-16T13:21:00+09:00","summary":"先日2014年9月9日(火)に『サーバ/インフラエンジニア養成読本 ログ収集〜可視化編』 出版記念!執筆者が語る大講演会!で、 「elastics","tags":["勉強会","本"],"title":"elasticsearch.もうちょっと入門という話をしてきました #gihyo_efk"},{"contents":"Elasticsearchのインデキシングに関するパフォーマンス検討\n原文:performance considerations for elasticsearch indexing\nElasticsearchユーザは様々な楽しいユースケースを持っています。小さなログを追加することから、Webスケールの大きなドキュメントの集合をインデキシングするようなことまでです。また、インデキシングのスループットを最大化することが重要で一般的な目標となります。 「典型的な」アプリケーションに対して良いデフォルト値を設定するようにしていますが、次のちょっとした簡単なベストプラクティスによってインデキシングのパフォーマンスをすぐに改善することができます。それらについて記述します。\n第一に、制御できないならば、巨大なJavaヒープを使用しない:必要なサイズ(マシンの持つRAMの半分以下)のheapだけを設定しましょう。Elasticsearchの利用方法のために必要な全体量を設定します。これは、OSにIOキャッシュを制御するためのRAMを残すことを意味します。OSがjavaプロセスをスワップアウトしていないことも確認しましょう。\n最新バージョン(現時点では1.3.2)のElasticsearchにアップグレードしましょう:多数のインデキシングに関連する問題点が最新リリースで修正されています。\n詳細に入る前に警告:ここで述べるすべての情報は現時点での最新(1.3.2)の情報です。しかし、Elasticsearchの更新は日々行われています。この情報をあなたが見た時点では最新ではなく、正確ではなくなっているかもしれません。自信がない場合はユーザメーリングリストで質問してください。\nクラスタのインデキシングスループットをチューニングする場合、Marvelは非常に有用なツールです:ここで述べている各設定を継続的に試し、変更の影響がクラスタの挙動をどのように変更されたかを簡単に可視化することが可能です。\nクライアントサイド bulk APIを常に使いましょう。1リクエストで複数のドキュメントをインデキシングでき、各バルクリクエストで送るのに良いドキュメント数を試しましょう。最適なサイズは多くの要因に依存しますが、最適サイズからずれるならば多すぎるよりも少なすぎる方が良いでしょう。クライアントサイドのスレッドで並列にbulkリクエストを使うか、個別の非同期リクエストを使ってください。\nインデキシングが遅いと結論付ける前に、クラスタのハードウェアの性能を引き出せているかを確認して下さい:すべてのノードでCPUやIOが溢れていないかを確認するためにiostatやtop、psといったツールを使いましょう。もし、溢れていなければ、より多くの並列なリクエストが必要です。しかし、javaクライアントからのEsRejectedExecutionExceptionや、RESTリクエストのHTTPレスポンスとしてTOO_MANY_REQUESTS (429)が返ってきた場合は並列リクエストを多く送りすぎています。もしMarvelを利用しているなら、Node Statistics DashboardのTHREAD POOLS - BULKにリジェクトされた数が表示されます。bulkスレッドプールサイズ(デフォルト値はコア数)を増やすのは得策ではありません。インデキシングスループットを減少させるでしょう。クライアントサイドの並列度を下げるか、ノードを増やすのが良い選択です。\nここでは、1シャードに対してインデキシングスループットを最大化する設定に注目します。1つのLuceneインデックスのドキュメントの容量を測定するために、単一ノード(単一シャード、レプリカなし)で最初にテストをして最適化し、クラスタ全体にスケールする前にチューニングを繰り返します。これはまた、インデキシングスループットの要件を見つけるために、クラスタ全体にどのくらいのノードが必要かをラフに見積もるためのベースラインを与えてくれます。\n単一シャードが十分機能したら、Elasticsearchのスケーラビリティの最大の利点や、クラスタでの複数ノードによるレプリカ数やシャード数の増加の利点が得られます。\n結論を導き出す前に、ある程度の時間(60分)くらいクラスタ全体の性能を計測しましょう。このテストは、巨大なマージ、GCサイクル、シャードの移動、OSのIOキャッシュ、予期しないスワップの可能性などのイベントのライフサイクルをカバーできます。\nストレージデバイス 当然ながらインデックスを保存するストレージデバイスはインデキシングの性能に多大な影響を及ぼします:\nSSDを利用する:これらは最も速いHDDよりも速いです。ランダムアクセスのための消費電力が低いだけでなく、シーケンシャルIOアクセスも高いです。また、同時に発生するインデキシング、マージや検索のための並列的なIOも高速です。 インデックスをリモートマウントされたファイルシステム(例:NFSやSMB/CIFS)上に配置しない:代わりにローカルストレージを使う 仮想化されたストレージ(AmazonのElastic Block Storageなど)に注意:仮想化されたストレージはElasticsearchで十分に動作します。また、十分早く簡単に用意できることから魅力的です。しかし、残念なことに、ローカルストレージと比較すると本質的に遅いです。最近の非公式なテストでは、最高の性能を持つプロビジョニングされたIOPSのSSDオプションのEBSでさえ、ローカルインスタンスにあるSSDよりも遅いです。ローカルインスタンスにあるSSDは物理マシン上のすべての仮想マシンから共有されてアクセスされます。もし他の仮想マシンが急にIOが集中した場合に不可解なスローダウンとなることがあることを覚えておいてください。 複数のSSDを複数のpath.dataディレクトリにインデックスをストライピング(RAID0のように):2つは同様で、ファイルブロックレベルでストライピングする代わりに、個別にインデックスファイルレベルでElasticsearchの\u0026quot;stripes\u0026quot;となります。これらのアプローチは、いづれかのSSDの故障によりインデックスが壊れるという、1シャードが故障する(IO性能を高速化することとトレードオフ)というリスクを増加させることに注意してください。これは、一般的に行うのに良いトレードオフです:単一シャードで最大のパフォーマンスを最適化し、異なるノード間でレプリカを追加すると、ノードの故障への冗長化ができます。また、snapshotやrestoreを使って保険のためにインデックスのバックアップを取ることもできます。 セグメントとマージ 新しくインデキシングされたドキュメントは最初にLuceneのIndexWriterによってRAMに保存されます。RAMバッファがいっぱいになった時もしくは、Elasticsearchがflushもしくはrefreshを実行した時など定期的にこれらのドキュメントはディスクに新しいセグメントとして書き込まれます。最後に、セグメントが多くなった時に、Merge PolicyとSuchedulerによってそれらがマージされます。このプロセスは連続的に生じます:マージされたセグメントはより大きなセグメントとなり、小さなマージが幾つか実行され、また、大きなセグメントにマージされます。これらがどのように動作するかをわかりやすく可視化したブログはこちらです。\nマージ、特に大きなマージは非常に時間がかかります。これは、通常は問題ありません。そのようなマージはレアで全体のインデックスのコストと比べればささいなものです。しかし、マージすることがインデキシングについていけない場合、インデックスに非常に多くのセグメントがあるような深刻な問題を防ぐために、Elasticsearchはやってくるインデキシングリクエストを単一スレッド(1.2以降)に制限します。\nもし、INFOレベルのログメッセージにnow throttling indexingと表示されていたり、Marvelでのセグメント数が増加しているを見た場合、マージが遅れているとわかります。MarvelはIndex Statistics dashboardのMANAGEMENT EXTENDEDの部分にセグメント数をプロットしており、それは、非常にゆっくりと指数対数的に増加しており、大きなマージが終了したところがのこぎりの歯のような形で見て取れます。\nセグメント数 なぜマージが遅れるのでしょう?デフォルトでElasticsearchはすべてのマージの書き込みのバイト数をわずか20MB/secに制限しています。スピニングディスク(HDD)に対して、これはマージによって典型的なドライブのIOキャパシティを飽和させず、並列に検索を十分に実行させることを保証します。しかし、もし、インデキシング中に検索をしない場合や、検索性能がインデキシングのスループットよりも重要でない場合、インデックスの保存にSSDを使用している場合などは、index.store.throttle.typeにnoneを設定して、マージの速度制限を無効化するべきです(詳細はこちらをご覧ください)。なおバージョン1.2以前には期待以上のマージIO制限の発生といったバグが存在します。アップグレードを!\nもし、不幸にもスピニングディスク(それはSSDと同等の並列なIOを扱えません)をまだ使っている場合、index.merge.scheduler.max_thread_countに1を設定しなければなりません。そうでない場合は、(SSDを支持する)デフォルト値が多くのマージを同時に実行させるでしょう。\n活発に更新が行われているインデックスでoptimizeを実行しないでください。それは、非常にコストの高い操作(すべてのセグメントをマージ)です。しかし、もし、インデックスにドキュメントを追加が終わった直後はオプティマイズのタイミングとしては良いタイミングです。それは、検索時のリソースを減らすからです。例えば、時間ベースのインデックスを持っており、新しいインデックスに日々のログを追加している場合、過去の日付のインデックスをオプティマイズするのは良い考えです。特に、ノードが多くの日付のインデックスを持っている場合です。\n更にチューニングするための設定:\n実際に必要のないフィールドをオフにする。例えば_allフィールドをオフ。また、保持したいフィールドでは、indexedかstoredかを検討する。 もし、_sourceフィールドをオフにしたくなるかもしれないが、インデキシングコストは小さい(保存するだけで、インデキシングしない)、また、それは、将来の更新や、前のインデックスを再インデキシングするために非常に価値があり、それはディスク使用率の懸念事項がない限り、オフにする価値はあまりない。それは、ディスクが比較的安価であるので価値がない。 もし、インデックスされたドキュメントの検索までの遅延を許容できるなら、index.refresh_intervalを30sに増やすか、-1を設定して、オフにする。これは、巨大なセグメントをフラッシュし、マージのプレッシャーを減らすことができる。 Elasticsearch 1.3.2(稀に、フラッシュ時に過度のRAMを使用するという問題を修正した)にアップグレードすることで、index.translog.flush_threshold_sizeをデフォルト(200mb)から1gbに増加し、インデックスファイルのfsyncの頻度を減らす。 MarvelにIndex Statistics dashboardのMANAGEMENTにフラッシュの頻度がプロットされている。 インデックスバッファサイズ 巨大なインデックスを構築中はレプリカ数を0にし、あとから、レプリカを有効にする。レプリカが0ということは、データを失った(ステータスがred)時に冗長性がないので、ノードの故障に注意すること。もし、optimize(ドキュメントの追加をすることがないので)を計画するなら、インデキシングが終わったあとで、レプリカを作成する前に実行するのが良いでしょう。レプリカはオプティマイズされたセグメントをコピーするだけになります。詳細はインデックス設定更新を参照。\nもし、ノードがヘビーなインデキシングを行っているだけなら、アクティブなシャードのインデキシングバッファに多くてい512MBをindices.memory.index_buffer_sizeに与えてください。(超えてもインデキシングのパフォーマンスは一般的には改善されません。)Elasticsearchはその設定(Javaヒープのパーセンテージもしくはバイト数)を受けて、min_index_buffer_sizeとmax_index_buffer_sizeの値を前提にノードのアクティブシャードに均等に割り当てます;大きな値はLuceneが最初のセグメントをより大きくし、将来的なマージのプレッシャーを減らすことを意味します。\nデフォルトは10%で、それで十分です;例えば、もし、5つのアクティブなシャードがノードにあり、ヒープが25GBの場合、各シャードは25GBの10%の1/5=512MB(すでに最大値)を持っています。ヘビーなインデキシングのあと、この設定をデフォルトに下げましょう。検索時のデータ構造のために十分なRAMを確保するために。この設定はまだ動的な設定変更はできません。Issueがここにあります。\nインデックスバッファによって現在利用されているバイト数は1.3.0のindices stats APIに追加されています。indices.segments.index_writer_memoryの値を見ることができます。これはMarvelではまだプロットされていませんが、将来のバージョンで追加される予定です。しかし、自分でグラフに追加することもできます。(Marvelはデータは収集しています)\n1.4.0では、indices.segments.index_writer_max_memoryとして、indices stats APIにアクティブシャードにどのくらいのRAMバッファが割り当てられているかも表示されます。これらの値はインデックスのシャード事の値として見ることができ、http://host:9200/\u0026lt;indexName\u0026gt;/_stats?level=shardsを使ってみることができます;これは、全シャードに対する合計と、各シャードごとのstatsを返すでしょう。\nオートIDの利用もしくは良いIDの利用 もし、ドキュメントのIDがなんでも良い場合、Elasticsearchで採番することができます:これは、(1.2以降)ドキュメントIDをバージョンを探さずに保存できるように最適化され、Elasticsearchの日毎のベンチマークで異なるパフォーマンスを見ることができます。(FastとFastUpdateのグラフを比較)\nもし、IDを自身が持っていて、自分の支配下でLuceneに対して素早く選ぼうとしているなら、1.3.2にアップグレードしましょう、IDのルックアップがさらにオプティマイズされています。JavaのUUID.randomUUID()はやめましょう。それは、セグメントに対してどのようにIDを割り当てるかという予測やパターン性がないため、最悪のケースでセグメントごとのシークが発生します。\nFlake IDsを利用した時のMarvelによるインデックス性能の違い:\nflakeIDsPerf ランダムUUIDを利用した場合:\nuuidsPerf 次の1.4.0では、ElasticsearchのID自動採番をUUIDからFlake IDに変更します。\nもし、Luceneのローレベル操作がインデックスに対してなにをやっているかについて興味があるなら、lucene.iwをTRACEログレベルで出力できるようにしてみましょう(1.2から利用可能)。これは、多くの出力がありますが、LuceneのIndexWriterレベルで何が起きているかを理解するのに非常に役に立ちます。出力は非常にローレベルです:Marvelがインデックスに何が起きているかをよりリアルタイムにグラフを描画してくれます。\nスケールアウト 我々は、単一シャード(Luceneインデックス)性能のチューニングに注目してきました。しかし、一旦それに満足できたならば、Elasticsearchはクラスタ全体にわたってインデキシングや検索を簡単にスケールアウトすることに長けています。シャード数(デフォルトでは5)を増やすのは可能です。それは、マシン全体に対して並列度、巨大なインデックスのサイズ、検索時のレイテンシの低下など得ることができます。また、レプリカを1位上にすることは、ハードウェア故障に対する冗長性を持つことを意味します。\n最後に、このドキュメントを見ても問題解決しない場合はコミュニティに参加しましょう。例えば、ElasticsearchのユーザMLに投稿するなど。おそらく、修正すべきエキサイティングなバグがあるでしょう。(パッチも常に歓迎です!)\n","date":1410250260,"dir":"post/2014/","id":"77d965afaebd7193badc746d52b4173f","lang":"ja","lastmod":1410250260,"permalink":"https://blog.johtani.info/blog/2014/09/09/performance-considerations-for-elasticsearch-indexing/","publishdate":"2014-09-09T17:11:00+09:00","summary":"Elasticsearchのインデキシングに関するパフォーマンス検討 原文:performance considerations for elasticsearch indexing Elasticsearchユーザは様","tags":["Elasticsearch"],"title":"Elasticsearchのインデキシングに関するパフォーマンス検討"},{"contents":"懲りずにまた、執筆してみました。みなさん「買って」から感想をいただけるとうれしいです!\n本書について 共著者の方々のブログが詳しいので、そちらを読んでもらいつつ。 実際にログを収集して解析されている方々と一緒に書かせていただくことで色々と勉強させていただいています。\n共著者の方々のブログ @suzu_vさん:サーバ/インフラエンジニア養成読本 ログ収集~可視化編 を書きました @yoshi_kenさん:ログ収集や可視化で話題のFluentd、Elasticsearch、Kibanaを徹底解説したムック本が発売となります @harukasanさん:書きました: サーバ/インフラエンジニア養成読本 ログ収集~可視化編 どの辺を書いたの? 「特集3:Elasticsearch入門」(なんか、入門ばっかりだなぁ)を書かせていただきました。 データストア入門ということで、ほんとうに簡単な他のデータストアを説明し、Elasticsearchってどんなものかを単語の説明をしつつ紹介してみました。\nElasticsearch自体は多くの機能を持っており、それ単体で分厚い書籍がかけるので、ログ検索に関係ありそうな部分をピックアップしてみました。 あとは、運用時に気をつける点や便利なツール(Curatorなど)の紹介をしています。\nまた、Hadoopと合わせて利用してみたい、すでにHadoopにあるデータも活用してみたいという話もありそうだということで、elasticsearch-hadoopについても簡単ですが紹介してあります。\nその他感想 個人的に、忙しい時期(参考記事)だったので、あんまり力になれてないので大変申し訳なく思っています。。。 ただ、素晴らしい出来(カラーでKibanaの解説が日本語で読めたり、Fluentdの逆引きのリストがあったり、ログを貯めて可視化する意義を説明してあったり)です。\nぜひ、読んだ感想をいただければと!\n","date":1407156840,"dir":"post/2014/","id":"bdea71d64cdfcc405e65e750fe8d9b86","lang":"ja","lastmod":1407156840,"permalink":"https://blog.johtani.info/blog/2014/08/04/release-magazine-book-of-log-aggs-and-viz/","publishdate":"2014-08-04T21:54:00+09:00","summary":"懲りずにまた、執筆してみました。みなさん「買って」から感想をいただけるとうれしいです! 本書について 共著者の方々のブログが詳しいので、そちらを","tags":["elasticsearch","kibana","本"],"title":"サーバ/インフラエンジニア養成読本 ログ収集~可視化編 を手伝いました"},{"contents":"Proxy環境で働いている方も結構いると思います。 Twitter上で、Elasticsearchのpluginコマンドでプラグインがインストールできなくて困っている方がいたので、 調べてみたのでメモしておきます。\nプラグインコマンド Elasticsearchでは、プラグインという形でいくつかの便利な機能が公開されています。 形態素解析ライブラリのKuromojiを使うためのプラグインや、クラスタの管理がGUIで可能なkopfプラグインなどがあります。 公式、サードパーティいろいろです。\nこれらのプラグインをElasticsearchにインストールする場合、以下のコマンドを実行すれば 自動的にダウンロードしてpluginsディレクトリにインストールしてくれます。\n./bin/plugin -i elasticsearch/elasticsearch-analysis-kuromoji/2.3.0 ここで、elasticsearch/elasticsearch-analysis-kuromoji/2.3.0がプラグインのパスになります(例では、提供元/プラグイン名/プラグインバージョンとなっています。)。\nこのpluginコマンドがダウンロード元にアクセスに行くのですが、プロキシ環境だとプロキシの設定が必要になります。\nプロキシの指定(Mac/LinuxとWindowsでの違い) Mac/Linux(shコマンド) 以前の記事でプロキシのポート番号などの指定方法を 以下のように説明していました。 (※昔の記事のため、kuromojiプラグインのバージョンが古いです)\nElasticsearchのpluginコマンドはJavaで実装されています。(org.elasticsearch.common.http.client.HttpDownloadHelper) プラグインのダウンロードには、java.net.URL.openConnection()から取得URLConnectionを使用しています。\nですので、pluginのインストールを行う際に、Proxy環境にある場合は以下のようにコマンドを実行します。\n./bin/plugin -DproxyPort=ポート番号 -DproxyHost=ホスト名 -i elasticsearch/elasticsearch-analysis-kuromoji/1.5.0 LinuxやMacの環境であれば、こちらのコマンドでプロキシの指定が可能です。 ただし、Windows環境ではうまくいきません。\nElasticsearchは、環境の違いにより、ダウンロードするファイルが異なります。 Windows環境の方は、zipファイルをダウンロードしてもらうようになっています。 elasticsearchコマンドおよびpluginコマンドがbat形式で提供されているのがzipファイルとなるからです。\nWindows(batコマンド) Windows環境では次のように指定します。\nset JAVA_OPTS=\u0026#34;-DproxyHost=ホスト名 -DproxyPort=ポート番号\u0026#34; bin\\plugin -i elasticsearch/elasticsearch-analysis-kuromoji/2.3.0 コマンドの実装方法が少し異なるために、このようになっています。\nまとめ プロキシ環境で利用される場合は、プラグインコマンドは上記のように実行していただければと。\n公式ガイドには、これらの情報を追記するPRを送る予定です。 また、WindowsのコマンドでもMac/Linuxと同様にできたほうがいい気がするので、Issueをあげようと思います。\n不明点などあれば、コメントいただければと。\n","date":1406874240,"dir":"post/2014/","id":"7cc605e721fdd1d2ccc16f5b6490e830","lang":"ja","lastmod":1406874240,"permalink":"https://blog.johtani.info/blog/2014/08/01/plugin-using-under-proxy-env/","publishdate":"2014-08-01T15:24:00+09:00","summary":"Proxy環境で働いている方も結構いると思います。 Twitter上で、Elasticsearchのpluginコマンドでプラグインがインスト","tags":["elasticsearch","plugin"],"title":"プロキシ環境でのpluginコマンドの実行"},{"contents":"原文:Elasticsearch 1.3.1 Releasedを日本語に翻訳したものです。\nバグフィックス版のElasticsearch 1.3.1をリリースしました。 ダウンロードおよび変更履歴はElasticsearch 1.3.1からお願いいたします。\nこのリリースはインデックスリカバリ時の後方互換性バグ(#7055)への対応です。 このバグはデータの欠損は起こりません。 Elasticsearch 1.3.1へアップグレードすることで問題を回避できます。 このバグは、以下のElasticsearchのバージョンで作成されたセグメントを含むインデックスを1.3.0へアップグレードしようとすると発生します。\nElasticsearch 0.90.7 Elasticsearch 0.90.2 Elasticsearch 0.90.0以前のバージョン このバグは、これらの古いインデックスをレプリカからリカバリできなくします。 これらのバージョンのセグメントを持つインデックスが、レプリカは可能ですが、 ステータスがYellowのままGreenに決してなりません。 ログには次のようなExceptionが発生します。\nIllegalArgumentException[No enum constant org.apache.lucene.util.Version.x.x.x]\nLuceneの特定のバージョンではLuceneのマイナーバージョンを含んでおらず、誤ったバージョン番号がセグメントに記録されました。 LUCENE-5850のチケットがこの問題に対処するためにオープンされています。 この問題は我々の後方互換テストで見つかるべき問題ですが、Luceneで不足しているため発見されませんでした。 テストスイートは今後の可能性のために改良されます。\nこのリリースはその他に、Aggregationのマイナーバグフィックスも含まれています。 詳細はリリースノートをご覧ください\nElasticsearch 1.3.1をダウンロードし、試してください。 もし問題を見つけた場合はGitHubのIssuesへご報告をお願いいたします。\n","date":1406604120,"dir":"post/2014/","id":"fb1da4a6ed74705ad98bb60ad4badaf2","lang":"ja","lastmod":1406604120,"permalink":"https://blog.johtani.info/blog/2014/07/29/elasticsearch-1-3-1-release/","publishdate":"2014-07-29T12:22:00+09:00","summary":"原文:Elasticsearch 1.3.1 Releasedを日本語に翻訳したものです。 バグフィックス版のElasticsearch 1.3.1をリリー","tags":["elasticsearch","release"],"title":"Elasticsearch 1.3.1 リリース(日本語訳)"},{"contents":"Curatorの1.2.0がリリースされました。\n前回のCuratorの記事が古くなってしまった(1.1.0からコマンドのI/Fが変更された)ので 1.1.0および1.2.0に関する記事を翻訳しておきます。\nちなみに、Curatorとは、Elasticsearchに時系列のインデックス(例:LogstashやFluentdでログを保存)を保存している場合にそれらのインデックスを管理(削除したり、クローズしたり)するための便利なツールです。 Curatorの概要については、GitHubリポジトリか前回の記事をご覧ください。\nCurator 1.1.0リリース (2014/06/13公開) 元記事:elasticsearch curator - version 1.1.0 released\nElasticsearch 1.0.0がリリースされ、新しい機能、Snapshot \u0026amp; Restoreが利用できるようになりました。 Snapshotはある時点でのインデックスの写真を撮るように、バックアップを作成することができます。 1.0.0が発表されてすぐに、この機能に関するリクエストが寄せられるようになりました。 「Curatorにスナップショットを追加して!」もしくは「いつCuratorでスナップショットが使えるようになる?」といった感じです。 これがあなたの要望なら、それはついに叶えられました。しかも他の追加機能も一緒にです。\n新機能 Curatorの新機能は以下のとおりです。\n新CLI構造 スナップショット(Snapshot) エイリアス(Aliases) パターンによる除外インデックス指定 配置ルーティング(Allocation Routing) インデックスとスナップショットの表示 リポジトリ管理(個別のスクリプトによる) ドキュメントWiki 新コマンドライン構造 注意:コマンドライン構造の変更とは、Curator 1.1.0以前のcron記述が動作しないことを意味します。Curator 1.1.0にアップグレードする場合はコマンドも修正が必要となるので注意してください。\nシンプルにするために、commandsという概念を追加しました。 また、ヘルプの出力もわかりやすくなっています。 前のバージョンと同じタスクをCuratorは実行できますが、異なるフォーマットを用いるようになりました。\n旧コマンド:\ncurator -d 30 新コマンド:\ncurator delete --older-than 30 コマンドは、フラグとは異なりハイフンを前に付けないことに注意してください。 また、似たような名前のフラグがあることに気をつけてください。 例えば、--older-thanフラグは多くのコマンドに利用できます。 指定される値は各ケースにおいて同一です。「指定された数よりも古いインデックス」となります。\n新しいコマンドのリストは次のとおりです。\nalias allocation bloom close delete optimize show snapshot コマンドのヘルプは次のコマンドで表示されます。\ncurator [COMMAND] --help コマンドに関係あるフラグがすべて表示されます。\nスナップショット(snapshots) snapshotコマンドで、存在しているリポジトリにインデックスのスナップショットを保存することができます。\nCuratorはインデックス毎に1つのスナップショットを作成し、インデックスから名前をつけます。 例えば、インデックスの名前がlogstash-2014.06.10の場合、スナップショットの名前はlogstash-2014.06.10となります。 指定した条件を元に、シーケンシャルに、1つずつインデックスのスナップショットを作成していきます。\ncurator snapshot --older-than 20 --repository REPOSITORY_NAME このコマンドは、20日以上古いインデックスすべてのスナップショットを作成し、REPOSITORY_NAMEで指定されたリポジトリに保存します。\nes_repo_mgrと呼ばれるリポジトリ作成を支援するスクリプトがCuratorには含まれています。 ファイルシステムおよびS3タイプのリポジトリ両方の作成を支援します。\nさらに、古いインデックスのスナップショットを取ることができることに加えて、Curatorは最新のインデックスをアップロードする方法も提供します。 これは、Elasticsearch Marvelのインデックスをアップロードするときに便利です。 トラブルシューティングを目的として、パフォーマンスデータを他の人に見せる場合などです。\ncurator snapshot --most-recent 3 --prefix .marvel- --repository REPOSITORY_NAME このコマンドでは、最新の3つのMarvelインデックスのスナップショットを指定されたリポジトリに保存できます。\nエイリアス(aliases) Curatorはすでに存在するエイリアスにインデックスを追加することも、削除することもできるようになりました。 ただし、エイリアスがすでに存在している必要があります。エイリアスの作成はできません。\nlast_weekという前の一週間のインデックスのエイリアスを保持していること想像してください。 この場合、次の2つのコマンドを利用することで、エイリアスを管理できます。\ncurator alias --alias-older-than 7 --alias last_week curator alias --unalias-older-than 14 --alias last_week 新しく作られたインデックスがインデックステンプレートによって 自動的にエイリアスの一部となるようにElasticsearchに設定しておくと、さらに便利です。 この場合、新しいインデックスが自動的にthis_weekというエイリアスの一部になるようにしてあれば、以下のコマンドのみとなります。\ncurator alias --unalias-older-than 7 --alias this_week this_weekとlast_weekのエイリアスのアップデートを保持できます。\nパターンによる除外(exclude pattern) 時には、指定したインデックスを操作から除外したくなる場合もあるでしょう。 ここまでは、プレフィックスや日付によって選択されたインデックスのみを対象にしてきました。 そこで、--exclude-patternオプションです。これは、指定したインデックスを除いて処理を行うことができます。\nlogstash-2014.06.11というインデックスを決して削除したくないとします。 この場合、次のコマンドのようになります。\ncurator delete --older-than 15 --exclude-pattern 2014.06.11 Curatorはデフォルトでlogstash-というプレフィックスにマッチしますが、2014.06.11というインデックスは対象外となります。\n配置ルーティング(allocation routing) Elasticsearchはノードにタグを付けることができます。 これらのタグはインデックスやシャードをクラスタのどこに配置するかをコントロールするために役立ちます。 一般的なユースケースだと、高性能なSSDドライブを持ったノードをインデキシングのために、ハードディスクを持った性能の低いマシンは検索頻度が低い古いインデックスを配置するといった場合です。 この場合、HDDノードには、elasticsearch.ymlにnode.tag: hdd、SSDノードにはnode.tag: ssdと設定されているべきです。 Curatorはこの時、インデックスをタグに基づいてオフピークの時間帯に再配置させることができます。\nコマンド:\ncurator allocation --older-than 2 --rule tag=hdd index.routing.allocation.require.tag=hddという設定が2日よりも古いインデックスに適用されます。 これは、インデックスのシャードがnode.tag: hddというノードに再配置される必要があると、Elasticsearchに伝えます。\nインデックスとスナップショットの表示(show indices and snapshots) これは、単にあなたの持っているインデックスやスナップショットがどんなものかを表示します。\ncurator show --show-indices これは、デフォルトプレフィックスのlogstash-にマッチするすべてのインデックスを表示します。\ncurator show --show-snapshots --repository REPOSITORY_NAME これは、指定されたリポジトリにある、デフォルトプレフィックスのlogstash-にマッチするすべてのスナップショットを表示します。\nリポジトリ管理(repository management) 前に説明したとおり、es_repo_mgrと呼ばれるヘルパースクリプトをCuratorは含んでいます。 現時点では、fsとs3タイプをサポートしています。 リポジトリを作る前に利用したいタイプのドキュメントを読むようにしてください。 例えば、fsタイプのリポジトリを各ノードで使う場合は、同じ共有ファイルシステムに、同じパスでアクセスできなければなりません。 パスの指定は--locationです。\nfsタイプリポジトリの作成\nes_repo_mgr create_fs --location \u0026#39;/tmp/REPOSITORY_LOCATION\u0026#39; --repository REPOSITORY_NAME 削除\nes_repo_mgr delete --repository REPOSITORY_NAME ドキュメントWiki Curatorのドキュメントが更新され、オンラインにWiki形式でだれでも更新できるようになっています。 コマンドやフラグのより詳細の情報はこちらで見つけることができます。また、もし、興味があれば、ドキュメントを追加することもできます。\nインストールと更新 Curator 1.1.0はPyPiリポジトリにあります。 インストールは以下のとおりです。\npip install elasticsearch-curator バージョン1.0.0からアップグレードする場合は以下のとおりです。\npip uninstall elasticsearch-curator pip install elasticsearch-curator バージョン1.0.0よりも古いバージョンからのアップグレードは以下のとおりです。\npip uninstall elasticsearch-curator pip uninstall elasticsearch pip install elasticsearch-curator pip uninstall elasticsearchで、古いパイションモジュールをを削除します。 適切なバージョンが依存関係により再インストールされます。\nまとめ Curatorの新機能は素晴らしいです!このリリースは大きな改善です。 もし、トラブルや足りないものを見つけた場合はGitHub Issueに報告してください。 また、Curatorが便利だと思ったら、私たちに伝えてください。#elasticsearchタグを付けてツイートしてください!\nCuratorはまだ、始まったばかりです。Curator 2.0のロードマップを作業中です。ここまで読んでいただきありがとうございます。 Happy Curating!\nCurator 1.2.0リリース(2014/07/24) 元記事:curator 1.2.0 released\nCurator v1.1.0のリリースから、数週間が経ちました。 私たちは、Curator 1.2.0をリリースしました。\n新機能(new features) ユーザ指定の日付パターン:長い間リクエストされていた機能 ウィークリーインデックスのサポート:これも長い間リクエストされていた機能 複数のログフォーマットオプション:Logstashフォーマットが利用可能 これらの変更はCuratorドキュメントにも記載されています。\n更新(updates) ログ出力の整理:デフォルトのログ出力を整理しました。デバッグログはすべて表示されます。 ドライランのログ出力の詳細化:テスト実行時に何が起きたかをわかりやすくしました。 日付パターンと--timestring(date patterns and \u0026ndash;timestring) 前のリリースで、セパレータ文字を利用して、インデックス名のエレメントを分離することで、日付を計算しました。 この設計の決定は、プログラムが管理するために設計されたLogstashのインデックスを使うのには簡単でした。 しかし、Curatorは時系列インデックス管理に成長しています。これは、異なる命名規則のインデックスを意味しています。\nまた、インターバルによって、日付の計算が必要になる場合もあります。 --time-unitオプションが残っており、weeksという単位を指定することもできます。 デフォルトの--timestringオプションは、以前のコマンドと同様の動作をしなければなりません。次のようになります。\nTime Unit Timestring days %Y.%m.%d hours %Y.%m.%d.%H weeks %Y.%W これが意味するものは、もし、単位にhoursをした場合、--timestringを指定しなかった場合は%Y.%m.%d.%Hとなります。 これは、Pythonのstrftimeフォーマットで\u0026quot;年.月.日.時\u0026quot;を意味します。 同様に、weeksを単位に指定した場合、Curatorはデフォルトの--timestringは%Y.%Wとなります。\nこの機能は、日付の間にセパレーター文字のないインデックスでも機能します。 例えば、production-20140724のような日時インデックスがある場合、2日よりも古いインデックスに対するブルームフィルタっキャッシュのオフのコマンドは次のようになります。\ncurator bloom --prefix production- --older-than 2 --timestring %Y%m%d この例で、デフォルトの単位はdaysであることに注意してください。hourly-2014072414のような時間インデックスの場合は次のようになります。\ncurator bloom --prefix hourly- --older-than 2 --time-unit hours --timestring %Y%m%d%H --separatorの置き換え もし、Curatorの前のバージョンでカスタムセパレータ文字を利用していた場合、次のように変更すべきです。 前のコマンドでcerberus-2014-07-24のようなインデックスがある場合、コマンドを--separator -の用に置き換える必要があります。 新しいコマンドは次のとおりです。\ncurator delete --prefix cerberus- --older-than 30 --timestring %Y-%m-%d 年(%Y)と月(%m)と日(\u0026rsquo;%d\u0026rsquo;)の間にセパレータ文字を置くだけです。\nこれは、また、Curatorで以前は不可能であったことをできるようにもします。 異なるセパレータ文字の混在です。 logs-2014.07.24-14というようなインデックスを処理するときに--timestringは%Y.%m.%d-%Hのようになります.\n--timestringの詳細はCuratorのドキュメントをご覧ください。\nフィードバック これらの新しい機能はユーザのコメントやリクエストから来ています。もし、機能のリクエストやバグを発見したら、こちらまで連絡してください。\nまた、Twitterでもお待ちしています。私たちのTwitter IDは@elasticsearchです。\nHappy Curating!\n","date":1406524740,"dir":"post/2014/","id":"0c1821d1069578551d0e3c7d9275f16b","lang":"ja","lastmod":1406524740,"permalink":"https://blog.johtani.info/blog/2014/07/28/curator-2-0-and-1-1/","publishdate":"2014-07-28T14:19:00+09:00","summary":"Curatorの1.2.0がリリースされました。 前回のCuratorの記事が古くなってしまった(1.1.0からコマンドのI/Fが変更された)","tags":["elasticsearch","curator"],"title":"Curator 1.2および1.1について"},{"contents":"第5回Elasticsearch勉強会を開催しました。 遅くなってしまいましたが、まとめてみました。\n今回は、Elasticsearchに入って初の勉強会でした。タイミングが良いことに、Honza、Igor、Shayの3名がトレーニングのために 来日していたため、特別回ということにして、話をしてもらいました。\nそして、サムライズムの@yusukeさんにテキスト翻訳してもらいました。 早くて正確なタイピング+翻訳、本当にありがとうございました。\n開場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 次回もよろしくお願いします! 参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\namazing turnout to the elasticsearch at Tokyo #elasticsearchjp pic.twitter.com/Aa88eVf5dF\n\u0026mdash; Shay Banon (@kimchy) 2014, 7月 14 動画があとで、アップされる予定です。お楽しみに。\nHonza\u0026rsquo;s talk djangoの開発者!であり、ElasticsearchのPythonクライアント、Curatorの開発者 Python Clientを利用しながら、ライブコーディングのような形で説明する方法が新鮮 Aggregationの便利さについての説明 Python Clientがクエリを組み立てるのにすごく便利そうだった Pythonユーザが結構いたので助かりましたw Igor\u0026rsquo;s talk スライド:elasticsearch data/\nSnapshot/Restoreの開発などを行っている開発者 Elasticsearchのデータ、ディレクトリ構造に関するお話 シャードの話から、ディレクトリ構造、メタデータに関する説明 transaction logの挙動の説明 検索のフェーズの説明 Igorは、実は私がElasticsearch社の人とコンタクトがとれた最初の人だと思います。 第1回Elasticsearch勉強会が開催する当日に帰国されるという不運だったのですが、1年越しでトークしてもらえました!\n@johtani I am so bummed! I am leaving Tokyo Thursday morning.\n\u0026mdash; Igor Motov (@imotov) 2013, 8月 27 QA ShayをメインにいくつかのQAをしてもらいました。 NetflixなどのMeetupの動画で見てたのですが、こんな形で日本でも実現できるとは。\nQ: なんで、ファイルデスクリプタの設定を大きくするの? A: Luceneのインデックスは複数のセグメントから構成されている。メモリに作られたあと、ファイルにfsyncされる。 Q: KibanaでAggregation使いたいんだけど? A: Kibana 4で対応するよ!異なるフィールドの値を1つのグラフにすることも出来るよ! Q: なんでElasticsearch作ったの? A: 暇だったからw奥さんのレシピ検索を作ってみようと思って作り始めて、Luceneを触って感動して。。。検索すげー、Compassってのを触ってこれもすごいと思いつつ、もっとLucene活用できるんじゃないかということでElasticsearch作ったんだ。奥さんのレシピ検索?まだ完成してないよw Q: 2000くらいスナップショット撮ったらパフォーマンスが悪くなっててなんで? A: 差分でスナップショットを作るんだけど、差分の計算に昔のスナップショットを見るので、定期的に新しくしたほうがいい。もし、気になることがあったらIssue上げたりMLに投げてくれるとうれしい。\n(あとでちょっと聞いたけど、古いスナップショットを消すのも有効っぽい。差分でスナップショットを作るけど、昔のを消した場合は、新しいスナップショットが利用しているファイルは残る仕組みになっているから。) Q: Relevancyのチューニングってどうすればいい?ドキュメントが少なくない? A: ドキュメンテーションは頑張ってるので、応援してねwあとは、definitive guideも参考になるよ。スコアはfunction_scoreクエリがすごいのでいろいろ使ってね。MVELをGroovyに帰る予定。性能もだけど、サンドボックス的な意味もあります。 Q: 次のVisionは?現時点は検索だけど。(最後の質問がとてもナイスで、助かりましたw私がしたほうがいい気がするww) A: 今後はアナリティクスのプラットフォームに向かってる。Aggregationとかね。メモリ効率よくしたりしてるよ。あとは、Field-collapsionも実装中だよ。あと、マシンラーニングとかもね。データを探索するための機能を色々作ってくよ。障害性にも。チェックサム機能をLuceneに入れて、ESにも入れていく予定。Zenの機能も改善している。 まとめ 今週は、トレーニングがあったり、いろいろな打ち合わせがあったりと、テンパってたので至らない点が多かったかもしれないですが。。。 楽しんでいただけと思います。 数日、Shay、Honza、Igorと行動を共にして、本当に情熱のあるチームでユーザのことを気にかけているなと感じることができました。 少しでもその片鱗を勉強会で感じてもらえたんじゃないかと。特に、QAでのShayによる情熱が伝わったんじゃないかと。\n懇親会でも数人の方から、日本語のサポートを望んでいるという声も頂きました。 興味のある方は私までコンタクトいただければと。\nあと、@yusukeさんのテキスト翻訳が素晴らしくて、参加してもらった方たちも絶賛してました。 次回も英語スピーカーの場合に助けてもらえると嬉しいです(私もそこまで出来るように頑張ります)\nその他のブログ ブログ記事ありがとうございます!\n第5回elasticsearch勉強会にいってきました - はやさがたりない。 感想戦:aggrigation から見える検索エンジンの次 - 第5回 Elasticsearch勉強会 - よしだのブログ 「第5回elasticsearch勉強会 #elasticsearch #elasticsearchjp」(2014年07月14日)の参加メモ - uchimanajet7のメモ ","date":1405774320,"dir":"post/2014/","id":"e3e146469ed4318eaa2ffbca3510c054","lang":"ja","lastmod":1405774320,"permalink":"https://blog.johtani.info/blog/2014/07/19/hold-on-5th-elasticsearch-jp/","publishdate":"2014-07-19T21:52:00+09:00","summary":"第5回Elasticsearch勉強会を開催しました。 遅くなってしまいましたが、まとめてみました。 今回は、Elasticsearchに入って","tags":["elasticsearch","勉強会"],"title":"第5回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"ということで、転職しました。 どーしてもやりたいことが出てきたので、無理を言って転職することにしてみました。\nサムライズムではなく、Elasticsearchにジョインします。(というか、しました。)\n初出社 #サムライズム\n\u0026mdash; Jun Ohtani (@johtani) 2014, 7月 1 冗談でツイートしたのですが、その前に英語アカウントのツイートがRTされてしまっていまいちでした。。。\nスキポール空港 先週、アムステルダムに行っていたのも退職前に休みをいただき、Elasticsearchの全社会議に参加していたためです。 とてもエキサイティングな経験(英語漬けとか)ができ、もっと精進しないとなという気持ちにもなり、ますます頑張らないとなと。\nということで、今後は日本中にElasticsearchやLogstash、Kibanaを広めるべく、いろいろな場所で話をしたいと思います。 興味のある方は、声をかけていただければと。\nあと、東京でElasticsearchのCoreトレーニングが行われます。 通常は2日間ですが、通訳の方が付く関係で3日間の開催となっています。 開発者2名がトレーナーとして来日します。開発者に質問をできる良い機会ですので、興味のある方は参加してみてはいかがでしょうか。 また、CTOのShay Banonも来日する予定です。\nトレーナー2名とShayは7/14の勉強会でも話をしてくれます。 こちらも興味のある方は参加してみてください。(参加登録はこの後、すぐに開始します。)\nまだまだ、勉強しなければいけないことだらけですが、ElasticsearchのいろいろなプロダクトやOSSについて広めていきたいと思いますので、よろしくお願いいたします。\nおまけ ということで、一度やってみたかったのでリンクを貼ってみます。\nほしい物リストはこちら\n","date":1404181800,"dir":"post/2014/","id":"21a8e6324e9330d4f8ebade604c62b6e","lang":"ja","lastmod":1404181800,"permalink":"https://blog.johtani.info/blog/2014/07/01/join-elasticsearch/","publishdate":"2014-07-01T11:30:00+09:00","summary":"ということで、転職しました。 どーしてもやりたいことが出てきたので、無理を言って転職することにしてみました。 サムライズムではなく、Elasti","tags":["転職"],"title":"転職しました"},{"contents":"退職しました。\n色々と書きたいんですが、時差ボケで頭痛いので、このくらいです。 余裕出たら書くかも。\nほしい物リストはこちら\n新天地についてはまた明日。\n","date":1404137940,"dir":"post/2014/","id":"40abea0a87a64bd832a1fad69458b293","lang":"ja","lastmod":1404137940,"permalink":"https://blog.johtani.info/blog/2014/06/30/resignation/","publishdate":"2014-06-30T23:19:00+09:00","summary":"退職しました。 色々と書きたいんですが、時差ボケで頭痛いので、このくらいです。 余裕出たら書くかも。 ほしい物リストはこちら 新天地についてはまた明","tags":["転職"],"title":"退職しました"},{"contents":"Elasticsearch server 2nd editionが発売されています。\n私が翻訳したのは前のバージョンですが。。。 まずは、目次を元にどのくらい変わってるかを見てみました。 (全部まだ読んでなくて。。。)\n1章 Getting Started with the Elasticsearch Cluster 冒頭に、全文検索とは、転置インデックスとはどんなものか、 Luceneの簡単なアーキテクチャの仕組みについて説明が追加されています。 検索の仕組みを知らない人が読んでもわかりやすくなっています。\nインストール方法なども少し追記されています。 バージョニングと簡単なデータ登録と検索方法についてもここで触れられています。 検索結果の構造の説明もちょっとあります。 まず簡単に触ってみるというところまでが1章でまとめられた感じです。\n2章 Indexing Your Data 新しく、切りだされた形です。 前のバージョンでは1章で説明されていた、Mapping周りが切りだされています。 シャードやレプリカの説明もこちらです。\nIPアドレスタイプ(IPv4のみ)とtoken_countタイプの説明も追加されてます。 similarityやpostingsフォーマットなどは新しく追記されています。 また、メタフィールドと呼ばれる_typeなどはこちらに移動しているようです。 マージ処理などの説明も追記されています。このあたりは、Mastering ElasticSearchに 記載されているものが移植された感じでしょうか。\n3章 Searching Your Data 前のバージョンでは2章だった章です。 クエリについては1.0で追加されたsimple_query_stringなどが追記されています。 constant_scoreやdismaxなどもです。\nまた、前のバージョンの3章で説明されていたハイライトや8章で触れられていたvalidate APIについても 移動しています。\n4章 Extending Your Index Structure 前のバージョンの3章で触れられていた、データの構造に関する部分がこの章になります。 親子や配列、ネスト等のデータのインデックスや検索の方法です。\n5章 Make Your Search Better スクリプティングや言語判定などの仕組みが記載されています。 また、ブーストについても同様です。Synonymについてもここです。 スパンクエリについては省略されたのかな?\n6章 Beyond Full-text Searching 1.0の目玉機能の一つであるAggregationの説明から始まります。 その後、ファセットやPercolatorについてです。メモリに関する注意点もありそうです。 また、Geoについての説明がこちらに移動されていました。 scroll APIについてもこちらで説明されています。\n7章 Elasticsearch Cluster in Detail 前の7章で記載されていたElasticsearchの分散の仕組み(Node Discovery)についての記載があります。 また、1.0で追加されたcircuit breakerやスレッドプール、インデックスのリフレッシュレートなど、Mastering ElasticSearchの 内容も追記されている気がします。\nインデックスやマッピングのテンプレート機能についてもここで説明があるみたいです。\n8章 Administrating Your Cluster 1.0で追加されたsnapshot/restoreの説明から始まります。 あとは、前のバージョンの7章で説明されていたクラスタ管理用のAPIについての説明です。 いくつか(例えばcat API)、1.0で追加されています。\nまた、シャードのリバランスの話も追加されているようです。 エイリアスやプラグインの話はこちらに移動してるみたいです。\n感想 ということで、とりあえず、駆け足で目次ベースで違いを見てみました。 Mastering ElasticSearchでの 知見がフィードバックされ、しかも1.0(すでに1.3が出そうな勢いですが。。。)にバージョンアップされた内容になっています。 冒頭がわかりやすくなっているので、検索をやったことのない方にもおすすめな書籍になった気がします。 英語が苦にならなければ、おすすめの一冊だと思います。\n来月から読み進めるつもりなので、また、面白い内容があったら感想を書いていこうと思います。 (また翻訳できるといいかもなー)\n","date":1402908420,"dir":"post/2014/","id":"916bda59bc7621d5c1790c040572a3c0","lang":"ja","lastmod":1402908420,"permalink":"https://blog.johtani.info/blog/2014/06/16/first-impression-elasticsearch-server-2nd-edition/","publishdate":"2014-06-16T17:47:00+09:00","summary":"Elasticsearch server 2nd editionが発売されています。 私が翻訳したのは前のバージョンですが。。。 まずは、目次を元にどのくらい変わってるかを見てみました。 (","tags":["elasticsearch","本"],"title":"Elasticsearch server 2nd editionのファーストインプレッション"},{"contents":"可視化ツール現状確認会に参加して、カジュアルウォーターじゃなくて可視化ツールの現状を確認してきました。\nということで、いつものメモです。\nMackerel と Graphite について (y_uuk1さん) Graphite 時系列 工夫すればスケーラブル SensuやCollectdと組み合わせたり GrafanaとGrapheneでGUI Mackerel素敵だよと。 架空のわかりやすいグラフが見れた Kibana \u0026amp; Grafana \u0026amp; Influga (hakoberaさん) Kibana\nかっこいい。 JVM大変。 Grafana\nGraphiteがカッコ悪いのでKibanaをフォーク なぜか、ESが必要。 InfluxDBに浮気しそう Influga\n@haoberaさん作 InfluxDB Queryサポート 迷ったら、Kibana入れとけ。\nDistinctがKibana出できないけど、それ以外はある程度行けるらしい。\naggregationがサポートされたら、できると思う。 Kibana以外は、バックエンドがタイムシリーズなので、縛りがある\n可視化ツール紹介(仮) (showyouさん) 誰がチャートを作るの? 誰が見るの? 一覧化されてて、あとで眺めたい IPython Notebookのデモ R shiny Serverのデモ Pentaho CE+Saikuのデモはネットワークがダメだったので割愛 分析側の視点を見せたかったので。 可視化とは何だったのか (harukasanさん) インフラ モニタリング、アナライズ、可視化どれ? 可視化は目的ではないよねと。 熱く、ユーザとサービスプロバイダ間の距離のお話。 ログ 生ファイルで残すのが重要 トータルで必要とか考えないといけないことがわかって面白かったw\nあなたの知らないrrdtool (shoichimasuharaさん) すげー! いろいろできるらしい(ノートPCの前にいなかったw) D3.jsとジオマッピング (Takaki_さん) 時空間推進課!すげー! ジオデータのおはなし。 TopoJSONとかGeoJSONとか Zipkinについて (synkさん) ものすごい数のJVMがThriftで殴りあってるらしい。 ZipkinはTwitterが作ったもの Brave、HTraceというのが、PureJava用のZipkinトレーシングプラグイン 見積もりする必要がないくらいでかいHBaseがあるので、そこにためてる。 まとめ LINEはエンジニアを大募集中 Graphiteについて (mickey19821 さん) ドリコムさんのGraphiteのおはなし Metricsの収集はCollectd Graphite-webがスケールできなくて困ってるらしい。 Graphiteで可視化ツラいw まとめ RRDTool最高\nあと、クックパッドの技術力がすごいという発表なんかもありました。\n","date":1401884100,"dir":"post/2014/","id":"5bb6f8322cdbda7a21e4aecbe04462b7","lang":"ja","lastmod":1401884100,"permalink":"https://blog.johtani.info/blog/2014/06/04/attending-visualize-study/","publishdate":"2014-06-04T21:15:00+09:00","summary":"可視化ツール現状確認会に参加して、カジュアルウォーターじゃなくて可視化ツールの現状を確認してきました。 ということで、いつものメモです。 Mackerel と Graphite","tags":["勉強会"],"title":"可視化ツール現状確認会に参加してきました。#可視化"},{"contents":"今月2回目の目黒で、初のドリコムさんです。 「最新インフラエンジニア技術勉強~Fluentd, Elasticsearch,Chefの実践実例~」に参加してきました。 もちろん、Elasticsearchってキーワードがあったからです。\nざっくりメモです。\nドリコムのInfrastructure as Code/ひらしーさん CM:jojoss、トレクル、など サーバ300台、クラウド○○台。月30〜50台の割合で増加中。 少人数でいかに回すか。 Chef Rubyが書ける人が多いから。 serverspec テストだよと。 すみません、色々と聞き逃しました。。。\nWinning the metrics battle/mickeyさん Graphiteとかを触っている。 1300台超えたら、色々大変だった。 失敗談 Cactiを利用して、色々と運用が大変だった。DCが別なのでProxyとか。 成功例?現行システム? 最大値、平均値、最小値などをプロット collectdを収集、送信に採用して、独自で開発? 受信して保存するのに、Graphite(carbon-relay、carbon-cache、DRBD、graphite-web)ってなってる。 1300台程度のサーバから、5分間隔で、問題ない。 Graphite良いツールだよ。 Q:過去データはどのくらい? A:5分間隔で1年分。\nQ:移動平均とかを使ったグラフとか時間かかりませんか?100台だと A:100台でもほとんど時間はかからない。\nFluentd プラグイン開発講座/外山 寛さん Fluentdプラグインを作ることができると威力倍増 Elasticsearchの勉強会の話までしてくれました! 勉強会スペース貸出しています。 未公開だけど、sedueのプラグインもあるらしい。 CHUNKとBUFFERとか覚えときましょう プラグインの作り方的なのがなかった気がしたので、今回の発表です。 gem作らなくてもディレクトリにおけば使えるよと。 td-agent使ってる人が大多数だよね。(fluentdを素で使ってる人は会場にはいなかった) エンジニア募集中 Q:エラー処理どうしてますか? A:今は、スルーしています\nQ:単体テストの書き方は? A:人によってバラバラみたいですね。\nMySQLと組み合わせて始める全文検索エンジン「elasticsearch」/yoshi_ken スライド:http://www.slideshare.net/y-ken/introduce-elasticsearch-mysql-importer\nElasticsearch歴は1年位です。\nMySQLを使っていて、モダンな検索がほしいですよね?ね?\nサジェスト、ファセット、位置情報、ネスト検索などなど。\nGoogleトレンドだとSolrに迫る勢いと。\n実データを用いて、手軽にElasticsearchと連携。\nBinaryLogではなく、SQLの結果を同意する方式。yamabiko\n今日は、新しいものを公開します。\nbulk import file generator as well as nested document from MySQL for elasticsearch bulk api 東京トレーニング\nElasticsearch本については、右にあるリンクをクリックしてくれるとうれしいなぁ。\n","date":1400840280,"dir":"post/2014/","id":"a578acf825a595ce95fe8f804b7208f0","lang":"ja","lastmod":1400840280,"permalink":"https://blog.johtani.info/blog/2014/05/23/attending-drecom-infra-study/","publishdate":"2014-05-23T19:18:00+09:00","summary":"今月2回目の目黒で、初のドリコムさんです。 「最新インフラエンジニア技術勉強~Fluentd, Elasticsearch,Chefの実践実例~","tags":["勉強会","elasticsearch"],"title":"最新インフラエンジニア技術勉強に参加しました。"},{"contents":"どうやら、中身がSolrベース?Luceneベース?になったらしいということで、 今日は「AWSプロダクトシリーズ|よくわかるAmazon CloudSearch」に行ってきました。\n※ElasticSearchではありません!\nということで、いつものメモ。\nCloudSearch Overview Amazon Web Services, Inc. Pravin Muthukumar(Product Manager) / Vivek Sriram (Business Development) Introduction to Search 検索の紹介。アイアンマンのDVD?のページにいろんな項目(フィールド)があるよねと。(もちろん、Amazonのページ) ファセット、Geo、テキスト処理(Analysis処理)、Postings listとか。とかとか ランキングも Amazon CloudSearch 独自実装orRDB拡張もある。 OSSもあるよね。 Legacy Enterprise SearchとしてFASTとかもある。 Building with CloudSearch 他のサービス同様、コンソールとかあるし、色々できるし、すぐ起動できるよと。 自動で、データが増えたら、パーティションが増えると。\n日本語の形態素解析があるらしい。何を使ってるのかな? ICUのノーマライズとかもやってくれるらしい。これかな?http://lucene.apache.org/core/4_8_0/analyzers-icu/index.html ユーザが辞書を指定できるのかな? 備えてる機能の説明\nファセット SimpleQuery Autocomplete Highlight などなど\nMulti-AZにも対応 QA Q:NGramありますか? A:今はないです。 Q:ユーザ辞書対応してますか? A:今はないです。 Q:lang-detectあるか? A:今はないので、自分で判定して、適切なフィールドに入れてね。 Expectation for CloudSearch Apache Solr contributor 大須賀 稔氏 Solr本の宣伝ありがとうございます!(右のアイコンから買ってもらえると更に嬉しいですw) Kinesisとかとの組み合わせとか、自然言語処理とか、いろいろとあるAWSのコンポーネントと組み合わせる例が欲しいと。 すばらしい、最後はManifoldCFがらみに持っていくとは。ACLがらみのクローリングとかあるといいじゃないでしょうかと。 Impression of using CloudSearch 吉田 匠氏 (@yoshi0309 http://blog.yoslab.com/) スライド:https://speakerdeck.com/yoshi0309/impression-of-using-cloudsearch\nお見かけしたことある気がするなぁ。 全部置き換えできる!わけではなさそう。。。 いいところ。 UIがいいし、セットアップが簡単 auto scaleがうれしい マルチドメイン、マルチスキーマがいい Luceneのdismaxサポートがいい。(edismaxじゃないのかな?) dismaxって書いてあるな。\nhttp://docs.aws.amazon.com/cloudsearch/latest/developerguide/search-api.html\nフィードの仕方に気をつけて!\nバッチサイズで課金されるので、1件ずつじゃなくて、複数件送ったほうがいい。 いきなりスケールアウトできるわけじゃない?\nウォームアップ機能がない。インスタンス上限がデフォルト50件\nVPC対応してほしい。\nインターネット経由になってしまう フィードのスピードが セキュリティグループ機能が使えない CloudSearch UseCase - SnapDish Vuzz Inc. 清田 史和氏 独自辞書をもって、Tokenizeは独自でやって、空白区切りでデータ登録している。 インデックス更新はSQSを使ってる。 古いAPIを使ってるらしい。 移行が結構大変らしい。 感想 使ったことないんですが、きめ細かい検索したい場合はちょっとテクニックが要るかもと思いました。 AWS初心者なんで、なんとも言えないんですが。。。\nといあえず、テキスト処理(アナライズ処理)で、単語がどうやって区切られるのかってのがわからないのはキツイんじゃなかろうかと。 ただ、簡単に起動できて、オートスケールできるのは素晴らしいと思います。\n","date":1400143800,"dir":"post/2014/","id":"706c033b4483b6d062b66d6e4ea0236a","lang":"ja","lastmod":1400143800,"permalink":"https://blog.johtani.info/blog/2014/05/15/amazon-cloud-seaarch-study-session/","publishdate":"2014-05-15T17:50:00+09:00","summary":"どうやら、中身がSolrベース?Luceneベース?になったらしいということで、 今日は「AWSプロダクトシリーズ|よくわかるAmazon Cl","tags":["勉強会","CloudSearch","AWS"],"title":"「よくわかるAmazon #CloudSearch 」に行ってきました!"},{"contents":"酔っ払ってなんとなく書きたくなったスピリチュアルなブログなので、流していただければと。\n最近、勉強会やTwitterで知り合いになって話をする人が増えたりで、 その方たちに色々と教えてもらうことが多いなぁと感じてます。 また、知り合いに恵まれてきたなぁとも。\nそもそも私が勉強会に参加し始めたきっかけはSolr勉強会(第1回から参加してて、気づいたら主催者になってた)で、 そのころは、Solr初心者で色々とやってる人、知ってる人がいて無料で話が聞けるのすごいと興奮したのを覚えてます。 (もちろん、ぼっちでしたが)\nSolr勉強会が定期的に開かれて、それに参加しているうちに少しずつ知り合いもできて、 面白そうな勉強会(Hadoopとか)が他にもあるんだ、参加してみようかって思うようになってと。\nそこにプラスで、関口さんと知りあえてSolr本を書く話が出てきて、本を書いてみたら、 今度は勉強会で話してみませんかとなって。\nスピーカーやると、顔を覚えてもらえるようで、また知り合いが増えてと。\n人のつながりって大事だし、自分が発信することで教えてもらえることもあるしと。 前にも書いた気がするけど、Solr勉強会(当時の主催の方)や関口さんやElasticsearch勉強会のスタッフの方や スピーカーやってくれた方、会場提供を心よくしてくれてるVOYAGE GROUP、リクルートテクノロジーズさん、という具合にどんどん頭が上がらなくなってきてるなぁと。\nということで、外の世界を知ると色々とつながりが出来て面白いですよという、個人的な感想でした。 ま、自分が思ってるだけで、違う意見もいっぱいあると思うけど。\nあー、なんか、酔って勢いで書いてしまった。。。 脈略のない文章なきがするけど、エイヤで公開しちゃおう。\n","date":1399999440,"dir":"post/2014/","id":"72df0bf7853e05560d94208817b83468","lang":"ja","lastmod":1399999440,"permalink":"https://blog.johtani.info/blog/2014/05/14/spiritual-entry1/","publishdate":"2014-05-14T01:44:00+09:00","summary":"酔っ払ってなんとなく書きたくなったスピリチュアルなブログなので、流していただければと。 最近、勉強会やTwitterで知り合いになって話をする","tags":["スピリチュアル"],"title":"外の世界を知るということ"},{"contents":"「アジャイルデータサイエンス」の見本をいただいてしまいました。\nなので、感想文でも書いてみようかと。\nどんな本? 想像以上に薄かったです、物理的に。 なのに、とても幅広い範囲をカバーしています。\nデータの分析にどんな人が関わっているのか、アジャイルにデータを分析する目的から始まり、 データから何かを見つけるための手順、考え方などをさらっとですが、 システムに取り込む流れから取り込んだあとに改良するという流れまで紹介してくれます。 流れはこんな感じ。\nイベント:ログとかのイベントの発生 コレクタ:イベントの収集 バルクストレージ:イベントの一時保存 バッチ処理:ストレージにあるデータに対して処理 分散ストア:処理結果をWebアプリなどで表示するために保存 Webアプリ:処理結果をユーザに提供 Webアプリでデータを見えるようにして、そこから更にフィードバックを受けることで、データの分析などを進めていくという流れです。\n私はデータサイエンス系の人ではないのでこの流れで作業をされているかはわからないのですが、 検索のシステムについてもこの流れに似ているなと感じました。\n検索システムでも、検索したいデータを収集して、加工(検索したい項目の洗い出しやファセットにする項目の選定とか)して、 インデックスを生成するといった処理が必要になるからです。\nこの本では、Python、Hadoop(Pig)、MongoDB、ElasticSearch(バージョンが0.90だから)、d3.jsなどが出てきます。 また、日本語版の付録では、Fluentd、Kibana+Elasticsearchといった組み合わせの紹介もあります。\nコードも書かれていますが、すみません、そこまでちゃんと読んでません。。。\n後半では、データを活用して行くためには順序があるという話が書かれています。\nレコード:レコード1件のアトミックな処理と表示 グラフ:レコードを元に集計したりグラフ作ったり レポート:関係性やトレンドを抽出し、インタラクティブに探求 予測:構造を利用して、推論やレコメンドとか 行動:上記の結果を元にユーザに行動を促す 前のステップがおろそかだと次のステップがうまくいかないという話です。 後半はこの流れに沿って、先ほどのシステムの流れを変更していく方法が展開されます。\n注意点 ちょっとだけ気になる点があったので。\nElasticsearch周りについては少し注意が必要かと。(Pigとかは詳しくないので不明です。) 紹介されているElasticsearchのバージョンが0.90と少し古いのと、 Hadoopとの統合(Pigで処理したデータをElasticsearchに出力)に利用されているWondordogというツールも最近更新がされていないみたいです。 おそらく、1.0系では動かないのではないかと。\n1.0系の場合は、Elasticsearchが提供しているelasticsearch-hadoopを利用するのが良いと思います。\n付録については1.0系で記載されているので問題ないかと。ただし、Elasticsearchは更新が早いので、公式サイトで最新情報を入手するのが良いと思います。\n感想 データを解析するシステムってどんなことやってるの?という全体像を 俯瞰するのに良い本なのではないかと思います。 また、データの解析を活かすために、必要な順序と疎かにできない点もあって面白かったです。\n紹介されているツール類については、OSSのトレンドや開発速度が早いので、参考程度にとどめておいて、 自分たちで使いやすいものを探してきて検討するのがいいと思います。\n付録がとても豪華です。FluentdやKibanaがわかりやすく解説されてます。\nあと、薄いのでさらっと読めます。w\n","date":1399563900,"dir":"post/2014/","id":"91fe03f994e8e85cede4e3bd62f4d6b7","lang":"ja","lastmod":1399563900,"permalink":"https://blog.johtani.info/blog/2014/05/09/reading-agile-data-science/","publishdate":"2014-05-09T00:45:00+09:00","summary":"「アジャイルデータサイエンス」の見本をいただいてしまいました。 なので、感想文でも書いてみようかと。 どんな本? 想像以上に薄かったです、物理的に","tags":["感想文","オライリー"],"title":"アジャイルデータサイエンスが届きました"},{"contents":"こんなツイートを見つけたので、Aggregationのサンプルでも書こうかなと。(前から書こうと思ってたんですが。。。)\n@elasticsearch Hi, Would you please tell me the way to do \u0026quot;Pivot Faceting\u0026quot; like Solr-4.0 in elasticsearch-1.1.1 or prior version? Thank you.\n\u0026mdash; Y.Kentaro (@yoshi_ken) 2014, 5月 2 ちなみに、Aggregationは1.0.0から導入された機能なので、ElasticSearch Server日本語版には掲載されていない機能になります。(ごめんなさい)\n公式ガイドのAggregationsのページはこちらになりますが、実例があったほうがいいかなと。\n@yoshi_ken さんから実例のサンプルの指定もいただいたので、ブログを書くのが非常に楽です。ありがとうございます。\n問題 元ネタ(gist)\n次のような不動産系のデータがあるとします。\nid 物件名 都道府県(東京、神奈川、\u0026hellip;..) 物件種別(賃貸、売買、\u0026hellip;..) この時、都道府県別に、物件種別ごとの件数を取得したいという趣旨です。\n東京 賃貸: xxx件 売買: yyy件 神奈川 賃貸: xxx件 売買: yyy件 \u0026hellip; これを、Elasticsearchでどうやって取得するかという問題です。\nインデックスとデータの登録 まずは、インデックスを作ります。 あくまでもサンプルなので、全部not_analyzedにしてますが、そのへんは適宜変更してください。\n# create index PUT /pref_aggs { \u0026#34;settings\u0026#34;: { \u0026#34;number_of_shards\u0026#34;: 2 }, \u0026#34;mappings\u0026#34;: { \u0026#34;japan\u0026#34; : { \u0026#34;_id\u0026#34; : { \u0026#34;path\u0026#34; : \u0026#34;id\u0026#34; }, \u0026#34;properties\u0026#34;: { \u0026#34;id\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;}, \u0026#34;name\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;}, \u0026#34;pref\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;}, \u0026#34;type\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;} } } } } _idを使用して、データ登録時にidフィールドにある文字列をそのままIDとして登録できるように指定してあります。\n登録するデータは次のようなものを適当に100件程度作ってりました。\n{\u0026#34;id\u0026#34;: \u0026#34;id0\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;name0\u0026#34;, \u0026#34;pref\u0026#34;: \u0026#34;01_北海道\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;売買\u0026#34;} {\u0026#34;id\u0026#34;: \u0026#34;id1\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;name1\u0026#34;, \u0026#34;pref\u0026#34;: \u0026#34;09_栃木県\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;売買\u0026#34;} {\u0026#34;id\u0026#34;: \u0026#34;id2\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;name2\u0026#34;, \u0026#34;pref\u0026#34;: \u0026#34;38_愛媛県\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;賃貸\u0026#34;} {\u0026#34;id\u0026#34;: \u0026#34;id3\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;name3\u0026#34;, \u0026#34;pref\u0026#34;: \u0026#34;40_福岡県\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;賃貸\u0026#34;} {\u0026#34;id\u0026#34;: \u0026#34;id4\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;name4\u0026#34;, \u0026#34;pref\u0026#34;: \u0026#34;35_山口県\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;売買\u0026#34;} {\u0026#34;id\u0026#34;: \u0026#34;id5\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;name5\u0026#34;, \u0026#34;pref\u0026#34;: \u0026#34;12_千葉県\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;賃貸\u0026#34;} ... データの登録には、前に紹介した方法「stream2esと複数データの登録」を用いました。\nファセット このようなデータがある場合に、まず思いつくのはファセットによる取得です。 いささか強引ですが。。。\nGET /pref_aggs/japan/_search { \u0026#34;size\u0026#34;: 0, \u0026#34;query\u0026#34;: { \u0026#34;match_all\u0026#34;: {} }, \u0026#34;facets\u0026#34;: { \u0026#34;type_賃貸\u0026#34;: { \u0026#34;terms\u0026#34;: { \u0026#34;order\u0026#34;: \u0026#34;term\u0026#34;, \u0026#34;field\u0026#34;: \u0026#34;pref\u0026#34;, \u0026#34;size\u0026#34;: 50 }, \u0026#34;facet_filter\u0026#34;: {\u0026#34;term\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;賃貸\u0026#34; }} }, \u0026#34;type_売買\u0026#34;: { \u0026#34;terms\u0026#34;: { \u0026#34;order\u0026#34;: \u0026#34;term\u0026#34;, \u0026#34;field\u0026#34;: \u0026#34;pref\u0026#34;, \u0026#34;size\u0026#34;: 50 }, \u0026#34;facet_filter\u0026#34;: {\u0026#34;term\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;売買\u0026#34; }} } } } facet_filterを使用して、typeフィールドによる個別の絞込を行っています。 あとは、prefフィールドのファセットを取得すれば、出力は次のようになります。\n{ \u0026#34;took\u0026#34;: 6, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 2, \u0026#34;successful\u0026#34;: 2, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 100, \u0026#34;max_score\u0026#34;: 0, \u0026#34;hits\u0026#34;: [] }, \u0026#34;facets\u0026#34;: { \u0026#34;type_賃貸\u0026#34;: { \u0026#34;_type\u0026#34;: \u0026#34;terms\u0026#34;, \u0026#34;missing\u0026#34;: 0, \u0026#34;total\u0026#34;: 52, \u0026#34;other\u0026#34;: 0, \u0026#34;terms\u0026#34;: [ { \u0026#34;term\u0026#34;: \u0026#34;00_北海道\u0026#34;, \u0026#34;count\u0026#34;: 1 }, { \u0026#34;term\u0026#34;: \u0026#34;01_青森県\u0026#34;, \u0026#34;count\u0026#34;: 2 }, { \u0026#34;term\u0026#34;: \u0026#34;03_宮城県\u0026#34;, \u0026#34;count\u0026#34;: 3 }, ... }, \u0026#34;type_売買\u0026#34;: { \u0026#34;_type\u0026#34;: \u0026#34;terms\u0026#34;, \u0026#34;missing\u0026#34;: 0, \u0026#34;total\u0026#34;: 48, \u0026#34;other\u0026#34;: 0, \u0026#34;terms\u0026#34;: [ { \u0026#34;term\u0026#34;: \u0026#34;00_北海道\u0026#34;, \u0026#34;count\u0026#34;: 2 }, { \u0026#34;term\u0026#34;: \u0026#34;02_岩手県\u0026#34;, \u0026#34;count\u0026#34;: 1 }, { \u0026#34;term\u0026#34;: \u0026#34;04_秋田県\u0026#34;, \u0026#34;count\u0026#34;: 1 }, ... } 望んでいた形式とは少し異なりますが、facet_filterする回数を少なくするため、 ファセットは都道府県のフィールドを指定したためです。 アプリで頑張って入れ替えてください。。。\nこの場合、\u0026rsquo;type\u0026rsquo;の個数がわかっているので、頑張ってこのような記述ができました。 ただ、typeが増えた時にアプリの修正とかが必要になりますよね。\nAggregations ということで、Aggregationsの出番です。 ファセットよりも柔軟に、検索結果に対していろいろな集計が行える機能になります。 一見に如かずということで、クエリを紹介します。\nGET /pref_aggs/japan/_search { \u0026#34;size\u0026#34;: 0, \u0026#34;query\u0026#34;: { \u0026#34;match_all\u0026#34;: {} }, \u0026#34;aggs\u0026#34;: { \u0026#34;pref\u0026#34;: { \u0026#34;terms\u0026#34;: { \u0026#34;order\u0026#34;: { \u0026#34;_term\u0026#34;: \u0026#34;asc\u0026#34; }, \u0026#34;field\u0026#34;: \u0026#34;pref\u0026#34;, \u0026#34;size\u0026#34;: 50 }, \u0026#34;aggs\u0026#34;: { \u0026#34;type\u0026#34;: { \u0026#34;terms\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;type\u0026#34;, \u0026#34;size\u0026#34;: 10 } } } } } } ファセットよりもシンプルですし、賃貸といったような値を指定していません。 aggsというのがaggregations機能を指定している部分になります。 検索結果は次のように出力されます。\n{ \u0026#34;took\u0026#34;: 4, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 2, \u0026#34;successful\u0026#34;: 2, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 100, \u0026#34;max_score\u0026#34;: 0, \u0026#34;hits\u0026#34;: [] }, \u0026#34;aggregations\u0026#34;: { \u0026#34;pref\u0026#34;: { \u0026#34;buckets\u0026#34;: [ { \u0026#34;key\u0026#34;: \u0026#34;00_北海道\u0026#34;, \u0026#34;doc_count\u0026#34;: 3, \u0026#34;type\u0026#34;: { \u0026#34;buckets\u0026#34;: [ { \u0026#34;key\u0026#34;: \u0026#34;売買\u0026#34;, \u0026#34;doc_count\u0026#34;: 2 }, { \u0026#34;key\u0026#34;: \u0026#34;賃貸\u0026#34;, \u0026#34;doc_count\u0026#34;: 1 } ] } }, { \u0026#34;key\u0026#34;: \u0026#34;01_青森県\u0026#34;, \u0026#34;doc_count\u0026#34;: 2, \u0026#34;type\u0026#34;: { \u0026#34;buckets\u0026#34;: [ { \u0026#34;key\u0026#34;: \u0026#34;賃貸\u0026#34;, \u0026#34;doc_count\u0026#34;: 2 } ] } }, ... Aggregationsの結果は、望んでいた通りの出力になっています。\nクエリの構成を見てみましょう。\n\u0026#34;aggs\u0026#34;: { \u0026#34;pref\u0026#34;: { #1 \u0026#34;terms\u0026#34;: { \u0026#34;order\u0026#34;: { \u0026#34;_term\u0026#34;: \u0026#34;asc\u0026#34; }, \u0026#34;field\u0026#34;: \u0026#34;pref\u0026#34;, \u0026#34;size\u0026#34;: 50 }, \u0026#34;aggs\u0026#34;: { #2 \u0026#34;type\u0026#34;: { \u0026#34;terms\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;type\u0026#34;, \u0026#34;size\u0026#34;: 10 } } } } } 最初の#1のprefは出力を扱いやすくするためにつけているラベルになります。好きな名前をつけることが可能です。 次のtermsがAggregationのタイプ(どのような集計をして欲しいか)になります。 今回は、prefフィールドにある単語(term)毎に、集計をしたいので、termsを指定します。 その他にどんなタイプがあるかは、公式ガイドをご覧ください。\n次に、さらにtypeフィールドで集計したいので、#2の部分で後続のAggregationを指定しています。 都道府県同様、typeフィールドにある単語毎に集計するために、termsを指定します。\nこれで、先ほどのような結果が出力できます。 ちなみに、さらにtypeの中に他の種別で集計したいという場合は、さらにaggsを追加していけばOKです。\nAggregationは非常に柔軟な集計を可能にする機能です。ただし、検索結果に対して集計処理を行っているため、 メモリやCPUなどのリソースを消費するので注意が必要です。\nAggregationの説明については、こちらのFound.noのブログ(英語)がわかりやすかったので参考にしてみてください。\nまとめ 非常に簡単ですが、Aggregationsについて紹介しました。 その他にもAggregationsでできることがあるので、後日別のサンプルを用意して説明しようかと思います。\n100件のデータやここまでの操作については、gistにあるので、興味がある方はご覧いただければと。 stream2esの操作以外は、Marvelに付属のsenseを利用しています。\n","date":1399456620,"dir":"post/2014/","id":"ed4f5a398056eef1cf6caa90786b340a","lang":"ja","lastmod":1399456620,"permalink":"https://blog.johtani.info/blog/2014/05/07/aggregation-example/","publishdate":"2014-05-07T18:57:00+09:00","summary":"こんなツイートを見つけたので、Aggregationのサンプルでも書こうかなと。(前から書こうと思ってたんですが。。。) @elasticsearch Hi, Would you please tell me the way to","tags":["elasticsearch"],"title":"Aggregations - ファセットよりも柔軟な集計"},{"contents":"今日はelasticsearch-kopfのAnalysis画面の紹介です。\n(簡単なところから。。。その3)\nちょっとあいだが開いてしまいましたが、再開です。 メニューのaliasesを選択すると、次のような画面が表示されます。\nAliases画面 Elasticsearchのaliasを画面で確認できます。\nエイリアスは、インデックスに別名をつけることができるElasticsearchの機能です。 1エイリアス=1インデックスでも良いですが、1エイリアスに対して複数のエイリアスを付与することもできます。 この機能を利用することで、次のようなことが可能となります。\nインデックスの切り替えをアプリ側に意識させずに実施(アプリはエイリアス名に対して検索すればOKなので) 直近1週間のログを検索するためのエイリアスの作成(複数のインデックスを1つのエイリアスに割り当て可能) 特定のルーティングによる検索(特定のデータに対する検索だけに絞るためにfilterを指定する) エイリアスについて詳しく知りたい方は公式ガイドをご覧いただくのが良いかと。\n画面は非常にわかりやすい作りになっているので、特に説明必要ないんですよね。。。\n","date":1399132860,"dir":"post/2014/","id":"2824bef72110575c78aeb979170212b8","lang":"ja","lastmod":1399132860,"permalink":"https://blog.johtani.info/blog/2014/05/04/intro-elasticsearch-kopf-alias-percolator/","publishdate":"2014-05-04T01:01:00+09:00","summary":"今日はelasticsearch-kopfのAnalysis画面の紹介です。 (簡単なところから。。。その3) ちょっとあいだが開いてしまいまし","tags":["elasticsearch","plugin"],"title":"elasticsearch-kopfの紹介(aliases画面)"},{"contents":"kopfの記事の続きも書く必要があるんだけど、こんなツイートを見つけてしまったので。。。\nElasticsearchのBulk APIの仕様、JSONファイルをいい感じに加工して置かなければならないしハマりどころ多い。 http://t.co/hmfycqZlqk\n\u0026mdash; Kenta Suzuki (@suzu_v) 2014, 4月 24 前に思いついたけど、放ったらかしにしてた疑問が再浮上してきたので、せっかくだから調べてみようかなと。\n複数JSONデータがある場合にもっと楽にデータを入れる方法ないかなぁと思って、これかな?というのがあったのですが、 そのまま手を動かさずに放置してたので、一念発起してブログ書いてます。\nBulk APIって? ElasticsearchはURLにアクセスしてデータを登録できます。 基本的には次のように1件毎の登録になります。\n$ curl -XPUT http://localhost:9200/bookshop/books/1 -d \u0026#39; { \u0026#34;book_id\u0026#34; : 1, \u0026#34;title\u0026#34; : \u0026#34;ElasticSearch Server Japanese Edition\u0026#34;, \u0026#34;price\u0026#34; : 3024, \u0026#34;publisher\u0026#34; : \u0026#34;KADOKAWA\u0026#34; }\u0026#39; これでもいいのですが、大量のデータを登録するときは、Elasticsearch側での効率が悪いです。 そこで、Elasticsearchは大量データを登録するためにBulk APIというものを用意しています。\nこれは、次のような形式のJSONを作ってデータを登録します。\n{ \u0026#34;index\u0026#34; : { \u0026#34;_index\u0026#34; : \u0026#34;bookshop\u0026#34;, \u0026#34;_type\u0026#34; : \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34; : \u0026#34;1\u0026#34; } } { \u0026#34;book_id\u0026#34; : 1, \u0026#34;title\u0026#34; : \u0026#34;ElasticSearch Server Japanese Edition\u0026#34;, \u0026#34;price\u0026#34; : 3024, \u0026#34;publisher\u0026#34; : \u0026#34;KADOKAWA\u0026#34;} { \u0026#34;index\u0026#34; : { \u0026#34;_index\u0026#34; : \u0026#34;bookshop\u0026#34;, \u0026#34;_type\u0026#34; : \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34; : \u0026#34;2\u0026#34; } } { \u0026#34;book_id\u0026#34; : 2, \u0026#34;title\u0026#34; : \u0026#34;Introduction of Apache Solr\u0026#34;, \u0026#34;price\u0026#34; : 3888, \u0026#34;publisher\u0026#34; : \u0026#34;gihyo\u0026#34;} これは、次のような構成になっています。\nコマンド データ コマンド データ ... これで効率よくデータが登録できるのですが、このようなJSONデータを別途作って上げる必要が出てきます。 結局、複数のJSONがあるのに、特殊なJSONを生成しないといけないということでプログラム書いて実行することになります。 これだと、Elasticsearchへのアクセスをプログラムで書くのとあまり大差がないかもしれません。\nstream2es もっとお手軽に複数のJSONを登録できないかな?と目をつけていたのが、stream2esです。\nどんなもの? Clojureで作られた、Elasticsearchにデータを流し込むためのツールです。 Java 7がインストールされていれば、ダウンロードしてくれば動作せることができます。\nインストール 公式ページに載っている方法そのままです。\n$ curl -O download.elasticsearch.org/stream2es/stream2es; chmod +x stream2es 実行したディレクトリにコマンドがコピーされます。 あとは、コマンドを実行すればOKです。\n実行 データは次のような形式でsample.jsonに保存してあるとします。\n{ \u0026#34;book_id\u0026#34; : 1, \u0026#34;title\u0026#34; : \u0026#34;ElasticSearch Server Japanese Edition\u0026#34;, \u0026#34;price\u0026#34; : 3024, \u0026#34;publisher\u0026#34; : \u0026#34;KADOKAWA\u0026#34;} { \u0026#34;book_id\u0026#34; : 2, \u0026#34;title\u0026#34; : \u0026#34;Introduction of Apache Solr\u0026#34;, \u0026#34;price\u0026#34; : 3888, \u0026#34;publisher\u0026#34; : \u0026#34;gihyo\u0026#34;} 先ほどのBulk APIで利用したJSONよりも、スッキリしていますね。 1行1ドキュメント1JSONです。\nあとは、次のコマンドを実行するだけです。\n$ ./stream2es stdin --target http://localhost:9200/bookshop/books \u0026lt; sample.json ファイルをstream2esに流し込んで、stream2esが1行ずつパースして、Elasticsearchに投げ込んでくれます。\n登録されたデータは次のようになります。 IDは自動で付与されています。\n{ \u0026#34;_index\u0026#34;: \u0026#34;bookstore\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;0Hvy4IJCRkKrvGb4Dgam_w\u0026#34;, \u0026#34;_version\u0026#34;: 1, \u0026#34;found\u0026#34;: true, \u0026#34;_source\u0026#34;: { \u0026#34;book_id\u0026#34;: 1, \u0026#34;title\u0026#34;: \u0026#34;ElasticSearch Server Japanese Edition\u0026#34;, \u0026#34;price\u0026#34;: 3024, \u0026#34;publisher\u0026#34;: \u0026#34;KADOKAWA\u0026#34; } }, { \u0026#34;_index\u0026#34;: \u0026#34;bookstore\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;b9M6TooFQzGYyJeix_t_WA\u0026#34;, \u0026#34;_version\u0026#34;: 1, \u0026#34;found\u0026#34;: true, \u0026#34;_source\u0026#34;: { \u0026#34;book_id\u0026#34;: 2, \u0026#34;title\u0026#34;: \u0026#34;Introduction of Apache Solr\u0026#34;, \u0026#34;price\u0026#34;: 3888, \u0026#34;publisher\u0026#34;: \u0026#34;gihyo\u0026#34; } } せっかく、book_idがあるんだし、_idをインデックスの設定に指定します。\n$ curl -XDELETE http://localhost:9200/bookshop $ curl -XPUT http://localhost:9200/bookshop -d \u0026#39; { \u0026#34;mappings\u0026#34;: { \u0026#34;books\u0026#34; : { \u0026#34;_id\u0026#34; : { \u0026#34;path\u0026#34;: \u0026#34;book_id\u0026#34; } } } }\u0026#39; あとは、登録すればbook_idが_idに採用されます。\n{ \u0026#34;_index\u0026#34;: \u0026#34;bookshop\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;_version\u0026#34;: 1, \u0026#34;found\u0026#34;: true, \u0026#34;_source\u0026#34;: { \u0026#34;book_id\u0026#34;: 1, \u0026#34;title\u0026#34;: \u0026#34;ElasticSearch Server Japanese Edition\u0026#34;, \u0026#34;price\u0026#34;: 3024, \u0026#34;publisher\u0026#34;: \u0026#34;KADOKAWA\u0026#34; } }, { \u0026#34;_index\u0026#34;: \u0026#34;bookshop\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;2\u0026#34;, \u0026#34;_version\u0026#34;: 1, \u0026#34;found\u0026#34;: true, \u0026#34;_source\u0026#34;: { \u0026#34;book_id\u0026#34;: 2, \u0026#34;title\u0026#34;: \u0026#34;Introduction of Apache Solr\u0026#34;, \u0026#34;price\u0026#34;: 3888, \u0026#34;publisher\u0026#34;: \u0026#34;gihyo\u0026#34; } } 複数ファイル ディレクトリに複数のJSONファイルが有った場合は、次のようなコマンドでOK\n$ cat sample_data/*.json |./stream2es stdin --target http://localhost:9200/bookshop/books まぁ、catして流してるだけですが。。。\nダメだったケース JSONが複数行になっているようなデータだとエラーが出てしまいました。\n(jqコマンドで1行に整形したりできるかなぁ?)\nまた、1行に2つのJSONが書いてある場合は、1つ目のJSONをパースしたら、そこでおしまいみたいで、その後に記述されたデータは登録されませんでした。\nインデックスがない場合 stream2esで登録するインデックスがElasticsearchに存在しない場合、stream2esがインデックスを作成してくれるのですが、 この時、シャード数などはstream2es内部に記述があるので注意が必要です。 以下がその設定です。\nindex.number_of_shards : 2 index.number_of_replicas : 0 index.refresh_interval : 5s 課題? 内部的にはおそらく、Bulkでデータを登録していると思うのですが、まだよくわかっていません。 Clojureが読めないので、せっかくだから、Clojureの勉強も兼ねてちょっとソースを読んでみようかなと思います。 それほど量があるわけでもないので。\nあとは、その他にWikipediaのデータやTwitterのデータ登録、 ElasticsearchからデータをScrollで読み出しつつ、別のElasticsearchに流しこむといったこともできそうなので、そちらも試してみようかと。 他にもオプションがいくつかありそうです。\n今回は2件ほどでしたが、大量データを流し込んだ時にどうなるか(stream2esが悲鳴を上げるのか、Elasticsearchで詰まることがあったらどうなるか)なども 気になるので、なんか適当なデータで試してみるのもいいかなぁと。 (ということで、だれか、いろいろ試してみてもらえると楽できるなぁ。)\n","date":1398341460,"dir":"post/2014/","id":"e396cbf9274b590a1d94ee43d823a0bd","lang":"ja","lastmod":1398341460,"permalink":"https://blog.johtani.info/blog/2014/04/24/usage-stream2es/","publishdate":"2014-04-24T21:11:00+09:00","summary":"kopfの記事の続きも書く必要があるんだけど、こんなツイートを見つけてしまったので。。。 ElasticsearchのBulk APIの仕様、J","tags":["elasticsearch","stream2es"],"title":"stream2esと複数データの登録"},{"contents":"第4回Elsticsearch勉強会を開催しました。 今回から、遅刻厳禁にしてみました。 それほど困った人もいないと思うので、次回からも遅刻厳禁で。\nということで、今回も多数の方にお集まりいただきありがとうございました。\nスタッフの皆さん、スピーカーの皆さん、プレゼント用に書籍を用意してくれたKADOKAWAさん、開場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 次回もよろしくお願いします! 参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\nさて、ブログですが司会業とかやってたので、あんまり書けてないけど。。。\n134番までチケットがはけていたので+スタッフで140〜150名くらいの参加者だったのではないかと思います。 懇親会まで残っていただいた方々も片付けなどありがとうございました。\nさて、感想とか補足です。\n「アナライズ処理の仕組みとクエリDSL」株式会社シーマーク 大谷 純 @johtani スライド:アナライズ処理の仕組みとクエリDSL※スライドはPDFです。\nプラグイン:elasticsearch-extended-analyze\nプラグインの紹介記事:http://blog.johtani.info/blog/2013/10/25/developing-es-extended-analyze-plugin/\nMarvel:http://www.elasticsearch.com/marvel/\n日本語版メーリングリスト:https://groups.google.com/forum/#!forum/elasticsearch-jp\nなんか、宣伝(本+プラグイン)ばっかりですみません。 「プラグインの紹介記事」に簡単な使い方が書いてあります。が、情報が古いので、Elasticsearchのバージョンに合わせたバージョンを使ってください。\nまだまだ発表に慣れてないので、頑張ろ。\nアンケート取ってみましたが、ログ検索と全文検索と半々くらいで興味がある人がいるみたいでした。 あと、有料トレーニングは人気ないっすね。。。\n「elasticsearch-hadoopを使ってごにょごにょしてみる」 株式会社マーズフラッグ R\u0026amp;D部 やまかつ さん @yamakatu スライド:elasticsearch-hadoopを使ってごにょごにょしてみる\nelasticsearch-hadoop:https://github.com/elasticsearch/elasticsearch-hadoop\nQAとして、Elasticsearchにプライマリデータを保存するのは的な話が出てました。 ESにのみデータを入れるのは個人的には考えたことないかなぁ。 どうしても、ElasticsearchのWriteが遅いんじゃないかという懸念事項を持ってる人がいるなぁと。(実際ツラいという話もちらほら)\nお腹痛い中の発表ありがとうございました。。。 次回はMapRの方に紹介してもらえそう(交渉中)なので楽しみです。やまかつさんの続きも聞きたいなぁ。\n「CouchbaseとElasticsearchが手を結んだら」株式会社アットウェア 佐竹雅央さん @madgaoh 河村康爾さん @ijokarumawak スライド:CouchbaseとElasticsearchが手を結んだら\nCouchbaseのElasticsearchに関するページ:http://docs.couchbase.com/couchbase-elastic-search/\nCouchbaseに入れたら、自動的にElasticsearchにもデータを入れてくれる。 デモがあるの、いいっすね。\n最新版はmasterを落としてきてビルドしないとダメらしい。確かに、上のページには0.90.5って書かれてる。 ここでも、やはり、Elasticsearchが詰まった時にどうするの?みたいな話が出てました。 CouchbaseのXDCRだと、後ろが詰まってる時によしなに?データを流すのを制御してくれるってのがあるみたいですが、 Elasticsearchだと悲鳴を上げているのがわかりにくいと。\nあと、Elasticsearchがインデキシングでキューを取りこぼしているのがログからわかりにくいってのも出てました。 (なにか、分かる方法があるかとかも調べてみようかなぁ。)\n自分の宿題:Transportプラグインって何かについて調べてブログに書くこと。\n「Elasticsearch at Wantedly」(タイトルあってるか不安) Wantedly, Inc 内田誠悟さん @spesnova スライド:Elasticsearch at Wantedly\n参考文献:Elasticsearchチュートリアル\n参考文献:Elasticsearch Workshop\n参考文献:elasticsearch-rails\nWantedlyでどうやって使ってるのか。 あと、オートコンプリートでも使ってます。(この話は次回聞けるといいなぁw)\nデータ数は少ないので、参考にまだならないかも。\n公式のサイト見難いですよねと。 ペンギン先生のブログが素晴らしかった! マッピングすごいw\n最後は、苦労して作ってもらったautocompleteの資料は放ったらかしにして、質疑応答してもらいました。 辞書とか、検索漏れとかの話は今後の課題っぽかったですね。\n「Elasticsearchのみに決めてました!」ってセリフがカッコ良かったw\nアクセスコントロール周りのノウハウもブログで共有してくれそうなので楽しみにしています!\nあと、「tireがretire」の話が出てましたが(この発表だっけ?)参考文献にあげてある、elasticsearch-railsが今は本流なんじゃないかなぁ?\nLT ###「ElasticsearchのScripting」株式会社富士通ソフトウェアテクノロジーズ 滝田聖己さん @pisatoshi\nスライド:ElasticsearchのScripting\n参考文献:elasticsearch-native-script-example\n色々とScriptがあるという話を説明してもらい感謝です。 もちろん、ElasticSearchServerにも書いてあるので、そちらも参考にしてください!\n「Elasticsearch 向け多言語解析プラグイン」ベイシス・テクノロジー株式会社 江口天さん スライド:Elasticsearch 向け多言語解析プラグイン\n参考文献:Elasticsearchで使えるRosette基本言語解析モジュール\n参考文献:Elasticsearch-inquisitorプラグインの紹介\nベイシステクノロジさんが提供しているRosetteをElasticsearchで活用できるモジュールみたいです。 いまなら、無料で体験できるみたいなので、どんなものか触ってみると面白いかもしれません。\nあと、デモで使用されていたプラグインについて、私が昔に書いた記事があるので、興味のある方は参考にしていただければと。 このプラグインはクエリがどのように内部でLuceneのクエリになっているか、どのフィールドでどうトークンが生成されるか? といったものが見ることができるプラグインになっています。\n関連ブログ 適当に見つけたブログを列挙してあります。これもあるよ!などあれば、教えてください。\n勉強会メモ - 第4回elasticsearch勉強会 2014/04/21\ntogetter 第4回elasticsearch勉強会 #elasticsearchjp\n参加レポート:第4回elasticsearch勉強会 #elasticsearchjp\n第4回elasticsearch勉強会に参加しました\nまとめ しつこいくらい宣伝してしまいましたが、「ElasticSearch Server日本語版」よろしくお願いします!\n今回も楽しい話が聞けました。メモがちょっと少ないんですが。。。\n次回は6末を目処に、MapRの方などと調整して開催しようと思います。 聞きたい話とか、発表したい方とかあれば、連絡くださいー!\n","date":1398077040,"dir":"post/2014/","id":"50562b09417cd8c4a2348a0a5aabe754","lang":"ja","lastmod":1398077040,"permalink":"https://blog.johtani.info/blog/2014/04/21/hold-on-4th-elasticsearch-jp/","publishdate":"2014-04-21T19:44:00+09:00","summary":"第4回Elsticsearch勉強会を開催しました。 今回から、遅刻厳禁にしてみました。 それほど困った人もいないと思うので、次回からも遅刻厳禁","tags":["elasticsearch","勉強会"],"title":"第4回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"今日はelasticsearch-kopfのAnalysis画面の紹介です。\n(簡単なところから。。。その2)\nメニューのanalysisを選択すると、次のような画面が表示されます。\nAnalysis画面 Elasticsearchの_analyze APIを画面で確認できます。 画面で動作の確認ができるのは嬉しいですよね。\n入力文字列:入力となるドキュメントに含まれる文字列や検索キーワードを入力 フィールドの指定:対象とするインデックス名、タイプ名、フィールド名を選択 analyze:ボタンを押す トークナイズされた結果:入力文字列がどのようなトークンに分割されるか start、end:入力文字列中の文字列の位置 pos:トークンの位置 という形でElasticsearchが指定されたフィールドで入力文字をどのようにトークナイズしたかを確認することができます。\nElasticsearchは内部でこのトークナイズされた単語を元に転置インデックスを作成し、検索に利用します。 ですので、特定のデータが検索に上手くヒットしないときに、この画面でデータの文字列をトークナイズしてみるといった用途に使えます。\nフィールドの設定がどのようにして入力文字列をトークンにしているかといった点については、今度のElasticsearch勉強会で話す予定です。\nフィールドの設定を利用する以外に、アナライザを指定してどのようにトークナイズされるかを見ることもできます。 「ANALYZE BYANALYZER」をクリックすると利用できます。\nANALYZE BY ANALYZER トークナイズしたい文字列を入力し、インデックス名と、インデックスに設定されているアナライザ名を選択してanalyzeボタンを押すと 結果が表示されます。 (例では、kuromojiアナライザを利用して出力になっています。また、出力結果のposの表示位置がFIELD TYPEの時と違うのが少し気になりました。)\nただ、残念ながら、インデックスのマッピングで指定したアナライザしか利用できないみたいなので、 どのアナライザがどんな挙動かを調べたい場合は、以前紹介したelasticsearch-inquisitorを 利用したほうが良さそうです。\nということで、今日はanalysis画面の説明でした。\n","date":1397011260,"dir":"post/2014/","id":"76a1fb7f21fda9eddb95426b65124517","lang":"ja","lastmod":1397011260,"permalink":"https://blog.johtani.info/blog/2014/04/09/intro-elasticsearch-kopf-analysis/","publishdate":"2014-04-09T11:41:00+09:00","summary":"今日はelasticsearch-kopfのAnalysis画面の紹介です。 (簡単なところから。。。その2) メニューのanalysisを選択","tags":["elasticsearch","plugin"],"title":"elasticsearch-kopfの紹介(analysis画面)"},{"contents":"JVM Operation Casual Talksに参加しました。 あんまり、運用とかやってないので、ついていけるか不安ですが、楽しそうだったので。 懇親会は予定されてないらしい。\n@stanaka\t15分でわかるJVMのメモリ管理 スライド:https://speakerdeck.com/stanaka/understanding-memory-management-of-javavm-in-15-minutes\nJVMの基礎知識\n某研究所で。。。\nElasticsearch、Solrの名前が!\nJVM困りどころ。ネットの情報が古いのが多いとか。\n使いこなすにはきちんと知識が必要。\nMemory Model 困ったらJava8に。。。\nHeapのチューニングが重要\nHeapの構成やGC処理の説明\nCMSでもすべて並列ではない\nOlgGenがフラグメントして確保が遅くなっていく G1GCの概念図。YoungやOld、Survivorの区別がない?\nリージョン? リファレンスリストすばらしい。\n@oranie\tCassandra運用で実施しているJVM監視について スライド:http://www.slideshare.net/oranie/jvm-operation-casual-talks-33218856\nCassandra(1.1)で運用中。 35TBとか エンジニアブログ読め。 Cassandraの監視って何すればいいの? GC頻度とかグラフで見れる VisualVM便利って教えてもらった。 VisualVMでどんな値があるか見ながら調べて、取りたい値を考える。 SNMPで頑張るの辛い=JMXかな?=Javaで叩くの?=Jolokia どんなことやってる? Nagios+Jenkins+。。。あとでスライド yohoushi+GrowthForecastも便利。 @waysaku\tSpray(Akka)運用でJVMをCPUスケールさせるために行った事 スライド:http://www.slideshare.net/waysaku/jvm-operation-casual-talks\nSpray Akkaアプリケーションの運用を任されちゃった人 カットオーバー直前の負荷試験でびっくりするくらいスループットでない。。。 いろんなActorが特定のActorに処理を投げた状態で待ってるという状況。。。 スレッドダンプ追っかけてる様子を追体験してる。 ログ出力がBLOCKしてた I/Oを伴う処理は非常にセンシティブ 以下、LT @oinume\t運用に効く!JVMオプション三選 スライド:http://www.slideshare.net/oinume/jvm-operationcasualtalks20140407\nサーバに入らなくても見れるのは VisualVM 最終形Java Mission Control Flight Recorder(商用だと有償) @y_uuki1\tなにもわからないところから始めるJVMモニタリング スライド:https://speakerdeck.com/yuukit/nanimowakaranaitokorokarashi-merujvmmonitaringu\nブログ:http://yuuki.hatenablog.com/entry/2014/04/08/074507\nなんでここにいるかわかりませんが。 色んな所記事とかのリンクがある。 Graphiteに放り込んでるらしい。 @tagomoris\tNorikraのJVMチューンで苦労している話 スライド:http://www.slideshare.net/tagomoris/norikrajvm\nNorikraで困ったので開催したらみんなしゃべりに来てくれてありがたい世の中ですね。 デフォルト設定で運用。mx4096mで4ヶ月は元気に動いてた 年末に崩壊 -\u0026gt; harukaさんのQiita見ながら設定してほったからした。 3月にまた崩壊OOM SoftRefが悪さしてるのか? nekopさんのブログにヒントが。 @shot6\tJVM的なナニカを話す、GC戦略をそえて スライド:http://www.slideshare.net/shot6/jvm-33248312\n某A社からきました。 CMSを中心が良い CPUコア少ないとCMS Incremental G1GCは6GB以上とかもっと大きい場合のほうが良さそう(雑感) 基本的に、ドキュメントに書いてあるけど、つらいので、まとめてみました。 後で見たいな、このスライドも。 @kazeburo\tWebアプリケーションとメモリ スライド:http://www.slideshare.net/kazeburo/jvm-casual\nJavaは1行も書いたことありません。 Java運用したけど、まぁ、ひどい目にあってます。 ということで、PerlとApacheの話? bumpyなんとかってのは頭良くプロセスの処理回数とかをなんとかしてくれる JVMとかどうなの? ということで、CA社の人が釣れたので良かったですね。 TBD\tJVMの運用について話す会(パネル) なんでJVM?\n全文検索だとJVMだなぁ。SolrとかElasticsearchとか 入社したらあった。 JVMこまったところは?\n突然Dioが出てくる JVMいいところは?\nうーん、あえて言うと。。。スレッド処理 型がある言語を調べるとJVM。というよりScala。 飛び入り参加。落ちないところ。人殺しは良くないw 簡単には殺せないところに使えるのは良いのでは。 チューンはどこまでやる?\n7,8割でやめたほうが良い? そんなに突き詰めなくてもいいのかな。 Cassandraだと、FullGCが走ってる時点で再起動しかない場合が多いです。 言語のランタイムについてチューンすることってJVMの他ある?\nRubyくらい? 自分たちで何とかできないものを相手にしている人たちは苦労してるんじゃないか\nCaなんとかさんとかHBなんとかさんは困ってる人が多い 最後に一言\nモニタリングツール参考にしたい 最後に 「やりたくなったら誰かやってください。」ということみたいです。\n基礎から監視まで結構幅広くキーワードが出てきたので楽しかったです。\nその他に話に出てきてた方のブログもリンクしとこうかな。\nnekopの日記\n","date":1396866240,"dir":"post/2014/","id":"299abcee56b05b312ed5700f686f79b8","lang":"ja","lastmod":1396866240,"permalink":"https://blog.johtani.info/blog/2014/04/07/attend-jvm-casual-1/","publishdate":"2014-04-07T19:24:00+09:00","summary":"JVM Operation Casual Talksに参加しました。 あんまり、運用とかやってないので、ついていけるか不安ですが、楽しそうだったので。 懇親会は予定されてないらしい","tags":["JVM","Java","勉強会"],"title":"JVM Operation Casual Talksに参加しました #jvmcasual"},{"contents":"今日はelasticsearch-kopfのREST画面の紹介です。\n(簡単なところから。。。)\nメニューのrestを選択すると、次のような画面が表示されます。\nElasticsearch自体が、さまざまな操作をRESTでできる仕組みになっています。 検索にも利用しますが、それ以外の設定などにつてもリクエストを送ればOKです。\nですので、リクエストや設定を自分で組み立てて送ることができる画面が用意されているととても便利です。 (もちろん、curlコマンドでもいいのですが、画面があると便利ですよね)\nREST画面 History 履歴表示画面です。 これまで、kopfのrest画面を利用して送信したリクエストが一覧で表示されます。\nHistoryという文字をクリックすることで、表示/非表示の切り替えが可能です。(最初は非表示) マウスオーバーすると、リクエストボディがポップアップで表示されます。\nHistory 履歴にあるURLはクリック可能で、クリックすると実行されます。 履歴はlocalStorageに保存されるみたいです。(ブラウザの仕様?あんまり詳しくないので。。。) たぶん、30件が上限かと(ソースで確認しただけ)\nURL rest画面でリクエストを送信する先のURLを指定します。 メソッドは右側のSELECTで選択可能です。\nリクエストパラメータも指定が可能です。\nリクエストボディ 検索や設定のJSONを記述するところです。 一応、JSON的にエラーがある場合は行数の左側にバツ印が出てきておかしなところもわかるようになっています。\nインデントなどは行ってくれますが、senseみたいな補完などはないので、少し辛いところです。\nレスポンス 送信したリクエストに対するレスポンスが返ってきます。 インデントされた状態で表示されるので読みやすいかと。 また、入れ子になっているJSONについては、閉じたり開いたりすることも可能です。 (開始のカッコの右側に-が表示されていて、クリックすると閉じることができます。閉じると+に変わります)\n簡単ですが、rest画面の説明でした。 KOPFを使っていて、ちょっとしたクエリを送ったりするのには便利だと思います。\n複雑な検索クエリなどについては、やはりsenseを使うのが良いかと思いますが。。。\n","date":1396837440,"dir":"post/2014/","id":"670744b945088de05866864f7d57bee7","lang":"ja","lastmod":1396837440,"permalink":"https://blog.johtani.info/blog/2014/04/07/intro-elasticsearch-kopf-rest/","publishdate":"2014-04-07T11:24:00+09:00","summary":"今日はelasticsearch-kopfのREST画面の紹介です。 (簡単なところから。。。) メニューのrestを選択すると、次のような画面","tags":["elasticsearch","plugin"],"title":"elasticsearch-kopfの紹介(rest画面)"},{"contents":"なんだか、ドタバタしてて久しぶりの更新です。 ベルリンの旅行記みたいなのも書きたいのですが、まずはこちらかと。\nelasticsearch-kopfプラグインの紹介です。\n今回は概要の説明だけになります。機能が結構多いので。\nelasticsearch-kopfとは? _siteプラグインの一つで、クラスタ管理用のプラグインになります。 headプラグインやHQプラグインと同様です。\nプラグインの画面 このようにシンプルな画面で、スッキリとしています。 緑を基調にした画面構成はElasticsearchの緑色を意識してるんでしょうか?\n上記の画像に簡単なコメントを入れてあります。\nメニュー KOPF:KOPF自体の設定(接続先とリフレッシュインターバルの変更) cluster:クラスタ管理、情報(デフォルト表示画面) rest:RESTリクエスト送信、結果表示画面 aliases:エイリアス管理 analysis:analysis API percolator:パーコレータ管理 warmup:ウォームアップクエリ管理 上記のようなメニューです。各メニューについては、今後のブログで少しずつ紹介しようかと。 このメニューの色が、クラスタの状態も表しています。ステータスがYELLOWなら黄色、REDなら赤色に変わります。\nインデックス インデックスは列として表示されます。先ほどの画像では、2つのインデックスが表示されている状態です。 インデックス毎に、シャードも表示されます。これは、各ノードがどのシャードを保持しているかという情報です。 色の濃いシャードがプライマリでしょう。 インデックス名やシャードの箱はクリックできるようになっていて、それぞれの情報がJSONで表示されます。 その他にもドキュメント数、サイズなども表示されます。 インデックスの各種操作(closeやdeleteなど)もここからメニューが表示されます。(これも次回詳しく)\nノード ノードの情報が行として表示されます。ノードが増えると下に追加されていきます。 node1というのが、ノード名です。(ヒーローの名前とかが出てくるやつです。)\nその他に、IPアドレス、ポート番号、負荷、ヒープサイズなども表示されています。 電源ボタンはノードのシャットダウンを行うためのボタンです。(確認用のダイアログが表示される)\nその他 その他に、クラスタの概要として、ノード数、インデックス数、シャード数、ドキュメント数なども表示されます。 インデックスの作成などは、アイコンから操作が可能です。 大規模なクラスタを管理している場合、検索ボックスを利用することで、インデックス名やノード名による絞込もできるようになっています。\n感想 シンプルな構成の画面で、個人的にはheadよりも好きな画面です。 HQよりもシャードの分散具合がわかりやすいので、今後はこのプラグインを利用していこうと考えています。\nまずは、簡単な紹介です。今後、各画面についてもう少し説明をブログに書いていこうかと考えています。 待てない方は、触ってみてもらうのが良いかと。 もちろん、続きを書いてもらってもいいですよ!!\n","date":1396707480,"dir":"post/2014/","id":"c1241374502f200cf9fc49c8d6fb5822","lang":"ja","lastmod":1396707480,"permalink":"https://blog.johtani.info/blog/2014/04/05/intro-elasticsearch-kopf-1/","publishdate":"2014-04-05T23:18:00+09:00","summary":"なんだか、ドタバタしてて久しぶりの更新です。 ベルリンの旅行記みたいなのも書きたいのですが、まずはこちらかと。 elasticsearch-ko","tags":["elasticsearch","plugin"],"title":"elasticsearch-kopfの紹介(概要)"},{"contents":"先日、「ElasticSearch Serverを翻訳しました」という記事を書きました。\nこの中で電子版も出ますよと書いていましたが、電子版も発売されたので、再告知も兼ねてブログを書いています。\nなお、最近よく「ElasticsearchのSは小文字」とツイートしていますが、本書は原著のタイトルが「ElasticSearch Server」となっているため、Sは大文字になっています。原著が出版された時期にはまだSが小文字に統一されていなかったためです。\n紙の書籍はすでに書店に並んでいたり、Amazonでも発送されているようです。\n私自身が電子書籍が場所を取らなくて好きというのもあり、電子版も出版していただけるようにお願いしていました。\n電子版についてはAmazonでKindle版、達人出版会からEPUBとPDFが購入可能です。\n達人出版会のElasitcSearch Serverのページ AmazonのKindle版ページ こちらのリンク(Amazonはアフィリンク)を参考にしていただければと。\n書籍の写真入りツイートしたら、原著者の方からレスを頂きました。\n@johtani Thanks for the great work out there :)\n\u0026mdash; Rafał Kuć (@kucrafal) 2014, 3月 23 また、原著者のサイトでも紹介してもらいました(結構うれしい)。 私が窓口をやっていた関係で、私の名前しか入っていませんが。。。 編集者と翻訳者の方々のお陰で良い本が出版できたと思っています。\nThanks for sharing! / ElasticSearch Server book in Japanese | ElasticSearch Server Book Blog http://t.co/fhCP1vVBd3\n\u0026mdash; Jun Ohtani (@johtani) 2014, 3月 24 ということで、Elasticsearchの導入の手助けになればと。 感想(賛否問わず)など、あればコメント、ツイート、ブログなど書いていただければうれしいです。 (その際に、連絡してもらえるとさらにうれしいです)\n","date":1395722580,"dir":"post/2014/","id":"d51032bef3e7117a94336fea18a3fad7","lang":"ja","lastmod":1395722580,"permalink":"https://blog.johtani.info/blog/2014/03/25/release-elasticsearch-server-ja-ebook/","publishdate":"2014-03-25T13:43:00+09:00","summary":"先日、「ElasticSearch Serverを翻訳しました」という記事を書きました。 この中で電子版も出ますよと書いていましたが、電子版も発","tags":["elasticsearch"],"title":"ElasticSearch Server日本語版(電子版も)が発売されました"},{"contents":"GOTO Night elasticsearchに参加しました。 初の海外の勉強会です(海外自体が初だし)。\nベルリンにあるWoogaという会社で開催された勉強会です。\nFull house at the #gotonight about @elasticsearch in the auditorium of @wooga pic.twitter.com/r2Vx2aMcEn\n\u0026mdash; GOTO Berlin (@GOTOber) 2014, 3月 18 会場はこんな感じで、とってもおしゃれです。(なんか、写ってますね、最前列にw) ベルリンの古い建物をリノベーションしたオフィスみたいで、そこにこういったひな壇を用意して発表するスペースにしているみたいです。\n内容としては、Elasticsearch1.0の新機能の話として、snapshot/restore、cat、aggregationなどの話題でした。簡単にどういったものかの説明です。\n一人目の発表が終わったら、ブレイクタイムとして上のフロアに用意されている軽食+ドリンクで軽く交流の時間が用意されていました。 ベーグルなどのサンドイッチとハイネケンやクラブマテ?と呼ばれるチープなレッドブルとかが飲めました。\nちょっと食べて談笑したあとに、次はLogstashとKibanaのお話でした。Logstashってどんなもの?という話がメインで、Kibanaは簡単な紹介という感じでしょうか。最後に、ライブデモがありました。 Kibanaを使ったライブデモはインパクトがあるなというのが感想です。 フィールド名の補完をしてくれたりと便利な機能が操作をしているところでわかるので。\nYoutubeなどでも見てても思っていた感想ですが、こちらの勉強会は質問が結構出てきます。 今日参加した勉強会も質疑応答が結構されてました。\nelasticsearchの方たちと少しだけ話しをできたので、かなり興奮気味でブログを書いています(ミーハー)。\nただ、やっぱり英語のヒアリングがまだまだだなぁとも実感出来ました。 場数踏むしかないと思うので少しずつ耳にしてなれるしかないかなぁと。 はぁ、ちゃんと高校とか大学の頃に単語を覚えとくんだったと軽く後悔。\nこんなツイートもしてもらって、興奮気味です。明日早起きしないといけないので寝ないといけないのにw\nMeeting @johtani finally in #berlin watching @spinscale talking about #elasticsearch\n\u0026mdash; Simon Willnauer (@s1m0nw) 2014, 3月 18 ","date":1395151860,"dir":"post/2014/","id":"65453a1ae403679bd2e47398a04205ca","lang":"ja","lastmod":1395151860,"permalink":"https://blog.johtani.info/blog/2014/03/18/attend-goto-night-elasticsearch/","publishdate":"2014-03-18T23:11:00+09:00","summary":"GOTO Night elasticsearchに参加しました。 初の海外の勉強会です(海外自体が初だし)。 ベルリンにあるWoogaという会社で開催された勉強会","tags":["elasticsearch","勉強会"],"title":"GOTO Night elasticsearchに参加しました"},{"contents":"Berlinからおはようございます。\nということで、人生で初めての海外に来ています。\n人生初の海外なのに、一人で乗り換えがあるようなBerlinに来ています。 今年はチャレンジの年になりそう。初めてづくしですが、楽しみたいなと。 会社に感謝です。ESのトレーニングを受けに来たのがメインなのです。 ついでに、Berlinでの勉強会にも参加してみようかなと。\n幸いにも時差ボケはなさそうなので、色々と見て回ろうと思います。 ただ、日曜日はお店が軒並みしまってそう。。。\n","date":1394916660,"dir":"post/2014/","id":"abc5ca9856a61831fd4ed06b402875d2","lang":"ja","lastmod":1394916660,"permalink":"https://blog.johtani.info/blog/2014/03/16/post-from-berlin/","publishdate":"2014-03-16T05:51:00+09:00","summary":"Berlinからおはようございます。 ということで、人生で初めての海外に来ています。 人生初の海外なのに、一人で乗り換えがあるようなBerlin","tags":["misc","travel"],"title":"Berlinからおはようございます"},{"contents":"elasticsearchに、このへん入れるときっと幸せになれるはず・たぶん。\u0026#10;elasticsearch/elasticsearch-analysis-kuromoji/1.6.0\u0026#10;oyrusso/elasticsearch-HQ\u0026#10;mobz/elasticsearch-head\n\u0026mdash; toshi_miura (@toshi_miura) 2014, 3月 5 こんなツイートを見かけたので、普段入れてるプラグインを簡単に紹介してみようかと。\nローカルの環境に普段入れているプラグインの紹介です。 ちゃんとクラスタを管理しているというよりは、最新版の動作などを確認するための環境になります。なので、ちょっと視点が異なるかもしれませんが参考になればと。\nelasticsearch-analysis-kuromoji URL : elasticsearch-analysis-kuromoji\nKuromojiという日本語形態素解析のTokenizerなどを使えるようにするためのプラグインです。 今度、発売される「ElasticSearch Server」日本語版には付録として、利用方法を執筆しました。参考にしていただければと。 READMEにもサンプルは掲載されてるので、こちらを参考にするのもありですが。\nelasticsearch-extended-analyze URL : elasticsearch-extended-analyze\n私が開発しているプラグインです。 ElasticsearchにはanalyzeというAPIが用意されています。 文章を渡すと指定したanalyzerなどでどのような単語に区切られるかがわかるAPIです。\nただ、analyzerの内部ではchar filter、tokenizer、token filterという個別のパーツがそれぞれ入力された文字列に対して処理を実施します。 この過程がanalyze APIではわかりません。 それをわかるようにしてみたのがelasticsearch-extended-analyzeプラグインになります。\n詳細については過去の記事を見ていただければと。 画面があると便利だよなぁと思いつつ、作ってない。。。\npolyfractal/elasticsearch-inquisitor URL : elasticsearch-inquisitor\nクエリのデバッグとかに便利なプラグイン。\nこちらも詳細は過去の記事を見ていただければと。\nmobz/elasticsearch-head URL : elasticsearch-head\nクラスタ管理に便利なプラグインです。クラスタに存在するノードに対してインデックスのデータ(シャード)がどこに配置されているかなどが一目瞭然になる便利なプラグインです。 プライマリシャードやレプリカなどもわかります。 インデックスの削除もできるし、クエリを投げることもできるし、全部入りな感じのプラグインです。\n私個人は、シャードの配置を見るのに主に利用しています。クエリを投げたりインデックスを消したりするのには殆ど使っていません。\nroyrusso/elasticsearch-HQ URL : elasticsearch-HQ\nこれも管理系のプラグインです。こっちのほうが個人的にスッキリしていて好きなプラグインです。 インデックスの管理やノードの停止などはこちらを主に使用しています。 あくまでもローカルの簡易クラスタを管理する目的というのもあります。\npolyfractal/elasticsearch-segmentspy URL : elasticsearch-segmentspy\nこちらはモニタリングでしょうか。 ElasticSearch Serverで紹介されていたのが主な理由で、入れてますがあんまり見てないかも。 インデックスのSegment単位の情報が見ることが可能です。 あと、ちょっと更新されてない感じがしますね。\nelasticsearch/marvel Elasticsearch社から提供されている、モニタリングなどに使えるプラグインです。 開発環境では無償提供という感じです。 渡しの場合、モニタリング目的ではなく、senseと呼ばれるクエリの補完をしてくれるツールの目的のために使用しています。 モニタリング部分を停止する方法とかないかなぁ。\n詳細については過去の記事を参考にしていただければと。\nまとめ? ということで、簡単にローカルに入っているプラグインの紹介でした。 他にもいっぱいあるので、おすすめがあれば、教えてもらえると助かります。\n","date":1394515380,"dir":"post/2014/","id":"386dc9d1b647a9f3965f1fbe29c7dfb9","lang":"ja","lastmod":1394515380,"permalink":"https://blog.johtani.info/blog/2014/03/11/es-plugin-installed-to-my-env/","publishdate":"2014-03-11T14:23:00+09:00","summary":"elasticsearchに、このへん入れるときっと幸せになれるはず・たぶん。\u0026#10;elasticsearch/elasticsearc","tags":["elasticsearch","plugin"],"title":"いつも入れているElasticsearchのプラグイン"},{"contents":"第3回Elasticsearch勉強会で、軽く触れていましたが、ElasticSearch Server日本語版が発売されます。 ツイートなどもちらほらとして頂いているみたいで嬉しい限りです。\n本書は、私自身、初の翻訳本となります。\nなお、ElasticSearchはAWSのサービスではなく、全文検索・解析サーバのOSSです\n内容、概要 PacktPublishingから発売されているElasticSearch Serverの日本語版となります。 以下の点が、原著とは異なる点になっています。\n0.90.xに対応(原著は0.20) Kibana、Kuromojiに関して追記 もちろん日本語 残念ながら、つい最近、Elasticsearchについては1.0がリリースされました。 1.0で追加された機能(SnapshotやRestore、Aggregatorなど)については触れていませんが、Elasticsearchの機能を網羅的にカバーした良書となっています。 どんな機能があるのか、どんなプラグインがあるのか、どういったことに使えるのかなど、幅広くまとめられた本になっていますので、 Elasticsearchに興味がある方はぜひ読んでいただければと思います。\nまた、現段階では予定ですが電子版の出版も予定されています。電子版が気になる方は、少しお待ちいただければと。\nElasticSearch?Elasticsearch? 1.0.0がリリースされた現在は、Elasticsearch(SearchのSは小文字)が正式な名称となっています。 ただ、原著が発売された当初(2013年2月時点)では、まだSは小文字と大文字が混在した状況でした(コミットログなどを見るとわかります。) このため、日本語版でもElasticSearchという表記に統一してあります。\n翻訳に関して 初の翻訳書ということもあり、大変でした。英語に精通しているわけではないので(むしろ苦手)。。。 他の翻訳者の方々には大変助けていただきましたし、勉強になりました。 また、監修社であるリクルートテクノロジーズにも色々とサポートしていただき、感謝の限りです。 (Elasticsearch勉強会の開場提供にも協力して頂いています。)\nわかりにくい日本語となっている部分などありましたら、ご指摘いただければ今後の参考にさせていただきます。 英語やElasticsearchについて、学ぶという目的もあって、本書の翻訳を買って出たのが本音です。\n翻訳作業について Githubのリポジトリを編集の方に用意してもらい、翻訳原稿を管理、校正していきました。 Github自体をあまり触っていなかったので、作業をしながらGithubも覚えられ一石二鳥でした。 Issueやプルリクエストによる校正、チェックも便利ですね。 他の原稿を書くようなことがあれば、またこの経験を活かしていきたいなと。 (翻訳の進め方や原稿のチェックなどについてはまた後日何か書こうかと。)\n原著について 原著のサイトが用意されています。 http://elasticsearchserverbook.com/elasticsearch-server-errata/\n原著を翻訳するにあたって見つけた、誤植などを報告し、掲載して頂いています。 原著をお持ちの場合はこちらも参考にしていただければと思います。\nご購入はこちらから ということで、簡単ですが書籍の紹介(というより宣伝!?)でした。 Elasticsearchに関する何かしらの助けになる書籍であれば嬉しい限りです。\n「ElasticSearch Server日本語版」をよろしくお願いします。 (もちろん、購入は下のリンクからですよね!)\n","date":1393836900,"dir":"post/2014/","id":"9ad72c2a5157f21741bd4581a562dfc7","lang":"ja","lastmod":1393836900,"permalink":"https://blog.johtani.info/blog/2014/03/03/release-elasticsearch-server-japanese-edition/","publishdate":"2014-03-03T17:55:00+09:00","summary":"第3回Elasticsearch勉強会で、軽く触れていましたが、ElasticSearch Server日本語版が発売されます。 ツイートなども","tags":["elasticsearch"],"title":"ElasticSearch Serverを翻訳しました"},{"contents":"今年初の「突撃!隣のElasticsearch」ということで、Wantedlyさんにおじゃましました。\n※写真を自分でも撮ったのですが、画像が壊れてたので、一緒に行ったペンギン先生の写真を拝借しました。\n第3回のElasticsearch勉強会を開催中にES使ってるってツイートを見つけたので、アタックかけて遊びに行きました。 交渉に快諾いただきありがとうございました!\nWantedlyさんがどのようにElasticsearchを使用されているかはきっと、ブログを書いてくれると思うので期待しておくとして、書いてくれました!! 「実践!Elasticsearch」 そこで、nestedでハイライトがなんかうまくいかないって話があったので、ちょっと調べてみました。 (※まだ、調査中です)\n前提条件 再現する手順はgistにあります。(Senseに貼り付ければ動作します。ただし、elasticsearch-analysis-kuromojiが必要です。)https://gist.github.com/johtani/9184287\nなお、このマッピングやデータはWantedlyさんとは全く関係ありません。\nnestedフィールド内部のデータに対して、検索しハイライトしようとするとうまく動作しないという状況です。 マッピングは以下のとおり。\n\u0026#34;books\u0026#34; : { \u0026#34;properties\u0026#34;: { \u0026#34;book\u0026#34; : { \u0026#34;type\u0026#34;: \u0026#34;nested\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;title\u0026#34; : { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;kuromoji\u0026#34;, \u0026#34;store\u0026#34;: \u0026#34;no\u0026#34;}, \u0026#34;contents\u0026#34; : {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;kuromoji\u0026#34;, \u0026#34;store\u0026#34;: \u0026#34;yes\u0026#34;} } } } } } このマッピングの特徴は以下のとおり。\n_sourceは保存される(デフォルト値) bookがnestedなオブジェクト titleはstore : no contentsはstore : yes 動作の挙動をわかりやすくするため、titleとcontentsのstore属性に違いを持たせてあります。\n問題点 nestedクエリを使って、検索した時にハイライトが返ってきません。 次のクエリを実行するとわかります。\nGET /bookstore/books/_search { \u0026#34;_source\u0026#34; : [\u0026#34;book.title\u0026#34;,\u0026#34;book.contents\u0026#34;], \u0026#34;fields\u0026#34;: [ \u0026#34;book.title\u0026#34;, \u0026#34;book.contents\u0026#34; ], \u0026#34;query\u0026#34;: { \u0026#34;nested\u0026#34;: { \u0026#34;path\u0026#34;: \u0026#34;book\u0026#34;, \u0026#34;query\u0026#34;: { \u0026#34;query_string\u0026#34; : { \u0026#34;query\u0026#34; : \u0026#34;Solr\u0026#34;, \u0026#34;fields\u0026#34; : [\u0026#34;book.title\u0026#34;, \u0026#34;book.contents\u0026#34;] } } } }, \u0026#34;highlight\u0026#34;: { \u0026#34;pre_tags\u0026#34;: [\u0026#34;\u0026lt;b\u0026gt;\u0026#34;], \u0026#34;post_tags\u0026#34;: [\u0026#34;\u0026lt;/b\u0026gt;\u0026#34;], \u0026#34;fields\u0026#34;: { \u0026#34;*\u0026#34;: {} } } } 結果はこちら。 ハイライトがありません。\n{ \u0026#34;took\u0026#34;: 3, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 5, \u0026#34;successful\u0026#34;: 5, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;max_score\u0026#34;: 0.5, \u0026#34;hits\u0026#34;: [ { \u0026#34;_index\u0026#34;: \u0026#34;bookstore\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;_score\u0026#34;: 0.5, \u0026#34;_source\u0026#34;: { \u0026#34;book\u0026#34;: { \u0026#34;title\u0026#34;: \u0026#34;Apache Solr入門\u0026#34;, \u0026#34;contents\u0026#34;: \u0026#34;Apache Solrについて日本語で書かれた唯一の書籍です。SolrはLuceneをコアにした検索サーバです。\u0026#34; } } } ] } } 次に、ハイライトが帰ってくるパターン。 nestedクエリではなく、_allを対象としたクエリを投げます。\n{ \u0026#34;_source\u0026#34; : [\u0026#34;book.title\u0026#34;,\u0026#34;book.contents\u0026#34;], \u0026#34;fields\u0026#34;: [ \u0026#34;book.title\u0026#34;, \u0026#34;book.contents\u0026#34; ], \u0026#34;query\u0026#34;: { \u0026#34;query_string\u0026#34; : { \u0026#34;query\u0026#34; : \u0026#34;Solr\u0026#34;, \u0026#34;fields\u0026#34;: [ \u0026#34;_all\u0026#34; ] } }, \u0026#34;highlight\u0026#34;: { \u0026#34;pre_tags\u0026#34;: [\u0026#34;\u0026lt;b\u0026gt;\u0026#34;], \u0026#34;post_tags\u0026#34;: [\u0026#34;\u0026lt;/b\u0026gt;\u0026#34;], \u0026#34;fields\u0026#34;: { \u0026#34;book.title\u0026#34; : {}, \u0026#34;book.contents\u0026#34;: {} } } } この場合の結果は次の通り。\n{ \u0026#34;took\u0026#34;: 2, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 5, \u0026#34;successful\u0026#34;: 5, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;max_score\u0026#34;: 0.27063292, \u0026#34;hits\u0026#34;: [ { \u0026#34;_index\u0026#34;: \u0026#34;bookstore\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;_score\u0026#34;: 0.27063292, \u0026#34;_source\u0026#34;: { \u0026#34;book\u0026#34;: { \u0026#34;title\u0026#34;: \u0026#34;Apache Solr入門\u0026#34;, \u0026#34;contents\u0026#34;: \u0026#34;Apache Solrについて日本語で書かれた唯一の書籍です。SolrはLuceneをコアにした検索サーバです。\u0026#34; } }, \u0026#34;highlight\u0026#34;: { \u0026#34;book.title\u0026#34;: [ \u0026#34;Apache \u0026lt;b\u0026gt;Solr\u0026lt;/b\u0026gt;入門\u0026#34; ] } } ] } } ハイライトが返ってきています。\n考察(原因は未特定) 残念ながら、まだ調査してません。 まずは、現象が理解できたというだけです。 問題点が実は2つありそうです。\n問題点1:nestedクエリの場合に、ハイライトされない。 nestedクエリではハイライトが動作していないようです。 想像ですが、検索に利用されたクエリで指定されているフィールドをハイライタ(ハイライトを実行するモジュール)が認識できてないのではないかと。 なぜ認識できていないのかという点を調査する必要がありそうです。\n考察(試してみたパターン) nestedではないクエリで、ハイライトが動作しているのですが、 \u0026quot;book.title\u0026quot; : {\u0026quot;require_field_match\u0026quot; : true},にした場合は、ハイライトが返ってこないです。 このオプションは、検索対象のフィールドでマッチした文字列だけがハイライトされるオプションになります。 したがって、book.titleフィールドに対する検索でSolrという文字を検索していないことになります。 _allに対するクエリであるためです。 このため、例えば、titleだけを検索対象にしたのに、contentsにSolrという文字が入っていてもハイライトされてしまうという状況が発生します。\n問題点2 store : yesのデータがハイライトできない。 GithubにIssueをあげました。https://github.com/elasticsearch/elasticsearch/issues/5245 (2014/02/25追記)\nnestedオブジェクトにあるデータのうち、store : noのものだけがハイライト結果として返ってきました。\n考察 なぜ、store : yesのデータがハイライトされないかを調べるために、fieldsパラメータをリクエストに追加してみました。\n{ \u0026#34;_source\u0026#34; : [\u0026#34;book.title\u0026#34;,\u0026#34;book.contents\u0026#34;], \u0026#34;fields\u0026#34;: [ \u0026#34;book.title\u0026#34;, \u0026#34;book.contents\u0026#34; ], ... } すると、fieldsの戻り値は次のとおりです。\n... \u0026#34;fields\u0026#34;: { \u0026#34;book.title\u0026#34;: [ \u0026#34;Apache Solr入門\u0026#34; ] }, ... このことから、store : noのデータの場合、_sourceから値を取得して返却しているというのがわかります。 ハイライトがされない原因も、fieldsで値が取れていないのも同じ原因であると思われます。 なぜなら、ハイライトは、保存された文字列を内部で取り出し利用して、ハイライトタグを埋め込むという動作をするためです。\n参考? これらの問題点についてですが、次のIssueが関係あるかもしれません。\nReturn matching nested inner objects per hit #3022\n今後? 残念ながら、現時点では、問題点がどんなものかというのを理解しただけとなります。 デバッグしたりソースを追っかけたりして何が問題なのかを調べて行ってみようかなぁと。\nなにか、気づいたことなどあればコメントしてもらえると助かります。\n","date":1393231920,"dir":"post/2014/","id":"f55d33371dcff207fd7d201128df2ea3","lang":"ja","lastmod":1393231920,"permalink":"https://blog.johtani.info/blog/2014/02/24/strange-behavior-of-field-in-nested-obj/","publishdate":"2014-02-24T17:52:00+09:00","summary":"今年初の「突撃!隣のElasticsearch」ということで、Wantedlyさんにおじゃましました。 ※写真を自分でも撮ったのですが、画像が","tags":["elasticsearch"],"title":"Nested Objectのフィールドの奇妙な動作"},{"contents":"今回はたまたま日本にいたElasticsearchの人をスペシャルゲストに呼べたので、大満足ですw 英語の通訳とかちゃんと勉強しないとなぁ。。。\nとりあえず、てきとーなメモですが、残しておきます。 参加者数は130人+スタッフ+リクルートテクノロジーズ社内の人。という感じでした。アンケート集計はもう少々おまちを。\nスライドがそろったら、また、更新すると思いますが、第一報という感じで公開しておきます。 懇親会にも50名も参加していただけて、非常に楽しかったです。 話ができてない方が多数いるかもしれませんが、次回以降、声をかけていただければと。 (物覚え悪いんで、あれですが。。。) 盛り上がってきてて楽しいなぁ。 スタッフの人達の練度も上がってきてるので、すごく楽ができてます。\n至らない点とかあれば、こちらにコメントしてもらったりしていただければと。\nGeohashing with Elasticsearch Florian Schilling, Elasticsearch Inc, スライド:https://speakerdeck.com/chilling/tokyo-es-study-session-iii-geohashes\n自己紹介 Geoのスタッフ Elsticsearchの概要 転置イデックスやREST APIなどの説明 マイクの調子が良くなくて申し訳なかったっす。。。 平賀さん、通訳ありがとう! Solr本もよろしくお願いします!!\nAWSで構築するsharding 株式会社イプロス 外山 寛さん @toyama0919 スライド:http://toyama0919.bitbucket.org/elasticsearch.html\nAWS対応の話 ルーティングが重要だよ。(宣伝ありがとうございますw) type指定しないとルーティングできない。(内部でtypeも使ってハッシュ値取ってたかなぁ?) 苦労話とかいくつか。 tireはre-tire\u0026hellip; 実サービスでのElasticsearch設定・使用例(仮) 株式会社じげん 多田 雅斗さん @tady_jp スライド:https://speakerdeck.com/tadyjp/tesutoqu-dong-jian-suo-falsesusume-at-tady-jp\n検索とは的な話がわかりやすい。 全文検索のお話。ログ検索じゃないよと。 書籍ないですよねー(ふふふ) specで検索条件記述しといて、ってのいいですよね。絶対必要だと思う Mapping変更した時にテストやり直す方法とかどうしてますか? 特にフレームワークは使ってないです。\nMySQLユーザ視点での、小さく始めるElasticsearch 株式会社リブセンス 吉田 健太郎さん @yoshi_ken スライド:http://www.slideshare.net/y-ken/introducing-elasticsearch-for-mysql-users\nやっぱりkuromoji便利だよね MySQLとかと連携したい。 river-pluginもいまいち安定しない なので、Yamabiko作ってみました。 Geo検索とKuromojiの話をしてくれました。(作者とか開発者がいるってのを狙ってたのかすごいなぁ。) Mappingとかはちゃんと指定したほうがいろいろいいですよ。 nodeJS+DynamoDB+Elasticsearchで全社基盤を作った話 株式会社リクルートテクノロジーズ 相野谷 直樹さん @naokiainoya スライド:http://www.slideshare.net/recruitcojp/elasticsearchnodejsdynamodb-7\nちょっと変わった使い方のElasticsearchで面白いです。 Scroll/Scanについては、Solrでもない機能なので、そういう意味でもElasticsearchなのかもしれないですね。 参加していただいた方々のブログ 第3回elasticsearch勉強会 [2014/02/07(Fri.)]に参加してきました - ほわいとぼーど\nhttp://a3no.hatenablog.com/entry/2014/02/09/022405\n第 3 回 elasticsearch 勉強会に行ってきた - ようへいの日々精進\nhttp://inokara.hateblo.jp/entry/2014/02/07/233057\nhttp://www.smokeymonkey.net/2014/02/3elasticsearch.html\n第3回elasticsearch勉強会でトークしました #elasticsearchjp\nhttp://y-ken.hatenablog.com/entry/elasticsearch-meetup-vol3\n第3回elasticsearch勉強会にいってきました #elasticsearchjp\nhttp://blog.livedoor.jp/ashibuya0128/archives/52058766.html\n","date":1391787720,"dir":"post/2014/","id":"229b7fc784707b1d2c702fbeba080e86","lang":"ja","lastmod":1391787720,"permalink":"https://blog.johtani.info/blog/2014/02/08/hold-3rd-elasticsaerch-meetup-in-tokyo/","publishdate":"2014-02-08T00:42:00+09:00","summary":"今回はたまたま日本にいたElasticsearchの人をスペシャルゲストに呼べたので、大満足ですw 英語の通訳とかちゃんと勉強しないとなぁ。。","tags":["elasticsearch","勉強会"],"title":"第3回elasticsearch勉強会を開催しました! #elasticsearchjp"},{"contents":"すずけんさんがVagrant+puppet使って、VM起動してElasticsearchのクラスタを組んでる記事を書いているのを見て、試してみたくなりました。 ということで、VagrantとかPuppetなに?くらいの私ですが、クラスタを起動するところまで行ったので、その時のメモを残しておきます。\n元記事とか参考 Vagrant環境にpuppet moduleを利用してさくっとelasticsearchをインストールする Vagrant環境にpuppetを利用してさくっとelasticsearchのclusterを作成する puppet-elasticsearch なんとなくの理解 VagrantやPuppetについては、何度か勉強会で話を聞いてはいたのですが、 想像していたレベルだったので良い機会でした。 今のところの認識はこんな感じです。\nVagrant VMを起動したり、VM周りの設定をあれこれできるツール。 VMのネットワーク設定や、インスタンス名?などを指定できる。\nPuppet 起動後のVM(VMとは限らないか。)のゲストOS側の設定周りやアプリのインストールなどを 実行できるツール。\n詰まった箇所 すずけんさんのブログを元に作業をしましたが、自分がVagrantやPuppetに疎いため、以下の部分で躓いたので、備忘録のために残しておきました。\nその1:Puppetのファイルの場所 search01.vm.localのVMを設定(というか、elasticsearchのインストール?)するときに、manifests/search.appとroles/search/manifests/init.ppファイルが必要で作成します。\nこのファイルの配置場所は/vagrant配下に作成する必要がありました。 ssh search01.vm.localでVMにログインした場合は/home/vagrantにログインしており、この場所でファイルを作ってもPuppetがエラーを吐いたためです。\nと思ったのですが、あれ?これひょっとしてVagrantfileがあるところにディレクトリとファイル作ると勝手にVMにコピーしてくれるんですか?destroyして、upしたら、ファイルが勝手にコピーされてる。ひょっとして、/vagrantってディレクトリはVagrantfileがあるディレクトリを共有してたりするのかな?そのうち、Vagrantについても調べてみようかな。\nその2:ネットワーク周り curl http://192.168.10.114:9200/ をホストOSから実行してみましたがうまく行きませんでした。。。 ネットワーク周りの設定だと思うんですが。 少なくとも「sshによるログイン」「ping」コマンドの応答は返ってきてます。\nまた、VM内でcurlコマンドを実行したらレスポンスが返ってきました。\nなんで?ってツイートしたら各所から「iptables」という単語が飛んできて、 service止めたら大正解でした。まぁ、そうですよね。基本ですよね。。。\nということで、Puppetがよくわかっていませんが、ググって変更してみました。\nmanifests/search.appに以下を追加\ninclude iptables roles/iptables/manifests/init.pp\nclass iptables { service { \u0026#39;iptables\u0026#39;: enable =\u0026gt; false, ensure =\u0026gt; stopped, } } iptablesを停止するmanifests?です(良くないことなんですが、よくわかってない)。\nということで、ローカルで1個のVM起動して、elasticsearchにアクセスできることは確認できました。\nと、書いてるそばから、元記事が修正されてしまいましたw\nクラスタ編(変更点) クラスタを組むときに、追加でプラグインを入れたのでroles/search/manifests/init.ppは次のようにしました。\nclass search { class { \u0026#39;elasticsearch\u0026#39;: package_url =\u0026gt; \u0026#39;https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.0.0.RC2.noarch.rpm\u0026#39;, java_install =\u0026gt; true, config =\u0026gt; { \u0026#39;cluster\u0026#39; =\u0026gt; { \u0026#39;name\u0026#39; =\u0026gt; \u0026#39;test-es-cluster\u0026#39; }, \u0026#39;network.host\u0026#39; =\u0026gt; \u0026#39;_eth1:ipv4_\u0026#39;,, \u0026#39;marvel.agent.exporter.es.hosts\u0026#39; =\u0026gt; [\u0026#39;192.168.10.114:9200\u0026#39;,\u0026#39;192.168.10.115:9200\u0026#39;] } } elasticsearch::plugin{\u0026#39;elasticsearch/marvel/latest\u0026#39;: module_dir =\u0026gt; \u0026#39;marvel\u0026#39; } elasticsearch::plugin{\u0026#39;mobz/elasticsearch-head\u0026#39;: module_dir =\u0026gt; \u0026#39;head\u0026#39; } elasticsearch::plugin{\u0026#39;royrusso/elasticsearch-HQ\u0026#39;: module_dir =\u0026gt; \u0026#39;HQ\u0026#39; } elasticsearch::plugin{\u0026#39;elasticsearch/elasticsearch-analysis-kuromoji/2.0.0.RC1\u0026#39;: module_dir =\u0026gt; \u0026#39;analysis-kuromoji\u0026#39; } elasticsearch::plugin{\u0026#39;info.johtani/elasticsearch-extended-analyze/1.0.0.RC1\u0026#39;: module_dir =\u0026gt; \u0026#39;extended-analyze\u0026#39; } elasticsearch::plugin{\u0026#39;polyfractal/elasticsearch-inquisitor\u0026#39;: module_dir =\u0026gt; \u0026#39;inquisitor\u0026#39; } } とりあえず、今日はクラスタ組んでMarvelやプラグインの動作確認でおしまいです。\n疑問点 いくつか疑問点が。試してみてもないんでなんとも言えませんが。気が向いたら、調べて追記するかも。\n:private_networkはVirtualBox内で完結する(Macから外には影響しない)ネットワークが構築される?たぶん、VagrantというよりはVM、仮想化周りの知識なんだろうけど どこから再開可能?elasticsearch.ymlの設定を書き換えた場合に、最後のコマンドだけ実行するとちゃんとやりなしてくれたりするのかな? VMのディスク増やすのもVagrantでできるんかな?まぁ、できると思うけど。 :forwarded_portのauto_correctとかわかってない。 JVMをSunのJVMでかつ、7u25に変更したいのだがどうしたものか?(現時点での推奨バージョン) 感想 Vagrantって便利ですね。あれ?って思ったら、destroyして、やり直すのがすごく簡単です。 元記事があるので、なんとなくですが、構成とかどうすればいいかがわかるのは本当に助かりました。 これで、あれこれと検証する環境が簡単に構築できることがわかったので、色々と楽できるかも。ありがとうございます、すずけんさん!\n","date":1391695740,"dir":"post/2014/","id":"c98cbc333fb7d95c6c9fc4924b0526e1","lang":"ja","lastmod":1391695740,"permalink":"https://blog.johtani.info/blog/2014/02/06/es-cluster-start-using-vagrant-and-puppet/","publishdate":"2014-02-06T23:09:00+09:00","summary":"すずけんさんがVagrant+puppet使って、VM起動してElasticsearchのクラスタを組んでる記事を書いているのを見て、試して","tags":["elasticsearch","vagrant","puppet","marvel"],"title":"すずけんさんのメモを元にVagrantでElasticsearchクラスタを起動してみた"},{"contents":"改訂新版Solr入門出版記念ということで、第13回Solr勉強会 #SolrJP 新Solr本出版記念を開催しました。\n出版記念なので、技術評論社様より、プレゼント用にSolr本を用意していただきました!ありがとうございます!! 書籍をゲット出来た方は、ツイートしたりブログ書いたり書評書いたりして、宣伝してください!!!\n今回は、私は手を抜いて他の人に喋ってもらいました!\n今回は、著者陣(関口さんは特別ゲスト)でスピーカーを固めてみました。 以下は、いつもの簡単なメモです。 スライドが集まったらまた更新していきます。\n1. 「はじめての検索エンジン&Solr」 株式会社NTTデータCCS 鈴木 教嗣さん スライド:はじめての検索エンジン&Solr 第13回Solr勉強会\n鈴木さんの発表初めて聞きましたw。 趣味が多いなぁ。 ちょこちょこと、宣伝を入れてるのが流石ですw\n入門らしい概要 クエリの概要とかも。 スコア計算とか 導入するとうれしいところとか Solr盛り上げましょう! 2. 「Solr SearchComponent 再訪」 株式会社ロンウイット 関口 宏司さん スライド:公開待ち\nベン図で検索の評価指標の説明 理論的なお話 Solrのサーチコンポーネントを使って何ができるか。ベン図で。 サーチコンポーネント以外にも NGramTokenizerも SynonymFilterも パーソナライズ検索 いきなり話をふられたのでちょっとびっくりしましたw\n3. 「自動補完(Autocomplete)ともしかして?(Did You Mean?)」 株式会社 ロンウイット 大須賀 稔さん スライド:Solr AutoComplete and Did You Mean?\nデモ:https://github.com/mosuka/solr-suggester-demo-ui\n職歴が相変わらずおもしろい 編集距離のお話 素晴らしいCM! 候補のランキングを変更できる? SpellcheckComponentのパラメータで指定できるものなら楽ですが。。。\n4. 「Lucene Revolution 2013 Dublin振り返り」 楽天株式会社 平賀 一昭さん スライド:公開待ち\nダブリンどこ?(間違ってベルリンって言っちゃいましたw) スタジアムで開催。グランドにも入れるのかなぁ? まずはTwitter Luceneの改良版 ちょっと特殊。140文字とか 青いRさんのライバル。Careerbuilder 元FASTユーザ 企業向けに検索キーワードとかの解析画面を用意 検索精度の改良の話とか 転職で引っ越す意思があるかとか。 最後はLinkedIn Luceneのユーザ まとめ ということで、スピーカーの方々のスライドにもありましたが、 改訂新版Apache Solr入門は良い本なので、購入していただけると嬉しいです。\n感想、コメントなど、いつでもお待ちしています!\n","date":1390988760,"dir":"post/2014/","id":"c6107ff57e96a1373c019d252c00ad84","lang":"ja","lastmod":1390988760,"permalink":"https://blog.johtani.info/blog/2014/01/29/hold-to-japan-solr-meetup/","publishdate":"2014-01-29T18:46:00+09:00","summary":"改訂新版Solr入門出版記念ということで、第13回Solr勉強会 #SolrJP 新Solr本出版記念を開催しました。 出版記念なので、技術評論社様より、プレ","tags":["Solr","勉強会"],"title":"第13回Solr勉強会を開催しました"},{"contents":"昨晩、Elasticsearchから初のプロダクトとなるMarvelがリリースされました。ということで、さっそく触ってみて、簡単な紹介と感想を書いてみました。\nMarvelって? Elasticsearch社が初のプロダクトとしてリリースした、Elasticsearchクラスタモニタリングツールです。 次のような特徴があります。\nplugin形式で提供 GUIがKibana メトリックスはElasticsearchに保存 SenseがChrome以外でも使える プロダクション環境で利用する場合は有料ですが、開発用途では無料で利用できます。 現時点(2014/01/29)では、0.90.9以上のバージョン(1.0.0.RC1含む)で利用が可能です。\nなにができるの? Elasticsearchクラスタに関するメトリックスを保存、可視化できるプロダクトです。 ドキュメント数やJVMの状況、クラスタの状態など、いろいろなメトリックスが保存されます。\n保存先は、別のElasticsearchクラスタにすることも可能です。 お試しでインストールして見る場合は、同一クラスタにサービスに利用するインデックスとMarvel用のメトリックス保存先インデックスを入れても良いです。\nただ、プロダクション環境では、Marvel用インデックスはあくまでもモニタリングに使用するため、サービスのクラスタへの影響を最小にしたくなります。\nこのような場合、Marvelのプラグインの設定を変更することで、メトリックス送信用のエージェントとして動作させることができます。\n詳しくは、Marvelのドキュメントにあるinstalling a secondary monitoring clusterを御覧ください。\n1/29 16時時点で、上記ドキュメントのエージェントの送信先の設定に関する部分に誤記がありました。 おそらく、configuration optionsの記述が正だと思います。 もう、なおってました。(1/30朝時点)\nキャプチャいろいろ 日本語WikipediaのデータをRiverで登録しながら各画面の動作などを見てみました。\nMarvel Overview 日本語WikipediaをRiverで登録してる途中。Loadが高くなってることなどがわかります。\nOverview (クラスタの状態が変化) クラスタの状態が変化したところに、タグが付くみたいです。 ここでは、ノードの一つを停止、起動しました。\nインデックス終了後に、クラスタを再起動してしまい、クラスタ内のシャードの再配置が実行されてしまったため、クラスタの状態がYellowになってしまうとこんな感じ。ちょっとわかりにくいです。\nSense Chromeプラグインとしてリリースされていたクエリ実行コンソールがMarvelのサイトプラグインとして提供されています。これがあるだけで、Elasticsearchへのクエリの実行が格段に効率良くなります。\nIndex Statistics インデックスに関する情報のグラフが見れるページです。ドキュメント数の他に、容量やリクエスト数なども見れます。\nインデックス終了後のグラフはこんな感じ。\nインデックス終了後のOverviewはこんなかんじです。\nCluster Pulse クラスタで発生したイベントとイベントの詳細を見ることができるページです。各種インデックスがYELLOWからGREENに変わっていっているのがmessageで分かります。\nすべて再配置が終わったらGREENになりました。\nNode Statistics 各ノードに関する情報を見ることができる画面です。 ノードごとにグラフの色を分けることもできます。\nその他 Marvelプラグインにブラウザから接続できなくなるとこんなメッセージが出ました。\n参考までに、elasticsearch-headの画面も。こちらのほうが、シャードの再配置中であるのがひと目で分かります。\n感想 綺麗です。まぁ、Kibanaが綺麗ですから。 クラスタ内で発生したイベントが時系列で保存されるため、あとからどんなことが発生したのかといった原因の追求などには非常に役に立ちそうです。\nただ、インデックスの状態や状況(クラスタ再起動やノード追加時にshard再配置などが実行されている状況とか)はelasticsearch-headのほうがわかりやすかったです。 インデックス単位でのStatusがMarvelの画面ではわからないため、shard再配置が完了したかどうかなどのタイミングがわかりにくかったです。\nある程度、多くのノードを利用したクラスタを利用する場合に、モニタリングツールとして利用するのは便利なのではないでしょうか? 時系列でログやイベントが保存されるので、ノードが追加されたり外れたりといった状況があとからでも追跡可能なのが便利です。\n疑問点 インデックスの情報などは、5s毎にMarvelのインデックスに保存されているようです。ただ、GUI上では5分毎のデータしか表示されません。 どうやって変更するんだろう?\nまた、Marvelのクラスタへの接続が切れた時のデータはどうなるのか?という部分も気になります。Marvelのクラスタを更新している時や、ネットワークが遮断されてしまった場合のデータがどうなるのかという点です。\n疑問点への回答(2014/01/30追記) 疑問点に対して中の人から回答を頂いたので、追記です。\nQ:GUI上で5分毎のデータしか表示されないんですが? A:ブラウザの負荷を高くしないようにするために、1つのグラフに20のプロットしてるだけです。ズームしたりすると、もっと細かなデータが見れますよ。 Q:Marvelのクラスタへの接続が切れた時のデータはどうなるんだろう? A:接続が切れた場合は、ローカルに保存されるけどデータは無視されます。接続が戻ると、戻った後のデータは記録されていきます。将来的には改善するかも。 ちなみに、昨日試してた環境が、足元Linux環境(監視対象のクラスタ)+手元Mac環境(Marvelモニタリングデータ格納クラスタ)という環境でした。 確かに、出社してから、手元Mac環境を起動すると、データが流れてくるようになりました。 ただ、監視対象のクラスタでは、socket timeoutのログがずっと出てましたが。\n参考文献 リリースブログ プロダクトページ ドキュメント ","date":1390983240,"dir":"post/2014/","id":"f6debed350f20a2b3aa4d970e3227411","lang":"ja","lastmod":1390983240,"permalink":"https://blog.johtani.info/blog/2014/01/29/simple-introduction-and-first-impression-es-marvel/","publishdate":"2014-01-29T17:14:00+09:00","summary":"昨晩、Elasticsearchから初のプロダクトとなるMarvelがリリースされました。ということで、さっそく触ってみて、簡単な紹介と感想","tags":["elasticsearch","marvel"],"title":"Elasticsearch Marvelの紹介と第一印象"},{"contents":"Lucene/Solr 4.6.1がリリースされそう(バイナリ配布待ち)lucene-gosenの4.6.1対応版をリリースしました。\nライブラリのインタフェースなどは特に変更はないのですが、ライブラリのダウンロード先が変更になっているため、注意喚起です。\nGoogle Project Hostingの仕様変更により、Downloadsに新規ファイルがアップロードできなくなっています。(2014年から)\nこのため、プロジェクトの選択肢としては以下の3点となっています。\nGoogle Driveにファイルをアップロードしてダウンロードしてもらう 他のソースコード管理サイトなどを利用する。 他のダウンロードサイトを利用する 1.と3.は場所が違うだけで、方法は一緒です。 今回は、暫定的に1.を利用してダウンロードするように対応しました。\nダウンロード先はプロジェクトのページにリンクが有りますが、わかりにくいのでキャプチャを撮ってみました。\nダウンロード先 これまでのFeatured - Downloadsとは異なり、Links - External linksの下に Downloads lucene-gosen 4.6.1というリンクを用意してあります。\nフォルダとなっており、各種jarファイルがリストされていますので、こちらからダウンロードをお願いします。 今後は、この下にダウンロードリンクを追加していく予定です。\nただし、2.で述べたように「別のソースコード管理サイト」も検討中です。\n","date":1390880040,"dir":"post/2014/","id":"c4e7199a586a308352b7a881add7e356","lang":"ja","lastmod":1390880040,"permalink":"https://blog.johtani.info/blog/2014/01/28/release-lucene-gosen-4-dot-6-1/","publishdate":"2014-01-28T12:34:00+09:00","summary":"Lucene/Solr 4.6.1がリリースされそう(バイナリ配布待ち)lucene-gosenの4.6.1対応版をリリースしました。 ライブラリのインタフェースな","tags":["Solr","Lucene","lucene-gosen"],"title":"lucene-gosen 4.6.1のリリースに関する注意点"},{"contents":"Elasticsearchのcuratorのブログ記事を読んで、日本語でツイートしたところ、Aaron Mildensteinさんから日本語(ローマ字)で返信を頂きました。 せっかくなので、ブログ記事を翻訳してもいいかを尋ねたところ、快くOKを頂いたので、翻訳してみました。参考になればと。(誤訳など見つけたらコメントください。)\n@johtani Kore no hou ga ii. Nihongo de no Curator RT, arigatou gozaimasu! #elasticsearch #curator #logstash\n\u0026mdash; Aaron Mildenstein (@theuntergeek) 2014, 1月 22 curator: 時系列インデックスの管理 原文:curator: tending your time-series indices\n背景 数年前、Elasticsearch、Logstash、Kibana(ELK)を管理し、ここ30日よりも古いインデックスを自動的に削除する方法を必要としていました。 APIドキュメントを読み、#logstashや#elasticsearchのIRCチャネルのコミュニティの助けを借りて、簡単なスクリプトとcronを用意するのが簡単であることを知りました。\ncurl -XDELETE \u0026#39;localhost:9200/logstash-2014.01.01?pretty\u0026#39; もちろん、これも動作しますが、日付を生成するのがめんどくさいのでもっとエレガントな方法が欲しかったです。\n最初に pythonでスクリプトを書き始めました。特定の日数のインデックスを管理するだけのコマンドラインクリーナーを書いてコミュニティにシェアしました。他の人が、新しい機能を追加してくれました。私は、古いインデックスをoptimizeすることができる他のスクリプトも書きました。これは、シャードごとにnセグメント以上存在しないように各シャードのセグメントをマージすることです。これらのスクリプトで1つになるようにマージしたりエンハンスし、古いインデックスを管理する助けになるツールです。\ncuratorの紹介 Curatorで可能なインデックスオペレーション\n削除(日付もしくは、トータル容量による制限) インデックスのクローズ(Close) bloom filter cacheの無効化 Optimize(LuceneのforceMerge) curatorのインストール この記事を書いている時点で、Curator は0.5.1がリリースされ、0.90.10に対応しています。Curatorはまた、Elasticsearchの1.0(現在はRC1)へも対応しています。各リリースへの互換性の保証のためのテストも行っています。\n現時点では、gitリポジトリで配布しています。近い将来、pipによるインストール可能なパッケージにする予定です。利用することを恐れないでください。もし、pythonとpipがあなたのマシンにインストールされていれば、次のようにインストールは簡単です。\ngit clone https://github.com/elasticsearch/curator.git pip install -r requirements.txt インストール後の確認は次のコマンドです。\n$ ./curator.py -v curator.py 0.5.1 利用方法とサンプル サンプルを示す前に、オプションを見ておくとよいでしょう。このリストは長いですが(この記事の最後に含まれています)、どのようなことがコントロールできるかを説明しています。デフォルトがどうなっているかに注意してください。もし、デフォルト値で良い場合は、フラグを指定する必要はありません。\nでは、簡単なサンプルを見ながら、CuratorがELKスタックをどうやって管理するかを見て行きましょう。\n削除(delete) 90日以上のインデックスを保存したくないとしましょう。コマンドは次のようになります。\n$ curator.py --host my-elasticsearch -d 90 -dで日数を指定しているだけです。簡単でしょ?\n容量による削除(delete by space) これは、指定したギガバイト数を超えたインデックスを場合に(最も古いものから)削除を行う特殊なケースです。\n$ curator.py --host my-elasticsearch -C space -g 10024 -Cでspaceによるcurationであること、-gでギガバイト数(10024、10TB)であることを指定しているのがわかります。-gは1.5や0.5という数値を指定できます。\nその他のCuratorオプションはspaceによる削除と組み合わせて使用できないことに注意してください。\nクローズ(close) Open/Close Index APIにより、インデックスをクローズすることができます。\nopen/close index APIを利用すると、インデックスをクローズしたり、あとでオープンしたりすることができます。クローズされたインデックスはクラスタのオーバヘッドにほとんどならず(メタデータの管理を除く)、読み書き操作の妨げにもなりません。クローズされたインデックスは、リカバリプロセス時に、オープンされます。\nインデックスをクローズすることは、存在はするが検索できないという意味です。何が便利なのでしょう?\n90日のインデックスを保存する義務があるが、検索は過去30日のインデックスを対象にする以外は稀であるような場合を想像してください。このような状況で、価値のあるリソース(ヒープスペースなど)を節約するためにインデックスをクローズすることができます。これは、クラスタに検索やインデキシングのためのメモリを与えることができることを意味します。そして、もし、クローズしたインデックスのデータが必要になったら、APIを呼び出してインデックスをオープンすれば検索できます。\nこのような場合、今オープンしているインデックスが再び、クローズされないように、一時的にCuratorのスケジュール実行をオフにしておくのが懸命です。\n$ curator.py --host my-elasticsearch -c 30 -d 90 先ほど説明した例の実行方法です。これは、30日よりも古いインデックスはクローズし、90日より古いインデックスを削除します。本当に簡単でしょ?\nbloom filterの無効化 これは、0.90.9以降のバージョンで利用可能な機能です。(リンク先はIssue #4525)\n心配しないでください。このスクリプトは操作を行う前に、elasticsearchが利用可能なバージョンであるかをチェックします。\nbloom filterとは何でしょう?なぜ、無効化したくなるのでしょう?\nbloom filterはインデキシング操作を高速化するためにリソースを割り当てられます。時系列データで、インデキシングしている間もこれは有用です。インデックスは2日後には、日付が変わると新しいデータはおそらくインデックスされません。そのインデックスにはもはや必要のないリソースをbloom filterはまだ持っています。Curatorはこれらのリソースを開放することができます!\n$ curator.py --host my-elasticsearch -b 2 -c 30 -d 90 これで、bloom filterのリソースは少なくとも2日(1にもできます)よりも古いインデックスについては利用せず、30日より古いインデックスはクローズし、90より古いインデックスは削除します。\noptimizeというよりもforcemerge コマンドの説明をする前に、Elasticsearch APIのoptimizeを見ることは、生きているインデックスや\u0026quot;cold\u0026quot;インデックス(インデキシングがアクティブではないという意味)に実行する必要があるということを理解するために重要です。実際、optimizeはLuceneではforceMergeと名前が変えられ、インデックスを改善するためにoptimizeを呼び出す必要はなくなりました。Elasticsearchのセグメントをマージすることは利点がありますが、coldインデックス全てに対してoptimizeを開始する前に、コストを理解する必要があります。\nforceMerge操作はインデックスにある各シャードのセグメントの数を少なくします。各セグメントはオーバヘッドがあるため、セグメントが多いということは、より多くのリソースを使うという意味です。良さそうですね?リソースが少ない?\nそれは、可能ですが、merge操作を実行するには多くのディスクやネットワークI/Oが必要で、ディスクやクラスタの通常の書き込み操作に悪影響を及ぼします。もし、これが必要なら私のアドバイスを良く考えてください。(数%ほど)検索を速くし、リソースの使用量も減らすことができます。また、管理しているセグメント数が小さくなるということは、クラスタのリカバリを速くすることにもなります。1つのインデックスをoptimizeするためにはおそらく1時間以上の時間がかかります。「使用する前に目立たない場所で試してください」というクリーニングボトル(訳注:洗剤とか漂白剤かな?)の注意書きと同様に、ディスクI/Oが低い時にテストし、もし操作とリソースがあなたのクラスタのユースケースにあっているかを見てください。デフォルトでは、シャードごとに2つのセグメントにマージしますが、--max_num_segmentsフラグで変更可能です。\nここまでのサンプルは次のようなコマンドになります。\n$ curator.py --host my-elasticsearch -b 2 -o 2 -c 30 -d 90 これで、bloom filterは2日より古いインデックスでは向こうにし、2日より古いインデックスは\u0026quot;optimize\u0026quot;し、30日より古いインデックスはクローズし、90日より古いインデックスは削除されます。\n操作の順序 スクリプトは操作が衝突するのを防ぐために次の順序で実行されます。なぜ、クローズされたインデックスはoptimizeしないのでしょう?なぜ、削除予定のインデックスはクローズされないのでしょう?\nDelete (by space or time) Close Disable bloom filters Optimize 使用の検討 最後の例で、3つの操作を1つのコマンドで実行していますが、それらが連続ですべて実行されるのを望んでいないかもしれません。\n$ curator.py --host my-elasticsearch -b 2 -o 2 -c 30 -d 90 これは、次の操作と同様です。\n$ curator.py --host my-elasticsearch -d 90 $ curator.py --host my-elasticsearch -c 30 $ curator.py --host my-elasticsearch -b 2 $ curator.py --host my-elasticsearch -o 2 これらのコマンドを異なる時間に実行したり、異なるその他のオプション(特に、optimize実行で--timeout 3600を追加したり)を指定して実行するのは簡単です。\nまた、デフォルトのlogstash-とは異なるプレフィックスのインデックスを持っているかもしれません。\n$ curator.py --host my-elasticsearch --prefix logstash- -d 30 $ curator.py --host my-elasticsearch --prefix othername- -d 30 最後に Curatorは時系列インデックスの保存ポリシーを管理するのに役立ちます。豊富な設定オプションがインデックスを管理することを簡単にします。クラスタに存在するノードの数に関係なく。https://github.com/elasticsearch/curatorへのフィードバックやコントリビューションをお待ちしています!\n参考(全引数とオプション) $ curator.py -h usage: curator.py [-h] [-v] [--host HOST] [--port PORT] [-t TIMEOUT] [-p PREFIX] [-s SEPARATOR] [-C CURATION_STYLE] [-T TIME_UNIT] [-d DELETE_OLDER] [-c CLOSE_OLDER] [-b BLOOM_OLDER] [-g DISK_SPACE] [--max_num_segments MAX_NUM_SEGMENTS] [-o OPTIMIZE] [-n] [-D] [-l LOG_FILE] Curator for Elasticsearch indices. Can delete (by space or time), close, disable bloom filters and optimize (forceMerge) your indices. optional arguments: -h, --help show this help message and exit -v, --version show program version number and exit --host HOST Elasticsearch host. Default: localhost --port PORT Elasticsearch port. Default: 9200 -t TIMEOUT, --timeout TIMEOUT Elasticsearch timeout. Default: 30 -p PREFIX, --prefix PREFIX Prefix for the indices. Indices that do not have this prefix are skipped. Default: logstash- -s SEPARATOR, --separator SEPARATOR Time unit separator. Default: . -C CURATION_STYLE, --curation-style CURATION_STYLE Curate indices by [time, space] Default: time -T TIME_UNIT, --time-unit TIME_UNIT Unit of time to reckon by: [days, hours] Default: days -d DELETE_OLDER, --delete DELETE_OLDER Delete indices older than n TIME_UNITs. -c CLOSE_OLDER, --close CLOSE_OLDER Close indices older than n TIME_UNITs. -b BLOOM_OLDER, --bloom BLOOM_OLDER Disable bloom filter for indices older than n TIME_UNITs. -g DISK_SPACE, --disk-space DISK_SPACE Delete indices beyond n GIGABYTES. --max_num_segments MAX_NUM_SEGMENTS Maximum number of segments, post-optimize. Default: 2 -o OPTIMIZE, --optimize OPTIMIZE Optimize (Lucene forceMerge) indices older than n TIME_UNITs. Must increase timeout to stay connected throughout optimize operation, recommend no less than 3600. -n, --dry-run If true, does not perform any changes to the Elasticsearch indices. -D, --debug Debug mode -l LOG_FILE, --logfile LOG_FILE log file ","date":1390542480,"dir":"post/2014/","id":"15f501351d482ffd73985a50f5c89d1f","lang":"ja","lastmod":1390542480,"permalink":"https://blog.johtani.info/blog/2014/01/24/curator-tending-your-time-series-indices-in-japanese/","publishdate":"2014-01-24T14:48:00+09:00","summary":"Elasticsearchのcuratorのブログ記事を読んで、日本語でツイートしたところ、Aaron Mildensteinさんから日本語(","tags":["elasticsearch","curator"],"title":"Curator: 時系列インデックスの管理(日本語訳)"},{"contents":"あけましておめでとうございます。今年もSolrやElasticsearchについて色々と頑張っていく所存です。 とまぁ、お決まりの挨拶はおいておいてと。(もう、新年も22日ですが。。。)\nElasticsearchの1.0.0RC1がリリースされました。 ということで、私が作っているExtended-Analyzeプラグインも1.0.0RC1向けに修正してリリースしました。\n1.0.0RC1向けに修正したこと コミットログを見てもらえば、いいのですが、ロジック自体は変更しなくても良かったです。\nただ、正式に、Elasticsearchのつづりが決定したようで、クラス名が「ElasticSearchほげほげ」から、「Elasticsearchほげほげ」と、SearchのSが小文字になりっています。 この影響で、例外クラスなどの名称を幾つか変更しました。 また、バージョン番号を1.0.0RC1とし、0.x系をElasticsearchの0.90系向けのバージョンにしていく予定です。\n今後は、UIを追加したいと思っているので、Elasticsearchのバージョン番号とはずれてくるとは思いますが。。。\nElasticsearch 1.0.0RC1を利用してみて 1点だけですが。 これまでは、-fオプションを指定すると、デーモンではない動作で起動できていました。(デフォルトがデーモン起動)\nこれが、1.0.0から(0.90の最新もかな?詳しく見ていない)デフォルトの挙動が変更され、デーモン起動ではなくなりました。 代わりに、-dオプションを指定することで、デーモン起動ができるようになりました。\nこれで、手元でうっかりデーモン起動することがなくなって、ひと安心です。(他の人は困るかもしれないけど)\nということで 1.0.0RC1が出たので、少しずつ1.0系で追加されたAPIや機能について、ブログで紹介していけたらと思います。\nこんなこと調べてよ?、これわかんないんだけど?などありましたら、コメントいただければと。 気が向いたら記事を書くので。\nあと、Extended-Analyzeプラグインの感想などもお待ちしています!\n今年もよろしくお願いします!\n","date":1390317360,"dir":"post/2014/","id":"6425af51edead39c0e439073986043fb","lang":"ja","lastmod":1390317360,"permalink":"https://blog.johtani.info/blog/2014/01/22/release-extended-plugin-for-1-0-0rc1/","publishdate":"2014-01-22T00:16:00+09:00","summary":"あけましておめでとうございます。今年もSolrやElasticsearchについて色々と頑張っていく所存です。 とまぁ、お決まりの挨拶はおいて","tags":["elasticsearch"],"title":"Extended-Analyze 1.0.0RC1をリリースしました"},{"contents":"昨年は、大晦日に書いてました。 ちょっと進歩したかも。\n振り返り(2012年に書いた抱負から) ということで、まずは昨年書いた抱負からの振り返りです。\nIntelliJ IDEAをメインに使う JIRAを継続して活用 ブログの継続 elasticsearch Luceneのソースコードリーディング 何かOSSのソースを読む Macでもっと開発 読書と英語を継続 お。思ったよりもできてるかも。 IntelliJ IDEAについては、メインになりました。Eclipseを開くことはまずないです。 Macがメインの開発マシンにもなってきてるので。(開発してないんじゃないかという話も。。。)\nJIRAは一応、継続しているという感じです。\n唯一Luceneのソースコードリーディングができてないですね。。。 言い訳をすると、明示的にソースコードリーディングをしているわけではないですが、Luceneのソース自体は時々見ています。 SolrやElasticsearchを調べるとそのままLuceneにたどり着くことがあるので。\nポモドーロのタスク管理用に使っていますが、時々忘れていたり。あと、振り返りがまだちゃんとできてないので、そこをやらないとかなぁと。 読書と英語は今後も継続です。もっと習慣づけないと。\n振り返り(今年あった出来事など) CROSSでモデレータやりました Xperia Zに機種変 メニエール病 リクルートテクノロジーズさんのお手伝い Lucene In Action輪読やってる MIR輪読も継続 Solr勉強会を不定期開催 Elasticsearch勉強会を始めた Solr本の改訂版を執筆 AWSちょっと触った Elasticsearchプラグイン作ってみた Githubの活用 Octopressでブログ こんなかんじです。\nCROSSでは、モデレータをやらせていただきました。すこしは検索を面白いと思ってもらえたかなと思います。 来年のCROSS 2014ではスタッフとして盛り上げていく予定ですので、スタッフに興味ある方は声をかけてください! 面白い話がいっぱい聞けますし、おいしい物も飲み食いできるかも!?\nXperia Zは良い買い物でした。ただ、すでに2回電源部分が故障してますが。。。 それ以外は非常に快適です。\n2月末から3月は少し休んでました。難聴→めまい→メニエール病という流れで、ちょっとしんどかったです。 ほぼ回復しましたが、原因は不明みたいなので、長く付き合ってくのかなぁと。\n4月からリクルートテクノロジーズさんの仕事を手伝っています(Solr本の著者紹介にも書いてます)。 色々と面白いことをしているATLという部署で面白い人達と仕事させて頂いてます。 来年もよろしくお願いします!(もっと価値を出さないとなぁ。。。)\nその一環で、Lucene In Actionの輪読を社内でやっていたりも。バージョンが3.x系で書かれているので、 ちょっと大変ですが、4だとどう違うかなどの話を交えつつ少しずつ読んでいます。\n輪読会といえば、MIR(Modern Information Retirieval)の輪読も続いています。 私は深いところまでわからないのですが、色々と詳しい方たちとボチボチ読んでます。教えてもらってばかりですが、来年も頑張りますよと。\nSolr勉強会も、引き継いでぼちぼちやっています。来年は1/29に開催します。Solrの入門的な話をしてもらうので、 ぜひ、触ったことがない方や興味がある人に参加していただきたいと。\nElasticsearch勉強会も主催し始めました。興味ある人がいるだろうとは思ったのですが、想像以上でびっくりしてます。 自分が理解を深め、発表するためにも、2ヶ月程度のスパンで来年も開催する予定です。 スピーカーに興味のある方は、elasticsearch-jpのMLや私にコンタクトしてください。\nSolr入門のSolr4対応版も執筆しました。今回は全体のコーディネートもやらせていただきました。 Solr活用のお役に立てていただければと。まだ購入してない方はぜひ、以下のリンクから!(PDF版もあります。) 質問などあれば、ブログにコメントをいただくか、ツイートしていただくか、技術評論社のサポートページに問い合わせていただければと思います。\nAWSをちょっとだけ触りました。 S3にバックアップ取ってるだけですが。。。来年はもう少し。。。 JIRA(さくらVPSに立ててる)のバックアップなどをやってます。\nあとは、Elasticsearchの勉強会も始めたこともあり、Elasticsearchを色々と触っています。 elasticsearch-analysis-kuromojiプラグインのREADMEを記述してコントリビュートしてみたり、 elasticsearch-extended-analysisプラグインを作ってみたり。\n勉強会のスピーカー探しも兼ねて、いろんなところに、「突撃!隣のElasticsearch」と称してElasticsearchの話を聞きに行きたいと思っていますので、使ってるよ!とか使いたいんだけど、どうすればいい?みたいな話があれば、声をかけてください。Twitterでツイート見たら勝手に、アタックすることもあるかもですが、その時はよろしくお願いします。\n来年はSolrやElaticsearchにもっと貢献できればと。\nGithub(git)もようやくまともに触り始めました。 某データの管理やプラグインの開発などでやっと触り始めました。 まだ、チーム開発ってほどではないので、チームで開発するときのやり方なども少しずつ勉強していこうかと。 プルリクとかも少しずつやってみたりしてます。\nあとは、Octopressでブログ始めました。その前はjugemだったのですが、なんとなく。 Markdownに慣れるためというのもありOctopressにしてみました。 (Solr本の原稿もMarkdownで書いてました) 昔のブログもこっちにコピーするプログラムも書いてみようかな。\n来年の抱負 Elasticsearch勉強会、Solr勉強会の継続+ミックスした検索勉強会の開催 IDEAのさらなる活用 もっと開発(プラグインとか) AWSをもう少し活用 海外のイベントに行ってみたい 読書と英語を継続 勉強会の開催は今後も継続していく予定です。会場を毎回提供して頂いているVOYAGE GROUPさん、リクルートテクノロジーズさんには、 今後もお手数をお掛けしますが、よろしくお願い致します。勉強会の開催を通じて、色々な人のノウハウがうまく共有できて、 もっと本質的な作業(サービスの改善とか)に注力できる環境ができると面白いなぁと思ってるので。\nあと、Elasticsearch、Solrと別々の勉強会になっていますが、検索エンジン勉強会という形でそれぞれのメリット・デメリットを 共有できる勉強会も面白いかもと思っているので、春とかに開催したいなぁと考えてもいます。(まだ考えているだけで何もネタがないですが)\nIDEAは、年貢(13のサブスクリプション)を収めたので、もっと活用しないとという意味で。プラグインの開発、gitやsvnのクライアントとしては 活躍していますが、もっと開発に活用していかないとなぁと。まだ、10%くらいしか活用できてない気がするので。\nもっと開発しないとなと。毎年言ってますが。今年は書籍に注力したのもあり、ソースを読んだり英語を読んだりが多くなってました。 偉そうにしてるためか、開発する機会が減ってきているので、細かなことでもいいので、すこしずつコードを書いていこうかと。 (もっと自分で問題点を見出してそれを補完するようなコードなりプラグインなり書けばいいんだろうな。)\n開発と合わせて、AWSをもう少し触りたいなと。これも数年言っていますができてないです。。。 ネタ探すのが下手なのかなぁ。\n海外イベントにも行ってみたいです。まだ、海外行ったことないんですが。。。 Lucene Revolutionとか。その訓練も兼ねて英語でメール書いたり、プラグインのREADME書いたりしてみてます。\n最後は、毎年恒例ですが、読書と英語です。 Packtのキャンペーンで買ってしまった英語の本とか貯まっているので、読まないと。 nasneが便利で通勤時間にドラマ見てるからなぁ。ま、必要なときにボチボチと読んでいく予定です。\n最後は、いつものようにですが、来年も勉強会やいろんなイベントに参加する予定です。 ブログも週1程度で書く努力しないとなぁ。 こんな話を書いてくださいとかのリクエストもお待ちしています。\n今年もまだ、大晦日が残っていますが、色々とお世話になりました。 この場を借りてお礼申し上げます。\n来年も、いろんな方に絡んでいくとは思いますが、よろしくお願いいたします。\n","date":1388406000,"dir":"post/2013/","id":"10c715f70de25ccb493bbbb532b78ced","lang":"ja","lastmod":1388406000,"permalink":"https://blog.johtani.info/blog/2013/12/30/looking-back-2013/","publishdate":"2013-12-30T21:20:00+09:00","summary":"昨年は、大晦日に書いてました。 ちょっと進歩したかも。 振り返り(2012年に書いた抱負から) ということで、まずは昨年書いた抱負からの振り返りで","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2013)"},{"contents":"昨夜、Elasticsearchの0.90.8がリリースされました。\nリリースされた内容などについては、本家のブログ「0.90.8 released」をご覧いただくこととして。 1点注意したほうが良い点があります。\nelasticsearch-analysis-kuromojiを利用している場合は、0.90.8に対応したバージョンがリリースされるのを待つ必要があります。\nelasticsearch 0.90.8はLuceneのバージョンが4.6.0に変更されています。 Lucene 4.6.0では、TokenStreamというTokenizerのI/Fに変更があり、Tokenizerの実装を変更する必要があります。\n現時点(2013年12月19日現在)のelasticsearch-analysis-kuromojiの1.6.0にはlucene-analyzers-kuromoji-4.5.1.jarが含まれており、この部分でI/Fが異なるためエラーが発生してしまいます。 プラグインをインストールする時点ではエラーは発生せず、実際にKuromojiのTokenizerやAnalyzerを利用するタイミングでエラーが出ます。 以下、0.90.8にanalysis-kuromojiの1.6.0をインストールした状態で_analyzeを実行した時のエラー。\ncurl -XPOST \u0026#39;localhost:9200/_analyze?tokenizer=kuromoji_tokenizer\u0026amp;filters=kuromoji_baseform\u0026amp;pretty\u0026#39; -d \u0026#39;寿司が美味しかった\u0026#39; { \u0026#34;error\u0026#34; : \u0026#34;IllegalStateException[TokenStream contract violation: reset()/close() call missing, reset() called multiple times, or subclass does not call super.reset(). Please see Javadocs of TokenStream class for more information about the correct consuming workflow.]\u0026#34;, \u0026#34;status\u0026#34; : 500 } ということで、1.7.0がリリースされるのを待つか、自分でmvn packageしてビルドする必要があります。 他にも独自でTokenizerなどを造られている方は注意が必要かと。\nたぶん、すぐにリリースされるんじゃないかなぁと。\n2013/12/20追記\nとりあえず、masterブランチが0.90.8に変更されたみたいです。(と書いてるそばから、1.7.0がリリースされました) ということで、0.90.8では1.7.0を使うとエラーが出ないです。 (あと、踊り字対応のcharfilterも追加されたみたいです)\n","date":1387524240,"dir":"post/2013/","id":"c18b12fff24dc87e7f1039bd17c0c6aa","lang":"ja","lastmod":1387524240,"permalink":"https://blog.johtani.info/blog/2013/12/20/release-elasticsearch-0-90-8/","publishdate":"2013-12-20T16:24:00+09:00","summary":"昨夜、Elasticsearchの0.90.8がリリースされました。 リリースされた内容などについては、本家のブログ「0.90.8 releas","tags":["elasticsearch","kuromoji"],"title":"Elasticsearch 0.90.8がリリースされました&注意点(2013/12/20追記)"},{"contents":"Solr本が出てから、質問を受けてブログ書くと言いながら書いてなかったことを思い出しました。。。\nプラグインの配置方法についてこんな質問を受けてたので、それっぽいエントリを書いておきます。(想像と違ってたらツッコミ入れてください)\n@johtani 追加でプラグインの配置方法とかあると便利かなと思いました\n\u0026mdash; Tsubosaka (@tsubosaka) 2013, 12月 2 改定前のSolr本では、日本語の形態素解析器をjarファイルとして追加する方法が書かれていました。 ただ、改定後のSolr本では、KuromojiがLuceneで実装されているためサンプルとしてjarファイルを追加するような方法の記載が明確にはありません。\n19ページのcollection1の説明ですこしだけ、libディレクトリについて触れています。\n独自のTokenizer(lucene-gosenなど)はjar形式でSolrに追加し、schema.xmlなどに利用するFactoryを指定してから利用します。\nこのとき、追加のjarファイルを配置する先がlibディレクトリです。\nlibディレクトリは2つの種類のスコープのディレクトリが存在します。\nSolr全体で利用可能なlibディレクトリ コア単位で利用可能なlibディレクトリ Solr全体で利用するlibディレクトリ これは、起動しているSolrにある全てのコアで利用するようなjarファイルを配置するディレクトリになります。 場所は$SOLR_HOME/libです。ここにjarファイルを配置することで、この$SOLR_HOMEを利用するすべてのコアで同じjarファイルを利用することができるようになります。\nですので、例えば、lucene-gosenはすべてのコアで利用するという場合にはここに配置すれば、1つのjarファイルを配置するだけで済むことになります。\nコア単位で利用するlibディレクトリ これは、コアごとにlibディレクトリを用意する場合です。 19ページにも記載されていますが、$SOLR_HOME/コアディレクトリ名/libとなります。\n特定のコアのみで利用するライブラリについてはこちらに配置する形になります。 他のコアで利用してほしくないjarファイルなどを配置するのに利用すればよいかと。\n簡単ですが、補足記事でした。 UIMAやlangidの利用方法などもあるとうれしですかね? そのうち気が向けば書くかもしれません。(他の人に書いてもらうのもありかも。)\n","date":1387447740,"dir":"post/2013/","id":"cb5b6f7ab4d36e90d2619cb907ebb956","lang":"ja","lastmod":1387447740,"permalink":"https://blog.johtani.info/blog/2013/12/19/add-jar-file-to-solr/","publishdate":"2013-12-19T19:09:00+09:00","summary":"Solr本が出てから、質問を受けてブログ書くと言いながら書いてなかったことを思い出しました。。。 プラグインの配置方法についてこんな質問を受け","tags":["Solr"],"title":"Solrへのプラグインの配置方法について"},{"contents":"ども。 プラグインのインストールに長いURL入れるの辛いですよね?ね?\nということで、MavenでリリースしてMaven Repositoryからダウンロードできるようにしてみました。\n流れとしては\nSonatypeにリリースできるように申請する Sonatypeにリリースする SonatypeからMavenにSyncしてもらう という流れです。\nSonatypeにリリースするための方法はイケメンの人(@yusuke)がブログに簡単ですが残してくれてました。 あと、こちらの@vvakameさんのブログも参考にしながら作業しました。\n【最新版】Maven Central Repository へのライブラリ登録方法 #maven JsonPullParser が Maven Central Repository に入るようです pom.xmlについては、プラグインのpom.xmlを参考にしてもらえればと。 1.の作業が終わったら、リリースを実行します。\nこの時、\u0026lt;scm\u0026gt;タグにgithubの情報が記載されているため(?)、githubにタグを打つ作業もmavenコマンドがやってくれるみたいです。\nmvn release:prepare を実行すると、リリースするバージョンやタグ名などを聞いてくれます。 それらに答えると、pom.xmlにバージョンを指定してcommit\u0026amp;pushしてくれ、タグも打ってくれます。(なんて便利)\nその後、release:performにてSonatypeへのリリースが完了します。 あとは、Sonatypeの画面で作業したら、Mavenのリポジトリにそのうち同期してくれます。\nということで、次のコマンドを実行すればプラグインがインストールできるようになりました。0.6.0と0.7.0の違いは実装には差異はありません。リリース方法が変更されただけということになります。\nbin/plugin -i info.johtani/elasticsearch-extended-analyze/0.7.0 これで少しは活用してもらえるようになるかなぁ? (どのくらいの人が使ってくれてるのかは不明。。。)\n","date":1387249860,"dir":"post/2013/","id":"a0a00c23556fcc5dbfb7b7f43fbbb61d","lang":"ja","lastmod":1387249860,"permalink":"https://blog.johtani.info/blog/2013/12/17/release-es-extended-analyze-plugin-to-maven-and-sonatype/","publishdate":"2013-12-17T12:11:00+09:00","summary":"ども。 プラグインのインストールに長いURL入れるの辛いですよね?ね? ということで、MavenでリリースしてMaven Repositoryから","tags":["elasticsearch"],"title":"elasticsearch-extended-analyzeプラグインをMavenとSonatypeにリリース"},{"contents":"少し遅くなってしまいましたが、12/05に電子書籍も発売されました。\n技術評論社の電子書籍サイトから購入可能です。\n書籍のページへのリンク PDF版となっております。 購入の際は、技術評論社の電子書籍サイトに会員登録後購入可能となります。\n個人的には電子書籍が便利なので、こちらを普段活用しようと思っています。\nもちろん、紙の書籍も発売中です!購入の際は右の書影をクリックしていただければと!\n","date":1386554880,"dir":"post/2013/","id":"d9560caeb797b302191f667b4264da40","lang":"ja","lastmod":1386554880,"permalink":"https://blog.johtani.info/blog/2013/12/09/release-introduction-solr-ebook/","publishdate":"2013-12-09T11:08:00+09:00","summary":"少し遅くなってしまいましたが、12/05に電子書籍も発売されました。 技術評論社の電子書籍サイトから購入可能です。 書籍のページへのリンク PDF","tags":["Solr"],"title":"改訂版Solr入門のPDF版も発売"},{"contents":"勉強会で宣伝もしましたが、改めて。\nSolr入門の改訂版を執筆しました。 考えてみれば、もう3年も前なんですね、Solr入門は。 Solr勉強会などでも何度も新しいのは出ないのですか?と聞かれていましたが、やっと出ました。(お待たせしました。)\n時が立つのは早いものです。前回のSolr入門はバージョン1.4にて執筆していましたが、今回は4.4をベースにし、4.5.1への対応を行っています。\n月曜日には手元に見本が届き、今週金曜日に発売予定です!\nSolrCloud、SoftCommit、Spatial、Joinなど、多彩な機能についても記載してあります。 また、ManifoldCFというSolrにデータを登録するのに 利用できるコネクタフレームワークについても書いてあります。\nより多彩になったSolrの機能を活用するための一助となれればと思います。 (電子版も出る予定です。詳細についてはもう少々お待ちください)\nまた、出版を記念して少し時期が先になりますが、Solr勉強会を開催しようと思います。\n日時:2014年01月29日 第13回Solr勉強会 #SolrJP 新Solr本出版記念 今回はせっかくのSolr入門の書籍の出版記念ということで入門的な話をしてもらう予定です。 Solr初心者の方、Solrに興味のある方などに来ていただきたいと思っています。 (プレゼントも用意できるかも!?)\nということで、「改訂版Apache Solr入門」をよろしくお願いします。 (もちろん、購入は下のリンクからですよね!)\n","date":1385436420,"dir":"post/2013/","id":"a2012a3c9cdb1d6fd69afdbadc1e76b6","lang":"ja","lastmod":1385436420,"permalink":"https://blog.johtani.info/blog/2013/11/26/introduction-to-solr-new-edition/","publishdate":"2013-11-26T12:27:00+09:00","summary":"勉強会で宣伝もしましたが、改めて。 Solr入門の改訂版を執筆しました。 考えてみれば、もう3年も前なんですね、Solr入門は。 Solr勉強会な","tags":["Solr"],"title":"改訂版Solr入門を執筆しました"},{"contents":"どーも。以前の記事で開発中としていたプラグインですが、とりあえず、pluginコマンドでインストール出来る形にしてみました。\nインストールなどについては、READMEに記載したのでそちらを参照してもらうことにして、試行錯誤した話をメモとして残しておきます。\nプラグインの開発はしいてたのですが、やっぱりpluginコマンドでインストール出来ないと使ってもらえないよなということで、勉強会も終わったのでちょっと調べてました。\nプラグインコマンド コマンドが用意されてますが、実態はJavaで実装されてて、通常はこんなかんじでプラグインをインストールします。\n./bin/plugin -i elasticsearch/elasticsearch-analysis-kuromoji/1.6.0 この「elasticsearch/elasticsearch-analysis-kuromoji/1.6.0」という文字列ですが、「ユーザ名/リポジトリ名/バージョン」という意味になります。\nで、ダウンロードするURLは以下のものの中から選ばれます。\nelasticsearch.orgのダウンロード用サイト search.maven.org oss.sonatype.org Githubのarchive これらのサイトに先ほどのユーザ名、リポジトリ名、バージョンを利用したURLを組み立てて、ダウンロードしてくれるという仕組みになっています。\nelasticsearch.orgについては、本家の人しかアップロードできないと思うので、なし。\nmaven、sonatypeについては、Mavenのリポジトリにリリースする必要があるんじゃないかなと。 で、昔調べてググって途中で挫折したんですが、挫折してます。手順が結構手間で。。。 (参考記事:【最新版】Maven Central Repository へのライブラリ登録方法 #maven)\nということで、Githubにアップしたらなんとかなるんじゃん?ということで色々と調査して試してみました。(結果はイマイチなんですが。。。)\nその1:mvn release:prepare せっかくGithubだし、せっかくMavenなんだしなんか、pom.xmlに便利な設定したらコマンド一発でリリースできるんじゃない?という甘い気持ちで調査したググったらそれっぽい記事が見つかりました。 「MavenとGitHubの連携」って記事です。\nで、pom.xmlの設定にも他のプラグインを真似してコピペしたものに\u0026lt;scm\u0026gt;ってタグがあったなぁと。このコマンドでついでにGithubにアップロードできるんじゃないの?ということで、試してみました。\nmvn release:prepare このコマンドを叩くと、記事にあるとおりにいくつか質問をされます。 タグについては、プロジェクト名-バージョン番号という文字列がデフォルトだと指定されているので、v0.5と変更して実施してみると、Githubのreleaseにv0.5ってのができてるじゃないですか。\n※pluginコマンドはGithubを見に行く時に次のファイルをダウンロードしに行きます。\nhttps://github.com/ユーザ名/リポジトリ名/archive/vバージョン名.zip やった!と思い、早速pluginコマンドを実行してみましたが、エラーが出ました。。。\nTrying https://github.com/johtani/elasticsearch-extended-analyze/archive/v0.5.zip... Downloading ...DONE Installed johtani/elasticsearch-extended-analyze/0.5 into /Users/johtani/projects/tmp/ess_env/second_node/elasticsearch-0.90.7/plugins/extended-analyze Usage: -u, --url [plugin location] : Set exact URL to download the plugin from ...省略... Message: Error while installing plugin, reason: IllegalArgumentException: Plugin installation assumed to be site plugin, but contains source code, aborting installation. あらら、なんで?と。\nで、実際にgithubにアップされてたzipファイルをダウンロードしてみたら、githubのリポジトリにあるディレクトリ構成がそのまま入ってるじゃないですか。。。 そうですか、そうですよね。prepareだし、タグ打ってzipにかためてくれるだけなんですねと。。。\nおそらく、siteプラグインだけの場合はこの方法でpluginコマンド叩けばOKなんでしょうが、私がダウンロードしてもらいたいのは.jarファイルが入ったzipファイルなんです。\nということで、断念しました。(タグ消したりをgitコマンドで叩いて綺麗にし直すとか虚しい作業をしてました)\nその2:github.comのWebでリリース おとなしく、Sonatypeのサイトにアップロードする方向でがんばればいいんですが、とりあえず使えるようにするのが先だと思い、 github.comのページでアップロードしてしまおうと。\n「release」というタブをクリックすると、画面からアップロードできるようになります。\nzipファイルを作ってアップロードしました。(zipファイル自体はmvn packageコマンドを実行したらtarget/releaseというディレクトリに作成されてる)\nこれで行けるだろということで、またpluginコマンドを実行すると\nTrying https://github.com/johtani/elasticsearch-extended-analyze/archive/v0.5.zip... Downloading ...DONE Installed johtani/elasticsearch-extended-analyze/0.5 into /Users/johtani/projects/tmp/ess_env/second_node/elasticsearch-0.90.7/plugins/extended-analyze Usage: -u, --url [plugin location] : Set exact URL to download the plugin from ...省略... Message: Error while installing plugin, reason: IllegalArgumentException: Plugin installation assumed to be site plugin, but contains source code, aborting installation. あれ?同じエラー?なんで?jar入りのzipファイルアップロードしたのに???\nと。で、https://github.com/johtani/elasticsearch-extended-analyze/releasesにreleaseのページができてたので見てみると、あら。 アップロードしたファイルについては次のようなURLになってるじゃないですか。\nhttps://github.com/johtani/elasticsearch-extended-analyze/releases/download/v0.5/v0.5.zip で、よく見ると「Source code(zip)」というボタンもあるぞ?このリンクは?\nhttps://github.com/johtani/elasticsearch-extended-analyze/archive/v0.5.zip 。。。あぁ。そうですか。そういうことですか。理解してない私が悪いんですねと。\n結論? ということで、とりあえず、releaseにjar入りファイルはアップロードできた(手動で)ので -uオプションで直接URL指定すればインストールできるだろ!と諦めました。 いい勉強になりました。。。\nREADME見ていただくとインストール方法が分かりますが、長いです。。。\n時間をとって本腰入れてSonatypeにMavenコマンドでアップロードできるようにしようかな。。。\n","date":1384419300,"dir":"post/2013/","id":"13684d16fdd07d5f0584e29265a270e7","lang":"ja","lastmod":1384419300,"permalink":"https://blog.johtani.info/blog/2013/11/14/release-elasticsearch-extended-analyze-0-dot-5/","publishdate":"2013-11-14T17:55:00+09:00","summary":"どーも。以前の記事で開発中としていたプラグインですが、とりあえず、pluginコマンドでインストール出来る形にしてみました。 インストールなど","tags":["elasticsearch","plugin"],"title":"elasticsearch-extended-analyzeを公開?"},{"contents":"第2回を開催しました! すごい、140人くらいくらいの参加登録者(参加者は100人ちょっと!)がいて、びっくりです。 ステキな会場を提供していただいた、リクルートテクノロジーズさん、運営していただいた方々、スピーカーの皆さん、参加者の皆さん本当にありがとうございました。 今回も素敵な看板ありがとうございます。\n今回もしっかり楽しめたので、次回も頑張ります!\n今回は、elasticsearch-jpMLの紹介とかをできたのでよかったかなぁと。 ぜひ、活用してください!どんな質問でもいいので。\nあと、スライドに入ってた例の本もよろしくです。\nということで、懇親会も盛り上がったし楽しかったです。 今後も場の提供+自分の勉強のトリガーとして、開催していくので、ご協力お願いします! 聞きたい話など、MLや@ツイートしていただければと。\nelasticsearchのRouting機能:株式会社シーマーク 大谷 純 (@johtani) スライド:Routing機能※スライドはPDFです。\nド緊張で、大した発表ではなかったですが。。。 どちらかと言うとSolr本の紹介だったかもなぁ。スミマセン。\n※スライドが一部文字が消えてるので、作りなおすかも。\nElasticSearchを使ったBaaS基盤の開発(仮):株式会社富士通ソフトウェアテクノロジーズ 滝田聖己さん(@pisatoshi) スライド:https://speakerdeck.com/pisatoshi/elasticsearch-trial-and-error\n本日はお越しいただきありがとうございました!しかも静岡から!今後もよろしくお願い致します。\nEnchantMoonでシステム構成w\n0.17.0から利用されていると。(スゴイ)\nプライマリのデータストア!ただし、登録元データはMySQLにもある。\n階層も深く、大きめのドキュメント。\nレプリカ1、インデックスのバックアップも取ってないと。。。\nルーティングの機能\nDynamicMappingの問題点\nマッピング定義が肥大、型がコンフリクト。。。苦労しっぱなし\nデータ登録は1台にして、1台で一気に登録してから再配置\n実際に運用とかされてるので、いろんなノウハウがまだまだありそう!\nKibana入門:水戸祐介さん(@y_310) スライド:https://speakerdeck.com/y310/kibanaru-men\n(やっぱりru-menになってるw)\n実は、押しかけて話してもらうように説得したのでした。今後もよろしくです。\nCOOKPADの方によるKibanaのお話。 Kibanaの利点とかなんで?とか。 画面構成の説明から ダッシュボードは必ず保存して!リロードしたら悲しい思いをしてしまうので。 sparkline便利そうだなぁ。ほんとに、データサイエンティスト系のツールを目指してるのかな 一通り、ダッシュボードに配置できるパネルの説明してもらえたのですごく参考になりました! Tips周りが役に立ちそう。not_analyzedは重要ですよね。 LT 「データ集計用ダッシュボードブラウザとしても使えるElasticSearch+Kibana v3を利用する際の運用ノウハウ紹介」:株式会社リブセンス Y.Kentaro さん (@yoshi_ken) さん スライド:http://www.slideshare.net/y-ken/elasticsearch-kibnana-fluentd-management-tips\nKibanaの紹介とかFluentdの紹介。 Tips満載すばらしい。 JDBC riverは0.90.6ではうまく動かないので、気をつけてと。 「Fluentd as a Kibana」:@repeatedly さん スライド(gist)?:https://gist.github.com/repeatedly/7427856\nKibanaがfluentdの中で動くと!?\n「Authプラグインでアクセスコントロール」:株式会社エヌツーエスエム 菅谷信介さん (@shinsuke_sugaya) スライド:http://www.slideshare.net/shinsuke/es-auth-plugin\nAPI毎?インデックスごと?にアクセス制御ができるプラグイン\n","date":1384247760,"dir":"post/2013/","id":"66f43ab4b823d67f52735bbbe6ba65b0","lang":"ja","lastmod":1384247760,"permalink":"https://blog.johtani.info/blog/2013/11/12/elasticsearch-japan-user-meetup-no2/","publishdate":"2013-11-12T18:16:00+09:00","summary":"第2回を開催しました! すごい、140人くらいくらいの参加登録者(参加者は100人ちょっと!)がいて、びっくりです。 ステキな会場を提供していた","tags":["elasticsearch","kibana","fluentd","勉強会"],"title":"第2回elasticsearch勉強会を開催しました! #elasticsearchjp"},{"contents":"Cloudera World Tokyo 2013に参加してきました。\n午前中はあいにくの雨でしたが、それでも結構な人数が最初の基調講演から参加されてました。 私が参加したセッションは大盛況な感じでした。\nおみやげとしてカステラも頂いちゃいました!\nまた、色々なセッションに現れたこんなメッセージ画像も見つけました!\n昨日の写真データの整理をしていたら、こんなものが・・・ @shiumachi さんよ・・・ #cwt2013 pic.twitter.com/S0JsxSYXIx\n\u0026mdash; Kenichiro HAMANO (@hamaken) November 8, 2013 やっぱり、スーツの人が多いなという印象。\n名刺を毎回回収されるのはちょっとつらかったです。なにか、いい方法ないですかねぇ。\n以下はいつもの個人メモです。\n「ビッグデータプラットフォームとして進化するHadoop」 Cloudera株式会社 代表取締役 ジュセッペ小林氏 Costcoなどの写真を元にビッグデータを可視化 BigDataとHadoopの関係 検索、SQL、機会学習、数理処理、データ管理などにもHadoopの活用されつつある。 セキュリティ、データ管理、クラスタ上でのツールの実行なども増えてきてる。\n「今日ビッグデータは明日のスモールデータ」\nアーキテクチャとしてのビッグデータ 多種多様なデータを一箇所に集約し、生データを直接活用できる。 OSSとしての責任も。\nデータサイエンス Opsだけでないデータ解析にも活用\n「Clouderaのビッグデータプラットフォーム戦略」(仮) 講師:Cloudera, Inc. CTO Dr.Amr Awadallah レガシーな情報アーキテクチャ→スケールできない、可視化の限界、硬直したスキーマなどなど。\nエンタープライズデータハブとしてのHadoopとか。\nビッグデータの歴史と将来展望 講師:国立情報学研究所 アーキテクチャ科学研究系 教授 佐藤一郎氏 ビッグデータの歴史的経緯とか 最初の事例はアメリカの1880年国勢調査。\n「ビッグデータがコンピュータを生み出した」。コンピュータがビッグデータを生み出したんじゃない。\n少量データにもHadoopを\nバッチ処理のリアルタイム化とか(一晩から10分へ) 原点は検索データのインデクシング\nHadoopを使うのが目的じゃないんだから、構築には手を掛けないのがいいよね。\nプラットフォームと発展している\n分散システム研究者から見たHadoop 分散ししテムの難しさを、処理範囲を限定することで巧みに回避 データの近くで処理 研究レベルではリアルタイム化や逐次処理化が活発 全工程で逐次・リアルタイムが必要とは限らない 聞いてばかりじゃなくて、動かしてみましょう。 データサイエンス:超並列分散処理を活用した新たなビジネス価値の創出 講師:アクセンチュア株式会社 工藤卓哉氏 「日経BPのビッグデータ総覧2013」に記事書いてる。 多様化するデータ(社外のデータも)をどうやってうまく活用していくか。 データが教えてくれたこと→まず、データありき、まずデータためましょう。それから解析とかすればいいのでは?というはなし? 競合他社さんはNGだけど、ブースでデモ?実機?が見れますと。 Hadoopデータプラットフォーム Cloudera株式会社 嶋内 翔氏 まずは宣伝 Cloudera Implaraのフリーブックの日本語版 Hadoop Operationの書籍でるよ プラットフォームを構成するもの Flume Sqoop HBase Hive Impala データ登録してBIアナリストのお仕事にどうやって役立てる? 外部テーブル:Hiveからはテーブルのように見える仕組み。元ファイルは消えない SerDe(さーでぃー):データをHiveレコードに変換する仕組み 生データを少し加工しましょう 圧縮したりファイル結合したりはしときましょう。 Hadoop活用のポイント 富豪的プログラミング。リソースケチるな。 ローカルでできることはローカル。むりにHadoopでやんなくてもいいですよねと。バランス重要 スケジューリング実行などはOozie使うと便利。(日次集計とか) Cloudera Searchで元データにインデックス貼れるぞと。検索しながら分析ができる クラスタ管理とか Cloudera manager便利ですよ ストレージリソースの管理。 声掛け、管理者が容量チェック、Cloudera Managerのレポート 少数精鋭でHadoop使おう=手が回らなくなる。 みんなで使おう=Kerberos認証とか管理をちゃんと考えないと。けど、文化が根付けば強力。Sentry、Cloudera Navigatorとか。 Hadoopシステムの全体構成図。データの流れと各製品のつながり。 We are hiring!ということで、興味のある方は@shiumachiさんにコンタクトをとりましょうとのこと。 SQLで実現するバッチ処理とストリーム処理 LINE株式会社 田籠 聡氏 資料:Batch and Stream processing with SQL\nLINEのキャラがちらほら出てきた。\nSQL好きですか?\nログの量とか。2.1TB/Day\nバッチ処理とストリーム\n速い集計のためにHadoopが重要 エラー系のログとかはストリームで処理したい\nアーキテクチャ説明\nデータ解析する人って色々。\n管理者 プログラマ サービスディレクタ 経営陣 みんなが集計用処理を理解、編集ができるほうがいい。\n顔あげたらHiveアイコンだらけだったw\nShibとか。\nなんでHiveに限るの?\nHiveに着目したバージョンアップだけを考えれば良くなる。 スケジュールクエリが増えてきて、つらい。\nTimeWindowを固定して集計処理をすることで、回避できる。 Norikra!! スキーマレス\nOSS。Esperベース。\nインストールが楽\nクエリの動作のお話。\nhttp://norikra.github.io\nWe Are Hiring!\nHadoop コミュニティと YARN の現状 日本電信電話株式会社 小沢 健史氏 なんでHadoop? PostgreSQLでやってたけど、大きなデータにはHadoopを使おうという感じになってきた。 なんで使い分けるの? スキーマ後付け NTTDocomoのモバイル位置情報の統計処理とか? 技術的な話をするので、HiveTに着替えます!w YARNのなにが嬉しいの? ImpalaとMapReduceが同時に動くような環境の時に、リソースをうまく管理できないのがV1 そこでYARN Apache Mesosとだいたい一緒。 Apache MesosとYARNの比較 ","date":1383786660,"dir":"post/2013/","id":"a106d7c1b1b277538367f9c8140e3a75","lang":"ja","lastmod":1383786660,"permalink":"https://blog.johtani.info/blog/2013/11/07/cloudera-world-tokyo-2013/","publishdate":"2013-11-07T10:11:00+09:00","summary":"Cloudera World Tokyo 2013に参加してきました。 午前中はあいにくの雨でしたが、それでも結構な人数が最初の基調講演から参加されてました。 私が参加したセッショ","tags":["Cloudera","Hadoop","Norikra"],"title":"Cloudera World Tokyo 2013に参加しました! #cwt2013 "},{"contents":"またまた、Riak Meetup Tokyo #3に参加してきました。Riak2.0のYokozunaの話があると聞いたので。\nということで、いつものように個人メモです。\n今日は自重して、懇親会はアルコールなしにしました。思いがけずfluentd+elasticsearch+kibanaという組み合わせの話も聞けて大満足です。 Yokozunaのデモが見れなかったのがちょっと残念だったかなぁ。\n少しだけSolr本の宣伝もしてきちゃいました。\n古城さん@Mixi 「RiakCSとmixi プライベートクラウド環境」 プライベートクラウドとは? 計算リソースが安い(ストレージは微妙) 開発者が好きに使える環境+運用側のチケットに追われる毎日からの開放 Riak CSの概要 S3互換の分散ファイルストレージ 検証とか 検証時はRiak CS 1.3\n5ノードで2Mファイルを40万個\n削除は遅延で削除される\nPUT性能とか。\nRiak CSの死活監視にはRiakのstatsとか\n障害対応とか\nクラスタ クラスタは3つ。ログ、サービス(画像) 、バックアップ保存用 ログの収集にfluentd、解析にelasticsearchやkibanaを使っているらしい。 篠原@Basho 「Riak 2.0: 分散データ型、セキュリティ、そしてより容易な運用へ」 riak 2.0 pre5をリリース アプリ向け機能強化、運用の容易性 設計ポリシーとか、1.xとか 運用、高可用性、水平拡張性 Capabilityネゴシエーションとか 2.0の機能強化 バケットタイプ キーの名前空間としてバケットがあったけど、同種のバケットをまとめて管理とかしたくなった。 データ型の導入(CRDT) Setデータ型 セキュリティとか 強い整合性\u0026hellip; 鈴木@Basho 「Yokozuna: Riak 2.0の新しい全文検索機能」 YokozunaやSolrの概要 1ノードにRiakとSolrが1プロセスずつ SolrプロセスはRiakが管理してくれる SolrCloudは使ってません。 Riakのノードに届いたデータをSolrに裏で書き込んでくれる。 検索時にはRiakのノードが分散検索をしてくれる X-Riak-Metaもインデクシングしてくれる。jsonやxmlの各要素をSolrのフィールドとして認識してくれる。 Extractor Solrは4.4で、JVMは1.7をユーザが入れるらしい。\n","date":1383746460,"dir":"post/2013/","id":"9dca844d353efed03fbaddfc0fab7c76","lang":"ja","lastmod":1383746460,"permalink":"https://blog.johtani.info/blog/2013/11/06/riak-meetup-tokyo-no3/","publishdate":"2013-11-06T23:01:00+09:00","summary":"またまた、Riak Meetup Tokyo #3に参加してきました。Riak2.0のYokozunaの話があると聞いたので。 ということで、いつものように個人メモで","tags":["Riak","Yokozuna"],"title":"Riak Meetup #3 #riakjp に参加しました。"},{"contents":"開発中ですと書きました、elasticsearch-extended-analyzeですが、改良しました。\n改良と変更は以下のとおりです。\nソースのパッケージをorg.elasticsearchからinfo.johtaniに。MLで気になったので質問したら、変えたほうがいいよとのこと。ダウンロード化については、もう少々お待ちを。 出力形式を変更。可能な限りCharFilter、Tokenizer、TokenFilterそれぞれが出力する内容を返すようにしました。 ただし、既存のAnalyzer(JapaneseAnalyzerクラスとか)に関しては、現時点では出力しません。CharFilterなどを取得するI/Fが見えないためです。(改良できるかの調査は未着手) 現時点でできてないのは以下の項目\npluginコマンドでインストール 出力したいAttributeの指定 TokenizeChainで変更されたTokenの追跡(現状はどのTokenがStopFilterで消されたかなどが不明) 画面の用意(簡単に確認できる画面) ということで、README.mdに出力サンプルは貼り付けてるので、興味のある方は試してみてください。 不明点などあれば、コメントかIssueかツイートでも。\n","date":1383570720,"dir":"post/2013/","id":"b5c628b0c1dbf857a475c4be5de4690d","lang":"ja","lastmod":1383570720,"permalink":"https://blog.johtani.info/blog/2013/11/04/improve-output-extended-analyze/","publishdate":"2013-11-04T22:12:00+09:00","summary":"開発中ですと書きました、elasticsearch-extended-analyzeですが、改良しました。 改良と変更は以下のとおりです。 ソー","tags":["elasticsearch","plugin"],"title":"elasticsearch-extended-analyzeの改良"},{"contents":"お久しぶりです。 気づいたらまた、結構ブログを書いてなかったです。。。\n今回は、今開発しているElasticsearchのプラグインに関するお話です。\nいやぁ、名前決めるの難しいですね。これで英語的に合ってるか不安ですが、elasticsearch-extended-analyzeというプラグインを作っています。\nどんなもの? Solrの管理画面のanalysisに相当する機能が欲しくて作り始めました。\nElasticsearchにはanalyze APIというAPI(名前あってるのかなぁ?)が存在します。\nこれは、文字列を投げると、指定したアナライザやトークナイザでどのようなトークンに分割されるかを調べることができるAPIです。\n例えば、elasticsearch-analysis-kuromojiをインストールしたElasticsearchに対して、以下のcurlコマンドを実行します。\ncurl -XPOST \u0026#39;localhost:9200/_analyze?tokenizer=kuromoji_tokenizer\u0026amp;filters=kuromoji_baseform\u0026amp;pretty\u0026#39; -d \u0026#39;寿司が美味しい\u0026#39; すると、トークナイズされた結果が次のようなJSONで返ってきます。\n{ \u0026#34;tokens\u0026#34; : [ { \u0026#34;token\u0026#34; : \u0026#34;寿司\u0026#34;, \u0026#34;start_offset\u0026#34; : 0, \u0026#34;end_offset\u0026#34; : 2, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 1 }, { \u0026#34;token\u0026#34; : \u0026#34;が\u0026#34;, \u0026#34;start_offset\u0026#34; : 2, \u0026#34;end_offset\u0026#34; : 3, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 2 }, { \u0026#34;token\u0026#34; : \u0026#34;美味しい\u0026#34;, \u0026#34;start_offset\u0026#34; : 3, \u0026#34;end_offset\u0026#34; : 7, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 3 } ] } トークナイズの結果がわかるのは嬉しいのですが、どんな品詞なのかといったKuromoji固有のTokenの属性情報がなくなってしまいます。\nSolrでは、こんな画面が用意されていて、品詞情報とかが出力されます。あとは、各TokenFilterでどのトークンがなくなっているかなどもわかるようになっています。\nこれって結構役立つと思うんですよ。 ということで、Pluginも作ってみたかったので、いい機会だから作ってみようかと。\n出力サンプル まずは、その他のAttribute(品詞とか)を表示するところを実装してみました。\ncurl -XPOST \u0026#39;localhost:9200/_extended_analyze?tokenizer=kuromoji_tokenizer\u0026amp;filters=kuromoji_baseform\u0026amp;pretty\u0026#39; -d \u0026#39;寿司が美味しい\u0026#39; 先ほどとほぼ一緒のcurlコマンドを実行します。違う点は**「_analyze」が「_extended_analyze」**となっている点です。\nで、実行結果はこんな感じです。(長いですがそのまま載せてます。続きの文章がしたにあります。)\n{ \u0026#34;tokens\u0026#34; : [ { \u0026#34;token\u0026#34; : \u0026#34;寿司\u0026#34;, \u0026#34;start_offset\u0026#34; : 0, \u0026#34;end_offset\u0026#34; : 2, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 1, \u0026#34;extended_attributes\u0026#34; : [ { \u0026#34;org.apache.lucene.analysis.tokenattributes.TermToBytesRefAttribute#bytes\u0026#34; : \u0026#34;[e5 af bf e5 8f b8]\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.tokenattributes.PositionLengthAttribute#positionLength\u0026#34; : 1 }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.BaseFormAttribute#baseForm\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.PartOfSpeechAttribute#partOfSpeech\u0026#34; : \u0026#34;名詞-一般\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.PartOfSpeechAttribute#partOfSpeech (en)\u0026#34; : \u0026#34;noun-common\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#reading\u0026#34; : \u0026#34;スシ\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#reading (en)\u0026#34; : \u0026#34;sushi\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#pronunciation\u0026#34; : \u0026#34;スシ\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#pronunciation (en)\u0026#34; : \u0026#34;sushi\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionType\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionType (en)\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionForm\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionForm (en)\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.tokenattributes.KeywordAttribute#keyword\u0026#34; : false } ] }, { \u0026#34;token\u0026#34; : \u0026#34;が\u0026#34;, \u0026#34;start_offset\u0026#34; : 2, \u0026#34;end_offset\u0026#34; : 3, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 2, \u0026#34;extended_attributes\u0026#34; : [ { \u0026#34;org.apache.lucene.analysis.tokenattributes.TermToBytesRefAttribute#bytes\u0026#34; : \u0026#34;[e3 81 8c]\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.tokenattributes.PositionLengthAttribute#positionLength\u0026#34; : 1 }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.BaseFormAttribute#baseForm\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.PartOfSpeechAttribute#partOfSpeech\u0026#34; : \u0026#34;助詞-格助詞-一般\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.PartOfSpeechAttribute#partOfSpeech (en)\u0026#34; : \u0026#34;particle-case-misc\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#reading\u0026#34; : \u0026#34;ガ\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#reading (en)\u0026#34; : \u0026#34;ga\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#pronunciation\u0026#34; : \u0026#34;ガ\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#pronunciation (en)\u0026#34; : \u0026#34;ga\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionType\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionType (en)\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionForm\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionForm (en)\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.tokenattributes.KeywordAttribute#keyword\u0026#34; : false } ] }, { \u0026#34;token\u0026#34; : \u0026#34;美味しい\u0026#34;, \u0026#34;start_offset\u0026#34; : 3, \u0026#34;end_offset\u0026#34; : 7, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 3, \u0026#34;extended_attributes\u0026#34; : [ { \u0026#34;org.apache.lucene.analysis.tokenattributes.TermToBytesRefAttribute#bytes\u0026#34; : \u0026#34;[e7 be 8e e5 91 b3 e3 81 97 e3 81 84]\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.tokenattributes.PositionLengthAttribute#positionLength\u0026#34; : 1 }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.BaseFormAttribute#baseForm\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.PartOfSpeechAttribute#partOfSpeech\u0026#34; : \u0026#34;形容詞-自立\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.PartOfSpeechAttribute#partOfSpeech (en)\u0026#34; : \u0026#34;adjective-main\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#reading\u0026#34; : \u0026#34;オイシイ\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#reading (en)\u0026#34; : \u0026#34;oishii\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#pronunciation\u0026#34; : \u0026#34;オイシイ\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#pronunciation (en)\u0026#34; : \u0026#34;oishii\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionType\u0026#34; : \u0026#34;形容詞・イ段\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionType (en)\u0026#34; : \u0026#34;adj-group-i\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionForm\u0026#34; : \u0026#34;基本形\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionForm (en)\u0026#34; : \u0026#34;base\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.tokenattributes.KeywordAttribute#keyword\u0026#34; : false } ] } ] } 先ほどの結果に**「extended_attributes」**という配列のオブジェクトが追加された形になっています。 ちょっと長くなってしまいましたが。。。\nSolrの処理を真似して作ったので大したことはやってないんですが、少しは便利になるかもなぁと。\n現時点では、最終的な結果しか取得できないですが、今後は次のような機能を作っていこうかと思っています。 できるかどうかは、やってみてって感じですが。\npluginコマンドでインストール pom.xmlはありますが、まだMavenとかに登録はされていません。ですので、mvn packageしてからjarファイルをpluginsフォルダに配置しないといけません。pluginコマンドでインストールできるともっと使ってもらえるはず? 出力したいAttributeの指定 リクエストパラメータで、出力したいAttribute名を指定するとか。 出力形式の変更 今は、Solrの真似をしていますが、せっかくJSONだったりするので、もう少し検討しようかと(同じAttributeの異なる値も1オブジェクトとして出力されてる) TokenizeChainの出力 Solr同様、CharFilter、Tokenizer、TokenFilterが動作して、最終的なTokenがインデックスに登録されます。ですので、各処理の直後のTokenがどうなっているかもわかったほうが嬉しいと思うので、それらも取得できるようにしたいなぁと 画面の用意 せっかくプラグインなんだし、画面で見れると嬉しいかなと。これは当分先になっちゃうと思いますが、Webページで確認できるような画面を作ると確認しやすくなるかなぁと。上記対応が終わってから取替かかると思いますが。 とりあえず、思いつくのはこんなかんじです。\nElasticsearchの_analyze APIを真似しただけのコードだし、テストも実装もまだまだですが、とりあえず公開してみました。\n要望などあれば、コメント、Issue、ツイート(もちろん、テストコードなども!)なんでも受け付けてますので、お気軽に。\n","date":1382695560,"dir":"post/2013/","id":"0302e8a57a5e8604342a925b2dc60737","lang":"ja","lastmod":1382695560,"permalink":"https://blog.johtani.info/blog/2013/10/25/developing-es-extended-analyze-plugin/","publishdate":"2013-10-25T19:06:00+09:00","summary":"お久しぶりです。 気づいたらまた、結構ブログを書いてなかったです。。。 今回は、今開発しているElasticsearchのプラグインに関するお話","tags":["elasticsearch","plugin"],"title":"elasticsearch-extended-analyzeプラグインを開発中"},{"contents":"不定期開催ですが第12回Solr勉強会を主催しました。\n今回は、前回ほどの過熱ぶりでは無かったですが、70人ほどの参加者の方がいらっしゃったかと。 ありがとうございます!\n今回は聞きたかったYokozunaの話をしてもらいました。あと、リベンジManifoldCF。 一部、追記しました。Bashoさんからツッコミがあったので。あと、4.5.1の話とか。\nManifoldCFのとSolrの組み合わせ(仮)株式会社 ロンウイット 大須賀 稔さん 前回お休みだったのでリベンジですw。\n英語だ。。。やっぱ英語がいいですか、スライド。。。\nManifoldCFの概要から。 最新版は1.3です。色々サポートしてるなぁ。\nデモもありました。(やっぱりちゃんと動かないので、鬼門みたいですが)\nデモ ManifoldCFのGUIで操作しながら。 いまいちちゃんと動かなかった。。。\nQA Q:Zipはうまく動かなかった A:Solr側で処理してくれてる。 Q:Notes対応するの? A:いまのところない。 Q:ExcelとかPDFはTika? A:Tika次第です。 Q:認証周りどこから取ってくるの? A:クローラ側にはなくて、SharePointとかの権限をみてる。 Q:Web系の認証は? A:まだないのでは。。。(調査します) あー、デモの続き忘れてましたね。。。\nSolrを組み込んだRiak 2.0の全文検索機能 -Yokozuna- Bashoジャパン株式会社 鈴木 一弘さん Riak色々使われてるよ!アングリーバードとか、Y!とか。 Riakで提供されている1機能としてのYokozuna。単独製品ではないですよと。\nRiakの説明。スケールするよ、いつでもRead/Writeできるよ、運用にフォーカスしてるよと。 マスターレスですよ。 Riak2.0のリリースは2013年末。Yokozunaもかな?\nダイナミックフィールド使ってるので、Yokozunaをonにするだけで簡単に使えるよ。\nRiakがSolrのプロセスを管理。\nインデックスの不整合の検知とかってどうやってるのかなぁ? インデックス比較用のハッシュツリーをノード間でコピーしつつ検査してる。(Active Anti-Entropy)\n(デモには魔物がいるようだ。。。)\nQA Q:JSONの属性を元にしてフィールドにインデックス可能か? A:可能です。IIJさんの発表で話が出ます。 Q:ProtocolBufferでSolrにアクセス可能? A:そのうちできそうです。リリース時にはできるようになっています。 Q:コアのスワップは?スキーマの変更は? A:事前に設定するのは可能。 Q:RiakのデータとSolrでデータがずれるってのはあるの? A:可能性はありますが、極力ずれAAEで修復。 Q:復旧中のインデックスにアクセスが行かないようにする仕組みなどはある? A:今はないです。 Yokozuna ベンチマークしました 株式会社インターネットイニシアティブ 曽我部 崇さん、田中 義久さん いいとこ取りで楽だなぁと。いうことで、試してみてます。 デモが動いてる。\nextractorでXMLやJSONをパースできる。 ベンチマーク結果。\nRiak Meetup Tokyo #2の時のQAも入ってるので助かります。素晴らしい。\nQA Q:スナップショットは両方取れるの? A:Riakは取れますが、インデックスは今は無理です。 フォロー:0.8はYokozunaにボトルネックがあったので、0.9以降だともっと性能が出るはずですとのこと。また次回とかに発表してもらうのもありですかねぇ。 Solr 4.5の新機能など @johtani 発表資料のPDFです。\nツイート見てて誤解を招いたなと思ったのですが、7u40は4.5限定ではなく、すべてのバージョンと考えてください。 チケットを見ると分かりますが、影響バージョンの記載はありません。\n※あ、4.5のChangesを紹介しましたが、4.5.1が出るかも。このへんが困ってるらしいです。\nSOLR-5306: can not create collection when have over one config SOLR-5317: CoreAdmin API is not persisting data properly LUCENE-5263: Deletes may be silently lost if an IOException is hit and later not hit (e.g., disk fills up and then frees up) LT @haruyama さん 資料:http://haruyama.github.io/solr_20131009/#(1)\n記号が捨てられるTokenizer困るので、捨てないのを作ってみました。\nKuromojiの困ったこと。全角数字を分解しちゃう。→MappingCharFilterFactoryで全角から半角にしましょう。 lucene-gosenデフォで半角記号が未知語になってしまい、半角カナと混ざるので、記号を全角にしましょう。\n","date":1381372500,"dir":"post/2013/","id":"76e127a44931bfefab991be3dd7a08b7","lang":"ja","lastmod":1381372500,"permalink":"https://blog.johtani.info/blog/2013/10/10/solr-meetup-memo/","publishdate":"2013-10-10T11:35:00+09:00","summary":"不定期開催ですが第12回Solr勉強会を主催しました。 今回は、前回ほどの過熱ぶりでは無かったですが、70人ほどの参加者の方がいらっしゃったか","tags":["Solr","Riak","Yokozuna","ManifoldCF"],"title":"第12回Solr勉強会を主催しました。#SolrJP"},{"contents":"今日は、ElasticSearchのMLで見つけたelasticsearch-inquisitorプラグインの紹介です。\nElasticSearchはREST API形式で簡単にコマンドラインからいろいろな処理を実行できて便利ですが、 GUIがあったほうが楽なこともまた事実です。 今回紹介する、inquisitorプラグインもSiteプラグイン(Webブラウザでアクセスできるプラグイン)の1つです。 (ただし、ローカルにインストールしてローカルのElasticSearchにしか接続できませんが。。。)\nインストール プラグインですので、以下のコマンドでインストールが出来ます。インストール後はElasticSearchの再起動が必要です。\nbin/plugin -install polyfractal/elasticsearch-inquisitor ElasticSearch再起動後に、以下のURLにアクセスすればOKです。 ※ローカルでのみ動作可能なプラグインです。(内部で呼び出しているJSにlocalhostと記載があるため)\nhttp://localhost:9200/_plugin/inquisitor/#/ 何ができるの? 自分の書いたQueryが正しく動作するかや、Analyzerによって文章がどのように、Term(Token)に分割されるかといった挙動をWebブラウザ上で確認することができます。用意されている画面は「Queries」「Analyzers」「Tokenizers」の3種類です。\nQueries クエリの確認、実行が可能な画面です。\n「Index」「Type」はプルダウンになっており、現在ElasticSearchに存在しているものが選択可能です。 その下のテキストエリアがクエリを入力する画面です。\nクエリを入力していると、入力しているクエリがValidかどうかをクエリのコンソール部分(右側上部)に表示してくれます。\n少し残念なことに、Tabを押すと、フォームのフォーカスが切り替わってしまうので、クエリを入力するのがちょっと面倒です。。。(私は通常の検索には、ChromeプラグインのSenseというものを利用してます。)\nクエリに問題がない場合は、「Query」ボタンを押すことで実際の検索が実行されます。 この時、画面真ん中のブルーのテーブル(内部で実行されるクエリ)の部分に、QueryがElasticSearch内部で解釈されたあとの、Luceneで実行されるレベルのクエリに変換されたクエリが表示されます。\nこれが便利です。JSONで記述したり、色々なタイプのクエリがElasticSearchでは実行できますが、望んだ形に単語が区切られているかなどを確認することができるため、非常に便利です。\nElasticSearchのQuery DSLではexplainをtrueにすることで、ヒットしたドキュメントのスコア計算に用いられた単語などがわかるのですが、そもそもヒットしないクエリの場合は、explainでは単語の区切られ方などがわかりません。\nその場合に、このプラグインで確認すると、想定と違う単語の区切られ方やクエリの造られ方がわかるかと思います。\nAnalyzers Analyzerによる文章のアナライズ結果の確認が出来る画面です。 ElasticSearchやSolrにあまり詳しくない場合、どんなAnalyzerが文章をどのように単語に区切って、転置インデックスのキーワードとして利用しているかがわからないと思います。\nこのAnalyzerが文章をどのように単語に区切っているかを確認することができるのがAnalyzers画面です。 こんなかんじの画面になります。\n一番上のテキストエリアが文章を入力する場所です。 文章を入力していくと、その下のテーブルの「Analyzed Text」の部分が変化していくのが分かります。 このグレーの単語が転置インデックスのキーワードとなります。\n予め用意されているAnalyzer以外に、用意されているTokenzier+Filterの組み合わせも簡単ですが確認可能です。(Tokenizer、Filtersとあるテーブル) ただし、ここまでのどちらも細かな設定は画面上ではできません(Filterの細かな引数の指定など)\n一番下の部分が、ElasticSearchに存在しているインデックスごとに定義されたAnalyzerやフィールドを元にした解析結果を表示することができる領域です。\n自分でマッピングを記述してフィールド定義したものの動作確認や、インデックスを適当に作ったけど、うまくヒットしない場合など、ここで、単語の区切れ方を確認することで、検索になぜヒットしないのかといった問題のヒントを得ることができると思います。\nAnalyzerによっては、インデックス対象の文字として扱わない文字があったりしますので。 先ほどのQueries画面のLuceneに投げられる直前のクエリと、Analyzersでの単語の区切られ方を確認することで、検索がうまくヒットしていないことが判明すると思います。\nTokenizers 最後はTokenizers画面です。Analyzersとほぼ同様ですが、ちがいは、デフォルトで用意されているTokenizerの挙動の確認ができるというだけになります。\n簡単な確認ならここで可能かと。\n注意点は? まだ開発途中のようで、つぎの部分が課題かと。\nローカルでのみ実行可能 Queries画面の結果の「Explain Result」リンクが未実装 Queries画面のクエリ入力が使いにくい(タブが打てないので) カスタム登録のAnalyzersはインデックスを用意しないと確認できない。(Kuromojiのプラグインを登録しただけでは確認できなかった) 細かな設定のフィールドも用意しないと、Analyzers画面では利用できない まとめ ということで、Inquisitor(読みがわからない)プラグインの簡単な説明でした。 検索にうまくヒットしないという理由は大体の場合、 クエリに入力した文字列が単語に区切られたものと、登録したデータが単語に区切られたものが異なるために検索にヒットしないというものです。\nそのクエリ、データの単語の区切られ方を確認するのに役に立つプラグインじゃないでしょうか。\nちなみに、このプラグイン自体はHTML+JSで作成されており、実際にはElasticSearchが持っているREST APIをキックしているだけになります。 ですので、Web画面なんか要らないという方は、このプラグインが実際に送信しているリクエストを参考にするとcurlコマンドでどういったリクエストを投げればいいかというのがわかると思います。\n私は軟弱者なので画面があったほうがいいですが。\n","date":1379906820,"dir":"post/2013/","id":"e1870dde155be1a375f155dd1f7ead13","lang":"ja","lastmod":1379906820,"permalink":"https://blog.johtani.info/blog/2013/09/23/intro-elasticsearch-inquisitor/","publishdate":"2013-09-23T12:27:00+09:00","summary":"今日は、ElasticSearchのMLで見つけたelasticsearch-inquisitorプラグインの紹介です。 ElasticSea","tags":["elasticsearch","plugin"],"title":"elasticsearch-inquisitorプラグインの紹介"},{"contents":"river-wikipediaの前々回の記事で書きましたが、bulk_sizeに関連して登録件数がやけにきりが良いのが気になると書いていました。\nで、Riverの仕組みを勉强がてら、elasticsearch-river-wikipediaのソース(1.2.0)を読んでみました。\nRiverの作り Riverはorg.elasticsearch.river.Riverというinterfaceを実装することで作らています。 ただ、Riverがinterfaceとなっていますが、o.e.river.AbstractRiverComponentというクラスを継承して作られています。\nAbstractRiverComponentにはRiverの名前や設定などが用意されています。 ま、ここはそれほど重要じゃないので、軽く流してと。\nRiverの設定関連は実装したRiverクラス(ここでは、WikipediaRiverクラス)のコンストラクタで、設定値の読み取りなどの記述を記載します。 このコンストラクタが、_river/hogehoge/_metaをPUTした時のJSONを元にElasticSearchから呼ばれて、Riverのインスタンスが作成されます。(たぶん、このへんがその処理だと思う。。。このあたりはまた今度)\n実際のRiverの処理はWikipediaRiverクラスのstart()メソッド内部に記述されています。\n@Override public void start() { logger.info(\u0026#34;starting wikipedia stream\u0026#34;); try { ① client.admin().indices().prepareCreate(indexName).execute().actionGet(); } catch (Exception e) { if (ExceptionsHelper.unwrapCause(e) instanceof IndexAlreadyExistsException) { // that\u0026#39;s fine } else if (ExceptionsHelper.unwrapCause(e) instanceof ClusterBlockException) { // ok, not recovered yet..., lets start indexing and hope we recover by the first bulk // TODO: a smarter logic can be to register for cluster event listener here, and only start sampling when the block is removed... } else { logger.warn(\u0026#34;failed to create index [{}], disabling river...\u0026#34;, e, indexName); return; } } ② currentRequest = client.prepareBulk(); ③ WikiXMLParser parser = WikiXMLParserFactory.getSAXParser(url); try { ④ parser.setPageCallback(new PageCallback()); } catch (Exception e) { logger.error(\u0026#34;failed to create parser\u0026#34;, e); return; } ⑤ thread = EsExecutors.daemonThreadFactory(settings.globalSettings(), \u0026#34;wikipedia_slurper\u0026#34;).newThread(new Parser(parser)); thread.start(); } 内部では\nインデックスの作成 バルクアップデート用クライアントの設定 WikiXMLのパーサの初期化 ページごとにキックされるコールバック処理の登録 デーモンスレッドの起動と起動 といった処理の流れになっています。\nで、このスレッドの起動後は、4.で用意したparser.parse()処理がグルグル回ります。\n1ページがパースされるたびに、WikipediaRiver.PageCallbackクラスのproess()メソッドが呼ばれます。 このメソッドの最後で、processBulkIfNeeded()メソッドが呼ばれています。ここで、実際にパースしたページをインデックスに登録する処理が実行されます。\nこのメソッドの1行目が鍵でした。 bulkSize以上の件数がバルクのリクエストに貯まった時だけ、実際にインデックスに登録する処理が実行されます。 このため、スレッドが回っている間は、bulkSize以上のデータが貯まらないと、インデックスへの登録は行われないわけです。\n次に、このスレッドを止めるには、前々回書いたように、_riverにPUTした、Riverの設定をDELETEするしかありません。(あとは、ElasticSearchを停止するとかでしょうか。)\nで、DELETEが実行される呼ばれるのが、WikipediaRiverクラスのclose()メソッドです。\n@Override public void close() { logger.info(\u0026#34;closing wikipedia river\u0026#34;); closed = true; if (thread != null) { thread.interrupt(); } } 見ていただくと分かりますが、スレッド止めて終了です。\n問題点は? ということで、\nWikipediaのXMLを読み込んでもRiverは停止しない Riverの停止を行ってもスレッドが止められるだけ。 bulkSize以下の件数がcurrentRequestに残っているけど、破棄される とまぁ、こんな流れになっているので、最後の端数のドキュメントがインデックスに登録されないようです。 (まだ、ちゃんと確認してないんですが、備忘録のため先に書いちゃいました。。。)\nじゃあ、全部うまく登録するにはどうしたもんかなぁと。 いまのところ思いついたのはこんな感じです。 他にいい案があったら教えて下さい。\n案1:close()処理の中で、スレッド停止後に、currentRequestに貯まっているデータをインデックスに登録しちゃう 案2:bulkSize以外に、定期的(指定された時間)で登録処理を実行してしまう。 簡単なのでとりあえず、案1を実装してみるかなぁと。 (さっさとコード書けよって話ですね。。。スミマセン) その前にMLで質問ですかねぇ、英語で。\nWikipediaのRiverをざっと眺めてみた感じですが、わかりやすい作りだなぁと。 他のRiverがどうなってるかをちゃんと見てませんが、他にもbulkSize指定をするRiverの場合は、このように件数がbulkSizeに満たない状態ではデータが登録されないといったことがあるかもしれません。\nElasticSearchのソースを読み始める取っ掛かりとしては面白いかと思いますので、興味ある方は読んで作ってみるといいかもしれません。(私は読んだだけですがw)\n追記(2013/09/13 21:00) MLで質問してみました。とりあえず、案1を。\nriver-wikipedia does not index all pages\n他のRiverでは対応してるしバグだね、Issue上げてとのことで、あげときました。 ついでにプルリクも出せばいいんでしょうが、プルリクまだやったことないヘタレです。。。\nあと、案2についても同じトピックで質問してます。 どうやら、BulkProcessorにその機能があるよと。 flushintervalというプロパティがありそうです。どうやって設定して、どうやって動くのかとか見てないので、 調査してブログorLTかな。\nbulk udpにはその値を設定できそうなのがあるんだよなぁ。\n追記その2(2013/09/16 23:50) さっそく修正版がコミット(コミットログ)されてました。 結構変わってます。BulkProcessorにflush_intervalの設定をすれば、よしなにやってくれる仕組みがすでに実装されているようです。 bulkSizeについても同様に、BulkProcessorに設定すれば良いようです。 Riverの仕組みが結構スッキリしています。 もともと実装されていた、bulkSizeごとの処理も消されています。 確かに、BulkProcessorの仕組みとして実装されている方がしっくりきますね。\nということで、考える暇もなくコミットされてしまいました。 こうやって質問しつつ、少しずつソースを読んでいこうかなと思ってるとこです。\n","date":1378921080,"dir":"post/2013/","id":"d2e805472f79f0b558f75b90b5e7b4ee","lang":"ja","lastmod":1378921080,"permalink":"https://blog.johtani.info/blog/2013/09/12/question-river-wikipedia/","publishdate":"2013-09-12T02:38:00+09:00","summary":"river-wikipediaの前々回の記事で書きましたが、bulk_sizeに関連して登録件数がやけにきりが良いのが気になると書いていまし","tags":["elasticsearch","wikipedia"],"title":"elasticsearch-river-wikipediaの疑問点"},{"contents":"前々回紹介した、日本語Wikipediaのデータをインデックス登録する記事の続きです。\n今回は、Kuromojiのアナライザを利用してインデックス登録してみます。\n余談(Proxy環境でのプラグインインストール) ElasticSearchのpluginコマンドはJavaで実装されています。(org.elasticsearch.plugins.PluginManager) プラグインのダウンロードには、java.net.URL.openConnection()から取得URLConnectionを使用しています。\nですので、pluginのインストールを行う際に、Proxy環境にある場合は以下のようにコマンドを実行します。\n./bin/plugin -DproxyPort=ポート番号 -DproxyHost=ホスト名 -i elasticsearch/elasticsearch-analysis-kuromoji/1.5.0 elasticsearch-analysis-kuromojiのインストール WikipediaのデータをKuromojiを使って、形態素解析ベースの転置インデックスを作成していきます。 まずは、Kuromojiを利用するために、Analysisプラグインのインストールです。 ElasticSearchのバージョンに対応したプラグインのバージョンがあります。(プラグインのページに対応したバージョンの記載あり) 今回はElasticSearchの0.90.3を利用しているため、1.5.0をインストールします。\n./bin/plugin -i elasticsearch/elasticsearch-analysis-kuromoji/1.5.0 インストール後は再起動しておきます。 なお、Kuromojiを利用して、Wikipediaのデータを登録するばあい、デフォルトの設定では、ヒープが足りなくなるおそれがあります。 ElasticSearchの起動時に以下のオプションを指定して、最大ヒープサイズを2Gとしておきます。\nexport ES_HEAP_SIZE=2g;./bin/elasticsearch Indexの作成(デフォルトでKuromojiのAnalyzerを利用する) Wikipediaのデータを登録する際に、Kuromojiのアナライザを利用したいのが今回の趣旨でした。 一番ラクな方法として、Wikipediaデータのインデックスの設定として、デフォルトのアナライザをKuromojiにしてしまいます。 (きちんと設計する場合は、必要に応じてフィールドごとに指定しましょう)\ncurl -XPUT \u0026#39;localhost:9200/ja-wikipedia-kuromoji\u0026#39; -d \u0026#39;{ \u0026#34;settings\u0026#34;: { \u0026#34;analysis\u0026#34;: { \u0026#34;analyzer\u0026#34;: { \u0026#34;default\u0026#34; : { \u0026#34;type\u0026#34; : \u0026#34;kuromoji\u0026#34; } } } } }\u0026#39; これでkuromojiのアナライザがデフォルトで利用される形となります。 あとは、Riverを起動して登録するだけです。\nRiverの実行 前回と一緒です。 インデックス名(_river/\u0026lt;インデックス名\u0026gt;/_meta)だけは、先ほど作成した「ja-wikipedia-kuromoji」に変更してください。\ncurl -XPUT localhost:9200/_river/ja-wikipedia-kuromoji/_meta -d \u0026#39; { \u0026#34;type\u0026#34; : \u0026#34;wikipedia\u0026#34;, \u0026#34;wikipedia\u0026#34; : { \u0026#34;url\u0026#34; : \u0026#34;file:/home/johtani/src/jawiki-latest-pages-articles.xml\u0026#34; }, \u0026#34;index\u0026#34; : { \u0026#34;bulk_size\u0026#34; : 10000 } }\u0026#39; あとは、インデックスされるのを待つだけです。\nデータ量とか 5.8gbになりました。Kuromojiを利用したため、形態素解析により単語にきちんとトークないずされた結果でしょう。 Uni-gramだと、転置インデックスのボキャブラリも単語に対してヒットするドキュメント数も大きくなるため、 インデックスサイズも大きくなっているのかと。\n検索クエリのサンプルなどはまた後日。(夜遅いので。。。)\n","date":1378138500,"dir":"post/2013/","id":"79e647a3f8b36a1221897f5837c84aff","lang":"ja","lastmod":1378138500,"permalink":"https://blog.johtani.info/blog/2013/09/03/ja-wikipedia-with-kuromoji/","publishdate":"2013-09-03T01:15:00+09:00","summary":"前々回紹介した、日本語Wikipediaのデータをインデックス登録する記事の続きです。 今回は、Kuromojiのアナライザを利用してインデッ","tags":["elasticsearch","kuromoji","wikipedia"],"title":"日本語Wikipediaをインデクシング(Kuromojiバージョン)"},{"contents":"ElasticSearch勉強会 第1回を主催しました。 昨年のpyfesでなんちゃって資料で喋って、1年たちました。\nElasticSearchの書籍(英語)も出てきて、今年はElasticSearchが面白くなりそうだし、使ってる人たちから話も聞きたいなぁということで、主催しました。\n思った以上に興味のある方がいらっしゃったようで、100人応募のところ、チケットがすぐ完売してしまうほど。。。 しかも、当日もほぼ満員ということで、大変な盛況ぶりでした。\nスピーカーの皆様、参加された皆様、会場を提供していただいたリクルートテクノロジーズさん、ありがとうございました!(たぶん、90人くらいいらっしゃってたかと。)\nこんなステキな案内板も用意してもらいました。スタッフのみなさんありがとうございます! トゥギャっても頂きました。まとめていただいてありがとうございます!\n自分の発表や個々の発表に関する感想は以下のメモに。\nElasticSearch入門 @johtani スライド:ElasticSearch入門※スライドはPDFです。\n緊張しまくりでわかりにくかったですかね。。。 とりあえず、AWSのサービスじゃないってのだけでも覚えて帰っていただければ満足です。 途中で見せたChromeプラグインのSense わからなかった点や質問、ご意見などは、当ブログのコメント、私宛の@ツイート、なんでもいいので、反応ください。なんでもいいので反応があると、今後の励みになりますので! ということで、発表でも言いましたが、わからないことがアレば、@johtaniまで投げてもらえれば、「知らない」「ブログのネタにします」「ソレはこんなかんじですかねぇ?(テキトー)」みたいに答えると思います。 Elasticsearch in Actionは帰宅中に、4章追加されたよというメールが届きました。 宿題 クラスタへのノードの追加の処理方法とか、シャーディングの実装とか。 elasticsearchプラグイン入門 ~ mocksolrpluginでSolrと入れ替えてみよう 菅谷さん スライド:elasticsearchプラグイン入門 slideshare\nプラグイン構成とか(公式でまとまってるの見つけられないので助かります。) 作る上でのポイントうれしいです。 パッケージ名変えられるとか、つらい。。。 Solr APIプラグインについて(Solrの振りしてくれる便利なヤツ) 感想 まだ、プラグインを書いたことがないのですが、ちゃんとプラグインはどういう構成で書くんですよというまとまった資料って本家のサイトにもない気がしています。 なので、スライドが公開されたらすごく役に立つかと。 そのまえに、何かプラグイン書いてみます。。。\nDebugging and testing ES systems Chris Birchallさん スライド:Debugging and testing ES systems slideshare\nテストの方法とか便利なお話(最後のほうしか聞いてなかったですが。。。。) クエリのデバッグは色々とやらないと、なんでヒットしないのってよくあるので。とくに形態素解析を利用した検索の場合、短い文章(クエリ)と長い文章(ドキュメント)で切れ目が変わってうまくヒットしないとかありますよね。 最後に少しだけ話しましたが、n-gramとKuromojiを組み合わせてOR検索とかすると良い場合があります。 インデックスが大きくなったり、OR検索なので遅くなったりというデメリットもありますが。 感想 実際に使われているノウハウを元に話をしていただいたので助かりました。 最初に席を外してたのですが、戻ってきて日本語で普通に発表されててほんとにびっくりしましたw テスト用プラグインがあるのとかは知らなかったです。 あと、使われてたIDEがIntelliJ IDEAでしたね!私も使ってます!\nニコニコ動画データセット 25億件を検索可能にしてみよう @PENGUINANA_ スライド:ニコニコ動画を検索可能にしてみよう slideshare\nkibana@cookpadのお話 どういう挙動するかをやってみればいいじゃんってことで、やってみるのカッコイイ! http://goo.gl/FYtO5T bigdeskとか。プラグインいろいろ。 感想 さすがです、ペンギン先生。大きなデータセットつかって、構築した環境に関する数値も書かれてる資料ができて素晴らしすぎです。 思った以上にサクサク動いてて、4hでインデクシングできるのもすごいなぁと。 私も見習ってこのくらいがサクッとできるようになりたい。。。 あと、発表後にムチャぶりしましたが、次回はぜひ検索側の性能とかも話してもらえたらと。\n反省点 イベントアテンドだと、キャンセル待ちができない+どのくらいの方が興味をもっているのかわからない。 イベントページの主催者は複数指定できる方がいい。(土壇場の登録の人が管理できない。私が司会やってたから) マイクが聞こえにくかった(音量調節とかちゃんと調べないと) 懇親会は立食のほうがやはり動きやすい。 懇親会が1時間ちょっとしかできなかった 雑感 ということで、ES勉強会、主催の私が一番楽しめました。ありがとうございます。 (あと、気前よく調べて答えますと言ってしまいました。。。まぁ、いいトリガーになるので、ウェルカムですが)\nやっぱりKibanaについて興味を持ってる人も多いのかなぁという感触がしたので、次回はぜひKibana3の話をしてもらえるように頑張ります。 あと、elasticsearch-headを使われてるんだなぁと。私はelasticsearch-HQを入れて使ってみてます。大きなクラスタ管理まではまだやってないので。\nあとは、やはりいろんな人に助けられてるなぁと実感しつつ、今後も開催するので助けてください!ということで。 (もちろん、Solr勉強会もがんばりますよー)\n関連ブログ ElasticSearch勉強会 第1回 - Go ahead! タムタムの日記 - ElasticSearch勉強会 の参加メモ #elasticsearchjp 第1回ElasticSearch勉強会に行ってきた! #elasticsearchjp - #侍ズム 第1回 ElasticSearch 勉強会に参加 #elasticsearchjp - seratch 他にもブログを書かれた方がいらっしゃいましたたら、リンクしたいので連絡いただければ。\n","date":1377798120,"dir":"post/2013/","id":"5931f8e3acdac724742c4ee0960d8d40","lang":"ja","lastmod":1377798120,"permalink":"https://blog.johtani.info/blog/2013/08/30/hold-first-elasticsearch-meetup-in-japan/","publishdate":"2013-08-30T02:42:00+09:00","summary":"ElasticSearch勉強会 第1回を主催しました。 昨年のpyfesでなんちゃって資料で喋って、1年たちました。 ElasticSearch","tags":["elasticsearch","勉強会"],"title":"第1回ElasticSearch勉強会を開催しました! #elasticsearchjp"},{"contents":"久々のブログはElasticSearchネタです。勉強会開催する予定だったりすので、もう少し触っておきたいなと。 お手軽に検索するデータとして、よくWikipediaのデータを使っています。 ElasticSearchにはelasticsearch-river-wikipediaという便利なプラグインがあり、Wikipediaのデータを簡単に検索可能な状態にできます。このRiverを利用して日本語のWikipediaのデータを入れたので、メモを取っておきます。 まずは、river-wikipediaで日本語のデータをインデクシングしてみるまでの説明です。 日本語特有の設定(Kuromojiを利用したインデクシング)などはまた後日。\nプラグインのインストール 対象とするElasticSearchは現時点で最新版の0.90.3とします。 最新版でRiver動かないなぁとつぶやいた影響かどうかはわかりませんが、2013/08/19に最新版のElasticSearchで動作するプラグインが公開されました。\nまずはインストールです。 HPにも書いてありますが、以下のコマンドを実行すればインストールされます。\n$ ./bin/plugin -install elasticsearch/elasticsearch-river-wikipedia/1.2.0 -\u0026gt; Installing elasticsearch/elasticsearch-river-wikipedia/1.2.0... Trying http://download.elasticsearch.org/elasticsearch/elasticsearch-river-wikipedia/elasticsearch-river-wikipedia-1.2.0.zip... Downloading ..........DONE Installed river-wikipedia into /opt/elasticsearch/plugins/river-wikipedia ElasticSearchが起動している場合はプラグインをインストール後、認識させるためにElasticSearchを再起動します。\n日本語Wikipediaのインデクシング 通常は英語のWikipediaがインデクシングされますが、対象となるファイルを変更することで日本語のWikipediaもインデクシング可能です。 手元に日本語Wikipediaのダンプファイルがあるものとします。(ダウンロードはWikipediaデータベースダウンロードのページにあるpages-articles.xml.bz2のファイルです)\nファイルを指定してインデクシングするには、つぎのcurlコマンドを実行します。 コマンドを実行するとすぐにインデクシングが始まりますので注意が必要です。\ncurl -XPUT localhost:9200/_river/ja-wikipedia/_meta -d \u0026#39; { \u0026#34;type\u0026#34; : \u0026#34;wikipedia\u0026#34;, \u0026#34;wikipedia\u0026#34; : { \u0026#34;url\u0026#34; : \u0026#34;file:/home/johtani/src/jawiki-latest-pages-articles.xml\u0026#34; }, \u0026#34;index\u0026#34; : { \u0026#34;bulk_size\u0026#34; : 1000 } }\u0026#39; ここでURLに含まれる「ja-wikipedia」がインデックス名になります。 また、JSONの\u0026quot;url\u0026quot;にはファイルの場所を指定するため、file:で開始するパスを指定します。 例では、bz2を解凍したファイルを指定していますが、bz2のままのファイルでもOKです。\n上記コマンドを実行すると、_riverというインデックスにつぎのようなエントリが増えています。 (curl -XGET 'localhost:9200/_river/ja-wikipedia/_search?pretty)\n{ \u0026#34;took\u0026#34;: 5, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 2, \u0026#34;max_score\u0026#34;: 1, \u0026#34;hits\u0026#34;: [ { \u0026#34;_index\u0026#34;: \u0026#34;_river\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;ja-wikipedia\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;_status\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;ok\u0026#34;: true, \u0026#34;node\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;gdyvwpiAR52lqUCcRhVwsg\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Blitzschlag, Baron Von\u0026#34;, \u0026#34;transport_address\u0026#34;: \u0026#34;inet[/192.168.100.7:9300]\u0026#34; } } }, { \u0026#34;_index\u0026#34;: \u0026#34;_river\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;ja-wikipedia\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;_meta\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;wikipedia\u0026#34;, \u0026#34;wikipedia\u0026#34;: { \u0026#34;url\u0026#34;: \u0026#34;file:/home/johtani/src/jawiki-latest-pages-articles.xml\u0026#34; }, \u0026#34;index\u0026#34;: { \u0026#34;bulk_size\u0026#34;: 100 } } } ] } } \u0026quot;_id\u0026quot;: \u0026quot;_meta\u0026quot;というエントリがさきほど登録したWikipediaのRiverに関する設定です。 \u0026quot;_id\u0026quot;: \u0026quot;_status\u0026quot;というエントリが起動したRiverの状態になります。\nRiverの停止 日本語Wikipediaは結構サイズが大きく、手元のAirでインデクシングするのに30分程度かかりました。(bz2圧縮されていないファイルで、何もしていない状態)\n途中でRiverを停止したくなった場合は、以下のcurlコマンドを実行します。\n$ curl -XDELETE \u0026#39;localhost:9200/_river/ja-wikipedia\u0026#39; 先ほど設定した_river/ja-wikipediaの情報を削除すると、エントリが削除されたのを検知してRiverが停止します。ログにはつぎのようなメッセージが表示されます。\n[2013-08-26 18:26:50,130][INFO ][cluster.metadata ] [Blitzschlag, Baron Von] [[_river]] remove_mapping [ja-wikipedia] [2013-08-26 18:26:50,130][INFO ][river.wikipedia ] [Blitzschlag, Baron Von] [wikipedia][ja-wikipedia] closing wikipedia river Riverを停止してもそれまでインデクシングされたデータは検索できます。 データはちょっとだけで良いという場合は、先ほどの_riverのデータを削除してください。 (◯件だけ登録したいとかできるかは調べてないです。)\nサイズとかマッピングとか サイズ インデックス前のXMLのサイズが5.7Gのとき、ElasticSearchのインデックスサイズ(Optimize後)は7.2Gとなりました。すこし古いファイルを利用しているため、最新版とはサイズが異なるかもしれません。\nあと、データ数が、1540000件とやけにきりがいいのがちょっと気になっています。。。 bulkのサイズを10000で指定してインデックスしたので、切れてるのかなぁと。\nということは、データが欠落しているような気がするのでRiverの作りの問題なのか、ElasticSearchの問題なのかはちょっと調べてみないとわからないなと。\nマッピング 出来上がったインデックスのマッピング(Solrでいうスキーマみたいなもの)は次のようになっています。\n{ \u0026#34;ja-wikipedia\u0026#34;: { \u0026#34;page\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;category\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;disambiguation\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;boolean\u0026#34; }, \u0026#34;link\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;redirect\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;boolean\u0026#34; }, \u0026#34;special\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;boolean\u0026#34; }, \u0026#34;stub\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;boolean\u0026#34; }, \u0026#34;text\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;title\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } } } } Wikipediaの各種データが上記のフィールドに入っています。 また、マッピングタイプはデフォルトで「page」というタイプになっています。\n検索 先ほどのマッピングを元に検索すればOKです。例えばつぎのような感じです。\ncurl -XPOST \u0026#39;localhost:9200/ja-wikipedia/_search?pretty\u0026#39; -d \u0026#39; { \u0026#34;size\u0026#34; : 3, \u0026#34;script_fields\u0026#34;: { \u0026#34;title_only\u0026#34;: { \u0026#34;script\u0026#34;: \u0026#34;_source.title\u0026#34; } }, \u0026#34;query\u0026#34; : { \u0026#34;query_string\u0026#34;: { \u0026#34;default_field\u0026#34;: \u0026#34;title\u0026#34;, \u0026#34;query\u0026#34; : \u0026#34;千葉\u0026#34; } } }\u0026#39; 結果はこんな感じ。\n{ \u0026#34;took\u0026#34;: 51, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 5, \u0026#34;successful\u0026#34;: 5, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 8616, \u0026#34;max_score\u0026#34;: 5.8075247, \u0026#34;hits\u0026#34;: [ { \u0026#34;_index\u0026#34;: \u0026#34;ja-wikipedia\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;page\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;3582\u0026#34;, \u0026#34;_score\u0026#34;: 5.8075247, \u0026#34;fields\u0026#34;: { \u0026#34;title_only\u0026#34;: \u0026#34;千葉\u0026#34; } }, { \u0026#34;_index\u0026#34;: \u0026#34;ja-wikipedia\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;page\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;2352241\u0026#34;, \u0026#34;_score\u0026#34;: 4.94406, \u0026#34;fields\u0026#34;: { \u0026#34;title_only\u0026#34;: \u0026#34;千葉千枝子\u0026#34; } }, { \u0026#34;_index\u0026#34;: \u0026#34;ja-wikipedia\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;page\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;14020\u0026#34;, \u0026#34;_score\u0026#34;: 4.8754807, \u0026#34;fields\u0026#34;: { \u0026#34;title_only\u0026#34;: \u0026#34;千葉千恵巳\u0026#34; } } ] } } 結果を見やすくするため、タイトルだけを「title_only」という表示にしています。 ただ、この検索だと、一見「千葉」できちんとヒットしているように見えますが、ElasticSearchのフィールドの定義はstring型になっています。なので、実は「千」や「葉」だけのデータもヒットしています。 マルチバイト文字は1文字ずつインデックスされてしまい、query_stringというクエリでは、フレーズ検索などができていないためです。\nまとめ プラグインいれて、XMLファイルがあれば、検索できるデータが出来上がるので、 暇があったら、お試しで触ってみるデータを簡単に入れてみてはどうでしょうか。\nただ、いくつか気になる点も。\n日本語が検索しにくい(string型のフィールドなのでuni-gramっぽくなっている) bulk_sizeの影響で端数が登録できてない(バグ?どうなの?) ということで、ちょっと使いにくいかもなぁということで、つぎはKuromojiを利用してインデックスしてみてみようかなと。次回のエントリで書く予定です。\n","date":1377226920,"dir":"post/2013/","id":"3931327ed463d1568868c5ab8e839148","lang":"ja","lastmod":1377226920,"permalink":"https://blog.johtani.info/blog/2013/08/23/index-wikipedia-ja-to-elasticsearch/","publishdate":"2013-08-23T12:02:00+09:00","summary":"久々のブログはElasticSearchネタです。勉強会開催する予定だったりすので、もう少し触っておきたいなと。 お手軽に検索するデータとして","tags":["elasticsearch","wikipedia"],"title":"ElasticSearchにプラグインで日本語Wikipediaデータを入れてみました"},{"contents":"宿題その2?かな。Solr勉強会でCloudera Searchのスキーマ周りってどうなってるの?という質問が出てて、 なんか調べることになってたので、関係しそうなMorphlinesのLoadSolrコマンドを調べてみました。 こいつが、Solrへの書き込みを実行するコマンドみたいだったので。\n(※Cloudera Searchのスキーマの設定方法とかは調べてないです。)\n(※めんどくさかったので、パッケージ名すっ飛ばしてクラス名書いてます。githubへのリンクを代わりに貼ってます。)\nRecord=Solrのドキュメント convert()メソッドにて、MorphlinesのRecord(コマンドの処理するデータの1単位)に格納されているKey-ValueデータをSolrInputDocumentクラスのフィールドとして格納しています。 Recordにもフィールドという概念があり、Recordのフィールド=Solrのフィールドという事みたいです。\nということで、Solrのフィールドは事前に定義しておき、Morphlinesの処理内部でSolrのフィールド名に値を詰めていく感じでしょうか。 別途、sanitizeUnknownSolrFildsというコマンドが用意されていて、Solrのスキーマにないものはこのコマンドを使って、無視するフィールド名に変えたり、雑多なデータを入れるためのフィールド名にするといった処理ができるようです。このコマンド内部で、Solrのスキーマ設定を元に、Solrのフィールドに合致する物があるかをチェックして処理しています。\nSolrへの登録処理は? Solrへの登録処理自体はLoadSolrクラス内部でDocumentLoaderというクラスのload()メソッドを呼び出しているだけでした。ということで、DocumentBuilderクラスを少し調査。\nDocumentLoader IFでした。。。実クラスは次の条件\nSolrMorphlineContextにDocumentLoaderがあればそちらを採用(他の種類はなにがあるんだろ?) なければ、SolrServerDocumentLoaderをnewしたものを利用 2.の場合がおそらくMapReduceではないパターンのloadSolrだと思われます。SolrServerDocumentBuilderはSolrJのAPIを利用して、Solrへデータ登録していく普通のアプリです。(対象とするSolrは外部に起動しているもののはず=FlumeのSolrSinkではこちらを採用かな?)\nSolrへの接続情報とか設定ファイルとかSolrCloud用のZooKeeperとかはSolrLocatorクラスに設定される内容が利用されます。\n1.のパターンは、どうやら、Cloudera SearchのMapReduceIndexerToolのクラスにあるMyDocumentLoaderかなぁと。 こちらは、MapReduceを利用する場合に、利用されてるっぽいです(ちゃんと見てないけど) 内部処理は、HadoopのContext.writeメソッドにでSolrInputDocument(=MorphlinesのRecord)を書きだして、ReducerでSolrOutputFormatでインデックス作成の流れかなと。たぶん、MorphlineMapRunnerあたりを読みこめば解読できるかと。 ちなみに、こちらは、2.とは異なり、SolrLocatorの設定は無視されそう。\n感想+妄想? ということで、Morphlinesのデータ流れを考える上で、現時点ではSolrのスキーマを頭の片隅に置きつつ、 Recordの中にあるデータをゴニョゴニョしてデータを形成していくって感じになりそうです。 うまく処理できなかったものとかのカウントとかもとれたりするのかなぁ?とか、また色々と気になるところが出てきますが、一旦ここまでで。。。(だれか、続きを調べて書いてみてくれてもいいんですよ!コマンドもいっぱいあるし!)\nとまぁ、こんなかんじでMorphlinesをちょっとだけ読みました。 よくよく考えたら、こんなの作ったことあるなぁと(こんなに汎用的じゃないけど)。 みんな同じ事考えるんですねぇ。 コマンドパターン?みたいな感じで、I/F決めてSolrとか別のシステムとかにデータ入れる処理を順番に記述できる的なバッチ処理良くかいてます(書いてましたのほうが正解かなぁ)。\n","date":1375434120,"dir":"post/2013/","id":"33e01e2271be22b5ed330045fe6aff50","lang":"ja","lastmod":1375434120,"permalink":"https://blog.johtani.info/blog/2013/08/02/morphlines-loadsolr/","publishdate":"2013-08-02T18:02:00+09:00","summary":"宿題その2?かな。Solr勉強会でCloudera Searchのスキーマ周りってどうなってるの?という質問が出てて、 なんか調べることになって","tags":["Cloudera Search","Morphlines","Solr"],"title":"MorphlinesのloadSolrをちょっとだけ調べてみた"},{"contents":"今朝起きたら、Xperia Zが故障してしまいました。 電源ボタンを押してもスリープにならないんです。しかも、スリープからの復帰もできない。。。\nということで、ドコモショップに行って来ました。対応も良かったです。 やっぱり、ボタンがおかしく再起動してもNGでした。 ということで、トントン拍子で交換品に変更してもらえました。\n2、3回繰り返し言われましたが、データなくなりますよ&交換品なので、復旧はご自分でとのこと。 ドコモショップ行く前に「Sony Bridge for Mac」というSony製のアプリでバックアップ取ってたし問題ないですと回答して、交換してもらいました。 最後に使ってないオプションとか要らないのでやめたほうが安くなりますよなどの提案もいただき満足でした。 さらに、前の機種に貼ってたフィルムもきちんと張り替えてもらえたし。時間はちょっとかかったけど。\nで、先ほど帰宅して、朝とっておいたバックアップから復旧しようとしたら。\n**「そんなバックアップありません」**みたいなメッセージが表示されて復旧出来ません。。。\nえ?なにそれ?と思い、とりあえず現時点のデータをバックアップ取ってみるかと。 バックアップ取ったあとに、再度復旧しようとしたらちゃんとリストがでてくるじゃないですか。\nなんだこれ?ということで、ファイル探しです。。。\n「Sony Bridge for Mac」バックアップファイルは次の場所に保存されるみたいです。\n/Users/ユーザ名/Library/Application Support/Sony Ericsson Bridge for Mac/Backups/製品番号みたいな文字列/日付 この最後のディレクトリが製品番号?ごとのディレクトリっぽく、2つありました。 どうせ初期化された状態だしということで、古い日付フォルダを新しい製品番号のフォルダにコピーしたら復元は可能でした。 壁紙の設定は再起動したら復活しましたが、復活してないものも。。。 復活してないのは以下のものです。\nインストールしてたアプリ ホーム画面の配置 アカウント色々(Google Playとか) ということで、スマホでインストールするのもだるくなってきたので、PCで黙々とGoogle Playのサイトからインストールしてますが、これもだるいですね。。。\n必要なアプリインストールし直したら、またSonyのアプリで復旧してみて、設定が復活するのを祈って。。。\n続き インストールしなおして、ホーム画面での配置をがんばりました。 Google Playのサイトから既存アプリをインストールするときに、ブラウザバックで戻ってたのですが、 一覧から別タブにインストールしたいアプリのページを開きまくってから、インストールボタン押すのが楽でした(半分くらい終わった所で気づいた。。。)\n一通りインストールしたあとに、ホーム画面の配置をやり直して、「Sony Bridge for Mac」もう一回復元。 twiccaやブクログなど、個別にアカウントとか設定を管理しているアプリについては復活しました。\nけど、Androidがアカウントを管理するもの(例:Facebookなど)については、残念ながら、一部のものはアカウントを再登録しないといけませんでした。\n写真や音楽についてはもともとSDカードに入れていたのもあったので、まぁ、被害は少なかったかなぁと。\nただ、iPadやiPhoneの用に簡単にバックアップ(アプリの情報、配置まで)ができて復元できると助かるなぁと思いました。(今度はホーム画面のキャプチャ撮ってから修理に出すかなぁ。。。)\n","date":1375364280,"dir":"post/2013/","id":"cd9ba1f582642d9cbe500f018afab341","lang":"ja","lastmod":1375364280,"permalink":"https://blog.johtani.info/blog/2013/08/01/replace-xperia-z/","publishdate":"2013-08-01T22:38:00+09:00","summary":"今朝起きたら、Xperia Zが故障してしまいました。 電源ボタンを押してもスリープにならないんです。しかも、スリープからの復帰もできない。。。","tags":["Xperia Z"],"title":"Xperia Zが故障したので交換したのでメモ"},{"contents":"Morphlinesについてちょっとだけ、さらに調べました。\n誤解 Solr勉強会でなんとなく私の認識を話しましたが、ちょっと誤解してたみたいです。スミマセン。\n誤解:Morphlineというプラットフォーム/ミドルウェアがありそうなイメージ まぁ、書いてあるのでちゃんと読めって話ですが、Morphlineはあくまでライブラリだということでした。 私はなんとなくManifoldCFのようなミドルウェアorプラットフォームが存在して、 そこにFlumeのSinkとかMapReduceによるIndexerが動作するのかと思ってました。\nまぁ、これが間違いでした。正解のイメージはこっちですね。\n各プラットフォーム(FlumeとかHadoopとか)に組み込んむライブラリで、 それぞれ組み込んだ先でMorphlineの設定を記述することで、パイプライン処理ができるっぽいです。\nFlumeについては、MorphlineSolrSinkというクラスでMorphlineの設定ファイルを読み込み、いろいろ処理出来ます。\nMap/ReduceだとCloudera Searchに含まれてるMapReduceIndexerToolがMorphlineの設定を読み込んでコマンド実行してくれるみたいです。 MapReduceIndexerToolはまだちゃんと読んでないのですが、MapperとしてMorphlineのコマンドが実行されるのかなぁ?という感じです。 (結構入り組んでるので、ちゃんと読まないとわからない。。。)\nということで、Morphlineというプラットフォームがあって、一元的にFlumeやMap/Reduceに対するコマンドをパイプライン化するという話でありませんでした。\n※ちなみに、上の画像ですが、愛用しているNUBoardを使って書いてます。 考えをまとめるのにすごく役立つ一品です。持ち運び可能なノート型ホワイトボードです。\n疑問点 ただ、読んでてまだ不明な点があります。まぁ、ぼちぼち調べるかなぁと。。。\nSolrのschemaはどーなってんの? MorphlineにSolrへロードするコマンド(loadSolr)があるけど、FlumeのMorphlineSolrSinkってのもSolrに書き込みそうだけど? Map/ReduceでSolrに書き込むもMorphlineのコマンドとの違いは?(前にソースを見たときはSOLR-1301がベースになっていて、SolrOutputFormatってクラスがEmbeddedSolrServer起動してインデクシングしてた) GoLiveってなんだろ?(MapReduceIndexerToolに入ってて、M/Rでインデックス作ったあとにSolrのクラスタに配布+マージするやつっぽい) どんなコマンドがあるの?(Cloudera Morphlines Ref Guide) 以下は、参考資料と参考資料にあるSlideshareの資料を一部訳したものになります。\n参考資料 Using Morphlines for On-the-Fly ETL(slideshare) cloudera/cdk/cdk-morphlines(github) メモ 現在のコマンドライブラリ(スライド 18-19ページ) Solrへのインテグレートとロード フレキシブルなログファイル解析 1行、複数行、CSVファイル 正規表現ベースのパターンマッチと展開 Avro、JSON、XML、HTMLのインテグレーション Hadoop シーケンスファイルのインテグレーション SolrCellとApache Tikaパーサすべてのインテグレーション Tikaを利用したバイナリデータからMIMEタイプの自動判別 動的Javaコードのスクリプティングサポート フィールドの割り当て処理、比較処理 リストやセット書式のフィールド処理 if-then-else条件分岐 簡易ルールエンジン(tryRules) 文字列とタイムスタンプの変換 slf4jロギング Yammerメトリックとカウンター ネストされたファイルフォーマットコンテナの解凍 などなど プラグインコマンド(スライド 20ページ) 簡単に新しいI/Oや変換コマンドが追加可能 サードパーティや既存機能のインテグレード CommandインタフェースかAbstractCommandのサブクラスを実装 Javaクラスパスに新規作成したものを追加 登録処理などは必要ない 新しいプラグインコマンドとして考えられるもの(22ページ) RDBやKVSやローカルファイルなどの外部データソースをレコードにjoin DNS名前解決とか短縮URLの展開とか ソーシャル・ネットワークからリンクされたメタデータのフェッチ(??) レコードの感情分析とアノテーション? 31ページの図がわかりやすいかも\n以上。\n","date":1375265520,"dir":"post/2013/","id":"b875f24d3d444fdda82b6bbfb75a4c92","lang":"ja","lastmod":1375265520,"permalink":"https://blog.johtani.info/blog/2013/07/31/introduction-morphlines/","publishdate":"2013-07-31T19:12:00+09:00","summary":"Morphlinesについてちょっとだけ、さらに調べました。 誤解 Solr勉強会でなんとなく私の認識を話しましたが、ちょっと誤解してたみたいで","tags":["Cloudera Search","Morphlines","Solr"],"title":"Morphlines入門?"},{"contents":"不定期開催ですが第11回Solr勉強会を主催しました。\n今回も大入り90人くらい?の参加者の皆さんがいらっしゃいました。ありがたいことです!(20時時点で最終的に補欠17人でした。)\nとりあえず、第一報です。このあと懇親会なので。\nということで、帰りの電車でいくつか感想を(忘れちゃうから)。\n小林さんの苦労話は細かいですが、結構はまりがちな点を共有していただいたので良かったかなぁと。 Solrのexampleの設定とか、ManifoldCFとかちょっとずつ罠があったりするので、あるあるネタはありがたいと思いますw\nCloudera Searchについては、安定の嶋内さんの喋りに圧巻でした。検索だけの視点とは異なる観点についての 話は私には足りないしてんだったりするので参考になります。 なんか、気づいたらMorphlineやスキーマ周りを調べてブログ書くことになっちゃったけど。。。 一つ質問しそこねたのがあって、Cloudera社は基本的に公開したOSSについてのトレーニングも立ち上げているイメージです。Cloudera Searchについてもトレーニングが立ち上がるのかなぁと密かに期待をしてみたり(予算の関係上参加できるかは不明ですが。。。)\n牧野さんの話は画像系について、私は詳しくないので、また関口さんのalikeと比較とかしてもらえると面白いかなぁと。とりあえず、青いロボットがちゃんと検索できるようになるといいですねww\n秀野さんの空間検索は緯度経度以外のPOLYGONなどを利用した検索で、実は私も知らない機能でしたw\nなとなくは知ってたんですが、そこまでちゃんと検索できるとは!地図以外にも活用できるような気がします(想像つかないんだけど。。。)\n最後は私の発表で、簡単な資料ですみませんでした。しかも発表よりも宣伝が。。。(ブログの宣伝だったりとか。。。) 最後に宣伝した「「ビッグデータ活用を支えるOSS」特集への論文投稿のご案内」もご検討ください!\n懇親会も楽しかったです。また思いついたら開催しますー\n最後に、今回の発表者の皆様、会場提供していただいたVOYAGE GROUPの皆様ありがとうございました!\n以下はいつものメモです。\nManifoldCFのとSolrの組み合わせ(仮)株式会社 ロンウイット 大須賀さん 残念ながら、発熱のため発表は次回に持ち越しに。\n##社内ファイル及びWEBコンテンツの検索システム構築時に苦労したこと ソフトバンクBB㈱ 小林さん\nManifoldCF+Solrを使って社内ファイルの検索システム構築 約1000万ドキュメント さまざまなDCにドキュメントがある クロールジョブのハング。。。 ログをDEBUGにしたら。。。ログファイル150GB。。。 一定時間ごとにAgentをリスタートするバッチを。。。(力技) MCFエラーによるジョブの停止 CONNECTORS-590 エラーが発生して止まったジョブを起動するバッチをcronで。。。 自作リアルタイムインデクシングの問題 MCF使わないでSlaveにインデックス openSearcher=falseだとautoCommitが実行されてもSearcherを再起動しないので検索にでてこない リプリケーションのNW負荷 別DCからのレプリケーションが複数が一度に実施される→ネットワーク負荷が。。。 cronで別々にレプリすることでNW負荷を分散できてるかな。。。 Cloudera Search 入門(仮) Cloudera 株式会社 嶋内さん マサカリ画像がw SolrのコミッターMark Millerさんもジョインしてる ClouderaとHadoop入門とか。 いろいろあるよ、エコシステム 4つの分類。 データの取り込み データの保存 データの活用 Search 検索エンジンなら数十億人が使い方を知ってる(Clouderaのチャールズ・ゼドルースキ) Cloudera Search Hadoopのためのインタラクティブな検索\nCDHとSolrの統合\nOSS!\n利点とか。\nデータ解析にも使えるよね、検索 非構造化データの検索にもいいよね 単一プラットフォームによるコスパ Cloudera Searchの事例 バイオテクノロジー企業で画像検索とか 医療系企業でいろんなログイベントの管理とか Cloudera Searchのアーキテクチャ Flumeでストリーミングで登録 HBaseデータの登録 M/Rでバッチ登録 HueのWebインタフェース Morphlines、HBaseはLinyプロジェクトのもの\nSolr使うならCDH!!\nQA Q:デモで使われたTwitterの検索のデータ料とかは?\nA:デモ環境ですので小さい。\nQ:スキーマってどうするの?\nA:スキーマは。。。私が書こうかなぁ、ブログ。。。\nコンピュータビジョン 株式会社 Curious Vehicle 牧野さん 色々やってます コンピュータビジョンの説明(某ネコ型ロボットのいろんな画像がw) 画像検索の流れ 特徴情報の抽出 特徴情報のクラスタリングによるword化 Solrによる画像情報の検索 1. 特徴情報の抽出 SIFT特徴点解析 グレースケールしてからSIFT 注意!SIFTは商用ライセンスが必要です 2. 特徴情報のクラスタリングによるword化 K-meansでクラスタリング クラスタ情報をヒストグラム化してSolrへ 3. Solrによる画像情報の検索 物体認識ベンチマークセット(ケンタッキー大)を使って。 やっぱり良し悪しある。データセットに特化したチューニングしてます。 つぎのステップ 文字認識とか顔認識 つぎはドラえもんじゃねぇ、検索とかも。。。 ガウシアンによる画像ぼかしの例 QA マイク回しててメモ取れず。。。\n国土交通省のデータをSolrで検索 株式会社ネクスト 秀野さん スライドはこちら\n評価の関係で。。。 Spatial検索の話 デモの想定機能 地図上の小学校を起点に物件検索 地図上をクリックしたところを中心に検索 デモ環境 Solr4.3.0、PostGIS 2.0.3、東京都のデータ 事前知識 ジオメトリーデータ(点、線、面がある) WKB/WKT、Intersects(しらなかった。こんなのもあるのか) 環境 EC2上にPostGIS+Solrで構築 WKT形式でDIHでインポートできるらしい。 Solr+S3をJSでGoogleMapへ Solr 4.4新機能をちょっと紹介 @johtani 紹介というよりも宣伝。。。\n","date":1375107300,"dir":"post/2013/","id":"59d1b7206e7664e76672d3de4dc9a8ed","lang":"ja","lastmod":1375107300,"permalink":"https://blog.johtani.info/blog/2013/07/29/study-of-solr/","publishdate":"2013-07-29T23:15:00+09:00","summary":"不定期開催ですが第11回Solr勉強会を主催しました。 今回も大入り90人くらい?の参加者の皆さんがいらっしゃいました。ありがたいことです!(","tags":["Solr","Cloudera Search","ManifoldCF"],"title":"第11回Solr勉強会を主催しました。#SolrJP"},{"contents":"Hadoopとか離れちゃってるし、Hive触ったこと無いにもかかわらず参加しました!\n(たまたま近くにいるからって理由なのは内緒で)\n玉川さんの四方山話を聞くのが主目的で参加しました。(ちょっと翻訳が気になってるので)\nイベントページはこちら\n刊行記念イベントにも関わらず、想像以上の人の入りでびっくりしました。Hadoop、Hive界隈はまだまだ人気なんだなぁと。\nプレゼントじゃんけん大会もあったのですが、そうそうに負けてしまったのが悔やまれます。。。\nTeam Geek欲しかったなぁ。もちろん、懇親会まで参加しました。\n以下、いつものメモです。\nHiveの正しい使い方(Cloudera 嶋内さん) 残念ながら、マサカリは持ってなかったです。\nスライドの各所に本の章番号が書いてあるのがうれしい。 Hiveロゴが回ってたのでスライドの時に集中できなかったw Impalaの話も出てきた。 速いけど、色々足りない。Hiveの置き換えじゃないよと。 HiveとImpalaのおいしいとこ取り(セラン 須田さん) スライド:http://www.slideshare.net/sudabon/20130724-oreilly-org\nオンプレだとCDH便利だよと教えてもらう いくつかSlideshareにImpalaの性能評価の資料を上げてある(必要になったら検索で。。。) リリースされたその日に性能評価やってレポート書くとかすごすぎ! 翻訳の四方山話(玉川さん) 翻訳=写経です 締め切り駆動勉強法w 4page/day 自分から電突してオライリーさんに翻訳させてくださいと。 他の方の本が読めない(チェックしちゃうのでw) 動機があるから読めるってのはあるだろうなぁ。 選び方:わくわくするもの、仕事に活きるもの 今年もあと2冊やる予定(Hadoop Operations、Vagrantを翻訳中) 来年の候補(Chefとか) 高可用性HDFSのご紹介(Cloudera 小林さん) スライドにどの版で書いてあったかがわかりやすく書いてある。 3段階の開発フェーズを経てる QJMのお話 Cloudera UniversityとHadoop認定試験(Cloudera 川崎さん) Clouderaデータアナリスト向けトレーニング(3日間、10月日本語で開催予定) Hive、Pig、Impalaなど Data Science入門コースも準備中 出版記念! 8月管理者向け先着20 or 30名にHadoop第3版贈呈予定 先着20名にプログラミングHive贈呈予定 ","date":1374685860,"dir":"post/2013/","id":"1b9c5ae60ec46be64a1877f0c6920edc","lang":"ja","lastmod":1374685860,"permalink":"https://blog.johtani.info/blog/2013/07/25/hadoop-hive-publication-party/","publishdate":"2013-07-25T02:11:00+09:00","summary":"Hadoopとか離れちゃってるし、Hive触ったこと無いにもかかわらず参加しました! (たまたま近くにいるからって理由なのは内緒で) 玉川さんの","tags":["Hadoop","Hive","Cloudera","オライリー"],"title":"『プログラミング Hive』 『Hadoop 第3版』刊行記念セミナーに参加しました! #oreilly0724"},{"contents":"Yokozunaの気になる点というか、自分だったらこのへん調べるだろうなって観点を上げてみます。 別に調べるわけじゃないので、完全に自己満足なメモですけど。\nちなみに、分散システムとかRiakの仕組みは詳しくないので、ズレてる点がいっぱいあるかも。\nというか、分散システムでテストというか、検討する点とかってまとまってる資料とかあるのかなぁ?\nスキーマ変更時の挙動 フィールド型変更とか、フィールド追加とか 既存RiakクラスタにYokozunaの機能を追加する方法と制限 タイムラグとかも Riak+Yokozunaクラスタに対してノード追加時に発生するオーバーヘッド(ネットワークとかディスクIOとか) 性能検証のためのシナリオ(どっちが先に悲鳴をあげるかとか) Riakメインで、Yokozunaはおまけ程度に検索するというシナリオ Yokozunaメインで使うシナリオ 更新が多い場合のシナリオ Riakのみ、Riak+Yokozunaの各種統計情報(CPU、メモリ、ディスクサイズ、ネットワークIO) 運用系(監視とか)の手法とか機能?とか バージョンアップなどの対応方法 Solrがコケた時とかの対処 とりあえず、こんな感じかなぁ。\n","date":1373474580,"dir":"post/2013/","id":"50557b455cba1a3ce9b4555fc3fd5433","lang":"ja","lastmod":1373474580,"permalink":"https://blog.johtani.info/blog/2013/07/11/yokozuna-check-point/","publishdate":"2013-07-11T01:43:00+09:00","summary":"Yokozunaの気になる点というか、自分だったらこのへん調べるだろうなって観点を上げてみます。 別に調べるわけじゃないので、完全に自己満足な","tags":["Riak","Solr","Yokozuna"],"title":"Yokozunaの気になる点というかなんというか"},{"contents":"先日、Bashoさんにおじゃましたのもあり、Riak Meetup Tokyo #2に参加しました。\nYokozunaの話も聞けるということで。 懇親会も参加しました。Vさん&リピさんと話し込んじゃってあんまり他の人と話せなかったけど。。。\n以下はいつものメモです。\nFreakOut 久森さん 「Riak環境をプロダクションで構築&運用してみた(仮)」 FreakOutとRTB ディスプレイ広告の新しい配信の枠の話 この人には何出すの?いくらで?みたいな感じ 純広告:表示保証、期間保証など RTB:1回の広告表示ごとに買い付け DSP(デマンド・サイト・プラットフォーム) 広告表示は大体0.1秒で表示しないといけない。この間に色々やってる。 50ms or die.で戦ってます。 RTBはCPUバウンド 多コアを安く並べたい Tokyoなんとかとか使ってた。 スケーラビリティがキツイ(クライアント側でアルゴリズム分散してる) データ解析もしたいけど、検索ができない RTBに適したRiakがうまくハマるのではと。 構成とかとか アプリはPerlなので、PerlでRiakクライアントが必要。Memcached互換とかあると嬉しい。 ProtobufサポートもPurePerlしかなかった。 ないなら、作ろうと。githubに上がってます。このへんかな? 監視はcloudforecastとかでやってる。 課題 Redirectがつらい(haproxy?がつらい?) Setが詰まるとつらい(ケースがまだわからない) 対策1 memcached+Riak 対応2(案) hashからpartitionに直接取りに行くとか まとめ 素のままRiakはちょっとつらい QA 聞き取れたやつだけ\nQ:1台いくら位ですか? A:10万から11万くらい Q:どのくらいの性能ですか? A:同時1000くらいをさばいてる? Q:50ms以下を出すのに、ネットワーク周りで近さとかを考えることありますか? A:国内だと10msあればなんとかなる。それよりもアプリ側のチューニングのほうがまだ重要 Q:Cassandraとか候補に挙がらなかったんですか? A:苦しんでる人が知人にいるので。。。あと、用途的に違うので。 Q:バックエンドとしてはなにを? A:bitcaskにしてる Q:サーバ構成、ネットワーク構成がどうなってる? A:。。。 Q:Redirectとは?RiakがやってるRedirect? A:はい。 Q:他に候補にあがったのは? A:商用のaerospike(これかな?)がスケールできそうだったけど、クライアントがいまいち。。。 感想 広告業界のことをよくわかってないので、微妙にピンときてなかったりもするのですが、以下に素早く返すかって観点でどこに注力して、問題点を潰していくのかってのは面白そうだなぁと。 リクエスト処理の性能がクリアできたらつぎはスケールの観点(ノード追加時の挙動とか)で検証していくんだろうなと。次回の話も聞いてみたい感じです。\nIIJ 曽我部さん、田中さん 「Yokozuna 日本語検索性能を評価しました」 Yokozunaって? Riak+Solrでいいとこ取り データの登録とかはRiakのAPIで。 SolrのAPIが使える。 YokozunaがSolrの分散検索の部分を隠してくれる。 Yokozunaのインストールとか。 SolrのAPIっぽい形で検索できるし、戻りもSolrのXMLっぽいのが出てくるよ。 Wikipediaデータってstoreの性能とか。 Riakのノード32台。(Xeon、メモリ24GB、HDD。。。) yz_extractor:Riakのコンテンツタイプを見てSolrにデータを入れる処理が書いてある。 自分でschema.xmlを書いてYokozunaに指定することもできる。 スキーマの変更とか登録とか。 すでに指定済みスキーマを変更した場合の挙動ってどうなるの? デモではSolrからid取って、Riakからその他のデータを取り出していた。 Rubyでの性能評価 ベンチマークプログラム側の問題が先に影響が出てしまった。 QA Q:Riak単体とYokozunaつかった時でディスク容量がどのくらい増えた? A:ちゃんと調べてないが、10%くらい増えた気がする。 Q:Solr側の設定でstored=trueだけど、falseにしてもいいんじゃないの? A:デモはfalseにしてます。 Q:スキーマってあとから変更できるんですかね? A:まだ良くわかってないです。 Q:ノードの追加、削除時の挙動とかも気になります。 感想 今回はStore性能に関してでしたが、今後は検索性能やシナリオによる性能(KVSの処理メインで、時々全文検索とか、全文検索の処理も結構あるパターンとか)の測定とか、耐障害性とかの観点で調査を進めてもらってSolr勉強会で話をしてもらえると面白そうだなぁと勝手に思ってみたり。 Solr勉強会へのコンタクトお待ちしてます!w\n","date":1373450220,"dir":"post/2013/","id":"146e8ca40c0d37f36eecea822028dd9e","lang":"ja","lastmod":1373450220,"permalink":"https://blog.johtani.info/blog/2013/07/10/riak-meetup-tokyo-no2/","publishdate":"2013-07-10T18:57:00+09:00","summary":"先日、Bashoさんにおじゃましたのもあり、Riak Meetup Tokyo #2に参加しました。 Yokozunaの話も聞けるということで。 懇親会も参加しました。","tags":["Riak","Yokozuna","Solr"],"title":"Riak Meetup Tokyo #2に参加しました。#riakjp"},{"contents":"Solr 4.4に取り込まれる予定のチケットで、気になるものを見つけたのでいつものごとく調べてみました。\n元となるチケットはこちら。SOLR-4897。\nスキーマレス? Solrはschema.xmlにデータの定義(フィールドタイプやフィールドなど)を記述して、データを登録する全文検索システムです。 これまでのSolrではこの設定ファイルを元にデータを登録するフィールド名を決定しており、 変更を行う場合はSolrのコアを再起動するなどの手順が必要でした。(※ダイナミックフィールドはすこし特殊)\nそれだと、Solrを管理するのがめんどくさいですね?という感じで現れたのがSchemaREST APIです。(たぶん。)\nSchema REST API Solr 4.2から導入されたSolrのスキーマに関する情報を提供するためのREST APIです。 4.2で導入されたのはあくまでもschema.xmlの情報を取得するためのAPIでした。 たとえば、Fieldの一覧を取得するとか。\n4.4から、フィールドの追加(変更、削除はできない)ができるようになりました。あくまでも、フィールドの追加で、フィールドタイプなどの追加はまだできません。(できるようになるのかもわからないですが。) フィールドの追加方法などはWikiに記載がありました。\nということで、簡単に試してみることに。\n起動方法 exampleディレクトリの下にexample-schemalessというディレクトリが新設されています。 ここに、スキーマレスモード用の設定がされているファイルが入っているので、こちらを利用します。\ncd $SOLR/example java -Dsolr.solr.home=example-schemaless/solr -jar start.jar ログにいくつかWARNが出ますが、影響の内パス設定ミスなので無視してOKです。\n最初に定義されているフィールドは「id」と「_version_」のみになります。(Schema Browserなどで確認できます。あ、REST APIでもいいですね。http://localhost:8983/solr/schema/fields)\nスキーマの更新 さて、フィールドを追加してみます。 PUTを利用すると1フィールドの追加が可能です。 「fugatext」というフィールド名でフィールドを追加しています。今のところJSONのみ対応みたいです。\n$ curl -X PUT http://localhost:8983/solr/schema/fields/fugatext -H \u0026#39;Content-Type: application/json\u0026#39; -d \u0026#39;{\u0026#34;type\u0026#34;:\u0026#34;text_ja\u0026#34;,\u0026#34;stored\u0026#34;:false,\u0026#34;multiValued\u0026#34;:true}\u0026#39; { \u0026#34;responseHeader\u0026#34;:{ \u0026#34;status\u0026#34;:0, \u0026#34;QTime\u0026#34;:18}} 追加できたかどうかもREST APIで取得してみます。\n$ curl http://localhost:8983/solr/schema/fields { \u0026#34;responseHeader\u0026#34;:{ \u0026#34;status\u0026#34;:0, \u0026#34;QTime\u0026#34;:0}, \u0026#34;fields\u0026#34;:[{ \u0026#34;name\u0026#34;:\u0026#34;_version_\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;long\u0026#34;, \u0026#34;indexed\u0026#34;:true, \u0026#34;stored\u0026#34;:true}, { \u0026#34;name\u0026#34;:\u0026#34;fugatext\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;text_ja\u0026#34;, \u0026#34;multiValued\u0026#34;:true, \u0026#34;stored\u0026#34;:false}, { \u0026#34;name\u0026#34;:\u0026#34;id\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;string\u0026#34;, \u0026#34;multiValued\u0026#34;:false, \u0026#34;indexed\u0026#34;:true, \u0026#34;required\u0026#34;:true, \u0026#34;stored\u0026#34;:true, \u0026#34;uniqueKey\u0026#34;:true}]} 追加できました。 ちなみに、同じフィールド名を追加しようとするとエラーが帰ってきます。\n$ curl -X PUT http://localhost:8983/solr/schema/fields/fugatext -H \u0026#39;Content-Type: application/json\u0026#39; -d \u0026#39;{\u0026#34;type\u0026#34;:\u0026#34;text_ja\u0026#34;,\u0026#34;stored\u0026#34;:false,\u0026#34;multiValued\u0026#34;:true}\u0026#39; { \u0026#34;responseHeader\u0026#34;:{ \u0026#34;status\u0026#34;:400, \u0026#34;QTime\u0026#34;:1}, \u0026#34;error\u0026#34;:{ \u0026#34;msg\u0026#34;:\u0026#34;Field \u0026#39;fugatext\u0026#39; already exists.\u0026#34;, \u0026#34;code\u0026#34;:400}} 設定の違い example-schemalessのsolrconfig.xmlは以下の設定が通常のexampleとは異なるようです。\nschemaFactoryの設定 schemaをAPIから変更可能にする設定です。これまでの変更しない設定の場合はClassicIndexSchemaFactoryを指定します。\n... \u0026lt;schemaFactory class=\u0026#34;ManagedIndexSchemaFactory\u0026#34;\u0026gt; \u0026lt;bool name=\u0026#34;mutable\u0026#34;\u0026gt;true\u0026lt;/bool\u0026gt; \u0026lt;str name=\u0026#34;managedSchemaResourceName\u0026#34;\u0026gt;managed-schema\u0026lt;/str\u0026gt; \u0026lt;/schemaFactory\u0026gt; ... update.chainの設定 更新処理(update関連のリクエストハンドラ「/update」とか)には次のような設定が追加されていました。(1006行目あたり)\n\u0026lt;requestHandler name=\u0026#34;/update\u0026#34; class=\u0026#34;solr.UpdateRequestHandler\u0026#34;\u0026gt; \u0026lt;!-- See below for information on defining updateRequestProcessorChains that can be used by name on each Update Request --\u0026gt; \u0026lt;lst name=\u0026#34;defaults\u0026#34;\u0026gt; \u0026lt;str name=\u0026#34;update.chain\u0026#34;\u0026gt;add-unknown-fields-to-the-schema\u0026lt;/str\u0026gt; \u0026lt;/lst\u0026gt; \u0026lt;/requestHandler\u0026gt; 「add-unknown-fields-to-the-schema」というupdate.chainが指定されています。このchainの定義自体は1669行目くらいに存在します。 (長い。。。)\n\u0026lt;!-- Add unknown fields to the schema An example field type guessing update processor that will attempt to parse string-typed field values as Booleans, Longs, Doubles, or Dates, and then add schema fields with the guessed field types. This requires that the schema is both managed and mutable, by declaring schemaFactory as ManagedIndexSchemaFactory, with mutable specified as true. See http://wiki.apache.org/solr/GuessingFieldTypes --\u0026gt; \u0026lt;updateRequestProcessorChain name=\u0026#34;add-unknown-fields-to-the-schema\u0026#34;\u0026gt; \u0026lt;processor class=\u0026#34;solr.RemoveBlankFieldUpdateProcessorFactory\u0026#34;/\u0026gt; \u0026lt;processor class=\u0026#34;solr.ParseBooleanFieldUpdateProcessorFactory\u0026#34;/\u0026gt; \u0026lt;processor class=\u0026#34;solr.ParseLongFieldUpdateProcessorFactory\u0026#34;/\u0026gt; \u0026lt;processor class=\u0026#34;solr.ParseDoubleFieldUpdateProcessorFactory\u0026#34;/\u0026gt; \u0026lt;processor class=\u0026#34;solr.ParseDateFieldUpdateProcessorFactory\u0026#34;\u0026gt; \u0026lt;arr name=\u0026#34;format\u0026#34;\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd\u0026#39;T\u0026#39;HH:mm:ss.SSSZ\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd\u0026#39;T\u0026#39;HH:mm:ss,SSSZ\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd\u0026#39;T\u0026#39;HH:mm:ss.SSS\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd\u0026#39;T\u0026#39;HH:mm:ss,SSS\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd\u0026#39;T\u0026#39;HH:mm:ssZ\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd\u0026#39;T\u0026#39;HH:mm:ss\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd\u0026#39;T\u0026#39;HH:mmZ\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd\u0026#39;T\u0026#39;HH:mm\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd HH:mm:ss.SSSZ\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd HH:mm:ss,SSSZ\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd HH:mm:ss.SSS\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd HH:mm:ss,SSS\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd HH:mm:ssZ\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd HH:mm:ss\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd HH:mmZ\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd HH:mm\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd\u0026lt;/str\u0026gt; \u0026lt;/arr\u0026gt; \u0026lt;/processor\u0026gt; \u0026lt;processor class=\u0026#34;solr.AddSchemaFieldsUpdateProcessorFactory\u0026#34;\u0026gt; \u0026lt;str name=\u0026#34;defaultFieldType\u0026#34;\u0026gt;text_general\u0026lt;/str\u0026gt; \u0026lt;lst name=\u0026#34;typeMapping\u0026#34;\u0026gt; \u0026lt;str name=\u0026#34;valueClass\u0026#34;\u0026gt;java.lang.Boolean\u0026lt;/str\u0026gt; \u0026lt;str name=\u0026#34;fieldType\u0026#34;\u0026gt;booleans\u0026lt;/str\u0026gt; \u0026lt;/lst\u0026gt; \u0026lt;lst name=\u0026#34;typeMapping\u0026#34;\u0026gt; \u0026lt;str name=\u0026#34;valueClass\u0026#34;\u0026gt;java.util.Date\u0026lt;/str\u0026gt; \u0026lt;str name=\u0026#34;fieldType\u0026#34;\u0026gt;tdates\u0026lt;/str\u0026gt; \u0026lt;/lst\u0026gt; \u0026lt;lst name=\u0026#34;typeMapping\u0026#34;\u0026gt; \u0026lt;str name=\u0026#34;valueClass\u0026#34;\u0026gt;java.lang.Long\u0026lt;/str\u0026gt; \u0026lt;str name=\u0026#34;valueClass\u0026#34;\u0026gt;java.lang.Integer\u0026lt;/str\u0026gt; \u0026lt;str name=\u0026#34;fieldType\u0026#34;\u0026gt;tlongs\u0026lt;/str\u0026gt; \u0026lt;/lst\u0026gt; \u0026lt;lst name=\u0026#34;typeMapping\u0026#34;\u0026gt; \u0026lt;str name=\u0026#34;valueClass\u0026#34;\u0026gt;java.lang.Number\u0026lt;/str\u0026gt; \u0026lt;str name=\u0026#34;fieldType\u0026#34;\u0026gt;tdoubles\u0026lt;/str\u0026gt; \u0026lt;/lst\u0026gt; \u0026lt;/processor\u0026gt; \u0026lt;processor class=\u0026#34;solr.LogUpdateProcessorFactory\u0026#34;/\u0026gt; \u0026lt;processor class=\u0026#34;solr.RunUpdateProcessorFactory\u0026#34;/\u0026gt; \u0026lt;/updateRequestProcessorChain\u0026gt; 使ってるUpdateProcessorはこんな感じみたいです。最後の2つはこれ用じゃないので省略。\nプロセッサ名説明 RemoveBlankFieldUpdateProcessorFactory値がないフィールドは除去 ParseBooleanFieldUpdateProcessorFactoryスキーマに定義されていないフィールドで、値がBooleanとしてパースできたら、Boolean型とする。 ParseLongFieldUpdateProcessorFactoryスキーマに定義されていないフィールドで、値がLongとしてパースできたら、Long型とする。 ParseDoubleFieldUpdateProcessorFactoryスキーマに定義されていないフィールドで、値がDoubleとしてパースできたら、Double型とする。 ParseDateFieldUpdateProcessorFactoryスキーマに定義されていないフィールドで、値がDateとしてパースできたら、Date型とする。(パースの形式がformatで列挙されてる) AddSchemaFieldsUpdateProcessorFactory入力されたドキュメントの中でスキーマに定義されていないフィールド(静的、動的両方)を見つけた時に、フィールドの値の型を元にフィールド型をマッピングする。 とここまで見てきたところで、スキーマレスという名前の意図がちょっとわかったかも。\n定義されてないフィールドを持ったデータを登録 起動時には定義されてないフィールドをもったデータを登録してみます。 boolean型で試してみることに。以下のデータを管理画面のデータ登録画面から登録します。(http://localhost:8983/solr/#/collection1/documents) (タイトルでbooleanってわかりにくいですが)\n{\u0026#34;id\u0026#34;:\u0026#34;change.me\u0026#34;,\u0026#34;title\u0026#34;:true, \u0026#34;price\u0026#34;:1.25, \u0026#34;fuga\u0026#34;:\u0026#34;100,200\u0026#34;} エラーは出ません。で、またフィールド一覧を取得すると。\n$ curl http://localhost:8983/solr/schema/fields { \u0026#34;responseHeader\u0026#34;:{ \u0026#34;status\u0026#34;:0, \u0026#34;QTime\u0026#34;:1}, \u0026#34;fields\u0026#34;:[{ \u0026#34;name\u0026#34;:\u0026#34;_version_\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;long\u0026#34;, \u0026#34;indexed\u0026#34;:true, \u0026#34;stored\u0026#34;:true}, { \u0026#34;name\u0026#34;:\u0026#34;fuga\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;tlongs\u0026#34;}, { \u0026#34;name\u0026#34;:\u0026#34;fugatext\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;text_ja\u0026#34;, \u0026#34;multiValued\u0026#34;:true, \u0026#34;stored\u0026#34;:false}, { \u0026#34;name\u0026#34;:\u0026#34;id\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;string\u0026#34;, \u0026#34;multiValued\u0026#34;:false, \u0026#34;indexed\u0026#34;:true, \u0026#34;required\u0026#34;:true, \u0026#34;stored\u0026#34;:true, \u0026#34;uniqueKey\u0026#34;:true}, { \u0026#34;name\u0026#34;:\u0026#34;price\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;tdoubles\u0026#34;}, { \u0026#34;name\u0026#34;:\u0026#34;title\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;booleans\u0026#34;}]} おー、最後にtitleが追加されてます。他にもfugaやpriceも。(日付は手を抜きました。。。)\n感想 詳細までは追いかけてないですが、こんなかんじです。 フィールド追加が可能になるのはいいんじゃないでしょうか。SolrCloudの機能との関連もあるのかもしれません。ZooKeeperへの出力も実装されてそうなので。\nただ、機械的に出力されたschema.xml(exampleだとmanaged-schemaというファイル)には_「DO NOT EDIT」_との記述があるので、修正するとなにかおきてしまうかもしれないですねぇ。 現時点では、フィールドタイプの変更やフィールドの更新、削除に関してはSolrCoreの再起動などの手順が必要です。 あと、変なデータ(タイプミスとか)が登録されたりしないかってのは気になりますね。\n※ちなみに、別の人が気づいたんですが、ちょっとバグが有ったみたいで、代わりにチケットつくったらキリ番(SOLR-5000) ゲットしましたw\n","date":1372867920,"dir":"post/2013/","id":"a98d42be181c01b8077e060b1b5080ec","lang":"ja","lastmod":1372867920,"permalink":"https://blog.johtani.info/blog/2013/07/04/schemaless-example/","publishdate":"2013-07-04T01:12:00+09:00","summary":"Solr 4.4に取り込まれる予定のチケットで、気になるものを見つけたのでいつものごとく調べてみました。 元となるチケットはこちら。SOLR-4897","tags":["Solr"],"title":"スキーマレスモード?(SOLR-4897)を調べて見ました。"},{"contents":"SolrのチケットをML経由で眺めてるんですが、便利そうなチケットが流れてきたのでブログを書いてみみようかと。 元になってるチケットはこちらです。昨日だか、今朝にtrunkとbranch_4xにコミットされたみたいです。試してみたい方は、branch_4xかtrunkをチェックアウトすると触ることができます。\nデータ登録用の画面(JSON) branch_4xをチェックアウトしてexampleを起動し、Solrにアクセスします。\n管理画面に「Dcuments」という項目が追加されてます。開くとこんなかんじです。\nなんと、デフォルトはJSONになってます。これも時代の流れでしょうかw\nSolrでは、これまで設定ファイルやデータ登録もXMLがメインになっていました。(Apache Solr入門もXMLを基本に書いてます。このころはまだデフォルトでは対応してなかったので)\n登録するデータをテキストエリアに記述して、「Submit Document」をクリックすればデータは登録されます。基本的には単件登録の画面でしょうか。 (登録されたデータを確認するには「Query」画面を利用すればいいです。) また、JSONのデータ形式はSolrのWikiを参照してください。\nCSVやXMLも この管理画面ではJSON以外の形式でもデータの登録が可能です。 「Document Type」の項目をクリックすると以下のように選択肢があられます。\nCSV、XMLについては、先ほどのJSONの画面の用に、テキストエリアが表示されます。 テキストエリアにCSV(データの形式はこちら)やXML(データの形式はこちら)を入力してボタンを押せば登録できます。\nSolr Command形式も(JOSNかXML) Solr Command というのはXMLやJSONで登録、コミット、削除などを実行するための画面になります。 JSONのコマンドはこちら、XMLのコマンドはこちらをご覧ください。\nあと、便利なのがファイルアップロードです。 こんなかんじで、ファイルを選んでSubmitすればデータが登録出来ます。\nファイルのサイズが大きいとちょっと時間がかかりますが、コマンドを打つより簡単かもしれません。 post.jarツールと違って、デフォルトでコミットをしてくれるわけではないので、「Extracting Req. Handler Params」に「commit=true」をつけないと、データが登録されてない?と思ってしまうかもしれませんが。\n組立もできるみたい(Document Builder) 最後に紹介するのが「Document Builder」というタイプです。\nもっと簡易にデータを記述できるようにということで用意されているようです。 フィールドの情報はSolrに接続して利用できるフィールド?(ダイナミックはないのかな?)が表示されます。\n追記していくとこんなかんじになります。\n日本語のデータもちゃんと登録できました。 ただ、まだ、開発中なんでしょうがないかもしれませんが、以下の様な制約があるようです。\nmultiValuedなフィールドに値を追加できない(上書きされる) 改行が入ったデータをテキストエリアにいれると「Add Field」を押しても反応しない ダイナミックフィールドは自分で書きましょう ただ、これまでXMLでファイルを作ってコマンドで登録したり、curlコマンドでJSON書いたりして登録していたよりはお手軽にさわれるようになるかと思います。つぎの4x系のバージョンが出たときはこちらからデータを登録してみてください。\n","date":1372318080,"dir":"post/2013/","id":"ecf3ac80454654d990d9c07d33d35d1c","lang":"ja","lastmod":1372318080,"permalink":"https://blog.johtani.info/blog/2013/06/27/upload-docs-solr-admin/","publishdate":"2013-06-27T16:28:00+09:00","summary":"SolrのチケットをML経由で眺めてるんですが、便利そうなチケットが流れてきたのでブログを書いてみみようかと。 元になってるチケットはこちらで","tags":["Solr"],"title":"Solrの管理画面でデータ登録"},{"contents":"前回は3番煎じぐらいでしたが、今回は初記事かな?(だといいな)\nKibanaには、前回の記事で書いたものとは別に開発中のKibana3というのが存在します。\nKibana3って? Kibana2はRubyで書かれていましたが、Kibana3はHTML+JavaScriptで構成されています。 ですので、ApacheなどのWebサーバに配置することで、利用が可能となります。 ただ、HTML+JavaScriptのため、ブラウザ上で動作するためブラウザが動作するマシンからElasticSearch(通常だとhttp://マシン名orIPアドレス:9200/とか)にアクセスできなければいけないという制限があります。\nこの条件さえクリア出来れば、Kibana3ではKibana2よりも様々なパネルが用意されていて、色々できそうなのでお勧めです。\nインストール ElasticSearchやログについては、前回の記事の環境を利用しました。 ですので、Kibana3のインストールのみです。(ApacheもCentOSのサーバに入っていたので。)\nダウンロードして、Apacheの公開ディレクトリに置いただけです。(お試し環境のため、権限とかは大目に見てください。\n$ git clone https://github.com/elasticsearch/kibana.git kibana-javascript $ cp -R kibana-javascript /var/www/html 今回はApacheとElasticSearchが同一マシン(=同一IPアドレスでアクセス可能)で動作している+ElasticSearchへのアクセスのポートがデフォルト(9200)のため特に設定が必要ありませんでした。\nElasticSeachサーバとKibana3のApacheのサーバが別のサーバの場合やElasticSearchサーバのポートが異なる場合はkibana-javascript/config.jsファイルの編集が必要になります。 cloneしてすぐのconfig.jsは、以下のとおりです。\n/* elasticsearch: URL to your elasticsearch server. You almost certainly don\u0026#39;t want \u0026#39;http://localhost:9200\u0026#39; here. Even if Kibana and ES are on the same host kibana_index: The default ES index to use for storing Kibana specific object such as stored dashboards modules: Panel modules to load. In the future these will be inferred from your initial dashboard, though if you share dashboards you will probably need to list them all here If you need to configure the default dashboard, please see dashboards/default */ var config = new Settings( { // By default this will attempt to reach ES at the same host you have // elasticsearch installed on. You probably want to set it to the FQDN of your // elasticsearch host elasticsearch: \u0026#34;http://\u0026#34;+window.location.hostname+\u0026#34;:9200\u0026#34;, // elasticsearch: \u0026#39;http://localhost:9200\u0026#39;, kibana_index: \u0026#34;kibana-int\u0026#34;, modules: [\u0026#39;histogram\u0026#39;,\u0026#39;map\u0026#39;,\u0026#39;pie\u0026#39;,\u0026#39;table\u0026#39;,\u0026#39;stringquery\u0026#39;,\u0026#39;sort\u0026#39;, \u0026#39;timepicker\u0026#39;,\u0026#39;text\u0026#39;,\u0026#39;fields\u0026#39;,\u0026#39;hits\u0026#39;,\u0026#39;dashcontrol\u0026#39;, \u0026#39;column\u0026#39;,\u0026#39;derivequeries\u0026#39;,\u0026#39;trends\u0026#39;,\u0026#39;bettermap\u0026#39;], } ); ポート番号が異なる場合は、1つ目の「elasticsearch:」で指定されている「9200」を環境に合わせて編集するだけになります。 Kibana3とElasticSearchのホストが異なる場合は、1つ目の「elasticsearch:」の行をコメントアウトし、2つ目を有効にしてから環境に合わせたURLに修正して保存すればOKです。\n以上で、インストールは完了します。あとは、以下のURLにアクセスするだけです。\nhttp://hogehoge/kibana-javascript/ 画面構成 アクセスすると次のような画面が表示されます。\n初期画面 左上に赤い帯で、「 Oops! Could not match index pattern to any ElasticSearch indices」とエラーが表示されました。\nKibanaはElasticSearchに「logstatsh-年.月.日」という日付ごとのインデックスが存在することが前提となっています。 Kibanaに初めてアクセスした場合、「logstash-当日日付」で始まるインデックスを描画しようとします。 これは、私が前回利用したElasticSearchの環境に古いデータ(試したのが19日、データは10日のみ)しか入っていないために出たエラーです。\n日付は「Options」というエラーが出ている付近の「Absolute」というリンクをクリックすると、特定の日付をカレンダーで指定することができるようになります。データは6/10にしか入っていないので、6/10(12時くらいから20時くらいまで)のを指定します。\n日付指定 選択すると無事データが見えるようになりました。\nデータ描画 ダッシュボードの構成(初期) Kibana3では、この画面をダッシュボードというようです。 このダッシュボードは初期状態では、以下のパーツが表示されています。(子要素があとで説明するパネル名です)\nOptions:描画対象の日付の指定やダッシュボードの保存などを行うRow timepickerパネル:日付の指定 dashcontrolパネル:ダッシュボードの制御(保存とか) Query:ログ検索式を入れるところ stringqueryパネル Graph:ヒストグラムの描画(X軸:時間、Y軸:ログ件数) histogramパネル Events:検索にヒットしたログデータの描画領域 fieldsパネル:表示するフィールドの選択(左側。チェックを入れると右側のログ表示領域のカラムが増える) tableパネル:ログデータ(右側。左側でチェックが入ったカラムだけが表示される。) あくまで初期表示です。各パーツの設定アイコン(歯車のマーク)をクリックすると色々と設定が可能です。 また、「Events」など名称はクリック可能となっていて、クリックすると、そのパーツが折りたたまれた状態にすることも可能です。\n折りたたんだ状態 ダッシュボードの設定 ダッシュボードには独自のパネルを簡単に追加することができます。 ダッシュボードの構成はページの一番上にある「Logstash Search」の設定アイコンをクリックすると設定画面が開きます。\nダッシュボード設定 「New row」にタイトル名を適当にいれて「Create Row」するとあたらしくパネルを追加することができるRowが追加されます。「Rows」の「Move」にある矢印でRow自体の表示場所を上下に移動することも可能です。\nRowの設定 追加した「Hoge」にパネルを追加する場合はHogeの上にある設定アイコンをクリックすると設定画面が開きます。\nRowの設定 ここでKibana3で用意されているパネルの追加ができます。\nPanel追加ボタン パネルを選んでボタンを押せばすぐに表示されます。\nパネルの羅列 こんな感じです。とりあえず、ポコポコと追加してみました。\n利用できるパネルの種類は以下の様なパターンです。 適当ですが、表にしてみました。\nパネル名概要 columnRowの中にパネルを配置するコンテナを用意するためのパネル dashcontrolダッシュボードの保存、保存したダッシュボードの表示などの操作ボタン textmarkdown形式などで記述が可能な文章を表示できるパネル stringquery検索クエリ入力用パネル derivequeriesフィールドと検索式がわかれた形式の検索入力用パネル timepickerログ表示の期間を指定するパネル histogramログの件数のヒストグラム表示用パネル hitsヒット件数表示用パネル pieパイチャート表示用パネル trends指定された時間でデータの増減を%表示するパネル sortソート条件指定用のプルダウン表示用パネル(変更したらtableの内容がソートされる) tableログデータ表示用パネル fieldstableパネルに表示するフィールドを選択するための補助パネル bettermapなんか地図が出てきたパネルGeoJSONデータをゴニョゴニョ(表示かな?)できるみたい mapなんか世界地図が出てきたパネル2文字の国コード(jaとかか?)かU.S.の州コードのデータを元に地図に色をつけるのかな? これらのパネルは個々に色々と設定が可能です。他にもdebug、map2など有りそうでしたがまだ使えないみたいです。\n適当に触ってて気づいた注意点です。\ntableは1ダッシュボードで1つだけが良さそう。 2つあると、どちらかにしか描画されない。columnに入れるとグルーピングできたりするのかなぁ? stringquery、timepickerも1ダッシュボードで1つが良さそう。 これもtableと似たような理由です。 ダッシュボード保存し忘れて泣きそうになる JSで実装されてて、自分で色々とカスタマイズできるのですが、保存するのを忘れて泣きそうになりましたw カスタマイズしたダッシュボードについては、ローカルに保存する以外にElasticSearchにも保存ができるみたいです。チームで共有することもできそうです。 derivequeriesを表示するとグラフがカラフルに derivequeriesを追加したらグラフが急にカラフルになりました。 どうもderivequeriesのFieldの部分を変更すると、そのフィールドの値を元にグラフを細分化してくれるようです。色の数の上限はderivequeriesのLength属性の数値で制御出来ます。(5だと5個まで色が出る) histogramのパネルで自分でクエリを記載することも可能です。ただ、derivequeriesのフィールド変更すると書き換わっちゃいます。。。 derivequeriesを追加したらカラフルに ヒストグラムは色々なパターンのグラフを描画できました。ラインによる描画(histo1)、総数を100%としたパーセンテージでの表示(histo2)、ライン+点による描画(histo3)などです。\nヒストグラムのいくつかのパターン 感想 ということで、適当にですが触ってみました。 Kibana2はApacheのアクセスログとかの表示しかできない感じがしましたが、Kibana3だといろいろなデータを描画できそうだなと。 logstash形式のインデックスを用意するのが前提になってるので、時系列データをグラフ描画するのに向いてるんでしょうか。 お手軽にグラフ化できるし、自分でダッシュボードをカスタマイズできるのは素敵です。 ただ、クエリとグラフの関係などはちょっと癖があるかもしれないので、色々と試してみないといけないかもしれないです。 (たとえば、特定のフィールドの値について「A、B、その他」みたいなグラフの描画とかをどうするかとか)\n地図の描画は試してみたいかなぁ。\n","date":1371652980,"dir":"post/2013/","id":"26c47355cbe966a94826cbe2fbf2b355","lang":"ja","lastmod":1371652980,"permalink":"https://blog.johtani.info/blog/2013/06/19/introduction-kibana3/","publishdate":"2013-06-19T23:43:00+09:00","summary":"前回は3番煎じぐらいでしたが、今回は初記事かな?(だといいな) Kibanaには、前回の記事で書いたものとは別に開発中のKibana3というの","tags":["elasticsearch","kibana"],"title":"Kibana3というのもありまして"},{"contents":"ちょくちょく書こうと言いながら、前の記事が1週間以上前になってる。。。\n昨日は、Basho Japanに遊びに行って来ました。 (Riak触ったことないのに。。。Erlangも。。。ゴメンナサイ)\nRiakにSolrを組み合わせたYokozunaというものの名前を最近耳にしていたので、どんなものなのかなぁと興味がありまして。Solrがどんな使い方をされているのかってのが気になったので、 情報交換したいなぁと思っていたところ、Vの人が調整してくれたので色々と有意義な話ができたかなぁと。 (Yokozunaについての最新のスライドはBerlin Buzzword 2013のものがここに) Twitter上で見かけたことのある方々と話ができたり面白かったです。(やっぱ英語で会話できたりスラスラと読めるの必要だよなぁと痛感したりもしました。。。)\nということで、遊びに行ったのに美味しいピザやこんなおみやげまでもらってしまいました。 (ピザの写真撮るの忘れてたw)\nRiak&Bashoグッズ ちなみに、Yokozunaですが、Riakに登録したデータを裏で起動しているSolにデータを流しこんでくれるものになります。 Solrの機能としては分散検索(Distributed Search)と呼ばれる仕組みを利用しているようです。 YokozunaのI/Fとしては、Solrのインデックスの分散構成は隠してくれていて、かつ、Solr(っぽい?)リクエストを投げれば裏の分散構成に問い合わせた結果をSolrのレスポンスの形で返してくれます。 KVSに全文検索の機能がついてくるお得感が満載な気がしますw。\nRiak自身のデータの取り扱いがどんなものかをまだちゃんと理解していないので(ゴメンナサイ。Little Riak Bookは開いてるんですが読んでなくて。。。)またおじゃましてもう少し情報交換したいかなぁとw。\nCloudera Searchといい、Yokozunaといい、Solrを利用したものが少しずつ増えてきて嬉しい限りです。 Solrの作りがしっかりしている?活発?、だから取り込む形が多いんですかねぇ。 Solr本を書いてから数年たちますが、やっと検索のニーズが出てきたのかもしれないなぁと思ってみたり。 (流れのつながりはあまりないですが)ElasticSearchも少しずつ人気が出てきてるし、日本語の本とかのニーズあったりするかなぁ?\n","date":1371603780,"dir":"post/2013/","id":"33919e866426ce8e7b2ce06f19bbf889","lang":"ja","lastmod":1371603780,"permalink":"https://blog.johtani.info/blog/2013/06/19/visited-basho/","publishdate":"2013-06-19T10:03:00+09:00","summary":"ちょくちょく書こうと言いながら、前の記事が1週間以上前になってる。。。 昨日は、Basho Japanに遊びに行って来ました。 (Riak触ったこ","tags":["Riak","Basho","Yokozuna","Solr"],"title":"Basho Japanに遊びに行きました"},{"contents":"Lucene/Solr 4.3.1のRCのVoteが始まっていますが、そのMLできになったコトがあり、ちょっと調べたので メモを残しておきます。\nマルチコアの設定ファイルであるsolr.xmlの記述方法と、コアの探索ロジックが4.4(実装的には4.3から入っている)から変更されるようです。4.x系の最新版である、branch_4xのexampleディレクトリにあるsolr.xmlも新しい記述に変更されていました。\n参考URL 新しいCore探索(4.4以降) 新しいsolr.xml(4.4以降) 4.3までのsolr.xml ちなみに、最後のold styleと呼ばれる4.3までの記述方法はつぎの5.0ではDeprecatedになるようです。(5.0がいつ出るのかはわからないですが。)\nCore探索ロジック 4.4から、$SOLR_HOMEディレクトリ以下の探索ロジックは次のようになるようです。 以下では、「新スタイル」(4.4以降の書式)、「旧スタイル」(4.3以下の書式)として記述します。\nsolr.xmlファイルの存在チェック solr.xmlが存在しない場合→旧スタイルとして処理→3へ(旧スタイル) solr.xmlが存在し\u0026lt;cores\u0026gt;タグが存在しない場合→2へ(新スタイル) solr.xmlが存在し\u0026lt;cores\u0026gt;タグが存在する場合→3へ(旧スタイル) 新スタイルのロジック SOLR_HOMEディレクトリに存在するディレクトリについて以下の処理を繰り返す SOLR_HOME/ディレクトリ/core.propertiesファイルが存在する→後続処理へ。存在しなければ終了 SOLR_HOME/ディレクトリ/conf/solrconfig.xmlを読み込み、コアを起動 旧スタイルのロジック これまで同様、solr.xmlの\u0026lt;core\u0026gt;タグの記載内容を元にコアを起動(instanceDir以下のconf/solrconfig.xmlを使って) solr.xmlが存在しない場合はSOLR_HOME/collection1/conf/solrconfig.xmlが存在するものとしてコアを起動 このようなロジックになります。\nちなみに、以下の場合はエラーとなりSolrは起動しますがログや管理画面にエラーである表示がされます。\n2.3でsolrconfig.xmlが見つけられなかった場合 3.1で\u0026lt;core\u0026gt;タグが存在しなかった場合(この場合、ログにはエラーが出ません) propertiesに記述できる内容やsolr.xmlの記述内容については、Wikiを見てもらうということで。。。 CoreAdminHandlerでコアを生成したりした場合に、新スタイルの設定がどのように出力されるのかといった点が気になりますが、また今度にでも。\n","date":1370945460,"dir":"post/2013/","id":"78292d953eafbdf9e57cc4bbbe6e8964","lang":"ja","lastmod":1370945460,"permalink":"https://blog.johtani.info/blog/2013/06/11/new-solr-xml/","publishdate":"2013-06-11T19:11:00+09:00","summary":"Lucene/Solr 4.3.1のRCのVoteが始まっていますが、そのMLできになったコトがあり、ちょっと調べたので メモを残しておきます。 マルチコアの設定ファ","tags":["Solr"],"title":"新しいsolr.xmlとCore探索ロジック"},{"contents":"もう何番煎じだ?ってくらい書かれてますが、コリもせず書いてみました。 Elasticsearch+Kibanaの環境を作って、タムタムさんのログ生成ツールからApacheのダミーログを流しこんで入れてみました。\n参考URL memorycraftさんのブログ Kibana Elasticsearch fluentd apache-loggen インストールと起動 今回はCentOSへのインストールです。 基本的にはmemorycraftさんのブログの流れのままです。\nelasticserchのインストールと起動 ダウンロードして、起動するだけ。 お試しということで、-fオプションにてコンソールにログ出力。\ncurl -OL https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-0.90.1.tar.gz tar zxvf elasticsearch-0.90.1.tar.gz cd elasticsearch-0.90.1 ./bin/elasticsearch -f Kibanaのインストールと起動 git cloneしてbundleインストール\ngit clone --branch=kibana-ruby https://github.com/rashidkpc/Kibana.git cd Kibana bundle install ruby kibana.rb これで、Kibana+ESのインストール+起動が完了。 下地が完了。\ntd-agentのインストールと起動 ログの流し込みはlogstashなのですが、fluentdのelasticsearchプラグインにて流しこむこともできます。 td.repoとしてtd-agentのリポジトリを登録してから以下を実行します。\nyum install td-agent -y /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-elasticsearch vim /etc/td-agent/td-agent.conf /etc/init.d/td-agent start これで、td-agentがインストール出来ました。 次は設定です。\n\u0026lt;source\u0026gt; type tail format apache path /var/log/httpd/dummy_access_log tag dummy.apache.access \u0026lt;/source\u0026gt; \u0026lt;match *.apache.*\u0026gt; index_name adminpack type_name apache type elasticsearch include_tag_key true tag_key @log_name host localhost port 9200 logstash_format true flush_interval 10s \u0026lt;/match\u0026gt; 以上が設定です。td-agentはtd-agentというユーザで起動されるので、/var/log/httpdディレクトリにアクセスできるかだけ確認が必要です。\nいくつかの設定値について気になったので調べました。\nindex_name:adminpackとなってるが、elasticsearchではlogstash-xxxとなってる。 これは、logstash_formatがtrueの場合は、利用されないので、指定しなくてもいい。 type_name:Elasticsearchのタイプ名 * これはlogstash_formatを指定しても有効。ただし、Kibana側で画面からのtype指定は不可能。KibanaConfig.rbにて指定することは可能。 logstash_format:Kibana用にlogstashフォーマットで出力するオプション この指定があるときは、index名が「logstash-YYYY.mm.dd」となる record(ログ)に@timestampとして時刻が追加される。 tag_key:include_tag_keyがtrueと指定されているため、record(ログ)にtag_keyで指定した文字列をキー、値としてtagの値(上記例だとdummy.apache.access)が付与されて登録される。 apache-loggenのインストールと起動 タムタムさんが作成されたApacheのログのダミーを生成するツールです。\ngem化されてるので、インストールは非常に簡単です。\ngem install apache-loggen で、ログを出力します。出力先は先程設定したdummy_access_logです。\napache-loggen --rate=10 --progress /var/log/httpd/dummy_access_log 秒間10アクセスログを出力してくれます。 これで、Kibanaでログが見れるようになりました。 なんて簡単なんでしょう。。。 簡単なログの検索ができてしまいました。 他の形式のログがどうなるのかとかは、また時間があれば。。。\n感想とか 非常に簡単でした。素敵です。いくつかこうなるのかな?というのを試してみたのでメモを。\nいくつか疑問点です。\n溜まったログの削除は手動? おそらく。日付ごとにindexが出来上がっているので、削除は楽そう。「logstash-年月日」なので。 認証とかかけれるの? ログ検索は内部でするだろうから、まぁ、なくていいのかな。ログインすらないし。 複数行のログとかってどーすんだろう?(JavaのExceptionとかが混ざるやつ) 本格的に触るようになれば調べるかなぁ。。。\nあと、ログが増えてきた時にどういった分割構成ができるだろう?って思って考えてみたのが以下になります。\n構成パターン ログを複数扱う場合は次のようなパターンがありそうかと。\nタグ(fluentdのタグ)で識別 「@log_name」という名前=fluentdのタグにてログを識別することで、異なるログを検索することができそうです。 タグであれば、プラグインによってはログ出力時に制御も可能だと思うので、td-agentの設定を変更したりすることもなく対応が可能かと。 ただ、ログの種別ごとにKibanaのプロセスを別にして起動したいといった用途には向いてなさそうです。\ntype_nameによる識別 ElasticSearchの機能であるtypeを利用したログの識別パターンです。\nfluent-plugin-elasticsearchの設定でtype_nameを指定しました。 ここを別の名前にすることで、識別することも可能です。\nただし、この場合はKibanaの画面から指定して検索することができません。 →コメント頂きました。検索条件に「_type:タイプ名」と検索することでtypeを利用した検索が可能です。\nタグ(@log_name)でも識別できるようにするなどの工夫が必要です。 その代わり、タグ識別ではできなかったKibanaのプロセスを別にして起動することは可能になります。\nKibanaConfig.rbのTypeに値を設定することで、起動したKibanaが対象とするログを絞り込むことが可能です。 こうすることで例えば、apache用のKibanaとtomcat用のKibanaは別プロセスにして、ElasticSearchのクラスタは1つという構成も可能になります。\nElasticSearchサーバを別立て ElasticSearchサーバをそもそも別のプロセスor別のサーバで起動し、Kibanaも別々にすればログの識別も可能です。 可能ですが、色々と管理するものが増えてめんどくさそうですね。。。\nインデックス名変更 最後は、fluent-plugin-elasticsearchの設定で「logstash_format」をfalseにすれば、好きなindex_nameを付与できるので、 ログ種別ごとに名前を変更することで識別できます。\nただ、logstash形式でないインデックス名の場合、日付ローテーションができなかったり、Kibana内部で検索時に日付で検索対象を絞り込んで検索することで高速化するといった処理など、使えない機能が多々出てきてしまうのであまりおすすめじゃないかと。。。\nということで、流行りものは触っておこうということで、さわってブログ書いてみました。\n開発中に立てておいて、各サーバのログを流しこんでおくなどにも利用できるかもしれないです。 アラート通知などの機能が出てくるともっと便利かもしれないです。\n","date":1370874840,"dir":"post/2013/","id":"c4d3a917f623f58646ce93015d79e8e0","lang":"ja","lastmod":1370874840,"permalink":"https://blog.johtani.info/blog/2013/06/10/fluent-es-kibana/","publishdate":"2013-06-10T23:34:00+09:00","summary":"もう何番煎じだ?ってくらい書かれてますが、コリもせず書いてみました。 Elasticsearch+Kibanaの環境を作って、タムタムさんのロ","tags":["kibana","elasticsearch","fluentd"],"title":"apache-loggen + fluentd + elasticsearch + kibana = ログ検索デモ"},{"contents":"昨日に引き続き、AWS Summit Tokyo 2013に行ってきました。\n@ryu_kobayashiさんからパシリを仰せつかるなどあり、忙しかったのですが楽しかったです。\n今日もすごい人出で、昼時の展示ブースは人だかりで、TDの方たち忙しそうでした。 後半はちょっとつかれたなぁ。 1日目よりも空調の温度が上がってたので快適でした。 飲物忘れたので、ちょっと喉がやられ気味でしたが。\nAWSはやっぱり勢いがあるんだなぁってのを実感しました。JAWS-UGまで残った感想です。 あとは、セルフハンズオンに参加するんだったかなぁというのもちょっとあります。あんまり触ったことないんで。\n以下はいつものメモです。\nAmazon Redshiftが切り開くクラウド・データウェアハウス 自己紹介と流れとニュース 6/5からTokyoリージョンでも利用可能に! Redshiftどんなもの? Redshift=クラウド型データウェアハウス オンプレの課題 初期投資、運用管理、費用対効果 EMRと同じで、分析処理向けのサービス 簡単な利用例 各種データストア→S3→Redshift 各種データストア→EMR→Redshift Data Pipelineでデータの流れの処理がかける。 データロードはパラレルに実行可能 バックアップは管理コンソールからボタンででも可能。 クラスタのリサイズも管理コンソールからできるよ。 NRIでの評価 2012年末の限定公開してすぐに先行評価に参加\nRedshiftの性能は?\n500億件からの検索処理(1週間分のデータを抜き出して処理するSQL) 8XLノード2ノードで43秒、4ノードで27.8秒、8ノードで19秒 データロドも線形に性能が上がる 1.2億件の検索処理は4ノードより8ノードのほうが性能劣化 EMRとRedshiftの比較。1.5TB、500億件でのJOIN+集計処理でRedshiftのほうが早かった。 Redshiftのチューニングポイント\nインデックスが存在得ず、Distribution Keyでノードに分散 Sort Keyも重要。データロード時間はSort Keyをつけると遅くなる ニガテなデータ形式もあるよ。EMRとかの組み合わせにすると安く済むこともあるよ\n簡単につくれるので、気をつけましょう。セキュリティとか。統制されないものが乱立してくるんで。\nそこでNRIですよ!(宣伝) 出てきた性能に関するものだけど、「ケース1」「ケース2」とかってなってるので、その部分の詳細が書かれたレポートが公開されないとどんなのがニガテなのかとかわからなかった。\n事例紹介とか オンプレのデータをどうやってRedshiftに持ってくの? インフォテリアのASTERIA WARP GUIツールでデータの変換とかして、S3に持って行って、Redshiftと連携できるよと。 無料セミナーの紹介 6/21、8/2にRedshiftの無料セミナーやりますよ。 インターネット上のユーザーの行動の可視化を実現したAWSによるビックデータ解析基盤 C-Finderのサービス紹介 元オプトの方。C-Finderの紹介。 10万ユーザの行動履歴の可視化。\nサイトに来たけど、行動せずに他サイトに移動したとか、サイトに来る前の状態ってのがわからない。これをC-Finderで可視化。\n例1:自動車業界 ライバル企業の動向を自社と比較したい。 Audi、BMW、ベンツで可視化。 例2:化粧品業界 Web上での化粧品のトレンドが見たい。 @cosmeサイトのPVとかから。 ユーザって会員登録とかしてる人を追っかけてるってことなのかなぁ? よくわかってない。。。\nレポーティングサービスしてたけど、納品まで1ヶ月かかってた。 リアルタイムにみたいという要望が多かったのでASPをTISと開発 ASPサービスの開発したよ AWSで。 可視化というタイトルだったんだけど、期待してた可視化の話ではなかった。。。\nネット選挙クラウド ~オバマ大統領選挙の事例:データ解析からネット募金まで~ ボランティアで構成ってすごいな。 本番まで1年 みんな髭の人だw GoogleとかFacebookとかの人がボランティアで開発に参加。 予算は抑えながら、スケールアップダウンがすぐ出来てとか。 秒間10万回のI/OのDB SQSとEC2のSoftware queueの比較。Softwareキュー選ぶと、さらにドレがいいのかってのを選ばないとい。 AWSにあるサービスなら、造らなくてもいいのではとか。 CloudSearchはつかわなかったのかなぁ? tsunami S3に静的ページをおいて、最後のとりでにしたり。 コードとか、ノウハウってどこまで公開されてるんだろ? 同時通訳もあったんですが、英語を聞いてみようと聞いてましたが、まだまだダメですねぇ。\nパネルディスカッション「ウェブテクノロジーをエンタープライズで活かすには?」 趣旨 B2B、B2C間でのトレンドのやり取りが加速されてるよねと。 ICTはもはやコモディティ? TD太田さん Consumerization Of IT 色々なものがSaaSになってきてる TD:Consumerization of Data Infrastructure オンプレ<AWS<TD 三井物産黒田さん 三井クラウド(プライベート&パブリック) ユビキタス これまで使ってきたものがクラウドで動くのかとかが観点 電通平川さん マーケティングダッシュボードはsalesforceでは厳しかった? ビジネスに注力したいので、柔軟で、質実剛健なICT基盤がほしい。 ディスカッション 新しい技術に対するスタンスは?\nいかにダメな部分を潰していくか(太田さん) R\u0026amp;Dを予算化して評価して取り組んでいく。評価でダメならつぎ。(黒田さん) 消費者の方たちがネットですごい勢いで活動してる。その人達へのアプローチが重要。(平川さん) コンシューマ系技術の懸念事項は?\nセキュリティ面。レベルがある。自分の所だけじゃなく、クラウドベンダーと二人三脚が必要。丸投げはNG(黒田さん) セキュリティ面の攻撃を受けたつぎの手をどう打つかが重要。堅牢性上げると、ユーザビリティが下がる。(平川さん) 法規制的に出せないとかもある。持ちきれないデータもあるよね。(太田さん) 何を見分けてどうやって取り組むか?\nとりあえず、やってみる。そこで見える課題に対応していく。見極めるのは難しい(平川さん) ということは、すぐに出来る環境ってのは当たり前になってますよね。\n尖った技術=セキュリティ面が弱い?みたいな印象があるのかなぁ?\nJAWS-UG AWSアップデート AmazonのCTO登場 Game Day Game Day。土曜日にやるよ。 障害を発生させて、それを復旧させる。 最もひどい壊し方をしたらかちw 最後はかるくボッチでした。。。 AWSあんまり使ってないからなぁ。。。\n","date":1370527200,"dir":"post/2013/","id":"d12c1c2a68be4c7fda5a7737d5493b4d","lang":"ja","lastmod":1370527200,"permalink":"https://blog.johtani.info/blog/2013/06/06/aws-summit-tokyo-day2/","publishdate":"2013-06-06T23:00:00+09:00","summary":"昨日に引き続き、AWS Summit Tokyo 2013に行ってきました。 @ryu_kobayashiさんからパシリを仰せつかるなどあり、忙しかったのですが楽しか","tags":["AWS","勉強会"],"title":"AWS Summit Tokyo 2013に行って来ました。(Day2) #awssummit"},{"contents":"ざっとインストールガイドとかCloudera Searchのソース眺めて、テキトーにメモを書いてみました。 (ユーザガイドはまだ読んでないです。)\nざっくりメモ ストリーム処理でインデックス作るときはFlume経由でSolrに SinkとEventの両方が用意されてる?(Flumeを良く知らないので、違いがわからない) FluemeからはリモートのSolrに対してインデックス登録するクラスがある。SolrServerDocumentLoaderがソレだと思う。 バッチ処理でインデックス作るときはMapReduceIndexerToolsってのを使ってSolrに SOLR-1301がベースになっている。色々と改良されてるようだけど、コアとなってる処理はSOLR-1301。 GoLiveってクラスの処理の中で、現在動作してるSolrに配布したバッチで作成されたIndexをマージする処理が書いてある。 HDFSへ出力されたインデックスはリモートのSolrからアクセスするとオーバヘッドとかどーなるのかなぁ? 検索処理自体はHueでもできるけど、基本的にSolrCloud任せ インデキシングの処理のフローについてはCloudera Mrophlinesで定義 ということで、 2つの流れがありそう。\nHDFS→Flume→Solr HDFS→MapReduce→Solr で、まだ、わかってないですが、構成要素として\nHadoop(HDFS):データソース Hadoop(MapReduce):データ変換処理、バッチインデキシング Zookeeper:SolrCloudのクラスタ管理 Solr:インデキシング、検索エンジン Flume:データをストリーミングでSolrへ Coudera Morphlines:HDFSからSolrまでのETLデータ処理を定義実行する環境 って感じでしょうか。 SolrCloudのクラスタとHadoopのクラスタが同一マシン上なのか、別なのかとか。組み合わせがどんなものができるのかがまだわかってないです。 ユーザガイド読んでみたらなにか出てくるかなぁ。\nちなみに、Cloudera SearchのgithubリポジトリにあるソースはCloudera Morphlinesのコードがメインで、SolrのHDFS対応版のソースがあるわけでは無かったです。\nSolrのHdfsDirectoryってのがClouderaのリポジトリにあるSolrには追加されていて、これが、HDFSのインデックスを読み込んだりする処理が出来る仕組みっぽい。 一応、SolrCloud以外(分散検索)も考慮された形になってるっぽい。 ってとこでしょうか。\n感想 読んでて思ったんですが、Cloudera Searchの肝はじつは、検索じゃなくて、Morphlinesにあるんじゃないかなぁと。今はSolrが出力先ですが、 その他のデータ変換処理とかが増えてくると、処理の流れがMorphlinesで定義できてデータ変換処理が簡便になりそうな気が。\nその他に気になる観点 CDH経由でSolrCloudのクラスタの管理するのかな? SolrCloud用のクラスタとCDHのクラスタって同一マシンに載るの?別マシンにもできるの? 併存したらIOがキツそうだけど Hueで検索アプリとか組めるの?(そもそもHueがわかってないんだけど。。。) ま、とりあえず、こんなとこで。 つぎは余力があれば、ユーザガイドかなぁ。 英語力。。。\n","date":1370489160,"dir":"post/2013/","id":"f45069216cd934b80ce882c9a2f2a08a","lang":"ja","lastmod":1370489160,"permalink":"https://blog.johtani.info/blog/2013/06/06/cloudera-search-memo2/","publishdate":"2013-06-06T12:26:00+09:00","summary":"ざっとインストールガイドとかCloudera Searchのソース眺めて、テキトーにメモを書いてみました。 (ユーザガイドはまだ読んでないです。","tags":["Cloudera Search","Hadoop","Solr"],"title":"Cloudera Searchメモ(妄想版)"},{"contents":"AWS Summit Tokyo 2013に行って来ました。\n@cocoatomoさんに行き掛けに出会ったので、アンデルセンの講演を一緒に聞いてました。 TDブースの@ryu_kobayashiさんに挨拶に伺ったりも。\nすごい人で、セッション間の入れ替え時には会場前のスペースが大変なことになってました。もう少し余裕のある建物のほうが良かったのかもしれないですねぇ。\nいつものように以下はメモです。\nRoad to AWS アンデルセンサービス とてもおいしいランチボックスでした。\n広島(ここ重要!)に本社のあるパン屋さん。\n2003年に汎用機からOpenシステムに 内製ではなく外注に。複数のSIerにお願いしてるとデータセンタに マスタ管理と生産管理はオンプレ 2004年に稼動時のネットワーク整備。店舗はISDNで、設定ミスとかを防ぐためにIIJのSMFサービスに PCはレンタル契約にしたので入れ替えを強制できる→レガシーシステムの対応が必要なくなる ネットワーク広帯域化→基本システムにデータセンターに。 2009年にリース満了などで、OSの変更とかミドルの変更という移行SI費用だけで結構な値段が。ものによっては会社もない。 データセンターの月額手数料にして、機器変更などの費用を平準化。仮想化など。 けど、サイジングにどうしても安全係数をかけてしまうことに。結構値段がかかる そこで、今後の方向性 SIerどっぷりのOLTP受発注基幹システムはSIerのホスティングで それ以外のシステムは外に出したい バッチの計算を早くすることができるとノーチラスさんから提案された バッチを外部化するか、性能あげるか。IOネックなどもありスペック上げるとコストになるから、外部化したい Hadoopを組むけど、オンプレじゃなくてAWSにした。ノウハウがないので、ノーチラスさんにお任せした。 AWSのEMRを利用。4時間かかっていたものが40分で。 EDIのサーバを6ヶ月でAWSに移行 S3絡みで2度の問題が。性能劣化があった。 パッケージ開発環境がAWSにあるなら、AWSでも動くでしょ?(NTTイントラマートとか) SIerどっぷりの部分もAWSに持っていく? アンデルセンサービスの部長さんからのAWSへの要望 メールサーバなどの基本サビスとか、コントロールパネルを充実して欲しい。 クラウド技術を活用したリアルタイム広告\u0026quot;Logicad\u0026quot;の入札・配信・ログ解析 Web広告の歴史 最初は広告主がWebサイト単位で契約 アドネットワークによる仲介 聞きそびれた。。。DSP? アドネッエクスチェンジ SSP(Supply Side Platform) リアルタイムビッティング(RTB) RTPの仕組みを説明。 AWSとオンプレでシステムを構築してる。\nSSP事業者との取引はオンプレ 配信はAWS オンプレとAWSはAWS Direct Conectで接続 S3とHadoopの接続が安くなったり速くなったりするらしい。 オンプレミス側 Bidリクエスト:秒間数万件。。。 KVSのユーザ数は3億件。。。 AEROSPIKEというSSD向けのKVSを利用してる AWS側 ログはS3に。溜まったデータは定期的にEMRで解析。DynamoDBに入れてレポート作成 RabbitMQを使ってる。 ELBで外部からのリクエストはバランシング データセンタ間通信 遅延を複数コネクションを貼る方法で回避? 非同期で、複数のMsgとAckをやり取りする。RabbitMQがこれに相当する機能を持ってる QueueとConsumerで多重送信が可能。 配信結果をオンプレ側に送るのにRabbitMQを使ってるのかな? ハイブリッド構成を支えるAWSテクノロジー 聞くつもりだったんだけど、すごい人だったので、諦めて充電してた。\nAWSクラウドで構築する、ワールドクラスの分散クラウドアーキテクチャ エマージングソリューション部の部長のshot6さん。\nマルチAZ(アベイラビリティゾーン)モデル AWS固有のコンセプト。 ELBやDynamoDBやRDS、S3とか。\nマルチリージョンとは違うよと。マルチリージョンは結構難しいので。 マルチリージョンがどんなに大変かをこれから説明。\nマルチリージョンアーキテクチャ(これは別物) 複数のリージョンを利用して作る。 AWSのビルディングブロックではカバーしない範囲をカバーしないとダメとか。 リージョン間の通信は基本的に非同期 ディザスタリカバリ コストバランス見てから決めるよね。 CAP定理とかもいろいろと出てくるよね。 合意プロトコル。正確性、生存性(時間が制限されても大丈夫)、理論的にパフォーマンス出る? 非同期レプリケーションになる(1トランザクション当たりのオーバヘッドが大きいから)けど、復旧の難しさがある。 GlusterFSとかでやってるとこもある。 NetflixはCassandraをクオラム+Geo-Replicationでマルチリージョンを構成してる。 マルチリージョンでのデータ一貫性は維持がむずい 注意点 必要になるまで分散させない。 まずは、マルチAZを考えましょう 物理制限を考慮する 同期型だとタイムラグあるし。 複合障害の伝搬をどう抑えるか。 NetflixはHYSTRIXというのがいて遮断できるようにしている 自動化が重要。ロールバックとかロールアウトとか。 テストをどーするの? 本番環境でアクティブ/アクティブ構成でのテスト。 ちゃんとフェイルオーバするかなどを実環境でやってる。DB落としたり。。。 障害は避けられないので、受け入れて日常に取り込むべきだよねと。\nAmazon.comではGameDay NetflixはChaos Monkey(OSS) Obama for America リカバリーオリエンテッドコンピューティングパターン\nボーアバグ:再現可能なソフトウェバグ ハイゼンバグ:通常ではありえないパターンで発生するバグで、調査が大変 ということで、マルチAZがいいよ 同期式レプリケーションを前提にできる。 アプリ開発者がアプリにフォーカスできる。分散系の難しいところはAWSが隠蔽してくれるから。 ","date":1370424600,"dir":"post/2013/","id":"1fe14e2e02b6e65e6e6e2ae3d8ddcc9f","lang":"ja","lastmod":1370424600,"permalink":"https://blog.johtani.info/blog/2013/06/05/aws-summit-tokyo-day1/","publishdate":"2013-06-05T18:30:00+09:00","summary":"AWS Summit Tokyo 2013に行って来ました。 @cocoatomoさんに行き掛けに出会ったので、アンデルセンの講演を一緒に聞いてました。 TDブースの@ry","tags":["勉強会","AWS"],"title":"AWS Summit Tokyo 2013に行って来ました。(Day1) #awssummit"},{"contents":"Cloudera Searchは次のようなモジュールから構成されています。 これはCloudera Searchのモジュールで、さらにこれらがSolrとかを使ってるみたいですね。pom.xmlを見たら何を使ってるかがわかるかな。\ncdk-morphlines search-contrib search-core search-flume search-mr search-solrcell てきとーに、README.mdみながらメモを残してみました。ソースとかはまだ読んでないです。 ざっと眺めたけど、インデキシング処理の話がメインで、検索側がどうやって動くかってのがわからなかったなぁ。 ユーザガイド(注:PDF)ってのがあるから、これを読んでみるか。。。\n各モジュールについては、以下。\ncdk-morphlines(Cloudera Morphlines) Cloudera Morphlinesという名前みたい。 検インデキシングアプリの構築、変更をラクにするためのフレームワーク。 ETLの処理チェインを簡単にCloudera Searchにデータを入れる設定(Extract/Transform/Load処理)がかけると。 バッチ処理、Near Real Timeのために使えるみたい。検索結果をさらに入れるとかもできるんかなぁ。?\nUnixパイプラインのの進化版みたいなもので、一般的なレコードに対するStream処理から、Flueme、MapReduce、Pig、Hie、SqoopのようなHadoopコンポーネントも使えるみたい。\nHadoop ETLアプリケーションのプロトタイピングにも使えて、リアルタイムで複雑なStreamやイベント処理やログファイル解析とかに使えるの?\n設定ファイルのフォーマットはHOCONフォーマット。AkkaやPlayで使われてる。\ncdk-morphlines-core Cloudera Morphlinesのコンパイラ、実行環境、コマンドのライブラリを含んでる。 ログファイル解析やsingle-lineレコード、multi-lineレコード、CSVファイル、正規表現パターンマッチ、フィールドごとの比較とか条件分岐とか、文字列変換とか色々なコマンドを含んでる。\ncdk-morphlines-avro Avroファイルやオブジェクトの抽出、変換、読み込み処理コマンド\ncdk-morphlines-tika バイナリデータからMIMEタイプを検出して、解凍するコマンド。Tikaに依存\n雑感 Cloudera Searchへのデータの流し込みを設定ファイルに記述して実行するとデータの変換処理とかが記述できるって感じかな? Morphlinesのコマンドとして独自処理や使えそうな処理を作ることで、いろんな処理ができるって感じかなぁ。\nsearch-core Solrに対するMorphlineコマンドの上位モジュール\nsearch-solrcell Tikaパーサを使ったSolrCellを使うためのMorphlineコマンド。 HTML、XML、PDF、Wordなど、Tikaがサポートしてるものがサポート対象。\nsearch-flume Flueme Morphline Solr Sink。 Apache Flumeのイベントから検索ドキュメントを抽出、変換し、SolrにNearRealTimeで読み込むためのコマンド\nsearch-mr HDFSに保存されたファイルに含まれる大量データをMapReduceで処理してHDFS上の検索インデックスに焼きこむモジュール。\nMapReduceIndexerToolは入力ファイルの集合からSolrのインデックスシャードの集合を作るためのmorphlineのタスクで、MapReduceのバッチジョブドライバー。 HDFSにインデックスを書き込む。 動作してるSolrサーバに対して出力されたデータをマージするのもサポートしてる。\nとりあえず、Near Real Time検索するにはFlueme使って、バッチ処理でインデックス焼くのはMapReduceIndexerToolみたいだなぁ。\n","date":1370412720,"dir":"post/2013/","id":"e30258aeb8475d4c27f7935945671856","lang":"ja","lastmod":1370412720,"permalink":"https://blog.johtani.info/blog/2013/06/05/cloudera-search-modules/","publishdate":"2013-06-05T15:12:00+09:00","summary":"Cloudera Searchは次のようなモジュールから構成されています。 これはCloudera Searchのモジュールで、さらにこれらがSolrとかを使っ","tags":["Cloudera","Hadoop","Solr","Cloudera Search"],"title":"Cloudera Searchのモジュールたち"},{"contents":"AWS Summitに来ていたのですが、TLでは、Cloudera Searchが賑わってました。 ということで、軽くどんなものか読んだり調べたりしたメモを残しとこうかと。 英語力はあやしいので、おかしいとこがあったらツッコミを。\nCloudera Searchとは? CDH4.3に対応したCDHユーザ向けの検索システム(beta版)なのかな? CDHに統合された検索フレームワークなのかな?\n基本はLucene/Solr 4.3でHadoopのペタバイトデータを検索することができるようになるみたいです。\nどんな仕組み? 次のものを利用しているようです。(GithubのREADMEから。)\n使ってるもの Apache Solr(4.3.0+α?) Apache Lucene(Solrつかってるからね) Apache SolrCloud(うーん、Solrに含まれるのに別に出してるのなんで?) Apache Flume Apache Hadoop MapReduce \u0026amp; HDFS Apache Tika SolrCellとしてSolrにも組み込まれてる、いろんな文書(WordとかHTMLなどなど)からメタデータと本文データとかを取り出せるライブラリラッパー。実際にはさらにpdfboxとかを使って各文書からのデータを取り出してる。 何ができるの? HBaseやHDFSの用にZookeeperを使ってインデックスのシャーディングや高可用性ができる。(SolrCloudがZookeeperを使ってるからね。) MapReduceのジョブの出力から自動的にSolrのインデックスにデータをマージできるらしい。 Cloudera Managerを使って、デプロイ、設定モニタリングなどが可能。\nFlumeのフィードをつかって、ストリーミングしてインデックスを作れる。FluemeがデータをSolrに流しこむのかな? 将来的にはHiveやHBaseのテーブルをインデックスすることも可能になるらしい。Impalaクエリの結果もフィードできるのか?\nApache Blurってキーワードも出てきた。HDFSのデータからLuceneのインデックス作るのかな? NGDataのチームがSolr/HBaseの統合とかしてるみたい。\n参考URL Cloudera社のブログ Cloudera SearchのFAQ(注:PDF) Githubのリポジトリ ","date":1370412300,"dir":"post/2013/","id":"cd90bce912f5743226af94c1efaaa4a7","lang":"ja","lastmod":1370412300,"permalink":"https://blog.johtani.info/blog/2013/06/05/what-is-cloudera-search/","publishdate":"2013-06-05T15:05:00+09:00","summary":"AWS Summitに来ていたのですが、TLでは、Cloudera Searchが賑わってました。 ということで、軽くどんなものか読んだり調べたりした","tags":["Cloudera","Hadoop","Solr","Cloudera Search"],"title":"Cloudera Searchってのが出たらしい(とりあえず、雑感?)"},{"contents":"憧れ?のfluentを使ってみました。 こちらの記事で紹介したZoomdataを最近触っているのですが、お試しにfluentdでデータ流し込むプラグインを作ってみようかなぁと。(今は、Javaでの接続も書いていて、主にそっちを使っています。) ということで、作ってみました。fluent-plugin-zoomdata。\n基本的にはtagomoris先生のfluent-plugin-growthforecastを参考(パクリ?)にさせてもらいました。 作っている最中もここわからんってツイートに反応していただき、大変助かりました。 私はベースがJavaの人間なので、手探り状態でRubyを書いています。そこおかしいんじゃないの?とかあればコメントもらえると嬉しいです。\nZoomdataのAPI ZoomdataのAPIはこんなかんじで、JSONをHTTPSでPOSTするものになります。\n指定する必要があるものは、以下の項目です。\nsource:Zoomdataのデータ保存先(Zoomdataでのデータを保存する単位。) user:Zoomdataのユーザ名 password:Zoomdataのユーザのパスワード JSONデータ:Zoomdataでグラフ化するデータ sourceはデータ保存先の名称で、この単位でZoomdataはデータを保存、描画します。fluentdのタグをこれにするとわかりやすいかなぁ?と考えていったん、実装してみています。\nで、作成したプログラムを使いつつ、Zoomdataの検証をしたかったので、つぎのような簡単なプログラムを作って動かしてみました。\nサンプルプログラムの構成 基本的にJavaの人なので、クライアントはJavaで書いてます。 CLIプログラムで適当なJSONを作って、fluent-loggerを使って、fluentdに投げ込みます。\nfluentdにfluent-plugin-zoomdataを設定して、localのZoomdataサーバに対してHTTPSでJSONをPostする仕組みです。(初keynote)\n利用しているライブラリなどのバージョンは次の通り\ntd-agent.x86_64:1.1.12-0 fluent-logger:0.2.8 Zoomdata:1.0.3 バグ? で、Zoomdataにいろんなデータを流し込んでみたのですが、つぎのようなエラーが出て、エラーが出力されたあとはZoomdataにデータが流れ込まなくなってしまいました。\n2013-06-03 14:42:33 +0900 [warn]: emit transaction failed error=\u0026#34;SSL_connect returned=1 errno=0 state=SSLv3 read finished A: sslv3 alert handshake failure\u0026#34; 2013-06-03 14:42:33 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/1.9.1/net/http.rb:799:in `connect\u0026#39; 2013-06-03 14:42:33 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/1.9.1/net/http.rb:799:in `block in connect\u0026#39; 2013-06-03 14:42:33 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/1.9.1/timeout.rb:54:in `timeout\u0026#39; 全ログはこちら。\nまだきちんと問題を調査しないでブログを書いています、すみません。\n現象 ログが発生した時の症状です。\nクライアントプログラムは送信が続いており、エラーは出ない td-agent.logに先ほどのエラーが出力 別途type fileにて出力しているログも停止 想像 とりあえず、ログを見た想像、所感です。\n問題の箇所はfluent-plugin-zoomdataからZoomdataサーバへのデータ送信部分 emit処理内部で、HTTPSでデータをPOSTする処理でエラーが起きて リトライ処理とか書いてないので、emitがコケて、その後データが送信されなくなる emitで例外をつかみそこねてるのがあるから止まってる? とまぁ、ちゃんと仕組みを理解しないでRubyとか書くからこうなるんですねぇ。 あとでちゃんと調べて考えて、改良してブログ書きます。\n悩んでいる点、今後手を入れたい点 上記バグとは別に作りの点でいくつか悩んでる点も書いてみます。\nBufferedOutputにしてみたい fluentdのバッファリングを使って、Zoomdataが落ちていても使えるようにしたいと思っているのでBufferedOutputで書くのがいいのかなぁとか。 ちょうどいいスライドがあったので、読みながらまずは中身を理解してみよう。\nZoomdataのsource、userなどの扱い 基本的には設定ファイルで切り替えるのが妥当かなぁと思っています。\nただ、Zoomdataのsourceやuserが増えるたびにfluentdの設定を書き換えて再起動するのかなぁと。userはしょうが無いにしても、sourceは設定じゃない所で切り替えたいなぁと。\nで、切り替えるのにつぎの案があるかなぁと。\nタグで指定(今実装してるもの) メッセージにメタ情報とボディ構造を設ける 設定をどんどん増やす(やりたくない) 1と3はまぁ、いいかと。2.のパターンはどうなのかなぁと。 毎回のメッセージでヘッダ部分が送信されるのはなんだか無駄だなぁというのが否めないので悩ましいところです。1、2の両方対応できるように作るのもありか。\n{ \u0026#34;header\u0026#34;: { \u0026#34;source\u0026#34;: \u0026#34;source_name\u0026#34;, \u0026#34;user\u0026#34;: \u0026#34;userid\u0026#34;, \u0026#34;password\u0026#34;: \u0026#34;userid\u0026#34;, }, \u0026#34;body\u0026#34;: { \u0026#34;label\u0026#34;: \u0026#34;label1\u0026#34;, \u0026#34;count\u0026#34;: 1 } } ということで、fluent触って遊ぶの楽しいですね。Rubyの勉強にもなりそうだし。 ちょっとずつ頑張ってみようかなぁと。 まぁ、まだ私以外にニーズは無さそうなプラグインですが。\n","date":1370234580,"dir":"post/2013/","id":"494557db52824555864d1106278cd1f0","lang":"ja","lastmod":1370234580,"permalink":"https://blog.johtani.info/blog/2013/06/03/fluent-plugin-zoomdata-0-0-1/","publishdate":"2013-06-03T13:43:00+09:00","summary":"憧れ?のfluentを使ってみました。 こちらの記事で紹介したZoomdataを最近触っているのですが、お試しにfluentdでデータ流し込む","tags":["Zoomdata","fluentd"],"title":"fluent-plugin-zoomdata作りました+悩み事とか"},{"contents":"最近、Markdownで文章を書くのに慣れてきました。 ということで、ブログをMarkdownで書けないかなぁと思い、TLの人たちのブログを見たりしていると 「Octopress」というキーワードがあるじゃないですか。 ということで、Github Pages作って、Octopressを使ってブログを書いてみました。 こちらです。\n独自ドメインは昨年から使っているものがあったので、ついでに独自ドメインの設定もしてみました。 ケチなので、.comなどではなく、.infoですが。。。\nということで、徐々にOctopressに移行していこうと考えているところです。 こちらのブログも当面は残しておく予定です。(有料会員は解約して、広告が出る形になると思いますが。。。)\nOctopressでこんなの便利だよとかアレば教えてもらえると助かります。\n","date":1370228038,"dir":"post/2013/","id":"16f10764f0ccce42d5be8cfeac36b446","lang":"ja","lastmod":1370228038,"permalink":"https://blog.johtani.info/blog/2013/06/03/octopress%E3%82%92%E8%A9%A6%E3%81%97%E4%B8%AD/","publishdate":"2013-06-03T11:53:58+09:00","summary":"最近、Markdownで文章を書くのに慣れてきました。 ということで、ブログをMarkdownで書けないかなぁと思い、TLの人たちのブログを見","tags":["misc"],"title":"Octopressを試し中(Jugemより移植)"},{"contents":"昨年から、ブログをどうしようかって話をしていて、そのままになっていたのですが、Octopress+Github Pagesというのがあるらしいと聞きつけて(Twitterで見かけたのかなぁ?)ちょっとやってみました。\n最近は、ドキュメントをMarkdownで記述しようとして癖をつけているのもあり、 ちょうどいい練習になるかなぁと。\nということで、まずは手始めのエントリーでした。 いくつか書きたいこともあるので、調べながら書いていこうかと。 まだ、イメージできてないこと\n画像をどうやって貼るの? About meみたいなのも貼り付けたい bitbucketやTwitterのリンクとかも アフィリエイトも貼る(とりあえずSolr本を) 検索とかは? デザインは? などなど。ちょっとずつ調べていこうかなぁと。 あ、調べたことも書いてくのもありか。\n","date":1370098620,"dir":"post/2013/","id":"dbcc4002c15afefef853a08a0804ba3a","lang":"ja","lastmod":1370098620,"permalink":"https://blog.johtani.info/blog/2013/06/01/first-octopress/","publishdate":"2013-06-01T23:57:00+09:00","summary":"昨年から、ブログをどうしようかって話をしていて、そのままになっていたのですが、Octopress+Github Pagesというのがあるらしい","tags":["octopress","misc"],"title":"Octopress始めました"},{"contents":"Lucene/Solr 4.3.0がリリースされた(LuceneのChanges、SolrのChanges)ので、lucene-gosen 4.3.0をリリースしました。(ダウンロードはこちら) なお、lucene-gosen 4.3.0ですが、Lucene/Solr 4.2.1以下のバージョンのLucene/Solrでは利用できません。 注意してください。 また、lucene-gosen 4.2.1もLucene/Solr 4.3.0では動作しませんので注意が必要です。\n現時点(2013/05/06)では、lucene-gosen 4.3.0はLucene/Solr 4.3.0でのみ利用できます。 これは、先日のエントリにも書きましたが、LuceneにてAPIの変更が行われたためとなります。 いくつかのクラスおよびメソッドが廃止されたため、下位互換が保てない変更が入っているためです。\n独自のTokenizerやTokenizerFactory、TokenFilterFactory、CharFilterFactoryを作成されている方は、Lucene/Solrのバージョンアップを行う際は注意が必要です。\n","date":1367850324,"dir":"post/2013/","id":"11d4726484be418849e1f4200ade9535","lang":"ja","lastmod":1367850324,"permalink":"https://blog.johtani.info/blog/2013/05/06/lucene-gosen4-3-0%E3%82%92%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E3%81%97%E3%81%BE%E3%81%97%E3%81%9Flucene-solr4-3-0%E4%BB%A5%E4%B8%8A%E3%81%A7%E3%81%AE%E5%88%A9%E7%94%A8%E3%81%8C%E5%8F%AF%E8%83%BD%E3%81%A7%E3%81%99/","publishdate":"2013-05-06T23:25:24+09:00","summary":"Lucene/Solr 4.3.0がリリースされた(LuceneのChanges、SolrのChanges)ので、lucene-gosen 4.3.0をリリースしま","tags":["lucene-gosen"],"title":"lucene-gosen4.3.0をリリースしました。(Lucene/Solr4.3.0以上での利用が可能です)(Jugemより移植)"},{"contents":" アジャイルな時間管理術 ポモドーロテクニック入門 ポモドーロテクニック入門という本を読みました。 きっかけは、Twitter上で何度か「ポモドーロ」という単語を何度か見ていたためです。 最初は、なんだろう?というのが発端です。 「ポモドーロ=トマト」なのですが、実際にはトマト型のキッチンタイマーが元になっているらしいです。 このタイマーを使った時間(タスク)管理術がポモドーロ・テクニックです。\n私は、ここ数年、複数の仕事がパラで走ることが時々ありました。 このような場合に、日によって異なる複数のタスクが存在します。 このとき、異なるタスクにスイッチするのに結構な時間を取られます。。。 また、急な割り込みが入った時も同様に、以前のタスクに戻るのになにしてたっけ?となることが多々あります。 普通に自己管理ができている方なら問題ないのでしょうが、私は結構ニガテでした。 そのようなときに、Twitter上で「ポモドーロ」という単語を見かけて、軽くググってみたところ、 タスク管理、時間管理によさそうな本だったので、その点を矯正するのも兼ねて、読んだ次第です。 また、タスクに集中できるという利点もあるそうです。\n本については、少し読みにくいところがありました。 ポモドーロテクニックとはどんなものかという全体像や単語に関する説明がないままに、話が進んでいくので。。。 1度読み終わったあとに実践しながらパラパラめくっているような状況です。 実際には、個々人のやり方などを考慮しながら、改善していくべきなのもあり、型を説明してないのかもしれないですが、もうすこし概観がわかる感じのほうが良かったです。\nで、4月初旬くらいから実践してみています。 効果が実際にあるかというと、まだわからないです。\n私がポモドーロテクニックに利用しているのはキッチンタイマーではなく、pomodairoというAdobeAIR上で動くアプリになります。 ほかにもPomodoroAppというのもあるのですが、Free版だと登録できるタスクの上限があったので、pomodairoを選びました。(今見たら、3.0にバージョンが上がって、Limitがなくなってるかも) AIRだと、WinでもMacでも動作するのというも決定した要因です。\nまだ、1ヶ月経ってませんが、私が実践してきて良かった点、できてない点、うまくいってない点はつぎのような感じです。\n良かった点 目の前のタスクに集中できる。(25分スパンなので、Twitterを意識的に見なくできる。。。) 適度な休憩が挟める。25分に5分の休憩が入るので、適度な没頭になる(没頭し過ぎない) 自宅で作業するときにかなり有効。(5分の休憩時にTwitterやFB以外に漫画をパラパラ読んだりもできるので) ということで、自宅で作業するときには結構いいです。 自宅ですと、pomodairoを使っていてタイマーの音を気兼ねなく出せるので、きちんとポモドーロが回せます。\nできてない点 アクティビティ在庫管理。個人的にJIRAを使っていて、そこで管理しようと思っているのですが、うまくできてないです。pomodairoのアプリにもタスクを登録しているのもあり2重登録などを手間に思ってしまって。。。 レコーディングと今日のTodo作成。 インタラプトの記録 アクティビティ在庫管理ができてないのは、レコーディングがきちんと出来てないためでしょう。。。 二重管理になっている+pomodairoで統計情報が出るが、当日分の統計情報がレコーディングできてないというのが痛いです。 また、このレコーディングが出来てないので、効果が出ているかがわからないという問題かと。。。 きりが悪かったりして、どうしても、仕事時間ギリギリまでタスクをこなしてしまい、レコーディング+アクティビティ在庫の管理の時間が取れていません。 ここは意識してちゃんとやらないと意味がないよなぁと。今後の大きな課題です。\nうまくいってない点 できてない(やろうとしてできてない)点とは別に、どうもしっくり来ていないのがつぎのような点です。\nプログラミングしていると、25分のタイマーで区切りがすごく悪い時がおおい 自宅以外でのタイマー音が出せない 自宅以外での休憩の取り方 プログラミングをやっていて、乗ってきたタイミングでタイマーが鳴ってしまったり、 ちょっと頭のなかで整理していたあとの今まさに、頭のなかにある処理の流れをコードに落としている途中でタイマーがなってしまったり。 このような状況だと、休憩に入れなくて、ずるずるとコーディングを続けてしまうということが多々あります。 メモ(ソース上のコメントや手元)を残して休憩すればいいのでしょうが、どうしても今までの癖もありズルズルとやってしまい、すごく時間が経ってることが何度もあります。 ポモドーロテクニック的にはやはりNGなんでしょうが、なかなか治らない+治したくない気もしています。 また、自宅以外の場合、基本的には自社ではなく客先に出ていることが多いのでどうしても音を出すことができません。 これもまた、切り替えができない要因になっています。 タイマーだけ携帯のアプリを使用しするという手もあるのでしょうが、この場合さらにレコーディングが出来ない状況に陥りそうで。。。 また、スマホだと電池が持たないのも問題点です。(Twitterを見るのに利用してるから電池が持たないという話もあるのですが。。。) レコーディングに関しては、手描きのメモを使うのがいいのかなぁと。本では+や◎などの印を付けるだけにしておけば良いとありますが、アプリのタイマーだと自動でそれができるので、悩みどころです。 最後の休憩の取り方も、ネットやTwitterを見るのもありなのですが、画面から離れる休憩を取りたいなぁと思うところもあり。。。 職場だと技術書やWEB+DBのような雑誌はあるのですが、休憩にはあまり向いていないなぁと。\nつらつらと書いて来ましたが、本を読んで、1ヶ月実践してきた(できてないとこも多いが)現状をメモしておきます。 こうやってるよ、こうしたら良かったよ、こうしてみれば?などありましたら、コメントいただけると助かります。\n来週以降はとりあえず、JIRAできちんとアクティビティ在庫管理をしながら、1日の結果をレコーディングしていくのを意識していこうと思います。\n","date":1367592139,"dir":"post/2013/","id":"db97311c24809f103575d8a7fee19680","lang":"ja","lastmod":1367592139,"permalink":"https://blog.johtani.info/blog/2013/05/03/%E3%83%9D%E3%83%A2%E3%83%89%E3%83%BC%E3%83%AD%E5%9B%9E%E3%81%97%E3%81%A6%E3%81%BE%E3%81%99%E3%83%9D%E3%83%A2%E3%83%89%E3%83%BC%E3%83%AD%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF%E5%85%A5%E9%96%80%E8%AA%AD%E3%81%BF%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2013-05-03T23:42:19+09:00","summary":"アジャイルな時間管理術 ポモドーロテクニック入門 ポモドーロテクニック入門という本を読みました。 きっかけは、Twitter上で何度か「ポモドーロ","tags":["読書"],"title":"ポモドーロ回してます。(ポモドーロテクニック入門読みました)(Jugemより移植)"},{"contents":"まだ、Vote公開されていない、Solr 4.3(2013/04/25 11:00現在)ですが、 ひさびさに訳してみた。詳細まで追っていないので、誤訳があるかもしれないですが。 おかしいとこあったらツッコミを。\n○Solr 4.3.0のChanges ・Upgrading from Solr 4.2.0 1.schema REST APIのcopyFields、dynamicFieldsの出力パスをCamelCaseに。他も同様。(SOLR-4623) 2.Slf4j/logging jarをSolrのwarに含めないことに。すべてのlogging jarはexample/lib/extに。(SOLR-3706、SOLR-4651) 3.SolrCloudでハードコードされてたhostContextとhostPortをdeprecatedに。Solr5.0で削除する。(SOLR-4622)\n・New Features 1.SOLR-4648 PreAnalyzedUpdateProcessorFactoryでPreAnalyzedFieldの機能をほかのフィールドタイプでも使えるようにした。詳しくはJavadocとexampleを見て。 2.SOLR-4623 REST APIで現在のschemaのエレメントをすべて読めるように。REST APIの返却の形式として、XMLとJSONとschema.xmlの形式を追加REST APIのパッケージを変更。 クラス名も変更しschemaにフォーカスした機能も除去。今後のschema以外のREST APIのために。 copyFieldsとdynamicFieldsの出力パスをすべてlowercaseのものからCamelCaseに変更。他のREST APIも同様。 3.SOLR-4658 REST APIリクエストでschemaを変更できるようにするために、「managed schema」を導入。solrconfig.xmlに「\u0026lt;schemaFactory class=\u0026ldquo;ManagedSchemaFactory\u0026rdquo; mutable=\u0026ldquo;true\u0026rdquo;/\u0026gt;」を追加。REST APIリクエストでスキーマ変更が可能にするために。 4.SOLR-4656 2つのハイライトパラメータ(hl.maxMultiValuedToMatch、hl.maxMultiValuedToExamine)を追加。 hl.maxMultiValuedToMatchは指定された数のsnippetが見つかったらそれ以降の探索を停止する設定。multiValuedフィールドがどんなに離れてても探索する。 hl.maxMultiValuedToExamineは指定された数のmultiValuedのエントリ数を調査したら探索を停止する設定。 両方を指定した場合、最初のlimitに達したら停止する。ドキュメント全体をハイライトするためにコピーされるのを削減する。これらの最適化はmultiValuedフィールドに大量のエントリが存在する時に効く。。。 5.SOLR-4675 PostingsSolrHighlighterでper-field/クエリ次のパラメータ指定のサポート 6.SOLR-3755 既存のshardを動的にsplitしてshardを追加するための新コレクションAPI(shard splitting) 7.SOLR-4530 DIH:TikaのIdentityHtmlMapperを使う設定の提供 8.SOLR-4662 solr.xmlにあるSolrCoreの定義よりもディレクトリ構造で見つける。また、solr.xmlのフォーマットを変えて、solrconfig.xmlに近くする。Solrのこのバージョンは旧スタイルの例で提供するが、新しいスタイルも試すことができる。Solr 4.4では、新しいスタイルで提供し、Solr 5.0では旧スタイルは廃止する予定。 SOLR-4347 Adminハンドラで新しく生成されたコアがsolr.xmlに永続化される SOLR-1905 Adminリクエストハンドラで生成されたコアもsolr.xmlに永続化される。また、solr.solr.datadirのようなプロパティの用にsolr.xmlに永続化される問題のfix。 9.SOLR-4717/SOLR-1351 SimpleFacetで同じフィールドに異なるファセットを適用出来るlocalParamsを追加 10.SOLR-4671 CSVResponseWriterのpseudoフィールドのサポート 11.SOLR-4358 HttpSolrServerでuseMultiPartPostでstream名を送信できる ・Bug Fixes 1.SOLR-4543:solr.xml/solr.propertiesでshardHandlerFactoryの設定が動作しない 2.SOLR-4634:Java 8\u0026quot;Nashorn\u0026quot;JavaScript実装の動作に関するscripting engineのテストのfix 3.SOLR-4636:SolrIndexSearcherをオープンする時に何かの理由でreaderがオープンできない時に、ディレクトリがリリースされない 4.SOLR-4405:Admin UIのadmin-extraファイルでcore-menuが表示されない 5.SOLR-3956:group.facet=trueでfacet.limitがマイナスの時の動作 6.SOLR-4650:copyFieldでダイナミックフィールドや暗黙的なフィールドがsourceでマッチしない。4.2で入ったバグ 7.SOLR-4641:Schemaで、illegalなフィールドパラメータで例外が発生するようにする。 8.SOLR-3758:SpellCheckComponentが分散groupingで動作しない。 9.SOLR-4652:solr.xmlプラグインのresource loaderで共有ライブラリの挙動がおかしい 10.SOLR-4664:ZkStateReaderがaliasを更新しても見えない 11.SOLR-4682:CoreAdminRequest.mergeIndexが複数コアやindexDirが複数の場合にマージできない 12.SOLR-4581:Solr4.2で数値フィールドのファセットでマイナスの値があるとソートがおかしい 13.SOLR-4699:Admin Handlerでデータディレクトリの場所がファイルシステムだと思い込んでる。(RAMの場合もある) 14.SOLR-4695:non-cloudセットアップでもコア管理のSPLITが使えるように 15.SOLR-4680:exampleのspellcheck設定のqueryAnalyzerFieldTypeの修正 16.SOLR-4702:exampleの/browseの「Did you mean?」のサジェストをFix 17.SOLR-4710:Zookeeperから全ノードをアップせずにコレクションを削除できないのを修正 18.SOLR-4487:HttpSolrServerからのSolrExceptionがリモートのサーバから戻るHTTPステータスコードを含んでない 19.SOLR-4661:Admin UIのレプリケーションで現在のレプリカ可能なマスタのバージョンを正確に表示 20.SOLR-4716,SOLR-4584:SolrCloudリクエストプロキシがTomcatなどJetty出ないコンテナで動作していない 21.SOLR-4746:Distributed groupingのトップレベルグループコマンドでSimpleOrderedMapの代わりにNamedListを使う。non-distributed groupingと出力形式が異なるため。 ","date":1366856040,"dir":"post/2013/","id":"286a9a4ee373398d7d2c93862c5f6661","lang":"ja","lastmod":1366856040,"permalink":"https://blog.johtani.info/blog/2013/04/25/solr4-3-0%E3%81%AEchanges%E3%82%92%E8%A8%B3%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F/","publishdate":"2013-04-25T11:14:00+09:00","summary":"まだ、Vote公開されていない、Solr 4.3(2013/04/25 11:00現在)ですが、 ひさびさに訳してみた。詳細まで追っていないので、","tags":["solr"],"title":"Solr4.3.0のChangesを訳してみた。(Jugemより移植)"},{"contents":"現在、RC3のVoteをやっている最中(2013/04/24 16:00時点)で、まだリリースされていない、4.3.0についてです。 開発者MLでChangesの書き方を考えないとね、みたいなエントリーが流れてて気になっていたので、訳してみた。 lucene-gosenの実装を変更しないといけないっぽいなぁ。Lucene/Solr 4.2.1以前と4.3.0でI/Fとかが変わることになりそうです。(3.とか8.とか) (ここで力尽きて、それより下はまだ読んでないです。。。)\n○Changes in backwards compatibility policy 1.LUCENE-4810:EdgeNGramTokenFilterが同じ入力tokenから複数のngramを生成した時にpositionを増加させていないのを修正 2.LUCENE-4822:KeywordMarkerFilterがabstractクラスで、サブクラスがisKeyword()メソッドを実装する必要がある。新しく、SetKeywordTokenFilterというクラスにすでにある機能を分解した。 3.LUCENE-4642:TokenizerとサブクラスのAttributeSourceのコンストラクタを削除。代わりにAttributeFactoryをもつコンストラクタを追加。 4.LUCENE-4833:IndexWriterConfigがsetMergePolicy(null)の時にLogByteSizeMergePolicyを使っているのをデフォルトmerge policyをTieredMergePolicyに。また、nullが引数に渡されたらExceptionを返す。 5.LUCENE-4849:ParallelTaxonomyArraysをDirectoryTaxonomyWriter/Readerのためのabstractとして作成。あと、o.a.l.facet.taxonomyに移動。 6.LUCENE-4876:IndexDeletionPolicyをInterfaceではなく、abstractクラスに。IndexDeletionPolicy、MergeScheduler、InfoStreamでCloneableをimplement。 7.LUCENE-4874:FilterAtomicReaderと関連するクラス(FilterTerms、FilterDocsEnumなど)でフィルタされたインスタンスをforwardしないように。メソッドが他のabstractメソッドを実装している場合に。(?) 8.LUCENE-4642, LUCENE-4877:TokenizerFactory、TokenFilterFactory、CharFilterFactoryの実装者は、少なくともMap\u0026lt;String,String\u0026gt;(SPIフレームワーク(Solrとか)によってロードされる)を引数にするコンストラクタを提供する必要がある。さらに、TokenizerFactoryはcreate(AttributeFactory,Reader)メソッドを実装する必要もある。\n","date":1366786800,"dir":"post/2013/","id":"99f5219da22485d0872a2529599c8440","lang":"ja","lastmod":1366786800,"permalink":"https://blog.johtani.info/blog/2013/04/24/lucene-4-3-0%E3%81%AEchanges%E3%81%AB%E3%81%82%E3%82%8Bchanges-in-backwards-compatibility-policy%E3%81%8C%E6%B0%97%E3%81%AB%E3%81%AA%E3%81%A3%E3%81%9F%E3%81%AE%E3%81%A7%E8%A8%B3%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F/","publishdate":"2013-04-24T16:00:00+09:00","summary":"現在、RC3のVoteをやっている最中(2013/04/24 16:00時点)で、まだリリースされていない、4.3.0についてです。 開発者ML","tags":["solr"],"title":"Lucene 4.3.0のChangesにあるChanges in backwards compatibility policyが気になったので訳してみた。(Jugemより移植)"},{"contents":"第2回目も参加しました。 とりあえずメモ。 自分には欠けてる視点の話しなので面白かった。 ちょっと寒かったなぁ。\nエンジニアのためのスキルアップ勉強会『Tech Compass』 #tecomp ― Vol.2 「人気Webサービスの作り方教えます!」 ― 日時:2013/04/23 19:00 場所:パレスサイドビル9F マイナビルーム ◎自己紹介 ●株式会社Zaim/閑歳孝子 小学校3年からFMVで草の根チャットとかにつないでた。(すげー) これがいい記事ですよ。http://www.1101.com/umeda_iwata/ テレビとかで紹介されてるZaimやってます。 3つの基準 ・日常的に使うもの ・普通の人が使うもの ・少なくとも自分は使うもの サービスの良さの基準 縦軸:影響の深さ 横軸:影響する人数 この面積が大きいのがいいんでは。 ●株式会社ワディット/和田裕介 いろいろ作ってます「カウントダウンチューブ」とか「君のラジオ」とか30~40くらい作ってます。 ・「ボケて」ってのやってます。 600万ボケ。アプリ120万DL 僕らがつくるための5Wについて ・なぜ? ・サービスの根本となる「哲学」をみんなで共有できるかが重要 ・内向けのビジョンも大事 ・何を? ・ユースケースで整理する ・いつ? ・つくろう!すぐ作れるようにしようねって感じ ・誰と? ・最強のチーム。意思決定がはやい。 自分主体でサービス設計して、作りなおすのをためらわない ◎ディスカッション Q:どうしてサービス作ったの? A:エンジニアへのあこがれから、サービスを作った(閑歳さん) ものづくりという意味では、Webサービス以外もあるけど?(馬場さん) 学内のSNSのようなものを作ってて、アクセスが伸びるのが面白かった。(閑歳さん) 大学でlastfmみたいなものを研究してて。。。(和田さん) 社会に出てサービスを作るまでの話は?作って稼ごうって思ったのは?(馬場さん) あんまりなかった。(閑歳さん) すでに起業してた。サービス作ると実績として認められて仕事が入ってきてた。(和田さん) 直接あった時に反応がもらえるのが楽しい。(和田さん) Q:どうやって、チームを組み立てたりして開発とかしてきたのか?(馬場さん) A:「ボケて」まとめサイトでブレイクしたけど、アクセス数が落ちてない。 同年代の知人で色々とチームが組めてて楽しい(和田さん) はじめは一人でやってて、しかも構想とか。あとロゴだけ最初に作ってた。 ノマド的に作業してました。(閑歳さん) Q:チームがバラバラですが、困らないですか? A:今のところ困ってないです。もっと人が増えると困るかもしれないですけど。(閑歳さん) それぞれが他に職を持ってるので特に困ってないです(和田さん) 向き不向きはあるんじゃないかなぁ。10人とかになるとどうなるか不明(閑歳さん) GoogleのMLでレスが早ければ問題ないかな。(和田さん) あとは、チームが大きくならないように上手く分割してる(?)(ふたりとも) Q:ユーザの声の吸い上げ方、サービス改善の判断材料は? A:ユーザの声は聞くけど、全部取り込むものではない。 細かな点はユーザの声を取り込むけど、軸はブレないようにしてる(閑歳さん) 古参ユーザよりも新しいユーザを取り込むのが大事。(和田さん) nanapiのけんすうさん Q:品質はどうしてる? A:セキュリティは絶対。(閑歳さん) 品質を気にするってのは難しい。品質を担保できる仕組みを作るとこまでいけるようにしたい。 投稿される画像はチェックしている。(和田さん) ","date":1366717542,"dir":"post/2013/","id":"36ff37ced0d3211db95a5ac0daac0c35","lang":"ja","lastmod":1366717542,"permalink":"https://blog.johtani.info/blog/2013/04/23/%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%82%B9%E3%82%AD%E3%83%AB%E3%82%A2%E3%83%83%E3%83%97%E5%8B%89%E5%BC%B7%E4%BC%9Atech-compass--tecomp--vol-2-%E4%BA%BA%E6%B0%97web%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%81%AE%E4%BD%9C%E3%82%8A%E6%96%B9%E6%95%99%E3%81%88%E3%81%BE%E3%81%99%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2013-04-23T20:45:42+09:00","summary":"第2回目も参加しました。 とりあえずメモ。 自分には欠けてる視点の話しなので面白かった。 ちょっと寒かったなぁ。 エンジニアのためのスキルアップ勉強","tags":["勉強会"],"title":"エンジニアのためのスキルアップ勉強会『Tech Compass』 #tecomp ― Vol.2 「人気Webサービスの作り方教えます!」に参加しました。(Jugemより移植)"},{"contents":"だいぶ、ブログを書くペースが落ちてきてて、危機感を感じている今日このごろです。。。 今回は、個人的に利用しているJIRAのバックアップについて、ブログに残しておこうかと。\nさくらVPSのサーバを借りてJIRAを運用しています。 運用といっても、自分の備忘録のためというのが大半の理由です。 タスクを忘れないように管理するのと合わせて、その作業を行ったときのメモも残したいなと。\nバックアップといっても、同じサーバ内に保存しても意味がない+AWSを触ると言いつつ1年以上経ってしまったので、 このへんで本腰を入れるという意味も込めてAWSのS3(ゆくゆくはGlacier)にバックアップを取る仕組みを作りました。 「作りました」というと凄そうですが、Cronとシェルだけで終わりました、なんて便利な世の中。 ということで、以下は作業の備忘録です。\n1.AWSのアカウント作成 アカウントを作ってください。ここは特に説明しなくてもいいかと。。。クレジットカードの登録が必要なのが注意点でしょうか。 アカウント作成後の1年間は無料枠と呼ばれる仕組みが用意されており、いろんなことが無料で行えます。 (まだ、S3しか使ってないので、他にももっと使わないと。。。)\n2.S3のバケット作成 AWSのアカウントが作成できたら、Amazon S3(Simple Storage Service)のバケットと呼ばれる、データの保存先を作成します。 作成手順はこちらの公式入門ドキュメント(英語)をそのまま行いました。 簡単な手順はこちら\nAWS Management Consoleと呼ばれるところから、S3のコンソールにアクセス 「Create Bucket」ボタンをクリック 「Bucket Name」を入力し、リージョンを選択したら「Create」ボタンをクリック 以上でバケットが作成されました。これだけです。WebのConsoleからファイルをアップロードすることも可能です。 ただ、今回はさくらVPSから定期的にバックアップしたいのでシェルでアクセスできるようにします。\n3.AWSのアクセスキーとシークレットアクセスキーの取得 次に紹介するs3cmdというツールを利用するのに、AWSのアクセスキーとシークレットキーが必要になります。 取得方法はこちらを参考にしましたが、今は日本語のページが用意されています。 セキュリティ証明書(Security Credentials)のページで、「アクセス証明書」というタブで、「新しいアクセスキーを作成する」リンクをクリックしてください。 アクセスキーIDが新しく表示されます。このアクセスキーIDとシークレットアクセスキー(表示リンククリック後に表示される)をメモしておきます。\n4.s3cmdのインストール 世の中には便利なものを作ってくれる方がいるもので。 s3cmdと呼ばれるS3へアクセスできるコマンドラインツールが存在します。 ということで、こちらをインストール。これまた、便利なものでインストール手順を書いてくれれてるブログもありました。(あれ、なんか、見たことある名前がURLにはいってるなぁ) インストールはこちら。\n# yum -y --enablerepo epel install s3cmd インストール後に、先ほど取得したアクセスキーIDを設定します。\n$ s3cmd --configure Access Key: xxxx Secret Key: xxxx 以上で、s3cmdが使えるようになりました。\n5.バックアップスクリプトの作成 つぎは、本題のJIRAのバックアップです。 バックアップ方法はこちらを参考にしました。ちょっと古いみたいですが。 おもなデータは「JIRAのXMLバックアップユーティリティ」にてバックアップするか、「データベースのバックアップツール」を利用する方法があります。 推奨は「データベースのバックアップツール」のようなので、私の場合は「pg_dump」にてJIRAのデータベースをまるごとバックアップすることにしています。 また、データベースには添付ファイルが保存されていないようなので、別途「/var/atlassian/application-data/jira/data」というディレクトリをtarコマンドで圧縮して保存すようにしました。 あとは、pg_dumpの結果と添付ファイルの保存先の圧縮したデータをまとめてディレクトリに保存して圧縮します。 さいごは、S3にアップロードすればおしまいです。 一応、ファイルが連綿と残り続けるのは嫌だなぁということで、ファイル数で世代管理することにもしました。 これまた、ググって見つけてきたサイトを参考にしただけですが。。。 ということで、こんなかんじのスクリプトを日時でcronに設定して動かしてます。\n#!/bin/sh TODAY=`date +%Y%m%d` BACKUP_HOME=\u0026#34;/var/atlassian/backups\u0026#34; S3SYNC_DIR=\u0026#34;/var/atlassian/backups/s3sync\u0026#34; AGE=7 mkdir -p ${BACKUP_HOME}/${TODAY}/ /usr/bin/pg_dump -U postgres -Fc jiradb \u0026gt; ${BACKUP_HOME}/${TODAY}/jiradb_backup.dump tar zcvf ${BACKUP_HOME}/${TODAY}/attachment.tgz /var/atlassian/application-data/jira/data tar zcvf ${S3SYNC_DIR}/jira_backup_${TODAY}.tgz ${BACKUP_HOME}/${TODAY} rm -rf ${BACKUP_HOME}/${TODAY} NUM=`ls ${S3SYNC_DIR} | wc -l` while [ ${NUM} -ge ${AGE} ] do DEL_FILE=`ls -lt ${S3SYNC_DIR} | tail -1 | awk \u0026#39;{print $9}\u0026#39;` rm -r ${S3SYNC_DIR}/${DEL_FILE} NUM=`ls ${S3SYNC_DIR} | wc -l` done s3cmd sync --delete-removed ${S3SYNC_DIR}/* s3://my_jira_backup/s3sync/ そこへんだよとかあれば、ツッコミを。 今のところ、S3へのsyncだけなので、このあとは、月1くらいでGlacierに落とすとかの仕組みも考えるかなぁ。これまた何かあるんだろうけど。 あとは、この応用で家のNASに溜まっている写真をS3経由もしくは直接Glacierにバックアップする仕組みを考える予定です。\n","date":1366639648,"dir":"post/2013/","id":"1ca04e5339ed1826c12fe61fd984e949","lang":"ja","lastmod":1366639648,"permalink":"https://blog.johtani.info/blog/2013/04/22/jira%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92s3%E3%81%B8%E3%83%90%E3%83%83%E3%82%AF%E3%82%A2%E3%83%83%E3%83%97/","publishdate":"2013-04-22T23:07:28+09:00","summary":"だいぶ、ブログを書くペースが落ちてきてて、危機感を感じている今日このごろです。。。 今回は、個人的に利用しているJIRAのバックアップについて","tags":["備忘録"],"title":"JIRAのデータをS3へバックアップ(Jugemより移植)"},{"contents":" HerokuではじめるRailsプログラミング入門 heroku気になってるのに使ってなくて、TDのアカウント作ってデータアップしてない軟弱者ですが、参加して来ました。。。 とりあえず、大事なことです。まずは、上記の書籍を買ってください(って中の人が言ってました。) イベントページはこちら。\n総じて、herokuの中のエンジニアの方たちがすごく情熱があって、ユーザと会話をしたがっているという感想だったようで、まだまだ、よくなりそうだなぁと。 私は、ベースがJavaなので、JavaやScala、Playで使ってる方の感想とか聞きたいかなぁ。 あと、herokuとS3の組み合わせだと思うんですが、料金とかはAmazonとheroku両方に別々に払うのかな?とかはちょっと気になりました。 AWSのアカウントも作ってS3にバックアップあげるの作ろうと思って手をつけてない軟弱者ですが。。。 今月は余裕がありそうなので、TDとか触ってみようと思います。。。\n懇親会ではTDのmuga-sanとお話できて、いくつか気になってた話ができたのでスッキリしました。 あと、株式会社サムライズムの名刺頂きました。写真載せろって言われたけど、また今度w\n最後に、大事なことです。まずは、上記の書籍を買ってください(って中の人が言ってました。)\n以下は、いつものようなメモです。最後の方はちょっとくたばってたのでメモがおざなりになってます、すみません。\n日時:2013年04月04日(木) 18時30分 - 21時00分 場所:日本創生ビレッジ 事業開発支援オフィス 東京21cクラブ コラボレーションスペース ◯Ayumu Aizawa(Heroku, Inc.) ・■ PostgreSQLが9.2になりました。 ・◆ メモリが2倍。βテスタ向けにスケールアップ。 JavaとかJavaとかJavaとかデプロイしてもいいよね。 けど、メモリ2xは価格も2x! ・● Heroku OAuthを提供。Experimentalだけど。 heroku-bouncer使うとOAuthが楽になる。 ◯Treasure Data and heroku Masahiro Nakagawa(TreasureData) ・会社紹介 ・フロントエンド部分の担当(fluentd) ・1500億レコード!? ・投資家の中にHerokuの方がいる。 ・ターゲットは? Cloud + Big Dataが対象 Hadoopは立ち上げるのはいいんだけどメンテナンスコストが。 Hadoopの処理基板を提供 ・Hadoop生ではなく、Plazmaを使っていたりする。 ・Viki herokuにtd-agent入れて、TDにデータ送って、Postgresに書き出して使ってる。 ・TDはどうやってheroku使ってるの? Webコンソール。 http://console.treasure-data.com Webサイトは大体heroku fluentdとかも ・herokuのaddonとしてtd-agentを提供してる。 ・STDOUTからTDにデータ送るのもできるよと。 ◯Waza Report ◯吉田雄哉さん(co-meeting) ・まずは、co-meetingの紹介。 1文字ずつ送信してるよと ・Chief Talk Officerらしいw ・MongoDB使ってるって言ったら、herokuのPostgreSQLの人と話して、鼻で笑われたw ・すごく熱意のある人達がエンジニアとして働いてる ・ユーザの声をきちんと聞いてくれる体制ができてるミーティングだった。 ・「クラウド」って単語を聞いてない。勉強会のレベルもすごい。 ◯山本裕介さん(株式会社サムライズム) ・ニッチなブログ書いてます。 ・Java屋が見るWaza Tシャツプレゼント! ・OSS好きが多い。 Java/Scala系の話が少なかった。Scala界隈では人気みたい ◯岡村純一さん(株式会社シャノン) ・スライド1枚も作らずに喋る人とかいました。 (すごい。。。) ・Django Playに似てて面白いかもと ・Ruby2.0 Matzが喋ってたとか ・クロージングはビールが出てきてた。 交流パーティみたいになってた。CROSSがそれに似てますね。日本でやってるイベント ◯小西俊司さん(株式会社フレクト) ・バックエンドの性能とかを収集して見ることができるツールがあるらしい。 ・クエリを登録しておくと監視ができるツールとか。(TDとかぶってる?) ・やっぱり、情熱的だし、OSS好きでオープンな感じのエンジニアが多い。 ◯Heroku LT 無慈悲なLTです。3分たったらケーブル引っこ抜きます。 (最後はくたばっててあまり聞けてない。。。) ◯山本 裕介(株式会社サムライズム) ・herokuでJava7! Java6終わってますからherokuも移行してね! ◯竹野 淳(Grow!) ・BoxTo? ・コラボレーター募集! ◯小西 俊司(株式会社フレクト) ・ExcelのテンプレートをアップロードしてGETでパラメータわたせばいいよみたいなの作ってる。 ◯大久保英樹(Job-Hub) ・CarrierWaveとかの注意点 ","date":1365128443,"dir":"post/2013/","id":"73d2fce4efa52675b35a11ee97bc2db0","lang":"ja","lastmod":1365128443,"permalink":"https://blog.johtani.info/blog/2013/04/05/heroku-meetup--8-treasuredata--waza-report-%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-herokujp/","publishdate":"2013-04-05T11:20:43+09:00","summary":"HerokuではじめるRailsプログラミング入門 heroku気になってるのに使ってなくて、TDのアカウント作ってデータアップしてない軟弱者","tags":["勉強会"],"title":"Heroku Meetup #8 TreasureData + Waza Report!! に参加しました。#herokujp(Jugemより移植)"},{"contents":"記念すべき!?第10回のSolr勉強会です。\n発表者が無事あつまり(本当にありがとうございました!)、今回も盛況な感じでほぼ満員でした。 ツイートのおかげか、キャンセル処理もちゃんと行なってもらえて助かりました。 開場直後にドタバタしてしまい、すみませんでした。。。\nとりあえず、第一報の記事をアップしておきます。 懇親会での話とか感想はまたあとで。\n関口さんの資料は実は、前もって見たことがある資料でした。 最初の発表にしては、少しむずかしいと思った方もいるかなぁと。 ただ、類義語の辞書は結構作るのが大変だし、探しても出てこないものなので、面白い話だったんではないかなぁと。 「ミスチル」はできないけど、「マツケン」ができるのは読みがあるからとかなんですかねぇ?って質問するの忘れてた。\n尾形さんの話は結構、みんな通ってきた道かもなぁと思いました。他の方も同じ経験してるんじゃないかなぁと。 ただ、一人でやるのはすごいですよね。検索って結構人数が割かれてない場合が多いのかなぁ。 あんまり使われていないというのが少し悲しい話でしたが。。。 サーバを要求すれば結構なスペックが用意してもらえるのはうらやましい限りですねぇ。 スキーマ変更については、レプリケーション機能を使うと追加などならうまくいくんじゃないでしょうか。(そんなツイートもありましたよ。togetter読み返すと出てきます。) フィールド名を変更しないで型を変更するなどしたらおかしくなると思いますが。\n野口さんの話はなかなかチャレンジングでいいなぁと思いました。よく挫けずに頑張られているなぁとw 試行錯誤した仮定も発表してもらえると同じ轍を踏んだ人が助かると思います。 大きな企業で本格的に横断的な社内検索が出来る仕組みが出来上がっているって話はなかなかきかないかなと。 どうしても、社内検索とかお金が出なくて手を付けられないといいう悲しい話が多いので、こういう話は共有したい情シスの方がいっぱいいるんじゃないかなぁと。 ManifoldCFが結構地雷を多く含んでいるのは大変そうですね。。。 SolrにもTikaが入っていたりしますが、個人的にはTikaがやるべき処理は前処理と思っているので、Solrとは別の場所でやりたいとか考えていたりします。 ManifoldCFがその辺りまでやってくれるかまではちゃんと調べてないんですが。 Solrは検索だけに注力させることで、役割を分割できるので、性能の対処とかを行うのが楽になるんじゃないかなぁとか。 ManifoldCFで困ってる人は他にもいるようなので、ジャンジャン使って、どんどんチケット上げて貢献してもらうといいかと。 また、定期的に発表してもらうと面白そうだなぁと。\n弘瀬さんの話は結構興味ある方がいたんじゃないかなと。 SolrCloudは壮大だなぁと思いつつ、手を出しづらいと思ってる方が多いと思います。 実際のサービスに投入して試行錯誤された話を細かな数値も上げて発表してもらえるのは検証をやる方の助けになります。 残念ながら、私もSolrCloudは興味有りつつちゃんと追っかけてないので、途中でnodeとshardとcoreの関係がわからなくなってしまいましたので。。。 もう一度勉強して、スライドを見たいと思います。。。 分散検索(1つのインデックスが複数のcoreやshardに分割された状態)が絡んでくると、複数台の検索の性能のうち、一番遅い性能が最終的な検索性能に響いてくるので、検索リクエストの偏りとかも影響が出たりするかもしれないなぁと。 そういった意味でも試行回数を3以上で計測した結果で再度発表してもらうと面白そう!(なんか、下心見え見えですがw)\n前回、今回も感じたのですが、もう少し質問をしてもらえると発表された方も励みになるかなぁと思いました。 質問しにくい雰囲気になってるのでしょうか?参加者が結構いるから質問しにくく感じたりするのでしょうか? そのあたりをもう少しうまくやれるようになにかコメントもらえると嬉しいかなぁと。 運営で気になった点などもコメントやツイートをいただけると今後の改善にも役立てますので気兼ねなく連絡いただけると助かります。 開場がドタバタしすぎとか、ハッシュタグがわからなかったとか。\n今回は思ったよりも懇親会に残る方が少なめでした。 コミッターの方(LuceneやManifoldCFとかlucene-gosenとか)が複数いたり、Solrを結構触ってる方がいたりと面白い話が聞けそうだったのですが。。。 Kuromojiのユーザ辞書の改良点をチケットにあげるって約束したのでやらないとなぁ。 早く帰るつもりだったのに気づいたら23時でしたwやっぱり色々と話ができるのが楽しくて。。。 駅前の機動隊とかびっくりしながら帰りました。 今回、お話ができなかった方もいらっしゃるかと思いますが、気兼ねなく、ツイートしてもらったり、声をかけていただければと。\nあと、常に発表していただける方は歓迎しておりますので、連絡いただけると非常に助かります! こんな話が聞きたいなどでもいいかと思いますので、連絡いただければと。\n#SolrJPもtogetterにまとめてもらいました。ありがとうございます。 以下は、いつものメモになります。\n日時:2013/03/26 19:00 to 21:00 場所:VOYAGE GROUP 会議室 1. 株式会社 ロンウイット 関口 宏司さん タイトル:Wikipediaからの類義語知識の自動獲得について 発表資料はこちら\n・「辞書型コーパス」という単語は造語かもしれません。 ・なんでこんなことを? →類義語辞書を自動生成したいから。 ・自賠責保険、自動車賠償責任保険を例にSynonymFilterの説明。 ・Wikipediaを入力として、類義語辞書を作成するときにLuceneのインデックスを活用してる。 ・類義語候補の見つけ方 いくつかヒューリスティクスな処理とかも入れてます。 日本語Wikipedia固有なもの。 ・実際に導出された単語も載ってる。 FTPなども導出で来てる。 丸ビルとかも。 ・導出できなかったものもあります。 「十六進法」が「十進法」になってる 「ミスチル」も無理。 ・ミスもあるけど、類義語が存在しない場合になんとなく、使う辞書としては採用できるのでは? 類義語検索対象のブーストを小さくするなどをすれば役に立つ Q:類似度にしきい値を用意したりしてますか? A:min.scoreという値を用意し、足切りをしている。 Q:ベクトルを作るという話があったが、品詞でフィルタリングとかしてる? A:名詞に限って処理してます。名詞に限らなくてもいいかも。。。(若干聴き逃しました) 重みの高いn件をベクトルの対象にしてます。 2. グリー株式会社 尾形 暢俊さん タイトル:GREEにおける全文検索の歴史 発表資料はこちら\n・GREEさん、検索はないがしろにされてる。。。 一人でつくって、一人でメンテナンスしてる。 ・GREEの検索は右上の検索ボックスが ・2007年はSennaつかってました。 Tritonnに移行。2009年くらいまで。 やっぱり安定しない+MySQLのバージョンアップしたいけど、追従できない ・2012年初頭までLuceneでやってた。(結構古い) フラグメントが発生してOptimizeすると、検索サーバが使えなくなる。。。 検索しにくるサーバが1000台いるので、Optimizeかけるときに、1000台のサーバの設定を書き換えるとかしてた。。。 ・現在まではSolrをつかってる。 Luceneのバージョンも古かったので100倍くらい速くなった。 ・Solr本が必須ですよ!!! ・Lucene+Tomcatから移行。 移行に気をつける点として、I/FをそのままSolrに置き換えると。 Solr返却のXMLをカスタマイズしたり、クエリをSolr向けに書き換えたり。 あと、メンテナンスが楽になるように。 40数台のインデックスサーバがあると。 一人でメンテナンスしてるから、楽になる方法が重要 ・レプリケーションで、Optimizeの影響が出ないように。 キューをつかって、マスタに登録して、スレーブにレプリカを配布 ・スキーマが7つ あんまり使われてなくてかなしい。。。 ・負荷のグラフもありました。 ・RangeQueryを結構使う。 ・作りこんだ部分 インデックスのMasterへ分散させる処理とか クエリの変換とか人力監視処理とかNGワードとか サーバ監視のための仕組み ・今でも大変なこと スキーマ変更が大変 スレーブをマスタに昇格とかが手動 ・今後改善したいこと 精度を上げたい 辞書を使ってみたいけど、各国語対応 あと、自動化とか 3. ソフトバンクBB株式会社 野口 勝義さん タイトル:企業内の大規模ファイルサーバ検索事例 ・情シスの企画版?という立場のかた。 ・売上に貢献したいのでクラウドサービスとして検索をオプションとして立ち上げてみた! ・Solr+ManifoldCFで作ってみたよと ・なんでSolr? OSSだし、機能が充実 ・なんでManifoldCF? Active Directory連携が使いたかったと。 社内検索ってやっぱりアクセス権がうるさいので。 ・ManifoldCFの説明はロンウイットさんの画像を使わせてもらいましたw ・ファイルサーバが、70TB。。。 ・困ったこと。 ・その1 ・クローラージョブの構成の最適化どうする? ・マルチコアで、クローラーとファイルサーバを1対1の構成にしてみた。 ・その2 ・ファイル数が増えるとまた問題が。。。 ・ファイルサイズが大きい→Heapが足りないエラーとか、MCFのタイムアウトとか。。。 ファイルサイズのリミットを設けてみた。 mp4とかでエラーがでるとか。既知のエラーでしたとか。 ulimitがたりないとか。 MCFの稀に出るバグとか。。。 ファイルサーバの不良ブロックとか。。。 ・その3 ・クロールに時間がかかる ・MySQLでスロークエリとか MySQLよく知らないとか言われながらコミッターに対応してもらうなど。 SSDつかうとか考え中 ・フルクロールで1週間 差分でも1日強かかる。 ManifoldCFだけで対応できないから、ファイルの特徴を元に →ManifoldCFを経由しないリアルタイムインデックス更新のAPIを経由してMasterじゃなくて、更新かけると。(特定のクライアントからの方法) ・その4 ・本文データをstored=falseに けど、ハイライトできないから、どうにかしたい ・ユーザの要望 ・もしかして検索 類義語?じゃないよねぇ。テザリング、tezaringuとか フロント側で頑張った。(Solr諦めました) ・検索スコアも弄りたいとか 外部データでブーストとかもしたい。External Fieldとか使うといいのでは?とか。 4. 株式会社サイバーエージェント 弘瀬 健さん タイトル:SolrCloudの導入事例 発表資料はこちら\n・Webエンジニアだったのに、検索エンジニアに! ・SolrCloudもサービスインしてると。 ・SolrCloud概要 4.0以降の機能とか。 ・SolrCloudの構成要素 概念的なもの。Collection、Shard 物理的なもの。Node、Core ・ Simplogってサービスに導入済み。 ZooKeeperが3台、6Shard、3nodeという形式 ・性能 平均レスポンスタイム50msec 思ったより出てないので、調べてみた。node数とかshard数を変えてみて調べてみた(まだ、模索中。) ・色々テストケース試したけど、試行回数が1回だけです。 詳細なデータが出てるのありがたい(全部はまだ理解できてないですw) ・検証まとめ ノード当たりのcore数が少ないほうが検索、更新性能がいい 1コレクション当たりのshard数が少ないほうが検索性能がいい ・まとめ ・SolrCloudの利点 クライアントが色々意識しなくていいのがうれしい。 ・SolrCloudの注意点 shardの分割機能がまだないので、大変。 コレクション情報が壊れると検索更新できないとか。4.0だとバグが有った ・性能的には素のSolrのほうがいいよと。 ","date":1364300160,"dir":"post/2013/","id":"26d0c0d8c465087cf160a3bdc479f2b4","lang":"ja","lastmod":1364300160,"permalink":"https://blog.johtani.info/blog/2013/03/26/%E7%AC%AC10%E5%9B%9Esolr%E5%8B%89%E5%BC%B7%E4%BC%9A%E3%82%92%E4%B8%BB%E5%82%AC%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-solrjp/","publishdate":"2013-03-26T21:16:00+09:00","summary":"記念すべき!?第10回のSolr勉強会です。 発表者が無事あつまり(本当にありがとうございました!)、今回も盛況な感じでほぼ満員でした。 ツイー","tags":["勉強会"],"title":"第10回Solr勉強会を主催しました。#SolrJP(Jugemより移植)"},{"contents":"なんか、とても久しぶりにイベント参加メモ以外の投稿です。 elastic searchのMLを見てたら、KuromojiのAnalyzerを使うときにユーザ辞書使うのどうするの?という投稿を見かけました。\nKuromojiのユーザ辞書にもちょうど興味があったり、elasticsearchもちょっとずつ触りたかったのでちょっと試してみました。(返信もしてみましたが、テキトーな英語です。。。)\nelasticsearch-kuromoji-pluginのインストールなどはElasticSearch で kuromoji を使う (ES 0.90.Beta1 + kuromoji 1.2.0篇)を参考にしてください。 私もこちらに記述のある組み合わせ(elasticsearch-0.90.0Beta1 + elasticsearch-analysis-kuromoji/1.2.0)を利用しました。 KuromojiのAnalyzerはデフォルトで「kuromoji」として登録済みですが、こちらはユーザ辞書の指定がありません。 ということで、「kuromoji_user_dict」というユーザ辞書指定をしたtokenizerと、それと使う「my_analyzer」というanalyzerを登録したIndexを作成します。 定義する前に、「userdict_ja.txt」を用意して、elasticsearch-0.90.0Beta1/config/ディレクトリに配置しておきます。 (以下のサンプルでは、SOLE_HOME/example/solr/collection1/conf/lang/userdict_ja.txtをコピーして使いました)\n$ curl -XPUT \u0026#39;http://localhost:9200/kuromoji_sample/\u0026#39; -d\u0026#39; { \u0026#34;index\u0026#34;:{ \u0026#34;analysis\u0026#34;:{ \u0026#34;tokenizer\u0026#34; : { \u0026#34;kuromoji_user_dict\u0026#34; : { \u0026#34;type\u0026#34;:\u0026#34;kuromoji_tokenizer\u0026#34;, \u0026#34;user_dictionary\u0026#34;:\u0026#34;userdict_ja.txt\u0026#34; } }, \u0026#34;analyzer\u0026#34; : { \u0026#34;my_analyzer\u0026#34; : { \u0026#34;type\u0026#34; : \u0026#34;custom\u0026#34;, \u0026#34;tokenizer\u0026#34; : \u0026#34;kuromoji_user_dict\u0026#34; } } } } } \u0026#39; 「user_dictionary」というのがユーザ辞書の定義ファイルになります。 注意点としては、6行目で指定した名前「kuromoji_user_dict」を14行目の「tokenizer」に指定しないとちゃんと動かないという点でしょうか。\n上記で指定したAnalyzerを利用して「朝青龍」という単語をを解析してみます。\n$ curl -XGET \u0026#39;http://localhost:9200/kuromoji_sample/_analyze?analyzer=my_analyzer\u0026amp;pretty\u0026#39; -d \u0026#39;朝青龍\u0026#39; { \u0026#34;tokens\u0026#34; : [ { \u0026#34;token\u0026#34; : \u0026#34;朝青龍\u0026#34;, \u0026#34;start_offset\u0026#34; : 0, \u0026#34;end_offset\u0026#34; : 3, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 1 } ] 「朝青龍」という単語がユーザ辞書に登録されているので、1単語として出力されます。 ちなみに、デフォルトの「kuromoji」のanalyzerを指定すると以下の様な出力です。\n$ curl -XGET \u0026#39;http://localhost:9200/kuromoji_sample/_analyze?analyzer=kuromoji\u0026amp;pretty\u0026#39; -d \u0026#39;朝青龍\u0026#39; { \u0026#34;tokens\u0026#34; : [ { \u0026#34;token\u0026#34; : \u0026#34;朝\u0026#34;, \u0026#34;start_offset\u0026#34; : 0, \u0026#34;end_offset\u0026#34; : 1, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 1 }, { \u0026#34;token\u0026#34; : \u0026#34;青龍\u0026#34;, \u0026#34;start_offset\u0026#34; : 1, \u0026#34;end_offset\u0026#34; : 3, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 2 } ] とまぁ、こんなかんじです。 ユーザ辞書を書き換えたあとは「close/open」しないと読み込めないのかなぁ?そのへんはまたあとで調べようかな。\nちなみ、以下のページを参考にさせてもらいました。 elasticsearch kuromoji plugin - natural days ElasticSearch で kuromoji を使う (ES 0.90.Beta1 + kuromoji 1.2.0篇)\n","date":1363765380,"dir":"post/2013/","id":"f5f28f42ad234b4389af4cbea54ff60d","lang":"ja","lastmod":1363765380,"permalink":"https://blog.johtani.info/blog/2013/03/20/elasticsearch-analysis-kuromoji%E3%81%A7%E3%83%A6%E3%83%BC%E3%82%B6%E8%BE%9E%E6%9B%B8%E3%81%AE%E5%88%A9%E7%94%A8%E6%96%B9%E6%B3%95/","publishdate":"2013-03-20T16:43:00+09:00","summary":"なんか、とても久しぶりにイベント参加メモ以外の投稿です。 elastic searchのMLを見てたら、KuromojiのAnalyzerを使うときにユーザ","tags":["elasticsearch"],"title":"elasticsearch-analysis-kuromojiでユーザ辞書の利用方法(Jugemより移植)"},{"contents":"久々にブログ+イベント参加です。 知り合いが開催+出演したので参加してみました。 「スマホ」ってキーワードはあまりなかったけど、面白かったです。\nとりあえず、メモ。 余力があれば感想追加します。\n日時:2013/03/19 19:00 場所:パレスサイドビル9F マイナビルーム (東京都千代田区一ツ橋1-1-1) URL:http://atnd.org/events/36966 登壇者:@naoya_ito @yusuke ◯@naoya_itoさんの発表 最近、感心してること。 ・RubyMotionやってます。 今年5月に ・AWSもやってるよ。 ・「継続的デリバリー」の話 GREEでは毎日デリバリーしてるよと。 ・Chefの話 DevOpsとか。 ・Obama for Americaの話 GitHubとか使ってた。 身に付けるべきものは? 「変化に適応する力」が必要だよね。 最近は Ruby、クラウド、AWS、iOS開発とかやってる、どうしてこうなったw 先は予測してないけど、変化に適応するには5分でいいからやり続けること。 ◯@yusukeさんの発表 自己紹介が難しい ・今やってること ブログ執筆 刺さるツイート研究 ソフトウェア販売代理店 思わぬ収穫。InDesign/Illustratorのスキル、ビジネスの仕方w 会社設立中。 Webサイト構築・運用 ・ハッタリが大事 ・プログラム好き プログラミング以外を仕事にしてる。 ・人と違うことがしたい。市場がない場所での差別化はしない=トレンドに逆行し過ぎない。バランス。 ・今は種まき中。 ◯ディスカッション ・2,3年後とか何やってると思いますか? @naoya_itoさん ドラクエやってると思ってるかもしれませんが、サービス作るコード書いてます。 将来的な見通しでやってるのか?って言われるとそうでもない。 ツールとかよりは、コミュニティとかのサービスを作るほうが好き。 @yusuke 一定の収入がありつつ、プログラミングしてたい。あわよくばサービス作ったのが当たるといいなぁ ・そもそもフリーランスをどう捉えているか? @naoya_ito いいところ。自由に自分の時間をコントロールできる。 悪いところ。自分でコントロールしないといけない。 自分をコントロールしないと厳しい。 フリーになってわかったのは、会社は人間を働かせるための仕組みをよく考えて出来てる。 フリーでいいのは、選択した結果に自分が責任を持つというのがいい。 @yusuke セフルマネージメントできたほうがいい。 しがらみを捨てるためにフリーになるのはおすすめしない。 ・情報発信を継続してるけど、必要なことか? @naoya_ito 必要とは思わないけど、みんな書いたらいいと思う。 検索すれば自分が助かるからw セルフブランディングのために重要?かなぁ。あまりそれが唯一の方法ではないと思う。 @yusuke 発信することで、何に興味を持ってるかをわかってもらえるから、便利かな。 ブログに残したほうがググって引っかかるよと。 ・技術の方向性?見つけ方?は? @naoya_ito 直近は、クラウド流行るしiOSはまだ伸びてるしと。 そっから先はどうするの? わからないよね。じゃあ、どうするの?って変化に対応してボトムアップで見つけてくのがいいんじゃないかなぁ。 人がやってないところを先にやらないと武器にならないけど、どうやって見つけるのか? プログラミングやってる時に、その先に必要なこととか、気付きがあるので、手を動かさないとだめだよねと。 @yusuke トレンドを追いかけつつ、知ったかぶりするのは重要 ある程度ハッタリ+手を動かす ","date":1363692480,"dir":"post/2013/","id":"5412fb82160d0f6093e4b6670f505c13","lang":"ja","lastmod":1363692480,"permalink":"https://blog.johtani.info/blog/2013/03/19/%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%82%B9%E3%82%AD%E3%83%AB%E3%82%A2%E3%83%83%E3%83%97%E5%8B%89%E5%BC%B7%E4%BC%9Atech-compass%E7%AB%B9%E6%A9%8B--vol1-%E3%82%B9%E3%83%9E%E3%83%9B%E6%99%82%E4%BB%A3%E5%88%B0%E6%9D%A5%E3%81%93%E3%81%AE%E5%85%88%E7%94%9F%E3%81%8D%E3%81%AE%E3%81%93%E3%82%8B%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E3%81%AF%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-tecomp/","publishdate":"2013-03-19T20:28:00+09:00","summary":"久々にブログ+イベント参加です。 知り合いが開催+出演したので参加してみました。 「スマホ」ってキーワードはあまりなかったけど、面白かったです。","tags":["勉強会"],"title":"エンジニアのためのスキルアップ勉強会『Tech Compass』@竹橋 ― Vol1 「スマホ時代到来、この先生きのこるエンジニアとは!?」に参加しました。#tecomp(Jugemより移植)"},{"contents":"技術ブログから離れていってますが。。。 Xperia Zを購入しました。\n前に使っていたのはXperia arcになります。 もうすぐ2年だったのですが、容量不足に悩まされていたため+芸の肥やし(仕事の足し)という名目で Xperia Zの購入に踏み切りました。 予約しての購入です。\nいくつか戸惑いなどを感じているので備忘録としてブログに残しておきます。 サイズが大きい___ まぁ、わかっていたことですが、5インチと大きいです。 ステータスバーを表示するのがちょっときついくらいです。 私は手が大きい方なのですがそれでもキツイので、普通の人は両手じゃないと厳しいんじゃないかと。。。 一応、ステータスバーを表示するためのアプリなんかもあるようなので、その辺を検討するのもいいかなぁと(まだインストールもしてませんが。) また、Angry Birdを演ってびっくりしたのですが、解像度が大きいため、startボタンなどが小さくて押しづらいですw\n移行がめんどくさい___ iPadも持っていて、ソレと比較するとひどくめんどくさかったです。 実は方法を知らないだけかもしれないんですが。。。 iPadだと、初期化したりしてもiTunesにインストールしたアプリなども覚えていてくれます。 ですので、すぐに同じ環境が出来上がります。 Xperiaに関しては、arcでインストールしてたアプリをインストール履歴を元に一つずつインストールして、 それぞれのアプリやアカウントを設定して行きました。 これが結構面倒で、まだ完全にはアプリがインストールできてないかも(他にも新しいものを入れたいなぁと思いつつ、探す手間を惜しんでます。。。おすすめアプリお待ちしてます。)\nZite、Angry Bird star warsがインストールできない___ Ziteは英語の勉強も兼ねて入れていたのですが、対応していないバージョンですと言われます。 AngryBirdもいっしょですね。 starwarsじゃない奴はインストールできたのですが、肝心のやってみたいstar warsがインストールできなくて。。。\nドコモアプリがいっぱい___ ドコモのアプリやプリインストールアプリがいっぱいあったので、どうしようか悩んでいます。 いくつかはアンインストールしました。HotpepperBeautyとか間違いなく使わないし SFA-QRというよくわからないアプリも入っていたのでこれまたアンインストールしました。\n通知に出さないアプリとか選択できない?___ 容量不足だったのも有り、TwitterクライアントにはTwiccaのみをインストールしていたのですが、今回はTwitter純正のクライアントもインストールしました。 お気に入り登録されたりといった状況も見れるので重宝するのですが、基本的にはtwiccaを使うつもりです。 ですが、通知バー(ステータスバー)に@ツイートが届いたなどといった通知は見なくてもいいと思っているんですが、なにか方法あるんでしょうか。\ndビデオが危険___ いわゆる携帯ショップで機種変更したため、いくつかのサービスに登録しないといけませんでした。 で、dビデオ(月額525円で映画とか見放題)に登録したので、せっかくだからと映画をダウンロードしてみたのですが、危険です。。。 ただでさえ、本読むのが遅かったり、コーディングしてないのにビデオ見ると更に時間ががが。。。 けど、面白くて。。。危険です。(スターシップ・トゥルーパーズ見ちゃいました。。)\nクレードルがもう一つほしい___ 防水なので、あまりキャップを開けたくないんです。 そして、dビデオとか見てるとやっぱり電池の減りがはやいんです。(ディスプレイが大きいのもあるのかなぁ。要らないサービス切るとかしないと) 結局、出先でも充電をしないといけなくて。 ただ、純正のクレードルが2100円と結構な値段でして。。。 あと、イヤホンを指すところもキャップがあるので、Bluetoothレシーバーも気になってたりします。 こちらも結構な値段でして。。。\nとまぁ、新しいものを手に入れて、色々悩んでますが、楽しいですね。購入したての色々と悩む時間がw おすすめアプリとかあったらコメントください\n","date":1360687980,"dir":"post/2013/","id":"b051fd352847c06e748b345e8ed0738b","lang":"ja","lastmod":1360687980,"permalink":"https://blog.johtani.info/blog/2013/02/13/xperia-z%E8%B2%B7%E3%81%84%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2013-02-13T01:53:00+09:00","summary":"技術ブログから離れていってますが。。。 Xperia Zを購入しました。 前に使っていたのはXperia arcになります。 もうすぐ2年だったのですが、容量不","tags":["備忘録"],"title":"Xperia Z買いました(Jugemより移植)"},{"contents":"金曜日に引き続き、イベントに参加して来ました。(仕事。。。これも仕事だよ。)\n「Hadoop Conference Japan 2013 Winter」です。 普段、Hadoopを触るのも少ないのですが情報を仕入れときたいなぁということで。 今年はビッグサイトですよ。そろそろ無料のカンファレンスもキツイのではないでしょうか。。。 こちらの写真はセッション会場。今回もすごいです。。。 簡単ですが、聞いていた感想です。 全体的に、Hadoop本体の話ではなく、エコシステムと呼ばれる周辺のプロダクトの話や実際に運用している実例が増えていました。 だいぶ普及期に来たのかなぁと。そして、自分の不勉強を実感できたなぁと。 (あと、TreasureDataに絡む話が多いなぁと言うのも印象です。そういうセッションを選んで出ていたのかもしれませんが) 懇親会まで残っていたのですが、結構、すごい方たちの顔ぶれだなぁというのを今更ながらに実感するとか。 (ハチ象Tシャツを着ているすごい集団でもありましたが。。。)\n以下はいつものメモになります。だいぶ金曜日のイベント後で腑抜けてるのでメモが雑ですが。\n◯ご挨拶 Doug Cuttingさんのビデオ(あんまり聞けてない) さすがのhamakenさんのトークの安定感。 後援はリクルートテクノロジーズさんが大半。 リクルートテクノロジーズの米谷さんが軽く発表 ◯LINEのHBaseを利用した大規模なメッセージストレージ:NHN Japan 中村 俊介 まずは、LINEの紹介が続く。 New Yearのメッセージは3倍位だったけど、何とかなっったよと。 データロスがない。 サーバ故障からのデータリカバリも自動でやってくれる 書き込み1ms、読み出し1-10msでできてる ・IDC onine migration クライアントベースで2つに書き込み Incremental replication(新データ)、BulkMigration(旧データ) 元のHBaseのレプリケータは利用してない(pushだったから。スループットコントロールしたかったから) ・NN failover 2012.10にNameNode障害発生 HA構成にしてたから問題が発生。 VIPはHDFSにつかうとリスキー 現在: 少ないダウンタイムを許容する ・Stabilizing LINE message cluster ※あとでHBase触るときに資料見直すくらいで。。。 Case1:Too many HLogs Case2:Hotspot問題 まぁ、けど1億ユーザのインフラとして使えるってすごいよな。。。 ◯Hadoop meets Cloud with Multi-tenancy: Treasure Data 太田 一樹 TDもFluentdも有名だなぁ Hadoopのメンテナンスとか、つらいよねというのを見てきたのでTD作った ・なぜ、BigData+Cloud? Hadoopだけみてもバージョンが混在してる+ディストリビューターも多くなってる 十徳ナイフみたいになってきてるけど、必要なのはナタだよね。というのを提示するためにTD立ち上げた。 ・なぜCloud? ・IaaSベンダーの対象としてるのはSCM。 オンプレだとHWが陳腐化してくよね→HWはクラウドが主流に ・PaaS、SaaSの対象は時は金なり バージョンアップとか大変だよねと ・TDのご紹介 唯一の解析用DBを目指して ・哲学とアーキテクチャ 解析とか運用をいかに楽にしていくかというのを主体においたサービスを提供したい? いかに速くレポーティングシステムを簡単に構築していくかとかの話 簡単なインタフェースと目的に集中することで、価値を提供 ・AWSとの違いは? ・アーキテクチャとか技術的な話 データを集める処理がデータ解析に実際には重要なフェーズ ・カラム指向でデータ保存 実装がどーなってるのかとか、TD内部のHadoopクラスタの運用、バージョンアップとかがどうなってるのかもきになる。(企業秘密だろうけど) ◯Amazon Elasti MapReduceとHadoopコミュニティの関わり:Amazon Web Services Peter Sirota ・3つのV Volume、Velocity、Variety ・yelpのAuto-suggestの例 カスタマーのレコメンデーションにElasticMapReduce使ってるよと。 ・razorfishの広告インプレッションの解析に使ってる ・Amazon.comでの話 AWS Public Datasetsの話 http://aws.amazon.com/jp/publicdatasets/ IonFluxのDNA解析の話 ・いろんな分野でのBig Data 事例がちらほら ※わかりやすい英語なんだけど寝不足が。。。 ◯ランチ! サンドイッチと豚汁とあとなんとかライス。 TDブースにて、fluentdのTシャツもらったよ! ◯Hadoop\u0026#39;s Power to Transform Business:MapR Ted Dunning ・Mahaut+Solrの単語が。8時間のレコメンデーションデータの作成が3分に?? ・Stormにてリアルタイム処理と連携。バッチ処理はMRで。 ・バッチ処理とリアルタイム処理の間としてのDrill ・Drillの概観とできるところの話。 (あとでスライドで)データ解析のために機会学習の処理とかも投げられそう。 Q:ImplaraとDrillの違いは? コミュニティベースかなどが違うよね(あまり聞き取れず) Q:Drillの開発はどのくらいすすんでるの? A:。。。 Q.クエリ言語としてSQLがいいの? A.No。というのも、単独の言語ですべてにベストというのはないから。SQLはわかりやすくて良いが、実行が非効率な場面も。 ◯Introduction to Impala~Hadoop用のSQLエンジン~:Cloudera 川崎 達夫 ・Impalaとは 分析に特化した低レイテンシクエリ実行基盤 Apacheライセンス バッチ処理要ではなく、データサイエンティストが試行錯誤するときに利用するのを想定 パフォーマンスが良い 実行エンジンはC++とかで実装されてる MapReduceに依存してない ・MapReduceの問題点 MR直接は難しい→Hiveとか、M/Rの実装を隠して使いやすくするものが増えてきた Hiveを例に説明。MRがベースなので高レイテンシ ・Impalaのアーキテクチャ 機能制限やGA版について言及されてる資料なのが良い ・GA以降の話もあり ピンチヒッターなのに落ち着いて発表とか凄すぎです。 jdbcサポートも入ると。 プランナーはjava実装 Hiveとの互換性は?→完全互換を目指す。 開発のプロセスが見えにくいのでは?開発主体がcloudera ◯Flumeを活用したAmebaにおける大規模ログ収集システム:CyberAgent 飯島 賢志 立ち見。 Flumeのコミッターの人がCAにいたんだ。 ◯Log analysis system with Hadoop in livedoor 2013 Winter:NHN Japan 田籠さん@tagomorisさん ・NHNJapanのお話 ・Webサービスのログ解析について話していく 400+Webサービス ・2011年8月にLTしました。 ・1.5TB/day。。。 ・batchとstream Batch集計も重要だし、Stream処理も重要なので、ハイブリッドシステム ・システムーバービュー FluentdClusterを中心にして各種ツール、保存先に転送してる。 これが結構重要。だけど、今日はFluentdの話ではない ・Fluentd周りを一人でやってるのか。。。 ・処理の流れ ・ログの収集と、生ログ保存 ・パース(主にHive用に)、変換、フラグ追加(分類しておくとあとで集計したいとか、保存すべきかを処理可能に) ・Hiveにロード ・第1世代のはなし すべてbatch処理、Scribe 遅延が1時間ちょっとあるため、Hiveクエリで結果が見れないとか。 ・第2世代の話 Fluentdのstream処理にHadoop Streamingを呼び出せるようなプラグインを書いた Fluentd+HoopServerの構成 ・第3世代 HoopをWebHDFS Fluentdでのオンライン集計 GrowthForcast、HRForcast ・第4世代(ここ1週間でやったこと) CDH4でQJMベースのNameNode(Failoverは手動) Hiveのスキーマを変更(これはブログに今度書くよ) とりあえず、現時点で改善点が思いつかない ・総括 HTTPベースでRPCベースにしたのでコンポーネント切り替えが結構楽 OSSで公開されてるからいいよね 公開することにより色々とドライブするよ! ◯いかにしてHadoopにデータを集めるか:Treasure Data 古橋 貞之 ・自己紹介 ・ビッグデータ収集の問題点 ・壊れたデータが入ってる ・読み書きの時間がかかる ログはサブケースである。メインはサービスとかだから。 ・トライ&エラー処理が時間かかる ・データを分割するのが基本的なアイデア 失敗した時のリトライが楽になる。さらに、それをStream処理すれば良いよねと。 ・flumeのお話 ・fluentdのお話 バッファリングは性能アップも兼ねてる 設定のクラスタへの伝搬とかインストールはpuppetとか使おうねと。 プラグインのインストールが楽 ・いくつかのプラグインの紹介 ・TDへのデータ投入のお話 ・最後にmuddydixonさんのプラグインの宣伝がw ◯Hadoopの次に考える分散システム技術:Microsoft 萩原 正義 ・CAP定理の克服をどうしていくか ・CAPのおさらい ・Lease クライアント主導、サーバ手動とか (理論重視の話で最後のセッションには辛かった。。。頭が疲れててついていけませんでした) おまけ 今回頂いたノベルティなどを写真に撮ってみました。(ランチはお腹すいてて写真取らずに食べちゃいました。。。) Hiveロゴへの愛を語ってHive Tシャツをゲット。 FluentdのTシャツももらいました! Hiveステッカーなどもゲット あと、メッセージボードなるものがあったので書いてみました。一応、Hadoopに絡んだことですよね!?\n","date":1358783400,"dir":"post/2013/","id":"bf4f86812812dab8d39db9aaefe94a78","lang":"ja","lastmod":1358783400,"permalink":"https://blog.johtani.info/blog/2013/01/22/hadoop-conference-japan-2013-winter%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-hcj13w/","publishdate":"2013-01-22T00:50:00+09:00","summary":"金曜日に引き続き、イベントに参加して来ました。(仕事。。。これも仕事だよ。) 「Hadoop Conference Japan 2013 Winter」です。 普段、Hadoopを触る","tags":["勉強会"],"title":"Hadoop Conference Japan 2013 Winterに参加しました。#hcj13w(Jugemより移植)"},{"contents":"1/18(金)に開催された、エンジニアサポートCROSS 2013で「検索CROSS」セッションのセッションオーナー(モデレータ)をやって来ました。\n@muddydixonさんに昨年の夏くらいに声をかけていただいたのがきっかけです。 こういったイベントの運営のお手伝い(ほとんど何もしてない)も初めてでしたし、セッションオーナー(モデレータ)も初めての経験で色々といい勉強をさせて頂きました(自分の足りない所とか、考慮すべき点がどういったところにあるとか)。本当にありがとうございます。\nスピーカーとして登壇していただいた久保田さん、佐藤さん、安田さんほんとうにありがとうございました。 頼りないオーナーで、モヤッとした内容を提示したにもかかわらず、意図を汲み取って話の内容をふくらませていただいてすごく助かりました。 また、会場にお越しいただいたみなさん、ありがとうございました。すこしでも検索に興味をもっていただければ、セッションは成功だったと思っています。 朝一だったのと、私の認知度の低さもあったのとで残念ながら満席とはいきませんでしたが。。。\n後日、録画されたセッションの内容を見て色々と反省しようかなぁと。。。 緊張していたので、うまくモデレートできてたのか、話ができていたのか不安ですが。 忌憚ない感想をお待ちしています。\nということで、反省終わり!ここからは、イベントの感想と聞いたセッションに関する感想です。\n###聞いたセッション\n####企業CROSS DeNA x グリー x Aiming: 大企業・ベンチャーが語る「スクラム」開発 (仮)\nGoogleの及川さん見たさで参加しました。 スクラム自体は名前くらいは聞いたことある程度だったのですが、その程度の私でもわかりやすいディスカッションで楽しかったです。 聞いていて感じたのは、次のようなこと。\n「スクラム」という開発手法の話しなんだけど目的はそこじゃなくて、どうやってうまくプロジェクトを回して(ドライブして)、目的(サービスを作るとか顧客の要望を叶えるとか)を達成するかというのが重要だなぁと。 「スクラムマスター」の仕事は子育てに似てる 「スクラムマスター」になりたい人はなかなかいないらしい 「スクラムマスター」の人は、俯瞰してプロジェクト全体を見渡して落穂拾いをしていく人なのかもなぁと 個人的には「スクラムマスター」の仕事がちょっとおもしろそうと思いました。(いつもいろんなことを面白そうと思う自分なのでなんともいえないですが。。。)\n####データ理解を助けるビジュアライゼーション\n昨年からビジュアライゼーションには興味だけ(実践とかできてない)は持っていたので、参加しました。 スピーカーの方々の対立軸がはっきりしていたのが面白かったかと。 聞いていて感じたのは、次のようなこと\nビジネスの視点からのビジュアライゼーションはコスパがどうなのかというのがまだ不明 可視化できたらおしまいじゃなくて、お金につながる可視化に心がけるのが重要そう 可視化して楽しむのも有りだとは思うけど、それは趣味だったり芸術の話かもなぁ 異なるコンテキストの人にでも誤解を与えない可視化というのが重要 何をどう可視化するかというのが実は統計学知ってると必要ないこともある 基本的にはCAの方の内容が一番しっくり来ました。やっぱりビジネス的な視点と学術的な視点は違うのかもなぁと。\n####継続的システム運用のゲンバのハナシ\n面白かったです。のっけから燃料がテーブルにならんでるしw 運用とかインフラはそこまで詳しくないのですが、少しは作業したりするので気になってましたが、ぶっ飛んだ話が聞けて楽しめました。 聞いていて感じたのは、次のようなこと\nサービス内容によっては夜中にアクセス数が低いものもある(cookpadは夜中はアクセス数が低い) アプリを修正することでインフラを楽にするという考えもある インフラエンジニアは実はリア充 cookpad面白い人多いw このあとは、おまちかねのプレモルタイムだったので、プレモル片手(失礼だろw)にTech10の池本さんに挨拶してきました。(Solr本のときはお世話になりました!) あとは、RedBull片手に知り合いの方々(Twitter上のみやいつもお世話になってる人)に挨拶をして回ってました。(プレモルも美味しかったのですが、プレモルおつまみも美味しかったです!) また、ちょっとつかれて座るために入った「体系的に学ぶ安全な利用規約の作り方」でも、面白い話を聞けました。 (利用規約をきちんと考えて変更している企業のほうが炎上をしてしまうとか無駄だしおかしいよねとか)\nイベント終了まで、会場にいて(いただけで大した手伝いしてないです、すみません。)その後打ち上げに向かって楽しみました。\n####さいごは、イベント通じて感じたことと気になったこと。(若干、意図的なものが入り込んでますが。。。)\n題材にもなってる「CROSS」ですが、ここ数年特に、エンジニアとして複数の技術や考えなどを身につけないといけないなぁと 有名人に会える!(ミーハーです。。。) プレモル美味しい!(いつも飲んでるビールが「え?」って思った) ケンタッキー美味しい! RedBull美味しい! いろんな技術分野に触れられる機会ができそう Wi-fiは用意してもらえると助かる。(参加者の方々が一斉にLTEとかでつなごうとするのでみんなが繋がらなくなってツイートされないとかちょっとつらいかも) 各会場が覗けるようになってたのは良かった(ただ、会場の後ろの人はざわつきを感じるためスピーカーの声が聴こえないことも) スクリーンはもう少し高い位置にあると良かった(後ろに座ると下のほうが見えないことも) 飲食の配布は会場内でできたほうが良かったのかも(NGなのかな?)。プレモルやRedBullは配ってくれたので良かったのだが、食べ物を取りに行くために入口付近が混雑してた気がした。 (これで、メッキ剥がれたかなぁ) 会場入り口の写真とか撮ってくるんだった。。。 ということで、総じて楽しかったので来年もあるならまた、手伝いたいです!\nおまけ\nプレモル! Amebaウォーター プレモル+プレモルおつまみ+RedBull いただいたスタッフTシャツとプレモル!\n","date":1358600940,"dir":"post/2013/","id":"322264a17ef7182eb1475bd2eaebc2eb","lang":"ja","lastmod":1358600940,"permalink":"https://blog.johtani.info/blog/2013/01/19/%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88cross-2013%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%8A%E6%89%8B%E4%BC%9D%E3%81%84%E3%83%A2%E3%83%87%E3%83%AC%E3%83%BC%E3%82%BF%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F--cross2013/","publishdate":"2013-01-19T22:09:00+09:00","summary":"1/18(金)に開催された、エンジニアサポートCROSS 2013で「検索CROSS」セッションのセッションオーナー(モデレータ)をやって来ま","tags":["勉強会"],"title":"エンジニアサポートCROSS 2013に参加(+お手伝い+モデレータ)しました #cross2013(Jugemより移植)"},{"contents":"いまさら感満載ですが、今週の金曜日(1/18)に開催されるCROSS 2013というイベントで「検索CROSS」のセッションを担当することになってます。\nここ数年、検索に携わっていますが、検索は色々な技術の組み合わせ(検索用インデックス、自然言語処理、機械学習などなど)でなりったていて奥が深いなぁと感じる毎日です。 そこで、実際のサービスで検索をやられている方、検索プラットフォーム製品を開発している方、自然言語処理や検索に長けた方を招いてつぎのような話をしてもらおうかと。\n・現在の事例(検索とその周辺技術) ・今後の検索にクロスすると面白い技術\nがっつり検索をやられている方々に登壇していただきますので、検索に興味のある方はぜひ、ご参加を! 登壇者の方々についてはこちらを御覧ください。\n検索CROSS以外にも楽しみなセッションが多数ありますので、参加をご検討いただければと。 あと、実はこっちがメインなのですが、夕方からのプレモルタイムも期待できるのでこちらへの参加だけでもぜひ!!\n","date":1358267340,"dir":"post/2013/","id":"20110c8f8da8304b6d9d3c2845a38128","lang":"ja","lastmod":1358267340,"permalink":"https://blog.johtani.info/blog/2013/01/16/%E3%81%84%E3%81%BE%E3%81%95%E3%82%89%E3%81%A7%E3%81%99%E3%81%8Ccross-2013%E3%81%A7%E6%A4%9C%E7%B4%A2cross%E3%81%A8%E3%81%84%E3%81%86%E3%82%BB%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E6%8B%85%E5%BD%93%E3%81%97%E3%81%BE%E3%81%99/","publishdate":"2013-01-16T01:29:00+09:00","summary":"いまさら感満載ですが、今週の金曜日(1/18)に開催されるCROSS 2013というイベントで「検索CROSS」のセッションを担当することにな","tags":["勉強会"],"title":"いまさらですが、CROSS 2013で検索CROSSというセッションを担当します(Jugemより移植)"},{"contents":"年末から年始にかけて、「コード・シンプリシティ」を読みました。\n先日の記事にも書きましたが、Kindle paperwhiteを思いかけず入手できたので、eBookを読みたいなぁと思いまして。 Kindleのお試しも兼ねて読んでみました。\nまずは、本の感想。 短めの書籍+読み物なので、サクっと読めました。 題名に「コード」と書かれていますが、コードの実例が出てくる書籍ではありません。 「ソフトウェア」を以下にシンプルに保って、管理しやすくするか、機能追加、テストをやりやすくするかといった指針について書かれています。 機能追加に関して検討しないといけないバランス(先読みしすぎずと実装しすぎないとか)の話や定期的なデザインの見直しなどについても書かれています。 ソフトウェアに関しては動くこともだが、デザインが重要であること。(確かに。) すでにあるソフトウェアについて、どのように簡潔にしていくかという話もありました。 ただ、読んでいて一番重要だと思ったのは、「悪いプログラマーと良いプログラマーの違いは理解力だ」という一文です。 何をしているかを「理解」していないと、根本的な問題点の解決もできないですし、どうすればコードが簡潔になるかといったこともわからないです。 また、やっている作業がどんなもので、何のためにやっているのか、それを行うことで今後にどのような影響があるのかといったことも理解しておく必要があるかと。 ま、ある程度考えながら作業とかしましょうってことですかね。(強引なまとめかも。。。)\nで本題です。 Kindle paperwhiteとiPadの使い分けを検討するのも兼ねて本を読んでました。 iPadを持っているのもあり、Kindleはそもそも眼中になかったのですが、めっけ物でした。 やはり実際に使ってみないとわからないことありますねぇと。 paperwihteはつぎのような利点があるかと。\n読書に没頭できる。→本を読むというシンプルな目的を達成するものだけが実装されている 目が疲れない→Twitterでも話に上がったのですが、液晶とは異なり字が読みやすいです 軽いし小さい→電車で立っていても楽に持てるし、カバンからの出し入れも楽です(iPadに比べて) 複数の端末のKindleアプリで同期できる。→あまり異なる端末では読まないですが、paperwhiteで読んだところが、iPadでも同期されるのですんなり続きが読めます 電池長持ち ということで、本を読むのに没頭できるし目が疲れないと。 ただ、つぎの点では不満もあります。\nPDFは読みにくい。→画面のサイズが小さいので大きめの書籍のPDF版は読みにくいです。 PDFは読みにくい。→文字のサイズを変更できないのもキツイです。Kindle専用のmobi形式の書籍が読みやすいです ページめくりに一定時間がかかる→紙の書籍やiPadで書籍を読むのとは異なり、ページをめくるのに時間がかかります。e-inkの再描画の問題かと。パラパラと書籍を読みたい場合は厳しいです 白黒。カラーの電子書籍は読めないですねぇ ソースコードなどもキツイ→長めのコードが書いてある本だとコードが頭に入ってこないです。。。 という感想でした。 今後は基本Kindle paperwhiteを持ち歩きmobi形式の本を読むようにすると思います。 iPadは自炊本やカラーの本を読むとき、映像、ネットを見るような場合に持ち歩くことになりそうです。 私は基本的にMBAを持ち歩いているというのもあるので、paperwhiteのほうが主流になりそうです。 ネットを見るときなどは最悪、MBAを開くでしょうし。 小説とかをメインに読むのであれば断然、paperwhiteだと思います(最近読んでないなぁ)\n","date":1357658880,"dir":"post/2013/","id":"992a00c30242b6217243f3c387ea18b7","lang":"ja","lastmod":1357658880,"permalink":"https://blog.johtani.info/blog/2013/01/09/%E3%82%B3%E3%83%BC%E3%83%89%E3%82%B7%E3%83%B3%E3%83%97%E3%83%AA%E3%82%B7%E3%83%86%E3%82%A3%E3%82%92%E8%AA%AD%E3%81%BF%E3%81%BE%E3%81%97%E3%81%9Fkindle-paperwhite%E3%81%AE%E4%BD%BF%E3%81%84%E5%8B%9D%E6%89%8B%E3%81%AE%E7%A2%BA%E8%AA%8D%E3%82%82%E5%85%BC%E3%81%AD%E3%81%A6/","publishdate":"2013-01-09T00:28:00+09:00","summary":"年末から年始にかけて、「コード・シンプリシティ」を読みました。 先日の記事にも書きましたが、Kindle paperwhiteを思いかけず入手で","tags":["読書"],"title":"「コード・シンプリシティ」を読みました。(Kindle paperwhiteの使い勝手の確認も兼ねて)(Jugemより移植)"},{"contents":"書こうと思いながら、気づいたら大晦日。 よくないですね、思いついた時に書かないと。\n昨年も書いたので、昨年書いた抱負から振り返りをと。\nMongoDB触ってみる Scala触ってみる なんかWebサービス作ってみる(Amazonとかで) elasticsearch、IndexTankを調べてみる NewSolrCloudDesignを読み込んで自分なりにまとめる Junsaiに参加する 「7つの言語7つの世界」の続き えーと。。。できてないことばかりですねw MongoDBはインストールすらしてないですし、Webサービスも作ってないです。(さくらVPSは借りたんですが) Junsaiは参加したけど何もできてないし。7つの言語もそのままですね。。。 SolrCloudDesignはまとめられてないですしね。 Scalaは少しだけ触りました。結局Javaみたいな記述をしてしまうという良くないくせが出てしまうので、 見送ってしまいましたが。。。 elasticsearchは少しだけやりました。#pyfesで話をさせて貰える機会があったので。\n興味がコロコロ変わってしまうのが問題点かもしれないです。少しは地に足をつけてなんかやったほうがいいのになぁ\n###今年の振り返り 今年はこんなかんじでしょうか。\nいろんな勉強会に出没 #pyfesでelasticsearchのさわりを紹介 個人的にJIRA導入 MIR輪読会開始 Solr勉強会の主催を引き継ぐ Kindle paperwhite当たった 相変わらずいろんな勉強会に出てました。最近は勉強しに行くのもありますが、人に会いに行ってるような気がします。 勉強会から帰ってきて復習したりしないとすぐ忘れちゃうんですよね。。。\n#pyfesではelasticsearchの入門中という話をしてきました。 人の多さに緊張しまくりでよくわかりにくい発表になってしまったのが反省点かと。。。 もっと話をする機会を増やすとなれるのでしょうか。\nJIRAの導入はパラで仕事をしているとタスク管理がおろそかになってくるので導入しました。 フリーのredmineを考えていたのですが、インストールが簡単なJIRAを導入しました。 有料ですが、1-10人までなら、ダウンロード版が$10ですし。いろんな時間を買ったと考えると安いかと\n検索に関してもまだまだ初心者に近いということでModern Information Retrievalという英語の本の輪読を主催しました。 Twitterでの呼びかけに答えてくれた方々に感謝です。 まだ、半分も行ってないですが、何周かしたいと思っています。\nSolr勉強会の主催者も引き継ぎました。Atnd立てるの手伝おうか?って言ったら主催者になってましたw 来年も開催するので、喋りたい方、こんな話を聞きたいなどTwitterやブログでコンタクトいただければと。\nあと、会社の忘年会で思いがけずKindle paperwhiteが当たりました!(やったー!) iPadを持っていることもあり、完全に購入する気も無かったのですが。。。 使ってみると結構いいです。画面のギラツキがないのと、他のソフトがないのがいいです。 読書に没頭できます。通常はKindleを持ち歩くことになるかと。(没頭できるけど、読むスピードが遅い+すぐ忘れるのが難点。。。)\n###来年の抱負 来年の抱負も書いておきます。 昨年の前科があるのでどこまでできるかわかりませんが。 すぐに興味が変わってしまうのもありますし\nIntelliJ IDEAをメインに使う JIRAを継続して活用 ブログの継続 elasticsearch Luceneのソースコードリーディング 何かOSSのソースを読む Macでもっと開発 読書と英語を継続 IDEA(アイデア)は11をインストールしてたのですが、使えていませんでした。 イメケンが主催したJetBrainsユーザー会で洗脳されて+タイミング良い75%オフセールにやられて購入しました。 普段はEclipseを使っているのですが、これを機にチャレンジしようかと。 少し変化をしてかないとすぐ取り残されちゃうので。。。\nJIRAはまだタスクを登録してクローズするという初歩段階の使い方しかできてないので、少しずつ研究してフィールド追加したり、ワークフローを変更してみたりと研究したいです。\nブログは、今年後半が勉強会参加ブログしかないのを反省して来年は、もう少しSolrやLucene、lucene-gosenについて書いて行きたいです。 (すくなくとも、4.0で動かす話を書かないと。。。)\nelasticsearchはまぁ触れる環境を維持しようという話です。 どこかで導入できればいいんでしょうが、なかなか。 (勉強会開いてみるのも面白いかな?)\nLuceneソースコードリーディングは誘われてるのに、ちゃんと返事をしていなかったので。 来年2月のどこかの土日を候補日にする予定です。\n何かOSSのソースも読もうと思ってます。 「何か」はまだ決めてないですが、人のソースを実はあまり読んでないなぁと。 Vさんと話をした時に人のソースを読むのがいいですよという話になったので。 真似をするためにもなんか読みたいなぁと。Javaになるのかなぁ。\nとある事情で週4はWindowsで開発してます。 Macはちょっとしか触ってないのでMacの環境が成長していないのが難点です。 できれば、Macで開発を継続できる環境を作りたいなぁと。Kobitoとか入れてるけど触ってないし。。。 IntelliJも入れたのでMacで開発したいものです。\n最後は毎年のことですが、本を読むスピードが買うスピードに追いついてないと。。。 英語の本もかってるんですが、これまた読むスピードが。。。 ということで、ざっくり目を通す読書をもっとやりたいなぁと。 買うのはいいのですが、必要にならないと呼んだ内容を忘れてしまうので、読んだあとに実践する機会も設けたいと思ってます(思ってるだけかもしれないですが)\nあと、来年もいろんな人に会うためにいろんな勉強会に出没すると思いますので、声をかけていただければと また、不抜けているのを見かけたらカツを入れてください。(技術内容のブログ書けとか、本読んだ感想をブログにかけとか) 来年もTwitterなどで絡みまくると思いますが、よろしくです。\n","date":1356908460,"dir":"post/2012/","id":"4c08b67e0c1fdeef50b1fdcc32cdcee2","lang":"ja","lastmod":1356908460,"permalink":"https://blog.johtani.info/blog/2012/12/31/%E4%BB%8A%E5%B9%B4%E3%81%AE%E6%8C%AF%E3%82%8A%E8%BF%94%E3%82%8A%E3%81%A8%E6%9D%A5%E5%B9%B4%E3%81%AE%E6%8A%B1%E8%B2%A02012/","publishdate":"2012-12-31T08:01:00+09:00","summary":"書こうと思いながら、気づいたら大晦日。 よくないですね、思いついた時に書かないと。 昨年も書いたので、昨年書いた抱負から振り返りをと。 Mongo","tags":["備忘録"],"title":"今年の振り返りと来年の抱負(2012)(Jugemより移植)"},{"contents":"Atlassian Advent Calendar 2012の20日目。(急遽参戦) (某イケメンにMT(改変リツイート)されたので書いてみました) 久々に、勉強会以外のエントリです。(Solrとかlucene-gosenじゃないんだが。。。)\n私は、最近忘れっぽくなってきてしまったので、さくらVPSを借りてJIRAを立てて、タスク管理とかに使い始めました。 有料ツールなので、まずは、評価版から入れましたと。 評価版をインストールするときに、楽なのでHSQLDBを選択していました。が、 インストール時に「HSQLDBは評価版だけで使用してください。正式版ではサポートしてないです」みたいなことを言われていたので、PostgreSQLに切り替えようかと。 ちなみに、MySQLも選択肢としてはあったのですが、PostgreSQLのほうが触ってるし(つかいこなせてるわけではない)、補完機能になれてるというのもありPostgreSQLを選んでみました。\n作業のログとして、ブログ書いとこうと思いたったのでメモ的に残しておきます。\n作業の流れはこんなかんじでした。 (基本的にはサポートサイトのここに載ってます。サポートいいね。) この手順通りでいいみたい。\n###1. JIRAのデータのバックアップ(JIRAの管理画面からバックアップ)\nまずは管理画面へ。ページ右上に管理へのリンクがあるのでクリック。 開いた管理画面の右下あたりにエクスポート(バックアップ)へのリンクがあります。 クリックしたあとに、エクスポートのファイル指定画面が現れるので、ファイル名を指定してバックアップボタンを押します。 バックアップが完了するとバックアップファイルの場所が表示されます。 ###2. JIRAの停止\nバックアップが終わったのでJIRAを停止します。\n###3. PostgreSQLのインストール(yum) PostgreSQLが入ってないので、yum installします。(軟弱者なので)\nyum install postgresql-server ####initdbで四苦八苦 PostgreSQLはインストールしただけでは起動できません。なので、初期化をします。 yumでインストールしたPostgreSQLだとつぎのコマンドでinitdbできるようです。(これが罠でした)\nservice postgresql initdb このコマンドでinitdbすると、encodingが指定できませんでした。(私がしらないだけという話も。。。) encodingを指定できていないと、このあと4.を実行するときにエラーが出ました。(これも回避方法あるのかも。) ということで、結局、昔とった杵柄なやり方でinitdbコマンドで\u0026ndash;encoding=UTF8 \u0026ndash;no-localeを指定しました。\ninitdb --encoding=UTF8 --no-locale -D/var/lib/pgsql/data service postgresql start これで初期化が完了するので、PostgreSQLを起動します。\n###4. JIRA用DBとユーザの作成\nまずは、ユーザの作成。そして、DB作成\ncreateuser jirauser createdb -E UNICODE jiradb テーブルなど作成しません。あとの処理がやってくれます。\n###5. JIRAにJDBCドライバを入れる(必要なかった。)\nwarじゃないJIRAをインストールした場合はすでに入ってるみたいです。 ここを見るとわかります。JIRA Installation Directoryの下のlibですかね。\n/opt/atlassian/jira/lib ###6. マニュアルでPostgreSQLの接続設定(あれ、これいらないのか。)\n~~ コンソールオンリーなので、JIRAが提供してくれているツールが使えないため、手で設定。 /var/atlassian/application-data/jira にあるdbconfig.xmlを修正~~ ちゃんと英語読めってことですね。。。必要なかったです。。。\n###7. JIRAのdbconfig.xmlを削除\nDB接続の設定を初期セットアップウィザードで再設定するため、dbconfig.xmlを消します。 (一応、インストールディレクトリとホームディレクトリとかバックアップしたほうがいいみたい) 場所はここ。 中身はdbcpとかのデータソースの設定に似てました。 今は、HSQLDBのJDBCドライバが記載されてました。\nrm /var/atlassian/application-data/jira/dbconfig.xml ###8. JIRAの起動\n7.のファイルを消したあとにJIRAを起動します。\nservice jira start ###9. JIRAにアクセスとDB接続設定\nアクセスすると、インストールした時と同じDB接続の指定を行うセットアップウィザードの画面が現れます。 今回はJIRAサーバの外にあるPostgreSQLなので、「外部」を選んで四角で囲んだ部分を入力します。 入力したら、「接続テスト」を押して接続できることを確認したら「次へ」を押します。 マシンのスペックにもよると思いますが、ここでJIRAサーバがDBに接続してテーブルのCREATEなどDBのセットアップを実行してるのでちょっと時間がかかります。\n###10. バックアップしたデータのインポート\nDBのセットアップが終わったら、アプリケーションのセットアップ画面が出てきます。 新規インストールではないので、「ここ」にある「既存のデータをインポート」リンクをクリックします。 すると、インポートファイルの指定画面が現れるので、1.でバックアップしたファイル名を指定してインポートします。 すると、インポート中画面が出てきます。 で、インポートが完了すると無事JIRAにログインできますと。\nとこんなかんじです。 私の場合は、まだJIRAをインストールしてから間もないため、チケットの数が少なかったり、添付ファイルが無かったりなので、すぐにインポートが完了しました。 添付ファイルがある場合は、別途添付ファイルが保存されているディレクトリのバックアップと復旧などもあるみたいです。 最初にも書きましたが、ドキュメントのサイトに「Switching Databases」という項目があり、そのページの手順で問題なく切り替えできました。 次は、定期的にデータをバックアップするのを考えないとですかね。\nいやぁブログ書くのが、思いの外、手こずりました。 手こずった原因はスクリーンショットだったんですけどね。。。 safariでページ全体のスクリーンショットがとれなかったので、結局ChromeでAwesome Screenshotプラグイン使いました。 safariの拡張もあるんですが、ページ全体のスクリーンショットがうまく動かないみたいです。。。 ということで、備忘録でした。(次はちゃんとSolrとかの記事書かないとなー。その前に忘年ブログかな)\n","date":1356002280,"dir":"post/2012/","id":"4a30eeb083acec8460150068ba0c6743","lang":"ja","lastmod":1356002280,"permalink":"https://blog.johtani.info/blog/2012/12/20/jira%E3%81%AEdb%E7%A7%BB%E8%A1%8Chsqldb%E3%81%8B%E3%82%89postgresql%E3%81%B8-augj/","publishdate":"2012-12-20T20:18:00+09:00","summary":"Atlassian Advent Calendar 2012の20日目。(急遽参戦) (某イケメンにMT(改変リツイート)されたので書いてみました) 久々に、勉強会以外のエントリです。(So","tags":["JIRA"],"title":"JIRAのDB移行(HSQLDBからPostgreSQLへ)#augj(Jugemより移植)"},{"contents":"イケメンが主催した「第一回 JetBrainsユーザーグループ #jbugj」に参加してきました。\nいろんな製品があるんだなぁと。入り口には良いイベントだったと思います。 個人的に、WebStorm、IntelliJが気になっていたので、参加しました。(あとは、イケメンがやってるイベントだからというのもあるかも) ちなみに、MBAにしてからインストールはしていたのですが、ほぼ触っていなかったのでこれを機会にちょっと触ってみようかなぁと。\n発表は、全般的な製品紹介、ライセンスの紹介から、ライブコーディングあり、ここがいいよ!という話ありという感じでした。\nMTLさんのおしゃれな空間で発表を聞いたので、いつもとは少し違った感じでしたでしょうか。\n私自身は、発表を聞きつつ、IDEAのCEで色々やってました。 一応、Lucene/SolrのSVNからチェックアウトしたり、lucene-gosenのtrunkをチェックアウトしたり、個人のbitbucketからlucene-gosen-wikiparseとかcloneしてました。 Eclipseで作ったプロジェクトなので、cloneとかチェックアウトしたあとに、Eclipseと並行開発するとどうなるのかなぁ?というのがちょっと気になります。(普通は移行しておしまいなんだろうけど。。。) ちなみに、lucene-gosenのプロジェクトもSVNからチェックアウトしたらすんなり使えそうでした。 こんな感じ。(lucene-gosenのプロジェクト) とりあえず、見た目がカッコイイw\nいくつか触ったり、聞いていて気になったのはつぎのような点です。ちょっとずつ触る機会を作った時に調べてみようかなぁと\nEclipseのワーキングセット相当の機能はどうするのか?→モジュールとかでやればいいらしい。 プラグインってどんなものがあるの?探す方法とインストールの仕方 JDKの複数の切り替え方とか Eclipseでやってる人とIntelliJでやってる人の混在チームでの開発とか で、いつものごとく、懇親会に参加しました。 @mike_neckさんや@sue445さんとお話できたのですが、VCSにEclipseの設定ファイルとか挙げないほうがいいですよねとか、テストが無いプロジェクトってないわーなどの話を聞いて、やっぱり自分はまだまだなんだなぁと認識できるとか面白かったです。 lucene-gosenのSVNにはEclipseの設定ファイルとかアップされてるからなぁ。ホントはAntとかMavenのターゲットでこれらの設定ファイルができるようにしとくのがいいんでしょうねぇ。 まだまだ勉強することだらけですが、コツコツ教えてもらいます\nちなみに、イベント参加者にはショートカットキーが印字されたキートップシールや2ヶ月有効な評価ライセンスがあとからもらえるなどの特典もありました。 普段はEclipseなのですが、運良くライセンスが当たったら本気で乗り換えようかなぁw\nちなみに、Eclipseでもそうですが、私自身はショートカットキーをほとんど覚えてない軟弱者ですので、メニューの場所などを覚えれば乗り換え自体はこんなんじゃないかと。 Mac自体にKeyRemap4MacBookを入れていて、Emacsっぽいショートカットを使うので、覚えられないというのもありますが。 ライセンス当たらないかなぁー\n以下はいつもの通り、聴きながら自分用にメモしたものになります。\n日時:2012/12/11(火)19:00-21:00 場所:メディアテクノロジーラボ イベントサイト:http://www.zusaar.com/event/450003\n◎JetBrains製品群、ライセンス形態などの紹介 - @yusuke ・日本でヤル気あるの!?→あるある!→じゃあ、ユーザグループ立ち上げるぜー ・あくまで情報交換の場を設けるだけ。 ・アンケート結果 IntelliJが1番人気 WebStromが2番 ・ステッカー(ちょっとかっこ悪いかも。。。) ・2名限定でIDEAのライセンスプレゼント! ブログ書いて、応募用フォームに登録してランダム抽選 ◎IntelliJの基本(インストール~プロジェクト作成、テスト、実行までのウォークスルー) @yusuke ・JetBRAINSはチェコの会社 ・IntelliJはなんでもできる(AppCodeは違うけど) ・.Net系もある(書きそびれた) ・YouTrack:課題追跡 ・TeamCity:継続インテグレーション ・読み方は「イデア」じゃなくて「アイデア」だよ! ・Community Editionはあんまり機能がない。 OSSライセンスだと、Ultimateの機能が使えるよと。 ・仙台の人が一人アドベント・カレンダーやってます。 http://d.hatena.ne.jp/masanobuimai/20121201\n・ライブデモ 黒いインタフェースにするのどーすんだろう? →Preferences→AppearancesでThemeで「Darcula」を選択すると黒くなる。 ・やべ、時間過ぎてたw終わり! ◎IntelliJのここが気持ちいい!→普通IntelliJでしょ? @mike_neck ・DQXやってます。 ・僕とeclipse ・新規クラス作成:3ステップかかる ・補完の素早さ: ・SprintFramework:Ultimateなら対応してるよ。 関係ないけど、TLで質問したので。 Eclipseのワーキング・セットに相当するもの。 http://d.hatena.ne.jp/masanobuimai/touch/20121024\n◎LT ◯WebStormとRubyMineについて @sue445 ・JavaScriptのIDEとして最強 jsの補完が素晴らしい。(外部のJSはプロジェクトに入れないと難しい。) jsTestDriver pluginがデフォルトで入ってる! ・RubyMine RubyのIDE ソースを追うのが楽。 erbのインポートしたものも追っかけられるの便利。 viewからhelperクラスにも飛べる。 QA UMLとか出せるの?→出せるよ。 DBクライアントもあるよ。 ◎JetBrains発のJVM言語Kotlinの紹介 - @ngsw_taro アドベントカレンダー(一人)http://atnd.org/events/34627\n・社畜してます ・Androidアプリとか作ってる。 ・Kotlinな活動 Pull Requestしてる ・マイルストーンなど。 M4が3時間前に出た! ・どんな言語? 静的型付け、オブジェクト指向、関数型プログラミング的、JSへコンパイル可 産業利用目的(初めて聞いたかも、この言葉w) ・Java大変だよね。 互換性問題とか ・ライブコーディング 大変そうだwKUnitってのもあるらしい。 (ゴメンナサイ、IDEA触ってて、流してました。。。Eclipseで作ってたプロジェクトをBitbucketから落としてきて四苦八苦してた) (参考にしたサイト(ググった):http://d.hatena.ne.jp/waman/20100506/1273166533)\n◎AppCodeについて ・IDEAには含まれないので、別途ラインセンス購入が必要。 ・XcodeとAppCodeの違いをライブコーディングで説明。 ・XCodeよりも補完が良くできてるっぽい。 GUIはXCodeで作って、コーディングはAppCodeでやるってのがいいですよ。 ※私が、iOS系のアプリの開発ってやったこと無いからよくわかってないです。。。 XCodeはコードフォーマットがないのが辛い by @yusuke ","date":1355228520,"dir":"post/2012/","id":"898d25a2ab9c0ba1fa9bad462405e475","lang":"ja","lastmod":1355228520,"permalink":"https://blog.johtani.info/blog/2012/12/11/%E7%AC%AC%E4%B8%80%E5%9B%9E-jetbrains%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%82%B0%E3%83%AB%E3%83%BC%E3%83%97--jbugj-%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%A6%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-12-11T21:22:00+09:00","summary":"イケメンが主催した「第一回 JetBrainsユーザーグループ #jbugj」に参加してきました。 いろんな製品があるんだなぁと。入り口には良いイ","tags":["勉強会"],"title":"第一回 JetBrainsユーザーグループ #jbugj に参加してきました(Jugemより移植)"},{"contents":"ヒカリエに行ってみたいという不純な理由で参加してきました。 新しいということもあり、おしゃれで綺麗なカフェでした。 入り口にはおっきな人形も立ってたし。 渋谷の夜景も見下ろせて素敵な場所でした。\nで、内容です。残念ながら、本編の3回めには参加していなかったのですが、 今回も濃い話が聞けたので楽しかったです。 論文読まなかったり、基礎を勉強したのに忘れてたりと抜けてる部分が多いので、 こういう機会が与えてもらえるというだけで目からうろこです。\n@kumagiさんの「あなたの知らないハッシュテーブルの世界」はハッシュテーブルの基本的な話から、最近の論文で発表されてる内容までをカバーする幅広いお話で面白かったです。 (大学でやってると思うんだけどすっかり抜けてる自分がなんとも。。。) こういうコアな中身も知ってると、色々とプログラム書いたりするときの見方や考え方も変わってきますよね。 (そんなプログラム書いてないけど。。。) で、随分おとなしい内容だなぁ?と思いきや、途中からちゃんとLock-Freeの話も出てきてさすがと感心させられましたw 最後はJubatusの宣伝まで入ってたし。(某氏のすごい写真入りで。。。)\n@hitoshi_niさんの文書要約の話は、NLPに興味があるので、楽しみにしていた内容でした。 今回もなめらかによどみなく喋られる発表にただただ感心させられるばかりでした。 内容は中級編ということで、文書要約のキモになる処理の文章の短縮の話です。 係り受け木を元にする手法をわかりやすく説明されて、もうなんか、すぐに実装できちゃうんじゃないかと錯覚してしまう始末でした。 係り受け解析というと、CaboChaを思い浮かべてしまうんですが、きっと違う実装なんだろうなぁ。 入門編と次回の重要文抽出の話も聞きたいなぁと。\n最後に、技術評論社さんから「Emacs実践入門」など3冊の書籍のプレゼントまでありました。 その他の2冊は購入済みだったのですが、Emacs本は購入したいリストに入れたままでした。 ということで、欲しいですというアピールをしてゲットしてきました! Emacsはなんだかんだで、もう10年以上使っていますが、そこまで深入りしないような使い方をしていました。 これを機に、再入門してもっと使いこなせるようになろうかと。 また、読了したタイミングでブログに感想かきます。\nということで、以下はいつもの自分用のメモになります。おかしいところ、それ書いちゃダメでしょ的なところのツッコミをいただければ。\n日時:2012年11月28日(水) 19:00 場所:渋谷ヒカリエ27F NHN Japan カフェ ◎開会、諸注意など @overlast 人材募集、会場説明など。 前回、本をもらった人はブログ書いてね。オライリー様より 今回も本のプレゼントあり。技術評論社様より ◎あなたの知らないハッシュテーブルの世界(30分 + 質疑応答10分) @kumagi さん ・まずは前提。 データの集合を扱いたいよね 配列でもできるね。けど、データ増えるとキツイね。 ・ハッシュ関数の話から。 リハッシュとかの話 ・ClosedAddressingとOpenAddressingの話 ・ClosedAddressingの場合、ポインタ使ってるからキャッシュミスあり。 メモリとかの話 ・OpenAddressingメモリに乗るのでキャッシュミスは少ないけど、削除データの扱いがちょっと大変 →削除がいっぱい有ると処理が面倒 ・RubyはClosedAddressing、PythonはOpenAddressing memcachedはClosedAddressing ・Cuckoo Hashing(2001) 密度50%以上になると急にコストが高くなる。 挿入がすごく遅くなる。追い出し操作が増えるから? ・そこで、Hopscotch ググった参考ページ:http://shnya.jp/blog/?p=639 http://en.wikipedia.org/wiki/Hopscotch_hashing 密度が上がっても性能劣化がない。 ・C++でHashtableが欲しくなったら、google_sparse_hashとdense使うよと。 ・ConcurrentHashmapのお話 テーブル部分がvolatile、Chain部分はfinal insertはChainの先頭に。 削除は遅い。ReadCopyUpdate。 空でも1.7M(K?)持ってく ・ここからはLock-free系 ・Lock-Free Hash Table http://www.azulsystems.com/events/javaone_2007/2007_LockFreeHash.pdf HotSpot VMの人のもの?こんなのやってる。http://www.0xdata.com/faq.html ・(聞きそびれた) ・日立謹製Lock-free hashtable 日立のDBで使ってる部品? ベンチマークが胡散臭い ・最後はJubatusのCM ◎文書要約入門 中級編(40分 + 質疑応答10分) @hitoshi_ni ・画数が少ないです。 ・ヒカリエ綺麗ですね。 ・文書要約とは? 「機械に」要約させる。 ・なんで要約? 長い文章読みたくない。人件費の削減 ・どうやって要約? 1.文分割:文書を文に分割 2.文短縮:就職説を削除するなどして、原文より短い文の亜種を出す。 3.重要文抽出:要約にふさわしい文を選び出す。 ・今回は文短縮について ・動機 長い文は文抽出で扱いにくい 文の中にも重要なところとそうでないとこがある ・係り受け木の剪定すると短くできると。 剪定のルール 中間ノードは落としちゃダメ 除去の時に考えること 重要度 言語 ・重要度? 文節に点数を付ける 文書集合中の出現頻度とかを採用。訓練データからでもいいよ(ロジスティック回帰とか)。 ・言語尤度 言語としての尤もらしさ 典型的にn-gram言語モデルを使う ・そして探索 基本的には2値ラベリング ビタビアルゴリズムではだめ。係り受け制約が考慮できない ナイーブいはビームサーチをする。 ・文短縮の評価 ・人間が書いた短縮文と比較 ・ROUGE-Lという尺度などで評価(これしらないなぁ。) ・幾つかの論点 係り受け解析しない 文節じゃなくて、単語単位でもいいよねとか。 Q:硬い文章以外の要約ってやってるの? A:あります。 技術的な話だと、係り受け解析がうまく出来ればできる。 係り受け解析がうまくいけば、そこまで大変じゃない。 Q:短さが短くなるほど難易度があがるけどどこまでやってます? A:短くすればするほど難しい。これは情報の欠落が激しくなるから。 文法性を担保するのも難しい。 10文字くらいならできそう。 Q:実例としてどのくらいの長さをどのくらい短くしてる? A:ある程度の長さを20文字にしてくれとか。Twitterに入るくらいにしてくれとか。 頂いちゃいました! Emacs実践入門 ~思考を直感的にコード化し、開発を加速する (WEB\u0026#43;DB PRESS plus) ","date":1354122000,"dir":"post/2012/","id":"e01e01d18582c7f69e1b0db7e1b111a0","lang":"ja","lastmod":1354122000,"permalink":"https://blog.johtani.info/blog/2012/11/29/dsirnlp-3-5%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9Femacs%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80%E3%82%92%E9%A0%82%E3%81%84%E3%81%A1%E3%82%83%E3%81%84%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-11-29T02:00:00+09:00","summary":"ヒカリエに行ってみたいという不純な理由で参加してきました。 新しいということもあり、おしゃれで綺麗なカフェでした。 入り口にはおっきな人形も立っ","tags":["勉強会"],"title":"#DSIRNLP 3.5に参加しました。&「Emacs実践入門」を頂いちゃいました!(Jugemより移植)"},{"contents":"第9回Solr勉強会に参加しました。 皆勤賞です!というか、主催者になってしまいました。 まだ不定期の開催になると思いますが、話をされたい方などいらっしゃいましたら連絡いただければ助かります。\n今回も面白い話が聞けました。\n最初はKuromojiの開発者でSolrのコミッターでもあるChristianの発表です。 Solr勉強会では初の英語の発表だったんじゃないでしょうか。 Atilikaでやってることの紹介から、Kuromojiの紹介、今後の改良に関する話とひと通り話してもらいました。 途中でKuromoji使ってる人?などの質問があったのですが、残念ながら反応が薄かったです。 漢数字をアラビア数字でも検索できるようにするチケットなど、今後のKuromojiの発展も楽しみです。 (コメントとかパッチを送れというプレッシャーもあったので、パッチ頑張って書きます。。。)\nつぎはニコ生でのSolrのお話。結構、赤裸々(前任者がいない状態で引き取ったとか)に語っていただき、ハラハラしながら聞いてました。 やはり、新語や略語で苦労されてるんだなぁと。 複数のサービスや開発者に対してSolrの環境を提供するという話はなかなか興味深かったです。 いろんな人がSolrを触るような状況になってきてるんだなぁと。 基盤となるラッパーのようなフレームワークとかも作ってるのかなぁ? 今後は台湾語や英語への展開も考えられているようなので、Language Detectionなどを利用してみた感想とその内容を今度発表してもらいたいですねw\nつぎはFacetPivotの話です。 昔から要望が出ていたのですが、4.0系でやっと使えるようになりました。 ファセットはSolrの売りの一つだと思います。 最初はこの考え方がしっくりこない人もいるかもなぁと。特にデータをどのように作れば、いいのかって悩むこともあります。 その悩んだ内容について発表してもらいました。 実際にどうやって使うかを悩んだ内容を発表してもらうのもいいなと思いました。\n最後はSolr勉強会なのに、elasticsearchの洗脳会になってましたw elasticsearchはSolrと同じ、Luceneをコアに採用した検索エンジンサーバーになります。 Solrとは別のアプローチでLuceneをラップし、REST APIでアクセスしやすくしたプロダクトです。 Luceneのコミッターの方もelasticsearchの開発に参加しています。 分散インデックスを念頭においた設計や、インストールが簡単なプラグイン構造といったSolrとは違ったアプローチがなされており、面白いものになっています。 残念ながら日本で利用されているという話はまだ聞いた事ないですが、だからこそ、触ってみて事例を紹介してみるのも面白いのではないでしょうか。 今回紹介したKuromojiも使えるようになっていたりしますので、日本語でもある程度使えると思います。\n以上が簡単ですが感想です。主催者だったのに、@hirotakasterさんや@ajiyoshiさんに受付などをやっていただいたので、いつもの様にしっかり話を聞いてしまいました。 発表者の方、会場提供いただいたVOYAGE GROUP、お手伝いいただいた皆さんに感謝です!\n今回初の主催でしたが、本当に助かりました。たどたどしい説明や紹介など至らない点も多々有ったかと思いますが、今後もよろしくお願いいたします。\n主催者的な立場として感じたことも書いておこうかと。 無料の勉強会で、ATNDという参加しやすい環境というのもあるかもしれないのですが、キャンセルをきちんとしていただくほうがいいなと思っています。 幸いにもSolr勉強会はここ数回は盛況で、キャンセル待ちの方が結構いらっしゃいます。 ギリギリまで業務との兼ね合いを見つつ、参加しようと思っていらっしゃる方もいると思うのですが、キャンセル待ちで行けるかな?どうかな?と思っている方もいらっしゃいます。 ドタキャンは問題ないのですが、キャンセルせずに欠席は出来れば避けていただけると助かるなぁと。 (残念ながら、きちんと集計をとれなかったので、次回からは集計取ってみようかなぁと)\n次回の開催は今のところ未定です。発表してみたい方、こんな話を聞いてみたいなど、気兼ねなく連絡いただければと思います。 このブログにコメントを頂いてもいいですし、ツイートしていただいてもいいので、反応をいただけると嬉しいです。 また、今回至らない点があったなどのツッコミ、批判も気兼ねなく言っていただければと思います。 今後の反省点にもしたいので、ぜひ反応をいただければと!\n懇親会でも色々な方とお話できました。(もう少し、Christianと英語で話す努力とかしないとなぁ。。。)\nとりあえず、メモをアップしときます。 リンクとか感想とかはまた(飲んだ)後で。。。\ntogetterでまとめてももらったみたいです。ありがたいです。\n第9回Solr勉強会 場所:VOYAGE GROUP 会議室 日時:11/26(月) 19:00~21:00 1. Atilika Inc. Christian Moenさん タイトル:Who we are, what we do, and a little bit about Kuromoji ◎Atilikaの紹介。 会社の目指すもの ・BigData、検索、NLP ◎プロダクト Kuromoji:形態素解析エンジン Akahai:日本語クエリサジェストエンジン Keywords:日本語キーフレーズ抽出 ◎Kuromojiの紹介 3.6からデフォルトで使える。 ◎将来の改良の話。 ・踊り字対応(コミット済み) ・漢数字に関するチケット&パッチのお話。 ・ユーザ辞書の重複エントリ改良とか(すみません、パッチ書きます。。。) 2. 株式会社ドワンゴ 吉村総一郎さん(@sifue) タイトル:Solr@ニコニコ生放送 ◎ニコニコ生放送の紹介 ・1日に10万番組。。。 ・10/17にバージョンQをリリースしたら、トップはひどい叩かれようでした。。。 ◎これまで。 Jackrabbit→Lucene→Solr→ニコ生のSolr ◎退職者と入れ替わりでSolr担当。。。 今回は資料と環境を調べて発掘した機能のお話。。。 ◎機能 キーワード検索。論理クエリ、などなど。 ◎利用してる環境 3.4ベース+Jetty マスタスレーブ構成(スレーブ2台) 途中は分散インデックスを自分で実装? ボトルネック自体がDBからのデータ収集だった ◎インデックス対象 ・見れるのは過去1週間と過去の公式番組すべて。 この部分だけ検索可能。 ・更新頻度の高い情報に「来場者数」「コメント数」 ◎インデックス作成 ・バッチにて更新 ◎アナライザ CJKTokenizerFactoryを利用 HTMLStripCharFilterFactory Bi-gramなので、「FF」とか「DQ」に弱い(FF1でFF13とかヒットしちゃう) 検索精度は悪いと言われてるみたい。 ◎1日のリクエスト ピーク時40QPS程度 5分おきにスパイクがある。(ユーザが作ったツールによる検索とか。。。) ◎UPDATEリクエスト ピーク時は80QPS ◎開発用のJettyのマルチテナント機能を利用したSolr環境の提供 ◎台湾語とか英語もやりたいなぁ。 3. 株式会社マーズフラッグ 柳吾朗さん(@hitode7456) タイトル:ドリルダウン色々 ◎Facetの紹介から ◎楽天でのドリルダウン例(これはFacetの紹介での例であり、実際にSolrが利用されているかはわからないです。) ◎多段ドリルダウン(ファセット)のお話。 アプリを実装するときの考え方とか。 ◎実直形、工夫形、PivotFacet Q\u0026amp;A Q:3つの性能系のコストは? A:まだ調べてないです。残り2つは工夫形がいいですよ。と 次回、調べた結果の発表もやってほしいなぁ。 4. 兼山元太さん (@penguinana_) https://speakerdeck.com/penguinco/solrtoelasticsearchfalsebi-jiao タイトル:SolrとElasticsearchの比較 ◎クックパッド! ◎elasticsearchの紹介 ◎比較サイトもあるよ! http://solr-vs-elasticsearch.com ◎サンプルデータ・セット(ライブドアグルメ)でサンプル実装。 https://github.com/penguinco/ld_gourmet_search ◎APIの紹介 REST APIがちゃんと造られてますよと。 設計時点でコレクションなどがURLに含まれてるのがいいよねと。 ◎_analyzeによりアナライザーもAPIとして公開されてるよと。 ◎Kuromojiも対応してるよ! ◎DynamicFieldよりも便利だよ。 ◎クエリのDSLが違うのでちょっとアレ。 ◎スコアリングも色々できるよ。 ◎感想 ・機能面の不足なし ・APIがいい コア追加とか、curlだけでできるのがいい。 ・習得が容易(Solrやってると機能とか似てる) ・大規模じゃなくても使えそう ◎分散検索がデザイン時に組み込まれてるのがいいよね。 write consistencyなどがインデックスごと(コレクションごと?)に設定可能なので便利。 ◎multi-tenant open/closeなどができる(時系列データとか) shard allocationなどの細かな制御も可能ですよと。 ◎plugin 色々プラグインがあるよ。管理画面もプラグインであります。 プラグインもコマンド一発で追加可能。 ◎クエリキャッシュがないので、自前でnginx、varnishなどでキャッシュが必要。 ","date":1353923040,"dir":"post/2012/","id":"7e23419e4fc69b5b533815681c9bb1a9","lang":"ja","lastmod":1353923040,"permalink":"https://blog.johtani.info/blog/2012/11/26/%E7%AC%AC9%E5%9B%9Esolr%E5%8B%89%E5%BC%B7%E4%BC%9A%E3%82%92%E4%B8%BB%E5%82%AC%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-solrjp/","publishdate":"2012-11-26T18:44:00+09:00","summary":"第9回Solr勉強会に参加しました。 皆勤賞です!というか、主催者になってしまいました。 まだ不定期の開催になると思いますが、話をされたい方など","tags":["勉強会"],"title":"第9回Solr勉強会を主催しました。#SolrJP(Jugemより移植)"},{"contents":"初目黒(たぶん)で、初Amazonな感じで、流行りの「ビッグデータ」のセミナーに参加してきました。\nとりあえず、いつもの自分用のメモを残しておきます。 感想はまた後日。。。(たぶん、頑張れ私。。。)\nAWS ビッグデータ活用事例セミナー 日時:2012/11/09 [ 金 ] 9:30 - 12:00 場所:アマゾンデータサービスジャパン目黒オフィス ★AWSビッグデータ概要 @understeer ○Amazonの紹介 ○Amazon Web Serviceの紹介 ・オンプレミスと比べ、初期費投資が不要 ・コストダウンを促進 過去6年で21回の値下げを実施 ・IaaSだけじゃなく、PaaSもやってますよ。 ・OSより上の層は好きに選べるよ。 ○AWSのサービスだけで20ある。 ○3つのV Volume 2012年で1.2ZB。95%が非構造データ。今後も非構造データが増加 Velocity デバイスの増加、パーソナライゼーション系の増加 Variaty 素粒子のデータの解析とか、地質学、気象予報とかいろいろやってるみたい。 ○BIG DATAの4つのプロセス。 収集、保存、分析、共有を繰り返しやりましょう。 そこで!AWS使いましょう。 ○収集 AWSへのデータアップロード オンプレにあるデータをAWS(S3)にアップロード ・インターネット経由 ・専用線サービス(AWS Direct Connect、1/10Gbps)も可能 ・AWS Import/Export(HDDを送りつけてS3にアップロードしてくれる。Tokyoリージョンにはだない) ・インターネットVPN経由も可能 ・EC2上のデータももちろんできる。 ※WAN高速化ソリューションも利用可能。 ○保存 ・AmazonS3 99.999999999%の耐久性。 同一リージョン内の3箇所以上のDCに自動複製 容量無制限で低コスト(1G 約10円/月) ・Amazon Glacier データの利用準備に3.5~4.5時間かかる。 S3の約1/10という低コスト ○分析 オンプレミスだと運用が大変。 ・Amazon EC2 スケールアップ/ダウン、アウト/インが即座に可能。ライセンス持ち込みや従量課金に対応 スペックの種類が豊富(SSDとかもあるよと) ・Elastic MapReduce Hadoopをサポートしたの仮想サーバが簡単に用意可能。 S3、Dynamoとの連携も可能 ディストリビューションも選択可能(Apache、MapR) 追加のアプリ(Hive、Pig、HBase)なども利用可能。 ジョブの大きさに合わせてクラスタサイズを適切にすることでコスパがよくなる。 →HadoopのMRのデータのローカリティとかはどうなってるんだろう? ○共有 ・AWS RDS MySQL、Oracle、SQLServerをサポート(PostgreSQLはないのかな?) 自動バックアップ、フェイルオーバー、パッチ適用機能があるよ ・Amazon DynamoDB AmazonオリジナルなNoSQLデータベース。論文有るよ。 運用管理は気にしなくていい。 性能については客指定の性能が出せるようになる。しかも変えられるよと。 ※データサイズに応じて以下を選択しましょう RDS、HBase on EMR、DynamoDB、S3 他にもEC2上で、CassandraやmongoDB、GlusterFSを使ってる事例もありますよ。 ○以上を繰り返すのが意味があります。そこで! ・Simple Queue Service マネージド分散キューサービス 最低1度のメッセージ到達の保証。複数DC間で複製保存 ・Simple Workflow Service 進捗などの管理も可能 NASAのCURIOSITYの制御に利用?10m前進するのに10時間のバッチ処理がある。。。 データがなくて試せない!そんなあなたに! ○AWS Public Data Sets すぐ使えるPublic Dataが用意されてるよ。 http://aws.amazon.com/jp/publicdatasets/ ★AWSのビッグデータ事例紹介 @shot6 ○NETFLIX ・どんな会社? 2500万人以上のストリーミング会員 500億以上のイベント ・AWSの利用は?(保存) 8TB/日のイベントデータを収集しS3に。 Cassandra上の顧客データもS3に。 1PB以上のデータがS3に保存。 ・AWSの利用は?(解析) EMRでレコメンデーション、アドホック分析、パーソナライゼーションなど。 本番クラスタ(ずっと動かしている) アドホック分析用クラスタ(必要に応じて構築) 解析用のアルゴリズムをAPIで叩けて、ジョブとして定義されてるらしい ・Cassandraを使ってるよ。 Cassandraのクラスタをマルチリージョンで対応したりもしてる。 CassandraのBackupもやってる。OSSで公開されてる? ※HBaseのものもあるよ。 ※AWS上のCassandra事例もいくつか広告系で出てるみたい。 ・High I/O Instances for EC2(SSDのインスタンスまだ東京に無いらしい。) ・AWSスケールアウトだけでなく、スケールアップも徐々に増えています。 ○yelp ・どんな会社? 口コミサイト。 スペルミスの自動修正、検索ワード自動補完、 ・AWSの利用は? WebサイトのログをS3に保存。 EMRを利用してHadoopClusterで解析してS3に保存している。 EMRは処理終了後にシャットダウンしてる。 ・データ解析が日常になった ○SHAZAM ・どんな会社? 広告配信、モバイル系の配信をやってる会社。 Super Bowlの広告配信でAWS、DynamoDBを利用。 ※マイネット・ジャパンでもDynamoDBを利用している ○CLIMATE Corporation ・どんな会社? 天候保険の会社 ・AWSの利用は? 200TBの地質、天候データを解析して ○THOMSON REUTERS ・どんな会社? 情報提供の会社。データの提供が元だけど、解析した結果の情報も提供してるみたい。 ・AWSの利用は? MarketScanという18年分の個人の医療データ(個人情報自体はないみたい)を販売する、販促ールとして利用。 1500万人分の患者データを提供。 マーケットの分析に使えるデータの提供。 KARMASPHEREとEMRの組み合わせで、ソリューションを提供していますよと。 ・事例 1.MarketScanをS3にアップロード。 2.分析官が、KARMASPHERE経由でEMRにアクセス。 3.EMRにS3からデータロードされ、結果がRDS(Oracle)に保存 4.RDSに他の人達もアクセスして使ってるよと。 ○RANGESPAN ・どんな会社? ECサイト向けのPaaSサービスを提供してるロンドンの会社。 ・AWSの利用は? NLP、機械学習にEMRを利用? mongoDBのクラスタを構築してる。 ※mongoDBの日本の事例としてCAがあるらしい。 ★Huahin Framework活用事例 on AWS @ryu_kobayashi ○Cassandra本とかもやられてるみたい。 ○EMRとは PaaSなんだけど、中身を自分でいじれるらしい。 Management Consoleでは3つのバージョンが使えるが、コマンドラインからだと他にも使えるみい。 ・HBaseはAmazonのDistributionのものだけ。 ・EMRのメリットは? インフラの面倒を見なくていい。 クラスタの立ち上げも複数あげられるので簡単。本番実行と同じ環境 ・EMRのデメリット オンプレミスにすでにデータがあるとアップロードが大変。実際に物理HDDを送ったこともある(2,3日でAWS上にアップロードされた) 外に出せないデータがあると。。。 ○EMRのTips(EMRの連載に載ってますよ!http://gihyo.jp/dev/serial/01/emr) ・Bootstrapを設定 EMRのクラスタの起動前にメモリ設定とかHadoopの設定が可能にできる。 ・ファイルサイズを適切に Map数=splitを決めるコード を指定することで、処理が早くできるのかな? ○EMRの起動には いろいろあるけど、HuahinEManagerを使うと使いやすいよ? ○Huahin Frameworkの構成 ・Huahinの名前の由来は? 社内のコードはワインの産地にするという決まり。 タイの観光地Hua Hinがワインの産地。 ・他のHadoop関連のマスコットより可愛いでしょ!? ・Huahin Core MRのプログラムを簡易化 WritableとかSecondary Sortとか書かなくていい 考え方がSQL寄り 素のMRも書ける。Pig、Hiveだとパフォーマンスが難しい Huahin UnitというMRUnitをラップしたものもある ・Huahin Tools 汎用的な処理を集めたツール群だけど、Apache Logの成形のみ。 オンプレミスHadoop、スタンドアロン環境でも動かせるようになってる。 ・Huahin Manager Jobを管理するマネージャ Jobの実行 キューを持ってるので、複数の実行が可能だよ。 EMR対応してる。bootstrapに設定するとできるらしい。 ・Huahin EManager EMRのいろいろが管理できるみたい。 初期設定20までしかインスタンスが挙げられない上限があるらしいので気をつけましょうと。 キュー登録のPOST機能は便利そうだ。(EMR触る機会まだまだないけど。。。) EMRにはJobのkillがない→Job FlowをターミネートすればOK→実際にはEMRのマスタノードにSSHすればできるよ。→めんどくさいよね。。。 EManagerなら可能ですよと。これは必須だよなぁ。 ","date":1352477220,"dir":"post/2012/","id":"98c640616f997a323af625e34ba34850","lang":"ja","lastmod":1352477220,"permalink":"https://blog.johtani.info/blog/2012/11/10/aws-%E3%83%93%E3%83%83%E3%82%B0%E3%83%87%E3%83%BC%E3%82%BF%E6%B4%BB%E7%94%A8%E4%BA%8B%E4%BE%8B%E3%82%BB%E3%83%9F%E3%83%8A%E3%83%BC%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-jawsug/","publishdate":"2012-11-10T01:07:00+09:00","summary":"初目黒(たぶん)で、初Amazonな感じで、流行りの「ビッグデータ」のセミナーに参加してきました。 とりあえず、いつもの自分用のメモを残してお","tags":["勉強会"],"title":"AWS ビッグデータ活用事例セミナーに参加しました。#jawsug(Jugemより移植)"},{"contents":"##Lucene/Solr 4.0.0リリース ついに、Lucene/Solr4.0.0がリリースされました。 MLで流れていましたが、3年越しのリリースだったようです。 コミッターの方々、JIRAにバグ報告をした方々、お疲れ様でした。\nということで、ちょっと忙しくなりそうです。。。 4.0の機能を調べたりもしたいですし、すこしずつ紹介もしたいです。\n本家サイトのニュースはこちら\n##lucene-gosenの4.0対応版について lucene-gosenも4.0正式版のjarを利用したバージョンを公開する予定です。 branches/4xでは、すでに作業を行なっており、jarファイルの差し替えは終了しています。 お急ぎの方は、branches/4xをエクスポートして、ビルドしていただくと利用可能となっています。 なお、Lucene/Solrのバージョンが上がっているため、lucene-gosenのメジャーバージョンも変更し、lucene-gosen-4.0.0としてリリースする予定ですしました。。(順当に行けば、3.0.0ですが、Luceneのメジャーバージョンに合わせたほうがわかりやすいかと思いまして。) また、現在、trunkが3.6.x対応のソースになっていますが、このあと、現在のbranches/4xのソースをtrunkにする予定です。 3.6.x対応のlucene-gosenについては、branches/lucene-gosen-rel2.0にて作業を行うこととなります。 今後は注意してチェックアウトするようにお願いいたします。\nということで、ダウンロードできるようにしました。 lcuene-gosen-4.0.0*.jarとついているものがLucene/Solr 4.0.0に対応したライブラリになります。\n","date":1350031500,"dir":"post/2012/","id":"922cc71fd28b1dac8f407f1d517f5595","lang":"ja","lastmod":1350031500,"permalink":"https://blog.johtani.info/blog/2012/10/12/lucene-solr-4-0-0%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9lucene-gosen%E3%81%AE4-0%E5%AF%BE%E5%BF%9C/","publishdate":"2012-10-12T17:45:00+09:00","summary":"##Lucene/Solr 4.0.0リリース ついに、Lucene/Solr4.0.0がリリースされました。 MLで流れていましたが、3年越しのリリースだったようです。","tags":["lucene-gosen"],"title":"Lucene/Solr 4.0.0リリース&lucene-gosenの4.0対応(Jugemより移植)"},{"contents":"このイベントにウチダスペクトラムの枠でMahoutのコミッターである、Grant Ingersollさんが講演されるということで、興味があったので聞いて来ました。 (この枠だけ)\nLucidWorks社が現在展開している、LucidWorks BigDataの概要とコンセプトといった話の内容でしょうか。 LucidWorks社(元Lucid Imagination)はLucene/Solrのコミッターの方々が多く在籍している会社です。 検索システムに関するノウハウを元に、発見や解析といった部分にニーズが広がってきているという話の ざっくりした概要のはなしでした。 検索システムを中核にして、ログや検索で提供しているデータの解析などの重要そうなポイントが散りばめられて いるお話でした。\nもっと詳しい話を聞きたいなぁ。\n講演では日本語の資料でしたが、サイトに英語の資料がアップされているとのことでした。 原文が読めるのは非常に助かります。他のイベントなどでもこのように英語の資料も見れるようになると嬉しいです。\n以下は、いつものメモになります。\n場所:富士ソフト アキバプラザ5Fホール 日時:16:10- ◯サーチ技術による情報の可視化 通常、検索と言うとWebサーチだけど、ウチダスペクトラムのやっている部分はエンタープライズ向け ナイスガイ=Grant S. Ingersollという紹介 ◯サーチからSDAへ LuceneやSolrのお陰で、検索自体は簡単になってきている。 ◯サーチの進化 ユーザとデータを結びつける意味での検索の進化が必要 ユーザインタラクションや、アクセスの方法とか ◯SDA Search, Discovery and Analytics ・ユーザからのニーズ 検索、優先順序付け、新たな気づき、フィードバックによる学習 ・ビジネスからのニーズ ナレッジの有効活用 ◯ユーザ事例 保険会社での請求に関する不正利用分析を含んだクレーム処理と分析 ◯事例:個人に最適化された医薬品 DNAをベースに検索やファセットで医薬品を検索したり。 ◯事例:通信会社における通話記録処理 ログを元に検索して、不正通話などを解析 ◯SDA基盤に必要な要素 高速で拡張性のある、検索 大規模でのコスト効率が高いストレージと処理 NLPとMLにより解析などが向上 ◯SDAのアーキテクチャ 基盤 LucidWorks Search、Hadoop、HBase、ApachePig、Mahout、 NLP、 管理 Zookeeper インフラ ZABBIX、AWS、Chef データの流し込み Twitterからのデータとか ◯検索部分にフォーカス ・LucidWorks Search SolrCloudによる簡単なshard処理 ・Hadoop ログ、生データ、中間ファイルの保存 WebHDFS 小さなファイルには向いていない ・HBase メトリック、ユーザ履歴などのストレージ 課題 どこに正式に保存する? リアルタイム処理 vs バッチ処理 分析はどこで行われるべきか? ◯検索の実装に関連すること 3つのポイント 性能と拡張性 関連性 オペレーション(モニタリング、フェイルオーバーなど) ビジネス側では検索結果の適合性を重要視する 開発側は性能を重視する傾向がある。 ◯適合性に関して テストが重要。 クエリ、クリック、表示したドキュメントなど、すべて保存すべき! ◯Discoveryにフォーカス ◯MahoutによるDiscovery 3つのC ・協調フィルタリング ・クラシフィケーション ・クラスタリング 追加事項 課題 収束を伴う計算コストの高い機械学習アルゴリズム Mahout ◯余談:Experiment Management ◯Analyticsにフォーカス Rとか、うまく活用 検索エンジン自体でもできることがある。ファセット、TF、DF/IDF SearchとDiscoveryの定量化 ログ、ナビゲーション分析 ","date":1348650492,"dir":"post/2012/","id":"43501cdf0de25278a208cbb9aad80012","lang":"ja","lastmod":1348650492,"permalink":"https://blog.johtani.info/blog/2012/09/26/lucid%E3%81%AEgrant-ingersoll%E3%81%95%E3%82%93%E3%81%AE%E8%AC%9B%E6%BC%94%E3%82%92%E8%81%9E%E3%81%84%E3%81%A6%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-09-26T18:08:12+09:00","summary":"このイベントにウチダスペクトラムの枠でMahoutのコミッターである、Grant Ingersollさんが講演されるということで、興味があった","tags":["勉強会"],"title":"LucidのGrant Ingersollさんの講演を聞いてきました(Jugemより移植)"},{"contents":"PFIオープンセミナー2012に参加してきました。 対象から微妙に外れてたり、話の内容についていけるか自信がありませんでしたが、参加してきました。 PFIさんは前から面白そうなことやってる会社だなぁと思っていたので。\n面白い話がいっぱい聞けました。 電池が切れそうなので、とりあえず、まずはメモをアップしときます。 かろうじてついていけたという感じですが。 丸山先生の話はアーキテクチャの話に入る前のビッグデータの光と影の話がよかったです。 ビッグデータと言っても、まずは、サンプリングなどで小さなデータで処理できるかもしれないと考えるのも必要なのでは?という話や、相関があるからといって、因果が有るわけではないとか、おそらく、統計やってる人や、数学やってる人にしてみれば、当たり前の事なんでしょうが、その部分に警鐘を鳴らす話が聞けたのは良かったです。 もちろん、ビッグデータでなければ意味が無い解析などもありますという話もきちんと出ていました。\n伊藤さんの話は、Screwと呼ばれる、多言語解析基盤のお話です。その前にSedueの紹介で、SolrとSedueの比較の話も出ていました。(若干、強引な感じもしましたが。。。) 多言語解析基盤は、Solrでも少し入ってきています。ただ、それよりも汎用的な作りになるようなので、今後Solrと組み合わせて使うといったことも可能になるかもしれません。 まだ、対応言語などが少ないので今後に期待という感じでしょうか。 複数の言語が混ざった時の挙動がどうなるのかや、身近な文章での言語判定の正確さは少し気になります。\nサイバーセキュリティの話も面白かったのですが、話が多岐にわたるのと、スライドの情報量の多さに少しついていけませんでした。 資料が公開されたら、もう一度見直したいかなぁと。\n比戸さんの話は、Jubatusと関連のある話でした。機械学習の実際の利用の話が特に興味深かったです。 最近になって、ようやく、実際のデータを利用した話が出てきているみたいで、もっと事例が出てくると機械学習も身近になりそうだなぁと。\n最後は、日経BPの中田さんの話でした。これが、一番想像していたものと内容が違って、驚きつつ、楽しめた話でした。 ビッグデータというバズワードがいかにして生まれたのかがよく分かりました。 私は、バズワードだなぁと思う程度だったのですが、出てきた背景にある程度意味があるという考察に感心して聞き入ってしまいました。\nということで、思っていたよりも話の内容についていけたので、講演された方々の話しのされ方が良かっただと思います。\n少し無理をして参加してよかったと。\n残念だったのは、会場が地下だったため、携帯が入らなかったことでしょうか。 私はe-mobileで接続していたので大丈夫でしたが、docomoの携帯は圏外でした。 ツイートがもう少し盛り上がれば、もっと質問も出たのかもしれないです。\nhttp://preferred.jp/news/seminar/\n資料が公開されたので、リンクを貼っておきます。 PFIの方たちの資料へのリンク: http://preferred.jp/news/?id=1139\nゲスト講師の資料へのリンク: http://preferred.jp/news/?id=1159\n◯「多様化する情報を支える技術」 講師:西川徹(株式会社プリファードインフラストラクチャー 代表取締役) ・PFIの説明 VCに頼らない。製品につながるビジネスにこだわる(受託開発しない)、技術の多様性を重視 ・PFIの技術領域、ビジネス 製品開発(Sedue/Bazil/Jubatus)、自然言語処理、機械学習、分散システムなど ・”人”が生み出すデータと\u0026#34;機械\u0026#34;が生み出すデータ ビッグデータの発端はGoogleが元じゃないか?→最後の公演で解説があるよ 人:質が高いけど、量が少ない 機械:質は低いけど、量が多い ・検索システムについてのお話 社内の資料とか情報が、人によって、まちまちなデータの保存(形式、場所など)が実施されてしまう。 情報検索技術と大規模データ ・人のデータへ必要なアプローチ より検索システムを活用してもらうために、楽に整理できる仕組みなどをどう提供するか 質の高いデータなのに、形式的な共有しかできていないのはもったいない ・機械のデータへ必要なアプローチ 大量データと高度な解析が重要(CEPとか) デバイスが性能向上→流れてくるデータが大量に→蓄積するだけでも問題になってくる →蓄積したデータを扱うだけでも処理コストが高くなる 分析をオンライン化、ストリーム化すること→Jubatusで貯めずに高度な解析をしましょう。 Edge-Heavyになりつつある。 ◯「ITアーキテクチャはどこへ向かうのか」 講師:丸山宏氏(統計数理研究所 副所長 モデリング研究系教授 工学博士) ・ビッグデータの光と影 「その数学が戦略を決める」という本がオススメ ・大量データでも、ランダムサンプリングでとければ、ビッグデータじゃなくてもいいよね。 もちろん、ランダムサンプリングだけじゃダメな場合もある。 ・Hadoopが解ける問題領域って少ないのでは。 ・TVを見る時間が長い人ほど、方言の使用率が高い 因果関係と相関関係の違いをきちんと理解しましょう。 ・データをきちんと理解して意思決定などをしたほうがいいよと。 ・つぎのアーキテクチャは何か? ・コンピュータ・アーキテクチャの歴史 ConnetionMachine CM-1(1985) SPARC Transputer(CSPによる並列性、Occam) SymbolicsLispMachine Intelアーキテクチャの台頭により、アーキテクチャの研究が廃れてくる ・クラサバ、スマホ・クラウドなどのアーキテクチャの話 ・じゃあつぎは? Edge-Heay Data=スマホなどデータが保存される場所がEdgeになりつつある ビッグデータのほとんどが廃棄されるデータ ・Edge-Heavy Dataに特化したアーキテクチャとは? 分散マッチング・プロトコル→サマリ情報を交換することで、絞り込みが可能 X=3とした場合、センサーとかなら、ピンポイントな値ではなく、範囲では。 分布表現を1stクラスオブジェクトとするプログラミング言語が必要では? ・アーキテクチャの変節点を見極めよう QA: Q:スパースネス問題がランダムサンプリングやフィルタリングじゃ解けないんでは? A:はい。ただ、その前にやることがあるはずですよねという注意喚起の意味での発表です。 価値に応じて、EdgeにあるデータをCenterに持ってくるという考え方が必要。 今は価値が見いだせないのなら、Centerにまで持ってこなくてもいいのでは。 ◯「グローバル化する情報処理」 講師:伊藤敬彦(株式会社プリファードインフラストラクチャー 研究開発部門 リサーチャー) ・Sedueの説明 NHKニュースなどで ・提供する機能 ・検索補助 レコメンド、サジェストなど ・レコメンド機能の紹介 ・Sedue/Solrの比較 サポート体制:開発チームがサポートしてくれる 安定性:GCがないのがいい 付加機能: 検索の完全性:接尾辞配列による検索 ・多言語処理の話 ・翻訳ではなく、任意の自然言語言語で動作・精度を向上させる処理の話。 ・背景 サービスのグローバル化、会社組織のグローバル化 ・複数言語を扱う場合の難しさ 多言語解析基盤Screwの開発。 1.必要な処理を順番に適用する 処理の順序は設定で。出力はJSONで。 例:言語同定、単語分割、単語正規化 →言語同定処理で 2.言語ごとに必要な処理を適用 ・疑問 ScrewはSolrとの組み合わせもできる? 複数言語が混ざった文章の場合にどういう形で動作する? 言語判定は独自実装? ◯「BigData処理技術とサイバーセキュリティ」→題名変更されてた 講師:桑名栄二氏(NTTセキュアプラットフォーム研究所 所長) ・経歴 Jubatusプロジェクト立ち上げに参画 ・攻撃に関する話 原因のわかっていないケースが多い。 ・端末の初期設定のパスワードとかが狙われるケースも多い ・変化する攻撃、変化するシステム・サービス、変化するデータ ・マルウェアの分類にJubatus ・不正IPアドレスを機械学習して ・ABC 「あたりまえ」のことを「ばかみたいに」「ちゃんとやる」 ◯「先進ビッグデータ応用を支える機械学習に求められる新技術」 講師:比戸将平(株式会社プリファードインフラストラクチャー 研究開発部門 リサーチャー) ・ビッグデータ分析はより深い地検を得られるビッグデータ「解析」へ ・ビッグデータ分析プロセス Volume、Variety、Velocity 蓄積(NoSQL系)、分析(CEP)、両方やるのがHadoop ・分析から深い解析へ 予測、カテゴリ分類、レコメンド、異常検知 これを機械学習で解決する方向で ・機械学習を応用している例 クレジットカードの不正利用検知:FICO ネットワーク攻撃/侵入検出 Jeopardy!でクイズ王に勝利 医療診断支援 ・データ解析技術への過度な期待と現実とのギャップ いろいろできるみたいだけど、何が必要? ・ビッグデータ処理系を使える人 ・データサイエンティスト ・機械学習ツール ・ビッグデータ処理系での機械学習への対応状況 Hadoop本体(YARN) MapReduce系(Mahout、AllReduce or Vowpal Wabbit、SystemML) 非MapReduce系(Spark) ・機械学習からビッグデータへの歩み寄り ベンチマーク性能への固執とか、応用との乖離を批判する論文もあるらしい。 ・機械学習の応用例 Machine Lerning for the New York City Power Grid[Rudin et al., TPAMI, 2012] 電力配電設備の障害予測・検知 実データを用いた例が今後増えていくのでは。 ・今後重要になる技術とPFIの取り組み ・データ解析の敷居を下げるためのトレーサビリティ 機械学習向けスクリプト言語は敷居が高い WekaやSPSSのようなアイコンベースのデータ処理プロセスの記述は前処理には強力だけど、機械学習とは相性が良くない 結果が見える化部分との統合が不十分。 ・Bazil Farm学習結果分析例 Tweet年齢推定、Tweet性別推定 ◯「“ビッグデータ”が話題になった理由」 講師:中田敦氏(株式会社日経BP社 記者) ・自己紹介 ・バズワードができるまで まずは、「クラウド」のバズワードの歴史 「バズワードはIT企業やThe Economist誌の煽りでなく一般企業の経営陣が納得すると生まれる」 ・なぜ経営者がビッグデータに興味を? 「ザ・クオンツ」という書籍に金融業界のルールの変化が書かれてる。面白いよ。 Google/Amazonに対する警戒心から。 破壊的な新規産業者へ対抗して行かないといけない思うところからビッグデータが流行ってるのでは。 「買ってきたIT」は差別化要因にならないのでは?→自分で作ったITなら差別化できる。 ・競争力は自分で作るしか無い 日本のとある特殊事情 ITエンジニアの所属先が日米で割合がぜんぜん違う。米国はユーザ企業が75%、日本は25%くらい ・ビッグデータの次はなに? 3次元プリンタがあれば、好きなモノが作れちゃう。=消費地の近くで作成しちゃえば良くなるのでは。 ","date":1348214700,"dir":"post/2012/","id":"89abaa7f21cf788ce4744e3e61173291","lang":"ja","lastmod":1348214700,"permalink":"https://blog.johtani.info/blog/2012/09/21/pfi%E3%82%AA%E3%83%BC%E3%83%97%E3%83%B3%E3%82%BB%E3%83%9F%E3%83%8A%E3%83%BC2012%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%A6%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F--pfiopen2012/","publishdate":"2012-09-21T17:05:00+09:00","summary":"PFIオープンセミナー2012に参加してきました。 対象から微妙に外れてたり、話の内容についていけるか自信がありませんでしたが、参加してきまし","tags":["勉強会"],"title":"PFIオープンセミナー2012に参加してきました。 #pfiopen2012(Jugemより移植)"},{"contents":"友人にお値打価格で購入したMac miniはMountain Lionにアップデートしてたのですが、手元のAirはまだアップデートしていませんでした。\n夏休み中にバックアップ+アップデートをしてしまおうと思いMountain Lionにアップデートはしていたのですが、 本格的に触り始めると色々と動かないものがあったので、備忘録としてブログを書いておきます。 (まだ途中ですが。)\n###1.Eclipseが起動しない Java6が未インストール状態になったみたいで、Eclipseを起動すると、Java6をインストールしなさいと言われました。 で、私の記憶が確かなら、前はJavaコマンドを実行するとインストールされたんですが、ターミナルでjavaコマンドを実行するとjavaはすでにインストールされてる模様。。。 あれ?と思い、-versionを実行すると、JDK7u4と出るじゃないですか。 どうやら、Java7u4は別途入れてたものが残ってる模様。 さて、どーする?ということで、ツイートしたりぐぐってみて、「Java Preferences」なる設定用のアプリ?が有ることに気づき、とりあえず開いてみたらJava6ないからインストールしたら?と言われました。 結果オーライということで、インストール開始。 無事、インストールも終了。Eclipseも起動しました。(ただし、今度はMercurialのプラグインがPythonのライブラリが無いとエラーを出すことに) ###2.Xcodeが起動しない。 使ってはいないんですが、Javaの件を調べるのに、起動したらLionじゃないと駄目だよと。 ということで、Xcodeもインストールしなおし。 ###3. homebrewが動かない 1.で書いた方法で、Eclipse自体は起動したんですが、Mercurialのプラグインがエラーを吐き始めました。 で、見てみると、hgコマンドを実行しようとしてなんか、壊れていると。 で、hgコマンドってどうやってインストールしたか思い出さないまま、とりあえず、homebrewだっけ?と勘違いしたまま、「brew update」を実行したらエラーがでて、「brew install git」でしょ?って言われてしまいました。 コメントにもいただいていたように、Xcodeをインストールしたのだが、コマンドラインツールが入ってないというのが影響しているみたいです。。。 で、ググってみると、こんな情報が。[http://labs.torques.jp/2012/07/04/2830/](http://labs.torques.jp/2012/07/04/2830/) ただ、そこに有るようにPreferenceのダウンロードを開いてもなーんにも表示されません。 で、更にググってこちらの情報に。[http://qiita.com/items/9dd797f42e7bea674705](http://qiita.com/items/9dd797f42e7bea674705)(なんだか、TLで見かける人のお名前が!) AppleのDeveloperサイトからダウンロードかぁと思いつつダウンロード用のリンクを踏んだら、アカウント登録しろとのページが。。。 なかなか遠い道のりですね。。。 Appleのアカウント自体は持ってるので、Developerへの追加登録なんですが、日本語が文字化けしまくりの確認ページが出る始末。 もう、めんどくさいので、そのまま登録しちゃいました。 で、ダウンロードする前にもう一回XcodeのPreference見てみたらなんか、ダウンロードする候補が出てきてるじゃないですか! 結局、XcodeのPereference画面からダウンロードすることにしました。 AppleのDeveloperに登録したからなのか、Xcodeのプロジェクトを作ろうとしてXcodeをきちんと起動したからなのかは結局わかっていません。。。 良くないよなぁ。(ご存知の方いたらコメントもらえると嬉しいです。) で、やっと「homebrew」を入れようかなぁと。 一応その前に「sudo brew update」ってやってみたらどうなる?と挑戦したら今度は動きました。 homebrewが何を判断してinstallでしょ?って言ってたのかもわかっていませんが、updateで良かったみたいです。 ついでに、upgradeもしときました。(こっちは後からインストールしたもののバージョンが上がってるものがあったら更新してくれるコマンドかなぁ?)\n###4. pipの更新 ただ、brewをupdateしても相変わらず、EclipseのMercurialのPluginはエラーを出してました。 で、ターミナルからhgコマンドを実行してみたら同じエラーが。まぁ、そうですよね。 エラーメッセージを頼りにこれまたググってみたら、同じ状況のひとがいました。[https://groups.google.com/forum/#!msg/mercurial-ja/MxY6lejLXxo/OgJA_knXV6cJ](https://groups.google.com/forum/#!msg/mercurial-ja/MxY6lejLXxo/OgJA_knXV6cJ)(ここにもTLでお世話になってる方のお名前が!!) で、書いてあるように「とりあえず pip install mercurial で解決しました. 」ということで、コマンドを実行して見ることに。 これが、また失敗します。。。(日頃の行いが悪い??てか、日頃MBAをメンテできてないのが悪いのか。。。) そういえば、過去のMBAセットアップのメモを残してたなぁと思い出して「johtani mercurial」でググってみるとちゃんと[書いてある](http://johtani.jugem.jp/?eid=34)じゃないですかー(偉いぞ、自分) ということで、「sudo easy_install pip」でpipを更新してから「sudo pip install Mercurial」で無事、hgコマンドもインストールし直せました。 Eclipseを起動してもエラーが出ない。(まだbitbucketに接続確認まではできてないですが。。。眠さに勝てず寝てしまいました。) ","date":1346650440,"dir":"post/2012/","id":"7604edf307a5e96120606c8dda06458f","lang":"ja","lastmod":1346650440,"permalink":"https://blog.johtani.info/blog/2012/09/03/%E3%83%A1%E3%82%A4%E3%83%B3mba%E3%82%92mountain-lion%E3%81%AB%E3%82%A2%E3%83%83%E3%83%97%E3%83%87%E3%83%BC%E3%83%88%E3%81%84%E3%82%8D%E3%81%84%E3%82%8D%E7%A2%BA%E8%AA%8D%E4%B8%AD/","publishdate":"2012-09-03T14:34:00+09:00","summary":"友人にお値打価格で購入したMac miniはMountain Lionにアップデートしてたのですが、手元のAirはまだアップデートしていませんで","tags":["備忘録"],"title":"メインMBAをMountain Lionにアップデート(いろいろ確認中)(Jugemより移植)"},{"contents":"興味をもちつつ、触っていない軟弱者ですが、興味があるので今回も話を聞きに行って来ました。\nまずは、作者古橋さんによるFluentdの魅力や次期バージョンのお話。 あいかわらずわかりやすいスライドで話もわかりやすくてよかったです。 どうしても実績という点を懸念事項として上げる人が多いというアンケートを元に、各社が使ってるし導入もしやすいですというお話。 ここまでしてもらってるのに触ってないなんてほんと申し訳ないです。。。\n次は楽天の方によるCloud Foundryのログの問題点解消のためのFluentd導入のお話。 EC2でもそうですが、ファイルが永続化されない?のでログが消えてしまうという問題があるので、 集約しましょうと。 いままでとは少し違う問題点からの話でした。\n次はドリコムの方(浴衣?甚平?でかっこ良く発表)のIDCをまたいだFluentdの活用と、Fluentd自体の監視などについてのお話。 実際にログが増殖して苦労された点を解決するために考えられた監視項目など、あとで見返したくなる資料でした。 実際に試行錯誤されたあとの話はやはりありがたいです。 あと、お子さんが可愛かったw\nつぎのCROOZの方のPCがWindowsだったため(?)プロジェクターに繋がらず、急遽QAタイム。 このあたりの@doryokujinの話のつなぎの旨さとかほんとすごいなぁと感心します。\nで、Macに乗り換えてCROOZの方の発表。 Fluentd+TreasureDataのお話。少人数(というか一人?)でも簡単にログ収集の仕組みが作れて、しかも保存先のサーバを用意せずに簡単な解析もできるというお話。 これは、ちょっとやってみようと思う人(少なくとも、私はやろうと思った)が増えたんじゃないかなぁという発表でした。 スライドがなぜか最後のほうが見えなくなってしまったので、第3回でも発表されるということになってましたw 最後は新大阪から文字通り駆けつけた玉川さんのHBase本+そのた今後の翻訳本の紹介。 つぎはHiveの本も出てくるみたいでした。 日本語の資料ってホント助かります。購入しないと翻訳本が出る機会もないみたいなので皆さん買ってくださいとのこと。 HBaseはまだ触りそうにないから9月に出るAWSの本でも買おうかなぁ。 あ、日本語で解説してあるSolrの本もあるので是非買ってください!\nその後は懇親会でした。今回もTL上でズケズケと私が勝手に絡んでいる方たちにリアルにお会いできたので楽しかったです。\n自分もフロントよりも、バックエンドに興味があるし、実際に運用されてる人の話が多く聞けるので次回も参加したいです。 それまでにどこかで触るかplugin作るかしないとなぁ。\nということで、以下はいつもの適当メモです。\n開催日時:2012/08/22 18:00 ~ 22:00 場所:グリー株式会社 14F セミナールームYosemite ◎「Fluentdの現在と未来」 Treasure Data, Inc. 古橋 貞之 (@frsyuki) ◯アンケートの内訳 ◯ドキュメント欲しい? ※思ったより日本語のドキュメントじゃなくてもよさそうだった。 ◯loggingってなんでいるの? いろいろな解析ってあるよね。 ◯ログの集約、保存、などの問題点について フォーマットが混在 集約するのもいろんなスクリプトが混在 ◯メリット ・プラグインアーキテクチャ in/outに合わせてプラグインが用意/開発可能 ・フォーマットがJSON アプリでの解析が楽 ・HA構成が可能 ◯実績がない?→ 誰が使ってる? COOKPADとか、NHNとか ◯次期バージョンの構想 ・設定ファイルで色々とらくできるよ。 ・MessagePackのv5に対応 ・td-agent-lite などなど ◯QA Q:時刻にミリ秒を持つことは可能? A:互換性も気になりますが、検討します。 Q:JSONで構造化が売りだが、Flumeとかはテキストだけど、テキスト A:ログのパース時にやるというスタンス。 Q:日本語ドキュメントがやっぱり欲しい。手伝います! A:別ブランチで翻訳しながら公開して欲しいし、バラバラにやるよりいいので。 Q:Windowsでも動かしたいけど、cool.ioの移植とか考えてないですか。 A:次期で、fluentdのコアからはcool.ioを外す予定です。 ◎「Logging Infrastructure in PaaS by Fluentd」 Rakuten, Inc. Yohei Sasaki (@yssk22), Waldemar Quevedo (@wallyqs) ◯Cloud Foundryの説明 ◯Cloud Foundryの問題点 解析しようにもログが消えてしまう。。。 なので、Fluentdでログを集める仕組みを作ったよと。 これかな? https://github.com/rakutentech/dea/ ◎「Fluentdを優しく見守る監視事例」 株式会社ドリコム 外道父 ( @GedowFather ) ◯概要: Fluentdをより穏やかに安定稼働させるための監視項目と自動処理について。また,その実運用における障害例なども紹介したいと思います。 ◯目次 ◯動作環境 ・IDCもバラバラな環境のログを一箇所に集約。 グローバルなネットで、圧縮、暗号化し、VPN使ってない ・tailのプラグインを改良して利用 copy、flow counterを利用 forwardも改良 Flume OGとは比較にならないし、FlumeNGはOGと全然違うから論外だった。 ◯ローカル監視 ・monit使って監視してる。 ログを記録してるか、内容が正しいか td-agentが正しく起動してるか、Collectorに送っているか 重複起動してないかとか、起動してるかとか。 ※重複起動でログが増えてた(@mazgi濡れ衣事件) HDFSに送ってるか、保存されてるか ◯リモート監視 アラート/グラフ作成の集約 状態の可視化 Collectorのキャパシティ管理 Agentにキャパシティの心配はほぼないが、Collectorは足りなくなる可能性がある。 ◯野望 CollectorでAgentを把握したい ◯QA Q:圧縮はどうやって? A:forwardを改造してやっている。 ◎QAタイム Q:秒間どのくらい出るの? A;秒間8000メッセージくらいらしい。 Q:ハートビートの取りこぼしは? A:案1:UDPじゃなくて、TCPにする。案2:TCP接続してたらハートビートのカウントとしてしまう。 Q:CollectorのCPUに影響があるのってなに? A:ロックがCPUを食う=ロックが影響→リクエスト量を減らす Q:Windows対応はいつ?(発生源がWindows) A:td-agent-liteをWindows対応にしたいと思ってる。 Q:F#の実装とかテストは? A:性能値の測定までは行ってない。メッセージが送れたなぁくらい。 Q:設定のDSL化はv11ではなくなったの? A:ホスト名は入れたい。設定はやっぱり設定だけにしたい(プログラムは入れたくない) プラグイン側がDSL対応してればDSLできるようなものは入れようかと思ってるが、 DSLは延期したい。 A(tagomoris):DSL化したいパターンが幾つかに絞れるなぁと思ってて、それに合わせたプラグインをいくつか作ってるよー。 ◎「Fluentd \u0026amp; Treasure Data でこっそり始めるログ集計」 CROOZ 株式会社 池田 朋大( @mikeda ) ◯概要: FluentdとTreasureDataプラットフォームを使って、1インフラエンジニアが勢いでログ集計システムを作ってみたお話です ◯アクセスログ、エラーログ、メールログ(試験中)を集めてる。 ◯TreasureData 500Gまで無料なのかー。 ◯ダマで入れてもばれないぞ! ◯最後は心の目で見えるスライドでした。 ◎祝・O\u0026#39;Reilly HBase 訳本発売。訳者本人によるPR。 Sky株式会社 玉川 竜司 ※ O\u0026#39;Reillyの新刊「HBase 」 http://www.oreilly.co.jp/books/9784873115665/ ◎懇親会 そうそう、ステッカーもらったのでアンケート書きましたw ","date":1345657200,"dir":"post/2012/","id":"775894425f5a7436f56fc5a3b4a2cfaa","lang":"ja","lastmod":1345657200,"permalink":"https://blog.johtani.info/blog/2012/08/23/fluentd-meetup-in-japan--2--fluentd-%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-08-23T02:40:00+09:00","summary":"興味をもちつつ、触っていない軟弱者ですが、興味があるので今回も話を聞きに行って来ました。 まずは、作者古橋さんによるFluentdの魅力や次期","tags":["勉強会"],"title":"Fluentd meetup in Japan #2 #fluentd に参加しました。(Jugemより移植)"},{"contents":"またまた飲みに行って参加してきました。 今回は、Rails、iOSでのTwitter連携の話から、ツイート分析、クライアントアプリの開発の苦労?楽しい話と、 幅広い話題でこれまた面白かったです。\nRailsはあとで、もう一回資料+ビデオがみたいかも。あと、発表者の方が言ってたけど他の言語の似たようなサンプルがあると面白いかも。(Solr入門みたいに同じ題材で違う言語のサンプルとか)\nツイート分析は、私の使い方とは異なる分析結果がちょっと意外でした。土日はあんまりツイートしないからなぁ。 利用時間帯とかは、他のSNS(Facebookとかmixiとか)の分析と比較してみると面白いのかも。 まぁ、深夜帯はそれほど利用は無いだろうけど。\nAttaccaは自社や自宅でコーディングするときに利用させてもらってます。 どうしても自分のお気に入りのリストを作ってそれを聞くので満足しちゃうんで、 他の人のお気に入りも一緒にシャッフルして再生とかできると面白いかもなぁ。 もう少し、他にも曲を発見したいんだけど、その導線がもう少しうまく行くと嬉しいかも。\nチャーハン諸島の話は開発者の原点みたいな話で面白かった。やっぱり、自分で作るの大事だよなぁと。 作りたいと思うものがあるのはいいことだし、実際作ってみないとわからないこともいっぱいありますよねぇ。 ただ、何か作ろうかなぁと思うものがあるのはちょっとうらやましいとも思いました。 なかなかサービスとか、ほしいものを作ろうと思うところまで行かないからなぁ。年取ったのかなぁ。\n懇親会では、いつものように@twtrfkさんと喋って、あと Lytroを触らせてもらいました! 思ったよりも大きいのが第一印象。 ぱっと見で、何の変哲もないところがズームするところだったりと、インタフェースがちょっとおもしろかったです。 ピントが後から合わせられるということで、どうしても同じ構図になっちゃうのがなぁという話も聞けましたw けど、ちょっと欲しいかもなぁ。動くものを撮るとどんな感じなのかも聞くんだった。\n次回は9月中旬!らしいので、余力がありそうだったらまた遊びに行きます。\n日時:2012/08/01 19:00 ~ 21:00 場所:デジタルハリウッド東京本校 1Fセミナールーム\nいつもの自己紹介タイム\n@i7a16k(@_gifteeの中の人) スライドはこちら\n「RailsでTwitter連携アプリをサクっと作る」 ・まずは、Railsの紹介 MVC+routes.rbの紹介 ・Dev Twitterの登録する必要なとことか。 ・Railsのインストールから起動まで。 ・実際にログイン画面を作成するまでの紹介 コーディングするコマンドの紹介。動画付き omniauth_twitter ってのを使うみたい。 ・サインイン、サインアウトまで。 ツイートは次回! 録画がよくできてて、それに合わせてしゃべるのもうまいなぁ。 @teapipin(ツイッター分析シリーズ の方) スライドはこちら\n「約173万ツイートを調査して分かったTwitterの利用動向」 ・ハンドル名は午後の紅茶からきてる?+ピピン@ ・ブログで色々公開してます。 ・サービス作るのに、下調べをしてみましたというお話 情報が無かったから、自分で調べてみたよと。(すばらしい) ・Streaming APIで取得 タイムゾーンとか言語設定の取得でもうまく取れない。。。 ということで、UnicodeBlockで判定してみたけど、、、 最後は手作業で不要データを除去(すごい!) ・4日間で172万ツイート (金環日食とかスカイツリーのイベントがあったので、4日間で我慢) ・上位5個で50%を占めるクライアントみたい ・日曜日が多いらしい ・携帯が60%くらい ・位置情報(Geoタグつき) 日本が多い。4sqが40%占めてる。 店舗情報や天気情報などもあるらしい。 人口と関係した相関が散布図でわかった。 そこで、ツイート内容との関係を分析 あとで資料みたいなー @i2key(#attacca の関係者) スライドはこちら\n「iOSのTwitterFrameworkを使ってみたら・・・・」 ・Twitter4Jのほうが楽だったよー デモがいいね! ・アーキテクチャ play!をバックエンド。Amazonとか。 iOS Twitter framework ・Reverse Authの使い方とか。 申請してから、20日間かかった。 @Mocel(チャーハン諸島 開発者) スライドはこちら\n「(仮)Twitter クライアントの開発とかについて」 ・趣味プログラマー ・「ラーメン大陸」のクローン:「チャーハン諸島」を開発 Excel溶けこむGUI Javaで実装 コマンドライン風のTL画面もある(自分では使ってないけど) 「電力会社の電力使用量モニター」もクライアント初搭載! ラーメン大陸のバージョンチェックも可能w ・開発したことで 自分のニーズにジャストフィット 優しい気持ちになれる(苦労がわかる) Twitter APIのテストとかもすぐ試せる ・GUIアプリ開発のノウハウも手に入るからオススメ ・API利用規約は読んどこうね ・自動アップデート機能がいるよ。→バージョンごとのサポートがなくなるよ。 ・通信エラー前提で作りましょう ・鍵付きの非公式RTはやめなさい。 ・Twitterクライアントの作成はおもしろいよ! 反応がプレッシャーになることもあるけど。 おもしろ機能をつけるのがいいよーと 話が上手で聞きやすかった。 ","date":1343875800,"dir":"post/2012/","id":"8a29f62d1bebfe7b8008d7f264b56b4e","lang":"ja","lastmod":1343875800,"permalink":"https://blog.johtani.info/blog/2012/08/02/twitter-%E5%8B%89%E5%BC%B7%E4%BC%9A--twtr_hack-%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-08-02T11:50:00+09:00","summary":"またまた飲みに行って参加してきました。 今回は、Rails、iOSでのTwitter連携の話から、ツイート分析、クライアントアプリの開発の苦労","tags":["勉強会"],"title":"Twitter 勉強会 #twtr_hack に参加しました。(Jugemより移植)"},{"contents":"ということで、ステッカー欲しさ?に勉強中の話を恥ずかしげもなく偉そうにしゃべってきました。 #pyfesは以前から、気になっていたんですが、タイミングがあわず初の参加になりました。 TwitterのプロフィールにSenseiDBに興味あると書いていたら、@voluntusさんに声をかけていただけて、 さらになぜかelasticsearchの話をすることにして話をしてきました。 まだまだ、いろんな意味(プレゼン的にも内容的にも)で至らない所だらけだったので反省しまくりですが、 これでまた経験値が稼げたかなと。次回に活かしたいと思いますです。 やっぱり、しっかり勉強して、シナリオを練ってから発表しないとダメですね。。。\n発表のスライドは一番最後にリンクを用意しておきましたので、興味があれば見てもらえればと思います。\nということで、いつものメモを残しておきます。\n日時:日本オラクル青山センター 場所:2012/07/28 10:00 - 20:00 概要:こちらにページあり\n前半(10時から15時)はハンズオンなどをやられてました。参加せずにスライドを微調整して、他の勉強会のスライドをいじったりしてました。 以下は、15時から行われたスライドのメモになります。\n◯PyConJP の宣伝 @shomah4a(LT) 9/15-17 PythonカンファレンスJapan App Engine、Django、Sphinxなどのカンファレンスも併設 遠方参加者支援制度があるらしい。 ◯elasticsearch 入門 @johtani わかりにくい話でしたかねぇ。。。 ◯たのしいうぇっぶくろーら @tokoroten(LT) index.htmlをクロールしまくってる社畜2.0の人らしい。 ◯Sphinxを使って翻訳してたら本が出てた話 @ymotongpoo(LT) OSSでもドキュメント翻訳でお手伝いできるよ。 そしたら、いつのまにか書籍も出せたよ。 スライド\n◯iOS関連のお話 @Seasons バイナリ解析をしてゴニョゴニョする話。 解析するのに何を使ったとか思考の遷移を説明してくれるのでわかりやすい。 スライドが大きなマインドマップを切り出した形。 ◯HBaseのお話 @shiumachi HBase 分散DB 列ファミリ思考 HBaseなんで? RDB→シャーディング→だるい。。。 シャーディング→スケールできねー nandeHBase? 書き込みスケールできるよ。 KVS HBaseのデータ構造 キーがいろいろな情報を含んでる キーがソートされてる HBaseのテーブル構造 リージョンがシャーディングの情報もと? リージョン見つけなど スライド\n◯PythonではじめるGit @mkouhei GitPython LXCホスト? GitもPythonも初心者だわー ◯勉強会を成長させる参加者になろう @sawonya イラストレーター(スタートアップRubyのイラスト書いた人。サインもらいましたw)。 参加者が増えるとなにがいいの?など。 勉強会参加に向けた勉強会の講師とかやられてるらしい。 スライド\n◯IT 系勉強会ネタ(仮) @tmmkr アジャイルサムライを読んだ情報を共有したくなって読書会を開催してみた! ビアバッシュのケータリングとかは楽天デリバリーとか、カクヤスがいいよ。 かなり、いいスライドなので、あとで見返す。 今、読書会やったりしてるし、Solr勉強会の役にも立てそうだし。 スライド\n◯Do not invent your RNG... @kenji_rikitake Androidの乱数のコードがすごいらしい(ひどい) Pythonの乱数ではos.urandomを使うのが安全です。 オレオレ乱数は作っちゃ駄目! ◯分散ファイルシステム(LeoFS) @yosukehara LeoFSの開発者の方。 Erlangで98%書いてある。 Masterノードは存在しない。SPOFになるから。 分散システムとして元にした概念とか論文ってあるんだろうか? ◯継続的デリバリー @troter CIとデリバリーの話。 いいこと書いてあるんだけど、実際のツールの話しがないのが辛いこともある ということで、Python周りのツールをこうして見たよというお話。 Rubyの方がものがいろいろ揃ってるらしい ◯クライアントサイドのみで作ったダッシュボード @takufukushima RESTアクセス用のUIのフロントエンドの話? JSのお話の?node.jsとかの話。 MVCにしたり、CSSフレームワーク使ったり。 backbone.jsつかってるらしい。 実際の画面がみたいなぁ。 現状の話なので、 ◯Meinheld @mopemope Python3対応とかLoggerとかやってから秋くらいに出るみたい。 このあたりは未知の領域です。。。 ◯3分間で開発環境構築 @tk0miya Vagrant+Chefみたい。 VeeWeeってのでIOSイメージからVMイメージを作ってくれる。 (githubから持ってこないといろいろ古いらしい) これ、重要だと思う。 実践するようにしよう。 手順書がわりにChefのレシピを書こうよと。 環境マニア募集中! 継続的デリバリー座談会やってます ◯筋トレ講座 @hiroki_niinuma ジムに通い続けるのはキツイ。 成功率5% 以下の条件に ・10時間以下の仕事時間 ・ジムが近い ・ジムという環境が好き ベンチマークw先入観を捨てましょうとw ジムで筋トレとかよりも歩くのが全然いいよと。 togetterがあったのでリンク。 http://togetter.com/li/346242 http://togetter.com/li/346270\nスライドはこちら。\n** [Elasticsearch入門 pyfes 201207](http://www.slideshare.net/JunOhtani/elasticsearch-pyfes-201207) ** from **[Jun Ohtani](http://www.slideshare.net/JunOhtani)** それにしても発表するといういい機会を与えてもらえて良かったです!。 継続的にelasticsearchも調べていきたいので、興味ある人は声をかけてくださいー\n","date":1343466900,"dir":"post/2012/","id":"7fa2f0877831b4c924438396760f1841","lang":"ja","lastmod":1343466900,"permalink":"https://blog.johtani.info/blog/2012/07/28/python-developers-festa-2012-07%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%A6%E3%81%97%E3%82%83%E3%81%B9%E3%81%A3%E3%81%A6%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F--pyfes/","publishdate":"2012-07-28T18:15:00+09:00","summary":"ということで、ステッカー欲しさ?に勉強中の話を恥ずかしげもなく偉そうにしゃべってきました。 #pyfesは以前から、気になっていたんですが、タ","tags":["勉強会"],"title":"Python Developers Festa 2012.07に参加してしゃべってきました #pyfes(Jugemより移植)"},{"contents":"今日はSolr 4.0 ALPHAの興味深い機能があったので紹介です。 数日前に「Solr 4.0: Partial documents update」という記事を見つけました。\nSolrには、ドキュメント(RDBで言うレコード)のデータを更新したい場合には、特定のフィールドだけを更新するという機能がありませんでした。 ですので、特定の項目(例えば、priceなど)を更新したい場合、ドキュメントの全データをSolrに再度上書き登録するという処理をしなければなりませんでした。 RDBを触っていた方が、Solrを始めた場合に必ず使いづらいと思われる点だと思います。\nで、4.0でその機能がありますという、「Solr 4.0: Partial documents update」の記事を見つけました。 ただ、SolrのWikiや4.0 ALPHAの紹介のページには「partial update」という記述が見当たりません。 (あれ、これかな?Update semantics) あと、まだ完成していないので、載っていないのかもしれないです。(このチケットSOLR-139が部分更新に関するもののはず。チケット番号をみても古くから望まれている機能だということがわかります。)\nということで、調べてみました。\n###機能概要\nSolrの機能として、特定のフィールドのみを更新するという機能です。 あくまでも、Solrレベルでの機能となり、Luceneの機能を利用したものではありません。 つぎのような流れになっています。\nSolrに対して特定フィールドを更新したいという形のドキュメントを投げる Solrはドキュメントを受け取ると、内部のインデックスに保存してあるデータを取り出す 取り出したドキュメントオブジェクトに対して、更新対象フィールドの値だけデータを更新する ドキュメントオブジェクトをインデックスに保存する このような流れです。 まぁ、言われてみれば当たり前な処理です。 ただし、この機能を使う場合はいくつかの前提条件があります。\n###前提条件\n前提条件はつぎのとおりです。\nすべてのフィールドをstored=\u0026ldquo;true\u0026quot;にする 「version」という特殊なフィールドを用意する 1点目は、データの保存方法についてです。 先ほど流れに書きましたが、Solrが内部に保存してあるデータを取り出して、更新対象以外のデータを保存しなおしてくれます。 このため、stored=\u0026ldquo;true\u0026quot;にしておかないと、元のデータがSolr内部で取得できません。\n2点目の「version」というフィールドは4.0から導入されたフィールドです。 SolrCloudに必要な機能としてドキュメントのバージョン管理を行うために導入されたフィールドだと思います。(あまり詳しく調べていない。。。) SolrCloud内でレプリカの更新などに使ってるのかなぁと(そのうち調べます。) 以上の2点が前提条件です。すべてのデータをstored=\u0026ldquo;true\u0026quot;としなければならない点は、インデックスのサイズや性能に関わってくるので考えて利用するほうがいいかと思います。\n###利用方法\nSolrのサンプルデータ(exampledocs/mem.xml)を例として利用します。 部分更新を行うにはつぎのような形のデータを投げると部分更新が可能です。 (JSONでの更新のサンプルについては、こちらの記事を参考にしてください。) ####XMLのサンプル(partial_update.xmlというファイルで保存する)\n\u0026lt;add\u0026amp;gt; \u0026lt;doc\u0026amp;gt; \u0026lt;field name=\u0026#34;id\u0026#34;\u0026amp;gt;VS1GB400C3\u0026lt;/field\u0026amp;gt; \u0026lt;field name=\u0026#34;_version_\u0026#34;\u0026amp;gt;バージョン番号\u0026lt;/field\u0026amp;gt; \u0026lt;field name=\u0026#34;cat\u0026#34; update=\u0026#34;add\u0026#34;\u0026amp;gt;cats_and_dogs\u0026lt;/field\u0026amp;gt; \u0026lt;field name=\u0026#34;popularity\u0026#34; update=\u0026#34;inc\u0026#34;\u0026amp;gt;10\u0026lt;/field\u0026amp;gt; \u0026lt;!-- set empty for SOLR-3502 bug --\u0026amp;gt; \u0026lt;field name=\u0026#34;price_c\u0026#34; update=\u0026#34;set\u0026#34;\u0026amp;gt;0.0,USD\u0026lt;/field\u0026amp;gt; \u0026lt;/doc\u0026amp;gt; \u0026lt;/add\u0026amp;gt; 上記サンプルのうち、バージョン番号の部分は、現在Solrに登録してある値を指定します。(Solrの管理画面で検索すれば表示されます。) 上記ファイルを「SOLR_HOME/example/exampledocs」に保存し、同フォルダにてつぎのコマンドを実行すると、部分更新されるのがわかります。 Solrに更新であるというフィールドがわかるように、fieldタグにupdateという属性を指定してあります。\njava -Durl=http://localhost:8983/solr/update?versions=on -Dout=yes -jar post.jar partial_update.xml ちなみに、上記post.jarのオプションで、「-Durl」「-Dout」を追加してあります。 「-Durl」はverions=onというパラメータを追加したいためです。 「-Dout」はPOSTした結果をターミナルに表示するために追加しています。 これらのオプションを指定すると、データ更新後のバージョンが取得できるようになります。\n####更新に利用できるコマンド? 部分更新にはつぎの3つのコマンド?(正式名は不明)が用意されています。fieldタグのupdate属性に指定します。\nコマンド? 説明 add 値を追加します。multiValuedのフィールドでない場合はエラーが出ます。 set 値を新規に登録しなおします。現在入っているデータは無くなります inc 指定された数値を加算(数値形式のみ) 以上が、部分更新の機能になります。 ちなみに、登録されているバージョンと更新データに入っているバージョンが異なる場合はエラーが発生する仕組みになっているようです。 それとは別に、この機能を調べていて、copyFieldのバグにぶつかってしまいました。。。 multiValuedでない、copyFieldを利用しているしている場合には注意が必要です。\n###copyFieldのバグ(SOLR-3502)\n4.0-ALPHA(3.6.0でも再現しました。)のexampleのデータで部分更新の機能を確認できると言いました。 ただし、「price_c」というフィールドのせいで、2回部分更新を行うと2回目にエラーが発生します。 根本的な問題は、部分更新ではなくcopyFieldのバグのようです。(部分更新の処理にも問題は有るような気がしますが。。。)\nバグの内容はつぎのとおりです。\nmultiValued=\u0026ldquo;false\u0026quot;のフィールドをdestに指定 srcに指定されたフィールドに値を設定(exampleのpriceフィールドに「1」を指定) destに指定されたフィールドに値を設定(exampleのprice_cフィールドに「2,USD」を指定) 上記のように設定した場合、「price_c」フィールドに、指定された値+「price」の値がcopyにより追加されます。 通常は「price_c」フィールドはmultiValued=\u0026ldquo;false\u0026quot;なのでエラーが出るはずなのですが、エラーが発生せず2つの値が登録されてしまいます。\nこのバグのため、exampleのデータを利用して部分更新を行うとつぎのような状態が発生します。 更新を行う対象のデータはprice、price_cフィールド以外のフィールドとします。\n1回目の登録後:priceフィールド「\u0026ldquo;185.0\u0026rdquo;」、price_cフィールド「\u0026ldquo;185.0,USD\u0026rdquo;」 2回目の登録後:priceフィールド「\u0026ldquo;185.0\u0026rdquo;」、price_cフィールド「[\u0026ldquo;185.0,USD\u0026rdquo;,\u0026ldquo;185.0,USD\u0026rdquo;]」 3回目の登録:エラーが発生 部分更新の処理で、すでに登録済みのデータをSolrが自動で取り出すため、2回目の登録処理にて「price_c」の登録済みの値がSolrから取り出され、さらにcopyField設定により、「price」の値が追加されます。 本当は2回目の登録でエラーが発生すべきなのですが、バグのためエラーが発生せずに登録できてしまいます。 部分更新の処理としては、copyフィールドのdestに指定されているフィールドの値を取り出さないほうがいいような気もしますが、きちんと考えてないのでなんとも言えないです。(制約事項とする形のほうがいいかもしれません)\n","date":1342177320,"dir":"post/2012/","id":"68a8f34c240a42ab521d2f885f7aa33c","lang":"ja","lastmod":1342177320,"permalink":"https://blog.johtani.info/blog/2012/07/13/partial-update%E3%81%A8copyfield%E3%81%AE%E3%83%90%E3%82%B0solr-4-0-alpha/","publishdate":"2012-07-13T20:02:00+09:00","summary":"今日はSolr 4.0 ALPHAの興味深い機能があったので紹介です。 数日前に「Solr 4.0: Partial documents update」という記事を見つけました。 Solrには、","tags":["solr"],"title":"Partial UpdateとcopyFieldのバグ【Solr 4.0 ALPHA】(Jugemより移植)"},{"contents":" Modern Information Retrieval: The Concepts and Technology behind Search (2nd Edition) (ACM Press Books) いやぁ、蒸し暑くてなかなか寝れない日がはじまりましたね。(あんまり関係ないですね。。。)\nModern Information Retrieval 2nd Editionを輪読会という形で読み始めました。 Solrに関わって数年ですが、昔から検索をやっていたわけではありません。 なので、そろそろ基礎的、理論的なところも勉強して行かないとなと思い、この本を買いました。 ただ、約1000ページある英語の本でして。。。 一人で読むと間違いなく挫折するし、理解不能になりそうだなと。。。\nということで、Twitterで呟いたら賛同してくれる方が現れ、輪読会を開催することにしました。 イベントの開催とか初めてなので、手さぐりしながらです。(それにしても、ほんと、Twitterは素晴らしい。賛同してもらえる人が見つかったのもTwitterのおかげだし。)\nさすがに細かく読んでいくと終わらなそうなので、1周目(できれば、2周目もやりたいなぁと思ってる。1週目が1年でも終わりそうにない感じだけど)は公開されているスライドを元に進めようと思ってます。 それにしても検索周りはいろんな技術が必要なのだなぁと分厚い書籍を見て、途方に暮れつつ、楽しみでもあるなと思いながら、輪読会後の飲みを楽しんでましたw\nということで、各分野の専門家もいそうなので、特別ゲストとして読んできて話に混ざってもらうのも面白いかもと夢想しつつブログを書いています。 だれかいないかなーw\n参考URL: 書籍のHPで公開されているスライドのページです。 http://grupoweb.upf.es/WRG/mir2ed/contents.php\n","date":1342111298,"dir":"post/2012/","id":"9ac7bb94e60dc30a023ce433de027364","lang":"ja","lastmod":1342111298,"permalink":"https://blog.johtani.info/blog/2012/07/13/mir%E8%BC%AA%E8%AA%AD%E4%BC%9A%E5%A7%8B%E3%82%81%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-07-13T01:41:38+09:00","summary":"Modern Information Retrieval: The Concepts and Technology behind Search (2nd Edition) (ACM Press Books) いやぁ、蒸し暑くてなかなか寝れない日がはじまりましたね。(あんまり関係ないですね。。。) Modern Information Retrieval 2nd Editionを","tags":["勉強会"],"title":"MIR輪読会始めました(Jugemより移植)"},{"contents":"Lucene/Solrの4.0.0-ALPHAが7/3にリリースされました。\nこれに伴い、lucene-goenの4xブランチのjarファイルも4.0-ALPHAのものに置き換え、現在のtrunkの修正もマージしました。 こちらにあります。チェックアウトしてビルドしてから利用してください。\n※さすがに、jarをダウンロードできるようにすべきかもなぁ。 あと、Maven登録も。。。\n","date":1341457909,"dir":"post/2012/","id":"dcc2e24df32287e89ee3b0f64d617f57","lang":"ja","lastmod":1341457909,"permalink":"https://blog.johtani.info/blog/2012/07/05/lucene-gosen%E3%81%AElucene-solr4-0-alpha%E5%AF%BE%E5%BF%9C/","publishdate":"2012-07-05T12:11:49+09:00","summary":"Lucene/Solrの4.0.0-ALPHAが7/3にリリースされました。 これに伴い、lucene-goenの4xブランチのjarファイル","tags":["lucene-gosen"],"title":"lucene-gosenのLucene/Solr4.0-ALPHA対応(Jugemより移植)"},{"contents":"またまた参加しました。いまだ皆勤賞です。 感想などはあとで。とりあえず、メモとったので第一弾です。\nということで、感想です。 まずは、参加人数。 今回は今までで一番、ATND登録した人が多かったんじゃないかなぁと。 埋まるのも早かったですし。やっとSolrというキーワードが多くの方に触れられるようになってきたんですかねぇ。\nmixiの事例はやはり、SSDを使った11億文書のインデックスが圧巻です。 実際にマイニングに利用していて、ネガポジ分析なども行われているようで楽しそう。 TLにもありましたが、「ヤバイ」はネガ?ポジ?など、そのへんの分析方法をもう少し詳しく聞いてみたい感じもしました。 あとは、Luceneソースコードリーディングの開催が楽しみです!(候補日知らせないと。。。)\nLucene Revolution 2012の参加レポートは、自己紹介がおもしろかったですw ずっと検索をやらてているのもあり、色々と理論ではなく、実践的なノウハウを持っていそうで、つぎはそのあたりの話を聞いてみるのも面白そうです(発表してくれないかなーw) 残念ながら、私はまだスライドを見ていないので、事例を中心にピックアップして見てみようかなぁと(時間がトレない。。。)\n最後は阿部さんの4.0の紹介です。タイムリーに、前日に4.0-ALPHAがリリースされたので、 資料がすごく参考になりそうです。 SolrCloudについても詳しく書かれてたし。(ちゃんと動くのかなぁ?)\n最後は懇親会です。最近知り合った方から、発表者、昔からの勉強会の参加者といろいろな方と今回も話ができて楽しかったです。 TL上で知り合った方にもお会いできたし。 次回もしゃべってもらえそうな人を捕まえつつあるので、また企画してもらうようにつついてみようかな。\n※そういえば、毎度のことながら4.0ベースで、書籍は出さないのかって言われましたw\n※ちなみに、4.0-ALPHAが出たので、lucene-gosenも4xブランチの更新作業をしています。 終わったらまたブログに書くと思います。\n第8回Solr勉強会 場所:VOYAGE GROUP 会議室 日時:7/4(水) 19:00 ~ 1. @haruyamaさん mixi での Solr の利用 ・mixiの全文検索 2011年以前:Hyper Etraier、Tokyo Dystopia、Senna 2011年以降:Solrを利用して新規案件の検索システムの構築、入れ替えを行なっている。 ・Anuenueの論理構成など。 ・物理構成 1マスター、2スレーブ インデックスが小さい、QPSが100以下 インデックスサイズが大きいものは今後構築予定 ・今後やりたいこと ・ログ分析 ・パーソナライズ ・外部ストレージ参照のカスタム関数 ・外部ストレージをファンクションカスタム関数クエリ FunctionQueryを活用したい。 ・上記のデモ(検討中のもの?) 現在はjar内部のファイルを読んでるよと。 速度的な面がどうなるかがきになるところ。 ・テキストマイニング mixiボイス haruyamaさん入社前:ダンプして解析してた haruyamaさん入社後:Solrに載せちゃえば 600GのSSD 約11億文書 約450GB 利用してるもの:Solr 4.0(2012/01) lucene-gosen 1.2.1 自作フィルタ haruyama/solr-filter - GitHub ・利用統計の説明。 女性が多い。 「AKB」だと20代前半が多い。男性はおっさんも頑張ってる。 ・mergeindex機能を利用して、過去データとマージしてる。 1日分だけ集計したいこともあるかもしれないから。 updateじゃなくて、mergeindexなのは、ソッチのほうが早かったから。 ・拡張してる分析 ・ポジネガ分析 形容詞>絵文字>顔文字でスコアが効く 機械学習して辞書を調整してる ・Luceneソースコードリーディングまたやりますよ! 2. 楽天株式会社 大須賀 稔さん Lucene Revolution 2012 in Boston参加レポート(仮) ・まずは自己紹介。 infoseekに転職→楽天→Ask.com→楽天(そして英語) ・Lucene Revolutionってなに? ・トレーニング Scaling Search with Big Data \u0026amp; Solr Hadoopの紹介 SolrとHadoopのMapReduceを利用したインデキシングのハンズオン Solrのスケーリング(Sharding、Replication)、マルチテナント ※http://www.lucidimagination.com/services/training/big-data-training-scaling-solr 日本ではやってない、残念。 ・カンファレンス スライドとかはlucidimaginationのサイトで見れるよと。 http://www.lucidimagination.com/devzone/events/conferences/lucene-revolution-2012 ・Lucidworks Big Dataの紹介 Hadoopとかいろいろ組み合わせて使えるよと ・Microsoftの人がAzureでSolrの紹介 IEとかWindows8の話ばっかり。 ・Kuromojiの紹介 やはり、マイノリティ。 内容は日本語勉強会w 中国語とかは対応するの?日本語しか知らないです。。。 ・ErickさんのSolrCloudの話 4.0は2012年にリリースする予定 スコアリングをプラガブルに。 管理系画面がリッチだよと。 ・一番重要だなぁと思ったのは。。。 「英語」!(会社的な感想ではありません。。。) Q:これはみとけ的なスライドは? A:Hadoop上でインデキシングして、ビットトレントとかで連携してるという例が面白かった。 Q:FASTとかと比べてSolrってどーなの? A:ESPは洗練されてる。クローラーとか、ベイシスのトークナイザーを内包してるとか。 Solrは言語処理系が弱かったとかあるけど、そろってきてるのでは。 4.0は互角になるんじゃないかなぁ。 ESPがWindowsオンリーになるので、LinuxユーザがSolrに行きつつある。 3. 株式会社 ロンウイット 阿部さん Solr 4.0の紹介 ・Solr 4.0の主な機能の紹介 3.xは3.6が最後4.0-ALPHAが7/3に出た ・プラガブルなスコアリング BM25、Language Models、Divergence from Randomness、Information-based Models 関口さんがスライド作ってる ・FST対応 Finite State Automata/Transducer オートマトン理論を活用したもの。 TokenStreamはFSAで実装 SynonymFilterがFSTになると、オフセットが変わってくるらしいと。 ・Codecプラグイン Luceneレベルのお話。 ドキュメントをファイルに保存するときの形式をプラガブルに変更可能。 SimpleTextなどもあるらしい。テストに利用できそう。 APIレベルで、マイグレーションの必要があるかも。 ・NRT Near Real Time Search softCommitのお話 Realtime-get:IDを入れたらGETできるよと。 KVSとしても活用できるぞ~と。 ・PivotFacet Facetが階層的(?)な感じで取れる ・JOIN、pseudo-join ローカルパラメータでできるよーと。 ・SolrCloud インデックスの分散配置をやってくれる(3.6まではやってくれない) shardがダウンしたらフェイルオーバーしてくれそう Master/Slave環境 リアルタイムインデクシングとリアルタイム検索とか ・ZooKeeperIntegration実装 リーダー選出、コンフィグの管理などなど ・ManifoldCFの近況 5月にトップレベルに昇格! http://manifoldcf.apache.org/ja_JP/index.html 0.6は7月に出そう。日本語にもなってる。すげー Alfresco Connector、ElasticSearch Connectorなども Solr Plugin for Enterprise Searchとか ","date":1341402000,"dir":"post/2012/","id":"8acc78be63e27e938ee53ec2c0b90c61","lang":"ja","lastmod":1341402000,"permalink":"https://blog.johtani.info/blog/2012/07/04/solr%E5%8B%89%E5%BC%B7%E4%BC%9A%E7%AC%AC8%E5%9B%9E%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F--solrjp/","publishdate":"2012-07-04T20:40:00+09:00","summary":"またまた参加しました。いまだ皆勤賞です。 感想などはあとで。とりあえず、メモとったので第一弾です。 ということで、感想です。 まずは、参加人数。 今","tags":["勉強会"],"title":"Solr勉強会第8回に参加しました。 #SolrJP(Jugemより移植)"},{"contents":"Hadoopからはちょっと離れているのに、面白そうなネタなので参加しました。 Data Science Summit、HBaseCon、Hadoop Summitのイベント参加レポートです。\n最初の草薙さんの発表が実は一番興味を惹かれていたので、参加しました。 データの解析に関するサミットというのはなかなか聞いたことが無いのでどんな内容なのかなぁと。 ちょうどVisualizeなどに興味を持っていたり、データ解析、今後重要ですよねという話が出ていたりしていたので。 実際にデータ解析が今後重要で、どんなことに使えるのかなど、製品に偏らない内容のようで色々とためになりました。 この内容をずっと聞くのは私には無理ですw英語も数学もイマイチなので、ついていけない自信がありますw。 「データ分析の結果をビジネスに結び付けられる人とかが今後重要になります」という話が一番気になったキーワードでした。\nHBaseConもかなり濃い内容だったようです。 私は残念ながら、HBaseの概要の概要くらいしか知らないので、内容にはついていけてないですが。。。 Facebookがかなり活用しているようですが、残念ながらスライドが上がっていないようです。 Solrに関連する話もあったようです。HBaseとSolrを組み合わせたLilyプロジェクトに関連する話のようでした。 スライドは登録しないと見れないみたいです。\n最後はHadoop Summitの参加レポートです。 まずは、ユーザ寄りの内容を@muddydixonさんから。個人的に、Twitterの話が多いのかなぁと。 ここでも、Visualizeの話が出ていたとか。 Lucidの話もあったようです。LucidWorks BigDataの話かな?\n最後は@shiumachiさんのHadoopのプロダクト寄りのお話。 YARN(Map/Reduce2.0?)やHBaseの今後の展望など。YARNはキーワードだけ知っていたので、わかりやすい解説で、やっと理解できました。 全体を通して、HBaseが今後もっといろんな局面で使われそうだなぁと。日本語の本も7/24に出るし。(まだページが無いみたいなので、英語のほうを。)\nいつものごとく、途中でビールが入ったので後半はメモが適当ですが、楽しかったです。皆さんお疲れ様でした。\n帰り着いたら、さっそくスライドが上がってました。すごい! スライドはこちら(2012/06/26 0時現在)\nData Science Summit / EMC Worldレポート HBaseCon 2012 参加レポート』の発表スライドをアップしました。(NTTデータ 猿田 @raspberry1123 /岩崎) @muddydixonさんのHadoopSummit2012参加レポート @shiumachiさんのHadoopSummit2012参加レポート @muddydixonさんのブログ いろんなキーワード、特に、データサイエンス寄りの話が面白かったです。 次回はJenkins関連のようで、7/30開催みたいです。\n以下はいつものメモです。\n日 時: 2012年6月25日(月) 19:00~21:00 (受付開始 18:40) 場 所: 豊洲センタービルアネックス(NTTデータ、豊洲駅直通) ◯ Data Science Summit / EMC World レポート (EMC Japan 草薙) ・Data Science Summitのレポート 揃ってるようで揃ってないスロットの写真w EMC World2012と併設 今回2回目。 ・OpeningKeynote: What We Can Predict About Prediction by Nate Silver 研究者は不確実性やリスクを包含した、現実的な予測モデルを開発すべき いろいろ ・Roundtable: Economic, Political, \u0026amp; Societal Roles of Social Data ユーザの「query-like intent」を自然言語解析と機械学習で捉える 属性だけじゃなく、活動を コンテンツからコンテキストへ、コンバージョンからカンバセーション ・Big Data Transformation - HealthMap ウィルスのアウトブレイクの検知(160日→20日)に。 ウィルス=コンピュータじゃない方 ・Big Data Transformation - Intuit int.com? データがあるから、こういうことが知りたいなどの新しいプロセスが 「https://www.mint.com/」 ・Big Data Transformation - InfoMotion Sports Technologies バスケのボールにセンサーつけて、試合や選手の解析に利用して、 チームが強くなったりしてるらしい。 ・Big Data Transformation - Decide.com アメリカ?の価格比較サイト ソーシャルデータを元に、買い時、売り時を予測して教えてくれる。 もうすぐ新しいモデル出るかもよ?などの噂を利用してる。 ・Analytics Maturity: Master or Novice? 2010年のアメリカの教育事情のレポート データサイエンス系の統計とかがもっと必要なんじゃないか。 ・Keynote: Navigating the Road from Business Intelligence to Data science Piyanka Jain BIの限界とか、データサイエンスの恩恵を受け入れるのに必要なもの?など システムじゃなくて、人やスキルに投資しましょう。 データ分析の結果をビジネスに結び付けられる人とか。 Panel: From Raw Data とValue Data プライバシー問題 データ品質の問題 異常値を除外するなと。最も興味深いデータになることもある。 \u0026#34;Data exhaust\u0026#34;の問題 個人が日々インターネット上で行う様々なインタラクションに関するデータの集合 相関と因果関係の区別が大変難しい。 Panel: Tapping Into the Pulse of the Data Science movement ストーリを持ってデータを語れるのが重要。 Keynote: Data Visualizeation at the Point of Influence by Adam Bly Closing Keynote: The Promise and Peril in the Human / Technology Relationship by Jonathan Harris TEDで有名な人 まとめ アメリカはこの分野での投資は回り始めている. http://www.greenplum.com/datasciencesummit/ ◯ HBaseCon レポート (NTTデータ 猿田/岩崎) ・GeneralSession HBaseの開発に参加してね。 ・レプリケーション、セキュリティ、セカンダリインデックス、スナップショット、バックアップなど特に貢献して欲しいと。 ・HBaseによりカバーできるアプリケーション領域 メッセージング、位置ベースアプリケーション、リアルタイムレコメンデーション、広告最適化 ・開発者への要望 メッセージをちゃんとして 解析用メトリクス 管理ツール ・M/Rジョブとの連携の改善 ・自動チューニングなど ・Applications ・GAPの事例 色々試してHBaseにした。 クラスタ構成、16Slave、3Master、NN Failover via NFS ※ZKはスレーブに置くと、アウト。 ・Tumblr 最初は失敗した。 OpenTSDBを経験して、Motherboy V1に。 テストフェーズまでが目的 →幾つかの知見が得られたよーと。 Motherboy V2を構築中。 ・Facebook ひと月250TBペースで増加中。。。 なんで、HBaseにしたの? 低レイテンシ、水平スケール、一貫性重視の設計、M/Rとの親和性とか Schema V1=Snapshot Schema Schema V2=Split Snapshot Schema Schema V3=Hybrid Schema HBaseのデータにさらにインデックス作ったりとか。 Schema Vertion Current=Finer grained schema and Indexer 読み書きの単位を分析して、スキーマを分割して細かくして行っていた。 ・Operations ・HBaseで困ったよ at Facebook ・リージョンサーバに特定データ入れると連鎖的に死亡 ・サーバが死に切らないとか。 ・HBaseは落ちるときは落ちるので、しぶとく生き残れるアプリを作ってねと。 ※Facebook関連のスライドなどがあがってませんと。 ・HBaseバックアップについて Clouderaの人とFacebookの人 ・選択肢 DistCP /hbaseディレクトリまるごとコピー。一貫性が保証されない exportツール MRジョブ。1度に1つのテーブルのみ copytableツール データを別クラスタに保存 exportツールに似てる。 レプリケーション 。。。 アプリケーションから複数クラスタへの書き込み 。。。 ・ユースケース ・HBASE-5509を利用したバックアップ ・開発中バックアップ HBASE-6055スナップショット、HBASE-4618など ・Development ・HBase Schema Design Salesforce.comの人 非正規化でやりなさいと。Joinはおすすめしないと 最後にデザインパターンが載ってると。 0.行キーの設計がすべて 1.Design for the questions, not the answers. 2.データサイズは2種類しかない。大きすぎるか、そうじゃないか。 3.コンパクトに詰め込め 4.行単位の原子性を活用する。 5.属性は行キー内に移動することができる。(Lars Georgeがfoldingと読んでいる手法) 6.エンティティをネストさせると、データを事前に集計できる。 ・HBase Performance Tuning And Organizations Facebookの中の人 テーブルの事前スプリット オフピーク時間を設定する。(0.94で入った) コンパクション設定が効いてくるよ ・SolrのバックエンドにHBase??? ◯ Hadoop Summit レポート (@muddydixonさん) ・オープニングビデオは必見 ・ショーケース ・Datameerを注目した。Visualizationの専任チームがいる。 UIじゃなくて、解析部隊だけで60名 お値打価格。$2900/年 ・Azure Big Data JavaScriptで ・ショーケースLucid Solr、HBaseとかいろいろ組み合わせて。 ・Session Hadoop... 2015までにApache Hadoopに世界のデータの半分が乗るらしいと。 ・Session Realtime analytics with Storm and Hadoop フォロワのフォロワをunique処理したり。 ・Session Scalding Twitter\u0026#39;s new DSL for Hadoop ※Zipkinにも出てきたな、名前。 ・Hadoop Plugin for MongoDB ・Hadoop and Vertica The Data Analytics Platform at Twitter Twitter社でのHadoop周りのデータフローとか。 Verticaは速度がいるものの処理に利用 80-100TB/dayとか。。。 ・Keynotes ・Big data analyzing system is censor of company. ・It is difficult in blind and deaf. ・Session Large Scale Search, Discovery and Analytics with Hadoop, Mahout and Solr ※@muddydixonさんのブログにセッションに対応するスライドのリンクを公開中。http://d.hatena.ne.jp/muddydixon/20120617/1339919125 ◯Hadoop Summit レポート (@shiumachiさん) ・Hadoop1.x MapReduce 非常に安定 ・課題。。。 ・YARN(Yet Another Resource Negociator) ターゲット:6000~10000ノード 100,000以上のタスクの同時実行 10,000ジョブの同時実行 性能は倍以上 Q:これは同じプログラムを動かして? A:。。。倍以上です!(わかんないっす。) 今後の予定 幾つかのJIRAの紹介 MAPREDUCE-4327とかHBASE-4329とか まとめ YARNは「汎用」分散処理基盤に向けて一歩踏み出したもの! 更なる進化に注目と ・HBaseの可用性とリペア ダウンタイムを短くしよう。 障害停止7割くらい。 設定ミスが44% 不安定な機能は使うな、推奨構成を推奨! HBase 0.92+Hadoop 2.0 HDFS HAによる高可用性とか 将来:HBase 0.96+Hadoop 2.x 計画停止時間削減:オンラインスキーマ変更(HBASE-1730) ローリングアップデート:バージョン間互換性が必須 HBase本読みなさい。 金があれば、サポート買ってください。 日本語HBaseトレーニング開催予定(来月) ・HBase NameNode HighAvailability ``` ","date":1340642460,"dir":"post/2012/","id":"9f29c6d9719fc6bc09a2981057642b69","lang":"ja","lastmod":1340642460,"permalink":"https://blog.johtani.info/blog/2012/06/26/hadoop%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89%E3%83%AA%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0%E7%AC%AC10%E5%9B%9E%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-hadoopreading/","publishdate":"2012-06-26T01:41:00+09:00","summary":"Hadoopからはちょっと離れているのに、面白そうなネタなので参加しました。 Data Science Summit、HBaseCon、Hadoop Summitのイ","tags":[],"title":"Hadoopソースコードリーディング第10回に参加しました。#hadoopreading(Jugemより移植)"},{"contents":"Issue 32で上がってきたlucee-gosenのUniDic対応の最初のパッチを書いたので、ブログに残しておきます。\n###UniDicとは___ UniDicとは、日本語テキストを単語に分割し,形態論情報を付与するための電子化辞書です。 UniDicの詳細や特長についてはHPを御覧ください。\n残念ながら、UniDicは利用者登録をして、利用規約に従うと利用が可能となります。 ですので、lucene-gosenでは、Ipadicやnaist-chasenの辞書とは異なり自動で辞書をダウンロードする機能はありません。\n###利用手順___ 以下が、Unidicの辞書を利用したjarファイルの作成方法となります。\n1. lucene-gosenをダウンロードし、パッチを当てる lucene-gosenのリポジトリからソースをエクスポートし、パッチをダウンロードし、パッチを適用します。 コマンドは以下のとおりです。\nsvn co . lucene-gosen-trunk-readonly cd lucene-gosen-trunk-readonly patch -p0 \u0026amp;gt; ...patch (パッチに関しては今後正式版をリリースされたら手順からは必要なくなります。)\n2. Unidic辞書生成のためのディレクトリを作成「$GOSEN_HOME/dictionary/unidic」\nmkdir dictionary/unidic 3. 対象となるUnidicの辞書のソースファイルをダウンロード 利用者登録をし、利用規約に同意の上、以下のファイルをダウンロードします。 「/」に添ってダウンロードページから遷移してダウンロードしてください。\n1.3.12個別ファイル/unidic-chasen/unidic-chasen1312src.tar.gz 4. ダウンロードしたtar.gzファイルを「dictionary/unidic/」にコピー\ncp .. lucene-gosen-trunk-readonly/dictionary/unidic/ 5. Antを実行してjarファイルの作成\nant -Ddictype=unidic 成功すれば、lucene-gosen-trunk-readonly/dist/lucene-gosen-2.1-dev-unidic.jarファイルが生成されます。 あとは、通常通り、SolrやLuceneで利用することが可能です。\n以上がjarファイルの作成手順となります。\n###制約事項(2012/06/18現在)___ 現在(2012/06/18)時点で公開しているパッチは、以下の制約が存在します。\nCOMPOUNDエントリー未対応 品詞情報(発音)の内容の制限 COMPOUNDエントリー未対応 Unidicの辞書のエントリーの中に1件だけ、COMPOUNDと呼ばれるエントリーが1件だけ存在します。 別々の単語を組み合わせて1単語として扱うことができるようになっているようです。 lucene-gosenでは、残念ながら、このような辞書の形式には対応していません。 1件しか存在しないデータでもあることを鑑みて、今回の辞書構築処理では、スキップするようにしました。\n品詞情報(発音)の内容の制限 lucene-gosenの実装上、単語の読みのバリエーション数と発音のバリエーション数には以下の制限が存在します。\n「読み」バリエーション数 < 「発音」バリエーション数 「読み」に対応する形で、「発音」がlucene-gosenでは品詞情報としてデータ登録されています。 UniDicのデータには上記制約を満たさないデータが5件ほど存在します。 現在、これら5件のデータについて、「読み」に対応した「発音」データには空文字が表示されるようになっています。\nまだ、簡単に動作確認をしただけです。UniDicを利用していて問題など有りましたら連絡、Issueへのアップをしていただけると助かります。\n","date":1340028180,"dir":"post/2012/","id":"d13aa56e27fe71ef40ff153c093ecdf8","lang":"ja","lastmod":1340028180,"permalink":"https://blog.johtani.info/blog/2012/06/18/lucene-gosen%E3%81%AEunidic%E5%AF%BE%E5%BF%9C/","publishdate":"2012-06-18T23:03:00+09:00","summary":"Issue 32で上がってきたlucee-gosenのUniDic対応の最初のパッチを書いたので、ブログに残しておきます。 ###UniDicとは___","tags":["lucene-gosen"],"title":"lucene-gosenのUniDic対応(Jugemより移植)"},{"contents":"「鉄は熱いうちに打て」ということで、残りも勢いでメモ。 まだ、見直しとかしてない状態なのでおかしいところとかありますが。。。 図とか入れるのはまた今度。\nTransport(転送)\nZipkinとHadoopに異なるサービスからのトレースを送信するのにScribeを利用します。 ScribeはFacebookにより開発されました。 システムの各サーバで実行できるデーモンとして作成されています。 ログメッセージをListenし、カテゴリごとのcorrectレシーバーに配送します。 Zipkin collector daemon\nトレースデータがZipkinコレクターデーモンに配送されたらvalidかどうかをチェックしてから保管し、インデックスを作成します。 Storage\nストレージにはCassandraを選びました。 スケーラブルで、柔軟なスキーマをもっており、Twitter内部で大変使われています。 このコンポーネントをプラガブルにしようと試みましたが、困難なため、ここでは公開しません。 Zipkin query daemon\n保存、インデックスされたデータを探す方法が必要です。 クエリーデーモンはユーザに対して簡単なThriftAPIを公開しており、トレースを探すことが可能です。Thrift fileを見て下さい。\nUI\n多くのユーザはUI経由でデータにアクセスします。 VisualizeにD3を利用したRailsアプリケーションです。 UIの認証は実装していないことに注意してください。\nモジュール Zipkin内部のモジュール関連図\n##インストール___ Cassandra\nZipkinはCassandraをストレージにしています。Cassandraクラスタが必要になります。 1. Cassandraサイトを参考にしてクラスタを構築してください。 2. Zipkin Cassandraスキーマを利用します。つぎのコマンドでスキーマが作成できます。 bin/cassandra-cli -host localhost -port 9160 -f zipkin-server/src/schema/cassandra-schema.txt Zookeeper\nZipkinは協調のためにZooKeeperを利用します。 これは、保存すべきサーバをサンプルレートで決定し、サーバを登録します。? 1. ZooKeeperのサイトを参考にインストールしてください。 Scribe\nScribeはトレースデータを配送するのに利用するロギングフレームワークです。 ネットワーク保存先としてZipkinコレクターデーモンを指定する必要があります。 Scribeの設定は次のようにします。 \u0026lt;store\u0026amp;gt; category=zipkin type=network remote_host=zk://zookeeper-hostname:2181/scribe/zipkin remote_port=9410 use_conn_pool=yes default_max_msg_before_reconnect=50000 allowable_delta_before_reconnect=12500 must_succeed=no \u0026lt;/store\u0026amp;gt; 注意:上記設定は、カテゴリーにより送信ホストを見つけるためにZooKeeperを利用するサポートのScribeのTwitterバージョンを使用する方法です。 コレクターのためのDNSエントリーを利用したりもできます。 Zipkinサーバ ZipkinサーバはScala 2.9.1、SBT 0.11.2そしてJDK6で開発しました。\n1. git clone https://github.com/twitter/zipkin.git 2. cd zipkin 3. cp zipkin-scribe/config/collector-dev.scala zipkin-scribe/config/collector-prod.scala 4. cp zipkin-server/config/query-dev.scala zipkin-server/config/query-prod.scala 5. Modify the configs above as needed. Pay particular attention to ZooKeeper and Cassandra server entries. 6. bin/sbt update package-dist (This downloads SBT 0.11.2 if it doesn\u0026#39;t already exist) 7. scp dist/zipkin*.zip [server] 8. ssh [server] 9. unzip zipkin*.zip 10. mkdir -p /var/log/zipkin 11. zipkin-scribe/scripts/collector.sh -f zipkin-scribe/config/collector-prod.scala 12. zipkin-server/scripts/query.sh -f zipkin-server/config/query-prod.scala SBTでコレクターとクエリサービスを起動します。 Scribeコレクターサービスの起動方法は次の通り。 bin/sbt \u0026#39;project zipkin-scribe\u0026#39; \u0026#39;run -f zipkin-scribe/config/collector-dev.scala\u0026#39; クエリサービスは次の通り bin/sbt \u0026#39;project zipkin-server\u0026#39; \u0026#39;run -f zipkin-server/config/query-dev.scala\u0026#39; Zipkin UI\nUIはRails3アプリです。 1. 設定をZooKeeperサーバでアップデートします。これはクエリデーモンを見つけるのに利用します。 2. Rails3アプリケーションサーバにデプロイします。テストの場合は次のようにすることもできます。 bundle install \u0026amp;amp;\u0026amp;amp; bundle exec rails server. zipkin-tracer gem\nzipkin-tracer gemをトレースしたいRailsアプリケーションにRack Handlerで追加します。 config.ruにつぎの記載をします。 use ZipkinTracer::RackHandler run \u0026lt;YOUR_APPLICATION\u0026gt; もし、アプリケーションのstatic assetsがRailsで提供されれば、リクエストがトレースされます。 ## Running a Hadoop job\nScribeからHadoopにログを保存する設定をすることも可能です。 これをすると、Zipkin自身でオンザフライで簡単に作れないデータから様々なレポートが作成可能です。 ScalaでHadoopのジョブをかけるScaldingというライブラリを利用します。\n``` 1. Hadoopジョブを実行するためのfatなjarを作成します。 2. scald.rbをjarをコピーしたいホスト名とjobを実行するホスト名に書き換えます。 3. 必要なら、scald.rbのjarファイルのバージョンを更新します。 4. scald.rbスクリプトを利用してジョブを実行できます。\n./scald.rb \u0026ndash;hdfs com.twitter.zipkin.hadoop.[classname] \u0026ndash;date yyyy-mm-ddThh:mm yyyy-mm-ddThh:mm \u0026ndash;output [dir]\n##計測ライブラリの利用方法\u0026lt;hr\u0026gt; 計測のためのライブラリとプロトコルがちょっとだけあります。 しかし、もっと計測するための役に立つものを望んでいます。 開始する前にトレースデータがどんな構造なのかを知る必要があります。\n・Annotation - 値、タイムスタンプ、ホストを含みます。 ・Span - 特定のRPCに相当するAnnotationの集合 ・Trace - あるルートSpanにぶら下がるSpanの集合\nZipkinに送信するトレースデータです。\nこれらの詳細な記述は[こちら](https://github.com/twitter/zipkin/blob/master/zipkin-thrift/src/main/thrift/zipkinCore.thrift)を見て下さい。 その他にトレースデータの重要なものは、トレースされたサービス間でやり取りされる情報である、軽量なヘッダーです。 トレースヘッダは次のものから構成されます。\n・Trace Id - トレース全体のID ・Span Id - 個々のリクエストのID ・Optional Parent Span Id - このリクエストが他のリクエストの一部として生成されたら付与される ・Sampled boolean - トレースすべきかどうかを表すフラグ\nデータタイプについて、理解したので、どのように計測が行われるかを順をおってみてみましょう 例はFinagleのHTTPがどのようにトレースされるかを示しています。 他のライブラリやプロトコルはもちろん、異なりますが、基本的な部分は一緒です。\n\u0026lt;b\u0026gt; サーバサイド\u0026lt;/b\u0026gt; 1. 到達したリクエストのトレースヘッダー存在するかどうかを調べます。存在すれば、なら、このリクエストに対して関連するIDとします。トレースヘッダーがなければ、サンプリング対象かどうかを決めて、新しいTrace Id、Span Idを生成します。参考には[HttpSererTracingFilter](https://github.com/twitter/finagle/blob/master/finagle-http/src/main/scala/com/twitter/finagle/http/Codec.scala)を見て下さい。 2. もし、現在のリクエストがサンプリングされる場合、サービス名、ホスト名、スパン名(例えば、http get/put)、その他のAnnotationのような情報を集めます。 リクエスト受信時には「server received」というAnnotationを生成し、処理が終了して結果を返すときに「server send」というAnnotationを生成します。 参考には[HttpServerTracingFilter](https://github.com/twitter/finagle/blob/master/finagle-http/src/main/scala/com/twitter/finagle/http/Codec.scala)を見てください。 3. 生成されたトレースデータはServerBuilderにより設定されたトレーサーに渡されます。 デバッグのためのConsoleTracerが例としてありますが、ZipkinTracerになります。 トレースデータを[ZipkinTracer](https://github.com/twitter/finagle/tree/master/finagle-zipkin)が受け取った時、Span Idにより集約されます。 4. ZipkinTracerが\u0026#34;end of span\u0026#34;イベント(\u0026#34;server received\u0026#34;アノテーションやタイムアウトのような)を受け取ると、Thrift構造としてデータを集約してScribeに送ります。もし、そのようなイベントが発生しない場合、ZipkinTracerはいつかそのデータを送信します???おかしい?。データ送信のための他の方法も追加します。 ThriftやScribeのようなものですが、JSONやHttpかもしれません? \u0026lt;b\u0026gt; クライアントサイド\u0026lt;/b\u0026gt; 1. リクエストを送る前にそれがトレースの一部かどうかをチェックします。 サーバで利用されているとします。 サーバは、リクエストを処理してすでに付与されているトレースIDを割り当てます。 トレースIDを再利用しますが、この新しいリクエストには新しいスパンIDを生成します。 また、親のスパンIDが存在すれば、前のスパンIDに設定します。 [ここ(TracingFilter)](https://github.com/twitter/finagle/blob/master/finagle-core/src/main/scala/com/twitter/finagle/tracing/TracingFilter.scala)や[ここ(Trace)](https://github.com/twitter/finagle/blob/master/finagle-core/src/main/scala/com/twitter/finagle/tracing/Trace.scala)が参考になります。 2. サーバサイドと同様に、送信されるHttpリクエストにトレースヘッダーを追加するための[HttpClientTracingFilter](https://github.com/twitter/finagle/blob/master/finagle-http/src/main/scala/com/twitter/finagle/http/Codec.scala)があります。 3. リクエスト送信前の「client send」やサーバからの返信を受信した「client receive」のようなアノテーションを生成します。 4. サーバサイドと同様に、データがZipkinにデータを送るZipkinTracerに到達します。 ","date":1339772520,"dir":"post/2012/","id":"9ccda414c322ebcdf875eacbba2e4b7e","lang":"ja","lastmod":1339772520,"permalink":"https://blog.johtani.info/blog/2012/06/16/zipkin%E3%81%AEreadme%E8%AA%AD%E3%82%93%E3%81%A7%E3%82%8B%E3%81%9D%E3%81%AE%EF%BC%92%E6%AE%8B%E3%82%8A/","publishdate":"2012-06-16T00:02:00+09:00","summary":"「鉄は熱いうちに打て」ということで、残りも勢いでメモ。 まだ、見直しとかしてない状態なのでおかしいところとかありますが。。。 図とか入れるのはま","tags":["Zipkin"],"title":"ZipkinのReadme読んでる(その2、残り)(Jugemより移植)"},{"contents":"ZipkinのGithubにあるReadmeを読んでます。 せっかくというか、頭が悪いので読みながら内容をメモ。 まずは、アーキテクチャとトレースデータ送信のためのクライアント側あたりです。 (誤訳とかおかしいだろというツッコミ大歓迎です。) あとで、リンク貼ったり絵を入れたりするかもしれませんが、とりあえず。\n◯アーキテクチャ(図はこちら)\n・対象とするサービスからScribeでデータを収集し、ZipkinのCollectorに投げる ・CollectorはCassandraにデータを格納 ・WebUIからはQueryでCassandraに問い合わせを行なってデータ取得 ・Scripe、CollectorはZookeeperと連携している(妄想) ◯計測用ライブラリ(図はこちら。図のSと書かれた青い箱)\n・各ホストの計測用ライブラリがトレースデータを集めてZipkinに送信する。 ・ホストは他のサービスへリクエストを飛ばすときに、リクエストにトレース用のIDを付与してます こうすることで、データをあとで、束ねることが可能となります。 ◯計測ライブラリの利用方法 ・Finagle\nJVMのための非同期ネットワークスタックである。 それは、JVMベース言語(JavaやScalaなど)で非同期RPCのクライアント・サーバを構築するのに利用できる。 FinagleはTwitterの内部ですごく利用されていて、トレースサポートを実現するのに当然のポイントです。 現時点で(Finagleは)ThriftやHTTP、Memcache、Redisのクライアント・サーバサポートも持っています。 ScalaでFinagleサーバをセットアップするのはつぎのようなコードになります。 トレースを追加するには、finagle-zipkinを追加して、ServerBuilderのtraceFactory関数を呼ぶだけです。\nServerBuilder() .codec(ThriftServerFramedCodec()) .bindTo(serverAddr) .name(\u0026#34;servicename\u0026#34;) .tracerFactory(ZipkinTracer()) .build(new SomeService.FinagledService(queryService, new TBinaryProtocol.Factory())) クライアント側も同様です。 上記のようにサンプリングしたリクエストにZipkinトレーサーを指定することで 自動的にトレースできるようになります。 サービスやホストでのリクエストの開始と終了を記録できます。 さらに付加的な情報を記録したい場合は、つぎのようなコードを追加します。 Trace.record(\u0026#34;starting that extremely expensive computation\u0026#34;) 上記コードは、上記コードが実行された時間に文字列を付加できます。 キーバリュー情報を付加したい場合は次のようになります。 Trace.recordBinary(\u0026#34;http.response.code\u0026#34;, \u0026#34;500\u0026#34;) Ruby Thrift\nリクエストのトレースに利用できるgemもあります。 リクエストに対してトレースIDを生成し、リクエストに付与し、トレーサーにプッシュするのにRackHandlerのgemを利用できます。 トレーサをトレースするサンプルはzipkin-webを参照。\nRubyからトレースクライアントをコールするのに、Twitter Ruby Thrift clientを使います。 つぎのようなコードを書きます。\nclient = ThriftClient.new(SomeService::Client, \u0026#39;127.0.0.1:1234\u0026#39;) client_id = FinagleThrift::ClientId.new(:name =\u0026gt; \u0026#34;service_example.sample_environment\u0026#34;) FinagleThrift.enable_tracing!(client, client_id), \u0026#34;service_name\u0026#34;) Querulous\nQuerulousはScala用のSQLデータベースのインタフェースライブラリです。 SQLクエリの実行のタイミング情報をトレースに追加できます。 Cassie\nCassieはFinagleベースのCassandraクライアントライブラリです。 CassieのトレーサーはFinagleの例とほぼ一緒ですが、 CassieではKeyspaceBuilderに設定します。 cluster.keyspace(keyspace).tracerFactory(ZipkinTracer()) とりあえず、ここまで。___ 2012/06/22 リンクを貼って体裁を修正\n","date":1339721820,"dir":"post/2012/","id":"69f755dd5b9e90a99c3086543790541c","lang":"ja","lastmod":1339721820,"permalink":"https://blog.johtani.info/blog/2012/06/15/zipkin%E3%81%AEreadme%E3%82%92%E8%AA%AD%E3%82%93%E3%81%A7%E3%82%8B%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E5%91%A8%E3%82%8A%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/","publishdate":"2012-06-15T09:57:00+09:00","summary":"ZipkinのGithubにあるReadmeを読んでます。 せっかくというか、頭が悪いので読みながら内容をメモ。 まずは、アーキテクチャとトレー","tags":["Zipkin"],"title":"ZipkinのReadmeを読んでる(クライアント周りについて)(Jugemより移植)"},{"contents":"久々にSolrの話です。 といっても、結構前からの話でして。。。\nschema.xmlのfieldTypeの設定に「autoGeneratePhraseQueries」という属性があります。 Solr3.1で導入されました。動作に関しては関口さんのブログで説明されています。 Solr 1.4までは、Analyzerがトークンを複数返してくる場合(例:lucene-gosenで「Solr入門」という文字列を入れた場合など)にフレーズクエリとして処理していました。 Lucene 3.1.0から、この処理がデフォルトfalse(つまり、フレーズクエリにならない)という挙動になりました。(詳しくは関口さんのブログで。) ただ、Solr 3.1.0では、下位互換性を考慮して、autoGeneratePhraseQueriesの設定値はデフォルトが「true」でした。\nこのデフォルト値がSolr 3.3以降で提供されているschemaのバージョン(1.4以上)からデフォルト値が「false」に変更されています。 schemaのバージョンを1.3以前のものから1.4以上に移行する場合は注意が必要です。\nとまぁ、偉そうに書きましたが、私もちゃんと追えてませんでした。 Solr勉強会第6回で、関口さんの発表できちんと説明されていて、参加してたのに聞けてなかったですし。(メモ取ってるのに、書いてない。)\nということで、Solr入門のサンプルschemaも少し修正しました。 こちらとこちらの記事に追記してありますので、参考にしてください。\n","date":1339603740,"dir":"post/2012/","id":"277f7f2177e2a265a62680ea0158f9b9","lang":"ja","lastmod":1339603740,"permalink":"https://blog.johtani.info/blog/2012/06/14/autogeneratephrasequeries%E3%81%AE%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88%E5%80%A4%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/","publishdate":"2012-06-14T01:09:00+09:00","summary":"久々にSolrの話です。 といっても、結構前からの話でして。。。 schema.xmlのfieldTypeの設定に「autoGeneratePh","tags":["solr"],"title":"autoGeneratePhraseQueriesのデフォルト値について(Jugemより移植)"},{"contents":"すでに読まれた方もいるかも知れませんが、気になったのでメモを書いてみようかと。\n先週の木曜日にTwitterのエンジニアブログでZipkinというOSSを公開したという記事がでました。 非常に興味深いシステムだったので、ちょっとずつ読み解いていきたいなという宣言(というか、ハッパをかけてもらうため)も兼ねて、まずはブログの内容をメモ程度に残しておきます。\nZipkinは分散トレースシステム(distributed tracing system)です。Twitter APIの1リクエストを構成する様々なサービスのタイミングデータ(計時データ)を集めるために作りました。 Firebugのような性能プロファイラのよなもので、しかもバックエンドのサービスもプロファイル可能です。 ZipkinはAPLv2ライセンスでOSSとしてGithubで公開しています。\nZipkinはWebのユーザインタフェースを持っています。(元記事参照) 各サービス(縦軸)でどのくらい時間がかかっているか(横軸)がわかり、クリックすることでより詳細な情報が得られます。 Zipkinはパフォーマンス改善の余地のある部分(遅いMySQLのSELECTなど)を見つけるのに役立ちます。\nZipkinはどのように動くの? Twitterに届いたリクエストからサンプリングしたリクエストに対してトレース可能なIDを付与して、すべてのサービスに渡していきます。 全リクエストの一部をサンプリングすることで、トレースのオーバヘッドを減らし、常に本番環境で利用できるようにしています。 Zipkinコレクタ(collector)が、Scribe経由でタイミングデータを受け取り、Cassandraに保存してインデックスを作成します。 Zipkinクエリデーモンがインデックスを利用して、WebUIにトレースデータを見つけます。\nZipkinはHack Weekで開始されました。 最初はThriftに対するGoogle Dapperの論文の基本的な部分の実装から始まり、現在ではHttp、Thrift、Memcache、SQL、Redisリクエストをサポートしています。 これらはFinagleライブラリで経由で動作します。Rubyのgemも用意してあります。\nということで、ほぼ直訳ですが、何かの役に立てればと。 ちょっとずつですが、Githubのページやソースを読みながら記事を書いていこうと思っています。\n","date":1339515600,"dir":"post/2012/","id":"ee48516e57684c5a4c22adccac34be92","lang":"ja","lastmod":1339515600,"permalink":"https://blog.johtani.info/blog/2012/06/13/twitter%E3%81%8C%E5%85%AC%E9%96%8B%E3%81%97%E3%81%9F%E5%88%86%E6%95%A3%E3%83%88%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%B3%E3%82%B0%E8%BF%BD%E8%B7%A1%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0zipkin/","publishdate":"2012-06-13T00:40:00+09:00","summary":"すでに読まれた方もいるかも知れませんが、気になったのでメモを書いてみようかと。 先週の木曜日にTwitterのエンジニアブログでZipkinと","tags":["OSS"],"title":"Twitterが公開した分散トレーシング(追跡?)システム、Zipkin(Jugemより移植)"},{"contents":"lucene-gosenの最新版(2.0.1)をリリースしました。\nプロジェクトページよりダウンロードが可能です。\n今回の修正では、@haruyama さんからいただいていたパッチの取り込み(リソース周りの改善など)が主な対応となっています。 また、コンパイルに利用するjarファイルがLucene/Solr3.6.0に変更になっています。(Issueはこちら) 3.6.0から追加されたテストケースにて、発生する問題への対処も施したものとなっています。\n","date":1339059234,"dir":"post/2012/","id":"216db319052b5742fc68862cb2f39905","lang":"ja","lastmod":1339059234,"permalink":"https://blog.johtani.info/blog/2012/06/07/lucene-gosen-2-0-2%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9%E5%91%A8%E3%82%8A%E3%81%AE%E6%94%B9%E5%96%84%E3%81%AA%E3%81%A9/","publishdate":"2012-06-07T17:53:54+09:00","summary":"lucene-gosenの最新版(2.0.1)をリリースしました。 プロジェクトページよりダウンロードが可能です。 今回の修正では、@haruy","tags":["lucene-gosen"],"title":"lucene-gosen 2.0.2リリース(リソース周りの改善など)(Jugemより移植)"},{"contents":"昨晩に引き続き、情けない内容のブログになってしまいますが。。。\n昨晩、書いた記事の調査をしていた時に気づいた、問題になるケースがあったので調査をしていました。 Issue32に登録した内容になります。 拙い英語を振り絞って書いた英語なので、伝わらないかもしれないのでブログに残しておきます。 昨晩の問題点となったクラス(StreamTagger2.java)の内部処理についてです。 lucene-gosenのLucene向けのTokenizerの内部処理では入力文字列の処理を行うのに、「char buffer[]」を用いて 入力文字列をReaderから読み込むときにバッファリングしています。 このバッファリングにて、特定のケースにて、想定していない場所を単語の切れ目と認識してしまう問題が実装上存在しました。 Issue32に記載した内容は次のようになります。\n上記バッファは4096文字というサイズで固定になっています。 StreamTagger2クラスでは、この4096文字をオーバーするような文字列の場合に、つぎの処理により、4096文字以下の場所に文章の区切りを探そうとします。\n4096文字以上の文字列が入力される バッファに入れられるだけの文字(4096文字)をバッファにコピーする。 バッファの後ろから、つぎの5種類の文字を探索し、見つかった場合(場所をkとし、k>0の場合)は、その場所を文章の切れ目と判定して、0からk+1文字目までの文字をStringTaggerを利用して形態素解析する。 あとは、繰り返し 上記条件に合致しない場合は、4096文字を文章とみなして形態素解析を行います。 ここで、5種類の文字は以下のとおり。\n0x000D:CARRIAGE RETURN(CR) 0x000A:LINE FEED(LF) 0x0085:NEXT LINE (NEL) 0x2028:LINE SEPARATOR 0x2029:PARAGRAPH SEPARATOR 見ての通り、制御文字ばかりです。 この5文字以外は切れ目と判断してくれません。 ということで、4097文字の文字列が存在し、上記5種類の文字が一度も出てこない場合、バッファのサイズで文字列が途切れてしまい、想定しない区切り位置で区切られた文章に対して形態素解析が実行されてしまいます. HTMLから文字列を抜き出して解析したり、長い文書を解析する場合に、改行文字を削除して処理するといったことも考えられます。 上記5種類の文字列のみで文章の区切り位置を判断してしまうのは問題ではないかと。 まずは、4096文字内に「。」句点が存在した場合に、その部分を区切り位置として認識するようなパッチを記載して、Issue32に添付しました。\n「。」句点を採用した理由はつぎのとおりです。 StreamTagger2では、上記バッファリングした文字列を更に、BreakIterator.getSentenceIterator(Locale.JAPANESE)にて取得したBreakIteratorにて文節単位に区切ってから、各文節ごとに形態素解析を実施しています。 ということは、BraekIteratorにて分節の区切りとして判断される文字については、上記の文字種に追加しても問題無いという判断からです。 ただし、この修正でも、純粋に4096文字以上、句点が出てこない場合には区切り位置がおかしなことになってしまいますが。。。 もう少し、BreakIteratorの挙動を調べて、他にも利用可能な区切り文字が存在しないかを調査していく予定です。。。\n1年以上コミッターをやっているのに、こんなことも理解していないのかよいうツッコミを受けてしまいそうでなんとも情けない話です。。。 まずは、現状報告でした。\n","date":1338913260,"dir":"post/2012/","id":"cbf9587a8187985725963b8bfc67004d","lang":"ja","lastmod":1338913260,"permalink":"https://blog.johtani.info/blog/2012/06/06/issue32%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A64096%E3%81%AE%E5%A3%81/","publishdate":"2012-06-06T01:21:00+09:00","summary":"昨晩に引き続き、情けない内容のブログになってしまいますが。。。 昨晩、書いた記事の調査をしていた時に気づいた、問題になるケースがあったので調査","tags":["lucene-gosen"],"title":"Issue32について(4096の壁)(Jugemより移植)"},{"contents":"久々にlucene-gosenを触っています。 trunkのlibにある、jarファイルが3.5ベースだったので、3.6ベースにしてテストをしたところ、 いくつかある、ランダムテストで結果の不整合が検出されたので、調査していました。 先程、trunkに対応版をコミットしました。もう少しテストケースを追加してからリリースします。 おそらく、通常の使い方では問題無いと思います。\nLuceneでは、ランダムな文字列を利用したテストが実装されています。 lucene-gosenでもこのテストを利用してランダムなテストをしています。 実際にはtest/以下のorg.apache.luceneパッケージにテストケースがあります。 今回、jarファイルを差し替えた時に、このランダムなテスト実施にて、assertが失敗するケースが発生しました。\n原因究明までに、いくつかフェーズがあったので、忘れないように書いておきます。\n1.ランダムテストのテストケースにてエラーがassertが失敗するケースが発生 ※ただし、成功する場合もあり。 2.該当のテストを再現しつつデバッグ+該当のテストがどんなものかを解読(勉強不足。。。) ※テストは、失敗した場合につぎのようなメッセージが表示され、同じテストが再現可能です。 以下、エラーの出力例。「NOTE: reproduce with: 」のあとにあるantコマンドを実行すれば、同じテストが再現可能です。\n[junit] ------------- Standard Error ----------------- [junit] TEST FAIL: useCharFilter=false text=\u0026#39;wgxznwk\u0026#39; [junit] [junit] ===\u0026gt; [junit] Uncaught exception by thread: Thread[Thread-3,5,main] [junit] org.junit.ComparisonFailure: term 0 expected:\u0026lt;w[gxznwk]\u0026gt; but was:\u0026lt;w[]\u0026gt; [junit] at org.junit.Assert.assertEquals(Assert.java:125) [junit] at org.apache.lucene.analysis.BaseTokenStreamTestCase.assertTokenStreamContents(BaseTokenStreamTestCase.java:146) [junit] at org.apache.lucene.analysis.BaseTokenStreamTestCase.checkAnalysisConsistency(BaseTokenStreamTestCase.java:565) [junit] at org.apache.lucene.analysis.BaseTokenStreamTestCase.checkRandomData(BaseTokenStreamTestCase.java:396) [junit] at org.apache.lucene.analysis.BaseTokenStreamTestCase.access$000(BaseTokenStreamTestCase.java:51) [junit] at org.apache.lucene.analysis.BaseTokenStreamTestCase$AnalysisThread.run(BaseTokenStreamTestCase.java:337) [junit] \u0026lt;=== [junit] [junit] NOTE: reproduce with: ant test -Dtestcase=TestGosenAnalyzer -Dtestmethod=testReliability -Dtests.seed=4ad9618caecb9fb2:d5476c03b8172df:-9c569f70013ffbb -Dargs=\u0026#34;-Dfile.encoding=SJIS\u0026#34; [junit] ------------- ---------------- --------------- [junit] Testcase: testReliability(org.apache.lucene.analysis.gosen.TestGosenAnalyzer):\tCaused an ERROR 3.デバッグの結果、Luceneのtest-frameworkにある「MockReaderWrapper」というクラスの影響を確認 LuceneのJIRAのLUCENE-3894にて追加されたクラスであるとわかる。 このクラス、Readerのreadメソッド内部で、ランダムな値を元に長さを途中で返すという実装のReaderになっている。 (全部で18文字の文字列なのだが、ランダムな値を元に、12文字として結果を一旦返すという仕組みが実装されている) 4.lucene-gosenの問題箇所を特定。 Readerが途切れた部分を分節として扱ってしまう実装になっていた。 該当の部分に修正をいれてコミット。 という具合です。 一応、テストを数回走らせてランダムテストが問題なく終了するのを確認はしてあります。 今回の問題に対する、個別のテストケースを追加してから近日中リリースする予定です。 対応が遅くなって申し訳ないです。。。\n","date":1338827340,"dir":"post/2012/","id":"0dcb6d0f17794bbca56b6cdb9e20b932","lang":"ja","lastmod":1338827340,"permalink":"https://blog.johtani.info/blog/2012/06/05/trunk%E3%81%AE%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E5%B7%AE%E3%81%97%E6%9B%BF%E3%81%88lucene-solr3-6-0%E3%81%A8%E3%83%A9%E3%83%B3%E3%83%80%E3%83%A0%E3%83%86%E3%82%B9%E3%83%88%E3%81%AE%E5%A4%B1%E6%95%97%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/","publishdate":"2012-06-05T01:29:00+09:00","summary":"久々にlucene-gosenを触っています。 trunkのlibにある、jarファイルが3.5ベースだったので、3.6ベースにしてテストをし","tags":["lucene-gosen"],"title":"trunkのライブラリ差し替え(Lucene/Solr3.6.0)とランダムテストの失敗について(Jugemより移植)"},{"contents":"録画してたEテレのスーパープレゼンテーションを見ててふと書きたくなったので、書いてます。 あとから読んだら恥ずかしくなりそうだけど。。。 「\u0026ldquo;知力の余剰\u0026quot;が世界を変える」というClay Shirkyさんの話を見て思ったことです。 社会的に貢献できる仕組みが最近増えているという話の内容でした。そこで、OSSについても同じことが言えるよなぁと思った次第でして。\n昔からいろんなかたが言ってると思うし、今さら何をとおもわれるかもしれないですが、なんとなく書きたくなってしまったので。\n私はシステム開発を生業にしています。特にOSSにはお世話になっています。 実際に、OSSを利用している方はかなりいると思います。 幸いにも、私はOSSのコミッターもやっています。 OSSに色々と関わってきて常々思っていることがありまして。\nOSSは基本は有志の方々が開発やメンテナンスを行なっています。(最近では会社で行なっているところもありますが。) そんなOSSに貢献する方法はいくつかあるのかなぁと。\nバグを発見したら報告したり、こんな機能を作ってみたけどどうですか?とパッチを送ってみたりするのは素晴らしい貢献だと思います。 ただ、なかなかアクションを起こすのって勇気がいるかなぁと。 実際、私もパッチ書いたりバグ報告するのは気後れすることがありしました。 ただ、貢献する方法ってこれだけじゃないよなぁと、コミッターをやり始めて思いました。\nもちろん、バグ報告してもらえるともっとありがたいですし、新機能とかリクエストを送ってもらえるともっと嬉しいです。 MLに質問するのもありです。ただ、ちょっとハードルが高いと思うこともあります。\nそんな時は、ただ使っているよと、ツイートしたりブログを書いてくれるだけでもありがたいし、ヤル気が出るものです。 使い勝手が悪いなぁというツイートでも、なんでこんなに使いにくいんだというブログでもいいんです。 気になるなぁという形でもいいと思っています。 githubでフォローするだけでもいいかと。 反応があれば、使ったり触ってもらえていることがわかります。 なので、使っているよとかアピールしてもらえると嬉しいよなぁと。\nなんか、締りのない感じになっちゃいましたが、反応があるとうれしいので、お気楽に反応しましょうよというお話です。\n","date":1338394320,"dir":"post/2012/","id":"ffdbd6a7d28c9a63976e9eec38cab0f5","lang":"ja","lastmod":1338394320,"permalink":"https://blog.johtani.info/blog/2012/05/31/%E3%82%AA%E3%83%BC%E3%83%97%E3%83%B3%E3%82%BD%E3%83%BC%E3%82%B9%E3%81%B8%E3%81%AE%E8%B2%A2%E7%8C%AE%E3%81%AE%E3%82%B9%E3%82%B9%E3%83%A1/","publishdate":"2012-05-31T01:12:00+09:00","summary":"録画してたEテレのスーパープレゼンテーションを見ててふと書きたくなったので、書いてます。 あとから読んだら恥ずかしくなりそうだけど。。。 「\u0026l","tags":["misc"],"title":"オープンソースへの貢献のススメ(Jugemより移植)"},{"contents":"JJUG CCC 2012 Springに参加してきました。 昨年のFallに続き、2回目です。 概要や、タイムテーブルはこちらを御覧ください。 今回は、午後一から参加しました。 色々と迷いましたが、つぎのを聞いて来ました。\nHotSpot vs JRockit ~ HotRockit到来の前に予習しよう! Play! Framework - モダンで高速なWeb開発 Grails/Groovyの開発活用術 Scala 最新状況報告 From Swing to JavaFX SwingからJavaFXへのマイグレーションガイド JRockitは使ったことがなく(たぶん)、新鮮でした。いろいろなコマンドが用意されているなぁと。 あと、jvisualvmの使い方も知らないこともあったのでいい話が聞けました。 プレゼンに慣れているようで、プレゼン中に、コマンドラインの拡大+コマンドのオプションに赤い下線を入れるなど、どうやってやっているのか、プレゼンの内容よりも気になってしまったのが本音です\nPlayは今回の目玉の一つでした。まだ、手元でPlayを触り始めたばかりだったので、概観がつかめたのが良かったです。 あとでスライドを見なおさないと。 頭がどうしてもServlet、JSPのため、未だにPlayに切り替えができてないので、もっと触ってみないとなぁと。 ちなみに、紆余曲折してまして、Play 1.2.4→Play 2.0(Javaアプリ)→Play 2.0(Scalaアプリ)と心変わりしまくりで、まだ完全に作ってないのに、ふらふらしてます。。。\nGrailsはGrailsを現場にどのように投入していくのがいいかという、技術よりは、政治的な話でしたが面白かったです。 実際に、あまり有名でないプロダクトを現場に導入するのに、Javaだからと無理やり説得してみたりw、開発コストがこれくらい下がりますという話をしてみたりと、いろいろやられているようでした。 あと、PlayのあとにGrailsということもあり、すこしPlayを意識した話もされていました。\nScalaはScalaDaysの話+Scalaの最近の動向ということで、ある程度Scalaを知っている人がターゲットのようでした。 少し触っただけなので、何となく分かる部分もありましたが、最後の方はついていけてないです、すみません。。。 一番感じたのは、発表者の水島さんのScalaに対する愛情でしょうか。\n最後は桜庭さんのJavaFXのお話です。 一応、昔、JFreeChart+Swingでちょっとしたものを作ったことがあるので面白かったです。 プレゼン自体もJavaFXで作成されていたり、オープニングがStarWars風だったりと凝ったプレゼンでした。 JavaFXとしては、JavaOneでも聞いたのですが、グラフやHTMLがリッチに書けるようになったことがびっくりです。\n実際のSwingアプリからJavaFXへの移行に関して、注意する点などがわかりやすく聞けました。 FXMLは確かに便利ですよねぇ。レイアウトをJavaで組むのがすごくめんどくさかったもんなぁ。\nさて、簡単ですが、感想でした。 今回一番残念だったのは、長丁場の割に電源の確保が難しかったことでしょうか。 ツイートしたり、メモ取ったりしたかったのですが、電源が乏しいので、Wi-fiオフにしてメモ取るのが限度でした。。。\n場所:オリンピック記念青少年総合センター 日時:2012/05/28 10:00 - 19:00 ◎13:10 - 14:00 C-1 HotSpot vs JRockit ~ HotRockit到来の前に予習しよう! 谷本 心 @cero_t ◯HotSpot from Sun ◯JRockit from BEA 今は、どちらもOracle ◯違いは? 1.歴史 2.プラットフォーム JRockitはMacではNG。Solarisは一部。 2.1Oracleさん曰く Solaris/Mac → HotSpot Windows/Linuxのサーバ → JRockit Windows/Linuxのクライアント → HotSpot 2.2谷本さんは? WebLogic → JRockit 1.4、5の時の開発環境はJRockit 当時はJRockitの解析ツールがカッコ良かった 3.解析ツール 3.1コマンドラインツール プロセス HotSpot : jps JRockit : jrcmd スレッドダンプ HotSpot :jstack JRockit : jjrcmd \u0026lt;pid\u0026gt; print_threads ヒープ解析 HotSpot:jmap -histo \u0026lt;pid\u0026gt; JRocket:jrcmd \u0026lt;pid\u0026gt; heap_diagnostics HotSpot: JRockit:jrcmd \u0026lt;pid\u0026gt; 他にもJRockitは色いろある。 print_utf8poolとか(内部の文字列が出てくる) 3.2GUIツール HotSpot:jvisualvm NetBeansベース JRockit:Mission Control Eclipseベース メモリリークの解消をツールを使ってみてみましょうデモ。 ・hprofファイルを吐き出して、jvisualvmで読みこむのが楽な方法 ・jrmcはヒープダンプファイルを読み込む機能がない。 memleakというツールがある。アプリを起動してから、プロセスを右クリックして選択可能。 タイプグラフや割当てトレースみたいなものが使えるよ。 フライトレコーダーというのもあるよ。 4.HotRockitの紹介 まだいつ出るのかなぁという状態だけど、HotSpotにJRockitのツールも使えるようになるVMが出る模様。(2013?) ※デモ中に画面拡大した時に、赤線でラインを引いているのがすごく気になった。(便利なツールなのかな?そこだけ?) ◎14:15 - 15:05 C-2 Play! Framework - モダンで高速なWeb開発 池田尚史 @ikeike443 ◯自己紹介 Play!Frameworkコミッター 日本Playframeworkユーザ会 ◯アンケート メイン言語は?Java多数 触ったことある?半分くらい? Play1?Play2?半々くらい プロダクションで使ってる人?3人 ◯Playframeworkって? JEEではないよ。 Webだよ。 ServletとかXML使ってないよ。 ◯JEEは難しいよね。RailsとかDjangoから流れてくると。 ◯Webフレームワーク なので、Webアプリが作れればいいよね。 開発すべきものに注力して、抽象化とかを頑張らないようにと。 ◯ライブコーディング! Play2.0のScalaアプリみたい。 プロジェクト作成~編集して起動まで。 エラーを起こして、エラーがどのように表示されるか。 エラーのリンクをクリックして、エディタを起動するということも可能みたい。 TODOとかで、まだ終わってないのも記述可能。 パラメータとControllerの関数の引数が勝手にひもづけられますよと。 ◯歴史 Servletとかもあった。 1.2からNetty、Websocket、Scalaサポート 2.0.1:Scalaで書き直し。Netty+Akkaで非同期 ◯1と2のちがいは? ・Play1 Javaで書かれたJavaのフレームワーク。Scalaはプラグインサポート ・Play2 Scalaで書かれたScala/Javaのフレームワーク ◯Playの特徴 ステートレスとかノンブロッキングとかリアクティブとか ・高生産性 XMLがないし、unzipするとすぐ使えるよ。 ホットスワップできるよ。 CoffeeScript、LESSサポートも。assetsに入れとくとコンパイルしてくれて静的コンテンツにしてくれる。(Railsにも似たようなのあったっけか?) ・ステートレス HttpSessionがない→必要ならMemcachedとかで管理してね。 「デプロイ→ニーズ・状況に応じて即時スケールアウトという時代じゃないか?」という主張 Playはステートレス養成ギブスであり、時代の要請にマッチ ・広範囲な型安全 コンパイルしてエラー検知 ・ノンブロッキングI/O 非同期処理が手軽に書けるように考えられている。 →リアルタイムWebの時代 NettyやAkkaにより実現されてるのがいい Akkaを使ったアプリを書くと、長い処理のActorを別サーバにするなども設定で変更が可能。 ◯テスタビリティ BDDフレームワーク(Specs2?) Viewもテストできるぞと。 ◯事例 Klout:ソーシャルスコアリング イギリスのガーディアン:コンテンツAPIの実装がPlay2 MinecraftのWebサイト ◎15:20 - 16:10 C-3 Grails/Groovyの開発活用術 ~Java EE資産を活かして開発を加速する~(仮) 上原潤二 山本剛 ◯充電中のためお休み ◎16:25 - 17:15 C-4 Scala 最新状況報告 ~或いはScala Days 2012リポート~ 水島宏太 ◯自己紹介 言語を作るのが夢みたい。 ◯Scala最新状況報告 ScalaDaysの雰囲気を伝えるよと。(どっちかというと、旅行記かも) ◯Scala? ・オブジェクト指向関数型言語 ハイブリッドじゃなくて、統合したもの ・強力な静的型付け NullPointerExceptionなども起きにくい ・超強力なコレクションフレームワーク ・Javaと同等の実行速度 ・コードが簡潔(1/4くらい) ◯Scala採用企業 Twitter、Amazon.com(どこに使ってるかは不明)、Foursquare、LinkedIn、VMWare、Klout、Tumblrなど ◯Scalaのバージョンは? 2.10が開発版。2.9.2がステーブル版。 ◯開発体制 Typesafe+世界のContributor Typesafeメンバの議決でいろいろ決定 githubでオープンに開発 ◯ScalaDays2012の目玉 豪華ゲスト(私は、わからなかった) Scala2.10の新機能紹介 今後のScala、多数の応用例 ◯ScalaDays2012を見ての方向性 ・All-in-oneパッケージの提供 Typesafe Stackの提供 重要なツール sbt(Simple Build Tool) gitter8(プロジェクトテンプレート生成ツール。githubを元に色々取ってくる?) Akka Play 2.0 Framework ・学習コストの削減 言語機能のモジュール化 高度な開発者が使う昨日はデフォルトOff ・バイナリ互換性問題への対処 ・Minor Release間での互換性を維持 MIMAでジドウテキに非互換性を検出 ・Major Release間では互換性は保証しない。 No more java.util.Date ソース互換性は「概ね」保証される deprecatedは次期メジャーバージョン時に削除される。 ・Scala IDEへの注力 インクリメンタルにコンパイルしてくれるから、遅いのも気にならなくなるかも。 デバッガとか、できるよと。 ・さらなるパフォーマンス改善 Value classes AnyValを継承したクラスが作成可能 該クラスのオブジェクトがインライン化 Pimp my libraryによるヒープ使用料が0に! ◯2.10最新機能紹介 \u0026#34;1+2=#{1+2}\u0026#34;ができない s\u0026#34;1+2=${1+2}\u0026#34;ができるように String = 1 + 2 = 3 f\u0026#34;1=${1}%03d\u0026#34;もできるようにSring = 1 = 001 自分でStringコンテキストにメソッド追加できるらしい(聞き取った日本語が合ってるか?) とか。(かなり不安。。。まだまだわかってない。。。) ◎17:30 - 18:30 BOF-B-1 From Swing to JavaFX SwingからJavaFXへのマイグレーションガイド 櫻庭 祐一 ◯JavaFX 次世代のJava GUI Library Swing+Java2D+α JavaSE8から標準(JavaFX3.0) ◯サンプル クラス名がいろいろ変わってる。 ◯はまりそうなところ コンテナへの追加がちょっと違う イベントリスナは1種類のみになった。(Genericsを使うようになったよと。) ◯Bind 値が変わるとModelが勝手に検知して変わるみたい。 双方向もあり。これだとEventを書かなくても良くなりつつ有るよと。 ◯シナリオベースでマイグレーション考えましょう 1.JavaFX in Swing JavaFXにSwingを埋め込むことはできないぞと。 SwingでできないことをJavaFXでやりますよと。 おー、グラフが動く。JavaDocのHTMLも綺麗に出てる。 使い方:JFXPanelを使う シーングラフを記述可能 データのやり取りが大変。Threadが違うから。 パフォーマンスが落ちます。Java2Dで画像を書くので遅いですよと。 新規のものはJavaFXで書きましょうと。 2.Swing to JavaFX w/o FXML SwingをJavaFXに置き換える。 使い方が違うものはTableViewなど、◯Viewとついてるもの。 ちょっと考えるのはLayout Swing:コンテナ+レイアウトマネージャー JavaFX:コンテナがレイアウトを含む BorderPaneクラスとか。 問題はTableとか Swing:TableModel JavaFX:BeanをColumnにバインド 3.Swing to JavaFX w/ FXML ・FXML GUIの構造をXMLで表す。 シーングラフを表現。 スキーマレス クラス:要素 プロパティ:属性 or 要素 アノテーションバリバリです。これで、FXMLとJavaのバインディングができるよと。 ツール Java :NetBeans e(fx)clipseってのがあるかも。 FXML:Scene Builder ","date":1338259500,"dir":"post/2012/","id":"de734259dfb9addebe2b226d96b4f744","lang":"ja","lastmod":1338259500,"permalink":"https://blog.johtani.info/blog/2012/05/29/jjug-ccc-2012-spring%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%A6%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-05-29T11:45:00+09:00","summary":"JJUG CCC 2012 Springに参加してきました。 昨年のFallに続き、2回目です。 概要や、タイムテーブルはこちらを御覧ください。 今回は、午後一から参加","tags":["勉強会"],"title":"JJUG CCC 2012 Springに参加してきました。(Jugemより移植)"},{"contents":"PlayFramework2.0を触ってみてます。 ちょっとコーディングしたくなったのと、最近のアプリの作成の調査も兼ねて。 まぁ、せっかくなので、Solr検索のアプリでも作ってみようかと言うことで触ってます。 ただ、Solr検索アプリでしかなく、今のところDBを使わないので、実はPlay Frameworkじゃなくてもいいのではないかという疑問も。。。\nまだ、触り始めたばかりなので、なんともですが。感想を。 たぶん、Ruby on Railsに似ているのかなと。 RoRは仕事で少し関わったので、なんとなく知っていますが、アプリの作成手順や、ディレクトリ構成などが似ている気がします。\nコントローラーの生成のタイミングとか、内部でオブジェクトをSingletonで保持する方法とかのイメージがまだ良くつかめていない状態で、まずは、Solr検索部分(Palyにあんまり関係ないところ)を実装しているところです。\n現状で一番の疑問点は、Eclipseプロジェクト化した時の参照ライブラリのパスに関するところでしょうか。 Play Frameworkは「play new ほげほげ」コマンドを実行するとアプリのディレクトリ構成が作成されます。 このあとに、eclipsfyというplayのコマンドを実行すると、Ecilpseのプロジェクトファイルが作成されます。 この時、PlayFrameworkが利用するjarファイルたちが参照ライブラリとしてクラスパスに設定されます。\nこのパスには、PlayFrameworkのインストールディレクトリが含まれた絶対パスが記述されるのですが、 複数人で開発するときにはどうしているのかなぁと。 あと、BitbucketやGitHubにアップするときもどうするのかなぁと。 以前、この疑問ツイートして、頂いた回答としては、環境変数として定義して、各自で設定してもらうというものでした。 私も同じ事を考えていたので、腑に落ちたのですが、他にもっといい方法があったりするんでしょうか? クラスパスやEclipseプロジェクトのファイルをアップしないというのもあると思いますが、それもちょっとなぁと。 なにか、オススメとかあれば、教えていただけると嬉しいです。\n最近、ブログ更新してなかったのもあったので、まずは、導入編でした。\n","date":1337151314,"dir":"post/2012/","id":"78f002cc3d512ea302c900d1da4dfeec","lang":"ja","lastmod":1337151314,"permalink":"https://blog.johtani.info/blog/2012/05/16/playframework-2-0-java%E3%81%AE%E6%96%B9-%E3%82%92%E8%A7%A6%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%A6%E3%82%8B/","publishdate":"2012-05-16T15:55:14+09:00","summary":"PlayFramework2.0を触ってみてます。 ちょっとコーディングしたくなったのと、最近のアプリの作成の調査も兼ねて。 まぁ、せっかくなの","tags":["備忘録"],"title":"PlayFramework 2.0(Javaの方)を触ってみてる(Jugemより移植)"},{"contents":"lucene-gosenの最新版(2.0.1)をリリースしました。\nプロジェクトページよりダウンロードが可能です。\n今回の修正では、Java7でUnicodeのバージョン変更に伴う対応(詳細はこちらを参照)を行なっています。\nリソース周りの対応はまた後日。。。すみません。2012/05/16 遅くなりましたが、昨晩、JavaDocをアップしました。\n","date":1336494900,"dir":"post/2012/","id":"c4b418764dca70aebfc965899a3fa7e5","lang":"ja","lastmod":1336494900,"permalink":"https://blog.johtani.info/blog/2012/05/09/lucene-gosen-2-0-1%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9java7%E5%AF%BE%E5%BF%9C/","publishdate":"2012-05-09T01:35:00+09:00","summary":"lucene-gosenの最新版(2.0.1)をリリースしました。 プロジェクトページよりダウンロードが可能です。 今回の修正では、Java7で","tags":["lucene-gosen"],"title":"lucene-gosen 2.0.1リリース(Java7対応)(Jugemより移植)"},{"contents":" IDの秘密 (丸善ライブラリー―情報研シリーズ) 非常に面白く読めました。 バーコードの話に始まり、最後はシステムで付与するIDに関する考慮点まで幅広くIDについて語られています。\n適度に配置されたコラムがまた面白く、ここまで書いてもいいのかな?と思いながらも楽しく読ませて頂きました。 2次元バーコードが汚れに強いのも知らなかったし、チロルチョコの話は知らなかったし、指コレクションとか面白すぎです。 また、JRのSuicaの導入に7年もかけている点などは、やはりすごい技術なのだなぁというため息混じりの感想です。 それほど長い期間のテストや設計は想像がつかないです。\n最後の2章(7,8章)については、エンジニアの以外のシステムに関わる方やエンジニアになられたばかりの方たちにぜひ読んで欲しいと思いました。 もちろん、エンジニアの方にも読んでほしい内容です。\nいくつか疑問点や気になる点もあったので。\n「静脈や指紋が人によって異なるって確率はどうやって決めたんだろう?」 Twitterの説明文のあとにFBの画面の図番号が書いてある。 日本語がデコードされたけど、QRコードの文字コードって、この中に含まれてるのかな?それとも規格で決まってるのかな? 最後に、書影がNIIに合ったので撮影しました。写真へのリンクです。\n","date":1335794635,"dir":"post/2012/","id":"95c0a5b8a66950b5f22dd82a8dfe0ce5","lang":"ja","lastmod":1335794635,"permalink":"https://blog.johtani.info/blog/2012/04/30/id%E3%81%AE%E7%A7%98%E5%AF%86%E3%82%92%E8%AA%AD%E3%81%BF%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-04-30T23:03:55+09:00","summary":"IDの秘密 (丸善ライブラリー―情報研シリーズ) 非常に面白く読めました。 バーコードの話に始まり、最後はシステムで付与するIDに関する考慮点まで","tags":["読書"],"title":"「IDの秘密」を読みました。(Jugemより移植)"},{"contents":"WebSolrの話があるらしいというのを嗅ぎつけて、初めてHeroku JP Meetupに参加しました。 herokuもWebSolrも知りつつ、手を出していなかったので、いい機会でした。 (SignUpだけ、勉強会直前に済ませましたw)\nHerokuはAWS上に構築されたアプリケーションプラットフォームで、簡単にアプリをデプロイして動作させることができるようです。 Ruby on Railsを使うのが多いみたいですが、他の言語も利用できると。 で、herokuの面白いところは、アドオンとして、開発が簡単にできるようなしくみが用意されていることみたいです。 今回発表のあった、IronMQ、WebSolr、PaperTrailもアドオンとして用意されており、簡単に利用することが可能です。 IronMQはメッセージキューとして利用できます。\nWebsolrはSolrを簡単に利用できる形で提供しているものになります。 今、利用できるのは3.5.0のようで、最新版(3.6.0)になるのはまだ未定のようです。 今回の発表はWebSolrの話しもありましたが、基本は全文検索の仕組みとKuromojiの説明でした。 ただ、残念ながら、Kuromojiは3.6.0からの提供となるので、現時点では利用できないようです。 あとで、聞いた話だと、schema.xmlを自分で変更できるようです。 ただ、jarファイルを置いたりはできないようなので、lucene-gosenを利用するとかはできないみたいですが。。。 ほかにも、bonsai.ioとして、ElasticSearchの提供も行うようです。 まだ、利用はできないようですが。\n最後がPapertrailです。 こちらは、ログを保存して、検索、グラフ化(視覚化)してくれるアドオンです。 まだ、ベータのようですが、ログを保存してくれるようです。無料版もあるようです。 アドオンとしての機能もそうですが、利用しているグラフ化のツールなど、面白そうなものが利用されていました。\nLTはRuby使いの方が多かったです。\nRuby使いではないのですが、いろいろなアドオンが用意されており、サービスを簡単に提供することができそうだという印象をうけ、ちょっと使ってみたいなぁと思いました。 普段参加していない勉強会だったので、普段では知りえない興味ある話が聞けて面白かったです。\n余談ですがPapertrailの人が利用していた、slideshareのようなサービスのSpeaker Deckもよさそうなので登録してみました。 次に何か発表があった時には資料はこっちにアップしてみようかなぁと\n以下は、いつものように自分用のメモです。\n日時2012/04/20 19:00 to 21:00 会場:パソナグループ本部 呉服橋 ◎オープニング – Ayumu AIZAWA (Heroku Evangelist) ◎新入社員からの挨拶 – Koichi SASADA (Ruby Developer) 前職:大学教員 仕事:CRuby開発 Heroku使った事無いですwRailsもよく知らないですw RUby2.0のリリースがゴール。2013/Feb 性能アップのことやってます。 ◎IronMQ – Chad Arimura (Iron.IO)\n「メッセージキューは涼しいです。」 (Google翻訳による日本語訳付きのスライド) Aggregation、Distribution。。。 IronMQ Elastic、RESTful heroku addon ironmq:rust 簡単にheroku上にキューが用意できるアドオンです。 Q:メッセージがキューに到達したのを確認する方法か? A:ステータスコードが帰ってくる。 Q:データのサイズのリミットは? A:postのリミットはある。S3とかに巨大データをおいて、ポインタを渡すとかしてほしい。 Q:キューへの到達の成功の保証は? A:アプリケーション側で判断してください? ◎Search \u0026amp; Indexing on Heroku – Nick Zadrozny (Websolr) スライドはこちら。\n※ツイートしてて、メモとってなかったので、ツイートをコピペ。 次はWebsolrのお話 Bonsai.io? Bonsai by onemorecloud - http://bit.ly/JjCuaE SQLのLIKE検索はO(n)でおそいねぇと。 クエリのパースについての話。 今度は転置インデックスのお話。 Termへの分割ってどーすんの?というお話。Tokenizeのお話。 その1:N-GramというTokenizeの方法。N文字ずつ先頭からTermを切り出す。開始位置は1文字ずつずらしていくと。 N-Gramはノイズがのるし、多くのTermがでてきちゃうよと。 その2:そこで、次は形態素解析ですね。 先週、Lucene/Solr 3.6.0がリリースされて、Kuromojiという日本語向けの形態素解析器がでましたよ。 Kuromojiはこちら。(Lucene版とは少し違うけど。)http://atilika.org/ Kuromojiのサーチモードのお話。 通常は、「関西国際空港」という単語になってしまうのを、Kuromojiでは「関西」「国際」 「空港」という切り方の単語も出してくれると。 ちなみに、lucene-gosenでは、サーチモードはないんですねぇ。。。 「の」はどこに消えたんだ??そこの説明は? ElasticSearchやSolrのコアの部分でLuceneを使ってるよ。 ElasticSearch http://bit.ly/qjjvWp Kuromojiはユーザ辞書をサポートしてるよ。 Q:まだ、3.5.0では? A:もうすぐやります ◎log analysis for your Heroku app – Eric Lindvall (Papertrail)\nheroku上にログを貯めて、検索したりグラフ化したりできるようになりそうなもの。 [スライドはこちら](http://speakerdeck.com/u/lindvall/p/log-analysis-for-your-heroku-app) ログを貯めて、検索や可視化できるようにするサービスみたいです。 まだ、アイデアレベルのものも発表資料には含まれていました。 内部で利用しているツールなど、資料の最後に出てきますが、色々と面白そうなものがありました。 ◎Lightning Talks ◯Receibo ( @shu_0115 ) デザイナーxエンジニアハッカソンでの成果らしい。 Webベースの家計簿アプリ。 買ったものの名称と料金を入れるだけ。 ◯Heroku + Pusherで作る!リアルタイムアプリケーション ( @satococoa ) WebSocketみたいなことが、Pusherでできるらしい。 http://www.slideshare.net/satococoa/heroku-pusher ◯Herokuアドオンを作ってみてわかったこと ( @takkam ) ◯heroku client のちょっと進んだ使い方 ( @hsbt ) ◯love heroku? – we love herokuのご紹介 ( @ppworks ) ","date":1334935380,"dir":"post/2012/","id":"c92c12a28fa219ad1aab60865046ff05","lang":"ja","lastmod":1334935380,"permalink":"https://blog.johtani.info/blog/2012/04/21/heroku-jp-meetup-4%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-herokujp/","publishdate":"2012-04-21T00:23:00+09:00","summary":"WebSolrの話があるらしいというのを嗅ぎつけて、初めてHeroku JP Meetupに参加しました。 herokuもWebSolrも知りつつ、","tags":["勉強会"],"title":"Heroku JP Meetup #4に参加しました。#herokujp(Jugemより移植)"},{"contents":"先日、Solr入門のサンプルschema.xmlの3.6.0対応版の作成をしていて、気になったことがあったので、 メモとして残しておきます。\nSynonymFilterFactoryの属性「tokenizerFactory」に関連する話です。 (「Apache Solr入門」の36-37ページに記載があります。)\nSynonymFilterFactoryでは、類義語設定ファイルを読み込む際に利用するTokenizerFactoryを「tokenizerFactory」という属性で指定できます。(以下は書籍の記述を抜粋)\n\u0026lt;filter class=\u0026#34;sold.SynonymFilterFactory\u0026#34; synonyms=\u0026#34;synonyms.txt\u0026#34; ... tokenizerFactory=\u0026#34;solrbook.analysis.SenTokenizerFactory\u0026#34;/\u0026gt; このように、TokenizerFactoryが指定できます。\nただ、こちらの記事で書いたように、 Solr 3.6.0のexampleのschema.xmlではCJKのフィールドは次のように設定されています。\n\u0026lt;!-- CJK bigram (see text_ja for a Japanese configuration using morphological analysis) --\u0026gt; \u0026lt;fieldType name=\u0026#34;text_cjk\u0026#34; class=\u0026#34;solr.TextField\u0026#34; positionIncrementGap=\u0026#34;100\u0026#34;\u0026gt; \u0026lt;analyzer\u0026gt; \u0026lt;tokenizer class=\u0026#34;solr.StandardTokenizerFactory\u0026#34;/\u0026gt; \u0026lt;!-- normalize width before bigram, as e.g. half-width dakuten combine --\u0026gt; \u0026lt;filter class=\u0026#34;solr.CJKWidthFilterFactory\u0026#34;/\u0026gt; \u0026lt;!-- for any non-CJK --\u0026gt; \u0026lt;filter class=\u0026#34;solr.LowerCaseFilterFactory\u0026#34;/\u0026gt; \u0026lt;filter class=\u0026#34;solr.CJKBigramFilterFactory\u0026#34;/\u0026gt; \u0026lt;/analyzer\u0026gt; \u0026lt;/fieldType\u0026gt; 3.6.0以前は、solr.CJKTokenizerFactoryを利用していましたが、3.6.0からはCJKTokenizerFactoryがdeprecatedになってしまい、代わりにStandardTokenizerFactory+CJKBigramFilterFactoryの組み合わせになっています。 exampleのCJKのフィールドタイプ設定を利用して、かつ、そのフィールドにSynonymFilterを利用する場合に、 StandardTokenizerFactoryを指定してしまうと、類義語が展開できなくなってしまうので注意が必要です。\nCJKのフィールドでSynonymFilterを利用する場合は、類義語の設定ファイル内の記述を自力でCJKTokenizerが分割する形で記述する(まぁ、やらないでしょうが)か、deprecatedですが、CJKTokenizerFactoryを利用するのが現時点での対応でしょうか。\nなお、これに絡んで、このようなチケットもできています。\nSyntaxHighlighterを導入してみました。 ちょっとはみやすくなってますかね? まだ、SyntaxHighlighterの設定を調べながら使っているので、コロコロ変わるかもしれないですが、気にしないでください。 ","date":1334592971,"dir":"post/2012/","id":"12d1e0cf7396dd33a9bbbca8da4cbc68","lang":"ja","lastmod":1334592971,"permalink":"https://blog.johtani.info/blog/2012/04/17/solr-3-6-0%E3%81%AEcjk%E3%81%AE%E8%A8%AD%E5%AE%9A%E3%81%A8synonymfilterfactory%E3%81%AE%E6%B0%97%E3%81%AB%E3%81%AA%E3%82%8B%E7%82%B9/","publishdate":"2012-04-17T01:16:11+09:00","summary":"先日、Solr入門のサンプルschema.xmlの3.6.0対応版の作成をしていて、気になったことがあったので、 メモとして残しておきます。 S","tags":["solr"],"title":"Solr 3.6.0のCJKの設定とSynonymFilterFactoryの気になる点(Jugemより移植)"},{"contents":"先日の続きです。「Apache Solr入門」の2章から4章の説明について、Solr3.6.0で動作させる時の変更点を以下に書いていきます。 なお、前回も説明しましたが、3.6.0からKuromojiという形態素解析器がSolrに同梱されるようになりました。 これから説明する2章の変更点の手順ですが、Kuromojiとlucene-gosenそれぞれの利用方法について説明します。 添付のschema.xmlについては、基本的にKuromojiを利用する形に変更してあります。 それに加えて、lucene-gosen用のフィールドを別途追加で定義しました。 これらのフィールド名については、次の表の用になります。 適宜、書籍のフィールド名と置き換えながら読み進めたり、試したりしてください。\nKuromojiフィールド lucene-gosenフィールド title title_gosen author auther_gosen summary summary_gosen intended_reader intended_reader_gosen from_author from_author_gosen toc toc_gosen 2章 2.1.3 schema.xmlのバージョン(27ページ) Solr3.xではschema.xmlのファイルの最新バージョンは**1.5**になっています。\n2.2.3 代表的なトークナイザ(35ページ) solrbook.analysis.SenTokenizerFactoryは必要ありません。 Solr 3.6.0からはKuromojiと呼ばれる形態素解析器が用意されています。 solr.JapaneseTokenizerFactoryがそれに該当します。 これとは別に、lucene-gosenを利用する場合、Solr向けのトークナイザが用意されています。 solr.GosenTokenizerFactoryがそれに該当します。\n2.2.4 代表的なトークンフィルタ(37ページ) 以下の2つについてはKuromojiが同等のトークンフィルタを提供しています。 また、lucene-gosenを利用する場合は、lucene-gosenに同等のトークンフィルタが存在します。\nsolrbook.analysis.KatakanaStemFilterFactory solrbook.analysis.POSFilterFactory 次のものがSolr 3.6.0に用意されているので、こちらを利用します。\nsolr.JapaneseKatakanaStemFilterFactory solr.JapanesePartOfSpeechStopFilterFactory それぞれ、次のものがlucene-gosenにあるので、こちらを利用します。\nsolr.GosenKatakanaStemFilterFactory solr.GosenPartOfSpeechStopFilterFactory 2章向けのschema.xmlはこちらです。その他のtxtファイルについては、特に変更はありません。\n3,4章は特に変更はありません。Solrの起動の仕方にだけ注意してください。(-Dsen.homeは必要ありません)\n以上が4章までの修正点になります。\n昨日に引き続き、眠い目をこすりながら修正したので、おかしいかも。 動かない、意味がわからないなどあれば、コメントorツイートいただければと思います。\n2012/06/14提供しているschema.xmlに関して修正を加えました。こちらの記事で説明しているautoGeneratePhraseQueriesの値をtext_gosen、text_cjkのフィールドに対してtrueを設定する記述を追記しました。\n","date":1334339880,"dir":"post/2012/","id":"d77cdb466c5063b99c5aea58e6da4d32","lang":"ja","lastmod":1334339880,"permalink":"https://blog.johtani.info/blog/2012/04/14/apache-solr%E5%85%A5%E9%96%80%E3%81%AE%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%81%AEkuromoji%E3%81%A8lucene-gosen%E5%AF%BE%E5%BF%9C2%E7%AB%A04%E7%AB%A0/","publishdate":"2012-04-14T02:58:00+09:00","summary":"先日の続きです。「Apache Solr入門」の2章から4章の説明について、Solr3.6.0で動作させる時の変更点を以下に書いていきます。 な","tags":["solr"],"title":"「Apache Solr入門」のサンプルのKuromojiとlucene-gosen対応(2章~4章)(Jugemより移植)"},{"contents":"以前より、アナウンスしていた、Kuromojiという日本語形態素解析が含まれるLucene/Solr 3.6.0がリリースされました。\n以下、各リリース内容について簡単に説明されているページへのリンクです。\nSolrリリースのお知らせ\nLuceneリリースのお知らせ\nSolr 3.6.0の変更の目玉は各言語のAnalyzer/Tokenizerの設定がexampleのschema.xmlに含まれるようになったことです。 Kuromojiという日本語用の形態素解析器もexampleを起動すればすぐに利用できる形になっています。 Kuromojiを利用する場合は、exampleのschema.xmlが参考になるでしょう。\nあと、大きな変更は、Ivyに対応した点です。ソースをダウンロードするとわかりますが、依存するjarファイルが含まれない形に変更されています。 SVNからチェックアウトした場合も同様です。ビルドにはネットワークに接続している環境が必要になりました。\nまた、このリリースに合わせて、以前書いた「Apache Solr入門」のサンプルについての記事も変更が必要かと思い、 前回の記事をベースに以下に変更した記事を書いたので、参考にしてください。 今回は、Kuromojiという日本語形態素解析がデフォルトで含まれるようになったので、 Kuromojiの利用方法とあわせて、lucene-gosenの利用方法も記載します。 サンプルのschema.xmlについては、Kuromoji、lucene-gosenが同時に利用できる形のものを用意しました。\nサンプルのschema.xmlを最新版(Solr 3.6 + lucene-gosen-2.0.0-ipadic)のものを用意しました。 なお、あくまでも、3.xでlucene-gosenを利用する場合の「Apache Solr入門」のサンプルプログラムの変更点(とりあえず、4章まで)の違いについて記述します。 申し訳ございませんが、1.4と3.xの違いについての説明はここでは行いません。\n以下では、各章でschema.xmlに関連する記載のある部分を抜粋して、変更点と変更したschema.xmlのリンクを用意しました。参考にしてもらえればと思います。\n1章 1.6.1 N-gram(17ページ) 1.6.1の手順に変更はありません。 サンプルプログラムが入っているZip「solrbook.zip」のintroduction/ngram/schema.xmlファイルの代わりに こちらのschema.xmlを利用してください。 ※なお、Solr 3.6.0から、SOLR_HOME/example/solr/conf/schema.xmlにデフォルトでN-gramで利用しているCJKTokenizerの設定が入るようになっています。 (実際にはCJKTokenizerではなく、CJKBigramFilterとCJKWidthFilterに変更されています。)\n1.6.2 形態素解析(18ページ~20ページ中盤まで) CJKと同様、exampleにKuromojiを利用した設定がすでに記述されています。text_jaというフィールドタイプになります。書籍の21ページ1行目に記載のある、 「Field」のテキストボックスに入力する文字列を「text_ja」とすると、Kuromojiを利用した形態素解析結果が表示されます。exampleですでに幾つかのフィルタも設定されているため、書籍の出力結果とは異なる表示となるはずです。\nlucene-gosenを利用する場合は手順が大きく変わります。 Senを利用する場合、Senの辞書のビルド、Senのjarファイルの配置、Senを利用するためのTokenizerクラスを含んだサンプルjarの配置という作業があります。 lucene-gosenではコンパイル済みの辞書がjarファイルに含まれています。 また、Solr向けのTokenizerもlucene-gosenのjarファイルに含まれています。 lucene-gosenを利用して形態素解析を体験するための手順は次の流れになります。 なお、schema.xmlについては上記N-gramでダウンロードしたschema.xmlに形態素解析の設定もあわせて記載してあります。\njarファイル(lucene-gosen-2.0.0-ipadic.jar)をダウンロードして、$SOLR/example/solr/lib(libディレクトリがない場合は作成)にコピーします。 コピーが終わりましたら、次のように$SOLR/exampleディレクトリでSolrを起動します。 (-Dsen.homeは必要なし)\n$ java -jar start.jar あとは、書籍の記述にしたがって管理画面のAnalysis画面で動作を確認します。 ほぼ、図1-6と同じ結果になっていると思います。 (lucene-gosenで出力される情報には本書のサンプルよりも多くの情報が含まれています。また、サンプルでは、形態素解析の後の単語に基本形を採用しているため、「な」が「だ」として出力されています。基本形を出力する場合は後述するこちらで紹介したTokenFilterを利用すれば可能です。)\n2章については後日説明することにします(眠くなってきた。。。)\n動作しないなどあれば、コメントください。\n2012/06/14追記提供しているschema.xmlに関して修正を加えました。こちらの記事で説明しているautoGeneratePhraseQueriesの値をtext_gosen、text_cjkのフィールドに対してtrueを設定する記述を追記しました。\n","date":1334339100,"dir":"post/2012/","id":"904b07170a0ce481b7491e7fecce4f79","lang":"ja","lastmod":1334339100,"permalink":"https://blog.johtani.info/blog/2012/04/14/lucene-solr-3-6-0%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9---apache-solr%E5%85%A5%E9%96%80%E3%81%AE%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%81%AEkuromoji%E3%81%A8lucene-gosen%E5%AF%BE%E5%BF%9C1%E7%AB%A0/","publishdate":"2012-04-14T02:45:00+09:00","summary":"以前より、アナウンスしていた、Kuromojiという日本語形態素解析が含まれるLucene/Solr 3.6.0がリリースされました。 以下、各","tags":["solr"],"title":"Lucene/Solr 3.6.0リリース / 「Apache Solr入門」のサンプルのKuromojiとlucene-gosen対応(1章)(Jugemより移植)"},{"contents":"Twitterでこのブログ流れてきて、気になったので、流し読みして簡単にメモ。 Amazonのサービスでスケールする検索サービスみたい。\n主に、機能面です。価格とかはみてないです。\nデータと検索トラフィックに対して自動でスケール(※automaticってのがどういう感じかは調べてないです) CloudSearch APIsでアクセス可能。AWS管理コンソールからオペレーションできる。コマンドツールもある データ登録にHTTPSも使えますよ。データ形式はJSON、XML、SDF(Search Document Format)と呼ばれるものに準拠したもの near real-timeで検索可能になる。RAMにインデックスを保持して更新処理が早くなる(Lucene/Solrと一緒か?) ステミングとかストップワードの設定変えたらre-index ファセット、フィールド指定検索が可能。(ファセットはファセットクエリみたいなのもできるのかな?) データ量が増えたら、サーチインスタンスを追加するか、インスタンスタイプを大きくしてスケールする? トラフィックが増えたら新しいインスタンスにデータをレプリケートしてインスタンスを追加する 簡単に実現できるよ。ファセット検索、全文検索、And/OR検索式、ランキングのカスタマイズ、フィールド指定ソート、フィールド指定検索、テキスト処理オプション(ストップワード、類義語、ステミングのような) ここから詳細のドキュメントが見れるみたいなので、また、見てみます。\nあと、WikipediaをCloudSearchで動かしてるデモとそれに関する記事もあるみたいです。これも暇を見つけて眺めてみます。\n","date":1334241069,"dir":"post/2012/","id":"bed3b7fcc1294e23639057435ac8756a","lang":"ja","lastmod":1334241069,"permalink":"https://blog.johtani.info/blog/2012/04/12/%E3%83%A1%E3%83%A2amazon-cloudsearch%E3%81%8C%E5%87%BA%E3%81%A6%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F%E3%82%88/","publishdate":"2012-04-12T23:31:09+09:00","summary":"Twitterでこのブログ流れてきて、気になったので、流し読みして簡単にメモ。 Amazonのサービスでスケールする検索サービスみたい。 主に、","tags":["備忘録"],"title":"【メモ】Amazon CloudSearchが出てきましたよ(Jugemより移植)"},{"contents":"JavaOne Tokyo 2012に参加してきました。 4/4-4/5の2日間開催されていたのですが、子供が体調を崩してしまい、4/5のみの参加となりました。 4/4はTwitterのTLを眺めて、羨ましがってました。\n7年ぶりに日本で開催されたJavaOneみたいです。 そういえば、7年前くらいに参加した記憶があるなぁと。\n会場入りして最初の感想は年齢層が高いなぁと。 最近、勉強会によく顔を出すようになったのですが、勉強会とは年齢層が少し異なりました。 まぁ、私も年齢層を上げている一人ではあるのですが。。。 Javaも熟成してきてるなぁというのが最初の感想でした。 あと、思ったよりもスーツ率は低かったと思いました。(5割はいましたが) 一番違和感を感じたのは、会場の所々の色が「赤い」ことです。。。\n以下は私が参加したセッションのカンタンな感想です。\nJava EE6 Modeling JS2-01 #jt12_s201\nJavaEEから離れてはや数年。私が関わっていた頃はEJB2.0が出たくらいのタイミングだったので、 色々と変わってきているなぁというのが第一印象です。 CDI、Singleton EJBなど、知らない単語もちらほらと。 earではなく、warファイル1つで済む、jQueryをリソースjarとしてパッケージングしてwarファイルに入れられるなどは簡易になっていいなぁと。 web.xmlがアノテーションで記述できて要らなくなるという話は一長一短だと思いました。 一覧性があるからいいと思うこともあるので。 中国の方?の英語だったので少し特徴的でした。すこしは頑張ってみたものの、やはり同時通訳を聞いてしまって反省しています。。。\nマルチコアCPU時代のJavaプログラミング JS2-14 #jt12_s214\nF社の方が実際に経験されてきた性能関連のプログラミングについての話でした。 現時点のJavaでマルチコアCPUで気をつけるべきプログラミングの観点をわかりやすく説明されたいいセッションでした。 詳細は下のメモを見ていただけるといいですが、色々とプログラミングで気をつけるべき点を説明されていました。 いいおさらいになりましたし、忘れていることや知らないこともあって勉強になりました。 TLでも見かけましたが、モダンJavaプログラミングみたいな、今のJavaでのプログラミングの気をつけるべき点を書いた書籍があるといいかもなぁと思いました。 あと、もうひとつ私が好印象だと思ったのは、F社の製品の紹介などがなかったからかもしれませんw\nサービス維持・発展を踏まえた楽天オークションのJava EEによる開発と運用 JS2-23 #jt12_s223\n楽天オークションの開発をサれている方の立ち上げから現在に至るまでの開発メンバーの管理の仕方や 実際に利用している開発手法、気をつけている点のお話です。 スライドに書いてあること以外のことを発表者の方が話をされており、もう少し、喋る内容に関連した図などを入れてもらえるとわかりやすかったかもしれません。 あとは、WebLogicの管理画面が使いやすくていいという話のあとに、GlassFishに移行していますという話があったりと、少し「?」が浮かぶ部分がありました。。。\nJSR 353: Java API for JSON Processing JS2-33 #jt12_s233\n最近、Twitterで遊んでもらっている(勝手に絡んでいるだけという話も。。。)@yusukeyさんの発表です。 結構な数の立ち見が出るほどの盛況ぶりで、発表者の@yusukeyさんもびっくりしていました。 JSRがどういった形で実際の仕様として公開されていくのかという話がわかりやすく紹介されていて勉強になりました。 所々で笑いが入るなど、さすがの安定感でした。立ち見が出るはずです。 ようやく、JavaもJSONに関する処理を仕様として取り入れようとしているのはいい傾向かと。 ※残念ながら資料は公開されないようです。\nUI Controls and Charts: Drag-and-Drop, Filtering, Sorting, Table Hookup with Charts JS2-42 #jt12_s242\n最近、Chartに興味を持っていたので、登録したセッションです。 内容としてはJavaFXのコンポーネントをリストアップして紹介していくというお話でした。 グラフ(Chart)周りも数種類が用意されるようです。 JavaFXをあまり知らないのですが、Swingをすこしやっていたのでなんとかついていくことが出来ました。 発表者の方が、実際にJavaFX内部の実装を行われている方だったようで、QAでいくつかこんなコンポーネントはないのか?という質問に、「私のPCでは動いているのですが、ドキュメントなどの整備が追いついていないので公開できていないです」という回答が出て、なかなか大変なのだなぁとw Chartに関しては、グラフの重ね合わせなどがまだできないということで、JFreeChartを触ったことがある身としてはすこし物足りなさそうだなぁというのが印象です。\nLearn how the JVM is fundamental to our architecture. BoF2-03 #jt12_b203\n今回JavaOneに参加した一番の理由がこのセッションです。 Twitterのアーキテクチャに関するセッションでした。 思った以上に濃い内容で、ツイートしたデータがどんな流れで登録されるのか、登録されたデータを各ユーザのTimelineにどのようにアクセスして表示しているのかが説明されました。 今回は主にFinagleについての話でしたが、非同期処理をどのように活用しているかというお話でした。 負荷分散を行なっているポイントやキャッシュについての考え方などです。 メモを取るのに夢中になってしまい、英語をヒアリングするという目的を見失ってしまいましたが。。。 期待以上の話が聞けて満足しています。\nパネルディスカッション\n最後はJavaに関連するコミュニティを運営されている方々のコミュニティ運営に関するディスカッションです。 コミュニティの運営の苦労している点や、心がけている点など、運営も大変そうだなぁと。 どうしても長くやっているとメンバーが固定化してしまうという話なども出ていました。 これは難しいですよね。会社も同じことが言えますし。 一番印象に残ったのは桜庭さんの「動くものが作れるのが楽しい」という一言でした。 エンジニアをやってるのは確かにそこが面白いからだなぁと。最近忘れかけているので、もっと色々と作っていきたいですね。\n以上がカンタンな感想です。 少し残念なのですが、事前に参加登録していたセッションについては、マイページと呼ばれるところから資料がダウンロードできるものもあるみたいですが、参加登録してないものについてはダウンロードが出来ない様でした。(4/6現在) 参加できなかったセッションの資料こそ見たいと思うのが普通だと思うのですが、どうでしょう?そのうちどこかに公開されるのかなぁ。\n以下は、いつもの通り個人のメモです。\n場所:六本木ヒルズ アカデミーヒルズ49F 日時:2012/04/05 ○Java EE6 Modeling JS2-01 #jt12_s201 スーツ禁止。Eva好き? ・特徴 Web Profile Pruing POJO、Annotation、Less XML Java EE6の半分のAPIは変更なし。新規が11% ・JavaEE6 Web Profile CDI、Interceptors、JSR 250 Singleton EJB JPAはEntityBeanの代わりかな? ・パッケージングがearではなく、war一つで済むように。 war(ウォーファイル) web.xmlはアノテーションで行えるようになり、要らなくなる。 ◯マルチコアCPU時代のJavaプログラミング JS2-14 #jt12_s214 HotSpotVM依存のお話ですよ。 ・GCとか ・java.util.concurrent.ForkJoinPool デフォルト並列数は論理CPU数 ・メモリアロケーション TLABが非効率に。先にある程度大きめにスレッドに割り当てを行うため、 スレッド数が上がるとTLABが非効率になる-\u0026gt;Eden全体では未使用領域があるんだけどGC発生とか ・JNIでの問題 GetStringCriticalとReleaseStringCritical間はGCが抑止されるため。 ・無意識のロック HashTableやStringBufferなど。 String#getBytes()も。 InetAddress#getAllByName()が内部でキャッシュを持ってる=ロック File#renameTo()も内部でキャッシュ(ExpiringCache)持ってる。 Javaでは時間がかかる処理にはキャッシュを利用するという仕組みなので。スレッド数を増加させる場合は注意が必要 ・フェアネスロック lock = new Object(); for (int i=0;i\u0026lt;100;i++0{ synchronized(lock){ System.out.println(\u0026#34;i=\u0026#34;+i+\u0026#34;tid=\u0026#34;+Thread.currentThread().getId()); } } 上記を実行してもかたよることがあるよ。=フェアじゃない モニターによるスレッド割り当ての説明。 RentrantLockでフェアネスになるよ。 ・性能分析 println()で区間分析。複数スレッドで実行したら実行時間にずれが。 println内部でもsynchronizedを利用している。=ロックのせいで処理時間が遅くなるスレッドが出てきたりする。 JVMTIで性能分析する場合RawMonitorEnter,RawMonitorExitでロックとりあいなるのでもマルチスレッッドだと正しい値がでない。GetThreadLocalStrage使え。 ・まとめ: ハードウェア更改時にプログラムの変更が必要になることもあるよ。 わずかのロックが命取りに(ロックをあんまり使わない、無意識なロックを見極めなさい) ロックポリシーの選択(レスポンス重視なのか、スループット重視なのか) QA Q:事例が合ったという話でしたが、コードの修正しかないんですか? A:はい。やっぱり治すのがいいです。あとは、チューニングですが。。。 Q:ReentrantLockが昔はスレッドダンプにでなかったのですが、今は? A:今は出ます。 Q:各世代とJavaのバージョンのマッピングは? A:第3世代が1.5くらいから。第2世代が1.3とか1.4? ◯サービス維持・発展を踏まえた楽天オークションのJava EEによる開発と運用 JS2-23 #jt12_s223 ・短期で人材が参加できるようにしているというお話 ・楽天オークションの成り立ち(郵政とdocomoと楽天) ・商品、コミュニティ系(出品とか検索とか)と流通系(入出金、配送など)の2軸 ・メンバー30人くらい ミドルエンジニア エンジニア プロデューサー ・楽天市場をベースとして機能追加 ・巨大でリリースが大変に。 ・この5年で機能分解して機能ごとのリリースをめざして改善している ・JavaEEを使う理由 WebLogic上にバッチが動いているなどの仕組みをしている? 管理機能が充実している(WebLogic) ・GlassFishへ移行中 あれ?Weblogicの管理機能がいいんじゃなかったっけ? EJB実装はWebLogicに依存してるのでWebLogicもバージョンアップしてる。 ※メモはここまで。電池の持ちを気にして ◯ JSR 353: Java API for JSON Processing JS2-33 #jt12_s233 ・JSONとは JavaScript Object Notation 「軽量な」データ交換フォーマット ・JSON仕様のグラフ ・XMLもあるのになんで? シンプルで可読性が高い 属性がなく、複雑なスキーマ仕様がない。 ・コンパクト ・Twitter、GoogleMaps、YahooWebServicesなど ・JCP、JSRのお話 JSRの役割とか。 リファレンス実装の話。 ・JSR-353 http://jcp.org/en/jsr/detail?id=353 StAXやDOMに対応するよ。 ・ゴールではないもの JSONをJavaのドメインオブジェクトにバインドするとかもどすとか。 ・メンバー @yusukeyも一人 ・参加になったきっかけ 2011/10にTwitterがJCPに参加 2012/12/6にJSON JSR提出 年越しに採択 @yusukey「これTwitterで重要じゃない?」 @cra 「やりましょう」 ・JSRのコミュニケーション 世界各地の人なので、基本メールベース(今は自己紹介したくらい。。) ・既存のJSONライブラリ json.org、jackson、google-gson ・なんで、いろいろあるのにJSR? 標準化、クラスパスにデフォ、シンプル、ライセンスで悩まないとか。 ・ロードマップ エキスパートグループ作成→アーリードラフト→パブリックレビュー→ファイナルリリース いま、アーリードラフト ・最新仕様 javax.json.* javax.json.spi.* javax.json.stream.* javax.json.tree.* メソッドチェインできるみたい。 JsonObject.create(reader);みたい JsonObject obj = …; JsonWriter writer = obj.accept(writer.) ・改善案 JSON***にしたいな。 spiはらないんじゃないかな?(いま、一個しか無い) treeもいらないんじゃないかな?(そんなに増えないし) parseじゃないかな? メソッド追加(asStringで文字列化とか、create(String)とか) QA Q:JSONのスキーマ決めないの?バリデータとか A:JSONスキーマはあんまりもてはやされてない。一応あるのはある。 さすがの安定感。適宜笑いが入ってて楽しかったです。 ◯UI Controls and Charts: Drag-and-Drop, Filtering, Sorting, Table Hookup with Charts JS2-42 #jt12_s242 ◯JavaFX 2.0のControls ◯Label、Button、ToggleButton、RadioButton、Hyperlink、CheckBox ◯Slider、ScrollBar、ScrollPane、ProgressIndicator、ProgressBar ◯TextField、PasswordField、TextArea ◯新しい機能 TitledPaneとAccordion TabPaneとSplitPane ◯Charts XYChartとPieChart XYChartにはLineChart、AreaChart、BarChart、ScatterChart、BubbleChartがある。 ◯Menu MenuItemの下に色々ある。 CheckMenuItem、RadioMenuItem、CustomMenuItem(SeparatorMenuItemとか) ◯ChoiceBox、ContextMenu、ToolTip ◯ListView ◯2.1の新機能 ComboBox、http://fxexperience.com/2012/03/new-in-javafx-2-1-combobox/ StackedBarChart、 StackedAreaChart MenuBarのMac OSへの対応(窓の中じゃなく、画面上部にちゃんと出る。) LCD Text QA: Q:テキストエリアの日本語入力とかは? A:JavaFX3.0で対応 Q:FXML(Scene Builder)を使ってコードが生成されるのか? A:ドラッグ・アンド・ドロップでやる場合はScene Builderでもできるでしょう。私はNetBeansとかでやりますけどね。 Q:Dialogはいつ対応されるんでしょうか? A:私は使ってるんですけど、JavaFXに入れてもらえませんwコードは出来てますw Q:Chartがありますが、pngやsvgでの出力は可能? A:できません。そのうちできるかも。 Q:Chartの結合はできる?Axisの時間を便利に使うツールはありますか? A:できないです。ありません。 Q:FX2.0でカスタムコントロール作るの大変? A:私のマシンでは動いてるんですがw Q:ChartにCSSを適用することは可能? A:可能です。データはJavaから出力されたものだけですけどね。 Q:JavaFX2.0の起動速度が上がったけど、どういう仕組? A:私は上の方のエンジニアなのでよくわからないですが、GPUをうまく使ってるみたいです。 ◯Learn how the JVM is fundamental to our architecture. BoF2-03 #jt12_b203 Java、Scala、Linuxのカーネルまで担当してます。 ・Twitterのアーキテクチャ ・スパイクが急にあがる場合にも対応できるスケールの話。 なでしこ、#バルス、大震災など ・Twitterはプラットフォーム ・最上位層:HTTP Proxy(Routing) ・中層:Twitter App(Models/Biz Objects、Composition) UserService、TweetService、TimelineServiceに分解(Models/Biz Objects) API(Composition) ・最下層:TimelineStorage、TweetStorage、SocialGraph、UserStorage(Storage/Retrieval) ・NEEDS サーバ負荷をハンドルできる必要がある。 言語のフレキシビリティ(JavaとかScalaとか) 成熟したコンカレンシーモデル ・Java が提供してるもの 開発者のエコシステムが素晴らしい。例:Nettyを使っている。Non-blocking I/O world class JITとコンカレンシーモデル メモリ管理 利点:メモリ管理を意識しなくていい 課題:GC。OpenJDKのコミュニティで参加してる。 複数の言語が実行可能な環境 ・OpenJDKについて ・Finagleのお話。 Netty上に作られた非同期なRPCサーバクライアントのライブラリ http://twitter.gthub.com/finagle/ ・TimelineServiceのお話 340M/day 10K/sec(イベント時) ・ツイートが入ってくる仕組み HTTP Proxy → tweet API → queue → tweet daemon → fanout (social graph)→ delivery → timeline cache → redis ・fanout 4000フォロワーごとにdeliveryにツイートが渡される。 ・Timelineを見る仕組み HTTP Proxy → timeline API(user service、) →timeline service →timeline cache ・timeline、tweets、users ・timeline serviceとtimeline cacheの関係 Finagleで負荷分散している ・timeline serviceからtimeline cacheへのリクエストを監視して、 高頻度のリクエストについては、timeline serviceのin-process cacheに入れる仕組み ・Service[Request, Response] Scalaの記述 service(request).onSuccess {response =\u0026gt; println(\u0026#34;got response! \u0026#34; + response) } ・Finagleのコンポーネント コネクション管理 プロトコルデコード ThriftでService以降がつながってる。 分散トレース オーバーヘッドを抑えて全体を監視(RPCトレース(呼び出しと処理時間のタイムラインチャート)) サービスディスカバリ observability ◯パネルディスカッション ・JGGUG、JRuby、Scala、Groovyのコミュニティ運営に関係している方々によるディスカッション。 ","date":1333698660,"dir":"post/2012/","id":"56d5711303378bd333ddb611a53ece94","lang":"ja","lastmod":1333698660,"permalink":"https://blog.johtani.info/blog/2012/04/06/java-one-tokyo-2012-%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-javaonejp/","publishdate":"2012-04-06T16:51:00+09:00","summary":"JavaOne Tokyo 2012に参加してきました。 4/4-4/5の2日間開催されていたのですが、子供が体調を崩してしまい、4/5のみの参加となりました。 4/4","tags":["勉強会"],"title":"Java One Tokyo 2012 に参加しました。#JavaOneJp(Jugemより移植)"},{"contents":"先日、2.0.0リリースの記事にも記載しましたが、Java7でテストケースが失敗する問題がありました。\n@haruyamaさんと@hideaki_tさんの協力により問題を解消し、trunkと4xブランチにコミットしました。\nissueにも記載しましたが、Java6からJava7にバージョンアップするタイミングで変更されたUnicodeのバージョンが原因でした。 Java6ではUnicodeのバージョンが4.0です。Java7ではUnicodeのバージョンが6.0に変更されています。 今回の問題は「・」(0x30FB)の文字列のCharacter.getType()がCONNECTOR_PUNCTUATIONからOTHER_PUNCTUATIONに変更されたのが原因です。(この変更自体はUnicode 4.1で変更されたみたい) カタカナ文字種の判別をlucene-gosenのnet.java.sen.tokenizers.ja.JapaneseTokenizerのgetCharClass(char c)メソッドで行なっています。 修正前は、ここで、charの範囲が0x30A0~0x30FFにある文字でかつ、Character.getType()がCONNECTOR_PUNCTUATIONでないものがカタカナとして判別されていました。 issueの添付ファイルにJava6とJava7で上記範囲の文字のCharacter.getType()のリストを生成して、該当する文字を探した所、「・」(0x30FB)のみであることがわかりました。 ということで、このコードの意図としては、「・」はカタカナではないと判別したかったのだと。 上記の確認を行えたので、ソースコードを修正してコミットしました。 2.0.1としてリリースするかは、Issue29のボリュームを見て考えますので、もう少しお待ちください。\n参考にしたサイト: JavaSE 7でメソッド名に使えなくなった文字 UNICODE CHARACTER DATABASEのHistory\n","date":1333552800,"dir":"post/2012/","id":"c7937b6b4bde2a96191dc31db913e1ab","lang":"ja","lastmod":1333552800,"permalink":"https://blog.johtani.info/blog/2012/04/05/lucene-gosen%E3%81%AEjava7%E3%81%A7%E3%81%AE%E3%83%86%E3%82%B9%E3%83%88%E5%A4%B1%E6%95%97%E5%95%8F%E9%A1%8C%E3%81%AE%E5%AF%BE%E5%BF%9C/","publishdate":"2012-04-05T00:20:00+09:00","summary":"先日、2.0.0リリースの記事にも記載しましたが、Java7でテストケースが失敗する問題がありました。 @haruyamaさんと@hideak","tags":["lucene-gosen"],"title":"lucene-gosenのJava7でのテスト失敗問題の対応(Jugemより移植)"},{"contents":"先日、宣言したとおり、lucene-gosenのパッケージ名+クラス名の変更を行ったlucene-gosen 2.0.0をリリースしました。 Lucene/Solr 3.6.0のリリースを待つつもりだったのですが、なかなか出ないので先にリリースを行いました。 現時点では、branches/4xについては、パッケージ名、クラス名の修正が追いついていません。 明日までに4xブランチについても修正を反映する予定です。\n参考までに、1.2.1から2.0.0への変更点について以下にまとめました。 また、変更に伴い、Solrのschema.xmlに記述するクラス名も変更になります。 schema.xmlのサンプルについてはこちらをご覧下さい。\n変更点 まずは、パッケージ名の変更点です。 左が旧パッケージ名、右が新パッケージ名となります。\n旧パッケージ名 新パッケージ名 org.apache.lucene.analysis.ja org.apache.lucene.analysis.gosen org.apache.lucene.analysis.ja.tokenAttributes org.apache.lucene.analysis.gosen.tokenAttributes また、パッケージ名とは別に、以下のクラス名も変更になっています。 まずは、org.apache.lucene.analysis.gosenのクラス名の変更点です。\n旧クラス名 新クラス名 JapaneseAnalyzer.java GosenAnalyzer.java JapaneseBasicFormFilter.java GosenBasicFormFilter.java JapaneseKatakanaStemFilter.java GosenKatakanaStemFilter.java JapanesePartOfSpeechKeepFilter.java GosenPartOfSpeechKeepFilter.java JapanesePartOfSpeechStopFilter.java GosenPartOfSpeechStopFilter.java JapanesePunctuationFilter.java GosenPunctuationFilter.java なし GosenReadingsFormFilter.java JapaneseTokenizer.java GosenTokenizer.java JapaneseWidthFilter.java GosenWidthFilter.java 次は**org.apache.solr.analysis**です。 旧クラス名 新クラス名 JapaneseBasicFormFilterFactory.java GosenBasicFormFilterFactory.java JapaneseKatakanaStemFilterFactory.java GosenKatakanaStemFilterFactory.java JapanesePartOfSpeechKeepFilterFactory.java GosenPartOfSpeechKeepFilterFactory.java JapanesePartOfSpeechStopFilterFactory.java GosenPartOfSpeechStopFilterFactory.java JapanesePunctuationFilterFactory.java GosenPunctuationFilterFactory.java なし GosenReadingsFormFilterFactory.java JapaneseTokenizerFactory.java GosenTokenizerFactory.java JapaneseWidthFilterFactory.java GosenWidthFilterFactory.java また、上記クラスに関連するテストクラスの名前も変更になっています。\n以上がクラス名、パッケージ名の対応に関する修正ついてでした。\nまた、現在、Java7にてテストケースが失敗する問題が見つかっています。 こちらの問題の対応版についても近日中にリリースを行う予定です。\n問題点、質問などありましたら、コメントしていただくと回答いたします。\n2012-04-03追記 忘れてました、すみません。今回のリリースで、以下の機能が追加されています。\nAntのパラメータにproxy.user、proxy.passwordの追加 GosenReadingsFormFilterの追加 TokenAttributeの修正(PronunciationsAttributeImpl、ReadingsAttributeImpl) Antは認証が必要なプロキシ環境で辞書のビルドを実施するときにユーザ名、パスワードを指定できるようにしました。\nGosenReadingsFormFilterは単語を読みに変換するTokenFilterになります。 よみは、辞書に登録してある読みになります。オプションとして、romanizedが指定可能です。指定をすると、よみをローマ字に変換します。\nTokenAttributeの修正は、バグフィックスになります。Issueはこちらです。\n","date":1333362120,"dir":"post/2012/","id":"06731164684f90f33ce4017eca9d8ec1","lang":"ja","lastmod":1333362120,"permalink":"https://blog.johtani.info/blog/2012/04/02/%E9%87%8D%E8%A6%81lucene-gosen-2-0-0%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9/","publishdate":"2012-04-02T19:22:00+09:00","summary":"先日、宣言したとおり、lucene-gosenのパッケージ名+クラス名の変更を行ったlucene-gosen 2.0.0をリリースしました。 Lucene/Solr","tags":["lucene-gosen"],"title":"【重要】lucene-gosen 2.0.0リリース(Jugemより移植)"},{"contents":"lucene-gosenを利用して頂いてる皆様に連絡があります。\n連絡事項 次期lucene-gosenのリリース(2.0を予定)にて、org.apache系のパッケージ名および、クラス名の変更を行います。 Lucene/Solrの次期リリース版である3.6.0以降では、lucene-gosen 2.0(予定)を利用するようにしてください。\n経緯 Twitterでは少しずつツイートしていますが、Lucene/Solr 3.6から日本語の形態素解析器がLucene/Solrにて用意されることになりました。 ベースとなっているのは、Atilika社が開発したKuromojiという形態素解析器です。 Lucene/SolrにコントリビュートされたタイミングではKuromojiAnalyzerなど、Kuromojiという名称が残った形で取り込みが行われました。 その後、LUCENE-3909にて、Kuromojiではなく、一般的な名称(Japanese*)に変更する提案が行われました。 この提案で、luene-gosenが利用しているクラス名、パッケージ名と大半のクラスが衝突してしまうこととなりましす。 今後も、lucene-gosenを利用していただけるように、lucene-gosenのIssueを発行し、 現在、lucene-gosenのtrunkにてパッケージ名の変更及びクラス名の変更作業を行なっています。 正式にリリースするタイミングになりましたら、再度連絡いたします。\nブランチなどについて 現時点ではパッケージ名、クラス名の変更はリポジトリの以下のものについてのみ作業を行う予定です。\ntrunk branches/4x 現時点でのリリース版(1.2系)のソースについてはbranches/rel-1.2にて、これまで同様のクラス名、パッケージ名のまま変更を行いません。 1.2系についてはこちらをご覧下さい。\nまた、当ブログにて、提供しているSolr入門のサンプルに利用可能なschema.xmlなどの記事についてもLucene/Solr3.6がリリースされた際には再度修正して掲載いたします。 Kuromojiの利用方法もあわせて記載したいです。\n参考: lucene-gosenとKuromojiの機能などの比較についてはこちらを参考にしてください。\n","date":1332783540,"dir":"post/2012/","id":"f8327953a0f0b80011b939111807999a","lang":"ja","lastmod":1332783540,"permalink":"https://blog.johtani.info/blog/2012/03/27/%E9%87%8D%E8%A6%81lucene-gosen%E3%81%AE%E6%AC%A1%E6%9C%9F%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/","publishdate":"2012-03-27T02:39:00+09:00","summary":"lucene-gosenを利用して頂いてる皆様に連絡があります。 連絡事項 次期lucene-gosenのリリース(2.0を予定)にて、org.","tags":["lucene-gosen"],"title":"【重要】lucene-gosenの次期リリースについて(Jugemより移植)"},{"contents":"子供の寝かしつけしてたら、寝かしつけされてしまって、2時に目が覚めてしまいました。 TSUTAYAでCD借りてきてウォークマンに入れようと思っていたのに。。。 ということで、今作業してます。\nMBAを買う前から使っている、もう9年目のWindows自作デスクトップで基本的にはCDの取り込みをしています。 ファイルサーバ(BuffaloのTeraStation)がLionから接続できないというのと、 X-アプリで曲管理していたのでという理由です。 あと、ウォークマンなのでMac用のソフトがなかったりというのも理由です。\nで、眠い目をこすりながらWindowsマシンを起動すると、ネットワークにつながらないじゃないですか。。。 再起動してもダメでした。\nとなってしまったので、せっかく、譲ってもらったMac miniも活用しないといけないなと思い、iTunesでアルバムを取り込んでみています。 ここ数年はWAV形式でデータを取り込んでいたので、WAVでの取り込みを設定して、iTunesで取り込みました。\nとまぁ、ここまでやってから、件のWindows機を再度、再起動したらネットワークに繋がってしまいました。。。 なので、残りのCDはWindows機で取り込みしてます。 けど、そろそろこのPCも危なそうなので、データをサルベージして、Mac miniで作業できるようにしないとなぁ。 Macでウォークマンを運用している人はどうやってるんだろう? ちなみに私が利用しているウォークマンはNW-A847です。 エンコードはWAV形式で取り込んで、X-アプリでウォークマンに入れています。 iTunes使ってる人は、アップルのロスレスエンコードをつかってるのかなぁ? ということで、調査・検討したい項目はこんなところですか。\n調査:TeraStationにMacからつなぐ方法(Lionで利用できそうなソフトなにかないかな?) 調査:iTunesでウォークマンに曲転送(やってみればすぐわかるだろう。。。) 調査:iTunesの曲をCDに焼く方法(車で曲聞くのにCDだから) 検討:ファイルサーバのリプレース対象となる機種(ファイルサーバは導入してまだ5年だから余裕がないと買い換えない) 検討:iPodに鞍替え(Sony好きだし、ウォークマン好きだし、買ったばっかりだからまず無い選択肢) 検討:Mac miniにVirtualBox入れて、WindowsからX-アプリ使うとか。(ファイルサーバが見えるようになるかな?) 検討:Mac miniをWindowsとして運用(もったいなさすぎる気がする) とまぁ、まだ悩んでるだけで、取り留めもない事を書いて、しかも結論が出ないままですが、ご容赦ください。 ご意見、提案を大募集してます!!\n","date":1332618420,"dir":"post/2012/","id":"8b76101d185700a8efed148d8722d926","lang":"ja","lastmod":1332618420,"permalink":"https://blog.johtani.info/blog/2012/03/25/%E4%B9%85%E3%80%85%E3%81%ABmac-mini%E3%81%AE%E3%81%93%E3%81%A8%E3%81%A7%E3%82%82/","publishdate":"2012-03-25T04:47:00+09:00","summary":"子供の寝かしつけしてたら、寝かしつけされてしまって、2時に目が覚めてしまいました。 TSUTAYAでCD借りてきてウォークマンに入れようと思っ","tags":["備忘録"],"title":"久々にMac Miniのことでも(Jugemより移植)"},{"contents":"はい。またまた、Twitter API勉強会に参加してきました。(今回から開催回数の記載がなくなった?) 今回は直前でタイムテーブルが変わってしまう波乱がありましたが、個人的には楽しめる内容でした。 Twitterの国際化や形態素解析などの話が聞けたのがすごく面白かったです。 アーキテクチャや利用されている形態素解析器の話など、また、現状の問題点なども話が聞けました。 日々、進化しているんだなぁと。 残念ながら、発表者の方が懇親会にいらっしゃらなかったので、詳しく聞けませんでしたが、挨拶だけは出来ました。 実際のテスト環境や導入方法、A/Bテストとかやってるのかなど、ブログをかきながら色々と気になることが出てきてしまいますw 頭の回転がよくないので、話を聞いてる間は質問があんまり思い浮かばなかったなぁ。。。\nその他にも(使ったことなくてすみません。。。)「昼会」のサービスの話、他の言語でのTwitterの活用の話も聞けました。\n途中で帰ってしまいましたが、懇親会でも数人の方とお話できて、楽しかったです。 (今回の懇親会会場はちょっと人数の割に手狭だったかもなぁ)\n次回は4月末を予定しているようでした。今度こそ、利用規約の話になるんですかね? 忙しさを見つつ、また参加しようかと思います。\nということで、いつものメモです。\n開催日時:2012/03/21 19:00 ~ 21:00場所:ハロー会議室shibuya Zusaarのページ\n◎Twitterの日本語検索、ハッシュタグについて @keita_f\n◯アーキテクチャ ・Twitterバックエンドの国際化 Before 各言語ごとに独自実装。 After 共通テキスト処理ライブラリ:Penguin ・アーキテクチャ:検索 Firehose → ingester → Earlybird ⇔ Blender ← ユーザの検索 Firehose:ツイートの受信 ingester:ツイート解析 Earlybird:Luceneベースのインデクサ Blender: ・アーキテクチャ:トレンド TrendsはGeo(ユーザ位置情報)を利用してるっぽい。 Term Statisticsは過去ツイートからHadoopで頻出フレーズを解析する。 今頻出しているフレーズ+過去頻出しているフレーズ ◯日本語関連 ・ツイートの言語判定 言語判定にはIndigenous Tweets(Kevin Scannell)をベースに実装。 50言語サポート、Javaで実装 ・文字種チェック ・エンコーディングチェック ・Ngram(the→英語、das→ドイツ語) 問題点: 2つ以上の言語が混じってる場合 絵文字が入ってる場合 Unicodeアルファベット ・形態素解析 日本語:Gomoku 中国語:LuceneのSmartCN その他:N-Gram 問題点: 形態素が小さすぎる →そのままだと細かすぎるので品詞情報を元に大きめに区切るようにしている iPhone4Sなどが数字で区切られる →ASCIIの数字とアルファベットは連結しなおす ・フレーズ抽出 他の言語もあったけど、キー入力間に合わず 日本語の場合: トークンに分割 トークンでNgramを生成 品詞情報を使ってフィルター 最初、最後が助詞はNG、接頭詞で終わるのはNG ・やりたい事はまだまだたくさん ・形態素解析の品質向上 辞書への単語追加 韓国語、タイ語のトークなイザー ・同義語、類義語、翻訳、音訳、略語などのサポート ・フレーズ・トピックのクラスタリング ・Sentiment Analysis ・日本語のできるエンジニア募集中w QA Q:顔文字を手動で抜き出すと言われたんですが、どのくらいあるんでしょうか? A:正規表現なので、なんとも言えませんが、パターンを Q:Gomokuの選択の理由は? A:Javaだから。jarに辞書が入るから。スピードが出るから。 ◎ランチタイム共有サービス「昼会(http://www.hirukai.jp/)」のご紹介 @setomits\n◯前提 ・ネットワーキングは重要 ・出会いも重要 ・飲み会だとコスパが悪い ◯ランチだと ・金額が限られる ・必ず食べる ということで、昼会だ! ◯画面でサービスの説明 パブリックな昼会、プライベートな昼会がある。 ◯なんでTwitter? LinkedInのOAuthを使ったログイン検討してた。 ビジネス目的+ 敷居が高いのでTwitterに変更 ◯Twitterのapiで利用しているものなど ◯ユーザの声 ・DMを使ってる=自分からのDMが気持ち悪い APIの使用制限やフォローしてもらう必要があるのが辛い。 - スパムかと思った - 乗っ取られたかと思った。 - エンジニアからは、「まぁ、こうするよね」 ・OAuthについて - ユーザ登録しなくていいのは嬉しい - イベント参加のためにOAuthでの書き込み権限まで与えたくない ◯8ヶ月経って ・新しい出会いがあった ・昼会を開催する敷居が高い =なかなか使ってもらえない ◯今後の計画 募集中! QA Q:AppEngineで月額どのくらい? A:料金改定前:数千円/1ヶ月、料金改定後:2万円くらい/1ヶ月 処理数を減らして、現時点では数千円/1ヶ月に最適化した Q:夜会はないんですか? A:設計していたら、出会い系サイト?になりそうなので、昼にした。 ドメイン的になぁ。まだ悩み中 Q:GAE特化したもの?AWSに移行できる作り? A:できない作りです。(pythonで書いてます。) GAEが楽なので、移行可能な作りにするのがつらい。 ◎LT ◯Twitter 4 contact @inda_re ・広告!アジャイルサムライの道場\n・問い合わせフォームをTwitterにしちゃう 今あるHTMLにフォームを入れる方法(MySQLとPHP) githubにサンプルあるよ。 ◯PerlのTwitterモジュールについて @xtetsuji\n・前回出席したら、ムチャぶりが! ・いまどきのPerl 進化してるよ、古い情報が検索で出てきてしまうのがネック ・perlbrewってのがある http://perlbrew.pl/ ・AnyEvent::Twitter::Streamをよく使ってます。 ・gistにサンプルあげてあるよ! ◯KotlinでもTwitter4J @ngsw_taro ・Kotlinの説明 ・以下のサイトでインストールしなくても動かせるよ! http://kotlin-demo.jetbrains.com/ ・NULL安全 Nullを許容する型、許容しない型がある。 ・一応、Twitter4Jのサンプルも作ったけど、ブログ見てね http://d.hatena.ne.jp/ngsw_taro/\n◯締め Twitter API勉強会ではスピーカーを常に募集中です。登録はこちら!\n","date":1332343680,"dir":"post/2012/","id":"16b3c9445539e9274282a612dea354c2","lang":"ja","lastmod":1332343680,"permalink":"https://blog.johtani.info/blog/2012/03/22/%E7%AC%AC5%E5%9B%9E-twitter-api%E5%8B%89%E5%BC%B7%E4%BC%9A--%E6%B8%8B%E8%B0%B7--twtr_hack/","publishdate":"2012-03-22T00:28:00+09:00","summary":"はい。またまた、Twitter API勉強会に参加してきました。(今回から開催回数の記載がなくなった?) 今回は直前でタイムテーブルが変わってし","tags":["勉強会"],"title":"第5回 Twitter API勉強会 @渋谷 #twtr_hack(Jugemより移植)"},{"contents":"TLで面白いと見かけて、Amazonで買ってしまいました。 SEやってるのに、つい最近Amazonを使い始めた軟弱者です。 それにしてもAmazon危険です。スマートフォンにAmazonの Androidアプリを入れたのですが、これがまた、レコメンドに面白そうな本が出てきて危険です。\n話がそれてしまいましたが、面白い本でした。 久々に、小説でも技術書でもない本を短期間で読みました。 「箱」と呼ばれる概念の中と外について、とある会社に転職した管理職の人が学んでいくという物語風の作りです。 いくつか、自分の経験にカブるシーンがあったので、サクサク読めました。 今までの自分になかった考えである「箱」という視点が得られたのがよかったです。\nただ、いくつか気になる点もあるので、また少し時間を開けてからサラっと流し読みしたいと思います。\nあと、すこしだけ、キリスト教チックな考え方でもあるかなぁと思う部分もありました。(キリスト教をちゃんと勉強してるわけではないので認識が間違ってるかもしれないです)\n人によっては共感出来なかったり、読みにくかったりすると思いますが、私は面白いと思った本でした。 なんとなく、人間関係に違和感を感じていることがある場合は目を通してみるといいかもしれません。\nTwitterで読み終えたというツイートをしたら、「自分を変える気づきの瞑想法」を読むとまた面白いですという@ツイート(これがmentionの日本語の正式名称らしい?)を@ledsunいただきました。 箱に入る原理が別の視点で書かれているようです。 読んでみたいです。(本会過ぎてる気がするので、図書館で探そうかなぁ。。。)\n自分を変える気づきの瞑想法【増補改訂版】 自分を変える気づきの瞑想法【増補改訂版】 ","date":1332253920,"dir":"post/2012/","id":"ee623aaa99b429863f89da313fffed97","lang":"ja","lastmod":1332253920,"permalink":"https://blog.johtani.info/blog/2012/03/20/%E8%87%AA%E5%88%86%E3%81%AE%E5%B0%8F%E3%81%95%E3%81%AA%E7%AE%B1%E3%81%8B%E3%82%89%E8%84%B1%E5%87%BA%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%E3%82%92%E8%AA%AD%E3%81%BF%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-03-20T23:32:00+09:00","summary":"TLで面白いと見かけて、Amazonで買ってしまいました。 SEやってるのに、つい最近Amazonを使い始めた軟弱者です。 それにしてもAmaz","tags":["読書"],"title":"「自分の小さな「箱」から脱出する方法」を読みました。(Jugemより移植)"},{"contents":"えーと、ブログ更新してないなぁとふと思ったので。 1年前くらいからずーっと、つぶやいてましたが、やっとScalaを始めました。 長かった。。。 とある、サンプルデータを作成するので、ついでにScalaを勉強してしまえという感じで始めました。\nScalaで学ぶ関数脳入門を買ってもう1年以上経ってました。。。 とりあえず、CSVデータからInsert文を作ってます。 書籍を見ながら、四苦八苦してるところです。 今日は、csvファイルを読み込んで適当に出力した所で終了でした。 現状を忘れないようにというのと、いくつか気になった点があったので、備忘録のため上げておきます。\nscala IDE for Eclipseを利用(もっさりしてる) classとは別にobjectというものがある点に慣れない セミコロンいらないのに、ついつい打ってしまう usingを利用しようとしたが、Eclipseに怒られた(なんで?) メソッドの戻り値を省略出来る場合とできない場合がよくわかってない Javaが混ざる(ファイル出力にBufferedWriterを使う)のがまた戸惑う ということで、四苦八苦してますw 7つの言語、7つの世界も参考にしつつ、コップ本をパラパラしながら、ググって書くといった感じです。 Javaだととっくにできていると思うのですが、まだ、読み込んで出力できただけです。\n新しいものに触れるのは頭を使って面白いのですが、思い通りに行かず(とくにIDEがもっさりしてたり、上手く使えなかったり)イライラもしていますw まぁ、ちょっとずつ勉強していきます。\n(ほかにもいろいろやらないとなぁ。。。)\nScalaスケーラブルプログラミング第2版 Scalaスケーラブルプログラミング第2版 ","date":1331652421,"dir":"post/2012/","id":"116c9be6d760b4befa6d51ce9e96604c","lang":"ja","lastmod":1331652421,"permalink":"https://blog.johtani.info/blog/2012/03/14/scala%E5%A7%8B%E3%82%81%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-03-14T00:27:01+09:00","summary":"えーと、ブログ更新してないなぁとふと思ったので。 1年前くらいからずーっと、つぶやいてましたが、やっとScalaを始めました。 長かった。。。 と","tags":["Scala"],"title":"Scala始めました(Jugemより移植)"},{"contents":"森ビルに行ったことなかったので、参加してみました。 あと、最近まともにコーディングしてないので、そのへんを矯正するためにもと思って。 (まぁ、遊びに行きたかっただけなんですけどね)\nすこし遅刻して参加です。 会場は、Twitter Japanさんの@yakitoriでした。ここだけ、撮影可でした。 で、肝心のハッカソンの中身です(ハッカソン自体、初参加!)。 Twitter APIもTwitter4Jも触ったことがありません。 なので、ソファーに座ってMac Book AirでTwitter4Jのサンプルを眺めながら、とりあえず、Solrに流しこむってのを作ってみました。 今回、Solrに用意したのはlucene-gosenによる形態素解析を行うフィールドとあとは、Solrのexampleについてるダイナミックフィールドたちです。 Twitter4Jからどんなデータが取れるかわからないので、ダイナミックフィールドで型だけ指定してSolrを起動しておきます。 次に、Twitter4Jにあるsample()にてパブリックなツイートの1%を取得(適当なのがこれくらいしか思い浮かばなかったから)。 あとは、SolrJのStreamingUpdateSolrServerを利用して、流し込みです。 あんまり時間がなかった(準備とかウォーミングアップで時間かかった)ので、結局、Screan名とツイート本文を SolrInputDocumentに無理やり詰め込んで登録しただけでした。 ほかにも色々と情報が取れるはずなので、そのへんも格納してファセットとかで遊びたかったなぁ。 とまぁ、こんな感じでタイムアップです。(コードは大したことないので文章だけでw) 画面も用意出来なかったので、発表はSolrのダサい管理画面で検索でした。 次回は、もう少し中身を勉強して画面もbootstrapで作ってとかやってみたいですね。 あと、自己紹介スライドに書きましたが、Scalaから使ってみるのもやってみたいです。(その前に、Scalaに入門しないといけないんですけど。。。)\nということで、個人的にいろいろと反省点があるハッカソンでした。 反省点:\n立ち上がりに時間がかかった(普段からコーディングしてないから) Twitter4Jについて事前に勉強してない(ごめんなさい) 環境面が整備しきれてない Twitter API ポケットリファレンス(右の本)を忘れた。。。 スターウォーズのピザの箱の写真取り忘れた>< 普段、コーディングをしていない仇が出てしまいました。 もっと、すぐにコーディングをできる環境、体質を日頃から鍛えておかないといけないなぁと。 (SolrやTwitter4JのJavaDocをオロオロしながら探すとか情けないです。。。)\n場所や雰囲気は全然問題ありませんでした。 ピザを@yusukeyさんからごちそうになったり、飲み物、お菓子が用意されていたりと至れり尽くせりでした。 iPadで音楽も流してくれてたし。 他のハッカソンに参加したことないので比較はできないですが、集中できてよかったです。 あと、ソファーでコーディングもなかなかいいなぁと実感出来ました。(初めて!) 人数的にもこのくらいのほうが話がしやすくていいかなぁと。発表も時間かからないですし。 ただ、帰り道に誰かが言っていましたが、「マラソンというよりは短距離走だったね」というのは否めないかなぁと。 時間は限られちゃうので、準備をしっかりしないとなぁと。 私としては、土日のハッカソンだと参加しづらいので、平日開催がうれしいのですが。 いやぁ、楽しかったです。みなさんの面白いネタも見れたし。(自分のやったのは普通すぎて少し恥ずかしかったです。。。) あと、GoogleDocsの使い方(自己紹介スライドとかアンケートの集計とか)も学べたのが収穫でした。 @yusukeyありがとうございます! 次回もありそうなので、懲りずに参加しようかな。\nさて、他の方たちのブログやtogetterは@yusukeyさんのページからたどってくださいw。 第0回Twitterハッカソンを開催しました #twtr_hack\n今日購入したCD聴きながらブログ書いてます。 タワレコで視聴して購入したCDです。 なかなか大人な雰囲気でオススメです。 Heaven ","date":1331230200,"dir":"post/2012/","id":"4d6c95b0b3ea2ddb30fdd3edf3b82391","lang":"ja","lastmod":1331230200,"permalink":"https://blog.johtani.info/blog/2012/03/09/%E7%AC%AC0%E5%9B%9E-twitter-hack--twtr_hack-%E3%81%AB%E9%81%8A%E3%81%B3%E3%81%AB%E8%A1%8C%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-03-09T03:10:00+09:00","summary":"森ビルに行ったことなかったので、参加してみました。 あと、最近まともにコーディングしてないので、そのへんを矯正するためにもと思って。 (まぁ、遊","tags":["勉強会"],"title":"第0回 Twitter Hack #twtr_hack に遊びに行きました。(Jugemより移植)"},{"contents":" Clean Coder プロフェッショナルプログラマへの道 Clean Coderを読みました。 理由はTwitterで「Clean Code」がいい本だと流れてきたためです。 「Clean Code」はまだ読んでいないのですが、クリーンなコード(メンテナンスしやすく、修正などもやりやすいコード?)を書くために必要な話が書いてあるのだと思います。(まだ妄想)\nそして、何も考えずに、「Clean Code”r”」という本が新しく出ていたので、新しい方に手を出しました。 まぁ、軽い勘違いですw(コードの構造の話などは出てこなかったです。) それほど分厚くなく、軽く読めそうだということで読み進めると軽い衝撃を受けました。 Clean Coderはプロのプログラマとして、どのような意識を持つべきか、立ち居振る舞いをするべきかなどが書かれています。 「~したい」はまず守らない約束だという話、ユニットテストを書くことはプロとして当たり前の行為だ、目的意識を明確に持つことなどなど、耳の痛いことが色々と書かれています。 これは、著者の方(パンチカードのころからコーディングをされている!)の実体験を元に、失敗した経験から導きだされているようです。 ところどころ、古くてよくわからない話やちょっとだけしっくりこない表現(ビジネス、QAといった単語)もありましたが、概ねわかりやすい話でした。\n基本的にはアジャイルなスタイルの開発を行うプログラマ(設計書に基づいてコーディングするだけの人ではない)について書かれています。 この本を読んでいて、昨年、仕事をご一緒させていただいたRubyistの方たちの開発スタイルを思い出しました。 私よりもこの本に書かれているプロに近いなぁと。 ペアプロやったり、実装方法について相談していたりと。\n勘違いでしたが、良い本に出会えて本当によかったです。 私もこの本に書かれているようなチームでのプログラミングをやりたい、またなにかコーディングをしたいという気にさせてくれました。(「~したい」じゃダメって書いてあったのに。。。) 自分を戒めるためにも、定期的に読み返したい本です。 プログラマでいたい方、ある程度プログラミングができるようになってきた方にはぜひ読んでいただきたい本です。 (この流れで、アジャイルサムライやClean Codeを読んだら理解が深まりそうだなぁ)\n参考URL: 35歳定年説をブチ破れ!「Clean Coder プロフェッショナルプログラマへの道 Robert C. Martin」 - ledsunの日記 ","date":1330704840,"dir":"post/2012/","id":"10eb415a232ad4be7d05c57eb850036c","lang":"ja","lastmod":1330704840,"permalink":"https://blog.johtani.info/blog/2012/03/03/clean-coder%E3%82%92%E8%AA%AD%E3%82%93%E3%81%A0/","publishdate":"2012-03-03T01:14:00+09:00","summary":"Clean Coder プロフェッショナルプログラマへの道 Clean Coderを読みました。 理由はTwitterで「Clean Code」がいい本だと流れてきたためです。","tags":["読書"],"title":"Clean Coderを読んだ(Jugemより移植)"},{"contents":" 親子で楽しめる 絵本で英語をはじめる本 Twitterでこの本について書かれたブログ記事が流れてきて、購入しました。\n最近、英語を身につけておいたほうがいいなと思うことが多々あり、子供にも英語を勉強してもらいたいなと思っていたところでした。 あとは、私自身が英語が苦手というのもあり、子供をダシにして勉強したいというのもありまして。。。 サラっと読んでみましたが、参考になりました。 特に「多読」というキーワードが面白かったです。こちらが元のようですが。 多読とは、文章を分析しないで大意を把握する読書法だそうです。\n辞書を引かずに楽しめるものを読む わかるところをつなげて読む 自分が面白いと思う本を選んで読む という原則があるようで、確かにいいなと思いました。 絵本だと絵が書かれているので、辞書を引かなくても想像できそうですし、楽しめそうだなぁと。 また、多読は先日読んだ、速読の本に書かれていた本の読み方にも通じるものがあるなと。(まだ、実践できてないんですけどね)\nどうしても英語を勉強させたい!、勉強しないと!と思ってしまいがちですが、この本にも書いてあるように楽に楽しんでやったほうがやっぱいいなぁと。 楽しくないと続かないですからねぇ(実際、何度も挫折してるし、押し付けられるとヤル気がなくなるので。。。)\nということで、実践してみようと思います。(平日は子供が寝てしまってから帰宅なので、まずは土日から)子供のためというよりは、自分の英語の勉強のために。 まずは、簡単な絵本を購入して。 この本の後半半分は、著者の方の感想や説明がついた、オススメの絵本50冊が書かれています。 英語の絵本を入手するのは、結構大変(実際に売ってる店もなかなかないし、手にとって見る機会も少ない)だと思うのですごく参考になりそうです。 いくつかピックアップして、あわよくば本屋で手にとってみようかと。なければ、Amazonで購入しようかなぁと思ってる所です。\n","date":1330186800,"dir":"post/2012/","id":"627a0c45dd07150343c81d856855590e","lang":"ja","lastmod":1330186800,"permalink":"https://blog.johtani.info/blog/2012/02/26/%E8%A6%AA%E5%AD%90%E3%81%A7%E6%A5%BD%E3%81%97%E3%82%81%E3%82%8B-%E7%B5%B5%E6%9C%AC%E3%81%A7%E8%8B%B1%E8%AA%9E%E3%82%92%E3%81%AF%E3%81%98%E3%82%81%E3%82%8B%E6%9C%AC/","publishdate":"2012-02-26T01:20:00+09:00","summary":"親子で楽しめる 絵本で英語をはじめる本 Twitterでこの本について書かれたブログ記事が流れてきて、購入しました。 最近、英語を身につけておいた","tags":["読書"],"title":"親子で楽しめる 絵本で英語をはじめる本(Jugemより移植)"},{"contents":"今週も勉強会に参加しました。 @yusukey さんが開催してるTwitter API勉強会です。 前回とは会場が異なりましたが、広くて大画面で良い会場でした。駅も近いし。(デジタルハリウッドさいこー!) 今回はLT枠のbootstrapの話が聞きたくて参加しました。(ムチャぶり駆動勉強会の現場をTLで目撃してたのでw) あと、バーチャファイター(昔、VF目当てでセガサターンを買ったなぁ、懐かしい)の話も聞きたかったので。 (ごめんなさい、Twitter APIはまだ触る機会がなさそうです。。。) 今回も途中で参加者同士を数グループ(座席が近い人)に分けて自己紹介タイムがあり素敵でした。 ちょっと残念だったのはネームプレートが今回はなかったことでしょうか。 自己紹介でツイッターID教える+聞くのがちょっと辛かったです。(やっぱり個人名刺作ったほうがいいかなぁ) 私はPCを開いていたのでTwitterのページを見せることで対応出来ましたが。 (次やるときはお手伝いするのでこえかけてください。)\n内容はメモをとってあり、下に書いてますので見ていただければ。\nTwitter APIの説明はいろいろ新鮮でした。今回はWebページに貼るリンクやボタンの話でした。 カスタマイズも出来るようになってるってのは知りませんでした。Webサイトやってる人は簡単にカスタマイズできるのは便利ですよね。\nバーチャファイターのTwitter連携の話は結構詳細な話が出てきてびっくりでした。(テーブル名とかまで出てきましたw) ゲーム筐体の前のユーザの動きまで考えてシステム作るとかすごいなぁとか。違う業界の話って面白いです。\nBootstrap入門はbootstrapの紹介だけじゃなく、Tips(bootstrap弊害とかw)やその他の便利なサイトの紹介までありました。 スライドもあとから読んでもわかるのがすごく嬉しいです。時間を見て試してみます。 TwitterSphereは懇親会でもデモが見れました。Groovyは名前を知ってるだけだったのですが、Swingとかまで動くんですね。(JVMだから当たり前なんだけどなんか新鮮。) 最後はAndroidのAPI Demoのお話。こちらも普段Android携帯使ってるのに知らないことが多くて。。。 Macでもデモが動くんですね。やっぱり動くものを作ってLTするのって素晴らしいですねぇ(なんか作るかー)\nとまぁ、最近はキーワードだけ知ってて、いろいろ触れてもいないものが多いなぁと思ってたところに、 今日の勉強会で色々見れて面白かったです。 Twitterがいろんな人に興味を持たれているのがわかります。 (けど、Twitterってどうやって儲かってるんだろう???) 懇親会は、入り口からは想像できない貸パーティースペースで素敵でした。 開始の乾杯の音頭を取ることもできましたし(もちろん、ムチャぶり)。 学生が多かったのですが、声をかける暇なく懇親会が終わってしまったのが少し心残りですかねぇ。 毛色が違うメンバーが居て面白いので、次回も空きがあれば参加しようと思います。 スタッフとかお手伝いもしますので。\nということで、いつものメモです。\n開催日時:2012/02/23 19:00 ~ 21:00 場所:デジタルハリウッド東京本校 1Fセミナールーム Zusaarのページはこちら。他にも学生枠とかありました。\n◯ Webサイト向けAPI @yusukey\n・Webサイト向けAPI フォローボタン、ツイートボタン、Web Intents、@Anywhere サーバサイドの実装扶養、htmlのみで構成可能 ・Twitterボタン Twitterのサイトで色々カスタマイズ可能なボタンが作れます。 ツイートのカウント表示とか。 ・Web Intents @ツイート、リツイート、お気に入りが簡単にできるものが作成可能。 ツイートの埋め込み用リンクがTwitterのWeb版のツイート詳細から生成可能。 「このツイートをサイトに埋め込む」リンクをクリックするとダイアログが出てきます。 ・@Anywhere あんまりフォローされてないけど、JavaScriptでサーバサイドなしにTwitterと連携可能。 ユーザIDを辞書的に検知してTwitterの情報をホバーで出してくれる。 ・ウィジェット(検索、プロフィール、お気に入り、リストなど) これもTwitterサイトでカスタマイズ可能。 ・ツイートボタンには公式ロゴを利用しましょう ・注意点 charsetを必ず指定しましょう。 IE/Firefoxで問題が発生します。 ◯ グルーブに分かれて簡単に自己紹介\n◯ デジタルハリウッドよりご挨拶\n◯ 「Virtua Fighter5 Final ShowdownのTwitter連動機能について」@twtrfk\n部内にAmitterというSNSを構築して自由に使ってもらって、Twitterを疑似体験してもらった。 VF5FSでの開発中はTwitter4JにAmitterのラッパーを追加してテストしてたらしい。(おもしろいなー) 当時は、筐体にツイート機能を入れることも考えていたらしい。 ツイート自体はバッチで処理してます。 ゲーム筐体にお客さんが座ってる時間もシステムの性能として考慮しないといけない。 苦労した点: テストアカウントを100個地道に作成(連番、内容がバレるアカウント名はNGだから) Twitter4Jがうまく動かなかった。。。 今後の展開: まだ未定 QA Q:FB連携とかは? A:今は考えてないです。 ◯ LT ・ @making「Twitter Bootstrap入門」 スライドはこちら\n・Bootstrapとは? Twtter者が提供するWebアプリケーションのフロントエンド 一般的にCSSフレームワークと呼ばれるもの 簡単にかっこいいデザインにするための枠組み ダウンロードしてきてHTMLで読み込むだけ。 ・Bootstrapのコンポーネント紹介 いろいろおしゃれなコンポーネントあるよ。(スライド見ましょう) ・Tips examplesがあるので、それをベースに作るのが簡単です! Initializrも対応してて、こっちで作るのもいいよ! bootstrap簡単すぎて、みんな同じデザインのサイトに(弊害) 差別化のサービスが出てきてます。 ・ @kimukou_26 「TwitterSphere of Twitter4J」\nGriffon? codehausで作られてるGroovy製のMVCイメージのGUIフレームワーク codehausはJetty作ってるとこですね 地球儀にツイートを乗っけることができるアプリ。 Groovyの記述がちょっと新鮮。 ・ @bina1204 「ApiDemos of Twitter4J for Android」\nAPI DemosというAndroidのデモがあり、ここにTwitter4Jを仕込んでみた? Android系は持ってるのに知らない。。。 ","date":1330015800,"dir":"post/2012/","id":"966fe8d32b86121f8a465a21b95f7e5c","lang":"ja","lastmod":1330015800,"permalink":"https://blog.johtani.info/blog/2012/02/24/%E7%AC%AC4%E5%9B%9E-twitter-api%E5%8B%89%E5%BC%B7%E4%BC%9A--%E3%83%87%E3%82%B8%E3%82%BF%E3%83%AB%E3%83%8F%E3%83%AA%E3%82%A6%E3%83%83%E3%83%89--twtr_hack-%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-02-24T01:50:00+09:00","summary":"今週も勉強会に参加しました。 @yusukey さんが開催してるTwitter API勉強会です。 前回とは会場が異なりましたが、広くて大画面で良い会場でした。駅","tags":["勉強会"],"title":"第4回 Twitter API勉強会 @デジタルハリウッド #twtr_hack に参加しました。(Jugemより移植)"},{"contents":"久々にlucene-gosenの話です。 しかも、あんまり嬉しくない話しです。\nすでにissueをアップしていますが、lucene-gosenとSynonymFilterを併用する場合に、特定の条件下でNullPointerExceptionが発生してしまいます。\n条件は以下の組み合わせになります。\nSolr 3.5.0以前 lucene-gosen1.2.0 - 1.2.1の辞書なしjar SynonymFilterFactoryにてtokenizerFactoryを指定 根本的にはSolr側の問題のようです。SOLR-2909としてissueが上がっています。\nSynonymFilterFactoryでは、類義語の設定ファイルの単語を読み込むときにtokenizerFactoryを指定できます。 このとき、SynonymFilterFactory内部でtokenizerFactoryに指定されたFactoryのクラスが読み込まれ、 インスタンス化されて、Tokenizerが作成されます。 この、Tokenizerのインスタンス化の処理シーケンスに問題があります。 schema.xmlの\u0026lt;tokenizer\u0026gt;タグで指定されたTokenizerFactoryでは、ResourceLoaderAwareインタフェースのinform(ResourceLoader loader)メソッドが実行されます。 このinform()メソッドがSynonymFilterFactoryのToeknizerのインスタンス化の場合に実行されません。 lucene-gosenのJapaneseTokenizerFactoryではこのinform()メソッドでdictionaryDirのパスの読み込みを行なっています。(このへん)\n上記の条件では、NullPointerExceptionが発生すると書きました。 辞書を内包したjarファイルを利用している場合、NullPointerExceptionが発生しなくても次のような問題点があります。こちらの問題は見た目は動いているように見えてしまうので注意が必要です。 すべて、SynonymFilterを利用する時点でも問題点になります。\ncompositePOS設定が類義語辞書読み込み時に無効 dictionaryDir設定が類義語辞書読み込み時に無効(=jarに内包されている辞書で動作する) 一見動いているように見えるかもしれませんが、望んでいてる動作になっていない可能性があるので注意が必要です。\n解決策(まだ途中) 先程書きましたが、基本的にはSolr側の修正をするのが妥当です。 SolrのJIRAにパッチもアップされました。 こちらのパッチをSolrに適用し、SynonymFilterFactoryを次のように指定することで問題を回避することが可能になります。\n\u0026lt;tokenizer class=\u0026#34;solr.JapaneseTokenizerFactory\u0026#34; compositePOS=\u0026#34;compositePOS.txt\u0026#34; dictionaryDir=\u0026#34;dictionary/naist-chasen\u0026#34;/\u0026amp;gt; ... \u0026lt;filter class=\u0026#34;solr.SynonymFilterFactory\u0026#34; synonyms=\u0026#34;synonyms.txt\u0026#34; ignoreCase=\u0026#34;true\u0026#34; expand=\u0026#34;true\u0026#34; tokenizerFactory=\u0026#34;solr.JapaneseTokenizerFactory\u0026#34; **compositePOS=\u0026#34;compositePOS.txt\u0026#34; dictionaryDir=\u0026#34;dictionary/naist-chasen\u0026#34;**/\u0026amp;gt; ... SynonymFilterFactoryの設定にcompositePOS、dictionaryDirを追加します。 ここの設定は\u0026lt;tokenizer\u0026gt;タグで指定された設定と同じ物を指定します。以上で問題なく動作することになります。\nただし、この方法はSolrにパッチを当てなければいけません。 Solrにパッチを当てるのもなかなかな作業だと思います。 ということで、どうにかlucene-gosen側だけでも対応出来る形にしたいなぁと考えているところです。 残念ながら、まだ考えているだけですので、もう少し提供できるのは先になってしまいますが。。。 現時点では、次の方法を考え中です。\ninformメソッドを呼ぶフラグを追加して、どうにかしてinformメソッドを呼び出す SynonymFilterの修正版をlucene-gosenに内包して提供する できれば、a.にて対応できればと思っています。 最悪、b.の方法かと。 悩んでいる間にSolrの次のバージョンが出てしまわないように出来るだけ早く対応しようと思っています。 他にも問題点や気になる点があれば、日本語、英語を問わないので、気兼ねなくissueに上げてもらうか、Twitterで私宛にメンションしてもらえればと。 (あ、issue23へのパッチでもいいですよ!)\n追記: まだ、SOLR-2909のパッチを適用してからの確認はできていません。(ソース見て大丈夫だと思ってるレベル) あと、現時点での対応方法としては、「lucene-gosenとは別のjarにSynonymFilterFactoryなどを入れて提供」が妥当かなぁと考えているところです。(無理やりinformメソッド呼び出すのは骨が折れそう+パッチが思いの外早く出て、導入されたのでlucene-gosen本体に特殊処理を入れるのはあまりメリットを感じない。)\n","date":1329756060,"dir":"post/2012/","id":"4e7b945feca199bd486653fea1d0e39c","lang":"ja","lastmod":1329756060,"permalink":"https://blog.johtani.info/blog/2012/02/21/lucene-gosen%E3%81%A8synonymfilter%E3%82%92%E5%88%A9%E7%94%A8%E3%81%99%E3%82%8B%E3%81%A8%E3%81%8D%E3%81%AE%E6%B3%A8%E6%84%8F%E7%82%B9%E5%95%8F%E9%A1%8C%E7%82%B9%E7%B7%A8/","publishdate":"2012-02-21T01:41:00+09:00","summary":"久々にlucene-gosenの話です。 しかも、あんまり嬉しくない話しです。 すでにissueをアップしていますが、lucene-gosenと","tags":["lucene-gosen"],"title":"lucene-gosenとSynonymFilterを利用するときの注意点(問題点編)(Jugemより移植)"},{"contents":"また、勉強会ログです、すみません。。。 直接業務とは関係ないのですが、今回はリクルートの中野さんが話しをされるというので顔を出してきました。 もちろん、内容も気になりましたというのもありますが。 実際には中野さんは2分くらいしか喋らなかったんですけどね。。。\n今回は、最初のセッションはちゃんとしたソースコードリーディングでした。 Hadoopの入力としてデータをHDFSじゃなくて、MongoDBから取得するときに利用するMultipleInputの実装をしてみたというお話でした。 MongoDBやHadoopを知らないと(私はあんまり知らない。。。)少しきつかったかもしれないです。 幸い、HadoopのMultipleInputについては以前、すこしだけ見たことがあったので、かろうじてついていけました。 最初の部分を聞きのがしてしまったので合っているか自信がないのですが、10genから出ているmongo-hadoopの使い勝手、効率の悪そうなところに手を入れた話しがベースになっているんでしょうか?(ツッコミあるとうれしいです) 気になったのは、MongoDBのデータをHadoopから直接取りに行くというユースケースがどういう場合に出てくるのかという点です。 ネットワークやMongoDBの負荷がHadoop処理へのボトルネックになるんじゃないかしらという懸念がありそうだなと。 発表を聞いていて感じたのは、やっぱりソース書いて動かさないとダメだよねぇ、自分も手を動かそうというところです。 リクルートさんの発表は波乱万丈(?)でした。 最後まで話しを聴いたあとに思った感想は「こんなに話して大丈夫なのかな?」「いろんな人を敵に回してない?」というものです。 実際に昨年の夏くらいからEMCの草薙さんも検証メンバーに入って、リクルート社内での活用シーンをベースにMapRの検証をいろんな項目でやられたようです。(ある程度の詳細は以下のメモ参照) で、最終的な結論はまだ出ていないのですが、最後に出てきた検討中の比較対象が某C社のCDH。 どちらかというとCDHの方に傾いてる感じに取れる終わり方で心配になりました。。。 会場が会場だからというのもあったのかなぁ? mesosというキーワードが出てきたのが気になりました。単語だけは以前Twitterで流れてきたのを目にしてたのですが、どんなものかという概要がわかったのは収穫でした。 リクルートさんの資料はどこまで公開されるかわからないですが、もう一度見たい気がします。(mesosの部分だけでも公開して欲しい)\nということで、以下はいつもの自分用メモです。\n日時: 2012年2月8日(水) 19:00~21:30 (受付開始 18:40) 場所: 豊洲センタービルアネックス(NTTデータ、豊洲駅直通)\n◎日本OSS貢献者賞・奨励賞のご案内 @hamaken 日本OSS貢献者賞・奨励賞\n◎『オレオレMultipleInputを作る方法(仮)』@muddydixon さん http://www.slideshare.net/muddydixon/multipleinput\nhadoopからMongoDBを利用する方法を紹介 CDH3u2かu3で試しました。 10genからも出てるけど使いにくい?から作った? MongoMultipleInputs.addInputPath で色々簡単に使えるようにしたかった。 絞り込みしてデータをMapperにとり込みたかったため。 =絞り込みできないと必要なデータ以外も取得できてしまいJSONのパース処理がオーバヘッドになるから。 com.mongodb.hadoop.input.DelegatingInputFormat mongodbの環境にあわせて多くのsplitを生成する。 mongosへのアクセスはメタ情報の取り出しだけ。 あとは、個々のサーバにアクセスしてるのでデータ取り出しが高速? ◎『MapRってどうよ? - 実際に使ってみた感触を紹介します』 - リクルート 中野さん、高林さん、大坪さん\nMapRの説明資料がなかったので、EMCの草薙さんが出てきて説明を開始。 Greenplum MRはMapRテクノロジが開発した実装のOEM版。 EMCは特に手を加えず。 ※MapRについては前回のMapR勉強会の記事を御覧くださいな。 Q:JavaのAPI互換と言われている部分はHadoopのどのバージョン? A:CDH3u2に近いパッチが当たってるらしい。 Q:DFSIO性能の比較対象のHadoopはどのバージョン? A:手元に資料は残念ながらないです。 ここからリクルートさん。 検証内容:性能検証 中古車サイトで利用されている3つのHiveに置き換えてみた。 結果(パーティション圧縮) MapRのほうが約1.3倍高速に(そこまで速くならなかった?) 結果(非パーティション圧縮) MapRのほうが約1.7倍高速に(そこまで速くならなかった?) ビルドイン圧縮はGzip圧縮と比較して高速 ※チューニング次第では結果変わるかもね。 機能検証:マルチテナント検証 目的: 複数ユーザに対して1つのクラスタを提供する セキュリティの担保() 余剰リソースの有効活用 複数ユーザのJobの並列実行? 結果1(ユーザ権限まわり) MapRのユーザはLinuxユーザに準拠。 同じmaprユーザでもUIDがずれてるとエラーが起きる。 MapR内のPermissionは内部のクラスタ、ボリュームの権限定義が可能 ※Volumeは管理者に付加的な情報を与えるような存在 Job実行はHadoopと一緒のアクセス権。 結果2(FairScheduler) MapRではデフォルトとなっている。 複数テナントからの同時ジョブ実行の動作を確認。 poolをベースにタスクを割り当ててく。 min/max値にあわせてslotが利用される模様 結果3(Load処理(Hive)、Job実行(HiveのSelect)) じゃらんPVデータ1ヶ月分をロード。 NFS→MFS 結果4(フェイルオーバー) HA機能 ノード切り替え時間、タスクの復旧までの時間とか。 結果5(DirectNFSでの転送) NFSGatewayをクライアント側にした場合との違いなど。 クライアント側に載せた場合、通信量が減るから速度が出てる。 Mesos概要 Apache IncubatorのOSS。C++により実装 効率的なリソース分離、リソース共有機能を提供するクラスタマネージャ。 Mesosでの検証 マルチテナント(ユーザ権限)硬い。 リソース制限ができない。などなど。 MapRとMesosの比較 資料期待! リクルートとしてのMapRの評価 保守/サポート/教育が充実してるのが重要。速度だけじゃない。 けど、まだ検討中です。 Q:クラスタに対するパーミッションの権限情報はどこで管理されてるの? どこが落ちたときにそのパーミッションの情報がとれなくなる? A:CLDBで管理されてます。 Q:CLDB内部でのデータはバイナリ?DBを別途持ってる? A:HDFS上にボリュームが作られてそこに吐き出されてる。 Q:Jobのスケジュールの情報とかはどこに? A:Job管理データはJobTracker用のボリュームに保存されてる。 それを別の人が引き継ぐ。 Q:ボリュームが壊れたら? A:さすがに壊れたら引き継げない。 けど、壊れにくくしてあるのが売り? Q:MapRのチューニングのポイントはどんなものがあるの? A:チューニングに関しては256Mのchunkサイズを64Mに減らした場合の化粧しかしてない。Apache Hadoopの方は若干チューニングした。 Q:DFSのシリアライズは?ボンディングとかでもできるんじゃないの? A:そこはやってないのでやってみます。 Q:MapRでの8台構成で全部のせてみた場合、CLDBのリソースはどのくらいもっていってるの? A:結構使ってる。CLDBを3台以上にしたらサポート対象外。 Q:CLDBを3台に制限してる理由は? A:わからない。 Q:本番MapR、検証CDHというのはあり? A:M3を開発環境で利用して欲しいですね。(ステマ?)開発目的だとM5を無償提供してほしいなー(EMCへのお願い?) Q:Pigの検証は? A:リクルートではHiveを利用してたので検証してない。 次回は3月ころかなぁ?だそうです。 ","date":1328716980,"dir":"post/2012/","id":"fa16213d24273d386d22332cd01ce774","lang":"ja","lastmod":1328716980,"permalink":"https://blog.johtani.info/blog/2012/02/09/hadoop%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89%E3%83%AA%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0%E7%AC%AC8%E5%9B%9E%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-hadoopreading/","publishdate":"2012-02-09T01:03:00+09:00","summary":"また、勉強会ログです、すみません。。。 直接業務とは関係ないのですが、今回はリクルートの中野さんが話しをされるというので顔を出してきました。 も","tags":["勉強会"],"title":"Hadoopソースコードリーディング第8回に参加しました。#hadoopreading(Jugemより移植)"},{"contents":"Fluentd meetup in Japanに参加しました。いつも面白そうな話を聞いてばっかりなので、役に立つためにスタッフとしても参加してみました。 まずは、会場が綺麗でびっくりしました。しかも電源タップまで用意されていてかなり充実してました。Ustはまだ見ていないのですが、Ustも録画までされていて素晴らしい運営メンバーでした。\n開発者の古橋さんほか、Treasure Data Inc.の方たち(太田さんはいなかった)が集まり、 Fluentdの仕組みから、プラグイン開発の方法、実際にプラグイン開発してしかも本番で利用してる実例まで 「パーフェクトFluentd」という本ががそのまま書けてしまうのではというくらい密度の濃い話が聞けました。 私個人は、いつものごとく興味を持ってるんだけど、仕事、私用では触っていないという腰抜けなので話についていくのが大変でしたが。。。 各セッションごとに、しっかりとしたQA時間が取られていて、質問者も質が高く、中の人や発表者の方も誠実に回答されている感じがすごく良かったです。 (残念ながらLTの時は懇親会の準備を手伝っていたので聞けてないです) 基本はログの中継サーバとして利用するという話でした。 個人的には性能系のデータやログ(遅いクエリのログに関するプラグインの話などもあった)をストレージに保存して、時間を軸にログとグラフを表示するとかいう仕組みに使うと面白いかもなぁと感じました。 今回はFluentdがメインなので、ログを集める部分の話が主だったところでしたが、懇親会直前の@doryokujinさんのスライドでも上がっていた集計後のビジュアライゼーションに関する部分のはなしも聞いてみたいなぁと思ってるところです。\nあとは、いくつか知りたかったことが。 Treasure Data Serviceというサービスをやってるみたいで、SQLライクな問い合わせやビジュアライゼーションされた画面があるみたいな話があがっていたんですが、画面が見てみたかったです。 また、@just_do_neetさんの構想図のその後を聞いてみたいですねぇ。\nそれにしても実例も構成から性能値まで上がっていたので、実際に利用する場合に参考になる資料だらけで普及にはずみがつきそうです。 Ust録画が上がっているようなので復習したいと思います。 (あ、内容とは関係ないけど、Ust録画にハッシュタグつきのツイートを時間軸で重ねて表示するサービスとか機能ってないのかな?)\nということで、以下はいつものメモ書きです。\n2012/02/04 12:30 ~ 19:00\nフューチャーアーキテクト セミナールーム\n参考URL:http://fluentd.org\n◎13:00~14:00 「What\u0026rsquo;s Fluentd? - The missing log collector」 http://www.slideshare.net/treasure-data/fluentd-meetup-in-japan-11410514 Treasure Data, Inc. 古橋 貞之 (@frsyuki)\nまずは、Fluentdの概要。syslogdみたいなもの Fileのtailで流すことが基本。 Clientライブラリから流すことも可能。 他との比較 ScribeとFluentd 構造化されたデータを扱う gemとかapt-get,yumでインストールあg可能 Rubyで書かれてるからカスタマイズもプラグインの追加も簡単。 FluentdとFlume FlumeはZKやマスタノードが必要=セットアップが面倒 JVMだから面倒、設定も簡単。 Fluentdのアーキテクチャ Bufferプラグイン:スレッドセーフ、バッファ処理など Outputプラグイン:出力だけ out_forwardプラグイン:Cassandraと同じアルゴリズムでHeartBeatしてる out_copyプラグイン:同じ出力を別の出力先にコピー bof_fileプラグイン:バッファ先をファイルにする。Fluentdがこけても大丈夫 out_exec_filterプラグイン:外部プログラムからの入出力を使える in_tailプラグイン:ログのパーサーが内蔵されてるみたい。 開発者用API Unitテストフレームワーク(MRUnitに似てる) TailInput(パーサカスタマイズも簡単) ドキュメントとか http://fluentd.org にあります。 会社紹介! Treasure Data Service Fluentdでは出力先がいろいろできるけど、自分で解析しないといけない !ここで、Treasure Data Service(クラウド)に保存すると。。。 データのVisualizationとかがリアルタイムで出来る。 QA: Q:ログ転送にUDP使ってますか? A:TCPです。UDPはハートビートに利用してます。 Q:文字コードはどういう扱い? A:バイナリ形式であつかってます。 文字列で扱う場合はプラグインで対応しましょう。 Q:性能大丈夫? A:Twitterで議論があがって、いろいろ対応しました。 Q:TreasureDataServiceはクラウド対応だけなの? A:データはクラウド上で管理してるので上げても大丈夫なものだけが現在は対応。暗号化などは行なっている。 Q:TreasureDataServiceはどこで動いてる? A:AWS上(S3にデータ保存) Q:解析プラットフォームを提供している?SQLだけ? A:HiveのSQLで解析可能。Visualizationのツールもある。 Q:コンサルタントもあるの?ログ出力系とか。 A:あとから解析できるように。 Q:in_tailでログローテート(iノードが変わって)も大丈夫? A:大丈夫。動かなかったら連絡ください。 Q:ファイルバッファリングされるデータの順序は保証される? A:キュー形式なので、保証される。けど、S3とかだと出力先が遅いので、 パラレルモードで対応が可能。だけど、パラレルだと順序は保証されない。 Q:実際のシステムが投げるときにFluentd側で認証とかできる? A:認証はないです。推奨は同一アプリサーバでFluentdを起動。 Q:Fluentd間のデータ通信のセキュリティ対応は? A:今はない。プラグインとか作ればOK。 Q:中間層のFluentdを置くのは推奨?なしで直接ストレージ保存も可能? A:柔軟な対応(送信先、バッファリングとか)が可能にできるように中間層を置くほうがいい。直接出すことも可能。 Q:TDAgentでのセットアップが推奨?gemは? A:gemはOSS版でtrunkに近い。TDAgentはテストとかしっかりやってる。 バージョンの対応表はリリースノート見ないとわからない。 Q:Flumeのほうが優れているのは? A:設定ファイルが一元管理ができる。大規模はFlumeのほうがいいかも ただし、includeでHTTPサーバ経由で設定ファイルを取得可能な機能あり。 Q:バッファサイズは指定可能? A:可能。 Q:ストレージがずっと停止している場合にログがあふれるのを防ぎたい場合の対処法は? A:セカンダリという機能がある。(ただし、対応できてないプラグインもある) Q:フェイルオーバーでローカルファイル出力とかはできる? A:out_forwardは対応してる? Q:Fluentdからのbuf_fileに出力してる部分で遅延、書き込み不可が発生したら? A:入力と出力がスレッドで分かれてる。 入力スレッドでのエラーはinput_plugin側にException上がる ◎14:15~15:00 「Dive into Fluent Plugin」 http://www.slideshare.net/repeatedly/fluentd-meetup-dive-into-fluent-plugin Preferred Infrastructure, Inc. Masahiro Nakagawa (@repeatedly)\n好きなプラグインとか言いましょう(発表者さん) MongoDBのプラグインをベースにプラグイン開発の説明 http://bit.ly/fluentd-with-mongo プラグイン名はfluent-plugin-xxxで統一されてます。 fluent-plugin-mongoがダウンロード数が1位に! (scribeのプラグインがデイリーでテストが走ってダウンロード数が増えるという卑怯なカウント稼ぎしてたらしいw) fluentd.confの説明 fluentdの起動は以下のとおり。開発中は-vつけるといいよ fluentd -c fluentd.conf プラグインをどう作る? Fluentdの構成図による説明 Cool.io、MessagePack、Rubyなど。 それぞれの説明を簡単に。 Cool.ioがファイル監視とかをやってくれるみたい。 プラグイン開発に関する詳細な説明 テスト、gem構成などを書いてくれてる。 QA: Q:複数行のログを扱うのはどこを作ればいい?tailプラグインの正規表現だとうまく行かなかった。 A:tailをoverrideしてparserLineを実装する。複数行のparserは難しいけどね Q:ログのアグリゲーションをやってみたいのだが、どう?CPU利用率とかを1分間バッファしてからアグリゲーションして平均出すとか。 A;fluent-plugin-aggregateってのがあって、forward-pluginを書き換えて作ってる。 TimeSlicedOutputでやると時間の期間指定とかが可能。 管理画面つくろうと思ってるので手伝ってください!@repeatedly Q:fluentd自体が処理した統計データの出力とかある? A:古橋さんが頑張ります!協力して!=\u0026gt;@tagomoris先生が書いてる! ◎15:15~16:00 「fluent を使った大規模ウェブサービスのロギング」 http://www.slideshare.net/hotchpotch/20120204fluent-logging COOKPAD, Inc. 舘野 祐一 (id:secondlife, @hotchpotch)\nCOOKPADでの基盤全般を見てる部署の人 PVログ+MySQL 1日分はオンメモリにのるから高速。けど、1週間前とかになると遅くなる blackholeエンジン(MySQLの一部?)だと速い(ときどきおそくなる) データ保存でも問題 直近データしか保存できない。大きすぎて。 今後スケールしないときつくなる(1日分もメモリに載らなくなる可能性も出てくる) 他のログはMySQLへJSONでシリアライズして出力とかもしてた。 アプリでDBにログ出力はinsertのコストが厳しい。PVとかなら、1リクエスト=1insertだけど、1リクエストで多数ログ出力とかが厳しい。 そこにFluentd登場!!! 出力先が色々使える。(MySQL以外もOK) パフォーマンス バッファリング+転送をやってくれるし、非同期で処理可能なのでレスポンスタイムへの影響が最小限にできてる。 安定性 プラグインはちょっと注意が必要。 バッファリングしてくれてるので、一時的に停止もできるのがうれしい。 6時間止めてもOKだったよ(テヘッw) 今後 PV系のログをMySQLから移行検討中 具体例!! td-agentをrpmで入れてるし、Rubyまで入ってくれる。 構成管理はpuppetを利用してる。 td-agentの設定の注意点 「retry_limit 9」に変更してる。標準だと17なんだけど、2の16乗=大体1日かかる。9だと大体10分くらい 中央転送用サーバ gitで設定ファイル管理してる。 よく変更するため。 gemfileで各種fluentd/pluginを利用してる。 自分たちで手を入れたソースを利用できるようにもしたいため。 テスト時にテストが書けるのが嬉しい(Rubyで出来てるアプリからもいじりやすいし、アプリのテストでも簡単に使える) ロガーへの実装追加もできる。 Tips バッファからすぐ処理させたい場合とかの説明 こんなのあったら嬉しいな。 設定ファイルの柔軟な設定記述方式 DSLにならないかなぁ(けど、やり過ぎも厳しいし。。。) ログの重要性 統計を考えられるエンジニアが重要。 どのデータにどんな価値があってそれを仕事(お金)に結び付けられるか? QA: Q:障害対応のノウハウとか? A:nagios、muninでサーバとか監視してる。 アラートチェックもしてる。 Fluentdの安定性は2ヶ月実際に導入してみて特に問題は出てない。 Q:MongoDBの構成は? A:master/slave構成。PVログはS3に保存してEMRで処理。 Q:パフォーマンスの測定は? A:40Mbit/sが処理できてたのは見てる。あとは、後ろの発表ですごいのがある! Q:設定ミスの防止とかをどうやった? A:今回はpuppetの設定後のリロードをチェックするような仕組みを入れた。 本来なら、データが流れてるかどうかのチェックを入れるプラグインを書いて欲しいw Q:データマイニングエンジニアの定義は? A:データの価値を見いだせるエンジニア。あとは、きちんと統計学を学んできてるエンジニア。両方募集中!! Q:DynamoDBは検討は? A:西海岸でしか動かないのでデータ転送の時間がかかってしまった+RESTで1件ずつ登録なので今回は見送った。スキーマレスなのでうまく使えそう。 A2(古橋さん):バルクインポートがないので使いにくい。 Q:ログ出力の形式をFluentdにあわせて変更したとかありますか? A:もともとアプリで出力してたから特に変更なかった。 ◎16:15~17:00 「fluentをサービスで使ってみた」 http://www.slideshare.net/naverjapan/20120204fluent-public NHN Japan株式会社 Tetsuya Ohira (@just_do_neet)\n自己紹介が面白かったw 実例の話。 事例1: 社内向けのログ解析に利用 Fluentd+Hadoop データノードにFluentdで出力して、データノードからHDFSに書き込んでる。 事例2: NAVERまとめのまとめ作成者へのデータ解析 Fluentd+Hadopo+Azkaban Azkaban(個人的にはオススメできないw) flutendの負荷は全然上がってない。 監視 tcp portの監視 転送されたデータサイズのチェック。HDFS側のデータ量でチェックしてる。 なぜか半死半生の状態になった(よくわからない。) プラグインを自分で直せるので対応が楽。(Ruby力は必要だけど。) demo 準リアルタイム解析基盤の構成案(おもろそう) fluentd、MongoDB、Hadoop、Jubatus、node.js 地図にアクセス解析結果をのっけて見せる。(maptail.js?) 提案or相談: 動的に設定ファイルの内容を変更できるようにしたい log rotateのタイミングでshell実行でfluentd再起動 必要な情報だけrelayしたい フィルタープラグインみたいなものが書きたい。 fluentd自体のメトリクスを出して欲しい jubatusプラグインはー? QA: Q:log rotateへの対応はどーしてる? A:今はログローテートのタイミングでfluentd再起動してる Q:Apps側のFluentdがコケたときにaccess_logをcopyしてるらしいけど、重複しないの? A:失敗した対象のログをストレージから一旦廃棄して、再送してる。 Q:Rubyがそこまで得意じゃないのにFluentdを選んだ理由は? A:他のモノが使いにくかった+既存システムに手を入れなくて済む+タイムリーだったという理由。 Q:構成案のデータの流れは? A:MongoDB、Hadoopへは同一ログを流して、リアルタイムが重要な場合はMongoDB、大量データ回すのはHadoop? ◎17:15~18:00 「Distributed message stream processing on fluentd」 http://www.slideshare.net/tagomoris/distributed-stream-processing-on-fluentd-fluentd NHN Japan株式会社 ウェブサービス本部 Tagomori Satoshi (@tagomoris)\nsed | grep | wc がメイン。 Hiveで集計してます。 なんでFluentd?(not Storm、Kafka or Flume?) Rubyが好き(ライブドアはJavaが入ってない環境もあるし) プラグインやTimeSlicedOutputがあるのも採用理由 ログ収集の構成図 ブログに別の勉強会の資料があるので見てください。 まだ10日間しか動いてないので実績は少ない? 127サーバからのログを流してる。 7万行/sec、ピーク120Mbpsが流れてる。 89 fluentd インスタンスが12ノード(4コアHT)で動いてる。 1行のログを1行のタブ区切りで出力する(Hiveでインポートしやすいから) Apacheのログに幾つか追加したデータなどが出力されてて、それをタブ区切りにするため設定一発では変換できない。 TimeSlicedOutputが重要 時刻単位でログ出力できないとキツイ(ログの流量が半端ないから) ログローテートでは時刻単位できちんと出力されてない。 ログから解析までの流れ図 以前は生ログをHadoopに書き出してたので25分くらいのタイムラグが出てしまっていた。(ノード数が少ないという理由もあるけど、お金的に増やしたくない)+Hadoopで他のジョブが実行されてるとさらに遅くなる。。。 fluentd でログを流しながらコンバートもかけられ、Hadoopでのデータコンバートの処理遅延が少なくなってハッピーに! ストリーミング処理の重要な点 バッチでもストリーミング処理でも同じことが可能。(out_exec_filterとHadoop Streaming) SPOFがないこと トポロジ、Fluentdの構成 ログエージェント(scribeline:お手製) pythonで書かれたscribelineというものを利用してる。 フェイルオーバーの処理(primary、secondary構成)が可能 fluentdは入れてない。(ログを拾い上げて流すだけには重い) workerノード serializerノードが必要なのは出力先の競合を減らす必要があるため。 出力先が大量のアクセスに向いてない場合があるから。 あと、ログの流れを元に監視したい項目にもここで対応可能。 watcherノード deliver、serializerからのデータを見ながら監視、統計処理を行える。 設定は自動生成してる。800行くらいになっちゃうから。 workerへの分散具合をよしなにしたいから。 remove_prefix 、add_prefixでデータの流れ先の交通整理してるのか。 GrowthForecastでグラフを出力してる。 https://github.com/kazeburo/GrowthForecast QA Q:大規模環境での移行はどうやったの? A:もともと流すような仕組みはあって、流し先を変えたので それほど大変ではなかった。ただ、アプリ側で動いてた部分に手を入れたときは配備が大変だった。 Q:workerが1サーバ8の理由は? A:4コアHT=8というので8としている。 Q:deliverのカーネルパラメータをいじってたりしない? A:ライブドア標準の設定がされてる。CentOSのデフォルトでもそれほどきびしくないかな? Q:deliverノードでラウンドロビン+out_forwardになってる理由は?out_forwardだけじゃだめ? A:バッファのタイミングでの切り替えだと溢れてしまうので、最大でも1秒でラウンドロビンしてworkerを切り替える必要がある。 ※懇親会設営の手伝いのためあんまり聞けず。 ◎18:15~19:00(Plugin紹介LT)(各10分) @shun0102: 「fluent-plugin-dstatを使ったリアルタイムクラスタモニタリング」 http://www.slideshare.net/shun0102/fluent-plugindstat\n@ixixi: 「fluent-plugin-couch」 http://www.slideshare.net/ixixi/fluent-plugins-for-couchdbamazon-sqssns\n@chobi_e: 「Fluentd \u0026amp; PHP」 http://www.slideshare.net/shuheitanuma/fluentd-and-php\n@railute:「Fluent Output Plugin for Cassandra」 https://skydrive.live.com/view.aspx?cid=D105615A0F594518\u0026amp;resid=D105615A0F594518%21333\n","date":1328367780,"dir":"post/2012/","id":"a2679a7d860a0bfb2645809ed92ce138","lang":"ja","lastmod":1328367780,"permalink":"https://blog.johtani.info/blog/2012/02/05/fluentd-meetup-japan%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-02-05T00:03:00+09:00","summary":"Fluentd meetup in Japanに参加しました。いつも面白そうな話を聞いてばっかりなので、役に立つためにスタッフとしても参加してみました。 まずは、会場が綺麗","tags":["勉強会"],"title":"Fluentd Meetup Japanに参加しました。(Jugemより移植)"},{"contents":"昨年末に今年の抱負について書いたのですが、 他にも興味あるものが増えたので備忘録&公約?を兼ねてブログに書いておきます。 (興味あるものがあれば、シェアしたりできると楽しいので、ツイート、コメント待ってます。)\nZooKeeper SolrCloud SenseiDB Lucene 検索システムのアジャイル開発? まずは、ZooKeeper。このなんとも言えないアイコンでお馴染みのヤツです。 こんな顔してますが(顔関係ない。。。)、いろんな所に出没します。 Katta、Lilly、SolrCloudにも出てくるんです。SenseiDBにも出てくるんです。分散処理にことごとく絡んできます。 で、これは、知っとかないとまずそうだと。\nSolrCloud。まぁ、妥当です。一応、Solrな人なんで。 昨年、NewSolrDesignを訳してみてもいます。訳しただけでほったらかし。。。 elasticsearchとかSenseiDBとかSolrに似たLuceneを利用している検索サーバがチラホラ話題になってます。 できれば、このあたりの分散の仕組みを比較しながら調べたいなと思ってみたり。 すべてをカバーするのはキツイので、SolrCloudかSenseiDBあたりを調べていきたいなぁと。\nで、SenseiDBです。先日、Publickeyで記事が出て飛びつきました。 Zookeeper使ってるし、分散だし、全文インデックスにLucene使ってるし。 なんだか興味あること、全部入りな感じです。\nLuceneも興味津津です。 Solrがコアとして使ってますし、昨年、Solrと同時にリリースされるようになりました。 Luceneも奥が深く、時々、Solr調べててLuceneのソースも見るのですが、本格的に全体像を把握したりは残念ながらできていません。 そのくせ、Zookeeper同様、いろんな所に出没するんです、これが。 ということで、足元を固めるためにもLuceneに入門しないとなぁと。\nで、最後に検索システムのアジャイル開発です。 lucene-gosenのコミッターをやらせてもらってたり、Solrに絡んだ仕事もしてますが、長期にわたってフィードバックをもらいながら検索システムを育てていくというのが最近興味が出てきてることです。 検索システムは作ったらおしまいとは行かないのが厄介なところです。 データは増加しますし、検索されるキーワードも変わってきます。 また、検索される方法も変わってきたりもします。 ユーザが検索したいものも変化があります。 思ったように検索にヒットしない場合とユーザが離れて行ってしまいますし、検索しにくい場合も同様です。 今日、クックパッドの方の話しを聞いて思い出した次第です。(前に、Solr勉強会でも同じ話しをされて、同じ思いに至ったのですが、いかんせん忘れやすくてw) また、ログ解析の話などをTwitterで見てることもあり、検索という側面でのログ解析ってのも重要だよなぁと。 いくつか思いつくこともあるのですが、実践出来る場も限られてます。 色々と話しをする場を設けるのも面白いかもなぁと妄想してる次第です。\n取り留めもなく、現時点で気になってることを書きだして見ました。 また、数ヶ月したら気が変わってるかもしれないですが、とりあえず書き残してみます。 興味がある方がいらっしゃったら声をかけてもらえるとうれしいですね。\n","date":1327596641,"dir":"post/2012/","id":"58e83fb33c120db338132d23b9112805","lang":"ja","lastmod":1327596641,"permalink":"https://blog.johtani.info/blog/2012/01/27/%E4%BB%8A%E8%88%88%E5%91%B3%E3%81%8C%E3%81%82%E3%82%8B%E3%81%93%E3%81%A8/","publishdate":"2012-01-27T01:50:41+09:00","summary":"昨年末に今年の抱負について書いたのですが、 他にも興味あるものが増えたので備忘録&公約?を兼ねてブログに書いておきます。 (興味あるものがあれば","tags":["備忘録"],"title":"今興味があること(Jugemより移植)"},{"contents":"ということで、いつものように勉強会に参加したメモです。\nhttp://atnd.org/events/23608 日時 :2012/01/26 19:00 to 22:00 会場 :アカデミーヒルズ(六本木ヒルズ内) 49階(タワーホールA) (港区六本木6-10-1) ハッシュタグ :#mnlgy\n■タイムテーブル 司会:CROOZLabs株式会社 研究所 所長 代表取締役社長 小俣 泰明 モーションノロジーの説明があったけど、他のことしてました。すんません。 1. 発表者: 有限会社未来検索ブラジル 森 大二郎 概要:groongaの索引構築の実装 全文検索とは。歴史から 1971:full-text。。。というキーワードが。 現代の全文検索の課題はあんまり変わってない 全文検索の手法 いくつかあるけど、転置索引の説明だけ。groongaも転置索引 groongaはインデックスの動的構築が得意 静的構築も考慮してます。 2. 発表者:CROOZ株式会社 長谷川 博紀 概要:MeCabからの脱出?(仮 CROOZ MALLの解説 MySQLとMeCabでやってます。 Tritonnつかってるのか? groongaとの性能比較検証やってみました。 MeCabが問題じゃなくて、辞書ありの形態素解析が問題。 辞書にない単語もうまく検索したい 辞書に単語登録したら形態素やり直し ソート用のデータが。。。(ここはわからなかった) QA Q:MeCabの代わりとなっているものは? A:MeCabを改善してみる? 3. 発表者 : グリー株式会社 一井 崇 概要:全文検索のちょっとちがった使い方(仮) グリーでの数値指標管理 事前集計してKVSに登録してみてみる 1億パターンのキーが存在する。。。 キーがわからなくなる問題とか事前集計できてる?とか迷子になる。 キーも全文検索に入れてみては? 「富士山の標高は何メートル?」とかでデータが取れる。 構造化されたキーをkey stringとして全文検索する。 構造化Keyに対応したKVSがあればいいんだけど。 データストアとしての全文検索もいいのでは。 4. 発表者:株式会社クリアコード 須藤 功平 概要:rroongaによる検索サービスの実装 groongaとRubyの組み合わせでrroonga。Rubyによるインタフェース? groongaとのつながり部分をRubyで書いたライブラリ 多段ドリルダウン機能 絞り込みによる検索結果の比較とかに利用可能 メタデータ抽出にドリルダウンが便利 例:番組説明から出演者を抽出 サジェスト機能もある コンテンツベース すぐできる。候補の精度がいい 統計情報ベース 元データがある程度必要 候補が増えるけど、精度の問題あり 5. 発表者: 株式会社ぐるなび 塩畑 公一 概要: groongaの位置情報検索関連について。 2010年4月からgroongaを利用し始めた レストラン検索、地図検索など 円形、矩形の緯度経度検索が可能。 距離算出もやってる。ソートとか用かな。 球面近似もやってる。 geoの検索速度についてパフォーマンステストしました。 Q:近似手法をいくつもサポートされてるけど必要? A:距離計算を正確にしないと不利になるお店が出てきちゃうから 6. 発表者: クックパッド株式会社 兼山 元太 概要: Solrを使ったレシピ検索のプロトタイピング クックパッドとは? 女性多いよ AWS上でRubyで組んであるよ プロトタイピングって? ユーザの問題を発見してから、プロトタイピング 本番デプロイ(一部ユーザに公開) 問題を抱えているユーザーに向けてそれぞれ数十のバージョンが動いている インタビューとかしてフィードバック受ける。 本番の検索エンジンのフィールドをいっぱい追加 Solrの紹介(MySQL(Tritonn)から移植しました) ダイナミックフィールドやレプリケーションの話。 JSON型でHTTP経由で検索できるのが便利。 Solr本の紹介して頂きました!あざっす! 気になってるSolrの新機能 not to cache SurroundQuery BloomFilter Q:全部AWS? A:全部AWSに移行しました。 とまぁ、参加してきました。 初六本木ヒルズで、おしゃれな場所、雰囲気にやられてしまって、あんまりちゃんと聞けてないところがありますが。。。 メモを取りましたので。参考までに。 groongaについては勉強不足のため、いまいちついていけませんでした。 ちょっと英語の記事を読んでいたのもありまして。(内職良くない。。。) MeCabに関する発表に興味があり、勝手にMeCabの代わりorMeCabよりいいものを使ってます!みたいな発表かと想像していました。(ちょっと違ったみたい、妄想は良くないですね。。。)\nグリーの方の発表は興味深かったです。ログ解析とかにも確かに全文検索の技術使えるし。 検討が進んだ次の話も聞いてみたいです groongaの位置情報の話やrroongaでのgroongaの色々な機能のはなしも出てきてgroongaの理解もちょっと進んだのはありがたかったです。\n最後のクックパッドさんの話は、今回もわかりやすくて面白かったです。 検索を成長させていくという姿勢と、実際にどんな形でそれを実施されているかが楽しそうに話されててとても羨ましかったです。 次はSolrで困ってる点とか、検索のログとか利用され方をどのように解析してるのかといった話も聞きたいですね。\nどうしてもSolrに思い入れがあるので、感想が偏ってるかもしれません、すみません。 気になる点やいや、こうなんだよ!ってツッコミがあれば、ぜひコメントやTweetしてもらえるとありがたいです。\n","date":1327593155,"dir":"post/2012/","id":"c6dc6e6567d673436ac41ebc8e79a9ec","lang":"ja","lastmod":1327593155,"permalink":"https://blog.johtani.info/blog/2012/01/27/%E3%83%A2%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%8E%E3%83%AD%E3%82%B8%E3%83%BC2012-1%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-01-27T00:52:35+09:00","summary":"ということで、いつものように勉強会に参加したメモです。 http://atnd.org/events/23608 日時 :2012/01/26 19:00 to 22:00 会場 :アカデミーヒルズ(六本木ヒルズ内) 49階(タワーホールA) (港区六","tags":["勉強会"],"title":"モーショノロジー2012#1に参加しました。(Jugemより移植)"},{"contents":"日時:2012/01/19 18:30-20:30 場所:ベルサール三田Room2シアター\nInside MapR デモ+内部のお話。 ・自己紹介 Susheel Kaushik 元YahooのHadoop系の人。製品担当責任者。 草薙さん 3台のベアボーンでMapRが動いてるデモが開始。 クラスタ管理画面の説明。 なぜか、NFSのサービスが1台落ちてますがw MapReduceなんかの実行結果なども出てくるのか。 ボリューム管理も画面から操作 レプリケーション、スナップショットも管理画面で操作、動作確認できますよ。 ミラー先はリードオンリーでボリュームの同期が可能。 スナップショットによりMapRのクラスタ内部にバックアップが保持可能。 NFSのHA構成可能。VIPの機能などもあるよ。 事前定義された各種Alertの発行も可能。 JobTrackerもMapRで拡張された表示がある。 例:MapTaskPrefetchCapacity:次のジョブのMapperを起動する準備可能な仕組み MapR内で独自に出力してる測定値をGangliaで見ることができるよ。 MapRはHadoopの置き換えとなる製品。 HDFS部分を重点的に性能アップさせるために主に置き換えた製品。 MapReduce部分にも手を入れてる。例:Direct Shuffle(HTTPじゃなくて、RPCでShuffleの通信を行ってるとか)ボリューム活用してるらしい。 分散NameNode、JavaGCの影響の排除、ビルトイン圧縮によるI/O削減など。 Mapperの出力をHDFSに置くと、メタデータ更新が多くなり、NameNodeがパンクする。(Apache Hadoop) Q:中間データもレプリケーションすると性能劣化しないんですか? A:中間データボリュームは特定ノードしか保持されない(=レプリカ数は1) ストレージプール(SP) ソフトウェアでストライピング。RAIDしなくてよい。 コンテナ(データ、ネームがある。) データブロックをグループ化したもの ※ストレージプールの数と同数のボリュームを作成すべき。 CLDBがコンテナを管理してる。 Q:トランザクション失敗するのは? A:どこかにかければトランザクションは成功。 コンテナが復旧してきたら、データがコピーされる。復旧されない場合は別途コンテナを割り当てることもある? Q:ノードが追加される場合の挙動は? A:。。。聞き逃した。 トポロジ ノードを階層的にグループ化してデータ配置をコントロール。 Q:トポロジ設定などの権限設定は? A:Permission画面があるよ。 Q:ボリューム単位のファイルシステムアクセスに関する設定は? A:???聞き逃した? ボリューム いろいろな設定が可能。 スナップショット Copy-on-Write方式による差分格納 ミラー ソースからミラーにコピー。手動orスケジュールによる起動が必要。 ミラー側はRead-only ※誤解を招きやすいので注意 読み出しが多い場合にミラーを利用することで対応が可能。 ビルトイン圧縮 LZZFの一種を高速化してる ネットワークIOにも効いてくる JobTracker HA 最大3ノードで構成可能。アクティブスタンバイ NFS HA すべてのノードで稼働可能。 NFS機能 NFSv3相当 クライアント側にNFSサービスをインストールするという構成も可能に。 Q:NFSマウントして作成したファイルもブロックサイズ分のファイルサイズになるの? A:8Kバイト単位で内部的にはファイルを作成してる。8KB単位で圧縮して管理してるので、小さいサイズでもいい。(アロケーションサイズが8KB) Q:8KBにしてしまったために大きなブロックサイズの利点がなくなるのでは? A:オーバーヘッド内容な構成になってる。シーケンシャルに8KBに並んでるから? Q:NFSによるとMapReduceによるアクセスの排他制御とかは? A:独自で頑張らないといけない。Job起動時に効果的にスナップショット取ったりはしてない。 リバランスもバックグラウンドで実行可能 Apache Hadoopが備えるJava APIは100%語幹 Q:なんで、HDFSをがりっと書き換えたの? A:運用性も、ノード管理も。。。全部です。 なくなっても良いデータなら、別にHadoopでもいいですよね。 けど、基幹システムとかだと、信頼性が必要だし、運用の効率も必要だしいろいろ必要。 Q:実績が必要なんですが、どのような試験を行われているのかという情報が公開される?EMCでやられてるテストのプロセスを適用しているなどの裏付けは公開されないの? A:内部で6ヶ月利用してデータロスはない。 品質については強化していく。 Q:MapRとしてHadoopコミュニティへの還元していく内容ってどんなもの? A:Apacheコミュニティに対して1000台のクラスタを提供してスケーラビリティテストとかやってくださいとしている。 Q:このクラスタを実際にはどう使ってもらうの? A:品質アップするためにテスト環境として使ってもらう? Q:ApacheのAPIの互換性を死守するのが必ずしもいいとは思えない場合にどうするの?MapR独自APIとかは出さないの? A:ApacheのAPIに準拠するのは非常に重要。他のHadoop上のアプリが動作しなくなるから。 Q:MapRを容量の大きなファイルシステムとしてだけ利用するなんて想定はありますか?MapReduceを利用しないパターンです。 A:いや、それはw Q:MapRはエンタープライズがターゲットだけど、Amazonはパブリッククラウドが対象。マルチテナントなパブリックサービスでMapRを利用するとかは? A:。。。 Q:ジョブ管理にも手を入れてるの? A:あんまり手を入れてません。 Q:EMCのストレージ製品でMapRのMapReduceない版みたいの出てない? A:中身はMapRじゃないですよ。 想定とは異なり、日本の草薙さんが主に説明されたのですごくわかりやすかったです。 しかもかなり内部まで理解されている方だったので突っ込んだ質問にもきちんと回答されてるので更に理解が進みました。 今回利用された資料は現時点では公開の予定はないという話でした。 ただ、かなりまとまってる資料なので、後悔して欲しいものです。 普通にviとかしてるだけなのに、すごいと思うデモってなんか新鮮でした。 MapR自体を触る機会はまだまだないと思うのですが、MapRとしてHadoopに対する思想が垣間見えたのが面白かったです。 すごいメンツが質問を投げまくるのでいろいろな側面で話が聞けました。 ただ、やっぱり英語のヒアリングがダメダメだというのが露呈しました。。。今年は少し頑張らないと、先が思いやられますね。。。 あと、疑問と言うか、感想ですが、MapR自体が結構多機能で、その機能をどう扱うか、どのようなノード構成やボリューム構成を取るかといった設計が結構大事でしかも大変なんじゃないかなぁという印象を受けました。 特にマルチテナントで利用する場合などは、想定されないミラーの利用などでデータ容量が足りなくなったりといった側面も出てくるのかなぁと。\n説明会のあと、Hadoopにあんまり絡んでないのに図々しくも飲み会にまで参加してきました。 これまた濃いメンバーだったので話についていくのも大変でしたが、面白い話が聞けました。やっぱり懇親会重要ですよねぇ。\n事前にこのブログを読んでいたので話しを聞くのが楽でした。 MapR勉強するために必須のページです。(どうやら今日説明した人がかいてるきがしますが。。。)\n追記: トゥギャってくれた人に感謝。 ","date":1326988680,"dir":"post/2012/","id":"7198e10ebcf1bb88dc479b5c5b9f2c15","lang":"ja","lastmod":1326988680,"permalink":"https://blog.johtani.info/blog/2012/01/20/mapr%E4%B8%AD%E8%BA%AB%E8%AA%AC%E6%98%8E%E4%BC%9A%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-01-20T00:58:00+09:00","summary":"日時:2012/01/19 18:30-20:30 場所:ベルサール三田Room2シアター Inside MapR デモ+内部のお話。 ・自己紹介 Susheel Kaushik 元YahooのHadoop系の人。製品","tags":["勉強会"],"title":"MapR中身説明会に参加しました。(Jugemより移植)"},{"contents":"お久しぶりです。インフルエンザで一家全滅という最悪の状況に陥っていた我が家でした。 流行してるみたいなのでみなさんも気をつけてください。\nさて、そんな中、OSSAJのミニセミナーでSolrについて簡単に話しをしてきました。 人生初Ustだったのですが、ぶっ倒れている中作成した資料だったためなんとも情けない発表だった気がします。(言い訳カッコ悪いですね。。。) 関係者の皆様、申し訳ございませんでした。\n内容としては、Solrの機能を簡単に紹介する程度の資料となっています。デモなどもないのでスライドだけ見てもなんだこれという感じかもしれませんが。\nということで、恥ずかしながら、録画もされているようなので、後で見て反省しようと思います。。。\n[オープンソースソフトウェア検索サーバ Solr入門](http://www.slideshare.net/JunOhtani/solr-11146713)** View more [presentations](http://www.slideshare.net/) from [Jun Ohtani](http://www.slideshare.net/JunOhtani) ","date":1326941184,"dir":"post/2012/","id":"a4462529ab493676987d946019a14945","lang":"ja","lastmod":1326941184,"permalink":"https://blog.johtani.info/blog/2012/01/19/ossaj%E3%81%AE%E3%83%9F%E3%83%8B%E3%82%BB%E3%83%9F%E3%83%8A%E3%83%BC%E3%81%A7%E8%A9%B1%E3%81%97%E3%82%92%E3%81%97%E3%81%A6%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-01-19T11:46:24+09:00","summary":"お久しぶりです。インフルエンザで一家全滅という最悪の状況に陥っていた我が家でした。 流行してるみたいなのでみなさんも気をつけてください。 さて、","tags":["勉強会"],"title":"OSSAJのミニセミナーで話しをしてきました(Jugemより移植)"},{"contents":"先日のSolr勉強会でLucene/Solr4.x系のlucene-gosenについて質問を受けていたのを忘れないように(年越しちゃいました、すみません。)先週金曜日(1/6)にissueに登録しました。 まずは忘れないようにと思って、登録だけして3連休に突入したのですが、Robertさんが1/7に対応してくれました。 Lucene/Solr 4.x系では3.x系とはパッケージやメソッドが変更されるなど少し異なる部分があります。 lucene-gosenでは、プロジェクトのページにもあるとおり、4.x系にも対応しています。 ただ、この4x系に対応したブランチが、2011年5月から放置されていました。\nということで、Lucene/Solr 4.0系でlucene-gosenを利用されている方、これから利用される方は、この4x系に対応したブランチを利用してください。 なお、このブランチにはLucene/Solrのtrunk (r1228509)のSNAPSHOT版のjarファイルが利用されています。\n今後はlucene-gosen側でバグ修正や機能追加を行った場合にも4xブランチを更新していく予定です。 ※ただし、Lucene/Solr 4.0が正式リリースされていないため、頻繁にSNAPSHOTのjarファイルを入れ替えることはこなわないと思います。\n","date":1326033660,"dir":"post/2012/","id":"f7df7b85af230b2623d3a827b0cbddd2","lang":"ja","lastmod":1326033660,"permalink":"https://blog.johtani.info/blog/2012/01/08/lucene-gosen%E3%81%AElucene-solr4-0%E5%AF%BE%E5%BF%9C%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E6%9B%B4%E6%96%B0/","publishdate":"2012-01-08T23:41:00+09:00","summary":"先日のSolr勉強会でLucene/Solr4.x系のlucene-gosenについて質問を受けていたのを忘れないように(年越しちゃいました","tags":["lucene-gosen"],"title":"lucene-gosenのLucene/Solr4.0対応ブランチ更新(Jugemより移植)"},{"contents":"あけましておめでとうございます。(もう5日ですが。。。) 今年もlucene-gosenを中心に色々と記事を書いていきますので、ツッコミ、コメント待ってます。\nたまには会社のブログを書かないとイカンということで、会社のブログにNearRealTime検索についての記事をアップしました。 読んでやってください。\nということで、今年もいろんな勉強会に出没しますので、よろしくお願い致します。\n","date":1325735817,"dir":"post/2012/","id":"cc573488dec311655890a205aad4fb65","lang":"ja","lastmod":1325735817,"permalink":"https://blog.johtani.info/blog/2012/01/05/%E3%81%82%E3%81%91%E3%81%BE%E3%81%97%E3%81%A6%E3%81%8A%E3%82%81%E3%81%A7%E3%81%A8%E3%81%86%E3%81%94%E3%81%96%E3%81%84%E3%81%BE%E3%81%99%E4%BC%9A%E7%A4%BE%E3%81%AE%E3%83%96%E3%83%AD%E3%82%B0%E6%9B%B4%E6%96%B0/","publishdate":"2012-01-05T12:56:57+09:00","summary":"あけましておめでとうございます。(もう5日ですが。。。) 今年もlucene-gosenを中心に色々と記事を書いていきますので、ツッコミ、コメ","tags":["misc"],"title":"あけましておめでとうございます+会社のブログ更新(Jugemより移植)"},{"contents":"他の方たちよりひと足はやいですが、今年の仕事が終わりました。 せっかくブログを始めたので、振り返りと来年の抱負など書いてみようかなと。\n今年の振り返り まずは、今年1年を振り返ってみます。 今年の出来事はこんな感じでした。\n3月に仕事が一区切り lucene-gosenに参加 ブログを始める 色々な勉強会に参加 Twitterでつぶやきまくり Mac Book Airの購入 PSVita買いました 3月に一昨年から参加していた仕事が一区切りつきました。 もう少し色々とやり残した感がある中で区切りがついたのが少し心残りでした。 あと、3月は震災もあり、色々と大変でした。ただ、自分の中では震災の記憶が少し薄れつつあるのが気がかりです。 良くも悪くも忘れて行ってしまうのだなと。今でも頑張っている方々もいるので、少しでも心に留めておきたいものです。\n個人的に一番大きな今年の変化は「lucene-gosenへの参加」です。 関口さんとここ数年ずっと仕事をご一緒させていただいていることもあり、コミッターとして参加させてもらうことが出来ました。 英語が苦手な中、Robertさんへ自己紹介のメールを書いたり、Issueを英語で書いたりと苦労もしていますが、OSSに参加できることがとても楽しいです。 また、使っていただいている方たちからのフィードバックもいただけているのがすごく励みになります。 やはり、OSSは使ってもらってさらに良いものになっていくのかなぁという感想です。 ただ、自分の腰が重いため、なかなか対応が遅かったりといったところもあるなと反省するところも。\n勉強会にも色々と参加しました。Solr勉強会を始めとして、かねてより興味があるHadoopのカンファレンスやソースコードリーディング。MongoDBの勉強会やDSIRNLPといった少し研究よりの勉強会にも参加しました。 Solr勉強会に参加してきた経験もあり、他の勉強会にも気負わずに参加できたので本当にSolr勉強会には感謝しています。 おかげで、社外のいろいろな方と話ができ、様々な刺激をうけることが出来ました。\n勉強会以外にもTwitterで色々な方に絡みまくったのもまた社外の方とのつながりが出来るいい機会でした。 Twitter依存症じゃないかというくらい、つぶやいたり、人に絡んだりしてます。。。(迷惑だったら言ってください。) お陰で@doryokujinさんや@wyukawaさんが主催してくれたログ解析の飲み会に誘ってもらえたり、@nobu_kさんや@ IjokarumawakさんにSolr勉強会で講演してもらえたりしました。 あと、Twitterを通じて勉強会やHadoop関連の情報、lucene-gosenへのフィードバックなどももらえていてかなり助かってます。 @yusukeyさんや@repeatedlyさんに遊んでもらってるのも楽しいですw\n最後の大きな変化はApple製品の購入でした。 これまでもブログで書いてきましたが、私は今年の中頃までアンチApple派でした。 それがここ半年足らずでAir、Mini、iPadと3つのApple製品に囲まれています。 Emacsのショートカットが使えるのが最大の要因ですが、何ごとも毛嫌いせずためしてみるのがいいなと思いましたね。 今では、Windowsで開発したくないくらいになってきています。\n2012年の抱負 さて、来年の抱負です。 今年いくつかチャレンジしようとして挫折してるものがあります。\nMongoDB触ってみる Scala触ってみる なんかWebサービス作ってみる(Amazonとかで) elasticsearch、IndexTankを調べてみる NewSolrCloudDesignを読み込んで自分なりにまとめる Junsaiに参加する 「7つの言語7つの世界」の続き 最初の3つはセットですかね。コップ本買ったり、NoSQLの本を買ったりしてるのですが、手付かずです。。。 電子書籍の検索サービスでもつくってみようと思いつつ、腰が重い状態です。 来年は余裕を見ながらちょっとずつやりたいですね。\nelasticsearchやIndexTankは仕事がらみです。 Solr入門を書いたこともあり、検索関連には興味があります。Solrだけでも2ヶ月おきに新バージョンがリリースされたり、4.0系でいろんな機能が実装されているのですが、それ以外にもOSSの検索サーバがいくつかあります。 気になってはいるものの英語が障壁でなかなか手を出して来ませんでした。 来年はSolr以外についてももう少し知識をつけていきたいです。 個人的ですが、分散処理にも少々興味を持っています。 慣れ親しんでいるSolrでもSolrCloudという壮大な計画が上がっていて、少しずつ実装もされています。 ブログでWikiページを翻訳してもみたのですが、翻訳に注力しすぎて理解ができていないです。 このあたりをもう少し理解しつつどのような実装がされているかも調べたいところです。\nJunsaiはSolr入門の著者である武田さんが最新のMeCab(今はMeCabが新しくなってしまったので、少し前のMeCabになってしまいました)をJavaに移植したプロジェクトです。 今年頭のSolr勉強会でお披露目があり、私も一応参画しているのですが、手が出せていない状態です。 lucene-gosenで少しは経験を積んできたので、その部分を生かしつつ、こちらももっと活性化させたいところです。 最後は夏ごろにやっていた「7つの言語7つの世界」の再開です。序盤で止まってしまっています。。。 新しい技術に触れる題材としてちょうどよいので、余裕をつくって続きを再開します。 なんか、抱負と言うよりも積み残しですね。。。 他にもTwitterで情報を仕入れるとやりたいことも変わってくるかもしれませんが、それも含めてブログに少しずつでも書きためていこうと思います。\n先ほども書きましたが、今年はTwitterを通じて色々な方たちと知り合いになれた一年でした。 ここには書ききれていませんが、フォローしてもらっている方々や勝手に絡んでも相手をしてくれている方々に感謝しています。 今後も絡みますのでよろしくお願いしますw あと、様々な勉強会に今後も顔を出していくので、かまってやってください。 いやぁ、色々書いたけど恥ずかしいですね。。。 まぁ、何事も経験なので、恥ずかしいと思いつつ今後も色々書いていきます。\n","date":1325006100,"dir":"post/2011/","id":"7164823f504286e3a762ee612ff0a988","lang":"ja","lastmod":1325006100,"permalink":"https://blog.johtani.info/blog/2011/12/28/%E4%BB%8A%E5%B9%B4%E3%81%AE%E6%8C%AF%E3%82%8A%E8%BF%94%E3%82%8A%E3%81%A8%E6%9D%A5%E5%B9%B4%E3%81%AE%E6%8A%B1%E8%B2%A0/","publishdate":"2011-12-28T02:15:00+09:00","summary":"他の方たちよりひと足はやいですが、今年の仕事が終わりました。 せっかくブログを始めたので、振り返りと来年の抱負など書いてみようかなと。 今年の振","tags":["misc"],"title":"今年の振り返りと来年の抱負?(Jugemより移植)"},{"contents":"@yusukeyさんにサインをもらう目的で勉強会に参加してきました。前回もらいそびれたのでw 残念ながら、まだTwitter APIを触ってないし、利用したサービスも思いついてないんですが。。。 けど、勉強になりました。 といことで、いつものごとく、自分メモです。\n◎APIの基本と最新動向について @yusukey 資料:http://www.slideshare.net/yusukey/21twitter-api-api\n・検索APIについて http://search.twitter.com/search.json?q=*** %3Aは「:」 詳しくはリファレンスを買ってね。 ・ページ処理のベストプラクティス Pageじゃなくて、MaxIdを利用して取得すると1500件以上のデータも取れるよ。 ・最近のTwitterAPIアップデートについて - ポケリファでの変更点 ストリーミングのエンドポイントがSSLのみに。(twitter4jは2.2.5以上) - ユーザ名が検索APIのスキーマに追加(12月以降) - in_reply_toの追加(12月以降) =\u0026gt;検索結果から会話を追える。 ・include_entitiesが追加 t.coの展開したリンクも取得可能。 けど、t.coリンクの飛び先はt.coリンクにしてね。パトロールとかしてるから。 ・本当にあった怖いt.co - URLのつもりじゃないのにリンクになる。 →仕様です - 日本語を含むURLがおかしくなる。 →少しずつ治ってきてる。 - リンク先のURLがわからない(クライアント依存) そのたいろいろ? ◎Zusaarについて何か @knj77 資料:\n・特徴 - SNSアカウントでログイン トラブル抑制など - 事前決済可能。最小催行人数が決められて、払い戻しも可能。 ・利用例 旅行とか合宿に使う例がないんだけど、できるんじゃないかな? ・イベントを依頼する機能 欲しいイベントを提案可能 http://www.zusaar.com/idea/ ・アーキテクチャ GAE/Java、Twitter4j、Yahoo APIのテキスト解析 ・SNS連携 TwitterのDMが送れない。他のSNSのアカウントが主催者とか。 なので、自分からDMが届く。 ・PayPal連携 小さいアプリほど相性がいい 固定費ゼロ、マイクロペイメント(100円とか可能) 銀行口座の登録不要、返金可能。部分返金も可能。 ・トラブル - SNS側のエラーが適当 ステータスコードは信用できないw - PayPalの実装を3回変更 - GAE料金体系の変更 9$/month。追加料金はほとんど使ってない。Googleのアナウンスが下手。 - ブルーオーシャンのはずが... Q:Zusaarで返金できるポイントは? A:主催者が主導(手動?)で返金可能。 Q:無料イベントで約束手形的に課金するのはできる? A:やろうと思えば出来ます。ただ、システム的には100円は手数料としてもらっている。 Q:新しいATNDに対抗意識はありますか? A:ZusaarはCtoCをターゲットにしてる。ATNDはBtoCなので、補完できる関係だと思ってる。 Q:APIでTwitterIDとかで検索したいんですが。 A:対応予定あります。 Q:できればATNDのAPIと共通化してほしい。 A:追加してるだけのつもりです。 ◎グループに分かれて自己紹介 6人中、懇親会参加者が5人もいたw\n◎LT - OAuth Echoについて@tkawa 資料:http://www.slideshare.net/tkawa1/oauth-echo-20111221-10657954\ntwitpicで使ってる。 認証をServiceProviderに委譲する仕組み。 クライアントがOAuth登録してあれば、。。。 ・問題点 非公式仕様 OAuth1.0に基づいてて2.0では変わってそう。 ・Railsで実装してみたよ。 - GroovyとQuartzとTwitter4Jの甘い生活G @mike_neck 資料:\nベトナムから緊急来日らしい。 しかもむちゃぶりされたらしい。 - 認証なしで使えるAPIまとめ?@ts_3156 えごったーの作者で学生!\n- TDD (Twitter4J Driven Development) @sue445 資料:\nAZusaarの作者! テストドリブンなはなし。 Twitter4Jを利用するときのTDDの簡単に実装できる仕組みの話。 ここにソースがあるのかな? http:/github.com/sue445/twtrhack/ - 放射線を自動計測してTwitterにつぶやくimaocandeの紹介 @imaoca 松山の方。 とまぁ、APIの話だけでなく、実際にAPIを利用している方のサービスの話など色々と面白い話が聞けました。 厚かましくも懇親会にも参加して、そこでも今までのイベントとは違うクラスタの方たちの話が聞けたのが楽しかったです。 やはり、APIを利用して色々とやってみようと思っている方が多かったのでいつもと違う話が聞けたんですかね。 私自身はサービスを思いついたりしないタイプなので、いい刺激になりました。(まだ、特になにか作る気にはなってないですがw) ということで、次回も余力があれば参加したいなー。 ","date":1324485660,"dir":"post/2011/","id":"da67e2f049b5b6babcf7906b85653399","lang":"ja","lastmod":1324485660,"permalink":"https://blog.johtani.info/blog/2011/12/22/%E7%AC%AC2-1%E5%9B%9E-twitter-api-%E5%8B%89%E5%BC%B7%E4%BC%9A--%E6%9D%B1%E4%BA%AC%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-12-22T01:41:00+09:00","summary":"@yusukeyさんにサインをもらう目的で勉強会に参加してきました。前回もらいそびれたのでw 残念ながら、まだTwitter APIを触ってない","tags":["勉強会"],"title":"第2.1回 Twitter API 勉強会 @東京に参加しました。(Jugemより移植)"},{"contents":"lucene-gosenの最新版(1.2.1)をリリースしました。\nプロジェクトページよりダウンロードが可能です。\n今回の修正では、特定文字列でメモリの使用量が爆発してしまうバグへの対処となっています。 1.2.1以前のバージョンを利用している場合は最新版を利用するようにしてください。\n","date":1324437339,"dir":"post/2011/","id":"584b2b145f362098fc5fc1e634d57de5","lang":"ja","lastmod":1324437339,"permalink":"https://blog.johtani.info/blog/2011/12/21/1-2-1%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-12-21T12:15:39+09:00","summary":"lucene-gosenの最新版(1.2.1)をリリースしました。 プロジェクトページよりダウンロードが可能です。 今回の修正では、特定文字列で","tags":["lucene-gosen"],"title":"1.2.1リリースしました(Jugemより移植)"},{"contents":"いつものようにSolr勉強会に参加してきました。 皆勤賞を継続中です。(暇人というはなしも。。。) 今回は話しを聞きたいですねぇといったら、いやいや、話もしてくださいと言われてしまったので、 発表もしてきました。 発表資料はブログの最後に掲載してあります。\n日時:2011/12/19(月) 19:00~21:00 場所:Voyage Group 8階\n1.Fessについて N2SM菅谷さん 資料:http://www.slideshare.net/shinsuke/solr-fess\nマルチコアで構成されてる。 S2Robotでクロールしてますよ。 ※ごめんなさい、あまり聞けなかった。。。あとで資料を読んで質問します! 2.lucene-gosenについて @johtani 発表しました。 3.ApacheConに参加しました @Ijokarumawak 資料:http://www.slideshare.net/KojiKawamura/apache-con-2011report\n日本-\u0026gt;カナダ-\u0026gt;ベルリン-\u0026gt;カナダ-\u0026gt;日本 50万円。。。 キーノート1: セキュアな開発について。 キーノート2: Hortonworksのコミュニティ運営大変だよねぇ、頑張るよという話。 キーノート3: 本題:Lucene 4.0の話:Simonさん ヨーロッパの方? PostingsFormatの話。 Document内部の情報を使うためにどうする? StoredField:あんまり効率よくないね。 FieldCache(on RAM):インデックス作る動作の逆を行う。これも効率よくないね。 IndexDocValue:インデックス作成時に作られるので読み込み性能が100倍!(DocValue) Document Writer Per Thread! Automaton Query あいまい検索の処理に利用。 Solr Flair Solr同梱 Prism LucidImaginationが出してるJRubyのラッパー GitHubで公開されてるらしい。 Blacklight RoR 図書館むけのパッケージじゃなかったっけ? VUFind PHP これも図書館向け? TwigKit JSPのタグリブ おぉ。これ直接読んでるのかな? Ajax Solr Ajax用 QA Q:TwigKit、Ajax Solrは直接Solrを呼んでるんですかね? A:たぶん、そうですね。JSPのはSolrJかもしれないですが。 4.サフィックスアレイの話 @nobu_k 資料:http://www.slideshare.net/nobu_k/suffix-arraysolr\nSuffix Arrayの話 全文検索インデックスの話。 Suffix Array=検索漏れがない。 Suffix=接尾辞 RedBullがどの文書に入っているか! SuffixArrayのメリット 検索漏れがない=n-gramと同様 仕組み上n-gramよりも早くなるケースが多い。 長いクエリに対して速い THIS IS IT:全部ストップワード SuffixArrayのデメリット インデックス構築系 アルゴリズムが難しい。 メモリ上での構築はちょっとだけ楽(けど、簡単ではない) SAISなど。けど、これだとメモリがいっぱいないとキツイ HDDでの構築 ランダムアクセスを排除したアルゴリズムが必要(dc3,dc7) インデックス更新、差分更新できない。 頑張って1台100GB/day Sedueでは? SA&インメモリn-gramのハイブリッド 更新分はn-gramに 検索時にはn-gram+SAの内容をマージして出力 検索 二分探索はHDDとは相性が悪い。 メモリ上で検索できればOKだけど、サイズが大きいからきびしい。 圧縮接尾辞配列なら可能だけど、低速。。。 SSDだとはやいよ! SSD対応のクラウドはまだないけど。。。 Sedueでは最初の20段でキャッシュしてる。 VSストップワード ストップワード込でインデックス作るみたい。 1.SAを二分探索 2.該当区間から出現位置をロード 3.出現位置をソート O(n)だけど、CPUのキャッシュミスが激しく影響 4.ソートした出現位置からヒット文書を求める。 同じくキャッシュミスがやばい ・実際にはmallocした領域のページフォルトが一番やばい SAが超活躍する場面 遺伝子の検索 n-gramとか死ぬ。形態素解析も無理。区切りがわからんw 5.P2P検索 ORBIS @ceeflyer 資料:http://www.slideshare.net/ceeflyer/p2p-search-engine-orbis\nORBISとは?ラテン語で「目」 ORBISとは? リアルタイム検索エンジン 自律分散検索エンジン もともとはAmebaなうの検索のため ノード構成 比較的小規模(~1000台)\u0026lt;=しょ、小規模ですか。すごいな。 Master-Slaveの差がなし MessagePack利用 フルメッシュネットワークを構築 インデックス フィールド: Content(形態素解析対象) Appendix(形態素解析しない) Flag(属性) ハッシュレプリケーションで登録。近いハッシュ値に登録(レプリカ数を指定できるのかな?) 単語に対して転置インデックスを一定数で固定 投稿日時が新しいものだけ検索するため。 検索: マージして結果を返す。 壊れてたら取れたものだけ返す。 QA: Q:ハッシュ値が大きくて1台しか選ばれないとかあるのでは? A:ハッシュ値は循環しているという形で3台とか選ぶ。 Q:最大何台で稼働させてる? A:現在はまだ5台程度 Q:障害時にレプリケーションの維持はするのか? A:現時点はしてない。 Q;Cassandra、Lucendraとかあるけど、それをしなかった理由は? A:単純にConfigurationができるから、1から作った。 今回はSolr以外の話も聞けたのがとても面白かったです。 やはり、Solr以外の検索エンジンについても知見があると、色々と比較の話しとかしやすいので。 それにしても、一からP2Pの検索エンジンを作っているのにはびっくりしました。 他にもSuffixArray(Sedue)の話も気になっていたのが少し氷解したし、海外旅行のノウハウがApacheConの話で聞けたしw やはり、発表をすると話しをしてもらえるのもあって、いい機会だなと再認識しました。 今回も紹介ネタだったので、ちゃんと事例とか測定したものも発表できるようにならねばと。。。\nということで、私の発表資料はこちらになります。疑問点とか質問事項とか、指摘事項など、コメントorTwitterで連絡いただけるとすごく嬉しいです。\n[Lucene gosenの紹介 solr勉強会第7回](http://www.slideshare.net/JunOhtani/lucene-gosen-solr7)** View more [presentations](http://www.slideshare.net/) from [Jun Ohtani](http://www.slideshare.net/JunOhtani) ","date":1324311660,"dir":"post/2011/","id":"c6696a730f7498efb66f5ba3a8b35d08","lang":"ja","lastmod":1324311660,"permalink":"https://blog.johtani.info/blog/2011/12/20/solr%E5%8B%89%E5%BC%B7%E4%BC%9A%E7%AC%AC%EF%BC%97%E5%9B%9E%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F%E7%99%BA%E8%A1%A8%E3%82%82%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-12-20T01:21:00+09:00","summary":"いつものようにSolr勉強会に参加してきました。 皆勤賞を継続中です。(暇人というはなしも。。。) 今回は話しを聞きたいですねぇといったら、いや","tags":["勉強会"],"title":"Solr勉強会第7回に参加しました。(発表もしました)(Jugemより移植)"},{"contents":"ということで、懲りずに#DSIRNLPに参加してきました。 基礎的な部分をおろそかにしたくないけど、TokyoNLPとかWebMiningではついていけないので。。。 今回もしがみつくのが精一杯かもしれないと思いつつ、聞いて来ました。\n0. DSIRNLPについて @overlast 講演者が可能なら実装に関して言及する。 「こうやって作って結果を出す」系の発表をしましょう。 開催に際して協力してくださったみなさんへの感謝の辞。 1.自然言語処理はじめました @phyllo 資料:http://www.slideshare.net/phyllo/ngram-10539181 ブログ:http://d.hatena.ne.jp/jetbead/20111210/1323499634 某Web企業の新入社員!(すごい) で、入って自然言語処理をはじめたらしい。 N-Gramの説明 Perl? 1.ナイーブな方法 Perlでハッシュ使って数えてみたよ。これでOK? いやいや、Nが大きくなったりデータが大きくなるとキツイでしょ 2.SuffixArrayを使う ということで、Suffix Arrayを使ってみた。 SuffixArrayのデータを作ってから、上からN文字数えれば数えられる! (数式出てきたけど目も取れなかったw) これでいいじゃん?いやいや、更に大規模だとどーすんの。1TBのメモリ 3.近似カウント法 いくつかある中からLossy Countingを説明します。 ストリームデータから数えてみよう。 C++の実装? 4.分散処理を使う方法 近似じゃダメ!正確な頻度が欲しい! =>Hadoopつかえ! 色々やってみた感想が良かった。 SuffixArrayのメモリ使用量という話がありましたが、ディスクを使う方法もあります。 by ? 新人から自然言語やり始めたというが、自分が新人の頃にはこんなに出来なかった気がするなぁ。 発表とかもってのほかだったし。 2.AI で AI 創ってみた(LT) @uchumik 資料: Luaプログラミングが出てきたので、 多クラスロジスティック回帰とListNetを書いて見ました。(ただし、本は読んでないよ。) 学習器のお話。 ラグナロクオンラインのAIがLuaでかけることを思い出した。 動画の途中で終了w GitHubにあげなさい。ブログ書きなさい。動画もあげなさい。 by @overlast 資料の割に時間がw 2.5.CMコーナー 技評の方からWEB+DBのCM!(ただし、商品なし) 読者層の95%が男性w 総集編買ってね!WEB+DB plusシリーズも買ってね! 書いてor買ってね。 技評さんつぎはオライリーさんに負けないように賞品持ってきてねw 3.Mahout にパッチを送ってみた @issay 資料:http://www.slideshare.net/issaymk2/mahout-10539755 人がやめていく会社で検索やHadoopやってます。 ※今日は皆既月食です。 機械学習関連 SGDはMapReduceでの分散に対応していないので、パッチを送ってみた。 MapReduce、Shuffleなどの説明 これをベースにナイーブベイズの説明をあわせて実装を見てみる。 ・単語wのカテゴリcにおける確率 ・文書dのカテゴリcにおける確率 -文書dに出てくる単語wの確率の積と定義 単語の相関を見ない。 ゼロ頻度問題の解説 文書頻度の逆数(IDF) カテゴリ毎の文書数のばらつきに対応するために、Complement Naive Bayes BayesFeatureDriver 次はランダムフォレスト 決定木とは? ランダムフォレストとは? ここでは素性。 Mahoutでの実装は? 決定木の数だけ処理分散が可能。 Reducerは使ってない。=Mapperで計算が終わっちゃうから? 次はロジスティクス回帰 尤度関数、損失関数、確率的勾配降下法(SGD) 先程まではオンライン。バッチ学習もある。 Mahoutでの実装はオンラインで、MapReduceに向いてない! Adaptive Logistic Regrettion(アダプティブロジスティクス回帰)というのも実装されてる。 送ったパッチの概要 Iterative Parameter Mixisngというのがあるので、それをSGDに適用するパッチ 今後 MapReduce以外も増えるかも。 Q:パッチがはいったバージョンはいつでる?A:3日前に送ったのでまだです Q:ナイーブベイズのMapReduceが一段ムダでは?(文書数のカウントは同時に出来るよね)A:そうですね、ぜひパッチを送ってみてください。 Q:Mahout、Hadoopの未来は明るいんでしょうか?A:HDFSのデータをMapReduce以外のフレームワークで使えるといい。 Q:Hadoopのパッチ送るの大変ですか?どのくらいかかりました?A:4,5ヶ月かかりました。 すみません、途中から頭がパンクしてしまいました。。。 ただ、MahoutがHadoopに乗っかってるからといって、MapReduce活用できてるわけじゃないという話がわかりました。 4.GraphDBのデータ構造 @kimuras 資料:http://www.slideshare.net/skimura/graphdatabase-data-structure LTみたいな資料にになっちゃいました。すみません。 mixiではMySQLだけど、いろんなDB触ってます。 なので、GraphDBに興味持ちました。 Luceneを教科書的に読んでます。 Neo4jモダンな作りでよかった。 http://www.slideshare.net/skimura/ss-8787632 ノードデータの構造 NodeManagerというのがいて、Cache系を管理してる。 プロパティのインデックス、トランザクションManagerもいて、PersistenceManager ここからNodeにアクセス(探索、)。 キャッシュとかいいね。 Soft LRU Cacheってのもあるよ。 その他色々w Q:トランザクション周りでLRUのキャッシュはどうなるんでしょうか@kumagi A:きちんとロックしてました。 Q:分散はネットワーク、HDDどちらがキツイ?A:HDDがかなりきつい Q:プロパティもキャッシュに乗ってたほうがいい?A:プロパティも必要なら載せたほうがいい。メモリのしてはできたはず。 Luceneがほめられてました。Neo4Jの 5.冬のLock-free祭り @kumagi 資料:https://docs.google.com/viewer?a=v\u0026amp;pid=explorer\u0026amp;chrome=true\u0026amp;srcid=0B72X9w6tG5q0NzMyODgwNDYtNjY4Yy00ZDgwLTliZDMtMjQwYmViMWE5NGU5\u0026amp;hl=en_US ※資料がうまく見れないのは、アニメーションガチガチって話だからかな? http://twitter.com/#!/kumagi/status/145363169718697984 辻Lock-free活動してます。 Lock-freeとツイートすると補足されるらしい。 CPUの系譜のおさらい ポラックの系譜 最新のIntelManyCoreとか東大とかに配られてるらしい。 なんで、マルチコアのCPUがTSUKUMOとかで売ってないの? 僕らが使いこなせてないから。=マルチスレッドの対応がうまくできてないから。 CAS=Compare And Swap まずは、Lock-free stack ABA問題? Lock-free Queue QueueのEnqueueの場合は2回のCASが必要になる。 不変条件を守る。ロックだと守りやすい。 2回のCAS処理の間が危険領域 Lock-free List 色々なロックの説明。 Lock-free hash map これも気が狂ってるアルゴリズム? ConcurrentHashMapなども話が出てきたが、説明しない=Lock-freeじゃないからw Lock-free SkipList SkipList: 順序関係のあるデータをO(log n)で検索・挿入・削除ができるデータ構造(2分木ともろかぶり) DougLea先生がjava.util.concurrentに入っています。 Lock-free Btree 論文ないんですよ。簡単すぎて。 SoftwareTransactionalMemory The Art of Multiprocessor Programmingを読みましょう! 論文のお話。 http://labs.gree.jp/Top/OpenSource/Flare.html を利用しているらしい。 The Art of Multiprocessor Programming関連サイト http://www.cs.brown.edu/courses/cs176/lectures.shtml すごくわかりやすかった。資料をもっと見たいなぁ。 Q:STMはメモリ使用量が2倍になる?A: Q:STM(Clojure)使ってみたけど残念な性能しか出なかったけど、なんで?A:Clojureのものはロックベース。でうーむ。。。 6.機械学習と最適化の基礎(仮) @tkng PFIの徳永さん 日本語入力を支える技術(技評)2012年2月発売予定 最適化の話、機械学習の話、学習率の話。 大域的最適、局所的最適の説明。(言いにくそう、大域的最適w) 凸最適化問題=最適解が1つしかない? 大域的最適解=局所的最適解 機械学習なはなし。 スパムメールの例で説明 淡々と語られてましたが、わかりやすい説明でした。もっと昔にこんな形で数学の説明聞きたかった。。。 7.機械学習・言語処理技術を用いた誤り検出・訂正(LT) @mamoruk 資料: スペル誤り訂正とかに機械学習とか使われてます。 8.神の言語による自然言語処理(LT) @AntiBayes 資料:http://www.slideshare.net/AntiBayesian/ss-10539347# Lispさいこー Clojureさいこー lucene-gosenもいいよーw 9.言語判定へのいざない(LT) @shuyo 資料: Solrで採用されたlanguage-detection libraryの紹介。 アゼルバイジャン語とか大変みたい。 12.作ろう!簡潔ビットベクトル @echizen_tm 資料:http://www.scribd.com/doc/73565169/Lets-Impl-Sbv 入門編: 簡潔データ構造 データサイズをほぼ情報量的下限にまで小さくしたデータ構造 データは小さいし、速度速いというのがこれ。 実用化されてる。 mozc(LOUDSが使われてます) Sedue(圧縮接尾辞配列(デフォルトではなくなった by @tkng)) 種類: ビット列:ここの説明がこのあと 木構造:トライ木をLOUDSが結構で実装するケースが多い。データサイズが小さくなる 文字列:ウェーブレット木が有名。全文検索、転置インデックスにウェーブレット木を使う研究が多い。 中級編 簡潔ビットベクトル: rank(i)関数:i番目より前の立っているビットの数。 疎なデータ列の効率的な実装に使える。検索結果が少ない場合のFacetとかに使える? select(i)関数:? 可変長データ列の効率的な実装 上級編 ダメでした。。。ごめんなさい。。。 体力的に厳しかったです。。。けど面白いし、わかりやすい。どういった所でこれらを使うべきかを取捨選択するのがすこし難しそうです。Luceneとかの内部ソース見ると実はこのあたりで実装されてる部分があったりするのかも。 11.類似文字列検索の仕組み @overlast 資料: 使い所のはなし 例:辞書メンテナンスコストを軽減したい 架空の事例から類似検索を適用できるというストーリー 既存データが活用されるうれしさの例? Apporoのデータ構造とかの話かな? 11.5.審査委員長から賞品持って帰る人の発表 @kumagi @tkng @echizen_tm の方たちでしたー 12.懇親会 いやぁ、前回も感じましたが、基礎ができてないなぁと実感できた勉強会です。 そして幅も広い。やはり、数学的な要素が時々出てくるのでその部分をもっと身につけないといけないなぁと。。。 ついていけなかったところも多々ありましたが、頭の中にキーワードが入ってればなんとかなるかなぁと。 Neo4jやLuceneのソースコードリーディングをやるのが仕事に役立ちそうなので、少しずつでもやろう。 これから懇親会なので、とりあえず、このへんで。 あとで、見返しながら、リンク貼り直したりすると思います。\n","date":1323529475,"dir":"post/2011/","id":"16fa0e4aefe18e1446bf6baefd3ba400","lang":"ja","lastmod":1323529475,"permalink":"https://blog.johtani.info/blog/2011/12/11/%E7%AC%AC2%E5%9B%9E-%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0%E3%81%A8%E6%83%85%E5%A0%B1%E6%A4%9C%E7%B4%A2%E3%81%A8%E8%A8%80%E8%AA%9E%E5%87%A6%E7%90%86%E5%8B%89%E5%BC%B7%E4%BC%9A%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-12-11T00:04:35+09:00","summary":"ということで、懲りずに#DSIRNLPに参加してきました。 基礎的な部分をおろそかにしたくないけど、TokyoNLPとかWebMiningでは","tags":[],"title":"第2回 データ構造と情報検索と言語処理勉強会に参加しました(Jugemより移植)"},{"contents":"ひさびさに、MBAのお話です。 セットアップといっても、物理的な方ですね。 以前、ケース(カバー)について記載しました。 この記事にも書いてあったのですが、付属の滑り止めが簡易なシールで、カバンの中から出し入れすると剥がれるは、作業をしてるとずれるわで、悩んでいました。 今日、たまたま、東急ハンズに行くことがあったので、店員さんに相談してすべり止め対策のグッズを購入しました。 相談した所、カバーは傷がつきにくくなるような素材ですから、シールもつきにくいとのこと。(言われてみればそりゃそうか。) 対策としては紙ヤスリで傷つけたところに薄手のシールゴムをつければはがれにくくなりますよとのこと。 ということで、やってみました。まぁ、ゴムにホコリはつくかもしれませんが、今のところ滑らず快適! いやぁ、ハンズの店員さんすごいですわ。 MBAについてはこんなとこです。最近また、出先に行っていてMBA使えないので、ブログを書くかメールにしか使ってないです。。。\nで、もう一つはMac Mini(2009 late:Core2Duo 2.26GHz、メモリ4G、HDD250G)です。 前職の同期から安く譲ってもらいました。音声が出力されないという問題点があるとFacebookでつぶやいているのをみて、興味を持ったらゲット出来ましたw で、セットアップをしたのです。 大変でした。まずつまずいたのが、キーボードとマウスでした。 これまで使っていたデスクトップのキーボードがあるのですが、これがPS/2ということで使えません。(軽いジャブ) MBAのキー配列にも慣れてきていたので、ビックカメラで悩みながらもApple純正のワイヤレスキーボードとまじっくトラックパッドを購入。 で、まずは、付属のLeopardで初期化。 このときは、ワイヤレスキーボードは認識したのですが、マジックトラックパッドはこの時代に無かったらしく、反応せず(さらに軽いジャブ) さすがに前のPCのマウスはUSBだったので、これを利用してセットアップ再開 次にSnow Leopard(これもつけてくれた)にアップグレードして最後にLionです。 Snow Leopardでソフトウェアアップデートしたところでようやくトラックパッドが認識できたと。 で、やっと使い始めたのですが、MBA(2011)に慣れていたので、思いの外もっさりした動きをしているMacMiniに 戸惑ってます。(トドメのストレート。現在ここ) ということで、どうやれば快適に使えるかアイデア募集中です。 とりあえず、Lionの設定のウィンドウ復元機能やアニメーションをオフにするなど対策してます。 HDDのSSD化とかメモリ増設とか考えないとダメかなぁ。 あと、ついでにBootcampも興味があるので、せっかくだから実験する予定です。 Windowsが前のデスクトップより快適に使えるようになるなら、Windowsマシンとするのもありかなぁと。。。\nセットアップ系はこのへんで。 あとは、最近興味が有ること2点です。(技術系ではありません) 1つ目は最近発売されたゼルダ。夜な夜なやってます。 もともとゲーム好きでゼルダも欠かさずやってきてますが、ゼルダらしさを残しつつ新しい要素やアクションも取り入れとなかなか楽しいです。 ただ、Wii全般に言えることですが難しい!まぁ、楽しんでますけどね 2つ目は前からつぶやいてるのですが、電子書籍を読むためのタブレットがすごく気になってます。 最初は財布に優しく、MBAを普段持ち歩いてるのもあるから、LenovoのA1(7インチ)で決まりだと思っていたのですが、技術書を読むのは少しキツイかもという印象。 どうしてもオライリー本などの大きめのサイズになるため、7インチの画面でPDFを表示したところ、字が小さくなってしまい拡大しないと見づらいのです。 ただ、拡大してしまうと今度はパッと見るという一覧性が下がってしまいます。。。 少々重くなってもいいので10インチにしたほうがいいのかな、けど、電車で立って読むの辛いかもなどなど考えているところで最終的な決断ができない次第です。。。 最初は毛嫌いしていたiPad2もいいかもと思う始末で困ってるとこです。 安い中華パッド(2万ちょっと)に手を出すか、7インチで我慢するか、Galaxy Tab 10.1のWifi版を輸入業者から購入するかと悩んでるところ。 ただ、長く使うのを考えると、OSのバージョンアップなどを保証してくれるiPad2が実はいいじゃないかなぁなど。 皆さんからしてみればくだらないなぁと思われるかもしれないけどずーっと悩んでつぶやいたりしております。 はぁ、こまった。(そもそもそんなにスペックいらないんじゃないかというのもあるからなぁ。メインはPDF読むことだから。) ゼルダの伝説 スカイウォードソード (期間限定生産 スペシャルCD同梱) ","date":1322668828,"dir":"post/2011/","id":"6e970d0818d58ff2d50c5bf037b1a565","lang":"ja","lastmod":1322668828,"permalink":"https://blog.johtani.info/blog/2011/12/01/mba%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97%E5%82%99%E5%BF%98%E9%8C%B2%E3%81%9D%E3%81%AE%EF%BC%95%E3%81%A8mac-mini2009late%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97%E3%81%A8%E3%81%9D%E3%81%AE%E4%BB%96%E3%81%8F%E3%81%A0%E3%82%89%E3%81%AA%E3%81%84%E8%A9%B1/","publishdate":"2011-12-01T01:00:28+09:00","summary":"ひさびさに、MBAのお話です。 セットアップといっても、物理的な方ですね。 以前、ケース(カバー)について記載しました。 この記事にも書いてあった","tags":["備忘録"],"title":"MBAセットアップ備忘録その5とMac Mini(2009late)セットアップとその他くだらない話(Jugemより移植)"},{"contents":" どんな本でも大量に読める「速読」の本 Twitterで知り合った方がこの本について書かれていたブログ記事を読んで興味を持ち、読みました。 書籍(特に技術書)が山になっていたこともあり、速読に興味を持っていたところちょうど記事を目にしたのは きっと何かのタイミングなんだろうなと。\n悪い癖で、電車で読もうと本を常に持ち歩くのですが、ついついスマートフォンやゲームで遊んでしまい、今回も読むのに時間がかかってしまいました。 3章の途中までを今月頭に読んでいたのですが、そこから少しほったらかしで、読み終わったのが昨日でした。\n本の内容ですが、先ほどのブログにも書かれていますが、速読は技術ではない。 ### 速読 = 速読技術 X ストック(知識、経験、情報) であると。あとは、わからなくてもいいから、ざっと目を通す感じで繰り返し読みなさいと。 さらに、1回でわからんくてもいいから、とにかく繰り返し読むことが重要だということでした。\n確かに「速読=1回で速く読む」、「読書=1回で理解する」という意識がどこかにあったなぁと気付かされました。 プログラム組んだり、あることを覚えるときは繰り返しを意識してたのに、読書は1回読んで「はい、おしまい。」という気になってました。(マンガは繰り返し読むんですけどねぇ)\n他の速読の本は胡散臭いし、絶対無理だよなぁと思ってたのですが、この本に書かれている話は筋が通っているように感じました。 ただ、考えずにサラサラ読みなさいという部分の実践はなかなか難しいかな。どうしても頭の中で音読してしまうので。 私は間を開けてしまったせいで、時間がかかってしまいましたが普通なら1日あれば読める内容なので速読に関してちょっとと思ってる方は読んでみると面白いかと思います。\nちょっとだけショックだったのは、この本の論理だと電子書籍は速読に向いていないというところです。 せっかく溜まった書籍をPDF化して、タブレット購入して(まだ買ってない。。。)読もうと思っていたところなのに。。。\n","date":1322542620,"dir":"post/2011/","id":"0ebe78077c8b48410cf52a0bccdff866","lang":"ja","lastmod":1322542620,"permalink":"https://blog.johtani.info/blog/2011/11/29/%E3%81%A9%E3%82%93%E3%81%AA%E6%9C%AC%E3%81%A7%E3%82%82%E5%A4%A7%E9%87%8F%E3%81%AB%E8%AA%AD%E3%82%81%E3%82%8B%E9%80%9F%E8%AA%AD%E3%81%AE%E6%9C%AC%E3%82%92%E8%AA%AD%E3%81%BF%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-11-29T13:57:00+09:00","summary":"どんな本でも大量に読める「速読」の本 Twitterで知り合った方がこの本について書かれていたブログ記事を読んで興味を持ち、読みました。 書籍(","tags":["読書"],"title":"「どんな本でも大量に読める「速読」の本」を読みました(Jugemより移植)"},{"contents":"Hadoopソースコードリーディング第7回に参加しました。 いつものごとく、自分用のメモをとっていたので。 第6回(2010/12)には参加してたのですが、あれからそういえば、話が無いなぁと思っていたところに 再開するという話がTwitterに流れてきたので、即申し込みしました。 思い返せば、Hadoopに興味をもって少し触っているところで参加したのだったなぁと感慨深い思いを思い出しました。\n今回は場所を変えて豊洲のNTTデータさんで開催されました。\n日時:2011/11/28(月)19:00~22:00 場所:豊洲センタービルアネックス NTTデータ\n◎アジェンダ+導入(NTTデータ 濱野さん) ちょっと間が空きましたが隔月で行う予定。 2012/01/12くらいに次回を予定。ネタ募集中。 ◎Hadoop World NYC 2011 参加レポート - NTTデータ 下垣 徹さん (Hadoop徹底入門著者の一人です!) ・イベント概要:2011/11/08~09にNYで開催 スポンサー企業の数がどんどん大きくなってる。 ・会場の様子 最初のキーノートは立ち見が出るほど。 個別に5並列でセッションが開催されてましたと。 ・キーノート紹介 1.Hadoop World(Michael Olson) アンケートからの概観 HadoopはNext Generation DataCenterだそうで。 2.JP Morgan(Larry Feinsmith) コスト削減+収入増加のためにHadoopつかうぞと。 BigData分析の戦略 ユースケース1:ETL(Extract/Transfer/Load)ツールとして ユースケース2:共通データ基盤 検索頻度が低いデータの低コストストレージなどなど。 ユースケース3:データマイニング 異常値検出とか。 3.eBay(E. Williams) Cassini:オークション情報の検索エンジン 柔軟な検索+協力なランキング機能 Hadoopで転置インデックス作成=Luceneは使ってるってことかな? HBaseも利用。データはHBaseに登録してる。 4.Informatica(James Markarian) データとプロセス Hadoopが賑わうからRDBMSも活気づく Hadoopはプラットフォームになるよと 5.Cloudera(Doug Cutting) Hadoopの背景と今後について BigDataを分散処理するためのカーネルになりつつあるよと。 Apacheプロジェクトの良さ 類似するプロジェクトも共存させてるよと。 Hadoopの今とこれから(0.20(今)、0.23(将来)) 0.23はHDFSの性能面改善、スケーラビリティの強化、HA MapReduce2.0 CDH4のはなし。 Hadoopコミュニティはまだまだ若い ・HadoopWorldの傾向 HBaseの利用増加 利用理由? 小さいレコードにも強い。 ランダムアクセス 大手ベンダ参加 Oracleすげー。Hadoopの周りを固めていくぞと。 Hadoopの周りを各社がどう固めていくかというはなし。 事例が多い WibiData:HBaseの利用事例。Fonedoctor Walt Disney:Big Dataに対する機会損失があるから、導入するよと。 テーマパークの交通流解析にも使うぞ! イケメンによる来年(2012年)のHadoop Worldの動向!? 参加者3000人! ラスベガスで開催? スポンサー拡大で食事が美味しく!? 全方位戦略vs.特化型 BIツールベンダの巻き込み 利用事例のアピール合戦 HBaseの利用事例が続々!(Salesforce.comあたりがセッション持つんじゃね?) Hadoop対抗アプリケーション、業界特化型キラーアプリケーションがますます増える? Mahout事例の増加 データマイニング+Web勉強会 - NTTデータ 政谷さんのHadoopNYでの発表のダイジェスト まずは印象。深く使っている人は去年より減っている。バズワードになってるからかな? 今後もHadoopコミュニティは健全なコミュニティになりそう。(いろんな所が出てきたけど、大丈夫そうだなぁ) ・発表スライドのダイジェスト版 日本でのHadoopの盛り上がりの話。 Hadoopと他との住み分けの話。 Sqoopのお話。PostgreSQLに向けたインテグレーションの話。これはPostしてコミット待ち。 Low-Latency Serving Systemへの受け渡し(前処理はHadoopでGPGPU使ってデータをクラスタリングして処理速度をあげる) FujitsuのETERNUSにHDFS APIが用意されたという話。 MapRの話に似ているよと。小さめのクラスタの場合に有効?セッションの後に少し話題になった。 扇子を配りましたよと。 ※ビールが配られ始めた!(ビールじゃないという声もチラホラw) ◎『Hadoop Troubleshooting 101』 セッションレポート - Cloudera 嶋内さん (@shiumachi) Hadoopを壊す7つの方法 Hadoop設定したりしたことある人?=結構いた。さすがソースコードリーディング Clouderaでは木曜日に重要なミーティング(ボードゲームするかFPSするか)というのがあるらしい。 チケット分析 設定ミス? HadoopやOSの設定ファイルの変更を必要とするあらゆるチケットの事 35%が該当 問題の原因別のグラフ 1番は設定ミス 2番はバグ(これはベータ版リリースからチケット管理してるから) メモリの管理ミス Task Out Of Memory Error io.sort.mb \u0026lt; mapred.child.java.optsとなるように設定すること io.sort.mb = mapバッファのサイズ mapperとreducerを減らす。 mapper=ノード上のコア数 これは机にはっとけ! Total RAM = (Mappers + Reducers) * Child Task Heap + DN heap + 3GB + RS heap + ? JobTracker Out Of Memory Error JTのメモリ使用量の合計 > 割り当てRAM 原因は? タスクが小さすぎ jobヒストリが多すぎ 解決は? maximumを減らしなさい? Unable to Create New Native Thread どういう意味? プロセスが起動中にもかかわらずDNが障害ノードとして表示されている。 原因は? nprocのデフォルト値が低すぎる 対応は? /etc/seurity/limits.confの値を考えろ Too Many Fetch-Failures 元スライドの発表者はこれが大好きらしい どういう意味? Reducerのfetch操作がmapperの出力の取得に失敗 ブラックリスト入りのTTで発生するらしい 原因は? DNSの問題 対応は? mapred.reduce.slowstart.completed.maps = 0.80 reducerの開始を遅らせることで対応 tasktracker.http.threads = 80 Jetty 6.1.26は使うな!CDH3u2に上げましょう。 Not Able to Place Enough Replicas 。。。きっとどっかにスライドあるからメモはこのへんでいいか。。。 ◎Hadoop World NYC 2011 参加レポート - Acroquest Technology 阪本 雄一郎さん (@frutescens) 落合 雄介さん (@taro_x) ・RとHadoopの融合(Revolution AnalyticsのDavid Champagneさん) R言語の紹介 Rとの接続点(rmr、rhdfs、?) R言語の利点がHadoopで使えるから、記述が少なくて済むよと。 統計処理がわからなくてもRが使えると分析ができるよ。(そう言われても、その分析で正しいのかとかは結局統計とかをある程度理解してないと厳しいんじゃないか?) ・Hadoopを使った衛星画像解析 スケールとかしたいからHadoopにしたけど、ジョブ起動遅いし、科学計算ライブラリが不十分 ・Hadoopをクラウド上に展開(vmware) Hadoopだけじゃなく、NoSQLとかもスケールしてから使いたいよねぇ。 ということで、vmwareの色々なものを使ってHadoopと他をうまく構築しますよ事例紹介。 マルチテナントのHadoopの話とかもありますよねと。 ◎最後はHadoopには関係ないのが多かったけどおみやげ争奪戦。 なぜか、MongoDBのシールをもらいました。 ということで、HadoopWorld2011の総括+各スライドの紹介でした。 これまでのHadoopWorldの傾向などから、参加者などのトレンドがどうなっているかなどの話が聞けたのが面白かったです。 ClouderaのスライドはHadoopのトラブルシューティングとして必見になりそうな感じでした。 内容が濃くて、それほど触っていない私にはわからないところもチラホラ。(日本語資料の公開されるかなぁ?) 案の定、ビール(発泡酒)を飲んだので、途中から一部が飲み会状態になってたし、ピザ食べてたので、私のメモも途中から適当になってしまいました。 あとは、とある件についていろんなかたからの知見を入手できたのが良かったですね。 他にもLilyプロジェクト(Solrが利用されているOSSの話)の話もあったようなのですが(HPの方が教えてくれました)、今回の参加レポートでは含まれてなかったです。(話聞きたかったなぁ。余力があれば、スライド読むかなぁ。誰か発表してくれないかなぁ) 今日もまた、Twitterで絡んでいた方たち数人と面識が得られました。 今後は定期開催の流れになるようなので、これからもHadoopにしがみついていくためにも参加するようにがんばりますよと。\n会場提供のNTTデータのみなさん、発表者の皆さんお疲れ様でした。次回も期待してます!!\n2011/12/01追記 Togetterのまとめ\n","date":1322499060,"dir":"post/2011/","id":"924727b6f380cf3cdfe5650163e92054","lang":"ja","lastmod":1322499060,"permalink":"https://blog.johtani.info/blog/2011/11/29/hadoop%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89%E3%83%AA%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0%E7%AC%AC7%E5%9B%9E%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-11-29T01:51:00+09:00","summary":"Hadoopソースコードリーディング第7回に参加しました。 いつものごとく、自分用のメモをとっていたので。 第6回(2010/12)には参加して","tags":["勉強会"],"title":"Hadoopソースコードリーディング第7回に参加しました。(Jugemより移植)"},{"contents":"先週末から勤労感謝の日まで風邪で寝こんでました。。。 みなさん、朝晩、冷え込みが激しいので風邪には気をつけてください。\n季節の言葉も入れたので本題です。 つい最近、「Apache Solr入門」のサンプルをlucene-gosenでどうやって動かすんですかー?という質問を受けました。 確かに、「Apache Solr入門」を書いたのはSolrのバージョンが1.4が出る直前でしたし、lucene-gosenは存在せず、 当時はSenを元にした日本語の形態素解析のサンプルとなっていました。 そのSenも入手しづらくなってきており、私もlucene-gosenのプロジェクトに携わるようになってきてある程度時間が 経ちました。 せっかくなので、サンプルのschema.xmlだけでも最新版(Solr 3.4 + lucene-gosen-1.2.0-ipadic)のものを用意しました。 なお、あくまでも、3.xでlucene-gosenを利用する場合の「Apache Solr入門」のサンプルプログラムの変更点(とりあえず、4章まで)の違いについて記述します。 申し訳ございませんが、1.4と3.xの違いについての説明はここでは行いません。\n以下では、各章でschema.xmlに関連する記載のある部分を抜粋して、変更点と変更したschema.xmlのリンクを用意しました。参考にしてもらえればと思います。\n1章 1.6.1 N-gram(17ページ) 1.6.1の手順に変更はありません。 サンプルプログラムが入っているZip「solrbook.zip」のintroduction/ngram/schema.xmlファイルの代わりに こちらのschema.xmlを利用してください。\n1.6.2 形態素解析(18ページ~20ページ中盤まで) 手順が大きく変わります。 Senを利用する場合、Senの辞書のビルド、Senのjarファイルの配置、Senを利用するためのTokenizerクラスを含んだサンプルjarの配置という作業があります。 lucene-gosenではコンパイル済みの辞書がjarファイルに含まれています。 また、Solr向けのTokenizerもlucene-gosenのjarファイルに含まれています。 lucene-gosenを利用して形態素解析を体験するための手順は次の流れになります。 なお、schema.xmlについては上記N-gramでダウンロードしたschema.xmlに形態素解析の設定もあわせて記載してあります。\njarファイル(lucene-gosen-1.2.0-ipadic.jar)をダウンロードして、$SOLR/example/solr/lib(libディレクトリがない場合は作成)にコピーします。 コピーが終わりましたら、次のように$SOLR/exampleディレクトリでSolrを起動します。 (-Dsen.homeは必要なし)\n$ java -jar start.jar あとは、書籍の記述にしたがって管理画面のAnalysis画面で動作を確認します。 ほぼ、図1-6と同じ結果になっていると思います。 (lucene-gosenで出力される情報には本書のサンプルよりも多くの情報が含まれています。また、サンプルでは、形態素解析の後の単語に基本形を採用しているため、「な」が「だ」として出力されています。基本形を出力する場合は後述するこちらで紹介したTokenFilterを利用すれば可能です。)\n2章 2.1.3 schema.xmlのバージョン(27ページ) Solr3.xではschema.xmlのファイルの最新バージョンは1.4になっています。\n2.2.3 代表的なトークナイザ(35ページ) solrbook.analysis.SenTokenizerFactoryは必要ありません。 先ほども説明しましたが、lucene-gosenにはSolr向けのトークナイザが用意されています。 solr.JapaneseTokenizerFactoryがそれに該当します。\n2.2.4 代表的なトークンフィルタ(37ページ) 以下の2つについてはlucene-gosenに同等のトークンフィルタが存在します。\nsolrbook.analysis.KatakanaStemFilterFactory solrbook.analysis.POSFilterFactory それぞれ、次のものがlucene-gosenにあるので、こちらを利用します。\nsolr.JapaneseKatakanaStemFilterFactory solr.JapanesePartOfSpeechStopFilterFactory 2章向けのschema.xmlはこちらです。その他のtxtファイルについては、特に変更はありません。\n3,4章は特に変更はありません。Solrの起動の仕方にだけ注意してください。(-Dsen.homeは必要ありません)\n以上が4章までの修正点になります。 動作しないなどあれば、コメントください。 サンプルアプリについてはまた後日余裕があれば。。。\n","date":1322244000,"dir":"post/2011/","id":"26d48d68b28f927bfebad454658f9425","lang":"ja","lastmod":1322244000,"permalink":"https://blog.johtani.info/blog/2011/11/26/apache-solr%E5%85%A5%E9%96%80%E3%81%AE%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%81%AElucene-gosen%E5%AF%BE%E5%BF%9C1%E7%AB%A0%E3%81%8B%E3%82%894%E7%AB%A0/","publishdate":"2011-11-26T03:00:00+09:00","summary":"先週末から勤労感謝の日まで風邪で寝こんでました。。。 みなさん、朝晩、冷え込みが激しいので風邪には気をつけてください。 季節の言葉も入れたので本","tags":["lucene-gosen"],"title":"「Apache Solr入門」のサンプルのlucene-gosen対応(1章から4章)(Jugemより移植)"},{"contents":"今回は、触ろうと思って触れていないMongoDBの勉強会に行って来ました。 2週連続の渋谷で、さすがに今回は出口をすんなりでれました。 今回は初のGMOさんのビルへの潜入です。 ということで、いつものごとく自分のメモを残しておきます。\n日時 :2011/11/15 14:30 to 20:00 定員 :140 人 会場 :GMO Yours (セルリアンタワー(11階)) ハッシュタグ :#mongotokyo\n1.fluentd plugins for MongoDB @doryokujin スライドはこちら。\nFluentとMongoDBのコラボレーション ・Fluentとは? 解析対象のログについて。データ量が膨大 これまでのログの扱い方。日次でS3に送信して、ログ解析サーバにて前日分を解析する。 これではリアルタイム性がないのが問題!しかも1日分なので、データ量が半端ない。 そこでFluentにてストリーミングアプローチ。 リレーサーバ(Fluentd)にログを流すと、適宜、解析サーバに流れていく仕組みが可能。 これにより、ネットワークに負荷をあまりかけずにログを定期的(時次とか)で流せる。 ※splunkに近い考えかな。 ここで、Fluentのスライドで説明が入りました。http://www.scribd.com/doc/70897187/Fluent-event-collector-update ・Out Mongo For Local Back-Up MongoDBへの出力。 信頼性をあげるためにローカルにmongoDBを置いておき、スプールしておく。 リレーサーバにも配置してみるという仕組み。 バッファリングにMongoDBを使うので Aggregation Mongoってのを作ったらしい。そのせいで、スライドの作成が遅れたらしいw ・Aggregation Mongo Map/Reduceの集約のようなプラグイン。 fluentdのアプリを通して、特定のキーをベースに集計してから、outputする仕組み。 更に、キーに対してshufleが行われて、次のfluentdにデータが集まる。 fluentdを使ってM/Rっぽいことが可能なのかな。 QA 最終的な流れ込み先のMongoDBはCappedCollectionじゃなくしたほうがいい。検索とかしたくなるから。 2.about Server Density and MongoDB @davidmytton スライドはこちら\nQueuingシステムで利用。 MongoDBとRabbitMQとの比較? MongoDB関連のノウハウかな。 データ量に関する話。メモリに載せたほうがいいのかとか、ログ出力の設定とか、ジャーナルとか。 HDDの見積もりに関連しそう。 健康状態の監視方法。 コネクションプールの話とか。 rs=ReplicaSet? mongostatってコマンドがあるのか。 ServerDensityのツールとダッシュボードなどについて。 ※英語のスライド見ながら話聞くとメモがとれない。 まとめ: Keep it in Ram インデックスはメモリに載せましょう。 Watch your Strage ストレージのサイズは監視しましょう。(ログ、データ、ジャーナルなどなど) db.serverStatus() コマンドあるよ。これで見れるデータが重要なのかな? rs.stats() コマンドあるよ。これで見れるデータが重要なのかな? QA:残念ながら聞き取れなかったっすw Q:MongoDBのクエリログの統計の質問。DBごと?=コレクションごと?のクエリ統計のとり方は? A:MongoDBにはないので、ログレベルを下げて統計取ったりする方法しかないかなぁ。 3.MongoDB: Case Study for AMN @koyhoge スライドはこちら\nサービス(アジャイルメディア・ネットワーク)で利用している実例について 広告配信に関連して利用してる。 最初にPostgreSQLにて実装。5分おきにCronで再起動するはめに。。。 PostgreSQLの次にSimpleDBへ(インサートが遅い。分散インサート) SimpleDB+SQSに変更。1日130$で断念。 SaaSなKVSはやめてMongoDBに移行してみる。 負荷も軽いし、インサートも速い! EC2でMongoDB。しかもレプリカを東京A、B、シンガポールAにしてみよう。 shardingは残念ながらうまく行かず。 ストレージはEBSの1TB 4.「MongoDBとHadoopの蜜月関係」 @muddydixon スライドはこちら\nお父さんエンジニアなので、土曜日の勉強会は無理です!=同じく辛いです! HadoopとMongoDBのつなぎについて。 MongoDBからデータを読み込んで、Hadoopで計算してMongoDBに戻すものがmongo-hadoop データロストがニュースになってて心配してる。データロストはめったにない(by @doryokujin) Hadoopを計算だけに利用できるのでクラスタが落ちても気にせず立ち上げができそう。 MongoDBからデータを取得する時点でフィルタリングが可能なので、Hadoopでの演算が楽。 AdHocなクエリをMongoDBに投げれるのがうれしいのかな? HBaseとかHiveに入れてやったりはダメなんかな? QA Q:なんで、みんなMongoDBにログ入れるの?@kzk_mover A:様々な形式を入れやすいから。 Q:捨てるのどーするの? A:コンパクションが大変(ただし、2.0以降は良くなる予定) Q:MongoDBのMap/Reduceは? A:時間がかかった上に死ぬというひどい目にあったので。。。 5.Fusion-io @hasegaw\n340の仮想マシンが4台で動きます! すごそう。。。一回は触ってみたいかも。 Fusion-ioすげーーーって感じ。(Ustストップ) 6.MongoDB on Cloud Foundry @yssk22\nVMWare社のPaaSオファリングの名称 感想など: mongoDBに興味はあるのに、腰が引けてるおじさんになって結局触らずに会場入りしてしまいました。 会場に入っていきなり、Treasure Dataの太田さんがマグカップを売っているという場面に遭遇するというインパクトがあるスタート。(思わず1個購入) 最初はMongoDB JPの主催者でもある@doryokujinさんの話から。今熱いfluentdとmongoDBの組み合わせに関する話で、面白かったです。 途中でfluentdを作っている古橋さんのスライドを用いてfluentdの解説まで入りました。 TL上では、その古橋さんが時々フォローを入れているという贅沢な流れ。 なんとなく仕組みはスライドなどを見ていたのですが、更に理解が深まりました。 次が、イギリスから来日されていた@davidmyttonさん(なんと24歳という若さ!)のお話。 残念ながら英語のヒアリングは微妙な私なので、あまり理解できなかったのですが、どうやら、MongoDBの運用でのTipsのお話だったようです。スライドを後で見なおしたほうがいいかな。 次は、実際のMongoDBを利用した事例の紹介。PostgreSQLから試行錯誤してMongoDB+AWSの組み合わせのお話。 やはり実例があると面白いですね。試行錯誤された部分があるので、非常にわかりやすかったです。 次が、HadoopとMongoDBの組み合わせのお話。HadoopのMap/Reduceの部分だけを利用して、データ保存先はMongoDBにしましょうという割りきった話でした。 いくつか疑問点がメモにもありますが、残念ながら質問する勇気なしという腰抜けっぷり(もうちょっと積極的にならないと。。。) で、このあとFusion-ioとCloud Foundryの話になるのですが、体力切れ+lucene-gosenのjavadocが古いことに気づいてしまい、作業をしながら聞いていたのであまり頭に残っていません。(ほんとに申し訳ない。。。) とまぁ、最近、Twitter上でいろんな人に絡みまくってまして、@doryokujinにも絡みまくってたというのもあり、今回参加することにしたという次第でした。 懇親会にも多くの人が残っており、良いコミュニティができてるなぁというのが正直な感想です。 各セッションでも@doryokujinさんが適宜QAなどのフォローをされていて感心しっぱなしでした。 あとは、Twitter上で会話をしていた方たちとも顔合わせができたので、大収穫でした。\n次は、少しでもいいので、触ってから参加することにしようかと思います。 来年1月にはMongo Tokyo 2012というイベントも開かれるようで、ますます注目を浴びていきそうですね。主催者もミドルウェアもw\nあ、そうそう、そんなMongoDBの勉強会でしたが、CouchDBの話もちらほら出てまして、CouchConf TOKYOというチラシも@Ijokarumawakさんから頂きました。こちらも1月開催のようです。\n追記: 戦利品の画像です。マグカップ(500円)以外は貰い物です。 なんと、このUSBにはMongoDBのコマンドやクエリのチートシート(PDF)が入ってました。びっくり!\n","date":1321376880,"dir":"post/2011/","id":"bda9a5da86ec9790262e14f953bbadcb","lang":"ja","lastmod":1321376880,"permalink":"https://blog.johtani.info/blog/2011/11/16/mongodb%E5%8B%89%E5%BC%B7%E4%BC%9A%E7%AC%AC7%E5%9B%9E%E3%81%AB%E8%A1%8C%E3%81%A3%E3%81%A6%E6%9D%A5%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-11-16T02:08:00+09:00","summary":"今回は、触ろうと思って触れていないMongoDBの勉強会に行って来ました。 2週連続の渋谷で、さすがに今回は出口をすんなりでれました。 今回は初","tags":["勉強会"],"title":"MongoDB勉強会(第7回)に行って来ました。(Jugemより移植)"},{"contents":"Solr本の武田さんから教えていただいたSplunkの イベントに行って来ました。 Splunkとは様々な機器のログなどを一箇所に集めてリアルタイムに検索、分析できるようにするための製品です。(ざっくりした説明ですが。。。) ちなみに、データ量が小さければフリー版も用意されています。 以前、話しを聞いていて気になっていた所イベントが開催されるということだったので参加してきました。 以下に、その時取ったメモを記載しておきます。いつものごとく、自分用のメモなので、役に立つかはわかりませんが。\nSplunk Live! in toyosu\n日時:2011/11/02 10:00-12:00 場所:豊洲\n1.挨拶+アジェンダ紹介 2.ビッグデータ取り込み、ロードマップ(Splunk Inc.)CEO Godfrey Sullivan 英語でした。。。 データの種類と量が大きくなってきてるのに、ツールが追いつかないし、回答するのもはやくしろと言われる。 非構造化データの例としてApacheのログが出ていた。 TimeSeriesのフラットファイルがsplunkのデータのインデックス。(No RDB=スキーマいらないよと。) ※ここが重要な点かもしれない。 リアルタイムに解析できるのが売り。Jubatusとの違いとか聞くと面白いかも。 Machine Data Engine=Splunk データの関連付けの方法がどんなものか? 事前のスキーマが不要=流しこむ前には定義が必要?だよね? ?No need to filter/forward?? デベロッパーフレームワークってなんだ?? Splunkbaseと呼ばれる場所にSplunk Appsと呼ばれるアプリケーションがある。色々な場所、OS、アプリで利用できるものらしい。 ?自動監視も学習する仕組みがある?? それとも定義するのか? あくまでもMachine Dataと言っている。これは、ユーザのリレーションの解析などはないということか? Leading Social Gaming Company=Zynga Introscopeのログバージョンに似てるかもなぁ。 Cloudベースのアプリの解析にも利用(saleforce) 色々な利用シーンのお話。 3.適用事例(独立行政法人理化学研究所) 和光と神戸で利用。10G程度のデータを扱ってる? ログから情報基盤を監視するのに利用している。 syslogベースでsplunkにログを送信している。 事例1:VPNに接続できない(接続数上限がある?) CISCOのログから解析 どの研究室で発生しているかも検索。 事例2:DHCPの接続ミス?(IPアドレスロスト) ここまでは問題が発生してからログを漁るという使い方。 事例3:LINK FLAPのアラート 短時間にUPDOWNを繰り返す場合にスイッチがおかしくなってるんでは? 事例4:メール大量送信(ウィルス感染) 不特定多数のサーバに短時間でメールを配信している ※使い方としては情報基盤環境すべて(ネットワークとかサーバなど)のログを集めておいて監視+解析に利用して障害対応などに利用している?データセンターとかに入れるのか? あくまでも、ログを保存して、検索できる仕組みが1箇所にまとめられているという感じ。 そのログの解析について(どういった問題に対して、どういったクエリを投げるか?どういったトラップを仕込むか?)は利用する側の腕にかかっている印象。 ※実際に触ってみたいなぁ。500M/dayか。ご近所に入れてみるか?syslogで転送設定+入れるサーバが必要。 4.最新アプリなどの紹介(Splunk Inc.) GUIがきれいだなー(最近のgoogleっぽいが。。。) リアルタイムにデータが入っているのが見えるのか。おもろいな。 どこのフィールドにヒットしたかがファセットで表示できるらしい。おもろい。 flashでできたビューがすごくおもろかったぞ。(ドキュメントどこだ?) 5.最新の取り組み(NTTデータ先端) やっぱり武田さんだった。 複数の監視システムのメッセージを統合して検索、アラートを出せるようにする。 消費電力を算出するためにログを集めて集計する。 6.QA ロードマップ ・2年以内にビジネスサイドでの利用に向けての動きを見せていく予定。 ・アプリケーションフレームワークにして、他のパートナーのアプリを載せていきたい。 ということで、感想ですが、事例紹介などを聴いた感じだと今のところはインフラ系のログを一元化して検索、監視、アラートをあげるということに活用するためのツールの用に感じました。 当初の使い方がそういったところにあるためだとは思いますが。 開発者としての視点で話しを聞いていて、活用できそうだというのは次のシーンでしょうか。\n開発時の開発環境のログ集約 性能試験などでのログ、性能データ集約 開発時点もしくは性能試験時ですが、色々なサーバ(DBやアプリサーバ)の時間を横串にして表示検索などができると思うので、問題があった時の各種サーバの状態を一元的に見れるため、どのサーバにどういった負荷がかかっていたか、 どこに問題があったかなどをグラフ化して見ることが簡単にできるのではないかなぁという感想です。 あとは、ログが一元化されているので、問題があったときにまずログを検索すればいいのが楽ですかね。\n基本的にはログが集まってるからあとは、どう使うかはご自由にという印象でした。 どのようなログを集めておき、どういったトラップでアラートさせるか、どのような検索をすれば望んでいるログが出てくるか、どのような集計をしたいかなどについては、やはり導入してからノウハウを貯めていくか、導入時にコンサルしてもらうなどが必要かと。 また、このツールを入れることでどのようなフィードバックをどのように活用できるかをイメージしていなければ、 宝の持ち腐れになりそうです。 あとは、使い方次第ですが、サーバログ以外にアプリログ(ユーザの行動履歴とか)などを入れることで、インフラ以外での使い道もありそうです。 とりあえず、保存しておいて、あとから特定の傾向を見出すのに検索できるのはちょっと面白いかも。\nあ、そうそう、ストラップとUSBメモリ(4G)のノベルティをお土産にもらいました。無料セミナーなのに。\n","date":1320822000,"dir":"post/2011/","id":"cc1a3b2f107510ac664e491d5f2412aa","lang":"ja","lastmod":1320822000,"permalink":"https://blog.johtani.info/blog/2011/11/09/splunk-live%E3%81%AE%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%81%AB%E8%A1%8C%E3%81%A3%E3%81%A6%E6%9D%A5%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-11-09T16:00:00+09:00","summary":"Solr本の武田さんから教えていただいたSplunkの イベントに行って来ました。 Splunkとは様々な機器のログなどを一箇所に集めてリアルタ","tags":["misc"],"title":"Splunk Live!のイベントに行って来ました。(Jugemより移植)"},{"contents":"最近忘れやすいので、記録しておこうかと。 読んだスライドの簡単な内容と感想です。 ちなみに、スライドの一覧はこちらです。 ※スライドへのリンクはすべてPDFへのリンクになっていますので、注意が必要です。\nSolr 4 Highlights(PDF)\nSolrの次期バージョン4.0で採用される機能の紹介でした。 紹介されているのは次の機能。各機能について、JIRAの番号も記載があるので便利ですね。\nDirectSolrSpellChecker NRT (Near RealTime search) Realtime Get SolrCloud - search side SolrCloud - indexing side (WIP) これまでと異なるSpellChecker、Commit前のデータが検索できるNRT(なんでNRSじゃないんだろう?)、Commit前の登録済みデータを取得することが出来るRealtime Getなどの簡単な紹介です。 あと、個人的に興味のあるSolrCloud周りが絵付きで紹介されてます。ZooKeeperもちょっと出てきます。 まだ、ちゃんとまとめてないですが、NewSolrCloudDesignの翻訳したものも参考までに。(その1、その2)\nArchive-It: Scaling Beyond a Billion Archival Web-pages\nInternetArchiveの事例紹介。1996年からWebページのアーカイブを行なっているサイトですね。 その一部でSolrが利用されています。 「1,375,473,187 unique documents」との記述もあり、データ量が巨大です。 データ量が多いのに、ここでFieldCollapsing/Groupingも利用しているようで、インデックス作成、検索両方に対してカスタマイズしたものをgithubで公開している模様です。\n[**Scaling search at Trovit with Solr and Hadoop**](http://www.lucidimagination.com/sites/default/files/file/Eurocon2011/MarcSturlese_scalingsearchTrovit_eurocon2011.pdf) 次は、Trovitという会社のSolr+Hadoopの事例紹介です。 最初はLuceneをベースに検索サーバ作ってたけど、Solrが出てきたので、Solrを使うようになったようで。 データ保存先として最初はMySQLを利用してDataImportHandlerでSolrにデータ登録してたけど、 データ量が増加するが、MySQLのShardingが面倒なので、Hadoop(Hive)でデータをパイプライン処理してSolrのインデックスを作成しましょうという流れになったようです。 私が以前、Solr勉強会で紹介したSOLR-1301のパッチをベースにMap/Reduceの処理を2段階にして性能をアップさせたという話が記載されてました。 ただ、これで早くなるのかはよくわからないんですが。。。 一応、資料では、いきなり大きなSolrのインデックスを作らずに、最初のM/Rで小さなインデックスを作成し(TaskTrackerの数>>Solrのshardサーバ数だから小さくしたほうが速い?)、 2段目のM/Rでインデックスをマージしてshardサーバ数のインデックスに集約する?という形みたいです。 (英語力のなさが。。。) あとは、テキスト処理を幾つかHadoopでやってますよという紹介でした。 SOLR-1301の利用者が他にもいて、違うアプローチをとっていたのが印象的。 毎回全データインデックス生成するときは、SOLR-1301を利用してshard数が増えてもすぐに対応が可能になるので、 かなり便利ですよ。\nSolr @ Etsy\nEtsyは個人の作家(編み物とかシールとか)の方が出店するためのショッピングモールのようなサイトです。 実は、最近、MacBookAirのステッカーを購入したのがここでした。 で、検索にSolrを使っています。 面白いのが、検索サーバとWebアプリ(PHPで書かれている)の間のデータのやり取りにThriftを利用していること。 Solrの前にThriftを話すサーバを別途用意しているようです。ネットワークのデータ量を減らすことが目的らしいです。 そのあとは、少しThriftのサーバでのLoadBalancingの話が続きます。 次にレプリケーションの性能問題のはなし。定期的にレプリケーションに異様に時間がかかるのが問題になったようで、 Multicast-Rsyncを試してみたけどダメでしたというはなし。 Bit Torrent + Solrという組み合わせで回避したらしいのですが、いまいち仕組みがわからなかったです。。。 こちらもgithubに公開されている模様。 あとは、QParser、Stemmerをカスタマイズしたものの話です。\nArchitecting the Future of Big Data and Search\nLuceneのカンファレンスにHortonworksが出てきてびっくりしました。 まぁ、Luceneの生みの親=Hadoopの生みの親ですから、問題ないのかもしれないですが。 大半が予想通り、Hadoopに関する話でした。 知らないApacheのプロジェクト「Ambari」というのが出てきました。これは、HadoopConferenceJapan2011 Fallでの発表にもチラッと出てきたようです。 「Ambari is a monitoring, administration and lifecycle management project for Apache Hadoop clusters.」ということで、Hadoopクラスタの統合管理のツールになるんでしょうか? 最後の2枚くらいにLuceneが出てきます。絡めてみたって感じですかね。\nConfiguring mahout Clustering Jobs\n今度はMahoutが出てきました。はやりのものが満載です。 まぁ、MahoutもLuceneのインデックスを利用するという話もありますので。 スライドはクラスタリングとはどういうものか、Mahoutの説明とテキストクラスタリング処理のお話、最後はstuckoverflowでのMahoutとSolrの活用の仕方について。\nということで、英語力がない中、かなり流し読みな感じですが、あとで思い出すために書きだして見ました。 何かの役に立てれば幸いです。\n他に、こんなスライドが面白かったとか、このスライドについても書いてほしいなどあれば、コメントください。\n","date":1320724920,"dir":"post/2011/","id":"d9c6ab5c6630a4a84e242c5765103d2d","lang":"ja","lastmod":1320724920,"permalink":"https://blog.johtani.info/blog/2011/11/08/lucene-eurocon-2011-barcelona-%E3%81%AE%E3%82%B9%E3%83%A9%E3%82%A4%E3%83%89%E8%AA%AD%E3%81%BF%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-11-08T13:02:00+09:00","summary":"最近忘れやすいので、記録しておこうかと。 読んだスライドの簡単な内容と感想です。 ちなみに、スライドの一覧はこちらです。 ※スライドへのリンクはす","tags":["solr"],"title":"Lucene Eurocon 2011 Barcelona のスライド読みました(Jugemより移植)"},{"contents":"Bookscanというサービスがあります。 書籍を電子化(PDF)して原本を破棄してくれるサービスです。\n電子書籍にはずっと興味を持っていました。 技術書を購入するのですが、技術書は300ページ超の大きな書籍が大半です。 また、日本語の技術書については、なかなか電子書籍が見つからないもしくは、電子化されるのが遅いとうのが現状です。 海外では、Manningなど、電子書籍も同時に発売(もしくは、製本前から電子書籍が売られている)サイトがありますが、やはり英語の書籍はハードルが高いなぁと。\nそんな中、Bookscanの噂を耳にしました。 ということで、どんどん、積ん読になっていく技術書だったので、思い切って、電子化してみることにしました。 ※残念ながらまだタブレット(電子書籍端末)は持っていないのですが。。。もうすぐ発売されるlenovoの7inchタブレットを待ちかねているところです。\nBookscanでは、1冊100円で書籍をPDFにしてくれます。(ページ数により変わってくる) この場合、あくまでも書籍をスキャンするだけで、検索などはできません。 OCR処理については別途1冊100円(これもページ数による)のオプションが必要になります。 詳しいサービス内容はこちらを御覧ください。 基本的には書籍をBookscanに発送してから約3ヶ月ほど電子化するのに時間がかかります。 これでは、すぐに見たい場合に手元にないという状態になってしまいます。 この電子化までの時間を短くできる、「プレミアム会員」というオプションが存在します。 月額固定の費用(9980円)を支払うことで、50冊(※ページ数により1冊の単位が異なります)まで無料で、「スキャン+OCR+書籍名をファイル名」のPDFファイルを書籍到着後1週間以内で作成してもらうことができます。 また、プレミアム会員は月単位での契約が可能なようで、1ヶ月(=50冊)だけ早く電子化してもらうといった利用方法もできるようです。\nで、実際にプレミアム会員となって49冊の書籍を送付して電子化してもらいました。 先週金曜日に発送、Bookscanに書籍が到着したのが翌土曜日、電子化が完了したのが火曜日の夜という感じでした。 すごくはやい!かなり感動してます。自炊自体をしたことがないので、出来上がりが自炊と比べてという比較はできないのですが、ざっと見ている感じでは全然問題なく読めそうです。\nただ、1冊の2ページだけ、ページの端が文章の途中で切れているPDFがありました。 この書籍に関しては、サポートサービスにお願いして、再スキャンをしてもらいました。 昨日夜に頼んで今日の午後には問題なく電子化されているというサービスの質でとても満足しています。 なお、原本の破棄が電子化後から10日後に行われるため、問題ないかの確認はそれまでに行う必要があるようです。 大量の本を送る場合は小分けに送ったほうが確認するのが楽になると思います。(送料は小分けにした分、かかってしまいますが。)\n書籍の山になっていた机がすっきりして、とても満足しています。 せっかく電子化したので、早くタブレットが欲しいなと思う今日この頃。。。 基本的には今後は電子書籍を購入するようにしていく予定なので、プレミアム会員を継続することはないと思いますが、 家に溜まっている漫画を電子化するのもありかなぁと思っているところです 漫画の場合はOCRに掛ける必要もないですし。\n個人的にはBookscanさんには悪いのですが、もっと電子書籍が増えると助かります。 技術書はページ数が多く、重たいうえ、実際に利用するときは検索したくなることが多々ありますので。 あとは、電子書籍を検索できるサイトがあるといいなと思ってもいるところです。 現在は、各出版社が個別に電子書籍のHPを持っている状況で、会社によっては検索すらできないです。 電子書籍があるかないかだけでも簡単に検索できると、いいなと思っています。(小説などはまた別なのかもしれないですが。) みんなはどう思ってるんですかねぇ?検索したくないですか?\n","date":1320225060,"dir":"post/2011/","id":"7a9609a971a8f31685e88da563eea5ce","lang":"ja","lastmod":1320225060,"permalink":"https://blog.johtani.info/blog/2011/11/02/bookscan%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-11-02T18:11:00+09:00","summary":"Bookscanというサービスがあります。 書籍を電子化(PDF)して原本を破棄してくれるサービスです。 電子書籍にはずっと興味を持っていました","tags":["misc"],"title":"Bookscanを使ってみました(Jugemより移植)"},{"contents":"lucene-gosenの最新版(1.2.0)をリリースしました。\nプロジェクトページよりダウンロードが可能です。\n新規追加機能についてはこちらのエントリを御覧ください。\nバグなどありましたら、容赦なく報告をいただけると助かります。\n","date":1320043560,"dir":"post/2011/","id":"14cf6e75aec1ead888e7101d3d94d28a","lang":"ja","lastmod":1320043560,"permalink":"https://blog.johtani.info/blog/2011/10/31/1-2-0%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9/","publishdate":"2011-10-31T15:46:00+09:00","summary":"lucene-gosenの最新版(1.2.0)をリリースしました。 プロジェクトページよりダウンロードが可能です。 新規追加機能についてはこちら","tags":["lucene-gosen"],"title":"1.2.0リリース(Jugemより移植)"},{"contents":"すぐやりますと言いつつ、はや1ヶ月。。。 腰が重い、ダメエンジニアですね。。。\nすみませんでした。。。 ようやくtrunkにコミットしました。 すぐにリリース版を用意すると思います。\n1ヶ月もあいてしまったので、追加した機能に関するまとめと、 用途別の利用方法を記載しておきます。 (lucene-gosenのWikiにもそろそろ書かないとなぁ。日本語でもいいから。)\n追加した機能\nこれまでのlucene-gosenはjarに辞書を含む形でライブラリを提供していました。 ただ、この場合、カスタム辞書を利用している環境ではカスタム辞書を修正し、ビルドしなおすたびに、 jarファイルを作成しなければなりません。 また、jarファイルをSolrなどに配布する必要も出てきます。 この手間を考慮して、辞書を外部ディレクトリで指定することができるようにしたものが 今回の修正になります。 また、修正の過程で同一VM内で異なる辞書を使えるようにする機能も副産物として生まれました。 今回追加した機能は次のようなものになります。 辞書を含まないjarのビルドおよび提供 ディレクトリ指定による辞書の指定 同一VM内での複数辞書の利用 辞書リビルド用のAntターゲットの追加 Lucene/Solr jarファイルの最新化(3.4.0対応) ディレクトリ指定による辞書の指定ですが、以下のような形になります。 まずは、LuceneのTokenizerでの指定方法です。 「辞書のディレクトリ」という引数が追加になっています。 ここに、辞書ディレクトリ(*.senファイルが存在するディレクトリ)を相対/絶対パスで指定します。\n... Tokenizer tokenizer = new JapaneseTokenizer(reader, null, \u0026#34;辞書のディレクトリ\u0026#34;); ... つぎは、Solrでの設定の方法です。 schema.xmlにて次のような設定を行います。\n... \u0026lt;fieldType name=\u0026#34;text_ja\u0026#34; ...\u0026gt; \u0026lt;analyzer\u0026gt; ... \u0026lt;tokenizer class=\u0026#34;solr.JapaneseTokenizerFactory\u0026#34; compositePOS=\u0026#34;compositePOS.txt\u0026#34; dictionaryDir=\u0026#34;辞書のディレクトリ\u0026#34;/\u0026amp;gt; ... \u0026lt;/analyzer\u0026gt; \u0026lt;/fieldType\u0026gt; ... schema.xmlの設定については、example/schema.xml.snippetにも説明がありますので、こちらもあわせて参考に。 なお、Solrの設定については、先ほどのLuceneでの辞書のディレクトリの指定方法(絶対/相対パス)に加えて、 $SOLR_HOME/conf からの相対パスでの指定も可能になっています。\nAntのターゲットについて\n辞書なしjarファイルを作成するターゲットなどを追加しています。 実際に追加したターゲットは以下のとおりです。 ターゲット名 説明 nodic-jar 辞書なしのjarファイルを生成するためのターゲット。辞書のダウンロード、コンパイルは行いません。 rebuild-dic lucene-gosenのビルド済み辞書(.senファイル)を削除してから辞書のコンパイル(ビルド)を行います。-Ddictypeにより辞書のタイプ(ipadic|naist-chasen)の指定が必要です。また、-Dcustom.dicsによりカスタム辞書の指定もあわせて可能です。 build-dic-ipadic テスト用に追加。-Ddictype=ipadicを指定してbuild-dicを実行。 build-dic-naist-chasen ついでに追加。-Ddictype=naist-chasenを指定してbuild-dicを実行。 最後の2つはあまり関係ありません。内部的に有ると便利だったため、作りました。 重要なのは最初の2つです。 ひとつめの「nodic-jar」は辞書を含まないjarファイルをビルドします。 このjarファイル+辞書の入ったディレクトリを利用することで、辞書の外部化が可能となります。\nそして、「rebuild-dic」です。こちらは、以前記事に書きましたが、カスタム辞書のコンパイルが思いの外面倒だったので、ターゲットを追加しました。 次のように指定することで、辞書のリビルドが可能です。\n$ ant -Ddictype=naist-chasen -Dcustom.dcs=\u0026#34;custom1.csv custom2.csv\u0026#34; rebuild-dic 提供されるjarファイルについて\n提供されるjarファイルは次のようになる予定です。 1番目のjarファイルが今回追加になる、辞書なしのjarファイルになります。\nlucene-gosen-1.x.x.jar lucene-gosen-1.x.x-ipadic.jar lucene-gosen-1.x.x-naist-chasen.jar 用途別の利用方法 利用用途別に利用するjarファイルやantのターゲットを利用シーンを交えて想定を書いてみます。 Solrでの利用シーンを想定します。\nお手軽に使う。辞書ありjarファイルで一発インストール。 これまでどおりの使い方になります。 辞書込みのjarファイルを利用すれば、すぐに利用可能になります。\nカスタム辞書を使い倒す。定期的に辞書をメンテナンス。 定期的にシステム固有の単語が増える(例:製品名、新語など)場合です。\n利用するjar:lucene-gosen-1.x.x.jar 辞書のコンパイル+配置:ant -Ddictype=naist-chasen -Dcustom.dics=\u0026ldquo;custom1.csv\u0026rdquo; rebuild-dir Solrの該当コアのRELOAD Solrのマルチコア環境を利用します。なお、sharedLib設定にlucene-gosen-1.x.x.jarを配置すると、辞書の再読み込みができないので注意してください。 設定は、上記のようにTokenizerFactoryの設定でdictionaryDirにて辞書のディレクトリを設定しておきます。 カスタム辞書に単語を追加後、antにて、辞書のリビルドを行います。 リビルドした辞書ファイルを必要に応じて対象の辞書ディレクトリにコピーします。(ビルド後のディレクトリをそのまま利用している場合はコピーの必要はないです。) 最後に、Solrの該当コアのリロードを行います。(リロードの仕方はこちらを参考に。) コアのリロードにより、辞書の再読み込みが行われるので、リロード後から新しい辞書が適用されます。\n異なる辞書を使い倒す。TokenizerごとにdictionaryDir設定するぞ 1つのSolrで異なる辞書を使ったフィールドを使いたい場合です。 ipadicとnaist-chasenといった異なる場合はあまり想定できないですが、カスタム辞書の部分が異なるという形が想定できるでしょうか。(例:製品名のフィールド、企業名のフィールド。。。など)\n利用するjar:lucene-gosen-1.x.x.jar 設定:schema.xmlに異なるdictionaryDirを設定したTokenizerFactoryを設定 上記、カスタム辞書の定期更新も一緒に行うことも可能です。コアをリロードすれば、リロードしたコアで利用している 辞書がすべてリロードされます。\n最後に 遅くなってしまいましたが、ようやく、trunkにコミットしました。 できるだけ速く、リリースしますので、もう少々お待ちを。\nSolrのconfディレクトリからの指定については、@shinobu_aokiさんにパッチを提供してもらいました。 また、trunkにコミットしていないパッチを適用して記事を書いてくれた方もいらっしゃいました。こちらもあわせて参考に。私より説明が上手です。 Java製形態素解析ライブラリ「lucene-gosen」を試してみる\n","date":1319559120,"dir":"post/2011/","id":"14a6d294550c9760aec57ba29682a750","lang":"ja","lastmod":1319559120,"permalink":"https://blog.johtani.info/blog/2011/10/26/%E8%BE%9E%E6%9B%B8%E3%81%AE%E5%A4%96%E9%83%A8%E5%8C%96%E3%81%A8lucene-solr3-4%E5%AF%BE%E5%BF%9C/","publishdate":"2011-10-26T01:12:00+09:00","summary":"すぐやりますと言いつつ、はや1ヶ月。。。 腰が重い、ダメエンジニアですね。。。 すみませんでした。。。 ようやくtrunkにコミットしました。 すぐ","tags":["lucene-gosen"],"title":"辞書の外部化とLucene/Solr3.4対応(Jugemより移植)"},{"contents":"JJUG CCC 2011 Fallに参加してきました。 個人的にはかなり久々のJavaのカンファレンスです。(※あくまで「Javaの」という話で。SolrやHadoopとは別という意味です。)\n概要やタイムテーブルはこちら。 予定があったので、残念ながら最後の2つのセッション(Scala、Twitter)しか参加できませんでした。 Hadoopの話も聞きたかったのですが、しょうがないかと。 いつものごとく、メモを個人的に取ったので。\n★楽々Scalaプログラミング 浅海 ◎OOPからOFPへの道しるべ ・関数型の使い所、プログラミングのコツ ・つながりの部分 ◎最近の活動 モデリングからモデル駆動によるソース生成などに利用。 Scala、2008年から使い始めている ◎Scalaと他の機能との比較図 ◎Scalaの用途 ・高い生産性 体感で3倍。コード量が少なくなる。 IDEのサポートを考えるとまだ、Java+Eclipseのほうが高い! ・DSL ドメインモデルの記述 フレームワークAPI ・並行プログラミング Many Core 消費電力的に複数のコアで動かす=関数型のほうが並行性が上がる(スレッドさわるJavaだけだときつい) Parallel Everything Object指向+関数型が扱いやすい。 ◎関数型言語とは ・公開関数をあつかえる 関数を値として扱える、引数と返却地に関数を渡せる。(やさしめ) <=> 数学(ラムダ計算、圏論など)的にプログラムを記述できる(きびしめ) ある程度使えるはず。厳しめの部分も ◎関数型言語の長所と短所 長所 ・高階関数を使った技が使える List(???) 短所 ・メモリ、関数実行オーバーヘッド、スタックの大きさが読めない(再帰的) ◎関数型言語の系譜 純粋関数型言語 pure Lisp 伝統的関数型言語 OCaml 新世代関数型言語 Haskell Scala 型クラス 代数データ型、モナド Parametric polymorphism ◎関数型でしたいこと DSL(Domain Specific Lanuguage) 昨年の資料を参考に! ◎準備 scalaの文法 ◎並列コレクション スレッドを利用しないで並列に動作実行させるか? ※List().par.map(sitelen).sum これで並行実行させられる。 ◎Future (これってJavaでもあるよね?=あるよ) 処理を非同期で先行実行し、あとから結果を取得可能 Scalaではアクターライブラリでサポート(cala.actors) 関数合成するとFutureの実行結果を取り出す所でブロックされる!! ◎Promise Futureより強力 関数合成すると、合成関数全体が非同期実行される! scalazを利用してた ◎5つのコツ コツ1: y=f(x) 引数がひとつの関数が基本 関数合成のビルディングブロックになるよ 引数が複数ある関数は他の関数(map関数とか)で合成しにくい 対処方法:カリー化(関数の戻りを関数とする) addc(a: Int)(b: Int) : Int = a + b とすることで、 コツ2:分割統治 コツ3:演算は転換 flatMapとかfoldLeftとか ※永続データ構造 前に作ったデータ コツ4:オブジェクトの世界と関数の世界を分ける 更新指示書の形でObjectに渡す? 関数型データ構造 コツ5:新しいデザインパターン 関数型プログラミングの用語 ・Functor(関手) ・Subgroup(半群) ・Monoid(モノイド) ・Monad(モナド) OOPのデザインパターン的に考えれば、数学的なところまで理解しなくてもよさそう? ★Twitterとオープンソース @yusukey http://dev.twitter.com http://bit.ly/tdt-ja id:twj_dev ◎OSSとの関わり 支援してます。 Apache、Eclipse、Open Invention、JCP、OpenJDK パフォーマンス系のためにもOpenJDKに参画してる ◎Twitter API オープンなAPIで無償提供 13言語でAPIライブラリがあるよ ◎Twitter4Jのこれまで ほぼ全てをカバー APIはだいぶ落ち着いてきていて、追加変更は少なくなってる。 ◎立ち位置 Twitterはコミュニティを活発にするためにもライブラリを出さないらしい。 ◎Twitter4Jのこれから キャッシング ストリーミングAPI利用を簡単に モックテスト レートリミットの影響を受けると辛いから。。。 ツイート/ユーザの永続化機能 jClouds対応? ライブラリからフレームワークへ 半公式ライブラリへ github/twitter/twitter4jへ JSR Social API Twitter4Jが参照実装に??? スケーラビリティの話。 Hadoopはユーザのデータ解析とかに使ってる。 メッセージはキューイングしている。デモ。 memcachedプロトコルなんだけど、値を取ると値が消えるよ。(memcachedとは動きが違うよねー。プロトコル的にはクライアントがいっぱいあっていいよねー) RubyのGCがきつかったのでJavaベースに変更 Kestrel(Scalaで記述。) Kestrelのフォーカス外 メッセージの順序保証(してないよ) トランザクション memcachedプロトコルの拡張1 ブロックフェッチ コンシューマから取りに行くというのが特徴 memcachedプロトコルの拡張2 リライアブルフェッチ ということで感想。\nScalaは前から気になっていて、本までかってるのになかなか手を付けられていない始末でした。 そんな時にこのJJUGの話があったので、ちょうどいいと聞きに。 関数型やScalaのぼんやりしたイメージのみを持って聴いていたのですが、思った以上にキーワードが多くてついていくのがやっとというイメージ。 で、いつものごとく、Twitterでつぶやいていた所、色々な反応が。(わからずにつぶやいたのもあり、波紋を呼んだ模様) お陰で、Scala関連の方たちをフォローできたので結果オーライでした。 話の内容自体はサラっとながす感じだったので、再度資料を見る+Scalaをもっと勉強しないと理解出来ないなぁという印象でした。 ちなみに、資料はこちら。\n次は、最近Twitterの中の人になった山本さん(@yusukey)の話しを聞きました。 Twitter4Jの話と、TwitterのOSSへの関わりの話。あとは、実際にTwitterが作成しているOSSのひとつKestrelについて。 TwitterはRubyベースで色々と作ってきていたのだが、Java(JVM上で動く言語(Scalaなど))に徐々にシフトしているというのが一番の印象です。あとは、Lucene、Hadoopなど私の興味のあるOSSも利用しているなど。 Kestrelについてはデモを交えながら、実際の動きを説明されていたのでとてもわかり易かったです。 プレゼン中もTweetを表示しながらという、さすがTwitterの中の人という印象でした。 Twitterでは少し前から知り合いだったのですが、実際にお会いできた(イケメンでしたよ!)のも収穫でした。 次はStormの話も聞きたいかなぁ\nで、2セッション(山本さんの話のあとにLT大会にも参加)だけですが、全体の感想を。 「クロスコミュニティカンファレンス」というだけあり、Java以外の話題(CouchDBとか名前がありました)もちらほらあったようです。 ただ、最近の他の勉強会やカンファレンスに比べると人が少ない印象でした。 私が参加したセッションは比較的大きな部屋だったせいもあり、40~50人くらい入っていたと思うのですが、ガラガラな印象でした。良い意味で、Javaも安定してきているため、参加者が少なかったのかなぁと あとは、年齢層がHadoopなどに比べると高めかなぁという印象(かく言う私も年齢層を上げている一人ですが。。。)。Javaも長いですからねぇ。 午前中から参加していると違った印象だったかもしれないですが。。。 あと、初めて行った会場で、しかも大きめの施設でした。午後の途中から行ったせいもあるかもしれないですが、 案内が出ていなくて若干迷子に。。。 ただ、セッションの部屋自体は各席に机があり、電源も比較的多めにあったので、PC持ち込みでメモを取るには最適でした。\n","date":1318922443,"dir":"post/2011/","id":"5d827a1e8ea70edb11d946b54f076cae","lang":"ja","lastmod":1318922443,"permalink":"https://blog.johtani.info/blog/2011/10/18/jjug-ccc-2011-fall%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%A6%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-10-18T16:20:43+09:00","summary":"JJUG CCC 2011 Fallに参加してきました。 個人的にはかなり久々のJavaのカンファレンスです。(※あくまで「Javaの」という話で。SolrやHad","tags":["備忘録"],"title":"JJUG CCC 2011 Fallに参加してきました。(Jugemより移植)"},{"contents":"昨日、文章から特定の単語(リストあり)を探したいという話を聞き、lucene-gosenでもできるねぇという話になりました。 まぁ、考えてみればごくごく当たり前なのですが。。。(その筋の方たちにしてみれば常識なのかもしれないですが。。。) 一応やってみたので、こんなこともできるなという一例ですということで、記録を残しておきます。\n今回の例文として野田首相の所信表明演説の一部を活用させてもらいます。 単語のリストは次のようにします。\n内閣総理大臣 正心誠意 東日本 日本 今回も結果をわかりやすくするためにSolrのanalysis画面を利用します。 作業手順は以下のとおり。\ndictionary.csvの編集 辞書のコンパイル fieldTypeの定義(Solrのschema.xmlの設定) 文章からキーワード抽出(Solrのanalysis画面) ### **1.dictionary.csvの編集** 今回はnaist-chasenディレクトリで作業します。 なお、今回利用するlucene-gosenは[ここ](http://johtani.jugem.jp/?eid=21)で紹介した辞書分離バージョンです。(はやくtrunkにコミットせねば。。。) dictionary.csvを先ほど上げた単語だけのエントリに変更します。 キーワードだけを抽出したいので、他の単語は必要ないからです。 ``` \u0026ldquo;内閣総理大臣\u0026rdquo;,1,名詞,一般,,,,,\u0026ldquo;内閣総理大臣\u0026rdquo;,\u0026ldquo;ナイカクソウリダイジン\u0026rdquo;,\u0026ldquo;ナイカクソウリダイジン\u0026rdquo; \u0026ldquo;正心誠意\u0026rdquo;,1,名詞,一般,,,,,\u0026ldquo;正心誠意\u0026rdquo;,\u0026ldquo;セイシンセイイ\u0026rdquo;,\u0026ldquo;セイシンセイイ\u0026rdquo; \u0026ldquo;東日本\u0026rdquo;,1,名詞,一般,,,,,\u0026ldquo;東日本\u0026rdquo;,\u0026ldquo;ヒガシニホン\u0026rdquo;,\u0026ldquo;ヒガシニホン\u0026rdquo; \u0026ldquo;日本\u0026rdquo;,1,名詞,一般,,,,,\u0026ldquo;日本\u0026rdquo;,\u0026ldquo;ニホン\u0026rdquo;,\u0026ldquo;ニホン\u0026rdquo;\n\u0026lt;/div\u0026gt; \u0026lt;div\u0026gt; ### **2.辞書のコンパイル** 先ほど作成した辞書をコンパイルし、lucene-gosen用バイナリ辞書を作成します。 $ cd $LUCENE_GOSEN_HOME¥dictionary $ ant -Ddictype=naist-chasen clean-sen compile\n\u0026lt;/div\u0026gt; \u0026lt;div\u0026gt; ### **3.fieldTypeの定義(Solrのschema.xmlの設定)** Solrのschema.xmlにlucene-gosenを利用するフィールドタイプを定義します。 追加するのは次の通り \u0026lt;fieldType name=\u0026quot;text_ja\u0026quot; class=\u0026quot;solr.TextField\u0026quot; positionIncrementGap=\u0026quot;100\u0026quot; autoGeneratePhraseQueries=\u0026quot;false\u0026quot;\u0026amp;gt; \u0026lt;analyzer\u0026amp;gt; \u0026lt;tokenizer class=\u0026quot;solr.JapaneseTokenizerFactory\u0026quot; compositePOS=\u0026quot;compositePOS.txt\u0026quot; dictionaryDir=\u0026quot;keyword-dic\u0026quot;/\u0026amp;gt; \u0026lt;filter class=\u0026quot;solr.JapanesePartOfSpeechKeepFilterFactory\u0026quot; tags=\u0026quot;keeptags_ja.txt\u0026quot; enablePositionIncrements=\u0026quot;true\u0026quot;/\u0026amp;gt; \u0026lt;/analyzer\u0026amp;gt; \u0026lt;/fieldType\u0026amp;gt; また、ここで定義しているcompositePOS.txt、keeptags_ja.txtは次のようになります。 compositePOS.txt 未知語\nkeeptags_ja.txt 名詞-一般\n未知語がバラバラに出現しないようにして見やすくするためと、必要な単語(今回は「名詞-一般」しか利用しないため。)だけを抽出したいための設定です。 \u0026lt;/div\u0026gt; \u0026lt;div\u0026gt; **### 4.文章からキーワード抽出(Solrのanalysis画面)** あとは、analysis画面で解析して見るだけになります。 ということで、辞書に登録された単語だけが抽出されてますね。 この例ではインデックスに登録となりますが。 ただし、「東日本」「日本」のような一部を含む単語の場合、「東日本」が見つかった場合は「日本」は抽出されません。 あくまでも、ベストな解が見つかるのみという形です。 すべての単語を出したい場合はもう少しやり方を考えたほうがいいかもしれません。 (まぁ、このやり方でキーワードを抽出するかも考えたほうがいいかもしれませんが。。。) \u0026lt;/div\u0026gt; 最近、頭が硬くなってきてるなぁと実感してしまいました。まぁ、こんな使い方もあるかなぁと。 もっと頭を柔らかくして問題を解けるけるようになりたいなぁと。 ","date":1318389420,"dir":"post/2011/","id":"b9d4f73fa7ca8ef66891554b66b2cded","lang":"ja","lastmod":1318389420,"permalink":"https://blog.johtani.info/blog/2011/10/12/lucene-gosen%E3%81%A7%E6%96%87%E7%AB%A0%E3%81%8B%E3%82%89%E3%82%AD%E3%83%BC%E3%83%AF%E3%83%BC%E3%83%89%E6%8A%BD%E5%87%BA%E3%82%A4%E3%83%AC%E3%82%AE%E3%83%A5%E3%83%A9%E3%83%BC/","publishdate":"2011-10-12T12:17:00+09:00","summary":"昨日、文章から特定の単語(リストあり)を探したいという話を聞き、lucene-gosenでもできるねぇという話になりました。 まぁ、考えてみれ","tags":["lucene-gosen"],"title":"lucene-gosenで文章からキーワード抽出(イレギュラー?)(Jugemより移植)"},{"contents":"ちょっと間があいてしまったが、ようやくIoの1日目を終了。 なれない感じの言語なので苦労しました。 今回もセルフスタディの私の回答が最後の方に記載されてます。見たくない人は気をつけてください。 ツッコミ大募集です。コメント欄にどしどしコメントください。そこは違うだろ?こっちのほうがいいのでは?という感じで。\n感想: プロトタイプ言語であり、すべての言語はクローンだそうです。\n○手始めに スロット、オブジェクトのクローンについて。 メッセージとその送信について。 あくまでもオブジェクトだけの世界。クローンであり、クラスのインスタンスではない。(まだつかめない。。。) ### ○オブジェクト、プロトタイプ、継承 slotNamesで取れないけど、継承してる。クローンで元をコピーしてるだけか? 頭文字が大文字かどうかがtypeかどうかの違い。大文字=type(クラスもどき=) オブジェクト=スロットの入れ物 オブジェクトのクローン=オブジェクトのチェーン?(Object => Vehicle => Car => ferrari) 疑問点: 存在しないスロット名をgetSlot()で呼び出したら?=>nilが返る 存在しないスロットをメッセージとして送信したら?=>Exceptionが出る ○メソッド method()で定義 メソッドもオブジェクト=スロットに入れることができる(まだつかめない。。。) メソッドをスロットから呼び出すと実行される。 ○リストとマップ リスト、マップは簡単。幾つか(スタックやキュー)のメソッドも用意されてる。 ○true、false、nil、singleton cloneメソッドを最定義することでsingletonの動作にする。(言われてみれば当たり前か) Object cloneをオーバーライドすることもできるが、プロセス停止などしないとダメ。(恐るべし。。。) ○インタビュー SIMD(Single Instruction Multiple Data)http://ja.wikipedia.org/wiki/SIMD やりながら感想: シンタックスが全然違うのでかなり戸惑い。 ただ、考え方はシンプル。slotとか。 まだ、予約語がわかってない(cloneとかprintとかslotNamesとか)ので。 ★セルフスタディ (探してみよう) ○Ioのいくつかの問題点の例 見つけられず。。。英語がダメダメ。。。 ○質問に答えてくれるIoコミュニティ\nML:http://tech.groups.yahoo.com/group/iolanguage/ twitter:http://twitter.com/#!/iolanguage **○Ioのイディオムに関するスタイルガイド** Io Note(英語) [http://iota.flowsnake.org/](http://iota.flowsnake.org/) Ioプログラミングガイド [http://iolanguage.com/scm/io/docs/IoGuide.html](http://iolanguage.com/scm/io/docs/IoGuide.html) [http://xole.net/docs/IoGuide_ja.html](http://xole.net/docs/IoGuide_ja.html)(日本語) Ioスタイルガイド [http://en.wikibooks.org/wiki/Io_Programming/Io_Style_Guide](http://en.wikibooks.org/wiki/Io_Programming/Io_Style_Guide) [http://d.hatena.ne.jp/katzchang/20080819/p1](http://d.hatena.ne.jp/katzchang/20080819/p1)(日本語訳してくれてるブログ) (確認してみよう) ○1 + 1を評価してから、1 + \u0026ldquo;one\u0026quot;を評価する。Ioは強く型付けされた言語か?\n``` Io\u0026gt; 1 + 1 ==\u0026gt; 2 Io\u0026gt; 1 + \u0026ldquo;one\u0026rdquo;\nException: argument 0 to method \u0026lsquo;+\u0026rsquo; must be a Number, not a \u0026lsquo;Sequence\u0026rsquo; message \u0026lsquo;+\u0026rsquo; in \u0026lsquo;Command Line\u0026rsquo; on line 1\nということで、型付けは強いです。 \u0026lt;/div\u0026gt; **○0は真か偽か?空文字列はどうか?nilは真か偽か?** \u0026lt;div\u0026gt; Io\u0026gt; 0 ==\u0026gt; 0 Io\u0026gt; true and 0 ==\u0026gt; true Io\u0026gt; true and \u0026quot;\u0026rdquo; ==\u0026gt; true Io\u0026gt; \u0026quot;\u0026quot; ==\u0026gt; Io\u0026gt; true and nil ==\u0026gt; false Io\u0026gt;\n0、空文字列はtrue、nilはfalseでした。 \u0026lt;/div\u0026gt; **○プロトタイプに存在するスロットを確認するにはどうすればよいか?** \u0026lt;div\u0026gt; Io\u0026gt; Highlander := Object clone ==\u0026gt; Highlander_0x1a233a0: type = \u0026ldquo;Highlander\u0026rdquo;\nIo\u0026gt; hoge := Highlander clone ==\u0026gt; Highlander_0x1a83630:\nIo\u0026gt; hoge proto slotNames ==\u0026gt; list(type) Io\u0026gt; Highlander name := \u0026ldquo;arnold\u0026rdquo; ==\u0026gt; arnold Io\u0026gt; hoge slotNames ==\u0026gt; list() Io\u0026gt; hoge proto slotNames ==\u0026gt; list(type, name) Io\u0026gt; Highlander slotNames ==\u0026gt; list(type, name) Io\u0026gt; hoge name ==\u0026gt; arnold Io\u0026gt; hoge getSlot(\u0026ldquo;name\u0026rdquo;) ==\u0026gt; arnold\nこんな感じ。slotNamesでスロット名を確認し、スロット内部についてはgetSlotで確認できます。 \u0026lt;/div\u0026gt; **○等号(=)、コロン等号(:=)および、コロンコロン等号(::=)の違いはなにか?どのようなときに使うか?** \u0026lt;div\u0026gt; \u0026lt;table class=\u0026#34;list_view\u0026#34;\u0026gt; \u0026lt;thead\u0026gt; \u0026lt;tr\u0026gt; \u0026lt;th\u0026gt;演算子\u0026lt;/th\u0026gt; \u0026lt;th\u0026gt;説明\u0026lt;/th\u0026gt; \u0026lt;/tr\u0026gt; \u0026lt;/thead\u0026gt; \u0026lt;tbody\u0026gt; \u0026lt;tr class=\u0026#34;spec\u0026#34;\u0026gt; \u0026lt;td\u0026gt;:::=\u0026lt;/td\u0026gt; \u0026lt;td\u0026gt;スロットへの代入+setterの追加\u0026lt;/td\u0026gt; \u0026lt;/tr\u0026gt; \u0026lt;tr class=\u0026#34;specalt\u0026#34;\u0026gt; \u0026lt;td class=\u0026#34;alt\u0026#34;\u0026gt;:=\u0026lt;/td\u0026gt; \u0026lt;td class=\u0026#34;alt\u0026#34;\u0026gt;スロットへの代入\u0026lt;/td\u0026gt; \u0026lt;/tr\u0026gt; \u0026lt;tr class=\u0026#34;spec\u0026#34;\u0026gt; \u0026lt;td\u0026gt;=\u0026lt;/td\u0026gt; \u0026lt;td\u0026gt;スロットへの代入(ただし、スロットが存在しない場合は例外が発生)\u0026lt;/td\u0026gt; \u0026lt;/tr\u0026gt; \u0026lt;/tbody\u0026gt; \u0026lt;/table\u0026gt; とまぁ、記載したが、実際に動かして確認しました。 Io\u0026gt; Highlander := Object clone ==\u0026gt; Highlander_0x223b800: type = \u0026ldquo;Highlander\u0026rdquo;\nIo\u0026gt; hoge := Highlander clone ==\u0026gt; Highlander_0x21acd60:\nIo\u0026gt; hoge slotNames ==\u0026gt; list() Io\u0026gt; hoge name ::= \u0026ldquo;arnold\u0026rdquo; ==\u0026gt; arnold Io\u0026gt; hoge slotNames ==\u0026gt; list(setName, name) Io\u0026gt; hoge sword := \u0026ldquo;long sword\u0026rdquo; ==\u0026gt; long sword Io\u0026gt; hoge slotNames ==\u0026gt; list(setName, name, sword) Io\u0026gt; hoge clothes = \u0026ldquo;armor\u0026rdquo;\nException: Slot clothes not found. Must define slot using := operator before updating. message \u0026lsquo;updateSlot\u0026rsquo; in \u0026lsquo;Command Line\u0026rsquo; on line 1\n\u0026lt;/div\u0026gt; ### (試してみよう) **○ファイルからIoプログラムを実行せよ** \u0026lt;div\u0026gt; ファイル「great.io」を作成し、以下を入力。 Highlander := Object clone Highlander giveWarCry := \u0026ldquo;Woooooooo!!\u0026rdquo; println Highlander giveWarCry()\nで、以下のコマンドを実行する。 $ io great.io Woooooooo!!\n\u0026lt;/div\u0026gt; **○スロットの名前を指定して格納されているコードを実行せよ** \u0026lt;div\u0026gt; Io\u0026gt; Masason := Object clone ==\u0026gt; Masason_0x20ae7d0: type = \u0026ldquo;Masason\u0026rdquo;\nIo\u0026gt; Masason recieveNiceTweet := method(\u0026ldquo;やりましょう\u0026rdquo; println) ==\u0026gt; method( \u0026ldquo;やりましょう\u0026rdquo; println ) Io\u0026gt; Masason getSlot(\u0026ldquo;recieveNiceTweet\u0026rdquo;) ==\u0026gt; method( \u0026ldquo;やりましょう\u0026rdquo; println ) Io\u0026gt; Masason getSlot(\u0026ldquo;recieveNiceTweet\u0026rdquo;) call やりましょう ==\u0026gt; やりましょう\ncallとgetSlotが鍵ですね。 \u0026lt;/div\u0026gt; 1日目の途中で間があいてしまったのでシンタックスを忘れてしまう始末。。。 ただ、そんなに込み入った記述もないので、最初に勉強することは少ないかもしれないです。 まだメソッドをあとから追加とか、cloneしたあとにまたプロトタイプを変更して反映可能など、考え方になれないもところがありますが、良い頭の体操になってます。 間を置かずに3日目まで行かないと!! ","date":1317990120,"dir":"post/2011/","id":"dc962e34780f0374b7eb3d583f6d7eb6","lang":"ja","lastmod":1317990120,"permalink":"https://blog.johtani.info/blog/2011/10/07/7%E3%81%A4%E3%81%AE%E8%A8%80%E8%AA%9E-7%E3%81%A4%E3%81%AE%E4%B8%96%E7%95%8C-io-1%E6%97%A5%E7%9B%AE/","publishdate":"2011-10-07T21:22:00+09:00","summary":"ちょっと間があいてしまったが、ようやくIoの1日目を終了。 なれない感じの言語なので苦労しました。 今回もセルフスタディの私の回答が最後の方に記","tags":[],"title":"「7つの言語 7つの世界」 Io 1日目(Jugemより移植)"},{"contents":"久々に、MBAの備忘録です。 あれから色々入れました。 なので、入れたソフトの一覧を追加。\nAIR:TweetDeckをインストールするのに必要だったため TweetDeck(AIR版):TwitterとFacebookを同じ画面で見ることができるため。 TextWrangler:テキストエディタ(まだあんまり使ってない) Skitch:Evernoteに買収されて無料に。先日のSolr管理画面の説明書きにもちょっと使用 ClamXav:フリーのセキュリティソフト。 SourceTree:Twitterで知ったMac用のgit、mercurialのクライアントソフト。AtlassianがSourceTreeを買収したのを機に一時的に無料公開されていたので。 Firefox:基本はSafariを使ってます。WindowsではChromeを使ってます。ただ、Webページを表示されていない部分もまるごとキャプチャするのにChromeのプラグインだとダメだったので入れました。今のところキャプチャ用のブラウザです。 Full Screen enable for Eclipse on Lion:Eclipseをフルスクリーン対応するためのプラグイン MercurialEclipse:bitbucketにアカウントをもっているので。 mercurial:pipを使ってインストール。MercurialEclipseでコマンドが必要だから。「sudo pip install Mercurial」 pip:mercurialをインストールするためにインストール。「sudo easy_install pip」でインストール iStat pro(ウィジェット):CPUなどの情報を表示するウィジェット。ウィジェットがアップルのサイト(AppStoreではない)から検索できるというのを人から聞いた。ウィジェットってあんまり使われないのか? Mac Blu-ray Player:現時点で有料ソフトはこれだけ。こちら。もともとNASのデータのバックアップ用にBlu-rayのドライブ買ったんですが、せっかくだからMacにも使ってみようと思い、MacでBlu-rayを見るために購入しました。所用で長距離移動もあったので、新幹線で映画見てました。 このくらいです。 ほんとはリンクを貼ればいいのですが、そこまでの元気がないので、ご勘弁を。\nSkitchがおすすめです。簡単に画像編集+説明書きが入れられて、矢印などがよくある画像編集の野暮ったさがないので、画面キャプチャに説明書くのに今後活躍する予定です。\nあと、ソフトではなく、サービスなのですが、Cacooというサービスが便利です。 ここ最近、ちょっとした作図にはこのサービスを使うようにしています。オンラインで利用できるので、いろんな場所で編集できます。 また、図の作成もさることながら、図を共有することが可能です。 先日は、lucene-gosenが思ったように動かないという相談を受けて、このCacooでanalysis画面や設定をを貼ってもらったりしながら使いました。結構便利ですね。 ただ、付属のチャットを使ったのですが、このチャットの内容がテキスト形式でコピー出来なかったのが残念でした。今後の改修に期待ということで。\nあと、セットアップとは少し違いますが、ジャケット買ってつけました。 ステッカーを直接貼るのがちょっと気になったので、ジャケットつけてステッカーを貼ってます。 ただ、ステッカーは思ったよりチープな感じが。。。ジャケットの中に貼らないとダメだったかも。まぁ、それが嫌でジャケット買ったんですが。。。 エアージャケットセット for Macbook Air 13inch(クリア)PMC-81 ","date":1317968700,"dir":"post/2011/","id":"de1ab82817c0fb24e591b9a89a82f736","lang":"ja","lastmod":1317968700,"permalink":"https://blog.johtani.info/blog/2011/10/07/mba%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97%E5%82%99%E5%BF%98%E9%8C%B2%E3%81%9D%E3%81%AE%EF%BC%94/","publishdate":"2011-10-07T15:25:00+09:00","summary":"久々に、MBAの備忘録です。 あれから色々入れました。 なので、入れたソフトの一覧を追加。 AIR:TweetDeckをインストールするのに必要だ","tags":["備忘録"],"title":"MBAセットアップ備忘録その4(Jugemより移植)"},{"contents":"Lucene/SolrのMLでSolrの管理画面を新しくするというチケットが流れていたのでちょっと触って見ました。 ほんとにちょっと触っただけですが、いくつかキャプチャ撮ってみたので、アップしときます。 ※以下ではサムネイル画像に元画像(100Kくらいの画像)へのリンクが設定されています。携帯などでは見づらいかもしれませんが、ご容赦を。\nURLは旧管理画面とことなり、http://localhost:8983/solr/になります。\nまずはトップ画面 ダッシュボードと呼ばれるトップ画面。メモリの利用率や起動してからの時間、Luceneなどのバージョンが表示されます。 次は検索画面すっきりしてます。facetが指定できるようになったのは大きいかな。ただし、facet.fieldを複数指定などができないが。結果についてはとくに指定がなければXMLで帰ってきます。ただ、パラメータの追加ができなくなってる気がするなぁ ちなみに、Solrを止めて検索したらこんな感じの画面になりました。クエリの実行ならこのようにエラーがわかったのですが、停止後に左のメニューにあるSchemaなどをクリックしても白い画面が出るだけで、エラーかどうかがわかりにくいです。 Analysis画面。入力画面がシンプルになりました。フィールド名はリストで表示されるので選択するだけです。あとは、これまでどおり。サンプルはlucene-gosenの解析結果です。ハイライトもきちんと表示されます。ただし、長い文章の場合は結果部分だけがスクロールできる形になり、ちょっとわかりにくかったです。 Analysisの入力画面を表示したあとにSolrを停止して解析してみたらこんなエラー画面が出ました。ちなみに、その後、画面を切り替えずにSolrを起動して解析したら、赤い帯のエラーは出たままでした。一度別画面にすれば、元に戻りますが。 Pluginsの画面(旧管理画面のstatisticsに相当)。 キャッシュの状態が確認できます。今まであった画面と情報的には一緒かと。一段カテゴリ(CACHEとかCOREとか)の選択ができるようになり、見やすくなりました。 同じくPluginsの画面。 こちらはupdateHandlerについての情報です。commit数やoptimizeの回数、updateして、commitする前の状態のドキュメント数などが表示されます。前より表示される項目が多くなってるかな? 最後はスキーマブラウザこの画面が一番良くなっています。旧管理画面では、フィールド名がすべて大文字で表示され、しかもソートがされていない状態だったため、ダイナミックフィールドを利用しているとフィールドを探すのが一苦労でした。 今回は、プルダウンでフィールドやフィールドタイプのリストが表示され、辞書順で並んでいます。Filterなどもわかりやすい表示になっているかと。 おまけ Solritasと呼ばれるVelocityを使った、3.x系で入ってきた新しいサンプル画面です。URLはhttp://localhost:8983/solr/browseです。ファセットなどを使った簡単なサンプル画面なので、検索結果画面でこんなことができるというデモにも使えるかと。ただ、これも旧管理画面よりはましですが、デザインが。。。 とまぁ、簡単ですが、4.x系の管理画面をいくつか触ってみて、キャプチャをとって見ました。 デザインは前よりもすっきりしています。ただ、クエリについてはパラメータの追加ができなくなっているので、もう少し改良されるといいかなぁ(自分でやれよと言われそうですが。。。)\n","date":1317811380,"dir":"post/2011/","id":"09677934e13a5d728f00c6ed7c8870a9","lang":"ja","lastmod":1317811380,"permalink":"https://blog.johtani.info/blog/2011/10/05/solr%E3%81%AE%E6%96%B0%E3%81%97%E3%81%84%E7%AE%A1%E7%90%86%E7%94%BB%E9%9D%A2solr4-x-trunk%E7%B3%BB/","publishdate":"2011-10-05T19:43:00+09:00","summary":"Lucene/SolrのMLでSolrの管理画面を新しくするというチケットが流れていたのでちょっと触って見ました。 ほんとにちょっと触っただけ","tags":["solr"],"title":"Solrの新しい管理画面(Solr4.x trunk系)(Jugemより移植)"},{"contents":"遅くなりましたが、続きです。 さらに英語力のなさを痛感して凹んでいるところですが、何かの役に立てばと恥を晒すところです。。。\n一応、訳してみたのですが、訳すのに必死になってしまい、つながりがわかっていない点もちらほら。 このあと一旦見直しつつ、再度理解する「理解編」をアップしようかと思います。 できれば、シーケンス図とかも交えつつ。(そうしないと理解ができない可能性が。。。) 前回同様、原文は最後に付加しておきます。\nBoot Strapping Cluster Startup(クラスタの起動) ノードはZookeeperのホストとポートを指定することから始めます。 クラスタの最初のノードはクラスタのschema/configとクラスタの設定を指定するとこから開始します。 最初のノードはZookeeperに設定をアップロードしてクラスタをブートします。 クラスタは「ブートストラップ」状態です。 この状態ではノード-\u0026gt;パーティションマッピングは計算されず、クラスタはクラスタ管理コマンド以外のどんなread/writeリクエストも受け付けません。\nクラスタの最初のノード集合が起動した後、クラスタ管理コマンド(TBD記述???)が管理者によって発行されます。このコマンドは整数「partitions」パラメータを受け取り、次のステップを実行します。\nCluster Lockを取得 「partitions」をパーティション数として割り当て 各パーティションのためのノードを取得 ZooKeeperのノード-\u0026gt;パーティションマッピングを更新 Cluster Lockをリリース 全ノードに対して最新版のノード-\u0026gt;パーティションマッピングをZooKeeper経由で更新させる Node Startup ノードが起動すると、自分がすでに存在するシャードの一部かどうかZooKeeperでチェックします。 もし、ZooKeeperがノードのレコードを持っていない、またはどのシャードの一部でもないと判断したら、 ノードは後述の「New Node」のステップを実行します。すでに存在するノードの場合は後述の「Node Restart」のステップを実行します。\nNew Node\n新しいノードはクラスタの一部ではなく、クラスタのキャパシティを増強するためのものです。\n「auto_add_new_nodes」クラスタプロパティが「false」の場合、新しいノードはZooKeeperに「idle」として登録され、他のノードが参加してくれと言うまで待機します。 そうでない場合(auto_add_new_nods=true)は次のステップを実行します。\nCluster Lockを取得します。 適切なnode-\u0026gt;partitionエントリを選び出します。 利用可能なパーティションのリストをスキャンして「replication_factor」のノード数以下のパーティションのエントリを探します。複数ある場合はノード数が最小のエントリを選びます。それも一緒ならランダムに選びます。 全パーティションが「replication_factor」以上のノードを持っている場合、ノードはパーティションが最も多いものをスキャンします。複数ある場合はパーティション内のドキュメント数が最大のエントリを選びます。ドキュメント数が同一なら任意のエントリを選びます。 もし、選んだノード-\u0026gt;パーティションエントリを現在のノードに移動させることでがクラスタのパーティション:ノード比率の最大値を小さくするなら、現在のエントリを返します。。それ以外の場合選ばれたエントリがないので、アルゴリズムは終了です。。 ZooKeeper内のノード-\u0026gt;パーティションマッピングを更新します ZooKeeper内のノードステータスを「リカバリ」状態にします Cluster Lockをリリースします 「リカバリ」はパーティションのリーダーから開始します。 リカバリが終了したら、再度、Cluster Lockを取得します。 元のエントリはZooKeeperのノード-\u0026gt;パーティションマッピングから削除されます。 Cluster Lockをリリースします 元のノードはZooKeeperからノード-\u0026gt;パーティションマッピングを更新させられます ステップ1に戻ります。 Node Restart ノードの再起動とは次のいずれかを意味しています。\nJVMがクラッシュし、手動または自動でのリスタート ノードが一時的にネットワークから切り離された。もしくは、ZooKeeperに接続できなかった(死んでいると思われた)。または、ある一定期間、リーダーからの更新を受信できなかった。 このシナリオが表す書き込み処理のライフサイクルの間にネットワークから分断された ハード故障もしくはメンテナンスウインドウによりクラスタからノードが分断され、ノードをクラスタにrejoinさせるために起動した。 ノードが各パーティションに対してメンバーであるパーティションのリストを読み、パーティションのリーダーがリカバリプロセスを実行する。その時、ノードは「auto_add_new_nods」プロパティをチェックして、「New Node」処理のステップを実行する。 これはクラスタが。。。(元の文章が切れてて意味が不明)\nクライアントは標準的なSolrの更新形式を利用して書き込みできます。 書き込み処理はクラスタの任意のノードに送信されます。 ノードはハッシュ関数を利用して、どのパーティションに所属するか決めるためにrange-パーティションマッピングを使います。 ZooKeeperはシャードのリーダーを識別して、書き込み処理をそこに送ります。 SolrJはリーダーに対して書き込みを直接送信するための拡張がされています。\nリーダーはPartitionバージョンの操作を割り当て、そのトランザクションログの操作を書き込み、シャードに属する他のノードにドキュメントバージョンハッシュを転送します。 ノードはインデックスにドキュメントハッシュを書き込み、トランザクションログに操作を記録します。 リーダーは、min_writesの最小数のノード以上のノードが「OK」とレスポンスを返したら「OK」とレスポンスを返します。 クラスタプロパティのmin_writesは書き込みリクエスト時に指定することで、異なる値を指定できます。\nクラウドモードはコミット/ロールバック操作を明示的には行いません。 コミットは特定の間隔で(commit_within)リーダーによりオートコミットにより管理されます。 また、シャードの全メンバーのコミットはトリガーにより管理されます。 ノードが利用可能な最新バージョンはコミットの時点で記録されます。\nTransaction Log トランザクションログは2つのコミットの間にインデックスに対して実行された操作全てを記録したもの コミットはそれ以前に実行された操作の耐久性を保証するために、新しいトランザクションログを開始します。 同期は調整が可能です。例えば、flush vs fsynです。fsyncがデフォルトで、JVMクラッシュに対して保証できるが、電源異常の場合には保証できないが、速度的には早いです。 Recovery 次のトリガーにより復旧が可能です。\nBootstrap パーティション分割 クラスタの再構築 ノードは自身に「recovering」というステータスを設定して復旧を開始します。 このフェーズの間、ノードは読み込みリクエストを受けることができませんが、トランザくkションログに書きこまれるすべての新しい書き込みリクエストを受け取ります。 ノードは自身が持つインデックスのバージョンを調べて、パーティションの最新バージョンのリーダーに問い合わせます。 リーダーはシャード内の残りのノードと同期する前に実行されるべき操作の集合を返します(???)。\n最初にインデックスをコピーし、最新のノードにあるトランザクションログをリプレイします。 もし、インデックスのコピーが必要ならば、インデックスファイルをローカルにまずコピーし、その後トランザクションログをリプレイします。 トランザクションログのリプレイは通常の書き込みリクエストの流れと同じです。 この時、ノードは新しい書き込みを受け付けるかもしれません。その書き込みはインデックスに再生されるべきです。 ある時点でノードは最新のコミットポイントに追いつき、自身のステータスを「ready」にします。 この時点で、このノードは読み込みリクエストを処理できます。\nHandling Node Failures 一時的にネットワークが分断され、幾つかのノードとZooKeeperの間の通信が遮断されるかもしれません。 クラスタはデータの再構築(リバランシング)の前にしばらく待ちが発生します。\nLeader failure\nノードが故障し、もしそれがシャードのリーダだった場合、他のメンバーがリーダー選出のプロセスを開始します。 新しいリーダーが選出されるまで、このパーティションへの書き込みは受け付けられません。 この時、これはリーダー以外の故障ステップを処理します。(???)\nLeader failure\nシャードの一部に新しいノードが割り当てられる前にリーダーはmin_reaction_timeの間待ちます。 リーダーはCluster Lockを取得し、シャードの新規メンバーとしてノードを割り当てるためのノード-シャード割り当てアルゴリズムを使用します。 ZooKeeperのノード-\u0026gt;パーティションマッピングが更新され、Cluster Lockがリリースされます。 新しいノードはZooKeeperからノード-\u0026gt;パーティションマッピングを強制的にリロードされます。\nSplitting partitions 明示的なクラスタ管理コマンドもしくはSolrによる自動的な分割戦略(ストラテジ)はパーティションを分割することができます。 明示的な分割コマンド(split command)は対象となるパーティションを分割するために実行されます。\nパーティションXが100から199のハッシュの範囲を持つものとし、X(100から149)、Y(150~199)に分割するとします。 Xのリーダーは、XとYの新しい値の範囲をZooKeeperに分割アクションを記録します。 ノードはこの分割アクションもしくは新しいパーティションの存在については通知を受けません。(???)\nXのリーダはCluster Lockを取得し、パーティションY(アルゴリズムはto be determined)を割り当てるノードを決定し、新しいパーティションを知らせ、パーティション-\u0026gt;ノードマッピングを更新します。Xのリーダはノードのレスポンスを街、新しいパーティションがコマンドを受付可能な状態になったら次の処理を実行します。 Xのリーダーは分割が完了するまですべてのコミットを停止します。 Xのリーダーは最新のコミットポイント(バージョンVとする)のIndexReaderをオープンし、同じバージョンのIndexReaderもオープンするように命じます XのリーダーはYのリーダーに対してバージョンV以降のトランザクションログのうちハッシュ値の範囲が150から199のものを流します。 Yのリーダーはトランザクションログの#2(#3の間違い?)で送られたリクエストだけを記録します??? Xのリーダーはステップ#2で開いたIndexReaderに対してインデックスの分割を開始します。 #5で作成されたインデックスはYのリーダーに送られ、登録されます。 Yのリーダーは「recovery」プロセスを開始するように(シャードの)他のノード命令し、インデックスのトランザクションログを再生し始めます。 パーティションYのすべてのノードがバージョンVに到達したならば YのリーダーはXのリーダーに#2で作成されたReaderの上に、ハッシュの範囲が100から149だけに属しているドキュメントを抽出するようにするFilteredIndexReaderを準備するように頼みます。 Xのリーダーは#8aのリクエストが完了したのを検知したら、YのリーダーがCluster Lockを取得し、クラスタ全体の検索/登録リクエストの受信を開始するためにレンジ-\u0026gt;パーティションマッピングを変更します。 YのリーダーはXのリーダーに検索リクエストのために#8aで作成されたFilteredIndexReaderの利用開始を頼みます YのリーダーはXのリーダーに、ZooKeeperからレンジ-\u0026gt;パーティションマッピングを矯正リフレッシュするように頼みます。この時点で#3で開始されたトランザクションログの流しこみが停止されるのが保証されます。 Xのリーダーは自身のパーティションに存在するべきでないハッシュ値をもつドキュメントを削除し、最新のコミットポイントのsearcherを再度開きます。 この時点で分割は完全に終了し、Xのリーダーはcommit_withinパラメータによるコミットをレジュームします(???) Notes:\n分割操作が完了するまで、commit_withinパラメータによるパーティションの分割は実行されない #8b開始から#8c終了までの間の分散検索は一貫しない検索結果を帰す場合がある(例えば:検索結果が異なる) Cluster Re-balancing クラスタは明示的なクラスタ管理コマンドにより再構築(リバランシング)できる。\nTBD (to be determined)\nCluster Re-balancing TBD (to be determined)\nConfiguration solr_cluster.properties これはクラスタ内の全ノードにわたって適用される一般的なSolr設定ファイルとは別のプロパティファイルの集合である。\nreplication_factor:クラスタによって管理されるドキュメントのレプリカの数 min_writes:書き込み操作が成功になる前の最小の書き込み????。これは書き込みごとに上書き設定可能 commit_within:検索に現れるまでの書き込み操作の最大回数 hash_function:ドキュメントのハッシュ値を計算するための関数の実装 max_hash_value:ハッシュ関数が出力することができる最大値。理論的には、この値はクラスタが保持できるパーティションの最大数でもある min_reaction_time:起動、停止の後に再配分/分割にかかる時間(??) min_replica_for_reaction:レプリカノード数がこの値以下になったら、min_reaction_timeにならなくても分割が実行される。 auto_add_new_nodes:booleanフラグ。もしtrueなら新しいノードは自動的にパーティションからレプリカを読み込む。そうでない場合は新しいノードはクラスタに「idle」状態で登録される Cluster Admin Commands すべてのクラスタ管理コマンドはすべてのノードでパス(/cluster_admin)を与えることで実行できます。 全ノードは同じコマンドを受け付けることができ、振る舞いも同じものになるでしょう。 以下のコマンドはユーザが利用できるパブリックなコマンドです。\ninit_cluster:(パラメータ:パーティション)このコマンドはノードの集合の初期化後に実施されます。このコマンドが実行されるまで、クラスタは読み込み/書き込みコマンドを受け付けません。 split_partition:(パラメータ:パーティション(任意))パーティションを2つに分割します。もしパーティションパラメータが指定されない場合は、ドキュメント数が最大の add_idle_nodes:このコマンドはauto_add_new_nodes=falseの場合に利用できます。このコマンドはクラスタに対して「idle」状態のすべてのノードを追加するトリガーとなります。 move_partition:(パラメータ:パーティション、from、to)fromのノードからtoの別のノードに引数で指定されたパーティションを移動します。 command_status:(パラメータ:completion_id(任意))上記コマンドはすべて非同期で実行され、completion_idを返します。このコマンドは特定の実行中のコマンドもしくは全ての実行中のコマンドの状態を表示するために利用できます。 status:(パラメータ:パーティション(任意))パーティションのリストを表示し各パーティションの次の情報を表示します。 リーダーノード ノードのリスト ドキュメント数 平均読み込み回数(reads/sec) 平均書き込み回数(writes/sec) 平均読み込み時間(time/read) 平均書き込み時間(time/write) Migrating from Solr to SolrCloud クラウドに移行するときに幾つかの特徴は不要かもしれないし、サポートされないかもしれません。 既存の(クラウドでない)バージョンでのすべての特徴をSolrCloudでサポートし続けなければなりません。\nレプリケーション:これは必要ありません。 CoreAdminコマンド:明示的なコアの操作は許可されません。内部にコアがあるかもしれないが、暗黙的に管理されるでしょう 複数スキーマのサポート?:単純化のため、ver1.0ではサポートしないかもしれない solr.xml:SolrCloudでほんとに必要? Alternative to a Cluster Lock リーダーを選出する常設の調停ノード(masterはインデックスレプリケーションで利用している用語なので、「調停」とする)を持つほうが単純かもしれません。 「truth」状態をZookeeperの状態としてみなすような次のパターンでは、将来の柔軟性(クラスタを制御するためのZookeeperの状態を直接変更するような外部管理ツールのような)を考慮に入れることができます。 (毎回ロックを取得するよりも)調停ノードを持つことにより、よりスケーラブルになるかもしれません。 特定条件下でのみCluster Lockを利用するハイブリッドも意味があるでしょう。\nSingle Node Simplest Use Case 単一ノードでスタートして、ドキュメントをインデックス登録できないといけません。 また、あとで、クラスタに2番目のノードを追加できないと行けません。\n1つのノードから開始し、最初にZookeeperに設定ファイルをアップロードし、shard1にノードを作成+登録します。 他の情報がない状態で設定が作成され、1つのシャードのシステムとなります。 いくつかのドキュメントをインデックスします 他のノードが起動し、「まだ割り当てられていない場合、レプリカの最小の数をもつshardに割り当てられ、「recovery」プロセスを開始します」というパラメータを受け取ります。 * 出来れば、同一ホスト上に同じシャードはコピーしない * この時点の後で、ノードが停止したら、再起動し、同じ役割が再開されるべきです。(Zookeeperでそれ自身であると判別されれば) 原文はこちらからです。\nBoot Strapping Cluster Startup A node is started pointing to a Zookeeper host and port. The first node in the cluster may be started with cluster configuration properties and the schema/config files for the cluster. The first node would upload the configuration into zookeeper and bootstrap the cluster. The cluster is deemed to be in the “bootstrap” state. In this state, the node -\u0026gt; partition mapping is not computed and the cluster does not accept any read/write requests except for clusteradmin commands.\nAfter the initial set of nodes in the cluster have started up, a clusteradmin command (TBD description) is issued by the administrator. This command accepts an integer “partitions” parameter and it performs the following steps:\nAcquire the Cluster Lock Allocate the “partitions” number of partitions Acquires nodes for each partition Updates the node -\u0026gt; partition mapping in ZooKeeper Release the Cluster Lock Informs all nodes to force update their own node -\u0026gt; partition mapping from ZooKeeper The Cluster Lock is acquired A suitable source (node, partition) tuple is chosen: The list of available partitions are scanned to find partitions which has less then “replication_factor” number of nodes. In case of tie, the partition with the least number of nodes is selected. In case of another tie, a random partition is chosen. If all partitions have enough replicas, the nodes are scanned to find one which has most number of partitions. In case of tie, of all the partitions in such nodes, the one which has the most number of documents is chosen. In case of tie, a random partition on a random node is chosen. If moving the chosen (node, partition) tuple to the current node will decrease the maximum number of partition:node ratio of the cluster, the chosen tuple is returned.Otherwise, no (node, partition) is chosen and the algorithm terminates The node -\u0026gt; partition mapping is updated in ZooKeeper The node status in ZooKeeper is updated to “recovery” state The Cluster Lock is released A “recovery” is initiated against the leader of the chosen partition After the recovery is complete, the Cluster Lock is acquired again The source (node, partition) is removed from the node -\u0026gt; partition map in ZooKeeper The Cluster Lock is released The source node is instructed to force refresh the node -\u0026gt; partition map from ZooKeeper Goto step #1 Node Restart A node restart can mean one of the following things:\nThe JVM crashed and was manually or automatically restarted The node was in a temporary network partition and either could not reach ZooKeeper (and was supposed to be dead) or could not receive updates from the leader for a period of time. A node restart ine node failure. Lifecycle of a Write Operation this scenario signifies the removal of the network partition. A hardware failure or maintenance window caused the removal of the node from the cluster and the node has been started again to rejoin the cluster. The node reads the list of partitions for which it is a member and for each partition, starts a recovery process from each partition’s leader respectively. Then, the node follows the steps in the New Node section without checking for the auto_add_new_nodes property. This ensures that the cluster recovers from the imbalance created by th\nWrites are performed by clients using the standard Solr update formats. A write operation can be sent to any node in the cluster. The node uses the hash_function , and the Range-Partition mapping to identify the partition where the doc belongs to. A zookeeper lookup is performed to identify the leader of the shard and the operation is forwarded there. A SolrJ enhancement may enable it to send the write directly to the leader\nThe leader assigns the operation a Partition Version and writes the operation to its transaction log and forwards the document + version + hash to other nodes belonging to the shard. The nodes write the document + hash to the index and record the operation in the transaction log. The leader responds with an ‘OK’ if at least min_writes number of nodes respond with ‘OK’. The min_writes in the cluster properties can be overridden by specifying it in the write request.\nThe cloud mode would not offer any explicit commit/rollback operations. The commits are managed by auto-commits at intervals (commit_within) by the leader and triggers a commit on all members on the shard. The latest version available to a node is recorded with the commit point.\nTransaction Log A transaction log records all operations performed on an Index between two commits Each commit starts a new transaction log because a commit guarantees durability of operations performed before it The sync can be tunable e.g. flush vs fsync by default can protect against JVM crashes but not against power failure and can be much faster Recovery A recovery can be triggered during:\nBootstrap Partition splits Cluster re-balancing The node starts by setting its status as ‘recovering’. During this phase, the node will not receive any read requests but it will receive all new write requests which shall be written to a separate transaction log. The node looks up the version of index it has and queries the ‘leader’ for the latest version of the partition. The leader responds with the set of operations to be performed before the node can be in sync with the rest of the nodes in the shard.\nThis may involve copying the index first and replaying the transaction log depending on where the node is w.r.t the state of the art. If an index copy is required, the index files are replicated first to the local index and then the transaction logs are replayed. The replay of transaction log is nothing but a stream of regular write requests. During this time, the node may have accumulated new writes, which should then be played back on the index. The moment the node catches up with the latest commit point, it marks itself as “ready”. At this point, read requests can be handled by the node.\nHandling Node Failures There may be temporary network partitions between some nodes or between a node and ZooKeeper. The cluster should wait for some time before re-balancing data.\nLeader failure\nIf node fails and if it is a leader of any of the shards, the other members will initiate a leader election process. Writes to this partition are not accepted until the new leader is elected. Then it follows the steps in non-leader failure\nNon-Leader failure\nThe leader would wait for the min_reaction_time before identifying a new node to be a part of the shard. The leader acquires the Cluster Lock and uses the node-shard assignment algorithm to identify a node as the new member of the shard. The node -\u0026gt; partition mapping is updated in ZooKeeper and the cluster lock is released. The new node is then instructed to force reload the node -\u0026gt; partition mapping from ZooKeeper.\nSplitting partitions A partition can be split either by an explicit cluster admin command or automatically by splitting strategies provided by Solr. An explicit split command may give specify target partition(s) for split.\nAssume the partition ‘X’ with hash range 100 - 199 is identified to be split into X (100 - 149) and a new partition Y (150 - 199). The leader of X records the split action in ZooKeeper with the new desired range values of X as well as Y. No nodes are notified of this split action or the existence of the new partition.\nThe leader of X, acquires the Cluster Lock and identifies nodes which can be assigned to partition Y (algorithm TBD) and informs them of the new partition and updates the partition -\u0026gt; node mapping. The leader of X waits for the nodes to respond and once it determines that the new partition is ready to accept commands, it proceeds as follows: The leader of X suspends all commits until the split is complete. The leader of X opens an IndexReader on the latest commit point (say version V) and instructs its peers to do the same. The leader of X starts streaming the transaction log after version V for the hash range 150 - 199 to the leader of Y. The leader of Y records the requests sent in #2 in its transaction log only i.e. it is not played on the index. The leader of X initiates an index split on the IndexReader opened in step #2. The index created in #5 is sent to the leader of Y and is installed. The leader of Y instructs its peers to start recovery process. At the same time, it starts playing its transaction log on the index. Once all peers of partition Y have reached at least version V: The leader of Y asks the leader of X to prepare a FilteredIndexReader on top of the reader created in step #2 which will have documents belonging to hash range 100 - 149 only. Once the leader of X acknowledges the completion of request in #8a, the leader of Y acquires the Cluster Lock and modifies the range -\u0026gt; partition mapping to start receiving regular search/write requests from the whole cluster. The leader of Y asks leader of X to start using the FilteredIndexReader created in #8a for search requests. The leader of Y asks leader of X to force refresh the range -\u0026gt; partition mapping from ZooKeeper. At this point, it is guaranteed that the transaction log streaming which started in #3 will be stopped. The leader of X will delete all documents with hash values not belonging to its partitions, commits and re-opens the searcher on the latest commit point. At this point, the split is considered complete and leader of X resumes commits according to the commit_within parameters. Notes:\nThe partition being split does not honor commit_within parameter until the split operation completes Any distributed search operation performed starting at the time of #8b and till the end of #8c can return inconsistent results i.e. the number of search results may be wrong. Cluster Re-balancing The cluster can be rebalanced by an explicit cluster admin command.\nTBD\nMonitoring TBD\nConfiguration solr_cluster.properties This are the set of properties which are outside of the regular Solr configuration and is applicable across all nodes in the cluster:\nreplication_factor : The number of replicas of a doc maintained by the cluster min_writes : Minimum no:of successful writes before the write operation is signaled as successful . This may me overridden on a per write basis commit_within : This is the max time within which write operation is visible in a search hash_function : The implementation which computes the hash of a given doc max_hash_value : The maximum value that a hash_function can output. Theoretically, this is also the maximum number of partitions the cluster can ever have min_reaction_time : The time before any reallocation/splitting is done after a node comes up or goes down (in secs) min_replica_for_reaction : If the number of replica nodes go below this threshold the splitting is triggered even if the min_reaction_time is not met auto_add_new_nodes : A Boolean flag. If true, new nodes are automatically used as read replicas to existing partitions, otherwise, new nodes sit idle until the cluster needs them. Cluster Admin Commands All cluster admin commands run on all nodes at a given path (say /cluster_admin). All nodes are capable of accepting the same commands and the behavior would be same. These are the public commands which a user can use to manage a cluster:\ninit_cluster : (params : partition) This command is issued after the initial set of nodes are started. Till this command is issued, the cluster would not accept any read/write commands split_partition : (params : partitionoptional). The partition is split into two halves. If the partition parameter is not supplied, the partition with the largest number of documents is identified as the candidate. add_idle_nodes : This can be used if auto_add_new_nodes=false. This command triggers the addition of all ‘idle’ nodes to the cluster. move_partition : (params : partition, from, to). Move the given partition from a given node from to another node command_status :(params : completion_idoptional) . All the above commands are asynchronous and returns with a completion_id . This command can be used to know the status of a particular running command or all the current running commands status : (params : partitionoptional) Shows the list of partitions and for each partition, the following info is provided leader node nodes list doc count average reads/sec average writes/sec average time/read average time/write Migrating from Solr to SolrCloud A few features may be redundant or not supported when we move to cloud such as. We should continue to support the non cloud version which supports all the existing features\nReplication. This feature is not required anymore CoreAdmin commands. Explicit manipulation of cores will not be allowed. Though cores may exist internally and they meay be managed implicitly Multiple schema support ? Should we just remove it from ver 1.0 for simplicity? solr.xml . Is there a need at all for this in the cloud mode? Alternative to a Cluster Lock It may be simpler to have a coordinator node (we avoid the term master since that is associated with traditional index replication) that is established via leader election. Following a pattern of treating the zookeeper state as the \u0026ldquo;truth\u0026rdquo; and having nodes react to changes in that state allow for more future flexibility (such as allowing an external management tool directly change the zookeeper state to control the cluster). Having a coordinator (as opposed to grabbing a lock every time) can be more scalable too. A hybrid model where a cluster lock is used only in certain circumstances can also make sense.\nSingle Node Simplest Use Case We should be able to easily start up a single node and start indexing documents. At a later point in time, we should be able to start up a second node and have it join the cluster.\nstart up a single node, upload it\u0026rsquo;s configuration (the first time) to zookeeper, and create+assign the node to shard1. in the absence of other information when the config is created, a single shard system is assumed index some documents start up another node and pass it a parameter that says \u0026ldquo;if you are not already assigned, assign yourself to any shard that has the lowest number of replicas and start recovery process\u0026rdquo; avoid replicating a shard on the same host if possible after this point, one should be able to kill the node and start it up again and have it resume the same role (since it should see itself in zookeeper)\n","date":1317720720,"dir":"post/2011/","id":"7052598d2355984237d126afea2f6e88","lang":"ja","lastmod":1317720720,"permalink":"https://blog.johtani.info/blog/2011/10/04/new-solrcloud-design%E3%81%AE%E7%BF%BB%E8%A8%B3%E3%81%9D%E3%81%AE2/","publishdate":"2011-10-04T18:32:00+09:00","summary":"遅くなりましたが、続きです。 さらに英語力のなさを痛感して凹んでいるところですが、何かの役に立てばと恥を晒すところです。。。 一応、訳してみたの","tags":["solr"],"title":"New SolrCloud Designの翻訳(その2)(Jugemより移植)"},{"contents":"ちょっと興味があるので、訳してみました。(Wikiのページはこちら) 更新されているようなので、もとの文章も残しておきます。(ページ下部の続きはこちら部分以降) 全部訳そうと思ったのですが、終わらなかったので、まずは前半部分です。まだ、訳しただけで理解できてない。。。 (英語力のなさをさらけ出してしまうのですが、これも修行です。。。おかしいところはツッコミを。)\nWhat is SolrCloud? Solrクラウドはクラウドでの検索サービスとしてのSolrを管理、運用するための既存のSolrを拡張するものです。\n用語集 Cluster:クラスタは1単位として管理されるSolrノードの集合です。クラスタ全体で単一のschema、solrconfigをもたないといけません。 Node:ひとつのJVMインスタンスで起動しているSolrのこと Partition:パーティションはドキュメント集合全体のサブセット(部分集合)のことです。パーティションは部分集合のドキュメントが単一のインデックスに含まれるような形で作られます。 Shard:パーティションはn(=replication factor)個のノードに保存される必要があります。このn個のノードすべてでひとつのshardです。1つのノードはいくつかのshardの一部にで有る場合があります。 Leader:各Shardは1つのリーダとなるノードを持っています。パーティションに登録されたドキュメントリーダーからコピーされます Replication Factor:クラスタによって保持されるレプリカの最小限の数 Transaction Log:各ノードによって保持される書き込み処理の追記ログ Partition version:これは各shardのリーダーが持っているカウンターで、書き込み処理ごとに増加し、レプリカに送られます。 Cluster Lock:これはrange(※後述されているハッシュ値の範囲のことか?)-\u0026gt;パーティションもしくはパーティション-\u0026gt;ノードのマッピングを変更するために取得しなければいけないグローバルなロックのことです。 ※用語だけだと関係がわかりづらかったので、図を書いてみました。\nドキュメントの集合とパーティションについての考え方\nクラスタ、ノード、シャードの考え方。\n処理原則 任意の処理はクラスタにある任意のノードに実行可能です。 リカバリできないSPOFはありません。 クラスタは伸縮自在(elastic)でなければならない 書き込みが失われないこと(耐久性)を保証する 書き込み順序が保証されなければならない 2つのクライアントが2つの「A」というドキュメントを同時に送信してきた場合、すべてのレプリカで一貫してどちらか一方が保存されなければならない。 クラスタの設定は中央管理されなければならない。また、クラスタのどのノードからもクラスタ設定が更新できます。 読み込み(検索)の自動的なフェイルオーバー 書き込み(インデクシング)の自動的なフェイルオーバー ノードの故障が発生しても自動的にrepcation factorの数は守られます。(故障したら動的にレプリカを再配置?) Zookeeper ZooKeeperクラスタは次のために使用されます。\nクラスタ設定の集中管理 分散同期に必要な操作のコーディネータ クラスタ構成を保存するためのシステム Partitioning クラスタは固定されたmax_hash_value=「N」が設定されます。 max_hash_valueは1000のような大きな値が設定されます。\nhash = hash_function(doc.getKey()) % N ハッシュ値の範囲がパーティションに割り当てられ、ZooKeeperに保存されます。 次の例のような形で、パーティションに対して範囲が設定されます。\nrange : partition ------ ---------- 0 - 99 : 1 100-199: 2 200-299: 3 ハッシュはドキュメントにインデックスフィールドとして追加され、変更されない値です。 これは、インデックスを分割するときにも利用します。\nハッシュ関数はプラガブルです。これはドキュメントを受け取り、一貫した正整数ハッシュ値を返します。デフォルトのハッシュ関数として、必須でかつ変更されないフィールド(デフォルトはユニークキーフィールド)からハッシュ値を計算する関数が提供されます。\nUsing full hash range max_hash_valueは必ずしも必要ではありません。各shardはいずれにしろハッシュ値の範囲持っているので、完全な32 bitsハッシュを使うこともできます。 設定可能なmax_hash_valueを利用しないで、クライアントからの値をもとにハッシュ値を作ることができます。 例えば、電子メールの検索アプリでは次のようにハッシュ関数を作ることができます。\n(hash(user_id)\u0026lt;\u0026lt;24) | (hash(message_id)\u0026gt;\u0026gt;\u0026gt;8) ユーザIDから8bitのハッシュコードの先頭8ビットを利用することで、任意のユーザのメールがクラスタの同じ256番目(のノード?)にあるのを保証します。検索時はこの情報をもとにクラスタのその部分への問い合わせだけで情報が得られます。\nおそらく、私たちは最大値から最小値をカバーする範囲を表現するのにハッシュ空間を輪(固定のハッシュではなく)とみなしたいです。(???円状のハッシュ空間とすることで、クラスタ内のノード数の増減に耐えられるようにするよということかな?)\nshard naming シャードからハッシュ値の範囲へのマッピングを別々に管理するよりも、ハッシュコードによりパーティションを構成するときに実際にはハッシュの範囲をシャード名にします。 (シャード「1-1000」は1から1000の間のハッシュコードを持つドキュメントが含まれるという形)\n現時点では(コレクション1つに対してシングルコアの1Solrサーバと仮定して)solrコア名はコレクション名をつけるようになっています。 同一コレクションのためのマルチコアに対してのいい命名規則をつけるという課題が残っています。 (※コレクションに対する説明がここまでないかな?)\nShard Assignment ノード-\u0026gt;パーティションのマッピングはZooKeeperにあるCluster Lockを取得したノードによってのみ変更が可能です。 ノードの追加時に、まず、Cluster Lockを取得し、次にそれがどのパーティションを取得できるかを識別します。\nNode to a shard assignment 新しいノードを探しているノードはまずCluster Lockを取得しないといけません。 第一に、リーダーはシャードを決めます。 シャードが持つ、すべての利用可能なノード数で最小の値を持つノードが選び出されます。 もし、同値ならランダムにノードを選びます。\n原文はこちらからです。\nNew SolrCloud Design (Work in progress)\nWhat is SolrCloud? SolrCloud is an enhancement to the existing Solr to manage and operate Solr as a search service in a cloud.\nGlossary Cluster : Cluster is a set of Solr nodes managed as a single unit. The entire cluster must have a single schema and solrconfig Node : A JVM instance running Solr Partition : A partition is a subset of the entire document collection. A partition is created in such a way that all its documents can be contained in a single index. Shard : A Partition needs to be stored in multiple nodes as specified by the replication factor. All these nodes collectively form a shard. A node may be a part of multiple shards Leader : Each Shard has one node identified as its leader. All the writes for documents belonging to a partition should be routed through the leader. Replication Factor : Minimum number of copies of a document maintained by the cluster Transaction Log : An append-only log of write operations maintained by each node Partition version : This is a counter maintained with the leader of each shard and incremented on each write operation and sent to the peers Cluster Lock : This is a global lock which must be acquired in order to change the range -\u0026gt; partition or the partition -\u0026gt; node mappings. Guiding Principles Any operation can be invoked on any node in the cluster. No non-recoverable single point of failures Cluster should be elastic Writes must never be lost i.e. durability is guaranteed Order of writes should be preserved If two clients send document \u0026ldquo;A\u0026rdquo; to two different replicas at the same time, one should consistently \u0026ldquo;win\u0026rdquo; on all replicas. Cluster configuration should be managed centrally and can be updated through any node in the cluster. No per node configuration other than local values such as the port, index/logs storage locations should be required Automatic failover of reads Automatic failover of writes Automatically honour the replication factor in the event of a node failure Zookeeper A ZooKeeper cluster is used as:\nThe central configuration store for the cluster A co-ordinator for operations requiring distributed synchronization The system-of-record for cluster topology Partitioning The cluster is configured with a fixed max_hash_value (which is set to a fairly large value, say 1000) ‘N’. Each document’s hash is calculated as:\nhash = hash_function(doc.getKey()) % N Ranges of hash values are assigned to partitions and stored in Zookeeper. For example we may have a range to partition mapping as follows\nrange : partition ------ ---------- 0 - 99 : 1 100-199: 2 200-299: 3 The hash is added as an indexed field in the doc and it is immutable. This may also be used during an index split\nThe hash function is pluggable. It can accept a document and return a consistent \u0026amp; positive integer hash value. The system provides a default hash function which uses the content of a configured, required \u0026amp; immutable field (default is unique_key field) to calculate hash values.\nUsing full hash range Alternatively, there need not be any max_hash_value - the full 32 bits of the hash can be used since each shard will have a range of hash values anyway. Avoiding a configurable max_hash_value makes things easier on clients wanting related hash values next to each other. For example, in an email search application, one could construct a hashcode as follows:\n(hash(user_id)\u0026lt;\u0026lt;24) | (hash(message_id)\u0026gt;\u0026gt;\u0026gt;8) By deriving the top 8 bits of the hashcode from the user_id, it guarantees that any users emails are in the same 256th portion of the cluster. At search time, this information can be used to only query that portion of the cluster.\nWe probably also want to view the hash space as a ring (as is done with consistent hashing) in order to express ranges that wrap (cross from the maximum value to the minimum value).\nshard naming When partitioning is by hash code, rather than maintaining a separate mapping from shard to hash range, the shard name could actually be the hash range (i.e. shard \u0026ldquo;1-1000\u0026rdquo; would contain docs with a hashcode between 1 and 1000).\nThe current convention for solr-core naming is that it match the collection name (assuming a single core in a solr server for the collection). We still need a good naming scheme for when there are multiple cores for the same collection.\nShard Assignment The node -\u0026gt; partition mapping can only be changed by a node which has acquired the Cluster Lock in ZooKeeper. So when a node comes up, it first attempts to acquire the cluster lock, waits for it to be acquired and then identifies the partition to which it can subscribe to.\nNode to a shard assignment The node which is trying to find a new node should acquire the cluster lock first. First of all the leader is identified for the shard. Out of the all the available nodes, the node with the least number of shards is selected. If there is a tie, the node which is a leader to the least number of shard is chosen. If there is a tie, a random node is chosen.\n","date":1317210300,"dir":"post/2011/","id":"927612b57ba01ca878b2d7edce52a563","lang":"ja","lastmod":1317210300,"permalink":"https://blog.johtani.info/blog/2011/09/28/new-solrcloud-design%E3%81%AE%E7%BF%BB%E8%A8%B3%E3%81%9D%E3%81%AE%EF%BC%91/","publishdate":"2011-09-28T20:45:00+09:00","summary":"ちょっと興味があるので、訳してみました。(Wikiのページはこちら) 更新されているようなので、もとの文章も残しておきます。(ページ下部の続き","tags":["solr"],"title":"New SolrCloud Designの翻訳(その1)(Jugemより移植)"},{"contents":"Hadoop Conference Japan 2011 Fallに行ってきました。 まずは、ユーザ会の方々、運営の方々、発表された方々お疲れ様でした。こんな機会を用意していただき、ありがとうございます。 Hadoopは昨年触っていたのですが、最近は縁がなくなってしまいました。 ただ、触っていたときに面白かったので参加してきました。 ということで、今回も自分用にメモを取ったので。(今回は英語のヒアリングがあって、メモがひどい事になってます。。。) いつものことながら、おかしいところとかあれば、ツッコミなどフィードバックをもらえると嬉しいです。\n場所:ベルサール汐留 日時:2011/09/26 10:00~18:00+懇親会:18:30~21:00\nオープニングトーク:濱野、太田 参加者:1100名超!(実際は800名弱?) Hadoopの経験:利用経験なしな方が580名 カンファレンスの認知:Twitterよりも知人、その他が多かった。 会場提供:リクルート様 リクルート米谷様より一言。 Question VOTE!!サイトを用意。 http://mit.recruit.co.jpにて情報提供。 ※残念ながら地下だったため、E-mobileにつながらず、あと、電源確保が難しかったのでMBAをスタンドアロンにしてメモをとっていたので、 QAサイトにはアクセスしませんでした。もう少し活用したかったんですが、携帯でTwitterを追っかけるので精一杯。。。\n◎The role of the Distribution in the Apache Hadoop Ecosystem:Todd Lipcon(Cloudera)\n1.Introduction Todd Lipcon:Clouderaエンジニア Hadoop とHBaseのコミッター 2. Hadoop Overview HDFS+MapReduceの説明 Hadoopの生まれてきた経緯 様々な形式のデータが大量に存在し、データのハンドリングが難しくなってきたため。 Flexible, Scalable Solutionが必要に。 Hadoop の2つのユースケース 1.Advanced Analytics SNS(Web)、Content Optimization(Media)、Network Analytics(Telco)、 2.Data Processing Clickstream SessionizationEngagement 3.Cloudera Overview ClouderaCustomers ・Large National Bank ・Web-Based Media click-through dataや広告のログ ・Wireless Telecom 大量のデータ 目標:大量データからビジネスを引き出すこと。 Cloudera Japan:トレーニング。NTTDと協業して開発支援も 4.CDH Overview 100% pure Apache Hadoop SCM Epress(Service \u0026amp;amp; Configuration Manager) Free なぜ、CDHを利用するの? Linuxを利用する場合にLinux.orgからはダウンロードしないように、Hadoopも同じように提供したい。 RedHat系を目指しているみたい。 様々なパッケージの依存関係が混乱を招く。 CDHならテストが終わってるものが提供されてる。 ※SolrはLWEがLucidWorksEnterpriseがこれを目指してるのか。 5.Cloudera Enterprise Activity Monitor:Jobのパフォーマンスをリアルタイムに監視 SCM:設定のvalidateや管理。 Resource Manager:。。。 6.まとめ CDH:簡単にHadopが使えるよ。 SCM Express:簡単にHadoopの設定ができてフリーだよ Cloudera:Hadoopに関していろいろサポートしているよ。(Enterprise用ソフトやトレーニングなど) ◎About Hortonworks:Owen O\u0026rsquo;Malley(Hortonworks)\n1.About Hortonworks 2011/2月に設立 22人のYahooからのアーキテクトとコミッタにより設立 2.Credentials Yahooのクラスタの経験者がいますよ。 OSSに長けた人達によるチームです。 3.What is Apache Hadoop Hadoopの説明(別の側面が幾つかあり。) Commodity Hardwareで動く 簡単にプログラムできる 典型的なアプリケーションのタグクラウド(あとでちゃんと見る) HadoopのほとんどのソースコードはYahooで作られてるよ。 Clouderaとか目じゃないよ 4.Hadoop @ Yahoo! 各種サーバや規模など Science Hadoop Cluster \u0026lt;-\u0026amp;gt; Production Hadoop Cluster \u0026lt;-\u0026amp;gt; Serving Systems という構成で、いろいろやってます。 5.Hadoop Market ビジネス:ビッグデータを扱って色々やろうね 金融系:IT系のコストをOSSとHadoopで削減 技術系: 6.Hortonworks Strategy Hadoopを利用、管理しやすくするためのいろんなことをコミュニティに還元しますよ。 性能などについても同様。 トレーニングやテクニカルサポートやりますよ。 QA: Q:42Kのノードの管理ツールはなに? A:手で管理してます。 Q:社名の由来は? A:童話でHortonという名前の象の話がある。 Q:CDHはおすすめ?それともほかのものがいい? A:※聞き取れず。。。 Q:500万Query/月はアドホックQueryもあるの? A:幾つかのクラスタに分けて使ってる。アドホックは不明 ◎How Hadoop needs to evolve and integrate into the enterprise:Ted Dunning(MapR)\n・Quick History ・英語わからない身には辛い。。。 Zookeeperの人らしい。 Narrow Foundations HDFSとNASの間には大きな壁があり、大きなデータを移動するのはコストが掛かる。 Broad Foundation HDFSの代わりにNAS、RDBMSの下に位置するMapRを用意 ど、どんな仕組み?-\u0026amp;gt;テクニカルセッションで。 QA: Q:MapRはOSSにしないのか? A:MapRで開発したものはApacheに還元はしますが、OSSにはしないよ。フリー版は提供するかも ここで昼食。午前中からいた人にはランチボックスが提供されました。 午後からはコミュニティトラックとテクニカルトラックの2トラックがありましたが、LTが聞きたかった(それよりも英語が辛かった?)のでコミュニティトラックのど真ん中、最前列に入り浸りました。 ★コミュニティトラック ◎Elastic MapReduce Amazonが提供するHadoop:大谷晋平(Amazon)\n・Amazonとは Eコマース 流通 AWS の3つのサービス ・AWS Low-level、High-level、Cross Service、Tools to access services、アプリケーション 色々あるなー ・Bigデータが大変な理由 ケタ違いのデータ量、異なる形式データ、即時性 現状システムはスケールしない ビジネスとして成立する? 成立するならすぐスケールだめならすぐ縮小 ・Hadoopとは? これまでのお話。 スケーラブル、低価格なハード 誰でも入手可能で、実績多数。 ・Amazon EMR AWS上でスケーラブルなインフラ上に構築が可能 オンプレミスからMapReduceアプリを移行可能なため、分析、解析に集中可能 S3からデータIN/OUTするので、データ欠損がない。 Hadoopそのままではチューニングやクラスタサイズ見積もりも難しい =>クラスタサイズを動的に拡張伸縮可能。パフォーマンス最適化もできるよ。 0.18、0.20が利用可能。 EMRはHDFSとジョブ(タスク)トラッカーを別構成にしている。 EC2上にMaster、Core、タスクノードを展開 S3にデータを格納 SimpleDB(KVS)を利用 ・EMR注目機能 ジョブフローの高速化 ジョブの再起動無しにコスト/パフォーマンス比を変更可能。 タスクノードを動的に増やせる 柔軟なデータウェアハウスクラスタ タスクノードをバッチ実行時にのみ増やせる。 ※増減できるのはタスクノード Coreノードは増加のみ EMR+Spotインスタンスの活用 コスト削減効果が非常に高い AWSの余剰リソースをリーズナブルに提供(Amazon的にもウハハだ) ・その他の機能 東海岸だけだけど、スパコンレベルのインスタンスも利用可能 AWS上での最適化設計など ※ちょっと時間足りなくなってきたw ・EMRの事例 1.Razorfish ROAS(広告費用対効果)を500%改善(すげー) 2.So-net ・EMR都市伝説 物理vs仮想 そりゃ、物理が速いよ EMRの柔軟性・拡張性がセールスポイント ビッグデータは成功/失敗が読めないのもあるので、 インフラに投資する部分を少なくできるよ。 オンプレミスが安い? いやいや、HWの購入から設定など時間かかる。 ・Beyond Hadoop HadoopのIn/Out含めてスケーラブル、フレキシビリティが重要 運用管理の仕組みも重要 まだまだやってくよ。 QA Q:EMRは複数サービスから構築してるけど、一部がダウンするとどーなる?(例:SimpleDBが落ちてるとか) A:ジョブはReRunしてもらうか、SimpleDBの状態をみてリカバリをしてもらう。 Q:上記にともない、SLAの計算は? A:SLAはEMRについては定義できてない。S3などはリージョン跨いで Q:S3のセキュリティが心配だが、どう考えてるか? A:いままで脆弱性を晒してデータをロストしてない。 ユーザコントロールなどもできる。基本的には問題ない Q:EMRでS3を使う=Hadoopのローカリティの利点が失われるのでは? A:オーバヘッドはあるが、実際のデータはS3で守られているので、HDFSが飛んでも大丈夫。 Q:S3からのコピーオーバヘッドはどーなるか? A:Single5で少しずつor分割して全部送るも可能 Q:EMRはマルチテナントだけど他のユーザのネットワークの影響を受けないの? A:マルチテナントだと起こる可能性がある。 M1(?)だと内部ネットワークは専有可能らしい。 ◎LT\n・Hadoop and Subsystems in livedoor @tagomoris ピーク時に15Gbps。 10ノード(36コア) CDH3b2を利用 データマイニングではなく、ログからレポーティングをするのに利用している。 hadoop streaming + Hiveで実施 580G/dayが96サーバから来る ScribeにてHadoop Streaming(Perl)でper hourでHiveにload scribelineをWebサーバに入れててログ配送してくれる。 ** ・Lightweight @stanaka(はてなCTO:田中慎司さん)**\nEMR以前 自前20台クラスタ ジョブがあふれてきた ナマMapReduceを利用 PerlでMapper/Reducerを記述(Hadoop Streaming) EMR導入 リソース増やせて便利! 必要な台数に伸縮可能 問題点: S3にアップしないとダメ =>ログデータをS3に展開するlog2s3.plを作成。毎時実行。 起動、ジョブキック、結果改修どーする? =>Net::Amazon::EMR::Wrapperを作成した。 クラスタ起動、ジョブキック、クラスタ停止などできる 作ってみて思ったこと よかったところ: Perlでかける。Cronで実行可能。HiveQL便利。 悪かったところ。 途中で失敗してクラスタ起動しっぱなしとかがある。S3にデータを展開が大変。複雑な計算がきつい。 慣れてないエンジニアにも触れるようにしたい =>Perlで書けるようにした?。 ** ・HBaseでグラフ構造を扱う(開発中):アメーバ鈴木**\n自己紹介@brfrnl69 アメーバのソーシャルグラフ 基本はMySQL マスタ分散が難しい、シャーディング管理が面倒 =>HBaseでやってみるか。 目的 グラフデータに対して高速に更新追加したい。 隣接ノードが取れればいい(これを高速化したい) オンライン処理したい 運用コストの削減したい。 Not目的 マルチホップはどうでもいい。 アーキテクチャ JavaでGatewayつくってみる。 ・Large-Scale Graph Processing:井上さん(@doryokujin)さん Map/Reduceではグラフ計算だめ? Vertex基本だとShuffleに問題ががが。 BSPの紹介 Bulk Synchronous Processing Google Pregel SSSP:MapReduce Model すごい計算時間が掛かりそう。MRの組み合わせが何回回ることやら。 枝が少ないとこっちのほうがいいのか? SSSP:PregelModel シンプルなアルゴリズム Pregel使えるのあるの? Hama GoldenOrb Giraph YERN?YARN? ◎リクルート式Hadoopの使い方:石川(リクルート)\n@ground_beetle ・導入の課題点 バッチ処理時間対策のため。 =>実は入れたかっただけw ・導入の障壁 現行システムへの影響+開発工数 =>これへの対処がこのあとの話 ・課題の克服と活用シーン Azkaban知らなかった。ジョブスケジューリングツール Hadoop単体ではなく、エコシステム(関連ツール)が魅力 ・活用シーン:Hive SQLゆーがざ多く、HiveQLがSQLライクのため導入が簡単に! 既存機能のリプレイス系案件に活躍(低工数+簡単に高速化) とりあえず、Hive実装 =>性能アップのためにMapReduceで書きなおし Hotpepperなどのアトリビューション分析に利用 ・活用シーン:Sqoop+Hive RDBとHadoop連携のツール:Sqoop 現行システムの横にHadoopを配置でき、RDBMSの利点も利用しつつHiveも利用できるようになる。 (※気を付けないといけないけどねぇ。) ゼクシィで活用しようとしてるところ。 ・活用シーン:Mahout マイニング用ツール カーセンサーのレコメンド(同時に閲覧される車種) アソシエーション分析+クラスタリング ・活用シーン:BIツールの導入 何度か導入しようとして失敗してます。。。 BIツールの前処理(クレンジングなど)にHadoopを活用 ・インフラリソースは? 全部で118台。 最小のクラスタ構成はサーバ6台で構成してる ・Hadoopで複数処理を回す方法 ここまで紹介したものを入れてますよ。Hive、Sqoop、Solr。。。 ・Azkaban TomcatにWar配置で利用可能。 LinedInのチームにより作成 ※若干マシントラブルで中断 ・今後のHadoop導入 ログ基盤 分析エンジン・レコメンドエンジンとして バッチ処理短縮=トライアンドエラーが簡単にできるようになる。=色々な気づきが出てくる。 アジャイル的な解析が可能に。 ・開発サイクルの短縮ができるエコシステムでビジネスが回りだす。 ・今後の展開 MapRが気になってる。 マルチテナント対応ができてうはうはできそう。 EMCと共同して検証中 QA: Q:性能監視ツールの選別の理由は? A:Zabbix、Cactiです。今から利用しようと思っている段階。 Q:CDH、GreenPlum、Apacheをそれぞれ利用してるけど、使い分けのシーンは?比較は? A:CDH3u0です。GreenPlumは使ってないです。理由は言うとクビが飛ぶ可能性ががが。 Q:高度なデータ分析ができる技術者はどこからヘッドハントしてるの? A:MITに別途分析チームが存在し、高度な分析をしてくれる。 Q:NameNodeの冗長化はどーやってんの? A:象本と一緒DRBD+HeartBeat Q:EMRの導入を検討してる? A:今後、サーバ数が多くなると導入の検討をしていくと思う。 現時点は、運用ノウハウも入手するために社内で使ってる。 EMRになるかRCloud(リクルート社内クラウド)になるかは不明。 Q:HBaseを利用してる? A:してないです。スペック的にサーバが買ってもらえないと厳しいです。 ◎The history and the future of Hadoop use case at Rakuten:Tarje Marthinussen(楽天)\n・Introduction(self、rakuten) NextGeneration Search Group Norwayから来ましたよ。 ・RakutenのBigDataとは ・Hadoop at rakuten Recommendation(2009) ProductRanking、GenreRanking、Log解析、(2010) Enhance Search。。。(2011) ・PigやHiveのようなものが簡単に利用できるようになってきた ・新しい検索プラットフォームを構築中 index 10k docs/sec search 400qps ・What\u0026#39;s Next Generation Search 20%はインデックスとQuery評価の 50%がデータの前処理(データとQuery) 30%がアナライズ ・Collecting Data? ログの取得はバッチ処理だった。これをStreamingに(Flume) ・Flume Zookeeperを利用してFlumeを管理してる??? ・気になる部分があったので、改善のコーディングしてるよ。 ・セキュリティ マスタで管理できるように ・Pools Agentが送信先がコケてると他のPoolにスイッチ可能に。 ・MasterlessACKs QA Q:パッチ作成は何人でやってるの? A:50人が働いていてOSSコミッターが何人いるかはわからんです。 Q:ログはテキストだけど、パース処理はどこで?(古橋さん) A:Flumeは各ノードでうまい構成になっていて Decorator 性能問題は? HiveはJSONデータをうまく活用できてるよ。 Q:Masterlessとそうじゃないバージョンの性能比は? A:ノード数が増えると Q:HBaseじゃなくてCassandraなの? A:(※英語きつい。。。聞き取れず) ◎マーケティング向け大規模ログ解析事例紹介:原謙治(NTTコミュニケーション)\n・自己紹介 ・BizCITYというクラウドサービスを展開中 まずは、宣伝。 Bizストレージ、Bizマーケティングとして大規模データ、分散処理を実施してる。 ・Hadoop in Bizマーケティング CGMデータを解析して口コミ情報抽出 アクセスログから行動情報抽出 ・Hadoop in BuzzFinder CGM DBからHDFSにインポートして解析開始。DBはPostgreSQL 処理フローは資料参照。 リッチインデクシング技術(NTT研究所が開発した日本語解析技術) ※検索インデックスってどんなものなんだろう? ポジネガ分析気になる。 ・Fast Map-Reduce for PaaS Services アクセス解析やマーケティング解析を行う上でShuffleコストが大きくなるため大量マシンが必要 =>マシン数を減らすことが目的? Map Multi-Reduce、PJoinはNTT研究所が開発した技術!?(子象本にないっけ??) =>Multi-Reduce。同一ノード上のMap出力をReduceすることで、shuffleフェーズに渡るデータを削減している。 =>PJoin QA Q:Map multi-reduce、PJoinはどう実現してるのか?公開するのか? A:Hadoopの0.19に改造をしてる。 公開できるかどうかはわかりません。NTT研究所が研究しているものを試しに実装してみてるから。 なのでパッチにはなりませんかね(研究所に聞いてみないとわからないっす) Q:性能が向上したパターンはあったが、悪化する場合などはあるのか? A:不明 Q:Map-side Joinとの違いは? A:。。。 ※この辺で少し集中力が途切れてしまいました、すみません。(次に集中したかったので。。。) ◎ミクシィにおけるHadoopの利用:伊藤敬彦(mixi)\nLSH-Based Recommendation engine powered by hadoop ・実はmixiの話はすくないよ。 ・利用している環境。5or6台/クラスタ ・Hadoopの活用 ログデータをHDFSに保存 DBコンテンツをHDFSに入れることで、DBに負荷をかけずに解析する。 ・マイニングも検証中 検索クエリログをベースにデータマイニング では、本題。 ・LSHを利用した推薦 ・推薦とは? mixiにはいろいろ推薦(レコメンド)を付加できるサービスがある。 ・推薦するには? 類似インスタンス集合を抽出する。 インスタンスは文書だったりユーザだったり ・類似インスタンスとは? 同じ特徴を持つ集合 例:同一商品購入したユーザとか同一単語を持つ文書とか ・抽出するには? 全ユーザごとに全ユーザとの類似性をチェックすると時間がかかりすぎる! =>LSHを利用しよう! ・LSHについて 特徴: ・速い! ・精度はそれほどではない 事例: ・Google Newsのレコメンド(USロケール) ・LSHの処理ステップ 2つだけ。 1.インスタンスベクトルを計算(似ているデータは同じ値が返りやすい関数) 2.同一値が帰ってきたデータが類似インスタンス ・インスタンスベクトル例(あとでスライド見ようね) ・Likelikeがいち実装。Hadoopでうごくよ ・実験について トップページに表示されていない記事を知ってもらうために推薦してみるぞ! ・実験1 性能を測ってみた ・実験2 精度を調べてみた。 精度はほんとにひどいな。。。 =>同一カテゴリの遷移を元に計算したらそれなりになってきた。 ・今後 データソースを増やしたい。 他のアルゴリズムも実装したい ・CM 以下も作ってますよ。 Oluolu Anuenue QA Q:Mahoutは使わないんですか? A:Likelikeを作った頃にMahoutになかったので作った。 性能比較したいと思ってる。 Q:ログサーバのデータ転送はどーやってる? A:伊藤さんのところにはどういう仕組みかは上がって来てない。 Q:ベクトルの次元数はどのくらいまで耐えられる? A:高次元のデータに対して耐えられるように作られてる。 次元数が低くて良い制度が欲しければ他のアルゴリズムがいいかも。 Q:ユーザのベクトルを作るテクニックは? A:画像などであれば大変だけど、ユーザであれば、単語とかキーワードとかで Q:ニュース以外のデータは? A:まだまだ実験中。まだやってない。 Q:推薦される記事数のばらつきはどういった理由が考えられる? A:後ほど考察してQAサイトに入れます。 Q:LSHをMapReduceに載せたということだけど、関数の計算をさせてる? A:Iterationはしてない。 Map側でLSH関数計算してる。Reduceにて類似インスタンスを導出してる。 Q:今後の予定の空間木とは?R-Treeだと高次元できついのでは? A:低次元にて利用できるように用意したい。 Q:HamaとかGiraphで高速化させてみるのはどう? A:イテレーションがいらないからあまり利用用途がないかなぁ。 ◎懇親会\nAWSを採用しない企業がいくつかあったのでそのあたりを質問してみた。 AWSは通常運用に利用すると結構なコストがかかる場合があるので、ノウハウがある企業や データ量が多い場合は、オンプレミスの場合を選択しているらしい。 やはりスポットで利用する方がお得感があるみたいだった。 Twitter上だけの知り合いだった方々と面識が持てたのが一番の収穫でした。 感想+調べること\n感想\n会場規模とかQAサイトとかオープニングムービーとかすごかったです。しかも無料。さすがリクルートさん。 ランチボックスとか出てきたし。装飾もとても無料のカンファレンスと思えない出来でした。 午前中はHadoopをもとにした各社の戦略とCMという感じが色濃かったです。少しずつ各社の立ち位置が違いそれはそれで面白かったです。 AWSの説明を聞いてやはりAWSを扱える技術は必要だと再認識。 お金かけないで触ってみれるレベルでまずは触ってみるかなぁ。 洗脳されてるのかもしれないけど、自社or自前でHadoop運用するのは厳しそうです。(懇親会ですこし認識が変わった) カフェコーナーでは、リクルートのMITの冊子が配られていたり、映像や案内に使われていたHadoopマスコットのシールが配られていたりと小技も聞いてました。 あと、オライリーの販売コーナーも用意されていて、思わず子象本を買ってしまう罠にはまったりもしましたが。。。 mixiの伊藤さんの話は最後で疲れていたのですが、ストーリーが上手くできていて、実験や事例もあったのでわかりやすかったです。 Hadoopはエコシステムと呼ばれるHadoopを活用するツール群(Hiveの話が多かった?)、Hadoopの今後、Hadoopを活用したログ解析の話など、 話題が豊富でそれぞれの話が面白くて困ってしいまうくらいです。 いくつかのセッションで出てきたのですが、アクセスログなどをHDFS上に集めるための仕組みがまだ乱立(定番がまだない)している感じを受けました。 Flume、Scribe、MapR。。。などなど あとは、テクニカルセッションのビデオがアップされたらまた目を通さないと。。。 残念ながらHadoopから少し縁遠くなっていますが、これからもネタや参考になりそうな話には事欠かなそうなのでかじりついていこうと思います。 ※一番やらないといけないのは英語の勉強かもしれないです。。。 調べること 一応Solrの人なので、Solrに関連しそうな話に興味がいってしまいます。\nNTT研究所のリッチインデクシング技術 やっぱりAWS触ってみる。EMRまでとは言わないが。(herokuもちょっと興味あるが。) Mesos、GreenPlum、Scribe、Storm、Flume、Giraphこれらの概要 関連サイト 公式QAサイト。後日録画していたセッションがアップされるそうです Hadoop Conferene Japan Fall 2011 - 急がば回れ、選ぶなら近道 Hadoopカンファレンスが開催、本格普及を見据えた支援サービスや先進事例が充実 - ニュース:ITpro Hadoop Conference Japan 2011 fallで使用された資料 #hcj11f | インフラエンジニアのつぶやき(スライドをまとめてくれてます。)\n","date":1317113460,"dir":"post/2011/","id":"97402287d8c6c03f0b63848e17e9d944","lang":"ja","lastmod":1317113460,"permalink":"https://blog.johtani.info/blog/2011/09/27/hadoop-conference-japan-2011-fall%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%A6%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-09-27T17:51:00+09:00","summary":"Hadoop Conference Japan 2011 Fallに行ってきました。 まずは、ユーザ会の方々、運営の方々、発表された方々お疲れ様でした。こんな機会を用意していただき、ありがとう","tags":["hadoop"],"title":"Hadoop Conference Japan 2011 Fallに参加してきました。(Jugemより移植)"},{"contents":"台風15号すごかったですね。幸いにも(?)夏休みだったので、通勤などでひどい目に合わずにすみました。 風雨はすごくてちょっと怖かったですが。。。\nさて、夏休みに進める予定が、子供の寝かしつけで一緒に寝てしまう日が続いてしまい、 間が開いてしまいました。\n0日目というタイトルになっているのは、まだ、1日目に入ってないからです。。。 Ioという未知の言語をMBAにそのままインストールするのも抵抗があり、VirtualBox上にLinuxをインストールしてから 進めようとして思いの外手こずってしまったためです。 ということで、0日目として、VirtualBox上にScientific Linux 6.1をインストールしてIoのインストールまでではまった箇所を記録として残しておきます。\n罠その1 罠と言うよりは、私の無知に関する部類なのですが。。。 Scientific Linux 6.1のインストールは特に手こずることなくインストールでき、 起動も出来ました。 次にscpコマンドでダウンロードしてきたIoのソースをLinuxに渡そうとしてはまりました。 問題となったのはネットワーク接続が「NAT」のみだったため。 NATのため、Linux(ゲストOS)から外部への接続は可能だったのですが、Mac(ホストOS)からLinux(ゲストOS)への接続ができませんでした。 で、変更したのは以下の2点。\nVirtualBoxの環境設定-\u0026gt;ネットワーク-\u0026gt;ホストオンリーネットワークの追加 仮想マシン(Linux)の設定-\u0026gt;ネットワーク-\u0026gt;アダプタ2を有効にしてホストオンリーアダプタを割り当て 1番目のホストオンリーネットワークの追加をしておかないと、2番目のアダプタ2でホストオンリーアダプタを選択したときにエラーが出て、設定ができませんでした。割り当てるべきアダプタを先に用意しとかないとダメですよね、そりゃあ。\n罠その2 これも罠というほどではないのですが。。。 Ioのビルドにはcmakeが必要なのですが、Scientific Linux 6.1に入っているcmakeはバージョンが古い(2.6.4)ため、必要なバージョン(2.8以上)をインストールしないとダメでした。 インストール自体はcmakeのサイトにある手順通りのため割愛します。\n罠その3 これもちゃんとドキュメント読めよというレベルですが。。。 Ioのインストールは以下のコマンドを実行するという話です。 私がcmakeについて知らなかったと言われればそれまで。。。\n$ cd io $ mkdir build \u0026amp;amp;\u0026amp;amp; cd build $ ccmake .. $ make $ sudo make install 3つ目の「ccmake」の部分がIoのGetting Startedの下の方にありました。上の方に記載がある「cmake」ではエラーがでてうまく行かなかったので。 IoのGetting Startedにもありますが、ccmakeの場合はCUI上にGUIのようなものが起動するので、「c」(configure)と実行後、「g」(generate)を実行して最後に「e」(exit)でccmakeを離れます。 するとmakeが実行できるようになりました。\nあとは、/etc/ld.so.conf.d/io.confファイルを作成し、「/usr/local/lib」と記述。ldconfigを実行することで、Ioが実行可能になります。 ということで、1日目に入れず終了。。。\n明日は出来るかなぁ。\n","date":1316716440,"dir":"post/2011/","id":"62f31128a21b0e240bdb7b3d5b121c04","lang":"ja","lastmod":1316716440,"permalink":"https://blog.johtani.info/blog/2011/09/23/7%E3%81%A4%E3%81%AE%E8%A8%80%E8%AA%9E-7%E3%81%A4%E3%81%AE%E4%B8%96%E7%95%8C-io-0%E6%97%A5%E7%9B%AE/","publishdate":"2011-09-23T03:34:00+09:00","summary":"台風15号すごかったですね。幸いにも(?)夏休みだったので、通勤などでひどい目に合わずにすみました。 風雨はすごくてちょっと怖かったですが。。","tags":["読書"],"title":"「7つの言語 7つの世界」 Io 0日目(Jugemより移植)"},{"contents":"Solr/Lucene 3.4がリリースされました。(速報)\n以下、各サイトへのリンクです。\nSolrリリースのお知らせ\nLuceneリリースのお知らせ\nちなみに、先日のSolr勉強会で関口さんが話されていたインデックスが壊れるバグですが、 先日のアメリカのハリケーン(Irene)で実際に電源が落ちて見つかったみたいです。\nということで、3.4がリリースされたので、3.1~3.3は利用しないほうがいいようです。\n追記: lucidimagination.jpのサイトに日本語のリリースノートが公開されていたので、リンクを記載しておきます。\n","date":1316046660,"dir":"post/2011/","id":"54da1b916f49ef40c822fab61d37cf66","lang":"ja","lastmod":1316046660,"permalink":"https://blog.johtani.info/blog/2011/09/15/lucene-solr-3-4%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E9%80%9F%E5%A0%B1/","publishdate":"2011-09-15T09:31:00+09:00","summary":"Solr/Lucene 3.4がリリースされました。(速報) 以下、各サイトへのリンクです。 Solrリリースのお知らせ Luceneリリースのお知らせ ちなみに、先日の","tags":["solr"],"title":"Lucene/Solr 3.4リリース(速報)(Jugemより移植)"},{"contents":"ということで、Rubyの最終日の感想。 今回もセルフスタディの私の回答が最後の方に記載されてます。見たくない人は気をつけてください。 ツッコミ大募集です。コメント欄にどしどしコメントください。そこは違うだろ?こっちのほうがいいのでは?という感じで。\n感想: ◎メタプログラミングが特徴 例:ActiveRecordのhas_many、has_oneがいい例\n◎オープンクラス クラス定義をいつでも変更可能。 あらゆるクラスやオブジェクトをいつでも再定義できる 書きやすいコードのために再定義が可能=何でもできるが気を付ける必要あり。 DSLの定義に便利。 確かに便利。ただ、範囲を限定しないと予期せぬ場所で問題が発生しそう。 ※解析するための手段はいいのがあるのかな?=\u0026gt;method_missingみたい\n◎method_missing 対象メソッドが見つからない場合に最後に実行されるメソッド 通常はNoMethodErrorが発行される。\n◎モジュールによるメタプログラミング defやattr_accessorなどその一例。 DSLではモジュール内にメソッドを定義してメソッド+定数を利用 ActsAs\u0026hellip;ってそういう意味合いだったのか。 親クラスバージョン、親クラス+マクロ、モジュールそれぞれの実装の仕方の紹介。 ※マクロもinclude同様、実行順で、メソッドの上書きが発生するのか? ActiveRecordではメタプログラミングを利用してDBのカラム名からアクセサを追加。 シンタックスの美しさ=読みやすさ\n感想&疑問点: メタプログラミングはフレームワークを作成するのが便利そう。 ただし、エラーや問題が起きた時の対処をきちんと準備しておかないとひどい目に合いそう。 クラスやモジュールはわかりやすい単位で1ファイルにまとめるもの? ファイル名の規則とかあったりする? ディレクトリ構成でパッケージ構成が可能? 複数のモジュール(gemとか)を組み合わせて使っている場合にincludeの順序がどのようになるかが気になる。 予期せぬ順序でincludeされて利用しようと思ったメソッドがオーバーライドされてるとかありそう。 追っかけるのがまた大変そうだ。 異なるパフォーマンス(開発者の開発速度)の観点が一番おもしろかった。ただ、なれるまでは大変そう。すんなりinjectとかコードブロックをうまく利用するイメージがわかない。 まぁ、思考については反復練習かな。これは他の言語でも一緒かな\nようやく、Rubyの世界が終わりました。楽しかった。次は未知の言語である「Io」です。\n(試してみよう:) ○eachメソッドがCsvRowオブジェクトを返すようにCSVアプリケーションを変更せよ。そのCsvRowのmethod_mmissingを使って、与えられた見出しの列の値を返すようにせよ。 モジュールにて実装してみた。 ``` module ActsAsCsv\ndef self.included(base) base.extend ClassMethods end module ClassMethods def acts_as_csv include InstanceMethods end end\nmodule InstanceMethods\ndef read @csv_rows = [] file = File.new(self.class.to_s.downcase + '.txt') headers = file.gets.chomp.split(', ') file.each do |row| @csv_rows \u0026lt;\u0026lt; CsvRow.new(headers,row.chomp.split(', ')) end end def each(\u0026amp;block) csv_rows.each(\u0026amp;block) end attr_accessor :csv_rows def initialize read end end\nclass CsvRow def initialize(headers, csv_contents) @headers = headers @csv_contents = csv_contents end\nattr_accessor :headers, :csv_contents def method_missing name, *args csv_contents.fetch(headers.find_index(name.to_s)) end end end\nここまでが実装したモジュール+クラス。 以下は実行例。id,name,sizeというheaderをもつCSVを使ってみた。 require \u0026lsquo;acts_as_csv_module_mod.rb\u0026rsquo; =\u0026gt; true class RubyCsv include ActsAsCsv acts_as_csv end =\u0026gt; RubyCsv csv = RubyCsv.new =\u0026gt; #\u0026lt;RubyCsv:0x103c4c530 @csv_rows=[#\u0026lt;ActsAsCsv::CsvRow:0x103c4c030 @csv_contents=[\u0026ldquo;1\u0026rdquo;, \u0026ldquo;RubyCsv.class\u0026rdquo;, \u0026ldquo;20\u0026rdquo;], @headers=[\u0026ldquo;id\u0026rdquo;, \u0026ldquo;name\u0026rdquo;, \u0026ldquo;size\u0026rdquo;]\u0026gt;, #\u0026lt;ActsAsCsv::CsvRow:0x103c4be78 @csv_contents=[\u0026ldquo;2\u0026rdquo;, \u0026ldquo;JRubyCsv.class\u0026rdquo;, \u0026ldquo;50\u0026rdquo;], @headers=[\u0026ldquo;id\u0026rdquo;, \u0026ldquo;name\u0026rdquo;, \u0026ldquo;size\u0026rdquo;]\u0026gt;]\u0026gt; csv.each {|row| puts row.name} RubyCsv.class JRubyCsv.class =\u0026gt; [#\u0026lt;ActsAsCsv::CsvRow:0x103c4c030 @csv_contents=[\u0026ldquo;1\u0026rdquo;, \u0026ldquo;RubyCsv.class\u0026rdquo;, \u0026ldquo;20\u0026rdquo;], @headers=[\u0026ldquo;id\u0026rdquo;, \u0026ldquo;name\u0026rdquo;, \u0026ldquo;size\u0026rdquo;]\u0026gt;, #\u0026lt;ActsAsCsv::CsvRow:0x103c4be78 @csv_contents=[\u0026ldquo;2\u0026rdquo;, \u0026ldquo;JRubyCsv.class\u0026rdquo;, \u0026ldquo;50\u0026rdquo;], @headers=[\u0026ldquo;id\u0026rdquo;, \u0026ldquo;name\u0026rdquo;, \u0026ldquo;size\u0026rdquo;]\u0026gt;] csv.each {|row| puts row.id} (irb):8: warning: Object#id will be deprecated; use Object#object_id 2179096600 (irb):8: warning: Object#id will be deprecated; use Object#object_id 2179096380 =\u0026gt; [#\u0026lt;ActsAsCsv::CsvRow:0x103c4c030 @csv_contents=[\u0026ldquo;1\u0026rdquo;, \u0026ldquo;RubyCsv.class\u0026rdquo;, \u0026ldquo;20\u0026rdquo;], @headers=[\u0026ldquo;id\u0026rdquo;, \u0026ldquo;name\u0026rdquo;, \u0026ldquo;size\u0026rdquo;]\u0026gt;, #\u0026lt;ActsAsCsv::CsvRow:0x103c4be78 @csv_contents=[\u0026ldquo;2\u0026rdquo;, \u0026ldquo;JRubyCsv.class\u0026rdquo;, \u0026ldquo;50\u0026rdquo;], @headers=[\u0026ldquo;id\u0026rdquo;, \u0026ldquo;name\u0026rdquo;, \u0026ldquo;size\u0026rdquo;]\u0026gt;]\n\u0026lt;span style=\u0026#34;color:#FF0000\u0026#34;\u0026gt;※idというcsvフィールド名にしたら、object_idとかぶっているようでwarningが出てしまった。\u0026lt;/span\u0026gt; CsvRowクラスの定義がモジュールの中に入っているが、この実装でも動くみたい。ただ、パッケージみたいな感じ7日までは調査してない。。。 ","date":1315992060,"dir":"post/2011/","id":"41b811063b9425de1934e77d89118022","lang":"ja","lastmod":1315992060,"permalink":"https://blog.johtani.info/blog/2011/09/14/7%E3%81%A4%E3%81%AE%E8%A8%80%E8%AA%9E-7%E3%81%A4%E3%81%AE%E4%B8%96%E7%95%8C-ruby-3%E6%97%A5%E7%9B%AE%E6%9C%80%E7%B5%82%E6%97%A5/","publishdate":"2011-09-14T18:21:00+09:00","summary":"ということで、Rubyの最終日の感想。 今回もセルフスタディの私の回答が最後の方に記載されてます。見たくない人は気をつけてください。 ツッコミ大","tags":["読書"],"title":"「7つの言語 7つの世界」 Ruby 3日目(最終日)(Jugemより移植)"},{"contents":"「第6回Solr勉強会」に参加しました。 なんだかんだと第6回で、今のところ皆勤賞です。\nということで、主に自分用ですが、メモなどとったので。\n概要\n日時 :2011/09/12 19:00 to 21:00 定員 :110 人 会場 :株式会社 ECナビ 1.「Lucene/Solr 3.2-3.4」 by ロンウイット 関口 宏司さん ※Solr2.9.4、3.1でデグレードし、Solr3.4で修正されたバグがあります。 インデックス中にPCがシャットダウンされた場合にインデックスが壊れてしまうものあり。 Solr3.1-3.3は使用しないようにとのこと。 ○index ・IndexWriter.addDocuments(docs) 複数ドキュメントの更新が可能になった。 ※検索で話をする親子関係のNestedQuery向けの登録にも利用する。 この登録では途中でフラッシュされないため、セグメントが分割されない特徴あり。 複数だけでなく、 ・TieredMergePolicy ※Lucene3.2/Solr3.3からデフォルトになった。 新しいインデックスのマージポリシー。(amebaの開発者ブログに説明があった。) インデックスの登録順が守られていたが、このマージ処理では保証がされなくなったので注意が必要。 ・update.chain update.processorがdeprecatedに。 update.chainというパラメータに変更 ○index(cont\u0026#39;d) ・TwoPhaseCommit ・UniqFieldsUpdateProcessor 重複した値を削除するための機能。 UIMAでの提案から取り込まれた ○search ・group=on 検索グルーピング機能を使えるパラメータ ・{!term} クエリパーサを通さないでTermQueryをかける機能。 ・structured explanation debug=onの算出根拠を XMLタグで構造化されたExplanationが取得可能に ・ReloadCacheRequestHandler 関口さん担当。ExternalFileField インデックス外(外部ファイル)を元にFunctionQueryの情報を利用可能にできるのだが、 このファイルのリロードが可能になる。 ・Carrot2 3.5.0 アップグレード。 デモあり。Carrot2のworkbenchとか ○search(cont\u0026#39;d) ・hl.phraseLimit parameter FastVectorHighlighterの高速化用パラメータ。 ・{!cache=false} キャッシュを利用しないためのローカルパラメータ。fqのローカルパラメータに利用可能。 検索セッション内でキャッシュへの処理(参照・登録)をしなくなる ・BlockJoinQuery NestedDocumentQueryの名前が変更された。 (Luceneで登録されたところまで。) ○schema ・KStemFilter PoterStemmerとは別のstemmer ・ReversePathHierarchyTokenizer パスの構造化インデックスの逆バージョン ・ommitPositions=\u0026#34;true\u0026#34; 指定が可能になった。 ・version 1.4 スキーマのバージョンが新しくなった。 ○admin/tools ・action=MERGEINDEXES\u0026amp;srcCore=coreName コア名指定可能。 ・action=UNLOAD\u0026amp;deleteIndex=true UNLOAD時にインデックス削除 ・action=CREATE\u0026amp;property.name ※ぎゃーーー。打ち込み失敗。 ○ぎゃーーーー失敗。 ○技術者大募集中!! Q\u0026amp;A Q:クラスタリングの日本語は大丈夫?入門には制限があると記載があったが。 A:analyzerが記載が簡単になってるかは不明 前処理をして別フィールドにメタデータ的にある程度単語で区切ったようなものを作成したほうがいい。 Q:グルーピングで、グルーピング後のファセット件数が取得可能か? A:3.4ではグループ数で表示可能。 パラメータ指定で可能。 2.「Solr@cookpad」 by @PENGUINANA_ さん ○COOKPADとは? ・レシピ投稿サイト ・105万のユーザのレシピ ・30代女性の1/2が利用 ○レシピ検索 ・PC:1307万UU、1億回強/月 ・モバイルで利用が多く、スーパの店頭などで利用? ・Androidもあるよ。 ○人気順検索(Solrですよ) ○自己紹介 ・@PNGUINANA_ ・情報可視化+検索が好き!! yats、など ○Solrはどのように利用 ・レシピ検索 ・もしかして ○Tritonnから移行 同じ検索結果になるようにして徐々に移行 ○なぜ? パフォーマンスが良い。 フィールド追加が簡単 レプリケーション-\u0026gt;ファイルベース プロトタイピングが楽 ○Solr4 nightly(on Oracle JVM) ・マルチコア利用 ・Ruby on Railsから ○簡単な構成+説明 ・バッチからSolrへの更新をしている。 ※Analyzerを利用せず、バッチ側で分かち書き、正規化、同義語展開を行っている。 Rubyで全部かけるほうが社内に展開しやすい。 ・バッチ終了後、可能ならoptimize ※検索速度がmax20%高速になる。 ・マスタ-\u0026gt;スレーブレプリケーションはschema.xmlもレプリケート 新規フィールド追加などはレプリケーションだけで実行できて楽。 ・アプリはMySQLとSolrのSlaveにアクセス。 Solrにはidのみ。本文はMySQLから取得 インデックスサイズを小さくできる=レプリケーション時間が短くなる オンメモリにできるため検索速度も向上 ○監視(munin) ・監視項目(コア別): クエリ:QTime/QPS キャッシュ:hit/eviction キャッシュから漏れている数をみてキャッシュサイズを定期的に変更して無駄をなくす インデックス:サイズ/docの数 運用してから重要。開始当初は気にしてるが、そのうち気にならなくなるため。 レプリケーション:所要時間 スレーブ間でのズレを検知するため。 ※コアごとに監視することで、問題点を把握しやすくしている。 ○監視(nagios) ・監視項目(コア別): サーバの基本的なヘルスチェック Solrが動いてるサーバのはなし。 レプリ:インデックスバージョンのチェック ズレが長いとメールが飛ぶ ○便利だった機能 ・DynamicField フィールドをあとから簡単に追加可能。 例:人気順のアルゴリズムの違うフィールド。検索用フィールド ・FacetQuery 絞り込み検索をクエリで記載可能。 現時点では社内向け検索機能で利用。 ※ファセットで簡単な解析もやってる。 例:鍋の季節ごとの登録件数。 ・HTTP経由で色々可能 検索の並列化 通常検索画面:3クエリを同時実行 あるプロトタイプ画面だと8クエリで実行したりしてる。 ・分散検索(Distributed Search) 簡単にsharding可能 思いクエリは4shardで投げる オーバヘッドが大きいので思いクエリにだけ利用しているらしい。 ○開発の流れ ・まずはステージングを更新 ・問題なければマスターも更新 例外: フィールド追加するだけだったら直接マスタへ 例:ファセット追加など。 ○パフォーマンスとか大丈夫? 本番で複数のバージョンを持っており、 バグっていても自動フォールバックするらしい。 価値があったらパフォーマンス向上+テスト追加 例:スニペット変更 ○気になっている機能 ・not to cache(SOLR-2429) ・SurroundQuery(Solr-2703) ・JOIN(SOLR-2272) SQLのJOINなイメージ ・BloomFilter(SOLR-1375) 単語が存在するかどうかのチェック ○Solr入門おすすめ ○おすすめ ・http://blog.sematext.com 月一で新機能が出てくる ・SolrのJIRA ・@otisg ○今後やりたいこと ・わかち書きの精度向上 ・検索セッションの分析 nDCG、クエリ分類、検索意図 ・デバイス対応 ・パーソナライズ Q\u0026amp;A Q:同義語は誰が集めている? A:外部辞書を利用。0件キーワードから解析して取得 単語登録も一緒。 Q:プチトマトとトマトの違いはどうやってる? A:上位、下位の概念で同義語を利用している。 本にあるよ。 Q:もしかしてはSolrの機能? A:Solrではない。訂正候補の単語をSolrに検索してからチェックして表示する。 Q:人気順はどういった計算をしてるんですか?計算してから登録?By 大谷 A:1フィールドに外から入れている。 Q:RubyからSolrの利用方法は?独自?ライブラリ?By 大谷 A:Rsolrを利用しており、コネクション管理にだけ利用している。 あとは、ラッパーを独自で作成。 Q:4.0を利用している理由は?なかなかチャレンジャー。By関口 A:グループクエリを利用したかったため。 実際には重くて使えていない。 今は必要ないかもと思っている。年始のバージョンを利用。いつでも入れ替え可能。 マスタスレーブ構成のsolrのバージョンアップはサービスアウトしてから入れ替える。 3. 「Solrを用いた検索システムの構築」 by データセクション株式会社 高井さん いろいろな試行錯誤について ○データセクションについて 言語処理を元にデータの解析(Twitterとかブログとか)している会社。 ・昔は自社で検索サーバを構築していた ・Luceneを利用して検索サーバを構築するように変更。 ○構成(過去?) ・Lucene+RMI 3.0から縮小で、4.0で廃止に ○SolrにするかLuceneにするか? ・いろいろ機能があるからSolr使ってみるかw ○Solr導入は1.4.1から スペック マスタ: メモリ:16G Disk:2Tx12 スレーブ: 256GのSSDを利用 JavaVMが32bit ○ひと月分を1shardにして登録 ○検証+手探り? メモリが足りない。 Solrのキャッシュを全Offに。 BOBO SolrPluginってのを利用 compressオプションも利用。 各スレーブにキューを用意して1つだけしか処理しない。(なんでだ??) ○結果 キャッシュはフィルタキャッシュのみ利用 ユーザが同じクエリを投げるのはほぼないので。 フィルタキャッシュのエントリのメモリ量の計算式(あとで資料が出てくるかなぁ。) ○問題点 ・レプリケーションでインデックスサイズの2倍の容量が必要になる。 ・レプリケーションの日時フォーマットのバグ(SOLR-1995)を踏んでしまった。 ・レプリケーション後にインデックスが消えない場合がある ○検討(1.4.1-\u0026gt;3.2) うれしい要素 レプリケーションバグがfix 省メモリや範囲検索の高速化など かなしい要素 compressが使えなく(しかも回答してからriindexしてくれる) ○検討 余計なインデックス消す nearinfinityが出しているlucene-compressionを利用 https://github.com/nearinfinity/lucene-compression ○残った問題 facet.rangeが使えないなど。 ○じゃあ集約サーバつくっちゃえ(すごいな。) facet書き換えコンポーネントなど。 ○シャードのインデックスサイズが下がった 130GiB-\u0026gt;90GiB これはlucene-compressionの効果 ○ここまでの変更はプラグインにて対応(この一覧いいかも) ○感想 コンポーネント化されてて、簡単に追加機能が実装可能 用途次第であまりスペック高くなくても使える。 Q\u0026amp;A Q:Twitterのデータのクロール方法は? A:HTMLをスクレイピングしている。publicなTLのみ。 Q:いきなりSolrに入れる?Solrの前処理は? A:SolrJを利用して前処理済みのデータを登録している。 4. 「Anuenueの紹介と最近の進捗」 by @takahi_i さん(mixi) ○自己紹介 ・NAIST出身 ・ファストサーチ ・今はmixi ○mixiとは? ○社内の緊急タスク ・内製検索エンジンをメンテナンスしやすいOSSにしたい! -\u0026gt;Solrを選択 Anuenueも実装 ○Anuenueの作成理由は? インデックス運用が面倒(検索(distributed search)はあるがインデックスは自前) クラスタ用のコマンドが提供されていない。 ○Anuenueが提供する機能 ・検索クラスタの簡単設定 ・クラスタ用コマンド ・もしかして機能 ○機能:Anuenueのクラスタ設定 Merger:クライアントからのクエリをMasterに分散 Master:インデックス作成側 Slave:検索用スレーブ。マスタからコピー ○クラスタの管理コマンド クラスタのコマンドを用意。 起動、コミット、登録など ○SolrCloud向けのAnuenueを検討中 branch-cloudにあります。 今後の予定 インスタンス追加削除を動的に実行できるようにしたい ○Hadoop Conferenceの宣伝w Oluolu:Hadoop上で動くクエリログマイニングツール Likelike:LSHをHadoopで実装(Hadoop Conference 2011 Fallで発表) 5. LT 5.1 「solrとRの連携について」 by @yutakashino さん(BakFoo) Python本、Zope本を書いてます。 ○NHKの実証実験で利用? ○TwitterストリームをSolrにストア facet.date ○Rでキーワード頻度グラフ Node.js、Redis、R、Solrを使ってる。しかもPython ○デモ キーワード+日付でグラフが出てくる。 Rでプロット。 GoogleのチャートAPIを利用すると面白いことができる。 5.2 「 Apache ManifoldCF」 by 阿部さん(ロンウィット) ○Apache Incubator ○Manifold Connector Framework Solr <- MCF <- web+non-web repositories すぐに利用可能。 ○概要 出力はSolr。 接続先はWeb、DB、CMS、などなどいろいろRepositoryConnectorというのがあります。 ○Crawler Agent クロールに関するJobの管理 接続先、スケジュールなど ○Windowsサーバのクロールもできる 社内のナレッジ共有などに使える。権限周りも簡単に対応可能。 JCIFS.jarによりWindowsの権限情報を取得 ○クロール設定画面もある デモ ○導入が簡単なのがおすすめ。 ○ManifoldCFの資料関連 http://www.manning.com/wright 懇親会についてはあとで記載します!! ということで追記です。 懇親会でも色々と面白い話を聞けました。 @PENGUINANA_さんにはCOOKPADのCI関連の話を聞けました。 1日に数度リリースするという話もあるようでした。\nあとは、Rについても@yutakashinoさんから概要が聞けたのが良かったです。\nちょっとだけ追記。まだ成形する予定ですが、とりあえず。\n追記:スライドが公開され始めたので。\n関口さんのスライドはこちら 阿部さんのスライドはこちら @PENGUINANA_さんのスライドはこちら。 @takahi_iさんのスライドはこちらからPDFダウンロード可能。\nその他に関連するブログも見つけましたので。 「Solr@Cookpad」- Solr勉強会で発表してきました Ars longa, vita brevis: 第6回 Solr 勉強会に行ってきた\n勉強会で出てきた各製品などのリンク: 色々とURLが出てきていたので、リンクをまとめておきます。\nlucene-compression Anuenue Apache Solr のラッパー Likelike LSH (Localtiy Sensitive Hashing)の実装 OluOlu 検索ログマイニングツール @takahi_iさんのLuceneRevolution2011のスライド Kuromoji 形態素解析器 lucene-gosen 形態素解析器(Senの後継) Apache ManifoldCF ","date":1315810980,"dir":"post/2011/","id":"37b622eaad1f79e759a722aacebf48ec","lang":"ja","lastmod":1315810980,"permalink":"https://blog.johtani.info/blog/2011/09/12/%E7%AC%AC6%E5%9B%9Esolr%E5%8B%89%E5%BC%B7%E4%BC%9A%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-09-12T16:03:00+09:00","summary":"「第6回Solr勉強会」に参加しました。 なんだかんだと第6回で、今のところ皆勤賞です。 ということで、主に自分用ですが、メモなどとったので。 概","tags":["勉強会"],"title":"第6回Solr勉強会に参加しました。(Jugemより移植)"},{"contents":"ということで、Ruby2日目の感想(2日目だけで2日間かかったのは内緒。。。) 今回もセルフスタディの私の回答が最後の方に記載されてます。見たくない人は気をつけてください。 ツッコミ大募集です。コメント欄にどしどしコメントください。そこは違うだろ?こっちのほうがいいのでは?という感じで。\n感想: ◎関数の定義:ありゃ、利用するのはダメなんだ、これじゃ。\u0026ndash;\u0026gt;単なるタイプミスでした。お恥ずかしい。。。 \u0026gt;\u0026gt; def tell_the_truth \u0026gt;\u0026gt; true \u0026gt;\u0026gt; end =\u0026gt; nil \u0026gt;\u0026gt; tell_the_trueth() NoMethodError: undefined method `tell_the_trueth\u0026#39; for main:Object from (irb):4 ◎配列:そしてシンタックスシュガー puts animalsで内容が出力されるのはうれしい。JavaだとHashCodeが出てくるから。出力メソッド書かないといけなくなる。 animals[-1]で最後の要素とかかなり便利。 animals[0..1]はRangeクラスを利用する形。Rangeはやはり便利。substringなどもできそう。 カラ配列の定義は必要。a = [] 1.9と1.8でinclude?の書き方が異なるので注意! 配列(Array)クラスは中はObjectが入る。 多次元配列もOK。popやpushでキューとしても利用可能。\n◎ハッシュ: Mapのようなもの。任意のキーが利用可能。:付きの文字列はシンボルと呼ばれる定数値を簡単に定義する方法。 object_idという属性?関数によりObjectのハッシュコードが取れるらしい。 ブレース=「{}」のカッコのこと。do~endでも代用可能\n◎コードブロックとyeild コードブロック=名前なし関数。習慣では複数行の場合、do/endで、1行は{}みたい。Javaと混同しそう。 コードブロックは引数も指定可能。 「yield」予約語?を利用してコードブロック自体をメソッド内部などで呼び出し可能。 ということで、コードブロックは引数にも指定できると。コードブロック=関数もObjectとして扱われてる感じか? 実行遅延、分岐、共通関数とか?Javaだとabstractメソッドを利用して処理するようなイメージか?ちょっと違うなぁ。 なれると、yieldはコードを読みやすくできそう。また、シンタックスハイライトしてくれるツールがあれば、更に便利。\n◎ファイルの実行 ruby ファイル名 vi、Emacs、TextMateなどがあるよ。\n◎クラスの定義 ※数字で始まる変数は利用できない!Javaと一緒 Tree.rbとログを参考にすること。 \u0026amp;使うとブロックに名前が付けられる。yieldじゃなくてもいい? クラス名はキャメルケース。 変数とメソッド名は「_」アンダーバーつなぎ インスタンス変数の頭は@ クラス変数は@@ 定数は大文字 ※メソッド名、変数名には違和感が。なんでこんな規則?? 判定用関数とメソッドには「?」(if test?)をつける!!Javaでいう「is」か。\n◎Mixin(多重継承?モジュールと呼ばれるものを利用) 多重継承のような類似の振る舞いを伝搬する仕組み。 Javaではインタフェースでやること。 Rubyではモジュールといい、関数と定数の集まり。 クラスに機能を盛り込む場合はincludeする ※複数includeして、includeしたものの中に同じメソッドとかあったらどーなる? \u0026ndash;\u0026gt;Overrideされた=includeがあとにあるもので上書きされる Abstractにできないものをモジュール化できるの楽。 javaだとstaticメソッドだらけのUtilクラスを別途起こすイメージだけど、内部で呼ばれるメソッド(コードブロック)が同じインタフェースじゃないと行けないから、インタフェースの記述もしないと行けない。 ただし、同一名のメソッドを持ってるとややこしそう。 ※モジュールからモジュールは呼べる?\n◎モジュール、Enumerable、セット EnumerableとComparable(JavaのCollectionまわりかな。) 宇宙船演算子(\u0026lt;=\u0026gt;)Javaのequalsに似てる any?とかCollectionUtils??に似たのあったな。 ※今利用しているクラスが何をincludeしてるかってのは分かる仕組みあるのかな? ※そういえば、メソッドごとに戻り値があるが、全部newされてインスタンス化されてGCの対象になってるのか?irbだけ? injectはすんなり使うイメージが出にくそう。また、ソースをぱっと見て理解出来ない。なれだろうけど。 ※injectしながらinjectとかあるんだろうな。\n(探してみよう:) ○コードブロックを使った場合と使わない場合の両方について、ファイルにアクセスするコードを書く。コードブロックの利点は? ※コードブロックあり。 ``` File.open(\u0026ldquo;tree.rb\u0026rdquo;, \u0026lsquo;r\u0026rsquo;) {|f| f.each {|line| puts \u0026ldquo;#{f.lineno} : #{line}\u0026rdquo;}}\n※コードブロックなし f = File.open(\u0026ldquo;tree.rb\u0026rdquo;, \u0026lsquo;r\u0026rsquo;) while line = f.gets puts \u0026ldquo;#{f.lineno} : #{line}\u0026rdquo; end\nコードブロックの利点: 見通しの良さ。行数が少なくてすむ。繰り返し処理が簡単に記述できる。 ※うーん、まだきちんと理解できてないか? \u0026lt;/dd\u0026gt; \u0026lt;dt\u0026gt;○ハッシュを配列に変換するにはどうすればよいか?また、逆に配列をハッシュに変換する方法は?\u0026lt;/dt\u0026gt; \u0026lt;dd\u0026gt; ※間違えた。。。 h = [:key1 =\u0026gt; \u0026ldquo;hoge\u0026rdquo;, :key2 =\u0026gt; \u0026ldquo;boke\u0026rdquo;, :key3 =\u0026gt; \u0026ldquo;fuga\u0026rdquo;] h.each {|key, value| puts \u0026ldquo;#{key} is #{value}\u0026rdquo;} =\u0026gt;key1hogekey2bokekey3fuga is\nハッシュ-\u0026amp;gt;配列変換 h.to_a\n配列-\u0026amp;gt;ハッシュ変換 a = [\u0026ldquo;value1\u0026rdquo;, \u0026ldquo;valu2\u0026rdquo;, \u0026ldquo;value3\u0026rdquo;] h = {} a.each {|i| h.store(a.index(i),i) }\n※また間違い?なんでそうなる? a.inject(h2) {|hoge, i| hoge[a.index(i).to_s] = i}\nこっちならいいみたい。まだinjectがわかってない。 a.inject(h2) {|hoge, i| hoge[a.index(i).to_s] = i;puts \u0026ldquo;#{i}\u0026rdquo;; hoge}\n\u0026lt;/dd\u0026gt; \u0026lt;dt\u0026gt;○ハッシュの各要素について繰り返すにはどうすればよいか?\u0026lt;/dt\u0026gt; \u0026lt;dd\u0026gt; h.each {|key, value| puts \u0026ldquo;#{key} is #{value}\u0026rdquo;}\n\u0026lt;/dd\u0026gt; \u0026lt;dt\u0026gt;○Rubyの配列はスタックとしても使える。スタック以外に配列で実現可能なよくあるデータ構造体を挙げよ。\u0026lt;/dt\u0026gt; \u0026lt;dd\u0026gt;キュー。 他にある?Treeとか?Treeはハッシュじゃないか?Set?順番が関係ないけど。\u0026lt;/dd\u0026gt; \u0026lt;/dl\u0026gt; ### **(試してみよう:)** \u0026lt;dl\u0026gt; \u0026lt;dt\u0026gt;○最初に、eachだけを用いて、16個の数値と4個の数値の配列の中身を同時に出力せよ。次に、同じ事をEnumerableのeach_sliceを用いて実行せよ。\u0026lt;/dt\u0026gt; \u0026lt;dd\u0026gt; \u0026lt;span style=\u0026#34;color:#FF0000\u0026#34;\u0026gt;\u0026lt;em\u0026gt;※これ日本語がわからないんだが、4個ずつ出せってことか??\u0026lt;/em\u0026gt;\u0026lt;/span\u0026gt;ということで、「16個の数字の配列の中身を4個ずつ同時に出力せよ。」と解釈して実装してみた ※each利用版 a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] s = [] a.each do |b| unless s.length \u0026lt; 4 puts s.inspect s.clear end s \u0026laquo; b end\n※each_slice a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] a.each_slice(4) {|b| puts b.inspect}\nまた、えらい違いだな。 \u0026lt;/dd\u0026gt; \u0026lt;dt\u0026gt;○Treeクラスは面白いクラスだったが、きれいなインタフェースを用いて新しいツリーを指定することは出来なかった。そこで、initializerにハッシュと配列が入れ子になった構造体を指定できるようにせよ。具体的には、次のようなツリーを指定できるようにしたい。{\u0026#39;grandpa\u0026#39; =\u0026amp;gt; { \u0026#39;dad\u0026#39; =\u0026amp;gt; {\u0026#39;child 1\u0026#39; =\u0026amp;gt; [], \u0026#39;child 2\u0026#39; =\u0026amp;gt; [] }, \u0026#39;uncle\u0026#39; =\u0026amp;gt; {\u0026#39;child 3\u0026#39; =\u0026amp;gt; [], \u0026#39;child 4\u0026#39; =\u0026lt; [] } } }\u0026lt;/dt\u0026gt; \u0026lt;dd\u0026gt;\u0026lt;span style=\u0026#34;color:#FF0000\u0026#34;\u0026gt;※root(ここではgrandpaレベル)が複数あると破綻しないのか?\u0026lt;/span\u0026gt; class Tree attr_accessor :children, :node_name\ndef initialize(name, children=[]) @children = children @node_name = name end\ndef initialize(hash) hash.each do |key, value| @node_name = key @children = value.inject([]) do |array, (child_key, child_val)| puts \u0026ldquo;inject! #{key}\u0026rdquo; [Tree.new({child_key =\u0026gt; child_val})] + array end end end\ndef visit_all(\u0026amp;block) visit \u0026amp;block children.each {|c| c.visit_all \u0026amp;block} end\ndef visit(\u0026amp;block) block.call self end end\n残念ながらちょっとカンニングしてしまいました。。。 \u0026lt;/dd\u0026gt; \u0026lt;dt\u0026gt; ○ファイル内で、あるフレーズを含む全ての行を出力する簡単なgrepをかけ。簡単な正規表現でマッチングを行い、ファイルから行を読み出す必要がある(この処理はRubyでは驚くほど簡単にかける)。必要なら行番号も出力してみると良い。\u0026lt;/dt\u0026gt; \u0026lt;dd\u0026gt;※メソッドだけでいいな。\u0026lt;span style=\u0026#34;color:#0000FF\u0026#34;\u0026gt;ファイルクローズはこの記述の場合はコーディングブロックのendのタイミングでクローズされるのか?\u0026lt;/span\u0026gt; class RegGrep def grep(filename, regexp) File.open(filename, \u0026lsquo;r\u0026rsquo;) do |f| f.each do |line| puts \u0026ldquo;#{f.lineno} : #{line}\u0026rdquo; if line.match(regexp) end end end end\n\u0026lt;/dd\u0026gt; \u0026lt;/dl\u0026gt; ということで、2日目終了。 恥ずかしいコードだらけだけど、ぜひツッコミ入れてもらえると助かります。 数年前までは、恥ずかしいからとか見せられるレベルじゃないからと、ほとんどアウトプットしなかったのですが、 最近はそれではものすごく損をしていると思っています。 ホントは発表するとか議論するとかする場もあればいいのですが。 アウトプットすることで、フィードバックが貰えて、いろんなかたの考えが参考になり、糧となり成長していけるのかと。 (これじゃ成長できないレベルだよという話でなければいいのだが。。。) 一度、Rubyのプロフェッショナル各位に見てもらいたいなぁw ","date":1315588260,"dir":"post/2011/","id":"73262345214f9b7794f2cc4a612b15e8","lang":"ja","lastmod":1315588260,"permalink":"https://blog.johtani.info/blog/2011/09/10/7%E3%81%A4%E3%81%AE%E8%A8%80%E8%AA%9E-7%E3%81%A4%E3%81%AE%E4%B8%96%E7%95%8C-ruby-2%E6%97%A5%E7%9B%AE/","publishdate":"2011-09-10T02:11:00+09:00","summary":"ということで、Ruby2日目の感想(2日目だけで2日間かかったのは内緒。。。) 今回もセルフスタディの私の回答が最後の方に記載されてます。見た","tags":["読書"],"title":"「7つの言語 7つの世界」 Ruby 2日目(Jugemより移植)"},{"contents":"実に3年ぶりくらいにゆっくりできる日々が訪れたので、積読状態の本を消化しようと「7つの言語 7つの世界」を読み始めました。\nせっかくブログも始めたので、備忘録も兼ねて感想などを書いていこうかと。\nこの本ですが、以下の7つの言語についてエッセンスがまとめられています。\nRuby Io Prolog Scala Erlang Clojure Haskell まずはRubyからです。 ここ2年ほどRuby(Rails)に関連する仕事をしていたのですが、Ruby周りはプロフェッショナルな方たちがいたので、きちんと勉強していないことがこの本を読み始めてわかりました。\nということで、前置きはそれなりな記述ですが、感想は適当になりますので、あしからず。\n感想: irbが便利。簡単に動作確認ができるのが便利。Javaだとコンパイルが必要。 変数を定義する必要がない気軽さはある。 必ず戻り値が帰ってくる「puts \u0026lsquo;hello, world\u0026rsquo;」でも。=\u0026gt;nil putsは楽かな。まぁ、Eclipse使ってると一緒か。 「4」もオブジェクトとなっている。ここもJavaと異なる。 (x \u0026lt;= 4).classという記述でTrueClassというクラスだとわかる。 unlessが結構便利。ただし、記述方法が多数あるので、可読性は落ちる?場合によってはわかりやすいか? あと、括弧()がないのも慣れない。(まぁ、これは慣れの問題。ただし、カッコありでもOK) {}のかわりがif~endなのはわかりやすいかも。 if not はわかりやすくていい。!はだいたい間違えるから。。。 whileも1行形式で書けるのか。「x = x + 1 while x \u0026lt; 10」慣れないと厳しい。個人的には混在すると読めないなぁ。 nilとfalse以外がすべてtrueに評価されるのは厳しいのでは?型のチェックがないので、booleanが入ってると想定してない場合に挙動を読めないかも。実行時に動作が変だなーと思うことが出てきそう。 and、orの記述が使えるのは読みやすい。ただし、混在するとやっかい。 判定結果が明らかになった時点で実行が中止されるのは普通。\u0026amp;、|の挙動はJava同様。\nやりながら疑問点:\nNetBeansとかIDEでフォーマッタやcheckstyleみたいなのはあるのか? コーディング規約はあるのか?(2日目に「習慣」があるらしいとの記載があった。) 必ず戻り値が戻ってくるのは、必ずGC対象になりうるオブジェクトが生成されるってことか? ここまでが感想と疑問点。で、この本の面白いところは最後に調査、コーディングを行う練習問題的なものがある部分です。 一応、私なりの答えを書いておこうかと。(一覧などで見えないようにはしますが、ネタバレがあるので注意してください。)\nということで、セルフスタディの回答。\n(探してみよう) ○Ruby API http://ruby-doc.org/core/ ○Programming Ruby: The Pragmatic Programmer's Guideのオンライン版 http://www.ruby-doc.org/docs/ProgrammingRuby/参考資料:http://www.swlab.it.okayama-u.ac.jp/man/ruby/uguide/uguide00.html ○文字列の一部を置換するメソッド \"hello\".gsub(/[aeiou]/, '*') ○Rubyの正規表現に関する情報 日本語:http://www.namaraii.com/rubytips/?%A5%D1%A5%BF%A1%BC%A5%F3%A5%DE%A5%C3%A5%C1 英語の試せるサイト(irbが動けば必要ないかもね):http://rubular.com/ ○Rubyの範囲に関する情報 日本語:http://doc.okkez.net/static/192/class/Range.html 英語:RDocのRangeクラスに相当するのかな。 (試してみよう) ○文字列\"Hello, world\"を出力する。 ``` ○文字列\"Hello, Ruby\"の中の\"Ruby\"という単語のインデックスを検索する。 ``` s = \u0026lsquo;Hello, Ruby\u0026rsquo; s.index(\u0026lsquo;Ruby\u0026rsquo;) //indexofで間違えた\n\u0026lt;dt\u0026gt;○自分の名前を10回出力する。\u0026lt;/dt\u0026gt; \u0026lt;dd\u0026gt;``` ※まずは、正統派。 i = 0 while i \u0026lt; 10 puts \u0026#34;johtani\u0026#34; i = i + 1 end ※Rangeを利用 (1..10).each {|n| puts \u0026#34;johtani #{n}\u0026#34;} ※forもあるよね for i in 1..10 puts \u0026#34;johtani\u0026#34; end ※timesってのもある。(0始まり) 10.times {|n| puts \u0026#34;johtani #{n}\u0026#34;} ※uptoなんてのもあるのか。 1.upto(10) {|n| puts \u0026#34;johtani #{n}\u0026#34;} ※downtoも 10.downto(1) {puts \u0026#34;johtani\u0026#34;} ※stepもある。 10.step(1, -1) {puts \u0026#34;johtani\u0026#34;}//step(上限,ステップ) ```\u0026lt;/dd\u0026gt; \u0026lt;dt\u0026gt;○文字列\u0026#34;This is sentence number 1\u0026#34;の1を10までカウントアップしながら10回出力する。\u0026lt;/dt\u0026gt; \u0026lt;dd\u0026gt;``` 1.upto(10) {|n| puts \u0026#34;This is sentence number #{n}\u0026#34;} ※あとは上記と一緒 ```\u0026lt;/dd\u0026gt; \u0026lt;dt\u0026gt;○ファイルに格納されているRubyプログラムを実行する。\u0026lt;/dt\u0026gt; \u0026lt;dd\u0026gt;``` vi hoge.rb ※#上記処理をどれか記述 $ ruby hoge.rb ○ボーナス問題:少し物足りない人は、乱数を選択するプログラムを書いてみてほしい。プレーヤーに数字を選択してもらい、その数字が生成された乱数よりも大きいか小さいかを返す。 ``` -- coding: utf-8 -- range = (1..100) while true puts \u0026ldquo;#{range.min}から#{range.max}の数字を入力してください\u0026rdquo; n = gets n = n.to_i if range.include?(n) break; else puts \u0026ldquo;範囲外の入力値です。もう一度入力してください\u0026rdquo; end end i = rand(range.max) if i \u0026lt; n puts \u0026ldquo;入力「#{n}」は乱数「#{i}」より大きいです\u0026rdquo; elsif i == n puts \u0026ldquo;入力「#{n}」は乱数「#{i}」と等しいです\u0026rdquo; else puts \u0026ldquo;入力「#{n}」は乱数「#{i}」より小さいです\u0026rdquo; end\n\u0026lt;/dl\u0026gt; とまぁ、こんな感じ。こんな方法もあるよ、ここおかしくない?などあれば、コメント欄まで。 リアクション大募集です。 はやく、シンタックスライター導入せねば。 ","date":1315545120,"dir":"post/2011/","id":"9baedcd033169611a42c3cfd58b3ae03","lang":"ja","lastmod":1315545120,"permalink":"https://blog.johtani.info/blog/2011/09/09/7%E3%81%A4%E3%81%AE%E8%A8%80%E8%AA%9E-7%E3%81%A4%E3%81%AE%E4%B8%96%E7%95%8C-ruby-1%E6%97%A5%E7%9B%AE/","publishdate":"2011-09-09T14:12:00+09:00","summary":"実に3年ぶりくらいにゆっくりできる日々が訪れたので、積読状態の本を消化しようと「7つの言語 7つの世界」を読み始めました。 せっかくブログも始め","tags":["読書"],"title":"「7つの言語 7つの世界」 Ruby 1日目(Jugemより移植)"},{"contents":"現在の出先でMBAを使えないので、なかなか進んでいないMBAのセットアップです。。。\nとりあえず、Eclipse、homebrewをインストールしたので、lucene-gosenの開発やビルドには支障がない程度になってきました。(肝心のSolrがまだ動く状況になかった。。。)\nあとは、Windowsで使用頻度の高いソフトを列挙して、対応するMacのアプリを探そうかと。 まずは、Windowsでよく利用するソフトのリストアップ\nEclipse Cygwin TeraTerm WinSCP meadow サクラエディタ WinMerge PDF-XChange Viewer Evernote FreeMind VMWare こんなところかな。 a.~e.についてはMacOS特に問題なし。Eclipseは入れたし、その他は標準で入ってるものでまかなえると。 f.についてもEmacsで当面対応する予定。ただ、OmmWriter やCotEditorがおすすめらしいと聞いてます。 g.についてはFileMergeなるものがあるらしいので、試してみようかと。 h.は現状Adobe Readerです。ほかにいいのあるのかしら。PDF-XChange Viewerはちなみに、Solr入門を書くときに編集の方から教えてもらったPDFのビューワです。コメントとかハイライトできるのが便利でした。 i.はMacOS版をインストールして、すでに活用中。 j.については一時期活用していたのですが、最近利用していないです。なので、保留 k.についてはVirtualBoxをインストールしてみました。フリーだったので。WindowsではVMWareだったのですが。。。\nほんとにこれくらいで大丈夫かどうかはもう少し使ってみてからかなぁと。 その他におすすめ、これがあるとかなり便利などあれば、教えてもらえると助かります。 まだ、MacOSに触り始めたところなので、細かな部分のカスタマイズなどができていないので、その辺りもオイオイ考えていこうかと。\n※余談ですが、現在「7つの言語 7つの世界」を読み始めました。いろいろな言語の特徴について学べる本のようでかなり楽しく感じています。どうしてもJavaで仕事優先だとコーディングする速度優先でJavaばかり使ってしまうので。 いい頭の体操にもなりそうなのでオススメです。(といってもまだ、最初の言語Rubyなのですが。。。)\n","date":1315329480,"dir":"post/2011/","id":"f23ca2aa066b1ee0fa4df1f2f865be4c","lang":"ja","lastmod":1315329480,"permalink":"https://blog.johtani.info/blog/2011/09/07/mba%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97%E5%82%99%E5%BF%98%E9%8C%B2%E3%81%9D%E3%81%AE%EF%BC%93/","publishdate":"2011-09-07T02:18:00+09:00","summary":"現在の出先でMBAを使えないので、なかなか進んでいないMBAのセットアップです。。。 とりあえず、Eclipse、homebrewをインストー","tags":["備忘録"],"title":"MBAセットアップ備忘録その3(Jugemより移植)"},{"contents":"すぐにテストケース追加しますといいつつ、はや一週間。\nようやく仕事が落ち着いたので、テストケースを追記しました。まだパッチの段階です。 一応、異なる辞書の読み込みのテストケースなどを追加し、テストケース追加時点で いくつか気になったところもあったので、ついでに修正を加えました。 一応、辞書の分離+複数辞書対応については現時点ではこんなところかと。\nあと、もう1項目対応してからtrunkに取り込む予定です。 対応する項目とは以下の項目です。\nカスタム辞書ビルドの簡易化 以前の記事にも書いていますが、カスタム辞書のビルドが思いのほか手間がかかります。 辞書の外部化は対応したのですが、せっかく辞書が外部化できたのですから、コマンド(ant?)で一発で カスタム辞書を含んだビルドをしたくなるのが人情です。 辞書なしのjarファイルもあることなので、すぐに対応可能かと。 ということで、今週中には対応する予定です(宣言しないとまた先延ばしになりそう)\n忘れてそうだったらTwitterやコメントでツッコミを入れてもらえると助かります。\n","date":1315328188,"dir":"post/2011/","id":"3c2523e65ff953fd73579aaaf5d7ce36","lang":"ja","lastmod":1315328188,"permalink":"https://blog.johtani.info/blog/2011/09/07/%E8%BE%9E%E6%9B%B8%E5%88%86%E9%9B%A2%E3%81%AE%E3%83%86%E3%82%B9%E3%83%88%E3%82%B1%E3%83%BC%E3%82%B9%E8%BF%BD%E5%8A%A0%E3%81%A8%E6%AE%8B%E3%82%BF%E3%82%B9%E3%82%AF/","publishdate":"2011-09-07T01:56:28+09:00","summary":"すぐにテストケース追加しますといいつつ、はや一週間。 ようやく仕事が落ち着いたので、テストケースを追記しました。まだパッチの段階です。 一応、異","tags":["lucene-gosen"],"title":"辞書分離のテストケース追加と残タスク(Jugemより移植)"},{"contents":"先日、辞書のjarファイルからの分離についてパッチと記事を書きました。\nIssueにあげていたパッチをRobertさんが見ていたらしく、次のようなコメントをもらいました。\nMaybe if we change SenFactory.getInstance to use a ConcurrentHashMap then you can easily use multiple dictionaries at the same time? 「SenFactory.getInstanceメソッドでConcurrentHashMap使ったら複数辞書対応できるんじゃない?」(訳) たしかに。。。なんで思いつかなかったのだろう。。。\nということで、実装してみました。 パッチはこちら。\n使い方ですが、先日の記事と代わりはありません。 ただし、あった制限事項が次のようになります。\nマルチコアの設定でsharedLibにlucene-gosenのjarを含まない 同一コア内で異なるdictinaryDirの指定はできない ソースの変更点ですが、ものすごく単純です。 dictionaryDirに指定された文字列をキー、その辞書ディレクトリを利用したSenFactoryのインスタンスを値に持つmapをSenFactory内に保持します。あとは、SenFactoryのgetInstance(String dictionaryDir)メソッドで取得する際にmapに対応するインスタンスがあれば、そのインスタンスをなければ、dictionaryDirから辞書を読み込んでインスタンス生成してmapにキャッシュしつつ返すという実装に変えただけです。 ということで、次のようなIPADICとNAIST-JDIC for ChaSenを同時に使う設定も可能となります。\n\u0026lt;fieldType name=\u0026#34;text_ja_ipadic\u0026#34; class=\u0026#34;solr.TextField\u0026#34; positionIncrementGap=\u0026#34;100\u0026#34;\u0026amp;gt; \u0026lt;analyzer\u0026amp;gt; \u0026lt;tokenizer class=\u0026#34;solr.JapaneseTokenizerFactory\u0026#34; dictionaryDir=\u0026#34;/tmp/lucene-gosen/dictionary/ipadic\u0026#34;/\u0026amp;gt; \u0026lt;/analyzer\u0026amp;gt; \u0026lt;/fieldType\u0026amp;gt; \u0026lt;fieldType name=\u0026#34;text_ja_naist_chasen\u0026#34; class=\u0026#34;solr.TextField\u0026#34; positionIncrementGap=\u0026#34;100\u0026#34;\u0026amp;gt; \u0026lt;analyzer\u0026amp;gt; \u0026lt;tokenizer class=\u0026#34;solr.JapaneseTokenizerFactory\u0026#34; dictionaryDir=\u0026#34;/tmp/lucene-gosen/dictionary/naist-chasen\u0026#34;/\u0026amp;gt; \u0026lt;/analyzer\u0026amp;gt; \u0026lt;/fieldType\u0026amp;gt; あと、注意事項です。 普通に考えるとわかることですが、辞書を複数読み込めるようになったことで、読み込んだ複数の辞書をメモリに保持することになります。ですので、今までよりも多くのメモリを利用するので、Heapのサイズには注意が必要です。 例のごとく(ほんとよくない。。。)テストコードを書いていない状態のパッチをまずはアップしました。 テスト書かないと。。。次回はテストコードかきましたと言う報告をしたいな\nあと、Robertさんのコメントの前に@shinobu_aokiさんからJapaneseTokenizerFactoryの設定では辞書のディレクトリを$SOLR_HOME/confからの相対パスで記述できるというパッチもいただいています。 この部分については先日と使い方が異なります。 (すみません、まだきちんとソースを見れてないです。。。)\n","date":1314668040,"dir":"post/2011/","id":"88a8e608108be939da9aab5a9a8af7d1","lang":"ja","lastmod":1314668040,"permalink":"https://blog.johtani.info/blog/2011/08/30/%E8%A4%87%E6%95%B0%E8%BE%9E%E6%9B%B8%E3%81%AE%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%81%BF%E6%A9%9F%E8%83%BD%E8%BF%BD%E5%8A%A0%E4%BB%AE/","publishdate":"2011-08-30T10:34:00+09:00","summary":"先日、辞書のjarファイルからの分離についてパッチと記事を書きました。 IssueにあげていたパッチをRobertさんが見ていたらしく、次のよ","tags":["lucene-gosen"],"title":"複数辞書の読み込み機能追加(仮)(Jugemより移植)"},{"contents":"ひさびさに、lucene-gosenの話題です。\nlucene-gosenはjarファイルに辞書も同梱されており、jarファイルをクラスパスに取り込むだけで、 簡単に形態素解析器が利用できるといお手軽さがあり、便利です。\nですが、以前カスタム辞書の登録について記事を書いたように、カスタム辞書の登録は思いのほか手間がかかります。 lucene-gosenのソースをダウンロードし、lucene-gosenを一度コンパイルし、カスタム辞書のcsvファイルを作成し、カスタム辞書を取り込んだ辞書のバイナリを生成し、最後にjarファイルにするという作業です。(書くだけでいやになってきました。。。)さらに作成したjarファイルをSolrや各プログラムに再度配布するという具合です。\nそこで、辞書ファイルの外部化ができないかという話があがっていました。 すこし時間ができたので、山積みになっているissueを横目に軽く実装をしてpatchをissueにアップしました。\n機能としてはごく簡単で、JapaneseTokenizerのコンストラクタに辞書のディレクトリ(*.senファイルのあるディレクトリ)を指定可能にしただけです。 また、JapaneseTokenizerFactoryでもdictionaryDir属性で指定可能になっています。 まずは、コンパイルの方法から。 trunkをSVNでcheckoutし、issueにあるpatchをダウンロードして適用します。(svnのチェックアウトについてはこちらを参考にしてください。)\n$ cd lucene-gosen-trunk $ patch -p0 --dry-run \u0026lt; lucene-gosen-separate-dictionary.patch $ patch -p0 \u0026lt; lucene-gosen-separate-dictionary.patch 次に、antを実行し辞書なし版のjarファイルをビルドします。\n$ ant nodic-jar これで、dictディレクトリに「lucene-gosen-1.2-dev.jar」というjarファイルが出来上がります。 (※ただし、これだけでは動作しないので、別途辞書のコンパイルは必要です。)\n次に、指定の仕方です。JapaneseTokenizerのコンストラクタは第3引数に辞書のディレクトリ(フルパスor実行ディレクトリからの相対パス)を渡すだけです。\nTokenizer tokenizer = new JapaneseTokenizer(reader, compositeTokenFilter, dictionaryDir); 最後に、Solrのtokenizerタグでの指定方法です。\n\u0026lt;fieldType name=\u0026#34;text_ja\u0026#34; class=\u0026#34;solr.TextField\u0026#34; positionIncrementGap=\u0026#34;100\u0026#34;\u0026amp;gt; \u0026lt;analyzer\u0026amp;gt; \u0026lt;tokenizer class=\u0026#34;solr.JapaneseTokenizerFactory\u0026#34; dictionaryDir=\u0026#34;/hoge/dictionarydir\u0026#34;/\u0026amp;gt; \u0026lt;/analyzer\u0026amp;gt; \u0026lt;/fieldType\u0026amp;gt; 以上が、簡単な設定の仕方です。なお、辞書を内包したjarファイルでもdictionaryDirは利用可能です。優先度としては、dictionaryDirが指定されている場合はdictionaryDirを探索しファイルがなければRuntimeExceptionです。指定がnullもしくは空文字の場合はjarファイルの辞書の読み込みを行います。\n次に利用シーン、制限事項についてです。 利用シーンとしてはカスタム辞書を定期的にメンテナンス(追加更新)しながらSolrを運用するというのが想定されます。定期的に辞書の再読み込みをしたい場合です。 利用方法は次のようになります。\nSolrのマルチコア構成を利用する 各コアごとにlib/lucene-gosen-1.2-dev.jarを用意 辞書の更新が終わったらコアのRELOADを実施 コアをリロードすることで、lucene-gosenが辞書を再読み込みようになります。(現状でも再読み込みするが、jarファイルを再配置しないといけない。)あとは、定期的に辞書ファイルを更新、再構築しコアをリロードすれば、 リロード後に新しい辞書が利用できるという具合です。 (もちろん、辞書更新後に入った単語は辞書更新以前に作成したインデックスにはでてこないですが。。。) また、コアごとにdictinaryDirを別々に指定することも可能です。\n制限事項は次のようになります。\nマルチコアの設定でsharedLibにlucene-gosenのjarを含まない 同一コア内で異なるdictinaryDirの指定はできない 以上が、辞書の外部ファイル化のパッチについてでした。 少しテストケースを追加したら、trunkにコミットする予定です。興味があれば、パッチを利用してみてください。\nSyntaxHighlighterの導入をしないとソースコードが見にくいですね。。。導入を検討しないと。。。どこかにWebサーバ用意しないとダメかも\n","date":1314062760,"dir":"post/2011/","id":"2f1ec795216d5bafa33a810af3421942","lang":"ja","lastmod":1314062760,"permalink":"https://blog.johtani.info/blog/2011/08/23/%E8%BE%9E%E6%9B%B8%E3%81%AEjar%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%8B%E3%82%89%E3%81%AE%E5%88%86%E9%9B%A2/","publishdate":"2011-08-23T10:26:00+09:00","summary":"ひさびさに、lucene-gosenの話題です。 lucene-gosenはjarファイルに辞書も同梱されており、jarファイルをクラスパスに","tags":["lucene-gosen"],"title":"辞書のjarファイルからの分離(Jugemより移植)"},{"contents":"すみません、また、MBA関連の記事になってしまいました。 ということで、備忘録その2です。\n前回からいくつかインストールや環境の設定をしたので、リストアップ。\nVirtualBoxとWindowsのインストール homebrewのインストール KeyRemap4MacBookのインストール Growlのインストール Time Machine用HDDの購入と設定 VirtualBoxのインストールとWindowsXPのセットアップ。会社関連でどうしてもWindowsが必要なので、 とりあえず、VirtualBoxとWIndowsを入れました。これまでのWindows環境ではVMWareを利用してたのですが、 Macだと有償ということで、無償版が存在するVirtualBoxを選択。 MBAにはDVDのドライブがなく、また、ケチって購入しなかったので、ちょっと手間取りました。 自宅のデスクトップでXPのイメージをisoにして、MBAにコピーしてからインストールと。。。 ただ、MBAのSSDの効果なのか、XPの起動がすごく速くてびっくりです。\nhomebrewのインストールは、まだインストールしただけの状態。。。 MacPortsってのがあるというのは知っていたのですが、最近はこちらがいいとのこと。 ちなみに、MacPortsにはSolrがあるらしいです。デフォルトのため、lucene-gosenとか入れる必要がありますが。\nKeyRemap4MacBookのインストール。入れた方がいいですよと言われてたのだが、きちんと調査してなく、 キーの入れ替えができる程度だと思ってました。昨日、EmacsModeなるものが存在するというのをKeyRemap4MacBookのドキュメントを読んでいて発見し即インストール。 とりあえず、Ctrl-x,Ctrl-cでEvernoteが終了できて喜んでるところです。\nGrowlのインストール。KeyRemap4MacBookのCtrl-xを通知してくれます。ほかにも使い方があるかは調査が必要。\nあとは、昨日、ビックカメラでWDの2TBのHDDを購入してTimeMachineの設定をしてバックアップをとりました。 まだバックアップをとっただけで、差分を見たりはしていないです。帰ってからやってみようかと。\n最後に、ケースを買いました。封筒とかいろいろ考えたのですが、やはり機能重視ということで、以下のケースです。 できれば、ファスナーが2つついていて、両方からあけられるとよかったのですが。リュックとショルダーバッグを使い分けるので、横でも縦でも取り出しが楽なものがよかったので、このケースを買いました。 一応、がんばれば縦でも出せるので。あとは、PCだけもって移動することもあるため、取っ手があるのが便利かと。\nとまぁ、お盆なので、このエントリーで許してください。次回は技術的なことを書きますので。。。 CaseLogic 機能的なモバイルコンピュータケース(13~14.1インチPC対応)、MacBookやMacBook Proにも対応 ダークグレー UNS-114J-DG ","date":1313369460,"dir":"post/2011/","id":"ce0aea06d44878b4a373efe090a66a62","lang":"ja","lastmod":1313369460,"permalink":"https://blog.johtani.info/blog/2011/08/15/mba%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97%E5%82%99%E5%BF%98%E9%8C%B2%E3%81%9D%E3%81%AE%EF%BC%92/","publishdate":"2011-08-15T09:51:00+09:00","summary":"すみません、また、MBA関連の記事になってしまいました。 ということで、備忘録その2です。 前回からいくつかインストールや環境の設定をしたので、","tags":["備忘録"],"title":"MBAセットアップ備忘録その2(Jugemより移植)"},{"contents":"Mac Book Airのセットアップ関連の備忘録\n(今回は備忘録なので、文体も変かも)\nインストールしたもの(順不同)だいたい、このサイトを参考にした。\nEvernote Dropbox XCode Twitter YoruFukurou GNU Emacs For Mac OS X Java Office for mac 現状はこんなところ。\nまだ、キーボードの配列とショートカット、ウィンドウの切り替えなどがすぐにできないので、かなりおぼつかない状態。\nCtrl+aなどの操作は快適なのだが、ウインドウを閉じたりする場合のcommandキーの扱いがまだなれない。キー配置を切り替えたりした方がいいのか悩み中。 Windowsでは長年XKeymacsを使ってきたため、通常のOfficeなどもCtrl+x Ctrl+sなどで閉じていたので、command+qなどがすんなり出てこない。。。\nあとは、VirtualBoxにWindowsを入れて、Eclipseを入れればなんとか、WindowsPCからMBAへの切り替えができそう。\n残っている課題は以下の通り。\nTime Machine環境の整備USB接続のHDDの導入(ミラーリング対応にするか悩み中)※ちなみにうちで使ってるNASは古い+NFSマウントできない機種だった。。。 対応可能だったらScientific Linux+Netatalk環境などを用意するのも考えたんだが。 homebrewのインストール 日本語入力(GoogleIME?SKK?) ウォークマン、Xperia arcの運用方法まぁ、今まで使ってたPCで対応かな キーの配置Emacsのショートカットに変更できたりするか調査したい データの移行Windowsに入ってるデータのうち移行するものしないものの選別Macでは利用できないデータやファイルもあると思う。 解凍ツールの選別?いるのかな? ブラウザのインストールchrome、Firefoxはいれるかな。 メーラーのインストールWindwosではBecky!を使ってたのだが、どうするか。デフォルトメーラで様子見? ウイルス対策ソフトの導入Macってどんなソフトがあるかがわからない。。。 あと、1週間触っての感想\nまずは、良かった点。\nいろんなUIがよくできてるセットアップなどきれいな画面で説明が進むのが新鮮だった。あと、フォントのきれいさも新鮮。これは、今までのPCが古いからかもしれないが。 トラックパッドがいいまだなれてないけど、スイスイ動くのでストレスなく作業できる。スワイプとかも画面の移動が楽でいい。 静かで速いSSDのため、静かだし起動がすごく速い。会社で支給されてるPCもSSD(3年くらい前のもの)だけど、こんなに起動などがはやくない。 あとは、気になった点。\nAppStoreでページ間のスワイプができない。かなり使いづらい。Safariと同じイメージでいるので。 手首がいたい手前のエッジ部分が手首に当たってちょっといたい。 アプリインストール時にファンがうるさい動画などはまだ見てないが、Office、XCodeのインストール時にファンの排気音がうるさくなり、結構な熱を発していた ファーストインプレッションはこんな感じ。\nただ、前回も書いたようにうらやましかったのもあり、かなり満足している。 もっと触る時間が欲しいのだが、なかなかとれないのが歯がゆい。。。\n持ち歩くようになったらとりあえず、「7つの言語 7つの世界」を読み進め+写経をやる予定。\n","date":1312904760,"dir":"post/2011/","id":"c0e423f9ac41cc5b265c95a3e97e3fcb","lang":"ja","lastmod":1312904760,"permalink":"https://blog.johtani.info/blog/2011/08/10/mba%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97%E5%82%99%E5%BF%98%E9%8C%B2/","publishdate":"2011-08-10T00:46:00+09:00","summary":"Mac Book Airのセットアップ関連の備忘録 (今回は備忘録なので、文体も変かも) インストールしたもの(順不同)だいたい、このサイトを参考にした。 Evernote Dropbox","tags":["備忘録"],"title":"MBAセットアップ備忘録(Jugemより移植)"},{"contents":"個人用のPCを8年ぶりに新調しました。\n前回購入した家のデスクトップPCがもう8年ものになりつつあるということで、\nさすがに今年はPCを買おうと思い、年初からいろいろと調べていました。\n当初は次もデスクトップPCを購入する予定でした。ただ、次のような状況ということもあり\nデスクトップは見送ることにし、代わりにノートPCにすることに。\n通勤時間が1時間を超えること\n基本、客先に出向いての仕事\n家でPCに触る時間が少ない(家族サービスのため。)\nで、ここ数週間悩んでいたのですが、Mac Book Air 13インチを購入しました。(そのMBAから初投稿です。)\n実は、Apple製品はこれが初の購入となります。\n対抗馬としてあがっていたのはSonyのVAIO Type Zでした。\n元々ソニスト(ソニー大好き)であり、携帯(Xperia arc)、ウォークマン(Sony)、PSP go、ハンディカムなど、\nソニー製品に囲まれており、デザインもType Zのほうが好みなのですが、MBAを購入しました。\nこの理由なのですが、私が大学時代にさかのぼります。\n情報系の大学の出身で、はじめてきちんと触ったマシンがSunOS4.1(最後の数年はSolaris2.6)でした。\nその後、大学6年間は基本的にEmacsでメールをみて、Emacsで文章を書いていました。\nそのため、社会人になってからもEmacsのキーバインドから抜け出せない日々を送っていました。\n社会人ではやはりWindowsでしたが、XKeymacsというフリーソフトのおかげ(せい?)でEmacsの\nショートカットからは抜け出せないまま。(家のPCはXPで、XKeymacsがインストールされてます。)\n今までの流れだと、何も考えずにWindows7+XKeymacsの流れだったのですが。。。\n職場でWindows7のPCを使う機会があり、XKeymacsを入れてみたのですが、これまでとことなり、\nうまく機能しないことこの上なし(例:chromeのアドレスバーでCtrl+Kとかできないなど)。\nさらに、64bit版の場合、XKeymacsを32bit、64bitの2つインストールしないといけないことに。(32bit用アプリのために32bitを入れないといけない)\nで、数ヶ月使っているのですが、ちょっとずつストレスがたまっている始末。。。\n今までは、「Mac?今更恥ずかしくてかえない」「Mac?おしゃれすぎて無理」「Apple?MSにかわって独占してるの気に食わん」と公言していたのですが。。。\nやはりUnixベースであり、Ctrl+aやCtrl+kが意識せずに利用できるということでコーディングなどを行う場合のストレスよりも保守的な思考を変える方が今後のためにも良さそうだということで、心機一転MBAを購入しました。\nということで、ついにApple教へ入信です。\nまだ、1時間も触ってないですが、すでに洗脳されつつあります。。。\n新しいものに触れるのって楽しいですよね。当分は何をインストールするかなど楽しい悩みでいっぱいになれそうです。(次回はちゃんとした技術的な記事書きたいと、書けるかな、書くぞ、たぶん。。。)\nとまぁ、いろいろと理由を書いてみましたが、要は(オシャレさに)憧れてて、あまのじゃくになって思ってもないこと言ってたんです!\n理由が欲しかったんです!!\nMacかっこえーわーw\nMac miniとかiMacとかもほしーわー\n","date":1312389240,"dir":"post/2011/","id":"7ed1d2efa3e0f0ed6b77eb4eff3d86b3","lang":"ja","lastmod":1312389240,"permalink":"https://blog.johtani.info/blog/2011/08/04/apple%E6%95%99%E3%81%AB%E5%85%A5%E4%BF%A1%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-08-04T01:34:00+09:00","summary":"個人用のPCを8年ぶりに新調しました。 前回購入した家のデスクトップPCがもう8年ものになりつつあるということで、 さすがに今年はPCを買おうと","tags":["備忘録"],"title":"Apple教に入信しました(Jugemより移植)"},{"contents":"かなり遅くなりましたが、第1回 データ構造と情報検索と言語処理勉強会 #DSIRNLPに参加しました。\n帰ってから2日半ほど寝込んでしまい、更新が遅れました。。。\n初の土曜日開催の勉強会でしたが、家族を説得してなんとか参加しました。\nおかげで色々と面白そうなキーワードが拾えてよかったです。(拾っただけで理解するのはかなり時間がかかりそうですが。。。)\nということで、前回同様、個人的にメモを取ったので。誤記などあるかもしれませんが、その時はコメントいただければと。\n0.DSIRNLPについて\n※ボランティアで受付してたので聞けず。\n1.TRIEにトライ!~今日からはじめるTRIE入門~\n@echizen_tm さん\n資料:http://www.scribd.com/doc/58688141/Try-for-Trie\n1.TRIEの説明\n実装についてはあとでスライドをみればいいか。(※ボランティアで受付してたので前半聞けず)\n・パトリシア木\n・Double Array\n・LOUDS\n・XBW\n2.作ってみた\nその1 ベーシック\nQ.ノードのラベルどーする?\n・固定長(ラベル=1文字)\n定数時間でアクセス可能\n・可変長(ラベル=任意文字列)\nPatricia木に拡張可能\nA.拡張性を考えて可変長に!\n3.LOUDSとは?\n概要\nJacobsonが提案 Level-Order Unary Degree Sequenceの略(いつからLOUDSになったのか不明)\n構築済みTRIEからLOUDSを構築\n作業領域がO(NlogN)からO(N)に\n・ノードに幅優先で順番(Level-Order)をつける\n・子ノードの数を付ける。Unary符号で実装\n作ってみた\n・UnaryよりVerticalCodeのほうがよさそう\nhttp://d.hatena.ne.jp/echizen_tm/20100531/1275323074\n・dag_vectorを使ってもいいかもよ?\n4.QA\nQ.可変長を配列にすればいいんじゃね?\nA.単純にやると効率悪そう?\n※LOUDSをlucene-gosenに適用するとなんか嬉しいことあるかな?\n現状はDouble-Arrayだけど。\n2. ランキング学習ことはじめ(Solr系に利用できそうな予感。。。ごごご。。。むずかしい。。。)\n@sleepy_yoshi さん NTTのSuharaさん「話がうまい」\n数原 良彦\n自己紹介\n情報検索、ランキング学習をやってる。\n三浦半島在住\nねらい\nランキング学習の認知度を高める、ざっくり伝える。 ごめんなさい 「実装」についてをわすれてた。\n・ランキング学習とは?\nLearning to rank\npreference learningとは違う\n教師あり機械学習で検索ランキングに適用\n・歴史\n従来は単一ランキング\nクエリ・文書関連度(TF-IDF、BM25)\n文書の重要度(PageRank、HITS、SALSAなど)\n近代的なランキングの実装方法\n上記データを利用して関数を適用する。\n・何を正解とするのか?\n適合性評価の作成方法\n評価点数を多段階で点数化\nランキング評価方法\nランキングを正解データと比較\nNDCG(Normalized Discounted Cumulative Gain) ※分類問題におけるモデルの生成\nTraining Data+学習アルゴリズム=>モデル\nランキング学習の訓練データ\n素性や評価はクエリごとに変わってくるTraining data(ここが違う)\nここまでのまとめ\n正解データは適合度至上主義!\nランキング学習手法\n3つのアプローチ\n教師あり機械学習(識別学習)≒\nどのような目的関数/損失関数を\nどのように最適化するのか\nアプローチ\n1.Pointwise手法\n単一のデータに対して損失関数を設定\n2.Pairwise手法\n同一クエリのペアに対して損失関数を設定\n3.Listwise手法\n同一クエリのリストに対して損失関数を設定\nPointwise:あまりつかえない。\n例:二値分類(適合+1不適合-1)で学習\n補足:Perceptron\n例:PRank\nしきい値と重み両方修正する。\nPairwise:Pointwiseよりいいらしい\n文書ペアで損失を設定\nMQ2007、MQ2008データセットの結果\nPairwise手法とListwise手法を比較しても\nそんなに悪くないらしい\nIR-SVMってので偏りなどを排除できて、精度向上になるよ\nNLP2011でPARankっての発表したよ(手前味噌)\nQA\nQ.じゃんけんみたいに循環しない?(nokuno)\nA.半順序のデータだと起きるが、検索の場合は全順序なので大丈夫だよ\nListwise:Pairwiseよりいいらしい\nListNetってのあり。\nAdaRank\n検索評価指標を直接最適化するブースティング手法\n性能はいまいち?実装は簡単\nその他の話題\nClick-through logs\nQuery-dependent ranking\nFeature selection\nTransfer learning/Domain adaptation\nDiversity/Novelty\n公開Dataset\nLETOR3.0/4.0 Dataset\nMSLR-WEB Datasetなど\n実装\nRankingSVM\nStoch\u0026hellip;.\nLearning to Rank教科書\n英語の資料が今年複数出たみたい\nまとめ\n近代的な検索エンジンは多数のランキング素性を利用\n評価データを用いてランキング素性の最適な重み付けを求める方法\n。。。\n機械学習手法は論文≒実装\nなので、ソースコード見るほうが重要(論文にないノウハウがあるよ)\n3.snappy調べてみた\n@machy 町永圭吾(赤いポータルサイト)\nTopCoderなどで活躍中?\n・snappyは圧縮/伸張ライブラリ\nzlibよりサイズが大きいけど一桁はやいですぞ。\n・インストールなど\ngoogle-gflagsってのがないと動作しないよ。\n・比較してみた(zlib)\n一桁は言い過ぎだけど、はやかった。\n・比較してみた(lzo)\nHadoopで利用されているlzo\nはやかった。\n・仕組みは?\nzlib 辞書式符号化+ハフマン符号化=出力\nsnappy 辞書式符号化+リテラル=出力\n・辞書式符号化は?\n前に出てきたデータで同じ文字列の部分について端折る\n・ハフマン符号化\nよく出てくる記号を短い符号で置き換えることで圧縮する。\n・snappyの符号化\n基本バイト単位での処理にすることで、高速化してるみたい。\n・snappyの辞書参照元の探し方\nハッシュテーブル利用してマッチする位置を検索\n4byte窓でハッシュ値を計算してハッシュテーブルを更新\n・圧縮しにくいデータ(同じ単語が出てこないパターン)について\n圧縮をあきらめ始める(32回同じのが見つからないと窓の移動幅が1つずつ大きくなる)\n16KB(フラグメント内)での比較回数が1008回に抑えられる。\n・特徴\nハッシュがしょうと移したらあるはずのマッチが見つからないこともある。\nメモリ消費量を抑えるためのハッシュのサイズ?\n最悪ケースのサイズを予め確保してから処理するため、メモリの再確保が起きないのではやいぞ。\n4.類似文字列検索してますか?\n@overlast さん Yな会社\n1.曖昧な情報を処理する能力\n曖昧な情報を解決しようとする能力が高い。\n例:お笑い芸人の芸がサンプルw\n画像検索は曖昧クエリに答える例。。。\nスターバックス、スタバ、SUTABA\nスータバでも画像が出てきた。-\u0026gt;女子高生とかが「スータバ」で画像をアップしてたりするから。\n文字列を使った検索は現代のインフラになってるよね。\n例:iタウンページ\nタイトルとかに「スターバックスコーヒー」って書いてないとだめ。?\n「スタバ」800件くらい -\u0026gt; 正規化で「ー」消してるんじゃないの?\n「スータバックスコーヒー」0件 ちがうな。シノニム辞書登録してるな。\n曖昧なクエリ(キーワード)から検索できないかなぁ?\n曖昧情報の処理は文字列処理にこそ必要\nなんでヒットしたかがわかるのが正解 なんでヒットしたかわからないけど、ちゃんと出てきたから正解!\n2.ゼロ件ヒット問題(ゼロマッチ)\nピクシブ百科事典\n「ピングドラム」だと17件\n「ピンクドラム」だと0件 しかも真っ白!!\n使いにくいよね。けど、一般的な検索システムの問題だよね。\nGoogleだと出てくる「ピンクドラム」の結果の最初にはピングドラムが出てくる。\n-\u0026gt;リンクがはられているから出てきた?みんなの間違いで助けられてる\n食べログ\n「俺のハンバーグ」\n「俺はハンバーグ」で検索したら。。。「俺はハンバーグで連れは。。。」がヒット-\u0026gt;しらねーよw\nまとめ\nゼロ件ヒットは機会損失!!\n3.曖昧な文字列で正しい文字列を探す方法\n正しい文字列って?\n1.表記誤りがない\n2.心の底で求めている\n※異表記同義、同表記異義、異言語表記(日本語の情報を英語で検索)などもある\n正しさはユーザによって変わる。\n正しい文字列をさがす手法\nクエリ表記の正誤という軸\n誤の場合表記をヒントに似た文字列を検索してみる。\n探したい対象が正確か曖昧か\n表記意外がヒントで同じ対象に到達できる?\nどんな情報を手がかりにする?\n編集距離(レーベンシュタイン)\n検索ログ\n4.Apporoの紹介\nチョコ?いや、ロケット?いや、Approximate \u0026hellip;\nhttp://code.google.com/p/apporo/\n中小規模だと使えそう\nSimString\n今後\nよみかな、ローマ字表記に基づく類似文字列検索+高速化の予定\n技術概要\nSuffix Array\nN-gram Searchベースの近似文字列照合\nBit Parallel Matchingによる編集距離計算\n5.検索と言語と文化(仮)\n@mizuno_takaaki さん\n放送禁止のためメモなし。\n7.自然言語処理におけるargmax操作\n@hitoshi_ni さん\n※順番変更\n・近似解法\nその1 全探索\nいや、無理でしょ、計算が。\nその2 貪欲法\n最適解が出るかは不明。\nその3 ビームサーチ\n上位kこの仮説を保持しながら幅優先探索\n・動的計画法\nすでに最大値がわかっていて、ゴールから眺めてみる。\n逆からたどるとルートがわかるんじゃないか。\nマルコフ性につけ込むことで、わかるんじゃないか。\n計算量:品詞数の2乗\n(品詞数の2乗)*形態素数\nDPの実装\nViterbiかなぁ?\n・整数計画法(線形-\u0026gt;整数)\n自然言語処理としては整数計画法でだいたいOK。\nアルゴリズム\n・手元の解空間中から許容解を得る\n・分枝してそこから最大値を求める\n最大値>許容解ならそちらを探索。\nプログラム実装する?\nすごく大変じゃないけど簡単でもないね。\n問題の弱点がわかってるなら実装してもいいよね。\n整数計画法の場合lp_solveなどのフリーのソフトで解くのがいいよ。エクセルでも解けるよ\nILP(整数計画法?)\n問題の切り分けに使える。\nまとめ\nILPで解けたら、いろいろ自分で考えると面白いよ。\nその他のバズワード\n参考資料\n組み合わせ最適化=1万円超\nアリ本\n6.ソーシャルグラフ分析(導入編)\n@kimuras さん mixiの木村さん\n・グラフ探索部分はまた今度。\n・テキストマイニングや検索エンジンまわりやってる。\n・ノードが数1千万、エッジが数億のオーダー\n・分散技術の発展によるアルゴリズムの多様化\nこれまで\nRDBからDumpしたデータをKVSに入れて頑張ってた。\nDump部分でデータ構造を毎回構築\n問題点\n変更による再実装、メンテナンスコスト、\nこれから\ngraphDBに取組中。マイニングに最適な感じ\ngraphDBの実装\nOrientDB、Neo4jとか\nNeo4jって\nACIDトランザクション可能\nEmbeddedGraphDatabaseだとAGPLv3だから気をつけてね。\nluceneで全文検索インデックスつくってるみたい。\nGremlinってのがquery言語を汎化してるらし。\nとあるSNSのデータを使ってみたよ。\nメモリ64G、CPUは1コアしか使えなかったよ。\nノード:15million、枝:600million\nまとめ\nということで、色々と面白い話が聞けました。特にTRIEの話はかなり興味を持ちました。\n検索周りで嫌というほど出てくるので。まだまだきちんと理解できてないので復習しないと。。。\nlucene-gosenにも関係あるので、しっかり資料をみて復習する予定です。\n基本的に検索系の話に関連があることが多くて面白く聞くことができました。\n「類似文字列検索してますか?」や「ランキング学習ことはじめ」などは身近な話(だけど、なかなかきちんと学習できてない話)でした。\nまた、「自然言語処理におけるargmax操作」では大学でやっていた線形計画法などのわかりやすい説明で10年経ってようやく理解ができた次第です。。。(もっとちゃんと勉強しとけば。。。)\n懇親会にも参加し、研究に近い分野の方が多い中でいろいろな話が聞けたのはよかったと思います。\n次回もいろいろなキーワードを拾いたいのでぜひ参加したいです。\n","date":1311737580,"dir":"post/2011/","id":"3811b40721f7ca651887aac4eb17f9f0","lang":"ja","lastmod":1311737580,"permalink":"https://blog.johtani.info/blog/2011/07/27/%E7%AC%AC1%E5%9B%9E-%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0%E3%81%A8%E6%83%85%E5%A0%B1%E6%A4%9C%E7%B4%A2%E3%81%A8%E8%A8%80%E8%AA%9E%E5%87%A6%E7%90%86%E5%8B%89%E5%BC%B7%E4%BC%9A%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-07-27T12:33:00+09:00","summary":"かなり遅くなりましたが、第1回 データ構造と情報検索と言語処理勉強会 #DSIRNLPに参加しました。 帰ってから2日半ほど寝込んでしまい、更新が","tags":["勉強会"],"title":"第1回 データ構造と情報検索と言語処理勉強会に参加しました。(Jugemより移植)"},{"contents":"以前から春山さんのブログ(リンク)や勉強会で耳にはしていたのですがソースは読んでいませんでした。 先日、Luceneにcontributeされた(リンク)ので軽くソースを読んでみました。\n公式サイトはこちら\nまずはMeCabのページにある比較表(リンク)を基準に特徴を調べてみました。せっかくなので、lucene-gosenも隣に。\n\u0026nbsp; Kuromoji lucene-gosen 解析モデル なし(学習機能なし) なし(学習機能なし) コスト推定 なし(学習機能なし) なし(学習機能なし) 学習モデル なし(学習機能なし) なし(学習機能なし) 辞書引きアルゴリズム Double Array Trie Double Array Trie 解探索アルゴリズム Viterbi Viterbi 連接表の実装 2次元 Table 3次元 Table 品詞の階層 無制限多階層品詞?ipadic、unidic形式に対応 無制限多階層品詞 未知語処理 字種 (動作定義を変更可能)(おそらく。) 字種(変更不可能) 制約つき解析 たぶん、不可? たぶん、不可? N-best解 不可能 不可能 こうやって比較してみるとlucene-gosen(Sen)とあまりかわりはありませんが、lucene-gosenが少し古いのがわかりますね。。。\nKuromojiで利用出来る辞書は現時点ではMeCab IPADIC、UNIDICの2種類のようです。\nソースを読んでの感想ですが、やはりMeCabが偉大だということがよくわかりました。 Senよりも新しいMeCabの処理に似ている点が多いです。解探索アルゴリズムや連接コスト表が特に。 MeCab向けの辞書を利用しているためというのもあるかと思います。\nKuromojiが特徴的なのは「searchモード」と呼ばれるモードが用意されていることです。 公式サイトにある例ですと、「関西国際空港」が「関西」「国際」「空港」というTokenで出力されます。 ソースを見たところViterbiアルゴリズムで辞書を探索しているときに特定の条件でコストをカサ増しすることで、結果を変えるという処理を行っているようです。\n全て漢字の単語:3文字以上の場合に「(単語の長さ-3)*10000」をコストに加算 その他の単語:7文字以上の場合に「(単語の長さ-7)*10000」をコストに加算 このようにコストを変化させることで「空港」でも「関西国際空港」という文字を含む文章が検索できる仕組みになっています。 また、「拡張searchモード」と呼ばれるモードも存在し、こちらは、未知語をuni-gramで区切って出力を行うようです。\nソース上で確認しただけで、未確認ですが、GraphvizFormatterというクラスがあるので、Graphvizで読み込める形式で形態素解析の結果が出力されるかもしれません。(すみません、確認してなくて。)\n未知語の処理やsearchモードなど面白い機能があるので、試してみるのもいいかもしれません。lucene-gosenを考えていく上でも参考になりそうです。\n最後に余談ですが、FAQのページ(リンク)が面白いです。。。\n","date":1311132540,"dir":"post/2011/","id":"5a765f9668608a39333fa90cf462657e","lang":"ja","lastmod":1311132540,"permalink":"https://blog.johtani.info/blog/2011/07/20/kuromoji%E3%82%92%E8%AA%BF%E3%81%B9%E3%81%A6%E3%81%BF%E3%81%9F/","publishdate":"2011-07-20T12:29:00+09:00","summary":"以前から春山さんのブログ(リンク)や勉強会で耳にはしていたのですがソースは読んでいませんでした。 先日、Luceneにcontributeされ","tags":["形態素解析"],"title":"Kuromojiを調べてみた(Jugemより移植)"},{"contents":"忘れてしまうので、備忘録を残しておきます。 一応、ソースには少しずつコメントをいれてはいるのですが。 私は残念ながら、自然言語処理は初心者に毛が生えた程度(現在、鋭意勉強中)で、対応方法に問題があるかもしれません。気づいた方はコメントをいただけると助かります。\n辞書ファイルについて NAIST-JDic for MeCabの辞書ファイルは以下の構成になっています。\nファイル名 メモ char.def 文字種の設定 feature.def 辞書学習用の設定? left-id.def左文脈IDのマスタ(左文脈ID、品詞情報) matrix.def 連接コスト表(前件文脈ID,後件文脈ID,連接コスト) pos-id.def 品詞IDのマスタ(品詞情報、ID) rewrite.def rewrite情報(左右文脈に出現した場合のそれぞれの品詞情報のrewriteルール。辞書学習で主に利用) right-id.def 右文脈IDのマスタ(右文脈ID、品詞情報) unk.def 未知語の品詞情報(文字種ごとに未知語のコスト、左右文脈ID、品詞情報が記載されている) naist-jdic.csv 単語辞書(単語、左右文脈ID、単語コスト、品詞情報、読みなど記載) 現時点では、MeCabDicPreprocessorでは以下のファイルを利用しています。\nleft-id.def matrix.def right-id.def naist-jdic.csv 上記以外のファイルは現時点では利用しない実装になっています。 ただし、rewrite.def、unk.def、char.defについては利用したほうがよりMeCabに近い結果が得られるような気がしています。(特に文字種ごとのコストを利用することは有効と思われます。)\nPreprocessorでの処理について lucene-gosenはSenの後継であり、MeCabの昔のバージョンを移植したものがベースとなっています。 lucene-gosenとMeCabの現時点での実装の大きな違いとして、連接コスト表の違いがあります。 ここからは憶測になってしまいますので、注意してください。(論文を探せばどこかにこの実装の変化の過程が記載してあるかもしれないですが、まだ探していません、すみません。) 過去のMeCabではChaSen向けの辞書を利用していました。 ChaSenでは連接コスト表が3つの項(前の前、前、後)から構成されていました。(n項まで定義可能らしい) ですので、lucene-gosenのViterbiアルゴリズムの引数も3つのノードが引数となっています。 lucene-gosen向けの連接コスト辞書も同様の作りになっています。 一方、現在のMeCabは先ほど書いたとおり、matrix.defでは2項の連接コスト表(前、後)となっています。この違いを保管するために、Preprocessorでは、matrix.defを3項にするために一番左(前の前)については任意の品詞を採用できるように「,,,,,,*」のみを設定しています。\n現時点では、Preprocessorの出力である中間ファイルを共通の形式に出力することで、DictinaryBuilder以降の処理に変更を加えることなくNAIST-JDic for MeCabへの対応を行う形を取りました。まずは使えるようにするのが先かと思いまして。 ただ、MeCabの辞書の構成から考えると中間ファイルに落とし込む処理に無駄があると感じています。 matrix.defでせっかく、IDによる連接コスト表を構成しているのに、IDを品詞情報の文字列に戻したconnection.csvを生成していますので。\nということで、備忘録でした。 あとは、テストをどうするか(正解をどう考えるか)なども考える必要があります。現時点での悩みの種です。。。アイデア募集中です。\n","date":1310432760,"dir":"post/2011/","id":"c70b78fd0b5dffcd38322355e9c2471e","lang":"ja","lastmod":1310432760,"permalink":"https://blog.johtani.info/blog/2011/07/12/naist-jdic-for-mecab%E3%81%AEpreprocessor%E3%81%AE%E5%AE%9F%E8%A3%85%E3%81%AB%E9%96%A2%E3%81%99%E3%82%8B%E5%82%99%E5%BF%98%E9%8C%B2/","publishdate":"2011-07-12T10:06:00+09:00","summary":"忘れてしまうので、備忘録を残しておきます。 一応、ソースには少しずつコメントをいれてはいるのですが。 私は残念ながら、自然言語処理は初心者に毛が","tags":["lucene-gosen"],"title":"NAIST-JDic for MeCabのPreprocessorの実装に関する備忘録(Jugemより移植)"},{"contents":"lucene-gosen 1.1.1をリリースしました。\n先日お知らせしたバグ修正を取り込んだjarを用意いしました。\nダウンロードはこちらから\n","date":1309777240,"dir":"post/2011/","id":"229975f1e84b5088e819cd5f2dc43080","lang":"ja","lastmod":1309777240,"permalink":"https://blog.johtani.info/blog/2011/07/04/lucene-gosen-1-1-1%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9/","publishdate":"2011-07-04T20:00:40+09:00","summary":"lucene-gosen 1.1.1をリリースしました。 先日お知らせしたバグ修正を取り込んだjarを用意いしました。 ダウンロードはこちらから","tags":["lucene-gosen"],"title":"lucene-gosen 1.1.1リリース(Jugemより移植)"},{"contents":"Solr/Lucene 3.3がリリースされました。(速報)\n以下、各サイトへのリンクです。\nSolrリリースのお知らせ\nLuceneリリースのお知らせ\nリリースのタイミングがどんどん早くなってる。。。\n","date":1309501779,"dir":"post/2011/","id":"10eb1e7dc64d8ca3dad92641dadb5de7","lang":"ja","lastmod":1309501779,"permalink":"https://blog.johtani.info/blog/2011/07/01/lucene-solr-3-3%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E9%80%9F%E5%A0%B1/","publishdate":"2011-07-01T15:29:39+09:00","summary":"Solr/Lucene 3.3がリリースされました。(速報) 以下、各サイトへのリンクです。 Solrリリースのお知らせ Luceneリリースのお知らせ リリースのタイミ","tags":["solr"],"title":"Lucene/Solr 3.3リリース(速報)(Jugemより移植)"},{"contents":"「Hadoopを中心とした分散環境での開発方法論・モデリング・設計手法等についての座談会(第5回)」に参加しました。300名入るイベントルームでしたが、後ろの方まで人が埋まっていました。\nということで、主に自分用ですが、メモを取ったので。\n※二次会行きたかった。。。\n1.「鉄道システムへの誘い」\n@ayasehiro(本名無理w)\nHadoopの話はありません。\n○鉄道系基幹システムの開発\n実態:\n耐用年数:10年以上\n開発期間:数年~5年程度\n開発規模:~10Mステップ、10k人月~\nほとんどテスト、しかも異常系が主体。\n夜間に実際に鉄道を走らせて試験したり。\n開発サイクルが長い\n人材育成が難しい、ノウハウがたまらない。\n開発自体はほとんど時間がなく、設計・製造・試験など新規技術の採用が難しい。\n開発4年前の調査・検証自体が2年程度。\nHadoopも調査中。\n○鉄道システム3大システム\nマルス(予約オンラインシステム)(1960~)\nコムトラック(運行管理システム)(1972~)\nヤックス(ヤード自動化システム)(1968~1984)\n○鉄道輸送システムとは\n用語:\n運行を計画する=\u0026gt;輸送計画\n列車を運行する=\u0026gt;運行管理\n需要想定+営業施策+その他(お召し列車など)=列車ダイヤ作成\n基本計画(長期)+短期計画(数日~四半期程度)=列車ダイヤ(重ねあわせてできあがり)\nダイヤの計画(発車時刻など)と車両運用(車両自体の走る組み合わせ(仮の車両))の作成\n+乗務員運用(乗務員の運用計画)\n運行管理:\nなにも起きなければすることなし。(車両故障、天候、人身事故などによる整合性を取る作業)\n=事前に計画した輸送計画をすべて見直し\n遅延の検知は?\n昔:人による伝令\n今:システムによる検知(レールに電流流して検知)\n運転整理(実際に遅れた):\n部分運休、折り返し駅の変更などにより対応\n元の計画になるべく近づく形で修正していく。\n新幹線、山手線、京浜東北線などは速度信号という信号が表示される。\n線路上に信号はないらしい。\n○鉄道システムを取り巻く情勢\n少子高齢化・人口減少のため凋落産業となっている。\n社会インフラの責務=動くのが当たり前\n2007年問題(ベテランの引退)=スジ屋さんは最近いないらしい。\n高度な判断支援をするシステムが必要\n連続稼動=分散技術を適用できない?\n関係各所との情報共有\n計画立案のための情報支援=最適化技術を適用できない?\n○分散処理技術の適用\n個人的な感想\n可用性(連続稼動)のための仕組み\nバッチ処理\n○分散技術の適用\n・連続稼動\nactive-active構成がメイン\n主系の出力だけを行う。問題が出れば副系の出力。\n3系統の出力を比較器にて出力もある\nmagiシステム\n問題点:\nハードが高い(H社)\nソフトウェアの作り込みが複雑=テストが前パターンできない\n解決案:\n汎用的なハードが使いたい。\n作り込みも減らしたい\n・バッチ処理:\nAsakusa使えないかなーw\n○最適化技術の採用\nコンピュータ技術の発展\n2007年問題\n職人に言わせれば最適化はいらない、俺の言うことを聞けw\n・車両運用のモデリング\n車両数大=\u0026gt;組み合わせ大\n制約条件が多い\n車両運用の場合、走行累積キロの条件もある\n-\u0026gt;有向グラフにモデル化される。(ただし、グラフ化するまでが大変)\n・乗務員運用のモデリング\n車両と違い、乗務員は1回で2人とか運べる(運転士+移動する人とか)\n・車両割当のモデリング\nやはり、グラフ化が可能\n・乗務員交番のモデリング。。。など\n結構一般的なモデルに落とし込める。ただし、落し込みが大変。\n机上研究だったものが、コンピュータの発展により実証研究になりつつある。\n○まとめ\n鉄道システムはまだまだ未到の領域が残っている。\n開発サイクルが長いため、保守的な開発になる(35年前の設計思想からあまり変わってなかったりする)\nしかし業務要件やシステム利用者の意識は変化している\n興味を持たれた方は、ぜひ、我社に!(社名は2次会でw)\n○Q\u0026amp;A\nQ:鉄道システムのカルチャーってイケイケ?保守的?(@okachimachiorgさん)\nA:最新技術も知らないとだめじゃないかという人が出てきている。\nコア部分(安全第一なところ)+周辺領域(ある程度融通が効きそうな部分)と考えることができるんじゃないかって人も出てきている。\nJR九○=先進的\nJR四○、北○道=お金ない\nJR○海=超保守(企業的に超保守)\nJR東、西=うーむ?\n東京メト○(運行計画)、阪○=先進的\n京○急行=基本人間で進路制御w\n基本的には新しいものには興味をもつ人たちでは。\nQ:Su○caとかで分散処理は利用出来るんでは?\nA:匿名なので外側から見ていると分散処理はいろいろ使えるんでは?\nログデータからいろいろできるんじゃないの?活かすべきでないの?\n使いどころはいっぱいある。\nQ:鉄道システムでどうしようもなくなったことはあるか?\nA:保守体制が一番気になる。\nOSSとかならまだ調べられる。ミドルウェアなどの保守契約が必要。\n保守体制が確立されてればある程度の保守費用は飲み込む。\nどうしようもないことはないが、今すごく困ってることは\nExcelで帳票を出したいとかいわれること。(ちょっと前に作ったシステムでExcel2003。バージョンあげると速度が遅くなったりするw)\nilog社のものを使ってたが、IBMに買収されて保守費用があがってこまってるw\n保守が10年と長いため、サポートなどの折衝が必要。\nQ:最適化の適用範囲は?\nA:走行順序(どこで追い抜くか)の算出に活用。ほぼ完成でユーザ教育中。\n1列車の波及がかなり影響が出る。ダイヤだけ見ると列車だけだが、乗務員も関係しており、大変。\nある時点から終電までを最適化の対象としたりして割り切っている。\nまた、不足分について算出が出来れば、そこで打ち切ったりもする。\n2.「九州電力におけるHadoopの取り組みについて」\n株式会社キューデンインフォコム e-ビジネス部 @hisashi_yano\n概要:2年間関係したOSSをメインにしたシステムの話。\n○九州電力の概要\n現在風当たりが強い業界。\n東電の1/10くらい\n部門ごとに大手ベンダーが関わってる。\n○Hadoop採用の経緯\n部門ごとに個別最適なシステムを導入していてベンダーロックインされてる。\n・ホストのリプレース\n・両現用センター構成への対応\n・スマートグリッドへの対応\n問題点\n・コスト削減\n・技術革新への中の人の対応(内部でも問題を理解できるように)\n・商用パッケージのカスタマイズの限界\n・脱ベンダーロックイン(実は楽なんだけど。。。)\n○過去2年間の研究内容\n・H21年度の結果\nテーマ:クラウドの要素技術の研究\nKVM、Eucalyptus、wakame、hadoop 性能比較:VMWareとKVM-\u0026gt;ベンチマーク比較\n結論:性能的にあまり問題なし。\nMapReduceの耐障害性など\nダミーデータにより台数増加による影響を検証\n結論:台数大-\u0026gt;性能向上\nストリーミングは性能劣化する\nスループットはリニアに向上\n信頼性は?\n実行中にノードを抜いたりして検証。\n結論:問題なし。\nクラウド環境におけるシステム管理手法\n複数ハードで1アプリという構成になる。\n監視対象が膨大になる。\n障害発生時の切り離しや監視対象も膨大。\nデータセンター自体を監視する仕組みが必要では?というところで終了。\n・H22年度の結果\n分散に特化した研究\n前年度の課題\nサーバの仮想化・管理に関する課題\n分散処理に関する課題\n分散処理環境の運用監視に関する課題\n目的:\nHadoopを本番への適用(実際にはダミーデータ+本番の仕組み)\n柔軟なサーバ統合基盤(サーバを起動-\u0026gt;バッチを起動-\u0026gt;回す仕組み)=MonkeyMagic\nlibvirtを使ってる\n50台の仮想サーバの起動が10数分で完了。\n運用監視基盤(monkey magic)\n仮想、実サーバ混在の監視\n監視状況(サーバの状況)から判断して制御する仕組みを構築\nDSLにてルール(判断+制御)を指定\n・ジョブの監視\n・ジョブの実行管理\n・構成管理の省力化\nvolanteと連携が可能=AmazonWebServiceとも連携可能\n・サーバリソース+アプリケーションの一括監視が可能\n分散バッチ処理の概要\nRDBからKV形式にして抽出し、MRで回してRDBに戻すという研究\n対象:\n配電部門(電柱の設備情報の目視検査)のデータの月間バッチ処理\n現状:\n19時間程度かかってる。\nテスト環境:\n実サーバ2台(仮想10台)\nMySQL、Javaで実装\n処理内容\n電柱104万本\n巨大バッチを分割して実装\n結果\nMySQL1台では15日以上かかる処理(現行システムで19時間)\n処理が32分で終了!他でも効果でるよね。\nバッチ短縮の理由は?\n1.データアクセスが分散された\n2.処理の並列化(多重化出来る部分がうまくできた)\n分散処理を書くのに2名死亡。。。\n適用基準の策定、開発ガイドライン、フレームワーク整備などが必要。\n・H23年度は?\nAsakusaの適用など。\n・さらに今後は?\nスマートグリッドへの適用\n-\u0026gt;メーターの交換が必要だが、10年くらいかかる\n-\u0026gt;スパンが長い(10年)ので商用製品だときつい?\nデータ量も半端ない。\nテネシー州とClouderaでOpenPDCってのやってるらしい。\n電力と気温の関係は密接な関係あり。\nエアコンが割合を占めてるから。\n過去実績と予想気温データから分析するのにHadoop使える!\n・2年間やってきて思うこと\n将来目指すべき理想像を掲げるのが重要\n新技術導入は段階を踏むことが必要\nコミュニケーション大切!\n○Q\u0026amp;A\nQ:仮想化環境のオーバヘッドは?(I/O)\nA:台数を増やしたときにどうなるか?というのを検証したかった。\nアプリ配布も考えていたので、物理サーバに縛られたくなかった。\nQ:仮想化に関して気をつけたM/RのPGで気をつけたことありますか?\nA:まったくないです。\nQ:日本でスマートグリッドははやるの?\nA:電力会社的にはやりたくない。費用対効果があまりない。\nQ:今後のスケジュールは?\nA:文書管理システムの組織名変更などの処理時間が540時間とかでてくるらしい。\nこれをHadoopで対応してみようかと思ってる。\nQ:Asakusaをどう評価していくのか?\nA:開発効率性があがるか?は検証する予定。1/3くらい楽になるんじゃないかなぁ?byのぐちさん\nバッチの種類などにもよると思うが、標準化も指標にする予定。\n結果はまたこの場で報告する予定。\nQ:Asakusa+MonkeyMagicの連携はどんなこと考えてる?\nA:MonkeyMagicを運用基盤として行く予定。合意が取れればだけど。\n※MonkeyMagicもOSSにするよー\nまとめ\nHadoopから少しずつ離れつつありますが、やはり興味があるので、非常に楽しく話を聞けました。\nまた、今回はインフラ分野のシステムということで、システムに要求されるレベルや\n運用周りにも気を配っている話が聞けたのが収穫でした。保守期間が長いため、テストが長い=\n運用もしっかりと考慮を入れた設計、実装が必要になるというのは最もだと思います。\nただ、少しずつ修正が入るアジャイルなども同様かと。\nMonkeyMagicが出来上がってきた背景の話を聞いて、さらに興味が湧いてきたところです。\n今後もかかわりが少ないかもしれないですが、ウォッチしていきたいと思いました。\nただ、興味あるモノが多すぎるので、優先度をつけつつこなして行かないと。。。\n少しずつでも身につけていきたいと思う今日このごろです。\n※追記:Twitterでコメントを頂いたので、忘れないように追記。\nコメントを貰えるだけでもうれしい。やはり、アウトプットしたらフィードバック貰いたいし。\nありがとうございます!\nTwitter / @cocoatomo: あの質問をまとめるとこうなるのかぁ…… 最適化そのも \u0026hellip;\nTwitter / @cocoatomo: @johtani すみません, コメントはコメント欄 \u0026hellip;\nTwitter / @cocoatomo: @johtani そこらへんの理論って最後には計算量 \u0026hellip;\nTwitter / @cocoatomo: @johtani あの話し振りだとどうもまだ本格的に \u0026hellip;\nあと、まとめも出来ていたので、ついでに。\nTogetter - 「2011/06/29_Hadoopを中心とした分散環境での開発方法論・モデリング・設計手法等についての座談会(第5回) #hadoopmodeling」\n関連するブログも見つけたので。\n第5回Hadoop座談会の感想 - ひしだまの変更履歴\nHadoopモデリング座談会(第5回)へ行ってきました - 虎塚\n","date":1309356600,"dir":"post/2011/","id":"49ba23148db9effdc3979aa0fe5876ea","lang":"ja","lastmod":1309356600,"permalink":"https://blog.johtani.info/blog/2011/06/29/hadoop%E3%82%92%E4%B8%AD%E5%BF%83%E3%81%A8%E3%81%97%E3%81%9F%E5%88%86%E6%95%A3%E7%92%B0%E5%A2%83%E3%81%A7%E3%81%AE%E9%96%8B%E7%99%BA%E6%96%B9%E6%B3%95%E8%AB%96%E3%83%A2%E3%83%87%E3%83%AA%E3%83%B3%E3%82%B0%E8%A8%AD%E8%A8%88%E6%89%8B%E6%B3%95%E7%AD%89%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E3%81%AE%E5%BA%A7%E8%AB%87%E4%BC%9A-%E7%AC%AC5%E5%9B%9E%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-06-29T23:10:00+09:00","summary":"「Hadoopを中心とした分散環境での開発方法論・モデリング・設計手法等についての座談会(第5回)」に参加しました。300名入るイベントルー","tags":["hadoop"],"title":"Hadoopを中心とした分散環境での開発方法論・モデリング・設計手法等についての座談会(第5回)に参加しました。(Jugemより移植)"},{"contents":"以前、こちらで話題に上がっていた「未知語」に関するcompositePOSのエラーの件を調査しました。(Twitterでも流れてました。) 次のような条件の場合にエラーが発生するようです。\ncompositePOSの設定に構成品詞として「未知語」が指定されたエントリが存在する。 未知語が連続して出現する文字列をanalyzeする。(例:ニンテンドーDSi) ということで、trunkに修正版をコミットしました。 Issueはこちら。\n※お茶をにごす感じの日記になってしまいました。次回はマシな記事を書く予定です。。。\n6/29追記:恥ずかしいバグをいれこんでしましました。。。 ということで、trunkに再度修正版をコミットしました。\n","date":1309232160,"dir":"post/2011/","id":"f6dff70097776e24c2a7c9c0f2514f79","lang":"ja","lastmod":1309232160,"permalink":"https://blog.johtani.info/blog/2011/06/28/compositeposcompositetokenfilter%E3%81%AE%E3%83%90%E3%82%B0%E4%BF%AE%E6%AD%A3/","publishdate":"2011-06-28T12:36:00+09:00","summary":"以前、こちらで話題に上がっていた「未知語」に関するcompositePOSのエラーの件を調査しました。(Twitterでも流れてました。) 次","tags":["lucene-gosen"],"title":"compositePOS(CompositeTokenFilter)のバグ修正(Jugemより移植)"},{"contents":"lucene-gosenのtrunkbranches/impl-mecab-dicにNAIST-JDic for MeCabの辞書を利用出来るPreprocessorをコミットしました。\nビルド方法は次のとおりです。\n$ cd lucene-gosen-trunk $ ant -Ddictype=naist-mecab 現在のstable版で利用できる辞書は「ipadic」「naist-chasen」の2種類でした。\n[以前の記事](http://johtani.jugem.jp/?eid=4)に書きましたが、naist-chasenの辞書でも2008年の更新となっています。\n今回コミットしたPreprocessorでは[NAIST-JDicのサイト](http://sourceforge.jp/projects/naist-jdic/)で公開されているMeCab向けの辞書である「mecab-naist-jdic-0.6.3-20100801」を利用出来るようになります。\nただし、lucene-gosenは昔のMeCabから派生したSenをもとにしていますので、最新のMeCabが持っている機能は\n利用できません。\nMeCab向けの辞書のうち一部のもの(matrix.def、naist-jdic.csvなど)を利用してlucene-gosen向けの辞書の中間ファイルを生成する仕組みになっています。\nまだ、仮実装版ということで、とりあえず動作するバージョンとなっています。\nまだテストが不十分ですが。。。\n利用してみて問題などあれば、lucene-gosenの[issue](http://code.google.com/p/lucene-gosen/issues/list)に登録していただくか、コメントを頂ければと思います。\n※更新が週1回に落ちてきてるので、もう少し頑張らねば。\n※2011/07/04追記 trunkにコミットしていましたが、branchに一旦移動しました。 仮実装として一旦コミットしたので、trunkとは別でテストする必要があるかと思った次第です。 ということで、試してみたい方は、[branches/impl-mecab-dic](http://code.google.com/p/lucene-gosen/source/browse/#svn%2Fbranches%2Fimpl-mecab-dic)にありますので、触ってみてください。 ","date":1308609480,"dir":"post/2011/","id":"991285e3967c3295b4ff2dcd835f7c61","lang":"ja","lastmod":1308609480,"permalink":"https://blog.johtani.info/blog/2011/06/21/naist-jdic-for-mecab%E5%AF%BE%E5%BF%9C%E7%89%88%E4%BB%AE%E5%AE%9F%E8%A3%85/","publishdate":"2011-06-21T07:38:00+09:00","summary":"lucene-gosenのtrunkbranches/impl-mecab-dicにNAIST-JDic for MeCabの辞書を利用出来るPre","tags":["lucene-gosen"],"title":"NAIST-JDic for MeCab対応版(仮実装)(Jugemより移植)"},{"contents":"前回、naist-chasenではアルファベットが別々の単語としてanalyzeされてしまうという話をしました。\nただ、これだと、英単語が含まれた文章を形態素解析すると、英単語がアルファベット単位に区切られてしまい、 単語の意味をなさなくなってしまいます。\nlucene-gosenでは、この問題に対応するための方法が提供されています。 CompositeTokenFilter(compositePOS)という機能です。\n文字通り「トークン」を「合成」するための機能になります。\n利用するためには以下の作業が必要です。(※Solrでのの利用方法を説明します。)\ncompositePOS設定ファイル(composite_pos_ja_naist-chasen.txt)の用意 schema.xmlのtokenizerにcompositePOS設定を追加 まずは、compositePOS設定ファイルの記述方法について説明します。 compositePOS設定ファイルには1行につき1つのcompositeの設定を記述していきます。 記述方法は次のようになります。品詞名を半角スペース区切りで記述します。\n連結品詞名 構成品詞名1 構成品詞名2 ... 構成品詞名n それぞれは次のような意味を持ちます。\n連結品詞名:合成したあとのトークンの品詞として出力する品詞名 構成品詞名:合成したい品詞名(スペース区切りで複数指定可能) TokenizerのcompositePOS機能は、構成品詞に定義されたトークンが連続して出力された場合に、 結合(合成)して1つのトークン(連結品詞名)として出力します。 また、以下のように構成品詞名が1種類で連続品詞名としても利用する場合は次のように省略した記述も可能です。\n以下にcompositePOSファイルの設定例を上げます。 ※なお、現時点では#によるコメント機能はありません。ので、記述した内容がそのまま利用されます。\n名詞-数 未知語 記号-アルファベット 1行目は連続した数字を1つのトークン(名詞-数)として出力する設定です。(連続品詞名=構成品詞名として省略して記述した例になります。) 2行目は連続したアルファベットを1つのトークン(未知語)として出力する設定です。\n次にSolrのschema.xmlにlucene-gosenのtokenizerを利用するフィールドタイプの設定を記述します。 $SOLR_HOME/conf/schema.xmlに以下を追加します。\u0026lt;types\u0026gt;~\u0026lt;/types\u0026gt;タグの間に記載します。\n... \u0026lt;types\u0026amp;gt; ... \u0026lt;fieldType name=\u0026amp;quot;text_ja\u0026amp;quot; class=\u0026amp;quot;solr.TextField\u0026amp;quot; positionIncrementGap=\u0026amp;quot;100\u0026amp;quot;\u0026amp;gt; \u0026lt;analyzer\u0026amp;gt; \u0026lt;tokenizer class=\u0026amp;quot;solr.JapaneseTokenizerFactory\u0026amp;quot; compositePOS=\u0026amp;quot;composite_pos_ja_naist-chasen.txt\u0026amp;quot;/\u0026amp;gt; \u0026lt;/analyzer\u0026amp;gt; \u0026lt;/fieldType\u0026amp;gt; \u0026lt;/types\u0026amp;gt; ... 重要なのはtokenizerタグのcompositePOS属性になります。ここに1.で記載したファイルを指定します。指定したファイルはschema.xmlと同じディレクトリに配置します。 以上が利用するための設定です。\n前回同様、「このComputerは、10回に1回の割合で起動中に青い画面が表示されます。」という文章をanalyze画面で解析した結果を示します。\nとまぁ、記事を書きましたが、すでにこちらで出ている話ですね。。。\nみなさん手が早くて困ってますw\nちなみに、上記の設定の場合、「100,000」や「3.14」といった文字列は「100」「,」「000」という形で出力されてしまいます。これらも数字とみなしたい場合は「名詞-数 名詞-数 記号-句点 記号-読点」という設定で1つのトークンとして出力されます。ただし、「。」も「記号-句点」なので注意が必要です。\n※なお、今回はlucene-gosen-1.1.0、Solr3.2を利用した例になっています。 ","date":1307977200,"dir":"post/2011/","id":"50f43b1726cf61066ef8656477b226be","lang":"ja","lastmod":1307977200,"permalink":"https://blog.johtani.info/blog/2011/06/14/compositepos%E3%81%AE%E5%88%A9%E7%94%A8%E4%BE%8Bnaist-chasen%E3%81%A7%E3%81%AE%E8%8B%B1%E5%8D%98%E8%AA%9E%E3%81%AE%E5%87%BA%E5%8A%9B%E6%96%B9%E6%B3%95%E4%BE%8B/","publishdate":"2011-06-14T00:00:00+09:00","summary":"前回、naist-chasenではアルファベットが別々の単語としてanalyzeされてしまうという話をしました。 ただ、これだと、英単語が含ま","tags":["lucene-gosen"],"title":"compositePOSの利用例(naist-chasenでの英単語の出力方法例)(Jugemより移植)"},{"contents":"lucene-gosenの1.1.0がリリースされました。\n大きな目玉はJapaneseTokenizerが出力する形態素に関するデータを遅延ロードすることで、パフォーマンスの改善を行ったことです。\n詳しくは関口さんのブログで実測されてます。さすが、早い。。。 あと、先日リリースされたLucene/Solr 3.2への対応も行われています。\nlucene-gosen-1.1.0のダウンロードはこちらから。\nうーん、中身がない記事だ。。。\n","date":1307934480,"dir":"post/2011/","id":"eeef60efe889349870426d10edc694be","lang":"ja","lastmod":1307934480,"permalink":"https://blog.johtani.info/blog/2011/06/13/lucene-gosen-1-1-0-%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9/","publishdate":"2011-06-13T12:08:00+09:00","summary":"lucene-gosenの1.1.0がリリースされました。 大きな目玉はJapaneseTokenizerが出力する形態素に関するデータを遅延","tags":["lucene-gosen"],"title":"lucene-gosen 1.1.0 リリース(Jugemより移植)"},{"contents":"lucene-gosenをSolr/Luceneで利用する場合、TokenFilterを利用してTokenizerが出力したToken対してさまざまな処理(Tokenに対する正規化や展開など)を追加することが可能です。\n今回は現在(ver. 1.0.1)用意されているTokenFilterについて説明します。 以下はTokenFilterの一覧です。 「フィルタ名」にはSolrのschema.xmlで記述するクラス名を書いてあります。\nフィルタ名(Factory名) 概要 solr.JapaneseWidthFilterFactory 全角のASCII文字を半角に、半角カタカナを全角にするフィルタ。例:「Computer」-\u0026gt;「Computer」 solr.JapanesePunctuationFilterFactory 区切り文字、記号などを除外するフィルタ。[※1](#token_filter_kome_1) solr.JapanesePartOfSpeechStopFilterFactory 設定ファイルに記載した品詞に該当するTokenを除外するフィルタ。ファイルは「tags=\"ファイル名\"」とfilterに記載。なお、ここで記述する品詞とはanalysis画面に表示される「partOfSpeech」の完全一致となります。 solr.JapanesePartOfSpeechKeepFilterFactory 設定ファイルに記載した品詞に該当するToken\"以外\"を除去フィルタ。ファイルは「tags=\"ファイル名\"」とfilterに記載。なお、ここで記述する品詞とはanalysis画面に表示される「partOfSpeech」の完全一致となります。 solr.JapaneseBasicFormFilterFactory Tokenを基本形に変換するフィルタ。例:「悲しき」-\u0026gt;「悲しい」 solr.JapaneseKatakanaStemFilterFactory カタカナの長音(ー)の正規化フィルタ。4文字以上のカタカナのみの文字列の最後の長音(ー)を除去した文字列に変換します。例:「コンピューター」-\u0026gt;「コンピュータ」、「コピー」-\u0026gt;「コピー」 上記のTokenFilterをJapanizeTokenizerを利用するフィールドタイプに設定することで 各フィルタによる機能が有効になります。 schema.xmlの記載に関する詳細についてはこちらを参考にしてください。\n※1 Characterクラスの以下の定数に相当する文字が。SPACE_SEPARATOR、LINE_SEPARATOR、PARAGRAPH_SEPARATOR、CONTROL、FORMAT、DASH_PUNCTUATION、START_PUNCTUATION、END_PUNCTUATION、CONNECTOR_PUNCTUATION、OTHER_PUNCTUATION、MATH_SYMBOL、CURRENCY_SYMBOL、MODIFIER_SYMBOL、OTHER_SYMBOL、INITIAL_QUOTE_PUNCTUATION、FINAL_QUOTE_PUNCTUATION\n","date":1307344980,"dir":"post/2011/","id":"4b046ac6a4796fb1338f0481dbd4003d","lang":"ja","lastmod":1307344980,"permalink":"https://blog.johtani.info/blog/2011/06/06/lucene-gosen%E3%81%AEtokenfilter%E3%81%9F%E3%81%A1/","publishdate":"2011-06-06T16:23:00+09:00","summary":"lucene-gosenをSolr/Luceneで利用する場合、TokenFilterを利用してTokenizerが出力したToken対して","tags":["lucene-gosen"],"title":"lucene-gosenのTokenFilterたち(Jugemより移植)"},{"contents":"辞書の特性について 現在lucene-gosenでは以下の2つの辞書が利用可能です。 簡単に違いについて説明します。\nIPAdicの辞書について\nバージョン:2.6.0(※IPAdicとして公開されている最新は2.7.0) 最終更新日:2003/06/19 登録単語数:約24万語 NAIST-Jdicができたためか、更新されていない NAIST-Jdic-for-ChaSenの辞書について\nバージョン:0.4.3(※NAISTとして公開されている最新はMeCab用の辞書0.6.3) 最終更新日:2008/07/07 登録単語数:約28万語 IPAdicの後継として整備。品詞の定義など大まかな仕様は共通。 IPAdicと異なり、アルファベットや数字が1文字ずつ単語として登録されている。 IPAdicとNAIST-Jdicで大きな違いはアルファベットと数字の扱いについてです。 次のような文章をそれぞれの辞書で解析した結果は次のようになります。(SolrのField Analysisの画面です。思いの外大きいのでサムネイルのみですが。) 「このComputerは、10回に1回の割合で起動中に青い画面が表示されます。」 ○IPAdicの場合 ○NAIST-Jdicの場合 「Computer」と「10」という単語の区切り方が異なることがわかります。 この違いは、辞書のエントリが異なるために発生します。 NAIST-Jdicでは、数字(例:「1」)やアルファベット(例:「a」)が個々のエントリで登録されているため、分割された単語として認識されます。\n※この問題への対応方法はまた後日。\nカスタム辞書について 実際のデータを形態素解析したい場合、辞書に存在しない単語を登録して、1単語として認識させたい場合があります。(固有名詞など) このような場合にカスタム辞書を利用することで、新しい単語を辞書に登録することが可能になります。 カスタム辞書を利用する手順としては次のようになります。\nカスタム辞書ファイルの作成 作成した辞書ファイルを利用したjarファイルの生成 まずは辞書ファイルの作成についてです。 以下では、naist-chasen(NAIST-Jdic)の辞書を例として説明します。(ディレクトリの違いだけで、IPAdicでも同じ方法でOKです。)\nlucene-gosenでは辞書のコンパイルに2つのフェーズが存在します。\ngosen用辞書を生成する前処理(中間csvファイルの生成) gosen用バイナリ辞書の生成 カスタム辞書は1の出力の形式(=中間csvファイル=dictionary.csv)にあわせたCSVファイルとして作成します。 CSVの各カラムは次のような意味を持っています。\n単語 単語の生起コスト 品詞 品詞細分類1 品詞細分類2 品詞細分類3 活用型 活用形 基本形 読み 発音 3カラム目以降は「素性(そせい?)」と呼ばれる項目です。ipadic、naist-jdicでは「品詞」「品詞細分類1」「品詞細分類2」「品詞細分類3」「活用型」「活用形」「基本形」「読み」「発音」となります。 ※「見出し語」「形態素生起コスト」「素性」と呼ばれる項目を表形式にする。 厳密な品詞の体系に関してはIPAdicやNAIST-Jdicのサイトをご覧ください(説明できるレベルにはまだまだなっていないので。。。) 今回は、固有名詞(人名、地名など)を追加するという例でカスタム辞書について説明します。 固有名詞として「達川」という人名を追加してみましょう。 まずは、次のようなエントリをもつ「custom-dic.csv」ファイルを作成します。ファイルはUTF-8で保存してください。 コストはすでにあるエントリで似たようなエントリのコストを真似します。(今回は固有名詞,人名で似ているものを採用)。ちなみに、コストは小さいほど単語として出てきやすくなります。 ※カスタム辞書にはSenで利用していたものが利用できます。 **\"達川\",2245,名詞,固有名詞,人名,名,*,*,\"達川\",\"タツカワ\",\"タツカワ\"** 上記ファイルを、先日紹介した$LUCENE-GOSEN/dictionary/ディレクトリにコピーします。 では、カスタム辞書を含んだlucene-gosenのjarを作成しましょう。 カスタム辞書のビルドは$LUCENE-GOSEN/dictionary/で行います。 また、カスタム辞書の指定はCSVファイル名をantの引数で指定します。次がコマンドの例になります。\n$ cd lucene-gosen-trunk $ cd dictionary $ ant -Ddictype=naist-chasen clean-sen $ ant -Ddictype=naist-chasen -Dcustom.dics=\u0026#34;../custom-dic.csv\u0026#34; compile $ cd .. $ ant -Ddictype=naist-chasen 上記コマンドの例で\u0026quot;clean-sen\u0026quot;というタスクを実行しています。これは、すでに出来上がっているgosen用のバイナリ辞書を削除するタスクになります。すでにgosen用の辞書が作成されている場合には辞書の再生成が行われないためです。 また、複数のファイルを利用したい場合は-Dcustom.dics=\u0026ldquo;custom-dic.csv custom-dic2.csv\u0026quot;という形でスペース区切りでファイル名を記述すればOKです。\nカスタム辞書を適用する前と適用後の違いは次のとおりです。 適用前 適用後 簡単ですが、以上がカスタマイズ辞書を利用する方法でした。 ちなみに、この記事を書く前にすでにカスタム辞書の件を書いているブログがありました。。。こちらも参考にしてください。 今回の例でいくつかSolrのanalysis画面を利用して説明してきました。Solrでのlucene-gosenの利用方法についてはまた後日記載したいと思います。 ※参考までに。Solrでの利用方法はこちらにも記載してあります。\nまた、IPAdicなどの辞書について記載のある書籍を見つけましたので、参考になれば。\nアプリケーションソフトの基礎 (講座ITと日本語研究) ","date":1307002560,"dir":"post/2011/","id":"b2621497b3313c97855ed951f0d9b291","lang":"ja","lastmod":1307002560,"permalink":"https://blog.johtani.info/blog/2011/06/02/%E8%BE%9E%E6%9B%B8%E3%81%A8%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0%E8%BE%9E%E6%9B%B8%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/","publishdate":"2011-06-02T17:16:00+09:00","summary":"辞書の特性について 現在lucene-gosenでは以下の2つの辞書が利用可能です。 簡単に違いについて説明します。 IPAdicの辞書について バ","tags":["lucene-gosen"],"title":"辞書とカスタム辞書について(Jugemより移植)"},{"contents":"今回はソースのダウンロードとビルドについてです。\n最新版のソースを利用したり、JavaDocを見たい場合はソースをダウンロードしてからビルドすることになります。 ソースのダウンロードからビルドまでの手順について説明します。\nまずはソースのダウンロードです。\n$ mkdir ~/work $ cd work $ svn co http://lucene-gosen.googlecode.com/svn/trunk/ lucene-gosen-trunk $ cd lucene-gosen-trunk ダウンロードしたソースは次のようなディレクトリ構成です。\n.classpathEclipse用ファイル .projectEclipse用ファイル .settingsEclipse用ファイル AUTHORS作者のリスト(Sen、GoSen) CHANGES.txtlucene-gosenにおける更新履歴 COPYING.LGPLライセンス README.txtReadme build.xmlAntのビルドファイル dictionary辞書コンパイル用ディレクトリ docsAPIドキュメント用ディレクトリ libライブラリ prettifyGoogle Code Prettify用ディレクトリ(APIドキュメントでの色づけ用) srcソースコード また、辞書やソースのコンパイルにはAntを利用します。 通常利用するAntのタスクには次のようなものがあります。\ncleanプロジェクトのクリーンアップ build-dic辞書のコンパイル(辞書のダウンロードも行う) jarjarファイル生成 dist配布パッケージの生成(2つのjarファイル生成) javadocJavaDocの生成 jarファイルの生成までの大まかな流れは「javaソースのコンパイル」~「辞書のダウンロード」~「辞書のプレコンパイル」~「辞書のコンパイル」~「jarファイルの生成」となります。 Antのタスク以外にjarファイルを生成する場合に利用するオプションは以下の通りです。\n-Dproxy.hostプロキシのホスト -Dproxy.portプロキシのポート -Ddictype辞書の指定(指定可能なものは次の通り。naist-chasen、ipadic) 以下はNaist-Jdicのjarファイルを生成するコマンドの実行例になります。プロキシサーバを利用する環境の場合は-Dproxy.hostと-Dproxy.portも指定してください。(※認証が必要なプロキシの場合はAntのビルドファイルを修正する必要が出てきます。)\n$ ant -Ddictype=naist-chasen jarファイルはdistディレクトリに生成されます。 これで、jarファイルが利用できるようになります。\n次回は、ipadicとNaist-chasenの辞書の違いとカスタム辞書を利用する方法について書こうと思います。\n","date":1306398840,"dir":"post/2011/","id":"ff1441a42144a7de9a3eaf9f5e7cfea9","lang":"ja","lastmod":1306398840,"permalink":"https://blog.johtani.info/blog/2011/05/26/%E3%82%BD%E3%83%BC%E3%82%B9%E3%81%8B%E3%82%89%E3%81%AE%E3%83%93%E3%83%AB%E3%83%89%E3%81%A8%E6%A7%8B%E6%88%90/","publishdate":"2011-05-26T17:34:00+09:00","summary":"今回はソースのダウンロードとビルドについてです。 最新版のソースを利用したり、JavaDocを見たい場合はソースをダウンロードしてからビルドす","tags":["lucene-gosen"],"title":"ソースからのビルドと構成(Jugemより移植)"},{"contents":"概要: Lucene/SolrのコミッターであるRobert Muirさんが始めたプロジェクト 歴史: MeCabのJava移植版としてスタートしたSenがベースになります。 その後、辞書の構築部分をPerlからJavaに置き換えたGoSenが登場しました。 が、どちらもメンテナンスされなくなってきたので、Robertさんが引き継いでメンテナンスとLucene/Solr対応をはじめました。そして、現在にいたります。 ライセンス: LGPLライセンス(ベースになったMeCabのライセンスにならって) 特徴: 以下のような特徴があります。 ・Lucene/Solrですぐに利用可能(3.1、4.0に対応済み) ・jarファイル1つで利用可能(辞書をjarファイルに内包) ・LuceneのAttributeをベースにしたTokenの解析 ・その他(パフォーマンス改善、テスト改善など) プロジェクトのサイト: http://code.google.com/p/lucene-gosen/ ダウンロード: http://code.google.com/p/lucene-gosen/downloads/list 現時点では2つの辞書を内包したjarファイルが用意されています。 Naist-jdic 0.4.3(for ChaSen) 参考サイト:http://sourceforge.jp/projects/naist-jdic/ IpaDic 2.6.0 参考サイト:http://sourceforge.jp/projects/ipadic/ ","date":1306130400,"dir":"post/2011/","id":"5988b62a0c0785a303b77c74608e8b55","lang":"ja","lastmod":1306130400,"permalink":"https://blog.johtani.info/blog/2011/05/23/lucene-gosen%E3%81%A8%E3%81%AF/","publishdate":"2011-05-23T15:00:00+09:00","summary":"概要: Lucene/SolrのコミッターであるRobert Muirさんが始めたプロジェクト 歴史: MeCabのJava移植版としてスタートした","tags":["lucene-gosen"],"title":"lucene-gosenとは(Jugemより移植)"},{"contents":"今さらですが、ブログをはじめてみようかと。今さらですが…\nはじめてみようと思った一番の理由は、自分で調べたことをメモがわりに残すためです。 あとは、自分を追い込むためもありますが。(こっちが一番の理由かも)最近勉強してないなぁと感じているので。 ということで、まずは、lucene-gosenやsolrについて書いていく予定です。\n","date":1305859440,"dir":"post/2011/","id":"94b85ba716dbb7c20b230e69248b8208","lang":"ja","lastmod":1305859440,"permalink":"https://blog.johtani.info/blog/2011/05/20/%E3%83%96%E3%83%AD%E3%82%B0%E3%81%AF%E3%81%98%E3%82%81%E3%81%BE%E3%81%99/","publishdate":"2011-05-20T11:44:00+09:00","summary":"今さらですが、ブログをはじめてみようかと。今さらですが… はじめてみようと思った一番の理由は、自分で調べたことをメモがわりに残すためです。 あと","tags":["misc"],"title":"ブログはじめます(Jugemより移植)"}]
\ No newline at end of file
+[{"contents":"今年も振り返りブログをリビングで書いています(ドミノ倒しすごいな)。 FMVのキーボードで書いているのでタイポがつらい。。。\n振り返り(2022年に書いた抱負から) まずは振り返りをと。\nフリーランス継続 今年も個人事業主として乗り越えられました。 ZOZOさんには今年も引き続きお世話になっている感じです。 そのほかにベクトル検索のお手伝いをしたり、OpenSearchを調べたりといった仕事を手伝っています。 今年も完全にリモートで作業していましたが、イベントに出かけたりできました。 来年はもう少し出かける感じになるかな? 今年はすこしのんびり仕事をしていたので、来年はもう少し仕事探さないとかな(営業しないとなあ)\nプログラミング 今年はプログラムを書いたほうかなと。 Goで個人用ですが、Slackのボットを書いてみたり(GoでSlackのボットを作った話 | @johtaniの日記 3rd | @johtani\u0026rsquo;s blog 3rd edition)、公開されているAmazonのプロダクトデータを使って検索アプリを書いてみたり。 プロダクト用のアプリを書いているわけではないですが、ちょっとずつコードを読んだり書いたりしています。\nベクトル検索まわりをさわる がっつりとまではいかないですが、Elasticsearchのベクトル検索の調査をやったりしました。 Amazonのプロダクトデータを使ってもうちょっとやろうと思いつつ、そこまでは手が回せてない感じですが。 速度という面でどうやって折り合いをつけつつ導入するのか? どういうシーンでつかうのがいいのか? どのモデル選ぶのか?とか気になることだらけ。 なんか、みなさんがどうしてるのか気になってしょうがないので、話をしてもいいよという方は連絡をもらえるとうれしいかもなぁ。 ベクトル検索とかLLMの周りの動きがはやすぎてついていけてるのかどうか。。。\n本を読む 今年は比較的読んだかも?\n単体テストの考え方/使い方 ユーザーの問題解決とプロダクトの成功を導く エンジニアのためのドキュメントライティング ザ・ダークパターン ユーザーの心や行動をあざむくデザイン これまでの仕事 これからの仕事 機械学習による検索ランキング改善ガイド ソフトウェア設計のトレードオフと誤り 初めてのGo言語 買って読んでない本ももっとあるんですが。。。\n振り返り(今年あったできごと) ここからは今年の出来事を。 今年もずっと自宅でしごとしてました。 あとは少し仕事が少なめだったのでゲームが多くなってしまったかも?(本読めばいいのに。。。)\nゲーム(ONI、ゼルダ、FactorioのSpace Exploration) Dev container導入 検索技術勉強会の再開 ゼルダの新作面白かったですね。年初はOxigen Not Includedをやっていたのに、ゼルダが出てからはご無沙汰中です。ゼルダが終わった後は、ゼルダロスになってPythonを書いたりしていたのですが、うっかりFactorioのSpace Explorationを始めてしまい大変なことに。。。 全然終わる気配がないw\nローカルでの開発環境などをDev containerにちょっとずつしています。 Slackのボット、検索の遊び場、このブログ環境など。Dockerが必要にはなりますが、VSCodeとDev containerで環境を隔離できるし、VSCodeの拡張もコンテナごとに入れるのもできたりと便利です。\n最後は、検索技術勉強会を再開したことです。再始動という感じで4年ぶり?に再開しました(12月に開催した時のページ)。残念ながら私は裏方をしてただけで、当日は参加できてないのですが、次回(たぶん4月くらい)は参加するつもりです。再開の声を上げてくれた@takuya_aさんありがとう。絶賛スピーカーを募集中です。\n来年の抱負 さて、来年の抱負です。\nフリーランス継続 プログラミング継続 ベクトル検索の使い方をいろいろ試す 本を読んだブログを書く 今年もなんとかフリーランスを継続できましたが、そろそろ営業をしないといけないのかも? ということで、外でしゃべったりもしていかないとなぁと。 あとは、検索ってどうやって導入すればいいのか?検索どうすれば改善できる?みたいなところのお手伝いをもっとしたいと思っています。 昨年出したこの本もあるので(『検索システム ― 実務者のための開発改善ガイドブック』 – 技術書出版と販売のラムダノート)、勉強会をやろうとしているところに顔を出したりしたいなあ。 外部の人を呼んで社内勉強会とかをできるというところがあれば参加したいので、声をかけてもらえればと。\nプログラミングはGo言語を触ったし、今年後半には検索の画面回りのプロダクトを触ってTypeScriptを勉強していこうかなという気になっています(なっているだけかもしれない?)。\nベクトル検索の使い方は、LLMだったりRAGだったりが世の中を席巻しているのもあり、いろんな記事が出てきて全然追いつけていません。だれか、少人数で勉強会とかやると興味ある人とかいるかなぁ? こんなブログ見つけたよ、こんな論文があったよ、こんな使い方したらよかったよとかの共有をやるとみんな楽になったりしないかなぁ?\n今年は時々出かけて移動するタイミングで書籍を読んでいました。 読んだだけになってるのもあるので、少しでもいいからブログか何かに残しとかないとな。\nさて、今年は少しゆっくりできたので、来年はもうちょっといろんなところに顔を出しつつ、新しい仕事もできるといいなぁ。 勉強会もスピーカー集めをがんばるぞと。\nということで、今年もあと少しというところで無事書き終わりました。 来年もよろしくお願いいたします。よいお年をー\n","date":1704008961,"dir":"post/2023/","id":"d869fb48cb9acba03dc639481524ee80","lang":"ja","lastmod":1704008961,"permalink":"https://blog.johtani.info/blog/2023/12/31/review-2023/","publishdate":"2023-12-31T07:49:21Z","summary":"今年も振り返りブログをリビングで書いています(ドミノ倒しすごいな)。 FMVのキーボードで書いているのでタイポがつらい。。。 振り返り(2022","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2023)"},{"contents":"この記事は、情報検索・検索技術 Advent Calendar 2023の15日目の記事です。\n昨年に続き2回目の情報検索のAdvent Calendar参戦です。\n今年は、夏にオンライン参加したBerlin Buzzwordsの「The Debate Returns (with more vectors) Which Search Engine?」というセッションでPhilippさんが話題に出したOrama searchという検索エンジンを紹介してみようと思います(Oramaが正式名称なのかな?)。\nOramaという検索エンジン 公式サイトのトップにも記載がありますが、エッジで動作する全文検索&ベクトル検索エンジンというもののようです。 なにそれ?という感じがしますが、オープンソース版のドキュメントを見るともう少しわかりやすい説明になっています。\nOrama is a fast, batteries-included, full-text and vector search engine entirely written in TypeScript, with zero dependencies.\nOramaはTypeScriptで書かれた、依存なしで利用できる検索エンジンということです(batteries-includedって初めて見たかも。「必要なものがそろってる」とかいう意味みたい(参考:英語のWikipedia))。\n以下は公式サイトにあるサンプルです。\ncreateでスキーマの定義をした検索エンジンのインスタンスを生成します。 insertで先ほど生成した検索エンジンにデータをインデックスします(後で紹介しますが、一括でインデックスするメソッドも用意されています)。 searchで検索し、検索した結果が返ってきます。 以上です。あとは、必要に応じてGUIを用意するだけです。\nimport { create, insert, search } from \u0026#39;@orama/orama\u0026#39; const db = await create({ schema: { title: \u0026#39;string\u0026#39;, director: \u0026#39;string\u0026#39;, isFavorite: \u0026#39;boolean\u0026#39;, year: \u0026#39;number\u0026#39; } }) await insert(db, { title: \u0026#39;The Prestige\u0026#39;, director: \u0026#39;Christopher Nolan\u0026#39;, isFavorite: true, year: 2006 }) const searchResults = await search(db, { term: \u0026#39;prestige\u0026#39;, where: { isFavorite: true, year: { between: [2000, 2008] } } }) サクッと動きそうですよね?依存関係がなくTypeScriptで書かれているということは静的なサイトなどでコンテンツを検索するのに使えるのでは?\nということで、自分のブログに組み込んでみました。 今回は組み込んだ時の流れと気になった点などを紹介します。 Hugoに組み込む際になるべく簡単にしたかったので、unpkg.comで公開されているJavaScriptだけを利用する形で検索ページを作ってみました。 JavaScriptやTypeScriptは不慣れなので効率がよくなかったり、間違っている点があればコメントなどをいただけると嬉しいです。\n構成 私のブログサイトはHugoで生成(参考:Hugo導入時の記事)して、GitHub Pagesとして公開しています。 現在のブログ検索にはAlgoliaを利用しているのですが、テスト目的としてOramaも使えるようにしてみました(右上のメニューでOramaをクリックすると以下で説明するOramaによる検索を試すことができます。\n今回実装してみたのは次のような流れです(日本語検索対応については後で説明します)。\nHugoでJSONのリストを生成(これまでと一緒) 1.で生成したリストをもとにNodeのスクリプトでOramaのインデックスファイルを作成 2.で作成したファイルを公開 画面で3.のファイルをダウンロードして検索 1. HugoでJSONのリストを生成(これまでと一緒) HugoでJSONのリストを生成します。Algoliaに記事を登録するのにも利用している仕組みです。 検索に利用する記事の情報を1記事を1つのオブジェクトとして出力します。1つの配列に記事ごとのオブジェクトが入っているJSONファイルになります。\n少しだけ特殊なことをしています。 ブログ記事にTagsというフィールドのありなしで処理を分岐しています。 Oramaが配列にNullを受け取った場合にうまく動かなかったので出力するJSON側で調整しています(あとで再確認してIssueあげておかないと)\n2. 1.で生成したリストをもとにNodeのスクリプトでOramaのインデックスファイルを作成 最初に紹介した公式のサンプルの場合、毎回Oramaのインスタンスを生成した後にインデックス登録の処理を行わなければいけません。 ただ、Hugoで生成したコンテンツは特に動的に更新があるわけでもないので、検索画面を表示するたびにインデックス登録するのも無駄が多い気がします。 Orama単体で最初に実装した時には、1.で作成した記事一覧のJSONをOramaで実装した検索ページのスクリプトが呼ばれたタイミングでフェッチし、insertMultiple(複数登録用のメソッド)を呼び出す実装にしていました。\nOramaでは、あらかじめ作成したOramaのデータベースを永続化・リストアするためのData Persistenceプラグインが提供されています。 インデックスに登録する処理コストはHugoでコンテンツを生成した直後に行い、検索画面では作成済みのインデックスファイルをフェッチしてリストアする形にすることにしました。インデックスと記事のJSONデータを含んだファイルになるので、元の記事一覧のJSONよりはファイルサイズが大きくなってしまいますが、処理時間も含めて考えると許容できるサイズではないかなと。\n次のスクリプトは1.で生成したJSONファイルを読み込んで、Oramaでインデックスした後にdpackというバイナリ形式でファイルに保存しています。 こののプラグインで選択できる形式は現時点ではjson、binary(デフォルト=msgpack)、dpackの3種類になります。 残念ながら今回試したところ、binaryではエラーが発生したので、dpackを使用しました。\n3. 2.で作成したファイルを公開 単にGitHub Pagesに公開しているだけです。 ブラウザが2.で作成したインデックスファイルをフェッチしてから利用するためです。\n4. 画面で3.のファイルをダウンロードして検索 あとは検索画面です(長すぎるので、styleの部分は省略しています)。\nまず、必要なライブラリなどを読み込みます(下のソースコードの1行目から14行目)。\nOramaだけであれば問題ないのですが、OramaのプラグインがOramaをモジュールとして参照しているため、importmapとして定義しています。 Oramaのプラグインがいくつか利用しているものがあったので、まとめてimportmapに定義してあります。\n次に、検索窓(search-searchbar)や検索結果(search-hits)などのHTMLタグを用意します。 ヒット件数と検索にかかった時間も取れるので、表示する場所としてstatsも用意してあります。\n22行目からが実際の処理になります。\n28行目で、手順2.で作成したインデックスのファイルをフェッチします。 32行目でフェッチしたファイルから取り出した文字列をリストアして、Oramaのインスタンスを生成します。 34行目のtokenizerに関しては日本語対応で説明します。\n48行目のquery関数がクエリの組み立て+検索の処理です。search-inputで入力されたテキストをtermとして渡して検索をしています(56行目)。 検索した結果のリストをもとに検索結果のHTMLタグを組み上げていきます。 検索結果には後述する@orama/highlightのモジュールを利用してスニペットを追加しています。\n日本語対応 残念ながらOramaは公式には日本語をサポートしていません(サポートしているスキーマに設定できるlanguageの一覧(=STEMMERSにあるものだけ指定可能)。一覧と実装分けたほうがいい気がするけど?)。 ただ、tokenize関数を変更できるようにしてくれています。これを利用して、少しトリッキーな形で日本語対応しました。\n先ほどの手順2.でOramaのcreate関数として、componentsに次のtokenizerを渡します。\nlanguageはenglishですが、日本語をtokenizeする処理に次のように書き換えました。 stemmingは今回は行わない(=用意されているstemmerを使えない)のでfalse、normalizationCacheは空のMapを用意しておかないとエラーが出るので、new Map()しています。 この設定を使ってcreateすることで、\ncomponents: { tokenizer: { language: \u0026#34;english\u0026#34;, stemming: false, normalizationCache: new Map(), tokenize: (raw) =\u0026gt; { return tokenize(raw) }, }, }, 少しわかりにくいですが、tokenizerのtokenize関数の中で呼び出しているreturn tokenize(raw)の部分はwakachigakiというライブラリのtokenize関数となっています。\nwakachigakiというライブラリ Elasticsearchなどのサーバー上で動作させる検索エンジンではkuromojiなどの辞書を内包した形態素解析器を利用するのが通常です。 ただ、今回はブラウザだけで完結した簡単な検索を行う仕組みをOramaを使って提供しようと考えました(kuromoji.jsというのもありますが、辞書のサイズがそこそこのサイズです)。 ですので、辞書ファイルのない軽量の形態素解析ライブラリとして、wakachigakiというライブラリ(=6.2Kbの軽量日本語分かち書きライブラリ)を利用してみました。\n最初はTinySegmenterの利用をしていたのですが、wakachigakiのサイトにもあるように、TypeScriptやES Moduleでも利用できる形式となっていたのでこちらに切り替えました。\n辞書もっていないため、品詞でのフィルタリングや読みを利用した処理はできませんが、日本語の文章を分かち書きしてくれます。\ntokenize関数の設定 OramaのTokenizerインタフェースのtokenizeは入力の文字列をstring[]として返すことを期待しています。 wakachigakiのtokenizeも文字列を引数にとり、string[]を返すので、そのまま呼び出すだけにしてあります。\nただ、今回のブログ検索の実装では、検索窓に入力された文字列も特に何も処理せずにtokenizeに渡す形にしています。 クエリパーサーなどを考える場合は、検索窓に入力された文字列を前処理したりする必要がありますが今回はいったんこれで。。。\ndata-persistenceはcomponentsはpersistしない 手順2.で導入した、data-persistenceプラグインですが、現在の実装ではOramaが生成したデータベース(転置インデックス)だけを永続化しています。 独自に設定したtokenizerは残念ながら含まれていませんでした。 手順4.の検索画面のコードの34行目の部分(下記)で、フェッチしたインデックスデータからrestoreした後のOramaのインスタンスのtokenizerに手順2.と同じ設定のtokenizerを設定することで検索時にも同じトークナイズがされるようになります(今の仕組みだと修正した場合には、両方のソースコードを修正しないといけないのがちょっと面倒かも?)。\ndb.tokenizer = { language: \u0026#34;english\u0026#34;, stemming: false, normalizationCache: new Map(), tokenize: (raw) =\u0026gt; { return tokenize(raw) }, } tokenizerはOramaの検索エンジンのインスタンスに紐づく設定となっているので、フィールドごとに切り替えるといったことも現在では想定されていない気がします。\nハイライト ハイライトのために、インデックスデータに単語のポジションを保存するためのプラグインも提供されています。 このポジションは検索の単語がヒットしドキュメントのどの位置に出てくるのか?をあらかじめデータとして保存しておくことで、ハイライトのたびに単語の位置を毎回計算しなくてもよくするためのものと思われます。\nこれを利用してもよかったのですが、今回は@orama/highlightというモジュールを利用することにしました。 検索にヒットしたドキュメントの元の文章と検索のキーワードを入力すると検索キーワードの周りにハイライトのHTMLタグを埋め込んでくれるライブラリを利用しました。これは普通に他でも便利かも?\n余力があればプラグインを利用した時のインデックスのサイズの違いや検索時の速度の違いを調べてみるのもいいかもしれないです。\nそのほかの機能 今回は利用していませんが、Oramaにはそのほかの機能も用意されています(公式ドキュメントの検索の紹介のページ)。詳細は公式ドキュメントをご覧ください。\nTypo tolerance Facet/Filter Vector Search Geo Search Grouping Threshold Preflight Oramaで(まだ?)できないこと 今回触ってみて、現在のOramaの実装ではできなそうなことがいくつかあったので書き出しておきます。 あくまでも現時点のことです。今後実装される可能性もあります。\nデフォルトでは、searchのtermに渡した文字列をtokenizeし、出力されたトークン列(単語の配列)のそれぞれのトークン(単語)にヒットしたドキュメントが全て検索結果に含まれます。 検索結果のドキュメントはBM25でスコアリングされるので、多くのトークンが含まれるものが上位に来る可能性が高いです。\nただ、特定の単語を含まない検索、ANDやOR検索など凝ったクエリは現在は書けないようです(Issueがある)。\nfilterは別途用意されているので、例えばファセットで表示したカテゴリで絞り込んだ状態にするといったことはできそうです。\n残課題 とりあえず日本語をなんとなく検索できるようにすることはできました。 が、気になることもいっぱいありました。 時間を見つけてTypeScriptなどを勉強しながら探っていく感じでしょうか。\nインデックスを小さくする方法 今回はブログ記事のサマリー(Hugoで生成されるSummary)でインデックスを作ったので、インデックスのサイズはまだ小さくなっています(といっても1MB超えてるけど)。ブログ記事全体を検索できるようにする場合は、インデックスファイルが大きくなります。\nこれは、OramaがデフォルトではインデックスしたJSON自体もインデックス(ドキュメントストア)に保存しているためです。 ですので、Oramaに登録したJSONデータ+検索用のインデックスがインデックスファイルとなります。 ただ、検索だけができればよい場合は、出来上がったインデックスがあればドキュメントのIDは取得できます。\n公式ドキュメントでもそのことに触れているページがあります(参考:Remote document storing)。\nまだちゃんと実装を見ていませんが、ブログ記事本体の文字列はドキュメントストアに保存しないようにすれば検索はできるが、容量が大きくならないといった工夫ができそうです。\nただ、検索結果にハイライトを含んだスニペットを表示したい場合は、コンテンツ文字列が必要になってくるので、代わりに何かしらの仕組みを考える必要が出てきます(例えばサマリー部分の文字列だけ保存しておいて、ハイライトはそこだけを対象とするなど)。\nそのほか そのほかに思いつくのはこの辺でしょうか?\nオートコンプリート:Oramaというよりも、JavaScriptやTypeScriptでうまく実装できるのか?という話のような気がしますが。。。 ファセット対応:機能としては存在していますが、今回は実装が間に合いませんでした。 Vector Search:検索キーワードのベクトルをどうやって作るのか?という問題が残りそう。コンテンツのベクトルだけで関連ページの表示みたいなことはできるかも?(動的にやる必要がないので、事前計算して各ページに埋め込むほうがよさそうだけど) Geo Search:緯度経度があるデータを探し出してこないと? relevanceの処理の変更:BM25以外に切り替えることができるかどうか(Oramaのソースとにらめっこしないといけなそう) tokenizeの改良:辞書を利用する形態素解析ライブラリやAPIを利用してみたり、「てにをは」といった1文字のひらがなを削ることで、無駄な検索ヒットを減らしてみたり。大文字小文字の正規化も必要。 検索ログの解析:検索ログを保存する仕組みなどはないので、Google AnalyticsやほかのAPIなどを用意する? まとめ ということで、Oramaという検索エンジン?ライブラリ?を利用して日本語のブログ検索を実装してみました。 まだ、機能が少ない部分もありますが、少数のデータをブラウザだけで簡単に検索できる仕組みをGitHub Pagesだけで提供することができそうです。 今回は静的なファイルだけで完結する形にしましたが、TypeScriptで利用できる簡単な検索エンジンライブラリとして使ってみるとまた別の面白さもあるかもしれないです。 まだ触っていない機能は思いついたこと(=残課題に書いたこと)もあるので、ちょっと試行錯誤してみようかなぁ。\n","date":1702566000,"dir":"post/2023/","id":"476e17b6f854414033d5cec1470774ee","lang":"ja","lastmod":1702566000,"permalink":"https://blog.johtani.info/blog/2023/12/15/introduce-orama-to-blog/","publishdate":"2023-12-15T00:00:00+09:00","summary":"この記事は、情報検索・検索技術 Advent Calendar 2023の15日目の記事です。 昨年に続き2回目の情報検索のAdvent Calendar参戦です。 今年は、夏","tags":["orama","search"],"title":"Oramaという検索エンジンでブログ検索を作ってみた"},{"contents":"PySpaアドベントカレンダーの12/08のエントリーです。昨日は渋川さんのアンラーニングで失敗した話でした。\n私は、今年は昨年の続きっぽい話を。\n音楽の再生とか停止とか 今年もリモートで仕事を継続しています。 昨年、OwnToneという音楽サーバーを導入しましたが、ミーティング開始時や終了後に音楽の停止や再生をするのに、ブラウザで操作するのはちょっと面倒です。 加えて、ミーティングする際には実際には\n音楽を止める 電気をつける といったことをっやります。 音楽再生についても\n音楽を再生する アンプの音は音楽再生用の音量にする といった複数のことを行います。\n基本的にPCの前にいるし、Slackを常に開いているからSlackのBotを作ると便利になるのでは? ということで、自分専用のSlack Botを作ってみました。\nGitHubリポジトリ 全く誰の役にも立たないけど、公開しています。\nhttps://github.com/johtani/smarthome Goで実装 知り合いに勧められたということもあり、Goをあまり触ったことがなかったので、Goでやってみました。時々新しい言語を触ってみたくなるので。。。\nコマンドパターンのような作りで、コマンド(操作)を増やしていく感じで実装してはみたのですが、この書き方がいいのかはまだよくわかっていないです。\nActionという単体の操作(例:OwnToneの一時停止)を、操作したい機器の操作ごとに作成しています。 インターフェースとしてはRunだけを定義しています。\ntype Action interface { Run() (string, error) } それらの操作(Action)をひとまとめにしたものをSubcommandという形で定義して、SlackのBotにはSubcommandの名前を送って処理を実行する形にしています。\ntype Subcommand struct { Definition actions []action.Action ignoreError bool } やりたいことを追加するタイミングで時々リファクタしたりもしていますが、基本はこんな感じです。 細かな実装はさておき、今回ボットを作るときの観点をいくつか。\n宅内ネットワーク 音楽サーバーのOwnToneもですが、YAMAHAのアンプのAPIも見つけたのでこれらの操作をボットから行っています。どちらも自宅のネットワークにあるので、今回作成したボットも同じネットワークで動作します。\n外部に公開されたHTTPのエンドポイントがあればよいのですが、今回は用意していません。 SlackのAPIではこれに対応したアプリを作るときのためにSocket Modeを用意してくれています。\nドキュメントがしっかりしているのもあり、チュートリアルなどを見つつ特に迷うことなく構築できました。\n基本的には「特定のチャンネルでボットがメンションされたら動作する」という挙動だけしか実装していないので、特に今回はこれで困ることもありませんでした(世の中の人たちはもっとすごいSlackの使い方をしていそうだけど。。。)。\n対象となるものたち ボットから操作しているのは今のところ3種類です。\nSwitchBot OwnTone YAMAHAのアンプ SwitchBot SwitchBotについては、go-siwtchbotを利用しています。 電気、エアコン、空気清浄機、サーキュレーターのオンオフをSwitchBot経由でやっています。\n室内灯の明るさのために、SwitchBot側でシーンを設定している(一番暗い明るさで電気をつける)ので、そこが少しと特殊でしょうか?\nあとは、SwitchBotの温湿度計を3つ(室内2つ、室外1つ)おいてあるので、これらの温度を表示するコマンドも用意しました。\nそれぞれの機器の電池残量(電池の絵文字の右側)を表示してます(書斎が2つあるように見えますが、温湿度計の名前なので、同じ部屋においてあります。。。温度が高いほうがデスクトップPCの近くにある)。 防水の温湿度計があるので、外の気温もわかるのは便利です。\nOwnTone JSONのAPIが用意されていますが、特にクライアントライブラリなどは用意されていません。 今回は、用意されているAPIのごく一部だけを利用するので、net/httpのClientでJSONを投げています。 必要になったらowntone/clientにメソッドを追加していく感じです。\nhttps://github.com/johtani/smarthome/blob/master/subcommand/action/owntone/client.go#L45 再生、一時停止、プレイリストの取得、音量指定あたりを実装しています。 音の出力先はAirPlay(次に出てくるYamahaのアンプ)になっています。\nあと、JSON APIのサンプルをChatGPTに渡して、「このJSONをレスポンスに受け取る処理をGoで書いてください」と聞いて処理を書いたりしました(細かいのはどう聞いたか覚えてないけど)。\nYAMAHAのアンプ ググって探してきましたが、利用しているYAMAHAのアンプにYXC(Yamaha Extented Control)と呼ばれるAPIが用意されていました。 PDFでAPIの仕様が公開されていたので、この資料とにらめっこしながら、必要そうなAPIを実行するクライアントを実装しました。 こちらは、OwnToneのAPIの処理をすでに書いた後だったので、それをもとに必要な実装を追加しただけです。\nちなみに、アンプの電源をONにするAPIは実装していません。\nOwnToneで音楽を再生する(AirPlayで信号が送られるみたい) シーン選択(Nintendo SwitchやPS5のシーンを用意している)のAPIを呼び出す という処理をすると自動で電源がONになりました。スタンバイしている状態でもAPIはリクエストを受け付ける状態になっているようです。 また、PS5のシーンを呼び出したら、PS5自体も起動するのが便利だったりします。HDMI経由で信号が飛んでるのかな? 「ミーティング開始」や「音楽停止」コマンドではアンプの電源をオフするAPIを呼び出すようにしています。\nタイポ対応 「入力間違いしちゃうんです、人間だもの。。。」\nということで、10月にタイポ対応の処理を入れてみました。 タイポ対応前の実装では、入力された文字列がコマンドの文字列と完全一致した場合にだけ、コマンドが実行される形になっていました。 結構タイポしちゃうので、完全一致で見つからない場合の処理として、入力された文字列とコマンド名のレーベンシュタイン距離が2以下のものを探し、その中で距離が一番小さな値のコマンドを実行する形にしてみました。 コマンド数はたかが知れているのでコマンドのリストを全部チェックする形にしています。 タイポするとこんな感じ。\nレーベンシュタイン距離の計算にはGo-edlibを利用しています。OSS便利ですね。\nやってよかったこと ミーティング開始時などのいくつかの手順が簡素化できたので満足しています。 SwitchBotの操作もスマホをわざわざ操作しなくてもいいですし(仕事してるとキーボードとSlackは常に使ってるし)。 また、副次的な効果として、部屋の外から電源を切り忘れていたり、エアコンの切り忘れなどの場合に、スマホから遠隔でまとめた処理ができるのが便利です。\n今後やってみたいこと こういうのがあるともうちょっと便利かもなぁ?というのもあるので今後も気が向いたらコマンドなどを追加していく予定です。 今のところこんなことやりたいなというのがいくつかあります。\nキーワードに関連する曲の再生 OwnTone自体に検索の仕組みがついているので、キーワードを受け付けてそれに関する曲を流す Flexispotの操作 ミーティングの時は立ち上がっているので、机をスタンディングの状態にしたい 電子工作しないとだめかも? Webカメラ用ライトの点灯 ミーティング時に明かりが必要なのですが、物理スイッチのOn/Off これも電子工作かな? 定期的に温度をBotに表示させるとと面白いかも? まとめ ということで、新しいプログラミング言語にも触れたし、作業環境も便利になって一石二鳥でした。 新しいプログラミング言語触るのはやっぱたのしいですね。\n","date":1701961200,"dir":"post/2023/","id":"516a7aa07f8faa6b7aa38beb5010cf8c","lang":"ja","lastmod":1701961200,"permalink":"https://blog.johtani.info/blog/2023/12/08/smarthome-bot/","publishdate":"2023-12-08T00:00:00+09:00","summary":"PySpaアドベントカレンダーの12/08のエントリーです。昨日は渋川さんのアンラーニングで失敗した話でした。 私は、今年は昨年の続きっぽい話","tags":["misc","music","bot"],"title":"GoでSlackのボットを作った話"},{"contents":"「機械学習による検索ランキング改善ガイド」を読みました。\n著者の鈴木さんより献本いただいたのを読み終わったのでレビューと、あとおまけです。\n紹介とレビュー どんな本なのか?は打田さんが書かれたブログ、「ブックレビュー:『機械学習による検索ランキング改善ガイド』 - Tomoko Uchida - Medium」に詳しく書かれているので、そちらも参考にしてもらうほうがわかりやすいと思います(丸投げ)。\n読みながらいくつかツイートしていたので、そちらも参考のために貼っておきいます。\nオライリーの検索ランキング本、負荷テストのことも書いてある、すごいhttps://t.co/YPnB6kxFY2\n\u0026mdash; Jun Ohtani (@johtani) August 28, 2023 私のレビュー わかりやすく検索の基本を紹介しつつ、本書のメインであるランキング改善について全体の流れが書かれています。 ランキング改善のやり方といっても、手法の話だけではなく、プロジェクトとしてどの様に進めていくべきなのか?また、関係するものはどんなものがあり(システムだけではなくチームについても書かれていたり)、どういう判断をもちながら運用していくのか?、負荷テストにまで言及されています。\n読んでいて特に私が気に入ったのは以下のような話でした\nランキング改善を進める前にきちんと解ける問題なのか?それ以前にやることはないのかを考えましょう マッチング改善についても少しだけ触れられているが、メインはランキングについてだと明記されている 実際に体験されたのであろう落とし穴の話 負荷テストについて1章設けてある! ハンズオンのパートでもレイテンシの話がされている 付録としてベクトル検索についても触れてある 日本語でまとまって読める本があるのは本当に幸せですよね。\nおまけ 書籍ではハンズオンで、Elasticsearchとランキング学習のプラグインであるelasticsearch-learning-to-rankを利用しています(GitHubにサンプルが公開されています)。 書籍ではElasticsearchが7.13.4、プラグインが1.5.7-es7.13.4というバージョンになっていました。\nブログを書いている時点でのElasticsearchは8.x系になっています。せっかくなので、書籍を読みながら現時点で最新のものに置き換えてみるというのをやってみました。\nElasticsearchは8.10.2が最新なのですが、ランキング学習のプラグインはサードパティ製で、1.5.8-es8.8.2が最新版となっています。 ハンズオンのサンプルコードをフォークして、以下の構成にして動くようにしてみました。\nElasticsearch : 8.8.2 learning-to-rankプラグイン : 1.5.8-es8.8.2 Kibana : 8.8.2 Python : 3.10 Elasticsearch、プラグイン、Kibanaのアップグレード Elastic社が提供しているDockerイメージが利用されているので、バージョン番号を書き換えました。 あとは、learning-to-rankプラグインのバージョンを書き換えるついでに、elasticsearch-pluginコマンドで直接ダウンロードさせる形に書き換えました。\nhttps://github.com/johtani/building-search-app-w-ml/blob/es8/part2/app/search-engine/Dockerfile\nPython3.10にアップグレード 本当は必要なかったのですが、Pythonのイメージもついでに3.10にしました。 ただ、このおかげでインストールされるXGBoostのバージョンも1系から2系に上がってしまい、XGBoostを利用してモデル生成をする処理でエラーが出るようになってしまいました。。。\n2系へのアップグレードは手間がかかりそうだということで、pipコマンドでのインストールでのバージョンを\u0026lt;2として、1系をインストールすることで回避しました。\nhttps://github.com/johtani/building-search-app-w-ml/blob/es8/part2/app/workspace/Dockerfile\nelasticsearch-pyのアップグレード Elasticsearchを8系にしたので、クライアントライブラリ側も8系に書き換えました(元は7.17以下に固定されていた)。 pipで7系に固定されていたものを外して最新のもの(8系)をインストールするようにしました。 これだけでも特に問題なく動いたのですが、「DeprecationWarning」が出ている部分が1か所だけあります(サンプルではDeprecationWarningが出力されない形になっていましたが、出力するように変更しました)。\nElastic公式のドキュメントにMigrate to 8.0というページが公開されています。Pythonクライアントのアップグレードを行う際はこちらを参考にすると指針が記載されています。\n今回のサンプルコードではsearchの時の引数としてbodyを渡していたのですが、8系のクライアントライブラリからこちらが廃止になり、queryやrescoreなど個別の引数を渡す形に変更されています(search APIのリファレンス)。 ですので、bodyを**bodyでアンパックして渡すようにしただけです。サンプルコードがわかりやすく書かれているので変更も少しで済みました。\nhttps://github.com/johtani/building-search-app-w-ml/blob/es8/part2/app/workspace/collect_responses.py#L59\n一応、これでエラーが出ないで動きました。 すべて適用した、フォークして修正したブランチはhttps://github.com/johtani/building-search-app-w-ml/tree/es8で公開しています。\nまとめ すごくわかりやすいうえに、手を動かしながらどんなデータを使ってどんなことをやるのかが体験できる良い本でした。 理論的な話だけでなく、システムとしてどういうものが必要で、どういうことをやらないといけないのか?というのがわかるのがイメージできるのは重要だと思います。\n最後は広告ですが、ランキング改善以外の検索システムについて学べる本を検索システム ― 実務者のための開発改善ガイドブック – 技術書出版と販売のラムダノート出していますので、こちらも参考書として読んでいただけるとうれしいです。\n","date":1695612744,"dir":"post/2023/","id":"7f78b02c531f09602ba4e140132d26a2","lang":"ja","lastmod":1695612744,"permalink":"https://blog.johtani.info/blog/2023/09/25/read-search-raking-guide/","publishdate":"2023-09-25T03:32:24Z","summary":"「機械学習による検索ランキング改善ガイド」を読みました。 著者の鈴木さんより献本いただいたのを読み終わったのでレビューと、あとおまけです。 紹介","tags":["読書","elasticsearch"],"title":"機械学習による検索ランキング改善ガイドを読みました"},{"contents":"趣味?(検索エンジンに関する趣味プロジェクト)でPythonのプログラムを書いています。 ベクトル検索などの確認なども含めて、Jupyter Notebookで簡単なAPIの呼び出しを書いていましたが、検索はやはり画面があるほうがにぎやかでいいですよね。 ということで、画面周りで調べものをしていた時のことを後日の自分のためのメモとして残しておきます。\nSearch UIとSearchkit ということで、それほど手がかからないで検索の画面をサクッと作る方法がないか?ということでちょっとだけ探してみました。 最初にElasticsearchを利用していることもあり、すぐに検索の画面を作れるライブラリ・フレームワーク・コンポーネントがないかな?ということで思いついたのが次の2つでした。\nElastic Search UI Searchkit どちらも直接Elasticsearchに接続して検索をすることができるコンポーネントです。 Elasticsearchだけで完結していればそれでおしまいだったのですが、今回はバックエンド経由でElasticsearchに検索を書ける必要があります(ベクトル検索の仕組みもデモをしたいため、クエリの文字列をLLMなどでベクトルにしてからknn検索をすることになります)。\nSearch UIの構成 もともとSearch UIはElasticのApp SearchのGUI構築向けのコンポーネントとして作られました。 最近になって、直接Elasticsearchに接続できるコネクターを提供しています(ベータだけど)。 このコネクターを利用した場合は、ざっくりですが、このような流れになります。\nまた、Search UIはCustom Connectorの仕組みも用意しており(ConnectorのAPIが宣言されているのでそのAPIで独自実装が可能)、これを利用することで、ブラウザではなくバックエンド(Node)でElasticsearch Connectorを利用するような構成も取れるようになっています。\n改めて要件をまとめると ということで、やりたいことは\n簡単にUIが作れる バックエンドはPythonを経由して検索したい となります。 Searchkitも調べようかと思いましたが、いったんはSearch UIのCustom ConnectorでPythonでFastAPIでバックエンドのAPIを実装して、Search UIの想定しているリクエスト・レスポンスに変換すればいいかな?ということにしました。\nとりあえずSearch UI+Custom Connectorからのリクエスト・レスポンス(フロントからバックエンドへの出入りの部分)を記録し、 Search UI+Elasticsearch Connectorのときのリクエスト・レスポンス(バックエンドからEsへのの出入りの部分)も記録して、 参考にしながらバックエンドを実装しようと試みました。 Search UIのCustom Connectorのサンプルとなっていた、Node上でElasticsearch Connectorを動かしている部分をPythonで簡単に再実装しようという試みです(まったく同じ実装にする必要はなく、必要最低限の機能(検索窓、ファセット、ページング)が動作するところを目指します)。\nElasticsearch API connectorの調査 方針が決まったので、Search UIがElasticsearch API Connectorに渡しているリクエストをブラウザのデバッグ機能を使って追いかけてみると。。。 内部でSearchkitを読んでいる??ことがわかりました。\nElasticsearch API Connectorがリクエストを変換しているのかと思っていたのですが、実は内部にもう一段変換が行われていました。\n方針を決めたつもりが、Searchkitが出てきてしまったので、Searchkitも調べてみることに。。。 なお、Search UIにElasticsearch API Connectorを導入したのがどうやら、Searchkitの作者で、現在はElasticのエンジニアになられているようです。\nSearchkitとは? Search UIが利用しているSearchkitは、3.0ですが、Searchkit本家のリポジトリを見ると4.x.0となっています。\nどうして新しいものをSearch UIで使っていないのかな?と思いつつ調べてみたところ、Searchkit V4のブログを発見しました。\nSearchkit V4 integrates with Algolia’s Instantsearch library, which is a Search UI library built by Algolia. Instantsearch is an amazing library, and it’s been used by many companies and supports many frameworks like React, Vue and Angular. ブログより引用\nどうやら、V4ではコンセプトをガラッと変更されたようで、Algoliaがオープンソースとして開発しているInstantSearchのコネクター(アダプター)としてSearchkit V4を開発しているようです。 これは最近出てきている検索エンジンのTypesenseやMeilisearchの戦略にもなっています。\nなお、SearchkitのGitHubリポジトリやSearch UIのリポジトリを見ていると、Search UIの開発(およびSearchkitの3系)は現在は活発に行われていないように見えました。 Searchkit V4はちょっとずつ開発が進んでいるようです。\nまとめ? 一応Searchkit V4の現状やInstantSearchもすこしだけ見てみたのですが、今回の私のプロジェクトでは検索画面はまだそこまで重要度は高くないので、いったん調べていたSearch UI+Pythonのバックエンドの構成で動作する最小限を実装したところで終わりにしました。 なので、Searchkit V4+InstantSearchの構成はまた今度という感じです。\nなお、Search UIの方は5月からコミットがされていないようです。どうも開発しているチームが別件で忙しそうだなというのを感じました。\n","date":1692768764,"dir":"post/2023/","id":"8f58cbe5f2ce85c22569af765de3f8d3","lang":"ja","lastmod":1692768764,"permalink":"https://blog.johtani.info/blog/2023/08/23/search-ui-and-searchkit/","publishdate":"2023-08-23T05:32:44Z","summary":"趣味?(検索エンジンに関する趣味プロジェクト)でPythonのプログラムを書いています。 ベクトル検索などの確認なども含めて、Jupyter N","tags":["searchkit","search-ui","画面"],"title":"search-UIとSearchkitと検索画面"},{"contents":"いくつかある環境をDev Containerで動くように変えていますが、最初に導入した時に疑問点だった「コンテナ名」について解消したのでメモを残しておきます。\nコンテナ名の指定 最初のDev Container導入の記事で、起動したコンテナの名前が自動で付与されて、ランダムに変わるという疑問点を書いていました。\ndocker-compose.yml対応の記事ではdocker-compose.ymlを利用すると、コンテナ名はファイル内で定義されたサービス名で起動されて見やすくなると気づきました。\nやはり、Dev Containerでイメージを指定している場合もわかりやすいコンテナ名がいいなと思ったところで、「runArgs」を思い出しました。 Dev Containerからコンテナを起動するときに渡す引数が書けるじゃないですか。そういえば、むかしdockerコマンドを使う時に名前を指定した記憶があったなと。ということで、Google検索です。「docker command args container name」で検索しましたw\n--nameというオプションで起動時のコンテナの名前の指定ができます。ということで、このブログを生成するためのdevcontainer.jsonに\u0026quot;runArgs\u0026quot;でコンテナ名を指定してコンテナ起動ができるようになりました(「ブログ記述環境としてのDev Container」という記事のdevcontainer.jsonにrunArgsの行を追加しただけ)。\n{ \u0026#34;name\u0026#34;: \u0026#34;Hugo - blog generator\u0026#34;, \u0026#34;image\u0026#34;: \u0026#34;mcr.microsoft.com/devcontainers/javascript-node:16\u0026#34;, \u0026#34;runArgs\u0026#34;: [\u0026#34;--name\u0026#34;, \u0026#34;blog_generator\u0026#34;], \u0026#34;postCreateCommand\u0026#34;: \u0026#34;/bin/sh ./.devcontainer/postCreateCommand.sh\u0026#34;, ... ","date":1690420969,"dir":"post/2023/","id":"f9e847ee886bdb9ab5583eeb6eabbd51","lang":"ja","lastmod":1690420969,"permalink":"https://blog.johtani.info/blog/2023/07/27/container-name-in-devcontainer/","publishdate":"2023-07-27T01:22:49Z","summary":"いくつかある環境をDev Containerで動くように変えていますが、最初に導入した時に疑問点だった「コンテナ名」について解消したのでメモを","tags":["dev container"],"title":"VS CodeとDev Container(コンテナ名の指定)"},{"contents":"このブログの生成には、Hugoを利用しています。 ブログ移行日記(その1)に書いてありますが、当時はbrewでインストールしていました。 また、Windowsに移行したタイミングで、WSL2のUbuntuにaptでhugoをインストールして利用していました。 WSL2の環境が壊れなければこのままでもいいのですが、最近Dev Containerを触っていたので、このブログを書く環境(おもにHugo)もDev Containerにできるのでは?と気づきました。\nということで、Hugo+αの環境をDev Container化したので、そのメモです。\n必要なもの ブログを書いて、記事を構築して、公開するところまでに利用するのは次のようなものです。\ngit Hugo node atomic-algolia GitHubのプライベートリポジトリでHugoのプロジェクトを管理しています。 また、GitHub Pagesで公開しており、生成したHTMLもgitコマンドを利用してGitHubにpushしています。 このため、gitコマンドが必要です。\nコンテンツの生成はHugoコマンドを利用します(テーマの適用とかいろいろ)。\nあと、Algoliaでブログを検索できるようにしており(ブログ移行日記(その4)参照)、Algoliaへドキュメントのデータをアップロードするために、atomic-algoliaを利用しています。こちらは、nodeのモジュールであるので、nodeの環境も必要です。\nベースにするイメージ Dev Container Templatesというリポジトリが公開されています。 こちらを探すと、元となるdevcontainer.jsonが見つかることがあります。 Hugoのものがあるか探してみましたが、残念ながら見つかったのはJekyllのテンプレートでした。 今回は、nodeの環境が必要なのでjavascript-nodeを元に編集していきます。\n手元のUbuntuのnodeのバージョンが16だったので、バージョン16のイメージを指定します(devcontainer.jsonは後述)。\nHugoの追加 Hugoのテンプレートはなかったのですが、Dev Container FeaturesにHugoのfeatureが用意されていました。 featuresに1行追加するだけでコンテナにHugoをインストールしてくれる便利ものです。\nMarkdownの環境 Dev Container Templatesを探索していて見つけたMarkdownのテンプレートも参考にしてみました。 VS CodeのMarkdown向けの拡張機能がいくつかリストアップされていたので、ついでに追加です。 markdown-all-in-oneやmarkdownlintはこれまでも利用していたので、他のものも便利だろうということで。 他の物はどんなものかを後で調べてみる予定です。\n作った.devcontainerの設定はこちら ということで、出来上がった設定は以下の通りです。\ndevcontainer.json { \u0026#34;name\u0026#34;: \u0026#34;Hugo - blog generator\u0026#34;, \u0026#34;image\u0026#34;: \u0026#34;mcr.microsoft.com/devcontainers/javascript-node:16\u0026#34;, \u0026#34;postCreateCommand\u0026#34;: \u0026#34;/bin/sh ./.devcontainer/postCreateCommand.sh\u0026#34;, \u0026#34;features\u0026#34;: { \u0026#34;ghcr.io/devcontainers/features/hugo:1\u0026#34;: {} }, \u0026#34;customizations\u0026#34;: { \u0026#34;vscode\u0026#34;: { \u0026#34;extensions\u0026#34;: [ \u0026#34;yzhang.markdown-all-in-one\u0026#34;, \u0026#34;streetsidesoftware.code-spell-checker\u0026#34;, \u0026#34;DavidAnson.vscode-markdownlint\u0026#34;, \u0026#34;shd101wyy.markdown-preview-enhanced\u0026#34;, \u0026#34;bierner.github-markdown-preview\u0026#34; ] } } } postCreateCommand.shでは、npm installで、必要なモジュールのインストールをコンテナビルド後に実行できるようにしました。 (apt updateはなくてもいいな)\npostCreateCommand.sh #!/bin/sh # postCreateCommand.sh echo \u0026#34;START Install\u0026#34; sudo apt update sudo chown -R vscode:vscode . npm install echo \u0026#34;FINISH Install\u0026#34; まとめ ということで、ここ最近Dev Containerについて色々調べていたのでサクッとDev Container化ができました。 まぁ、HugoのFeatureが用意されていて、他に大したことをやっていないというのが大きいのですが。 このブログは今回構築したDev Containerで生成して公開した記事になります。\n","date":1690189832,"dir":"post/2023/","id":"7884b62c561b999b9358d52779a18218","lang":"ja","lastmod":1690189832,"permalink":"https://blog.johtani.info/blog/2023/07/24/introduce-dev-container-to-hugo-env/","publishdate":"2023-07-24T09:10:32Z","summary":"このブログの生成には、Hugoを利用しています。 ブログ移行日記(その1)に書いてありますが、当時はbrewでインストールしていました。 また、","tags":["hugo","dev container"],"title":"ブログ記述環境としてのDev Container"},{"contents":"WSL2にUbuntuを入れて、開発とかはこちらを利用しています。 また、Docker DesktopもWSL2のバックエンドエンジンを利用しています。\n知り合いとの話で、Ubuntuの外付けのSSDをマウントしたという話が出てきて、それだと遅くない?Ubuntu自体を移動できるんじゃないかな?という 流れになりました。 知り合いは、特に移動とかは考えてなかったのですが、自分のディスクの容量が今どのくらい使われているのかが気になり、調べてみると、 Cドライブの使用率が90%を超えてるじゃないですか。\nWizTreeというソフトを前回入れていたのを思い出して、再度調べてみたところUbuntuらしきvhdxファイルのサイズが171GB、Docker Desktopのデータ領域のvhdxファイルのサイズが81GBと、結構な割合です。\n前回は、Hyper-V管理ツールで仮想ディスクの圧縮処理を行ったのですが、Dドライブに移行したほうが安心できそうな気がしたので、移動の方法を調べました。\nWSLコマンドのドキュメントが公式で公開されています。こちらのコマンドを元に作業をしました。 また、ググって出てきた記事も参考にさせていただきました。ありがとうございます。\nwsl をDドライブに入れ直してディスク拡張する | blog.ojisan.io WSL2環境をコピー(複製)する方法 - Qiita まずは確認と停止 WSL2で使っているディストリビューションを確認します。コマンドは以下の通り。 実行した結果も含まれています。コマンドの実行にはコマンドプロンプトを使用しました。公式ドキュメントのドキュメントではスニペットはPower Shellと書かれてますが、コマンドプロンプトでも大丈夫そうでした。\nD:\\\u0026gt;wsl -l -v NAME STATE VERSION * Ubuntu Running 2 docker-desktop Running 2 docker-desktop-data Running 2 残念ながら、wslのコマンドでは実体がどこにあるのかを調べることができなかったですが、WizTreeでディレクトリ名などを見ていたのでなんとなう予測ができました。 (これ、他に知る方法あるのかなぁ?)\nディストリビューションの移動は次のような手順になります。\nwslのshutdown エクスポート(ディストリビューションのコピー) 今あるディストリビューションを削除 インポート(今ある名前で2.のファイルをインポート) まずは停止です。これをやらないとエクスポートができないので。\nD:\\\u0026gt;wsl --shutdown エクスポート 次にエクスポートです。 今回は以下の2種類の仮想環境をエクスポートします。\nUbuntu docker-desktop-data エクスポートでは、元のディストリビューションのファイル(Cドライブにあるファイル)が消えることはありません。 また、エクスポートの形式として、tarとvhdxの2種類が指定できます。 エクスポートのコマンドのデフォルトはtar形式ですが、エクスポート元のファイルがvhdxなので、vhdxでエクスポートしたほうがCPUにやさしかったです。 ちなみに、docker-desktop-dataはtar形式でエクスポートしてインポートしました。tar形式の場合は、ディスクのサイズが小さくなる可能性があるみたいです(不要なデータがvhdxの中に残っていたりする影響かと)。\nコマンドは以下の通りです(詳細は公式ドキュメントを参照してください)。出力ディレクトリはあらかじめ作っておきました(作ってない場合の挙動は未確認です。)\nD:\\\u0026gt;wsl --export Ubuntu .\\wsl\\Ubuntu\\ext4.vhdx --vhd docker-desktop-dataはtar形式です。\nD:\\\u0026gt;wsl --export docker-desktop-data .\\Docker\\ docker-desktop-data.tar ディストリビューションの削除(こわい?) 今ついているディストリビューション名を利用したいので、いったん、Cドライブ上にあるディストリビューションを削除する必要があります。 コマンドは公式ドキュメントにある--unregisterオプションを利用します。 以下のコマンドはUbuntuですが、docker-desktop-dataもやりました。\nD:\\\u0026gt;wsl --unregister Ubuntu ちなみに、このコマンドを実行すると、Cドライブの容量がいきなり空きました。 コマンドいっぱつでなくなりました。きちんとエクスポートしてから実行しましょう。 (なんなら、一度、別名でインポートして動作確認するのもいいかもしれないです。私はしましたw)\nインポート インポートするオプションも2種類あります。vhdxファイルの場合は、インプレースでのインポート(vhdxファイルをそのまま利用する形式)が可能です。 Ubuntuについてはこちらを利用しました。この場合、vhdxファイルがそのまま利用されるため、バックアップとしては利用できなくなります。今回は170GBもあるので、これでいいかと。\nD:\\\u0026gt;wsl --import-in-place Ubuntu .\\wsl\\Ubuntu\\ext4.vhdx tarファイル(docker-desktop-data)の場合は、通常のインポートを行いました。\nwsl --import docker-desktop-data D:\\Docker\\docker-desktop-data\\ D:\\Docker\\docker-desktop-data.tar この場合、tarファイルは残ったままで、新たにD:\\Docker\\docker-desktop-data\\ディレクトリにext4.vhdxファイルが作られました。 バックアップも取りつつ移行したい場合は--importがいいかもしれません。 また、WSLはバージョン1とバージョン2があり、インポートの際にこの部分も気にする必要があるようです。 今回はすべてバージョン2で、かつ、wslのデフォルトのバージョンを2にしてあったので特に意識していません。\nUbuntu起動ユーザーの指定と注意点 公式ドキュメントに、既存のユーザーを変更するコマンドの記載があります。 インポートしたディストリビューションは、デフォルトユーザーがrootになっていることがあるようなので、Ubuntuのユーザーを次のようなコマンドで変更しました。\nubuntu config --default-user johtani 公式ドキュメントの警告にもありますが、実行可能ランチャーがない場合があります。 今回のubuntuは、WSL2でUbuntuをインストールした時に作成されたコマンドで、unregisterした後にimportしてもきちんと動いたので問題にはなりませんでした。これは、インポートするときに、既存のディストリビューション名を利用したためと思われます。\nエクスポートやインポートの検証するために、NewUbuntuという名前で別途インポートした時には、NewUbuntuという実行可能ランチャーは作成されず、上記のデフォルトユーザーの設定は別の方法が必要になります(罠だ)\ndocker-desktop-dataのほうは、特に変更してないけど動いてそうだからいいのかな? 前の設定の確認とかやっておくのがいいんだろうな、本当は。。。\nまとめ ということで、Cドライブに300GB近い空きができて、心の余裕もできました。 今回は、同じPC内で別のドライブへの移動でしたが、他のPCにもこれで移行ができそうですね。 たまにはバックアップをとっておくのもいいのかも?と思いました(やるかどうかはまた別の話)\n","date":1690180128,"dir":"post/2023/","id":"ed431877ce11fe403fee77f7d26ce637","lang":"ja","lastmod":1690180128,"permalink":"https://blog.johtani.info/blog/2023/07/24/move-distribution-to-another-disk/","publishdate":"2023-07-24T06:28:48Z","summary":"WSL2にUbuntuを入れて、開発とかはこちらを利用しています。 また、Docker DesktopもWSL2のバックエンドエンジンを利用して","tags":["wsl","windows"],"title":"WSL2のディストリビューションの環境移行"},{"contents":"前回の記事で、VS Code+Dev Containerを導入しました。 残課題として「マルチコンテナ化」があるという話もしました。今回はDev Containerのdocker-compose.yml対応をした話をメモとして残しておきます。 実際、VS Code + Dev Containerに移行した後に、Esを起動してアプリからつなげるというのがうまくいかないというのがあったので対応がんばりました。。。\nDev Containerのdocker compose設定 この記事ではすでにdocker-compose.ymlが存在している状態の話をします。 変更する前は、devcontainer.jsonでベースのコンテナイメージの指定、マウントの設定などを行っていましたが、docker-compose.ymlにいくつかを移動しないといけません。 対応した時の作業の流れは以下のような感じです。\nワークスペース用のDockerfileの作成 docker-compose.ymlにワークスペース用のサービスを追加 devcontainer.jsonをdokcer-compose.ymlを利用する形に書き換え アプリでの接続文字列をlocalhostからdocker-compose.ymlのサービス名に変更 参考:対応した時のコミットです。差分などはこちらをごらんください。\ndevcontainerのリポジトリにPython+PostgreSQLのサンプルが公開されており、こちらを参考にしながら作業をしました。\n1. Dockerfileの作成 docker-compose.ymlだけでも完結するのかもしれないですが、いろいろやりたいことも出てくるかもしれないので別のファイルに切り出しました。 といっても、コンテナのイメージはdevcontainer.jsonに記述していたものを使っています。\nARG VARIANT=3.11-bookworm FROM mcr.microsoft.com/devcontainers/python:${VARIANT} ENV PYTHONUNBUFFERED 1 ENV TZ Asia/Tokyo TZはdevcontainer.jsonで指定していたものを、こちらに移行した形になります。 PYTHONUNBUFFEREDは参考にしたDockerfileの記載です。標準出力・エラーをバッファリングしない指定になっています。\n2. dokcer-compose.ymlにサービス追加 backendという名前のサービスをdevcontainer(VS Code)から接続するコンテナのサービス名にしています。\nservices: backend: build: context: . dockerfile: .devcontainer/Dockerfile init: true environment: - TZ=Asia/Tokyo command: sleep infinity volumes: - .:/workspace/search-research:cached - venv-search-research-backend:/workspace/search-research/.venv ... volumes: venv-search-research-backend: 1.で作成したDockerfileを利用します。docker-compose.ymlファイル自体は、プロジェクトのルートディレクトリに配置していますが、Dockerfileは.devcontainerディレクトリに入れたため、contextとdockerfileはこのような指定になっています。\ninitは、devcontainer.jsonで指定していた\u0026quot;runArgs\u0026quot;: [\u0026quot;--init\u0026quot;],の設定になります。\ncommandの部分は、コンテナが起動したままにしておくための設定です。\nvolumesでは2つのボリュームに関しての指定があります。 1つ目の/workspace...は、VS Codeがコンテナにプロジェクトをマウントする場所の指定です。 devcontainer.jsonだけを利用していた場合は意識していませんでしたが、/workspace/プロジェクト名というディレクトリにプロジェクトがマウントされていました。 docker-compose.ymlを利用する場合は、明示的に指定が必要です。 2つ目のvenv-...は.venvのディレクトリをコンテナの中だけのものにする設定を移植したものになります。 前回の記事ではコンテナIDをボリューム名に含めていましたが、こちらのほうがわかりやすいかと思い、プロジェクトの名前とサービス名をつけるようにしてみました。 Dev Containerで起動した場合はsearch-research_venv-search-research-backendという名前がついています(最初の部分はDev Containerがつけてるのかな?)\n3. dovcontainer.jsonの変更 devcountainer.jsonから呼び出すものの準備ができたので、devcontainer.jsonを書き換えます。 公式のドキュメントとしてDocker Compose向けのプロパティが紹介されています。 変更したものは次のような形です。\n{ \u0026#34;name\u0026#34;: \u0026#34;search-research\u0026#34;, \u0026#34;dockerComposeFile\u0026#34;: \u0026#34;../docker-compose.yml\u0026#34;, \u0026#34;service\u0026#34;: \u0026#34;backend\u0026#34;, \u0026#34;workspaceFolder\u0026#34;: \u0026#34;/workspace/search-research\u0026#34;, \u0026#34;postCreateCommand\u0026#34;: \u0026#34;/bin/sh ./.devcontainer/postCreateCommand.sh\u0026#34;, \u0026#34;customizations\u0026#34;: { ... dockerComposeFile : 利用するdocker-compose.ymlのファイルパス service:VS Codeが利用するワークスペース用のサービス名 workspaceFoldeer:VS Codeがコンテナに接続したときに開くフォルダのパス を指定します。これで、VS Codeでこのプロジェクトを開いた時に、Dev Containerがdocker-compose.ymlを使ってコンテナの起動(ビルドとか)を行ってくれます。\n4. アプリの接続文字列の書き換え こちらはおまけです。 PythonのアプリからElasticsearchに接続するときの文字列として、Dev Container化の前は、http://localhost:9200と指定をしていました。 Elasticsearch用のサービス(es)で、ポートフォワードをしていたためです。\nアプリ側もコンテナ化したので、Docker Composeが名前の解決をしてくれるので、http://es:9200という接続文字列で接続ができるようになりました。\nということで、ここまでで、VS Codeでプロジェクトを開くと、2つのコンテナ(backendとes)が起動してVS Code上でPythonアプリからEsへの接続ができるようになりました。\n追加の変更 参考のプルリクでは、上記まででしたがさらにいくつかの変更をそのあとやっています。\n起動するサービスの指定(開発だけするときはEsを起動したくない) devcontainer.jsonでrunServicesを使って指定できます(公式ドキュメント) GPUをコンテナから利用できるように devcontainer.jsonでfeaturesのnvidia-cudaを指定し、docker-compose.ymlでnvidiaのドライバーなどを設定することで対応しました。 nvidiaが公開しているcuda対応のコンテナイメージでもよかったのですが、こちらのほうが楽そうだったという理由です。featuresとコンテナのビルド、postCreateCommandの順序などはもうちょっと勉強しないといけない気がしています。 これらの対応はこちらのコミットで対応しています。\nGPUの対応は、私個人の環境はこれでいいのですが、複数の人がこのリポジトリを使う場合はどうやって切り替えたりするんだろう?という疑問が残っています。。。 今回はrinna/japanese-clipのモデルを使って、テキストからベクトルを生成する部分の処理のためにGPUを使いたいというモチベーションがあり、コンテナでもGPUを使えるようにしています(CPUだと時間がすごくかかる。。。)。\nサービス起動の新たな問題点 runServicesで起動するサービス名を指定したのはよかったのですが、Elasticsearchのサービスを起動して、データ登録や検索の確認を行おうと思った時に、EsのコンテナをVS Codeだけで起動する方法がまだわかっていません。。。 一度コンテナをビルドした後なら、「Remote Explorer」でOther Containerというくくりで表示され、右クリックで起動や停止ができそうなのだけど、新規サービスをdocker-compose.ymlに追加した場合は、自分でターミナルなどでコンテナのビルドをしないといけないかもしれないです。もうちょっと調べてみないとなぁ。\n副次的な効果 Docker Compose対応をしたことで、前回の記事での疑問点のうち、「コンテナ名」「VolumeのID」については懸念点がなくなりました。\n「コンテナ名」は、docker-compose.ymlのサービス名がコンテナ起動時に名前として利用されるため、Docker Desktopで見た時などの探しにくさはなくなりました。 ただ、「イメージ名」については、いまだに2つできています。「-uid」がつかないものの代わりに、search-research-backendというイメージが作られています。 ただし、実際に利用されるのは前回の記事に書いたようなvsc-search-research-bf04371c017c8d2f1dd5ad2529841b02e9ea1d1aaa4354c19edf53cef3f0c13b-uidという名前のイメージです。\n「VolumeのID」については、docker-compose.ymlのファイルで自分で名前をつけるようにしたので、コンテナのIDが利用されなくなったという次第です。 代わりに、プロジェクト名である「search-research」という名前を直接記述しているので、変数などで置き換えたほうがいいのかも?という気がしています。\nまとめ ということで、複数のコンテナを利用するプロジェクトでVS Code+Dev Container対応ができそうだということがわかりました。 ついでに、GPU対応もできたのでこれで、やっと他の検索エンジン対応などができる気がしています。 (その前にpre-commitを保存時にチェックする形に変更かなぁ) やりたいことからちょっとずつ外れている気もするけれど、新しいことを調べるのは楽しいですね。\n","date":1689902010,"dir":"post/2023/","id":"086b4fd5f77021a0a2aa6b0e90061486","lang":"ja","lastmod":1689902010,"permalink":"https://blog.johtani.info/blog/2023/07/21/multi-containers-with-dev-container/","publishdate":"2023-07-21T10:13:30+09:00","summary":"前回の記事で、VS Code+Dev Containerを導入しました。 残課題として「マルチコンテナ化」があるという話もしました。今回はDev C","tags":["python","dev container"],"title":"VS CodeとDev Container(docker-compose.yml対応)"},{"contents":"前回の記事で、pre-commitとPyCharmとWindowsの組み合わせで困っていることを書きました。 これについて、知り合いとチャットで話をしていて、それほどPyCharmにこだわりもないよなぁということになり、 であれば、ISIDのブログ(Dev Containerを使ってステップバイステップで作るPythonアプリケーション開発環境 - ISID テックブログ)を試してみるとすっきりするかもしれないとなり、Dev Container対応をブログを参考に行ってみました。\n順を追ってブログで説明されているので、どういう仕組みなのか、どの設定が何を意味しているのか?がとてもよくわかりやすくすんなり対応することができました。\nブログの手順をなぞっているところでいくつか固有の手順や疑問点が出てきたのでブログに書き記しておきます。 結果は、コミットしてあるものを見てください。\nブログとは違う手順 まずはISIDのブログとは違う点をいくつか。\n.venvはいったん削除 ブログでは新規のプロジェクトを作成していく過程で、コンテナ化した環境を作った後に.venvをDockerコンテナのボリュームにして、最後に仮想環境のPythonを生成していました。 私の場合は、すでにホストOS(実際にはWSL2のUbuntuだけど)で.venvのディレクトリを作成してある状態だったので、いったん削除する必要がありました。 すでに存在する.venvがbindマウントされてしまっている状態になるため、Dockerのボリュームとの整合性が取れなくなるようです。\nこの作業を行う前か、途中でDev Containerを停止した状態で、.venvを削除することで問題なくDockerのボリュームに仮想環境のPythonが登録されるようになります。\npostCreateCommand.shの呼び出し方 ファイルに実行権限がないと、実行権限エラーが出ました。 実行権限を与えるか、次のような記述で動くようになりました。 今は、ファイルに実行権限をつけるのではなく、次のような記述にしていますが、何か問題あるかな?\n\u0026#34;postCreateCommand\u0026#34;: \u0026#34;/bin/sh ./.devcontainer/postCreateCommand.sh\u0026#34;, 実際に動作しているログを見ると\n/bin/sh -c /bin/sh ./.devcontainer/postCreateCommand.sh\nとなっているので、少し気持ち悪いのだけれども。。。\npostCreateCommand.shの追加処理 今回Dev Containerを適用したプロジェクトでは、sentencepieceを利用します。 この、sentencepieceをpoetryがインストールするタイミングで、cmakeを要求してきました。 今回利用しているDocker Imageにはcmakeは含まれていないため、以下の処理を追加しています。\nsudo apt update sudo apt-get install cmake -y また、rinna/japanese-clipも利用しているのですが、こちらは、poetryで追加してインストールでは依存するパッケージがインストールされないため、pipコマンドを利用するようにしています。\npip install git+https://github.com/rinnakk/japanese-clip.git コンテナイメージを作った後にやりたいことを、自由にスクリプトで書けるのは便利ですね。\npre-commitのスクリプトの再生成 こちらも、既存の環境が残っているとPythonへのパスの違いの問題が出たので、作り直しました。 .git/hooks/pre-commitのファイルを削除し、pre-commit installをやったものをリポジトリにコミットしてあります。\n疑問点 作業をしていて疑問点もいくつか出てきたのでメモを残しておきます。ちなみに、これらの疑問について実際に調べるまでには至っていません。 時間を見て解決できればなぁと(できるのか?)。\nImageが2つ Dev Containerの設定を書いた後に、コンテナをビルドすると、Docker DesktopのImagesにイメージが出来上がります。 この時、イメージが2つできあがっています(なぜ?)。\nREPOSITORY TAG IMAGE ID CREATED SIZE vsc-search-research-bf04371c017c8d2f1dd5ad2529841b02e9ea1d1aaa4354c19edf53cef3f0c13b-features-uid latest 25c7e23416ec 3 days ago 1.69GB vsc-search-research-bf04371c017c8d2f1dd5ad2529841b02e9ea1d1aaa4354c19edf53cef3f0c13b-features latest fcf9eaeb2187 3 days ago 1.69GB こんな感じで、最後に-uidがついているかいないかの違いです。 実際にコンテナ起動時に利用されるのは-uidがついているものになります。 なぜ2つになっているのか、1つにする設定などがあるのか?といったところが気になるところです。\nContainerの名前 devcontainer.jsonの設定を書き換えて、コンテナをリビルドすると起動したコンテナの名前が自動で割り振られているようです。 今は、fervent_hopperとなっています。ランダムにつけられているようなのですが、名前を付ける方法はないのかなぁ?と。\ndevcontainer.jsonにはnameというプロパティもあるのですが、この値がどこで使われているのかはよくわかっていません。 Remote Explorerでコンテナの一覧が見えますが、ここでは、リポジトリ名が利用されているようです。\nVolumeのIDはどこから? devcontainer.jsonで次のような記述で、.venvのディレクトリようにDockerにボリュームを作っています。\n\u0026#34;mounts\u0026#34;: [ \u0026#34;source=venv-${devcontainerId},target=${containerWorkspaceFolder}/.venv,type=volume\u0026#34; ], 実際にコンテナでマウントされている情報を見ると\n/workspaces/search-research/.venv /var/lib/docker/volumes/venv-04emir9hi2caivtjunfe3l17452hkbb3hdut1qflbrn8n924ho5c/_data となっています。 04emir9hi2caivtjunfe3l17452hkbb3hdut1qflbrn8n924ho5cがdevcontainerIdに相当するのだとは思うのですが、誰がつけたものかなどがまだよくわかっていません。 もうちょっとわかりやすいものが使えるほうが嬉しいかも?と思っていたりします。 (複数Dev Containerを使い始めると、Docker Desktopで見ると、どのボリュームがどのDev Containerに紐づいているかがぱっと見ではわからない)\n.vscodeディレクトリどうしよう? たぶん、VS Codeを触っている過程で、何かの設定をしてしまったのだとは思うのですが、 .vscode/settings.jsonというファイルができており、次のような内容になっています。\n{ \u0026#34;git.ignoreLimitWarning\u0026#34;: true } 何か意味があるかも?ということで、コミットしてリポジトリに入れたのですが、いらないのかもしれないなぁと。\n残作業 とりあえず、VS CodeでPython環境ができて、VS CodeのTerminalでPythonのプログラムが実行できるのはわかった段階です。 いくつか、今後調べながらやる必要があるものが残っているのでメモとして残しておきます。\nマルチコンテナ化 今回Dev Containerに対応したプロジェクトでは、検索エンジンもDockerのコンテナとして起動して、Pythonのプログラムから接続したいと思っています。 となると、docker composeでいろいろと起動するほうがネットワークなどの設定も楽になるのでは?と思っているところです。 Dev Containerのテンプレートがいくつか用意されており、その中に「Python 3 \u0026amp; PostgreSQL (postgres)」というのを見つけたので、このあたりが参考になるのでは?と考えているところです。\npre-commitではなく、保存時にフォーマット pre-commit+localのコマンドも動くようにはなったのですが、保存時にフォーマットなどをかける設定もISIDのブログで記載がありました。 コミットしようとして、怒られるよりも、保存時に怒られたりするほうがいいかも?という気分になってきています。 どこまでが切り替え可能なのか?なども見ながら対応してみようかなと。\nもう少し開発してみて改善点を探っていく とりあえず動いたという段階です。 PyCharmとの違いがあるはずで(たとえば、git周りのGUIの違いとか)、そのあたりでどんな違いがあり、どんなものがあると嬉しいのか?といったものを調べる必要もあるかなと考えています。 TerminalでCtrl+rがうまく使えなかったり(Auto Hot Keyで検索のショートカットに割り当ててしまっているから。。。)などもあるので、この辺も調べていきたいなと。 Windows Terminalを使えたりするのかなぁ?\nまとめ さて、とりあえず、VS CodeでPythonのDev Container環境を作って動くところまでは来ました。 PyCharmを使いこなしていなかったのもあり、それほど違和感なく移行できるような気がしています。 調べることはまだまだあるし、プログラム書くつもりが、環境を整える方向に話がずれている気もしますが、まぁ面白いのでよしとするかなぁ。 いろいろまだまだ知らないことだらけです。。。\n","date":1689254123,"dir":"post/2023/","id":"a12474027c91fad5a861aa9919817d72","lang":"ja","lastmod":1689254123,"permalink":"https://blog.johtani.info/blog/2023/07/13/introduce-vs-code-and-dev-container/","publishdate":"2023-07-13T22:15:23+09:00","summary":"前回の記事で、pre-commitとPyCharmとWindowsの組み合わせで困っていることを書きました。 これについて、知り合いとチャット","tags":["python","dev container"],"title":"VS CodeとDev Containerの導入(まだ途中)"},{"contents":"最近、趣味(検索エンジンに関する趣味プロジェクト)でPythonのプログラムを書き始めました。\nきちんとPythonのプログラムをプロジェクトとして書いたことがないので、 Pythonのプロジェクトのディレクトリ構成などを手探りで進めているところです。 コードのフォーマットとかもやらないとなぁ?と知り合いのいるSlackでつぶやいたところ、gitのpre-commitフェーズでblackなどのフォーマットやスタイルを修正してくれるツールを実行する方法を教えてもらいました(PRまで送ってもらえたのでありがたい)。\nで、pre-commit周りの設定などを変えている段階で遭遇した問題点についてログを残しておこうと重いブログを書いています。 残念ながら現時点では解決してないんですけどね。。。\n手元の環境 簡単に環境を書いておくとこんな感じです。\nWindows上のPyCharmを開発で使用 プロジェクトのディレクトリはWSL2のUbuntu上 Python、gitはUbuntuのものを利用 プロジェクトのルートディレクトリにある.venvにvenvでPythonの仮想環境を作成してある 問題点 遭遇したpre-commitの問題点は次の通りです。\npre-commitの設定でrepo:localでローカルのプロジェクトにインストールしたコマンドを利用するように変更 すると、PyCharmでコミットすると、blackなどのコマンドが見つからない ターミナルでコミットするときはきちんと動作する 色々調べて試行錯誤した結果、現在はrepo:localでのローカルコマンドを使用する方法はあきらめました。 移行は、作業記録みたいなものです。どういう流れでpre-commitを取り込み、ローカルに切り替え、切り戻したかという話です。\npre-commitとpre-commit 最初に少し戸惑ったのは、pre-commitというツールとgitのpre-commitフックです。 gitのpre-commitのフックのために作られたPython製のpre-commitというツールがあります。\nこのPython製のツールを利用することで、プロジェクトに.pre-commit-config.yamlという設定ファイルを置けば設定に記述されたツールをgit commitのタイミングで実行してくれます。 実際には、pre-commitというツールの初期設定のタイミングでpre-commit installというコマンドを実行して .git/hooks/pre-commitというスクリプトが生成されます。 gitコマンドはcommitされた時に(commit前のフェーズ)でこのスクリプトを実行し、そこで.pre-commit-config.yamlが参照されています。\n.pre-commit-config.yamlの記述は次のようなものになります(最初にもらったPRより)。\nrepos: - repo: https://github.com/psf/black rev: 23.3.0 hooks: - id: black args: [\u0026#34;--line-length\u0026#34;, \u0026#34;120\u0026#34;, \u0026#34;.\u0026#34;] - repo: https://github.com/pycqa/flake8 rev: 6.0.0 hooks: - id: flake8 - repo: https://github.com/pycqa/isort rev: 5.12.0 hooks: - id: isort args: [\u0026#34;--profile\u0026#34;, \u0026#34;black\u0026#34;, \u0026#34;--filter-files\u0026#34;, \u0026#34;--multi-line\u0026#34;, \u0026#34;3\u0026#34;] - repo: https://github.com/pre-commit/mirrors-mypy rev: v1.4.1 hooks: - id: mypy 実際に、PRを取り込んで動かしてみたところ、blackなどが動いて行末のスーペースの除去や未使用のimportについて指摘をしてくれました。 便利だなと思ったのですが、ここで疑問が。\n今回は対象とするプロジェクトはpoetryで依存パッケージの管理を行っています。 今回、上記を動かすためにpoetryに追加されたものはpre-commitだけでした。 「あれ?blackとかはどこにあって、どうやって動いてるんだ?」という疑問が出てきます。 コンフィグファイルにはパスなどの記載をせず、それぞれのgithubリポジトリの記載とバージョンがあるからです。\npre-commitが使用するツールのインストール先 調べてみたところ、どうやらホームディレクトリにある.cache/pre-commitにblackなどのコマンドが見つかりました。 pre-commitツールが設定ファイルを基に、必要なコマンドをgithubからダウンロードしてきて実行時に利用しているようです。 pre-commitは便利なのだけど、せっかくPythonのプロジェクトだしそれぞれのツールはpoetryでpyproject.tomlでバージョンや設定を管理したほうがすっきりするのではないか?ということで、少し調べてみました。\n同じようなことを考えている方がブログを残していてくれました(Pythonレポジトリ用のpre-commit環境を整える)。 設定をpyproject.tomlに移行し、そのあと、ローカルのpetryでblackなどのコマンド類をインストールして利用する設定に書き換えています。 先人の肩に乗っかって、手元で同じようにpre-commitの設定ファイルのrepoをlocalに書き換えていき(その時のコミット)、ターミナルでpoetry run pre-commit run -aで動作確認できました。\nPyCharmでコミットしたらエラー ですが、実際に変更した状態でPyCharmからコミットしたら、コマンドが見つかりませんというエラーが出ます。。。 WSL2のターミナルでgit commitした場合は問題ありません。 どうして?となりますよね。。。。\n.git/hooks/pre-commitはPyCharm、ターミナルのどちらからも実行されています。 ですが、PyCharmではblackなどが見つからないというエラーが出ました。\n.git/hooks/pre-commitを見てみると、python実行するためのpythonのパスはプロジェクトにある.venv/bin/pythonを指定しています。 デバッグのために、このスクリプトにecho $PATHを差し込んで、git commitをPyCharmとターミナルからそれぞれ実行してみたところ、大きな違いがあります。\nターミナルで実行した場合は、\u0026lt;プロジェクトのディレクトリ\u0026gt;/.venv/binもPATH環境変数に存在していました。このため、.venv/binにあるblackなどを実行できています。\nPyCharmはWindowsから起動しています。プロジェクトのインタプリタとしては、WSL2のUbuntuにある.venv/bin/pythonを指定しているためもあり(?)、出力されたパスは/mnt/c/などのWindowsのパスなども入っていたりしますが、\u0026lt;プロジェクトのディレクトリ\u0026gt;/.venv/binは見つかりません。\nここからはソースコードは読んでいないので憶測ですが、.git/hooks/pre-commitで呼び出されているpre-commitツール(Python製)は、設定ファイルで指定されたコマンド(blackなど)を、コマンドとして今の呼び出されたコンテキストで実行しているのではないかということです。 実際、ターミナル上でもsource .venv/bin/activateを実行していない状態だとコマンドが見つからないというエラーが出ました。\n対処方法は? ということで、今考えられる対処方法としては次の通りです。\n.git/hooks/pre-commitのスクリプトを修正して、\u0026lt;プロジェクトのディレクトリ\u0026gt;/.venv/binのパスを見えるようにする PyCharmで何かしらの設定を探す PyCharmではgit操作しない repo:localはあきらめて、.pre-commit-config.yamlでblackなどは管理して、pyproject.tomlからは除外する 1.ですが、.git/hooks/pre-commitはprecommit intallを実行すると自動で生成されるスクリプトです。自分の環境で書き換えたとしても他の人が同じ環境を作るときにパッチを当てるなどをしないといけなくなります。\n2.はそれらしい設定を見つけることができませんでした。\n3.はめんどくさいですよね。。。ターミナルでgitのコメントを日本語で書くためにいくつか他の設定を考えないといけないです。。。\nということで、今回は4.の対処をとりました。やりたいことは、ツールや環境をそろえるのではなく、プロジェクトでやりたいことをやることなので。。。\nまとめ 最終的には元に戻ってしまいました(pyproject.tomlに設定周りは移動した)。 Windows環境がちょっとややこしくしてるかもな?というのと、個人のプロジェクトなのでそこまで気にしなくてもいいのでは?というのもありそうです。 それにしても、世の中の皆さんはフォーマッターとかどのタイミングで動かしてるんだろう?とかどういう環境構築してるんだろう?とか気になってます。 最近だとこういうディレクトリ構造にする、こういうツールを使うと便利などあれば、コメントいただけると嬉しいです。\n教えてもらったISIDのブログ(Dev Containerを使ってステップバイステップで作るPythonアプリケーション開発環境 - ISID テックブログ)も参考にさせてもらおうと思ってるところです。Pythonの環境をコンテナに移動したいなぁというのもあるので。ただ、PyCharmだからこのブログの通りには行かないけど(VS Codeに移るのも検討したほうがいいのかなぁ)。\n参考サイト Git - Git フック pre-commit Pythonレポジトリ用のpre-commit環境を整える Dev Containerを使ってステップバイステップで作るPythonアプリケーション開発環境 - ISID テックブログ ","date":1688954148,"dir":"post/2023/","id":"698cf3cbd796161d82c9ac438ebab5d2","lang":"ja","lastmod":1688954148,"permalink":"https://blog.johtani.info/blog/2023/07/10/pre-commit-and-python/","publishdate":"2023-07-10T10:55:48+09:00","summary":"最近、趣味(検索エンジンに関する趣味プロジェクト)でPythonのプログラムを書き始めました。 きちんとPythonのプログラムをプロジェクト","tags":["python"],"title":"pre-commitとvenvとPyCharm(困ったな?)"},{"contents":"今年もこの季節がやってきました。 Berlin Buzzwordsにオンラインで出張してました。 今年もハイブリッド開催をしてくれたので、オンラインで参加できました。 現地ではブースが出たり、朝食なども用意されているようでした。今年は昨年と違いマスク必須でもなくなったようです。 MICESも去年同様、現地開催のみのようです(今見たら、昨年のビデオとスライドが公開されてるので、時間見つけてみてみよう)。\n今年はうれしいことに検索に絡むセッションが大多数でした。世の中的にChatGPTの盛り上がりやベクトル検索がいろんな検索エンジンで使えるようになってきたこともあり、 大規模言語モデルと検索エンジン、ベクトルデータベースに関する話がたくさんありました(昨年まではKafkaやストリーム処理の話も多かったんですが)。\nということで、今年もセッションを見ながら残したメモを公開しておきます。\n簡単にメモ What defines the “open” in “open AI”? セッションページ:What defines the “open” in “open AI”? 動画: Jennifer Ding - What defines the \u0026ldquo;open\u0026rdquo; in \u0026ldquo;open AI\u0026rdquo;? - YouTube \u0026ldquo;OpenAI\u0026quot;の話ではなく、オープンなAIとは?という話で、ライセンスの話であったり、コミュニティ(データセットの公開とかベンチマークの共有とか)に関する話であったり。 後半は気を抜いてしまって話をうまく聞き取れてないので、興味がある方はビデオで。。。\nVectorize Your Open Source Search Engine セッションページ:Vectorize Your Open Source Search Engine 動画: Atita Arora - Vectorize Your Open Source Search Engine - YouTube ベクトル検索が流行ってきてるけど、これまでの検索(エンジン)に対して、どうやってベクトル検索を取り入れる?という話です。 ベクトル検索ってどんなもので、どういうことの助けになりそうか?じゃあ、どうやって、これまでの検索が改善したかを見ていくのか? という、これからベクトル検索を取り入れようとしている時にどのようなアーキテクチャにして、 どのような考慮するポイント(モデルの選択とかスケーラビリティとか)にどんなものがあるのか?といった紹介でした。 ざっくりですが、ベクトル検索やるのにどんなことをやっていけばよいのか?という地図になるようなセッションでした。\nSupercharging your transformers with synthetic query generation and lexical search セッションページ: Supercharging your transformers with synthetic query generation and lexical search 動画: Milind Shyani - Supercharging your transformers with synthetic query generation and lexical search - YouTube AWSの人の話でした。こちらもトランスフォーマーが検索に使えると便利だよねという話なのですが。 LLMを使うと高コストでサイズがどんどん大きくなっていて、小さな学習済みのモデルだといまいちな精度でだし、 ファインチューニングしたい場合、ドメインに特化したデータはなかなかないよね。とくにデータ(検索したいもの)はあるけど、クエリがないということがよくあるよね。 そこで、LLMを使って、データからクエリを作って、正解データを作り、それでファインチューニングすればいいのでは? ということで、やってみました、どうでしたという話でした。\nブログなどもあるので参考にすると面白いかも\nThe Debate Returns (with more vectors) Which Search Engine? セッションページ:The Debate Returns (with more vectors) Which Search Engine? 動画:Charlie Hull - The Debate Returns (with more vectors) Which Search Engine? - YouTube 今年も検索エンジンの人を集めてパネルディスカッションです。今年は次の方たちが参加してディスカッションでした。\n参加者 Jo:Vespaの人。ランキングとかがよくできてるからVespa好き Alessandro:Apache Solrの人。SolrのPMCメンバー。なんでSolr?Pure OSSだし。スケーラブルだ Etienne:Weaviateの人。新しいAI nativeなベクトルデータベース Philipp:Elasticの人。 Kacper:Qdrantの人。 質問は次のようなものでした。\n最初の質問:スケールの話。スケールアウトかな? 2つ目の質問:どんなアプリケーションが適していないか? 3つ目の質問:どうやってAIをサポートできるの? 4つ目の質問:どうやってコミュニティにアプローチしてる? 5つ目の質問:自分の検索エンジンが使えない時に何を使う? 6つ目の質問:今後に何が面白そう? 最後の質問:あなたの検索エンジンが使われてるユースケースで一番好きなものは? 2つ目や5つ目の質問が面白いですよね。実際の内容はぜひビデオを見ていただくのがいいかと(メモも取ったけど、聞いてもらうほうが面白そうだし)。\nWhat\u0026rsquo;s coming next with Apache Lucene? セッションページ:What\u0026rsquo;s coming next with Apache Lucene? 動画:Uwe Schindler - What\u0026rsquo;s coming next with Apache Lucene? - YouTube 毎年恒例Uweさん。今年Luceneが25周年という話で、これまでの進化の話を駆け足でしてくれました。 あとは、後半は来週9.7が出るよということで、9.7で入ってくるベクトルの距離計算の最適化に関して説明してくれています。 次のバージョンのElasticsearchでもこの最適化が使えるようになるという話もされていましたので、ベクトル検索を使ってる方は、次のバージョンも楽しみですね。\nBuilding MLOps Infrastructure at Japan\u0026rsquo;s Largest C2C E-Commerce Site セッションページ:Building MLOps Infrastructure at Japan\u0026rsquo;s Largest C2C E-Commerce Site 動画:Berlin Buzzwords 2023: Building MLOps Infrastructure at Japan\u0026rsquo;s Largest C2C E-Commerce Site - YouTube メルカリの検索システムに関係しているMLOps周りがどうやって進化してきたのか?という話でした。 英語にいらすとやの絵があるスライドがドイツで使われているのがとても新鮮ですw\nHighly Available Search at Shopify セッションページ:Highly Available Search at Shopify 動画:Khosrow Ebrahimpour - Highly Available Search at Shopify - YouTube Shopifyの検索プラットフォームチームの人の、Shopifyの検索プラットフォームがどういったものか?(EsとKafka使ってる)どんな工夫をしているか?という話です。 Kubeconでも他の同僚の方が話をされている見たいで、そちらも参考になるとのことでした(動画)。 スキーマ変更時の話とかもあり、実践的でした。最後に将来的な話でやはりベクトル検索というキーワードが出てきていました。あとは、データ量が大きいのでスケーリングの挑戦もあるとのこと。\nUsing Dense Vector search at the EU Publications Office セッションページ:Using Dense Vector search at the EU Publications Office 動画:Martin Bayton - Using Dense Vector search at the EU Publications Office - YouTube EUのPublication Office(日本だと公文書館とかになるのかなぁ?)の検索サービスで、Googleみたいなこと(検索結果の上にスニペットが出たり、そこにハイライトされたり)をやってみたいよね?という話みたいでした。実際公開してるかはわからないですが、途中からはPureinsightsという会社のプラットフォームで似たようなことをやるデモになってました。\nGoogleでも12%のクエリが、質問の自然文になっているという話で、検索結果にナレッジグラフからの情報(スニペットとか、質問に対する答えとか、地図とか)が出るようになってきていますと。 それをPublication Officeのデータで再現したデモを行った後に、どんな感じのアーキテクチャなのか?という概略を説明されています。国会図書館とかの検索サービスやってる方が興味を持ったりするかもなーと思ったり、思わなかったり?\nLearning to hybrid search セッションページ:Learning to hybrid search 動画:Berlin Buzzwords 2023: Learning to hybrid search - YouTube これまたキーワード検索とセマンティック検索のハイブリッドの話です。 よくハイブリッド検索というのを聞きますが、データだったりベンチマークなどの話があまりないですよね?昨年AmazonがECSIというデータセットを公開したりしています(rejasupotaroさんが年末に書かれた記事にも出てきていました)。 これにLearn to Rankとかもテストできるようなデータ(レビューや評価、カテゴリーとか)を拡張したものを作って、それをもとにいろいろとハイブリッド検索で精度を測ってみたというお話でした。 Metarankというリランキングエンジンの会社の方たちで、Metarankを使ってハイブリッドな検索結果のリランキングで精度がどのように上げられるか?という話です。 今年のTRECのProduct Search Trackの話もされていました。 これが元ネタのブログかな?\nCatch the fraud — with observability and analytics セッションページ:Catch the fraud — with observability and analytics 動画:まだ? 最後は元同僚のセッションです。こちらは検索ではなく、ちょっと自虐的なネタをもとにしたオブザバビリティおよび分析のお話です。 コミュニティの人たちの貢献(ブログ書いたりプルリク送ったり、どこかで話をしたり)を計測して、年間の貢献者に対してプレゼントを上げるというのをやっているみたいです。 で、昨年の最も貢献した人にMac Bookをプレゼントするというすばらしい(暴挙)話で、チートしようとした人がいてそれを分析した話でしたw 締め切り直前に信じられない量の貢献したという登録がブラジルからあり、何かおかしいよね?ということで、Elastic Stackのオブザバビリティの機能などを元に分析してチートした人を除外していったよという話でした。 Kibanaが使いやすくなってるのがわかるセッションで面白かったです。\nまとめ 検索がまたすごく盛り上がってきたなーという時間があるカンファレンスでした。みんな似たような話(ベクトル検索、LLM、AIなど)だったりしますが、 知らないプロダクトで興味が出てくるものもあったし、Amazonのデータセットがあるからいろいろ試してみることもできそうだなぁと。\nすでにビデオが公開されはじめているので、気になったセッションのビデオも見てから後日またブログを書こうとおもいます (たぶん、一覧が作成されるので後日リンクを貼っておきます)。\n来年の予定(6月11日から開催)も公開されていましたし。来年も楽しみですね。 来年はプロダクションでベクトル検索やってみた話とかがさらに出てくるのかなぁ?\n","date":1687278645,"dir":"post/2023/","id":"9335522f4c8dbc7256a42a091e6e00bc","lang":"ja","lastmod":1687278645,"permalink":"https://blog.johtani.info/blog/2023/06/21/attend-berlin-buzzwords-2023/","publishdate":"2023-06-21T01:30:45+09:00","summary":"今年もこの季節がやってきました。 Berlin Buzzwordsにオンラインで出張してました。 今年もハイブリッド開催をしてくれたので、オンラインで参加で","tags":["conference","belin buzzwords"],"title":"今年もオンラインでBerlin Buzzwordsに参加した"},{"contents":"今年もなんとか振り返りブログを書いてます(時間大丈夫かな?w)。紅白をリアタイで見ながら。\n振り返り(2021年に書いた抱負から) まずは振り返りをと。\nフリーランス継続 ありがたいことに個人事業主として今年も1年乗り越えられました。 ZOZOさんには引き続きお世話になっている感じです。 10月からは今月末まで別のお客さんを手伝っていたりという感じでした(アップグレードの手伝いとか)。 相変わらず完全リモートで作業をさせていただいてます。\nただ、来年は今の所、余力がある感じになっているので、新しい仕事を見つけたいところだなあという感じです。 検索で何かお手伝いできることあれば、気軽にお声がけいただければと。\nプログラミング Linderaの大須賀さんのおかげで、レビューは定期的にやらせていただいてますw 業務がっつりというほどではないのですが、検証用のコードを書いたりはしています。\n個人用では、BGM環境のためにシェルを書いたり、文字化けしてるデータを解析したりするのにコードを書いてますが、もうちょっと量を増やしたいところです。 コードがっつり書く仕事をやらせてもらうのとかやらせてもらうのがいいかもなぁ。\n書くよりもどうしても読むほうが多くなってる気がします。\nブッチャー本ちゃんと読む 全部ではないですが、ZOZOさんで輪読をしたりしていました。 が、自分で全部読むといったところまではできてないです。\n読んだ本のブログを書く これはできてないですね。 読むのはちょとちゃってるんですが、ブログを書くところまではできてない。 メモとりながら読みたいですね。\n振り返り(今年あったできごと) ここからは今年の出来事を。 今年もずっと自宅で仕事した。来年は出張とかできるのかなあ?\n自宅環境 今年もDIY 検索ペンギン本が出版された 仕事場を模様替えしました。 今年もずっとWindows環境をメインで仕事をしていました。 年末まではM1 Macを借りて作業するという経験もできたのでよかったです。 今年仕事の環境は少し変わって、AVアンプ(譲り受けたもの)+Polk Audioのスピーカーで音が良くなりましたw あと、机の天板を大きくして、作業がやりやすくなりました。写真はそのうち。\n仕事場の模様替えにもなるのですが、今年のDIYはラブリコ+有孔ボードでケーブルやキーボードをすっきり片付けられる環境を作ってみました。 壁を有効活用できるのはよかったです。こちらについては、別途ブログを書こうと思います。\n今年最大のニュースは検索ペンギン本を出版したことです。 声をかけていただいた打田さんには感謝です。著者の皆さん検索システムを色々と手掛けられているので良い本になったと思います。\n『検索システム ― 実務者のための開発改善ガイドブック』 – 技術書出版と販売のラムダノート おー、届いたー pic.twitter.com/RbY5tOe9GB\n\u0026mdash; Jun Ohtani (@johtani) May 17, 2022 いろんなところで輪読も開催されているようで、顔を出してみたいなぁ。 輪読やってます!外部の人を呼んでもOKという方がいたら、参加してみたいのでTwitterでメンションしてもらえると嬉しいです。\n来年の抱負 ということで、来年の抱負です。\nフリーランス継続 プログラミング ベクトル検索まわりをさわる 本を読む 今年もありがたいことに仕事を継続していただけて、乗り越えられました。 来年も価値を提供できるように頑張っていきます。 もっといろんな会社の検索システムを見てみたいですし、検索エンジン入れてみたけどここからどうすればいい?という方も増えて来ているような気がするので、気軽に声をかけていただければと。\nプログラミングは、家の音楽ファイルの文字化けを直すプログラムをもう少しちゃんと書いてからブログを書きたいなと。まぁ、個人的なプログラムなので誰も嬉しくないかもですが(色々検討した結果Javaで書いてる)。 あとは、オライリーさんの初めてのGo言語を買ったのもあるので、前にRustで書いたElasticsearchへのBulk登録のツールをGoで書いてみようかなと考えているところです。みんなはデータ登録するときはどうしてるんだろう?\nNLPでBERTなどによる目まぐるしい進歩の影響もあり、ベクトル検索やセマンティック検索といった検索技術が各社から出て来ています。 ElasticsearchでもGAされたのもあり、今後ますます注目を浴びる技術になるのだろうなと。 ただ、これまでの検索とどう組み合わせるのがいいのか?どう言ったメリットデメリットがあるのか?向き不向きは?といったものもあるので、仕組みを調べながら色々と試行錯誤してみたいと思っています。\nさいごは、毎年書いてる気もしますが、本を読むのもやらんとなぁ。 あたらしいネタを仕入れては実践できる時間もとりつつ、他のことにも目を向けたいと思っています。\n今年は仕事の変化も少し出て来ているので、来年は新しいことをいくつかやってみたいところです。 あとは、外に出る機会が増やせるといいなぁ、少しずつ人から刺激をもらいたいと思っています。\nさて、今年は年内に無事描き終わりました。 来年もよろしくお願いいたします、良い年にしたいなー。\n","date":1672486684,"dir":"post/2022/","id":"df30d810068e4656498e5972c6de7e3d","lang":"ja","lastmod":1672486684,"permalink":"https://blog.johtani.info/blog/2022/12/31/review-2022/","publishdate":"2022-12-31T20:38:04+09:00","summary":"今年もなんとか振り返りブログを書いてます(時間大丈夫かな?w)。紅白をリアタイで見ながら。 振り返り(2021年に書いた抱負から) まずは振り返","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2022)"},{"contents":"PySpaアドベントカレンダーの12/15のエントリーです。昨日はtaichiさんでした。 今年はDIYではなく、PCにまつわる話を。\n仕事中はBGMが基本 フリーランスを始めて(2020年初頭)からすぐに、自宅で仕事をする情勢になりました。 打合せをしていないとき、カンファレンスの発表などの動画を見ていないときは基本的にBGMをかけて作業をしています。 音源としては、CDなどから音楽ファイルにしたり、AmazonやSonyのサイトで購入した音楽ファイルなどがNASにあります。\n今年10月までの環境 2020年の後半に次のような環境を構築して今年の10月まで使っていました。\nLibreELECをラズパイ4に入れて、Kodiのリモコンをスマホに入れたら快適になった\n\u0026mdash; Jun Ohtani (@johtani) October 20, 2020 KODIと呼ばれるマルチメディアセンター?のようなソフトで、それを動かす最小限のOSとして、LibreELECが公開されています。 これをラズパイ4に入れて、NASからファイルをSSDにコピーしてそれをラズパイに接続して音楽を聞いていました。 毎回ラズパイの画面を見に行くのも面倒なので、再生などの操作にはAndroid用のKodiのリモコンアプリを使っていました。\n場所も取らないのでよかったのですが、使っているといくつか問題点が。\n時々調子悪(音が出ない、リモコンからつながらない、無反応など)くなって、ラズパイ再起動 音楽ファイルを購入して増えた時に、外付けSSDを取り外してPCでコピーしたり スマホじゃないと再生できない(PCのクライアントもあったのかもだけど調べてなかった) Ubuntu on Mac mini 10月に模様替えをして、2012年製のMac Miniが宙ぶらりんになりました。 さすがに古いしメインマシンがWindowsになっているのもあり、macOSである必要も特にないので、Ubuntu 22.04を入れて何かに使えるのでは?と。 また、1TBのSSDに内臓ディスクを乗せ換えていたのもあり、音楽再生に使ってみようということに。 なので、Kodiの環境で困っていた点も考慮して、ほしい機能を元にちょっと探してみました。\n音楽再生 on Ubuntu 音楽再生でほしい要件としては次のようなものです。\nUbuntuで音楽再生できるソフト(あたりまえ) PCから操作したい(できればブラウザ) 音楽ファイルの更新(ローカルでもいいけどNASからもってきたり) 日本語の曲情報も表示 対象音楽ファイルが豊富(そんなに制限があるものはないだろうなぁ) 上記の要件をもとに適当にググって見つけてきたのがOwnToneというソフトでした。\nOwnTone OwnToneの説明は公式サイトを見ていただくとして、OwnToneにしてよかったなというのが以下の点です。\nインストールが簡単(apt-getでインストールできる) サポートフォーマットが豊富 Web UIがついてる(ブラウザで見えるし、スマホでもOK。どのブラウザから見ても今の状況も分かる) 簡単だけど検索できる プレイリスト対応(ファイルパスを入れるだけ) サムネイルとかも出てくる(どうやってんだろう?w) AirPlayで再生できる(AVアンプを利用しており、そこにAirPlayで再生できてる) OSS(まだソースは見たことないですがw) 再生画面例\nやっぱ検索も気になるよね?\n日本語も検索できるな。 pic.twitter.com/EF6WHkJKli\n\u0026mdash; Jun Ohtani (@johtani) October 19, 2022 とりあえず、インストールして画面もすぐに出て操作も簡単で、便利な世の中になったなーと感動しましたw\nただ、音がヘッドフォン端子に刺したアナログ出力先のスピーカーではなく、本体のスピーカーで最初はなってしまいましたww Linuxの音周りが全然わかってない問題が発覚。\n幸い、先週のPyspa Advent Calendarのエントリーを書いていたaodag先生に助言をいただき、alsamixerで音の設定を見たところ、ヘッドフォン端子がミュートされていたので、ミュートを外して無事再生できました。 インストール当初はYAMAHAのアクティブスピーカーにJust Mixer経由でヘッドフォン端子(アナログ)で出力して音楽再生をしていました。 今は(この記事を書いてる現時点で)、AVアンプのAirPlayにOwnToneから音を流している形で聞いています(便利なんだけど、当初の想定とは異なる、理由は後述)。\nファイルのコピーとか さて、上にも書きましたが、NASにバックアップもかねて音楽ファイルを保存してあります。 新しく買ったファイルもここに置くようになっています。 OwnToneのMac MiniからNASをネットワーク経由で見に行くのもいいのですが、できればローカルにあったほうがネットに影響も出ないなと。\nということで、定期的にNASをウォッチしてMac Miniにファイルをコピーするようなプログラム(Bashスクリプト)を書いてみました。 毎回購入後に手で実行もめんどくさいので毎日夜中にcron実行するような設定になっています。\nスクリプトの中身は次のような感じです。\nfindコマンドで特定の日時(最近コピーしたファイルの日付)以降(-newermtオプション)のファイルのリスト(音楽ファイルの拡張子に限定)を取得 取得したリストをもとに以下の操作 ファイルをコピー コピーしたファイルをコピーした日付のプレイリストを作って入れる(プレイリストはパスだけ書けばOK) mp4形式だと聞けない端末もあるので、soundconverterコマンドでmp3に変換してNASに戻す 最新のファイルの日付を保存(次回のfindコマンド) ファイルがあったら、OwnToneの再読み込みのエンドポイントをcurlでキック NASはSambaでマウントして、見えるようにしてあります。 やっぱり、自動化便利ですねぇ。 気に入った曲を買ってNASに入れとけば聞けるようになるのは本当に便利。\n他にもスマートプレイリストとかもあるので、活用しないとな。\n今後の課題 さて、すごく便利になったのですが、課題も残っています。\n音声出力問題 アナログ出力はaodag先生の助言ですぐに解決したのですが、takabowから譲り受けたAVアンプを導入してから実は音の出力がうまくいっていません。\nHDMI、光端子出力でAVアンプにつなごうとしたのですが、私のUbuntu力(Linux力?)が全然不足しているのでうまくいっていません。ググりつつ、HDMI、光出力でamixerというコマンドで音声ファイルを鳴らすところまでは行ったのですが、OwnToneに設定するとうまくいかない状況です。 結局、解決してないのですが、AVアンプのAirPlayのレシーバー経由で音楽再生ができてしまったので、とりあえずAirPlayで運用することにしました。時間を見つけてaodag先生の記事を読み直して再チャレンジしないとな(けど、鳴ってるしなぁ、音w)。\n文字化け問題 これは、OwnToneというよりはもともとあった問題です。 古い音楽ファイルだったり、Wav形式のファイルなど、様々な形式のファイルを持っています。 音楽サーバーとは別に、音楽ファイルの検索をできるようにしつつ、付加的な情報(Wikimediaなどのデータとか)を付与して、検索できるようにしてみようと思い、音楽ファイルからメタデータを抜き出して、ElasticのApp Searchにいれるデータを作るツールを書いたりしています。 この時にも文字化けに遭遇しました。\n様々な音楽ファイルにはメタデータを付与することができる仕様が決まっています(ID3タグ - Wikipediaなど)。 ただ、文字コードの情報が入っていなかったり、デフォルトとは違う文字コードでデータを付与したファイルがあったり、いろいろな原因で文字化けしているものがあります。 昨年Amazonで購入したmp3の中にも文字化けしているものもあったりします。Wavファイルに付与されたタグなどは、容赦なくShift-JISだったりしますが、読み込むソフトはUTF-8で読もうとしたり。。。\n検索サーバーにデータを抜き出して入れるツールを書いているときは、元のファイルを変更することなく、抜き出す時点でいくつかの文字化けに対応した処理を書いたのですが、今回のOwnToneで曲を流すと結局、元のファイルをきれいにしないとダメだということに気づきました(すぐわかるだろ。。。)\nということで、書いている途中のツールをもとに、根本的な文字化けのファイルのメタデータをきれいにするプログラムを書かないといけないなぁと。\nちなみに、メタデータの抜き出しにはJavaでプログラムを書いており、JAudiotaggerというライブラリを利用しています。 Pythonや他のJavaのライブラリを試そうとしたのですが、文字コードが決め打ちで抜かれているものが多く、ライブラリから読みだした時点ですでにどうしようもない状態のものが多いといった問題からこのライブラリにたどり着きました(まぁ、まだちゃんとしたものができていないんですけどね)。\n検索サーバー OwnToneのUIはブラウザでうごきます。 検索窓もついています。 が、先ほども書いたように、他にもデータを追加して、いろんな検索をしてみたいなぁと(ドラマに使われてたとか、CMにつかわれてたとかとか)。 検索が好きでいろいろとやってるので、その辺も遊んでみたいなぁと思っているところです(実際、ElasticのApp SearchにWikidataから生成した類義語を入れてみたりしている)。\nこうやってブログにしてしまったので、課題をつぶしていなかったら、Twitterなどでつついてくださいw\nまとめ 構成図とかは書かなかったですが、OwnToneを使うと簡単にWeb UIが入った音楽サーバーが使えるようになって、仕事がはかどりますよという記事でした。 他にもこれに関するネタを募集してますので、コメントもらえるとうれしいです(Twitterでメンションも大歓迎)。\n","date":1671030358,"dir":"post/2022/","id":"67c2ae6761e89be0fa66db9623b40d30","lang":"ja","lastmod":1671030358,"permalink":"https://blog.johtani.info/blog/2022/12/15/music-server-on-mac-mini/","publishdate":"2022-12-15T00:05:58+09:00","summary":"PySpaアドベントカレンダーの12/15のエントリーです。昨日はtaichiさんでした。 今年はDIYではなく、PCにまつわる話を。 仕事中は","tags":["misc","music"],"title":"仕事中のBGM環境"},{"contents":"本記事は情報検索・検索技術 Advent Calendar 2022の9日目の記事です。\nだいぶ間が空いてしまいましたが、日本語のオートコンプリートに関する記事の続きです。 という感じで、Suggesterのデータ構造とか仕組みを書こうと思っていたのですが、思ったよりも調べないといけないことが多くて挫折しました。。。 (これの続きは年末年始で調べて書くはず?)\nということで、代わりにElasticsearch/OpenSearchのアーキテクチャの変更に関してさらっとまとめてお茶を濁してみようと思います。\n発端はElasticON Tokyo? 先週の11月30日に、ElasticのオフラインイベントであるElasticON Tokyoが開催され参加しました。 参加しようと思ったのは、10月の頭にElasticのブログで公開された「Stateless — your new state of find with Elasticsearch」というアーキテクチャの変更がきっかけです。\n(図はElasticのブログから引用)\nElasticsearchはLuceneのインデックスを分散したシステムとしてスケールアウトできるようにするという目的でリリースされました。 インデックスをシャードという単位で複数のElasticsearchのノードにデータを保存し、レプリカを作ることで分散する仕組みを実装していました。 Elasticsearchでは、インデックスのレプリカは、作成したインデックスを定期的にコピーするのではなく、登録するデータがElasticsearchのクラスターにやってきた時に、 データ自体をコピー先にも配り、プライマリーやレプリカとなるシャードがあるノード上でそれぞれインデックスに登録する処理を行うという処理の流れです(古いけど、わかりやすい説明はこちら)。 この場合、インデックスにデータを登録する処理(転置インデックスのデータ構造に変換する処理など)は、レプリカの数だけ同じ処理がクラスター上で発生します。\nこの基本的なアーキテクチャをもとに、保持するデータの鮮度(新しいデータのほうが検索頻度が高い、インデックス登録する時はマシンは多く、古くなったデータが入ったインデックスはコストが低いマシンになど)などを元に、クラスター内のノードの特性を異なるものが混在するような複雑な仕組みを作ってきました。 いろいろなデータの持ち方などで多くのデータなどを保持できるようにしてきたのですが、クラスター全体としては、検索の負荷のピークをさばけるような構成を基本的に保持しておくというかんがえです。\nただ、昨今は必要に応じてスケールアウト(リクエストが増えたりデータ量が増えた時)、スケールイン(夜中は利用者が少ないからクラスターを小さくしたい時)できるような仕組みのほうが求められています。 そこで、発表されたのが上記のブログであり、上図の新しいアーキテクチャです。 計算処理(データを登録、検索する処理)とストレージを分離し、さらに登録する処理と検索する処理も分離した構成です。 このようなアーキテクチャにすることで、登録処理の演算コストがレプリカごとに必要ではなくなり、検索の部分だけだったり、登録の部分だけをスケールアウト・インできるような自由度が手に入ります。 また、ストレージ部分でレプリカを担保(S3とかのオブジェクトストレージで冗長性を担保)できれば、レプリカのストレージコストも必要なくなります。\nというブログが発表されたのですが、詳細などはまだよくわからなかったのでElasticON Tokyoに参加して詳しい話が聞けるのかなぁと期待していました。\n参加当日の朝のびっくりするニュース 11月30日の朝に起きて、出かけようかと思っていたところに、AWSのre:Inventで発表されたニュースが舞い込んできました。\nほー(まだタイトルしか読んでない)https://t.co/KK22duaBNH\n\u0026mdash; Jun Ohtani (@johtani) November 29, 2022 Amazon OpenSearchがServerlessオプションを発表というニュースです。 (Amazon OpenSearchとは、AWSがElasticsearchをフォークして始めた検索エンジンで、Amazon OpenSearch Serviceというのは、AWSがそれをSaaSとして提供しているものです)\nまぁ、気になりますよね、「Serverless」ってキーワードに。 ElasticON Tokyoに向かう電車でブログを読んだり、どんな仕組みかを調べたので、それを簡単にまとめておきます。\nプレビュー段階(Tokyoリージョンではもう試せる) これまでのAmazon OpenSearch Serviceとは別(オンザフライで移行はできない?) 「コレクション」という単位でクラスターを管理(スケールインとかアウトとか) コレクションにはタイプがあり、タイムシリーズ(ログとか)か検索のユースケースなのかで使い分ける(公式ドキュメント) インデックス処理と検索処理で計算ユニット(OCU)が別々にスケールできる(下図) 作成されたインデックスはAmazon S3に保存され、そこで冗長性は担保される。(下図) 検索処理のユニットはS3のデータをローカルに持ってきて処理をできる データ登録とかのAPIは基本的にServerlessかどうかで違いはなさそう(これまで通りのクライアントでアクセスとかで競う) 設定した範囲でいいかんじにスケールアウトインしてくれそう(ほんとかな?) もちろん、いくつか制限がある(サポートしてないプラグインとか操作もある) (図はAWSのドキュメントより引用)\n発表時のブログでは詳しくはわからないのですが、公式ドキュメントではさらに詳しく説明がありました。 こちらを読むほうが仕組みがわかると思います。 今後もどんどんドキュメントは充実していくんだろうなと。今ならまだサクッと読める量ですw\nただ、「サーバーレス」という定義が私はよくわかりませんでした。 公式ドキュメントを読むとコレクションを作ると少なくとも4つのOCUが起動しているみたいで課金されると記載があります。\nまぁ、Elasticの発表と同様に、これまでは最大負荷の時を元にクラスターを維持せずとも、より柔軟に検索だけ、登録処理だけを一時的にスケールできるとコストを下げられそうですね。 すぐに誰かが使ってみたブログなどを出してくれると思うので、細かな使用感などはそのうちわかってくるかと。\n今後は? ElasticもAWSも考え方の基本となっているのは、Berlin BuzzwordsでAmazonのMikeさん(Luceneのコミッター)が2019年に発表されたものだと思っています。 アーキテクチャの変更がどんな影響が出るかはわからないですが、少なくとも検索のユースケースでよりスケールアウトしやすくなるだろうなと。 どちらもSaaSとしての仕組みとして提供するので、検索エンジンそのものの機能として公開されるかはわからないです。 ですが、そのほかの検索エンジンも出てきていますし、今後も検索エンジンから目をはなせないです。 今回は残念ながら触っていませんが、時間を見つけて使ってみたいです(Elasticも早く出してくれないかなー)\nということで、当初の予定とは違うブログになってしまいました。。。 技術的な深い話はまたどこかで。。。\n参考文献 Stateless — your new state of find with Elasticsearch | Elastic Blog Preview: Amazon OpenSearch Serverless – Run Search and Analytics Workloads without Managing Clusters | AWS News Blog Berlin Buzzwords 2019: Michael Sokolov \u0026amp; Mike McCandless–E-Commerce search at scale on Apache Lucene - YouTube ","date":1670516125,"dir":"post/2022/","id":"9693a1e77dee5785b1dc61ccffd2e906","lang":"ja","lastmod":1670516125,"permalink":"https://blog.johtani.info/blog/2022/12/09/open-search-serverless/","publishdate":"2022-12-09T01:15:25+09:00","summary":"本記事は情報検索・検索技術 Advent Calendar 2022の9日目の記事です。 だいぶ間が空いてしまいましたが、日本語のオートコンプリートに関する記事の続きです。","tags":["elasticsearch","opensearch"],"title":"ElasticsearchのアーキテクチャとStateless / Serverless"},{"contents":"前回は日本語用オートコンプリートのためのAnalyzerとして、どうやって使うのかを簡単に紹介しました。\n今回はもう少し、いろんなパターンを試してみたいと思います。\nローマ字入力のゆれ 前回のサンプルでも「吾輩\u0026hellip;」のデータをサジェストするためのサンプルとして、「wagah」という「わがはい」をローマ字にしたものを利用しました。\nちなみにローマ字というとどんなものを思い起こしますか? 普通は学校で習ったヘボン式あたりだと思います。 Kuromojiの読みでローマ字出力するには通常、kuromoji_readingformでuse_romajiをtrueにします。 以下、「吾輩」のサンプルです。\nGET _analyze { \u0026#34;text\u0026#34;: [\u0026#34;吾輩\u0026#34;], \u0026#34;tokenizer\u0026#34;: \u0026#34;kuromoji_tokenizer\u0026#34;, \u0026#34;filter\u0026#34;: [ { \u0026#34;type\u0026#34;: \u0026#34;kuromoji_readingform\u0026#34;, \u0026#34;use_romaji\u0026#34;: true } ] } レスポンス { \u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;wagahai\u0026#34;, \u0026#34;start_offset\u0026#34;: 0, \u0026#34;end_offset\u0026#34;: 2, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 0 } ] } 「吾輩」の場合は特に問題ないのですが、ローマ字による日本語入力の場合、次のような単語を入力するときに、ゆれが生じます。\nシャボン=「shabon」 新橋=「shimbashi」 括弧内はkuromoji_readingformで出力したもの(=ヘボン式のローマ字)です。 ですが、ローマ字入力の場合は「syabon」や「shabon」と入力したり、「sinbasi」や「sinnbasi」と入力すると思います。 JapaneseCompletionAnalyzerを利用したCompletion Suggesterの場合、これらのゆれも考慮してサジェストしてくれるようになっています。 前回のサンプルデータを用いると次のような感じです。\nGET aozora_index/_search { \u0026#34;explain\u0026#34;: true, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: { \u0026#34;prefix\u0026#34;: \u0026#34;sha\u0026#34;, \u0026#34;completion\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;suggest_ja\u0026#34; } } } } GET aozora_index/_search { \u0026#34;explain\u0026#34;: true, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: { \u0026#34;prefix\u0026#34;: \u0026#34;sya\u0026#34;, \u0026#34;completion\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;suggest_ja\u0026#34; } } } } これらのリクエストは、「しゃ」について2パターンになっていますが、結果はどちらも次のものが返ってきます(このレスはsyaのレスになります)。\n{ \u0026#34;took\u0026#34;: 1, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;sya\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 3, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;シャドウ・ワーク\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;000739\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;シャドウ・ワーク\u0026#34;, \u0026#34;朝倉 克彦\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;シャボン玉\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;045054\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;シャボン玉\u0026#34;, \u0026#34;豊島 与志雄\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;上海\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;050899\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;上海\u0026#34;, \u0026#34;横光 利一\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;斜坑\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;002095\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;斜坑\u0026#34;, \u0026#34;夢野 久作\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;社会事情と科学的精神\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;053864\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;社会事情と科学的精神\u0026#34;, \u0026#34;石原 純\u0026#34; ] } } ] } ] } } 「sinnba」や「shinba」も試してみました。\nGET aozora_index/_search { \u0026#34;explain\u0026#34;: true, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: { \u0026#34;prefix\u0026#34;: \u0026#34;sinnba\u0026#34;, \u0026#34;completion\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;suggest_ja\u0026#34; } } }, \u0026#34;_source\u0026#34;: [\u0026#34;suggest_ja\u0026#34;] } GET aozora_index/_search { \u0026#34;explain\u0026#34;: true, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: { \u0026#34;prefix\u0026#34;: \u0026#34;shinba\u0026#34;, \u0026#34;completion\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;suggest_ja\u0026#34; } } }, \u0026#34;_source\u0026#34;: [\u0026#34;suggest_ja\u0026#34;] } これらも同じ結果です。\n{ \u0026#34;took\u0026#34;: 0, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;shinba\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 6, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;しんばい\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;044942\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;しんばい\u0026#34;, \u0026#34;村山 籌子\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;新橋\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;002409\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;新橋\u0026#34;, \u0026#34;北原 白秋\u0026#34; ] } } ] } ] } } 入力されるパターンを想定した実装がされているので対応できている形です。 使い方が楽なだけでなく、より使いやすくなってるのは便利ですね。\nうまくいかないパターン 万事OKかというと残念ながらそうでもありません。 うまくいかないパターンもあります(これが本当にうまくいかないかは難しい話な気がしますが)。 「日本」という漢字ですが、「にほん」「にっぽん」どちらとも読めますよね? これらを試してみると次のようになります(リクエストは省略します)。\nまず「にほん」\n{ \u0026#34;took\u0026#34;: 0, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;にほん\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 3, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;日本橋\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;004565\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本橋\u0026#34;, \u0026#34;泉 鏡花\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本橋\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;045357\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本橋\u0026#34;, \u0026#34;牧野 信一\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本橋あたり\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;047648\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本橋あたり\u0026#34;, \u0026#34;長谷川 時雨\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本橋附近\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;055666\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本橋附近\u0026#34;, \u0026#34;田山 花袋\u0026#34; ] } } ] } ] } } 次に「にっぽん」\n{ \u0026#34;took\u0026#34;: 1, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;にっぽん\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 4, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;日本アルプスの五仙境\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;056269\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本アルプスの五仙境\u0026#34;, \u0026#34;木暮 理太郎\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本出版協会論\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;049436\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本出版協会論\u0026#34;, \u0026#34;嶋中 雄作\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本文化と科学的思想\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;055750\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本文化と科学的思想\u0026#34;, \u0026#34;石原 純\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本文化のために\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;003183\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本文化のために\u0026#34;, \u0026#34;宮本 百合子\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本文化の特殊性\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;055290\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本文化の特殊性\u0026#34;, \u0026#34;戸坂 潤\u0026#34; ] } } ] } ] } } 最後に「日本」\n{ \u0026#34;took\u0026#34;: 1, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;日本\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 2, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;日本アルプスの五仙境\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;056269\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本アルプスの五仙境\u0026#34;, \u0026#34;木暮 理太郎\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本出版協会論\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;049436\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本出版協会論\u0026#34;, \u0026#34;嶋中 雄作\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本文化とは何ぞや(其二)\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;002940\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本文化とは何ぞや(其二)\u0026#34;, \u0026#34;内藤 湖南\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本文化と科学的思想\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;055750\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本文化と科学的思想\u0026#34;, \u0026#34;石原 純\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本文化のために\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;003183\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本文化のために\u0026#34;, \u0026#34;宮本 百合子\u0026#34; ] } } ] } ] } } 最初の「にほん」は「日本橋」がヒットしているようです。返ってきたoptionsの数は4件しかなく、どうやらこれがすべてのようです(取得件数はデフォルト5件)。 2番目の「にっぽん」は「日本」という単語から始まるものがヒットしていますが、「日本橋」はなさそうでした。 最後に「日本」という漢字を入力にした場合は2つの合計が帰ってきているようです(今回のレスポンス例にはありませんが、サイズを大きくすると「日本橋」が帰ってきていました)。\nどうしてそうなるの? JapaneseCompletionAnalyzerの基本的な動作としては、\nKuromojiが単語に区切る 区切られた単語ごとに読みを持っている 元の単語と読みをローマ字にしたものが最終的に出てくる というような動きです。 この時、単語には「1つ」の読みが対応しています。 読みから単語を探そうとすると、読みの違い(ゆれ)を吸収することはできないためです。 JapaneseCompletionAanlyzerは3点目のローマ字のゆれに対応していますが、入力となる読みのゆれまでは対応できないです。 対応しているといいかどうかというのも難しい判断になる気もします。。。\nそのほかの例としては次のようなものもあります。 これは、今回のオートコンプリートの話とは少しずれてるかもしれませんが、1番目の処理の結果が変わってくる例です。 「南方熊楠」という名前の間にスペースがあるかないかで、出力される読みが変わってくる例です。\nGET _analyze { \u0026#34;text\u0026#34;: [\u0026#34;南方 熊楠\u0026#34;], \u0026#34;tokenizer\u0026#34;: \u0026#34;kuromoji_tokenizer\u0026#34;, \u0026#34;filter\u0026#34;: [\u0026#34;kuromoji_readingform\u0026#34;] } GET _analyze { \u0026#34;text\u0026#34;: [\u0026#34;南方熊楠\u0026#34;], \u0026#34;tokenizer\u0026#34;: \u0026#34;kuromoji_tokenizer\u0026#34;, \u0026#34;filter\u0026#34;: [\u0026#34;kuromoji_readingform\u0026#34;] } # GET _analyze { \u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;ナンポウ\u0026#34;, \u0026#34;start_offset\u0026#34;: 0, \u0026#34;end_offset\u0026#34;: 2, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 0 }, { \u0026#34;token\u0026#34;: \u0026#34;クマグス\u0026#34;, \u0026#34;start_offset\u0026#34;: 3, \u0026#34;end_offset\u0026#34;: 5, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 1 } ] } # GET _analyze { \u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;ミナカタ\u0026#34;, \u0026#34;start_offset\u0026#34;: 0, \u0026#34;end_offset\u0026#34;: 2, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 0 }, { \u0026#34;token\u0026#34;: \u0026#34;クマグス\u0026#34;, \u0026#34;start_offset\u0026#34;: 2, \u0026#34;end_offset\u0026#34;: 4, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 1 } ] } 人名や地名は1つの漢字に対して多くの読みが存在しているので大変です。。。 どうしてこれは出てこないんだろう?と不思議に思った場合は、_analyze APIを使ってどういう動きなのかを見てみるのがいいかと。\nまとめ ということで、少しだけですが、こんなことができるよ、できないよというのを書いてみました。 挙動をしっていれば、なんでこうなってるんだっけ?といったことを調べる役に立つかと思います。 入力された文字をもとにどれをサジェストするかなどについてはもう少し違う動きなので、中の仕組みをそろそろ書かないとなぁ。\n参考 同形異音語 - Wikipedia ","date":1660099802,"dir":"post/2022/","id":"73279888a8fe482c836fb19ca23318dc","lang":"ja","lastmod":1660099802,"permalink":"https://blog.johtani.info/blog/2022/08/10/jp-auto-completion-2/","publishdate":"2022-08-10T11:50:02+09:00","summary":"前回は日本語用オートコンプリートのためのAnalyzerとして、どうやって使うのかを簡単に紹介しました。 今回はもう少し、いろんなパターンを試","tags":["elasticsearch","lucene"],"title":"ローマ字入力のゆれと読み(JapaneseCompletionAnalyzerその2)"},{"contents":"風のうわさで、日本語用のオートコンプリートのためのTokenFilterとAnalyzerがLuceneに取り込まれたと聞きました(LUCENE-10102)。 Elasticsearchでも使えるかなぁ?ということで調べたところ(調べた?聞いた?)、どうやら8.1から利用できるようになっている(GitHub Issue #81858)みたいです(まだ、公式ドキュメントには記載がないのですが)。\n8/17追記\n作者の打田さんがブログ書いてたの見落としてた(もしくは見たけど忘れてた)ので貼っておきます。マルチテナンシー下での Query Auto Completion 設計・運用戦略 - LegalForce Engineering Blog\nということで、こんな感じで使えるよというのを試してみました。\nどういうもの? 日本語入力方法を考慮したオートコンプリート用のトークンを生成してくれるTokenFilterと、 それをLuceneのSuggesterで動くようにしたAnalyzerが用意されています。 Elasticsearchでは、Kuromojiプラグインにそれらを使えるようになっています(バージョン8.1.0以降)。 KuromojiTokenizerと一緒に利用する前提の仕組みとなります。\nオートコンプリートとは? 検索窓などでキー入力をしていると、入力した文字で始まる単語の一覧が現れることがあると思います。 あの機能がオートコンプリートと呼ばれるものです。search-as-you-typeとも呼ばれることもあります。 (検索ペンギン本にも書いてあるので興味のある方はぜひ!(ステマ)) 入力された文字列を含むパターンもありますが、今回紹介するものは入力された文字で始まる単語を見つけてくる機能になります。\n何がなんで追加されたの? 日本語の入力方法は、かな入力の人もいればローマ字入力の人もいます。 ですので、オートコンプリートでの入力として、「しゃ」という入力が来る場合もあれば、「sha」というローマ字入力途中のものが来る場合もあります。 これらを考慮したトークンの扱いができるように、 JapaneseCompletionFilterというクラスが追加されています。 内部的にはKuromojiTokenizerでトークンに分割された後に、もともとのトークンと同じポジションで読みをローマ字にしたものを出力します。 JapaneseCompletionAnalyzerは上記Filterをすぐに使えるようにしたAnalyzerです。\n動かし方 百聞は一見に如かずということで、Elasticsearchでの使い方を見たほうが分かりやすいので、簡単に動かしてみることにします。\nインストールとインデックスの用意 Elasticsearch(8.1以上)とKuromojiのプラグインをインストールします(今回試したのは8.3.1)。\nサンプルデータ なにかいいデータはないものか?と思っていたところ夏休みだというのを思い出しました。 夏休みといえば読書感想文だ、ということで、書籍のタイトルがいいかもなと。 青空文庫の著者名と書籍のタイトルの一覧を見つけたのでそちらのデータを使って試してみました。\nCSV to JSON CSVファイルは最後の参考にある青空文庫のページから、「公開中 作家別作品一覧:全て(CSV形式、zip圧縮)」をダウンロードしたものを利用しました。 CSVファイルだったので、jqコマンドで必要な部分だけをNDJSONの形でとりあえずファイルに出力します。\ncat list_person_all_utf8.csv | tr -d \u0026#39;\u0026#34;\u0026#39; | jq -c -R \u0026#39;split(\u0026#34;,\u0026#34;) | {\u0026#34;auth_id\u0026#34;: .[0] | tonumber, \u0026#34;author\u0026#34;: .[1], \u0026#34;id\u0026#34;: .[2] , \u0026#34;title\u0026#34;: .[3], \u0026#34;suggest_ja\u0026#34;: [.[3], .[1]]}\u0026#39; 次のようなJSONが1行ずつ出力されます。\n{\u0026#34;auth_id\u0026#34;:1257,\u0026#34;author\u0026#34;:\u0026#34;アーヴィング ワシントン\u0026#34;,\u0026#34;id\u0026#34;:\u0026#34;056078\u0026#34;,\u0026#34;title\u0026#34;:\u0026#34;駅伝馬車\u0026#34;,\u0026#34;suggest_ja\u0026#34;:[\u0026#34;駅伝馬車\u0026#34;,\u0026#34;アーヴィング ワシントン\u0026#34;]} suggest_jaがオートコンプリートの対象となるデータになります。今回は著作と著者にしてみました。 あとは次に紹介するスキーマでインデックスを作成して、適当なプログラムを使ってBulkでElasticsearchに登録しましょう(私は個人作のツールで入れました)。\nインデックス オートコンプリート用のSuggesterを利用するための特殊なフィールド(completion)を利用したフィールドを用意します。 ちなみに、今回はLUCENE-10102に記載があった設定をそのまま使わせていただきました。 そのほかのフィールドは今回は特に必要はないのでおまけです。\nPUT aozora_index { \u0026#34;mappings\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;completion\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;japanese_completion_index\u0026#34;, \u0026#34;search_analyzer\u0026#34;: \u0026#34;japanese_completion_query\u0026#34;, \u0026#34;preserve_separators\u0026#34;: false, \u0026#34;preserve_position_increments\u0026#34;: true, \u0026#34;max_input_length\u0026#34;: 50 }, \u0026#34;auth_id\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;author\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;fields\u0026#34;: { \u0026#34;keyword\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;keyword\u0026#34;, \u0026#34;ignore_above\u0026#34;: 256 } }, \u0026#34;analyzer\u0026#34;: \u0026#34;kuromoji\u0026#34; }, \u0026#34;author_id\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34; }, \u0026#34;id\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34; }, \u0026#34;title\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;fields\u0026#34;: { \u0026#34;keyword\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;keyword\u0026#34;, \u0026#34;ignore_above\u0026#34;: 256 } }, \u0026#34;analyzer\u0026#34;: \u0026#34;kuromoji\u0026#34; } } }, \u0026#34;settings\u0026#34;: { \u0026#34;index\u0026#34;: { \u0026#34;number_of_shards\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;analysis\u0026#34;: { \u0026#34;analyzer\u0026#34;: { \u0026#34;japanese_completion_index\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;index\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;kuromoji_completion\u0026#34; }, \u0026#34;japanese_completion_query\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;query\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;kuromoji_completion\u0026#34; } } } } } } 動作確認 ここまでで、インデックスとデータの用意ができました。 オートコンプリートを実現するためにはElasticsearchのSuggesterという機能の、Completion Suggesterを利用します。検索の仕方が通常のものとは少し異なります。 ちなみに、速度重視のためにインメモリで動いているとの記載がドキュメントにあります。\nCompletion Suggesterのクエリ Suggester用のクエリがあるのでこちらを使います。 例えば、「wagah」という入力がある時に、サジェストする内容を取得するには次のようなリクエストになります。\nGET aozora_index/_search { \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: { \u0026#34;prefix\u0026#34;: \u0026#34;wagah\u0026#34;, \u0026#34;completion\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;suggest_ja\u0026#34; } } }, \u0026#34;_source\u0026#34;: [\u0026#34;title\u0026#34;, \u0026#34;author\u0026#34;] } 最初の「suggest」がsuggest用のパラメータを意味しています。 次の「title-suggest」は好きな名前をつけられます。レスポンスにこの名前がついた配列がサジェストの結果になります(同時に3. 複数suggestを呼び出せるので、対応した結果が分かるように名前が付けられます)。 「prefix」に入力の文字列を渡します。 「completion」がsuggesterのタイプの指定です。今回はCompletion Suggesterなので「completion」を指定します。その中に「field」でcompletionに利用するフィールド名を指定します。先ほどのスキーマでcompletionタイプを指定したフィールドです。今回は「suggest_ja」になります。 「_source」は結果を見やすくするために、ヒットしたデータの一部だけ取得するオプションです。 すると、次のような結果が返ってきます。\n{ \u0026#34;took\u0026#34;: 1, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;wagah\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 5, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;『吾輩は猫である』中篇自序\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;002671\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;『吾輩は猫である』中篇自序\u0026#34;, \u0026#34;夏目 漱石\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;わが俳諧修業\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;003771\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;わが俳諧修業\u0026#34;, \u0026#34;芥川 竜之介\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;わが母をおもう\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;003997\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;わが母をおもう\u0026#34;, \u0026#34;宮本 百合子\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;わが母を語る\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;049723\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;わが母を語る\u0026#34;, \u0026#34;上村 松園\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;吾輩は猫である\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;000789\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;吾輩は猫である\u0026#34;, \u0026#34;夏目 漱石\u0026#34; ] } } ] } ] } } 「suggest」の「title-suggest」がCompletion Suggesterのレスポンスになります。 最初の「text」は入力の「prefix」の値です。「offset」、「length」もこの文字に関する情報なので特に気にしなくてもいいかと。 「options」がサジェストされた内容になります。それぞれの「text」がサジェストされた文字列になります。「suggest_ja」には著作と著者名を入れましたが、今回は著作が「text」に帰ってきていることがわかります。 次に著者名でもやってみましょう。 「太宰」という入力が来たものとしてリクエストを投げます。\nGET aozora_index/_search { \u0026#34;explain\u0026#34;: true, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: { \u0026#34;prefix\u0026#34;: \u0026#34;太宰\u0026#34;, \u0026#34;completion\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;suggest_ja\u0026#34; } } } } レスポンスは次のようになります。\n{ \u0026#34;took\u0026#34;: 1, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;太宰\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 2, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;太宰 治\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;000236\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;ア、秋\u0026#34;, \u0026#34;太宰 治\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;太宰 治\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;001572\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;I can speak\u0026#34;, \u0026#34;太宰 治\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;太宰 治\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;001578\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;愛と美について\u0026#34;, \u0026#34;太宰 治\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;太宰 治\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;046597\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;青森\u0026#34;, \u0026#34;太宰 治\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;太宰 治\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;004357\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;青森\u0026#34;, \u0026#34;太宰 治\u0026#34; ] } } ] } ] } } 先ほどとは異なり、「options」の中の個々の「text」はすべて「太宰 治」になってしまいました。 登録したデータは著作の一覧ですが、「suggest_ja」には著作と著者名を入れたためです。 これでは、実際に検索窓に実装したときに同じものが並んでしまいます。 こんな時のためのオプション「skip_duplicates」が用意されています。 先ほどのリクエストに「\u0026ldquo;skip_duplicates\u0026rdquo;: true」を追加します。\nGET aozora_index/_search { \u0026#34;explain\u0026#34;: true, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: { \u0026#34;prefix\u0026#34;: \u0026#34;太宰\u0026#34;, \u0026#34;completion\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;suggest_ja\u0026#34;, \u0026#34;skip_duplicates\u0026#34;: true } } }, \u0026#34;_source\u0026#34;: [\u0026#34;suggest_ja\u0026#34;] } するとレスポンスは次のように変化します。\n{ \u0026#34;took\u0026#34;: 1, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;太宰\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 2, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;太宰 治\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;000236\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;ア、秋\u0026#34;, \u0026#34;太宰 治\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;太宰治との一日\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;042582\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;太宰治との一日\u0026#34;, \u0026#34;豊島 与志雄\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;太宰治情死考\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;043137\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;太宰治情死考\u0026#34;, \u0026#34;坂口 安吾\u0026#34; ] } } ] } ] } } 「options」は3つに減り、重複していないことがわかります。 「text」が同じ場合は最初に出てきたものを返すようです(注意:結果から観測しているだけで、実装はまだ見ていません)。 (なお、今回は説明を省きますが、入力データでスコアを指定することも可能になっています)。 そのほかにもCompletion Suggesterにはいくつか仕組みが用意されているのですが、それはまた今度にでも。\nまとめ ということで、Luceneコミッターの打田さんに感謝です。 便利な仕組みが簡単に使えるようになるのはとてもありがたいですね。\nまずは簡単にどういうものかとどうやって使うのかを記事にしてみました。 中の動きや、注意点、これまでとの違いなどは次の記事にしようと思います。 そういえば、公式ドキュメントにはまだ出てきてないな、それを書こうと思ってついでに動かしてみたんだけど、追加するのはまた後日かな。。。\n参考資料 青空文庫 - 公開中 作家リスト:全て [LUCENE-10102] Add JapaneseCompletionFilter for Input Method-aware auto-completion - ASF JIRA Expose Japanese completion filter to kuromoji analysis plugin by mocobeta · Pull Request #81858 · elastic/elasticsearch Suggesters | Elasticsearch Guide [8.3] | Elastic ","date":1660028402,"dir":"post/2022/","id":"6639ec6f88c4976f8ca20fa840f169e3","lang":"ja","lastmod":1660028402,"permalink":"https://blog.johtani.info/blog/2022/08/09/japanese-auto-completion/","publishdate":"2022-08-09T16:00:02+09:00","summary":"風のうわさで、日本語用のオートコンプリートのためのTokenFilterとAnalyzerがLuceneに取り込まれたと聞きました(LUCE","tags":["lucene","elasticsearch"],"title":"日本語用オートコンプリートのためのAnalyzer"},{"contents":"Hugoを0.84から0.92にアップデートをする際に、これまでのブログ記事やレイアウトファイルを修正したので個人的にメモを残しておきます。\nなんでアップデート? うっかり魔がさして、メインのWSL2のUbuntuを20.04から22.04にアップグレードしました。。。 新規に22.04を落としてきて移行ではなく。 皆さんはまねしないほうがいいですよ! アップデートした後にGitの環境がおかしくなったりと大変でした。 WSL2のUbuntuではHugoでブログのビルド、いろんな確認のためのElasticsearchの起動、個人的なプログラムとかを書く環境として利用しています。\nで、Ubuntuを上げたところ無事(?)Hugoもアップデートされたわけです。 最初はGitでfetchが出来なくなって修正していましたが、そのほかの動作確認を行なう段階でHugoでブログがビルドできなくなっていることが判明しました。\nバージョンアップに伴う修正 hugoコマンドを実行すると、いくつかのERRORとWARNが出力されました。 次のようなものです。\nhugo v0.92.2+extended linux/amd64 BuildDate=2022-02-23T16:47:50Z VendorInfo=ubuntu:0.92.2-1 ERROR 2022/08/05 13:22:32 Page.URL is deprecated and will be removed in Hugo 0.93.0. Use .Permalink or .RelPermalink. If what you want is the front matter URL value, use .Params.url WARN 2022/08/05 13:22:32 The \u0026#34;tweet\u0026#34; shortcode will soon require two named parameters: user and id. See \u0026#34;/home/johtani/blog_generator/content/post/2020/2020-12-04-build_corne_choc.md:46:1\u0026#34; ... ERROR 2022/08/05 13:22:33 Failed to get JSON resource \u0026#34;https://publish.twitter.com/oembed?dnt=fa... If you feel that this should not be logged as an ERROR, you can ignore it by adding this to your site config: ignoreErrors = [\u0026#34;error-remote-getjson\u0026#34;] ERROR 2022/08/05 18:44:11 Page.UniqueID is deprecated and will be removed in Hugo 0.93.0. Use .File.UniqueID ERROR 2022/08/05 18:44:11 Page.Dir is deprecated and will be removed in Hugo 0.93.0. Use .File.Dir Page.URLなどがdeprecatedに 最初と最後2行のERRORがこちらになります。 どうやら、Pageオブジェクトの変数に変更があったようです(まだdeprecatedであり、存在はしていそう?)。 レイアウト(テンプレート)ファイルで「Previous Post」や「Next Post」といったリンクを作ったり、 Algoliaに登録するためのJSONファイルを生成するところでURL文字列を取得するために参照していました。\nログ出力でどのように変更すればよいのか?という記載があるので便利ですね。 ただ、どのファイルにこの記述があるのかはログに出てなかったので少しだけ苦労しました。\n実際には「UniqueID」という文字列でディレクトリ内を検索してあたりを付けた感じです。 利用させていただいているテーマ(Clean White)がすでにアップデートに対応されていたのでそちらが参考になりました。\nいくつか、テーマをもとに修正したテンプレートがlayoutsディレクトリにあったので、それらを修正した形です(参考のリンクはテーマのファイルになります)。\n.URLを.Permalinkに変更(参考:single.html) .UniqueIDを.File.UniqueIDに変更(参考:list.algolia.json) tweetのshortcodeの引数が増えた これまでは以下のようにIDだけで良かったのですが、userとidという2つの引数が必須になるという変更が入ったようです。\n変更前:\n{{ \u0026lt;tweet 1449214872143609860\u0026gt; }} 変更後:\n{{ \u0026lt;tweet user=\u0026#34;johtani\u0026#34; id=\u0026#34;1449214872143609860\u0026#34;\u0026gt; }} WARNにはファイル名、行番号が出力されていたので、1つずつ修正していきました。 結構な量があったので、地味に大変でした、 公開しているブログを見ながら、該当するツイートを見つけてはuserを指定していく部分が特に。 自分のツイート以外もブログに貼っていたので画一的には対処できなくて。。。\nなにかプログラムで機械的に対応ができたかもなぁ。\n鍵付きツイートによるエラー tweetのshortcode対応を行なった後でもビルドがエラーになっており、次のようなエラーが消えないままでした(エラーの一部は省略しています)。 (幸いにも)1つのツイートだけ、ブログ記事を書いた後で鍵付きになってしまった方のツイートがあったようで、ツイート用のJSONが取得できなくてエラーになっていました。\nERROR 2022/08/05 13:22:33 Failed to get JSON resource \u0026#34;https://publish.twitter.com/oembed?dnt=fa... If you feel that this should not be logged as an ERROR, you can ignore it by adding this to your site config: ignoreErrors = [\u0026#34;error-remote-getjson\u0026#34;] こちらもログに対処方法が出ています。 config.tomlにignoreErrors = [\u0026quot;error-remote-getjson\u0026quot;]を追加すれば、エラーが出力されなくなりビルドも成功するようになります。 ただ、tweet以外でもエラーが出る可能性がありそうで、その場合に、ブログに書いたつもりが一部が出力されないまま公開されそうな気がします。 なので、今回はconfig.tomlに該当の設定を追加するのではなく、ブログ記事から該当のツイートを消す対応をしました。 幸いにも、ツイートを消してもブログ記事自体には影響がありませんでした。\n.hugo_build.lockファイルが生成される これは、エラーではないのですがgit addしようとした際に、ファイルが増えていたのでどういったファイルなのかを調べました。 0.89.0から追加されたロックファイルのようです(参考:0.89.0のリリースノート)。 こちらは特に保管する必要もなさそうなので.gitignoreに追加して対処しました。\nまとめ ということで、気軽にUbuntuをアップグレードしないほうがいいですね。。。 期せずしてHugoのアップグレードができたのは良かったかもなw\n参考 【WSL2】Ubuntu 20.04.4 LTS を 22.04 LTS へアップグレードした ","date":1659689954,"dir":"post/2022/","id":"167a7c9d579ce6f2cebf64a6f6329ecb","lang":"ja","lastmod":1659689954,"permalink":"https://blog.johtani.info/blog/2022/08/05/upgrade-hugo-accidentally/","publishdate":"2022-08-05T17:59:14+09:00","summary":"Hugoを0.84から0.92にアップデートをする際に、これまでのブログ記事やレイアウトファイルを修正したので個人的にメモを残しておきます。","tags":["hugo"],"title":"Hugoをアップデートした"},{"contents":"今回はQuerqyのElasticsearchのプラグインがどんなつくりになっているか?をちょっとだけ調べてみました。 SolrでもElasticsearchでも使えるという形なので、どんなつくりになっているのかな?と思ったのが発端です。\nGitHubのリポジトリ GitHubにリポジトリが公開されています。 2つのリポジトリに分かれています。\nEs向けのプラグイン コアのライブラリ どちらもJavaのライブラリで、ビルドシステムとしてはMavenを利用しています。 コアのライブラリのリポジトリにはさらに、以下の2つが存在しています。\nlucene向けライブラリ(Solr向けのモジュールもこちらに含まれる) コアライブラリ pom.xmlを読んだところ、次のような依存関係になっています(それ以外にも使ってるライブラリはあるけど)。\nEsプラグイン -\u0026gt; Lucene向けライブラリ -\u0026gt; コアライブラリ Esプラグイン Es向けのエンドポイントの実装、Esのクエリの組み立てを行なっています。 Rewriterの実装については、Lucene向けライブラリ、コアライブラリを利用する形になります。\nquerqy用のQueryBuilderを実装しており、EsがクエリをパースするタイミングでRewriterなどを呼び出してクエリの書き換えを行う仕組みです。 なお、Es向けのクエリの組み立てと書きましたが、ほとんどLuceneのクエリの組み立てになっています(そりゃそうだ)。 実際にquerqyのクエリ組み立て処理を行っているのは、Lucene向けライブラリのQueryParsingControllerになります。 いくつかのRewriterは、生のEsクエリをルールなどとして登録することができるようになっています。 これらのクエリのパースをEs側にやらせる処理の部分もこちらで定義されている感じです。\nそのほかに、ドキュメントには記載がないエンドポイントが2つ用意されていました。 インデックスに登録してあるRewriterの設定を各ノードでキャッシュする仕組みがあって、そのキャッシュの操作(クリア、リロード)用みたいです。 これらは、Rewriterの追加、削除のアクションの内部で呼び出されているので、ユーザー側で呼び出す必要はなさそうです。\nLucene向けライブラリ Luceneに関連する処理がまとめられています。 Es内部ではLuceneを使って検索処理が行なわれるため、Luceneのクエリを組み立てる必要があります。 querqyとしてLuceneのクエリを組み立てるときに必要なクラスがこのライブラリに含まれています。\nまた、Word Break Rewriterの実装はコアライブラリではなくこちらのライブラリに実装されています。 これは、Luceneのタームディクショナリを活用したRewriterになっているため、Lucene必須となっているからのようです。 (まだちゃんと実装を見ていないので、どんな活用の仕方をしているのかまではわかっていませんが。。。)\nコアライブラリ Rewriterの設定のパース処理、クエリのリライト処理の実装がまとめられています。 querqyのクエリが、Rewriterの処理に基づいて、querqyとして定義されたクエリのモデルに一旦変換される作りになっています。 Lucene向けライブラリやEs向けプラグインはこの内部のクエリモデルになったものをもとに、Lucene向けのクエリに書き換えていくというながれになっています。\nまとめ ざっくりですが、どんな構成なのかを見てみました。 Esのプラグインとなっているのですが、プラグインではなく、外部に出すことってできるのかな?と思いつつ、なんとなくソースを読んでみました。 パターンとしては、Lucene向けのクエリからEs向けのクエリを組み立てるとかの無駄な努力が必要になる気もするけど。。。 Luceneを使っていない検索エンジンに対しては、コアライブラリをもとに、それぞれの検索エンジンむけのクエリを組み立てる仕組みを作る形になると思います。 その際、Rewriterの設定を保持する仕組み、querqyが置き換えたクエリのマッピングができるか?といった点を考える必要がありそうです。 デバッグとかするときに、EsのクエリDSLのJSONとして見れるといいなぁと思ってたけど、そんなことできるかなぁ?\n","date":1658300650,"dir":"post/2022/","id":"3384ea6bb47d70f8ca94b4510813f36a","lang":"ja","lastmod":1658300650,"permalink":"https://blog.johtani.info/blog/2022/07/20/querqy-architecture/","publishdate":"2022-07-20T16:04:10+09:00","summary":"今回はQuerqyのElasticsearchのプラグインがどんなつくりになっているか?をちょっとだけ調べてみました。 SolrでもElast","tags":["elasticsearch"],"title":"Querqyの調査(その2:アーキテクチャ)"},{"contents":"Querqyというクエリのリライト用のプラグインがあるのでどんなものかを調べてみました。とりあえずは概要をドキュメントから追いかけてみた感じです。対応しているのはSolrとElasticsearch(以降、Es)になります。手元にはEsの環境があるのでそちらで試してみました。\nなにもの? EsやSolrのプラグインで、ルールやパラメータを利用して、クエリの書き換えをEsやSolr側で行えるプラグインです。 なお、本記事ではEsのプラグインを説明します。 今回はドキュメントを読みながらメモを取った感じなので、詳細については公式ドキュメントを見ていただくのが良いかと。 手元では動作させてみましたが、今回の記事ではざっとメモを取っただけになります。\nインストール Esのpluginコマンドでインストール可能ですが、Mavenにアップロードされているバージョンは限定的なので、必要に応じて自分でビルドする必要があります。 対応しているかは、公式ドキュメントのInstallationのプルダウンが参考になります。\nどうやって使うの? Query DSLにquerqyというクエリが追加されるので、あとはドキュメントをもとにクエリを組み立てるクエリを書いていきます。 すると、プラグインが指定されたルールに従い、EsのQueryに書き換え、実際の検索が実行して結果が返ってきます。 普通にmatchなどの既存のQueryと同レベルのものになるので、既存のEsのクエリと組み合わせた使い方もできるようです。\nサンプルとして紹介されている短めのクエリ(このクエリではルールによるクエリの書き換えはない)。\nGET ecommerce/_search { \u0026#34;query\u0026#34;: { \u0026#34;querqy\u0026#34;: { \u0026#34;matching_query\u0026#34;: { \u0026#34;query\u0026#34;: \u0026#34;notebook\u0026#34; }, \u0026#34;query_fields\u0026#34;: [ \u0026#34;title^3.0\u0026#34;, \u0026#34;brand^2.1\u0026#34;, \u0026#34;short_description\u0026#34;] } } } また、書き換え(Rewriter)の設定をElasticsearchに対して保存できるエンドポイント_querqy/rewriterが用意されています。\nSynonymの書き換えを行なうサンプル(後述するCommon Rules Rewriterの設定)。\nPUT /_querqy/rewriter/common_rules { \u0026#34;class\u0026#34;: \u0026#34;querqy.elasticsearch.rewriter.SimpleCommonRulesRewriterFactory\u0026#34;, \u0026#34;config\u0026#34;: { \u0026#34;rules\u0026#34; : \u0026#34;notebook =\u0026gt;\\nSYNONYM: laptop\u0026#34; } } どんな書き換えができるの? 用意されているRewriterは2022年7月時点では次のようなものになります(がんばれば、Javaで実装すれば自作もできそう)。\nCommon Rules Rewriter Replace Rewriter Number Unit Rewriter Word Break Rewriter また、複数のRewriterをチェインして使うこともできる。記述した順番で適用されます。 それぞれのRewriterについて簡単にメモを。\nCommon Rules Rewriter シノニム、結果のブースト、フィルター、結果に対して追加情報を付与したりできます。\nrulesにルールを記載していきます。 以下のようなフォーマットになっています。 クエリが入力に合致したら、ルールが適用される形です。プロパティは後述しますが、ルールの適用する順序などをハンドリングするために使用します。\n入力 =\u0026gt; ルール ルール @プロパティ @プロパティ 入力部分に関する書式 ルールの左辺に該当する部分で、クエリに入力された文字列がマッチするかどうかで、右辺のルールを適用するかがきまります。\n入力の一致の条件は次のような感じです。 完全一致、前方一致、後方一致の使い分けが可能。ダブルクォート\u0026quot;で制御 デフォルトでは、大文字小文字の区別なし(後述するオプションで変更可能) 単語の末尾にワイルドカード*で1文字以上にマッチ。入力の最後にだけ利用可能 書き換えの命令(ルール) 右辺に利用できる命令で、次のようなものがあります。\nSYNONYM 同義語展開するための命令です。Synonym Token Filterとの違いは、複数のルールを同時に適用できます。 フィールドに依存しない設定なのでメンテナンスが楽になるとのこと。 ただし、双方向の設定はないため、例えば\u0026quot;personal computer\u0026quot;と\u0026quot;pc\u0026quot;の場合、2つの設定を個別に定義する必要があります。 また、ステミングなどには未対応なので、\u0026ldquo;personal computers\u0026quot;も対応する場合はこれも追加する必要があります。 類義語ごとに重みを変えることが可能になっています。同列ではなく、同義語のスコアを下げるなどで、リコールを増加させつつ、入力語のスコアを上位にすると行ったことが可能です。\nUP/DOWN 入力文字列がマッチした場合に、追加のクエリを正か負のブーストをしつつ追加できます。 例えば、「iphone」と検索された場合に、「apple」もクエリとして追加しつつスコアをブーストし、「case」のクエリをスコアを下げるように追加できます。 これにより、アクセサリーではなく本体が検索結果の上位に出てくるような仕組みを提供できます。\nFILTER UP/DOWNではクエリとして追加されていたが、こちらはフィルターとして追加されます(=スコアで調整ではなく、結果から除外される)。\nDELETE クエリからキーワードを削除できます。 単語自体をそのまま削除することも、入力された単語に合わせて他の単語を削除することもできます。\nDECORATE 2022年7月時点でEsでは利用不可で、Solrのみで利用可能です(なので読み飛ばしました)。\nプロパティ 各ルールの設定にタグをつけられるような機能です。 このプロパティを利用して、ルールのソートやフィルタリングなどが可能になります。 複数のルールにクエリがマッチした場合に、優先度が最高のものだけを適用したり、プロパティに特定の値を持っているものだけを採用したりできます。 なお、プロパティは命令のあとに記述する必要があります(パーサーの関係かな?)。\nReplace Rewriter クエリタームの置き換え用のRewriterです。クエリの正規化処理として、他のRewriterの前処理に利用したりできます。 サンプルではタイポの修正などに利用したり、不要な語の除去などがあげてありました。\nWord Break Rewriter クエリトークンを分解・結合します。 たとえばドイツ語は、複合語と呼ばれる個別の意味の単語を結合した1つの単語を持っているため、個別の意味に分解して検索すると便利なことがあります。 そういった単語を辞書を基にして分割できるようにする機能です。 辞書とは実際のインデックスのタームディクショナリのことと思われます(要調査。どのインデックスのフィールドを指し示すのかなど、設定とドキュメントではよくわからない)。 なお、利用可能な形態素解析を基にした実装はドイツ語のみとなっており、また、分解の時には形態素解析を考慮しますが結合時には考慮しません。\nNumber-Unit Rewriter クエリの数値と単位を判別し、対象となるフィールドにマッチさせます。範囲での一致や完全一致やブーストが可能です。 単位をもとにして、特定のフィールドに対する数値のクエリに書き換えることができます。\nShingle Rewriter Solrのみで利用可能なので読み飛ばしました。\nルールはどこに保存されるの? .querqyというインデックスが内部で作成され、そこに保存されます(公式ドキュメントより)。 (ちなみに、Mappingはこんな感じみたいです)。 現状、プラグインでは設定したRewriterの取得ができないようなので、自分で登録した設定がどんなものかは、このインデックスを検索する必要がありそうです。\n気になった点・改善点? 気になった点があったので。\nRewriterのエンドポイントは、登録・更新・削除のみ対応しており、登録したものの確認は直接インデックスを見に行くしかなさそうです(Issueは作られてた)。 [要検証]書き換えられたクエリがどんなものか?は残念ながら確認できなそうで、_validate/queryで最終的なLuceneレベルのクエリで確認するしかなさそう? スキーマ側で定義したものと、Querqyで定義したものの兼ね合いがどういう形になるのか?などを気にする必要があるのが注意点かも。組み合わせたときの副作用などがどんなことになりそうか?が予測がつきにくそう。 Rewriterの定義自体のテストはどうしたものか? まとめ とりあえず、ざっとドキュメントを見ながらメモを取った感じです。 設定などの記述が独自のものなので、そこに慣れていく必要がありそうです(特にルールの改行の部分とか)。 次は実際にどんな感じで使えそうか、既存の仕組みとの違いは?みたいなところをもう少し見ていきたいとおもいます。\n参考文献 querqy/querqy: Query preprocessor for Java-based search engines (Querqy Core and Solr implementation) Getting started with Querqy — querqy.org documentation ","date":1658285563,"dir":"post/2022/","id":"779e444b4bc720a9eed97f19c41e8773","lang":"ja","lastmod":1658285563,"permalink":"https://blog.johtani.info/blog/2022/07/20/intro-querqy/","publishdate":"2022-07-20T11:52:43+09:00","summary":"Querqyというクエリのリライト用のプラグインがあるのでどんなものかを調べてみました。とりあえずは概要をドキュメントから追いかけてみた感じ","tags":["elasticsearch"],"title":"Querqyの調査(その1)"},{"contents":"今年もBerlin Buzzwordsにオンライン出張してました。 今年はハイブリッドな開催だったようで、現地で再開している人もいるようでした。 ブースもあったみたいです。ちなみに、現地で参加する人はマスク必須のようでした(Health \u0026amp; Safetyというページが用意されていました)。 昨年オンラインだったMICESは現地のみでの開催みたいで見ることはできなかったです(録画公開されないかなぁ)。\nさて、いくつか見たセッションで面白かったものがあったので簡単にメモを。 すでにセッションのビデオがYouTubeで公開されているので、興味のある方は見てみてください。\n面白かったセッション The future of Lucene\u0026rsquo;s MMapDirectory: Why use it and what\u0026rsquo;s coming with Java 19 and later? セッションページ: The future of Lucene\u0026rsquo;s MMapDirectory: Why use it and what\u0026rsquo;s coming with Java 19 and later? :: Berlin Buzzwords 2022 動画:Uwe Schindler – The future of Lucene\u0026rsquo;s MMapDirectory: Why use it \u0026amp; what\u0026rsquo;s coming with Java19 \u0026amp; later - YouTube 毎年恒例になってる気も? 前半は昨年も話をした内容で、後半はJava 19がリリースされたら、Previewという形でフラグを立てて使えるようになるようです。 使えるようにするから、テストしてみて!という感じで終わっていますw\nScaling an online search engine to thousands of physical stores セッションページ:Scaling an online search engine to thousands of physical stores :: Berlin Buzzwords 2022 :: pretalx 動画:Aline Paponaud – Scaling an online search engine to thousands of physical stores - YouTube 数千の実店舗の商品をオンラインで検索できるようにしつつ、オンラインのマーケットプレイスのような検索も一緒にできるようにしたというお話でした。 インデックスの構成をどう工夫したのか?とかどういうクラスター構成にして、どんなことをモニタリングしてるよ?というお話です。 実際の店舗がどんなものかなどは出てこなかったので、少しイメージは沸きにくかったのですが、どんなことを考えながらインデックスの構成とか考慮したよという話はおもしろかったです。 実際に検索したときに、実店舗のデータがどんな感じで結果として表示されたりするのか?といった点はわからなかったので、そのあたりの話をもうちょっと聞いてみたかったなぁ。\nOffline Ranking Validation - Predicting A/B Test Results セッションページ:Offline Ranking Validation - Predicting A/B Test Results :: Berlin Buzzwords 2022 :: pretalx 動画:Andrea Schütt \u0026amp; Yunus Lutz – Offline Ranking Validation - Predicting A/B Test Results - YouTube otto.deというECサイトでのランキングをどうやって改善していくか?という話。 現在はマニュアルなチューニングをコンテキストごとにやっているけど、リクエスト量とかデータとかが増えてきてて、このままマニュアルで改善していくのも大変なので、 モデルベースのランキングを開発できないか?というのをはじめていますよと。 そのために、これまでのデータから、A/Bテストの結果を予測できるモデルが作れないか?というのをやっていますという話。 いくつかわからない単語も出てきたので、誰か詳しい人教えて!\nAI-powered Semantic Search; A story of broken promises? セッションページ:AI-powered Semantic Search; A story of broken promises? :: Berlin Buzzwords 2022 :: pretalx 動画:Jo Kristian Bergum – AI-powered Semantic Search; A story of broken promises? - YouTube Vespaの開発にかかわってる方の、Semantic Searchに関する話。 Semantic Searchが流行り始めていて、どうやればできるのか?という話が出てきています。 けど、どういうものでどういう点に気を付けたほうがいい?という話でした。 LtRってこんなもの、そのあとに出てきたLLM(Large Language Model)でどうやって検索の改善に使えるの?というのが分かりやすく説明されていました。 それらの説明の後、BEIRという論文を紹介しつつ、LLMを使うときの注意点の話がありました。\nBERTとかをちょっと勉強してたのもあり、なんとなくそうだよなぁと思っていた結論と同じ結論が出てきたので面白いと感じました。 BEIRの論文は時間を見つけて読んでみないとな。\nHybrid search \u0026gt; sum of its parts? セッションページ: Hybrid search \u0026gt; sum of its parts? :: Berlin Buzzwords 2022 :: pretalx 動画:Lester Solbakken – Hybrid search: Greater than the sum of its parts? - YouTube こちらもVespaの人の話。 先ほどのSemantic Searchの話では、Semantic Searchがどんなものか?という話でした。 が、それだけで検索ができるわけでもないので、キーワードサーチとSemantic Searchの両方をうまく活用するには?というのがこのセッションでした。 最終的にはVespaを使うとうまくハイブリッドできるよという話ですが、考え方は参考になるかなと。 Vespaも触ってみたいなぁ。\nThe life of a search engine administrator セッションページ:The life of a search engine administrator :: Berlin Buzzwords 2022 :: pretalx 動画:Lucian Precup \u0026amp; Vincent Bréhin – The life of a search engine administrator - YouTube 検索システムの管理者ってどんなことやるの?それにはどんなことができるツールがあるといいの?という話です。 まぁ、ツールについてはこの会社の人たちのツールの宣伝なのですが、検索システムを作って育てていくのにどんなことを考えたりするのか?という参考になるかなぁと。\nShould we stop using distance in our location-based data recommendation models? セッションページ:Should we stop using distance in our location-based data recommendation models? :: Berlin Buzzwords 2022 :: pretalx 動画:Charlie Davies – Should we stop using distance in our location-based data recommendation models? - YouTube TravelTimeという会社を立ち上げた人の話。 位置に関する情報って重要だし、検索するときに利用しますよね?例えば、ホテル決めたりとか、仕事探したりするときに。 ということで、位置情報を検索エンジンで利用する方法(Bounding Box、ポリゴン、距離)をまず紹介して、どんなユースケースで使えるかという話があります。 また、それとは別に検索速度(いかに検索を速く返すか)も重要だという話があります(ウォルマートはページロード時間を1秒早くしてコンバージョンが2%あがったとか)。 で、実際に検索結果に距離とかでるけど、実際に知りたいのはどのくらいの時間で行けるのか?という話だったりしませんか?と。 公共交通機関を使ったりする場合に、実際に45分で移動できる距離というのは半径5マイルとかできまるものではないのに、単純に位置情報を利用した距離だけでソートしていいの?という問いかけから、 その辺を考慮した検索ができるAPIを開発しているよ、検索速度もはやいよというお話でした。 残念ながら具体的にどうやって作っているのか?というのはなかったですが、観点がおもしろかったです。\nWord2Vec model to generate synonyms on the fly in Apache Lucene セッションページ:Word2Vec model to generate synonyms on the fly in Apache Lucene :: Berlin Buzzwords 2022 :: pretalx 動画:Daniele Antuzi \u0026amp; Ilaria Petreti – Word2Vec model to generate synonyms on the fly in Apache Lucene - YouTube Word2Vecのモデルを使った、Apache LuceneのSynonym Filterを開発中だよという話 DeepLearning4Jを使ってみたが、遅くて使えなかったんだけど、最近Luceneに入ったkNNを使うことでそれなりの速度で使えそうなものができるかもよ?って感じでした。 モデル学習用のツールも作ってて、イタリア語のWikipediaで学習したものでちょっと動かしたらそれっぽい感じになってるという話でした。 まだ途中でいくつかやりたいことがあるという話で、実用はまだ先のようでした。例えば、1単語のSynonymにしか対応してないとか、モデルをインメモリでしか動かせないとか。\nQAでも出たのですが、Word2Vecだと対義語も類似していると判定されてしまうと思うので、その辺がどうなっているのかなぁ?という疑問があります。 ルールベースの類義語ではないので、調整するのはどうやるのかなぁ、学習用のコーパスをいい感じにするとかなのかな?とか、気になるところです。\nNrtSearch: Yelp’s fast, scalable, and cost-effective open source search engine セッションページ:NrtSearch: Yelp’s fast, scalable, and cost-effective open source search engine :: Berlin Buzzwords 2022 :: pretalx 動画:Umesh Dangat – NrtSearch: Yelp’s fast, scalable, and cost-effective open source search engine - YouTube YelpがLuceneベースで開発をしているNrtSearchというOSSの話です。 Elasticsearchを使っていたんだけど、どういった点が問題点になってどういうモチベーションでNrtSearchを開発したのか?を説明しています。 アーキテクチャがどんなもので、実際に動かしてみてどんな利点があって、どんな点が問題として出てきているか、将来どんなことをやろうとしているかがわかります。 QAでもいろんな質問が出ていて面白いです。\nまとめ ということで、簡単でしたがセッションの感想でした。 Neural/Semantic Searchというのがセッションのタイトルなどに入っているのが多くなってるなぁという感想です(ちょっとやってみたい気はしてるんだよなぁ)。 すでにYouTubeに動画が公開されているので興味があるセッションを見つけてみてください。 Berlin Buzzwordsの次の日に開催されたMICESも観てみたかったですが、オンラインでも参加できる形式で海外のカンファレンスが開催されるのはとても助かりますね(ヨーロッパだと時差もそれほど大変じゃないし)。 けど、落ち着いたらまたオフラインで参加してみたいなぁ。\n","date":1655283615,"dir":"post/2022/","id":"f56c19442484b3e4f47875b58b3f72b2","lang":"ja","lastmod":1655283615,"permalink":"https://blog.johtani.info/blog/2022/06/15/ttend-berlin-buzzwords-online/","publishdate":"2022-06-15T18:00:15+09:00","summary":"今年もBerlin Buzzwordsにオンライン出張してました。 今年はハイブリッドな開催だったようで、現地で再開している人もいるようでした。","tags":["conference","berlin buzzwords"],"title":"今年もオンラインでBerlin Buzzwordsに参加した"},{"contents":"7.16で正式リリースされましたが、Elasticsearchの新しいJavaのクライアントが出ています。 使ってみたので、ちょっとだけ紹介でもしてみようかな。\nこのクライアントが出るまでは、ElasticsearchのJavaクライアント(REST版)はElasticsearch本体の一部として実装・管理されていました(Elasticsearchのリポジトリにあるclientディレクトリ)。\nHTTP経由でElasticsearchにアクセスするクライアントだったのですが、Elasticsearch本体のリポジトリで管理されていることもあり、Elasticsearch本体で利用されているクラスを使用していました。 このため、クライアントライブラリなのですが、Elasticsearch本体のJarが必要になりサイズが大きくなっていました。 また、JavaのObjectへの詰め替えなどの機能も備えておらず、すこし古臭い感じでもあります。 この辺りを刷新する目的もあり新しいクライアントが公開されたようです。 3月くらいに触った時はまだ、ドキュメントが揃ってなかったのですが利用方法などが増えているので移行も楽になってきているようです。 根本的に作り直されたため、これまでのREST Clientとは使い方が違います。ですので、jarだけの差し替えでこれまで動いていたプログラムを移行ができるわけではないので注意が必要です。\nどの辺が便利? 順次移行が可能 これまでのRESTクライアントとはパッケージ名もjarも別モノになっています。 ですので、少しずつ新しいJava Clientに切り替えていくことが可能になっています。 根本的に使い方が変わっているので、大きなシステムのクライアントを全部切り替えるのは結構大変かと思います。 ですので、Indexをしている部分だけとか、検索部分だけなどといった部分的な置き換えをしつつ新しいクライアントに慣れていくことができます。\nラムダっぽく書ける 検索のクエリのサンプルを見るとわかりますが、こんな感じでクエリが書けます(公式ドキュメントより抜粋)。\nSearchResponse\u0026lt;Product\u0026gt; response = esClient.search(s -\u0026gt; s .index(\u0026#34;products\u0026#34;) .query(q -\u0026gt; q .match(t -\u0026gt; t .field(\u0026#34;name\u0026#34;) .query(searchText) ) ), Product.class ); また、最後で渡しているProduct.classは、検索結果をどのクラスのインスタンスにして返すかの指定です。 Elasticsearchのレスポンス(JSON)から値をコピーして返してくれるようになっています。 ですので、値を入れ替える処理を書く必要がなくなっています。\nJSON文字列をそのまま使える 触り始めてからリリース(7.17.2より後なら使える)された、JSON文字列からリクエストを作る機能もあります。\nこれまでのREST Clientだと、Elasticsearchへのリクエストを必ずJavaのメソッドで構築する必要がありました。 今回のこの機能を利用すると、JSON文字列(やファイル)からリクエストオブジェクトを作るためのメソッド.withJson()が提供されています。 例えば、スキーマや設定変更用のリクエストのJSONなどは、Kibanaやcurlから試験的に投げたリクエスト(JSON)と同じものを使いたいことが多いです。また、ElasticsearchのAPIは数が多く、ドキュメントを見ながら利用方法を調べてJSONでまず試行錯誤することが多いです。 このwithJsonメソッドを利用することで、動作確認などをしたJSONがそのままソースにも利用できるので、リクエスト変更時の確認なども容易になると思います。\n使ってみて困ったのは? 便利な面も多いのですが、使っていて少し困ったこともあったのでそれもメモを残しておきます。\nどんなリクエストを投げているかが不明 先ほども書きましたが、Elasticsearchのリクエストを試行錯誤するときは公式ドキュメントを見ながら、Kibanaなどを利用して試すことが多いです。 ですので、自分がやりたいことのJSONは手元にあることが多いです。 ただ、プログラムでクエリを組み立てる必要も出てきます。この時、実際にRESTリクエストとしてどんなJSONを投げているのかを知りたいことがあります(実際、検索クエリ作っててメソッドの使い方がうまくいかなくて四苦八苦してました)。 4月時点では簡単にリクエストで投げているJSONを文字列としてログに出すメソッドなどは用意されていないようでした。 デバッグ用に次のようなメソッドを書いてみました。 Elasticsearchへ投げるRequestのクラス(例:CreateTemplateRequestとか)を引数に渡すことで、JSON文字列に変換できるようになっています(StringWriterに書き出されてる)。 ここのLoggerはサンプルです。writer.toString()で取り出せる文字列がJSON文字列になっているので、ログに出してみるなり、ファイルに落とすなりしてデバッグのお供にしてください。\nimport java.io.StringWriter; import co.elastic.clients.elasticsearch._types.RequestBase; import co.elastic.clients.json.SimpleJsonpMapper; import jakarta.json.stream.JsonGenerator; ... private void printRequestBodyJsonForDebug(RequestBase request) { //for debug Logger.log(\u0026#34;** Debug print start **\u0026#34;); StringWriter writer = new StringWriter(); SimpleJsonpMapper mapper = new SimpleJsonpMapper(); JsonGenerator generator = mapper.jsonProvider().createGenerator(writer); mapper.serialize(request, generator); generator.close(); Logger.log(writer.toString()); Logger.log(\u0026#34;** Debug print finish **\u0026#34;); } プラグインなどで提供されるクエリが書けない LtRプラグインなどは、Elasticsearchの検索クエリを拡張しています。 残念ながら、現時点(2022/06/13)ではカスタムクエリを新しいJavaクライアントで利用しようとした場合、エラーが発生してしまいます(知らないJSONだと判断されてしまいます)。\nGitHubのIssueとして「[roadmap] Add support for plugin-defined custom components · Issue #252 · elastic/elasticsearch-java」があります。 これに対応されたら、拡張されたクエリも利用できるようになるでしょう。 プラグインなどで拡張されているものを使いたい場合は、残念ながら既存のRESTクライアントを当面は使うことになりそうです。\nまとめ 新しいElasticsearchのJavaクライアントを簡単ですが触ってみて、気になった点を記事にしました。 JavaのObjectに詰め替えてくれる機能など便利になっているので使ってみてください。 ドキュメントもちょっとずつ増えているようで、使い方も分かりやすくなっていました(触った時はレスポンスの扱い方などがJavaDocしか用意されてなかったんです)。 説明が欲しいなぁと思うことがあれば、GitHubにIssueを上げてみるといいかもです。\n参考 公式ドキュメント Java Clientチームの人がカンファレンスで利用したスライド ","date":1655119446,"dir":"post/2022/","id":"5eebdf85fd1726db301194bfeeee4377","lang":"ja","lastmod":1655119446,"permalink":"https://blog.johtani.info/blog/2022/06/13/new-elasticsearch-java-client/","publishdate":"2022-06-13T20:24:06+09:00","summary":"7.16で正式リリースされましたが、Elasticsearchの新しいJavaのクライアントが出ています。 使ってみたので、ちょっとだけ紹介で","tags":["elasticsearch","java"],"title":"Elasticsearchの新しいJavaクライアント"},{"contents":"Azure Cognitive Searchで2月に新しい機能が公開されました。 「Index Alias」(インデックスの別名)です。まだ、パブリックプレビューの段階ですが、ドキュメントなどが公開されていたのでどんな機能かを調べてみました。なお、本ブログの内容は2022/05/18時点での内容となります、ご注意ください。\n公式ドキュメント まずは公式ドキュメントです。1つ目の「インデックスの別名を作成する」の冒頭で別名(エイリアス)がどんなものかを説明しています。\nインデックスの別名を作成する - Azure Cognitive Search | Microsoft Docs エイリアスの作成または更新 (2021-04-30-Preview) - Azure Cognitive Search | Microsoft Docs Alias Operations (2021-04-30-Preview) - Azure Cognitive Search | Microsoft Docs REST APIのドキュメント(2022/05/18現在、日本語のページだと左のメニューが壊れているため、どんなAPIがあるかがわかりにくいため、Alias Operationsのページは英語のリンクになっています)\nインデックスエイリアスってどんなもの? 文字通り、インデックスにエイリアス(別名)をつけることができるようになります。 Azure Cognitive Searchでは残念ながらインデックスを作成するタイミング以外ではインデックスの名前を変更できません。 このため、インデックスのスキーマ(Analyzerの設定変更など)を変更したい場合、新しいインデックスを作成します。 新しいインデックスの名前はこれまでのものとは別の名前になってしまうため、アプリケーションで指定しているインデックス名も書き換える必要が出てきます。 利用しているアプリが複数ある場合は、すべて変更が必要です。\n今回出てきたエイリアスを利用することで、アプリケーションではエイリアスを指定することで、アプリケーション側の変更なくインデックスを入れ替えることができるようになります。\nエイリアスの操作方法 公式ドキュメントにAPIの一覧や利用方法の記載があるので詳細はそちらをご覧ください。 本ブログでは、いくつか利用するときに気になった点を書き残しておきます。\n作成 aliasesというエンドポイントにエイリアスの名前とインデックス名をPOSTすることで作成できます。 以下のサンプルは公式ドキュメントの例です。\nPOST /aliases?api-version=2021-04-30-preview { \u0026#34;name\u0026#34;: \u0026#34;my-alias\u0026#34;, \u0026#34;indexes\u0026#34;: [\u0026#34;hotel-samples-index\u0026#34;] } ちなみに、インデックスの指定がindexesで配列になっていますが、公式ドキュメントに以下の記述があり、複数の指定はできないです(エラーが返ってきます)。\nindexes 配列に指定できるインデックスの名前は 1 つだけです。\nまた、1つのインデックスに対して複数のエイリアスをつけることは問題ありません。\n確認 エイリアスのリストも取得できます。\nGET /aliases?api-version=2021-04-30-preview 現在どんなエイリアスが、どのインデックスに対して付与されているかがリストで取得できます。 きちんと作成されたかどうかなどの確認にも使えるかと思います(もちろんエイリアス名を指定したGETも可能です)\n検索での利用 検索のREST APIでインデックス名を指定していた部分をエイリアス名に置き換えるだけです。\nPOST /indexes/my-alias/docs/search?api-version=2021-04-30-preview { \u0026#34;search\u0026#34;: \u0026#34;pool spa +airport\u0026#34;, \u0026#34;searchMode\u0026#34;: any, \u0026#34;queryType\u0026#34;: \u0026#34;simple\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;HotelId, HotelName, Category, Description\u0026#34;, \u0026#34;count\u0026#34;: true } 更新 エイリアスの更新(インデックスの入れ替え)は作成と同じリクエストです。 更新が成功すれば204のステータスコードが返ってきます(エイリアス初回作成時は201) なお、ドキュメントには以下のような記述があります。入れ替え時の注意点になるかと(入れ替えのタイミングをきちんと制御したい場合は、少しだけアプリケーションを停止するなどが必要かと思います)。\n別名に対する更新がシステムに反映されるまでに最大 10 秒かかります。以前その別名が対応付けられていたインデックスを削除するのは、10 秒以上待ってからにしてください。\n削除 もちろん削除もできます。\nDELETE /aliases/my-alias エイリアスを利用する場合の注意点 便利なエイリアスですが、エイリアスが使用できない場合もあるので注意が必要です。\nデータ登録のAPIと検索のAPIでのみエイリアス名を利用可能 インデックスの設定変更やAnalyze Text APIではこれまで通りインデックス名を指定します。 また、エイリアス名はインデクサー機能でtargetIndexNameにも指定できません。 エイリアス名がついているインデックスは削除不可 エイリアスがついているインデックスを削除しようとした場合はエラーが出るようになっています。 まずはエイリアスを削除してからインデックスを削除するという手順になります。 まとめ 簡単ですが、インデックスのエイリアスに関しての紹介でした。まだパブリックプレビューなので正式リリース時点では利用方法が変わっている可能性もあります。こちらは注意してください。\n正式公開されればですが、今後Azure Cognitive Searchを使ったアプリを開発する場合はインデックスエイリアスを利用することを基本にするのがいいかもなと思います (ちなみに、Elasticsearchにもインデックスエイリアスの機能がありますが、異なる点が多いので同じものとは思わないほうがよさそうです)。\n","date":1652856857,"dir":"post/2022/","id":"7cc21814165879f72529e91682ece5c6","lang":"ja","lastmod":1652856857,"permalink":"https://blog.johtani.info/blog/2022/05/18/index-alias-in-azure-cognitive-search/","publishdate":"2022-05-18T15:54:17+09:00","summary":"Azure Cognitive Searchで2月に新しい機能が公開されました。 「Index Alias」(インデックスの別名)です。まだ、パブリックプレビューの段階です","tags":["azure search"],"title":"インデックスエイリアス - Azure Cognitive Searchの新機能"},{"contents":"年末までに知り合いと次の論文を読んだので軽くまとめておきます。\nExtreme Multi-label Learning for Semantic Matching in Product Search なんで読んだの? 前回読んだ理由と一緒ですが、Semantic Searchに絡んだ検索の論文であり、Amazonの製品検索での話も関係していたので読みました。\nどんな論文? Amazonの製品検索でセマンティックマッチングを利用する方法、レイテンシを低くしつつ再現率を改善できるような仕組みを検討して評価した論文です。 実際には商品検索のマッチングを大規模なマルチラベル問題(Extreme Multi-label Classification:以下ではXMC問題とする)として定義して、その問題を効率よく解く方法について検討評価しています。\n検索には大きく2つのフェーズがあります。マッチング(クエリにヒットした文書の集合を求める)とランキング(マッチングのデータを関連性の高い順序で並べる)です。 前回のMSの論文では、マッチング後のランキングのフェーズで言語モデルを利用した並び替えを行う話でした。 今回の論文ではマッチングに関してセマンティックサーチを有効活用できないか?という論文になります。 転置インデックスベースの(語彙による)検索では、スペルミスや類義語などを検索することが難しいです。 語彙以外のデータ(クリックや購入といったユーザーの行動や製品の意味的表現など)を学習できる埋め込みベースのニューラルモデルを活用して、マッチングを補完する方法を検討しています。 下図のようにあくまで転置インデックスベースの検索の補完として利用するみたいです(論文に掲載されていたアーキテクチャ)。\nXMC問題とは? セマンティックサーチを行なう場合、埋め込みベースのニューラルモデル(例えばBERTとか)を利用することが多いですが、 クエリトークンを埋め込み空間にベクトル化する部分が推論のボトルネック(レイテンシが高くなる)になることが多いです。 これは、ニューラルネットワークの複雑さに依存します。 低レイテンシになるように、複雑ではないエンコーダーを用いることもありますが今度は性能(精度)が良くなくなります。\nそこで、この論文ではセマンティックマッチングをXMC問題として定義し、これを効率よく解くための手法を提案しています。 ここで、XMCの問題とは、入力(今回はクエリ)に対して、最も関連性の高い複数のラベル(今回は製品)を出力することとなります。 Amazonでの製品なのでほんとに大規模(ラベル=製品=1億件)です。\n従来のXMC問題を解くための手法として、疎な線形モデルの手法、パーティションベースの手法、グラフベースの手法などが列挙されています。 疎な線形モデルの手法では、ナイーブなOVR(one-versus-rest)だと出力となるラベルの数に対して線形に推論時間も大きくなるため、今回の用途には適しません。 この論文ではパーティションベースの手法として、推論時間を短くできるツリーベースで疎な線形モデルの手法を評価しています。\nどういう仕組み? ツリーベースのモデルは次のような感じです。 PECOSのXR-Linearモデルを利用しています。 モデルに関する詳細についてはこちらの論文に詳しく載っているようです(まだ読んでいないです、、、)。\n一番上に入力として与えられるxがクエリ(ベクトル)で一番下の四角が製品にあたるラベル(Y={1,...,l,...L})です。 これらが与えられたときに最も関連性の高い上位k件のラベル(製品)を出力するモデルを生成します。 モデルのパラメータは、学習データとして(x, y)(ここで、y∈{0, 1}^𝐿、すなわちクエリに製品がマッチするかしないかの二値)を使って調整します。\nこれは、ツリーのそれぞれの階層のノードで、その下の層に関連するデータがあるかどうか?という分類を学習すればよいことになります。 学習データとしては、入力と最下層のラベルにマッチするかどうかというデータです。 これをもとに、ツリーの最下層のデータをもとにひとつ上の層の分類器の学習をすればよいことになります。\n推論は出来上がったツリーベースのモデルに対して、ビームサーチで行ないます。 この時、それぞれの層のノードの分類器では推論の効率化のために枝刈りの閾値を設定しています。 本論文で閾値の違いによる精度とレイテンシの比較も行われています。 また、ビームサーチのビームサイズを変化させた場合の性能についても実験しています。\nどうやって検証した? 次のようなデータを用いてAWS上にモデル構築、推論のシステムを用意し実験しています。\n10億件以上のポジティブなクエリ-商品ペアのデータセット クエリ:2億4千万、商品:1億 ポジティブなペアとは、クリック数や購入数の集計値が閾値以上。ただし、データセットとしては集計値は利用していない。 トレーニングセット:12か月分の検索ログ 評価用テストセット:1か月分の検索ログ(12%の製品はトレーニングセットには出てこない) というデーセットをもとに上記のモデルを学習しています。 特徴量はクエリテキストと製品のタイトルをもとにTF-IDFをいくつかのパターンで導出したものが使われています。 詳しくは論文の結果に関する表などを見ていただくとして。。。\n結果として、1億件の商品カタログで60.9%のRecall@100を1.25ミリ秒/リクエストという低レイテンシで達成したとなっています。\n気になる点は? 知り合いと3人で読んでいて次のような気になる点が出てきました。\nツリーの構築をするときに、製品のラベルの並び順(製品のクラスタリング?に他製品が似た場所に来る感じ)が推論の効率の良し悪しに影響するんじゃないの?=Amazonではないところではうまくいかない? PECOSの論文読まないといけない? 製品が増えたときにモデルの組み換えとかどうするの? コールドスタート問題という形で今後の課題として書かれていたので、今後に期待 転置インデックスでのマッチングの補完として利用しているということだったけど、ランキングはどうしてるんだろう? 別のランキング用の指標があるのかな?上位k件とした場合にどうやって、決めているのか? モデル更新のタイミングはどのくらいのスパンなんだろう? まとめ&感想 セマンティック検索の処理を分類問題に置き換えてその手法を用いて行い、実際のシステムに適用できそうな速度と精度を出しているのが面白かったです。 セマンティック検索にもいろんな手法があるのだなと(そして、いろいろ勉強しないといけないんだなと。。。)。\n気になる点にも書きましたが、ツリーの作り方になにかコツがあるのか?他の検索結果と組み合わせるときに、どのような基準で上位を選択しているのか?など疑問点も残っています。 個人的には特にどのように既存のシステムにくっつけていくのかというところが気になっています。 論文の続編でその辺の話が出てくるのかなぁ?\nツリーの作り方に関するPECOSの論文を誰か解説してくれると嬉しいかもなぁと思いつつ、とりあえずブログに書き残してみました。参考になるかなぁ。。。\n参考文献 Extreme Multi-label Learning for Semantic Matching in Product Search - ACM Extreme multi-label learning for semantic matching in product search - Amazon Science PECOS: Prediction for Enormous and Correlated Output Spaces 数えきれないほどの分類を行うExtreme Classification - Technical Hedgehog ","date":1641980462,"dir":"post/2022/","id":"0645bdb1cdf88ec74288d503eb71839c","lang":"ja","lastmod":1641980462,"permalink":"https://blog.johtani.info/blog/2022/01/12/reading-xmc-for-semantic-search-in-prod/","publishdate":"2022-01-12T18:41:02+09:00","summary":"年末までに知り合いと次の論文を読んだので軽くまとめておきます。 Extreme Multi-label Learning for Semantic Matching in Product Search なんで読んだの? 前回読んだ理由と一緒ですが、Semantic","tags":["search","paper"],"title":"Extreme Multi-label Learning for Semantic Matching in Product Searchという論文を読んだ"},{"contents":"今年も振り返りブログです。録画した紅白をオッかけ再生して気になるアーティストだけ見ながら書ています。\n振り返り(2020年に書いた抱負から) まずは去年の抱負を元に書きます。今年もコロナウィルスの影響が年末まで続き、ほとんどで書けなかったです。\nフリーランス継続? ありがたいことに個人事業主として無事1年を終えられました。 夏頃は5社ほどお手伝いをさせていただき、年末時点では3社をお手伝いさせていただいています。\n昨年の振り返りで書いた2社はありがたいことに継続していただいています。\n今年も完全リモートで仕事が終わりました。オミクロン株が来ているし、来年春くらいにはミーティングに出かけられるかなぁ。 相変わらず検索のお手伝いをしています。手伝いをしつつ勉強させていただいている感じです。 ありがたし。\nプログラミング ちょっとペースダウンしています。。。\nextract-kana-java 新しく書いたのはこれくらいかな。 SudachiやNeologdのkuromojiでフリガナを出力して違いを見るというコマンドツールです。 ちょっと比較してみたくなったので書いて公開しました。\nあとは、Sudachiをいろいろと触り始めています。 来年はそのへんをもうちょっと何かできるかなぁ。 コーディングしないとよくないなぁと思っているので、強制的になんかやらないとだ。\n検索の勉強 仕事でやってます。ブッチャー本は昨年買って手を付けてませんが。。。 来年は少しずつやる予定です。 あとは、Azure Cognitive SearchのSemantic Searchを触った関係でSemantic Searchに関する論文を探してちょっとずつ読んでいます。 知り合いと読んでいたAmazonの論文をブログにまとめるのは来年早々に。。。\n検索のポッドキャスト? これはできませんでした。重い腰が上がらない。 公開しないまでも雑談したいなぁ。\n振り返り(今年あったできごと) ここからは今年の出来事を。\n自宅環境 キーボード以外もDIY 検索Slack爆誕 車買い替えた WindowsノートPC買った 今年もずっと自宅で仕事でした。 昨年だいぶそろえていたのでそれほど変更はないですが。\n2月バージョン 切り替えてからずっとWindowsです。Macもブラウズ用に使ってはいますが。 ただ、Windowsといっても、プログラムなどに関する環境はほぼWSL2になっています。コマンドプロンプトは触ってないなぁ。 今年最後に更新された自宅環境は椅子になります。 詳しくは昨日のブログをご覧ください。\nキーボードもDIYしましたが、今年はほかにも少しDIYしました。\n今年のDIYキーボードとコントローラーラック このブログにも書きましたが、来年はキーマップやファーム関連を触っていきたいなと。あとロータリーエンコーダー。。。 BLE化は快適で、3台のPCの切り替えがとっても便利です。\ntakuya_aさんの鶴の一声で検索のSlackが爆誕しました。 検索に関連する情報交換ができる場として楽しませてもらってます。 年末には検索100本ノックの話が立ち上がってきています。 来年も面白い話が聞けそうでワクワクしています。\nあとは、車を買い替えました。初のハイブリッドです。 まだまだ慣れないですが、燃費とかがとても楽しみです。\n結局まだ出かけていませんが、出かけられるようにFMV Zeroを購入しました。 このブログもリビングでFMV Zeroで書いています(まだちゃんとセットアップしていないので、実際にはリモートデスクトップでデスクトップにつないでそこのVSCodeで書いちゃってますが。。。)。 ブログ書いたりコード書ける程度の環境は作らないとな。\n来年の抱負 ということで、来年の抱負です。\nフリーランス継続 プログラミング ブッチャー本ちゃんと読む 読んだ本のブログを書く 今年もありがたいことに仕事を継続していただけて、乗り越えられました。 来年も価値を提供できるように頑張っていきます。\nプログラミングは失速気味のでなにかテーマを見つけないとなあ。\nブッチャー本は読み始めます。必ずw\nブログのペースが落ちていたり、本を読むペースが落ちているので、 本を読んで自分のためにもブログを書こうと思います。 書いてないって思ったら叱咤してください。。。\n今年も出かけられませんでしたが、仕事も安定してあり、無事乗り切れました。 人と話をする機会は減っているので雑談したいな、オンラインなどで。 相手をしてやってもいいぞという方はぜひ連絡ください。\nさて、来年(もう年あけちゃったけど)は出かけられるかなぁ。 何はともあれ、今年もよろしくお願いします!\n","date":1640957359,"dir":"post/2021/","id":"104b8ee17a8bf1f7043d236659680493","lang":"ja","lastmod":1640957359,"permalink":"https://blog.johtani.info/blog/2021/12/31/looking-back-2021/","publishdate":"2021-12-31T22:29:19+09:00","summary":"今年も振り返りブログです。録画した紅白をオッかけ再生して気になるアーティストだけ見ながら書ています。 振り返り(2020年に書いた抱負から) ま","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2021)"},{"contents":"2021年もあと少しですが、今年買って良かったものをリストアップしておこうかと思います。 今年買ったといいながら、昨年このネタを書くといいつつ書いてないので、昨年の分も入っているかも? Amazonのアフィリンクを貼っていますが、急いでないものはAliExpressで購入したりもしています。\n象印のポット Amazon | 象印 電気ケトル 1.0L コーヒードリップ用機能付き ホワイト CK-AX10-WA | 象印マホービン(ZOJIRUSHI) いわゆる電気ケトルというやつです。これが来るまでは鍋で湯を沸かしていました。 水を入れてボタンを押し、湯を沸かしている間に他のことができるのはやはり便利です。 また、コーヒーを入れるためのコーヒードリップモードがあるので、ドリップするためにわざわざ湯を他のものに入れたり、 専用のヤカンを使わなくても簡単にドリップができるのがさらに便利で重宝しています。\nウォータードリップコーヒーサーバー Amazon | iwaki(イワキ) コーヒーサーバー SNOWTOP ウォータードリップ ここ数年、冬以外は水出しコーヒーを飲んでいます。 麦茶のポットのような水出しコーヒー用ポットを使っていたのですが、滴下式のほうがえぐみが少ないというのを見かけてウォータードリップのサーバーに変えてみました。 このひとつ前に水のタンクの部分がプラスチックのものを利用していたのですが、ドリップする部分を壊してしまったので、部品を購入することができるこちらに切り替えました。 朝、仕事をする前に豆を挽いて仕込んでおくと、昼にはコーヒーが落ちています。 夏は入れ終わったポットごと冷蔵庫に入れておくと氷を入れなくてもアイスコーヒーが飲めるので気に入っています。\neufyの掃除機 Amazon | Anker Eufy HomeVac H11(ハンディクリーナー) USB充電 仕事に使っている机でプラモデルを作ったり、DIYキーボードの工作をしたりと細かなごみが出る作業を行ないます。 ちょっとごみを吸いたいだけなのに、掃除機を毎回取りに行くのも面倒なので充電式のクリーナーを買ってみました。 仕組みも簡単だし、USBで充電できるのでおすすめです。アタッチメントを利用してキーボードの掃除なんかもしています。\n電動精密ドライバー Amazon | Wowstick 1F\u0026#43; 69in1 電動精密ドライバー ビット56種セット ケース USB充電式 LEDライト付き [並行輸入品] キースイッチを付け替えたり、工作したりでねじの開け閉めを頻繁に行います。 思ったよりも頻度が高くなってきたので、電動の精密ドライバーを試しに使ってみたらすごく楽ができました。 電池の入れ替えなどでもねじの開け閉めは行なうので、すごく役に立っています。 ビットが56種類もついていますが、プラスとマイナス以外はまだ使ってないかも。。。\n磁石のUSBケーブル Amazon | SUNTAIHO マグネット充電ケーブル DIYキーボード、エネループの充電器、上記のドライバーや掃除機など、USBで充電したり、接続するものが結構あります。 毎回ケーブルを差し替えるのも大変なのですが、@ymotongpooに教えてもらった磁石のUSBケーブルがお気に入りです。 先端部分(USB-C、micro)とケーブル部分が別々になっており、また、ケーブルと先端は磁石でくっつく構造なので、充電したい機器に先端部分を刺しておきます。 充電や接続したいときにケーブルを近づけると磁石でくっついてくれるのでケーブルの抜き差しが必要なくなります。 先端部分だけを個別に購入できたので、色々な機器にあらかじめつけてあります。\nMaker hart Just Mixer 5 Amazon | Maker hart Just Mixer 5 ステレオ5入力音声ミキサー/Bluetoothオーディオ入力対応 3台のPC+音楽サーバーとしてラズパイを主に利用しており、通知音などを1つのスピーカーから聞きたいので、ミキサーを導入しました。 5つの入力個別に音量調節できるので打ち合わせの時だけ他の音源を小さくしたりなど重宝しています。 ただ、入力が増えるとノイズが乗っている気もしますが。。。\nリストレスト(アームレスト) Amazon | エレコム リストレスト アームレスト 肘起き 扇形 左右で使える2個セット ブラック MOH-EL01BK 扇形のものを分割キーボードの手間においてリストレストとして使っています。 使用例の写真を見ると肘を置いていますが、手のひらをおくのにちょうどいいです。 これまでいくつかパームレストを試してみましたが、凹凸もなく適度な硬さで気に入っています。\nコンテッサセコンダ Amazon | オカムラ オフィスチェア コンテッサ セコンダ 10月に注文してクリスマスに届きました。部品が不足しているようで年内に届かないかもといわれていたのですが。 2003年くらいからアーロンチェアを使っていたのですが、さすがに買い替えるかということで奮発しました。 アーロンチェアは座面がメッシュなのですが、ももが疲れるのもあり、クッション座面のものにしてみました。 冬寒くないのがいいですねwまだ届いたばかりなので調整しないと。\nKindle paperwhite Amazon | Kindle Paperwhite - 大きくなった6.8インチディスプレイ 防水機能搭載 wifi 8GB 電子書籍リーダー 車の点検などでちょっとした待ち時間があるようなときに新書や小説が読めるようにセールで安くなったタイミングで購入しました。 健康診断で読書がはかどりました。もっと本を読まないとなぁ。\nということで、ここ数年で買って便利なものをまとめてみました。 他にもある気がするけど、とりあえずこの辺で。\n","date":1640784504,"dir":"post/2021/","id":"218e2c36d5945ece02fdc55d6cbcbc38","lang":"ja","lastmod":1640784504,"permalink":"https://blog.johtani.info/blog/2021/12/29/best-buy-2021/","publishdate":"2021-12-29T22:28:24+09:00","summary":"2021年もあと少しですが、今年買って良かったものをリストアップしておこうかと思います。 今年買ったといいながら、昨年このネタを書くといいつつ","tags":["misc"],"title":"2021年かって良かったもの"},{"contents":"Azure Cognitive Searchのスキーマの確認をするときに、Azureのポータルでは次のようにフィールドの一覧として見ることができます。\nただ、実際のインデックス定義はJSON形式でやり取りする形になっています(JSONの例:Create Index | Microsoft Docs)。 上記のスクリーンショットのようにフィールド数が少ない場合はそれほど気にならないのですが、フィールド数が大きくなると一覧で見たくなることがあります。 また、ポータルを自分で確認できない場合にJSONファイルを受け取って確認することもあります。 こういう時は、Excel(CSV)って便利ですよね?\nということで、サクッと確認するときには、次のようなjqコマンドをWSL2上で利用して、CSVに変換して確認しています。\necho \u0026#34;Name\u0026#34;, \u0026#34;Type\u0026#34;, \u0026#34;Searchable\u0026#34;, \u0026#34;Facetable\u0026#34;, \u0026#34;Filterable\u0026#34;, \u0026#34;Retrievable\u0026#34;, \u0026#34;Sortable\u0026#34;, \u0026#34;Analyzer\u0026#34;, \u0026#34;IndexAnalyzer\u0026#34;, \u0026#34;SearchAnalyzer\u0026#34; \u0026gt; index_schema.csv cat index_schema.json | jq -r \u0026#39;.fields[]|[.name, .type, .searchable, .facetable, .filterable, .retrievable, .sortable, .analyzer, .indexAnalyzer, .searchAnalyzer]|@csv\u0026#39; \u0026gt;\u0026gt; index_schema.csv 例えばこんな感じになります(上記のポータルのスクショとは別のスキーマですが。。。)。\nどんなフィールドオプションが利用されているか?などをExcelで開いてフィルターなどを活用してチェックするのには便利かなと。 jqコマンドをもっとうまく使うと、ヘッダ行ももっとスマートに出せるかもしれないんですが。。。\nちなみに、上記のコマンドでは残念ながらEdm.ComplexType(参考: 複合データ型をモデル化する方法 - Azure Cognitive Search | Microsoft Docs)には対応していません。 必要になった時に考えるかな。。。\n","date":1640141671,"dir":"post/2021/","id":"f0fdc140e18514362a4e52376a6fecba","lang":"ja","lastmod":1640141671,"permalink":"https://blog.johtani.info/blog/2021/12/22/azure-search-schema-json2csv/","publishdate":"2021-12-22T11:54:31+09:00","summary":"Azure Cognitive Searchのスキーマの確認をするときに、Azureのポータルでは次のようにフィールドの一覧として見ることができます。 ただ、実際のインデ","tags":["azure search","misc"],"title":"Azure Cognitive SearchのIndex Schema JSONをCSVで見たくなる"},{"contents":"今年もアドベントカレンダーの季節になってしまいました。 今年で2回目となる、pyspa Advent Calendar 2021の投稿です。 昨年に引き続きDIYがらみの投稿です。\nコントローラーラック 3つのコントローラーがあるのですが、結構場所を取ります。 また、それぞれ充電しないといけません。\n充電しつつ、邪魔にならない置き方はできないものか?と思っていたところ次のようなコントローラーラックを見つけました。\nAmazon | 山崎実業(Yamazaki) ゲームコントローラー収納ラック これそのものは場所を取るので購入は見送りましたが、エレクターの棚にワイヤーネットをつけると似たようなものができるのでは?ということで、DIYしてみることにしました。\n材料 材料は以下の通りです。 書いていない材料としてあとは、結束バンドがあります。\nワイヤーネット44×29.5cm オフホワイトB28 | 【公式】DAISO(ダイソー)ネットストア スリム型ネットフック50mm 2本入り | 【公式】DAISO(ダイソー)ネットストア クロームメッキワイヤーフック(2連、U字、2個) | 【公式】DAISO(ダイソー)ネットストア Amazon | マグネット 充電ケーブル SUNTAIHO USBケーブル LEDインジケーター付き Amazon | Anker PowerPort Atom III Slim (PD 充電器 65W 4ポート USB-C) 設置 まずは、2連のワイヤーフックでワイヤーネットをエレクターの棚にぶら下げました。\nそのままでは固定されないので、下のエレクターの棚とワイヤーネットを結束バンドで固定。 これで、コントローラーを置いたり取ったりしてもぐらぐらしません。\n固定したワイヤーネットの表(コントローラーを配置する側)に、ネットフック50mmをコントローラーの数だけ配置しました(上の写真でフックとコントローラーの関係がわかります)。\n前から見るとこのような形です。 裏側に、2連フックを使って、Ankerの充電器を固定し、USBのケーブルをコントローラーの上に来るように配置します(写真ではPS4とPS5のコントローラーの上の部分にぶら下がる形です)。\nコントローラーには磁石の端子をコントローラーに差し込んでおきます。\n磁石のUSBケーブルを利用していることで、コントローラーを取り出すときは少し力を入れて引っ張るだけ、収めるときは、ケーブルに近づけて充電できる状態にした後にフックに載せるだけとなりました。 ケーブルの抜き差しをしなくてもよいのでとても便利。 全体像は次の写真のようになっています。一番上のコントローラーはエネループを利用しているのでケーブルは不要になっています。\n磁石のUSBケーブルをpyspaでとんぷーに教えてもらって思いついたアイデアです。 磁石の端子は色々と使い勝手が良いので、DIYキーボードやテンキー、MX Ergo、Kindleなど色々なところに使っています。\n今年のDIYキーボード キーボードを作ったのは2つですが、改造を色々やってました。 ブログに記載したものはリンクだけにしておきます。\nケーブル自作 自作ケーブルキット – 遊舎工房 ケーブルも自作できるみたいなので作ってみました。 現在はテンキーの配置の問題もあって、メインでは利用はしていませんが工作としては面白かったです。 熱収縮チューブを処理するための道具を持っていなかったので、チューブの固定が甘いのが失敗でした。ドライヤーくらいの熱では足りないので作ろうと思っている方は要注意かと。\nCorne Light v2のBLE+LPME-IO対応 詳細はブログ記事を。Corneはこれ以外に、キースイッチの付け替えも行ないました。ルブしたGateronクリアをハンダでつけなおしました。\nCorne Light v2のBLE+LPME-IO対応 #DIYキーボード Sofle keyboard v2のBLE+LPME-IO対応 詳細はブログ記事を。このブログはSofleで書いています。現在メインに利用しているキーボードです。\nSofle v2を組み立てて、BLE+LPME-IO化してみた #DIYキーボード 10月には電池モジュールを次のものに付け替えました。家で主に使用するのもあり、充電池のほうが使い勝手がよさそうだという判断です。スイッチのON/OFFもしやすくなって満足しています。\n単4電池昇圧モジュール - のぎけす屋 - BOOTH Sofleの電池モジュールをボタン電池から単4電池用に差し替えた。 pic.twitter.com/TUizwr2qmw\n\u0026mdash; Jun Ohtani (@johtani) October 16, 2021 Lunakey Miniの組み立てとBLE+LPME-IO対応 詳細はブログ記事を。Sofleと時々入れ替えて使っています。小指のあたりのずれの大きさ、親指のキーの多さが使い勝手のよいキーボードです。コンパクトなのもあり、こちらは持ち運びにも利用できるかなと考えています。\nLunakey Miniを組み立てて、BLE+LPME-IO化してみた #DIYキーボード Soyuzの組み立て(Numpadキット) Soyuz (黒基板) – 遊舎工房 自宅の作業環境(2021/02)の写真にもありますが、分割したキーボードとは別にテンキーを利用しています。 WindowsのログインでPinコードを入力したり、色々な場面で数字の入力をすることがあるためです。 Soyuzを組み立てる前は素 - Shiro – 遊舎工房を利用していたのですが、これでは「⁺」や「Enter」など、電卓のような利用方法の場合にはキーが足りません。 かゆいところに手が届かないので、きちんとしたNumpadをということでSoyuzを組み立てました。\nShiroよりもだいぶ存在感があります。\nGK21S(Numpad) USB Type C充電器付きの滑らかな交換用キーボードキット (Gk21s/k21),スイッチ,デュアルモードPCB|Keyboards| - AliExpress 最後は独身の日のセールで見つけたNumpadキットです。キットといってもこちらは、基盤からケースまで組み立てが終わっているキットで、キースイッチを差し込んで、キーキャップを付けるだけというものになります。 現在はこれをメインに利用しています。通常のNumpadの上に1列キーが多く、Backspaceなどを割り当てられるのが便利です。 ドライバーソフトも用意されており、キーマップのカスタマイズも可能です(まだそこまでやってないけど)。\nお気に入りキースイッチ Kailh Box Silent ピンク軸 5個 | Kochi Keyboard Input Club Hako スイッチ(10個入り) – 遊舎工房 最後はキースイッチの紹介です。 現時点ではこの2種類を組み合わせるのが私の好みに合っているようです(今のところ)。 Box Silentのピンクをアルファベットのキーに、Input Club HakoのVioletをCtrlやShift、Enterなどのキーに割り当てて使っています(下の写真の左側で、キーキャップをつけている部分がHako Violetになっています)。\nまとめ ということで、pyspa Advent Calendar 2021の8日目の記事でした。 それほど作ったりしてないなと思っていたのですが、記事にしてみると今年も色々とDIYしてたみたいです。 キースイッチやキーキャップも自分の好みが固まってきたので、来年はファームウェアやキーマップ周りをいじっていきたいと思っています。\n","date":1638889200,"dir":"post/2021/","id":"26e44dfd16a2963d4c18e99806c26fd7","lang":"ja","lastmod":1638889200,"permalink":"https://blog.johtani.info/blog/2021/12/08/controller-rack/","publishdate":"2021-12-08T00:00:00+09:00","summary":"今年もアドベントカレンダーの季節になってしまいました。 今年で2回目となる、pyspa Advent Calendar 2021の投稿です。 昨年に引き続きDIYがらみの投稿","tags":["DIYキーボード","misc"],"title":"今年のDIYキーボードとコントローラーラック"},{"contents":"Domain-Specific Pretraining for Vertical Search: Case Study on Biomedical Literatureという論文を読んだので軽くメモを残しておきます。論文自体はリンクから参照してください。\n読んだ理由 Azure Cognitive SearchでSemantic Searchが利用可能になったこともあり、「Semantic Search」に関するMSのリサーチチームが発表している論文をたまたま見つけたためです。 Elasticsearchとニューラルモデルを利用したランカーでのリランクする仕組みがSemantic Searchと似ていたので読んでみました。\nざっくりメモ どんなもの? クリックログなどで関連度を改善できないような場合に、ドメイン固有の言語モデルを利用して検索結果の改善をする方法が提案されているので、バイオメディカル検索で実際に評価してみたという論文です。 特定分野の大量の文書から検索をするときに、ドメイン固有の事前学習した言語モデルを用意して、さらにファインチューニングする方法を評価しています。 言語モデルの生成に利用されたのはBERTになります。\n技術や手法のキモはどこ? 医療分野のデータを利用して評価していますが、ほかのドメインにも一般化できる可能性があることや、実際のシステムを提示している部分が肝になりそうです。\n論文から引用した言語モデルを用いてランキングを行う仕組みを構築する部分の構成です。\n左半分が、ドメイン固有の事前学習についてです。Wikipediaなどを利用したBERTのモデルが公開されたりしていますが、大量のドメイン固有データが用意できるのであれば、ドメイン固有のデータで事前学習することが有効であるという主張です(参考文献。これもMS Researchでした。同じチームなのかな?)。 この論文ではBERTの学習データとして、ドメイン固有のテキストを用いています。 実際にはPubMedBERTを利用しています。\n右半分がドメイン固有のデータで生成された言語モデルを利用して、ドメイン固有のニューラルランカー(検索結果のランキングを行なう仕組み)をファインチューニングする処理です。 MS MARCOと呼ばれるMSが公開している機械学習向けのデータセットのうち、ドメイン固有のサブセットを取り出して利用しているようです。\nこの論文では、L1検索(第1段階の検索)にBM25を利用して、L2検索にここで作成したニューラルランカーを利用し、検索結果を返す仕組みとなっています。 これは、Azure Cognitive SearchのSemantic Searchのシステムに似ています。\nこの論文では、BM25で検索した結果の上位60件の結果がL2のランカーの入力となっています。\n以下の2つが主な論文の成果となっています。\nドメイン固有の事前学習を利用することで、高度な学習コンポーネントなどの追加することなく高い精度が出た。 既存のBM25の検索エンジンと組み合わせてニューラルランカーを使うことで、計算コストを下げつつより良い上位の検索結果を返す仕組みを構築した。 どうやって有効だと検証した? TREC-COVIDデータセットを用いて評価して、TREC-COVIDに参加しているシステムと論文で提案している構成のシステムとの比較をしています。 また、ドメイン固有の事前学習が、一般ドメインなどの事前学習と比較して影響があるかどうかの評価もしています。\n実際にAzure上で構築した仕組みをMicrosoft Biomedical Searchとして公開しているようです。 上記のシステム構成のように、Elasticsearchで検索して、ニューラルランカーはKubernetes上に展開されたGPUで計算をしています。 論文には使用しているマシンの構成や台数なども記載があります。\n実際に構築したシステムをユーザーに利用して体験したもらった結果としては、 複雑な意図を持った長いクエリに対してはPubMedなどの他の検索ツールとしても良い結果が返ってきたことが確認されたとなっています。 ただし、一般的な短いクエリの場合は十分な結果にならない場合があったとのことです。\n議論はある? 実際にほかのドメイン(金融、法律、小売りなど)で適用してもうまくいくかは今後の研究に期待だと思います。 また、ファインチューニングするときに利用できるデータが今回の論文にあるようにMS MARCOのサブセットとして抽出できればよさそうです。\n他に読むべき論文は? TREC-COVIDに参加しているほかのシステムがどのような学習や仕組みが必要なのかを見ることで、どのくらいの手間・コストが軽減しているのかがわかるはずです。\n感想 ということで、読んでみました。 細かなほかの手法については調べていませんが、システム構成としてはAzure Cognitive SearchのSemantic Searchの仕組みと同じだと思われます。 違いは、ドメイン固有の事前学習のモデルではないことでしょうか。 ある程度のドメイン固有のモデルを利用できる仕組みができると、さらにSemantic Searchがうまく使えるようになるのかもしれません(前回書いたブログではWikipediaのデータを利用してみましたが、思ったほど良い感じはしなかったです。。。ファインチューニングの仕組みもないしなぁ)。 また、短いクエリでは芳しくない結果もあったというのは、おそらくニューラルランカーで評価するための情報が少なくなってしまうのだと思います。Semantic Searchに向いているクエリの作り方とかが出てくるのかな?\n","date":1636522396,"dir":"post/2021/","id":"35200cbf0b5b45d7f5f0b343cb18868b","lang":"ja","lastmod":1636522396,"permalink":"https://blog.johtani.info/blog/2021/11/10/reading-ms-biomedical-search-paper/","publishdate":"2021-11-10T14:33:16+09:00","summary":"Domain-Specific Pretraining for Vertical Search: Case Study on Biomedical Literatureという論文を読んだので軽くメモを残しておきます。論文自体はリンクから参照してください。 読んだ理由 Azure Cognitive S","tags":["search","paper"],"title":"Domain-Specific Pretraining for Vertical Search: Case Study on Biomedical Literatureという論文を読んだ"},{"contents":"今年もMICESにも参加してました。 昨年はBerlin Buzzwordsと共同開催でしたが、今年は別開催(別日程)でした。\nMICESは2017年から始まったe-commerceの検索にフォーカスしたカンファレンスです。 ECに関連する話に特化されていますが、話題は多岐にわたっています。色々やることありますねぇ、ECも。\n参加したセッション 参加したセッションの個人メモを今回も残しておきます。 セッション個別のリンクは用意されていないみたいですが、公式サイトにタイムテーブルがあり、セッションのタイトル、概要に加えて、スライドのPDFもリンクがあります。動画が公開されているものもあります。\nDreaming Search ビデオが公開されています。スライドがざっくりしたものなので最初に聞いた時にはしっくりこなかったので、聞き直してのメモです。 GDPRのような話で、個人の情報を自分たちで管理しようと流れがあります。 それぞれのECサイトなどでのユーザーのイベント(何を検索して、何をクリックした)情報はそれぞれのサイトで閉じた情報になっています。このため、自分の興味のある情報が断片化された情報でそれぞれのサイトで管理されてしまい、パーソナライゼーションされるもの(ランキングだったりレコメンドだったり)がいまいちな場合があります。 この個人の情報(ユーザーのイベント)をユーザー自身がハンドリングして、どの情報までをどこまで公開できるようにするというように管理できる仕組みができないか?という話のようでした。実際にそのための仕組み(もっと大きな話の仕様)を検討しているプロジェクトがあり、それに関連して検索という観点で夢を語っているセッションです。\nざっくり私が理解したのをまとめましたが、empathy.coという会社としてはいくつかPoCなども実施されているようでした。 個人の情報の扱い方に関する話は新鮮で面白かったです。 仕組みが出来上がり、各サイトが対応するとより個人が欲しい情報が集まりやすくなるのかなぁ?\nForget Facets, welcome Refinements (TM) Berlin BuzzwordsでいくつかLTをやられていた方によるファセットとその応用(彼らはRefinementsと名前をつけたみたい)についての話でした(ビデオとスライドが公開済み。)。 検索エンジンとファセットの関係の歴史から始まって、Kibanaでの使い方、モバイルや音声検索・チャットボットでのファセットは難しいよね?という話につながります。 ということで、Refinementsとして、ファセットを提示してユーザーに選んでもらうだけでなく状況に応じて、提案するための情報としてファセットを使うといいのでは?という話でした。例えば、チャットボットや音声検索での結果の場合、検索結果数が多くなるとユーザーが望んだものが返せるとは限らないです。その時に、ファセットの情報をもとに絞り込み条件を聞き返すネタに使うのはどうか?というような話でした。オートサジェスト(検索があいまいな時に、追加のキーワードを提案するもの)のような形でブランド名だったり、カテゴリーなどを表示する仕組みです。 実際の実装の話は、彼らが過去にBerlin Buzzwordsなどで話をしているのでそちらが参考になるとのことでした(参考:berlin buzzwords 2019 / Heystack 2019)\nReinforcement learning in search 検索における強化学習の話みたいです。ビデオとスライドが公開されています。ビジネス的に検索のランキングが重要だが、そのランキングをどうやって良くしていくのか?という話です。 ランキングでデフォルトのBM25から始まり、LtRを導入し、A/Bテストなどをしつつ、モデルの変化がどのようにビジネスに影響するかをはかるのが難しくなります。 LtRに対するオンライン機械学習のアプローチについて実際に直面した課題の話などがされている(はず?)です(どうも、実際にCTRなどを用いたところまでは行ってなさそう)。\n多腕バンディットなどの強化学習の話が続いたあたりでギブアップしてしまいました。。。\nBetter Search through Query Understanding - Panel Query Understandingに関するパネルとして3社の人がそれぞれどういった取り組みをしてるか?という話をしたあと質問などに答えていく形式でした。残念ながらビデオはまだ公開されていませんが、スライドが公開されています。QA部分も結構な時間だったのでビデオの公開がされるといいなぁ。\nUnderstanding queries by analysing user interaction / Andrea Schütt (OTTO) OTTOというECサイトでのQuery Understandingの紹介と、LtR導入にまつわる話。 データサイエンスとして最初はQuery Understandingやってたけど、スケールしないのでLtR導入して色々と試行錯誤しているところのようだった。\nQuery Understanding AI search eBayの方の発表。Query Understanding = ユーザーの興味をクエリから類推するという定義から、クエリを分類する、同定するためにどうしているか?という話でっした。 単語の表面的な文字としての近さだけでは、語順が変わると意味が変わるものや、ステミングのせいで同じになってしまうものといった例を紹介しつつ、クエリをベクトルにして表現(コンバージョン、クリックなどの情報を元にプロダクトのベクトルにしてみたり)し似ているかどうか?を判断している話です。\nCase study : Autocomplete Search Suggestions Digitec Galaxusというサイトでのオートコンプリートをもっと使いやすくするためにどんなデータを集めて、どうやって表示しているか?という話でした。 とりあえず入力されたものにヒットしたものを出すような実装だった場合に、サジェストされる量が多く、ノイズも多いので使いにくかったものをどうやって改善して行ったかという処理の流れなどの説明もありました。\nThe need for an open web search in Europe - The approach of the Open Search Foundation and its implications for E-Commerce-Companies Speaker: Alexander Decker / OPEN SEARCH FOUNDATION\nもっとオープンな検索システムを作っていこうという団体の話でした。 AWSが最近1.0をリリースしたやつとは別物です。 Googleでみんな検索しているけど、ブラックボックスなのでバイアスがかかっている。 もっとバイアスフリーなインデックスを提供できると、使いやすくなるよね?みんなでそういうインデックスを作っていかないか?という話でした。 ECとの直接の関係はセッションからは読み取れませんでした。 どうやって、集めるデータの基準(入れるべき、入れるべきではないなど)を作るんだろう?という疑問が残っています。公共的なものやオープンデータについてはあるとよさそうかもなぁ。\n101 hints to improving the customer satisfaction on search engines in the retail industry Speaker: Marion Hemery (Carrefour France) \u0026amp; Lucian Precup (a// \u0026amp; Adelean)\nカルフールのECサイトでの検索に関する顧客満足度の改善についての話です。 どんなものをどうやって図るのか、フィードバックを取るための仕組みは? そこからわかったものをどうやってシステムに優先度をつけながら取り込んでいくのか? というのをどんなものを使っているかという説明を交えながらのセッションです。 スライドが結構細かく書かれているのでスライドを見るだけでもわかりやすいかな。\n“An ounce of prevention is worth a pound of cure”: establishing a gold standard-based evaluation in customer projects Speaker: Bertram Sändig \u0026amp; Cornelia Werk / NEOFONIE\n検索の性能指標(速度ではないほうの性能)をきちんと評価する仕組みが重要だよというセッションです。 検索の仕組みを変更(例ではステミングを導入するはなしをしてました)した場合に、現行システムにどういう影響が出るのか?それをどうやって図るのか、どうやってテストしていくのか?という話です。 ステミングを導入したら、検索にヒットしやすくなったものも出てきたけどその弊害として今までよかった検索の結果にノイズが増え多という話をもとに、検索結果としてこうあってほしいというゴールデンスタンダードをきちんと作って育てていくべきですよという話でした。完ぺきなものなどないので少しずつやっていきましょうと。\nということで、見ていないもの(LTや最後のワークショップ)もありますが、見たものに関してメモを残してみました。\n","date":1626160103,"dir":"post/2021/","id":"10a7f69bd03d2632722300194f01e93d","lang":"ja","lastmod":1626160103,"permalink":"https://blog.johtani.info/blog/2021/07/13/attend-mices-2021/","publishdate":"2021-07-13T16:08:23+09:00","summary":"今年もMICESにも参加してました。 昨年はBerlin Buzzwordsと共同開催でしたが、今年は別開催(別日程)でした。 MICESは201","tags":["conference","berlin buzzwords","MICES"],"title":"今年もMICESにオンライン出張してた"},{"contents":"今年もBerlin Buzzwordsにオンライン出張してました。 今年の開催は6月14日から17日まででした。 どんなカンファレンスなのかは昨年のブログ記事をごらんください。\n今年はHAYSTACKは共同開催で、MICESは別開催でした。 MICESにも参加していたので、また後日にブログ記事を公開する予定です。\n参加したセッション 参加したセッションの個人用のメモを取ってあるので、簡単にまとめておきます。 セッションページに動画やスライドも追加されつつあります。興味のある方はそちらをご覧いただければと。 (今のところYouTubeに上がっているビデオは69本あります。再生リストはこちら) 気になっていたセッションもあるので、ビデオを見てまたメモを公開すると思いますが、まずは第1弾を。 ちなみに、検索をメインに見ています。Berlin Buzzwords自体はオブザバビリティやOSSコミュニティ、データのストリーミングの話などの話題もあるので、この辺りも興味があれば探してみても面白いかもです。\nHow to measure Diversity of Search Results セッションページ: How to measure Diversity of Search Results | Berlin Buzzwords 2021 従来の検索では、クエリに対して精度の高い検索結果を1件または数件返すのはどうするか?というものだったが、最近、あるユースケース(ほかの物の発見を促したいケース)では 検索結果の多様性を高めつつ、精度もある程度確保したいという場合があります。\nざっくりした検索クエリ(例えば自転車)の場合に、自転車だけが1ページ目にある場合よりも自転車とは別に自転車グッズも表示された場合のほうがクリック率やGMV(Gross Merchandice Value?)が上がったという話が紹介されていました。 この時どのくらい混ぜればいいのか?というのを、シャノンのエントロピーを使って、検索結果の多様性を保つための具体的なヒントについて話をされています。 実際にこういう計算をしてやれますねという紹介がされています。\nFrom text search and recommendation to ads and online dating; approximate nearest neighbors in real world applications セッションページ: From text search and recommendation to ads and online dating; approximate nearest neighbors in real world applications | Berlin Buzzwords 2021 Vespa.ai(OSS)の紹介でANNの話でした。通常、ANNを用いた検索の場合に他の検索条件(地理情報、日付など)をANNの結果に対して適用すると、望んでいる数がとれないです。その場合に、Vespaは内部でいい感じの動きをしますよという紹介でした。\n\u0026ldquo;Are You Sure?\u0026quot;: blending product comparisons and recommendations with A.I. セッションページ: \u0026ldquo;Are You Sure?\u0026quot;: blending product comparisons and recommendations with A.I. | Berlin Buzzwords 2021 Amazonの製品ページにある、類似商品との比較一覧のような一覧をどうやって実現するか?という話でした。比較一覧に掲載する商品を選出するパイプラインをこうやれますよね?という話でした。ログ(クリックやカートに入れたかどうかなど)を元にkNNで似ているデータを洗い出し、どの商品、どの項目を比較一覧として選ぶかという流れでした(セッションではもっと詳しい話がされています)。オフライン実験の話までがセッションでされています。\nThe future of Lucene\u0026rsquo;s MMapDirectory: Why use it and what\u0026rsquo;s coming with Java 16 and later? セッションページ: The future of Lucene\u0026rsquo;s MMapDirectory: Why use it and what\u0026rsquo;s coming with Java 16 and later? | Berlin Buzzwords 2021 Apache Lucene PMCのUweさんによるLuceneのMMapDirectoryの話です。 ファイルシステムとJavaに関する歴史と、なぜMMapなのか、現在のMMapの実装の問題点とJDK 16でどうなっているか(どんな感触か)、さらにその先(JDK17)は?という話です。 Luceneでの利用方法からJDKへのフィードバックが行われている話や、そのフィードバックをもとに今後どのようにしていくのか?という話がされています。\nSearch and Sushi; Freshness Counts セッションページ: Search and Sushi; Freshness Counts | Berlin Buzzwords 2021 こちらもVespa.aiの紹介です(今年はスポンサーしてるから多いのかも?)。Yahoo!とVerizon Mediaで利用している話をしたあと、Vespaでのリアルタイムインデキシングに関するアーキテクチャの紹介でした。内部で転置インデックスやそれ以外のデータをどのように保持しているのか?どういったことができるのか?というのをアーキテクチャ、ストレージの観点から紹介しています。\nEncores? - Going beyond matching and ranking of search results セッションページ(動画がまだない): Encores? - Going beyond matching and ranking of search results | Berlin Buzzwords 2021 検索のマッチングやランキング以外のいくつかの機能についての紹介をワークショップ形式で行うセッションです。ファセット、クエリオートコンプリート、スペル訂正、クエリリラクゼーションについて、データとSolrのクエリを基準に説明をしてくれます。\nThe Invasion of Transformers - Boosting Search with Latest NLP セッションページ: The Invasion of Transformers - Boosting Search with Latest NLP | Berlin Buzzwords 2021 deepsetという会社のCTOの方で、自社で作っているOSSのhaystackという製品の紹介です。 最近のGoogleの検索結果にはいろんなもの(問いかけに関する答えそのもの、またそのプレビューやサマリー)が出てきているという話から、Transformersを使って検索ができないかということで自社のOSSの仕組みを紹介しています。\n参考 Google: BERT now used on almost every English query deepset-ai/haystack: End-to-end Python framework for building natural language search interfaces to data. Leverages Transformers and the State-of-the-Art of NLP. Supports DPR, Elasticsearch, Hugging Face’s Hub, and much more! Learning to Judge セッションページ: Learning to Judge | Berlin Buzzwords 2021 otto.deというECサイトでLtRを導入し、そのLtRにどんな特徴を利用しどうやって実験したかというセッションでした。Apache Solrで検索ができていて、これまでは検索の管理を人手で行っていたがスケールしない(扱う商品などは増えているのに)のでLtRを導入し始めたという感じでした。LtRの導入の過程でどういう仮定を置いて、どうモデルを決め、それをどうやってテストしてどう分析したか?という流れでした。\nText categorization with Apache Lucene セッションページ: Text categorization with Apache Lucene | Berlin Buzzwords 2021 LTなので短めです。BBCのデータセットをインデックスに登録し、そのデータをもとにLucene(デモではKibana+Esを利用していた)でテキスト分類を行なう方法について紹介しています。BBCのデータセットは記事(テキスト)とカテゴリ(タグ)というデータです。 このデータが登録されているインデックスに対して、More Like Thisクエリに分類したい文章を与え、ヒットしたデータをもとにAggregationでカテゴリを取得し、上位のカテゴリが分類された結果になるというデモでした。 テキストフィールドにはEdge N-Gramを利用していること、Aggregationのソートの条件はMore Like Thisクエリでのスコアの平均を利用していることというのがこの方法がうまくいくことのようでした(なるほど!)。ただ、日本語でもこれが使えるかな?というのはやってみないとわからないかなぁと(やってないです)。\nとりあえず、メモしておいたのはこの辺でした。 他にもセッション一覧を眺めながら面白そうな話をピックアップしてメモを取っていこうかなぁ?気になるセッション、メモがおかしいなどあればコメントいただければと。\n","date":1625815493,"dir":"post/2021/","id":"59b7b60e6bbf4858d72643d22ad90451","lang":"ja","lastmod":1625815493,"permalink":"https://blog.johtani.info/blog/2021/07/09/berlin-buzzwords-2021-1/","publishdate":"2021-07-09T16:24:53+09:00","summary":"今年もBerlin Buzzwordsにオンライン出張してました。 今年の開催は6月14日から17日まででした。 どんなカンファレンスなのかは昨年","tags":["conference","berlin buzzwords"],"title":"今年もBerlin Buzzwordsにオンライン出張してた"},{"contents":"Azure Cognitive Searchで新機能「Semantic Search(セマンティック検索)」という機能の日本語対応が発表されました。 実際にはPublic Previewという状態ではありますが、どんな機能か気になったので調べてみました。 なお、本ブログは2021年6月時点での内容となります。\n公式ドキュメント 公式ドキュメントでいろいろと説明されています。まずは公式ドキュメントを見ていただくのが良いかなと。最初のドキュメントには10分ちょっとの紹介ビデオもあります。ピックアップしたのは概要、クエリ、レスポンスの構造、紹介ブログになります。ブログ以外は日本語(たぶん機械翻訳?)になっています(新機能の紹介の日本語ページにはまだ記載がありません)。\nSemantic search - Azure Cognitive Search | Microsoft Docs Create a semantic query - Azure Cognitive Search | Microsoft Docs Structure a semantic response - Azure Cognitive Search | Microsoft Docs The science behind semantic search: How AI from Bing is powering Azure Cognitive Search - Microsoft Research 簡単にですがデータを入れて試してみたので、どんな仕組みなのかどういう挙動なのかを紹介します。\nSemantic Searchとは? 言語理解、セマンティック関連性などを提供する機能です。BingとMSリサーチにより開発されて、Azure Cognitive Searchに導入されました。 クエリの書き方を少し変更する必要がありますが、再インデックスや設定変更などは必要ないという仕組みになっています。\n検索クエリからコンテキストを読み取って、検索し、リランクするアルゴリズム(Semantic Ranker) 関連する一節を強調表示(Semantic Caption) クエリに対するセマンティック回答(Semantic Answer) スペルチェック機能 言語によって利用できる機能が異なります。\nSemantic Searchの利点は先ほどの紹介にも書きましたが、インデキシング時に特殊処理をする必要がないことかなと。 すでに登録してあるデータ(制限がありますが)でもすぐに試すことができます。\n仕組み https://docs.microsoft.com/ja-jp/azure/search/media/semantic-search-overview/semantic-query-architecture.png\nスペル修正機能 クエリパース スコアリング 上位50件に対してSemantic Rankerにより再評価(検索ヒットが50件以上の場合でも上位50件のみがリランクの対象) 言語表現モデルを利用 結果の要約として最適な部分をキャプションとして抽出。 クエリが質問形式の場合は一番よさそうな場所を回答として選択 1および4番目の処理が今回新しく使えるSemantic Searchの機能になります。スペルチェックは日本語がまだ対象外なので、4番目の機能について紹介します。\n利用できる環境と制限 冒頭でも書きましたが、Public Previewの段階です。実際に利用するにはリクエストページから申し込みが必要になっています。\n利用リクエスト時に利用するAzure Cognitive Searchのサービス名が必要になるので、あらかじめ起動しておかなければいけません。 また、利用できるリージョンが限定されているのでサービス起動時のリージョンには気を付けてください。\n利用できるリージョン 米国中北部、米国西部、米国西部 2、米国東部 2、北ヨーロッパ、西ヨーロッパ 利用できるTier セマンティック検索はStandardレベル スペルチェックはレベル制限なし 価格(セマンティック検索のみ) 7月初旬までは25万クエリで500ドル Analyzerの制限 Azure Cognitive Searchが提供する言語アナライザーが対象(Custom Analyzerでは利用不可) サービス起動後にプレビュープログラムを申請すると、利用できるようになるとメールが届きます。そこから利用ができるようになります。\n今回は日本語のWikipediaのデータをいれてどんな機能なのかを確認してみました。\nWikipediaのデータを入れて試してみた 日本語のWikipedia(あとで英語も入れました)を一部(10万件程度)登録してSemantic Search(主にRanker)の動きを確認してみました。\nデータの登録には自作ツールを利用。\nJSONデータ生成ツール:https://github.com/johtani/wiki-extractor-rs JSONデータ登録ツール:https://github.com/johtani/wiki-json-loader 日本語Wikipediaの2020年6月のデータ、英語Wikipediaの2021年6月のデータを利用。上記ツールで生成したもののうち約10万件をAzure Cognitive Searchに登録して動作確認をしました(英語のデータでJSONデータ生成ツールでバグがあるのですが修正していません。。。)。 また、クエリの実行にはVisual Studio CodeのREST Client拡張(どんなものかは以前のブログをご覧ください)を使いました。簡単にREST APIを呼び出せるのはすばらしい。\n日本語のWikipedia 日本語のWikipediaのデータを「96,344件」登録し実験しました。 スキーマは次のような形です(説明に必要なものだけ抽出してあります)。自然分が入っているtitle、contents、headingsの3つのフィールドを今回はSemantic Searchの対象にしてみるので、AnalyzerをLuceneベースの日本語Analyzerであるja.luceneを設定しました。\nフィールド名 : タイプ / Analyzer id : Edm.String / keyword categories : Collection(Edm.String) / keyword title : Edm.String / ja.lucene contents : Edm.String / ja.lucene headings : Edm.String / ja.lucene Analyzerに言語Analyzerを設定するくらいで、他の設定は特に必要ありません。\nクエリとデータの確認 デモの動画や説明のサンプルを見たところ英語で「Where was Alan Turing born?」や「What\u0026rsquo;s the capital of France?」のような自然文のクエリが出てきたので、次のようなクエリで試してみました。\nフランスの首都はどこですか? 実際にパリのページがインデックスに存在していることは以下のクエリで確認しました。\nパリ:3047件 POST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;パリ\u0026#34;, \u0026#34;top\u0026#34;: 10, \u0026#34;searchFields\u0026#34;: \u0026#34;title, categories, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id, contents\u0026#34; } ※ここで{{host}}などはREST Client拡張で変数として定義したものです。\nhost : Azure Cognitive Searchのサービス名 index-name : インデックス名 api-key : 接続のためのAPIキー URLパラメータのapi-version=2020-06-30-PreviewがPreview機能を呼び出すための指定になっています。\n3047件の1件目が「パリ」のページで以下のようなWikipediaの文章をセクションごとに文字列としてページ全体を配列に入れてcontentsに登録してあります。\n\u0026#34;パリ(、巴里)は、フランス北部、イル=ド=フランス地域圏にある都市。フランスの首都であり、イル=ド=フランス地域圏の首府である。\\nフランス最大の都市であり、同国の政治、経済、文化などの中心である。ロンドンと共に欧州を代表する世界都市。行政上では、1コミューン単独で県を構成する特別市であり、ルーヴル美術館を含む1区を中心に、時計回りに20の行政区が並ぶ(エスカルゴと形容される)。\u0026#34;, このインデックスに対して「フランスの首都はどこですか?」というクエリを、セマンティック検索のクエリと通常のクエリの2パターンで検索をしてみました。\nこれまでのクエリ(セマンティックではない検索) まずは通常のクエリです。 searchがクエリ文字列、searchFieldsが検索対象フィールドになります。\nPOST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;top\u0026#34;: 100, \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;フランスの首都はどこですか?\u0026#34;, \u0026#34;searchFields\u0026#34;: \u0026#34;title, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id\u0026#34; } クエリを実行するとヒット件数が'13996\u0026rsquo;件で、トップ5件のデータは次のようになりました。\n\u0026#34;@odata.count\u0026#34;: 13996, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 17.059355, \u0026#34;id\u0026#34;: \u0026#34;462\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;首都\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 16.086372, \u0026#34;id\u0026#34;: \u0026#34;21053\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;首都圏\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 15.059893, \u0026#34;id\u0026#34;: \u0026#34;71414\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;どこでもドア\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 14.086605, \u0026#34;id\u0026#34;: \u0026#34;51972\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;首都機能移転\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.996841, \u0026#34;id\u0026#34;: \u0026#34;3877\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;首都の一覧\u0026#34; }, 見るとわかりますが、「首都」「どこ」といった単語を含むデータが上位に入っています。「フランス」を含むデータは8件目と10件目に「フランス植民地帝国」、「ラ・フランス」といったデータが出てきます。\n{ \u0026#34;@search.score\u0026#34;: 12.705561, \u0026#34;id\u0026#34;: \u0026#34;129279\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;フランス植民地帝国\u0026#34; }, ... { \u0026#34;@search.score\u0026#34;: 12.036648, \u0026#34;id\u0026#34;: \u0026#34;3173\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ラ・フランス\u0026#34; }, 残念ながら望んでいる結果にはほど遠いかと。\nどんな検索になっているのでしょうか?まずは、クエリの解釈から。 デフォルトで、Azure Cognitive Searchはデフォルトでは、入力された文字列をtype=simple、mode=anyで検索します(クエリパラメータ参照)。 対象となるフィールドはsearchFieldsで今回は指定してあるので、これらのフィールドに対して、入力された文字列を渡してAnalyzerで単語分割し(今回はsimpleクエリ用の特殊文字が入っていないため文字列として扱われる)、 出てきた単語で(mode=anyだから)OR検索します。 ja.luceneのAnalyzerが出力する単語列がどんなものかは以下のリクエストを実行するとわかります。\nPOST https://{{host}}/indexes/{{index-name}}/analyze?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;analyzer\u0026#34;:\u0026#34;ja.lucene\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;フランスの首都はどこですか?\u0026#34; } 結果は以下の通りです。\n\u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;フランス\u0026#34;, \u0026#34;startOffset\u0026#34;: 0, \u0026#34;endOffset\u0026#34;: 4, \u0026#34;position\u0026#34;: 0 }, { \u0026#34;token\u0026#34;: \u0026#34;首都\u0026#34;, \u0026#34;startOffset\u0026#34;: 5, \u0026#34;endOffset\u0026#34;: 7, \u0026#34;position\u0026#34;: 2 }, { \u0026#34;token\u0026#34;: \u0026#34;どこ\u0026#34;, \u0026#34;startOffset\u0026#34;: 8, \u0026#34;endOffset\u0026#34;: 10, \u0026#34;position\u0026#34;: 4 } ] これで、どのような単語が出てきているかがわかりました。 それぞれのフィールドでどのようなスコアになっているかまではわからないですが、検索結果には上記3つの単語のいずれかがsearchFieldsにヒットすれば出てきます。おそらく、ヒットした単語数が多い、短い文字列のフィールドがより高いスコアになるというような動きになっていると思われます(BM25になってるはず)。\nセマンティック検索 では、セマンティック検索のクエリに変更してみましょう。\nPOST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;top\u0026#34;: 100, \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;フランスの首都はどこですか?\u0026#34;, \u0026#34;searchFields\u0026#34;: \u0026#34;title, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id\u0026#34;, \u0026#34;queryType\u0026#34;: \u0026#34;semantic\u0026#34;, \u0026#34;queryLanguage\u0026#34;: \u0026#34;ja-jp\u0026#34; } queryType、queryLanguageがセマンティック検索のクエリを実行するためのパラメータになります(公式ガイド参照)。 今回は日本語のデータであるため、日本語のモデルを利用するようにqueryLanguageを指定します(許可されていない文字列を渡すとエラーになる)。 この2つを追加するだけです。簡単ですね。\n結果は次のようになります(上位5件抜粋)。\n\u0026#34;@odata.count\u0026#34;: 13996, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 12.036648, \u0026#34;@search.rerankerScore\u0026#34;: 2.3456064984202385, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;ラ・フランス\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;ラ・フランス\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;3173\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ラ・フランス\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 11.144733, \u0026#34;@search.rerankerScore\u0026#34;: 2.3173404783010483, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;ラン (フランス)\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;ラン\u0026lt;/em\u0026gt; (\u0026lt;em\u0026gt;フランス)\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;108094\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ラン (フランス)\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 11.144793, \u0026#34;@search.rerankerScore\u0026#34;: 2.1937477812170982, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;ブレスト (フランス)\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;ブレスト\u0026lt;/em\u0026gt; (\u0026lt;em\u0026gt;フランス)\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;116154\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ブレスト (フランス)\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 10.199907, \u0026#34;@search.rerankerScore\u0026#34;: 2.1590753793716431, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;フランス・ハルス\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;フランス・ハルス\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;81566\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;フランス・ハルス\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 11.273148, \u0026#34;@search.rerankerScore\u0026#34;: 2.1434053033590317, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;バカロレア (フランス)\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;バカロレア\u0026lt;/em\u0026gt; (\u0026lt;em\u0026gt;フランス\u0026lt;/em\u0026gt;)\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;54514\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;バカロレア (フランス)\u0026#34; }, 検索結果数を見ると、通常のクエリと同じ値です。 これは、公式ドキュメントのセマンティック検索に説明があるように、 セマンティック検索が通常のクエリで実行した後の検索結果に対して、上位50件のデータだけに対してsemantic rankerによってスコアを再計算するという仕様のためです(ドキュメントからの推測)。\n実際に検索結果の50件目、51件目は次のようになっていました。50件目までのデータには@search.rerankerScoreというスコア(と@search.captions)が追加されています。 51件目のデータについては、前の通常のクエリの51件目のデータと同じデータでした。\n{ \u0026#34;@search.score\u0026#34;: 10.909212, \u0026#34;@search.rerankerScore\u0026#34;: 0.07321979058906436, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;首都高速埼玉大宮線\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;67667\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;首都高速埼玉大宮線\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 10.049902, \u0026#34;id\u0026#34;: \u0026#34;68569\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;スタッド・ド・フランス\u0026#34; }, 上位5件のデータに戻ります。 これらは、通常のクエリとは異なる結果となりました。 見ると@search.captionsというところにハイライトされた項目が表示されています。 検索クエリをもとにそれっぽい部分がキャプションという形で返ってくる仕組みです。\n結果を見るとわかりますが、残念ながら「パリ」のページは返ってきませんでした。 もともと通常のクエリを実行したときの「326」番目の結果として返ってきているため、セマンティック検索の対象とはならなかったためです。 ただ、「首都」「どこ」といった単語よりも「フランス」に関するドキュメントが通常の検索よりも上位に来ています。 クエリに存在する単語で「フランス」がより重要であると判断されているようです。\nSemantic Rankerに処理させてみる ちなみに、今回登録したデータにはWikipediaのカテゴリも登録してあります。 「ヨーロッパの首都」というカテゴリで絞り込んでから検索してみるとどうなるかもやってみました。 filterのパラメータが絞り込み条件です。\nPOST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;top\u0026#34;: 100, \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;フランスの首都はどこですか?\u0026#34;, \u0026#34;searchFields\u0026#34;: \u0026#34;title, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id\u0026#34;, \u0026#34;queryType\u0026#34;: \u0026#34;semantic\u0026#34;, \u0026#34;queryLanguage\u0026#34;: \u0026#34;ja-jp\u0026#34;, \u0026#34;filter\u0026#34;: \u0026#34;search.ismatch(\u0026#39;ヨーロッパの首都\u0026#39;, \u0026#39;categories\u0026#39;)\u0026#34; } 結果は次の通りです。カテゴリで絞り込みをしているので検索結果数は39件となります。このため、すべてのデータがSemantic Rankerの対象です。 ですが、「パリ」のページは11件目に出てきました。\n\u0026#34;@odata.count\u0026#34;: 39, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 3.8405614, \u0026#34;@search.rerankerScore\u0026#34;: 2.0472740978002548, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;ウィーン\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;9465\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ウィーン\u0026#34; }, ... { \u0026#34;@search.score\u0026#34;: 4.8915977, \u0026#34;@search.rerankerScore\u0026#34;: 1.8480307757854462, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;レイキャヴィーク\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;レイキャヴィーク\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;112253\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;レイキャヴィーク\u0026#34; }, ... { \u0026#34;@search.score\u0026#34;: 7.277628, \u0026#34;@search.rerankerScore\u0026#34;: 1.7982495501637459, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;パリ\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;パリ\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;31\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;パリ\u0026#34; }, キャプションは入力された単語だけではなく、クエリが持っている単語をもとにした何かしらの基準(おそらく言語モデルで近い単語?)で選択されていると思われます。首都というカテゴリーで絞り込んでしまったので、ヒットした文章が似たようなものが多くなったせいか、残念ながらそこまでSemantic Rankerが意図を汲み取るところまでは行きませんでした。\nフランスの歴史 視点を変えてみましょう。質問そのものの答えではなく、クエリの意図に近いものが出てくるかを見てみましょう。 ここまでのクエリでフランスに関するクエリを投げていました。今回のインデックスに「フランスの歴史」で検索すると「30820」件のドキュメントがヒットし、上位にはフランスには関係ない「歴史」のページや「フランス」の文学、都市など「フランスの歴史」とは少し離れた意味のものが上位に来ています。\n\u0026#34;@odata.count\u0026#34;: 30820, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 12.888079, \u0026#34;id\u0026#34;: \u0026#34;17875\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;スコットランドの歴史\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.718105, \u0026#34;id\u0026#34;: \u0026#34;10665\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;世界の歴史\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.701981, \u0026#34;id\u0026#34;: \u0026#34;31397\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ベトナムの歴史\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.579847, \u0026#34;id\u0026#34;: \u0026#34;22433\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;フランス文学\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.524254, \u0026#34;id\u0026#34;: \u0026#34;34667\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;フランスの国旗\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.52136, \u0026#34;id\u0026#34;: \u0026#34;108094\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ラン (フランス)\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.41088, \u0026#34;id\u0026#34;: \u0026#34;20717\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;歴史小説\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.388911, \u0026#34;id\u0026#34;: \u0026#34;56229\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;演劇の歴史\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.343941, \u0026#34;id\u0026#34;: \u0026#34;39669\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;イギリスの歴史\u0026#34; }, このクエリをセマンティッククエリで検索すると次のようになりました。\n\u0026#34;@odata.count\u0026#34;: 30820, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 12.274498, \u0026#34;@search.rerankerScore\u0026#34;: 1.482184374704957, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;自由フランス\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;自由フランス\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;96475\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;自由フランス\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 11.446766, \u0026#34;@search.rerankerScore\u0026#34;: 1.3535655084997416, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;フランスの地域圏\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;フランスの地域圏\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;51845\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;フランスの地域圏\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 10.926437, \u0026#34;@search.rerankerScore\u0026#34;: 1.3261859538033605, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;フランス第一帝政\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;フランス第一帝政\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;57573\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;フランス第一帝政\u0026#34; }, 上位には「フランスの歴史」に関連しそうなタイトルが上がってきています。 また、先ほど「歴史」という単語でヒットして上位に来ていた「スコットランドの歴史」は@search.rerankerScoreの値が低くなっていました(31件目に出現)。\n{ \u0026#34;@search.score\u0026#34;: 12.888079, \u0026#34;@search.rerankerScore\u0026#34;: 0.42768346797674894, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;スコットランドの歴史\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;17875\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;スコットランドの歴史\u0026#34; }, 考察 日本語のWikipediaを約10万件入れたインデックスでセマンティック検索を試してみました。 デモや説明などでクエリが自然文の質問だったこともあり、質問の回答になりそうなページが上に来るかと期待しましたが、期待しすぎました。\nこれは、Azure Cognitive Searchのセマンティック検索の仕組みを考えると納得のいくものです。 説明を読んだ時にも感じたのですが、入力された文字列でまず検索をし、上位50件をセマンティック検索の対象としています。\nですので、そもそもクエリの文章に出てくる単語が含まれたデータだけが対象となります。 このため、クエリに出てこない単語のみで構成されているものは残念ながら対象とできません。 また、上位50件だけがSemantic Rankerの対象となっているため、検索にヒットしたとしても上位に食い込まなければ言語モデルによるランキングの対象にもなりません。 セマンティック検索といっても、残念ながらドキュメントに出てこない単語(似た単語、質問に対するそのものの回答)まで読み取る機能はありません。\nただ、「フランスの歴史」の検索で見たようにそれぞれの単語だけで検索をしていた場合とは異なり、 クエリの意味に沿ったスコアづけにより、通常の検索よりも意図したものに近いデータが出ていることが確認できました。 複数の単語で構成されるクエリの場合に、単語だけでスコアを計算した場合よりもよさそうな結果が上位に出てくることがわかりました。\nただし、重要なのは「上位50件」までしかSemantic Rankerの対象にはならない点です。\n英語のWikipedia セマンティックは英語対応が一番最初にリリースされているので、英語のWikipediaについてもデータを登録してみました。\n英語のWikipediaのデータを「111,649件」登録しました。 スキーマは以下の通り(今回の調査に利用していないものは省略)です。日本語と異なる点はAnalyzerがen.luceneになっていることぐらいです。\nフィールド名 : タイプ / Analyzer id : Edm.String / keyword categories : Collection(Edm.String) / keyword title : Edm.String / en.lucene contents : Edm.String / en.lucene headings : Edm.String / en.lucene クエリとデータの確認 日本語同様に首都に関する質問形式にしてみました。\nWhat\u0026rsquo;s the capital of Italy? 実際にRomeのページがインデックスに存在していることは以下のクエリで確認済みです。\nRome:2302件\nPOST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;Rome\u0026#34;, \u0026#34;top\u0026#34;: 10, \u0026#34;searchFields\u0026#34;: \u0026#34;title, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id, contents\u0026#34; } 以下のようなWikipediaの文章をセクションごとに文字列としてページ全体を配列に入れてcontentsに登録してあります(これも日本語と同じです)。\n\u0026#34;\u0026#34;\\n\\nRome (Italian and Latin: Roma ) is the capital city and a special comune of Italy (named Comune di Roma Capitale), as well as the capital of the Lazio region. The city has been a major human settlement for almost three millennia. With 2,860,009 residents in , it is also the country\u0026#39;s most populated comune...\u0026#34;, このデータ群に対して「What\u0026rsquo;s the capital of Italy?」というクエリを、Semantic Searchのクエリと通常のクエリの2パターンで検索をしてみる。\nこれまでのクエリ(セマンティックではない検索) まずは、Semantic Searchではないクエリです。\nPOST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;top\u0026#34;: 100, \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;What\u0026#39;s the capital of Italy?\u0026#34;, \u0026#34;searchFields\u0026#34;: \u0026#34;title, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id\u0026#34; } ヒット件数は18049件で、トップ5件は次のような形です。\n\u0026#34;@odata.count\u0026#34;: 18049, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 17.870815, \u0026#34;id\u0026#34;: \u0026#34;14532\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Italy\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 16.596167, \u0026#34;id\u0026#34;: \u0026#34;14702\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Economy of Italy\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 16.180624, \u0026#34;id\u0026#34;: \u0026#34;183878\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Louis II of Italy\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 15.917025, \u0026#34;id\u0026#34;: \u0026#34;29665\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;State capitalism\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 15.88901, \u0026#34;id\u0026#34;: \u0026#34;215741\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Capitalization\u0026#34; }, 日本語の場合よりもItalyに関連するものが上位に多く含まれます。 ただ、Rome自体のページは上位50件には出てきていませんでした。 また、capitalとは意味の異なるcapitalizationやcapitalismが上位に来ています。 日本語の場合と同様にクエリがどのように解釈されているのか?も見てみます。\nPOST https://{{host}}/indexes/{{index-name}}/analyze?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;analyzer\u0026#34;:\u0026#34;en.lucene\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;What\u0026#39;s the capital of Italy?\u0026#34; } 結果は以下の通りです。\n\u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;what\u0026#34;, \u0026#34;startOffset\u0026#34;: 0, \u0026#34;endOffset\u0026#34;: 6, \u0026#34;position\u0026#34;: 0 }, { \u0026#34;token\u0026#34;: \u0026#34;capit\u0026#34;, \u0026#34;startOffset\u0026#34;: 11, \u0026#34;endOffset\u0026#34;: 18, \u0026#34;position\u0026#34;: 2 }, { \u0026#34;token\u0026#34;: \u0026#34;itali\u0026#34;, \u0026#34;startOffset\u0026#34;: 22, \u0026#34;endOffset\u0026#34;: 27, \u0026#34;position\u0026#34;: 4 } ] 日本語とあまり変わってはいません。ただ、単語が入力されたものとは少し変わっています。 これは、en.luceneの処理で、stemmingが行われているためだと思われます。たとえば、「capital」の場合、Stemmingにより「capital」「capitalize」などの単語が元になりますが、動詞、名詞などの違いなく検索できるようにするためにこのようなStemmingの処理が行われます。 ということで、これらの単語を含むドキュメントがヒットしています。Italyが一番上に来ているのはItalyという単語が多く含まれるからのようです。\nSemantic Searchクエリ では、Semantic Searchのクエリに変更してみましょう。\nPOST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;top\u0026#34;: 100, \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;What\u0026#39;s the capital of Italy?\u0026#34;, \u0026#34;searchFields\u0026#34;: \u0026#34;title, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id\u0026#34;, \u0026#34;queryType\u0026#34;: \u0026#34;semantic\u0026#34;, \u0026#34;queryLanguage\u0026#34;: \u0026#34;en_us\u0026#34; } queryType、queryLanguageがsemantic searchのクエリを実行するためのパラメータになります(公式ガイド参照)。 今回は英語のデータであるため、英語のモデルを利用するようにqueryLanguageを指定します(許可されていない文字列を渡すとエラーになる)。\n結果は次のようになります(上位5件抜粋)。\n\u0026#34;@odata.count\u0026#34;: 18049, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 17.870815, \u0026#34;@search.rerankerScore\u0026#34;: 1.9688458815217018, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Italy\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;14532\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Italy\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 14.239678, \u0026#34;@search.rerankerScore\u0026#34;: 1.9419755563139915, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Capital city\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;181337\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Capital city\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 10.181764, \u0026#34;@search.rerankerScore\u0026#34;: 1.8902588561177254, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Lepontii\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;325133\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Lepontii\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 10.865718, \u0026#34;@search.rerankerScore\u0026#34;: 1.875102698802948, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;ItalY\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;14482\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ItalY\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 11.689348, \u0026#34;@search.rerankerScore\u0026#34;: 1.8201303631067276, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Savoy\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;27885\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Savoy\u0026#34; }, 日本語で見てきたように、検索結果数を見ると、通常のクエリと同じ値で、残念ながら50件までにRomeは入っていないため、Semantic Rankerによるブーストもかかりませんでした。 ただし、「Capitalization」や「State capitalism」といった別の意味(地理に関するものではない単語)のものが上位に出てこなくなっています。 これは、capitalという単語が地理に関する意味を持っていると判断された結果のように見えます。 Capitalizationの@search.rerankerScoreは上位のスコアに比べて小さいものとなっています。\n{ \u0026#34;@search.score\u0026#34;: 15.88901, \u0026#34;@search.rerankerScore\u0026#34;: 0.93921028636395931, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Capitalization\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;215741\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Capitalization\u0026#34; }, What\u0026rsquo;s the capital of Finland? 上位50件以内(20件目)に「Helsinki」のページが出てくるクエリでセマンティック検索をしてみました。\nPOST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;top\u0026#34;: 100, \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;What\u0026#39;s the captial of Finland?\u0026#34;, \u0026#34;searchFields\u0026#34;: \u0026#34;title, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id\u0026#34;, \u0026#34;queryType\u0026#34;: \u0026#34;semantic\u0026#34;, \u0026#34;queryLanguage\u0026#34;: \u0026#34;en-us\u0026#34; } 結果としては、2件目にHelsinkiが返ってきていたので、Semantic Rankerがによる並び替えがうまくいきました。 (下記の結果は上位3件を抜粋したものです)。\n\u0026#34;@odata.count\u0026#34;: 16673, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 14.026371, \u0026#34;@search.rerankerScore\u0026#34;: 2.42378556355834, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Vanaja (Finland)\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;7132102\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Vanaja (Finland)\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.434971, \u0026#34;@search.rerankerScore\u0026#34;: 2.383675143122673, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Helsinki\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;13696\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Helsinki\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 13.380153, \u0026#34;@search.rerankerScore\u0026#34;: 2.2026549801230431, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Rauma, Finland\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;178635\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Rauma, Finland\u0026#34; }, 考察 今回の英語のクエリではSemantic Rankerがある程度の役割をはたしていそうだということはわかりました。 Capitalがいくつもの意味を持っていることもあり、文章をもとにより意味の近いドキュメントが上位に来たということです。 ただ、英語の場合も基本的には上位50件以内のデータに対して処理が行われるので上位50件以内にデータが入らなければうまくいかないようです。\nまとめ Azure Cognitive Searchの新機能であるセマンティック検索について調べてみました。 まだPublic Previewですが、簡単に使えるような仕組み(データの再登録なし、クエリでパラメータを追加するだけ)が用意されているのは便利でした。 ただ、最初に想像していたもの(私の早とちりもありますが)ほどのセマンティック検索とは行きませんでした。 似たような言葉の意味を持ったものを探してくれたり、答えそのもののページのスコアがすごく高くなるといったものではありませんでした。\n仕組み上、クエリに含まれる単語で検索し、上位50件以内のデータだけが対象になる(残念ながら現時点ではこの件数の変更はできません。)ため、これまでの検索とは劇的に変化するものではないことはわかりました(銀の弾丸はないんですけどね)。\nある程度の挙動をわかっていれば、Wikipediaのようなデータでもそれなりの結果は取得できそうだということはわかりました。\n「言語モデル」でクエリとヒットしたデータをもとにスコア計算をし直しているようですが、この部分がどのようなデータ・クエリだと有効活用できるのか?というのをもう少しいろいろな角度で試してみる必要がある気がします(適材適所が何なのか?)。 あとは、上位50件までが対象なので、それ以上の件数のデータの並びに関してはこれまでと同様の結果となる点は注意しないといけません。 また、今回試していないほかの機能(スペルチェック、Semantic Answerなど)にメリットがあるのかもしれません。\nざっくりですがセマンティック検索について調べてみました。 こんなデータだとどうなの?ここの考え方が間違ってるのでは?などの指摘がありましたら、コメント欄またはTwitter(@johtani)でコメントを頂けたらと。\n","date":1625130583,"dir":"post/2021/","id":"43caef5d41c4e74826e4a8d82088739d","lang":"ja","lastmod":1625130583,"permalink":"https://blog.johtani.info/blog/2021/07/01/semantic-search-in-azure-cognitive-search/","publishdate":"2021-07-01T18:09:43+09:00","summary":"Azure Cognitive Searchで新機能「Semantic Search(セマンティック検索)」という機能の日本語対応が発表されました。 実際にはPublic P","tags":["azure search"],"title":"Azure Cognitive Searchの新機能、Semantic Searchを試してみた"},{"contents":"Sofle v2を長らく使っていましたが、コンパクトなのもやっぱりいいよなぁというときにKochi KeyboardからLunakey Miniが発売していました。 小指のあたりの傾斜が使いやすいかも?ということで、組み立ててみました。\nもちろん購入はKochi Keyboardさんからです(購入はこちらから)。\nLunakey Miniビルドガイド 作者のYoichiroさんが公開しているビルドガイドが詳細まで書かれています。 こちらをまずは参照してください。\nLunakey Mini ビルドガイド (Rev.4以降) ビルドログ(主にツイート) 私の組み立てについては、Twitterでツイートしていたものがありますので、そちらを貼っておきます。 ちなみに、ツイートしていて躓いているときに、作者のYoichiroさんからたびたびコメントをいただきました。 ありがとうございました!!\n間にいくつかコメントを差し込んでいます。\n結局両方のダイオードつけてしまいました。今日はここまで pic.twitter.com/3qLI6EpfXB\n\u0026mdash; Jun Ohtani (@johtani) April 12, 2021 ハンダはつけた pic.twitter.com/ySE9SA3gZn\n\u0026mdash; Jun Ohtani (@johtani) April 13, 2021 コンスルー問題 左手じゃん、T。Tのダイオード浮いてた。右手も一回全部見直すか\n\u0026mdash; Jun Ohtani (@johtani) April 13, 2021 ここで問題が発覚。右手(ツイートではぼけていて、左手と書いています)についてはダイオードが1か所浮いていただけなので、はんだ付けですぐ直りました。 左手側が大問題です。そもそも右手につけたProMicroへの書き込みができませんでした。 キーボードによっては、ダイオードなどを付ける前からまず、リセットボタンを付けて、ProMicroを指して書き込みをする場合もあります。 ただ、その書き込みができない。 (ちなみにこのタイミングでテスターをつけっぱなしにしていたのが発覚し、9V電池切れのため翌日に持ち越した。。。)\nさて、デバッグのお時間です pic.twitter.com/CaEOv4E5Bg\n\u0026mdash; Jun Ohtani (@johtani) April 14, 2021 ただ、ProMicro刺した状態で、リセットボタン、リセットボタンの足をショートさせても書き込みはできず、ProMicroのGndとResetの足のショートでは書き込みができる。\n\u0026mdash; Jun Ohtani (@johtani) April 14, 2021 テスターで調べてみたところ、リセットボタンとProMicroがうまく通電していません。\nだいぶ進んだけど、Eの列がおかしいなぁ。さて、どこの接触だ? pic.twitter.com/5tci12Vk05\n\u0026mdash; Jun Ohtani (@johtani) April 14, 2021 どうも、左手の基盤のProMicroの足の穴がコンスルーとの接触が悪いみたいでした。 コンスルーの足を無理やりまげて(3個のコンスルーの足を折りました。。。)、通電できるようにして解決(結局あとでいくつかの足についてははんだ付けしました)。\n終わった。LEDの予備はんだまでやってからおしまいにしよ\n\u0026mdash; Jun Ohtani (@johtani) April 16, 2021 LED実装 鬼門の表面実装ですが、LEDを1個破損するだけで乗り切りました。ちょっと色はおかしかったですが、これはおそらくProMicroの足のせい。\n一個逆につけてしまい、お亡くなりになりましたが、まぁ、良いかな。まずは右手 pic.twitter.com/zldu6fRsXR\n\u0026mdash; Jun Ohtani (@johtani) April 18, 2021 ソケットの実装x2 ロープロファイル(Kailh choc v1)のキースイッチも試してみたいので、MXと両方のソケットをはんだ付けしました。 両方利用できるのは便利ですね。はんだ付けも楽しいし。\nソケットを片手だけ(両方のソケットつけるのでまだ、1/4) pic.twitter.com/7XFRDx0D0I\n\u0026mdash; Jun Ohtani (@johtani) April 18, 2021 キースイッチ設置 親指以外にはKailh Box Silentのピンク軸(Kochi Keyboardから)、親指にはKailh Input Club Hako Violet(AliExpressで購入したもの。リンクは遊舎工房のもの)をつけました。 どちらもそれほどぶれもないものです。Silent ピンクはリニアで静かでそれほど力がいらないスイッチになっています。 親指はタクタイルで小気味のいい音が気に入っています。Sofleもこのキースイッチになってます。\n残りのソケットつけて、キースイッチも設置して、動確してボトムプレートも装着。残りはキーキャップ。 pic.twitter.com/hGc1TtI6fu\n\u0026mdash; Jun Ohtani (@johtani) April 25, 2021 キーキャップ+キーマップ お試しにXDAのキーキャップをはめてみたのですが、キーの境目がわかりにくく、タイプミスが多かったです。 その後のツイートにあるようにOEMに切り替えています。\nキーマップについては、Lunakey Miniの作者のYoichiroさんが作ったRemapというブラウザベースでキーマップの書き換えができるツールで楽々変更ができました。JISキーまで対応しているのでJISベースでキーマップを作成している私にはうってつけでした。 Remapの利用方法についてはサリチル酸さんのブログが詳しく書いてあります(本当に頭が下がります)。\nRemap使ってキーマップいじったら、すごく楽だった。\n\u0026mdash; Jun Ohtani (@johtani) April 26, 2021 BLE + LPME-IO化 ここまでで、USB接続で動作はしていたのですが、Sofle同様に3台をBluetoothで切り替えながら使いたかったので、 Corne Light v2につけていたBLE+LPME-IO(Corneの実装などは前のブログを参照)を抜き取って、Lunakey Miniに移植してみました。\nBLE ProMicro化は作者の方のブログで行われていたので、LPME-IO対応も何とかなるだろうと。\nBLE+LPMEに変えた。後でブログ書こう pic.twitter.com/mGePN52v6k\n\u0026mdash; Jun Ohtani (@johtani) April 29, 2021 LPME-IOへの対応はCorneとSofleの時に行なったこともあり、なんとなくあたりがついていました。 流れとしては、以下の通りです。\nBLE Micro Pro用の設定ファイルを作成 BLE Micro Proのサイトの「キーボードの設定ファイルを編集する」のコマンドでコンフィグファイルを生成 LPME-IOのジャンパをはんだでブリッジ 1.で生成したコンフィグから、Corne Lightと同じ個所のジャンプをすれば良いとわかったので今回はスキップ TRRSのI2C対応 Corne LightのLPME-IO対応の時と同様にSDAとSCLをTRRSの足にショートカット ただ、今回右手側は、下記ツイートのようにOLEDの足からTRRSの足にショートカットしました。Corneの基盤を見ていた時にこれでも行けそうだな?と思っていたので、試してみた次第です。ちなみに、左手はCorneの時と同じPro Microから長い銅線を引っ張っています(電池基盤があったので、外すのがめんどくさかったため)。 BLE Micro Proにファームウェア書き込み BLE Micro Proのサイトの手順に従います。 設定ファイルには1.で出力されているLPME用のファイルを使用。 といった感じです。キーマップが設定されていないので、Remapで設定しなおしました。 Remapは、キーマップをPDFで出力する機能までついていて、すごくいいですね。サイコー\nあと、足。 pic.twitter.com/W0Wpf5k5SE\n\u0026mdash; Jun Ohtani (@johtani) April 29, 2021 傾斜がつくように奥側に高さを出すためのゴム足を貼り付けました。 あとは、3台のPCにBluetoothで接続すれば終了です。 (AD_WO_Lのキーを利用して追加していくのを毎回忘れる。。。)\n疑問点 ちょっとだけ疑問点がありますが、時間があればそのうち調べるかな。\nRemapはクラウドに設定ファイルをセーブできるけど、json形式で手元にダウンロードしたりはできないのかなぁ? LEDは有線じゃないと点かないみたいだけど、音はどうなんだろう? 音が出せそうなら、Bluetoothの接続切り替えするときに音の出方を変えるとかをやってみたいなぁ。 まとめ ということで、Lunakey Miniを組み立てて、BLE+LPME-IO対応してみました。 はんだ付けはだいぶ慣れてきましたし、今回もトラブルがあったおかげでテスターを利用して、どのあたりがおかしいかという調査をするのも慣れてきました。 あとは、キーの配置の違いを体感して、どれが自分に合ってるかなぁ?というのを試したり仕様と思います。 ロープロファイルも試してみようかな。\nあ。もちろん、このブログは組み立ててBluetoothで接続したLunakey Mini Rev5、Kailh Box Silentピンク軸+Input Club Hako Violetで書きました!!久々に数字列がないので記号入力とかがちょっとバタバタしましたw\n","date":1619709972,"dir":"post/2021/","id":"f4baa43cc7ca712d83b99a794c4e2dbd","lang":"ja","lastmod":1619709972,"permalink":"https://blog.johtani.info/blog/2021/04/30/build-lunakey-mini-ble/","publishdate":"2021-04-30T00:26:12+09:00","summary":"Sofle v2を長らく使っていましたが、コンパクトなのもやっぱりいいよなぁというときにKochi KeyboardからLunakey Miniが発売して","tags":["DIYキーボード","misc"],"title":"Lunakey Miniを組み立てて、BLE+LPME-IO化してみた #DIYキーボード"},{"contents":"みなさんは、スライドの作成には何を使っていますか? Keynote?Powerpoint?Google Slides?\n私は、Macでスライドを作るときは前職ではテンプレートもあったのでKeynoteでしたが、ちょっとしたものはMarkdownベースのDecksetを利用していました(買い切りタイプの有料ソフト)。\nフリーランスになってもこちらを利用していたのですが、Windows環境に切り替えたので使えなくなってしまいました。 一度はGoogle Slidesで作ったのですが(第39回Es勉強会スライド)、既存の資産を流用したくなりどうしたものかと悩んでい(ツイートし)たら。\nMacの頃はDecksetってアプリでMarkdownで書いてたんだけど、Winに移動したのでこのタイミングでGoogle Slidesにでもしようかなと考えてるところ。Markdownでスライド作るのほかになんかあるか探すほうがいいかなぁ?\n\u0026mdash; Jun Ohtani (@johtani) March 18, 2021 僕はこれ使ってますhttps://t.co/sFaAmKZY6V\n\u0026mdash; miyake | ZEN (@kazuyukimiyake) March 18, 2021 ということで、利用してみようかなとなりました。\nMarpとは? Markdownでプレゼンテーションのスライドを作ることができるOSS?になります。\nMarp公式サイト といっても、これ自体を使わなくても、VS Code上でプレビューしたりHTML形式で動作するスライドを吐き出すことが可能です。 なので、VS Code用のプラグインを利用しています。\nサンプル この間利用したスライドはこんな感じのMarkdownになってます。 ---でページを区切りつつ、記述していく形です。\n--- marp: true theme: poster --- \u0026lt;!-- _class: big-center --\u0026gt; # 本当にその検索は\u0026lt;br/\u0026gt;自分が想像している検索に\u0026lt;br/\u0026gt;なってますか? \u0026lt;br/\u0026gt; \u0026lt;br/\u0026gt; \u0026gt; 2021/03 \u0026gt; Jun Ohtani / @johtani --- ![bg right:40% 40%](johtani_face.jpg) # 自己紹介 - フリーランスエンジニア - 検索技術勉強会主催者 - Apache Solr入門(第2版まで)や データ分析基盤構築入門の著者の一人 --- プレビューで見るとこんな感じです。\nプラグイン Marp for VS Code プラグインをインストールするのも簡単ですよね。 マーケットプレイスからインストールすれば完了です。\n機能については上記のページにあるように、プレビューとスライドの出力です。 プレビューでは、Markdownのプレビューみたいな形で、スライドが表示できます。\n先日この機能を利用して作成して、HTMLで出力して利用しました。 PDFとかPPTX出も出せるようなので、今後試してみようかなと。\nDecksetのスライドとの違い ページの区切りなども同じだったので、大筋ではそれほど違いはありませんでした。 ただ、画像周りとスタイルの設定は細かく修正をしました。\n変更した点としては、以下のようなものがあります。\nヘッダ部分の変更 上のサンプルにありますが、marp: trueを含む部分がMarp独自の記述です。 ページごとのちょっとした変更 ページごとにスタイルの変更ができるみたいで(Decksetではできなかったはず?)、タイトルページのスタイルを変えてあります。 画像の指定 画像の読み込み自体は違いはないのですが、画像の配置についての指定方法は カスタムテーマ用CSSの作成 デフォルトではなく、Decksetで用意されているような感じのスタイルに変更してみてます。 カスタムテーマはCSSで設定できるので、CSSファイルを用意して、VS Codeの拡張機能の設定からファイルパスを指定する形です。\nということで、当面はMarpでスライドを作っていくことになるかと思います。 まぁ、ただ、スライドを作るいこと自体が減ってきてはいるのですが。 ほかの配色を試したり、ヘッダフッタとかも試してみるのもいいかもな。\n気が向いたら、CSSをどこかにアップロードするかもです。\n※今回のブログはGateronサイレントクリア軸をルブしてみた、Corne Light v2で最後の数行を書いてみました。 キースイッチだけだとこすれる音が減った気がしてましたが、キーキャップを付けたら少しこすれる音が気になる感じです。\n","date":1617615911,"dir":"post/2021/","id":"f41d4fde94cbd7bbd28808dc080a2019","lang":"ja","lastmod":1617615911,"permalink":"https://blog.johtani.info/blog/2021/04/05/intro-marp/","publishdate":"2021-04-05T18:45:11+09:00","summary":"みなさんは、スライドの作成には何を使っていますか? Keynote?Powerpoint?Google Slides? 私は、Macでスライドを作","tags":["勉強会"],"title":"スライド作成の環境をMarpにしてみた"},{"contents":"新型コロナウィルスの影響もあり、オフラインで集まって勉強会も開催できなくなっています。 検索技術勉強会も、もう1年以上開催できていないです。\nスピーカーの人にオンラインでしゃべってもらうのもありだとは思うのですが、 懇親会とセットでその価値があったかもなぁと思うところもあり、オンラインでの開催に乗り気になれないまま時間がたってしまいました。 (配信周りを調べるのがめんどくさいなぁというのもあったかも(反省))\nそんな中、takuya-aさんと話をしていて、エンジニア同士のゆるいつながりができる場所が欲しいですねぇということに。\nはー、検索技術勉強会、オフラインでできないまま1年以上たってしまったのか。オンライン勉強会とかはスピーカーの人の負担とかもあるし、Discordみたいなオープンな場だけ用意してみるのありかなぁ?ただ、活発に話がされるのかどうかわからんし、ROMな人ばかりだとアレなんだけどなぁ。\n\u0026mdash; Jun Ohtani (@johtani) March 30, 2021 そこからの、このツイートです。 ちらほらと興味のありそうな人が出てきたねという話をしていたら、Slackのワークスペースが出来上がってましたw\n検索技術に関する情報交換を目的とした Slack を立ち上げました!こちらの招待リンクからご参加ください。 https://t.co/Tca70vuMff\n\u0026mdash; takuya-a (@takuya_b) March 31, 2021 ありがとう、takuya-aさん!\nということで、検索周りでわいわいできる場になればいいなぁと。 盛り上がってくれば、オンラインでの勉強会とかもありかもしれないですね! 興味のある方は、上記ツイート内のリンクからご参加下さい!!\n","date":1617200894,"dir":"post/2021/","id":"ce426b7f3190c8a4a47d45ac799e91a4","lang":"ja","lastmod":1617200894,"permalink":"https://blog.johtani.info/blog/2021/03/31/search-tech-jp-slack/","publishdate":"2021-03-31T23:28:14+09:00","summary":"新型コロナウィルスの影響もあり、オフラインで集まって勉強会も開催できなくなっています。 検索技術勉強会も、もう1年以上開催できていないです。 ス","tags":["勉強会"],"title":"検索技術に関する情報交換を目的としたSlackができました!"},{"contents":"Azure Cognitive SearchにはOData式という書式で条件が書ける仕組みがあります。 ODataは検索条件($filter)やソート条件($orderby)、取得する項目名の指定($select)です。\n私は、Luceneの構文に慣れているので、普通のsearchパラメータを利用しようとします。 が、OData式として特殊な書き方がいくつかあるようなのでこちらの利用方法も調べてみました。 その時、N-Gram(よくやるのはN=2)で陥る問題の話もあるのでこちらについても言及します。\nOData式で検索 次のような3件のドキュメント(フィールド名はbodyとします)をN-Gramで登録していたとします。\nミルクティを飲みたいです。 マティーニはカクテルですが、ミルクセーキは? 風呂上がりのミルクは最高です。 この時、OData式でミルクティという単語で検索してみましょう。\n検索条件は$filterで指定します。 フルテキスト検索用に関数が用意されており、こちらに単語を指定します。\n$filter=search.ismatchscoring(\u0026#39;ミルクティ\u0026#39;) こんな感じ。フィールドの指定がない場合、対象のフィールドは検索可能なフィールドすべてが検索対象になります(公式ガイドのクエリパラメータのqueryTypeに説明あり)。\nでは、実行してみましょう。で返ってくるのは?1だけかな?と思う人が多いかもしれません。 が、結果は3件とも帰ってきます。\n問題点は? では問題点はどこでしょう? ismatchscoringのオプションなどを見る前に、転置インデックスを用いた検索エンジンの挙動をおさらいしましょう。 転置インデックスの仕組みを理解することで、なぜそんな挙動になるのか?というのがわかりやすくなります。 おさらいにはElasticsearchをベースに話をしますが、Azure Cognitive Searchでも同じような挙動になります。\n転置インデックスとトークナイザー(アナライザー)の関係(おさらい) 昨年、オンラインで開催されたOSC広島で発表した資料(録画あり)でもざっくりと説明しています。\nView 本当にその検索は自分が想像している検索になってますか? on Notist.\nざっくりですが、おさらいです。\n検索エンジンでは、入力された文章を、ある規則(アナライザー)で単語に分割し、その単語ごとにどのドキュメントに出現したのか?というリストが作られます。 このリストが転置インデックスです。書籍の後ろにある索引を想像するとどんなものかがわかりやすいです。 単語に対してその単語が出てくるページ番号がわかるという仕組みです(下図は本の索引の一例)。\n書籍の索引は著者や編集の方により厳選された単語のみが採用されています。 が、検索エンジンでは文章を単語に区切る機能が存在します。 この「ある規則」で単語を区切る仕組みが「アナライザー(トークナイザー)」と呼ばれる機能です。 例えば英語用のアナライザーに英語の文章が入力されたとき、文章はこのように単語に区切られたもの(単語列)を出力します(下図)。\n今回はNGramの話なので、NGramのAnalyzerを利用してみるとこんな感じになります。\n実際に出来上がる転置インデックスは次のような形になります。 検索の仕組み(おさらい) 出来上がっている転置インデックスに対して検索をする場合、入力文字列(検索条件)に対して、転置インデックス作成時と同様にAnalyzerが動作します。 処理としては、\nクエリのパース フィールドのAnalyzerで処理 転置インデックスを検索 という形です。 例えばこんな感じ。\n同じAnalyzerの処理が入ることで、転置インデックスに採用されているのと同じ単語が出てくるため、検索がきちんとできるということになります。\n英語と日本語(NGram)の違い 英語と日本語の違いは、スペースの意味になります。 英語の場合は、スペースが単語の区切りになりますが、日本語の場合スペースでは区切られていません。\nですので、検索窓に入力された文字列は、英語の場合、クエリのパースの時点で単語に区切られます。そのあとにAnalyzerになるので、基本的には単語単位でAnalyzerの処理が動きます。そのあと、転置インデックスへの検索となります。なので、多くの場合はAnalyzerの出力は1単語です(類義語などを利用していたりする場合は異なりますが)。\n日本語の場合、スペースでは区切られていないので、クエリのパースの時点で入力された文字列がそのままAnalyzerにわたります。 今回はAnalyzer(NGram)が単語に分割し、それをもとに検索処理が実行されます。\nismatchscoringの問題点は?(やっと帰ってきました) さて、回り道をし、簡単ですが転置インデックスやAnalyzerについて説明しました。 では本題です。\n$filter=search.ismatchscoring(\u0026#39;ミルクティ\u0026#39;) このismatchscoring関数ですが、そのほかにも引数の指定が可能で、省略した場合にデフォルトで採用される値がいくつかあります。 公式のドキュメントにパラメータの意味が掲載されています。\n今回は、第4引数のsearchModeの値が問題点です。デフォルトでは、anyが指定されます。 この、anyは検索語(今回はミルクティ)の任意の検索語句が一致する必要があることになります。 「検索語句」?なんでしょう?これが、ここまで回り道をして説明してきた、Analyzerの出力した単語になります。 「ミルクティ」はNGram(N=2)のAnalyzerを通すと、\n「ミル」「ルク」「クテ」「ティ」\nという4つの単語が出力されます。 これが、「検索語句」です。「任意の」とあるので、上記4つの2文字のどれか?が出現すれば検索条件にヒットしたこととなります。\nですので、以下のように(一部のみ色を変えてます)3つの文章にはそれぞれの文字が含まれているため、先ほどの条件では3件の結果が返ってくることになります。\nミルクティを飲みたいです。 マティーニはカクテルですが、ミルクセーキは? 風呂上がりのミルクは最高です。 NGramで一部分の単語だけで一致したものがヒットしてしまうと違和感があるので、allに変更します。\n$filter=search.ismatchscoring(\u0026#39;ミルクティ\u0026#39;, \u0026#39;body\u0026#39;, \u0026#39;simple\u0026#39;, \u0026#39;all\u0026#39;) 今度はどうなるでしょう?\nミルクティを飲みたいです。 マティーニはカクテルですが、ミルクセーキは? 先ほどよりもマシになりました。 3がヒットしなくなっています。3の文章には「ティ」などが出てこないためです。 ただ、感覚的に2番目がヒットするのは少し違和感がありますよね? 確かに4つの単語がすべて出てきていますが、「ミルクティ」とは少し遠いです。\nさらに「ミルクティ」にヒットさせるにはフレーズ検索にする必要があります。 Elastic社のブログの日本語の検索に関する記事でも出てきますが、フレーズで検索することで「ミルクティ」だけにヒットさせることができます。\n「フレーズ検索=語順を保証する検索」となります。 ですので、\n「ミル」「ルク」「クテ」「ティ」\nこの順序で出てきた場合のみ、検索にヒットしたことになります。 OData式でフレーズ検索する場合は、単語をダブルクォート\u0026quot;でくくる必要があります(公式ドキュメントの例に記載あり)。\n$filter=search.ismatchscoring(\u0026#39;\u0026#34;ミルクティ\u0026#34;\u0026#39;, \u0026#39;body\u0026#39;, \u0026#39;simple\u0026#39;, \u0026#39;all\u0026#39;) これで結果は以下の1件だけとなります。\nミルクティを飲みたいです。 これでNGramで部分一致のような挙動で日本語の検索ができるようになりました。\nちなみに、フレーズにした場合は第4引数はanyに変更しても1件だけの検索結果となります。 フレーズ検索には「すべての語が含まれる」、「すべての語が順番に現れる」という2つの条件が含まれるためです。\n$filter=search.ismatchscoring(\u0026#39;\u0026#34;ミルクティ\u0026#34;\u0026#39;, \u0026#39;body\u0026#39;, \u0026#39;simple\u0026#39;, \u0026#39;any\u0026#39;) この例の引数をミルクティを\u0026quot;ミルク\u0026quot; \u0026quot;最高\u0026quot;のような検索条件に変えた場合、「\u0026ldquo;ミルク\u0026rdquo;」「\u0026ldquo;最高\u0026rdquo;」の2つの条件をanyで扱うため、 「\u0026ldquo;ミルク\u0026rdquo;」「\u0026ldquo;最高\u0026rdquo;」のどちらかが出てくれば良い結果となり、3件の結果が返ってきます。 第4引数をallに変更すると、「\u0026ldquo;ミルク\u0026rdquo;」「\u0026ldquo;最高\u0026rdquo;」の両方が出てこなければならないため、3件目のデータのみが返ってきます。\n$filter=search.ismatchscoring(\u0026#39;\u0026#34;ミルクティ\u0026#34; \u0026#34;最高\u0026#34;\u0026#39;, \u0026#39;body\u0026#39;, \u0026#39;simple\u0026#39;, \u0026#39;all\u0026#39;) これは、\n$filter=search.ismatchscoring(\u0026#39;\u0026#34;ミルクティ\u0026#34;\u0026#39;, \u0026#39;body\u0026#39;, \u0026#39;simple\u0026#39;, \u0026#39;any\u0026#39;) and search.ismatchscoring(\u0026#39;\u0026#34;最高\u0026#34;\u0026#39;, \u0026#39;body\u0026#39;, \u0026#39;simple\u0026#39;, \u0026#39;any\u0026#39;) と同じ意味となります。 少し長くはなりますが、後者の書き方をプログラムで書くと思います、私の場合は。 検索窓に入力された単語に必ず\u0026quot;を追加する処理を書くために、画面入力の文字列を一旦パースをすることになるからです。\nまとめ 簡単?にですが、OData式でのフルテキスト検索と、NGramでのフレーズ検索について説明しました。 英語の場合、もともとスペースで区切られているので、フレーズといわれてピンときますが、日本語の場合はAnalyzerの挙動をわかっていないと「?」となるかと思います。 なぜフレーズ検索が必要なのか?というのが少しでもわかっていただければと。 ちなみに、NGramのTokenizerには別の落とし穴もありますが、その話はまた後日にでも。\n参考として日本語関連の検索に関する記事のリンクを残しておきます。\n参考 Elasticsearch日本語でフレーズ検索が必要なわけ NGramも含め、Elasticsearchでの日本語の検索の設定やクエリについては、Elastic社のブログで日本語で書かれた記事が詳しいのでこちらをご覧いただくのがいいです。 ","date":1614756213,"dir":"post/2021/","id":"eced95e5f301a8340e83d81d3c0d5c0d","lang":"ja","lastmod":1614756213,"permalink":"https://blog.johtani.info/blog/2021/03/03/phrase-query-in-japanese/","publishdate":"2021-03-03T16:23:33+09:00","summary":"Azure Cognitive SearchにはOData式という書式で条件が書ける仕組みがあります。 ODataは検索条件($filter)やソート条件($orderb","tags":["azure search","elasticsearch"],"title":"OData式と日本語の検索(NGram)とフレーズ検索"},{"contents":"自宅の環境がいろいろと変わったのですが、書いていなかったので更新版です。 前回のブログ(2020/09)、前々回のブログ(2020/03)はそれぞれリンクをたどってください。\n現状のデスクトップはこんな感じ\nPC 別のブログにまとめましたが、Windowsメインに切り替えました。 ハードの話以外に、Windows OSに切り替えたときにいくつか入れたものもあります。 それは、移行のブログに少しだけ書いてあります。\nひさびさにWindowsに戻ってきていますが、だいぶ慣れました。 まぁ、それほど大したことをやってないというのもあるかもですが。。。\nメインPC以外にこれまでのmacをブラウジング用にサブディスプレイにつなぎ、マウスをLogicool Flowで行き来できるようにし、 キーボードはKVMスイッチで切り替えてやりくりしていました(最新環境はキーボードのところを参照してください)。\nAmazon | サンワダイレクト USB切替器 キーボード・マウス用 KVMスイッチ キーボード いくつかDIYしましたが、今はメインでSofle Keyboard v2を利用しています(Kochi Keyboardさんで購入できます)\nSofle keyboard v2を有線で使っていましたが、最近Bluetooth対応して無線化しました(その時のブログはこちら)。 ですので、PCとの接続の切り替えはキーボード上で特定のキーの組み合わせを押すことで、切り替えられるようになっています。 KVMとは異なり、Bluetoothの接続が切り替わるのにタイムラグがある+どこにつながっているのか?というのがわからないので、想定していないところでキーが入力されていることがあります。 これは、何とかしたいかもなぁと考えてはいるところ。\nマイク&オーディオインターフェース 基本的に自宅でリモート作業をしています(ありがとうございます)。 なので、ミーティングもオンラインです。 となるとやはり、音がいいほうがお客さんにも喜ばれるかなぁと。 2020年3月時点ではSAMSONのGoMicを利用していました。 これもいい音なのですが、大きいマイクでもいいかなと。 あとは、ほかの使い道もあるかも?ということで、オーディオテクニカのマイク(+ポップガード)とフォーカスライトのオーディオインターフェースに変えてみました。 自分は実感ないですが、きっと役に立っていると思いますw\nAmazon | audio-technica サイドアドレス コンデンサーマイクロホン AT2050 | コンデンサ | 楽器 Amazon | AUDIO-TECHNICA AT-PF2 ポップフィルター | マイクアクセサリ | 楽器 Amazon | Focusrite フォーカスライト オーディオインターフェイス 2イン/2アウト 24bit/192kHz Scarlett Solo (3rd Gen) ステッカー付きセット 【国内正規品】 | 楽器・音響機器 | 楽器 ディスプレイ 以前は、MacBookProの16インチで、メインディスプレイの下に2枚目のディスプレイも兼ねて開いて利用していました(前回のブログ参照)。 自作PCに切り替えたので、ディスプレイがなくなってしまうので、同じような大きさのモバイルモニターを利用しています。 今のところは据え置きになっていますが、持ち運べるので、ほかの部屋や外出時にも使えるんではないかなと。 ディスプレイの足などはないので、邪魔にもならず便利ですね。\nAmazon | モバイルモニター モバイルディスプレイ 4K 15.6インチ cocoparスイッチ用モニター 非光沢IPSパネル 薄い 軽量HDRモード/FreeSync対応/ブルーライト機能 3840x2160 UHD/USB Type-C/標準HDMI/mini DP/カバー付3年保証付 | cocopar | ディスプレイ 通販 音楽再生環境 サブディスプレイにサンダーボルトディスプレイを使用していたので、Mac Miniを接続していましたがサンダーボルトディスプレイには退役してもらいました。 それに伴って、Mac Miniも別の場所に移動しました。音楽再生環境にラズパイ4を復活させました。 以前購入したセットについていたケースではファンの音が気になっていたので、ヒートシンク型に変えました。 結構重いですが、冷えてそうです。\nAmazon | Geekworm Raspberry Pi(ラズベリーパイ) 4 B 用アーマー金属ケース パッシブ冷却/シェル熱放散 ラズベリーパイ4 コンピュ ータモデルB適用 (アーマーケース(ファン無し)) | Geekworm | 冷却パーツ・ファン 通販 Webカメラ カメラ自体に変更はないですが、付属品をいくつか。 Webカメラではないカメラもつけてみたいなと思い、モニターアームにカメラを付けられるものを付けてみました。 ただ、おっさんの顔をきれいに映してもなぁという結論に至ったので、Webカメラが乗っかっています。。。 あとは、デスクトップPCになり、カメラのケーブルだけではPCまで届かなくなってしまったのでUSB Type-Cの延長コードを買ってみました。実はこれ2本目ですが。。。 スタンディングデスクの昇降でケーブルに負荷がかかってしまったことがなんどかあり、1本目の延長コードは接触が悪くなってしまいました。。。時々外したりしていて、ケーブルの配置がおかしいときがあるので、気を付けるようにしています。\nAmazon | 長尾製作所 モニターアーム用 VESA カメラ&マイクマウント NB-MV001MH | 長尾製作所 | モニタアーム\u0026amp;スタンド 通販 Amazon | iVANKY USB Type C 延長ケーブル USB 3.1 Gen 2(4K@60Hz/1.0m/オス-メス)10Gbps高速データ転送 3A急速充電 usb-c 変換 Huawei MateBook13, iPad Pro11, Nintendo Switch, MacBook等対応 | IVANKY | USBケーブル 通販 照明 裸の蛍光管だったのですが、リモコンで点灯したり、照度を変えられるようにしたかったので、 パナソニックの照明に変えました。\nAmazon | パナソニック LEDシーリングライト 調光・調色タイプ リモコン付 6畳 3, 699lm HH-CD0620AZ 【Amazon.co.jp限定】 | パナソニック(Panasonic) | ホーム&キッチン 変えたのはよかったのですが、部屋が長細い+Webカメラの位置(自分から見て左にカメラを置いて、部屋の奥への画角?になっている)のせいで、右半分の顔が暗くなる場合がありました。 幸い、右にはスチールラックが組んであるので、そこにつけられる照明を購入して女優ライトみたいな感じで使っています(頻繁ではないですが)\nAmazon|ルミナス メタルラック用 LEDライト 磁石で簡単設置 連結可能 幅60cm 昼白色 LED60R-N|メタルラックパーツ オンライン通販 フットレスト 昨年3月くらいに配置して、座っているときに足を置くのに便利に使っていました。 が、1台だと幅が足りないので最近2つ目を購入して並べて使っています。 片足ずつ載せられるのは便利ですね(基本ガニ股なので。。。)。\nAmazon | サンワダイレクト フットレスト スチール製 角度10° 幅40×奥行30cm 足置き台 100-FR011 | フットレスト | 文房具・オフィス用品 ということで、最近はこんな環境で仕事をしています。 当分これで更新しないんじゃないかなぁ。 (サブディスプレイが左に寄っているので、局面ディスプレイが気になっているところですが。。。)\n","date":1614246182,"dir":"post/2021/","id":"fcb0105fa6b5777a133f247784b9d930","lang":"ja","lastmod":1614246182,"permalink":"https://blog.johtani.info/blog/2021/02/25/update-working-facility/","publishdate":"2021-02-25T18:43:02+09:00","summary":"自宅の環境がいろいろと変わったのですが、書いていなかったので更新版です。 前回のブログ(2020/09)、前々回のブログ(2020/03)はそ","tags":["misc"],"title":"自宅の作業環境(2021/02)"},{"contents":"Azure Cognitive SearchにSuggestやAutocompleteの機能があるのを見つけたので、どんな挙動なのかを調べてログとして残しておきます。\n公式ドキュメント 日本語で公式ドキュメントが公開されています。使い方や流れについてはこちらをまずは見れば使えると思います。\n本ブログでは、ざっくりとした機能の紹介と内部がどんな挙動をしていそうか?、日本語だとどういう感じになるのか?という点を紹介しようと思います。\nどんな機能? 検索窓でよく、キーワードを入力しているときに検索キーワードの候補が表示されることがあります。 このキーワードの候補を表示するための機能が今回紹介するSuggesterと呼ばれる機能です(日本語の公式ドキュメントでは「先行入力エクスペリエンス」)。 Suggesterには、以下の2つの機能が用意されています。\nAutocomplete:キー入力しているときに、入力されている文字列で始まる単語で、検索できるもの(転置インデックスに登録されている単語)をリストで返す機能 Suggestion:入力した文字列で始まるキーワードを含む、元のデータを返す機能 利用方法 Suggesterの機能を利用するにはインデックスに設定を追加する必要があります(新規、既存どちらでも可)。 ただ、既存のインデックスに設定を追加した場合、内部にすでに存在するドキュメント(データ)については、このSuggesterのデータは作られません。 ですので、既存データを再度登録しなおすといった作業が必要となるので注意が必要です。\n本ブログでは、いくつかAzure Cognitive Searchのサンプルのリクエストが出てきます。Visual Studio CodeのREST Client Extensionの書式となります。拡張機能の簡単な紹介は昨年のブログをご覧ください。\n設定編 Suggesterの設定では、主に以下の2つを設定する必要があります。\nname: suggesterの名称。クエリ時に指定します。 sourceFields: 入力データのもととなるフィールド名。 String型のみ指定可能。また、Azureで用意されたアナライザーだけが利用可能です。自分で用意するカスタムアナライザーは利用できないので注意が必要です(制限についてはこちら)。 今回使用するサンプルのインデックス設定は次の通りです。\nインデックス作成のリクエスト(@host、@api-keyはご自身のものに置き換えてください。)\n## 設定 @host = 名前.search.windows.netと記載 @api-key = APIキーを入力 ### Create index with suggester POST https://{{host}}/indexes/?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;name\u0026#34;:\u0026#34;suggester-test\u0026#34;, \u0026#34;fields\u0026#34;:[ { \u0026#34;name\u0026#34;:\u0026#34;id\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;Edm.String\u0026#34;, \u0026#34;key\u0026#34;:true, \u0026#34;searchable\u0026#34;:false }, { \u0026#34;name\u0026#34;:\u0026#34;name\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;Edm.String\u0026#34;, \u0026#34;searchable\u0026#34;:true, \u0026#34;analyzer\u0026#34;:\u0026#34;ngram_analyzer\u0026#34; }, { \u0026#34;name\u0026#34;:\u0026#34;category\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;Edm.String\u0026#34;, \u0026#34;filterable\u0026#34;:true, \u0026#34;facetable\u0026#34;: true } ], \u0026#34;suggesters\u0026#34;: [ { \u0026#34;name\u0026#34;: \u0026#34;name_suggester\u0026#34;, \u0026#34;searchMode\u0026#34;: \u0026#34;analyzingInfixMatching\u0026#34;, \u0026#34;sourceFields\u0026#34;: [ \u0026#34;name\u0026#34; ] } ] } 公式ドキュメントのサンプルでは日本語がないので、日本語のデータも入力しています。\nデータ登録リクエスト\n### Index data POST https://{{host}}/indexes/suggester-test/docs/index?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;value\u0026#34;: [ { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Microsoft Office\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;microsoft\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;2\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Microsoft Azure\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;microsoft\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;3\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;GitHub Enterprise\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;github\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;4\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;GitHub dot com\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;github\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;5\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Bluetooth Mic\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;hardware\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;6\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;東京スカイツリー\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;japanese\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;7\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;東京タワー\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;japanese\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;8\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;東京特許許可局\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;japanese\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;9\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;グランメゾン東京\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;japanese\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;10\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;東京都庁\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;japanese\u0026#34; } ] } 以上が事前準備です。データ登録時に内部でSuggester用のデータを内部で生成しているようです(公式ドキュメント)。\nクエリ編 最初に説明しましたが、Suggesterの中ではAutocompleteとSuggestionという2種類の機能が用意されています。それぞれについて例をもとに説明していきます。\nAutocomplete API 検索窓に入力された文字を元に、前方一致でどのような単語で検索できるか?という候補を表示するための機能です(2単語も対応していますが今回は省略。APIの仕様はこちら)。\nたとえば、micという文字が入力されているところでAutocomplete APIを呼び出す時は、次のようなリクエストです。searchというパラメータに入力値を与えます。suggesterNameはインデックス作成時につけた名前になります。\nPOST https://{{host}}/indexes/suggester-test/docs/autocomplete?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#34;mic\u0026#34;, \u0026#34;suggesterName\u0026#34;: \u0026#34;name_suggester\u0026#34; } レスポンスとして、次のようなJSONが返ってきます。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;value\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;microsoft\u0026#34;, \u0026#34;queryPlusText\u0026#34;: \u0026#34;microsoft\u0026#34; }, { \u0026#34;text\u0026#34;: \u0026#34;mic\u0026#34;, \u0026#34;queryPlusText\u0026#34;: \u0026#34;mic\u0026#34; } ] } サンプルデータとして登録したデータにcategoryというフィールドを入れていました。 Autocompleteは条件を絞り込んで結果を返すこともできます。 filterにODataの書式で条件を書けます。 categoryフィールドにmicrosoftが設定されているデータだけを取得するということができます。\n### Autocomplete with filter POST https://{{host}}/indexes/suggester-test/docs/autocomplete?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#34;mic\u0026#34;, \u0026#34;suggesterName\u0026#34;: \u0026#34;name_suggester\u0026#34;, \u0026#34;filter\u0026#34;: \u0026#34;category eq \u0026#39;microsoft\u0026#39;\u0026#34; } レスポンスはこちら。先ほどとは違い、micというデータは返ってきていません。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;value\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;microsoft\u0026#34;, \u0026#34;queryPlusText\u0026#34;: \u0026#34;microsoft\u0026#34; } ] } 英語の場合、「単語」の単位は字面の通りです。スペースで単語が区切られているのでわかりやすいです。 日本語の場合は普通の人には少し想像しにくいです。 東京という文字を入力してみます。\n### Autocomplete in Japanese POST https://{{host}}/indexes/suggester-test/docs/autocomplete?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#34;東京\u0026#34;, \u0026#34;suggesterName\u0026#34;: \u0026#34;name_suggester\u0026#34; } すると返ってくるのは以下の通り「東京」だけになります。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;value\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;東京\u0026#34;, \u0026#34;queryPlusText\u0026#34;: \u0026#34;東京\u0026#34; } ] } 入っているデータは「東京スカイツリー」、「東京タワー」などです。 普通に考えると、これらがそのまま返ってくると思うかもしれませんが、違います。\nこれは、Suggesterの元となるフィールドのAnalyzerの挙動によります。 今回のインデックスのnameフィールドのanalyzerにはja.luceneです。これは、日本語用のアナライザー(Kuromoji)になります。いわゆる形態素解析器で日本語の文字列を「単語」に分割します。 英語についてはスペース区切りで分割しますが、日本語についてはKuromojiが内部の辞書とアルゴリズムに基づいて単語に分割してくれます。 Azure Cognitive Searchでは、Analyzerの挙動を確認するためのAPIも用意してあるので実行しみると、\n### Autocomplete in Japanese POST https://{{host}}/indexes/suggester-test/analyze?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;text\u0026#34;: \u0026#34;東京スカイツリー\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;ja.lucene\u0026#34; } このような結果が返ってきます。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;東京\u0026#34;, \u0026#34;startOffset\u0026#34;: 0, \u0026#34;endOffset\u0026#34;: 2, \u0026#34;position\u0026#34;: 0 }, { \u0026#34;token\u0026#34;: \u0026#34;スカイ\u0026#34;, \u0026#34;startOffset\u0026#34;: 2, \u0026#34;endOffset\u0026#34;: 5, \u0026#34;position\u0026#34;: 1 }, { \u0026#34;token\u0026#34;: \u0026#34;ツリー\u0026#34;, \u0026#34;startOffset\u0026#34;: 5, \u0026#34;endOffset\u0026#34;: 8, \u0026#34;position\u0026#34;: 2 } ] } ja.luceneのAnalyzerによって、3つの単語に分割されているのがわかります。 Autocomplete APIの実行結果も、このAnalyzerによって分割された単語をもとに、候補となる単語を前方一致で検索して結果を返しているのです。 ですので、「東」と入れても「東京」が返ってくるのがわかります。 一方で、「東京ス」と入力した場合は次のような結果となります。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;value\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;スカイ\u0026#34;, \u0026#34;queryPlusText\u0026#34;: \u0026#34;東京スカイ\u0026#34; } ] } これは、autocompleteModeと呼ばれるパラメータの挙動となります。 デフォルトでは、oneTermという設定で、最後の単語(例の「東京ス」の場合は「東京」「ス」と区切られるので「ス」という文字を単語とみなす)にマッチする単語(例では「スカイ」)が返ってきます。 queryPlusTextについては、入力された文字にtextで返ってきた単語をくっつけたものが取得できます。\n英語であれば、スペースで区切られており、単語が切れているのが簡単にイメージできますが、日本語の場合は少し違和感が出るかと。\nこのように、入力された文字が含まれる「単語」を基本的に返す動作をするのがAutocomplete APIです。\nSuggest API では、もうひとつのSuggest APIはどういったものでしょうか? autocomplete APIに似ていますが、返ってくるデータが登録されたデータそのものになります。\nたとえば、micという文字列を入力とした場合、\nPOST https://{{host}}/indexes/suggester-test/docs/suggest?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#34;mic\u0026#34;, \u0026#34;suggesterName\u0026#34;: \u0026#34;name_suggester\u0026#34; } 次のような結果が返ってきます。Autocompleteの時は単語でしたが、こちらは入力データがそのまま返ってきています。 入力データの中にmicで始まる単語が含まれたものが候補となっています。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.text\u0026#34;: \u0026#34;Bluetooth Mic\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;5\u0026#34; }, { \u0026#34;@search.text\u0026#34;: \u0026#34;Microsoft Office\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;1\u0026#34; }, { \u0026#34;@search.text\u0026#34;: \u0026#34;Microsoft Azure\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;2\u0026#34; } ] } 日本語の場合、Autocompleteとは異なり、その単語を含むものがサジェストされるので、「東京」をsearchに指定すると「東京」を含むデータが出てきます。\n### Suggest in Japanese POST https://{{host}}/indexes/suggester-test/docs/suggest?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#34;東京\u0026#34;, \u0026#34;suggesterName\u0026#34;: \u0026#34;name_suggester\u0026#34; } レスポンスはこちら。単語を含む元の文字列が返ってきます。ここまでは違和感はありません。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.text\u0026#34;: \u0026#34;東京タワー\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;7\u0026#34; }, { \u0026#34;@search.text\u0026#34;: \u0026#34;グランメゾン東京\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;9\u0026#34; }, { \u0026#34;@search.text\u0026#34;: \u0026#34;東京都庁\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;10\u0026#34; }, { \u0026#34;@search.text\u0026#34;: \u0026#34;東京スカイツリー\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;6\u0026#34; }, { \u0026#34;@search.text\u0026#34;: \u0026#34;東京特許許可局\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;8\u0026#34; } ] } では、「東京」「特許」という2つの単語をスペースで区切ったものが入力されたとするとどうでしょう?\n### Suggest in Japanese POST https://{{host}}/indexes/suggester-test/docs/suggest?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#34;東京 特許\u0026#34;, \u0026#34;suggesterName\u0026#34;: \u0026#34;name_suggester\u0026#34; } スペースがありますが、内部処理では形態素解析器が分割した後でこの単語の順番で出てくるものを探しているので、出てくることになります。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.text\u0026#34;: \u0026#34;東京特許許可局\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;8\u0026#34; } ] } なお、このSuggestのAPIは、単語の語順を気を付ける必要があります。 「特許」「東京」と順序を入れ替えたスペース区切りの場合は、\n### Suggest in Japanese POST https://{{host}}/indexes/suggester-test/docs/suggest?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#34;特許 東京\u0026#34;, \u0026#34;suggesterName\u0026#34;: \u0026#34;name_suggester\u0026#34; } 結果は返ってこないです。おそらく内部では、フレーズクエリで、最後の単語だけを前方一致で検索するような仕組みが動いているのだと思われます。 スペースで区切られてはいるが、順序があるので少し違和感を感じるかもしれません。英語だとフレーズの部分のイメージは沸きやすいのですが。\n短い文章のデータ(例:本のタイトルやランドマーク名など)では、このSuggestAPIを利用するとデータそのものが返却されるので、便利かもしれません。\nまとめ ということで、Azure Cognitive SearchのSuggesterの簡単な紹介でした。APIのページにはそのほかのパラメータについても説明があるので、使ってみようと思う方は目を通していただくのがよいかと。\n今回のブログは裏の仕組みがどんな感じなのか?を想像しながらAPIについて調べた形になります。日本語の場合に、少し違和感を覚える人もいそうだろうなということでブログを書いてみました。 今回は書いていませんが日本語でAutocompleteをやりたい場合は、読み仮名でも漢字が表示されるほうがよいという場合もあると思います。 その場合は、用意されている機能では難しいので、独自実装するといった方法になりそうです。 英語や、読みを利用しない場合は、挙動を理解していれば役に立つ場面もありそうです。\n","date":1612515120,"dir":"post/2021/","id":"931b2ebd9bfaeb5dcf1973e724a1f8d0","lang":"ja","lastmod":1612515120,"permalink":"https://blog.johtani.info/blog/2021/02/05/autocomplete-and-suggest-on-azure-search/","publishdate":"2021-02-05T17:52:00+09:00","summary":"Azure Cognitive SearchにSuggestやAutocompleteの機能があるのを見つけたので、どんな挙動なのかを調べてログとして残しておきます。 公","tags":["azure search"],"title":"Azure Cognitive Searchでオートコンプリートやサジェストをしてみる"},{"contents":"オライリー・ジャパンから出ている「コンピュータシステムの理論と実装」を読み始めたのでメモを取ることに。\n原著はオライリーじゃないのかというのが、まず最初の気づきでした。\nNANDからテトリス コンピュータのハードウェアからOS、さらにその上で動くアプリケーションまでを動作させるというのを少しずつやっていくという書籍みたいです。 イントロと1章を読みましたが、1章では論理回路の話でした。\n実際に物理的に作るわけではなく、シミュレーターなどのソフトウェアが用意されており、 そのソフトウェア上で動くものを作っていくことになります。 ソフトウェアのために専用のサイトが用意されて、ダウンロードもできるようになっているので、実際に手を動かしながら理解を進める感じになるのかと。\n目次を見ていただくとわかりますが、すごく幅が広いです。 1年で読み終われるかなぁ?まぁ、のんびりやっていこうかなと。\n用意されているソフトウェアなどで便利だなと思ったのは、どの章からでも興味のある部分から始められるようになっているようです(まだ始めてなくて。。。) 内部ではすべてのパーツがそろえてあるけど、章ごとのプロジェクトでは、個別に自分で実装したものがあればそちらが動くという挙動のようです。\nということで、ちょっとずつやっていこうかなと。 ほんとにテトリス動くのかなぁ?\n","date":1612424444,"dir":"post/2021/","id":"aa61b4543e8a7c67fccabee27a6e99cd","lang":"ja","lastmod":1612424444,"permalink":"https://blog.johtani.info/blog/2021/02/04/reading-elements-of-computing-systems/","publishdate":"2021-02-04T16:40:44+09:00","summary":"オライリー・ジャパンから出ている「コンピュータシステムの理論と実装」を読み始めたのでメモを取ることに。 原著はオライリーじゃないのかというのが","tags":["輪読","Nand2Tetris"],"title":"「コンピュータシステムの理論と実装」を読み始めた #Nand2Tetris"},{"contents":"Corne使ってましたが、数字キーがあるとどうなのかな?というのがやはり気になって。 そこに、Kochi KeyboardさんからSofle Keyboard v2というのが発売されたので組み立ててみました(去年末に)。また、先日Corne Light v2のBLE化に成功したので、Sofle keyboard v2のBLE Pro Micro + LPME-IO化にもチャレンジしてみました。\nSofle keyboard v2 ビルドログ 自分で書くよりもすごくよくできたビルドログがKochi Keyboardさんで公開されているので、そちらを参考にしてください。\nSofle Keyboard v2ビルドガイド すごく詳しく書いてあります。なので、こちらを見ていただければ問題ないかなと。 ただ、自分ではいくつか失敗したので自戒を込めてログを残しておきます。\nOLED用のジャンパをはんだ付けし忘れ 単にビルドログを流し読みしたツケが。。。 Sofleは同じ基盤を左右で利用します。なので、右手と左手で、同じ基盤の表と裏を利用します。 OLED用のジャンパする部分は両面に用意されていますが、はんだでジャンプするのはPro Microが実装される面となります。\n両面にジャンプ用のランドがあるとは気づかないで、左手の裏面をジャンプしてすべて実装し終わってから、OLEDが表示されないことに気づいてしまいました(ビルドログ用にと思って撮った写真に証拠が残ってますねw)。。。\nということで、またはんダッシュ太郎くんのお世話になりました(Pro Microを外してジャンプしました)。本当に有能ですよ彼は。。。\nAmazon | サンハヤト はんだシュッ太郎NEO 45Wタイプ HSK-300 | ハンダゴテパーツ ソケットのはんだ付け甘すぎ あとは、慣れてきたなぁと思っていたところに天罰が。 キースイッチのソケットを付けるの慣れてきたなーと思って、サクサクとつけていたのですが、 いざキースイッチをはめるときにボロボロとはがれていきましたw 半分くらいは外れたんじゃないかな?ちゃんとはんだ付けした後にピンセットなどで軽くいじってみるべきですね。。。\n滑り止め 利用しているキーキャップがOEMプロファイルということもあり、数字キー側を少し高くしたほうが入力しやすいです。そのために、少し大きめのソフトクッションを購入しました。\nAmazon | WAKI ソフトクッションCN-020 クリアータイプ: 産業・研究開発用品 上の左右の角に貼り付けると、がたつきがあったので少しずらして貼り付けて安定させています。 OLEDのプレートの部分を押すと手前が浮き上がってしまいますが、そこにはキーはないので問題ないかと。\nということで、毎回気づきがあって面白いですね。。。\nSofle keyboardのBLE化 Corne LightのBLE化がうまくいったので、もうひとセットのぎけす屋さんから購入しました。 BLE Micro ProやLPME-IO、電池基盤などについては前回のCorneのBLE化の記事を参照してください。\nハードウェア編 Sofle keyboard v2は残念ながらせきごんさんの公式ページの対応キーボード一覧には掲載されていません。 が、Sofle KeyboardのGitHubのページには次のような記載があります。\nSofle is 6×4+5 keys column-staggered split keyboard with encoder support. Based on Lily58, Corne and Helix keyboards.\n基盤の写真のPro Micro周りもCorneに似ています。 ということで、おそらくBLE + LPME-IO化が行けるのでは?と予測して作業に取り掛かりました。\nPCBの確認 Sofle Keyboardの基盤の設計図はGitHub上に公開されています。 この設計図を見る方法をまずは探しました。\n自作キーボードについて探すにはまずはサリチル酸さんのブログ「自作キーボード温泉街の歩き方」です。 回路図なので、設計ノウハウあたりのカテゴリーにあるだろうと探したところ見つかりました。\n(設計者向け)オートルーターを使って睡眠時間を確保しよう 配線のテクニックというブログですが、回路図を書くためのツールKiCadについて記載があります。 このブログにある以下の記事をもとに、KiCadのインストールや使い方をちょっとだけ勉強しました。\nfoostanさんのMeishi Keyboardの開発者向けガイド(JP) KiCadことはじめ KiCadの中の回路図エディタ「Eeschema」でSofle keyboardのPCBのフォルダを開くと回路図が開きます。 実際の基盤になる前に、Pro Microのどの足と何がつながっているのか?などが見て取れます。 前回のCorneのBLE化でLPME-IO対応したときに、学習しましたが、 TRRSの足とPro MicroのSDAとSCLをつなぐことで、LPME-IOを使うことができるようになるというのがわかっています。 それをもとに回路図を見たところ、以下のような記述がありました。\nどうも、JP9とJP10というはんだでジャンプする場所を用意してくれていそうです。 先を見越した設計本当にありがたいですね。\nJP9とJP10のはんだ付け 今ついているPro Microを外し(またはんダッシュ太郎が活躍)、基板を確認したところ対象の個所がありました。下の写真は左手の裏側です。\nこれらをはんだでジャンプします。\n右手は表側にあるので、Pro Microを外した後にジャンプしました。 左手は裏側です。 Corne Lightでは、Pro Microの足から導線を使ってTRRSの足につなぎましたが、今回はすっきり実装できました。 ジャンプした後はBLE Micro Proをはんだ付けします(はんだ付けせずに動作確認しようとしましたが、うまく通電しなくてちゃんと動かなかったです)。\nLPME-IOのジャンパ LPME-IOのGitHubページにあるように、利用するキーボードによって、いくつかはんだでジャンプする必要があります。 これは、BLE Micro Pro用のConfigファイルを見て、対象を決める必要があります。 が、Sofleは事前に用意されたものがありません。\nConfigファイルの生成 用意されていないConfigファイルが、QMKの設定ファイルから生成することができるようななっています(本当に感謝しかないですね)。 手順はBLE Micro Proのドキュメントにありました。\n新しいキーボード用の設定を作成する - QMK用の設定から変換する この変換スクリプトで3種類のconfig(右手用、左手用、LPME-IO用)が生成されます。 私の場合はLPMEを利用するので、lpmeという名前の入ったconfigを利用します。 中を見るとcol以下の記載が以下の通りだったので、8からDをジャンプします。\n\u0026#34;col_pins\u0026#34;:[18, 17, 16, 15, 14, 13, 18, 17, 16, 15, 14, 13], ここまででハードウェア側が終了です。\nファームウェア・設定編 ハードウェアの実装が終わったので、ファームウェアおよびアプリの設定です。\nファームウェアのセットアップ キーボードをUSBで接続し、BLE Micro Pro Web Configuratorのページにアクセスすると、 セットアップ初期画面が出てきます。\n公式ページの「キーボードを選ぶ」を参考にファームウェア、アプリのアップデートを行います。 「設定ファイルの書き込み」のタイミングでupload your ownを選択すると、ファイル選択画面が出てくるので、変換スクリプトで生成したJSONファイルを選択します。 このとき、Mas Storage Classとしてキーボードが認識されている状態だとうまく書き込めなかったので、キーボードのドライブを「取り出し」してからファイルをアップロードしました。\nキーマップの設定 BLE Micro Proのアプリが設定をきちんと認識すれば、あとはWeb Configuratorでキーマップの設定が可能になります。 これまた、残念なことに、BLE化する前のキーマップをJSONファイルで保存してなかったので(泣きそうw)、QMKのkeymap.cのファイルをもとに、ブラウザ上でがんばって設定しましたw また、新しい設定ではBLE関連のキーをマッピングとして追加しています。\nBluetooth接続 あとは、接続確認です。 MacとWin2台と接続するのですが、Win→Mac→Winの順番でBluetoothの接続をやっていたら、なぜか3つ目のWindowsで接続候補に出てくるけど、接続しようとするとタイムアウトをするという現象に遭遇しました。 MacのBluetoothの設定を一旦削除してから、Win→Win→Macの順番でペアリングしたところ問題なく接続できました。ただ、これが本当の対処なのかどうかは不明です。3番目だと接続できなかったWindowsマシンは再起動もしてみたのですがダメでした。この辺よくわかってないなぁ。\nまとめ ということで、Corne Lightに引き続き、Sofle Keyboard v2もBLE+LPME化に成功しました。 導線なども使わずにLPME対応ができたので見た目もすっきりしています。 これで、KVMスイッチだと2台までしか切り替えできなかったのが、3台をひとつのキーボードで操ることができるようになりました。 だいぶ楽になりそうな予感がしています。\nまだ、完ぺきではないので、次のような対応をやっていく予定です。\nロータリーエンコーダー対応:BLE以前はQMKのkeymap.cの中でロータリーエンコーダーの動作を記述していたので、BLE Micro Proでどうやるのかを調べたい。encorder.jsonというファイルがあったのでその辺ではないかな? OLED対応:Corne Lightの時と同様に、OLEDが点かなくなったのでこの辺りを調べたい。 ということで、とりあえずキー入力するのには困らない程度にはできたので、より便利にする方法を時間を見つけて模索する感じになりそうです。 あと、KiCadも面白そうなのでこっちもちょっと触ってみたくなってきたかも?\n","date":1612106122,"dir":"post/2021/","id":"d95522c691013bfe66dd46ded85a98ed","lang":"ja","lastmod":1612106122,"permalink":"https://blog.johtani.info/blog/2021/02/01/apply-ble-to-sofle/","publishdate":"2021-02-01T00:15:22+09:00","summary":"Corne使ってましたが、数字キーがあるとどうなのかな?というのがやはり気になって。 そこに、Kochi KeyboardさんからSofle Keyboard v","tags":["DIYキーボード","misc"],"title":"Sofle v2を組み立てて、BLE+LPME-IO化してみた #DIYキーボード"},{"contents":"メインマシンとMacは下記のサンワサプライのUSB接続のKVMスイッチを使っていますが、もう一台ノートPCがありここに接続しているCorne(初めてのDIYキーボード)が長いUSBケーブルでつながっています。\nAmazon | サンワダイレクト USB切替器 キーボード・マウス用 KVMスイッチ 時々必要になって、デスクにキーボードだけ引っ張ってきて利用するのですが、ケーブルの取り回しがまぁ邪魔で。。。 BLE対応(BLE Micro Pro)をしてみようかなということに。\nBLE + LPME-IO対応 分割キーボードをBLE対応(それぞれにBLE Micro Proを実装)すると、キーボード間のつながりがいまいちになることもあるというのをちらほら見ていたので、BLE Micro Pro + LPME-IOという構成で、 Corneのキーボード同士はTRRSケーブルで接続し、PCとCorne間をBluetoothで接続する構成にしてみました。\nBLE Micro Proについては、公式ドキュメントにいろいろと記載があります。\n材料 ということで、材料は以下の通り。セット販売は売り切れていたので、個別に購入しました。 コンスルーと電池以外は1つずつです。\nBLE Micro Pro(のぎけす屋) x 1 LPME-IO(のぎけす屋) x 1 BLE Micro Pro用電池基盤(遊舎工房) x 1 コンスルー(Kochi Keyboard) x 4 CR1632ボタン電池(近所のスーパー) x 2 実装 まずは、それぞれ組み立てです。\n電池基盤 以下の記事を参考にはんだ付けしました。\nQiita: 自作キーボードビルドログ:その2「ErgoDash」無線化対応 ハードウェア編 - 電池基盤の組み立て・半田付け yfuku docs - Claw44 / 無線接続について 注意点は以下の通りです。\n基盤が軽いので固定が必要(マスキングテープでマットに貼り付けたらましになった) 電池ホルダーが変形しやすい(設置して、足を折るために上から押さえつけたら、本体が曲がってしまった。。。) 部品が細かいので大変(老眼だから?) BLE Micro Proとの接続は参考にしたyfuku docsにある方法(余っていたピンヘッダを1本ずつ使ってはんだ付け)を採用しました。 (パッと見大丈夫そうだったので電池基盤の裏に絶縁テープは貼ってないです貼ってないです)\nBLE Micro Pro(もげ対策) BLE Micro Pro自体はコンスルーをはんだ付けするだけですが、今回はもげ対策として、ダイソーで買ってきたグルーガンで ちょっとだけ補強してみました。 初グルーガンだったので不細工だけど。これ難しいな。\n効き目あればいいけど?\nLPME-IO対応 いくつかのジャンパをはんだでブリッジ まずは、LPME-IOのREADMEのページの導入手順を読み、いくつかのピンをジャンプしました。 せきごんさんのBLE-Micro-Proのリポジトリに、CorneのLPME用コンフィグファイルを見ると、ジャンプするのは20, 19, 18, 17, 16, 15に対応している、F,E,D,C,B,Aの6つです(写真撮り忘れた。。。)。\nTRRSのI2C対応(って言い方であってるのかなぁ?) ジャンプだけでいけないかなぁ?と思いましたがダメでした(USBでつないでみたけど、左手(BLE-Micro-Proがついている側)だけ入力可能です。\nBLE Micro Proの公式サイトにLPME-IOについても記載があります。 実績のあるキーボード一覧にCorne Lightの記載もあったので、試してみようと思ったのが発端です。\nただ、LPME-IOの欄に注意書きが。\n*LPME-IOを使うには改造が必要\nまた、一覧の最初にも記載があります。\nLPME-IOを使うにはキーボードの左右の有線通信がI2Cである必要があります。とくにOLEDに対応しているキーボード等の場合は、I2C用のピンをTRRSジャックに接続する改造を施すことでI2C化できる場合があります。\nまだ、自作キーボードの仕組みをがっつり理解しているわけではない初心者なので、まぁ、ちょっとわからないかなと。。。 BLE Micro Proのはじめにのページを見ると、 Self Made keyboard in JapanのDiscordに専用チャネルがあるようで、過去ログを検索してみました。 検索したところ、Corneの場合Micro ProのSDA(写真の青い線)とSCL(写真の黄色い線)(参考:Corneの基盤の図)をそれぞれ、TRRSの2つのピンに接続する必要がありそうだというコメントがありました。\nCorne Cherry v2の場合は、接続するためのショートカットが用意されていましたが、Corne Light v2だと見当たりませんでした。 ということで、線を使って物理ショートカットしました。ちなみに、ショートカットは両手ともに必要なようです。\nUSB-Cで接続テスト 上記対応が終わって、基板に設置してUSB-Cケーブルで接続したところ、外部ドライブとして見えるようになりました。\nキーマップの書き換えとか 公式ドキュメントのBLE Micro Pro Web Configuratorを使うの手順通りに書き込みを行っていくと、特に問題なく接続できました。 便利すぎですね。キーマップの変更は、これまでのCorneのキーマップJSONファイルからコピペして書き込んだだけです。 (この後、BLE用のキーマップを書き足すためにもう一度変更しますが)\nLPME-IO対応なので、Micro Proは片側しかないので、書き換えも楽々でした。\nBLEで接続テスト 今回の目的だったWindowsにBluetoothで接続できるようにしてみました。 最初はサリチル酸さんの記事を見ていたのですが、キーコードがちょっと変わっているようでした。\nで、よくよく見ると、BLE Micro Pro Web ConfiguratorにBLE関連のキーも用意されているじゃないですか。。。\nBLE関連のキーを割り当てた後は、USBをオフにして、Bluetoothをオン、BTNEWで新しくペアリングするようにすれば接続完了でした。\n課題 これまでと違い、すんなり実装ができましたがまだいくつか気になる点が。\n複数の機器とペアリングして切り替え Macともペアリングしてみようとしたのですが、切り替えがうまくいかないようで。。。 OLEDつけるにはどうするんだろう? 左手側は電池が乗っているのですが、右手側はLPME-IOだけなので、上にOLEDを載せる余裕があります。 なので載せてみましたが点かないですね。ファームウェアを何かしないといけないんじゃないかな?調べないとなぁ。 という感じです。 まだちゃんと長時間使っていないので、他の問題点も出てくるかもしれませんが、まぁとりあえず使ってみてからかな。 うまくいくようなら、メインマシンにBluetoothモジュール追加してみるのもありかと考えているところです。\n調べながら、自分なりに対応してみましたが他にもいい方法とかあれば教えてもらえると助かります。\n","date":1610332951,"dir":"post/2021/","id":"4ad8239a37f641bcd17abeb96106314e","lang":"ja","lastmod":1610332951,"permalink":"https://blog.johtani.info/blog/2021/01/11/apply-ble-and-lpme-to-corne/","publishdate":"2021-01-11T11:42:31+09:00","summary":"メインマシンとMacは下記のサンワサプライのUSB接続のKVMスイッチを使っていますが、もう一台ノートPCがありここに接続しているCorne","tags":["DIYキーボード","misc"],"title":"Corne Light v2のBLE+LPME-IO対応 #DIYキーボード"},{"contents":"振り返りブログにも書きましたが、デスクトップPCを自作(DIY)しました。 組み立てたに使ったパーツのアフィリンクを貼っておきます。\n10月くらいにPC組もうと思って、組み上がったのは11月半ばでした。 最初はもうちょっと小さいPCにしようと思ってたのに気づいたらATXになってました。 パーツの選定の基準は以下のツイートです。影響されやすいなぁ。\nタワーってほど大きくなくていいと思いますが、NZXT H510 ぐらいの大きさは欲しいですね。https://t.co/s1c1fOnPyI\n単純に、スペースがないと組みにくいのと冷えにくい、買ってきたものがやっぱりこれだと入らない、というリスクがかなり減るので。\n\u0026mdash; さぼてん(さぼ福)🌵 (@cactusman) October 9, 2020 今年3台作りました。ノートPC使えない体になります。 pic.twitter.com/8zDmeRwNkS\n\u0026mdash; miyake | ZEN (@kazuyukimiyake) October 9, 2020 白いケースいいなぁという感じで、ケースとCPUクーラーが決まったんで、ググってこちらのHAKKAさんのYouTube見ながら妄想してました。 パーツがなかなか揃わなくて。 そして、PCが光るのどうなの?と思ってたのに、気づいたら光ってました(なぜ?)。\nグラボがない状態(CPU内蔵GPU)で12月頭までは動作してました。\n購入自体はTSUKUMO、ビックカメラオンライン、パソコンSHOPアーク、イートレンドオンラインショップでオンラインで購入しました。\nPCケース Amazon | NZXT H510i White CA-H510I-W1 CS7946 | NZXT | PCバッグ・ケース・スリーブ 電源 Amazon | NZXT E850 デジタル電源ユニット 80 Plus Gold 認証 [ 定格 850W 出力 ] NP-1PM-E850A-JP NP-1PM-E850A-JP SP947 | NZXT | パソコン・周辺機器 通販 マザーボード Amazon | ASRock AMD Ryzen 3000シリーズ CPU(Soket AM4)対応 X570チップセット搭載 ATX マザーボード X570 Steel Legend | ASROCK CPU AMD Ryzen 4750G\nCPUクーラー Amazon | NZXT KRAKEN Z63 簡易水冷CPUクーラー 液晶モニタ搭載 RGB対応 280mm RL-KRZ63-01 FN1441 | NZXT | CPUファン 通販 メモリ Amazon | G.SKILL 128GB(4 x 32GB)Trident Z NeoシリーズDDR4 SDRAM 3200MHz PC4-25600デスクトップメモリモデルF4-3200C16Q-128GTZN | G.Skill | メモリ 通販 SSD Amazon | Seagate FireCuda 520 M.2 1TB PCIe Gen4x4 内蔵SSD M.2 2280 3D TLC ZP1000GM3A002 | SEAGATE グラボ Amazon | GIGABYTE NVIDIA GeForce RTX3080搭載 グラフィックボード GDDR6X 10GB ホワイトモデル【国内正規代理店品】GV-N3080VISION OC-10GD | 日本ギガバイト 拡張カード Amazon | ASRock 拡張インターフェースボード Thunderbolt 3 AIC R2.0 | ASROCK | インターフェースカード 通販 拡張カードは実は差し込んだら最初うまく動かなくてサポートに連絡しました。同じ構成の検証機を用意して解決方法を見つけてもらいました。しかも数日で。サイコーのエクスペリエンスでした!\n日本語でサポートしてもらえてしかも数日で解決してもらった。ASRockのサポートすばらしかったです! https://t.co/8FasCInIqt\n\u0026mdash; Jun Ohtani (@johtani) December 8, 2020 その他 ケースのフロントパネルのUSB-Cポートを使えるようにするために。\nAmazon | Cablecc USB 3.1フロントパネルソケットType-E-マザーボード用USB 3.0 20ピンヘッダーオス拡張アダプター | cablecc | PCアクセサリ・サプライ 通販 最近のPCパーツはUSBでモニタリングできるみたいで、マザボのUSBポートが足りなかったので拡張しました。\nAmazon | マザーボードのUSB 9ピン 増設 内部用4ポートUSB2.0 HUB | ノーブランド品 | USBハブ 通販 白いケースだし、「映え」のために白いケーブルを。\nAmazon | Novonest 電源専用延長スリーブ 補助電源モジュラーケーブル 長さ300mm 6本1セット スリーブガイド24点セット付き 【SC304】 | novonest | 電源ユニット 通販 組み立て中 手元にあったCPUでBiosアップデート(Ryzen 5000シリーズにしたかったから。まだできてないけど)。\n応急処置でBiosアップデートしてる pic.twitter.com/mXf2B5kwqB\n\u0026mdash; Jun Ohtani (@johtani) November 8, 2020 さーて、頑張るぞー pic.twitter.com/HmlGqREjmP\n\u0026mdash; Jun Ohtani (@johtani) November 13, 2020 さて、仮起動実験ですよと pic.twitter.com/5HP3cbs6SH\n\u0026mdash; Jun Ohtani (@johtani) November 13, 2020 きたきたー pic.twitter.com/4sL3ymecEo\n\u0026mdash; Jun Ohtani (@johtani) November 13, 2020 コネクター刺しまくらないと pic.twitter.com/Soye3lS4M9\n\u0026mdash; Jun Ohtani (@johtani) November 13, 2020 完成はこんなかんじ 初期構成\n組み上がったよー pic.twitter.com/sBwpvLsZh3\n\u0026mdash; Jun Ohtani (@johtani) November 14, 2020 グラボデプロイ\n設置完了してこんな感じ。なんかベンチマーク走らせるかなぁ。何がいいだろ pic.twitter.com/aZufAE9fJA\n\u0026mdash; Jun Ohtani (@johtani) December 4, 2020 グラボのおまけも付けてみた。\nまぁ、せっかくついてきたので取り付けてみました(グラボ下の光ってるパネル)。 pic.twitter.com/068IxaV1ps\n\u0026mdash; Jun Ohtani (@johtani) December 4, 2020 とまぁ、こんな感じでした。 メモリは多分使い切れないだろうなぁと思いながら、やってみたかったという感じです。。。\n","date":1609422526,"dir":"post/2020/","id":"64a421c2367372c3199c66a6420faf89","lang":"ja","lastmod":1609422526,"permalink":"https://blog.johtani.info/blog/2020/12/31/diy-pc/","publishdate":"2020-12-31T22:48:46+09:00","summary":"振り返りブログにも書きましたが、デスクトップPCを自作(DIY)しました。 組み立てたに使ったパーツのアフィリンクを貼っておきます。 10月くら","tags":["misc"],"title":"PCもDIYしました"},{"contents":"今年も振り返りブログ書いてます。カタンの航海者版を購入して家族とやってましたが、負けてしまいました。\n振り返り(2019年に書いた抱負から) まずは去年の抱負を元に書きますが、3月以降はコロナウィルスの影響でいろいろと生活が変わってしまいましたね。\n職につく 厳密には達成してないことになるのかな?\n1月末にフリーランスはじめました(仮)という記事を書きましたが、 そのまま、現時点では個人事業主でフリーランスとして4社ほどお手伝いさせていただいています。\nお手伝いしてるお客さんの事例が出てた。直接的に類似画像検索の部分を手伝ってるわけではないんですが、Azure Cognitive Searchの調査とかやってます。 / 「ハッカソン」で社外の知見を積極的に活用! 富士フイルムソフトウエアが実践するサービス開発の理想形 - https://t.co/yDIwYmYDBM\n\u0026mdash; Jun Ohtani (@johtani) June 19, 2020 名前出てた。ZOZOさんの手伝いさせていただいております。 / ZOZOTOWNにおける検索速度改善までの道のり - ZOZO Technologies TECH BLOG - https://t.co/OqaFMYe0TY\n\u0026mdash; Jun Ohtani (@johtani) August 20, 2020 こんな感じです。 コロナウィルスの影響もあり、完全リモートで仕事をさせていただいています。 感謝しかないです。\nブログプラットフォームの移行 昨年の振り返りの時点で目を付けていたHugoへの乗り換えを行いました。 乗り換えについてもまとめてあります。\nOctopressからHugoへ移行中(まだ途中) ブログ移行日記(その1) - Hugoとテーマ ブログ移行日記(その2) - Markdownファイルの変換 ブログ移行日記(その3) - Hugoの設定と微調整(テーマに合わせた) ブログ移行日記(その4) - 検索機能(Algolia)の導入 ブログ移行日記(その5) - Jugemのブログを移行 無事移行できて、特に困ってない感じです。\nプログラミング 昨年よりは書いた気がしています。 まぁ、書きなぐって放置してるのもありますが。。。\n細々としたツールがいくつか。\nfrom-octopress-to-hugo bulk2es-rs azure-search-analyze-client wiki-extractor-rs kuromoji-graphviz-output kuromoji-cli あとは、Linderaという形態素解析も手伝ってみました。 ちょっと後半は忙しくなり、コーディングが減ってるんで、また復活させないと。\nRust再入門 Tantivyは結局触れてないけど、Linderaを手伝えました。あとは、ちょっとしたツール(bulk2es-rs)なども作りました。 知り合いとやっていたRust the bookを読むのも一通り終わりました。 Linderaまわりのリファクタとかを年明けにやろうかな?\n検索の勉強 仕事になりました。というか、しました。 ブッチャー本も買ったんですが、手を付けられてないので、年明けから心機一転、よみ始めようと思います。\n検索技術勉強会の継続 残念ながらだめでした。 年初にスピーカーの方に連絡は入れて履いたのですが、コロナウイルスの影響で 今年はオフラインの勉強会は無理だろうとい事で延期したままです。 オンラインの勉強会もいくつか開催されていましたが、検索技術勉強会は残念ながらモチベーションもわかずのまま今年も終わってしまいました。 単に話を聴くセミナーのようなものよりは、Podcastのような形を取るのがいいのかもなぁとは思っているのですが。。。 だれか、サクッと話したい人いたらやってみませんか?\n振り返り(今年あったできごと) さて、ここからは今年の出来事を。\n自宅環境の改善 Windowsへの移行 キーボードDIY フリーランス ブログ書いたなぁ 3月以降はずーっと自宅で仕事してました。 ということで、自宅の環境がどんどんアップデートされていった1年でした。 最終バージョンは年内に間に合わなくて、年明けに書きますが。。。 途中経過はこんな感じでした。今は更に変わっていますが。\n3月バージョン 9月バージョン 12月バージョンでも書きますが、ずっと自宅で作業だったのもあり、自作PCをやりたくなったので、久々にWindowsに帰ってきました。Ubuntuもチョット検討しましたが、Windowsに今は落ち着いています。自作PCはこんな感じ。 自作PCブログも後で書きますね。\n設置完了してこんな感じ。なんかベンチマーク走らせるかなぁ。何がいいだろ pic.twitter.com/aZufAE9fJA\n\u0026mdash; Jun Ohtani (@johtani) December 4, 2020 Windowsをお試し中 Windowsへの移行(その1) AutoHotKeyで色々と弄っているので、素のWindowsは触れる気がしないけど。。。\n自作つながりで、キーボードもDIYしました。\nDozen0を作成した Corne Light v2を作成した Corne Chocolateを組み立てた Sofle Keyboardも組み立てた(けど、ビルドブログはまだ) 分離キーボードには昨年から興味があったのですが、手を付けていませんでした。 今年は自宅でずっと作業でしたから、これを機会に作ってみました。 既製品(Moonlander)も気になってはいたのですが、DIYキーボードはプラモデル感覚で作れそうだし面白そうだなと。 今年一番ハマったものかもしれないです。 知り合いが始めたKochi Keyboardで最初に発売されたのがCorne Light v2だったので、これが初めての分割キーボードです。 40%キーボードからいきなり入ったので最初はかなり大変でしたが、なれると入力が早くなる気がします。ホームポジションからほぼ動かないのはいいですね。最初は数字列がないのでアホか???と思っていましたが。 今は、Sofle(60%キーボード)がメインになっています。40%から60%に移行すると 数字のキーが遠いなと思ってしまいますねw\nどうなるものかと思いつつ、フリーランスを続けています。 最初に仕事をいただいた富士フイルムソフトウェアさんには非常にお世話になっています(今もお手伝いさせてもらっています、ありがたい)。来年も精進していきます!\n今年はブログを書きました、最後はちょっと息切れしてる感じになってるけど。。。 もっとカジュアルに書くようにしないとなぁ。 年明けにまだ書いてないブログを書いていかないと。「自作PCブログ」「Sofleのビルドブログ」「2020年買ってよかったブログ」とか。\n来年の抱負 ということで、来年の抱負です。\nフリーランス継続? プログラミング 検索の勉強 検索のポッドキャスト? とりあえず今年は乗り切れました。来年も食べていくためにもフリーランスを継続できるように、お手伝いさせて頂いてる各社に 継続してもらえるように精進していきます。色々と勉強させて頂いてるのでほんとうにありがたいです。\nプログラミングは今年の後半はスローダウンしてしまったのでがんばらないと。 検証用のコードやちょっとしたツールを書くほうが多いので、もう少し継続してメンテナンスするようなものも書きたいなぁと。\n検索の勉強はまずはブッチャー本を買ってしまったので、ここからでしょうか。 値段も厚みもすごいので、コツコツ元を取れるようにがんばります。。。\n来年もまだまだ自宅で仕事が続きそうなので、勉強会というよりもポッドキャストみたいなものをやるのがいいのかもなと。 2020年初にやらせていただいた、「検索システム探訪」をポッドキャスト風にやるのもありなのかもなぁ。 興味ある人いたら連絡ください。公開しない雑談とかもありだと思ってるので。\n今年は色々ありましたが、無事に乗り切れました。 気軽にランチなどで遊びに行けない状況ですが、雑談相手になっていいなと思う方、連絡お待ちしています。\nさて、来年はどんなキーボード作るのかなぁ(え?また作るの??)。 今後もよろしくおねがいしまーす!\n","date":1609406004,"dir":"post/2020/","id":"a5b2ee641e10d3e4db8f888217ab9ecc","lang":"ja","lastmod":1609406004,"permalink":"https://blog.johtani.info/blog/2020/12/31/looking-back-2020/","publishdate":"2020-12-31T18:13:24+09:00","summary":"今年も振り返りブログ書いてます。カタンの航海者版を購入して家族とやってましたが、負けてしまいました。 振り返り(2019年に書いた抱負から) ま","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2020)"},{"contents":"Elastic stack (Elasticsearch) Advent Calendar 2020の18日目の記事になります。\n本日の勉強会でLTをしましたが、しゃべり足りなかったんで。 Elasticsearch 7.8でこっそりとリリースされたIndex Template V2について調べたのでどんなものかをまとめてみます。 リリースブログには出てきてない(7.8のEsのページのWhat\u0026rsquo;s newには出てた)ので気づいてない人も多いのではないでしょうか?\nIndex Templateとは? まずはIndex Templateがどんなものかを説明しましょう。\nIndexの設定やマッピングはデフォルト値以外を設定したい場合に、毎回\u0026quot;mappings\u0026quot;や\u0026quot;settings\u0026quot;の設定を指定してIndexを作成するのは手間がかかります。 そこで便利な機能として提供されているのがIndex Templateです。このIndex TemplateはCluster Stateに保管されます。\nIndex Templateを利用するときの流れは以下の通りです。\nIndex Templateの作成 Indexの作成 例えば、3ノード構成のクラスターでインデックスを作成するときに常に\u0026quot;number_of_shards: 3\u0026quot;を設定したいとします。 Index Templateは次のような感じになります。\nPUT _template/blog_num_shards { \u0026#34;index_patterns\u0026#34;: \u0026#34;blog_*\u0026#34;, \u0026#34;settings\u0026#34;: { \u0026#34;index\u0026#34;: { \u0026#34;number_of_shards\u0026#34;: 3 } } } または日本語のシンプルな形態素解析のアナライザーの設定を\u0026quot;jp_\u0026ldquo;という名前でるようできるようにしたい場合には次のような感じになります。\nPUT _template/jp_simple_kuromoji { \u0026#34;index_patterns\u0026#34;: \u0026#34;jp_\u0026#34;, \u0026#34;settings\u0026#34;: { \u0026#34;index\u0026#34;: { \u0026#34;analysis\u0026#34;: { \u0026#34;simple_jp\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;custom\u0026#34;, \u0026#34;tokenizer\u0026#34;: \u0026#34;kuromoji\u0026#34; } } } } } インデックステンプレートの登録が終われば、インデックスを作成するタイミングでIndex Templateが適用されます。 例えば、blog_2020というインデックスを作成すると、number_of_shards: 3のインデックスが作成されます(デフォルトは1)。 jp_blog_2020というインデックスを作成すると、simple_jpというAnalyzerが設定されています。 このように、インデックス名を意識するだけで設定が適用されていくのが利点です。\nちなみに、Index TemplateはIndex作成時に適用されるだけなので、Index Templateを変更してもこれまでのインデックスへは影響はありません。\nこれまでのIndex Templateの問題点 と、Index Templateが便利なのはわかりましたが、ではなぜ今回V2がリリースされたのでしょうか? 先ほどの例を見るとわかりますが、これまでのIndex Templateは部品化が難しいのが問題でした。 Index Templateはそれぞれがインデックスの作成時に適用されます。 が、Index TemplateにIndex Templateを組み込むことはできません。 例えば、先ほどサンプルとして作成したjp_simple_kuromojiのIndex Templateはjp_で始まるインデックスにしか適用できません。\nでは、blog_で始まるインデックスにもkuromojiのシンプルなアナライザーを使いたくなった場合はどうなるでしょう? 残念ながら、jp_simple_kuromojiと同じ設定をblog_num_shardsのテンプレートに追加するか、jp_simple_kuromojiのindex_patternsの部分だけを書き換えた新しいテンプレートを用意するか、jp_simple_kuromojiのindex_patternsにjp_を追加する方法です。 いずれにしてもIndex Templateの継承(複数のテンプレートを1つのインデックスに紐づける)が必要となります。 この時、複数のIndex Templateが適用されるため、適用する順番が出てきます。 この順番をIndex Templateのorderパラメータで指定できます。\nただ、これも問題のもととなっていました。 複数あるIndex Templateのどれがどの順番で適用されるのか?それはインデックスを作成時にようやくわかります。 使いたい側(インデックス)が、使いたいもの(テンプレート)を指定するのではなく、その逆(使いたいものに使いたい側の情報を設定しなくてはならない(index_patternsやorder))になっているのでわかりにくくなっていました。\nということで解決策としてリリースされたのがIndex Template V2です(ちなみに名前にV2とは言ってるわけではなく、現在のIndex Templateの機能がlegacy index templateという名前になり、Deprecatedになっています(まだログには出ない))。\nIndex Template V2 7.8のWhat\u0026rsquo;s newドキュメントではComposable Index Templateと紹介されています。 大きく3つのエンドポイントが提供されます。\nComponent Template 用API テンプレートのコンポーネントという単位で管理するためのAPI。 登録更新、削除、取得が可能 Index Template 用API Index Templateを管理するためのAPI 登録更新、削除、取得が可能 Simulate index template API(Experimental) Index Template Legacy Index Templateとの大きな違いは、\nテンプレートをコンポーネントにできる 1つのインデックスに適用されれるテンプレートは1つだけ という点です。これまでとは挙動が異なるので注意が必要です。\n新しいIndex Templateを利用する際の流れは次のようになります。\nComponent Templateの作成 Index Templateの作成 作成したIndex Templateの挙動を確認 実際にIndex名を指定してIndex Templateの挙動を確認 という形です。では、それぞれの機能を見ていきましょう。\nCoponent Template API テンプレートコンポーネントを管理するためのAPIです。 具体的なAPIごとに説明していきます。\nPUT _component_template コンポーネントを登録、変更するためのAPIです。公式ドキュメントはこちらです。 先ほどのkuromojiのAnalzyerをコンポーネントとして登録してみましょう。\nPUT _component_template/jp_simple_kuromoji { \u0026#34;template\u0026#34;: { \u0026#34;settings\u0026#34;: { \u0026#34;index\u0026#34;: { \u0026#34;analysis\u0026#34;: { \u0026#34;analyzer\u0026#34;: { \u0026#34;simple_jp\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;custom\u0026#34;, \u0026#34;tokenizer\u0026#34;: \u0026#34;kuromoji_tokenizer\u0026#34; } } } } } }, \u0026#34;version\u0026#34;: 1, \u0026#34;_meta\u0026#34;: { \u0026#34;description\u0026#34;: \u0026#34;simpleなKuromoji analyzer\u0026#34; } } 先ほどと特に違いはありません。templateという階層が1段増え、index_patternsがなくなりました。 template部分はIndexに設定するsettings、mappings、aliasesが指定可能です。 ちなみに、\u0026ldquo;template\u0026quot;の中身をそのままIndex作成時に使用した場合にエラーにならない設定である必要があります。 ここは注意が必要です。例えば、component Aでkuromojiのアナライザーの設定をし、component Bでそのアナライザーを使用するフィールドのmappingだけを記述した場合、component Bでエラーが発生します。上記のようなシチュエーションでは、Index Templateで利用するフィールドを定義し、component Aを利用する宣言をすれば問題ありません。\nそのほかに使えるパラメータで便利なものを紹介しておきます。\nクエリパラメータ\ncreate: URLに指定するパラメータ。trueを指定することで、既に存在する場合にエラーを返してくれる。更新も同じAPIなので間違わないようにするために利用すると便利。デフォルトはfalse リクエストボディ\n_meta: テンプレートにメタ情報を付与できる。_metaの中は自由に記述可能。コメントなどを書いておくとあとでわかりやすい GET _component_template コンポーネントを取得するためのAPIです。公式ドキュメントはこちらです。 一覧での取得とリストでの取得が可能です。\n一覧取得サンプル\nGET /_component_template GET /_component_template/* これ以外に、IDを指定して取得することも可能です。\nGET _component_template/jp_simple_kuromoji *を利用して複数取得も可能です。\nGET _component_template/jp* GET _component_template/j*_* DELETE _component_template コンポーネントを削除するためのAPIです。公式ドキュメントはこちらです。 IDを指定してコンポーネントを削除できます。\nDELETE /_component_template/jp_simple_kuromoji ID指定以外に*を利用することも可能ですが気を付けて使用しましょう。\nDELETE /_component_template/jp_* DELETE /_component_template/* ちなみにIndex Templateで利用されているコンポーネントを削除しようとした場合はエラー(ステータスコード400)が返ってきます。 *などを使用して削除しようとした場合は、ひとつでも利用されているものが含まれている場合は削除は実行されずにエラーだけが返ってくるようになっています。\nIndex Template API Index Templateを管理するためのAPIです。 Component Template APIで定義したコンポーネントを利用してテンプレートを作成できます。コンポーネントを利用しないで単体で完結したテンプレートも作成可能です。 具体的なAPIごとに説明していきます。\nPUT _index_template Index Templateを登録・更新するためのAPIです。公式ドキュメントはこちらです。\nこれまでのLegacy Index TemplateのAPIのエンドポイント(_template)ではなく、(_index_template)というエンドポイントになっていることにまず注意してください。 先ほど作成したjp_simple_kuromojiコンポーネントと、追加で作成した3_shardsというコンポーネントを利用して blog_で始まるインデックスに適用できるIndex Templateを作成してみましょう。\nPUT _index_template/blog_template { \u0026#34;index_patterns\u0026#34;: [\u0026#34;blog_*\u0026#34;], \u0026#34;template\u0026#34;: { \u0026#34;mappings\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;hoge\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;simple_jp\u0026#34; } } } }, \u0026#34;priority\u0026#34;: 100, \u0026#34;composed_of\u0026#34;: [\u0026#34;jp_simple_kuromoji\u0026#34;, \u0026#34;3_shards\u0026#34;] } composed_ofというパラメータに利用したいコンポーネントを配列で記述していきます。 Index Templateが適用される時に、ここに記述されている順番でコンポーネントが適用されていきます。 ですので、最後に書いてあるテンプレートが一番強いことになります。 これは例えば、同じ設定値number_of_shardsを2つのコンポーネントが設定している場合に、最後に設定した値がインデックスに採用されるという意味です (公式ドキュメントにサンプルが掲載されています)。 なお、存在しないコンポーネントをcomposed_ofに指定した場合は400エラーが返ってきます。同じコンポーネントを複数重複して指定した場合は特にエラーにはなりませんでした。 composed_ofを指定しなければ、単体で完結したテンプレートを定義可能です。\n次に重要な設定はpriorityです。これまでのテンプレート機能と異なる点で説明しましたが、\n1つのインデックスに適用されれるテンプレートは1つだけ となっています。 この1つを決めるための値がpriorityになります。 インデックス名によってはindex_patternの定義によって、複数のIndex Templateにマッチします。例えばblog_*と*_2020のIndex Templateがあった場合にblog_2020というインデックスを作った場合です。 この時、Elasticsearchはpriorityの大きい値を持ったIndex Templateだけを適用します。 blog_*のIndex Templateのpropertyが10、*_2020のIndex Templateのpropertyが100だった場合、*_2020のテンプレートが適用されます。Legacy Index Templateではorderという似たパラメータがありましたが、こちらは適用する順序を決定するためのものでした。挙動が違うので注意しましょう。\nちなみに、blog_*と*_2020のpropertyがどちらも10というIndex TemplateをPUTしようとした場合、2番目にIndex TemplateをPUTするタイミングでエラーが返ってきます。\nそのほかに使えるパラメータで便利なものはPUT _component_templateと同様にcreateと_metaです。\nGET _index_template Index Templateを取得するためのAPIです。公式ドキュメントはこちらです。 一覧での取得とリストでの取得が可能です。\n一覧取得サンプル\nGET /_index_template GET /_index_template/* これ以外に、IDを指定して取得することも可能です。\nGET _index_template/blog_template *を利用して複数取得も可能です。\nGET _index_template/blog_* GET _index_template/b*_* DELETE _index_template Index Templateを削除するためのAPIです。公式ドキュメントはこちらです。\nIDを指定してコンポーネントを削除できます。\nDELETE /_component_template/jp_simple_kuromoji ID指定以外に*を利用することも可能ですが気を付けて使用しましょう。\nDELETE /_component_template/jp_* DELETE /_component_template/* 最後のサンプルを実行すると、Elasticのツールなどが登録したIndex Template以外はすべて削除されてしまうので本当に気を付けましょう。\nSimulalte API さて、コンポーネントとテンプレートを作成したので確認をしましょう。 Legacy Index Templateでは確認するためには実際にインデックスを作成するしかありませんでしたが、V2ではSimulate APIが用意されています。 このSimulate APIには2つのAPIがあります。\nPOST /_index_template/_simulate/\u0026lt;テンプレート名\u0026gt; POST /_index_template/_simulate_index/\u0026lt;インデックス名\u0026gt; Index Templateの確認のためのAPIとインデックス名を指定したときに出来上がるIndexの設定を確認するためのAPIです。 Indexを実際に作成しなくても確認できるのは便利ですね。\n例えば先ほど作成したblog_templateを試してみましょう。\n_index_template/_simulate API POST _index_template/_simulate/blog_template レスポンスはこんな感じです。\n{ \u0026#34;template\u0026#34; : { \u0026#34;settings\u0026#34; : { \u0026#34;index\u0026#34; : { \u0026#34;analysis\u0026#34; : { \u0026#34;analyzer\u0026#34; : { \u0026#34;simple_jp\u0026#34; : { \u0026#34;filter\u0026#34; : [ \u0026#34;kuromoji_readingform\u0026#34; ], \u0026#34;type\u0026#34; : \u0026#34;custom\u0026#34;, \u0026#34;tokenizer\u0026#34; : \u0026#34;kuromoji_tokenizer\u0026#34; } } }, \u0026#34;number_of_shards\u0026#34; : \u0026#34;3\u0026#34; } }, \u0026#34;mappings\u0026#34; : { \u0026#34;properties\u0026#34; : { \u0026#34;hoge\u0026#34; : { \u0026#34;type\u0026#34; : \u0026#34;text\u0026#34;, \u0026#34;analyzer\u0026#34; : \u0026#34;simple_jp\u0026#34; } } }, \u0026#34;aliases\u0026#34; : { } }, \u0026#34;overlapping\u0026#34; : [ { \u0026#34;name\u0026#34; : \u0026#34;blog_template2\u0026#34;, \u0026#34;index_patterns\u0026#34; : [ \u0026#34;blog_*\u0026#34; ] } ] } templateにコンポーネントがマージされた結果が出力されます。 overlappingはindex_patternsがかぶる可能性があるIndex Templateの情報が出力されます。 サンプル用にblog_template2という、同じindex_patternsでpriorityが低いものを登録してあるためです。 index_patternsが完全に同じではなくとも、重複する可能性があるものはここに出力されます。 例えば、index_patternsがb*という別のIndex Templateを作成してからSimulate APIを実行すると、overlappingにそのIndex Templateも出力されます。\nSimulate Index Template APIのもう一つの機能は登録前のIndex Templateの確認です。 リクエストのURLのテンプレート名をなくし、PUT _index_templateと同じJSONをリクエストボディとして送信した場合、コンポーネントをマージしたテンプレートがどんなものかを確認できます。\nPOST _index_template/_simulate { \u0026#34;index_patterns\u0026#34;: [\u0026#34;blog_*\u0026#34;], \u0026#34;template\u0026#34;: { \u0026#34;mappings\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;hoge\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;simple_jp\u0026#34; } } } }, \u0026#34;priority\u0026#34;: 10, \u0026#34;composed_of\u0026#34;: [\u0026#34;jp_simple_kuromoji\u0026#34;] } このリクエストを送信すると、コンポーネントがマージされた結果が返ってきます。index_patternsがかぶるものがある場合はoverlappingも一緒に返却されます。\n_index_template/_simulate_index API 今度はインデックス名を指定するSimulate APIを試してみましょう。\nPOST _index_template/_simulate_index/blog_2021 これだけです。\n{ \u0026#34;template\u0026#34; : { \u0026#34;settings\u0026#34; : { \u0026#34;index\u0026#34; : { \u0026#34;analysis\u0026#34; : { \u0026#34;analyzer\u0026#34; : { \u0026#34;simple_jp\u0026#34; : { \u0026#34;filter\u0026#34; : [ \u0026#34;kuromoji_readingform\u0026#34; ], \u0026#34;type\u0026#34; : \u0026#34;custom\u0026#34;, \u0026#34;tokenizer\u0026#34; : \u0026#34;kuromoji_tokenizer\u0026#34; } } }, \u0026#34;number_of_shards\u0026#34; : \u0026#34;3\u0026#34; } }, \u0026#34;mappings\u0026#34; : { \u0026#34;properties\u0026#34; : { \u0026#34;hoge\u0026#34; : { \u0026#34;type\u0026#34; : \u0026#34;text\u0026#34;, \u0026#34;analyzer\u0026#34; : \u0026#34;simple_jp\u0026#34; } } }, \u0026#34;aliases\u0026#34; : { } }, \u0026#34;overlapping\u0026#34; : [ { \u0026#34;name\u0026#34; : \u0026#34;fuga\u0026#34;, \u0026#34;index_patterns\u0026#34; : [ \u0026#34;b*\u0026#34; ] }, { \u0026#34;name\u0026#34; : \u0026#34;2021\u0026#34;, \u0026#34;index_patterns\u0026#34; : [ \u0026#34;*_2021\u0026#34; ] } ] } 例で作成したblog_templateが適用されていますが、それ以外にindex_patternsに合致したがpriorityが低くて適用されなかったものがoverlappingに出力されています。 実際に適用されたテンプレートの名前も別途出力してくれるとわかりやすいかもしれないですね。 (*_2021というインデックスパターンのテンプレートを試しに作ってみたのですが、これはバグがありそうです。2021に合致するインデックス名をSimulateしたらoverlappingに合致しないものがたくさん出てきました。バグ報告しとくか)。\nKibana対応 ここまで、Index Template V2のAPIの説明でしたが、Kibanaでの対応についても調べてみました。\nIndex Management(Stack Management機能。Elasticライセンスが必要だが無償の機能) 7.9からKibanaのIndex管理画面でComposable Templateが利用できるようになっています(GitHub Issue)。 画面のスクショを一通り貼っておきます。残念ながら、それぞれのJSONの編集部分では補完などはサポートされていないようでした。 頑張って自分でsettingsやmappingsのJSONを記述していく感じになります。JSONとして正しいかどうかはチェックしてくれます。 Index Templateのウィザードでは、ボタンでコンポーネントを追加したり削除したり、順序を入れ替えたりといった作業が可能になっています。 また、プレビュー表示が可能なので、composed_ofで選択したものが今どのように適用されているか?といったのも確認できるようになっていました。 結構便利に管理できそうです。ちなみにスクショは7.10の画面になります。\nComponent Template周り 一覧表示とウィザード Index Template周り 一覧表示とウィザード Console(Dev Tools。OSSで利用可能) リクエストを実行は可能ですが、自動補完機能は一部のみ対応しているようです(GitHub Issue)。\n対応済みの機能\nDELETE _component_template (ただし、ここまで。存在するコンポーネント名は補完されない) 上記以外はまだ未対応のようです。 プルリクエストチャンスかも?\n参考 Composable Templates · Issue #53101 · elastic/elasticsearch What’s new in 7.8 | Elasticsearch Reference [7.8] | Elastic Index management | Elasticsearch Reference [7.10] | Elastic [Composable template] Create / Edit wizard by sebelga · Pull Request #70220 · elastic/kibana [Console] Support suggesting index templates v2 · Issue #75967 · elastic/kibana まとめ ちょっと長くなってしまいましたが、新しいIndex Templateについての紹介でした。 これまでと違い、複数のテンプレートが適用されない点があるのでそこは注意が必要そうです。 コンポーネントをうまく使えば、管理が簡易化はされそうですね。\n","date":1608216955,"dir":"post/2020/","id":"c6fc88bd57a0e57ddf22e2eb1bef892c","lang":"ja","lastmod":1608216955,"permalink":"https://blog.johtani.info/blog/2020/12/17/index_template_v2/","publishdate":"2020-12-17T23:55:55+09:00","summary":"Elastic stack (Elasticsearch) Advent Calendar 2020の18日目の記事になります。 本日の勉強会でLTをしましたが、しゃべり足りなかったんで。 Elasticsearch 7.8でこっそりとリリースされたI","tags":["elasticsearch"],"title":"Index Template V2"},{"contents":"はじめまして、pyspa。 ということで、pyspa Advent Calendar 2020の4日目(大谷コンビの2号)の投稿になります。 コンビそろってキーボード記事ですね。\n今年はDIYキーボードにはまった(はめられた?)年でした。 もともと分割キーボードには興味があり、自宅で作業するのが基本となったのもあり手を出した次第です。 まだまだ使いこなすところまでは来てないかもしれないですが、組み立てたり、問題点のキリ分けしたり、試行錯誤するのは楽しいなと。\n今回はCorne Chocolateというキーボードを組み立てたのでそちらのビルドログ(かつ今後のための教訓)になります。 LEDを使ったキーボードがどんなものなのか+薄いキーボードも気になるなということで取り組んでみました。 今回もいくつか失敗をしつつ、リカバリーして動くものができました。\nパーツ(材料) 基本のパーツは今回もKochi Keyboardさんから購入しました。\nキット : Corne Chocolate(ベースキット) キースイッチ : Kailh Choc v1 Blue (25gf リニア) 5個 キーキャップ : Kailhロープロ刻印キーキャップ ケーブル類は家に転がっていたケーブルを利用しました。 キースイッチセットもあるのですが、軽いキータッチが好みなので、一番軽いKailh ChocのBlueを試してみたくキースイッチを個別に選択しました。 キーキャップはShiroを作るときに調達していたものを利用した形です。\n今回も公式のビルドガイドにざっと目を通してから着手しました。\n準備 ビルドログにもあるようにPCBがリバーシルブなので、作業中に迷子にならないようにこんな感じで表にマスキングテープで目印をつけておきました。\n今回から耐熱ワーキングマットで作業をすることにしました。机の天板に傷つくの嫌だし。 気兼ねなくはんだできるのでおすすめです。\nhttps://t.co/0qntPD8qIa\n2ヶ月ぐらいにここで買いました!\n\u0026mdash; 西田和史(k.bigwheel) 開発基盤EM (@k_bigwheel) November 11, 2020 ダイオード、OLEDソケット、コンスルー、TRRSソケット、 こちらは前回のCorneとほぼ同様だったのでビルドガイド通りに進めます(写真撮り損ねました。。。) 前回との違いはダイオードの形です。 表面実装するタイプのダイオードなので向きに気を付けつつ、つけていきます。\nビルドガイドに向きやダイオードのつけ方が紹介されています。 拡大鏡とピンセット必須ですね。 前回同様に、ここまででいったんqmk_toolsでファームウェアをインストールして、ピンセットを使いながらキーの認識とOLEDの動作確認を行いました。 今使っているファームウェアがあるのでそれを入れて問題ないかを確認しました。\nLED実装 今回のメインイベントです(そして苦杯をなめたイベントでもあります)。 ビルドガイドにも記載がありますが、信号が流れる順番があるようなので1番から取り付けていきます。 また、ビルドガイドにLEDに関する注意事項もいくつか掲載されています。必ず読みましょう。\nこの1~6までのLEDがすごく大変でした。。。\n表面実装のLED(Underglow LED)で四苦八苦 いくつかのブログを参考にしながら作業を進めました。\nコルネキーボードを作りました ~LED取り付けに四苦八苦記~ | キオクノロンダリング SK6812miniの仕様などについて書いてあります。デバッグするのにすごく役に立ちました。 Corne Chocolateビルドログ - nokの雑記 手書きでどんな感じでやればいいのかを解説してくれています。最終的にはこの方法が一番だったのかも? 自作キーボードキット「Corne Cherry」のレビュー - 自作キーボード温泉街の歩き方 あとで出てきますが、リカバリ方法の参考になりました。 皆さん苦労されてますね、そして私も苦労しました。。。\n試してみた方法、考察は次の通りです。\nLEDチェック用のファームウェアをインストールして1つつけては動作確認 HelixのLEDテスト用ファームウェアをインストールしました。 白光 1C型こて先 失敗した後にリカバリするために購入しました。 LEDのランドなどが2Cよりも面積が小さいので、そのサイズに合わせたこて先のほうがよかったようです。 はんだの温度(温調できるはんだごて必須) 最初は250℃でやっていましたが、なかなかはんだが溶けません。そのせいで焦りも出てきます。 最終的には270度で作業しましたが、温度のせいでLEDが壊れたのはなかった気がします。1Cのこて先だったので無事だったのかもしれません。 フラックスなし あると楽だったのかも?残念ながら試してないです。 予備はんだ手法(だめっぽかった) 基盤のランド4か所に予備はんだをし、はんだを温めつつLEDを乗せる方法 LEDの裏にも予備はんだ どちらも試してみましたが、温めている個所以外のはんだと高さの違いが出てしまい、LEDが浮いてしまいます。4か所を同時に温めることはできないので、すこしずつ調整しているうちにLEDを物理的に壊してしまうことがありました。。。 ちょっとコツが分かったかも? pic.twitter.com/ruwrmEWCAe\n\u0026mdash; Jun Ohtani (@johtani) November 19, 2020 わかった気になっていますが結局失敗しました。。。\n結局最後までこれというコツはわかってない気がします。結局3つか4つのLEDがお亡くなりになりました。 うまくいかなかった原因は、予備はんだで傾きなどができ、それを修正していくうちに基盤やLEDにダメージを与えてしまったのだと思います。\nよく見ると基盤が一部剥がれかけてるのがわかるかなぁと。\nリカバリー 右手側の表面実装の4番と5番が失敗しました。\n4番目(以下のツイート右側画像の上) こちらは、1度付けたLEDをはがすときにはんだを取り除くのが不十分な状態でLEDをはがしたために、基板のランドごとはがれてしまいました。 なのでここはLEDはつかないです。。。 5番目(以下のツイート右側画像の真ん中あたりの黄色い線がつながっているLED) LED自体はつけてありますが、青色しか発光しなくなっています。 4番目が完全に死んでしまったので、無事な3番目のLEDのDINに流れている信号を 5番目のLEDのDINにも流れるようにするために10芯コードでショートカットさせました。 (リカバリ方法は先ほど紹介したブログが非常に参考になりました、先人の知恵ありがたし)。 黒い線も売っていたのですが、自戒も込めて目立つ色にしてみました。\n勉強させていただきました、、、 pic.twitter.com/Zp16fJKziM\n\u0026mdash; Jun Ohtani (@johtani) November 22, 2020 ちなみに、左側のショートカットのコードはつけた後に1か所LEDの向きが違うことに気づき必要なくなっています (上記の基盤が傷ついている画像をよく見ると上下が逆になってるのがわかる人にはわかるかも)。\n片方は導線なくて良くなった。表から見たら向きが違うのに気がついたわ、、、 pic.twitter.com/7TSDMPPxlX\n\u0026mdash; Jun Ohtani (@johtani) November 22, 2020 最終的に2か所おかしいLEDにはなりましたが、幸いにもアンダーグローです。 Kochi Keyboardさんで購入したキットのボトムプレートはFR4なのでほぼ見えません!(負け惜しみ)\nソケット さて、気を取り直してソケットをつけていきます。 Dozen0にて経験済みなのでそれほど手間はかかりませんでした。 LEDの失敗の時に1Cのこて先を購入していたため、ソケットの横の隙間からこて先が差し込めたのが便利でした(LEDでダメージを受けていたのもあり写真撮り忘れ)。\n完成 ということで完成です。デフォルトで赤く光ってます。キーキャップがLEDを透過してくれるタイプだったのがこれまたよかったですね。 作る前は光らなくてもなんて思ってたのに。\nキーマップ(v2) Corne Lightで作業を数週間ほどして、いくつか入力しにくい部分があったのでマッピングを少しだけ変えました。 相変わらず日本語キーボードベースですが、数字のレイヤーにいくつかの記号を使えるように割り当てました。 コーディングをするときに、ライブラリのバージョン(例:7.10.0とか)やIPアドレスを入力していてレイヤー切り替えのためのキーを押したり話したりするのは効率が悪すぎたためです。 数字との組み合わせでよく使いそうな以下のキーを数字のレイヤーに移動しました。\nセミコロン(JP_SCLN) コロン(KC_QUOT) アンダースコア(JP_UNDS) コンマ(KC_COMM) ピリオド(KC_DOT) スラッシュ(KC_SLSH) #include \u0026#34;keymap_jp.h\u0026#34; const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [0] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, JP_MINS, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, JP_SCLN, KC_QUOT, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, MO(1), KC_SPC, KC_ENT, MO(2), KC_RALT //`--------------------------\u0026#39; `--------------------------\u0026#39; ), [1] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LCTL, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_LEFT, KC_DOWN, KC_UP,KC_RIGHT, JP_SCLN, KC_QUOT, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LSFT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, JP_UNDS, XXXXXXX, KC_COMM, KC_DOT, KC_SLSH, XXXXXXX, //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, _______, KC_SPC, KC_ENT, MO(3), KC_RALT\\ //`--------------------------\u0026#39; `--------------------------\u0026#39; ), [2] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. KC_TAB, JP_EXLM, JP_DQUO, JP_HASH, JP_DLR, JP_PERC, JP_AMPR, JP_QUOT, JP_LPRN, JP_RPRN, JP_CIRC, KC_BSPC, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LCTL, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, JP_MINS, JP_EQL, JP_LBRC, JP_RBRC, JP_YEN, JP_AT, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LSFT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, JP_UNDS, JP_PLUS, JP_LCBR, JP_RCBR, JP_PIPE, JP_TILD, //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, MO(3), KC_SPC, KC_ENT, _______, KC_RALT //`--------------------------\u0026#39; `--------------------------\u0026#39; ), [3] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. RESET, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,\\ //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| RGB_TOG, RGB_HUI, RGB_SAI, RGB_VAI, RGB_SPI, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,\\ //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| RGB_MOD, RGB_HUD, RGB_SAD, RGB_VAD, RGB_SPD, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,\\ //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, _______, KC_SPC, KC_ENT, _______, KC_RALT\\ //`--------------------------\u0026#39; `--------------------------\u0026#39; ) }; LEDの色が変えられる!(気づくの遅い) あと、キーマップを変更しているときに4つ目のレイヤーにRGBなどのボタンがあるのに気付いて押してみたら、LEDのパターンや色を変えることができるのに気付きました。 (遅すぎでは。。。)\nキーキャップが白いのもありこんな感じの色にしてみています。\nユニコーンガンダムっぽくなった pic.twitter.com/vHxZkMrYyP\n\u0026mdash; Jun Ohtani (@johtani) November 28, 2020 まとめ ということで、失敗も多々ありましたがキーボードとしてはちゃんと動くできたものができたので安心しました。 今後、状況が落ち着いてきて自宅以外で仕事をするときにはCorne ChocolateをPCと一緒に持ち歩くと思います。 薄くて邪魔にならなくてよさそうです。\n今回もはんだっしゅ太郎大活躍でした。本当に買ってよかった。 LEDがつかないときはちょっと落ち込みましたが、これのおかげで立ち直れたのもありますし。 あとは、試行錯誤しつつLEDとかの理解ができたのも楽しかったです。 キーマップの変更時にLEDの変更などができるのに気づいたのはちょっと遅すぎたので、qmkの仕組みや割り当てられるキーにどんなものがあるのかをもう少し研究したいなと思います。\nさて、次はどんなことを試すかなぁ。\n","date":1607004824,"dir":"post/2020/","id":"a46c601d03a3a26bc418d0096fe83a42","lang":"ja","lastmod":1607004824,"permalink":"https://blog.johtani.info/blog/2020/12/03/build_corne_choc/","publishdate":"2020-12-03T23:13:44+09:00","summary":"はじめまして、pyspa。 ということで、pyspa Advent Calendar 2020の4日目(大谷コンビの2号)の投稿になります。 コンビそろってキーボード記事です","tags":["DIYキーボード","misc"],"title":"Corne Chocolateを組み立てた #DIYキーボード"},{"contents":"前回のブログのまとめに書いたように、セパレートタイプのキーボードであるCorne Light v2を作成したのでそのビルドログです。DIYキーボードとしては2つ目になります。\nまとめで書いていたお店が開店したので、購入してみました。 購入したのはこちらのKOCHI KEYBOARDさんです。 ついこの間オープンしたばっかりのお店です!\nなんで作ったの? スプリット型(セパレートタイプ?どっちが正しいんだろう?)のキーボードに興味があって、KOCHI KEYBOARDさんで買えたのがこれだったというのが大きな理由です。こういうのってタイミングだと思うので。 あとは、組み立てていくのがプラモデルみたいで面白いというのもあります。 基本的にここのところ自宅で仕事をしているので、ノートPCのキーボードにこだわる必要もないなというのも理由ですね。今後も当面は自宅で仕事になると思いますので。\nCorne Light v2 foostanさんが設計された(って言い方であってるのかな?)、3x6のサイズに親指の3キーが配置された分離型のキーボードの一種です。 シリーズ?の名前としてはCorne Keyboardと呼ばれています。 (そういえば、由来は何だろう?自作キーボードがどうやって設計されていくのかという流れがまとめられた作者の方のブログがおもしろいです。) また、基板の設計などがGitHub上でMITライセンスで公開されています。 オープンソースなハードウェアというのも面白いです。\nビルドログ 作者の方がビルドガイドを公開してくれています。ですので、こちらに沿って作業をしていきます。 ちなみに、私は今回Gateronのクリア軸を選択してみました。さらさらと入力できるのが好きなので。 サイレント軸にも興味はあるのですが、今回は実際にスプリット型のキーボードを早く触ってみたいというのが勝ちました。キーキャップについては後述します。 ツイートに都度、写真をアップしていたので組み立ては画像でお楽しみください(時々取り忘れてるけどw)。\nうむ pic.twitter.com/svW9WdzaZv\n\u0026mdash; Jun Ohtani (@johtani) October 21, 2020 刺して曲げる pic.twitter.com/M0jfQJg2k8\n\u0026mdash; Jun Ohtani (@johtani) October 22, 2020 両方できたと。ハンダまでやって今日はおしまいにすっか pic.twitter.com/HgsSrxqpcg\n\u0026mdash; Jun Ohtani (@johtani) October 22, 2020 写真取り忘れたけど、ProMicroつけた pic.twitter.com/RS4z0lqsUZ\n\u0026mdash; Jun Ohtani (@johtani) October 22, 2020 OLEDもついたと。今日はここまで pic.twitter.com/p6Z8MMP0Xz\n\u0026mdash; Jun Ohtani (@johtani) October 22, 2020 ここまでは順調です。\nOLEDがつかない? ビルドガイドに従って、この後キースイッチをつけちゃうと問題の切り分けが難しくなるということで、 ここまでの段階でQMK Toolboxを使ってProMicroにファームウェアを書き込んで、それぞれのキーのソケットの取り付け部をピンセットでショートさせつつ、キーが入力されるかどうかを見ていきます。 QMK Toolboxについてはサリチル酸さんのブログがわかりやすいので参考にさせていただきました(わかりやすい記事をありがとうございます)。 で、ビルドガイドにあるように動いてるかを確認しようとしたのですが。。。\nさて、ファームウェア書き込んだけど、OLEDがつかないな。どっかつながってないのか?\n\u0026mdash; Jun Ohtani (@johtani) October 24, 2020 ビルドガイドのようにはいかず。。。 USBでPCとつないだ状態で、QMK Configuratorをサイトで開いて、キーボード入力テストを開くと、ショートさせたキーがPC側で認識されているかのテストができます。 これで、一通りキーは認識できていそうだというのはピンセットでショートさせながら確認しました。 ただ、OLEDには何も表示されないんです。。。\n前回Dozen0を組み立てた時に、ソケットのはんだ付けが甘かったというのもあったので、 OLEDやソケットのはんだを温めなおしたりしてみて、何度か確認してみたものの特に進展がなしです。 (ちなみにうまくいかないのもあって、ぼけたツイートしたりもしてます。)\nまぁ、OLEDはビルドガイドを見てもオプション扱いなので、それよりも触ってみたい衝動に駆られて、 キースイッチをはんだ付けしていきます。\nちなみに昨晩、OLEDはとりあえず置いといてって感じでキースイッチつけてた。キーキャップはまだない pic.twitter.com/SzLmzNg60Y\n\u0026mdash; Jun Ohtani (@johtani) October 26, 2020 それも終わって、問題点の切り分けに何かできないかな?と思ってやったのがOLED単体でArduinoと接続してみて動くかどうかです。 Qiitaにちょうどいい感じの記事を見つけたのでこれまた参考にさせていただきました(4本のジャンパー線を一人で持ちながら確認するの大変だったw)。\nはんだでの修正にしっぱい で、自分の中での結論として、「OLEDソケットのはんだ付けが怪しい」となりました。 そこで、まずは外してみようかと思ったのが間違いでした。 はんだごてとはんだ吸い取り線で何とか外せるだろうと思っちゃったんですよ。 OLEDピンソケットは足が4本あって、とりあえずとれるところまではんだ吸い取り線で吸い取ってみましたが、 さすがに基盤の穴に流れ込んだはんだまでは吸い取れず、頑張って温めながらソケットを抜こうとがんばって、 ラジオペンチでピンソケットを引っ張りながら引き抜きました。かろうじて引き抜きはできたのですが、ソケットは足が折れてしまいました。\n作者登場(OLED問題の解決) そんなところにCorneの作者の方がツイートを拾ってくれたみたいで以下のような返信を頂きました。\nOLEDが点かないのはファームのせいかもしれません(最近以前のファームで動かない新しいタイプのOLEDモジュールが出回るようになりました)。お手数ですが、https://t.co/vfSBfIeeJX のブランチのものを試して頂けますか?(ただいまPRレビュー中でまだマージされていない状態です)\n\u0026mdash; c7s (@foostan) October 25, 2020 暗闇に光明とはこのことです。 教えていただいたブランチを手元でビルドしてファームウェアを書き込むと、\nすごい、出ました!右側のディスプレイにロゴが。ありがとうございます(左側のOLEDはソケットのはんだ付け直し失敗したのでもうちょっと先になりますが)!\n\u0026mdash; Jun Ohtani (@johtani) October 26, 2020 なんと、ファームウェア書き込んだ瞬間にOLEDが点くじゃないですか。 感謝感激ってやつです。お礼を言うのに便乗してOLEDの問題の切り分けの方法についても聞いてしまいました。\nOLEDリベンジ 片側は無事だったのですが、もう一方は修復が困難になったので救世主を発注します。 自作キーボードの作成に便利なものリストとして、いくつかのブログに上がっていたのですが、必要ないだろうと見送っていたツールです。\nAmazon | サンハヤト はんだシュッ太郎NEO 45Wタイプ HSK-300 | ハンダゴテパーツ 本当にすごく使いやすかったです。 OLEDのピンソケットが修復不可能だったのですが、ProMicro用に付属して余っているピンヘッダがちょうどいい長さでした。 なので、これを4本分切り取り、OLEDモジュールにつけてしまったOLEDヘッダピンを抜き取って、代わりに切り取ったピンヘッダをつかって、OLEDと基盤を直接はんだ付けすれば修復できそうだと判断しました。\nはんだシュッ太郎君を使ってOLEDについてるヘッダピンをまずは除去。 そのあとはこんな感じで繋げました。\n見にくいかもだけど pic.twitter.com/YAHoxjgppN\n\u0026mdash; Jun Ohtani (@johtani) November 5, 2020 取り外しにくくはなったけど、無事両方のOLEDが点くのも確認できました。やったー。\nヤッター、両方のOLEDがついたよー pic.twitter.com/6KLDWvnaEC\n\u0026mdash; Jun Ohtani (@johtani) October 28, 2020 キースイッチがご機嫌斜め キーキャップは別途、AliExpressで発注をかけたのですが、ここまで来たら待ちきれないですよね? ということで、手元にあった上海問屋のキーボードのキーキャップが同じMXキースイッチ用のものだったので移植しました。キーキャップ付けてみないとわかならいものですね、1つだけキースイッチがうまくはまっておらず、斜めについているのがこの時点で判明しました(ボトムプレート付けた後だったので、プレート外してから、はんだで修正)。\nちなみにキーキャップはめてる途中で、一箇所キースイッチが斜めにはんだ付けされちゃってるのを発見して慌てて直しました。 pic.twitter.com/qofHp3o4Pc\n\u0026mdash; Jun Ohtani (@johtani) October 30, 2020 無事使えるようになりました。\nアンスコが打てない&Escどこ? キーキャップ付けたので仮運用ということで、まずはデフォルトのキーマップをもとにどんな感じで入力できるのかを試してみました。 ここにも罠がw ブラウザでQMK Configuratorを開いてデフォルトのキーマップを確認しながら試し打ちをしていたのですが、どうも思ったのと違う動きをしているキーが。\nまずBASEレイヤー(レイヤー0)の右側のシフトと、LOWERレイヤーやRAISEレイヤーのEscです。 入力しているとどうも、右のシフトがEscで、レイヤーを切り替えてもTabのままだなと。 しょうがないので、OLEDが出なくてもいいのでQMK Toolboxでダウンロードしてきたものを利用したら想定通りなのにと。 きちんとqmk_firmwareの構成を理解しないままやってたつけでしたね。 結論としては、OLED用に教えてもらったブランチではキーマップが書き換わっていたようでした。 make crkbd:defautでビルドした時に利用されるkeymap.cがキーマップの定義が書いてあるファイルです。 qmk/qmk_firmwareのリポジトリにあるkeymap.cとfoostanさんにもらったブランチでは差分があったみたいでした。\nおかげで、qmk_firmwareのkeymap.cの仕組みがわかったし結果オーライです。 問題があって調べるとどんな作りになってるかとかちゃんと確認できますしね。 手順通りにやってるだけで問題が起きないと、どんな仕組みになってるのかがわからないので人に聞きまくるしかできなくなっちゃいますしね。\nこれでEsc問題は解決したのですが、アンスコがどうしても入力できません。 自作キーボード以外はすべて日本語配列のキーボードを使用しているのもあり、 日本語配列のキーボードだとどうもキーのマッピングが異なるようだと。\nググって参考にしたのはこの辺でした。\n【QMK】JPキーコードでキーマップを定義する - 天高工房 自作キーボードキット「Corne Cherry」のレビュー - 自作キーボード温泉街の歩き方 そのほかにもVIAのファームなども試したのですが、どれもうまくいかず。 色々ググってみて最終的な解決策はkeymap.cでkeymap_jp.hというファイルが読み込まれていないので、日本語用の設定とかを読み込んでみたつもりがうまく反映されていないという感じでした。\nJISにする場合、keymap_jp.hっていうヘッダファイル読み込んだほうがいいです\n\u0026mdash; Yoshi Yamaguchi (@ymotongpoo) November 3, 2020 今の時点ではこんなキーマップにしてあります。 今後も日本語配列のキーボードをベースに考えていくつもりです。\n#include QMK_KEYBOARD_H #include \u0026#34;keymap_jp.h\u0026#34; const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [0] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, JP_MINS, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, JP_SCLN, KC_QUOT, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, MO(1), KC_SPC, KC_ENT, MO(2), KC_RALT //`--------------------------\u0026#39; `--------------------------\u0026#39; ), [1] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LCTL, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_LEFT, KC_DOWN, KC_UP,KC_RIGHT, XXXXXXX, XXXXXXX, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LSFT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, _______, KC_SPC, KC_ENT, MO(3), KC_RALT\\ //`--------------------------\u0026#39; `--------------------------\u0026#39; ), [2] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. KC_TAB, JP_EXLM, JP_DQUO, JP_HASH, JP_DLR, JP_PERC, JP_AMPR, JP_QUOT, JP_LPRN, JP_RPRN, JP_CIRC, KC_BSPC, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LCTL, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, JP_MINS, JP_EQL, JP_LBRC, JP_RBRC, JP_YEN, JP_AT, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LSFT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, JP_UNDS, JP_PLUS, JP_LCBR, JP_RCBR, JP_PIPE, JP_TILD, //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, MO(3), KC_SPC, KC_ENT, _______, KC_RALT //`--------------------------\u0026#39; `--------------------------\u0026#39; ), [3] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. RESET, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,\\ //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| RGB_TOG, RGB_HUI, RGB_SAI, RGB_VAI, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,\\ //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| RGB_MOD, RGB_HUD, RGB_SAD, RGB_VAD, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,\\ //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, _______, KC_SPC, KC_ENT, _______, KC_RALT\\ //`--------------------------\u0026#39; `--------------------------\u0026#39; ) }; キーキャップが待ちきれなくて この右下のトンガリがちょっと気になる pic.twitter.com/W0A0z67cns\n\u0026mdash; Jun Ohtani (@johtani) October 30, 2020 キーキャップが待ちきれなくて上海問屋のキーキャップを付けてみて、いろいろ試行錯誤してみました。\nあー。上下関係ないのか。だからみんなこんな感じにしてるのか? pic.twitter.com/KTBlPLespr\n\u0026mdash; Jun Ohtani (@johtani) October 30, 2020 どのくらい離すのが良いか実験中 pic.twitter.com/ozK4WyBXY8\n\u0026mdash; Jun Ohtani (@johtani) November 2, 2020 キーキャップもいろいろあるのね 届いた。 pic.twitter.com/jccNW1ZcEM\n\u0026mdash; Jun Ohtani (@johtani) November 2, 2020 もう一個 pic.twitter.com/9y6qat4JiN\n\u0026mdash; Jun Ohtani (@johtani) November 2, 2020 とりあえずセミコロンの位置につけてみた。 pic.twitter.com/TDk5213IHi\n\u0026mdash; Jun Ohtani (@johtani) November 3, 2020 今はこのDSAプロファイルの青いグラデーションのキーキャップを使っています(Dukeはここにはいないですw)。 キーキャップのプロファイルはこれまた、サリチル酸さんのブログがわかりやすく書かれています(ほんとすごいなぁ。)。\n高さ調節 そのまま使っていたのですが、やはりもうちょっと奥側に高さがほしいなと。 ダイソーなどで打っているケーブルクリップがお試しには良さそうだったのでこんな感じで内側がちょっとだけ高くなるような感じにして使っています。\nこうなった。とりあえず仮運用 pic.twitter.com/VkhjawdhLM\n\u0026mdash; Jun Ohtani (@johtani) November 4, 2020 まとめ ということで、駆け足ですがCorne Light v2のビルドログでした。 いきなりフルキーボードから40%キーボードかつ異なる並びにしたので、 混乱しっぱなしですが、いい頭の運動になっているし、なにより作って動かすまでの間に いろいろと調べたり試行錯誤できたのがすごく楽しかったです。\nあとは、スプリット型+Column Staggeredになったので「c」や「b」を間違えまくっていますが、 いい気付きでした。まだまだ記号とかの入力に慣れていないですが、ちょっとずつ身に着けていけたらなと。\nただ、もう次のキーボードをDIYしたい気持ちも出てきているので困っているところです。\n書ききれてないこともあるかと思うので、ここはどうしてるの?これはどうやったの?などあれば、Tweetなりコメントなりを頂けたらなと思います。いやぁ、DIYキーボード楽しいわ。\n","date":1604503527,"dir":"post/2020/","id":"b16bddd1a6d3e5f4136446bebe7ffbc7","lang":"ja","lastmod":1604503527,"permalink":"https://blog.johtani.info/blog/2020/11/05/build-corne-light-v2/","publishdate":"2020-11-05T00:25:27+09:00","summary":"前回のブログのまとめに書いたように、セパレートタイプのキーボードであるCorne Light v2を作成したのでそのビルドログです。DIYキーボードとし","tags":["DIYキーボード","misc"],"title":"Corne Light v2を作成した #DIYキーボード"},{"contents":"ヒゲが不評だったのでいつも通りの長さに切りました。\n前回「Windowsをお試し中」と書きましたが、いくつかソフトをインストールしたりしたので現状を忘れないようにブログに残しておきます(また同じ作業する予定なので)\nインストールしたものたち 今のところインストールしたのはこの辺。 特にコメントしたいものについてこのあと明記します。\nドライバインストール from CD MX Ergoのソフトインストール。接続はコネクター Windowsアップデート Chrome Visual Studio ビルドツール(Lindera用) JetBrains Toolbox IntelliJ CLion Rider Visual Studio Code Slack Teams Google Drive共有 Gitter Divvy for Windows Zoom DeepL Sophos Twitter for Windows Office 365 AutoHotKey WSL2 - Ubuntu Windows Terminal Rustup Git for Windows wsl-ssh-agent PeaZip Speccy Hugo (WSL2のUbuntuにapt-get install hugoした) PowerToys AutoHotKey 前回のブログに書いたように、カーソル系のEmacsショートカットが体に染みついて離れないのです。 そこで、ググって見つけた記事はこちら。 AutoHotKeyというツールが Windowsに常駐して、特定のキー入力の時に、別の操作を実行してくれるツールです。\n見つけた記事にあった、https://github.com/lintaro-jp/gtk-emacs-theme-like.ahkのキーマップをもとに、いくつか変更したものを使用させていただいています。\n書き換えたのは、以下の通りです。\nCtrl+\\でIMEの切り替え(Wnn風) Ctrl+kをEmacsと同じ挙動に(もとにしたキーマップでは、カーソルから行末までが削除されてしまう) Win+sでもファイル保存(Ctrl+sと同じ挙動に。デフォルトではCortanaが起動して邪魔くさいので) すごく快適です。そのうち、もう少し自分が使いやすいようにキーマップを追加していったりするかもしれません。 特に、Macのショートカットがしみついているものについてなどです(仮想デスクトップ切り替えとか?)\nPowerToys Divvyをインストールしたのですが、グローバルショートカットがうまく動かなくていまいちでした(なんでだろ?) そこでググって見つけたのが@ITのPowerToysの記事でした。 PowerToysはMS製のOSSツールで、GitHub上で公開されています。 中には「ColorPicker」、「FancyZones」、「File Explowrer Add-ons」など、複数のツールが入っています。 「FancyZones」です。\nWindowsでは、デフォルトで、アプリにフォーカスしているときにWin+カーソルでウィンドウの配置場所をいくつか(左右どちらかに半分、4分の1(右上、左上など))に配置してくれるAero Snapというものが動いています。が、上半分などデフォルトにない柔軟な配置を設定することができません。 MacではDivvyというツールをいれて、それを実施していたのですが、先ほど書いたようにWindows版はあるものの、なぜかグローバルショートカットが動かず、システムタスクトレイのアイコンをクリックしなければいけませんでした。\nそれを解消してくれるのがFancyZonesです。 FancyZonesの設定項目で、自分で画面上にどのような割り当て領域を作るかを設定できます。さらに、マルチディスプレイ、仮想デスクトップを使っている場合、それぞれのディスプレイかつ仮想デスクトップで個別にレイアウトが設定できるようになります。 レイアウトを設定した後は、Shiftキーを押しながらウィンドウを移動すると、設定した領域が出てきて、あとは、割り当てたい領域にウィンドウを移動するだけでその領域いっぱいにウィンドウをリサイズしてくれます。 また、設定を変えることで、Shiftキーを押さなくてもウィンドウ移動するだけで領域にリサイズすることも可能です。また、Aero Snapの機能をオーバーライドしてWin+カーソルで動作させることも可能になります。\nWSL2 + Windows Terminal 三宅さんからコメントを頂いたので。\nもう少し幅広い感じですかね。あわせて Windows Terminal 使うとわりと快適です。\n\u0026mdash; miyake | ZEN (@kazuyukimiyake) October 15, 2020 なんとなく噂は聞いていましたがということで、MSのドキュメントを見ながらインストールしました。クイックスタートに則って作業するだけで特に問題なくUbuntuまで無事インストールできました。 Windows Terminalも同様です(クイックスタートで入れることになる)。\nGit for Windows + wsl-ssh-agent 少してこずったのがこちらです。 チュートリアルに記述はあったのですが、どちらで作業するのか?などが少しわかりにくかったので。ググって出てきた記事をもとに作用しました。\nRustのプロジェクトファイルをMacから丸ごとコピーしていたのですが、Git for Windowsを入れるまでは、CLion+Rust pluginの環境では、.gitファイルをきちんと認識してくれませんでした(この時WSL2と少し混同してた)。\n無事環境は用意できました。 作業の手順は以下のような感じです。 Macで使用していた.sshのディレクトリを持ってきて作業しました。\nWindows側での作業 Macから.sshディレクトリをc:\\\\Users\\johta\\にコピー Git for Windowsのインストール OpenSSHクライアントの設定 管理者権限でコマンドプロンプトを起動して sc config ssh-agent start=auto sc start ssh-agent [wsl-ssh-agent(https://github.com/rupor-github/wsl-ssh-agent)のインストール ダウンロードして.7zファイルを展開 wsl-ssh-agent-gui.exeとnpiperelay.exeをc:\\\\Users\\johta\\binに移動 c:\\\\Users\\johta\\bin\\wsl-ssh-agent-gui.exeのショートカットをスタートアップに作成 作成したスタートアップのリンク先に -setenv -envname=WSL_AUTH_SOCKを追加 Git BashでOpenSSHを利用するように設定 setx GIT_SSH C:\\\\Windows\\system32\\OpenSSH\\ssh.exe ssh-addで秘密鍵を登録 ssh-add .ssh/id_rsa WSL2のUbuntuでの作業 Ubuntuはgitがすでに入っていたのでインストールはスキップ git config --global user.name \u0026quot;Jun Ohtani\u0026quot; git config --global user.email \u0026quot;メールアドレス\u0026quot; mkdir .ssh .bashrcの最後行にwsl-ssh-agentのWSL2 compatibilityにあるexportからfiまでをコピー。この時、パスを自分のパスに変更すること(私の場合$HOME/winhome/.wslの部分を/mnt/c/Users/johta/binに書き換えました) これで、WSL2側では.sshのファイルを管理しなくても、Windows側のOpenSSHに接続してssh周りの処理をしてくれるようになりました。\nPeaZip wsl-ssh-agentが.7z形式で圧縮されていたので、ダウンロードしました。 とりあえずこれを入れてみたのですが、ほかにお勧めがあれば教えてほしいです。\nSpeccy CPUの温度やスレッドごとのCPU使用率などを見てみたいので入れてみました。 これもとりあえず入れてみた感じなので、ほかにお勧めのソフトがあれば教えてもらえればと。 リソースマネージャーでもスレッドごとのCPU使用率は見れたのですが、温度が見れなかったので。\nHugo + WSL2にあるUbuntuにsudo apt-get install hugoしてインストールしました。\nそこで、VS Code の Remote Extension です。WSL2 から ‘code’ で起動できます😎\n\u0026mdash; Daiyu Hatakeyama@Microsoft, Hack in ChatGPT (@dahatake) October 17, 2020 あとは、畠山さんに教えてもらったVSCodeのRemote - WSLを入れて、 WLSに接続した状態でVSCodeを起動して記事のMarkdownを書くと、VSCodeのターミナルを開くとWSL2に接続してくれて、hugoコマンドが実行できます。\nまとめ とりあえず、ブログが書ける環境ができました。 Mac上にあった各種プロジェクトのディレクトリをコピーして、Rustの開発もできるようになりました。\n今後も環境構築は続いていきます。Javaとか入ってないし。 SDKMan使ってたけど、切り替えどうしよう?とか。\nそういえばSDKMAN!をJDK切替に使ってたけど、結局windows側のパスは通らんので自力インストールになった。scoopがよさげ\n\u0026mdash; きしだൠ(K1S) (@kis) October 17, 2020 IDE系から呼び出すターミナルはWSL2がいいなぁとか。\nhttps://t.co/X4Jj4tih1I\n\u0026mdash; そーだい@初代ALF (@soudai1025) October 17, 2020 ほかにもおすすめなどがあれば教えてください!\n","date":1603029710,"dir":"post/2020/","id":"188c1ee5132a6752dfce5a0235354070","lang":"ja","lastmod":1603029710,"permalink":"https://blog.johtani.info/blog/2020/10/18/restart-windows-no1/","publishdate":"2020-10-18T23:01:50+09:00","summary":"ヒゲが不評だったのでいつも通りの長さに切りました。 前回「Windowsをお試し中」と書きましたが、いくつかソフトをインストールしたりしたので","tags":["misc","windows"],"title":"Windowsへの移行(その1)"},{"contents":"ヒゲが伸びてきて(試しに伸ばしてる)不評を買っている今日このごろです。\n自宅で作業することが多くなってきたので、自作PCでもと思っていますが、OSをどうしようか悩み中。 とりあえず、試しにWindowsにしてみるかということで、10年ぶりくらいにWindowsに帰ってきました (この文章はMacで入力してますが)。\nむかしむかし もともとはWindowsを使っていたのですが、Win7くらいに32bitと64bit混在の時期に、 Xkeymacsを利用するときに少し手間がかかるなぁと思ったのもあり、Macに移行しました。 Macだと自分がよく使うEmacsっぽいショートカットがデフォルトいろんなアプリで使用できる利点があったからです。\nただ、最近、TL上で光るPCとかを見てしまったのもあり、 自作PC(どちらかというとDIYかな?)熱が復活しました。 まだ、OSをWindows、Ubuntuのどちらをメインにしようかな?と悩んでいるところではありますが、まずはWndowsをちょっと試してみるかなと。\nまずは、やりたいことをちょっとリストアップしておこうかなと思います(きっと、先人の知見が集まってくるはず!)。\nどうしてもほしい機能 大学の頃にSunOSやSolarisを使用し、Emacsでメールを読んだしていたせいで、Emacsのショートカット操作が体から抜けない状態です(抜こうとしてないという話もあるが)。 ですので、社会人になってからWindowsを利用していたときはXkeymacsというソフトのお世話になっていました(神アプリでした。まだあるのかな?)。\nショートカット操作とか カーソル移動(必須) 上下左右:Ctrl+n、p、f、b 行頭、行末:Ctrl+a、e 編集 デリートキー:Ctrl+d Ctrl+hがバックスペースだけど使わないな、そういえば カーソルから行末までをカット:Ctrl+k 必須! カーソル移動がホームポジションから移動しなくてもいいのもあって、多用してしまっています。 これ、WindowsとかUbuntuでいい感じにできるのあるのかな? できれば、IMEやブラウザのURLのサジェストなどもこのカーソル移動で移動できると嬉しいです。 (昔はM-%とかで置換などもやってたけど最近はやらないな。)\nデスクトップ操作系 仮想デスクトップ やることごとにデスクトップを切り替えて使うので ウィンドウのリサイズ? DivvyというアプリをmacOSで利用中 自分で登録したサイズ(例:画面右半分)にウィンドウサイズを変更などがショートカットで可能 仮想デスクトップはあると思うけど、ウィンドウのリサイズの便利なツールあるかなぁ?\n利用するアプリ SNS、オンラインミーティング Twitter macOSではTweetDeckと夜フクロウを使用 Slack ネイティブアプリ Gitter ネイティブアプリ Chatwork ブラウザ Teams ネイティブアプリ Zoom ネイティブアプリ Google Meet ブラウザ Discord ネイティブアプリ(最近使ってないな) 色々使ってますが、最悪ブラウザで使う感じかな?\nオンラインストレージ Google Drive 同期アプリ使ってる Dropbox あんまり使ってない 開発系 JetBrainsのIDE Toolbox App IntelliJ CLion + Rust plugin Rider zsh macOSで標準になったから コマンド系 git SDKman ant gradle JDK Rust Hugo Jasper GitHubのIssueとかを見るネイティブアプリ 自分が関連しているIssueとかが楽に見える(メールだと埋もれてしまう) エディタ Visual Studio Code 開発系では?と思われるかもだけど、Markdownエディタとして使ってる Emacs by Homebrew 最近は起動してない その他 カレンダー macOSのカレンダーで複数のGoogleカレンダーを取り込んでる ScanSnap Ubuntuで使えるやつあるのかな? Mac miniにつないであるので、画面共有とかで入れればそれでOK 画面共有 winやubuntuからMac miniとか見えるかな? キーボード共有 macも使うので、KVMスイッチとかかな? マウス共有 MX ErgoのFlowを使うと行き来が簡単にできたので良さそう。 ただし、Ubuntuだとどうなるのか? システム監視系 CPUの温度とかCPU、メモリの使用率とか まとめ とりあえずこんなところです。カーソル移動系が一番重要なので、そのへんから色々とちょっとずつ試していく予定。 ぜひオススメアプリとかあれば教えていただければと。\n","date":1602727442,"dir":"post/2020/","id":"de37d9fae011687eb1eb5a127fcb89e3","lang":"ja","lastmod":1602727442,"permalink":"https://blog.johtani.info/blog/2020/10/15/restart-windows/","publishdate":"2020-10-15T11:04:02+09:00","summary":"ヒゲが伸びてきて(試しに伸ばしてる)不評を買っている今日このごろです。 自宅で作業することが多くなってきたので、自作PCでもと思っていますが、","tags":["misc","windows"],"title":"Windowsをお試し中"},{"contents":"今年の春くらいから、セパレートタイプのキーボードが気になっています。 また、なんか知らないですが、Twitterのタイムラインが自作キーボード(DIYキーボード)で盛り上がってる気がします。 (たぶん、気になってるから余計目についてる)。 これとか。このスライドから、自分がやってるのは「まだ」DIYキーボードだなということで、タイトルに使ってみました。\n#toruby \u0026quot;DIYキーボードは実質Ruby\u0026quot; 本日のスライドです! とちぎでこの話をできてよかった!!!q: https://t.co/RJot71Ngu9\n\u0026mdash; Kakutani Shintaro (@kakutani) September 12, 2020 セパレートタイプのキーボード 今年の夏まではMac Book Pro 16インチのキーボードを利用していました(参考:自宅の作業環境(2020))。 これまで、自宅で作業することよりも、外で仕事をすることが多く、また、外といっても様々な場所(サムライズムだったり、オフィスだったり、カフェだったり)で作業をすることが多かったので、ノートPCのキーボードにしていました。流石にキーボードを持って歩くほどは気にしていなかったので。\nただ、コロナウイルスの影響もあり、ほぼ自宅で作業することとなりました。 となると、前から気になっていたセパレートタイプのキーボードが俄然気になり始めます。 (といいつつ、寄り道してたりしますが)\n気になっていたのはこのあたりなのですが、\nErgodox EZ Moonlander Mark I 流石にいきなり行くにはちょっと気が引けるなぁと(なかなかいいお値段)。 また、自分が日本語キーボードを利用しているというのもちょっとあります。\nキースイッチの感触を知りたくて ただ、日々、楽しそうな自作キーボードの記事や画像が流れてきます。 で、思い出したのが自分の趣味。プラモデルです。色を塗ったりはしないですが、組み立てるのは楽しいなと。 じゃあ、趣味と実益を兼ねればいいのでは?(ほんとか?)となり、作る気になってきました。\nただ、全く知らない世界だし、どんなものなんだろう?と。 市販のキーボードでも、キーの押し具合が色々合ったり、形もまちまちです。 また、このご時世ですので、自宅からあまり出ていないので遊舎工房さんなどに遊びにも行けず。\nそんなところに流れてきたのがキースイッチのテスターでした(世の中誘惑だらけ)。\nスイッチテスター人気スイッチ詰め合わせ 18個セット 「なるほど、これでどんな感触かわかるじゃないか!」と、気づけばポチッと押していました。。。 届いて、「ふむふむ、これがこういう感触なのか。なるほど」ポチポチ押しながら、さらに自作キーボードについて調べていきます。\nいろんな感触なんだなぁ pic.twitter.com/PaGDMIRJiv\n\u0026mdash; Jun Ohtani (@johtani) September 22, 2020 キースイッチのストロークの深さを知りたくて まぁ、当たり前なのですが、先程のキースイッチテスターどこにもつながっていません。 キーボード触ってるとわかりますが、ストロークが違いがあるんですよ。 ただ、これだとわからない。けど知りたい。\nで、ググっているとArduinoを使ってLチカやってる人とか、キー入力させている人がいるじゃないですか。 これでは?そういえば、Arduinoもどきうちにもあるぞ?と。 で、準備をしていたときに見かけてしまったのがこのツイートでした。。。\nhttps://t.co/ALl7OcRVRa 高機能テスターとしてもおすすめ\n\u0026mdash; Kakutani Shintaro (@kakutani) October 4, 2020 やられてしまいました。。。\ndozen0作りました ということで、前置き長かったですが、Dozen0というキーボード(マクロパッド?)を遊舎工房さんから購入して作ってみました。 手順はビルドガイドという形でまとまっています。\n基本的にはこれに沿って作成しました。\nパーツと手順の確認 さてと。 pic.twitter.com/GTBJ7zDleN\n\u0026mdash; Jun Ohtani (@johtani) October 10, 2020 まずは入っているパーツがきちんとあるか確認します。 また、ビルドガイドでどんな作業があるのかをざっと眺めておきます。 まぁ、プラモデルといっしょですよね。\nキットにはキースイッチとキーキャップは含まれていません。これはご注意ください。 私は、キースイッチテスターとして入手していたキースイッチとキーキャップがどんな押し具合なのかを確認したかったので特に問題ありません。\nハンダづけ Amazon | 白光 ダイヤル式温度制御はんだこて FX600 | ハンダゴテ Amazon | 白光 こて先 2C型 T18-C2 | ハンダゴテパーツ Amazon | 白光(HAKKO) セラミックヒーターはんだこて専用こて台 クリーニングスポンジ付き FH300-81 | ハンダゴテパーツ Amazon | goot(グット) 高密度集積基板用 鉛入りはんだ Φ0.6mm スズ60%/鉛40% ヤニ入り SD-60 | ハンダゴテ はんだ付け用に揃えた道具です。「自作キーボード ハンダゴテ」とかでググると出てきたものがこれだったので。 デフォルトのコテ先ではなく、2Cのコテ先に付け替えてから作業を開始しました。\n私の持っていたソケットはCherry MX系なのですが、気が向いたらKailh Chocも試したくなるかも?ということで、 すべてはんだ付けしました。本格的にはんだ付けしたのは大学以来だからもう20年近く経ってますね。 ソケットの足をプリント基板にはんだ付けするのですが、2Cのコテ先が大きくなかなか手こずりました(これがこのあと問題を引き起こしました)。\nソケット、リセットスイッチ、ProMicroをはんだ付けすればはんだの作業は終了です。\npic.twitter.com/jjUo162n54\n\u0026mdash; Jun Ohtani (@johtani) October 10, 2020 pic.twitter.com/p5atvtHfFN\n\u0026mdash; Jun Ohtani (@johtani) October 10, 2020 スイッチの取付と組みたて 試したいキースイッチを選んでトッププレートにつけていきます。\nキーテスターからスイッチとキーキャップ持ってきて完成。動作確認はまだなのでまた、最初に戻るかもだけど、、、 pic.twitter.com/ZmBd3bgOKI\n\u0026mdash; Jun Ohtani (@johtani) October 10, 2020 組み立ても終わり次は実際の動作確認です(ツイートしていますが、予想通りの展開でした)。\nファームウェアの書き込み USBで接続して、ファームウェアの書き込みです。 書き込み手順はビルドガイドにありますが、QMK Toolboxの使い方やQMK Configuratorの使い方は以下のサリチル酸さんのブログがわかりやすかったです。\n(初心者編)自作キーボードにファームウェアを書き込む (初心者編)QMK Configuratorを使ってキーマップを書き換えよう 実際に書き込んで動かしてみると。。。。\nうーん、上半分が死んでる気がするなぁ。\nデフォルトキーマップの書き込みはできたけど、カーソルの上とかバックスペースが入らないw\n\u0026mdash; Jun Ohtani (@johtani) October 10, 2020 とりあえず、もう一回確認してみた。デフォルトのキーマップで、「Cut」「Paste」が強く押さないと入力されない。UpとDeleteは動くようになってた。CopyとBkSpがうんともすんとも言わない。下段のキーは全部動く。https://t.co/zEyINdAK6t\n\u0026mdash; Jun Ohtani (@johtani) October 10, 2020 といった具合に上半分が動作があやしいです。\n再度、はんだ付け ということで、ネジを外して上の段のソケットをはんだで温めてみると、片側だけ温めるとはずれるじゃないですか。 どうやら、うまくソケットの足が基盤にはんだ付けできていなかったようです。 この時、最初に作業したときに2C型のコテ先が大きくて、ソケットの足に入らなかったのを思い出したので、 最初にはんだごてについていたコテ先に戻してから作業をしました。 これだとソケットの足の隙間に入るんです。ということで、挙動のおかしい上段のソケットをすべてつけ直したところ無事動作しました。\n上の段、全体的にソケットがうまくはんだ付けできてなかったみたいだった。今回はMX系のスイッチしかないので、Kailh Chocのソケットの導通は未確認。ざっとブログにまとめるか。\n\u0026mdash; Jun Ohtani (@johtani) October 10, 2020 現在のキーマップ これが今のキーマップです。仕事中のBGMをラズパイ4の音楽プレーヤーで流していますが、 部屋から出るときや、打ち合わせがあるときに音楽の停止、開始などを画面共有経由でやっています。 が、わざわざマウス移動するのもめんどくさいなと。これに使えそうだというのもあったので、Dozen0を購入したというのがあります。 残念ながら、Prev Trackとかがうまく動かないので、ショートカットを調べてキーマップ書き換える予定ですが、非常に便利になりました。\nまとめ ということで、Dozen0を作ってみましたが、楽しかったです。すんなりと行かなかったのがまた良かったです。 試行錯誤して動いたときの喜びが何倍もありました。また、キースイッチの感触も知ることができました。 たぶんGateron Silentクリア軸もしくは赤軸くらいが良さそうだなぁと(こうやって沼へ。。。)。 キーマップの仕組みを調べたり、もっと面白い使い方できないかな?と探りつつ、次のステップに進もうかなと。\n次は本格的なセパレートタイプのキーボードを作る予定です。が、お店のオープンを待ってからということになってます。はやくオープンしないかなぁ!!\nがんばって!!\n\u0026mdash; Jun Ohtani (@johtani) September 29, 2020 ","date":1602428006,"dir":"post/2020/","id":"c377351433a941a927aab543931f6026","lang":"ja","lastmod":1602428006,"permalink":"https://blog.johtani.info/blog/2020/10/11/build-dozen0/","publishdate":"2020-10-11T23:53:26+09:00","summary":"今年の春くらいから、セパレートタイプのキーボードが気になっています。 また、なんか知らないですが、Twitterのタイムラインが自作キーボード","tags":["DIYキーボード","misc"],"title":"Dozen0を作成した #DIYキーボード"},{"contents":" 2020/10/06 11:00くらいにマージされました。\n@minoru_osuka さんが開発を引き継いだLinderaというKuromojiのRustクローンがあります(リポジトリ) 。 最近趣味でRustを勉強しているので、こちらを少し手伝っています。\nRustの勉強仲間である@takuya_bさんや@ikawahaさんと話をしているときに、FST部分をDouble Array Trieに置き換えると速度が向上するのでは?という話が出まして、@takuya_bさんがDouble Array Trieを作るらしいという話になったので、下準備などをしつつ、作ってもらったライブラリyadaを組み込んでみたという話です。\nベンチマークの追加 下準備として、今のLindera(FST実装)がどのくらいの性能なのか?というのを計っておく必要があります。 幸いにも、Linderaのオリジナルの開発者の方が、criterion.rsというライブラリを使ったベンチマークプログラムを作成してくれていました。\nただ、1種類だけだと少し心もとないなというのと、長い文章やパターンを増やしたほうが良さそうだなということで、 ベンチマーク自体をいくつか追加しました(追加したときのPR)。\n種類としては、5種類のベンチマークです。\nシステム辞書のみのTokenizerのコンストラクタ呼び出し カスタム辞書ありのTokenizerのコンストラクタ呼び出し システム辞書のみのTokenizerのtokenize処理の呼び出し カスタム辞書ありのTokenizerのtokenize処理の呼び出し 青空文庫の坊っちゃんのテキストをシステム辞書のみのTokenizerでtokenize 1,2はコンストラクタ部分だけの処理をベンチマークテストする目的で作成しました。 LinderaはTokenizerがtokenize処理するのに利用するデータをいくつか内部で保持しています。 これらはファイルにシリアライズされており、Tokenizerのオブジェクト生成時に読み込みやデシリアライズ処理が発生します。 この部分だけも速度を計測したい目的でコンストラクタだけを切り出しました。\n3,4はTokenizerのメインの処理です。コンストラクタはベンチマークの対象外にしました。 純粋にtokenizeの処理だけを切り出して計測するためです。 カスタム辞書がある場合、ない場合は念の為切り出した形になっています。\n5は長い文章(文章が多いのでバリエーションも増える)を扱いたいために別にしました。\nこれで、一応下準備が完了です。 ちなみに、Criterionは賢くて、前のベンチマークの結果と最新の結果を比較してくれる機能があります。 どんな感じで出てくるかはベンチマーク結果をご覧ください。\nyadaの組み込み ベンチマークの準備をしていたところyadaがリリースされたので、Linderaへの組み込みを検討し始めました。\nというわけで、またダブル配列を書いてしまったので crate として公開しました。フィードバックお待ちしております! https://t.co/As7h0tfmjf\n\u0026mdash; takuya-a (@takuya_b) September 20, 2020 中身の理解 lindera-fstを利用して、prefix searchしている処理があるので、そこで利用しているFSTをyadaに置き換えれば良さそうだと判断して、 処理を読んでいきます。\nTokenizerは、PrefixDictという構造体でlindera-fstを利用している prefixメソッドが入力文字列を元に、FSTを前方一致検索して、ヒットした単語の情報をIteratorとして取り出せる(単語の情報は「入力文字列の先頭からの文字数」と「ヒットした単語のWordEntry構造体」) PrefixDictのfstは辞書(例:ipadic)ごとにlindera-\u0026lt;辞書名\u0026gt;-builderで生成される システム辞書としては、デフォルトではlindera-ipadic-builderでfstを構築している 構築処理はこの辺 という感じです。 また、辞書周りのファイルがそれぞれどんな役割なのか、どんなデータの持ち方をしているのか?といった点を、変更点の調査のついでに書き出してみました。lindera-dictionary/FILES.md。TODOになっている部分も追記が終わっています(PR)\n変更点 実際に変更したプログラムの詳細についてはのPRを見ていただくとして、簡単には以下の点になります。\nRustのバージョンを1.46.0に(おもにREADME.md) yadaが利用している機能に1.46.0で導入された機能があるため lindera-fstをyadaに変更(lindera-core/Cargo.toml, lindera-ipadic-builder/Cargo.toml) 合わせて、dict.fstというファイル名をdict.daに変更 dict.daに関して構築部分と検索部分を変更 FSTではFSTから返ってくる値(入力文字列に出てきた単語に関連する値)はu64だったが、yadaのDoubleArrayがu32しか扱えないため、u32に変更。テストの記述はしていないが、扱うデータ的にu32で問題なさそうだったので。 検索部分:PrefixDict構造体のprefixメソッドでDoubleArrayのprefix_common_searchを使用 DoubleArray自体がprefix_common_searchのメソッドを持っていたので、処理が簡単に置き換え可能だった。FSTはprefixメソッド内で独自で前方一致検索を実装していた。 構築部分:lindera-ipadic-builder/src/lib.rsのbuild_dictとbuild_user_dictのdict.da構築処理 ipadicのCSVファイルを読み込んで、見出し語をキーに、辞書にある単語情報のベクタを値とするBTreeMapを生成し、このBTreeMapに基づいてFSTを構築していた部分をDoubleArray構築処理に置き換えた。 シフト演算などで、実際の値(dict.vals)へのポインタを作っていたのだが、ここの処理を読み解くためにFILES.mdを書き出した。 という感じです。そもそもデータ構造がどうなっているのか?から読み解いて、変更部分を洗い出して変更していった形になります。 取り込み作業中にいくつかyadaに要望(このへん)を上げて、変更を取り込んでもらい、最終的にyadaのバージョン0.3.2で問題なく動きそうだという形になりました。@takuya_bさん、対応ありがとうございました。\nエッジケースバグの発見 作っててよかった、テストケースでした(実際にはベンチマークテストですが)。 取り込み作業中に、Lindera本体のcargo testはすべてOKになるが、ベンチマークを取ろうとしたときに、坊っちゃんの文字列を入力にしたベンチマークが失敗するという事象が発生しました(PRのコメント参照)。 切り分けのために、入力の文章のどこでおかしくなるのか?DoubleArrayのbuildメソッドに渡している値がおかしくないか?などをすこしずつ調べていくと次のバグが判明したという感じです。\n特定のデータ(ipadicの見出し語一覧)をDoubleArrayに入れて、特定の文字列(「は相」)をcommon_prefix_searchにいれたら、 返ってくる情報(0から何バイト目の文字が一覧に存在した)が、不正な値が返ってくるというバグでした。 @takuya_bさんに見てもらいつつ(DoubleArrayの中身わからん。。。)、修正してもらいました。素早い対応ありがとうございます。\nyada 0.3.1 をリリースしています。特定の条件で不正な遷移を許すダブル配列が構築されてしまうバグを修正しています。このエッジケースは @johtani さんが見つけてくださいました。ありがとうございました! https://t.co/CiftZi5GDn\n\u0026mdash; takuya-a (@takuya_b) September 30, 2020 やはり、いろんな文字列入れてテストしてみるの重要ですね。 ということで、ベンチマークだけでなく、テストケースとしても坊っちゃんのファイルを読み込んでトークナイズするようにPRでテストケースを追加しています。\nベンチマーク結果 yadaを利用した変更が終わったので、再度cargo benchを実行して計測です。 計測としては、masterブランチでまずcargo benchを実行し、yadaの実装をしたブランチに切り替えてからcargo benchを実行します。 すると、Criterion? cargo benchが、最終的な結果に前回との差分でどのくらい性能が改善、改悪したかも合わせて出力してくれます。 実行環境と結果は以下のとおりです。\nMacBook Pro 16インチ CPU:Core i7 6コア 2.6GHz メモリ:32GB コンストラクタのベンチマークについては10%ほど性能が悪くなっています。 これは、FSTよりもDoubleArrayTrieのほうがデータが大きくなってしまうためだと思われます。 実際にファイルのサイズは次のようになりました。yada(DoubleArrayTrie)のほうが2倍以上大きいことがわかります。 また、このファイル以外にもLinderaが利用しているデータはありますが、それらは今回変更の対象にはなっていません。 なので、単純にこのファイルの読み込みの処理に時間がかかっているのだと想像できます。\n2147765 / FST / dict.fst 5425152 / yada / dict.da tokenizeのベンチマークについては、11%〜28%の改善が見られました。 文章から、内部に保持している辞書に存在する単語を見つけ出す処理に利用されるのがFST、DoubleArrayTrieです。 今回の変更では、この処理に利用しているデータ構造だけを変更しました。 実際には\nDoubleArrayTrieを用いた単語の検索処理 見つかった単語の持つ値(data.valsのオフセット情報)を元にシフト演算 といった処理が実行されます。シフト演算はu64だったものがu32に変更されたくらいなので、大した処理量ではないかと。 大部分はDoubleArrayTrieを利用したルックアップ処理が速度向上に寄与していると思います。\nまとめ 最近Linderaに加えた変更、作ったPRについて少しブログにまとめてみました。 ちなみに、まだPRの段階でレビュー\u0026amp;リリース待ちという感じです。\n実際には作ってもらったライブラリを組み込んでみたというだけなのですが、速度が向上した結果が見れたのは面白いです。 また、基本的なデータ構造とかアルゴリズムの勉強にもなりました(2次元配列を1次元配列に押し込むとか)。このへんも今後も勉強していきたいです。\n組み込む際に色々と協力していただいた@takuya_bさん、@ikawahaさん、巻き込んでくれた@minoru_osukaさんに改めて感謝いたします。\nRustや形態素解析のプログラムの勉強を兼ねて、今後もなにか改善できる部分がないかなどを見ていこうと思っています。 Rustで形態素解析をしたいという人がどのくらいいるかはわかりませんが、おかしなところや疑問点などあればコメントください。\n","date":1601865378,"dir":"post/2020/","id":"15932a656f7acfac897d27766eadc9e2","lang":"ja","lastmod":1601865378,"permalink":"https://blog.johtani.info/blog/2020/10/05/switch-fst-2-da/","publishdate":"2020-10-05T11:36:18+09:00","summary":"2020/10/06 11:00くらいにマージされました。 @minoru_osuka さんが開発を引き継いだLinderaというKuromojiのRustクローンがあります(リポジトリ)","tags":["Rust","Lindera"],"title":"LinderaのFSTをDoubleArrayTrieに変更した話"},{"contents":"先日は「検索システムを構成するパーツ」ということで検索システムを構成しているパーツについて書いてみました。\n大体、検索がうまくヒットしないといった場合に、問題になるのがコンテンツ自体のデータもしくは、転置インデックスのキーワードだったりします。 そこで今回は、前回のパーツの「データソース・コンテンツ」周りについて少し書いてみようと思います。言葉の定義、それぞれがどんなことをやるのか、とりあえず導入したあとにコンテンツ周りでどんな改善ができるかなどを書いてみます。\n言葉の定義 コンテンツ 実際に検索させたいデータになります。 コンテンツにはWebページ、データベースのレコード(CMSで登録されたデータなど)、ファイルサーバーにある文書(PDF、Word、Excelなど)などになります。\nデータソース コンテンツのマスタデータが保存されている先です。 よくあるデータソースとしては以下のものが考えられます。\nWebサイト - 自社もしくはインターネットに存在しているWebサイトです。 ファイルサーバー - ローカルネットワーク上のファイルサーバーもありますが、最近ではGoogle DriveやDropboxといった外部のWebサービスもあります。 RDB - CMSや自社システムでのデータの保存先です。 クローラー コンテンツをデータソースから収集してくるプログラムのことです。 Webサイトやファイルサーバーからコンテンツを収集して検索エンジンに登録するところまでを担当します。 RDBにあるデータを検索エンジンに登録する場合はクローラーがデータを登録するというよりは、RDBにデータを登録するシステムが検索エンジンに登録する機能を持っていることが多いです。\nデータの収集と登録 収集 クローラーを使用した収集の場合は、サービスの特性とデータソースによって、どの程度の頻度でクロールするのか、クロール対象はどこまでか?といったものを決める必要が出てきます。 これらが決まれば収集ができるかと(他に権限とかもありますが。)。 収集コンテンツは、そのままでは利用しにくかったり、利用できないことがあるので、次はデータの変換を行います。\nデータ変換 コンテンツはそのままの形では検索エンジンには扱いにくいデータ形式である場合があります。\nWebページの場合 Webページの場合、コンテンツにはHTMLタグが入っていたり、JavaScriptなど検索対象にはしたくないデータなどが入っています。これらを除去して、検索させたいものを取り出す必要があります。 また、Titleタグなど、いくつかメタデータとして扱えるものがHTMLで規定されているので、これらを別の項目として取り出して個別に検索できるようにすると便利です。 HTMLをパースしてデータを抜き出す処理ができるライブラリなどがあるので活用します。\nファイル PDFファイルなど、ファイルの場合もメタデータと呼ばれるファイル自体が持っている情報が存在します。作成者、更新日時、ファイル名、パスなどです。 これらも検索時に有効な情報になります。 また、ファイルから文字列を抜き出す処理も必要になります。 それぞれデータフォーマットが異なりますので、そのフォーマットに合わせて文章データを抜き出す処理が必要です。OSSや製品がありますので、それらを利用して、ファイルから文章を抜き出します。\nRDB RDBのデータの場合、データが正規化されています。 検索エンジンでは、非正規化のデータを登録して検索することが基本となるため、まずは非正規化して取り出す必要が出てきます。\n例えば、ジャンルやカテゴリ、各種IDなどが実際のコンテンツのレコードに入っていると思いますが、これらをユーザーが入力したキーワードで検索したい場合などは、IDではなく表示名を取り出して、検索エンジンに登録する必要が出てきます。\nその他 データごとの変換処理について説明しました。 その他に、データのクリーニング処理などと言ったことも必要になってきます。例えば、HTMLのタイトルに必ずサイト名が入っているが、除去したいといった場合や、検索エンジン固有のデータの前処理などもあります。\n登録 最後は検索エンジンへの登録です。 最近の検索エンジンはJSON形式でデータを受け取る場合が多いので、JSONに変換することが多いです。 基本的には各種プログラミング言語のライブラリが用意されているのでこれらを利用するのが基本となります。\n検索したい項目、検索させたい方法などを洗い出し、必要なデータを作成して検索エンジンに登録します。 登録と書いていますが、更新、削除などもここでの対象となります。\nここまでの流れで、データソースからコンテンツを取得し、変換して、検索エンジンへの登録が終わりました。\n検索の改善 検索のログから分析して改善していくのが良いですが、ユーザーからの質問や意見などからも改善すべき点が見えてくると思います。 検索ログでは、次のようなものを元に、検索がうまく行かないものを見つけ出します。\n0件ヒット 0件クリック ヒットしていない検索ワードがある場合、コンテンツに問題がある場合があります。まずはこのあたりをとってみるのが良いかと。 そもそも、入力されたキーワードにマッチするコンテンツを扱っていないこともわかりますし、入力されたキーワードに似た単語を持ったコンテンツなども存在するはずです。 類義語の辞書を用意して、検索にヒットできるようにするといった分析と改善にも利用できます。\nあとは、検索エンジン側の話ですが、形態素解析器などを利用している場合に、意図した区切りになっていないために、うまくキーワードがヒットしないと言ったこともあります。\nコンテンツの理解 実はこれが一番だったりします。 どんなコンテンツを自分たちが扱っているのか?どんなデータがどういった項目でコンテンツに入っているのか?といったところから、 コンテンツのデータを元に検索にヒットさせる方法が改善できます。\nCMSなど人が入力したデータをコンテンツとして扱う場合、入力画面を改良することで、望んでいるデータを入れてもらえたり、不要なデータが入らなくなる可能性があります。 例えば、ECサイトなどで商品の説明文やタイトルにいろいろなキーワードが入っている場合などがあります。むりやりどんなキーワードでもヒットさせたいという入力者の意図もあるのですが、検索しているユーザーにはノイズになることも多いです。適切にカテゴリやジャンル、属性といった項目に分けることでおかしな入力データを減らすことも可能です。\nWebサイトなどをクローリングしたものの場合は、サイトごとに文章の特徴があったり、重複している部分などが合ったりする場合があります。 これらもコンテンツをよく調べることで、不要な情報を除去したりといったことが可能になります。\nまとめ 簡単ですが、検索のデータソースやコンテンツにまつわる話を紹介しました。 もちろんここでは紹介しきれていない項目がいっぱいあります。 また、具体例ではなく概略をざっくりと書いているのでわかりにくい場合もあるかもしれません。 すこしユースケースを絞り込んで書いたほうがわかりやすくなるのかも?\n次はUIとか書くかも?\n不明点とか疑問点、指摘事項などあればコメントしていただければと。 要望などもお待ちしております。\n","date":1600136614,"dir":"post/2020/","id":"b2c4cf0fb96d02d37f03668caaecbc57","lang":"ja","lastmod":1600136614,"permalink":"https://blog.johtani.info/blog/2020/09/15/improve-search-no3/","publishdate":"2020-09-15T11:23:34+09:00","summary":"先日は「検索システムを構成するパーツ」ということで検索システムを構成しているパーツについて書いてみました。 大体、検索がうまくヒットしないとい","tags":["検索"],"title":"検索対象のデータとデータソース(検索システムに関する妄想その3)"},{"contents":"自宅環境に少しアップデートがあったので更新版です。 お客さんのおかげで相変わらず自宅で作業させてもらってるのもあり、昨今のコロナウイルスの影響で出かけることもないので、自室の作業環境が更新されている感じです。 前回のブログはこちらです。 前回のまとめで触れていた2点について更新されています。\nまずは、現状のデスクの上の写真です。\n基本的には前回紹介したものと大きくは変わっていません(?)。 変わったものについて紹介していきます。\nデスク 先程の写真ではちょっとわかりにくいですが、スタンディングデスクになりました。\nタイマーついてるの便利 pic.twitter.com/E9engTIMnM\n\u0026mdash; Jun Ohtani (@johtani) April 30, 2020 Flexispotの天板と足の組み合わせにしました。 前のElectaの天板が明るめの色だったのもあって、メープルの天板です。 組み立てはちょっと大変でした。 足が重たいのと、天板にはネジ穴がなく電動ドライバーもないので、ネジ締めと机を起こすのがちょっと大変です。子供に手伝ってもらいながら組み立て設置をしました。 オンラインミーティングなどのときには基本、立って作業しています。 あとは、デフォルトのタイマー設定のままですが、45分ごとに立ったり座ったりを数回繰り返す感じです。\nAmazon | FLEXISPOT オフィスデスク用天板 スタンディングデスク120×60cm Amazon | FLEXISPOT スタンディングデスク 電動式 昇降デスク メモリー機能付き ブラック EN1B(天板別売り) スタンディングデスクマット フローリングに45分立ちっぱなしだと結構、足の裏がつかれるんですよ。なので、クッション性が高いフロアマットを立ってるときは利用しています。ちょっとめんどくさいのですが、椅子のときは壁に立て掛けて、立つときにマットを敷くようにして使っています。\nちなみに、ウレタン素材なので開封直後はすごい匂いでした。。。 数日は陰干しみたいなのが必要です、ご注意を。 ただ、これを利用してから膝やかかとが痛いことはなくなっています。\nAmazon | 疲労軽減マット スタンディングデスクマット 滑り止め加工 立ち仕事 耐水 耐油 耐菌 (ブラック, 75cm*50cm*2cm) ケーブルトレー スタンディングデスクだとケーブルをぶら下げた状態だと危なそうだなということで、ケーブルトレーも机の下に追加してあります。電源タップを配置して、ディスプレイなどの電源はこちらから取るようにして、ケーブルトレーからは電源タップとスタンディングデスクの電源コードを垂らすという感じです。実際にはLANケーブルも伸びてたりはしますが。。。 また、後で出てくるラズパイ+SSDも最近こちらに移設しました。 最初にチャコールグレーを発注したのですが、配送日が未定になったので、Lサイズのシルバーを発注するという慌てようでした。 結局、今は両方使っています。テーブルタップにラズパイと、結構乗せるものがあるんですよね。見えない場所だし、色が揃ってないのは気にならないかなと。\nAmazon | プラス Garage ワイヤーケーブルトレー Lサイズ 幅63.7cm シルバー Amazon | プラス Garage 配線ケーブルトレー 幅40cm チャコールグレー キーボード+パームレスト 10数年ぶりに外付けキーボードじゃないかな? 少なくともMacに移行してからは、ずっとMac bookのキーボードを使ってました(極稀にMac mini起動後とかにMagic Keyboard使うくらい)。 外出して仕事をすることが多かったのもあり、体をキーボードに合わせる感じでした。\nが、ずっと在宅で仕事をしていますし、ふるさと納税でRealforce(リンクは楽天)がということで、申し込んでみました。2週間ちょっとで到着。 箱が厳重でびっくりしました。\nAmazon | 東プレ REALFORCE SA for Mac ホワイト R2SA-JP3M-WH | Realforce まだ深いキーに慣れつつあると言った感じです。 付属の2mmのキースペーサーでAPCを2.2mmの設定で使用しています。最初は3mm+APC 1.5mmでやっていたのですが、流石にキーが敏感すぎてちょっとキーボードに手をおいたまま考え事をしているだけで「lllllllllll」のようになってしまったので現在の組み合わせに落ち着いています。\nあと、特殊な設定としてはスペースの横のeng/kanaキーを設定でキーロックして使えなくしました。どうも、ご入力の原因になっているようだったので。 日本語の入力切替は、昨日まではCtrl+Spaceを使用していましたが、このブログを書き始めてからCtrl+\\に変更しています。 むかーし、使っていたIME切り替えのショートカットです(知っている人は知っているやつ)。\nマウスは使用しておらず、キーボードの手前にトラックパッドをおいて使っています。パームレストの部分は、サムライズムさんのトラックパッドがきれいに入るmagicTrayPalmです。 Mac book Proと同じような感じでトラックパッドが使えるのがいいですね。 興味がある方は、侍割のリンクをたどってもらうと、初めてサムライズムさんで買い物をする方に限り割引がつくようになってるみたいです(なんと、私もなんか割引になる!)。\nディスプレイアーム 外付けキーボードになったのですが、Mac Book Proの画面も活用したく、さらに上下での配置がやはり目線の移動距離が少ないので気に入っていました。ただ、前回のブログで紹介したアームでは少し高さが足りず。。。 思案しながらAmazonを回遊していたら、同じ会社の新しいアームがあり、調べると高さが取れそうだということで付け替えました。 アーム2本ありますが、今のところ1本だけを使っています。 2本目のアームにカメラを乗せるのもあり?と思いながらまだ試していませんが。玉突き式に前に使っていたアームがサンダーボルトディスプレイ(縦置き)のアームになっています。前にサンダーボルトにつけていたアームは重量オーバーで悲鳴を上げていたので。。。\nAmazon | HUANUO 2画面 アーム デュアル ガススプリング式 スマホ充電器 寝室で利用していた斜めに立てかけるタイプのワイヤレス充電器を作業デスクに持ってきました。 実は部屋に時計がなく、Pixel 3 XLを使っているので、スマホの画面に常に表示されている時計を置き時計の代わりに使えそうだなと (スマホで写真を撮っているので上の画像ではスマホがありませんが)。 結構便利です。ちょっと時間を確認したいときに、メニューバーの時計では流石に小さすぎるのでw\nAmazon | Anker PowerWave 7.5 Stand, Qi ワイヤレス充電器 ミキサー 音声のミキサーです。Yamahaのスピーカーは入力が2系統あるのですが、入力したい音声は3系統あります(ラズパイ4、Mac mini、メインディスプレイ)。2入力を1系統にまとめるプラグを試しに買ってみて、Mac miniとラズパイをまとめてみたのですが、残念ながら切り替わるときに数分無音状態が続くという問題が発生しました。 USB給電できるタイプを購入しました。スライダーとかいらないなと思っていたのですが、電話やミーティング時にBGMの音を下げたりするのに地味に便利だったりします。 ただ、スライダーを動かそうとすると本体も動いてしまっていたので、本体裏に滑り止めを貼ってあります。\nAmazon | Maker hart Just Mixer ステレオ3入力音声ミキサー/電池とUSB電源可能 Webカメラ おっさんの顔がきれいに写っても仕方ないんですが、下からのアングルよりはいいかなぁということと、今後の勉強会で使えそうかな?ということで、購入してみました。 縦でも横でも使える便利なカメラです。また、あんまりないのですが、部屋の中などを写すときにカメラを持ち回せるの便利ですね。 ディスプレイの上に置いてしまうと高さがありすぎるということで、スピーカーの上に乗っけています。仮置きなのですが、このままになるんじゃないかな? 打ち合わせ中は画面共有してることが多いのでオンライン飲み会などで主に活躍してる気も。。。\nAmazon | ロジクール ウェブカメラ フルHD 1080P 60FPS StreamCam C980OW オフホワイト USB-C接続 Mac miniのSSD化 見えないところですが、Mac miniのHDDをSSDに差し替えました。 性能検証用のマシンとしてMac miniを利用し始めたのですが、 計測するたびに速度の差がありすぎるのでおかしいな?と。 よくよく考えてみると、このMac miniはFusion Driveだったんです。。。 開発などで使う分には大容量だし便利だったのですが、負荷計測に利用する場合は挙動をハンドリングできないので、弊害でしかないです。。。 ということで、頑張って差し替えました。想像以上の大手術でした。 「Mac mini HDD 交換」などでググると換装している方たちがいらっしゃいます。興味ある方はググってみてください。\nさて、復路 pic.twitter.com/SwndXPoKqn\n\u0026mdash; Jun Ohtani (@johtani) July 25, 2020 Amazon | シリコンパワー SSD 1TB SATA3 6Gb/s 2.5インチ ラズパイ4 Mac miniの負荷検証マシン化のため+Linuxを触りたかったというのもあり、ラズパイ4を追加しました。 Mac miniは主な使用用途が音楽再生だったのでラズパイ4で肩代わりできるだろう+その他の検証にもラズパイ4が使えそうだと。 現在はUbuntuをインストールして、画面共有で操作しています。\nAmazon | LABISTS Raspberry Pi 4 4B MicroSDHCカード64G まとめ かなり快適になりました。キーボードもうるさくないですし、熱くもありません。マイクのポップガードは意味がなさそうなので外しました。\nまだいくつか気になってるものもあるので、また更新するかもしれません。\n分離式キーボード - 胸を広げた状態でキーを打ったほうがいいのでは?という気がしています。ただ、最近はずっと日本語キーボードを使っているので選択肢が少ないんですよね。。。\nサンダーボルト?USB-C?ドック - MacBook Proのポートがすべて埋まっているし、もう少しケーブルを減らせると幸せになれそうなきが。。。\nモバイルディスプレイ - MacBook Proのディスプレイを使っているのですが、キーボードの上にかぶってるんですよね、結構。。。クラムシェルにしてiPadもしくはモバイルディスプレイに置き換えたほうがスッキリはしそうかなと。ただ、Touch IDが使えなくなったり、クラムシェル状態でMacBook Proの電源を入れられないというはなしなので、あまり意味がなさそうだなというのもあります。\n","date":1599531445,"dir":"post/2020/","id":"d08a3fdc040bbbdd81c9927ce296318c","lang":"ja","lastmod":1599531445,"permalink":"https://blog.johtani.info/blog/2020/09/08/update-working-facility/","publishdate":"2020-09-08T11:17:25+09:00","summary":"自宅環境に少しアップデートがあったので更新版です。 お客さんのおかげで相変わらず自宅で作業させてもらってるのもあり、昨今のコロナウイルスの影響","tags":["misc"],"title":"自宅の作業環境(2020/09)"},{"contents":"Rustで便利なクレートを見つけたので、紹介がてら、自分のメモのためにブログに残しておきます。\nそもそもの問題 Rustで処理を書いていて、なんかちょっと遅いな?どこの処理で時間がかかってるんだろう? ということがありませんか?ありますよね?\nというのを調べるために、最初に思いつくのは自分で計測する方法です。 流石にそれはなぁ、と思ったのでググって出てきた方法を最初は使っていました。\nRustで実行時間計測 3年前の記事ですが、とりあえず計測する分には問題なかったのでこちらの方が書いていたマクロを拝借していました。 が、ちょっと面倒なのが戻り値がある処理などのときに、このマクロを挟むのが結構めんどくさいなと。 また、処理の時間を測りたいのは基本的にはメソッドや関数単位であることが多いです。\nで、さらにググっていて見つけたのが、meteredでした。\nどんなもの? 計測したい部分に#[metric]のようなアノテーションを追加することで計測対象としてくれます。 あとは、計測したものを保存するレジストリという場所を指定するだけです。 処理が終わったタイミングなどで、そのレジストリの内容を出力することで、次の情報を計測することができます。\nHitCount : 実行された回数 ErrorCount : エラーを返した数(Resultを戻り値にしているメソッドが対象) InFlight : 処理中の回数かな? ResponseTime : レスポンスタイム(処理に何秒かかったか) Throughput : スループット(1秒あたり何回呼ばれたか) とりあえず試してみたのは、ResponseTimeとThroughputです。他のメトリクスはまた後日(機会があれば)。 また、metered::metric::Metricトレイトというものが用意されているようで、これを実装した独自のメトリクスも扱うことができるようです。\n使い方 使い方としては次のようになります。\n計測対象となるメソッドがある構造体に、メトリクスを保持するためのレジストリを用意 計測対象にしたい構造体のメソッドに#[measure]を追加(このとき、計測したいものも指定する。) あとは、実行したあとに構造体をダンプするとメトリクスが出力されます。\nレジストリの用意 #[derive(Default, Debug, Serialize)] pub struct NekoParser { metric_reg: NekoParserMetricRegistry, } NekoParserMetricRegistryという型はこのあとのimplのアノテーションで指定する名前になります。 実際にはこの型の構造体を自分で定義する必要はありません。 構造体のderiveでDefaultを指定します。構造体のインスタンス化のときにdefault()メソッドを呼び出して初期化したいためです(おそらくレジストリの初期化をやってくれるのだと思う(要確認))。 レジストリの用意はこれだけです。\nレジストリの指定と計測対象の指定 計測対象側です。少し長いですが、NekoParserのメソッドすべてを掲載しました。 まずは、1行目でレジストリの名前の指定(registry = NekoParserMetricRegistry)、レジストリのフィールド名(registry_expr = self.metric_reg)、レジストリの可視性(visibility = pub(self))を定義します。 2行目では、implブロック全体で計測したいメトリクスを指定しています。今回は、スループットとレスポンスタイムを計測したかったので #measure([ResponseTime, Throughput])]と2種類を指定しています。 メトリクスが2種類のため配列で指定していますが、1種類だけの場合は[]の記号は必要ありません。\nあとは、計測したい各メソッドに#[measure]をつけるだけです。 なお、メソッドごとに#[measure(ErrorCount)]といったかたちで個別にメトリクスを指定することも可能です。 今回はお試しということもあり、すべて#[measure]だけになっています。 アノテーションを付けただけで、メソッド自体を変更はしていません。\n#[metered(registry = NekoParserMetricRegistry, registry_expr = self.metric_reg, visibility = pub(self))] #[measure([ResponseTime, Throughput])] impl NekoParser { #[measure] pub fn load_and_parse_neko(\u0026amp;self) { let file_path = \u0026#34;./data/chap04/neko.txt\u0026#34;; let file = File::open(file_path).unwrap(); let buf = BufReader::new(file); let mut out = File::create(\u0026#34;./data/chap04/neko.txt.lindera.json\u0026#34;).unwrap(); buf.lines().filter_map(|item| item.ok()).for_each(|line| { let tokens = self.tokenize(line.as_str()); self.output_tokens(\u0026amp;tokens, \u0026amp;mut out); }); } #[measure] pub fn output_tokens(\u0026amp;self, tokens: \u0026amp;Vec\u0026lt;Token\u0026gt;, buf: \u0026amp;mut File) { writeln!(buf, \u0026#34;{}\u0026#34;, serde_json::to_string(tokens).unwrap()) .expect(\u0026#34;Error during output json\u0026#34;); } #[measure] pub fn tokenize(\u0026amp;self, line: \u0026amp;str) -\u0026gt; Vec\u0026lt;Token\u0026gt; { let mut tokenizer = lindera::tokenizer::Tokenizer::new(\u0026#34;normal\u0026#34;, \u0026#34;\u0026#34;); let lindera_tokens = tokenizer.tokenize(line); let tokens = lindera_tokens .iter() .map(|lindera_token| { let surface = lindera_token.text.to_string(); let pos = lindera_token.detail[0].to_string(); let pos1 = if pos != \u0026#34;UNK\u0026#34; { lindera_token.detail[1].to_string() } else { String::new() }; let base = if pos != \u0026#34;UNK\u0026#34; { lindera_token.detail[6].to_string() } else { String::new() }; Token { surface, base, pos, pos1, } }) .collect(); return tokens; } } 計測結果の出力 最後は計測結果の出力です。 今回はテストメソッドで実行して結果を出力する処理を書きました。\nlet parser = NekoParser::default();で構造体をインスタンス化します。 あとは、処理をそのまま実行します。\n最後に出力結果をJSON形式の文字列にしてから出力しました。 let serialized ... println!(\u0026quot;{}\u0026quot;, serialized);という形です。 簡単ですね!\n#[cfg(test)] mod tests { use crate::chapter04::answer::NekoParser; use std::path::Path; #[test] fn success_output_tokenlists() { let parser = NekoParser::default(); parser.load_and_parse_neko(); let serialized = serde_json::to_string(\u0026amp;parser).unwrap(); println!(\u0026#34;{}\u0026#34;, serialized); assert!(Path::new(\u0026#34;./data/chap04/neko.txt.lindera.json\u0026#34;).exists()); } } 出力結果 ここまで紹介したものの実行結果は次のような形でした。 レスポンスタイム、スループットともに、最小、最大、99パーセンタイルなどを出力してくれます。 出力はメソッド名ごとにくくられているのでとても便利です。\n{ \u0026#34;metric_reg\u0026#34;: { \u0026#34;load_and_parse_neko\u0026#34;: { \u0026#34;response_time\u0026#34;: { \u0026#34;samples\u0026#34;: 1, \u0026#34;min\u0026#34;: 176128, \u0026#34;max\u0026#34;: 177151, \u0026#34;mean\u0026#34;: 176640.0, \u0026#34;stdev\u0026#34;: 0.0, \u0026#34;90%ile\u0026#34;: 177151, \u0026#34;95%ile\u0026#34;: 177151, \u0026#34;99%ile\u0026#34;: 177151, \u0026#34;99.9%ile\u0026#34;: 177151, \u0026#34;99.99%ile\u0026#34;: 177151 }, \u0026#34;throughput\u0026#34;: { \u0026#34;samples\u0026#34;: 0, \u0026#34;min\u0026#34;: 0, \u0026#34;max\u0026#34;: 0, \u0026#34;mean\u0026#34;: 0.0, \u0026#34;stdev\u0026#34;: 0.0, \u0026#34;90%ile\u0026#34;: 0, \u0026#34;95%ile\u0026#34;: 0, \u0026#34;99%ile\u0026#34;: 0, \u0026#34;99.9%ile\u0026#34;: 0, \u0026#34;99.99%ile\u0026#34;: 0 } }, \u0026#34;output_tokens\u0026#34;: { \u0026#34;response_time\u0026#34;: { \u0026#34;samples\u0026#34;: 9964, \u0026#34;min\u0026#34;: 0, \u0026#34;max\u0026#34;: 143, \u0026#34;mean\u0026#34;: 0.03592934564431955, \u0026#34;stdev\u0026#34;: 1.5152489085107463, \u0026#34;90%ile\u0026#34;: 0, \u0026#34;95%ile\u0026#34;: 0, \u0026#34;99%ile\u0026#34;: 0, \u0026#34;99.9%ile\u0026#34;: 6, \u0026#34;99.99%ile\u0026#34;: 143 }, \u0026#34;throughput\u0026#34;: { \u0026#34;samples\u0026#34;: 174, \u0026#34;min\u0026#34;: 39, \u0026#34;max\u0026#34;: 71, \u0026#34;mean\u0026#34;: 57.103448275862064, \u0026#34;stdev\u0026#34;: 3.8417981983375835, \u0026#34;90%ile\u0026#34;: 60, \u0026#34;95%ile\u0026#34;: 61, \u0026#34;99%ile\u0026#34;: 64, \u0026#34;99.9%ile\u0026#34;: 71, \u0026#34;99.99%ile\u0026#34;: 71 } }, \u0026#34;tokenize\u0026#34;: { \u0026#34;response_time\u0026#34;: { \u0026#34;samples\u0026#34;: 9964, \u0026#34;min\u0026#34;: 12, \u0026#34;max\u0026#34;: 79, \u0026#34;mean\u0026#34;: 16.897230028101177, \u0026#34;stdev\u0026#34;: 2.331145559054724, \u0026#34;90%ile\u0026#34;: 19, \u0026#34;95%ile\u0026#34;: 20, \u0026#34;99%ile\u0026#34;: 24, \u0026#34;99.9%ile\u0026#34;: 46, \u0026#34;99.99%ile\u0026#34;: 79 }, \u0026#34;throughput\u0026#34;: { \u0026#34;samples\u0026#34;: 174, \u0026#34;min\u0026#34;: 39, \u0026#34;max\u0026#34;: 71, \u0026#34;mean\u0026#34;: 57.103448275862064, \u0026#34;stdev\u0026#34;: 3.819293076427424, \u0026#34;90%ile\u0026#34;: 60, \u0026#34;95%ile\u0026#34;: 61, \u0026#34;99%ile\u0026#34;: 64, \u0026#34;99.9%ile\u0026#34;: 71, \u0026#34;99.99%ile\u0026#34;: 71 } } } } 出力内容で気になったのはoutput_tokensとtokenizeのthroughputが全く同じ結果が出ていることです。 なにかバグを踏んでいる気がします。。。(時間を見つけてソースコード読んでみるか。)\n気をつけること meteredの導入時にわかりにくいコンパイルエラーが出たので備忘録として残しておきます。 (下からコンパイルエラーを読んでしまうくせがあったのが問題なのですが。。。) エラーメッセージは次のとおりです。\nerror[E0412]: cannot find type `ResponseTime` in this scope --\u0026gt; src/chapter04/answer.rs:13:12 | 13 | #[measure([ResponseTime, Throughput])] | ^^^^^^^^^^^^ not found in this scope | help: consider importing one of these items | 1 | use metered::ResponseTime; | 1 | use metered::common::ResponseTime; | error[E0283]: type annotations needed --\u0026gt; src/chapter04/answer.rs:12:1 | 12 | #[metered(registry = NekoParserMetricRegistry, /* default = self.metrics */ registry_expr = self.metric_reg)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type | = note: cannot satisfy `_: std::default::Default` = note: required by `std::default::Default::default` = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) 最初のメッセージにはわかりやすく出ていますが、ResponseTimeをuseせずに利用しようとした場合に以下のようなエラーが出ていました。 ターミナル画面が狭かったのでE0283のエラーが目に入り、何を言ってるんだろう?という状態になってしまいました。 スクロールアップしたら、答えが載っているのに。。。\nコード全体 元ネタはNLP100本ノックの第4章です。 コードの全体はGitHubのソースをご覧ください。\nまとめ meteredを簡単ですが紹介してみました。 導入自体も簡単で、想像していたような使い方ができたので満足しています。 ほかにもプロファイラなどはあるのかもしれませんが、まずはこれを使っていこうかと思っています。\nバグらしきものがありそうだったりするので、そのへんは今後調査してみようかと。 まだ、ちょっと試してみただけなので、metered自体のオーバーヘッドや、独自のメトリクスの実装方法、メソッドではなく関数に対して利用する場合にはどうするのか?などいくつか疑問点があるので、今後試してみてまたブログに残しておこうと思います。\n","date":1599487900,"dir":"post/2020/","id":"827de2d7a9d231f6bcb44caf35896c1f","lang":"ja","lastmod":1599487900,"permalink":"https://blog.johtani.info/blog/2020/09/07/intro-metered-rs/","publishdate":"2020-09-07T23:11:40+09:00","summary":"Rustで便利なクレートを見つけたので、紹介がてら、自分のメモのためにブログに残しておきます。 そもそもの問題 Rustで処理を書いていて、なん","tags":["Rust"],"title":"meteredクレートの紹介"},{"contents":"Rustで言語処理100本ノックの第4章です。\n前回はこちら。\n今回は早めに続きをやりました。 「形態素解析」ですしね。\n第4章の概要 吾輩は猫であるの文章が用意されていて、MaCabで形態素解析した結果をファイルに保存したところからが開始となります。\nが、せっかくRustでやっているのでKuromojiのRust版であるLinderaを利用して形態素解析した結果を保存する部分から作成しました。 3章に引き続き、大きな流れのところの説明だけにしておきます。\n形態素解析 もとのneko.txtが文章が1行ごとになっているので、そのまま1行ずつ読みならが、形態素解析していきます。読み込みの部分は3章とあまり変わらないので割愛します。 以下は、形態素解析の処理と形態素解析結果用の構造体です。\n#[derive(Clone, Debug, Serialize, Deserialize)] struct Token { surface: String, base: String, pos: String, pos1: String, } まずは構造体です。今回の問題では、必要な情報は4種類だったのでそれを構造体にしました。\n表層形(surface) 基本形(base) 品詞(pos) 品詞細分類1(pos1) deriveでSerialize、Deserializeを付与しているのは、形態素解析の結果をJSON文字列として保存し、あとのそれぞれの課題で読み出すためにserde_jsonを利用するためです。\nfn tokenize(line: \u0026amp;str) -\u0026gt; Vec\u0026lt;Token\u0026gt; { let mut tokenizer = lindera::tokenizer::Tokenizer::new(\u0026#34;normal\u0026#34;, \u0026#34;\u0026#34;); let lindera_tokens = tokenizer.tokenize(line); let tokens = lindera_tokens .iter() .map(|lindera_token| { let surface = lindera_token.text.to_string(); let pos = lindera_token.detail[0].to_string(); let pos1 = if pos != \u0026#34;UNK\u0026#34; { lindera_token.detail[1].to_string() } else { String::new() }; let base = if pos != \u0026#34;UNK\u0026#34; { lindera_token.detail[6].to_string() } else { String::new() }; Token { surface, base, pos, pos1, } }) .collect(); return tokens; } 次が形態素解析の処理です。 入力に1行分の文章を受け取り、出力として、さきほどの構造体をベクタに入れたものVec\u0026lt;Token\u0026gt;を返します。 内部ではLinderaのTokenizerをnormalモードでインスタンス化してそのtokenizer()メソッドを叩いているだけです。 インスタンス化のときの第2引数は辞書のディレクトリですが、今回はデフォルト辞書(IPADIC)を利用しています。 戻り値はLinderaが用意したToken構造体なので、これを今回作成したToken構造体に詰め替えているだけです。\n注意点としてLinderaはMeCabとは異なり、未知語(辞書に出てこない単語)の処理が実装されていないので、品詞が\u0026quot;UNK\u0026quot;の場合にはその他の情報が取得できないので、空文字を構造体に設定するようにしました。\n結果の保存 形態素解析の結果はJSONで保存しました。 もとのファイルが1文が1行になっていたので、 1行を読み込み、形態素解析し、それをVecで取り出して、1行1配列JSONの形で保存するようにしてあります。\nfn output_tokens(tokens: \u0026amp;Vec\u0026lt;Token\u0026gt;, buf: \u0026amp;mut File) { writeln!(buf, \u0026#34;{}\u0026#34;, serde_json::to_string(tokens).unwrap()).expect(\u0026#34;Error during output json\u0026#34;); } serde_json::to_stringにVec\u0026lt;Token\u0026gt;を渡しているだけですが、構造体にderiveをつけているのでよしなにやってくれます(便利ー)。\nJSONの読み込み処理 1行1JSONの読み込み処理です。 今回も3章のように読み込みながら、各文章ごとの形態素解析結果に対して処理を実施するために、処理を実行するためのtraitをCommandとして用意し、それぞれの問題で形態素解析結果に対して処理を書くような実装にしました。また、設問37で「猫」と共起している単語を処理するという課題があるので、文章に「猫」が入っているものだけを処理できるようにするためのFilterも用意し、これをJSONの読み込み処理のイテレータのfilterにわたすようにしています。 特にフィルタリングが必要ない場合ように、NonFilterを予め実装済みです。\ntrait Command { fn execute(\u0026amp;mut self, tokens: \u0026amp;Vec\u0026lt;Token\u0026gt;); } trait Filter { fn is_target(\u0026amp;self, line: \u0026amp;str) -\u0026gt; bool; } struct NonFilter {} impl Filter for NonFilter { fn is_target(\u0026amp;self, line: \u0026amp;str) -\u0026gt; bool { true } } // ch04-30. 形態素解析結果の読み込み fn load_json\u0026lt;T: Command\u0026gt;(cmd: \u0026amp;mut T) { load_json_with_filter(cmd, \u0026amp;NonFilter {}); } fn load_json_with_filter\u0026lt;T: Command, U: Filter\u0026gt;(cmd: \u0026amp;mut T, filter: \u0026amp;U) { let file = File::open(\u0026#34;./data/chap04/neko.txt.lindera.json\u0026#34;).unwrap(); let buf = BufReader::new(file); buf.lines() .filter_map(|item| item.ok()) .filter(|line| filter.is_target(line)) .for_each(|line| { let tokens = parse_line_json(line.as_str()); cmd.execute(\u0026amp;tokens); }); } output_tokensではserde_json::to_stringを呼び出してましたが、読み込みでは、serde_json::from_strを使うと構造体にしてくれます。\nfn parse_line_json(line: \u0026amp;str) -\u0026gt; Vec\u0026lt;Token\u0026gt; { return serde_json::from_str(line).unwrap(); } あとは、設問ごとにCommandトレイトを実装していく形です。 たとえば、32.の動詞の原形を出力する場合は次のようになります。\nstruct ExtractVerbBase { out: File, } impl Command for ExtractVerbBase { fn execute(\u0026amp;mut self, tokens: \u0026amp;Vec\u0026lt;Token\u0026gt;) { tokens .iter() .filter(|token| token.pos == \u0026#34;動詞\u0026#34;) .for_each(|token| { writeln!(self.out, \u0026#34;{}\u0026#34;, token.base).expect(\u0026#34;Error during writeln\u0026#34;); println!(\u0026#34;{}\u0026#34;, token.base); }) } } 標準出力とは別にファイルにも出力できるようにExtractVerbBaseにoutでファイルを保持しています。\n34. 名詞の連接 「名詞の連接(連続して出現する名詞)を最長一致で抽出せよ.」という課題だったのですが、最初は読み間違えて、名詞の連接の最も長いものだけを出力するようにしてました。。。 やっぱり、出力結果とかのサンプルは用意しといてほしいなぁ。。。\nimpl Command for ExtractMaxConjunctionNoun { fn execute(\u0026amp;mut self, tokens: \u0026amp;Vec\u0026lt;Token\u0026gt;) { let mut nouns = vec![]; // TODO 参照保持でどうにかしたいけどなぁ。 tokens.iter().map(|token| token.clone()).for_each(|token| { if token.pos == \u0026#34;名詞\u0026#34; { nouns.push(token); } else { if nouns.len() \u0026gt; 1 { self.buffer.push(nouns.clone()); } nouns = vec![] } }); } } 名詞の場合に、nounsにバッファリングしつつ、違う品詞が来たら出力するという処理になっています。 cloneを呼び出していますが、これを参照を引き回す感じにできるといいのかもなぁ(結構めんどくさい)。\n36. 頻度上位10語 頻度を数えるのにはBTreeMapを利用しています。 数えながら、Top10を保持する方法がいい気がしたのですが、いい入れ物を見つけられなかったので、数え上げたあとにBTreeMapのIteratorを回しながら、キーバリューのVecをまず生成します。 その生成したVecに値でソートし、その後Iteratorから最初の10件を取得して表示する方法にしました。\nソートして取り出すという処理がついでにかかっています。。。 BinaryHeapがなにか使えそうな気もしたのですが、いい方法が思いつきませんでした。\nfn print_top10(\u0026amp;mut self) { let mut key_values: Vec\u0026lt;(\u0026amp;String, \u0026amp;u32)\u0026gt; = self.terms_count.iter().collect::\u0026lt;Vec\u0026lt;(\u0026amp;String, \u0026amp;u32)\u0026gt;\u0026gt;(); key_values.sort_by(|x, y| y.1.cmp(\u0026amp;x.1)); key_values.iter().take(10).for_each(|(key, value)| { writeln!(\u0026amp;self.out, \u0026#34;{}, {}\u0026#34;, key, value).expect(\u0026#34;Error during writeln\u0026#34;); println!(\u0026#34;{}, {}\u0026#34;, key, value); }); } まとめ 形態素解析結果をちゃんと眺めてはいないですが、処理としてはこんなところかなと。 グラフはめんどくさいのでスキップしてしまいました。。。 Kibana/Esに食わせて見てみるのもありかなぁ?\n次は係り受け解析です。Rustで使えるライブラリとかあるかなぁ?\n","date":1599445027,"dir":"post/2020/","id":"3c5d4d351e0fb9e33e0e8b6d1d43c0f2","lang":"ja","lastmod":1599445027,"permalink":"https://blog.johtani.info/blog/2020/09/07/reboot-nlp100-ch04/","publishdate":"2020-09-07T11:17:07+09:00","summary":"Rustで言語処理100本ノックの第4章です。 前回はこちら。 今回は早めに続きをやりました。 「形態素解析」ですしね。 第4章の概要 吾輩は猫である","tags":["Rust","nlp100"],"title":"第4章終了(言語処理100本ノック2020)"},{"contents":"Rustで言語処理100本ノックの第3章です。\n前回はこちら。\n少し間が空きましたが、再開しました。 間が空いた理由は。。。「正規表現」ですかね。。。 苦手なんです、正規表現。 なので、28はちょっとギブアップしてしまいました。\n第3章の概要 個別に説明はせずに大きな流れのところだけ。 それぞれの問題の解についてはリポジトリを御覧ください(興味ある人いるのかなぁ?)\n第3章はNDJSON(new line delimited JSON)という、 1行に1JSONという形式のデータを格納したファイルがgzipで圧縮された状態で提供されます。 まずは、このJSONファイルからJSONを読み込むのが主な処理になります。\n読み込んだデータに「イギリス」のWikipediaの記事が入っているので、そこから正規表現で必要なデータを抽出します。\n最後の問題が少し特殊で、抜き出した情報の「国旗」のファイル名を元に、MediaWikiのREST APIを叩いて、結果を取得し、その一部の情報を抜き出すというものです。\nJSONの読み込み処理 gzipファイルを読み込んでから、1行ずつ抜き出してVecに入れる処理が次のようになります。 今回のgzipファイルは大した量が入っていないので、全部先に抜き出す処理としてまとめました。 もっと巨大なファイルの場合は個別のJSONに対する処理を buf.lines().map()のmapのなかで実行する形にすると思います。 gzipのファイルを開くのにflate2というクレート(ライブラリ)を利用しました。便利なのは、BufReaderにlines()というメソッドがあるところですかね。\n// https://docs.rs/flate2/1.0.14/flate2/read/struct.GzDecoder.html pub fn extract_ndjson_from_gzip(input_file_name: \u0026amp;str) -\u0026gt; Vec\u0026lt;String\u0026gt; { let f = File::open(input_file_name).expect(\u0026#34;file not found?\u0026#34;); let gz = GzDecoder::new(f); let buf = BufReader::new(gz); let lines: Vec\u0026lt;String\u0026gt; = buf.lines().map(|l| l.unwrap()).collect(); return lines; } こちらは、上記のメソッドで抜き出したVecを元に、記事の情報を抜き出す処理をしています。 JSONをパースして構造体Articleにデシリアライズするために、serdeというライブラリを使用しています。 serde自体は様々なデータ形式(JSON、YAMLなど)をパースするためのフレームワークです。今回はJSONなので、serde_jsonの実装を利用しています。 また、JSON文字列から構造体にデシリアライズするのを簡単にできるように構造体に#[derive(Deserialize)]をつけています。 あとは、let article: Article = serde_json::from_str(json.as_str())という処理を実行すればserde_jsonがJSONをパースして構造体に変換してくれます。形式がわかっているJSONの扱いはこれが楽ですね。変数に型を明記してあるので、型の推論もしてくれてるようです。\n#[derive(Deserialize)] pub struct Article { title: String, text: String, } // ch03-20. JSONデータの読み込み // https://serde.rs/ pub fn load_json(input_file_name: \u0026amp;str, target_title: \u0026amp;str) -\u0026gt; Vec\u0026lt;Article\u0026gt; { let mut results = vec![]; let ndjson = extract_ndjson_from_gzip(input_file_name); for json in ndjson { let article: Article = serde_json::from_str(json.as_str()).expect(\u0026#34;json parse error\u0026#34;); if article.title == target_title { results.push(article); } } return results; } 後続の処理ではパースしたArticleから記事情報を取得して色々と処理をしています。\n正規表現 正規表現用のクレートregexがRustに用意されています。Regex::new(正規表現)で、正規表現をコンパイルし、あとは、この構造体のメソッドを利用して文字列を処理していきます。 問題では、マッチするかどうか、マッチした一部の文字列を抜き出す、不要なタグを削除するといった処理を正規表現で行いました(Rust書くよりも正規表現の書き方とかを調べるのに大半の時間をもっていかれてます。。。)。\npub fn extract_category_lines(article: \u0026amp;Article) -\u0026gt; Vec\u0026lt;String\u0026gt; { let re = Regex::new(r\u0026#34;\\[\\[Category:(.*)\\]\\]\u0026#34;).expect(\u0026#34;syntax error in regex\u0026#34;); let mut lines = vec![]; article.lines_from_text().iter().for_each(|line| { if re.is_match(line) { lines.push(line.to_string()); } }); return lines; } MediaWiki APIリクエスト処理 最後の問題で国旗のファイル名を元にMediaWiki APIを叩いて、URLの文字列を取得しましょうという問題がありました。 ファイル名をREST APIの引数に渡してHTTP経由でリクエストを送信し、返ってくるJSONレスポンスからURLを抜き出すという処理です。\nHTTPのリクエストの送受信にreqwestというクレートを利用しました。 ちょっと長いけど、APIコールしている箇所はこんな形です。\nこの関数にはasyncとついています。非同期処理の関数です。内部で2回ほど(リクエスト送信の結果待ちとレスポンスのパース待ち).awaitがあります。\nclientに.get(URL)やquery(\u0026amp;[])といったメソッドが用意されているので、URLやクエリパラメータを用意してsend()でリクエスト送信します。\nasync fn call_api(file_name: \u0026amp;str) -\u0026gt; Result\u0026lt;String, String\u0026gt; { let client = reqwest::Client::new(); let file_name2 = format!(\u0026#34;File:{}\u0026#34;, file_name); //let mut file_name2 = file_name.to_string().replace(\u0026#34; \u0026#34;, \u0026#34;_\u0026#34;); let query = [ (\u0026#34;action\u0026#34;, \u0026#34;query\u0026#34;), (\u0026#34;format\u0026#34;, \u0026#34;json\u0026#34;), (\u0026#34;prop\u0026#34;, \u0026#34;imageinfo\u0026#34;), (\u0026#34;iiprop\u0026#34;, \u0026#34;url\u0026#34;), (\u0026#34;titles\u0026#34;, file_name2.as_str()), ]; let result = client .get(\u0026#34;https://en.wikipedia.org/w/api.php\u0026#34;) .query(\u0026amp;query) .send() .await; match result { Ok(response) =\u0026gt; match response.status() { StatusCode::OK =\u0026gt; { let body = response.json::\u0026lt;MediaWikiResponse\u0026gt;().await; match body { Ok(obj) =\u0026gt; match obj.get_url() { Some(url) =\u0026gt; Ok(url), None =\u0026gt; Err(String::from(\u0026#34;Cannot get url...\u0026#34;)), }, Err(error) =\u0026gt; Err(error.to_string()), } } _ =\u0026gt; Err(String::from(format!( \u0026#34;Status code is {}.\u0026#34;, response.status() ))), }, Err(error) =\u0026gt; { let error_msg = format!(\u0026#34;Error occurred... {:?}\u0026#34;, error); println!(\u0026#34;{}\u0026#34;, error_msg.as_str()); Err(error_msg) } } } あとは、呼び出し元で非同期の処理を実行するために、tokioというクレートを利用しています。 block_on()でcall_api()の実行をして、結果が返ってくるのを待ち受けています。結果が返ってきて、問題なければ、call_apiの戻り値Result\u0026lt;String, String\u0026gt;の左側のStringの値が取り出され、get_image_urlの戻り値となります。\nfn get_image_url(file_name: \u0026amp;str) -\u0026gt; String { let mut _rt = tokio::runtime::Runtime::new().expect(\u0026#34;Fail initializing runtime\u0026#34;); let task = call_api(file_name); _rt.block_on(task).expect(\u0026#34;Something wrong...\u0026#34;) } 一応、非同期に関して説明してみましたが、合っているのかどうか。。。 クレートの関係などはまだちょっと自身がないです。。。 あとは、エラーの処理の仕方とかももうちょっと勉強したいかな。\nまとめ 一応、3章を終わらせました。だいぶ強引かつ1つスキップしましたが。。。 次は第4章の形態素解析です。\n","date":1599230785,"dir":"post/2020/","id":"eb2a5824e03996c1966bee38866ce349","lang":"ja","lastmod":1599230785,"permalink":"https://blog.johtani.info/blog/2020/09/04/reboot-nlp100-ch03/","publishdate":"2020-09-04T23:46:25+09:00","summary":"Rustで言語処理100本ノックの第3章です。 前回はこちら。 少し間が空きましたが、再開しました。 間が空いた理由は。。。「正規表現」ですかね。","tags":["Rust","nlp100"],"title":"第3章終了(言語処理100本ノック2020)"},{"contents":"負荷を計測するために、数回、Azure Cognitive Searchのクラスターを起動したり、停止したりしてました。 これは、Terraformでやると楽できるのでは?と思ったので、やってみました。 1パーティションのクラスターなので、全然大したことはないのですが、メモを残しておくためにブログに書いておきます。\n基本的にはTerraformの公式ドキュメントにあったものを自分用に変数を抽出しただけです。\nファイルたち 単にクラスターを起動するためだけなので、2種類のファイルだけ作成しました(1個でもいいかも)。\nvariables.tf - 変数用のファイル。いくつかの設定を変数として定義しました。 terraform.tf - Terraform本体のファイル。 variables.tf まずはvariables.tfです(ファイル内の並びは異なりますが。。。)。terraform.tfで利用する5つの変数です。\nresource_group - リソースグループ名。既存とは異なるリソースグループ名にしました(変に壊してもいいので)。 machine_type - 価格レベル(SKU)。公式ドキュメントに設定できる値の一覧があります。今回はWikipediaのデータを登録していたのでそれが入るサイズにしています。 region - 場所(リージョン)。リージョンの一覧はどこにあるんだろう?これを参考にしましたが。 partition_size - パーティションのサイズ(=Elasticsearchでのシャードかな?)です。今回は1つでの性能を計測したかったので1にしてあります。 search_cluster_name - Azure Cognitive Searchのサービス名。search.windows.net名前空間で一意である必要があったので、他の人が使わなそうな名前をつけています。 variable \u0026#34;machine_type\u0026#34; { default = \u0026#34;standard\u0026#34; } variable \u0026#34;region\u0026#34; { default = \u0026#34;East Asia\u0026#34; } variable \u0026#34;resource_group\u0026#34; { default = \u0026#34;johtani-wiki-test\u0026#34; } variable \u0026#34;search_cluster_name\u0026#34; { default = \u0026#34;johtani-wikipedia\u0026#34; } variable \u0026#34;partition_size\u0026#34; { default = 1 } terraform.tf terraform.tfは以下の通り。Terraformの公式ドキュメントにある例にproviderを追加しただけのものになります。\nprovider - プロバイダーの設定。Azureを利用するという宣言です。features {}がないとエラーになります。空でも必ず指定が必要です。認証周りについては、azure-cli経由で認証する方式を採用しました。azure-cliはHomebrewでインストールしています。 azurerm_resource_group - リソースグループの設定。variables.tfのresource_groupとregionを利用しています。必須項目はこの2種類だけです。 azurerm_search_service - Azure Cognitive Searchの設定。partition_count以外は必須項目です。variables.tfとazurerm_resource_groupの設定を利用しています。今回は利用していませんが、レプリカ数なども指定できるようになっています。 # Azureのproviderを指定。 provider \u0026#34;azurerm\u0026#34; { features {} } # リソースグループの設定 resource \u0026#34;azurerm_resource_group\u0026#34; \u0026#34;wiki-test\u0026#34; { name = var.resource_group location = var.region } # Azure Cognitive Searchの設定 resource \u0026#34;azurerm_search_service\u0026#34; \u0026#34;search_service\u0026#34; { name = var.search_cluster_name resource_group_name = azurerm_resource_group.wiki-test.name location = azurerm_resource_group.wiki-test.location sku = var.machine_type partition_count = var.partition_size } 以上がファイルです。ほぼ公式ドキュメントのサンプル通りですねw\nデプロイとか ファイルの準備ができたら実際にデプロイします。 Azureの環境への認証にはAzure CLIを利用して、事前にログインした状態にします。 実際にデプロイするまでの手順は次のようになります。\naz login - Azureの認証。ブラウザが起動してログイン画面が表示されます。無事認証がOKなら、azコマンドでAzure Cloudの情報が取得できます。 terraform init - 初回だけです。Terraformのワーキングディレクトリの初期化処理を実行します。 terraform plan - Terraform \u0026lt; 0.12の場合は実行。最新版だともういらないみたいだ。 terraform apply - 実際にAzure上にクラスターを起動します。Terraformが隠蔽してくれているので、実際にどんなことをやっているかはわかってないですが。 以上で、Azure Cognitive Searchのクラスターが起動します。 すごく簡単です。Webコンソールでチェックすれば、起動していることも確認できます。\nこの状態では、クラスターが起動しただけなので、あとは必要に応じてデータをロードしたり、アプリから検索したりと行ったことが可能になります。 そのへんの話はまた機会があれば。\nDestroy 今回は負荷テスト用にクラスターを起動していましたので、必要なくなれば、クラスターを削除します。Terraformを導入したもう一つの理由がこの簡略化です。 terraform destroyを実行するだけで、Azure Cognitive Searchのクラスターおよび、リソースグループが削除されます。\nまとめ ということで、ほぼ公式ドキュメントのままですが、TerraformでAzure Cognitive Searchのクラスターを起動する方法の紹介でした。 ブログを書いていて、1点気になったのは、ロケーション(リージョン)の一覧はどこにあるんだろう?という点です。azコマンドとかで出てくるのかなぁ?\n","date":1597742807,"dir":"post/2020/","id":"f5effd616a3f8db6193b482caec37912","lang":"ja","lastmod":1597742807,"permalink":"https://blog.johtani.info/blog/2020/08/18/azure-search-with-terraform/","publishdate":"2020-08-18T18:26:47+09:00","summary":"負荷を計測するために、数回、Azure Cognitive Searchのクラスターを起動したり、停止したりしてました。 これは、Terraformでやると楽でき","tags":["azure search"],"title":"TerraformでAzure Cognitive Searchのクラスターを起動"},{"contents":"先日は「システムの特徴と検索機能について」という感じでふんわり書きました。 まぁ、頭の中でぼんやり考えてることを文章にしてみた感じです。 他にもぼんやりしてるものはいくつかあるので今日も書いてみることに。 検索システム?みたいなツイートも見かけたので、検索システムってこんなイメージですというブログを書いてみました。\n検索システム(機能)を構成するパーツ 今回はシステムに組み込まれる検索機能を構成するパーツについて書き出してみようかなと思います。 パーツといってもユーザー、UI、コンテンツなども入れています。\nユーザー 検索UI 検索窓 オートコンプリート 検索結果画面 ファセット ソート ハイライト 詳細画面 レコメンド 検索エンジン コンテンツ 検索ログ クリックログとかも サービス提供者 ざっくり書くとこんな感じです。 システム構成だったり、機能だったり、アクターだったりといろいろなものが混ざってしまっていますが、登場するものはこんなものです。\nざっくりした繋がりの図はこんな感じです。\nそれぞれの役割について見ていきましょう。\nユーザー サイト、システムのユーザーです。 検索UIを経由して望んだコンテンツを探します。 探す目的は、サイトによって異なります。 「何かを購入(ECサイトやオークション)する」だったり、「情報(レシピや社内文書)を見つける」だったりします。 図では「キーワード」と記載しましたが、最近では自然文(文章)を受け付ける検索もあります。\n検索UI サイト、システムが提供するUIです。ユーザーはこのUIにキーワード(質問)を入力し、検索結果を取得します。 UIにはいくつものパーツがさらに存在します。簡単に例を上げると以下のようなものです。\n検索窓 - キーワードを入れるための入力ボックスです。 オートコンプリート(自動補完) - サイトによっては、検索窓に何かを入力すると、キーワードを保管したりサジェストしたりしてくれます。 検索結果画面 - 質問にマッチしたコンテンツの一覧を表示する画面です。一覧以外にもいくつか情報が表示されます。 検索結果一覧 - コンテンツの一覧です。何かしらの基準(日付順や人気順など)によってソートされたものが表示されます。 ファセット - 検索結果が持っている属性(価格帯、カテゴリ、メーカー名など)の一覧で、絞り込み検索のヒントです。 ハイライト - 入力したキーワードがどこにマッチしたかがわかるように、強調表示されたスニペット(情報の一部)が出ます。 検索APIとUIに分かれている場合が多いでしょうか? 処理の流れとしては、検索窓に入力されたキーワードを検索エンジンに問い合わせができるクエリに書き換えてからリクエストを投げます。 あとは、検索エンジンからのレスポンスにある検索結果を表示できる形に変換して表示するのが役割です。 また、検索ログの出力もこの部分で担当することが多いです(もしくは、検索エンジン自体がログ出力の機能を持っている場合もあります)。\n検索エンジン 検索に特化したデータ構造を内部に持っているサーバーもしくはサービスです。 ElasticsearchやApache Solr、Azure Cognitive Searchなどは転置インデックスと呼ばれるデータ構造になっています。 検索エンジンの検索処理に対しての主な役割は次の2つです。\nクエリにマッチするコンテンツの集合を決定する マッチしたコンテンツを特定の条件で並び替える(ランキング) クエリを受け取り、検索結果のリストを返すのが処理の大きな流れです。 その他に、ファセット、ハイライトといった付加的な処理を実行することがあります。\nまた、データ登録(インデキシング/インデクシング)の処理もあります。\n登録するコンテンツを検索に特化したデータ構造にして格納する 転置インデックスの場合は、入力されたデータ(文章)から単語列を作り出して、単語からコンテンツのIDが判別できる形にする処理になります。\nAlgoliaやElastic App SearchのようなSaaSであったり、RDBの機能を利用するといった選択肢もあります。\nデータソース・コンテンツ 実際に提供したいコンテンツになります。 コンテンツが保存されている場所は、サイトによって異なります。\nWebの検索サイト - インターネット上のホームページ ECサイト - データベースに格納されているアイテムのデータ 社内文書検索 - ファイルサーバーやWikiなどのファイル、文書 といった感じです。 実際には、データソースからコンテンツを検索エンジンに登録する場合は、いくつかの処理(いわゆる前処理)が必要になります。 社内文書検索やWebの検索サイトの場合は、データを収集するためのクローラーが必要ですし、 収集したデータから、検索エンジンに登録するデータを加工したり(HTMLタグを除去したり、メタデータ(URL、収集日、タイトル)を付与したり)もします(ETL処理とか言われる)。\n検索ログ 検索を提供するだけであれば、必要ありません。 が、実際に検索がどのような使われ方をしているか?を知るために必要な機能になります。 この検索ログがユーザーのニーズを読み解くための情報になります。 検索ログには次のような情報が入ります。\n検索窓に入力された文字列 入力された文字列でヒットした件数 検索結果を出したタイミングでのログです。他にも実際にヒットしたコンテンツのIDなどをログに残したり、他のユーザーと区別をつけるために、ユーザーのセッションごとにIDを発行してログに残したりもします。\nまた、検索に満足してもらえているかを見るために、実際に検索結果のどのコンテンツに興味をもったのか?という情報も検索ログとして残すことがあります。クリックログなどとも呼ばれます。検索結果のどのドキュメントが実際にクリックされたか(詳細画面に遷移したか)という情報です。1回の検索結果に対してクリックされるごとにログが残ります。 もちろん、結果に満足しない場合は、クリックされずに、キーワードを変えたり、絞り込み条件がクリックされたりします。\nECサイトなどの場合は更に、実際に購入されたかどうかといった情報もユーザーのニーズを読み解くための情報となります。 詳細画面へのクリックログや購入ログについては、検索以外からの流れ(広告やDMだったり、レコメンドだったり)なども考えられます。 これらのログを元に、検索を改善していくことになります。\nサービス提供者 サイト・システムの提供者です。 コンテンツの準備、検索UIにはどんな物が必要なのか、サイト・システムにとって良い検索とはなにか?、検索ログからユーザーのニーズを分析して何を改善していくのか?といったことを考えます。 例としては次のようなことです。\n検索結果に表示するコンテンツとはなにか? コンテンツの持っている項目・属性の何を検索対象とするか? 検索結果の並び順(ランキング)がどんなものがよいのか? 検索UIにはどんなものを表示するのか? 検索機能を作るときの流れ 検索機能を構成するパーツにどんなものがあるかを紹介しました。 実際にシステムに検索機能を追加する場合は、最低限、次のものが必要になります。\n検索UI 検索エンジン(RDB?SaaS?ミドルウェア?) データソース・コンテンツ とりあえずこれらがあれば、検索機能を作ることはできるかと。 ただ、作っただけでは、いいか悪いかの判断がつかないので、どういった使われ方をしているかを知るために検索ログをとったりして、 改善をしていく必要が出てきます。\nまとめ わかってるよそんなことはと言われそうな感じになったかもしれないですが、 検索の機能を構成するパーツについて紹介してみました。 細かなはなしは色々とありますが、大まかにはこのような役割のパーツがあります。\n実際にはこれらのパーツを用意すればよいわけではなく、それぞれで検索を良くしていくためにどんなことを考えていくのか?などが出てきます。そのあたりの話はまた、別のブログで書いていく感じでしょうか。こんな感じで書いてくと、終わらない気がしてきたけど。。。 次はどんなはなしを書くかなぁ。\n","date":1595907282,"dir":"post/2020/","id":"11a61827e80739a6065960eb188d5758","lang":"ja","lastmod":1595907282,"permalink":"https://blog.johtani.info/blog/2020/07/28/improve-search-no2/","publishdate":"2020-07-28T12:34:42+09:00","summary":"先日は「システムの特徴と検索機能について」という感じでふんわり書きました。 まぁ、頭の中でぼんやり考えてることを文章にしてみた感じです。 他にも","tags":["検索"],"title":"検索システムを構成するパーツ(検索システムに関する妄想その2)"},{"contents":"今年の頭からシステムの検索周りを手伝う仕事をフリーランスとしてやっています。 検索の仕組みを知れば知るほど面白くなってきたからという理由になるのかな? LuceneやSolr、Elasticsearchなどを長く触っているというのもあるかと思います。\nということで、検索についていつも考えています。 頭の中でまとまっていない状況ですが、システムにおける検索機能についていくつか頭の中にあることを書き出して、 いろんな方にダメ出しやコメントをもらいたいなと思ったので、色々と書いてみようかと。 思いつきのままに書いているので、はなしがあちこち飛ぶ可能性もありますが、あしからず。\n検索って難しい 「「検索」とは、データの集合から目的のデータを探し出すこと」By Wikipedia\n一言で「検索」といっても、使う人、ユースケースによっていろいろな「検索」があります。 例えば、新しいスマホを買ったときに、スクリーンロックの時間を設定する機能を「検索」したりします。 また、PCで仕事をしているときに、ファイルの中身をある文字列で「検索」したりもします。 TSUTAYAに行って、欲しかった本がおいてあるかどうか店内の端末で「検索」もします。 Rustを書いていて、こんなことをやるライブラリありそうだよな?と思ってGoogleでウェブの検索をしたりもします。\n私が特にそうだと思いますが、なにかあったらまず検索をするという生活をしています。 ただ、このとき、「検索」といっても望んでいる挙動が違ったりするものです。 以下は自分が「検索」しているときに想定していることになります。\nファイル内の検索をしているときはgrep的な検索を想定していることが多い。 書籍の検索をしているときは、特定の項目(著者など)に対してgrep的な検索を想定しているが、名前の読みなどでも検索されることを想定している(漢字覚えてなかったりする。。。)。 Rustを書いているときに機能をGoogleで検索するときは、いい感じに検索してくれることを望んでいる(入力するキーワードが曖昧なことが多々ある。例えば、そのものズバリの名前をしらないときとか) あくまでも私が想像している挙動です。他の人とは違う可能性もあります。 なので、「検索」といってもさまざまな要素があるし、想定しているシーンも異なるので「難しい」なと思っています。 また、そんな「検索」ですが、世の中的にはあって当たり前だと思われていたり、お金や時間がかかるものと思われてなかったりもします。ま、けどそういったことも含めてやればやるほど面白いなと感じている今日このごろです。\n前置きはこのくらいにして、今回はシステムの特徴と検索機能について感じていることを書いてみようと思います。\nシステムの特徴と検索機能 先ほども書きましたが、検索は今やシステムに欠かせない機能となっています。 が、あればいいというものでもないのではないかなと。とりあえず検索できるべきだということで 検索機能を追加しても使いにくいものや、想定している動きをしない場合は使われないものになってしまいます。\nシステムでの検索機能は特に、「情報検索」(Wikipediaはこちら)と呼ばれたりもします。Wikipediaによるとこんな説明です。\n情報検索(じょうほうけんさく)とは、コンピュータを用いて大量のデータ群から目的に合致したものを取り出すこと。検索の対象となるデータには文書や画像、音声、映像、その他さまざまなメディアやその組み合わせとして記録されたデータなどが含まれる。\n「目的」と呼ばれるものは「ユーザーのニーズ」と呼ばれたりもします。 「合致したもの」というのがシステムが返す「検索結果」になります。検索結果は大体の場合、何かしらの順序でソートされていることが多いです。 ざっくり話をすると、「ユーザーのニーズ」を元に「(何かしらの順序でソートされている)検索結果」を返すという処理です。\nただ、この「ユーザーのニーズ」や「何かしらの順序でソートされている検索結果」はシステムの特性、特徴によってぜんぜん違うものになります。検索エンジンを入れただけで解決するものではありません。\nまた、システムは提供する側のニーズもあります。 ECサイトであればより多くのユーザーに購買してもらったり、 コミュニティサイトの場合は利用ユーザーを増やしてコンテンツや広告の収入を増やしたりといったニーズがあります。\nこれらの両方のニーズが検索機能に影響を与えたりもします。\nいくつか例を上げてみましょう。\n書籍の検索の場合 ユーザーのニーズは、「ある本を探す」ことです。そのためにユーザーがクエリを入力します。 クエリは、例にも出しましたがタイトルや著者名の読みだったりします。 検索窓が1つしかないというよりは、著者やタイトル、出版社などそれぞれの項目ごとに検索できるほうが便利だったりしますよね。 検索結果については、完全一致したものが一番最初に出てきてほしいこともあれば、出版年月日の降順で並べたいことなど、 その時々でやりたいことが変わったりもします。\n場合によっては、説明文などでも検索できると嬉しいこともあります。また、システムからは離れますが、図書館や書店で時々、「〇〇について書かれている本ありますか?」といった聞き方をしたりもします。\nまた、書店としては、探している本を見つけてもらうために検索端末などを用意しますが、そ れ以外の本も買ってもらえるといいですよね。 オンラインの書店などでは、検索結果や書籍詳細の画面に関連書籍が出ていることもあります。\n検索とは少し異なり、探索(なにか面白い本とかないかな?というようなニーズ)をしに、書店に行くこともあります。 書店で平積みされた本やポップなどを見て新しい本に興味を持つこともあります。\nオークションサイトやECサイトでの検索の場合 ユーザーのニーズは、「欲しい物を探す」ことです。 ユーザーが入力するクエリは、幅広いものになると思います。製品の型番を入力する人もいれば、 メーカー名や製品名だったり、ジャンルで絞り込んで検索することもあります。\n探されるもの(コンテンツ、アイテム)も多数に渡ります。 検索窓は1つかもしれませんが、検索結果には、絞り込み条件(ファセット)がいくつか並んで、絞り込んでいける仕組みが用意されていることが多いです。\n検索結果のソートは、価格順だったり人気順だったりします。 ただ、オークションサイトの場合は新しいもの順や、終了日時の早い物順だったりします。\nサイト提供者のニーズとしては、より多くのアイテムを購入してもらうこと(売上)です。 また、オークションサイトの場合は、アイテムを提供している人のニーズも影響してくるでしょう。 売りたい人はより多くの人の目に止まってほしいと思うはずなので、 様々な情報を付与していかに目にとまるか?といったことを考えてくると思います。\nまた、様々な商品を扱うECサイトの場合は、さらに色々と大変になってきます。たとえば、「iPhone」で検索されたときに、 iPhoneそのものが上位に来るべきなのか、ケースなどの周辺商品なのかだったりといった問題が出てきます。 商品の提供者が多数に渡る場合は、同一商品でもさまざまなお店から提供されてしまうために、検索結果一覧に多数同じ商品が並んだりもしますよね。\nレシピサイトでの検索の場合 ユーザーのニーズは「レシピを探す」です。が、探し方はユーザーによって様々です。 冷蔵庫にある材料を入力して検索することもあれば、食べたいものが決まっていてそのレシピを検索することもあります。 このとき、重要なのは類義語だったりするでしょう。食材やレシピは同じものでも様々な名前(例:パクチー、コリアンダー、シャンツァイ(香菜)など)を持っていたりします。また、部位や形によっても名前が変わったりもします。\n検索結果は人気順で並ぶことが多いでしょうか? ただ、レシピの提供がユーザーによるものなのか、サイト運営者が提供しているものかによっても変わってくるでしょう。\nサイト提供者のニーズとしては、レシピコミュニティサイトの場合は、ユーザー数の増加や広告の売上などがあるでしょう。 調味料などのメーカーがレシピサイトをやっている場合は、調味料の売上だったりします。この場合は、検索がどの程度売上に寄与しているのか?などを測ることが難しかったりしそうです。\n社内文書検索の場合 ユーザーのニーズは「文書を探す」です。探し方はファイル名であったり、ファイルのなかに出てくる単語だったりします。 社内用語・略語のような特殊な単語で検索されることもあるでしょう。ユーザーによっては、ぼんやりとした「こんな資料を探している」といったふんわりとした検索をしたくなることもあります。\n検索結果の表示順は「それっぽいもの」が上位に出てくることが望まれそうです。 ただ、古い文書が出てきても役に立たないこともあります。新しい文書のほうが役に立つことが多いので、最近作られたものというのも重要な情報になります。ただし、権限によっては見ることができなかったり、そもそも探すこともNGだったりもします。\n社内文書検索の提供者は、素早く検索できるものを提供することで仕事の効率を上げてもらったり、無駄を省くことができることを期待しているでしょう。\n昔からですが、社内の文書は様々な場所に散らばっていることが多いです。顧客管理システム、ファイルサーバー、Wiki、ウェブサイトなどこれらをまとめて検索できるシステムなどが望まれていることも多いです(使われるかはまた別ですが。。。)。\nスマートスピーカーの場合 ちょっと特殊な面白い例かなと思ってます。 音声で検索(というかお願い?)します。 システムとしては、ユーザーのニーズを理解するのに2段階あるのかなと。\n音声認識 認識した文章・キーワードで検索(場合によってはコマンド発行) これだけでも難易度が増します。\nさらに、画面のないスピーカーの場合は、結果は1件だけになります。これって結構難しいことだと思うんです。 画面があれば、検索結果を上位10件などのリストで表示して、あとはユーザーに選んでもらうことができますが、 音声の場合は1件だけしか返せません。 また、レスポンスタイムもシビアなものだと想定されます。ずっとスピーカーに黙っていられると困りますよね? きっと大変なんだろうなぁ(妄想)。\nこのように、検索と言っても、システムごとに要求・想定されるものは変わってきます。\nまとめ 例をいくつか上げましたが、ざっくりしすぎて発散してますかね。。。 想像している部分もあるので、この通りではないと思います。 ただ、システムによって、「検索」といってもシステムの特性上、 さまざまな物事、思惑が絡んでくるというのは想像してもらえたと思います?(思いたい)。\nシステムに検索機能を追加すると言っても、探したいものが何なのか?、探してもらうものはどういったものなのか?、 検索機能を追加することで何を達成したいのか?など考えることは色々あります。 どうやって、検索機能を実装するのか、その検索機能を実装するためにはどんな情報が必要なのか?などの検索機能のコアな部分を考えるだけでなく、提供しているシステム、コンテンツがどんなものかなど、システム全体を考えながら検索機能を考えていく事が検索をより良いものとして行くことだと思います。\nまた、検索されるものも検索する人もシステムが成長するのに合わせて変化していきいます。システム同様、一度作ればおしまいというものではないので、やることはいっぱいあるのかなと。\n次は、検索のパーツについてなにか書こうかなぁ。\nボヤキ もう少しまとめてから書いたほうがいいのかもなぁ。 もしくは、出てくる要素を整理するとか。 ユーザー、コンテンツ、コンテンツ提供者とかで。 ふんわりとしたブログになってしまった。 個別のシステムごとにもっと書けることもありそう。\n","date":1595842134,"dir":"post/2020/","id":"9da845cd31310b8952efd1be1881e651","lang":"ja","lastmod":1595842134,"permalink":"https://blog.johtani.info/blog/2020/07/27/improve-search-no1/","publishdate":"2020-07-27T18:28:54+09:00","summary":"今年の頭からシステムの検索周りを手伝う仕事をフリーランスとしてやっています。 検索の仕組みを知れば知るほど面白くなってきたからという理由になる","tags":["検索"],"title":"システムの特徴と検索機能について(検索システムに関する妄想その1)"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章 Rust the book - 第9章 Rust the book - 第10章 Rust the book - 第13章 14章は飛ばして、15章です(Cargoはまた別途調べればいいかな?と思って)。\n第15章 スマートポインタ たぶん、これを理解すれば、参照とベクタや構造体とかの組み合わせがもう少し効率よく使えるようになるのかなぁ?\nポインタの強い版? 参照カウント方式のスマートポインタ型 - Luceneとかで実装されてた気がするなぁ 複数の所有者!? DerefとDropトレイトを実装している構造体 ヒープのデータを指すBoxを使用する これはコンパイルエラー。let yのタイミングで借用してるので、書き換えでエラーになる。\nfn main() { let mut x = 5; let y = \u0026amp;x; assert_eq!(5, x); assert_eq!(5, *y); x = 6; assert_eq!(6, x); assert_eq!(6, *y); } こっちはOK。\nfn main() { let mut x = 5; // in stack let y = Box::new(x); // in heap assert_eq!(5, x); assert_eq!(5, *y); x = 6; assert_eq!(6, x); assert_eq!(6, *y); } 余談:コンパイラが変なワーニングを出してくれた。\nuse std::ops::Deref; impl\u0026lt;T, Z\u0026gt; Deref for MyBox\u0026lt;T, Z\u0026gt; { type Target = T; fn deref(\u0026amp;self) -\u0026gt; \u0026amp;T { \u0026amp;self.0 } } struct MyBox\u0026lt;T, Z\u0026gt;(T, Z); impl\u0026lt;T, Z\u0026gt; MyBox\u0026lt;T, Z\u0026gt; { fn new(x: T, y: Z) -\u0026gt; MyBox\u0026lt;T, Z\u0026gt; { MyBox(x, y) } } fn main() { let x = 5; let z = \u0026#34;10\u0026#34;; let y = MyBox::new(x, z); assert_eq!(5, x); assert_eq!(5, *y); } Derefトレイトでスマートポインタを普通の参照のように扱う 参照外し型強制 : 日本語ムズカシイネ Derefを自分で実装しないといけない場面がちょっと想像できてない。たぶん、Boxとかの説明に必要なので出てきたって感じなんだろうけど。 Dropトレイトで片付け時にコードを走らせる こっちは、リソース開放とかでいい感じにできそうだってのはわかった。 Dropはどんなときに実装するんだろう?Tantivyだとオブジェクトプールとかで使ってた。 Rcは、参照カウント方式のスマートポインタ これ、ここで作ったConsのリストを追っかけるためのサンプルも書いてほしい。 #[derive(Debug)] enum List { Cons(i32, Rc\u0026lt;List\u0026gt;), Nil, } fn print_typename\u0026lt;T\u0026gt;(_: T) { println!(\u0026#34;{}\u0026#34;, std::any::type_name::\u0026lt;T\u0026gt;()); } use List::{Cons, Nil}; use std::rc::Rc; use std::borrow::Borrow; fn main() { let z = Cons(5, Rc::new(Cons(10, Rc::new(Nil)))); let a = Rc::new(z); let _b = Cons(3, Rc::clone(\u0026amp;a)); let _c = Cons(4, Rc::clone(\u0026amp;a)); match \u0026amp;(*a) { Cons(v1, v2) =\u0026gt; { print_typename(v2); println!(\u0026#34;{}, {:?}\u0026#34;, v1, v2); }, Nil =\u0026gt; println!(\u0026#34;Nil!!\u0026#34;) }; } RefCellと内部可変性パターン 循環参照は、メモリをリークすることもある ","date":1594288778,"dir":"post/2020/","id":"208a8c072ea521c813b86ca7730eb880","lang":"ja","lastmod":1594288778,"permalink":"https://blog.johtani.info/blog/2020/07/09/hap15-rust-the-book/","publishdate":"2020-07-09T18:59:38+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第15章"},{"contents":"6月7日の週に開催されたBerlin Buzzwordsにオンライン出張してました。\nBerlin Buzzwordsとは? ベルリンで開催されている、Big Data、Scarability、Storage and Searchabilityに関するカンファレンスです。 今年はコロナウイルスの影響で、オンラインで開催されました。 また、同時期に検索に関する他のカンファレンス(以下の2つ)もベルリンで毎年開催されているのですが、今年はこれら3つのカンファレンスが1つのチケットで参加できる形で開催されました。\nMICES - MIX-CAMP E-COMMERCE SEARCH HAYSTACK - The Search Relevance Conference! sponsored by OpenSource Connections MICES、HAYSTACKは初参加ですが、検索に関するいくつかのトピックが聞けたので楽しかったです。\n6/7から6/12まで(がんばって)参加したので、その感想などをブログにとどめておきます。\nオンラインってどんな感じで開催されてた? まずは、オンライン開催がどのような感じだったのかをメモしておきます。\n有料のオンラインカンファレンス(事前にチケット購入が必要) 参加者用Slack カンファレンス数日前まではここで連絡とか質問が可能だった(もちろん、メールも来ましたけど)。 基本的なプラットフォームはBrellaのバーチャルイベントプラットフォーム 参加者同士のSNS機能 - 参加者同士の興味によって参加登録時に似たような人ですよとマッチングしたり。ビデオチャット機能もあり。 カンファレンスのスケジュール確認 - セッションのスケジュールの他に、参加者同士でのチャットのスケジュールも可能。一番便利だったのは自分のタイムゾーンも表示してくれること。 ストリームチャネル - セッションが行われている場所への誘導 スピーカー・スポンサーのリスト - スピーカーやスポンサーを探せる機能。スポンサー企業からは参加者も見ることができる セッションはYouTubeライブ ストリーム中だったらちょっと戻ったり、ポーズもできるので、便利だった セッション後の質疑応答にはJitsiというオープンソース!?のビデオカンファレンスの部屋が用意されてた(GitHubで公開されてるのか。https://github.com/jitsi)。 2日目、3日目はLTとかが終わったあとに、オンライン飲み会やってたっぽい(不参加) 主催者側も初めてだとは思うのですが、目立ったトラブルはなかったです。 ちょっとだけ遅れたりしてましたが、それほど影響はなかったです。 オンラインでの開催の一番のネックは、日本だと時差が辛いということです。 ベルリンが開催地なのですが、スピーカーや参加者はアメリカからの方が結構います。 そのため、開始時間が日本の23時といった具合になりました。\n面白かった\u0026amp;気になったセッション いくつか面白かった\u0026amp;もう一度見ないとなと思ったセッションと感想を。\nNatural Language queries at Salesforce scale セッションのページはこちら(2020年7月現在) Salesforceでどのような自然言語のようなクエリに対して書き換え、サジェストのようなことをやっているか?という話です。 Salesforceはテナント(企業)ごとに、データ構造などがカスタマイズ可能なため、 それぞれ個別に入力クエリ(例: new leads in sf)に対して、どういったパーツ(時間?場所?状態?)なのか?、どのフィールドへの条件なのか?といったものをNERのディープラーニングモデルとして捉えて解析しているという話でした。 企業毎にパーソナライズもされていると。実際にはパイプラインの一部でこの処理をやっており、それ以外にも処理はされているという話もありました。評価の話もされています。\nAMA - AI-Powered Search セッションのページはこちら(2020年7月現在) ManningでMEAP(絶賛書いているところ)のAI-Powered Searchの著者2名がAMA形式でいろんな質問に答えていく感じのやつです。 最初は近況報告(Treyさんがカンファレンス直前に転職してた)と、書籍がどんなものかを簡単に紹介したあと、質問に答えていく形式で2時間あります。ディープラーニングのモデルに関する話なども出てきています。 もう一度見たいと思ってたやつなので見ないとな。。。 (パネルっぽいセッションは、ヒントがなにもないので結構辛い)\nAsk Me Anything: Lucene 9 セッションのページはこちら(2020年7月現在) LuceneのPMCメンバーのUweさんが今後のLucene/Solrのいくつかの質問に答える感じのAMAです。 出てきた話(質問の前の)としては、Lucene 8の現状(Bloc-Max WANDとか)や、Java 11対応になるよとかです。 QAでは、SIMDの話、Approximate Nearest Neighborがどんな感じか?などの話でした。\nFrom commercial search to owned search セッションのページはこちら(2020年7月現在) カルフールスペインがECの検索をどのように導入したかという概要レベルの話でした。 モノリシックなものをマイクロサービスでk8s上に載せ替えたという大きなアーキテクチャ以降の話です。 Empathy.coが提供しているものを最終的には使用したみたいだけど、 どんな検索がされているのかといったニーズの調査ができるようになり、検索に絡んだKPIが改善した話でした。 COVID-19に絡んだクエリの変化についてもちょっと話が出てました。\nNeural Search in Practice セッションのページはこちら(2020年7月現在) Zalandoの検索の一部でNIR(Neural IRモデル)を利用してクエリの改善をやって、それをどうやってトレーニングして、テストしたかなどの話。 NIRを利用することで、複数の言語に対して改善が見られたという話だった。 今までは、クエリをいくつかの処理を元に翻訳して、入力された単語がカテゴリーに対するものなのか、スタイルに関するものなのか?などを判別して、クエリの補強?を行っている手法だった。 これに対して、ディープラーニングでクエリに対するクリックデータを元にトレーニングして、どういうクエリに対してどんなアイテムを出すのか?というモデルで検索を改善していた。 ヒット件数が0件だったり少ないものを対象にして上記の処理を入れているらしい。 (ということで、ディープラーニングをしっかり勉強しないといけないみたいなので、どうにかしたい。。。)\nTop 10 Lessons learned in search projects the past 10 years セッションのページはこちら(2020年7月現在) 10年検索プロジェクトをやってきた10個の気づきという感じのセッション。 ごく当たり前のことなんだけど、検索の導入・改善に関して、こういう事あって、何も考えないとこうなっちゃうよね。 だから、こんなことをやるべきだよね?という話です。 たとえば、検索窓はあるけど分析すらしていない状況(レッスン1)だとまずはこういうのやらないとね。とか、 検索クエリの分析・改善ばかりして、コンテンツの分析・改善を怠っていないか?という当たり前の話です。 当たり前なんだけどまとめてくれてるのは、やはりいいなぁと。\nClick logs and insights: Putting the search experts in your audience to work セッションのページはこちら(2020年7月現在) 検索ログとクリックログがあったときに、どういったことに使えるのかを料理のレシピに見立ててデモをするセッションで説明が面白かったです。 「こんなログがあったときに、ログのこの項目とこの項目を材料にすると、こんなのができますね」というのを、Elasticsearchにログを取り込んで、JupyterNotebookでデモをしていました。やはり動くものがあるとわかりやすいですねぇ。\nMixing and Matching: Diversifying Search Results セッションのページはこちら(2020年7月現在) これまたパネルセッションです。 検索結果の多様性に関するディスカッションでした。 これは、ECだからこその課題でもあるのかなと。検索自体は「何かを見つける」ための手段です。 普通に考えた場合は、ピンポイントで探していたものが見つかるのが嬉しいです。 が、例えば、ユーザーが検索した単語そのものが入っているだけのものが見つかるよりも、似たような商品も一緒に出てきてほしいことありますよね?また、ECサイトだと、回遊してほしいというのもあります。ということで、それぞれの方がどんな観点で多様性を考えているのかという話をするディスカッションになっていました。\nThought Vectors, Knowledge Graphs, and Curious Death(?) of Keyword Search セッションのページはこちら(2020年7月現在) AI-Powered Searchの著者の一人、Treyさんのセッション。ベクトルを検索にどうやって使うのか、 ベクトルで表現できるものはどんなものがあるのか?どんな検索エンジンで使えるのか?という話でした。 歴史的な話も交えつつ、検索だとこのへんで使えるんじゃないか?というような話でした。\n録画は? 気になったセッションをいくつか書き出してみました。 ちなみに、全セッションのビデオが公開されています。興味がある方は、ご覧いただければと。\nThe recordings from this year\u0026#39;s Berlin Buzzwords / MICES / Haystack joint event are now online. You can watch them all on our YouTube channel. Thank you once again to all of our wonderful speakers. https://t.co/hTRDmKNdpd\n\u0026mdash; @berlinbuzzwords@floss.social (@berlinbuzzwords) July 6, 2020 感想そして来年は? 楽しかったです。検索に関する話が色々聞けるのはやっぱ楽しいですね。サイトの特性(ECなのか、Wikipediaなのかなど)によっても「良い検索」の定義も変わるので、サービスなどがどんなものか、そしてそれを良くするためには検索はどんなことができるのか?といった話や、技術的な濃い話までいろいろな話を聞けました。 ただ、パネルは英語の聞き取りが辛いですね。。。あと、時差が。日本にいながらにして時差ボケは辛い。。。 オンライン飲み会には流石に参加できませんでした(4時とか5時から始まるし)。\n来年もオンラインで開催されたら間違いなく参加します。 オフラインのみだった場合はどうなるかなぁ。。。\n","date":1594005164,"dir":"post/2020/","id":"e5cb2e5d501d3db2db5d8f14984a66d4","lang":"ja","lastmod":1594005164,"permalink":"https://blog.johtani.info/blog/2020/07/06/attend-berlin-buzzwords/","publishdate":"2020-07-06T12:12:44+09:00","summary":"6月7日の週に開催されたBerlin Buzzwordsにオンライン出張してました。 Berlin Buzzwordsとは? ベルリンで開催されている、Big","tags":["conference","berlin buzzwords"],"title":"Berlin Buzzwordsにオンライン出張してた"},{"contents":"luceneutil - マニアックなツールのセットアップの続きです。 今回も誰得?なブログなので興味ない場合は飛ばしましょう。\n一応、luceneutilのREADMEにあるlocalrun.pyを動かせるところまでいったんですが、そこで一旦本題を思い返してみました。\nKuromojiの性能が落ちてるらしいし、Analyzer系のベンチマーク測ってるグラフに載せたほうがいいよね。\nこれが、そもそも動かしてみようと思った本題です。 READMEに書いてある手順で動いたんですが、よくよく調べてみると、Analyzer系の性能テストをやってるのは、別物っぽいぞと。 なんとなく、「ソフトウェア考古学」っぽくなってきましたね。\nAnalyzerの性能テストやってるのは? Analyzerのパフォーマンステストのグラフに出てきたTokenizerの名前を元にluceneutilのリポジトリを検索してみました。 EgdeNGrams当たりで検索するとヒットしたのが以下のファイルです。\nsrc/main/perf/TestAnalyzerPerf.java src/main/perf/TestAnalyzerPerf4x.java src/python/sumAnalyzerPerf.py 本命はsrc/main/perf/TestAnalyzerPerf.javaっぽいですね。 これを動かしている人はどれかな?ということで、今度はこのファイル名で検索します。\nsrc/python/runAnalyzerPerf.py どうやら、このPythonのファイルが先程のJavaファイルを実行して、性能を計測しているみたいです。 最初に出てきた、sumAnalyzerPerf.pyはrunAnalyzerPerf.pyの実行結果をAnalyzerの計測結果のグラフに追加する処理をしているようだということまでがわかりました。\nKuromojiをTestAnalyzerPerfに追加してみる 動かす対象がわかったので、あとは、やることを追加しましょうと。\nKuromojiの実行をTestAnalyzerPerfに追加 引数を追加して日本語版のWikipediaのファイルも読み込むようにする runAnalyzerPerf.pyに引数の追加とクラスパスの追加 JapaneseAnalyzerはlucene/analysis/kuromojiにビルドされるのでクラスパスを追加 引数に日本語版のWikipediaのファイルを追加 日本語版のWikipediaのデータの用意 こんなものかな?と。\n1と2はそれほど大変ではないので、3をまずはというところから始めてみました。\nWikipediaのXMLから1行1データのTSVファイルに まずは、どんなファイルを想定して動いているのかな?ということで、英語版のファイルがどんなものかを探してみることに。\nTestAnalyzerPerf.javaでは入力ファイルから1行ずつ文字列を読み込んでAnalyzerに処理させているだけというのがわかっています。なので、とりあえず、1行ずつ読めるような形式だと。 次に、runAnalyzerPerf.pyの55行目でenwiki-20130102-lines.txtというものを読み込んでいます。 が、これがよくわからないw\n前回とりあえず動いたときに、src/python/constants.pyにいろんなファイルへのパスとかが記載されていたのを覚えていたので、その当たりから調べてみます。 52行目に約665万件のドキュメントだというような記載があります。 前回のlocalrun.pyのファイルと似たような構造(1行に1記事が埋め込まれたTSVファイル)だろうと判断して、それを作りそうなプログラムを探してみました。 Wikiとかで検索して見つけたのがこのソースたちでした。\nsrc/python/wikiXMLToText.py - それっぽい名前ですよね? 中身を見ると、第1引数のファイル(XML)からpageタグごとにデータを抜き出し、処理をしてからタブ区切りで第2引数のファイルに書き出してます。 src/python/WikipediaExtractor.py - これもそれっぽいですね。 WikipediaExtractory.pyは界隈では有名なhttps://github.com/attardi/wikiextractorみたいです。こっちはなんとなく使い方はわかっています。 src/python/combineWikiFiles.py - これまたそれっぽい。 中身を見ると、1番目のコードで出力したデータに、2番めのコードで出力されたデータを元になにかしら処理をして、引数で与えられたファイルに出力する感じになってます。 ということで、完全に憶測ですが、日本語のWikipediaのXMLファイルを元に次のような流れでファイル作ってみればいいのかな?と。\njawiki-20200620-pages-articles.xml.bz2をwikimediaからダウンロードして、unbzip2で展開 python src/python/wikiXMLToText.py jawiki-20200620-pages-articles.xml jawiki-lines.txtで、1行ごとのデータを作る ちなみに、このプログラムは2箇所ほど修正しました。usernameタグが存在しないpageが出力されなさそうなので、デフォルトでusername: \u0026quot;\u0026quot;みたいなデータをattrってディクショナリに設定しました。 cat jawiki-20200620-pages-articles.xml | python -u src/python/WikipediaExtractor.py -b102400m -o extractedで別途XMLからデータを抽出 python src/python/combineWikiFiles.py jawiki-lines.txt extracted/AA/wiki_00 jawiki-20200620-lines.txtで2と3の出力をかけ合わせる で、まぁ、一応ファイルはできたんですが。。。 前回のブログ記事でセットアップしたときにダウンロードされたファイルはtitle、日付、本文の3つのカラムしかないんですが、上記の手順で作り出したファイルにはいろんなカラムが存在するんですよね(2が出力する項目が結構ある)。。。\n性能テスト用プログラムの書き換え 入力ファイルは出来上がったので、あとは、性能テストを走らせる部分の修正です。 修正部分はプルリク見たほうが明確なので省略で。\n実行してみた で、実行してみました。 せっかくなので、ブランチをbranch_8_5とmasterを対象にしてやってみました。 実際にはsrc/python/runAnalyzerPerf.pyにディレクトリ名やブランチ名が直書きされてたので書き換えつつ実施した結果はこちら。\n他の英語系のAnalyzerと同じグラフに載せてみたのですが、遅いので、下の方に表示されてます。 で、下に凹んだ部分(23 Juneのところ)がbranch_8_5で実行したときの性能値でした。 実際に遅くなってますね。ただ、他のAnalyzerの振れ幅も大きいので、別のグラフにしたほうがわかりやすくなるのかもなぁと思った次第です。\nということで、一応動いたんでプルリク出してみました。 採用されるかなぁ?\n一応誰得ブログはこれでおしまい。 Noriとかもこの感じで対応できるんじゃないかな?\n","date":1593050518,"dir":"post/2020/","id":"bbd2824ff0d5b801bb6f5da3a2a1a888","lang":"ja","lastmod":1593050518,"permalink":"https://blog.johtani.info/blog/2020/06/25/analyzer-perf-test-with-luceneutil/","publishdate":"2020-06-25T11:01:58+09:00","summary":"luceneutil - マニアックなツールのセットアップの続きです。 今回も誰得?なブログなので興味ない場合は飛ばしましょう。 一応、luceneutilのREAD","tags":["lucene"],"title":"luceneutil - Analyzer性能テストへのkuromojiの追加"},{"contents":"LuceneのFSTの修正に関連して、Kuromojiのパフォーマンス問題が出ているようです。 この問題自体はLucene 8.6.0以降で直る予定のようなのです(Elasticsearchへの影響範囲についてはこれが参考になるかな?)。 で、これに関連して、ベンチマーク計らないとねという話が出ていて、 昔から、LuceneのMikeさんがやっているベンチマークのグラフに載せるのがいいよねという話になっていました。 どうも、これについては、Luceneの中にあるbenchmarkというプロジェクトではなく、MikeさんのGitHubリポジトリにあるプログラムで計測しているようです。\nじゃあ、手元でこれどうやって動かすんだろう?ということでやってみたブログになります。 おそらく、99.99%の人は興味ないと思うのでスルーしていただくのがいいと思います。備忘録のために書いてます。\nとりあえずgit clone 公開されているリポジトリはこちらです。\n手順通りに? とりあえず、READMEにセットアップなどのやり方があったんで追っていくことに。 とりあえず動くまでの手順は以下のとおりです。\nディレクトリを決める $LUCENE_BENCH_HOMEが起点になります。名前は何でもいいみたいです。 cd $LUCENE_BENCH_HOME リポジトリをクローン - git clone https://github.com/mikemccand/luceneutil.git utilです。 コレ自体は問題なし。 cd util セットアップスクリプトを実行 - python src/python/setup.py -download ここがすごく時間かかります。6GBのファイルをゆっくりダウンロードしてきますので、一晩置いておきましょう(起きたら終わってた) $LUCENE_BENCH_HOME/dataにenwiki-20120502-lines-1k.txt.lzmaとwikimedium500.tasksいうファイルがダウンロードされている。 ダウンロードした圧縮ファイルを展開 - unlzma enwiki-20120502-lines-1k.txt.lzma macOSにlzmaのコマンド入ってるんですね。知らなかった。 終わったらcd ../で$LUCENE_BENCH_HOMEに戻っておく ベンチマーク対象となるLuceneを用意 - git clone https://github.com/apache/lucene-solr.git READMEにはlucene_candidateとlucene_baselineって名前でって書いてあったのですが、これだと、この後の実行フェーズでエラーになりました。 trunkとpatchというディレクトリにそれぞれ変更しました。localrun.pyを実行したらこのディレクトリ名だったので(相変わらず、自分、行きあたりばったりな対応してるなぁ。。。) とりあえず動くかどうかを確認したかったので、trunkとpatchはどちらもリポジトリをcloneしたものになってます。動いたのを確認したら、タグを指定して比較したいブランチをチェックアウトする予定。 trunkとpatchをビルド - ant jar * localrun.pyを実行 - cd utilそして。。。 5.で記述したディレクトリ以外に1箇所Pythonのコードを書き換えた。 src/python/benchUtil.py内部にhppc-0.8.1.jarのファイルの存在チェックをしているのだが、2020/06/23時点でのLuceneのリポジトリの依存関係だとhppc-0.8.2.jarになっており、ファイルが見つからないエラーが出たため、0.8.2に書き換えた。970行目付近。 改めて実行したら成功した。 まだ途中 とりあえず、実行するところまではできましたが、結果の見方とかちゃんと調べないとなぁ。 いくつかローカルで対応したものについてはあとでGitHubにIssue立てとくべきだな。\nと、動くのを確認したので、日本語周りの準備をしてみてるところです。\n終わったこと\n日本語のWikipediaのデータjawiki-20200620-pages-articles.xml.bz2をダウンロードして展開 試している途中\nWikipediaExtractorでXMLからデータを抽出 - cat ~/tmp/wiki/jawiki-20200620-pages-articles.xml | python -u src/python/WikipediaExtractor.py -b102400m -o extracted これは手順が違うかも???? python src/python/wikiXMLToText.py ~/tmp/wiki/20200620-pages-articles.xml ./hoge.txt これで、title、日付、本文が抜き出せそう? この後にcombineWikiFiles.pyの実行かな? って感じです。 誰得だろうこれ???\n","date":1592917109,"dir":"post/2020/","id":"8a1ea5d5cf843bc5955a94cfcc321e92","lang":"ja","lastmod":1592917109,"permalink":"https://blog.johtani.info/blog/2020/06/23/how-to-use-luceneutil/","publishdate":"2020-06-23T21:58:29+09:00","summary":"LuceneのFSTの修正に関連して、Kuromojiのパフォーマンス問題が出ているようです。 この問題自体はLucene 8.6.0以降で直る","tags":["lucene"],"title":"luceneutil - マニアックなツールのセットアップ"},{"contents":"Azure Cognitive Searchで日本語を扱うときに、形態素解析器を使いたい場合、2種類のAnalyzerが用意されています。今回はこれらの違いがどんなものかを見ていくことにします。\nAnalyzerとは? まずは、その前にAnalyzerとは何者か?というのを少しだけ。 Azure Cognitive Searchは転置インデックスを内部で作成して、検索を行っています。 この、転置インデックスは、「単語」がどのドキュメントに入っているか?を素早く見つけることができるデータ構造となっています。\nAzure Cognitive Searchは、この「単語」を入力された文章から生成するときに、Analyzerというものを利用します。 Analyzerは入力された文章をある規則に則って単語に分割する機能です。 この「ある規則」が、各種言語や用途によって様々に用意されています。 今回はこの中のja.luceneとja.microsoftという2種類のAnalyzerについて違いを見ていきます。\n2種類のAnalyzerの違いはどんなもの? このAnalyzerの挙動を見るためのエンドポイントとしてanalyzeというAPIがあります(詳細は昔のブログを参照)。\nこのAPIを利用して、Wikipediaのいくつかの文章を単語に区切って見て、 ja.microsoftがどんな動きをしているのか想像してみます(残念ながらja.microsoftの仕様?や挙動についてはページが見つからないため)。\nもとの文章と解析結果(一部抜粋) 文章は、手元のElasticsearchに登録したjawikiのデータからランダムに抽出しています。また、自前のツールで生成したWikipediaのデータなので、まだ一部、見苦しい文字列になっています(そっちもなおさないと)。\n1. 砂川(熊本県) thumb|250px|right|上砂川橋より上流方砂川(すながわ)は、熊本県宇城市・八代郡氷川町を流れる二級河川。\nこの文字列から抽出された単語で特徴的なものを一部抜粋しました。\nja.microsoft ja.lucene 250px 250 px 上砂 上, 上砂川 川橋 砂川 橋 宇城 宇 市 城市 二級 二 ^ 級 まず、最初の250pxですが、ja.microsoftでは、pxが単位であると判定しているのか、数値と合わせた単語として抽出されています。この場合、250で検索しても、この文字列はヒットしない形になるので、ノイズが減ることが考えられるかと。\n上砂川橋という文字は、分割の仕方が別れました。 ja.luceneでは、上砂川という単語が地名として辞書に存在するために、このような分割になっています。ja.microsoftのデータは品詞の情報が取れないのですが、上砂、川橋ともに、名詞として辞書に存在しているのではないかなと。ja.luceneには川橋という単語は存在していないようでした。\n宇城市(うきし)については、2005年に合併でできた市のようで、ja.luceneが利用している辞書には存在しない可能性があり、宇城という文字が抽出できてないと思われます。\n最後は二級です。ja.luceneでは、数字と助数詞として分割されています。こちらも何かしらのロジックにより、二級という1単語でヒットできるように数字と単位?が合わせた単語で出てくる仕組みがja.microsoftなのかなと。\n2. UEFA U-18女子選手権2000 UEFA U-18女子選手権2000は第3回目のUEFA U-18女子選手権である。決勝トーナメントは2000年7月27日から8月4日までフランスで行われ、ドイツが初優勝を果たした。\nこの文字列から抽出された単語で特徴的なものを一部抜粋しました。\nja.microsoft ja.lucene u-18, u u 18, nn18 18 第3回目 第 3 回 目 トーナメント, トナメント トーナメント 2000年 2000 年 7月 7 月 27日 27 日 数字を含む単語第3回目や2000年、7月などは、ja.microsoftは先程と同様、数字と単位の組み合わせを1単語として出力しています。\nまた、トーナメントという単語をトナメントという形で、長音を除去した形で出力しています。 今回の文字列ではないですが、この他に、センターをセンターとセンタの2パターンの単語で出力するといったことを行っています。 ja.luceneの場合、単語の最後に長音がある場合だけセンタとして、長音を除去した単語が出力されます。 これは、長音の表記ゆれに対応するためではないかなと。たとえば、インターフェースとインタフェース、インターフェイスのように、人や文章によって、間にでてくる長音を使ったり使わなかったりという表記ゆれに対応するためだと思われます。 その他にも、イプロゥヴェトをイプロゥベトに、ネクストをネキストに、バラエティをバラエチにも変換するなどといった処理をしてくれるようです。カタカナの表記ゆれには強そうですね(これどうやってるんだろう?)。\nja.microsoftでは、nn18というちょっと変わった単語も出てきていました。純粋な数字の場合はnnと入力してくれるようで、数字だけで検索したい場合に利用できるのかな?これはドキュメントに書いておいてほしいかも?\n共通点 ja.lucene、ja.microsoftともに、共通している動作として、「てにをは」といった単語は除去されていました。違いがあるものとしては、「より」(助詞-格助詞-一般)、「されている」(動詞-自立、動詞-接尾、助詞-接続助詞、動詞-非自立)、「ある」(助動詞)といったものはja.microsoftでは除去されずに出てきていました。 ストップワード的に「てにをは」あたりを除去をしている感じでしょうか?\nアルファベットで構成されている単語についても、基本はそのまま出力される挙動のようでした。\nじゃあどっちがいいの? 残念ながらどちらがいいかは、一長一短かなぁと。 ja.luceneに関しては、Luceneの仕組みを利用しているので、Elasticsearchなどを使えば、個別の単語についてより詳細の情報を取得することが可能です(品詞、読みなど)。ja.microsoftについては、残念ながら手の入れようがないので、そういう動きのものだという割り切った使い方になるでしょうか? ただ、長音の除去による表記ゆれなどについては、便利な機能なので、そのあたりの問題に対応したい場合は、ja.microsoftを活用するのも良いかと思います。\n個人的には、より細かい単語としてインデックスに登録できるもののほうが、柔軟な検索には対応できるのではないかなぁと考えています(Kuromojiの辞書をUniDicにするとか?も考えますが、これはAzure Searchではできないですが)。\nまとめ Wikipediaのデータをいくつか使って、ja.microsoftとja.luceneの違いについて、考察してみました。何かの役に立てばと。 他に、これはどんな感じになるの?などありましたら、コメントいただければと。\n","date":1591692240,"dir":"post/2020/","id":"82a115ab8d617e4e96813587fe3a6049","lang":"ja","lastmod":1591692240,"permalink":"https://blog.johtani.info/blog/2020/06/09/difference-analyzers-in-azure-search/","publishdate":"2020-06-09T17:44:00+09:00","summary":"Azure Cognitive Searchで日本語を扱うときに、形態素解析器を使いたい場合、2種類のAnalyzerが用意されています。今回はこれらの違いがどんなもの","tags":["azure search","kuromoji"],"title":"Azure Cognitive Searchでの日本語向けAnalyzerの違い"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章 Rust the book - 第9章 Rust the book - 第10章 11章、12章はちょっと飛ばして、13章です。\n第13章 イテレータ、クロージャです。 12章の話もちょっと出てくるのか。\nクロージャ 基本的に、「変数には値が束縛されている」という固定観念がずっと頭にこびりついたままなので、クロージャに慣れないんだろうなぁ。そろそろこの固定概念をどうにかしないと。\n匿名関数で、変数に保存したり引数に渡せる ちょっと面白い話(ワークアウト)で実際に考えられる手法の説明がいくつか行われる 関数でリファクタリング これが自分がよくやるパターンかなぁ。クロージャになれてないので。。。 クロージャーを変数に束縛 呼び出しは関数みたいな感じ(ここで少し混乱) これだと、結局呼び出されたタイミングが複数回あるよね? -\u0026gt; あはりそうだった ここで、閑話休題で、クロージャの型推論とか注釈の話。 クロージャは狭い文脈だし、外に公開しているものでもないので、戻り値なども定義してなくてもいいよねとのこと。書くことも可能?なので、書いてわかりやすくするのもありなんだろうな。\n推論についてはこれまで通りで、2回異なる型の変数で呼び出すと、2回目で怒られていた。\n遅延評価(クロージャを保持する構造体!?) Fnトレイト トレイトとMatchの組み合わせだからこのへんで説明する形になるのか。 これを真似すれば、いくつか処理を簡素化できるかもしれないなぁ、たしかに。 なければ実行するみたいな処理を書きたいことがよくあるし。Javaだとnullで定義しといて、nullだったらみたいなのがあるから。 Cacherはサンプルだからこの名前でいいけど、自分だと、どんな名前にするかなぁ?\n振る舞いは難しくなるのか。Cacher実装の限界を読むと。\n関数にするとスコープが変わるのでアクセスできなくなると。。。コンパイラが教えてくれるのは便利だな。\n環境から値をキャプチャする3つの方法\n多分この話が一番クロージャに意味がある話なんだと思う。 イテレータ 回しましょう。\n便利。ただ、こういう書き方に自分が慣れてないので、そっちを補正しないとなぁ。 どれがイテレータ?っていうのを判別するのがちょっとむずかしい(慣れの問題かなぁ) イテレータアダプタ便利。どんなのがあるのか?とかがやっとわかってきた。 パフォーマンスに関しては、うーん、どうなんだろう?という感想だった。 ","date":1591259849,"dir":"post/2020/","id":"e74d071363645a588f858b35231128c4","lang":"ja","lastmod":1591259849,"permalink":"https://blog.johtani.info/blog/2020/06/04/chap13-rust-the-book/","publishdate":"2020-06-04T17:37:29+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第13章"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章 Rust the book - 第9章 第10章 ジェネリック、トレイト、ライフタイムです。 手強そう。\nいきなり関数の切り出し方みたいな話が始まって面食らいました。\nジェネリックなデータ型 ジェネリックはJavaにもあるので、それほど理解に苦しむことはなかったです。 また、OptionやResultですでに経験済みでしたし。\nただ、impl\u0026lt;T\u0026gt; Point\u0026lt;T\u0026gt;{、このメソッド定義は少し最初は戸惑いました。 言われてみれば、なるほどなんですけど。\nコンパイル時にコンパイラが単相化を行うことにより、必要最低限なコードを生成してくるというのは理にかなっているなぁと。\nトレイト: 共通の振る舞いを定義する 出だしにもありますが、「インターフェイス」という機能に類似していると考えると割とすんなりと理解が進みました。 ただ、Javaだと、インターフェースはクラスとセットなため、トレイとの実装に関する記述方法は少し戸惑いが。\nデフォルト実装との組み合わせはAbstractに似た処理になるなと考えながら読みすすめました。\n「トレイト境界」という日本語には少し違和感を覚えましたが、線引をして、制限をかけるという理解でいいのかな?\n実際には#[derive()]などで、トレイトを自分で実装する必要がないなどの、便利機能も用意されており、このあたりのコードの追い方がまだ少し慣れていないかもなぁと。便利なんですけど。。。\n少しだけ気になったので、動作確認したのは次の実装です。\nトレイトで宣言されている関数と構造体が独自に実装する関数の名前がかぶるとどうなるのかという実験です。 構造体独自のメソッドが優先される感じになりそう。\npub struct Tweet { pub username: String, pub content: String, pub reply: bool, pub retweet: bool, } pub trait Summary { fn summarize_author(\u0026amp;self) -\u0026gt; String; fn summarize(\u0026amp;self) -\u0026gt; String { // {}さんからもっと読む format!(\u0026#34;(Read more from {}...)\u0026#34;, self.summarize_author()) } } impl Tweet { fn summarize_author(\u0026amp;self) -\u0026gt; String { format!(\u0026#34;hoge {}\u0026#34;, self.username) } fn to_string(\u0026amp;self) -\u0026gt; String { format!(\u0026#34;fuga\u0026#34;) } } impl Summary for Tweet { fn summarize_author(\u0026amp;self) -\u0026gt; String { format!(\u0026#34;@{}\u0026#34;, self.username) } } pub fn summary\u0026lt;T: Summary\u0026gt;(hoge: \u0026amp;T) { println!(\u0026#34;{}\u0026#34;, hoge.summarize_author()); } pub fn main() { let tweet = Tweet { username: String::from(\u0026#34;horse_ebooks\u0026#34;), content: String::from(\u0026#34;of course, as you probably already know, people\u0026#34;), reply: false, retweet: false, }; println!(\u0026#34;{}\u0026#34;, tweet.summarize_author()); summary(\u0026amp;tweet); println!(\u0026#34;{}\u0026#34;, Summary::summarize_author(\u0026amp;tweet)); } ライフタイムで参照を有効化する 言われてみればそうですが、プログラマが色々考えないとまぁ、行けないんですねという感想。\nただ、借用チェッカーが賢くやってくれるおかげで、全てにライフタイム注釈をつけなくて良くなっているというのがわかりました。 逆に言うと、なんとなくRustを書き始めてしまったので、それを知らずに書いたせいで、コンパイラに怒られてても「?」となっていたのかと。。。\n疑問点がいくつかあって、\n通常はどんなライフタイム注釈をみんな書いてるんだろう?'aとかざっくりしすぎてる? 1つのメソッド、関数にライフタイム注釈が大量に出てくるような書き方をした場合は設計がおかしいのでは?って考えたほうがいいのかも? ジェネリックな型とライフタイム引数の順序を入れ替えてみても動くだろ?とおもって入れ替えてみたら怒られた。 あとは、構造体+ジェネリックが絡んできたら少しこんがらがってきそうっという感じです。 まぁ、これから先は実際に書いてみないことにはわからないんだろうなと。\nまとめ 読みました。 実際にはプログラムを書きながら慣れていく感じだろうなぁと。 まだまだ、あれ?ジェネリックってどう書くんだっけ?とか、ライフタイム注釈どうやって付けて、使うときはどうすんだ?みたいになりながら、 出てくるサンプルを少し変えてみてはどうやって動くんだろうこの場合?みたいなことをやってました。 次は、11章、12章を少しだけ自習しつつ、13章に入る予定です(知り合いと一緒に読みすすめてる)。\n","date":1590656815,"dir":"post/2020/","id":"163beeae9620c1a6a46a38aa7ebd9663","lang":"ja","lastmod":1590656815,"permalink":"https://blog.johtani.info/blog/2020/05/28/chap10-rust-the-book/","publishdate":"2020-05-28T18:06:55+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第10章"},{"contents":"今回はAzure Cognitive SearchのSDKを利用したアプリケーションが、実際にAzure Cognitive Searchに対して送信しているリクエストのパラメータとボディをログに保存する方法について紹介します。\n動機 アプリケーションでリクエストを組み立てて、SDK経由で送信していると、最終的にAzure Cognitive Searchに対して送信されているリクエストのパラメータや検索条件などをひと目で見たいことがあります。 アプリケーションでは、ソート条件や、クエリ文字列の組み立てなどの処理は異なる場所で行われたりしますので。\nまた、公式リファレンスでは、機能の説明はRest APIの使い方と組み合わせで説明されることが多いです。\nということで、SDKを利用しているアプリからAzure Searchへ送信されているリクエストをログに保存する方法を調べてみました。\n方法 調べてみるといくつかの手段を取ることができそうだとわかりました。実際に調べて実装する方法を4種類ほど試してみたのでブログに残しておきます。なお、2020年4月時点でのSDKとAzureの仕組みに基づいたブログになります。最新版ではお手軽な方法があるかもしれません。\nDelegatingHandlerを利用する ServiceClientTracingの機能を利用する Azure Application Insightsを活用する Azure Cognitive Searchのコンソールにある診断情報の機能を利用する 1、2はAzure Cognitive SearchのSDKのリファレンスから当たりを付けて見つけた方法です。 3はApplication Insights、4はAzure Cognitive Searchの機能になります。 これらの方法について個別に説明していきます。\n1. DelegatingHandleを利用する まずは、SDKでロギングの機能がないかを調べて見つけた機能がこちらです。 SDKのSearchServiceClientのコンストラクタの引数にDelegatingHandlerというものが渡せることを発見しました。\nこれは、.NET FrameworkのHttpのAPIに存在するクラスで、HTTPのクライアントがHTTPの送受信時に、処理を挟むことができる機能です。フレームワーク側で、LoggingHttpMessaggeHandlerというクラスを用意してくれていましたが、残念ながらこちらは、リクエストとレスポンスのヘッダのみをロギングするクラスでした。 ということで、リクエストボディをログに出力したい場合は独自に拡張してやる必要があります。なお、ロギングにはMicrosoft.Extensions.LoggingのILoggerを使用します。\nまた、Azure Cognitive SearchのSDK側に違う問題点もありました。チュートリアルにあるように、検索するときには、SDKは次のような使い方を想定しています。\n// Create a service and index client. _serviceClient = new SearchServiceClient(searchServiceName, new SearchCredentials(queryApiKey)); _indexClient = _serviceClient.Indexes.GetClient(\u0026#34;hotels\u0026#34;); インデックス用のクライアントを取得するために、GetClient(インデックス名)というメソッドを使用します。このGetClientメソッドのバリエーションとして、DelegatingHandlerを受け取るメソッドがないのです。。。\nということで、DelegationHandlerを活用する方法としては、以下の2つを実装する必要があります。\nCustomなLoggingHttpMessageHandlerクラスを実装 GetClientと同等の処理をDelegatingHandlerを引数にしたものを実装する 以上の2つを実装し、アプリケーション側から2で作成したGetClientを呼び出すことで、リクエストをボディも含めてログ出力することが可能になります。以下は実装例です。\nCustomHttpMessageHandlerクラス。\nusing System; using System.Collections.Generic; using System.Diagnostics; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; namespace AzureSearchSample { public class CustomLoggingHttpMessageHandler : DelegatingHandler { private readonly ILogger _logger; private readonly bool _logContent = false; public CustomLoggingHttpMessageHandler(ILogger logger, bool logContent) { if (logger == null) { throw new ArgumentNullException(nameof(logger)); } this._logger = logger; this._logContent = logContent; } protected override async Task\u0026lt;HttpResponseMessage\u0026gt; SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { if (request == null) { throw new ArgumentNullException(nameof(request)); } await Log.RequestStart(this._logger, request, this._logContent); var stopwatch = new Stopwatch(); HttpResponseMessage response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false); stopwatch.Stop(); await Log.RequestEnd(this._logger, response, stopwatch.Elapsed); return response; } private static class Log { private static class EventIds { public static readonly EventId RequestStart = new EventId(100, \u0026#34;RequestStart\u0026#34;); public static readonly EventId RequestEnd = new EventId(101, \u0026#34;RequestEnd\u0026#34;); } public static async Task RequestStart(ILogger logger, HttpRequestMessage request, bool logContent) { StringBuilder message = new StringBuilder(); message.AppendLine($\u0026#34;Sending HTTP request {request.Method} {request.RequestUri}\u0026#34;); if (logger.IsEnabled(LogLevel.Trace)) { LogHttpHeaders(message, request.Headers); await LogHttpContent(message, request.Content, logContent); logger.Log( LogLevel.Trace, EventIds.RequestStart, message, null, (state, ex) =\u0026gt; state.ToString()); } } public static async Task RequestEnd(ILogger logger, HttpResponseMessage response, TimeSpan duration) { StringBuilder message = new StringBuilder(); message.AppendLine( $\u0026#34;Recieving HTTP response after {duration.TotalMilliseconds}ms - {response.StatusCode}\u0026#34;); if (logger.IsEnabled(LogLevel.Trace)) { LogHttpHeaders(message, response.Headers); await LogHttpContent(message, response.Content, false); logger.Log( LogLevel.Trace, EventIds.RequestEnd, message, null, (state, ex) =\u0026gt; state.ToString() ); } } private static void LogHttpHeaders(StringBuilder message, HttpHeaders headers) { if (headers == null) throw new ArgumentNullException(nameof(headers)); foreach (KeyValuePair\u0026lt;string, IEnumerable\u0026lt;string\u0026gt;\u0026gt; header in headers) { foreach (string value in header.Value) { message.AppendLine($\u0026#34;{header.Key}: {value}\u0026#34;); } } } private static async Task LogHttpContent(StringBuilder message, HttpContent content, bool logContent) { if (content != null) { foreach (KeyValuePair\u0026lt;string,IEnumerable\u0026lt;string\u0026gt;\u0026gt; header in content.Headers) { foreach (string value in header.Value) { message.AppendLine($\u0026#34;{header.Key}: {value}\u0026#34;); } } if (logContent) { string contentBody = await content.ReadAsStringAsync(); message.AppendLine(contentBody); } } } } } } GetClientの実装\nprivate ISearchIndexClient GetClient(string indexName, params DelegatingHandler[] handlers) { var rootHandler = _searchServiceClient.HttpMessageHandlers.OfType\u0026lt;HttpClientHandler\u0026gt;().SingleOrDefault(); var indexClient = new SearchIndexClient(_searchServiceClient.SearchServiceName, indexName, _searchServiceClient.SearchCredentials, rootHandler, handlers) { SearchDnsSuffix = _searchServiceClient.SearchDnsSuffix }; indexClient.HttpClient.Timeout = _searchServiceClient.HttpClient.Timeout; return indexClient; } 出力されるログ例\n2020/04/14 19:17:53.591|TRACE|Sending HTTP request POST https://サービス名.search.windows.net/indexes(\u0026#39;インデックス名\u0026#39;)/docs/search.post.search?api-version=2019-05-06 client-request-id: be02140f-3a07-48cc-b018-d8aa5e819bc3 Accept-Language: en-US Accept: application/json; odata.metadata=none api-key: APIキー User-Agent: FxVersion/4.700.20.11803 User-Agent: OSName/MacOs User-Agent: OSVersion/Darwin.19.4.0.Darwin.Kernel.Version.19.4.0.Wed.Mar.4.22.28.40.PST.2020.root.xnu.6153.101.6.15RELEASE.X86.64 User-Agent: Microsoft.Azure.Search.SearchIndexClient/10.100.19.52907 Content-Type: application/json; charset=utf-8 { \u0026#34;count\u0026#34;: false, \u0026#34;facets\u0026#34;: [], \u0026#34;queryType\u0026#34;: \u0026#34;simple\u0026#34;, \u0026#34;scoringParameters\u0026#34;: [], \u0026#34;search\u0026#34;: \u0026#34;azure\u0026#34;, \u0026#34;searchMode\u0026#34;: \u0026#34;any\u0026#34; } |AzureSearchSample.SearchService|EventId_Id=100, EventId_Name=RequestStart, EventId=RequestStart メリット、デメリット Azure Cognitive Searchの検索の処理だけを対象にリクエストのログを出力することが可能です。また、影響範囲はアプリケーションだけに閉じていますので、デバッグ目的などでログ出力したい場合に、自分だけの手元でログの確認が可能になります。\nデメリットとしては、独自に実装しなければいけない範囲が広いことです。\n2. ServiceClientTracingの機能を利用する Microsoft.Rest.ClientRuntimeというライブラリをAzure Cognitive Searchは利用しています。 このライブラリにServiceClientTracingというクラスが存在します。 なにやら、クライアントの処理のトレースができそうです。\nAzure Cognitive SearchのSDKの実装がGitHubに公開されており、検索リクエストの処理を投げる直前に、このトレースの仕組がONになっていると、ServiceClientTracing.SendRequestメソッドを呼び出していました。\n実際にSendRequestメソッドに送られたものに対して何かしらの処理を行うのは、IServiceClientTracingIntercepterインターフェースを実装したクラスになります。 このインターフェースの実装がLog4Netに存在します。Log4Netを利用している場合は、これを活用すれば楽ができます。\n実際にServiceClientTracingを有効にするには、以下の2行を呼び出すだけです。\nServiceClientTracing.IsEnabled = true; ServiceClientTracing.AddTracingInterceptor(new Log4NetTracingInterceptor()); あとは、Rest.ClientRuntimeがよしなにやってくれます。 1とは異なり、トレースログなので、リクエストのボディについても出力してくれます。\n2020-05-26 19:09:04,058 [1] DEBUG Microsoft.Rest.Tracing.Log4Net.Log4NetTracingInterceptor [(null)] - invocationId: 1 instance: Microsoft.Azure.Search.DocumentsProxyOperations method: SearchPost parameters: {searchRequest=Microsoft.Azure.Search.Models.SearchRequest,clientRequestId=,cancellationToken=System.Threading.CancellationToken} 2020-05-26 19:09:04,164 [1] DEBUG Microsoft.Rest.Tracing.Log4Net.Log4NetTracingInterceptor [(null)] - invocationId: 1 request: Method: POST, RequestUri: \u0026#39;https://サービス名.search.windows.net/indexes(\u0026#39;インデックス名\u0026#39;)/docs/search.post.search?api-version=2019-05-06\u0026#39;, Version: 2.0, Content: System.Net.Http.StringContent, Headers: { client-request-id: 591cb14f-e5c2-4a85-977d-01d1f6431ddc Accept-Language: en-US Accept: application/json; odata.metadata=none api-key: APIキー Content-Type: application/json; charset=utf-8 } Body: { { \u0026#34;count\u0026#34;: false, \u0026#34;facets\u0026#34;: [], \u0026#34;queryType\u0026#34;: \u0026#34;simple\u0026#34;, \u0026#34;scoringParameters\u0026#34;: [], \u0026#34;search\u0026#34;: \u0026#34;azure\u0026#34;, \u0026#34;searchMode\u0026#34;: \u0026#34;any\u0026#34; } } 2020-05-26 19:09:04,459 [Thread Pool Worker] DEBUG Microsoft.Rest.Tracing.Log4Net.Log4NetTracingInterceptor [(null)] - invocationId: 1 response: StatusCode: 200, ReasonPhrase: \u0026#39;OK\u0026#39;, Version: 1.1, Content: System.Net.Http.StreamContent, Headers: { Cache-Control: no-cache Pragma: no-cache request-id: 591cb14f-e5c2-4a85-977d-01d1f6431ddc elapsed-time: 72 OData-Version: 4.0 Preference-Applied: odata.include-annotations=\u0026#34;*\u0026#34; Strict-Transport-Security: max-age=15724800; includeSubDomains Date: Tue, 26 May 2020 10:09:04 GMT Content-Type: application/json; odata.metadata=none Expires: -1 Content-Length: 376 } メリット、デメリット Log4Netを利用しているアプリの場合、2行だけを追加することで実装が完了するのがお手軽な点です。\n難点としては、Rest Client全てにたいしてトレース処理が入ってしまうので、Azure Cognitive Search以外にもRestクライアントを利用しているものが存在した場合、ログの量が増えてしまいます。また、検索以外の処理でもトレースされてしまうのもデメリットになります。\nLog4Net以外のログ機構を使用している場合は、自分でIServiceClientTracingInterceptorを実装する必要も出てきます(参考:StackOverflow)。\n3. Azure Application Insightsを活用する ここから紹介する3と4については、ログの出力先がAzure上になります。\nAzureのApplication Insightsを利用する方法です。 Azure?.NET?のアプリケーションパフォーマンスモニタリングのサービスです。\nApplication Insightsを自分のアプリケーションに設定することで、アプリケーションのパフォーマンス監視に関する情報がAzure上のApplication Insightsリソースに送信されるようになります。\nただ、Application Insightsのデフォルトの機能では、URL程度の情報だけが送信されます(参考:しばやんさんのブログ)\nこちらも拡張機能が用意されており、ITelemetryInitializerのインターフェースを実装したクラスを用意することで、独自の情報をApplication Insightsに出力することが可能となります。詳細についてはしばやんさんのブログを参考にしてもらうのが良いかと。\nHttpリクエストを出力する実装例は次のとおりです。ただ、ちょっとうまく行かないパターンがあったので、コメントアウトとして残してあったりします(なんでだろう?)\nusing System.Collections.Generic; using System.Net.Http; using System.Net.Http.Headers; using Microsoft.ApplicationInsights.Channel; using Microsoft.ApplicationInsights.DataContracts; using Microsoft.ApplicationInsights.Extensibility; namespace AzureSearchWebSample.ApplicationInsights { public class HttpRequestInitializer : ITelemetryInitializer { public void Initialize(ITelemetry telemetry) { if (!(telemetry is DependencyTelemetry dependency)) { return; } HttpRequestMessage requestMessage = null; HttpRequestHeaders requestHeaders; if (dependency.TryGetOperationDetail(\u0026#34;HttpRequest\u0026#34;, out var details) \u0026amp;\u0026amp; details is HttpRequestMessage request) { requestMessage = request; requestHeaders = request.Headers; if (requestMessage.Method == HttpMethod.Post) { string contentBody = requestMessage.Content.ReadAsStringAsync().GetAwaiter().GetResult(); dependency.Properties.Add(\u0026#34;RequestBody\u0026#34;,contentBody); } } else if (dependency.TryGetOperationDetail(\u0026#34;HttpRequestHeaders\u0026#34;, out details) \u0026amp;\u0026amp; details is HttpRequestHeaders headers) { requestHeaders = headers; } else { return; } foreach (KeyValuePair\u0026lt;string,IEnumerable\u0026lt;string\u0026gt;\u0026gt; header in requestHeaders) { foreach (string value in header.Value) { dependency.Properties.Add(header.Key, value); } } //この実装の場合は出力されなかった。なぜ? // if (requestMessage != null \u0026amp;\u0026amp; requestMessage.Method == HttpMethod.Post) // { // string contentBody = requestMessage.Content.ReadAsStringAsync().GetAwaiter().GetResult(); // dependency.Properties.Add(\u0026#34;RequestBody\u0026#34;,contentBody); // } } } } メリット、デメリット すでにApplication Insightsを利用している場合はついでに情報が出力されるので便利です。かつ、常にリクエストログを見れるようにしておく場合はとても便利だと思います。\nApplication Insightsを利用していない場合は、そこから導入しなければならなくなるので、手間が増えるかもしれないです。\n4. Azure Cognitive Searchのコンソールにある診断情報の機能を利用する。 最後はAzure Cognitive Searchの診断ログを有効にする方法です。 ここまで説明してきた方法の中で、一番お手軽な方法です。。。\nこれまでは、リクエストボディを出力する方法を考えていましたが、Azure Cognitive Search側の診断ログを有効にすると、リクエストボディで送信したものが、Azure Cognitive Search側で、クエリパラーメータとして、診断ログに出力されます(診断ログのQuery_s)。\nあとは、Azureのコンソールで当該時間のログを見ればよいだけです。以下は出力されたログの一部です。Description_sにはURLのパスが記載されています。\n診断ログ例(一部)\nDescription_s POST /indexes(\u0026#39;multi-field-test\u0026#39;)/docs/search.post.search Query_s ?api-version=2019-05-06\u0026amp;searchMode=Any\u0026amp;search=azure\u0026amp;queryType=Simple\u0026amp;$count=false メリット、デメリット アプリケーション側に手を入れる必要がなのでお手軽です。 一度設定しておけばコンソール側でログをいつでも見れるので便利です。\nリクエスト量が多くなってしまうと、ログの量も多くなり、費用がかさむ恐れがあります。また、複数の人が触る環境の場合は自分で送信したリクエストがどれだったのか?といった状況に陥る可能性はあります。\nその他は? Azureに対してではないですが、昔似たようなことをやるときにやっていた方法として、ローカルにプロキシサーバーを起動し、そのプロキシサーバー経由でアプリケーションから、Azureに接続することで、リクエストを保存する方法もあります。 ざんねんながら、未調査ですがアプリなどにはそれほど手を入れる必要はないかと思います。\nまとめ ちょっと送信リクエストの内容が見てみたいという話でしたが、いろいろな手段が存在しました。 自分の状況、環境に合わせて手段を選択肢てみるのがいいかと思います。 まずは、簡単な診断ログあたりからでしょうか?\n","date":1590481367,"dir":"post/2020/","id":"36dd94159e3e60076c0c6098086e255f","lang":"ja","lastmod":1590481367,"permalink":"https://blog.johtani.info/blog/2020/05/26/logging-azure-search-request/","publishdate":"2020-05-26T17:22:47+09:00","summary":"今回はAzure Cognitive SearchのSDKを利用したアプリケーションが、実際にAzure Cognitive Searchに対して送信しているリクエストのパラメータ","tags":["azure search",".net"],"title":"Azure Cognitive Searchのリクエストのロギング"},{"contents":"Mircosoft Buildというイベントが今週ありました(MSの方やお客さんに教えてもらった)。\nそこで、Azure Cognitive Searchのセッション(MyBuild - Cognitive Search: The pocket-knife for knowledge mining)があったので、見てみました。 内容がどんなものかをメモっておきます。 最初はCognitive Searchがどんなものよという説明でした。\nビルトインスキルの拡充の話 データソースからデータを取り出し、エンリッチし、検索エンジンに保存するという、パイプラインが組めるようになっています。\nこのパイプラインで利用できる処理のことがスキルと呼ばれています。ここで利用できるビルトインスキルが拡充されますよという話でした。ちょっとだけ抜き出すと以下のとおりです。\nAzure Machine Learning Text translation Brand detection Object detection スキルのリファレンスには載ってるものと載ってないものがあるので、今後追加されてくのかな? Brand detectionがどんなものなんだろう?ってのがちょっと気になりました。どっかにデモとかあるかなぁ?\nスキルセットのための新機能 : Debug Sessionのデモ 上記のスキルを組み合わせてパイプラインを組んで、データソースから取り出したデータをエンリッチしてから、検索エンジンに入れる処理をかけるのですが、その処理のデバッグ用に新しいGUIの機能が追加されてますよという紹介とデモでした。\nTutorial: Use Debug sessions to diagnose, fix, and commit changes to your skillset - Azure Cognitive Search | Microsoft Docs Manage Identityの話 Azure Cognitive Searchにデータを登録するパイプランの最初の段階で、各種データソースにアクセスが必要です。 このアクセス時にコネクションの設定にアカウントキーなども含めてましたが、これをコネクション設定ではなく、専用の管理機能が用意されましたよという話でした。\nSet up a connection to a data source using a managed identity (preview) - Azure Cognitive Search | Microsoft Docs QA Similarityとかの話 BM25になってるよとか SDKの話とか ほかにRelevancyの話 Analyzerをデフォルトのままじゃなくてちゃんと考えて使いましょう(例:各言語用のAnalyzerがいっぱいあるよとか) こんな感じでした。\n","date":1590117041,"dir":"post/2020/","id":"21982f43bc435f22efef22b309a48c66","lang":"ja","lastmod":1590117041,"permalink":"https://blog.johtani.info/blog/2020/05/22/watching-azure-cognirive-search-session-at-ms-build/","publishdate":"2020-05-22T12:10:41+09:00","summary":"Mircosoft Buildというイベントが今週ありました(MSの方やお客さんに教えてもらった)。 そこで、Azure Cognitive Searchのセッション(MyBuil","tags":["azure search"],"title":"Microsoft Build(2020)のAzure Cognirive Searchのセッションを見たのでメモ"},{"contents":"ElasticのWorkplace Searchを触ってみています(その1、その2)が、Elastic Stackの7.7.0がリリースされてしまいました。\n簡単ですが、リリースブログを見ながら気になった点をメモしとこうかと。\n本家のリリースブログ いっぱいあるんですよ、これが。まぁ、内容かぶってるのもあるんですが。\nElastic Stack Elastic Stack 7.7.0をリリース Elasticsearch 7.7.0 released Kibana 7.7.0 released Logstash 7.7.0 released Enterprise Search系 Elastic Enterprise Search 7.7 released, featuring Workplace Search GA | Elastic Blog Elastic App Search updates: Scale your way with new configuration options | Elastic Blog Elastic Workplace Search: 新しい、統合された働き方へ Observability系 Elastic Observability 7.7 released | Elastic Blog\nElastic APM 7.7.0 released with service maps, async profiler, and more | Elastic Blog\nElastic Logs 7.7.0 released with PCF support, MQTT support, and more | Elastic Blog\nElastic Metrics 7.7.0 released with enhanced Prometheus integration and PCF support, | Elastic Blog\nElastic Uptime Monitoring 7.7.0 released with alerting, anomaly detection and more | Elastic Blog\nNew alerting framework released for Observability, Security and the Elastic Stack | Elastic Blog\nIntroducing Elastic Security 7.7.0 | Elastic Blog\n個人的に気になったもの で、全部読んだわけではないのですが、個人的に気になった機能についてメモを残しておきます。 多分に検索によっている可能性がありますが、お気になさらず。 また、ブログとドキュメントを元に気になるところをピックアップしてます。 実際の実装とか動作に関してはまだ未調査の段階です。\nAsync Search - Elasticsearch ElasticsearchのAPIとして非同期に検索できるAPIが実装されました (公式リファレンス)。 大量データを検索が終了してから検索結果を返すのではなく、クエリは実行しつつわかったところまでは都度取得したいという要望だったり、Coldインデックスのように遅いストレージ上にあるデータへの検索でも少しずつ取得できるようにという具合だと思います。ログとか大量に扱う場合にまぁ、ほしいですよね。今回はEsのリリースがメインで、今後はKibanaなどとの連携だったり色々改善していくよという話みたいです(Kibanaの一部の機能は利用しているみたい)。\nライセンスとサブスクリプションのレベル Elastic License Basic 気になるところ(と、予想とか) 仕組みがどうなっているか? Search APIと同等のリクエストパラメータが使える。が、いくつか制約はありそう おそらくTask Manageerで検索してる処理が管理され、レスポンスにはIDが発行されて、そのIDで処理の進み具合を取得する感じ。 Shard単位?Segment単位? 内部的にはShard単位で検索処理を扱ってるので、Shard単位がとりあえず楽そう? Aggsとかも? 対象の模様 Sortは? 有効。ソートのフィールドがインデックス対象だった場合は、そのデータの統計値を使ってShardをソートするっぽい(公式リファレンスのNOTE参照) 関連しそうなGitHubのIssuesとか まだ読んでない\nAsync search · Issue #49091 · elastic/elasticsearch Add a listener to track the progress of a search request locally by jimczi · Pull Request #49471 · elastic/elasticsearch Pre-sort shards based on the max/min value of the primary sort field by jimczi · Pull Request #49092 · elastic/elasticsearch Async search: store intermediate results · Issue #55464 · elastic/elasticsearch Reduced consumption of heap - Elasticsearch ヒープの使用量が7.7で減ってるよというブログも別途ありました。\n元になっているLuceneの実装に関するIssueが「[LUCENE-8635] Lazy loading Lucene FST offheap using mmap - ASF JIRA」です。ヒープ上に展開していたデータをmmapで扱えるようにすることで、ヒープのメモリを削減してる。\nで関連して、これがLuceneで操作できるようになって(「Use reader attributes to control term dict memory useage by s1monw · Pull Request #42838 · elastic/elasticsearch」)、そこからEsに取り込まれたと。\n_idをoff-heapにする話は[ここ](Move the terms index of _id off-heap. by jpountz · Pull Request #52405 · elastic/elasticsearch)にあった。\nこれに関連して、ヒープサイズの推奨について再考が必要かも?というIssue(Reconsider our recommendations for heap size? · Issue #52561 · elastic/elasticsearch)も上がってる。\nPainless Lab - Kibana ほんとにPainless?と言う話はさておき、_script APIでexecuteはできていましたが、やはりもう少し楽に実行したいですよね?ということで画面ができたみたいです。\nシンタックスハイライトとかもできるので、より簡単に使えるようになってますね。 まだ、ベータなので足りないContextとかもあるっぽいけど。\nライセンスとサブスクリプションのレベル Elastic License Basic? まだベータだからか、サブスクリプションのページにはなかった。 公式ドキュメントとGitHubのリポジトリから、Elastic Licenseであることは判明。\n気になるところ(と、予想とか?) 制限事項がどんなものか? 使えるContextがまだ少ない?まだGAではない サジェストがどのくらい効くのか? シンタックスハイライトはあるけど。まだかなぁ? その他Elasticsearch関連 7.7リリースのハイライトが別途用意されています。\n7.7.0 release highlights | Elasticsearch Reference [7.7] | Elastic こっちで気になるのは、ClassificationとかTransformsあたりかなぁ。ML関連の機能で。\nWorkplace Search GA これは別のブログに書くかな。\n気になるところ Betaと何が変わったのか? APIとかどういう形で提供されるのか?そもそも提供されるのか? どんな機能?みたいなのも書く予定です。\nData VisualizerでFilebeatのConfigをサジェスト - Kibana and Filebeat Kibanaの画面からデータをちょっと?(100MB)だけアップロードして、Elasticsearchにサクッとデータ登録できる機能が実はあります。この機能の拡張として、Filebeatの設定だとこんな感じに作れるよ?というのを提示してくれるようになったみたいです。 手元にあるファイルを定期的に読み込むときに、設定を書く下地ができるのは便利じゃないかな?\nライセンスとサブスクリプションのレベル Elastic License Basic Data Visualizerってどんなもの?というのはここにブログがあります。残念ながらKibanaとかの公式リファレンスには使い方のページがないんだよなぁ。\nAPMのサービスマップ - APM and Kibana アプリケーションアーキテクチャのどこでAPMが動作しているか、どこと通信しているかという、APMのエージェントが入っているアプリ間のつながりをKibana上で可視化できる機能っぽいです。まだ、ベータみたいですが、面白そう。Azure Application Insightのアプリケーションマップに似てる気がします。\nライセンスとサブスクリプションのレベル Elastic License Platinum 気になるところ どうやって作ってる(つながりをどうやて判断してる)のか? 分散トレーシングのデータを元に誰がどこと通信してるってのは取れるんじゃなかろうか? Log categorization and contextual examples - Kibana and Elasticsearch 7.6から入ってたっぽいですが、ログの分類をMLの機能を使ってできるものが、LogsのUIとかでさらに使いやすくなった模様。\nライセンスとサブスクリプションのレベル Elastic License Platinum 気になるところ 7.6の機能から追いかけないとなぁ。。。 似たようなログをカテゴリーごとに分析できるようになるので、プラスMLの仕組みでこれまでとは異なる種類のログが出始めたみたいなことが分析できそう。 まとめ 眺めるだけで時間かかりましたが、まぁ、相変わらずいっぱいありますね。 興味のあるところの濃淡が出た感じになりましたが、気になる点をピックアップしてみました。 おかしなところとか、ここはどういう意味?などあればツッコミお願いします。\n","date":1589509037,"dir":"post/2020/","id":"306cecb32320ead508346ad8fed3394d","lang":"ja","lastmod":1589509037,"permalink":"https://blog.johtani.info/blog/2020/05/15/elastic-stack-7_7/","publishdate":"2020-05-15T11:17:17+09:00","summary":"ElasticのWorkplace Searchを触ってみています(その1、その2)が、Elastic Stackの7.7.0がリリースされてし","tags":["elastic stack"],"title":"Elastic Stack 7.7がリリースされた"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章 第9章 エラー処理です。 NLP100とか、いくつかのプログラムを書いていて、なんとなくは扱っていますが、きちんと勉強しないと。\nとりあえず、「Rustには例外は存在しません。」が一番知っておくことかな。\npanic!で回復不能なエラー panic!マクロでスタックを巻き戻して掃除をして終了。 異常終了(panic = 'abort')にもできる。 「RUST_BACKTRACEを0以外の変数にセットして実行」 * Resultで回復可能なエラー expect()は気持ち悪い名前じゃないかなぁ? ここでio::Errorではないものもエラーが発生する場合には panic!すべきかするまいか まとめ 「Rustには例外は存在しない」ので、回復不能か可能かを考えつつ処理を書こうと。\n","date":1589449406,"dir":"post/2020/","id":"1e220a934e16fd941bd804ca03865b60","lang":"ja","lastmod":1589449406,"permalink":"https://blog.johtani.info/blog/2020/05/14/chap9-rust-the-book/","publishdate":"2020-05-14T18:43:26+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第9章"},{"contents":"Rustで言語処理100本ノックの第2章の残りです。\n前回はこちら。\nちなみに、標準入力から受け取る処理は書いてないです。 出力に関してはファイル分割、保存と支持があるもの以外は文字列として取り出すところで終わっています。\n12. 1列目をcol1.txtに,2列目をcol2.txtに保存 pub fn extract_column(input_file_name: \u0026amp;str, num: usize, output_file_name: \u0026amp;str) { let input_f = File::open(input_file_name).expect(\u0026#34;file not found\u0026#34;); let read_buf = BufReader::new(input_f); let mut output_f = OpenOptions::new() .write(true) .create(true) .open(output_file_name) .expect(format!(\u0026#34;can\u0026#39;t open file[{}] with write option\u0026#34;, output_file_name).as_str()); read_buf.lines().for_each(|line| match line { Ok(line) =\u0026gt; { let columns: Vec\u0026lt;_\u0026gt; = line.split(\u0026#39;\\t\u0026#39;).collect(); writeln!(output_f, \u0026#34;{}\u0026#34;, columns[num]); output_f.flush().expect(\u0026#34;Error during flush\u0026#34;); } Err(_) =\u0026gt; panic!(\u0026#34;parse error \u0026#34;), }); } 13で出力結果を利用するので入力として出力ファイル名も受け取るようにしました。 問題としては、1列目と2列目を別々に出力すればいいので、1回の処理で書いても良かったのですが、1回1ファイルの出力という形で実装しました(効率は悪い)。\n改行コードあたりを考えるのがめんどくさかったのでwriteln!マクロでファイルに書き出しています。が、普通にwriteメソッドで改行コードを追加しても良かったのかなと。\nあとは、出力先ファイルが存在しない場合だけopenするようにOpenOptionsを利用してみています。\nflushを呼び出すべきなのかどうか?を調べないとな。。。\n13. col1.txtとcol2.txtをマージ pub fn merge_files(col1_file: \u0026amp;str, col2_file: \u0026amp;str, output_file_name: \u0026amp;str) { let col1_buf = BufReader::new(File::open(col1_file).expect(\u0026#34;file not found\u0026#34;)); let col2_buf = BufReader::new(File::open(col2_file).expect(\u0026#34;file not found\u0026#34;)); let mut output_f = OpenOptions::new() .write(true) .create(true) .open(output_file_name) .expect(format!(\u0026#34;can\u0026#39;t open file[{}] with write option\u0026#34;, output_file_name).as_str()); col1_buf .lines() .zip(col2_buf.lines()) .for_each(|(col1, col2)| { let col1 = col1.expect(\u0026#34;parse error col1\u0026#34;); let col2 = col2.expect(\u0026#34;parse error col2\u0026#34;); writeln!(output_f, \u0026#34;{}\\t{}\u0026#34;, col1, col2); output_f.flush().expect(\u0026#34;Error during flush\u0026#34;); }); } 2つのファイル名を入力として受け取り、タブでくっつけて出力します。 zipを利用することで、2つのイテレーターを同時に回しています。\n14. 先頭からN行を出力 pub fn head(input_file_name: \u0026amp;str, lines: usize) -\u0026gt; String { let buf = BufReader::new(File::open(input_file_name).expect(\u0026#34;file not found\u0026#34;)); let mut head = String::new(); buf.lines().take(lines).for_each(|line| { head.push_str(format!(\u0026#34;{}\\n\u0026#34;, line.expect(\u0026#34;parse error\u0026#34;)).as_str()); }); return head; } イテレーターのメソッドにtakeがあります。 これを利用することで、引数に指定した数のエレメントが取得できるので、これでheadが実現できます。\n15. 末尾のN行を出力 pub fn tail(input_file_name: \u0026amp;str, lines: usize) -\u0026gt; String { let buf = BufReader::new(File::open(input_file_name).expect(\u0026#34;file not found\u0026#34;)); let mut tail = String::new(); let line_count = word_count(input_file_name); buf.lines().skip(line_count - lines).for_each(|line| { tail.push_str(format!(\u0026#34;{}\\n\u0026#34;, line.expect(\u0026#34;parse error\u0026#34;)).as_str()); }); return tail; } tailの場合は少し複雑で、11で作成した行数をカウントするメソッドで総行数を取り出し、そこから引数で指定された行数を引き算した数(=出力しない行数)を、イテレーターのskipメソッドの引数に渡しています。これにより、指定された数のエレメントをスキップしたあとの処理がかけます。\n16. ファイルをN分割する pub fn split_files( input_file_name: \u0026amp;str, num: usize, output_file_prefix: \u0026amp;str, output_file_suffix: \u0026amp;str, ) { let total = word_count(input_file_name) as f64; let lines_in_file = total / num as f64; let lines_in_file = lines_in_file.ceil() as usize; // let buf = BufReader::new(File::open(input_file_name).expect(\u0026#34;file not found\u0026#34;)); let output_files: Vec\u0026lt;File\u0026gt; = create_file_vec(output_file_prefix, num, output_file_suffix); println!(\u0026#34;split file each {} lines.\u0026#34;, lines_in_file); let mut lines = buf.lines(); for mut output_f in output_files { let mut current = 1; while current \u0026lt; lines_in_file + 1 { let line = lines.next(); if let Some(line_rs) = line { if let Ok(line_str) = line_rs { writeln!(output_f, \u0026#34;{}\u0026#34;, line_str); } } current = current + 1; } output_f.flush().expect(\u0026#34;error during flush\u0026#34;); } } fn create_file_vec(output_file_prefix: \u0026amp;str, num: usize, output_file_suffix: \u0026amp;str) -\u0026gt; Vec\u0026lt;File\u0026gt; { let mut files = Vec::with_capacity(num); for i in 0..num { let output_file_name = format!(\u0026#34;{}{}{}\u0026#34;, output_file_prefix, i + 1, output_file_suffix); let output_f = OpenOptions::new() .write(true) .create(true) .open(output_file_name.as_str()) .expect(format!(\u0026#34;can\u0026#39;t open file[{}] with write option\u0026#34;, output_file_name).as_str()); files.push(output_f); } return files; } ちょっと長いですね。\n入力としては、分割するファイル数Nが指定されます。まずは、総行数/Nで各ファイルに保存されるべき行数を計算します。 次に、2つ目の関数をつかって、必要な数のファイルオブジェクトをベクトルとして生成します。\nファイルオブジェクトのベクトルの要素を元にしたfor文を回しつつ、それぞれのファイルに必要な行数を出力している処理になっています。\n総行数がNで割り切れない場合にceilで切り上げした行数にするというちょっとした処理を入れてあります。\n17. 1列目の文字列の異なり pub fn count_uniq_words(input_file_name: \u0026amp;str, col: usize) -\u0026gt; usize { let mut words = HashSet::new(); let buf = BufReader::new(File::open(input_file_name).expect(\u0026#34;file not found\u0026#34;)); buf.lines().for_each(|line| match line { Ok(line_str) =\u0026gt; { let columns: Vec\u0026lt;_\u0026gt; = line_str.split(\u0026#39;\\t\u0026#39;).collect(); words.insert(columns[col].to_string()); } Err(_) =\u0026gt; panic!(\u0026#34;parse error \u0026#34;), }); return words.len(); } HashSetを利用することでユニーク性を担保して、最後はHashSetの数を数え上げれば終了です。\n18. 各行を3コラム目の数値の降順にソート pub fn sort_on_col3(input_file_name: \u0026amp;str) -\u0026gt; String { let mut lines: BTreeSet\u0026lt;Line\u0026gt; = BTreeSet::new(); let buf = BufReader::new(File::open(input_file_name).expect(\u0026#34;file not found\u0026#34;)); buf.lines().for_each(|line| match line { Ok(line_str) =\u0026gt; { let columns: Vec\u0026lt;_\u0026gt; = line_str.split(\u0026#39;\\t\u0026#39;).collect(); let num: u32 = columns[2].parse().expect(\u0026#34;parse error\u0026#34;); let line = Line { line: line_str, num, }; lines.insert(line); } Err(_) =\u0026gt; panic!(\u0026#34;parse error\u0026#34;), }); let mut sorted = String::new(); lines.iter().for_each(|line| { sorted.push_str(format!(\u0026#34;{}\\n\u0026#34;, line.line).as_str()); }); return sorted; } #[derive(Eq)] struct Line { line: String, num: u32, } impl Ord for Line { fn cmp(\u0026amp;self, other: \u0026amp;Self) -\u0026gt; Ordering { let ord = other.num.cmp(\u0026amp;self.num); if let Ordering::Equal = ord { other.line.cmp(\u0026amp;self.line) } else { ord } } } impl PartialOrd for Line { fn partial_cmp(\u0026amp;self, other: \u0026amp;Self) -\u0026gt; Option\u0026lt;Ordering\u0026gt; { Some(self.cmp(other)) } } impl PartialEq for Line { fn eq(\u0026amp;self, other: \u0026amp;Self) -\u0026gt; bool { self.eq(other) } } Lineという、行の文章と第3カラム目の値をもった構造体を作成しました。そこにEq、Ord、PartialOrd、PartialEqを実装し、3カラム目での大小比較できるようにしました。 この構造体をBTeeSetに格納していき、イテレーターで回すことで、ソートされた状態にしてあります。 同一数値の場合は行の降順でソートできるようにOrdを実装してあります。\n19. 各行の1コラム目の文字列の出現頻度を求め,出現頻度の高い順に並べる pub fn sort_on_frequency(input_file_name: \u0026amp;str) -\u0026gt; String { let mut names: HashMap\u0026lt;String, u32\u0026gt; = HashMap::new(); let buf = BufReader::new(File::open(input_file_name).expect(\u0026#34;file not found\u0026#34;)); buf.lines().for_each(|line| match line { Ok(line_str) =\u0026gt; { let columns: Vec\u0026lt;_\u0026gt; = line_str.split(\u0026#39;\\t\u0026#39;).collect(); let name_str = columns[0].to_string(); let count = names.entry(name_str).or_insert(0); *count += 1; } Err(_) =\u0026gt; panic!(\u0026#34;parse error\u0026#34;), }); let mut sorted = String::new(); let mut sorted_names: Vec\u0026lt;(\u0026amp;String, \u0026amp;u32)\u0026gt; = names.iter().collect(); sorted_names.sort_by(|(aname, acount), (bname, bcount)| { let ord = bcount.cmp(acount); if let Ordering::Equal = ord { bname.cmp(aname) } else { ord } }); sorted_names.iter().for_each(|(name, count)| { sorted.push_str(format!(\u0026#34;{} {}\\n\u0026#34;, count, name).as_str()); }); return sorted; } もうすこしうまくできる気がしますが、いったんこれで。 数え上げのためにまずはHashMapに第1カラムの文字列, 個数という組み合わせでデータを入れていきます。 出来上がったHashMapをタプルのベクターに変換し、変換したベクターのsort_byメソッドに比較用の関数を渡すことで個数の降順に並べています。同一個数の場合は文字列の降順になっています。 で、最後に並びかわったベクターのイテレーターを使って出力しておしまいです。 内部的には最悪3回回る感じでしょうか? 最初からベクトルに入れつつソートできる仕組みにするようなのがいいのかなぁ?\nまとめ Unixコマンドの勉強になりましたw あとは、HashMapなどの勉強にもなりました。 最後の方は効率がいまいち良くない気もしてはいますが、とりあえず第3章に進もうかと思います。\n","date":1589253809,"dir":"post/2020/","id":"09155bf417a93847b538ad607f78cca2","lang":"ja","lastmod":1589253809,"permalink":"https://blog.johtani.info/blog/2020/05/12/reboot-nlp100-ch02-12to19/","publishdate":"2020-05-12T12:23:29+09:00","summary":"Rustで言語処理100本ノックの第2章の残りです。 前回はこちら。 ちなみに、標準入力から受け取る処理は書いてないです。 出力に関してはファイル","tags":["Rust","nlp100"],"title":"第2章の12から19まで(言語処理100本ノック2020)"},{"contents":"気づいたら1ヶ月サボってました、ごめんなさい。。。\nRustで言語処理100本ノックの第2章をはじめました。\n前回はこちら。\n確認用のUnixコマンド 確認用のファイルを先に生成して置きました。 これで、Rustでコードを書いて、作成済みの確認ファイルを元にassert_eq!でチェックするという方式を取ろうかと。\nで、コマンド群はこちらです。\nUnix/Linuxコマンド、昔から使っています。が、なにかちょっとした文字列処理やファイル処理をやるときは、Javaのプログラム(最近だとPython)を書くというのが基本になってるので、結構、使ったことの無いコマンドが今回ありました。使ったことがなかったのはこちらです。\nsed tr expand paste cut split sedとかは普通さわってるだろ?って思われそうですね。。。\nで、コマンドをmanで調べつつやりました、macOS上で。 これがまたいくつか罠があったので書き残しておきます(自分が知らないだけかもしれないので、おかしいところがあったらツッコミお願いします。)。\nsedコマンドでのタブの扱い ## sed command for macOS. If using Linux, use \u0026#34;\\t\u0026#34; for tab character cat $INPUT_FILE_NAME | sed -e \u0026#39;s/\t/ /g\u0026#39; \u0026gt; $OUTPUT_DIR/11_sed.txt \\tで行けると思ったのですが、うまく動きませんでした。\u0026lt;tab\u0026gt;みたいな書き方もあると思うのですが、これも駄目で、結局タブ文字をそのまま打ち込みました。。。 これ、めんどくさくないですか??? ちなみに、ターミナルで動作確認して、GitHubにあげてあるシェルファイルにコピペしてたのですが、CLionに貼り付けたらタブ文字がスペースに変換されてしまってて20分くらい悩みました。。。\nsplitコマンドに-nオプションがない LINES=`cat $OUTPUT_DIR/10.txt` SPLIT_LINES=`echo $LINES/$N | bc` split -a 1 -l $SPLIT_LINES $INPUT_FILE_NAME $OUTPUT_DIR/16_ splitコマンドについてググると、-nで指定した数のファイルに分割できるという記事がいくつも出てくるのですが、man splitをターミナル上でやるとそんなオプションがないと。。。 macOSがBSD系だからっぽいです。 ということで、行数を元に、指定した数(N)で行数を割ってから、指定行数ごとにファイルを分割する方式にしました。\nこれらのコマンドの違いはHomebrewとかでインストールするとなくなるのかなぁ?(めんどくさいので確認してないですが。。。)\nってことで、2章のそれぞれの課題の正解ファイルの生成はこれでできたはずです。\n10. 行数のカウント wc -lですね。\n// ch02-10 行数のカウント pub fn word_count(file_name: \u0026amp;str) -\u0026gt; usize { let f = File::open(file_name).expect(\u0026#34;file not found\u0026#34;); let buf = BufReader::new(f); return buf.lines().count(); } ファイルを読み込んで行数を数えます。 文字列として読み込んで改行コードの数を数えるというのもありかな?と思いましたが、RustのBufReaderにlines()という行のイテレータ?が取れることがわかったので、それでカウントを取りました。\n11. タブをスペースに置換 // ch02-11 タブをスペースに置換 pub fn tab_2_space(file_name: \u0026amp;str) -\u0026gt; String { let mut f = File::open(file_name).expect(\u0026#34;file not found\u0026#34;); let mut contents= String::new(); f.read_to_string(\u0026amp;mut contents).expect(\u0026#34;read error\u0026#34;); return contents.replace(\u0026#34;\\t\u0026#34;, \u0026#34; \u0026#34;); } こっちはファイル全体を文字列に読み込んでしまってから、文字列のreplaceで置換するという方式です。 ファイルが大きい場合にこれでいいのか?という問題がある気がしますが、まずはこの実装にしました。 やるとしたら、readメソッドとbufferを用意して、少しずつ読みながら、置換して吐き出す感じでしょうか? ちゃんとした文字コードの区切りで取れるかどうかを気にしないと行けないと思うので、思ったよりはめんどくさくなりそう。\nBufReaderをつかってread_lineのほうがましかも?\nまとめ ということで、サボっていたのを再開しました。 Rustのコードを書く前に、Unixコマンドの処理に結構悩みましたw\nRustのコードとしてはファイル処理なので、今後も役立つ気がしてます。 ということで、頑張っていくぞと。\n","date":1588948640,"dir":"post/2020/","id":"c098c6f0901979bd914ed7a345200f90","lang":"ja","lastmod":1588948640,"permalink":"https://blog.johtani.info/blog/2020/05/08/rebootnlp100-ch02-10to11/","publishdate":"2020-05-08T23:37:20+09:00","summary":"気づいたら1ヶ月サボってました、ごめんなさい。。。 Rustで言語処理100本ノックの第2章をはじめました。 前回はこちら。 確認用のUnixコマ","tags":["Rust","nlp100"],"title":"第2章の10から11まで(言語処理100本ノック2020)"},{"contents":"Rustで言語処理100本ノックのリファクタリングの続き。\n前回はこちら。\nとっくに終わってたのに、ブログ書いてなかった。。。\n08. 暗号文 pub fn cipher(text: \u0026amp;str) -\u0026gt; String { return String::from_iter(text.chars().map(|x| { if x.is_ascii_alphanumeric() \u0026amp;\u0026amp; x.is_lowercase() { let mut b = [0; 4]; x.encode_utf8(\u0026amp;mut b); b[0] = 219 - b[0]; char::from(b[0]) } else { x } })); } Rustの文字列はUTF-8でエンコードされたテキストを保持しているので、文字コード自体は意識していないです。 chars()でUnicodeスカラー値のイテレータが返ってくるので、1文字ずつ扱えるようになります。\nただ、1文字をバイトとして扱うのに手こずりました。 encode_utf8というメソッドを利用して1バイトだけ取り出して、計算するというのをやっています。 文字種の判別のメソッドが用意されているのは便利ですね。\nなんかもうちょっとスマートにできないのかな?と思いつつ動いたのでこれになってます。\n09. Typoglycemia pub fn typoglycemia(text: \u0026amp;str) -\u0026gt; String { return text .split_whitespace() .map(|word| { if word.len() \u0026lt;= 4 { word.to_string() } else { let original = word.chars().collect::\u0026lt;Vec\u0026lt;char\u0026gt;\u0026gt;(); let first = original.get(0).unwrap(); let last = original.last().unwrap(); let mut typo = original[1..original.len() - 1] .iter() .map(|x| x.clone()) .collect::\u0026lt;Vec\u0026lt;char\u0026gt;\u0026gt;(); let mut rng = thread_rng(); typo.shuffle(\u0026amp;mut rng); let mut typo = String::from_iter(typo.iter()); typo.insert(0, first.clone()); typo.push(last.clone()); typo } }) .collect::\u0026lt;Vec\u0026lt;String\u0026gt;\u0026gt;() .join(\u0026#34; \u0026#34;); } 一応、1行で記述できたかな? まずは、スペースで単語ごとに区切った後に、word(単語)の長さによって、処理を分岐し、単語が5文字以上の場合にランダムに並び替えを行うというのをやっています。 文字単位で処理を行うために、chars()で1文字ずつ取り出しています。 最初と最後の文字だけはそのままに、間の文字をランダムにシャッフルするというのをやるのに、もとのwordのスライスからコピーした文字列を作り出してから組み立て直すということをやっています。\nコピーしないでゴニョゴニョする方法ってあるのかなぁ? 思いつかなかったので、結構泥臭い感じの実装になってしまいました。\nまとめ めんどくさいので、コードをGitHubのソースコードからではなく、ブログにコードスニペットとしてコピペしました。Hugoでいい感じにGitHubのコードスニペット表示するのないかなぁ?\nということで、2年越しで1章が終了しました。 2章もやらないとなぁ。\n","date":1588923657,"dir":"post/2020/","id":"2c3270f8797ace2fb37402ea6a09d126","lang":"ja","lastmod":1588923657,"permalink":"https://blog.johtani.info/blog/2020/05/08/reboot-nlp100-finish-ch01/","publishdate":"2020-05-08T16:40:57+09:00","summary":"Rustで言語処理100本ノックのリファクタリングの続き。 前回はこちら。 とっくに終わってたのに、ブログ書いてなかった。。。 08. 暗号文 pub fn cipher(text: \u0026amp;str) -\u0026gt;","tags":["Rust","nlp100"],"title":"第1章の08から09まで(言語処理100本ノック2020)"},{"contents":"前回はWorkplace Searchの概要について書きましたが、今回はインストールと構成要素について説明します。なお、2020/5/7時点での情報を元に本記事は書いていますのでご注意ください。基本的にはインストールと起動方法についての手順を元に書いています。所々に考察を挟んだ形の記事になっていますので、気になるところだけ呼んでいただければと。\n記事一覧 ElasticのWorkplace Searchを触ってみる - その1 インストール インストール方法は公式リファレンスもしくはダウンロードページに記載があります。 現時点ではMacもしくはLinuxが対象でWindowsはまだサポート対象外となっています。\n必要なもの インストールに必要なものは以下になります。\nElasticsearch 7.6.x + Platinum license Elastic CloudのElasticsearch Service もしくは ダウンロードしてローカルで起動 enterprise-search-7.6.0.tar.gz ダウンロードページはこちら Java 8もしくは11 Long Term Supportの対象であるJavaです。2020/5/7時点では8か11 今回はローカルにElasticsearchの7.6.2をインストールしてから試してみます。30日間のトライアルライセンスが有効になっているので、Platinumの機能を試すことができます。\nJavaの8か11が必要になります。Elasticsearchには7.xからJDKが同梱されるようになりましたが、Workplace SearchがJettyを元に動作しているからです(enterprise-search-7.6.0.tar.gzにjettyというフォルダあり)。\nインストール手順 大まかには以下の3つです。\nJava 8もしくは11のインストール 14でも大丈夫でした(ローカルにはSDKMANでインストールした14.0.1が利用された)。 Elasticsearchのインストール(Elastic Cloudの場合はクラスタの起動) 今回はローカルにインストール Workplace Searchのインストール Javaはもともとインストールされていたので、今回は2と3をインストールしました。どちらもローカルで起動するので、2つをダウンロードしてtar.gzファイルを展開するだけになります。\n起動方法と設定 起動方法に起動前の設定の手順も記載があります。 設定しながら起動していきます。\nElasticsearchの起動 既存のElasticsearchのクラスターがあり、Platinumのライセンスが有効になっている場合はこの手順は必要ありません。\nElasticsearchの設定ファイルでSecurity機能をオンに 7.1から基本的なセキュリティ機能はベーシックの機能に含まれています。 Elasticsearchを起動 まずは起動(パスワードなどを設定するために必要) Elasticsearchのパスワードの設定 Elasticsearchでデフォルトで用意されているユーザーのパスワードを設定してします。手順では自動で生成させる方法ですが、独自に設定することも可能です。 Workplace Searchの起動 Elasticsearchが起動したらWorkplace Searchの設定をして起動します。\nEsへの接続設定をconfig/enterprise-search.ymlに指定 Esのパスワード設定時に生成されたelasticというユーザーのパスワードをここで指定。 yamlファイルに記載があるが、${ELASTICSEARCH_PASSWORD:changeme}という記述をした場合に環境変数を読み込める allow_es_settings_modification: trueをconfig/enterprise-search.yml ここに記載があるような変更をWorkplace SearchがEsのクラスターに対して実行する模様。Workplace Search以外でも使用しているElasticsearchクラスターの場合はallow_es_settings_modificationを有効にする代わりに、リンク先にあるような設定を自分で追加する。 secret_management.encryption_keysを複数設定 Encryption Keysのガイドに少し詳しい説明がある。 opensslコマンドとかで作ればいいかな?? 1.と同じような設定をしようとしたがうまくいかなかったので、ファイルにキーを設定する方式にしました(バグ?) 起動するときにデフォルトユーザーパスワードを指定 指定しなければ勝手に生成してコンソールに出力してくれるので、そちらの方がいいかと。 今回は手順通りに指定した。 起動確認のためhttp://localhost:3002にアクセス 起動するとログが流れ、問題がなければ次のようにデフォルトユーザーの情報が出力されます。\n######################################################### *** Default user credentials have been setup. These are only printed once, so please ensure they are recorded. *** username: enterprise_search password: pas...ple ######################################################### そして無事起動に成功したことも出力されます。\n######################################################### Success! Elastic Workplace Search is starting successfully. In a few moments, you\u0026#39;ll be able to login at the following address: * URL: http://localhost:3002 * If this is your first time starting Workplace Search, check the console output above for your user authentication credentials. * Visit the documentation: https://swiftype.com/documentation/enterprise-search Secret session key has been generated. Set the key in your config file to persist user sessions through process restarts: secret_session_key: c23...3 ######################################################### ブラウザで画面にアクセスすると、次のような画面が表示されました。\n起動時のエラー いくつかのパターンも試してどんなエラーが出るのかを見てみました。 おまけですね。\nElasticsearchが見つからないエラー Esを起動しないでWorkplace Searchを起動してみました。\n200秒間アクセスしようと試みて駄目だったらエラーで終了みたいです。\n[2020-05-07T03:48:33.645+00:00][13709][2002][app-server][INFO]: Failed to connect to Elasticsearch backend. Make sure it is running. ... [2020-05-07T03:51:54.038+00:00][13709][2002][app-server][INFO]: Could not connect to Elasticsearch backend after 200s. Terminating... [2020-05-07T03:51:54.039+00:00][13709][2002][app-server][ERROR]: -------------------------------------------------------------------------------- Error: Workplace Search is unable to connect to Elasticsearch. Ensure a healthy Elasticsearch cluster is running at http://127.0.0.1:9200 for user elastic. -------------------------------------------------------------------------------- ElasticsearchのSecurityがオフのときのエラー ちなみにSecurityをオフにしたままWorkplace Searchを起動した場合は以下のようなエラーが出ました。\n[2020-05-07T03:46:53.474+00:00][13567][2002][app-server][ERROR]: -------------------------------------------------------------------------------- Elastic Workplace Search requires Elasticsearch security features to be enabled. Please enable Elasticsearch security features as outlined here: https://www.elastic.co/guide/en/workplace-search/current/workplace-search-install.html -------------------------------------------------------------------------------- 構成要素 ここまでインストールして起動してきました。 では、Workplace Searchがどういったコンポーネントから構成されているかを予測してみましょう(あくまで外から見た予想となります。そのうちElastic社のウェビナーとかイベントで内部の発表とかあるかも?)。\nインストールページの記載から インストールページに最小ハードウェアという記載があり、そこで何が動く可能性があるかというのがわかります。\n起動するものはこんな感じみたいです。\nElasticsearch - 外部でもOK App Server - Workplace SearchのWeb機能 Worker - クローラーとかかな? Filebeat - Workplace Searchのログ収集用 その他プロセス - なんだろ? という具合です。\n設定などからの予想 次は設定項目や起動時のログなどからの予想です。\nWorklpace Search配下のセキュアなデータストア - アクセストークンなどの管理のため JRubyアプリケーション - App ServerはJRuby上で動いているRailsアプリ Filebeatも起動している - Workplace Searchのログ収集のため? Filebeatの接続設定はWorkplace Searchの設定値を利用 では構成要素は? ということで、現時点でわかった構成要素は以下のとおりです。\nElasticsearch Workplace Search App Server - Railsアプリ on JRuby Webアプリとは別に(内部?で)、いくつかのワーカーが存在する 管理画面と検索画面の2種類が存在 Filebeat - ログ収集 といった感じです。 まだ起動したばかりなのでこのくらいでしょうか。ログを見るともう少しわかりそうな気がします。\n基本的には、EsをバックエンドにしたRailsのミドルウェアになります。コネクターや検索画面はすべてWorkplace Searchのミドルウェア経由でアクセスする形になりますので、普通に検索で利用するユーザーにはElasticsearchの存在は見えない作りになっています。\n次は? Getting Startedを元に、どんなアクターがいて、どんな機能が提供されているのか、どんな利用方法なのか?というのを見ていこうと思います。\n","date":1588818770,"dir":"post/2020/","id":"44db1f1fefc97cd28d55d443f2bd2b63","lang":"ja","lastmod":1588818770,"permalink":"https://blog.johtani.info/blog/2020/05/07/install-workplace-search/","publishdate":"2020-05-07T11:32:50+09:00","summary":"前回はWorkplace Searchの概要について書きましたが、今回はインストールと構成要素について説明します。なお、2020/5/7時点で","tags":["elasticsearch","workplace search"],"title":"ElasticのWorkplace Searchを触ってみる - その2 - インストールと起動"},{"contents":"2月のElastic社のブログですが、Enterprise Searchとこれまで呼んでいた製品をWorkplace Searchという製品名に変更し、App Searchなどを含む製品群をEnterprise Searchという名前に変更しました(ちょっとややこしい)。 Workplace Search自体はまだβ版という位置づけですが、ダウンロードして試すことが可能です。\nきちんと触ったことがないので、ちょっと触って見ようかなと思い、何回かに分けてブログを書いてみます。まずは概要とかから。\nWorkplace Searchとは? Elasticsearchをバックエンドに利用するElastic社が提供するアプリケーション(ミドルウェア?)の1つです。\nもともとはSwiftypeという会社が作っていた、Site Search、App Searchと同じような系列で開発されている統合検索の検索エンジンミドルウェアという感じです。 製品ページを見るとわかりますが、様々なデータソースから、データをクロールしてElasticsearchに保存することで、統合された検索を提供することができるようになる製品です。 最近は会社のドキュメントがさまざまな場所(Google Drive、Saleseforce、GitHub、Dropboxなど)に保存されています。 それぞれで検索窓などはありますが、1箇所で検索することで横断的に検索でき、仕事の効率があがりますよね?ということで作られている製品です。\n提供(利用)方法は? 今後の提供方法としては、Elastic Cloudで利用できるSaaS形式のものと、独自に(クラウドのコンピューティングエンジンやオンプレのサーバーなどで)Workplace Searchのアプリを起動する方法(オンプレ版)があります。後者の場合は、Elasticsearchのクラスターを用意する必要があります。なお、後者の場合、Elasticsearchのサブスクリプションのプラチナライセンスが必要になるようです(ダウンロードページに記載あり)\nまだ、β版という位置づけなので、今後どのように変更されるかはわかりませんが、今回は2020年5月1日時点でのベータ版(7.6.0)を元にどんなものかを紹介します。現時点で利用できるのはβ版のオンプレ版で、MacやLinuxで利用可能です。\nダウンロードとインストール ダウンロードページにインストール方法などの記載があります。\nインストールして触って見るところはまた後日。\nライセンス、価格は? まだ不明です。SaaS版の提供はまだです。 オンプレ版については少なくとも、Elasticのサブスクリプションのプラチナが必要になります。こちらは、価格は公開されていません。Elastich社もしくはパートナー企業での問い合わせが必要になります。 (たぶん、ドキュメントレベルのセキュリティとかSSOとかの仕組みがプラチナで提供されているのでそのあたりを使っているのでは?と想像してます。)\n想定できそうな用途は? 社内の文書検索でしょうか。ただ、いわゆる昔ながらのエンタープライズサーチと呼ばれている、社内のファイルサーバーなどの文書検索ではなく、クラウドサービスを複数利用している会社が利用する想定になっています。\n例えば、開発者は社内Wiki(Confluence)で社内文書を書き、Issue管理にはJIRAやGitHubを活用しており、ただ、社内での説明にはGoogle Driveを利用しているといった場合です。こういう場合、あの機能についての説明や資料ってどこだっけ?というので、あちこち探し回ったりしないといけないです。また、営業部門やサポート、マーケティングなどが絡んでくると更に、SalesforceやZendeskといったデータソースも出てきます。 情報が散らばっていて、それらを探し出したりまとめるだけで時間を取られている場合などに便利かもしれません。\n次は? 実際にインストールしてから起動して、どんな感じで使えるのかといったところを見て、どんな機能が提供されているのかを見ていこうと思います。\n","date":1588318144,"dir":"post/2020/","id":"4d71d2a23c85fb7af20e8d1e8b3e0de8","lang":"ja","lastmod":1588318144,"permalink":"https://blog.johtani.info/blog/2020/05/01/intro-workplace-search/","publishdate":"2020-05-01T16:29:04+09:00","summary":"2月のElastic社のブログですが、Enterprise Searchとこれまで呼んでいた製品をWorkplace Searchという製品名に","tags":["elasticsearch","workplace search"],"title":"ElasticのWorkplace Searchを触ってみる - その1"},{"contents":"先日、Elasticsearchでのカスタム辞書の利用方法についてブログを書きました。\n辞書の設定方法について記載しましたが、今回は辞書の更新について書いていなかったので、書いてみようと思います。 ここで「辞書」としているのは、Kuromojiのユーザー辞書、Synonym Graph Token FilterのSynonym辞書(いわゆる類義語辞書)のことになります。サードパーティのAnalyzer等に関する話ではありません。\n辞書更新に関する制限事項 辞書の更新について、大原則と制限事項が存在します。\n大原則(辞書の更新=データも更新) ElasticsearchはAnalyzerが切り出した単語を元に転置インデックスを作成して、検索を行っています(この仕組みに関するスライドはこちらを参照のこと)。 Analyzerが辞書を持っている場合、その辞書を元に単語を切り出して転置インデックスに利用します。 また、検索クエリの単語に対してもこのAnalyzerの辞書が利用されます。\n辞書に新しい単語を追加するということは、その単語に関連するドキュメントも更新しないと行けないということになります。\n例えば、Kuromojiを利用していて、「グランベリーパーク」という単語「グランベリー」「パーク」という単語に分割できるような新しい単語として辞書に追加する場合を考えてみましょう。ユーザーが「グランベリー」で検索しても検索結果として出てきてほしいという場合です。\n辞書に「グランベリーパーク」を登録していない頃に登録されたドキュメントは「グランベリーパーク」という1単語として転置インデックスの見出し語を切り出します(Kuromojiはカタカナの連続している文字列については未知語として1単語にし、「名詞-一般」の品詞を付与)。\n更新前でのドキュメントのAnalyze結果\n「グランベリーパーク」「で」「ショッピング」 もし、辞書に「グランベリーパーク」を「グランベリー」「パーク」から構成される新規の単語として登録しそれを使用した場合、辞書を更新したあとから、「グランベリーパーク」という単語がAnalyzerからは出てこなくなります。\n更新後でのドキュメントのAnalyze結果\n「グランベリー」「パーク」「で」「ショッピング」 ということは、辞書更新以前のドキュメントは「グランベリーパーク」という見出し語に対して登録されているので、辞書更新以前に登録されているドキュメントは検索にヒットしなくなります。\nこのように転置インデックスを利用している検索エンジンでは、単語の区切りが変更されるような辞書の更新があった場合、最低でも影響があるドキュメントについては再登録が必要となるわけです。\nこれが大原則(辞書更新=データも更新)となります。 基本的には辞書の更新を行った場合は、ドキュメントの再インデックス(再登録)が必要となります。\nElasticsearchでの制限事項 Elasticsearchでは、辞書の更新に関して実装上の制限事項が存在しています。 内部的な実装として、ElasticsearchではAnalyzerのインスタンス(正確にはAnalyzerのFactoryのインスタンス)の生成がインデックスに関する内部のインスタンスが生成されたタイミングの1回のみとなっています。\nこのインスタンスの生成時に設定ファイル(辞書を含む)を読み込んでいます。\n言い換えると、辞書(ファイル、インデックス設定に関わらず)の読み込みは、インデックスが作られたタイミングのみということになります。 なおここで言う「インデックスが作られたタイミング」というのは、以下の2パターンです。\nインデックス新規作成時 インデックスオープン時 では、ここから辞書を更新してそれを既存のインデックスに適用する方法について説明しましょう。\n辞書の更新方法(ファイル編) 前回のブログで説明しましたが、Elasticsearch 7.4よりも古いバージョンでは、ファイルでKuromojiのユーザー辞書を設定していました。まずはこちらの方法について説明します。前提として、すでにユーザー辞書を設定したKuromoji Tokenizerがインデックスに設定されているものとします(ユーザー辞書の設定方法については公式リファレンスを御覧ください)。\n辞書ファイルに新規にエントリーを追加しただけでは、設定は読み込まれていません。新規辞書を反映させるためには以下の手順が必要となります。\n更新した辞書ファイルの配布 複数ノードでElasticsearchのクラスターを構成している場合はすべてのノードに更新した辞書ファイルを配布する必要があります。 インデックスのクローズ(公式リファレンス) 設定ファイルを再読込させるために一度インデックスをクローズします。 クローズするので、書き込み、検索などの処理を停止する必要があります。もし停止していない場合はクライアント側ではインデックスがクローズされているという旨のエラーを受け取ります(400で、index_closed_exception)。 インデックスのオープン(公式リファレンス) 設定ファイルを読み込みます。これで、新規追加された単語が読み込まれます。 再インデックス _update_by_queryを利用することで、対象のインデックスのデータを再インデックスすることができます。条件無しでAPIを呼び出すとすべてのデータが再度登録されます。 _sourceがfalseの場合は_update_by_queryは利用できません。元データをもう一度外部からElasticsearchに対して登録する必要があります。 Kibanaでの手順をGistにしてあります。手順はこちらをご覧ください。\n辞書の更新方法(インデックス設定編) ファイルの場合とは少し手順が異なります。 インデックスの設定としてユーザー辞書を登録しているため、ファイルをElasticsearchのクラスターにあるノードに配布する必要がありません。 また、辞書の設定はインデックスの設定に指定してありますが、こちらは動的に設定変更できる項目ではないため、インデックスを先にクローズする必要があります。\nインデックスのクローズ(公式リファレンス) 辞書の設定を更新するにはインデックスをクローズする必要があります。辞書の設定は動的に更新できる項目にはなっていないためです。 オープンしているインデックスで更新しようとした場合はillegal_argument_exceptionでCan't update non dynamic settings...というメッセージが返ってきます。 辞書の更新(公式リファレンス:インデックス設定の更新) user_dictionary_rulesに単語と追加します。 インデックスのオープン(公式リファレンス) 設定ファイルを読み込みます。これで、新規追加された単語が読み込まれます。 再インデックス _update_by_queryを利用することで、対象のインデックスのデータを再インデックスすることができます。条件無しでAPIを呼び出すとすべてのデータが再度登録されます。 _sourceがfalseの場合は_update_by_queryは利用できません。元データをもう一度外部からElasticsearchに対して登録する必要があります。 Kibanaでの手順をGistにしてあります。手順はこちらをご覧ください。\n第3の方法(新規インデックス作成) ここまで、インデックスのクローズ、オープンで既存のインデックスに対して辞書を更新する方法について説明しました。 ただ、残念なことにAmazon Elasticsearch ServiceではElasticsearchが提供しているすべてのAPIが利用できるわけではありません(Amazon ESの利用可能なAPIの一覧はこちら)。 (_closeは駄目だけど_openは呼べるのかな???)\nということで、新規にインデックスを作成して、新しい辞書の設定を反映したインデックスを用意し、そこにデータをコピーもしくは登録するという方法になります(Amazon ESのカスタム辞書のドキュメントに手順がありますね)。\n手順としては以下のとおりです。\n辞書の更新(用意) 新しい単語などを登録した辞書を用意します。 ファイル、インデックス設定どちらでもOKです。 ファイルの場合は、既存のファイル名とは異なるファイル名にしたほうが混乱がなくなります。 新規インデックス作成 1.で作成した辞書を元に新規インデックスを作成します。 新規インデックスにデータコピー _reindex APIを利用するとデータコピーが簡単です。sourceとdestを指定するだけです。 _sourceがfalseの場合は_update_by_queryは利用できません。元データをもう一度外部からElasticsearchに対して登録する必要があります。 アプリケーション側で新規インデックスを利用するように変更 _aliasを使用しておくと切り替えが簡単です(公式リファレンスはこのあたり)。 考慮すべき点としては、サービスを提供しながら行う場合は、3.の_reindexを実行し始めたタイミング以降の登録・更新データの扱いについてでしょうか。\nまとめ 辞書の更新に関する大原則、制限事項、手順などについて説明しました。 辞書の変更は検索に大きく影響がでます。そのあたりをきちんと考慮しながら更新しましょう。 ユーザー辞書、カスタム辞書を扱う際の参考にしていただければと。 他にもユーザー辞書で気をつけないといけないこともありますが、今日はこのあたりで。\n","date":1587951855,"dir":"post/2020/","id":"be2c49ea5816e7daa6d3b3ff45353291","lang":"ja","lastmod":1587951855,"permalink":"https://blog.johtani.info/blog/2020/04/27/note-updating-dictionary/","publishdate":"2020-04-27T10:44:15+09:00","summary":"先日、Elasticsearchでのカスタム辞書の利用方法についてブログを書きました。 辞書の設定方法について記載しましたが、今回は辞書の更新","tags":["elasticsearch"],"title":"辞書の更新についての注意点"},{"contents":"Elasticsearchで日本語を扱うときに、カスタム辞書を使いたいという要望がよくあります。 AWSのElasticsearch Serviceでカスタム辞書ファイルを読み込める機能が発表されたようです。\n実は、Elasticsearchの7.4からファイルを使用しなくても日本語のTokenizerでカスタム辞書を利用することができるようになっています。\nカスタム辞書をインデックスの設定で指定 やり方はドキュメントに記載があります。\nトークナイザーの設定をインデックスの設定に記述しますが、このときに user_dictionary_rulesという設定を利用することでカスタム辞書を指定できます。\nPUT custom_dic_sample { \u0026#34;settings\u0026#34;: { \u0026#34;index\u0026#34;: { \u0026#34;analysis\u0026#34;: { \u0026#34;tokenizer\u0026#34;: { \u0026#34;kuromoji_user_dict\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;kuromoji_tokenizer\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;extended\u0026#34;, \u0026#34;user_dictionary_rules\u0026#34;: [ \u0026#34;グランベリーパーク,グランベリー パーク,グランベリー パーク,カスタム名詞\u0026#34;, \u0026#34;高輪ゲートウェイ,高輪 ゲートウェイ,タカナワ ゲートウェイ,カスタム名詞\u0026#34;] } }, \u0026#34;analyzer\u0026#34;: { \u0026#34;my_analyzer\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;custom\u0026#34;, \u0026#34;tokenizer\u0026#34;: \u0026#34;kuromoji_user_dict\u0026#34; } } } } } } 辞書の内部は\u0026quot;単語,出てきてほしい単語列(スペース区切り),読みの単語列(スペース区切り),品詞名\u0026quot;になります。配列で設定可能で、複数の単語を登録したい場合は、カンマ区切りで登録していきます(上記例では2つの単語を登録しています)。\n_analyzeを利用して設定の確認 実際に上記の設定がうまく動作するかは_analyzeのエンドポイントを利用します。\nGET custom_dic_sample/_analyze { \u0026#34;text\u0026#34;: \u0026#34;グランベリーパークがオープンしました。\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;my_analyzer\u0026#34; } 出力は以下のようになります。\n{ \u0026#34;tokens\u0026#34; : [ { \u0026#34;token\u0026#34; : \u0026#34;グランベリー\u0026#34;, \u0026#34;start_offset\u0026#34; : 0, \u0026#34;end_offset\u0026#34; : 6, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 0 }, { \u0026#34;token\u0026#34; : \u0026#34;パーク\u0026#34;, \u0026#34;start_offset\u0026#34; : 6, \u0026#34;end_offset\u0026#34; : 9, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 1 }, { \u0026#34;token\u0026#34; : \u0026#34;が\u0026#34;, \u0026#34;start_offset\u0026#34; : 9, \u0026#34;end_offset\u0026#34; : 10, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 2 }, { \u0026#34;token\u0026#34; : \u0026#34;オープン\u0026#34;, \u0026#34;start_offset\u0026#34; : 10, \u0026#34;end_offset\u0026#34; : 14, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 3 }, ...(省略) ] } ちなみに、デフォルトのkuromojiを利用した場合は、グランベリーパークが1単語として出力されます。\nGET _analyze { \u0026#34;text\u0026#34;: \u0026#34;グランベリーパークがオープンしました。\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;kuromoji\u0026#34; } ## レスポンス { \u0026#34;tokens\u0026#34; : [ { \u0026#34;token\u0026#34; : \u0026#34;グランベリーパーク\u0026#34;, \u0026#34;start_offset\u0026#34; : 0, \u0026#34;end_offset\u0026#34; : 9, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 0 }, { \u0026#34;token\u0026#34; : \u0026#34;オープン\u0026#34;, \u0026#34;start_offset\u0026#34; : 10, \u0026#34;end_offset\u0026#34; : 14, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 2 } ] } これで、カスタム辞書を使用することでグランベリーで検索された場合に、グランベリーパークもヒットするという仕組みです。\n_analyzeはexplainというパラメータも持っており、こちらを利用することで、単語の品詞情報なども取得できます。これを使うことで、実際に設定がきちんと動作しているかの確認に利用できます。\nGET custom_dic_sample/_analyze { \u0026#34;text\u0026#34;: \u0026#34;グランベリーパークがオープンしました。\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;my_analyzer\u0026#34;, \u0026#34;explain\u0026#34;: true } ## レスポンス(一部のみ) { \u0026#34;detail\u0026#34; : { \u0026#34;custom_analyzer\u0026#34; : true, \u0026#34;charfilters\u0026#34; : [ ], \u0026#34;tokenizer\u0026#34; : { \u0026#34;name\u0026#34; : \u0026#34;kuromoji_user_dict\u0026#34;, \u0026#34;tokens\u0026#34; : [ { \u0026#34;token\u0026#34; : \u0026#34;グランベリー\u0026#34;, \u0026#34;start_offset\u0026#34; : 0, \u0026#34;end_offset\u0026#34; : 6, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 0, \u0026#34;baseForm\u0026#34; : null, \u0026#34;bytes\u0026#34; : \u0026#34;[e3 82 b0 e3 83 a9 e3 83 b3 e3 83 99 e3 83 aa e3 83 bc]\u0026#34;, \u0026#34;inflectionForm\u0026#34; : null, \u0026#34;inflectionForm (en)\u0026#34; : null, \u0026#34;inflectionType\u0026#34; : null, \u0026#34;inflectionType (en)\u0026#34; : null, \u0026#34;partOfSpeech\u0026#34; : \u0026#34;カスタム名詞\u0026#34;, \u0026#34;partOfSpeech (en)\u0026#34; : null, \u0026#34;positionLength\u0026#34; : 1, \u0026#34;pronunciation\u0026#34; : null, \u0026#34;pronunciation (en)\u0026#34; : null, \u0026#34;reading\u0026#34; : \u0026#34;グランベリー\u0026#34;, \u0026#34;reading (en)\u0026#34; : \u0026#34;guramberi\u0026#34;, \u0026#34;termFrequency\u0026#34; : 1 }, { partOfSpeechにカスタム辞書で設定したカスタム名詞が出力されていますね。 _analyzeのAPIはこのように、アナライザーの挙動の確認に非常に便利なので是非活用してみてください。\nKibanaでこのAPIを使うためのプラグインも開発していますので、こちらも合わせて利用してみてください。\n注意点 ちなみに、user_dictionaryとuser_dictionary_rulesを両方指定した場合はエラーとなります。 ファイルをベースにしつつ、追加の設定をするという使い方はできないので、注意しましょう。\nインデックスの設定で書くことにより、バックアップ・リストアは楽になるかな。ただ、クラスターステートに取り込まれるから、あまりにも巨大なカスタム辞書だと心配かなぁ。ファイルの場合はクラスターステートには取り込まれないので、そこは圧迫しない。\n\u0026mdash; Jun Ohtani (@johtani) April 22, 2020 それ以外の注意点については、別途ブログを書きました。 「辞書の更新についての注意点」、こちらも合わせてご覧ください。\nまとめ カスタム辞書をファイルではなくインデックスの設定値として設定する方法を紹介しました。こちらは、Elasticsearch 7.4で導入された機能になります。7.4以降を利用している場合はこちらを利用することも検討してはいかがでしょうか? また、_analyze APIも便利なので合わせて活用してみてください。\n","date":1587519056,"dir":"post/2020/","id":"15357b6978e83daa2d97692c861dc177","lang":"ja","lastmod":1587519056,"permalink":"https://blog.johtani.info/blog/2020/04/22/custom-dictionary-after-7-4/","publishdate":"2020-04-22T10:30:56+09:00","summary":"Elasticsearchで日本語を扱うときに、カスタム辞書を使いたいという要望がよくあります。 AWSのElasticsearch Servi","tags":["elasticsearch"],"title":"Kuromojiのカスタム辞書をインデックスの設定で指定"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 第8章 7章はパッケージなので後回しにして、8章に入ります。 8章はコレクションです。\nベクタ型 ベクタは同じ型の値だけ保持可能。 ジェネリクスで型を指定可能 - Vec\u0026lt;i32\u0026gt;とか。 vec!マクロで初期値とか設定すると便利。 ベクタに値を追加するのはpush。もちろん値が変わるので元のベクタにはmutが必要 ベクタのスコープ(ライフサイクル)は要素に対する参照があるのとないので話が変わってくる メモリの確保などの影響で、ベクタ全体に対して借用の規則が矯正されると。 ベクタの値を読むのはいくつか方法あり getメソッドはOptionを返す \u0026amp;v[2]の添字記法の場合はパニックの可能性あり 走査(唐突に参照外しが出てきた) 単純に値を取り出す場合はfor - in \u0026amp;v Enumをベクタにいれることで、異なる型も保持可能(まぁ、Enumの型では固定されるけど)。 これだけのためにEnumを使うことってあるのかな? トレイとオブジェクトに関する文章はちょっとわかりにくい。。。 説明以外のメソッドなどについてはAPIドキュメント見ましょうと(リンクも張ってくれてると嬉しいなぁと思ったり。まぁ、バージョンとかの絡みがあるから難しいか)。\n文字列型 文字列はUTF-8でエンコードされた文字を扱うための型。\nstrは文字列データへの参照。\nString型は言語のコアではなく、標準ライブラリに入っている文字列型。\n他にもあるのか。。。OsStringとか。。。 文字リテラルはDisplayトレイトを実装していると。\n.to_string() = String::from\nStringはコレクションだから追加とかが可能なのか、なるほど。\npush_strとpush\n+演算子での参照。\n\u0026amp;Stringは\u0026amp;strに型強制(キャスト?)してくれる。してくれる場合としてくれない場合もあるのかな?s2の所有権は奪わない形で扱うのでs2はこのあとも使えていると。 ここでは、s1を変更したあとに所有権がs3に持っていかれてる? format!を使うとどの所有権も奪わないので、これを使うほうが考え方は簡単そう。ただし、効率がいいかはわからん。 添字記法でのアクセスをStringは許容していない\n文字の境界が必ずしも1バイトとは限らないから。 スライスも同様。 基本的には.chars()で文字としてアクセスするのが良い。\n逆にバイト表現を得る方法はどうするんだろう?\nNLP100本ノックではencode_utf8メソッド使ったけど。 ハッシュマップ いろんな呼び方あるよね。Rustではハッシュマップだよ。 ハッシュマップはuseしないと使えない キーは1つの型、値も1つの型 タプルのベクタからcollectで生成。なるほど。 タプルのベクタだと、タプルの中身は同じものであることが言える? -\u0026gt; 言える。エレメント数が異なるとコンパイルエラーになった 所有権周りの話。 これ、ベクタのときに話してほしい感じがした。 値を渡すか参照を渡すかによって話が変わってくる。詳しくは10章 このあたりが自分が混乱していた元だ。 entryとinsertの違い entryの戻り値はEntryというenumでor_insertというメソッドがありそれを使うと存在しない場合だけinsertが呼ばれる。 これ便利だ。毎回existあたりで存在チェックしてた気がする。 or_insertは可変参照\u0026amp;mut Vを返す。 これをlet countで束縛するときに、中身が可変かどうかをcountには指定しないのか。。。 まとめ 一応、大学などで習ってた(はず)ですが、 スタックとヒープを意識して考えないといけないなぁというのを何度か意識させられた感じです。\nあと、これはRustに限らずですが、それぞれがどんな関数を持っているか、どんなメソッドを持っているか、どんなマクロが存在するかなどを探すときにみんなどうしてるんだろう? 人に教えてもらっているのか、APIリファレンスを探すのか、そういったところをみんながどういう感じにプログラミング言語を勉強しているか、業務で書いているのかと言うのが気になりました。\n","date":1587028650,"dir":"post/2020/","id":"f488aa62d39194824861a134567cadb8","lang":"ja","lastmod":1587028650,"permalink":"https://blog.johtani.info/blog/2020/04/16/chap8-rust-the-book/","publishdate":"2020-04-16T18:17:30+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 第8章 7章はパ","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第8章"},{"contents":"Rustで言語処理100本ノックのリファクタリングの続き。\n前回はこちら。\nコードも載せたほうが見やすいかなぁ?\n03. 円周率 2年前はこちら。 どちらかというとJavaっぽい書き方かな? 入れ物を用意して、入力を整形して、それからループを回す感じで書いてました。\n今回は1行で収めてみました。 Rustっぽく、returnを省略してみました。 あとは、Iteratorを組み合わせる感じでやってます。 アルファベットの文字数ということで、is_alphabetic()メソッドでfilterしてます。\n04. 元素記号 2年前はこちら。 エラー処理が多いのと、文字の扱いがちょっと\nここまで同様に極力イテレータを利用するという方針でリファクタリングしました。 あとは、エラー処理を除去してます。 正常系だけのテストなのでスッキリさせました。\nこういった、ストリーム系?の書き方の場合にエラー処理をどう入れるかってところはちょっと悩みどころになるんじゃないかなぁ?と思いつつ、イレギュラーなものは後回しで(あとにやるのかなぁ?)\n05. n-gram 2年前はこちら。 これまでと同じく、入れ物を作ってから処理をしてます。\n同じく、極力イテレータを利用する形で実装しました。 いくつか型の変換が必要なので、.map()を呼び出して詰め替えたりしています。\n06. 集合 2年前はこちら。 独自に実装しています。\nせっかく05で文字n-gramの配列を返す処理を実装しているので、 そちらを呼び出して、Setに入れるという処理に書き換えました。 その後の集合に対する処理については特にリファクタリングしてないです。\nまとめ 2年前にやってたところまでは追いつきました。 07は特にリファクタリングする必要がないので、次は08からの予定です。\nリファクタリングしているときになるのは、速度とかでしょうか。 実装の違いでなにか差が出るのかどうかはちょっと気になるところですが、 今回の目的ではないので、目をつぶって進める予定です。\n","date":1586423695,"dir":"post/2020/","id":"9a687babb0f44db51dc389b75bdaa19d","lang":"ja","lastmod":1586423695,"permalink":"https://blog.johtani.info/blog/2020/04/09/reboot-nlp100-ch01-03to05/","publishdate":"2020-04-09T18:14:55+09:00","summary":"Rustで言語処理100本ノックのリファクタリングの続き。 前回はこちら。 コードも載せたほうが見やすいかなぁ? 03. 円周率 2年前はこちら。 どちらか","tags":["Rust","nlp100"],"title":"第1章の03から06まで(言語処理100本ノック2020)"},{"contents":"今回もツイートから。\n言語処理100本ノックの2020年版を公開しました。最近の自然言語処理の研究動向を反映し、深層ニューラルネットワークに関する問題を追加しました。留学生も一緒に取り組めるように多言語化を進め、その第1弾として英訳を部分公開しています(40番以降は順次公開予定)。 https://t.co/52h362PIQQ\n\u0026mdash; Naoaki Okazaki (@chokkanorg) April 6, 2020 言語処理100本ノックが2020年版になったそうです。 そうです、2年前に初めて、準備運動で止まっていたんです!(衝撃的な続かなさ。。。)\nということで、Rust the bookも読んでいることだし、過去のプログラムをチェックしつつ再開しようかなと。 ということで、いくつかリファクタリングしてみました。\nソースはリポジトリを御覧ください。\n00. 文字列の逆順 2年前の実装では、chars()メソッドで取り出したあとに、collect()でVecにしていたのですが、RustのIteratorトレイトにrev()という便利なメソッドが存在していました。\nということで、これを取り出すと、最初の文字列の逆順で文字を取り出すIteratorが取得できます。 あとは、Stringが実装してくれているfrom_iterに渡せば文字列が出来上がります。\n01. 「パタトクカシーー」 ストリーム処理っぽい書き方に変更しました。 2年前はIteratorを取り出して、詰替していましたが、 enumerate()で添字と文字のタプルのイテレータに変換し、 filterで添字が偶数のときだけフィルタリングして、 mapで対象の文字をまとめたイテレータにします。 で、最後はそれを元に文字列を生成することにしました。 iterを使わないでそのままString::from_iterの引数に渡すことも可能ですね。\n02. 「パトカー」+「タクシー」=「パタトクカシーー」 2年前は2つのIteratorをloopで回して頑張って結合してました。 ではなく、zip()を使って、2つのイテレータを組み合わせる方法に替えてみました。 このとき、2つの文字列が違う文字数の場合の処理として、長い方から取り出した文字をあとに結合する処理を追加で記述しました。 ちょっとスマートな感じになりましたかね?\nzipしたあとに出てきたタプルの文字列を結合するのにformat!マクロを使いましたが、他にいい方法有るかなぁ?\nまとめ とりあえず最初の3つをリファクタリングしてみました。 残りもやりつつ、準備運動以降もがんばるぞと。\n","date":1586338425,"dir":"post/2020/","id":"dc9580308938069159c5afc55b2f3b96","lang":"ja","lastmod":1586338425,"permalink":"https://blog.johtani.info/blog/2020/04/08/reboot-nlp10-with-rust/","publishdate":"2020-04-08T18:33:45+09:00","summary":"今回もツイートから。 言語処理100本ノックの2020年版を公開しました。最近の自然言語処理の研究動向を反映し、深層ニューラルネットワークに関","tags":["Rust","nlp100"],"title":"言語処理100本ノック、再び"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 第6章 Enumです。match式に大活躍\nEnumを定義する 列挙型は取りうる値をすべて列挙できる。これが名前の由来 列挙型と列挙子 2連コロン(::)で列挙子を指定可能 列挙子にデータ(構造体も)が格納可能。 標準ライブラリに実装例あり。 疑問:Write(String)とかはタプルの表現になるのかな? と思ったが、タプルでは1つだけの変数を持つものは定義(正確には定義できるが、内部で普通の変数にもどされてるっぽい)できなかった。 メソッド定義も可能 関連関数もできる? -\u0026gt; できる Optionの紹介 Rustにnullはない。代わりにOptionがある Noneを指定する場合に型が必要。Someの場合はすでに値が入るから推測可能なため。 match制御フロー演算子 アーム -\u0026gt; matchしたときの処理のこと 短い場合は波括弧は不要 returnなしでmatchが書いてあるだけだと、慣れない場合に値を返していることに気づかないかも(実際気づけてないかも) Enumが値を持っているときに、値の束縛がmatch式で可能 すべての列挙子を網羅していないことをコンパイラが検知してくれるのはすごく助かる。 ただし、_を利用していなければだけど if letで簡潔な制御フロー enumで1つのパターンのときに処理をしたい場合に使えるmatchの糖衣構文 elseもかけるよ。 まとめ enumに慣れていないので、値や構造体を持つenumを利用するという想像ができないことがありそうだなぁと読みながら思いました。 それになれると、色々とプログラムがシンプルに書ける部分が多くなりそうかな。\n","date":1586255231,"dir":"post/2020/","id":"4fbdc9c57a37781dc5dd86f470c61d04","lang":"ja","lastmod":1586255231,"permalink":"https://blog.johtani.info/blog/2020/04/07/chap6-rust-the-book/","publishdate":"2020-04-07T19:27:11+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 第6章 Enumです。matc","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第6章"},{"contents":"Kuromoji-CLIの使い方などについては過去のブログを御覧ください。\nKuromojiのCLIコマンドとpicocliとGraalVM GitHubリポジトリ Issueだけ上げていたJSON出力対応をしました。 また、ラティス(後述)の出力対応もしました。\nJSON出力 LinderaがJSON出力に対応してるのでそれを真似しました。 -o jsonで指定していただくと、次のようなJSONが出力されます。\n% echo \u0026#34;春眠暁を覚えず\u0026#34; | build/graal/kuromoji -o json [ { \u0026#34;text\u0026#34;: \u0026#34;春眠\u0026#34;, \u0026#34;detail\u0026#34;: [ \u0026#34;名詞\u0026#34;, \u0026#34;一般\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;春眠\u0026#34;, \u0026#34;シュンミン\u0026#34;, \u0026#34;シュンミン\u0026#34; ] }, { \u0026#34;text\u0026#34;: \u0026#34;暁\u0026#34;, \u0026#34;detail\u0026#34;: [ \u0026#34;名詞\u0026#34;, \u0026#34;一般\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;暁\u0026#34;, \u0026#34;アカツキ\u0026#34;, \u0026#34;アカツキ\u0026#34; ] }, { \u0026#34;text\u0026#34;: \u0026#34;を\u0026#34;, \u0026#34;detail\u0026#34;: [ \u0026#34;助詞\u0026#34;, \u0026#34;格助詞\u0026#34;, \u0026#34;一般\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;を\u0026#34;, \u0026#34;ヲ\u0026#34;, \u0026#34;ヲ\u0026#34; ] }, { \u0026#34;text\u0026#34;: \u0026#34;覚え\u0026#34;, \u0026#34;detail\u0026#34;: [ \u0026#34;動詞\u0026#34;, \u0026#34;自立\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;一段\u0026#34;, \u0026#34;未然形\u0026#34;, \u0026#34;覚える\u0026#34;, \u0026#34;オボエ\u0026#34;, \u0026#34;オボエ\u0026#34; ] }, { \u0026#34;text\u0026#34;: \u0026#34;ず\u0026#34;, \u0026#34;detail\u0026#34;: [ \u0026#34;助動詞\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;特殊・ヌ\u0026#34;, \u0026#34;連用ニ接続\u0026#34;, \u0026#34;ぬ\u0026#34;, \u0026#34;ズ\u0026#34;, \u0026#34;ズ\u0026#34; ] } ] Viterbiラティス出力 Kuromojiが内部でトークンをどのように切り出すかを計算するためのViterbiのラティスです。これをGraphvizというツールのDOTフォーマットのファイルとして出力できるメソッドがデバッグ用ですが、Kuromojiに用意されています。 こちらを呼び出して出力するオプション-v(もしくは--viterbi)を追加しました。 注意点として、このオプションを指定すると、DOTファイルが標準出力に出力され、トークンの結果は標準エラーに出力されます。\necho \u0026#34;春眠暁を覚えず\u0026#34; | build/graal/kuromoji -v \u0026gt; viterbi.dot .dotファイル自体は画像ではないので、Graphvizのdotコマンドにて画像ファイルに変換する必要があります。\ndot -Tpng viterbi.dot -oviterbi.png これで、PNGファイルが出来上がります。出来上がったファイルはこんな感じです。\n画像を見ていただくと、緑色のパスがあるのがわかります。 こちらが、Kuromojiが実際に採用した形態素のリストです。それ以外のパスは不採用だったパスとなります。\nちなみに、macOSで1行で画像表示まで行うにはこんな感じで実行します。 openコマンドでpreviewアプリを指定することで画像が表示できます。 Windowsは。。。わかりません、すみません。\n% echo \u0026#34;春眠暁を覚えず\u0026#34; | build/graal/kuromoji -v -o json | dot -Tpng | open -f -a preview.app まとめ これ以前に複数辞書対応などもしていました。 今回は2つの出力形式を追加してみました。 特にViterbiラティス出力については、内部的にどのようなコスト計算で最終的な結果が出てきているかという理解に役立ちます。想定していない切れ方の場合は、そもそも想定している形態素になっていないか、コスト計算で不採用だったかなどを確認できますので、使ってみると面白いかもです。\n","date":1586143600,"dir":"post/2020/","id":"6fbf7c3d0f4f89e415e89cec28811a94","lang":"ja","lastmod":1586143600,"permalink":"https://blog.johtani.info/blog/2020/04/06/update-kuromoji-cli/","publishdate":"2020-04-06T12:26:40+09:00","summary":"Kuromoji-CLIの使い方などについては過去のブログを御覧ください。 KuromojiのCLIコマンドとpicocliとGraalVM G","tags":["misc"],"title":"KuromojiのCLIコマンドにJSON出力とラティス出力を追加"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた Rust the book - 第4章 第5章 構造体です。勝手知ったるなんとやら?オブジェクト指向的な部分は問題ないかなぁと。\n定義とインスタンス化 structで定義 インスタンスの生成は引数は順不同でOK 構造体のインスタンスを可変にするとフィールドの値も変更可能 特定のフィールドのみ可変にすることは不可能 インスタンス化する関数の最後でreturnなしでインスタンスの返却を暗黙にできる(return書いてほしいな。。。) インスタンス化時にフィールド初期化省略記法が可能(これはちょっと便利?) 構造体更新記法..user1のように、明示的に設定されていない他のフィールドをコピーしてくれる機能あり タプル構造体 タプル構造体!? struct Color(i32, i32, i32); いつ使うんだろう? ユニット様構造体 ユニット様構造体 = フィールドのない構造体。トレイトを実装したいけどインスタンスで持つ値はない場合に利用 ライフタイム 構造体が参照を持つときにライフタイムという話が出てくる。なるほど。 ライフタイム指定子が必要になる -\u0026gt; 10章での話 プログラム例 タプルを引数かぁ。タプルは慣れないので構造体作りそう Debugトレイトと{:?}という書き方 derive(Debug)でデバッグ用のトレイトを自動で実装=継承してくれる {:#?}だとpretty printになる(改行とか入る) この辺の便利なトレイとは付録Cにあるらしい。この辺はやりながら覚えるしかないか。\nメソッド記法 最初の引数は必ずself implは構造体とは別の場所に書く = Javaのクラスとは違う struct Rectangle { width: u32, height: u32, } impl Rectangle { fn area(\u0026amp;self) -\u0026gt; u32 { self.width * self.height } } 参照じゃないselfも使えるらしい。どういうときに使うんだろう? 関連関数 selfなしの関数をimplにかける。Javaのスタティックメソッドみたいな感じ その他 implブロックがあちこちにかける。これはつらいな。。。 2つにわかれたimplブロックに同じメソッドを書いてみたら、CLionのプラグインではエラーを検知してもらえなかった。 cargo buildではきちんとエラーが表示された。 複数のimplブロックが有用になるケースは第10章で見ますが、そこではジェネリック型と、トレイトについて議論します。\n人の構造体に自分のトレイトを適用したりもできる。 実験 スコープとかどうなりそう?って実験もしてみた。\nfn main() { trait Hoge { fn trim(\u0026amp;self); } impl Hoge for String { fn trim(\u0026amp;self) { println!(\u0026#34;hogehoge {}\u0026#34;, \u0026amp;self); } } let c = String::from(\u0026#34;hoge\u0026#34;); c.trim(); println!(\u0026#34;{}\u0026#34;, fuga(\u0026amp;c)); } fn fuga(d: \u0026amp;String) -\u0026gt; \u0026amp;str { d.trim() } 出力はこんな感じ\nhogehoge hoge hoge まとめ 気になったのは以下の点。そのうち分かるようになってくるのかな。\n構造体更新記法はどういったときに使うのを想定して作ったんだろう?とか 可変長引数はマクロじゃないとだめ ","date":1585807758,"dir":"post/2020/","id":"8d9c3760395e8e0eb40e335b22750b68","lang":"ja","lastmod":1585807758,"permalink":"https://blog.johtani.info/blog/2020/04/02/chap5-rust-the-book/","publishdate":"2020-04-02T15:09:18+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた Rust the book - 第4章 第5章 構造体です。勝手知ったるなんとやら?","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第5章"},{"contents":"すもけさんが在宅勤務環境をブログに書いてておもしろそうだな(あと、アフィリンク貼れるな)と思ったので自分の環境も書いてみようかなと。\n私自身は昨今の新型コロナウイルスの影響というのではなく、もう10年以上自宅でも作業ができる環境を整えています。 前前職の頃から家でも仕事をすることがよくあったので。今は、お客さんに恵まれていてリモートができる形で働かせていただいてます。\n机周りはこんな感じです。机はこれも15年以上前から使用しているエレクターの机です。椅子も15年以上前から使っているアーロンチェア(購入時は高いと思ったけど、これだけ使えているので大満足)です。\nメインのPCはMac Book Pro16インチを使っています。それとは別にMac miniがMac bookの後ろに隠れています。こっちはブラウジングや音楽を聞いたりするために使っています。\nまずはディスプレイ周りから。\nディスプレイ周り ディスプレイ Acerの31インチディスプレイです。昨年の夏に購入しました。28インチの4Kディスプレイを探していたのですが、セールか何かで2-3000円の違いでこのサイズが買えたので、このサイズになっちゃいました。Mac Book ProはDisplay port-USB-Cケーブルで接続し、PS4をHDMIで接続しています。 【Amazon.co.jp 限定】Acer モニター ディスプレイ ET322QKwmiipx 31.5インチ マイクの左側に写っているのはAppleのサンダーボルトディスプレイです。縦にしてブラウザやミュージックプレイヤーなどで音楽かけながら仕事をしています。 サブディスプレイって感じです。 Mac Book ProとMac miniの両方を操作するのですが、できれば同じキーボード+トラックパッドがいいなということで、Synergyというソフトを使って、Mac Book Proのキーボードとマウスでネットワーク越しにMac miniを操作しています。ただ、マシンの再起動後などにこのソフトが起動していない場合もあるので、Mac Book Proの右側にMac miniのためのトラックパッドがおいてあります。\nディスプレイアーム ディスプレイはそれぞれディスプレイアームを使っています。写真のようにMac Book Proを下に、外部ディスプレイを上にという上下で作業をしています。 16インチの画面だと普通のディスプレイの足だとメインディスプレイにかぶってしまうので、アームに切り替えました。 最初はグリーンハウスの激安を使っていたのですが、31インチのディスプレイだとアームの高さが足りなかったので、2つ目のガススプリング式のアームを追加で購入しました。ガススプリング式なのに5千円しないので、かなりお得感があります。ただ、ディスプレイは基本的に動かさないので、どちらかというとディスプレイの足の部分を効率良く使うことが目的です。\nAmazon | グリーンハウス 液晶ディスプレイアーム 4軸 クランプ式 Amazon | HUANUO PC モニター アーム 液晶ディスプレイ アーム ガススプリング式 サウンド関連 スピーカー 基本、音楽を聞きながら作業をするので、小型だけどしっかりと音がでるスピーカーを買いました。スタイルもいいし気に入ってます。 入力が2系統あるので、31インチディスプレイのヘッドフォン出力とMac miniのからの出力の2つをつないでいます。 仕事中はMac miniで音楽流しつつ、テレカンやゲームのときはメインディスプレイからの音が出る形です。 Amazon | ヤマハ パワードスピーカー NX-50 マイク 前職がDeveloper Advocateということで、インタビューなどに行くこともあるかも?ということで小さめのも運びができるコンデンサマイクを購入してました。結局それほど持ち運びはしてないのですが、値段の割には音がいいんじゃないかな?一応、無指向と単一指向の2種類を切り替えることが可能です。\nAmazon | SAMSON マイク ポータブル USB コンデンサ Go Mic | コンデンサ | 楽器 マイクスタンド マイクはあったのですが、クリップ式でした。PCのディスプレイにクリップしていると、打鍵音を拾ってしまうので、マイクスタンドを最近導入しました。やすかったです。 前まではヘッドフォンのケーブルに付いているマイクで喋っていたのですが、服によってはマイクに擦れてしまい、ノイズが載っていました。 マイクスタンド+スピーカーでもスピーカーの音をマイクが拾わないので、最近はヘッドフォンを使用しないで気楽に話ができるようになっています。 Amazon | Luling Arts マイクスタンド アーム その他 モニタスタンド Mac Book Proの後ろで見えにくいですが、Mac miniが下に入っていて、上にMac mini用のキーボード、スピーカー、Qiの充電パッドが載せてあります。 Mac miniのキーボードをじゃまにならないように置きたいという目的で購入しました。3次元で空間が利用できるので結構重宝してます。 Amazon | サンワサプライ 机上液晶モニタスタンド(D200・黒) MR-LC303BK 充電関連 スマホ充電用にスピーカーの横においてあります。ただ、スイートスポットを探すのがちょっと大変で、時々充電できてないことがあったりします。。。 Amazon | DesertWest Qi 急速充電ワイヤレス充電器 【Qi認証済み/PSEマーク付き】15W USBでの様々な充電用にはMercariさんのカンファレンスでいただいたAnkerの充電器をおいてあります。Mi Band 4、キーボードなどの充電向けです。 Amazon | Anker PowerPort 6(60W 6ポート USB急速充電器) まとめ 簡単ですが作業環境でした。だいたい満足しています。もうちょっと改善したいなと思っているのは次の点です。\nUSB-Cドック?ハブ?みたいなものがほしい 充電ケーブル、マイク、ディスプレイケーブル、有線LANの4つのケーブルがMac Book Proに刺さっており、ポートが全滅です。出先から帰ったときにつなぐのも少し面倒なので、1つか2つのポートでまとめられるといいなぁと思っています。が、ドック系はいい値段するのでまだ置き換わっていない感じです。 スタンディングデスクが気になる 自宅でずっと座っているのはやはり気になるもので。スタンディングデスクにして時々たって作業したいなぁと思うことがあります。ただ、使ったことがないので、どれがいいのかわからず手を出せない状況です。 ウェブカメラいる? Mac Book Proのカメラでオンラインミーティングなどしています。気にするほどのことではないとは思いますが、メインディスプレイを見ながらしゃべると下からカメラで撮影されている形になります。。。 今のところはこんな形です。なにかの参考になればと。 あと、なにかおすすめのもの(特にスタンディングデスク)があれば教えて下さい!\n","date":1585217511,"dir":"post/2020/","id":"3f431bf71ee866f626daf42bc915fa3f","lang":"ja","lastmod":1585217511,"permalink":"https://blog.johtani.info/blog/2020/03/26/working-facility/","publishdate":"2020-03-26T19:11:51+09:00","summary":"すもけさんが在宅勤務環境をブログに書いてておもしろそうだな(あと、アフィリンク貼れるな)と思ったので自分の環境も書いてみようかなと。 私自身は","tags":["misc"],"title":"自宅の作業環境(2020)"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた 第4章 第4章です。たぶん、これがいちばん大事な概念だと思います、Rustの。 そして、つまみ食いしながらRust書いてましたが、ここがきちんと理解できないまま書いてたってのもあります。。。\n所有権とは? drop関数ってのがあって、明示的に呼ぶことも可能。次のような感じで。2つ目のprintln!はエラーになる。sがもう無いのに借用しようとしてるから。 fn main() { let mut s = String::from(\u0026#34;hello\u0026#34;); s.push_str(\u0026#34;, world!\u0026#34;); println!(\u0026#34;{}\u0026#34;, s); drop(s); println!(\u0026#34;{}\u0026#34;, s); } ムーブ - shallow copyではない。以下の2行目がムーブ。 let s1 = String::from(\u0026#34;hello\u0026#34;); let s2 = s1; println!(\u0026#34;{}, world!\u0026#34;, s1); スタックとヒープの話が絡んでくる。あんまり意識すること無いよなぁ。 スタック = 固定長のデータを入れる場所。ポインタ、数値など ヒープ = 可変長のデータが入る場所。可変の文字列とか。\nクローン - ヒープのデータをコピーすること。 コピー - スタックに収まるデータの場合はクローンが必要なくコピーで事足りる。 CopyトレイととDropトレイとは同居できない。 タプルのコピーはややこしそう 所有権と関数でまた、スタックに入れられるような変数と可変のオブジェクトの違いが出てくる。 takes_ownership(s: String)が参照を受け取れば問題なく、このあとも使える。 戻り値でもムーブが発生 参照と借用 借用 - 関数の引数に参照を取ること 可変な参照\u0026amp;mutは1つ(不変な参照も含めて1つ)しか許さない データの競合を防ぐため。 不変な参照を複数用いるのはOK 実際に変更が実行されるタイミングでエラーと判定される場合もある。 let mut s = String::from(\u0026#34;hello\u0026#34;); { let r1 = \u0026amp;mut s; } // r1はここでスコープを抜けるので、問題なく新しい参照を作ることができる let r2 = \u0026amp;mut s; ダングリング参照はテスト書くときとかにやってるかも。。。 fn dangle() -\u0026gt; \u0026amp;String { // dangleはStringへの参照を返す let s = String::from(\u0026#34;hello\u0026#34;); // sは新しいString \u0026amp;s // String sへの参照を返す } // ここで、sはスコープを抜け、ドロップされる。そのメモリは消される。 // 危険だ スライス型 部分的な参照。開始位置+長さで構成されているっぽい \u0026amp;strの説明がよくわからなかった。 引数としての文字列スライスのテクニックは色々と使いまわせそう。\nまとめ 所有権、これまで特に難しいと思ってたのは、固定長の変数と、可変長の変数の違いを意識してなかったのが原因っぽい。 まぁ、Vecとかがどうなるのかとか、他にもいくつか気になるところはあるので、もうちょっとやらないといけないなと思いました。\n","date":1585210331,"dir":"post/2020/","id":"7fded0345c258eea966c0b5ee1b7c7aa","lang":"ja","lastmod":1585210331,"permalink":"https://blog.johtani.info/blog/2020/03/26/chap4-rust-the-book/","publishdate":"2020-03-26T17:12:11+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた 第4章 第4章です。たぶん、これがいちばん大事な概念だと思","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第4章"},{"contents":"先日、Visual Studio Codeのプラグインを作ってみた(Azure Search Analyze Client)というブログを書きました。 このプラグインを作ってたタイミングで、Elasticの河村さん経由で、Microsoft Open Tech Night #9 w/ ElasticでなにかLTしませんか?という打診がありました。\n仕組み的には似たようなものだし、Elasticsearch用の拡張機能も作れるし、発表のネタにもなるし一石二鳥では?ということで、LTを快諾し、昨日発表してきました。\n資料とか 発表資料やGitHubのリポジトリなどは、以下のとおりです。\n発表資料 : Analyze APIのVS Codeプラグインを作ってみた GitHub Repository : https://github.com/johtani/vs-code-es-analyze-client Visual Studio Code Marketplaceページ 機能 まだ、必要最低限の機能を実装した感じです。\nAnalyze APIのパラメータ入力用のエディタ起動(Elasticsearch Analyze Client: Create Elasticsearch Analyze Request) Esにリクエストを送信して結果の表示 インストールからリクエスト送信して結果が出てくるまでのデモです。\n1点LTのデモのときに話すのを忘れていましたが、.esanalyzeという拡張子のファイルであれば、このプラグインが入力値を見つけ出して、「Analyze text with analyzers」というコマンド送信用のリンクをエディタ画面に表示する機能があります。 ですので、パラメータ入力用のエディタを起動し、値を設定したあとにファイルをhoge.esanalyzeというような名前で保存してもらえれば、後日そのファイルを開くことでリクエストが再送できます。\nAzure Search版との機能の違い 先日のAzure Search向けのクライアントとの違いがいくつかあります。 ElasticsearchのAnalyze APIの方が多機能であるため、プラグインとしても違いがあったほうがいいかなと。\n入力がJSON形式 結果画面に詳細表示切り替えボタンを追加 現時点では対応していませんが、Analyze APIはカスタムのtokenizer、filter、char_filterの設定を入力として受け付けることが可能です。そのときに指定するのはJSON形式でtokenizerなどの設定を記述します。 今後、これらの対応をすることを考えると、入力全体をJSON形式で読み込めるほうがわかりやすいかなということで、入力はJSON形式で入力してもらうことを想定しました。\n結果画面に詳細表示切り替えボタンを追加したのは、2つの理由があります。1つはAzure SearchのAnalyze APIよりもTokenの情報としていくつか他の情報も存在するためです。複数のAnalyzerとの比較をする場合は、単語列だけを比較したいですが、Analyzer個別の詳細情報を見たい場合もあるので、切り替えができたほうがよいかなと。 2つ目の理由はまだ実装していませんが、explainパラメータの出力への対応のためです。 explainパラメータを指定すると、カスタムAnalyzerの場合に、Analyzerの設定にあるchar_filter、tokenizer、token_filterのそれぞれのステップでの単語列の出力が結果として返ってきます。この結果には標準の出力よりもさらに多くのtokenの情報(例えば、kuromojiだと品詞情報、読み、原型など)が追加されてきます。これらの表示を切り替えることができたほうがよいかと。\nこれらは、実はKibanaのプラグインとしてすでに実装済みになっています。 同等の機能は実装できるかなという目論見もあり、そちらに合わせた感じにしてあります。\n今後の対応 現時点では、Analyzer名の指定のみが可能となっています。Kibanaのプラグインと同程度の機能はGitHubのIssueとして登録してみました。\nexplainパラメータ対応 fieldパラメータ対応 custom analyzer対応 その他に、インデックス名やアナライザ名の自動補完みたいな機能があると便利かも?と妄想していたりします(実装が大変かもですが。。。)。Kibanaのプラグインの場合は、Mappingやインデックス名を調べるときに、KibanaのConsoleからチェックすればよかったのですが、このプラグイン単体だとそのあたりの情報の取得に他のツール(Kibanaだったり、REST API Clientだったり)を使わないといけないという問題点はあるかなぁと。\nあとは、結果画面がこのままで本当に見やすいかどうか?なども気になってはいます。\nまとめ まだまだ、作ってみたというレベルのプラグインです。 どのくらいの人に使ってもらえるかもわかりませんが、こんな機能あるといい?など要望があればリクエストいただければと。 Twitterで聞いていただいてもいいですし、GitHubのIssueとして登録していただいても構いません。 そもそもいらないなぁなんて意見でももちろん大歓迎です。フィードバックお待ちしてます!\n","date":1585102205,"dir":"post/2020/","id":"a7f0e85fcad4f5bc5ae5c18c10de4f9e","lang":"ja","lastmod":1585102205,"permalink":"https://blog.johtani.info/blog/2020/03/25/vsc-es-analzye-plugin/","publishdate":"2020-03-25T11:10:05+09:00","summary":"先日、Visual Studio Codeのプラグインを作ってみた(Azure Search Analyze Client)というブログを書きました。 このプラグインを作ってたタイミン","tags":["elasticsearch","visual studio code"],"title":"ElasticsearchのAnalyze APIのVisual Studio Codeのクライアントプラグイン"},{"contents":"自転車本を読み始めましたが、その前にRust the bookを読んだほうが良いかも?と知り合いと話をしていてなったので、先にRust the bookを読み始めてます。 コツコツ読むってのが苦手なので、知り合いと小規模オンライン読書会しながら読むことになりました(基本的になにか書きながら、使い方を調べるので、存在そのものを知らない記述や使用法などがあったりする)。\n日本語版Rust the book Rust the book 基本は日本語版を読んでいます。まずは1章から3章あたり。\n気になった点などを。自分用のメモなので、読みやすさとかは考えてないです(あとで自分が死ぬパターン?)。\n1章 rustfmt便利。\nCLionのRustプラグインでは、保存時にrustfmtするというオプションがある。デフォルトはオフ。\u0026ldquo;Run rustfmt on Save\u0026rdquo; cargoの--binオプション。意識してつけたことなかった=デフォルトだった。\nライブラリにするときは--lib 2章 「変数を値に束縛」という言い回しにまだ慣れない。 「代入」という言い方に慣れているから? ただ、エラーにはassignってあるな。\u0026ldquo;error[E0384]: cannot assign twice to immutable variable x\u0026rdquo; preludeというのがデフォルトで読み込まれる型が存在する場所。 .expect()により、Resultが評価済みになる マクロがまだ慣れない extern crate rand;が最新版だと要らなくなっている。 rand::Rngはgen_rangeのためにuseしている。CLionだとかってにuseを推測して追加してくれた。 matchはswitch文みたいな感じ。けど、defaultが必ず実行されるって感じではないな。 ただし、全て網羅しないと怒られるのが便利。 アームという呼び方が新鮮 単一の式のときは{}が省略できる ブロック{}のときは、終わりにカンマを入力するとrustfmtが除去する(最後の条件かどうかは関係ない)。 シャドーイングは面白い。 よく、hoge_strやhoge_intのような変数を書くので、ありがたい。 ただし、コードを読むときに少し混乱しそう? let ... matchで変数への束縛でmatchが使えるのは便利(これまで知らなかったので、変数宣言して条件つけて束縛する処理書いてた)。 シャドーイング? fn main() { let x = 5; let x = x + 1; let x = x * 2; println!(\u0026#34;The value of x is: {}\u0026#34;, x); } とか\nlet spaces = \u0026#34; \u0026#34;; let spaces = spaces.len(); みたいに、同一変数名を使い回せること。再代入ではない\n3章 constは型注釈が必須 100_000のような記述が便利(Javaもできるって言われてびっくりしたw) タプルの中身を一部だけ書き換え可能。(mutを指定すれば) tup.0 = 20;のような感じで。 配列は固定長でかつ、同一の型のものだけが入る 文末にセミコロンがない場合に四季になるというのはちょっと射にくいので辛いのでは。。。 自分は明示的にreturnを書きたくなる。が、returnだと動かない場合もある。。。 let ... ifのような記述もできる。 (1..4)はRange型 おまけ フィボナッチ数列計算してみろというのがまとめにあったので。こんな感じでいいのかな?\nfn calc_fibonacci(n: usize) -\u0026gt; usize { if n == 0 { return 0; } else if n==1 { return 1; } else { return calc_fibonacci(n-1) + calc_fibonacci(n-2); } } その他 知り合いと読みすすめると、人が不思議に思ったところが、自分が理解が曖昧だったことなどに気づけて便利です。\n","date":1584928642,"dir":"post/2020/","id":"48b5ab9805919736382ffea5a9554c02","lang":"ja","lastmod":1584928642,"permalink":"https://blog.johtani.info/blog/2020/03/23/start-reading-rust-the-book/","publishdate":"2020-03-23T10:57:22+09:00","summary":"自転車本を読み始めましたが、その前にRust the bookを読んだほうが良いかも?と知り合いと話をしていてなったので、先にRust the bookを読","tags":["rust","読書","rust-the-book"],"title":"Rust the Bookを読み始めた"},{"contents":"動機 Azure Cognitive Searchを検索エンジンに使っているお客さんを手伝っています。 そこで、検索の基本的な話をさせていただきました(もともとJJUGナイトセミナーでしゃべる予定だったスライドがベース)。\nで、Elasticsearchなどの転置インデックスを利用している検索エンジンで検索の基本的な動作がどうなっているかを理解するのに、 個人的には一番重要だと思っているのがAnalysis(Analyze)の機能です。 転置インデックスの単語の切り出し方がどうなっているかによって、望んだ単語でうまく検索できているかいないかなどがわかります。\nAzure Cognitive SearchもAnalyze TextというAPIを提供してくれています(内部的にはElasticsearchだし)。 APIはあるのですが、返ってくる結果はJSONです。また、他のAnalyzerの設定との違いなどをみたくなったりもします。 やはり、普段使っているツールなどで簡単にどういう単語が出てくるかがわかるとうれしんじゃないかなぁ?と。\nということで、最初はPythonでちょっとAPI呼び出して、カンマ区切りで出力するものを作ってみたのですが、GUIとかあると便利かなぁという話になりました。 最近、ブログ書いたりするのにVisual Studio Codeを使い始めているので、これなら使いやすいかなと。 ということで、Visual Studio Codeの拡張機能(プラグイン?)としてインストールできるツールを作ってみました。 Azure Cognitive Searchを使っている人向けなので、ニッチなツールですが。。。\n余談 Elastic Stack(Elasticsearch)向けにはKibanaのプラグインでAnalyze APIを可視化するツールを作ってます。 analyze-api-ui-pluginです。Elastic Stack、特にKibanaを必ず利用する方はこちらを使うと便利かもです。\n概要と機能 GitHub リポジトリ Visual Studio Marketplaceのページ Marketplaceに公開しているので、johtaniやAzure Search Analyze Clientなどで検索してもらえれば出てきてインストールができます。\n機能としては、以下の2つです。\nテンプレートから入力値設定用のドキュメントを作成(Untitled-1というドキュメントをエディタに新しく開く) Azure Cognitive SearchのAnalyze Text APIを呼び出して、結果をHTMLのテーブル形式で表示 入力値設定用のドキュメント作成 APIの呼び出しに必要な情報を記入してもらうのに、いくつか案を考えました。\nプラグインの設定に記入してもらう 環境変数とかを読み出す テキストとして保存したファイルを使う 設定や環境変数だと、異なる環境に接続したりするときに、わざわざ設定し直すのがめんどくさいかもと。 で、愛用していたREST API Clientを真似するのが良いかもという結論になり、.analyzeという拡張子のファイルから必要な項目を読み出して、APIを呼び出す形にしてあります。\nCommand Palette(左下の歯車マークもしくは、メニューのViewから開ける)からAzure Search Analyze Client: Create Azure Search Analyze Requestというコマンドを選びます。\nすると、以下のようなファイルがエディタに開きます。\nこれらの項目をまずは埋めていきます。 それぞれの値がどういったものかはGitHubのREADMEを御覧ください。\n入力値エラー(存在チェックしかしていない)がある場合は、ダイアログが表示されます。\n結果表示 値を入力したら、設定値と###の間に表示されているAnalyze text with analyzersというグレーの文字をクリックします。すると、APIにリクエストを送信し、結果が返ってきて、別のパネルとして表示されます。\n複数のAnalyzerを入力値に設定すると、それぞれがどのような区切り方をするかがわかります。 文字の下にある[0:2]は、その単語がもとの文章の何文字目から何文字目までに出現しているかというオフセットの表示になります。\nもし、Analyzer名の設定ミスなどで指定されたAnalyzerがない場合は、結果画面にエラーが表示されるようにしています。\n以上が簡単な機能の説明です。 簡単なと言いつつ、これだけしか機能がありませんが。\nVisual Studio Codeのプラグインの作り方 プラグイン自体の作り方に関してはVisual Studio CodeのGetting Startedがわかりやすかったです。 APIや機能が豊富なので、最初はちょっと戸惑いましたが、サンプルもGitHubで多数公開されています。\nあとは、REST API Clientを参考にさせていただきました。\nGetting Startedを一通り読むことで、なんとなくプラグインの作成からMarketplaceへのリリースまでが完了できました。 (TypeScriptに慣れていないのがあるので、プログラミング自体は手間取りましたが。。。)\n今後の対応? いまのところ、こんなところを考えていますが、こんな機能がほしい、バグが有るなどあれば、GitHubにIssueを上げていただければと(使う人すくないだろうけど)。\nいろいろなエラーに関する対応 Readmeに画像をアップ アイコン作成? 自動補完機能? まとめ Visual Studio Codeの拡張機能を作ってみました。 Yeomanによるプロジェクトテンプレートが用意されているので、とりあえず、Hello worldを作るのは簡単でした。 試行錯誤しつつTypeScriptを書いたので、TypeScriptっぽくないところなどもあるかもですが、誰かの役に立つツールになってくれれば良いなぁと。\n","date":1584582615,"dir":"post/2020/","id":"c9d257aba54475c20b3737ce7c779e55","lang":"ja","lastmod":1584582615,"permalink":"https://blog.johtani.info/blog/2020/03/19/azure-search-analyze-plugin/","publishdate":"2020-03-19T10:50:15+09:00","summary":"動機 Azure Cognitive Searchを検索エンジンに使っているお客さんを手伝っています。 そこで、検索の基本的な話をさせていただきました(もともとJJUGナイ","tags":["azure search","visual studio code"],"title":"Visual Studio Codeのプラグインを作ってみた(Azure Search Analyze Client)"},{"contents":"これまで\n実践Rust入門はじめました 実践Rust入門の3章を読んでるところ 3章終了 3章の終わりまで読み終えた。\nいきなり実践的なプログラムで少し面食らっていたが、ステップを追って所有権周りの話まで来たので、 なんとなくRustのいいところが理解できたような気がする。\nただ、最後のsplit_at_mutが実際には内部でどういう形に変換することによって、コンパイルエラーにならずに、 借用がうまく行っているのかあたりは、まだきちんと理解できていない。\nこれは、どの言語にも言えるんだけど、リファレンスをうまく読み解きながら、 自分がやりたい処理ができるかどうかを考えるのって結構むずかしいなぁと思う。\nbenchmark.rsはコピペして実行しただけなので、またあとで読み返してみるかな。\nということで、ここから先は、基本を勉強する感じで4章から読みつつ、なんかプログラムをまた書いてみるか。\n","date":1583140813,"dir":"post/2020/","id":"6f47cb314fd780c122adb8cc1f44f785","lang":"ja","lastmod":1583140813,"permalink":"https://blog.johtani.info/blog/2020/03/02/finish-bicycle-book-chap3/","publishdate":"2020-03-02T18:20:13+09:00","summary":"これまで 実践Rust入門はじめました 実践Rust入門の3章を読んでるところ 3章終了 3章の終わりまで読み終えた。 いきなり実践的なプログラムで少","tags":["rust","読書"],"title":"実践Rust入門の3章を読み終わった"},{"contents":"Kuromoji-CLI Rust初心者がRust製の日本語形態素解析器の開発を引き継いでみたという記事にありますが、LinderaというRust製の日本語形態素解析が出てきました。KuromojiのRustクローンみたいなものです。 で、作者の人とのチャットの中で、「MeCabみたいなKuromojiのCLIないですかね?誰か知りませんか?」という話になりました。\n自分は普段はKuromojiの確認をするのは、Elasticsearch関連もしくは、Azure Searchなどだったりするので、 当たり前のようにKibanaを立ち上げたり、REST APIを叩いてましたが、たしかにコマンドラインインタフェースあると便利かも? と思い、作ってみるかということに。\npicocli いま、JavaでかんたんなCLI作るとなったら何がおすすめ?\n\u0026mdash; Jun Ohtani (@johtani) February 26, 2020 で、いつものツイートです。で、picocliという返信がありました。 JavaでCLIのプログラムを書くのが簡単になりそうだと。 ドキュメントもしっかりしてます。サンプルも載ってるし。\nAnnotationで、コマンドの説明などパラメータ、オプションなどが記述でき、必須チェックなども可能です。\nまた、オプションの説明文に関しては、テンプレートを用いることで、取りうる値をEnumの値で出力してくれたりといった便利機能まで備わっていました。\nGraalVM また、GRAALVMとPICOCLIでJAVAのネイティブコマンドラインアプリを作ろうというスライドも教えてもらい、ネイティブコマンドまで作れるらしいと。 なんて便利なんでしょう!ってことで、こちらもチャレンジしてみました。 GraalVMがどんなものかはなんとなくは知ってたのですが、何者だろう?とツイートしたところ、これまた返信が。\nっ 資料はかなり古いので現行版と乖離はあるけど概念は変わってないので..https://t.co/KRQjhNdD9f\n\u0026mdash; たむたむ🏫 (@tamtam180) February 26, 2020 本当に、Twitter便利ですね。\nGraalVMがどんなものかもいただいた資料でサクッと理解できました。 ただ、picocliが実はものすごく良くできており、自分でインストールする必要も実はありませんでした。\ngradle-graalというGradleのプラグインと、 Picocli Code Generationを利用することで、 以下のコマンドを実行することで、ネイティブコマンドアプリが作成できました。\ngradle nativeImage build.gradleファイルに記述したのは、以下のような項目です。\npluginの利用 picocli-codegenをannotationProcessorとして呼び出し jarに関する記述(メインクラスと依存するJarを含める設定) ネイティブコマンドの名前とか(gradle-graalの設定) 辞書が読み込めなかった で、native imageを作って実行しましたが、Kuromojiが内包している辞書ファイルが読み込めませんでした。 どうやら、picocli-codegenの自動生成では対応できない、リソース関連設定が必要らしいと。\npicocli-godegenの設定を見ていて見つけたのが、other.resource.patternsというオプションでした。\nkuromoji-cliのbuild.gradleに、その設定を加えたら辞書が読み込めるようになりました。\nこの設定をどうやって書くのか?というのを探すのにちょっと時間がかかりました。Picocli作者のRemko Popmaさんのサンプルリポジトリに設定を利用したbuild.gradleがありました。サンプル本当にありがたいですね。\n完成 出来上がったのは、kuromoji-cliというリポジトリになります。 内部で利用しているのはAtilikaのKuromojiです。LuceneのKuromojiではないのでご注意を(LuceneのKuromojiで最初やってみたのですが、リフレクションなどが多用されてて、Single Imageにするのが手間がかかりそうだった)。 コマンドのポータビリティはそれほど無いと理解してる(あってる?)ので、利用してみたい方は、リポジトリをクローンしてからビルドしてみてください。\n参考資料 kuromoji Picocliドキュメント Getting Started GraalVM / GraalVM超入門 一体何モノなの? GraalVM入門編 / GraalVM for beginners まだ途中? ほかにもあると便利かも?という機能があればIssueやPRを上げてください。 とりあえず、頭にあるのは以下のとおりです。\nJSONの出力はまだ未対応 いろんな辞書をAtilikaのKuromojiはサポートしてるのでそのへんも対応してみる? ","date":1582858179,"dir":"post/2020/","id":"d710a073be2da219a388a150eb7b6b6a","lang":"ja","lastmod":1582858179,"permalink":"https://blog.johtani.info/blog/2020/02/28/kuromoji-cli/","publishdate":"2020-02-28T11:49:39+09:00","summary":"Kuromoji-CLI Rust初心者がRust製の日本語形態素解析器の開発を引き継いでみたという記事にありますが、LinderaというRust製の日本語形態素解","tags":["misc"],"title":"KuromojiのCLIコマンドとpicocliとGraalVM"},{"contents":"これまでのはこちら。読書メモなので、本と合わせて読んでいただくのが良いです。\n実践Rust入門はじめました 3章のクイックツアーを読んでます。 バイトニックソート自体の理解はちょっとおいておいて、読み進めています。 いくつか疑問に思ったことがあったので、またメモを。 まだ、3.5.7の手前ですが。\n疑問点 3.4.1のジェネリクス対応のテストケースの部分で、既存のu32用のテストケースの入力のデータ列にVec\u0026lt;u32\u0026gt;という型注釈をつけるのですが、 追加した文字列の入力データには注釈をここではつけないのはなんでなんだろう?ちなみに、なくても動いた。バージョンの違いとかあるのかしら?\n3.4.6のmatch文\nmatch文の引数?が*orderになっていたが、orderでも実行できた。引数にくるのが参照だから*が付いてるんだとも運だが、なくても動くのはコンパイラがよしなに解釈してくれてるからかな? 便利なツール Rust標準のツールの説明がいくつか3章で紹介されてて便利だったのでメモ。\nrustfmt フォーマッター。デフォルトでフォーマット機能が付いてるの便利ですね。言語として決まってると、プロジェクトごとに悩まなくていいってのがありますし。\nrustfmt ファイル名 という形で使えるみたい。 プロジェクトごとだとcargo fmtのほうが楽そうかな。\n標準ライブラリAPIドキュメントをブラウザで閲覧 rustup doc --std これでデフォルトブラウザでRustの公式ドキュメントが開きます。 しかもローカルファイルだからサクサク。検索バーもついてて便利です。\nエラーのドキュメントを閲覧 rustc --explain 308 コンパイル時にエラーが出たときに、error[E0308]のようにコンソールに出てきます。 ヒントも出てくるのですが、詳細が上記のコマンドで読めるみたいです。\n","date":1582443437,"dir":"post/2020/","id":"71cf83ae0f45e9ede3a3f979b9c74933","lang":"ja","lastmod":1582443437,"permalink":"https://blog.johtani.info/blog/2020/02/23/bicycle-book-chap3/","publishdate":"2020-02-23T16:37:17+09:00","summary":"これまでのはこちら。読書メモなので、本と合わせて読んでいただくのが良いです。 実践Rust入門はじめました 3章のクイックツアーを読んでます。 バ","tags":["rust","読書"],"title":"実践Rust入門の3章を読んでるところ"},{"contents":"もう2020年2月になってしまってますが、2019年に買って便利だったもの良かったものをいくつか記録に残しとこうかなと。\nBRAVIA KJ-55X9500G Amazon | ソニー SONY 49V型 液晶 テレビ ブラビア 4Kチューナー内蔵 テレビをやっと買い替えました。 前に使っていたのはプラズマディスプレイで、10年以上たったもので、パネルの一部が赤い残像が残ってたりしました。 もう流石にいいでしょうということで、買い替えたのがSonyのテレビです。 4Kのチューナーもついているし、アップコンバーターもついているので普通の地上波でもきれいです。 まぁ、10年前のテレビに比べればたくさんいいことがありますよねw\n新しいTV買って一番活躍してるのはYouTubeボタンだったりします。 最近はミュージックビデオがYouTubeにたくさんあるので、King Gnuなどの音楽流したりするのに便利です(テレビなのに)。 今は、プライムビデオボタンがより活用される感じになってきてます(テレビなのにw)。\nSodastream Amazon|スピリット ワンタッチ ホワイト スターターキット ここ数年、炭酸を普段飲んでます。甘いもの飲まないようにって意味でも。。。 で、これを買うまでは、サントリーの天然水スパークリングレモンとかを、箱買いしてました。 が、まぁ、ペットボトルのゴミが半端ないんですよ。場所も取るし。\nソーダストリームのことは知ってたのですが、自分で炭酸の量を考えながら、入れないといけないので避けていました。\nが、今回購入したものは、水の入ったボトルを指して、ボタン一つで3段階の炭酸を入れることができるんです!買って本当に重宝してます。うちでは1Lのボトルを1本追加して、2本で運用してます。 家族はなっちゃんのオレンジとかを炭酸割りしたり、カルピスソーダ作ったりして楽しんでます。 ワンタッチということで、簡単に入れられるので家族も重宝してます。\nNature Remo + Chromecast Amazon | Nature スマートリモコン Nature Remo mini Remo-2W1 Google Home miniがキャンペーンで手に入ったので、ベッドルームの照明やクーラーの操作もできそうなのでNature Remoを導入しました。 Chromecastは余っている液晶モニターにつないで、スマホからキャストできるようにしたり、音楽聞けるようにしてあります。\nNature Remoは温度計などもついているので、部屋の温度に合わせてエアコンのオンオフなども可能で、 暑い夏にとても便利でした。寝る時間にはクーラーが入っているのですんなり寝れたりと。 スマホから電源オンオフできるのも便利ですね。 Chromecastはモニターにつなぎましたが、今は、Google Music Playのプレーヤーになってます。 (最近、家にあるCDを読み込んでGoogle Play Musicにアップしてる)。\nただ、それ以上のことには使えてないので、もうちょっと面白いことしてみないとなぁ。\nモニターアーム Amazon | HUANUO PC モニター アーム 液晶ディスプレイ アーム ガススプリング式 Amazon | グリーンハウス 液晶ディスプレイアーム 4軸 クランプ式 ディスプレイがふるくなってたので、4Kディスプレイに買い替えた(27インチで4万切るとかで安い。。。)んですが、Mac Book Pro 15インチ(今は16インチ)を使っていて、Macの画面がディスプレイにかぶるので モニターアームを買いました。 1つ目がガススプリング式のアームです。なのに、5000円を切ってるんですよ。おそるべし。 2つ目はクランプ式です。アームにしたものの特に動かすことはなく、高さを出したいだけってことがあるので、クランプ式のも使ってます(家ではディスプレイ2枚使ってる)。 コスパ最高です。\nAnker PowerCore 10000 PD Amazon | Anker PowerCore 10000 PD(10000mAh PD対応最小最軽量 大容量 モバイルバッテリー) Pixel 3にしてから、電池の持ちはよくはなってるんですが、もしもの時のためにモバイルバッテリーは話せないですよね。 PD対応なので、Pixel 3に急速充電ができるし、サイズもそれほどじゃまにならないサイズなので便利です。USB-Aもついているので、このあと紹介するイヤホンの充電ケーブルなんかも差し込めて大活躍です。\nサウンドピーツのイヤホン Amazon | SOUNDPEATS(サウンドピーツ) Q35HD ワイヤレス イヤホン 高音質・低遅延 IPX8防水 私が持ってるのはこの前のバージョンで、micro-USBで充電充電するタイプですが、こちらもコスパ最高です。 冬は防寒も兼ねてヘッドフォンをしているのですが、春から秋にかけてはこれまで、優先のイヤホンを使ってました。もしくは、Bluetoothのレシーバーに優先のイヤホンつけてました。電池切れたら、イヤホンさして使う感じで。 が、Pixel 3はイヤホンジャックがありません。ということで、ワイヤレスイヤホンに移行するかということで選んだのがこちらです。 世の中的には、完全ワイヤレスイヤホンが流行っていますが、片方無くなってしまうイメージしかわかなくて。。。 これが壊れても、完全ワイヤレスではなくつながったワイヤレスイヤホンを使うと思います。\nヘッドルーペ Amazon | Tumao ヘッドルーペ ルーペ メガネ LED付拡大鏡 眼鏡の上装着 メガネゴムバンド両用 5レンズ交換調節 プラモデルをちょいちょい作るんですが、もう年ですね。。。細かいところが見にくくて。 ガンダムのRG系のプラモデルだと、1/144なんですよ。小さいんですよ。見えないんですよ。。。\n完成しましたー! pic.twitter.com/S9QTS4kJDI\n\u0026mdash; Jun Ohtani (@johtani) February 16, 2020 ということで、ヘッドルーペ導入してみました。 最初は、卓上に置けるルーペにしてみたんですが、自分がルーペがあるところに動かないといけないの結構つらくて。 これのおかげで、プラモデル作成に問題はなくなりました。老眼とは関係なく、ちょっと猫背になっちゃうのが今は悩みの種ですが。。。こたつで作ってるからなぁ。\nまとめ ということで、いくつかよかったものを紹介してみました。 今年はちゃんと年末に書こう。。。\n","date":1582272302,"dir":"post/2020/","id":"daa3fe935b0be9f31b6b362ad9e0d2d6","lang":"ja","lastmod":1582272302,"permalink":"https://blog.johtani.info/blog/2020/02/21/best-buy-2019/","publishdate":"2020-02-21T17:05:02+09:00","summary":"もう2020年2月になってしまってますが、2019年に買って便利だったもの良かったものをいくつか記録に残しとこうかなと。 BRAVIA KJ-55X9500G Amazon | ソニー SONY 49","tags":["買い物"],"title":"2019年に買ってよかったもの"},{"contents":"ブログ移行日記(その5)です。前回まではこちら\nブログ移行日記(その1) ブログ移行日記(その2) ブログ移行日記(その3) ブログ移行日記(その4) 今回はこれまでとは異なる特殊な話です。\n最初にブログを書き始めたときに利用していたのがJugemのブログでした。 その後、Octopressに移行して、今年、Hugoに移行したという流れです。\nで、よくよく考えると、Jugemのブログも移行できるんじゃないか?となりました。 じゃあ、やってみるかと。なので、今回のブログは自分の備忘録です(興味のない人が大多数じゃないかな)。 一応、Pythonで書いたプログラムはGitHubに上がっています。文字列置換と正規表現のオンパレードです。\nJugemからExport まずは、移行元のデータが取り出せるかどうかを調べたところ、text形式もしくはXML形式でエクスポートが可能でした。\n変換処理が必要なはずなので、XMLでダウンロードします。 独自のXMLですが、記事ごとにXMLのタグ(\u0026lt;entry\u0026gt;)でまとめられているので、処理が楽です。\nXMLをMarkdownに \u0026lt;entry\u0026gt;タグの下に次のような項目が入っているので、抜き出します。\nヘッダ部 title - 記事タイトル author - 著者 category - タグ date - 投稿日付 description : 本文(先頭部分) sequel : 本文(つづき) titleからdateまでをHugoのMarkdownのヘッダ部分として出力します。 日付は形式が違うので合わせるように変換し、 titleは(Jugemより移植)という文字列を追加しました。\nまた、Hugoの個別のコンテンツにするためにそれぞれをMarkdownのファイルに変換しています。 ファイル名は変換後のdateの先頭10文字(yyyy-MM-dd)に-を付け加えて、 タイトルを追加しました。ホントは英語のファイル名にしたかったんですが、ちょっと手抜き。ファイル名に使用できないような文字は-に置換しています。\n本文 本文部分はもう少し複雑です。 まずは、descriptionとsequelから抜き出した文字列を結合します。\nで、内部の文字列に次のようなものがあるので、それぞれMarkdownに変換したりという処理を書いてます。\nHTMLのheadingタグをMarkdown形式に br、hr、del、strongなどのタグもMarkdown形式に aタグの処理 Amazonのアフィリエイトタグの処理 ul、olタグの処理 などです。 アフィリエイトタグは、数行に渡るの複数のHTMLタグで記述されているので、 ASINと商品タイトルだけを抜き出しています。 Hugoでアフィリエイトのリンクを作るために、hugo-amazon-jpという公開されているshortcodeを元に、カスタマイズしたものを使っています。 これ用に、必要なASINとタイトルを別ファイルに出力したりしています。\nまた、いくつか画像を使っている記事があったのですが、これが曲者でした。 XMLに入っているimgタグに画像へのURLがあるのですが、アクセスしても存在しないURL担っています。。。 ブログで公開している画像のファイル名に似たものがXMLに入っていたので、URLを組み直して、ダウンロードするという処理も書いています。\nあとは、昔ちょっと凝った書き方(spanタグで章みたいなことやってた)をしていた部分の処理を加えて完成です。\nまとめ 元のXMLを見たり、抜き出したファイルを見ながら、トライアンドエラーでプログラムを書きました。 なんとなく変換できたなかっていうところで、取り込んで公開しました。 まだ、全部の記事をチェックしてないですが、なんとなく移植できたので一旦これでいいかなと。 昔の記事を見たときにおかしい場所があったら手で治すつもりでいます。\nなんか、もうちょっとうまくプログラムかけた気もしますが、書き捨てのプログラムだと思うのでこんなもんかな。\n1点気になっているところは、コメントの部分です。 ブログにコメントをいただいていたのですが、その部分は移植できてないです。\nOctopresに移植していこうは、Disqusのサービスでコメント部分を提供しています。ここに移植するのも変な話だなぁと思っているので、本文にコメントを取り込む感じかなぁ?\nもともとのJugemのサイトもそのまままだ残してあるので、そのうち気が向いたらで。\n","date":1582254240,"dir":"post/2020/","id":"ef8a399c9679ce4e9710c7c6ecf8bcc7","lang":"ja","lastmod":1582254240,"permalink":"https://blog.johtani.info/blog/2020/02/21/import-jugem-posts/","publishdate":"2020-02-21T12:04:00+09:00","summary":"ブログ移行日記(その5)です。前回まではこちら ブログ移行日記(その1) ブログ移行日記(その2) ブログ移行日記(その3) ブログ移行日記(その4","tags":["hugo","ブログ"],"title":"ブログ移行日記(その5) - Jugemのブログを移行"},{"contents":"お手伝いしているお客さんがAzure Cognitive Searchを利用してます。 検索周り=Azure Cognitive Searchに関する手伝いをする形で入っており、 いくつか触った感触をブログにまとめてみようかと(お客さんからはOKいただいてます)。\nAzure Cognitive Searchとは? 公式サイト 「AIを活用した」クラウド検索サービスと紹介されています。\n昔はAzure Searchと呼ばれていましたが、ここ最近はAzure Cognitive Searchと呼ばれているみたいです(Microsoft Igniteで発表された話がまとまっているページもあります)。 もともと、検索エンジンのSaaSサービス(キーワード検索、あいまい検索、オートサジェスト、スコアリングなどの機能)として作られていた部分に、データの登録パイプラインにCognitive Serviceの便利な機能を簡単に使えるようにしたものというイメージでしょうか。\nバックエンドはElasticsearchのはずです。変わってなければ。 昔、Elastic社主催のユーザーカンファレンスでMSの方が公演された資料が公開されていたりします。 ちなみに質問が多いのでしょうか、Azure Cognitive SearchとElasticsearchの違いはなんですか?というページがよくある質問のページに用意されていました。参考までに。\n今回はちょっとしたインデックスをつくって検索する部分を紹介してみようかと思います (Cognitiveなところは機会があればまた)。\n普通の使い方については、Azureのドキュメントなどを読んで頂く形にします。 ポータルと呼ばれるブラウザ上でAzureのサービスを触ることができる画面が用意されています。 ここで、簡単な操作(インデックス作成、フィールドの追加)\nAPIを使ってインデックス(特にAnalyzer)の設定をしたり、データをいれて、クエリしてみるというところをサクッと紹介しようと思います。\nインデックスの作り方 インデックス作成に関するドキュメントも用意されています。最初はポータル(GUI)でインデックスを作成する方法が紹介されています。 ですが、今回はn-gram(n=2)のAnalyzerを利用したかったので、GUIではなくAPIでインデックスを作成しました。 カスタムアナライザーを利用する場合、REST APIを利用しなければ行けないということになっています。 n-gramのAnalyzerを含むインデックス生成のREST APIは以下のとおりです。こちらを実行することで、インデックスが作成されます(JSONの記述ミスなどがある場合はエラーが返ってきます)。\n@host = \u0026lt;サーチのサービス名\u0026gt;.search.windows.net @api-key = \u0026lt;APIキー\u0026gt; ### POST https://{{host}}/indexes/?api-version=2019-05-06 Content-Type: application/json api-key: {{api-key}} { \u0026#34;name\u0026#34;:\u0026#34;ngram-test\u0026#34;, \u0026#34;fields\u0026#34;:[ { \u0026#34;name\u0026#34;:\u0026#34;id\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;Edm.String\u0026#34;, \u0026#34;key\u0026#34;:true, \u0026#34;searchable\u0026#34;:false }, { \u0026#34;name\u0026#34;:\u0026#34;ngram\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;Edm.String\u0026#34;, \u0026#34;searchable\u0026#34;:true, \u0026#34;analyzer\u0026#34;:\u0026#34;bi_gram_analyzer\u0026#34; } ], \u0026#34;analyzers\u0026#34;:[ { \u0026#34;name\u0026#34;:\u0026#34;bi_gram_analyzer\u0026#34;, \u0026#34;@odata.type\u0026#34;:\u0026#34;#Microsoft.Azure.Search.CustomAnalyzer\u0026#34;, \u0026#34;tokenizer\u0026#34;:\u0026#34;bi_gram_tokenizer\u0026#34;, \u0026#34;tokenFilters\u0026#34;:[ \u0026#34;lowercase\u0026#34; ] } ], \u0026#34;tokenizers\u0026#34;:[ { \u0026#34;name\u0026#34;:\u0026#34;bi_gram_tokenizer\u0026#34;, \u0026#34;@odata.type\u0026#34;:\u0026#34;#Microsoft.Azure.Search.NGramTokenizer\u0026#34;, \u0026#34;minGram\u0026#34;:2, \u0026#34;maxGram\u0026#34;:2 } ] } なんだかどこかで見たことのある記述のようなそうでないような。。。 Analyzerは、charFilters(0以上複数可)、tokenizer(1つ必須)、tokenFilters(0以上複数可)から構成されます。 フィールドで指定するのはAnalyzerなので、まずanalyzersにCustomAnalyzerの設定を行います。 名前はbi_gram_analyzerにしました(好きに付けてください)。 tokenizerにはこのあと設定するtokenizerの名前を設定します。ここでは、bi_gram_tokenizerという名前にしています。 また、大文字小文字を気にせずに検索したいため、tokenFiltersにlowercaseを指定しています。こちらはすでに定義済みのため、定義済みの名前で呼び出すだけで使用できます。\n次が、bi_gram_tokenizerの設定です。 n=2としたいので、tokenizers配下にTokenizerの設定をします。 @odata.type\u0026quot;:\u0026quot;#Microsoft.Azure.Search.NGramTokenizerがTokenizerの名前です(ちょっと独特な名前ですね)。 Tokenizerごとにオプションがあり、NGramTokenizerの場合は、minGram、maxGramがオプションに相当します。 今回は2文字ごとにトークンを出力したいので、minとmaxをそれぞれ2としています。\nこれで、あとは、フィールドでanalyzerという設定にbi_gram_analyzerを指定すればそのフィールドはbi_gram_analyzerを使用してアナライズされるようになります(このへんはElasticsearchといっしょですね)。 フィールドは文字列を扱うので、Edm.Stringというタイプにしてあります。データ型については、フィールドコレクションとフィールド属性というドキュメントを参考に設定しましょう。\n閑話休題 - REST Client Exstension for Visual Studio Code なお、今回のサンプルはREST Clinet Extention for Visual Studio Codeを利用する想定の記述になっています。\nVisual Studio Codeで.restもしくは.httpというファイルに以下のAPIを記述すると、Send RequestというリンクがURLの上部に出てくるような拡張機能です。REST APIにリクエストするときに便利なツールになっています。 変数も使えるので、APIのキーやURLの一部をこのように共通化して、他の環境でも使いやすくできるのは素晴らしいなと。\nアナライザーの挙動の確認 設定したAnalyzerがきちんと機能しているかというのを確認する必要があります。 入力した文字列がきちんと想定している単語として切り出されて、転置インデックスの見出し語に使われるかというのが重要になるからです。\nAzure Cognitive Searchでもアナライザーのテスト用APIが用意されています。 使い方はこちら。 APIの仕様のページもありました。 「アナライザーの挙動はどんな感じ?」という文字列が、作成したインデックスの定義したアナライザーbi_gram_analyzerにより、 どのように分割されるかを確認するAPIの呼び出しは以下のとおりです。\n### POST https://{{host}}/indexes/ngram-test/analyze?api-version=2019-05-06 Content-Type: application/json api-key: {{api-key}} { \u0026#34;analyzer\u0026#34;:\u0026#34;bi_gram_analyzer\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;アナライザーの挙動はどんな感じ?\u0026#34; } レスポンスはこんな形です。ヘッダ部分は省略してあります。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;https://{{host}}.search.windows.net/$metadata#Microsoft.Azure.Search.V2019_05_06.AnalyzeResult\u0026#34;, \u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;アナ\u0026#34;, \u0026#34;startOffset\u0026#34;: 0, \u0026#34;endOffset\u0026#34;: 2, \u0026#34;position\u0026#34;: 0 }, { \u0026#34;token\u0026#34;: \u0026#34;ナラ\u0026#34;, \u0026#34;startOffset\u0026#34;: 1, \u0026#34;endOffset\u0026#34;: 3, \u0026#34;position\u0026#34;: 1 }, { \u0026#34;token\u0026#34;: \u0026#34;ライ\u0026#34;, \u0026#34;startOffset\u0026#34;: 2, \u0026#34;endOffset\u0026#34;: 4, \u0026#34;position\u0026#34;: 2 }, { \u0026#34;token\u0026#34;: \u0026#34;イザ\u0026#34;, \u0026#34;startOffset\u0026#34;: 3, \u0026#34;endOffset\u0026#34;: 5, \u0026#34;position\u0026#34;: 3 }, { \u0026#34;token\u0026#34;: \u0026#34;ザー\u0026#34;, \u0026#34;startOffset\u0026#34;: 4, \u0026#34;endOffset\u0026#34;: 6, \u0026#34;position\u0026#34;: 4 }, { \u0026#34;token\u0026#34;: \u0026#34;ーの\u0026#34;, \u0026#34;startOffset\u0026#34;: 5, \u0026#34;endOffset\u0026#34;: 7, \u0026#34;position\u0026#34;: 5 }, { \u0026#34;token\u0026#34;: \u0026#34;の挙\u0026#34;, \u0026#34;startOffset\u0026#34;: 6, \u0026#34;endOffset\u0026#34;: 8, \u0026#34;position\u0026#34;: 6 }, { \u0026#34;token\u0026#34;: \u0026#34;挙動\u0026#34;, \u0026#34;startOffset\u0026#34;: 7, \u0026#34;endOffset\u0026#34;: 9, \u0026#34;position\u0026#34;: 7 }, { \u0026#34;token\u0026#34;: \u0026#34;動は\u0026#34;, \u0026#34;startOffset\u0026#34;: 8, \u0026#34;endOffset\u0026#34;: 10, \u0026#34;position\u0026#34;: 8 }, { \u0026#34;token\u0026#34;: \u0026#34;はど\u0026#34;, \u0026#34;startOffset\u0026#34;: 9, \u0026#34;endOffset\u0026#34;: 11, \u0026#34;position\u0026#34;: 9 }, { \u0026#34;token\u0026#34;: \u0026#34;どん\u0026#34;, \u0026#34;startOffset\u0026#34;: 10, \u0026#34;endOffset\u0026#34;: 12, \u0026#34;position\u0026#34;: 10 }, { \u0026#34;token\u0026#34;: \u0026#34;んな\u0026#34;, \u0026#34;startOffset\u0026#34;: 11, \u0026#34;endOffset\u0026#34;: 13, \u0026#34;position\u0026#34;: 11 }, { \u0026#34;token\u0026#34;: \u0026#34;な感\u0026#34;, \u0026#34;startOffset\u0026#34;: 12, \u0026#34;endOffset\u0026#34;: 14, \u0026#34;position\u0026#34;: 12 }, { \u0026#34;token\u0026#34;: \u0026#34;感じ\u0026#34;, \u0026#34;startOffset\u0026#34;: 13, \u0026#34;endOffset\u0026#34;: 15, \u0026#34;position\u0026#34;: 13 }, { \u0026#34;token\u0026#34;: \u0026#34;じ?\u0026#34;, \u0026#34;startOffset\u0026#34;: 14, \u0026#34;endOffset\u0026#34;: 16, \u0026#34;position\u0026#34;: 14 } ] } このAzure SearchのAnalyze API、使用できるオプションはすくないですが、ElasticsearchのAnalyze APIと似ています。\nデータの登録の仕方 データ登録もAPIからできます(あたりまえですね)。 APIは1件ずつではなく、バルクで登録できる形で提供されています。\nサンプルとしては、以下のような形です。 @search.actionの部分(searchがあるとわかりにくい気がするけど。。。)が、ドキュメントの登録、更新、削除の命令を書き込むところになります。 今回は単純に登録するだけなので、uploadを指定しました。 ほかにもいくつかアクションが用意されています。用途に合わせて指定する感じになります。 id、ngramはそれぞれフィールド名です。ドキュメントに登録したい値を記述します。\nPOST https://{{host}}/indexes/ngram-test/docs/index?api-version=2019-05-06 Content-Type: application/json api-key: {{api-key}} { \u0026#34;value\u0026#34;: [ { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;ngram\u0026#34;: \u0026#34;新しいAzure Searchの使い方\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;2\u0026#34;, \u0026#34;ngram\u0026#34;: \u0026#34;Elasticsearchの紹介\u0026#34; } ] } 検索クエリ 最後は検索クエリです。 検索クエリはいくつかのオプションがあります。 ざっくりだと、queryTypeがsimpleとfullという2種類が用意されており、ちょっとした検索を作る場合はsimpleで事足りそうという感じです。 入力された単語(スペース区切りで複数扱い)をフィールド(複数可)に対していずれかの単語を含むもしくは、すべての単語を含むという検索に行くというパターンですね。 このときの、「いずれか」か「すべて」の設定がsearchModeというパラメータになります。 anyの場合、Googleの検索と同様に、どれかの単語が入っているドキュメントが対象に、allの場合すべての単語が含まれるドキュメントだけがたいしょうになるといった形です。\nqueryType=fullの場合はLuceneの構文でクエリがかけます。ElasticsearchのQuery String Queryみたいな形です。\n簡単なサンプルは次のような感じです。このサンプル\nPOST https://{{host}}/indexes/multi-field-test/docs/search?api-version=2019-05-06 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#39;ngram:\u0026#34;使い方\u0026#34; ngram:\u0026#34;紹介\u0026#34;\u0026#39;, \u0026#34;queryType\u0026#34;: \u0026#34;full\u0026#34;, \u0026#34;searchMode\u0026#34;: \u0026#34;any\u0026#34; } すこしだけクエリの補足を。 searchに入力された単語をダブルクォートで囲んでいます。これは、「使い方」という文字がbi_gram_analyzerにより「使い」「い方」に 分割されるのですが、必ずこの順序で出現したものだけを検索対象にしたい(フレーズ検索)という意味になります(*bi_*gramなので、「紹介」に関してはダブルクォートは厳密には必要ないです)。\nあと、レスポンスは今回記載していませんが、@search.scoreという項目で、スコアが返ってきます。 デフォルトのスコア計算には何を使ってるんだろう?ドキュメントにはTF-IDFとの記述があるのですが。。。カスタマイズもできそうです。\n少しオモシロイと思ったのは、スキーマ(インデックスの設定)に定義されているが、ドキュメントとしては登録していない項目についても、 Azure Cognitive Searchはドキュメントのフィールドがnullという形で返ってくるようでした。 そもそもフィールドが存在しないドキュメントとフィールドの値がnullのものの違いは無いようです。\n簡単ですが、インデックスの設定、ドキュメントの登録、検索の方法の紹介でした。\nちょっと触った感想 一番売りである、Cognitiveの部分はまだ触っていないです、すみません(こっちが売りな気もするんですが)。 検索エンジンの部分としては、Elasticsearchを知っていると、「あー、そんな感じね」という気持ちになれるサービスです。 個々のAPIやデータの形式は異なるので、きちんとAPIのリファレンスなどを確認しつつという形になりますが、なんとなくこういうAPIなどがありそうだな?と予測しつつ使えるかなと。 内部的にはElasticsearchだと思いますが、独自のAPIでラップされているおかげで、バージョンの違いなどを意識せずに使えるのではないかと思います。\nまた、今回は紹介していませんが、マイクロソフト独自の各言語のアナライザー(日本語も含む)があります。 Luceneのアナライザーとマイクロソフトのアナライザーのどちらも利用できますので、ここの違いを見てみるのも面白そうだなと思いました。 緯度経度を利用した検索、フィルター検索(スコア計算対象にならない)、ファセット、スコア調整の機能なども備えているようです。\nなんにせよ、利用する場合やドキュメントを読む場合に、全文検索の仕組みをなんとなく知っておいたほうが読みやすいんじゃないかなというのが感想です。\nここ数年はElasticsearchがメインでほかはほぼ触っていない状況だったので新しい製品に触れるのは面白いですね。 時間があったら、アナライザーの違いなども調べてみたいなと思います。\n","date":1582080481,"dir":"post/2020/","id":"c3053579ae25e2fb9b967076a06373af","lang":"ja","lastmod":1582080481,"permalink":"https://blog.johtani.info/blog/2020/02/19/research-azure-cognitive-search/","publishdate":"2020-02-19T11:48:01+09:00","summary":"お手伝いしているお客さんがAzure Cognitive Searchを利用してます。 検索周り=Azure Cognitive Searchに関する手伝いをする形で入っており、 いく","tags":["azure search"],"title":"Azure Cognitive Searchでインデックスを作って検索"},{"contents":"また、ツイートから始まるお話です。 まだまだ、検索システムってどんなものかを勉強したいしということで、こんなのをツイートしてました。\n「検索システム探訪」みたいな名前がいいかな? https://t.co/sG7BDdGI9h\n\u0026mdash; Jun Ohtani (@johtani) February 6, 2020 検索について知り合いとお茶をしながら話をしていて、こういう話を聞くの面白いなぁと思ったので。 どんなことを個人的には聞きたいかな?というのをまとめといたほうがいいかと思いブログを書いています。 こんなことも面白そうだよね?\nどんなこと聞きたいかな? いまのところ思いついた内容はこんな感じかな? こんなのも聞くと面白そうだよね?などありましたら、コメント欄に書いてもらえればと。\n利用しているシステム・サービスは? 構成やどこのサービスなのか? 検索ユーザーはどんな人? ユーザーの種類 ユーザーの検索ニーズ 検索対象データはどんなもの? データ件数はどのくらい? 属性、項目がどのくらいあるか? 検索結果として出したいものは? ソートはどんなものがあるの? ランキングで重要なものは? UI/UXはどんな感じ? ハイライト、ソート、ファセット(Aggs) キーワードサジェスト、オートコンプリート 検索システムの監視(オブザバビリティ??) ビジネス的な指標 クエリログ、クリック(ユーザーに関する情報) システムメトリクス 困っていることは? ランキング クエリ 検索システム分析 第1回やりました。 ちなみに、最初のツイートに対して、すぐに返事をくれた方がいました。\nうちでよければご説明します!\n\u0026mdash; Kizashi (令和もRailsエンジニア募集中) (@kizashi1122) February 6, 2020 Twitter本当にありがとうございますという感じです。\nで、早速話を聞かせていただきました。大阪の方だったので、テレカンでやらせていただきました。 移動時間とか気にせずにできるので、テレカン形式いいですよね。\n内容は、非常に面白かったです。 使ってるシステムについて、どんなところで、どのようなように検索エンジンをつかっているのか、 どんなことで困っているのかなどをお聞きすることができました。\n2020/02/13 追記 対応していただいたIngageの永田さんから、内容を公開しても良いという承諾をいただいたので、メモを公開します。\nサービス : Re:lation 問い合わせメールなどのチームで対応する対応 利用している検索エンジン Elasticsearch (AWS Es) ノード数 8 - 3 master + 5 data データ データ数 : 約1億5千万 親子関係 : チケット - メール(=1ドキュメント) - コメント 画面としてはチケットの一覧=aggsでチケットIDの一覧を生成してリスト表示 インデックス数 : 5 = テナントごとに振り分けしてる。 8シャード - スケールアウトした場合も対応できるので。 PostgreSQLにマスターは保存 データの単位はメール。コメントはtextの配列でメールに保存されている。 EsはIDの一覧を返す。ただし、チケットのIDの一覧 機能 ハイライト Esではなく独自実装。 クエリ n-gramでやってる = kuromoji使ってない min=1, max=2 悩み事 EBS上だったものをローカルにしたので速くなった。 期間が長いと、検索結果一覧の表示が遅い aggsが遅いのかな? 検索結果一覧はチケットが持っているメールの日付の降順。結果一覧はチケットの一覧。 詳細検索はDB、左のステータスもファセットも現在はDBから生成 Es使ったほうが早いかも? マルチテナントのつらさ 検索ログ 独自ログはとっていない = アプリのログから判別 今後 アドレス帳検索 お誘いお待ちしております! 今後もこれやっていきたいなぁ。話してもいいよ!という方がいらっしゃいましたら、@johtaniまでDMもしくはメンションをください。お待ちしております!\n","date":1581344427,"dir":"post/2020/","id":"7b080dc43fce482af14de61c6ab819a5","lang":"ja","lastmod":1581344427,"permalink":"https://blog.johtani.info/blog/2020/02/10/explore-search-system/","publishdate":"2020-02-10T23:20:27+09:00","summary":"また、ツイートから始まるお話です。 まだまだ、検索システムってどんなものかを勉強したいしということで、こんなのをツイートしてました。 「検索シス","tags":["検索システム探訪"],"title":"「検索システム探訪」したいな=\u003eやりました"},{"contents":"年末、何種類かのボードゲームを家族で楽しみました。 家族の感想を交えて簡単に紹介しようかと思います。 家族や知人でボードゲームを購入するときの参考に参考にしてもらえたらと。 それぞれのゲームの詳細については、それぞれWikipediaなどのリンクを張っておくので、参考にしていただけたらと。 結構有名なボードゲームが多いのかな?\nカタン Amazon | カタン スタンダード版 | ボードゲーム | おもちゃ 簡単な紹介 プレーヤー数 : 3-4名 (拡張版を追加すると5-6名でもプレイできるみたい) 対象年齢 : 10歳以上 種類 : 対戦型 紹介 : 大航海時代に発見された無人島を複数の入植者たちが開拓していき、もっとも繁栄したプレイヤーが勝利するという内容のボードゲーム(Wikipediaより)。 特徴 : 5種類の資源を元に、道を作ったり、開拓地や都市を作ったり、サイコロを使った運も必要ですが、プレーヤー同士で手持ちの資源を交渉することも可能なゲームです。 感想 最初の配置が重要な気がします。資源の組み合わせによってできることが変わってくるので、何をやりたいかというのを元に考えて配置するのが重要そうです(私はまだうまくできてませんがw)。 プレーヤー同士の交渉も1つの手段なので、会話しながら、自然と交渉術も身についてきそうです。 戦略だけじゃなくサイコロを使った運もあるので、子供と大人が混ざっていても偏った結果にはならないです。 自分の道や町が発展していくのも楽しみの1つです。 お化け屋敷の宝石ハンター Amazon | お化け屋敷の宝石ハンター FBH20 | おもちゃ | おもちゃ 簡単な紹介 プレーヤー数 : 2-4名 対象年齢 : 8歳以上 種類 : 協力型 紹介 : お化け屋敷がおばけでいっぱいになる前に、みんなで協力して8つの宝石をみつけて、屋敷から脱出しよう!(メーカーホームページより)。 特徴 : 対戦ではなくプレーヤーみんなで協力してやるボードゲーム。おばけのフィギュアも可愛いです。サイコロを利用した運もありますが、みんなでどういった戦略で宝石を取り出すかなど会話も進むゲームです。上級編という難しめのルールも用意されているので、ハラハラ・ドキドキしながらプレイできます。 感想 負けて悔しくなったり機嫌が悪くなることがないのがいいですね。 普通のルールだと少し物足りない感じですが、上級編のルールはより、みんなで協力する必要が出てきます。 また、上級編のルールは絶妙な難易度で、もう一度やりたいと思わせるのが良い仕組みです。 ラビリンス Amazon | ラビリンス (Labyrinth) ボードゲーム | ボードゲーム | おもちゃ 簡単な紹介 プレーヤー数 : 1-4名 対象年齢 : 8歳以上 種類 : 対戦型 紹介 : 動く迷路で宝探し!通路が動く不思議な迷路の中に、「宝物」や「奇妙な生き物」が隠されています。プレイヤーはこれらを集めてこなければなりませんが、そのためには、巧みに迷路を動かさなければなりません。(メーカーホームページより)。 特徴 : サイコロがないボードゲームです。先を予測しながら人のじゃまをしつつ、自分に有利に進めていくゲームです。プレーヤー個別に難易度を変えられる仕組みがあります(子供だけに有利なルール設定が可能)。 感想 子供ルールがあるので、1度のゲームで別々の難易度が設定できるのがいいです。左右盲の人には子供ルールとかもありです。 ラビリンスが得意な人は地図を読むのが得意な人だと思います。 頭も使うけど、自分が望んだ道ができた時の快感があります。 モノポリー Amazon | ハズブロ ボードゲーム モノポリー クラシック C1009 正規品 | ボードゲーム | おもちゃ 簡単な紹介 プレーヤー数 : 2-6名 対象年齢 : 8歳以上 種類 : 対戦型 紹介 : プレイヤーは双六の要領で盤上を周回しながら他プレイヤーと盤上の不動産を取引することにより同一グループを揃え、家やホテルを建設することで他のプレイヤーから高額なレンタル料を徴収して自らの資産を増やし、最終的に他のプレイヤーを全て破産させることを目的とする。モノポリーとは英語で「独占」を意味する。(Wikipediaより)。 特徴 : 資本主義とは?みたいなのを体験できるゲーム。すごろく型ですが、ゴールがあるわけではなく、決着がつくまでぐるぐる回る感じです。 感想 資本主義を象徴しているゲーム展開。真剣勝負間違いなしです。 負けると途中退場ってのがちょっとつらいです。。。 カタンとは違った感じの交渉術になります。 コマが色んな種類があってかわいいです。 パンデミック Amazon | パンデミック:新たなる試練 (Pandemic) 日本語版 ボードゲーム | ボードゲーム | おもちゃ 簡単な紹介 プレーヤー数 : 2-4名 対象年齢 : 8歳以上 種類 : 協力型 紹介 : 『パンデミック』(Pandemic)は、プレイヤーが新型ウイルス対策チームの一員となり、協力しあい感染症の世界的流行(パンデミック)に立ち向かうというボードゲームである。(Wikipediaより)。 特徴 : プレーヤーが個別のロール(役割)を持っており、よりみんなで協力をしないとウイルスに打ち勝てない感じです。 感想 ルールが結構複雑で、理解しながらだと少し時間かかりました。 8歳以上になっていますが、少しむずかしい印象でした。 戦略、戦術が問われる形のゲームなのでしっかり理解すると楽しそう。 世界地図上で、ウイルスと戦っていく感じは臨場感があって面白いです。 ナインタイル Amazon | ナインタイル | カードゲーム・トランプ | おもちゃ 簡単な紹介 プレーヤー数 : 2-4名 対象年齢 : 6歳以上 種類 : スピード対戦型 紹介 : 「ナインタイル」の基本ルールは、それぞれの手元にある、9枚のタイルを自由に動かしたりひっくり返したりして、誰よりも早くお題どおりに並べるだけ。(公式サイトより)。 特徴 : ボードゲームというか、カードゲーム。ルールは簡単ですが、記憶力と素早さが重要です。 感想 脳トレに良さそう(子供に勝てませんでした。。。)。 瞬発力+記憶力が重要。 デザインがきれい じゃあ、家族の人気は? ラビリンス、カタン、モノポリーあたりが人気です。 ゲーム性もありますが、デザインとしてもきれいなものが多かったです。\nテレビゲームも面白いですが、ワイワイ喋りながらボードゲームをやるのも楽しかったです。 今回紹介したボードゲームはどれもある程度ルールを理解するところから始めないといけないですが、理解力や説明力なども必要になってくるので色んな楽しみがあるかなと思います。\n","date":1580558694,"dir":"post/2020/","id":"90f9355781403b92e844de8568863ae8","lang":"ja","lastmod":1580558694,"permalink":"https://blog.johtani.info/blog/2020/02/01/intro-board-game/","publishdate":"2020-02-01T21:04:54+09:00","summary":"年末、何種類かのボードゲームを家族で楽しみました。 家族の感想を交えて簡単に紹介しようかと思います。 家族や知人でボードゲームを購入するときの参","tags":["ゲーム"],"title":"ボードゲーム紹介"},{"contents":"実践Rust入門という本を買っていた(去年の7月だ。。。)のですが、積んであったので、時間を作って読み始めようかと。\n実践Rust入門[言語仕様から開発手法まで] | κeen, 河野 達也, 小松 礼人 |本 | 通販 | Amazon 経緯 もともとは、言語処理100本ノックはじめました(Rust)という感じで、触っていたのですが、場当たり的にやってても時間を持っていかれるだけだなということに気づいたのが最初です。\n今年の目標は、覚えられなので、ちょっとずつでもアウトプットしていこうってのもあり、 読書記録をつけつつ、読んでいこうかなぁと。\nどこまで読んだ? 2章の2-2-5までです。 前回、Rustの環境はセットアップしていたのですが、新PCに切り替わったので、rustupからはじめました。\nrustup rustupではデフォルト設定のままではなく、PATH変数の書き換えだけはしない形でインストールを行いました。\nPATH変数は.zshrcファイルで変更したかったためです(rustupコマンドに変更して貰う場合は.profileなどのファイルが変更されそうだったため)。\nインストールが終わったあとに.zshrcに以下の行を追加しました。\n### For Rust env source $HOME/.cargo/env 疑問点 ここまで読んだ疑問点です。\ncargo new helloしたあとにmain.rsに以下のmain()関数が出来上がっている!? fn main() { println!(\u0026#34;Hello, world!\u0026#34;); } 驚きましたが、cargo new hogeってやっても、おなじmain.rsができてました。デフォルトで出来上がるんですね。どんな超能力!?と思ってしまいましたw\ncargo new helloして出来上がったCargo.tomlに著者名が入力されていた。 authors = [\u0026#34;Jun Ohtani \u0026lt;メアド\u0026gt;\u0026#34;] なんで?と思いました。まだ解明してないです。 本を読んでいけばわかるかな?\n予想:gitの設定(~/.gitconfig)に氏名とメアドが設定されているので、これを利用しているのかな? ","date":1580475492,"dir":"post/2020/","id":"7fcfaa8dd34dbd508f19e8ca0fcfda0f","lang":"ja","lastmod":1580475492,"permalink":"https://blog.johtani.info/blog/2020/01/31/start-reading-bicycle-book/","publishdate":"2020-01-31T21:58:12+09:00","summary":"実践Rust入門という本を買っていた(去年の7月だ。。。)のですが、積んであったので、時間を作って読み始めようかと。 実践Rust入門[言語仕","tags":["rust","読書"],"title":"実践Rust入門はじめました"},{"contents":"12月に退職しますブログを書きましたが、その後どうなったのか?という話をしてないなと思ったので、一応現在の状況を書き留めておこううかと。\n結論 実際にはフリーランスとして働き始めてます。検索周りをお手伝いするお仕事を。読解いとこあれば所属するつもりでもいるし。\n\u0026mdash; Jun Ohtani (@johtani) January 27, 2020 フリーランスとして最初の仕事はElasticsearchではなく、Azure Cognitive Searchの支援だったりします。Esで困ってる方の手伝いもしますので、興味ある方はDMください。\n\u0026mdash; Jun Ohtani (@johtani) January 31, 2020 2020年1月24日が、正式なElasticの退職日でした(有給休暇消化してた)。 で、現在のステータスはこのツイートです。\n現在の心境 どこかに就職してガッツリ検索もやりたいし、いろんな会社の検索やElastic Stackに関するお手伝いをするのにも興味があるし、どちらにも興味がある状況です。まぁ、検索に興味が尽きないというのだけは決まってますかね。\n悩んでいるところに、幸いにもAzure Search周りで手伝ってほしいという話が舞い込んできたので、フリーランスとしてお手伝いをさせていただいてます(現時点で、半稼働で、が3月末まで)。\nElastic Stackなどの知見もあるのでのお手伝いをするというのもありかなぁと。お仕事発注してもいいな?という方があれば、TwitterのDMなど、連絡をいただければと。\n現在の状況でした。\n副業ができる会社に就職するのがどっちもできていいのかも?\n","date":1580470659,"dir":"post/2020/","id":"c61a5bda3f1667498626ae52ad0362e0","lang":"ja","lastmod":1580470659,"permalink":"https://blog.johtani.info/blog/2020/01/31/start-freelance/","publishdate":"2020-01-31T20:37:39+09:00","summary":"12月に退職しますブログを書きましたが、その後どうなったのか?という話をしてないなと思ったので、一応現在の状況を書き留めておこううかと。 結論","tags":["転職"],"title":"フリーランスはじめました(仮)"},{"contents":"ブログ移行日記(その4)です。その他の記事はこちら。\nブログ移行日記(その1) ブログ移行日記(その2) ブログ移行日記(その3) ブログ移行日記(その5) 前回までで、なんとなく移行は終わってます。 今回はテーマで使えるようになっているブログの検索機能の導入の話です。\n検索サービスはAlgoliaを利用します。 OctopressのころはElastic社のサービスであるElastic Site Searchの機能を利用して、クローリングしてから検索できるようにしていましたが、Hugoで導入できるモジュール?があったので、今回からこちらに移行しました。\n参考記事 Clean White ThemeのREADME(Algoliaの設定方法) 参考ブログ:hugoで作ったblogにalgoliaで全文検索機能を追加する Algoliaとは? 検索のas-a-serviceをやっている会社です。Wikipediaによると本社はサンフランシスコにあるみたいですね(フランスの会社のイメージでした。起業された方がフランス出身だからかなぁ?)。 クラウドで検索インデックスを保持でき、API経由で検索したり登録したりできる感じのサービスです。内部で使われているのはOSSではない独自の検索エンジンです。\nクラウドで提供されているサービスなのでサクッと検索を使い始めることができるのがいい点ですね。 また、小さな非商用のプロジェクトにフリーで利用できるプランも提供されているようです(2020年1月現在)。\nAlgoliaのサービス登録からインデックス作成 私が利用しているテーマで設定する方法の記載があったので手順の通りにやってみました。 大きく2つの作業(Algolia側とHugo側)が必要です。まずは、Algoliaで必要な作業から。作業の流れだけ記載しておきます。詳細は「Static site search with Hugo + Algolia」の3)を確認してください。\nAlgoliaのサインアップ(すでにアカウントがあれば不要) New Applicationの作成(名前とプランの指定) リージョンの指定 インデックス名の指定 APIキーを確認 です。これで、Algolia側の準備は完了です。\n今回は関係ないですが、Algoliaの管理画面で、利用状況(データ登録などの操作回数、クエリの回数、インデックスに保存されているレコード数)の確認が可能です。 ほかにも有料プランを利用するとAnalyticsなどもできるようです。\nHugo側で必要な設定 今度はHugo側です。Hugoのサイトのディレクトリに移動してからの作業です。\n仕組みとしては、\nHugoのoutput機能でAlgolia向けのJSONファイルを生成する Node.jsのライブラリを使用してAlgoliaに1.で生成したJSONを登録、更新する 検索画面の作成 という流れになります。 ですので、作業としては以下のとおりです。\nOutput出力の設定(すでにテーマ側で設定されているので、特に作業は必要なし) npm環境の構築(Hugoのconfig.tomlと同じディレクトリ階層) Node.jsのインストール(必要であれば) npm環境の初期化 npmでatomic-algoliaのインストール atomic-algolia向けの設定(登録のためのAPI関連の設定) Algolia向けJSONの出力設定 検索関連の設定 content/search/placeholder.mdの作成 検索用のAPIキーなどを設定 npm関連の作業 以下、npm関連の作業です。\nNode.jsのインストール(必要であれば) 割愛します。環境に合わせてインストールしてください。私はnvm経由でインストールしています。 npm環境の初期化 Hugoのディレクトリでnvm initを実行 npmでatomic-algoliaのインストール Hugoのディレクトリでnpm install atomic-algolia --save atomic-algolia向けの設定(登録のためのAPI関連の設定) Hugoのディレクトリに.envファイルを作成し、以下を設定します。 Algolia向けJSONの出力設定 特に変更なし(config.tomlに少し設定があります)。 ALGOLIA_APP_ID=AlgoliaのApplication ID ALGOLIA_ADMIN_KEY=AlgoliaのAdmin API Key ALGOLIA_INDEX_NAME=先程作ったインデックス名 ALGOLIA_INDEX_FILE=public/algolia.json 最後のALGOLIA_INDEX_FILEは固定文字列でいいと思います。 hugoコマンドを実行するとpublicディレクトリ配下にalgolia.jsonというファイルが生成され、Algolia登録用のJSONが出力されています。\n余談 : algolia.jsonの出力の設定は、config.tomlに記載があります。また、JSONファイルのテンプレート自体はthemes/hugo-theme-cleanwhite/layouts/_default/list.algolia.jsonにあります。Algoliaに登録するデータの構造など変更をする場合はこのテンプレートをカスタマイズすれば良さそうです。\n検索関連の設定 実際に検索の画面を表示するために、検索用の画面と、検索用のAPIの設定が必要です。\ncontent/search/placeholder.mdの作成 /search/が検索用のページになります。空のファイルです。実際にはJavaScriptが検索用の窓を表示したりしてくれます(これが必要な理由がまだ不明だなぁ)。 検索用のAPIキーなどを設定 検索のためのAPIキーなどの設定が必要となります。テーマ作者の方のサンプルのconfig.tomlにパラメータは用意されています。 以下の値を設定します。\nalgolia_search = true algolia_appId = \u0026#34;AlgoliaのApplication ID\u0026#34; algolia_indexName = \u0026#34;作成したインデックス名\u0026#34; algolia_apiKey = \u0026#34;AlgoliaのSearch-Only API Key\u0026#34; 以上でAlgolia関連の設定などの作業が終了です。\nAlgoliaへのデータ登録方法 最後に、実際にデータを登録する必要があります。 手順は、以下のとおりです。\nhugoコマンドの実行(htmlと一緒に登録データのalgolia.jsonを生成) npm run algoliaコマンドの実行(atomic-algoliaを利用してAlgoliaにデータを登録) 設定などが問題なければ、Algoliaの管理画面で登録ができているはずです。 実際にブログのデプロイにはdeploy.shというファイルをこちらを元に作成して使っています。このなかで、hugoコマンド実行後にnpm run algoliaを実行するようにしいます。\n今後の課題 Hugoで生成された記事はそれぞれのブログポスト以外に、タグごとのページも生成されています。 こちらも実はAlgoliaのインデックスに登録されていて、タグを入力すると、タグ名のリンクが出てきます。\nこちらはelasticsearchで検索したときの検索結果です。1件目はタグページです。\nこれらのページはAlgoliaに登録しないようにするのが良さそうかな?と考えているところです(考えてるだけ)。\n2020/01/29更新\nlist.algolia.jsonを編集して、記事だけをインデックスするように修正しました。 テーマに存在するlayouts/_default/list.algolia.jsonを、自分のところにコピーし、次のように変更しました。if文を1行追加して、postという種類のものだけを出力するようにしました。\n{{/* Generates a valid Algolia search index */}} {{- $.Scratch.Add \u0026#34;index\u0026#34; slice -}} {{- $section := $.Site.GetPage \u0026#34;section\u0026#34; .Section }} {{- range .Site.AllPages -}} {{- if or (and (.IsDescendant $section) (and (not .Draft) (not .Params.private))) $section.IsHome -}} {{- if (and (eq .Section \u0026#34;post\u0026#34;) (ne .URL \u0026#34;/post/\u0026#34;)) -}} {{- $.Scratch.Add \u0026#34;index\u0026#34; (dict \u0026#34;objectID\u0026#34; .UniqueID \u0026#34;date\u0026#34; .Date.UTC.Unix \u0026#34;description\u0026#34; .Description \u0026#34;dir\u0026#34; .Dir \u0026#34;expirydate\u0026#34; .ExpiryDate.UTC.Unix \u0026#34;fuzzywordcount\u0026#34; .FuzzyWordCount \u0026#34;keywords\u0026#34; .Keywords \u0026#34;kind\u0026#34; .Kind \u0026#34;lang\u0026#34; .Lang \u0026#34;lastmod\u0026#34; .Lastmod.UTC.Unix \u0026#34;permalink\u0026#34; .Permalink \u0026#34;publishdate\u0026#34; .PublishDate \u0026#34;readingtime\u0026#34; .ReadingTime \u0026#34;relpermalink\u0026#34; .RelPermalink \u0026#34;html\u0026#34; .Params.Description \u0026#34;title\u0026#34; .Title \u0026#34;type\u0026#34; .Type \u0026#34;url\u0026#34; .URL \u0026#34;weight\u0026#34; .Weight \u0026#34;wordcount\u0026#34; .WordCount \u0026#34;section\u0026#34; .Section \u0026#34;tags\u0026#34; .Params.Tags \u0026#34;categories\u0026#34; .Params.Categories \u0026#34;author\u0026#34; .Params.authors \u0026#34;content\u0026#34; .Params.Description \u0026#34;excerpt_html\u0026#34; .Params.Description \u0026#34;excerpt_text\u0026#34; .Params.Description \u0026#34;summary\u0026#34; .Summary)}} {{- end -}} {{- end -}} {{- end -}} {{- $.Scratch.Get \u0026#34;index\u0026#34; | jsonify -}} まとめ これで、ブログ内記事検索ができるようになります。 Algoliaは個人の非商用利用の場合、フリープランが用意されているのがありがたいですね。 まだ、Hugoと連携しただけで、Algolia自体でどんな機能があって、どんなことができそうかといったところは調べていませんが、簡単に利用できるのはとても助かります。\nまぁ、個人ブログの検索機能ってそんなに使う人はいないんですが、自分としては便利かなぁと。\n","date":1580186404,"dir":"post/2020/","id":"d9018f459d3c94a91e92b459e152f7e7","lang":"ja","lastmod":1580283604,"permalink":"https://blog.johtani.info/blog/2020/01/28/introduce-algolia/","publishdate":"2020-01-28T13:40:04+09:00","summary":"ブログ移行日記(その4)です。その他の記事はこちら。 ブログ移行日記(その1) ブログ移行日記(その2) ブログ移行日記(その3) ブログ移行日記(","tags":["ブログ"],"title":"ブログ移行日記(その4) - 検索機能(Algolia)の導入"},{"contents":"ブログ移行日記(その3)です。その他の記事はこちら。\nブログ移行日記(その1) ブログ移行日記(その2) ブログ移行日記(その4) ブログ移行日記(その5) 今回は、Hugoの設定とテーマの一部変更した点について記載します。\n設定ファイル(config.toml) Hugoの設定ファイルはconfig.tomlになります。hogo new siteコマンドで生成したディレクトリの中にデフォルトで含まれていますが、こちらではなく、テーマの作者が用意してくれたconfig.tomlを元に変更を加えました。\nちなみにテーマの作者の方が設定とコンテンツを含めたサンプルも公開してくれています。設定やディレクトリの構成はこちらを参考にしました。\n設定ファイルで変更した項目は以下のとおりです。\nサイトのタイトルや説明など 特記することはありません。好きなように変えました。\nbaseurl title SEOTitle description keyword slogan sidebar_about_descrption 画像関連(ヘッダーや著者近影) 画像の置き場はstatic/images/ディレクトリですが、設定ファイルには images/から設定します。\nheader_image : ブログのヘッダー背景 sidebar_avatar : 著者近影 言語周り(特に多言語対応する予定は無いのですが) languageCode = \u0026ldquo;ja\u0026rdquo; defaultContentLanguage = \u0026ldquo;ja\u0026rdquo; オフにした機能、削除した項目 freands = false bookmarks = false 上記の設定変更以外に、[[params.bookmark_link]]や[[params.friend_link]]も削除。\n中国のサービスや、特化した設定など。\nBaidu Analytics関連 Disqus proxy関連 Reward(wechat pay \u0026amp; alipay関連) params.social関連 rss = true twitter linkedin github ほかはすべてコメントアウト。\n外部サービス関連 disqusShortname : Disqusのショートネーム googleAnalytics : Gooogle AnalyticsのトラッキングID algolia関連 : 別のブログ記事として、設定方法などを書きます。 追加した設定(昨日のブログで説明済み) Octopressと同じ形のパーマリンク [permalinks] post = \u0026#34;/blog/:year/:month/:day/:slug\u0026#34; Markdownファイル中のHTMLタグ表示 [markup.goldmark.renderer] unsafe = true 以上が設定ファイル関連です。\nテーマの変更点 テーマそのままでは問題があったり、独自に変更したいという点があったので、いくつか変更をしています。\nフォントの変更 そのままテーマを適用するだけでうまく行けばよかったのですが、フォントの問題が発生しました。テーマの作者の方が中国の方だから?かどうかはわかりませんが、デフォルトのままだと中華フォントになってしまいました。\nあー、中華フォントだな。 pic.twitter.com/OvHpY4LSp1\n\u0026mdash; Jun Ohtani (@johtani) January 16, 2020 config.tomlにcustom_cssという設定があり、こちらで指定したCSSのファイルがテーマのlayouts/partials/head.htmlから読み込まれる仕組みがあるようなので、フォントに関するCSSをこの機能を使用して指定するようにしました。\nconfig.tomlの設定は次のとおりです(リスト)になっているので、複数のファイルに分割して、読み込ませることも可能なのかな?。\ncustom_css = [\u0026#34;css/custom-font.css\u0026#34;] cssファイルについては、static/css/custom-font.cssというファイルを作成し、次のような記載になっています。 フォントの指定と右側サイドバーの自己紹介の部分の文字色を変更するためのものです。\nbody, h1, h2, h3, h4, h5, h6, .navbar-custom { font-family: Helvetica,\u0026#34;Sawarabi Gothic\u0026#34;,Meiryo,\u0026#34;メイリオ\u0026#34;,\u0026#34;Hiragino Kaku Gothic ProN\u0026#34;, \u0026#34;ヒラギノ角ゴ ProN\u0026#34;,YuGothic,\u0026#34;游ゴシック\u0026#34;,Arial,sans-serif; } .sidebar-container { color: #404040; font-size: 14px; } faviconの変更 テーマにfavicon.icoが含まれていたのですが、せっかくなので独自のものに変えてみようかと。 ただ、残念ながら、こちらはパスおよびファイル名がlayouts/partials/head.htmlに直書きされていました。\n画像はimages配下にと思っていたのですが、このパスだけを変更するためにhead.htmlを自分の配下にコピーしてカスタマイズするのもどうかと思った(テーマに変更やバグ修正が入るたびに手動でコピーするのはなぁと思った)ので、static/img/favicon.icoファイルを作成しました。\nテーマよりもHugoのプロジェクトにあるファイルを優先するようなので、ファイルだけをプロジェクトに作成しました。\n記事一覧のテンプレート 記事の一覧で表示される、作成者と作成日時が英語表記でかつ、冗長な感じがしたので、スッキリさせるために、layouts/partials/post_list.htmlをテーマからコピーして、次のように変更しました。\n元の形式は : Posted by author Monday, January 2, 2006 現在の形式 : 2006-01-02 by author 記事のテンプレート 今回採用したテーマでは、記事の先頭に記事のセクションを元に目次を生成してくれるものでした。\n目次をコンテンツから自動で作ってくれるの便利だな。 pic.twitter.com/9bU3sLnUrm\n\u0026mdash; Jun Ohtani (@johtani) January 16, 2020 とても便利です。ただ、表示が「TOC」なんです。 英語でしかも「ToC」という表記ならまだ気にならなかったかもですが、大文字だと流石に気になったので、プロジェクトのlayouts/_default/single.htmlにコピーして「目次」という日本語に書き換えました。 このHTMLにテーマで修正が入った場合はどうしようかなぁ。。。というのが目下の悩みです。。。\nArchetypeテンプレートの追加 最後は新規記事を書くときに生成されるMarkdownのメタデータの追加です。 HugoにはArchetypesというのが存在します。\nHugoではhugo new 記事としたときに、記事の種類(content/ディレクトリ名=記事のタイプ)によって、作成するmarkdownファイルをテンプレートから生成する機能があります。この生成時に使われるのがarchetypesというディレクトリにあるファイルです。\n私のブログサイトでは、今のところcontent/postというブログの記事だけを書く予定ですので、archetypes/post.mdというファイルを作って以下のようなメタデータをhugo newしたときに自動で生成するようにしました(テーマにあったpost.mdファイルの代わり)。\n--- layout: post title: \u0026#34;{{ replace .Name \u0026#34;-\u0026#34; \u0026#34; \u0026#34; | title }}\u0026#34; slug: \u0026#34;{{ substr .Name 11 }}\u0026#34; author: johtani date: {{ .Date }} comments: true tags: [] draft: true --- タイトルはファイル名のハイフンを空白に変換したもの(実際にはファイル名は英語にしているので、使いませんが。。。) slugはファイル名の先頭からYYYY-MM-DD-という11文字を除いたもの。これは、OctopressのURLに合わせるために使用するURLの一部の文字列です。 author: johtani : 著者は私だけだから固定文字列 comments: true : ブログ記事にはDisqusのコメント機能を利用 tags: [] : 各内容によってタグを付けるが、生成時には空 draft: true : 明示的にこの行を消すまではドラフト記事としたいため という感じです。ほかにどのよなメタデータがあるのかまではまだ調べていないので、今後また適宜変更していくと思います。\nまとめ Hugoの設定や、テーマそのままではなく独自の変更を加えた部分を思い出して書き出してみました。\nこれで、Algoliaに関する部分以外はだいたい思い出して書いたと思います。 次は、Algoliaの使い方と設定について書き残す予定です。\n","date":1579853081,"dir":"post/2020/","id":"99c9c80a6532e4ea3b535c5a92d07a25","lang":"ja","lastmod":1579853081,"permalink":"https://blog.johtani.info/blog/2020/01/24/setting-hugo/","publishdate":"2020-01-24T17:04:41+09:00","summary":"ブログ移行日記(その3)です。その他の記事はこちら。 ブログ移行日記(その1) ブログ移行日記(その2) ブログ移行日記(その4) ブログ移行日記(","tags":["ブログ"],"title":"ブログ移行日記(その3) - Hugoの設定と微調整(テーマに合わせた)"},{"contents":"その他の記事はこちら\nブログ移行日記(その1) ブログ移行日記(その3) ブログ移行日記(その4) ブログ移行日記(その5) ブログ移行日記(その2)です。前回はHugoとは?というのと、自分が選んだテーマについて記載しました。 本家の手順などを参考にすると、Hugoにテーマを適用し、でHTMLを生成して、表示するところまでできるはずです。\n今回は、OctopressのmarkdownファイルをHugo用に変換する方法について紹介します。お手製ですが、Pythonスクリプトを作ったので、そちらも合わせて簡単に紹介する予定です。\n参考ブログ 「Octopress Hugo 移行」でググるといくつか出てきます。先人の知恵ありがたいですね。 ということで、私はこちらの2つのブログを参考にさせていただきました。ありがとうございます。\nOctopress から Hugo へ移行した - iriya-ufo\u0026rsquo;s blog OctopressからHugoへ移行する方法 | gam0022.net 画像のコピー 画像はそのまま上記参考ブログを元にsource/imagesからstatic/imagesにコピーしました。特にディレクトリ構造の変更とかもしませんでした。\nコンテンツのコピー こちらは、コピーのタイミングでいくつか変換などの処理を行いました。 ファイルの変換にはPythonのスクリプトを書きました。 自分向けの移行ツールなんで、ディレクトリ名とか引数にすらしてないです。。。\n参考ブログと同様の変換\nメタデータの日付変換 categoriesをtagsに変換 画像タグの変換 タイトル、画像のサイズなどに合わせていくつか分岐があります。 参考ブログとは異なる変換、変更\nコードブロックは無変換 0.60.0からCode Fencesに対応したみたいなので不要でした。 ディレクトリ構造の変更 ファイルを年ごとのディレクトリに格納(これまでは、全てのファイルが同一ディレクトリにあった) 拡張子の変更 (.markdown -\u0026gt; .md) メタデータにauthorの追加(自分しか書かないんですけどね) URLをOctopressに合わせる Google検索からの流入もあり、これまでのURLに変更はかけたくないなと。 こちらも参考ブログに記載があるので、そのまま参考にさせていただきました。\nslugについては、移行ツールでファイル名を元に追加する処理を書きました。\nHTMLを含んだMarkdownの対応 TweetやAmazonのアフィリエイトのリンクがHTMLタグでいくつかの記事に含まれており、デフォルトの設定だと表示されません。 config.tomlファイルに以下の設定を追記することで、出力されるようになりました。\n[markup.goldmark.renderer] unsafe = true 名前がunsafeなので、ちょっと気になりますが。。。 すべての記事を表示してチェックしてみたわけではないので、おかしな記事を見つけた方は連絡をいただけると助かります。\nまとめ OctopressのファイルをHugo用にコピーや変換した方法を思い出しながら書いてみました。基本的には参考ブログに上げた2つのブログを真似したものになります。\n次は、利用したテーマのサンプル設定を元に、自分用に変更した点などについて書き残しておこうかな?\n","date":1579775514,"dir":"post/2020/","id":"018b365b00dd3a6ad17c813d21590549","lang":"ja","lastmod":1579775514,"permalink":"https://blog.johtani.info/blog/2020/01/23/convert-md-from-octopress-to-hugo/","publishdate":"2020-01-23T19:31:54+09:00","summary":"その他の記事はこちら ブログ移行日記(その1) ブログ移行日記(その3) ブログ移行日記(その4) ブログ移行日記(その5) ブログ移行日記(その2)","tags":["ブログ"],"title":"ブログ移行日記(その2) - Markdownファイルの変換"},{"contents":"その他の記事はこちら\nブログ移行日記(その2) ブログ移行日記(その3) ブログ移行日記(その4) ブログ移行日記(その5) 起因 いつものツイートから始まる私の行動です。\n(もしかしたら前に一度おすすめしたかもですが) Goのtemplate構文に拒絶反応がなければHugo割と良いですよ〜。\n\u0026mdash; Nobuyuki Kubota (@nobu_k) October 10, 2019 ってことで、Hugo勧められたし、テーマが豊富だしということで、乗り換えた次第です。\n(元)同僚に教えてもらった記事を見てる。Gatsbyも気になるんだけど、デザインセンスないし、テーマが豊富なのがいいなぁ。/ Comparison of Gatsby vs Jekyll vs Hugo | GatsbyJS - https://t.co/yUbKiBmtMS\n\u0026mdash; Jun Ohtani (@johtani) January 9, 2020 一応Gatsbyのサイトにあった比較も見たのですが、テーマの豊富さが勝ちました。デザインを自分でやれるほどではないので。\n理由 乗り換えるに至ったのは主に2つの理由です。\nOctopressが更新されていない ページが増えてきてサイトの生成に時間がかかる 前に使っていたOctopressもJekyllというものがベースになっていました。 Jekyllは今でも更新があるのですが、Octopressが更新されなくなってしまったのと、Rubyがベースになっているため?なのかはわかりませんが、 ブログのページ数が増えてきて、サイトのビルドに時間がかかってくるようになりました。\n結果 まだ、改良点があるかもですが、とりあえず公開できる感じになったと思ったんで切り替えました。\n前のブログはこんな感じで、\n移行後はこんな感じです。\nHugoとは? 公式サイト こちらにあるように、Go言語で実装されているウェブサイト構築フレームワークです。 Go言語で実装されているのもあり、インストールが簡単でした。 Macを使っていますが、Homebrewでインストールができてしまいます。 他の方法もあるようでしたが、Emacsをインストールするのにbrewを入れているので、brewでインストールしました。\n使い方は色んな人が書いてるし、公式ドキュメントを見ていただけばいいかな。\nテーマとは? Hugoのサイトにテーマの一覧があります。 一応、個人のブログなので、それなりにデザインを入れつつ、他の人と違う感じにしたいなと。 テーマ一覧をざっと眺めて良さそうなのをピックアップしたら、最終的にこちらのテーマになりました。\nClean White それなりに更新されてますし、DisqusとSearch(Algolia)が使えるのでこのテーマに決めました。 テーマのインストール方法などはGitHubのREADMEの「Quick Start」に記載があります。\n私は、Hugo自体の設定などをGitHubで管理したかったので、git submoduleを利用して、次のような構成になりました。\nhugo - main repository ├── archetypes ├── content ├── data ├── layouts ├── public - github.com/johtani/johtani.github.io ├── resources ├── static └── themes └── hugo-theme-cleanwhite - github.com/zhaohuabing/hugo-theme-cleanwhite.git hugo : hugo new siteコマンドで作成されたディレクトリです。このディレクトリでまずgit initしました(このリポジトリはプライベートで管理してます)。 themes/hugo-theme-cleanwhite : テーマのQuick Startにあるgit submodule addコマンドでサブモジュールとしてテーマをインストールしました。 public : hugoが生成するHTMLのトップのディレクトリがこちらです。私はGitHub pagesを利用してブログを公開しているので、git submodule addでjohtani.github.ioをサブモジュールにしました。 Hugoで生成したHTMLなどをGitHub pagesで公開するときの手順などはHugoのドキュメントに記載がありました。\nまとめ Hugoに移行した理由や、Hugoとテーマの簡単な紹介でした。 テーマが豊富なのはデザイン力(りょく)がない身としてはありがたいですよね。 次はOctopressのmarkdownファイルをHugo用に変換したり、それに関する設定周りの話を書く予定です。\n","date":1579659814,"dir":"post/2020/","id":"a65bd31d4c3dab0a41712823a5d6002b","lang":"ja","lastmod":1579659814,"permalink":"https://blog.johtani.info/blog/2020/01/22/intro-hugo-and-theme/","publishdate":"2020-01-22T11:23:34+09:00","summary":"その他の記事はこちら ブログ移行日記(その2) ブログ移行日記(その3) ブログ移行日記(その4) ブログ移行日記(その5) 起因 いつものツイートから","tags":["ブログ"],"title":"ブログ移行日記(その1) - Hugoとテーマ"},{"contents":"5年くらい、Octopressを使用していましたが、更新されなくなっているのと、コンテンツの生成に時間がかかることもあり、 ほかのプラットフォームを使用するように変更しました。\nとりあえず、今回の移行で参考にした記事とかURLをリストアップしてみました。 詳細についてはまた明日以降で。\n参考記事 移行関連 : https://iriya-ufo.net/blog/2018/12/27/octopress-to-hugo/#github-pages- 移行関連 : https://gam0022.net/blog/2016/09/25/migrated-from-octopress-to-hugo/ Hugo自体の日本語紹介記事 : https://knowledge.sakura.ad.jp/22908/ Hugo概要 https://gohugo.io/ テーマ 一覧 : https://themes.gohugo.io/ 利用したテーマ : https://github.com/zhaohuabing/hugo-theme-cleanwhite データ移行 作ったスクリプト : https://github.com/johtani/from-octopress-to-hugo favicon 作ったサイト : http://emblemmatic.org/markmaker/#/ Algoliaセッティング 参考 : https://blog.uni-3.app/2019/01/02/hugo-algolia-search/ GitHub Pagesでの運用 https://gohugo.io/hosting-and-deployment/hosting-on-github/#types-of-github-pages 残タスク Amazonのアフィリンクをきれいに表示するlayoutか何かを用意する? ","date":1579166617,"dir":"post/2020/","id":"3c299a4d77be8b4f886ce9fcd23a2561","lang":"ja","lastmod":1579166617,"permalink":"https://blog.johtani.info/blog/2020/01/16/moving-to-hugo/","publishdate":"2020-01-16T18:23:37+09:00","summary":"5年くらい、Octopressを使用していましたが、更新されなくなっているのと、コンテンツの生成に時間がかかることもあり、 ほかのプラットフォ","tags":["hugo","ブログ","octopress"],"title":"OctopressからHugoへ移行中(まだ途中)"},{"contents":"今年も振り返りブログ書いてます。Sasukeがついてる。\n振り返り(2018年に書いた抱負から) まずは去年の抱負を元に。\nTOEIC 受けました。\nお。TOEICの点上がってた(まだまだだけど。。。)\n\u0026mdash; Jun Ohtani (@johtani) October 21, 2019 無事、上がってました。テストの点数を上げるのが目的ではなく、今の実力が どんな感じかというのを確認するために受けました。 前回までが低かったのもあるんですが。 また、数年後に受けてみるのかな?\nCfP見つけて応募 \u0026amp; いろんな場所に顔を出す 色んな所には顔を出しました。 CfPはそれほど出せていなく、とちぎRubyとDevRelJPで喋った程度かと。 12月に最終出社日を迎えたので、今後は顔を出したりCfP見つけて応募も、 一旦休憩に入る予定です。\nもっとブログ! 12月に入ってから、一気に増えてますねw Elasticでは結局それほどかけなかったなぁ。\nRustの継続 こっちは、書籍も買ったのに手がついてないです。 来年に書籍を読みながら再入門する予定です。\n開発の継続 一応ほそぼそと続けてますが、メンテナンスですね。 Analyzer向けのKibanaのプラグインのバージョンアップにだけ対応していたり。 年初にReact化には着手しました。 あとは、Luceneにちょっとしたパッチ(Lukeの画面とKuromojiのUniDic対応)を送った感じかな。もっとLucene周りやりたいかな。\n日本でエンジニア獲得! トレーナーやエンジニアが入社してくれました! が、私が退職してしまいますが。。。 私自体が次のステップに移らないとなぁと。 Elasticに興味がある人いたら、中の人を紹介できるので声をかけてください!\n振り返り(今年あったできごと) さて、ここからは今年の出来事を。\n検索技術勉強会発足 勉強会運営座談会 初フロリダ 初カナダ\u0026amp;初ナイアガラの滝 退職(予定) 検索技術勉強会ってのをはじめました(はじめましたブログはこちら)。 やっぱり検索の話を聞いたり考えたりするのが好きなので、もっといろんな話を聞く機会がほしいなぁと。ツイートすると何人かの知り合いが手を上げてくれたので、初めて見たのが2月でした。 所属会社もあったので、自分が全面に出ない形で運営に協力するという形式でやっています。なんだかんだでもう4回も開催できています。スピーカーへの声掛けなど、複数人で運営するとそのあたりが多様性が出るし、楽になるのですごくいいなぁと。 来年も2月か3月にやりたいねと話をしているところです。興味のある方は、ぜひスピーカーを!\nで、その流れで、他の勉強会の運営ってみんなどうしてるんだろう? という疑問も出てきたので、勉強会運営座談会なるものもやってみました。少人数で集まって、勉強会の運営ってどんなやり方してます?どんなことに困ってます?みたいなのを共有してみました。 自分自身がそれほど、ほかの勉強会の運営に顔を出してたわけでもなく、やり方をみんなはどうやって共有してるのかなぁ?というのが気になったので。 思った以上に属人化してるのかもなぁというのが感想でした。 ドタバタしてたので、あれからやってませんが、共有する勉強会みたいなのも面白いのかも?\n今年も2回ほどElasticの社内イベントで海外に行かせてもらいました。 5月にフロリダと11月にトロントでした。 フロリダでは、NASAにも行けたし、トロントでは足を伸ばしてナイアガラの滝を見に行くなどもしてみました。こういう機会が定期的にあるのは、いいですよねぇ。\n最後は、退職イベントですね。5年5ヶ月勤めたElasticでの仕事が、12/6で最終出社日でした。実際の退職日は1/24となっています(現在有給休暇消化中)。長かったような、短かったような。日本で1人目で入社してさまざまなことをやらせてもらい、本当に色んな経験ができました。英語も上達したし。 ただ、外にいることでできることがありそうだなと感じたこともあってのこの決断でした。\n最終出社日以降、色んな人とランチさせてもらったりしています。 次に何をやろうかな?ってのんびり考えながら休んでいるところなので。 やっぱり、検索周りのことをやりたいなぁというのが念頭にあるので、そのあたりで模索中という感じです。 が、せっかくの機会なので、少しのんびりしようかなとも思ってます。 なので、プラモデルの作成や配達業(デス・ストランディング)をやってみたり、16インチMacbookのセットアップしながらブログ書いたりしています。 年明けに入ったら、プログラミングもちょっとやりたいな。\nあとこの場を借りて、ブログの欲しい物リストのものを送っていただいた皆様に感謝を述べさせていただきます。本当にありがとうございました!この感謝はまた何かの機会にでも!\n来年の抱負 ということで、来年の抱負です。\n職につく ブログプラットフォームの移行 プログラミング Rust再入門 検索の勉強 検索技術勉強会の継続 まぁ、まずは職につかないとですね。どこかに在籍しつつ、副業で検索周りのこととかやるのもありかもなぁと考えたりしています(プラモデルつくりながらw)。\nブログのプラットフォームをOctopressからHugoあたりに移行しようかなと思ってます。Octopress自体がもう開発がされてないようですし。Hugoだとテンプレート?テーマ?がそれなりにありそうなので良さそうかなぁと。移行プログラムも書かないとかな。新しいものを調べるのって楽しいですよね。\nプログラミングも復活させたいなと。どうしてもこれまでは、しゃべるのをメインにしていたので、後回しにしてしまっていたのもあります。まぁ、向いてないのかもと思ったりもしますが、下手の横好きなりに少しずつでも何かを改善したり作ったりしたいなと。 勉強会の運営周りですこし楽をするためのプログラム書いたりもしているので、この辺もブログに書こうかな?\nRustはTantivyというプロダクトも出てきているし、勉強しようと思って、自転車本を買いつつ、Kindleの肥やしにしているので、手を動かそうとおもいます。 ブログ書いてサボった場合の可視化しないとなw\n検索の勉強もやりたいなと。これまではElasticsearchに注力していましたが、ほかのプロダクトやサービスも調べてみたいなと。教えを請いに皆さんのところにお邪魔するかもしれないので、そのときは優しくしてください。\n今年始めた検索技術勉強会を今後も継続できるようにしたいなと。 で、運営周りを楽にできるような仕組みをもう少し導入できればなぁと考えていきたいなと思います。\nさて、嵐の曲も始まったし終わりです。\n今年も様々な方々に助けていただきました。また、最終出社日以降にランチを一緒にさせていただいたり、遊びに行かせていただいたりとありがとうございました。年明けもひましてるので、ぜひランチしましょうw\n来年はなにやってるんだろうなぁ? 今後も皆さんよろしくおねがいします!!\n","date":1577764743,"dir":"post/2019/","id":"35aa9e09db936aee7ec407c431816573","lang":"ja","lastmod":1577764743,"permalink":"https://blog.johtani.info/blog/2019/12/31/looking-back-2019/","publishdate":"2019-12-31T12:59:03+09:00","summary":"今年も振り返りブログ書いてます。Sasukeがついてる。 振り返り(2018年に書いた抱負から) まずは去年の抱負を元に。 TOEIC 受けました。 お。TO","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2019)"},{"contents":"このブログ書こうと思って、これまでMacのセットアップしてたんだった。。。\n普段、macOSの標準ターミナルを使ってます。 で、ターミナルを使うシーンは次のような感じです。\nブログのデプロイ(参考:Octopress環境のDockerイメージ化) ElasticsearchとKibanaの動作確認 Elasticsearchの起動用ターミナル Kibanaの起動用ターミナル プラグインの開発(elasticsearch-ingest-csv と analyze_api_ui) elasticsearchのリポジトリ kibanaのリポジトリ ingest-csvのリポジトリ analyze_api_uiのリポジトリ 上記のように1.以外については複数のターミナルをそれぞれのディレクトリで起動して使っています。 これらの3つのパターンのときに、毎回ターミナル(シーンによっては複数のウィンドウ)を開いて、ディレクトリに移動って大変だなと。\nウィンドウグループって? そこで、ターミナルに便利な機能がないのかな?と思い、メニューを見ていたところ「ウィンドウグループ」というのがあったので調べて、現在の使い方に至っています。\nウィンドウグループの使い方の説明はこちらです。\n使い方にあるようにウィンドウの場所、設定、タブなどを保存できます。 そして、「ウィンドウグループを開く」というメニューから保存しておいたグループを開くと、簡単に作業環境が再現可能になります。\n開くときのメニューはこんな感じです。\n作り方 ウィンドウグループの使い方に載ってます。 まずは、保存したいターミナルを開いて、開いたときに移動していたいディレクトリに移動します。 複数のタブやウィンドウを開いた状態にしたい場合は、複数ターミナルを起動して、それぞれ移動したいディレクトリに移動しておきます。\nグループとしてまとめたいウィンドウが起動できたら、あとは、「ウィンドウ」メニューの「ウィンドウをグループとして保存」を選択します。\nこれだけです。あとは、使いたくなったときに開くだけです。 簡単ですよね?\n作るときの注意点としては、複数のウィンドウグループを作りたいときは、 それぞれグループごとに作成しては、個別にやる必要があります。 現在開いているターミナルのうち、あれとこれをウィンドウにしたいというやり方はできないので、そこだけ注意点です。 環境ごとにプロファイル(バックグラウンドの色やテーマ)を覚えさせることができるので、1.のシーンだとIceberg、2.のシーンではBasic、3.のシーンではHomevrewで設定していたりします。 (ただ、Preztoのテーマをagnosterにしてしまったので、Basicだとプロンプトが見にくくてしょうがないのですが。。。)\n設定はどんな感じ?? ウィンドウグループの管理については、ターミナルの「環境設定」に管理用の画面があります。\nこの画面でいらないグループを削除したり、設定のエクスポート/インポートも可能です。\n私の使い方 3つの利用シーンは説明しました。 すべてのウィンドウグループを変更するたびにインポート/エクスポートしてます。 上記1.と3.のユースケースはほぼ変更がないので、エクスポートしたものを移植用に管理していますが、2.のユースケースについては、頻繁に更新しています(ElasticsearchとKibanaのバージョンをアップしないといけないので)。\nこのとき、MacのGUIで毎回設定をしているわけではありません。 エクスポートしたファイルは、.terminalという名のXMLファイルになっています。\nその中に、次のようなパスが記述されています。このバージョン番号の部分をアップデートのたびにemacsなどで変更し、ターミナルの管理画面で、削除してからインポートし直すだけで、バージョンアップに対応している感じです。\n\u0026lt;key\u0026gt;Tab Working Directory URL\u0026lt;/key\u0026gt; \u0026lt;string\u0026gt;file://johtani-mac-15.local/Users/johtani/tmp/elastic_stack/v7.5/elasticsearch-7.5.1/\u0026lt;/string\u0026gt; \u0026lt;key\u0026gt;Tab Working Directory URL String\u0026lt;/key\u0026gt; \u0026lt;string\u0026gt;file://johtani-mac-15.local/Users/johtani/tmp/elastic_stack/v7.5/elasticsearch-7.5.1\u0026lt;/string\u0026gt; まとめ ということで、標準ターミナルのウィンドウグループを使うと、よく開くディレクトリやウィンドウ、タブを覚えて置かせることができるので、それぞれの環境向けのターミナルを、好きなときに開くことができるようになります。 私は、ウィンドウは1つで複数のタブをウィンドウグループという形で覚えさせておくことで、各シーンの切り替え、もしくは併用を閉じたり開いたりを簡単にできるようにしています。\n他のターミナルソフトを使うと似たようなことが簡単にできたりするのかな? みなさんがどうやってこのような作業やってるのかな?ってのはちょっと気になるところです。\n余談(いつものようにツイートとその反応) ちなみに、みんなどんなターミナル環境なんだろう?と思いツイートしてみた結果はこちらです。 (コメントRTってうまいことひろえないのかなぁ?)\nMac標準のターミナル使ってる人ってどのくらいいるんだろ?iTermとか入れてるのかな?tmuxとか?\n\u0026mdash; Jun Ohtani (@johtani) December 11, 2019 Iterm2使ってtmux使って今はIterm2だなー\ncommand2回押すだけでターミナル出すくせが抜けん https://t.co/P8o4M1HSoj\n\u0026mdash; GO☆ | TAFDATA (@_gogoponz) December 11, 2019 Alacritty + tmux やなー。標準はもう使ってない。 https://t.co/HI7hPCg3uo\n\u0026mdash; Ryo HIGASHIGAWA (@biwakonbu) December 11, 2019 標準です https://t.co/W27e2pcq3j\n\u0026mdash; shin higuchi @Acroquest (@shin0higuchi) December 11, 2019 Macを買って以来、ずっと結局標準ターミナル以外使っていない感じ。珍しかったのか。。 https://t.co/Zjz32SgjC6\n\u0026mdash; Kazuhiro Hara™ (@kara_d) December 11, 2019 ","date":1577063679,"dir":"post/2019/","id":"1a1a8cc0040b356d06eacd22e0526476","lang":"ja","lastmod":1577063679,"permalink":"https://blog.johtani.info/blog/2019/12/23/whats-window-group-of-terminal/","publishdate":"2019-12-23T10:14:39+09:00","summary":"このブログ書こうと思って、これまでMacのセットアップしてたんだった。。。 普段、macOSの標準ターミナルを使ってます。 で、ターミナルを使う","tags":["misc"],"title":"macOS標準のターミナルのウィンドウグループが便利"},{"contents":"ドットファイル系(.emacsとか)をこれまでは、PCを引っ越すたびにコピーしてたんですが、いいかげん、GitHubとかで管理したいなと。\nで、ツイートしたところ(こればっかりだなw)、homeshick(homesick)が便利だよとの情報を得たので使ってみました。\nhomesick、正確にいうとhomeshickを使ってます。悪くないです\n\u0026mdash; 🤓k.bigwheel🤓 (@k_bigwheel) December 10, 2019 使い方とか 実物はGitHubで公開されていました。\nhttps://github.com/andsens/homeshick\n何者かというと、ホームディレクトリにあるドットファイル(.zshrcなど)をgitコマンドで管理するのを楽にしてくれるシェルの関数群みたいです。 インストールは至ってかんたんで、git cloneで持ってくるだけです。homeshickのリポジトリのREADMEに記載があります。\n使い方はTutorialsにあります。\nhomeshick generate ほげほげで管理する単位(castle)を作ります。ほげほげが名称です。今回私はdotfilesにしました。 homeshick track ほげほげ .zshrcで管理したいファイルを指定します。すると、homeshickが対象のファイル(ここでは.zshrc)をcastleの保存先ディレクトリにコピーしてから、シンボリックリンクをホームディレクトリ上に作ってくれます。 homeshick cd ほげほげで、castleの実際のディレクトリに移動します。実態は.homeshick/repos/ほげほげです。 git remoteコマンドでcastleとGitHubの関連をつけて、あとは、普通にgitコマンドでコミットしたりすればOKです。 すごく簡単に導入できました。あとは、実際にtrackしたいファイルを追加していく感じです。 現状は、.zshrc、.gitconfigあたりを管理しています。 ついでに、homebrewでインストールしたものもbrew bundle dumpで出力して、homeshickで管理することで、brewでインストールしたものの管理もできそう(参考)。\nってことで、至極かんたんでした。すばらしい。\n参考 homeshick Tutorials Qiita : homeshickを使ったdotfilesの管理 ","date":1576624266,"dir":"post/2019/","id":"80c8fca02ebfecc7a931dad1ec38466e","lang":"ja","lastmod":1576624266,"permalink":"https://blog.johtani.info/blog/2019/12/18/introduce-homeshick/","publishdate":"2019-12-18T08:11:06+09:00","summary":"ドットファイル系(.emacsとか)をこれまでは、PCを引っ越すたびにコピーしてたんですが、いいかげん、GitHubとかで管理したいなと。 で","tags":["misc"],"title":"homeshick導入"},{"contents":"Macbook Proが新しくなり、OSがCatalinaになっちゃいました。 これまで使ってた、.bash_profileをコピーしてターミナルを立ち上げたところ、 なんか色々と設定が動いてないな?と思ったら、zshがデフォルトに切り替わってました。\nということで、デフォルト変わったし、時間あるしzshってどんな感じなのか調べてみようと。\n準備前(ツイート) で、ツイートをしたところ、海外の方?より返信が来ました。\nI have a series of posts explaining the transition: https://t.co/dz8QNjxxGf\n\u0026mdash; Scripting OS X (@scriptingosx) December 10, 2019 おもしろそうなので、ざっくりと読んでみました。zshを利用されているTwitterの知り合いの何人かからはzsh + oh-my-zshがいいよとコメント頂いてたんですが、\nMoving to zsh Catalinaからzshがデフォルトになるからと、手元の環境を変更するための話をブログにまとめてくれてます。\nMoving to zsh\nサラッと読んだので、いくつか抜粋すると\nbashでいくつか今設定しているものがあるのでその説明 alias - ファイルをそれぞれの拡張子ごとにアプリを切り替えてる(openコマンドの利用例があって参考になりました)。 functions - manコマンドのときに新しいWindowひらいたりとか shell settings - 大文字小文字関係なくファイル名をTabで候補を表示したり、historyをターミナル個別ではなく共有できるような設定にしたり prompt - 現在のディレクトリがどこかとか表示したり zshの設定ファイル群の説明 shellオプションの抜粋 といった感じでした(途中で読むのやめましたが。。。)\n面白かったのは、Suffix Aliasesです。 ファイル名だけをターミナルで指定すると、拡張子に応じて起動するコマンドを切り替えたりできると(結局まだ採用はしてないですがw)\n結局? 結局、上記ブログを読んでいろんなオプションあるんだなぁ。と思ったのですが、手っ取り早く試すためにPreztoをインストールしました。 以下のような構成になってます。\nなるほど、これがzsh + prezto + powerline fontか。前までgit-promptを拾ってきてbashに組み込んでたけど、ブランチ表示されるし便利だな。 pic.twitter.com/Z2ArBgRZey\n\u0026mdash; Jun Ohtani (@johtani) December 12, 2019 Mac標準ターミナル Iceberg プロファイル Powerline font Prezto agnoster theme - prompt agnoster or ~/.zpreztorc の変更 .zshrcにいくつかaliasなどを追加。参考:gist Preztoのデフォルトでlessなどからエディタを立ち上げるとnanoが起動したので、vimに変更 Preztoが作る設定と自分の設定を混ぜたくなかったので、.zshrcでinit.zshを呼び出し になりました。フォントサイズだけはちょっと大きくしました(老眼ェ。。。) ターミナルの参考にさせていただいたブログは「preztoでzsh構築した時のメモ 」です。\nターミナルソフト(余談?) terminalも人によっては、色んなものを使ってたなと思いツイートしました。 結構みなさん標準のterminalを使ってるみたいでした。ただ、私が聞いたこともないターミナルソフトもちらほらあったので、色々あるんだなぁと。\nMac標準のターミナル使ってる人ってどのくらいいるんだろ?iTermとか入れてるのかな?tmuxとか?\n\u0026mdash; Jun Ohtani (@johtani) December 11, 2019 ","date":1576542903,"dir":"post/2019/","id":"f3ef819656f68b87a91c53afbd441fec","lang":"ja","lastmod":1576542903,"permalink":"https://blog.johtani.info/blog/2019/12/17/move-to-zsh/","publishdate":"2019-12-17T09:35:03+09:00","summary":"Macbook Proが新しくなり、OSがCatalinaになっちゃいました。 これまで使ってた、.bash_profileをコピーしてターミナルを立ち上げ","tags":["misc"],"title":"zshへの移行"},{"contents":"最近使っていたPCが手元からなくなったので、16インチ Macbook Proをセットアップしているところです。 で、時間もあるのでこれまでほったらかしてきた、このブログの環境をちょっと変更しようかなと。\nまずは、変更するにしても、Octopressのブログの環境自体は必要です。 実際に、移行する前のこの記事自体も書いているわけですし。\nただ、今後なくなる環境をローカル環境にセットアップするのもどうかと思い、Docker環境にしてみました。\n参考 \u0026ldquo;Octopress Docker image\u0026quot;でググって出てきたサイトを参考にしました。\n参考ブログ:Octopress in a Docker Container\nセットアップからDockerイメージのビルドまで Docker for Mac自体もインストールしていなかったので、インストールしておきます。 参考ブログの方がGitHubのリポジトリにDockerfileをアップしてくれているので、手順に従い、cloneします。 cloneしたDockerfileの3行目にENV LC_ALL C.UTF-8を追加します(UTF-8でブログを書いており、previewした場合にエラーが出たため) 参考ブログにある「Build the docker image」の手順に従い、Gemfile、.gitconfigをコピーしてイメージをビルドします。 参考ブログの「Rakefile」にあるように、自分のoctopress/RakefileのProcess.spawn(...)にアドレスを追加します(Dockerコンテナの外からアクセスできるように) 自分のoctopressにあるGemfile.lockを削除しました(ビルドしたイメージにはいるGemと一部バージョンが異なる記載のものがあったため) ここまでで、\nDocker run 実際にコンテナを実行するためのスクリプトを書きました(書いたと言っても参考ブログにある起動コマンドを叩いてるだけですが。。。)\nlaunch-octopress-docker.shというファイル名で以下のコマンドを実行してるだけです。\n!/bin/sh docker run -p 4000:4000 --rm --volume /Users/johtani/projects/blog/octopress:/octopress --volume /Users/johtani/.ssh:/home/blogger/.ssh -ti blog/octopress /bin/bash このシェルを起動すると、Dockerコンテナにbashで接続し、/octopressディレクトリにログインしています。 あとは、いつものようにrake new_post[\u0026quot;....\u0026quot;]で新規記事のテンプレートを作成したりすればOKです。\nrake generate; rake previewと実行してからローカルのブラウザでhttp://localhost:4000に接続すればプレビューも可能。\nということで、このDockerファイルとかを持っておけば、他の環境でもかんたんにOctopressの環境が再現できそうです。 先人の知恵有り難し。 これで、クリーンなまま他のブログ環境に移行できそう。\n追記(2019/12/17) Docker環境でいくつか問題があったので、追記しておきます。\nDocker for Macが再起動しない Docker for MacがCatalina環境だと問題があるみたいでした。 CPUの数やメモリの数を変更してDockerを再起動したところ、ずっとStartingのまま。\n解決方法としては、launchctlの設定に$PATHを追加するみたい。これで、問題なく起動するようになった気がする\nsshの設定ファイルの問題 .ssh/configにMacのKeyChainを利用する設定を記載してるんですが、Ubuntu上だとこの設定のせいで、エラーが出てしまいます。 IgnoreUnknownという設定で、知らないオプションがあったら無視するという設定になる模様。ということで、Dockerコンテナ上でrake deployのときにエラーが出てたのが解消できました。\n","date":1576458061,"dir":"post/2019/","id":"1abc586d67f0b6c05fd5e60f25492340","lang":"ja","lastmod":1576458061,"permalink":"https://blog.johtani.info/blog/2019/12/16/dockernize-octopress/","publishdate":"2019-12-16T10:01:01+09:00","summary":"最近使っていたPCが手元からなくなったので、16インチ Macbook Proをセットアップしているところです。 で、時間もあるのでこれまでほったらかしてきた","tags":["octopress"],"title":"Octopress環境のDockerイメージ化"},{"contents":"本日、Elasticでの最終出社日でした。実際の退職日はまだ先ですが、有休消化という感じです。\n思い返せばもう5年と5ヶ月も前ですが、Elastic(当時はElasticsearchって社名だった)に参加しました。\n社名も変わりましたし、プロダクトの数も増えたし、IPOもしました。 初の外資+スタートアップということもあり、ものすごくエキサイティングな5年半でした。 Elasticを離れはしますが、検索自体にはまだまだ興味があるので、LuceneやElasticsearchになにかしら関わる感じのことをする予定です。 検索技術勉強会も今後もやっていきますし。\nただ、激動の5年半だったので、退職日までちょっとゆっくりしようと思っています。 次にどんなことをするのかはまた、別の機会にでも。\nおまけ ということで、まぁお約束です。\nほしい物リストはこちら\n","date":1575615090,"dir":"post/2019/","id":"1bbf2ef67f096960e13d8578fa544536","lang":"ja","lastmod":1575615090,"permalink":"https://blog.johtani.info/blog/2019/12/06/leaving-elastic/","publishdate":"2019-12-06T15:51:30+09:00","summary":"本日、Elasticでの最終出社日でした。実際の退職日はまだ先ですが、有休消化という感じです。 思い返せばもう5年と5ヶ月も前ですが、Elas","tags":["転職"],"title":"退職します"},{"contents":"これは、情報検索・検索エンジン Advent Calendar 2019 の 4 日目の記事です。\n1日目から、質の高いエントリーが続いていましたが、一旦休憩して頂く感じの記事になってます。気軽に読んでくださいw。Advent Calendarつくらないの?と煽ったのもあり、穴を埋めようかなと。 発端 ちょっと先ですがこういうのやります。実装寄りの話やOSS開発に興味がある方,きてください~ / Lucene 版 #Kuromoji のコードを読む会(辞書ビルダー編) https://t.co/NgEmUohoPo #kuromoji\n\u0026mdash; Tomoko Uchida (@moco_beta) September 6, 2019 「Lucene 版 #Kuromoji のコードを読む会(辞書ビルダー編)」という勉強会があり、参加したところ、UniDicの辞書のビルドがコケるという話を聞いたんで、ちょっとやってみるかと。\nちなみに、Kuromojiとは、Apache Luceneに入っている、日本語向けの形態素解析ライブラリです。IPAdicの辞書を内包しており、SolrやElasticsearchといった、Apache Luceneを利用している検索エンジンで手軽に使える形態素解析ライブラリになっています。が、対応している辞書がデフォルトだとIPAdicなのです。\n問題点 LUCENE-4056というIssueが上がっています。\nbuild.xmlには記載はないけど、辞書のビルダーは対応していそうな雰囲気を醸し出しているので、試してみたというのが発端?かと。で、実際に動かしてみると動かない点がありましたと。\nまた、Issueの会話で出ていたUniDicの辞書のライセンスの話もありました。 ただ、UniDicがライセンスを変更したので、このあたりはクリアできそうかなと。\nパッチ ということで、動かしてみていくつか修正してパッチを作りました。\nhttps://github.com/apache/lucene-solr/pull/935\n最近のLuceneはGitHubでプルリク遅れるのが便利ですね。 そんなに大したことはやってないです。以下の点が問題だったので直しています。\nIPAdicとUniDicで語彙定義ファイルのCSVの形式(カラムの数)が異なる unk.defのカラム数も異なる あとは、辞書のダウンロードの部分やbuild.xmlでの処理を追加した形です。 このプルリクを適用したlucene-solrのソースディレクトリを持ってきて、手元でjarをビルドすれば普通はIPAdicの辞書を内包したkuromojiのjarファイルが出来上がります。\nlucene/analysis/kuromoji/build.xmlファイルを、このGistにあるように変更して、ant build-dictとやれば辞書のビルドが可能です。 また、cd lucene/;ant jarとすれば、UniDicの辞書を内包したjarファイルもビルドできます(lucene/build/analysis/kuromojiの下にjarファイルができあがります)。\n確認? 一応、パッチは動くのですが、パッチ自体はUniDicの辞書をビルドする仕組みはオフのままです。なので、テストをどうやろう?というところでやなんで止まっています。。。\nただ、実際に作ったパッチできちんとIPAdicとUniDicがそれぞれビルドできているかの確認はしないとなと。\nということで、2つのjarファイルを読み込んで、それぞれトークナイズして、その出力を表示するツールを作ってみました。\n上記パッチを適用したlucene-solrのソースを持ってきて、IPAdicの辞書を内包したkuromojiのjarファイルと、UniDicの辞書を内包したjarファイルを用意し、ツールの支持に従って、ファイルをディレクトリに配置して、実行すれば以下のような出力がされるようになっています(とりあえず作ったものなので、Javaファイルにトークナイズしたいテキストを書かないといけないのですが)。\nたとえば、「自転車と自動車の違いはなんでしょう?」という文字列を入力すると、以下のような出力になりました。\n+++ ipadic ++++++++++++++ token[0] is [自転車] token[1] is [と] token[2] is [自動車] token[3] is [の] token[4] is [違い] token[5] is [は] token[6] is [なん] token[7] is [でしょ] token[8] is [う] +++ unidic ++++++++++++++ token[0] is [自転] token[1] is [車] token[2] is [と] token[3] is [自動] token[4] is [車] token[5] is [の] token[6] is [違い] token[7] is [は] token[8] is [なん] token[9] is [でしょう] UniDicは[短単位]で語彙が扱われるため、「自転車」や「自動車」がそれぞれ「自転」「車」、「自動」「車」という形でトークナイズされていることがわかります。\nどちらがより便利なのか?というのは用途によっても変わってくるかと思いますが、検索の転置インデックスとしては、より短い単語で区切られている方が、より多くの文書にヒットする可能性が高くなるので、便利な可能性が高いです。\nまとめ ということで、パッチを作ってみたものの、まだ取り込まれていない状況です。 着地点をどうするかって話かなと思っています。興味があれば遊んでみていただければと。\n将来的には、辞書をjarから切り離して別のディレクトリやjarとして使えるようにしようというIssueも作られています。こちらがすすめば、UniDicだけでなく、その他の辞書を切り替えながら使えるようになる日が来るのではないでしょうか?\n","date":1575385200,"dir":"post/2019/","id":"c2d39f2f7fe6cb69fc8efb6c5495c932","lang":"ja","lastmod":1575385200,"permalink":"https://blog.johtani.info/blog/2019/12/04/about-lucene-4056/","publishdate":"2019-12-04T00:00:00+09:00","summary":"これは、情報検索・検索エンジン Advent Calendar 2019 の 4 日目の記事です。 1日目から、質の高いエントリーが続いていましたが、一旦休憩して頂く感じの記事になって","tags":["Lucene"],"title":"Apache LuceneのKuromojiのUniDicビルド対応パッチについて"},{"contents":"Elastic stack (Elasticsearch) Advent Calendar 2019の1日目の記事になります。\nまだ、1ヶ月を残してますが、簡単に今年起こったことを振り返ってみようと思います。毎年恒例ですね、ここ数年。\nElastic Stack 6.6.0リリース(1月) リリース記事はこちら\nElastic APMが6.6のリリースと同時にElastic CloudでAPM Serverが無料で利用できるようになったのが地味に便利でした。APMのデモをやるために、それまでは手元にAPM Serverの起動が必要だったので。。。\nユーザーの方たちにはIndex Lifecycle Management(インデックスライフサイクル管理:ILM)がリリースされたのが便利だったと思います。 まだ、ベータでしたが、インデックスの世代管理を格段に便利にしてくれるツールになり、現在では必須アイテムとなっています。 もう一つ、地味に便利なのは、KibanaからElasticsearchへの接続を複数指定できるようになった点かと思います。\nElatic Common Schemaのベータリリース(2月) リリース記事はこちら\nElastic Stackではメトリック、APM、ログなど、様々なデータを一元的に可視化することができるという利点があります。ただ、一元的にデータを可視化、検索するためには異なるデータセットに統一されたフィールド名が欠かせません。そのための手段としてElasticが公開したのがElastic Common Schemaです。 各種データの項目名、型などを共通化する仕様をGitHub上で公開しています。最近のBeatsのモジュールはこのElastic Common Schemaに則ってデータが定義されるようになってきています。これにより、ログからメトリックへ、APMからログデータへというシームレスな移動ができるようになっています。\nElastic Stack 6.7.0リリース(3月) リリース記事はこちら\nElastic MapsやUptimeといった、これまでの可視化とは異なる便利なアプリが増え始めました。Mapsでは地図の表現が格段にアップしたので、コレまで以上に地理情報と合わせた可視化が楽しくなりました。\nもちろん、基本的に必要な技術が着実にGAされていくのもElastic Stackの素晴らしい点です。\nIndex Lifecycle Management(ILM)がGA Cross Cluster Replication(CCR)がGA CanvasがGA Logs \u0026amp; Infra UIがGA Elastic Stack 7.0.0リリース(4月) リリース記事はこちら\nメジャーバージョンのリリースです。 KibanaのUIが刷新されたり、Elasticsearchのクラスター管理の機能が新規に構築されたり、様々な改善がこのリリースでも入っています。また、メジャーバージョンのリリースのタイミングが、さまざまな大きな仕様の変更や改善が入るタイミングでもあります。これまで以上にパフォーマンスが改善(Top-Nクエリ高速化など)されたり、新しい機能の追加(ナノ秒のサポート)されたりしました。\nElasticsearchのセキュリティの主要な機能が無料に(5月) リリース記事はこちら\n6.8.0および7.1.0のリリースはこの機能の無償提供となりました。 結構衝撃的な話だったのではないかなぁと。これ以前は有償の機能だったセキュリティの以下の機能をElastic License配下で無料で提供する形に変わりました。まだ、ご存知でない方は、データの安全のためにもセキュリティ機能を利用することをおすすめします。\nTLSによる通信暗号化 ユーザー作成と管理にファイルおよびネイティブのレルム認証を使用可能 クラスターAPIとインデックスに対するユーザーアクセスの管理にロールベースのアクセス制御を使用可能、またSpaces機能でKibanaのマルチテナンシーの安全性を向上 Elastic{ON}19開催(5月) 今年も東京で開催しました。ビデオなどはこちらで公開されています。 https://www.elastic.co/elasticon/tour/2019/tokyo\n今回も偉そうにElatic Stackの新しくなった点を紹介するなどしてました。。。\nElastic Stack 7.2.0リリース(6月) リリース記事はこちら\nElastic SIEMがベータリリースされたのがこのタイミングです。 2月の発表したElastic Common Schemaをフルに活用していると言ってもいいのがこの機能になります。まだ今後もどんどん改善が入るであろうきのうになります。\nまた、Elasticsearchをバックエンドにした検索ミドルウェアとして利用いただけるElastic App Searchのセルフマネージド版もこのタイミングでリリースされています。\nさらに、このリリースの直前にはElastic Cloud on Kuberunetes(ECK)というものベータリリースされました。少しわかりにくいかもですが、ElasticsearchやKibanaをKubernetesのOperatorとして利用できるようになっています。こちらもElastic Licenseでリリースされているのでk8s上でKibanaやEsを管理しようとしている方は触ってみると面白いかもです。\nElastic Cloud Elasticsearch ServiceがGCP日本で利用可能に(7月) リリース記事はこちら\nElastic Cloudもプラットフォームが拡大した年でした。 Google Cloud Platformの東京リージョンを選択できるようになりました。さらなる統合(支払いをGCP経由にまとめたり、GCPのコンソールから利用できたりなど)も進んでいます。\nElastic Stack 7.3.0リリース(8月) リリース記事はこちら\nデータフレームと呼ばれるデータ取り込み時のピボット機能が導入されました。また、MapsのGAリリース、Elastic APMの.NETエージェント正式リリースなど、細かいですが様々なものがリリースされています。\nElastic Cloud Elasticsearch ServiceがAzureで利用可能に(9月) リリース記事はこちら\nMicrosoft Azureへのデプロイも可能になりました。残念ながらまだ日本リージョンには来ていないですが、今後出てくるはずです!さまざまなクラウドベンダーのサポートにより、より多くの人に使っていただけるようになるのかと。\nElastic Stack 7.4.0リリース(10月) リリース記事はこちら\nもう7.4.2まで出ていますが、いい感じの間隔で7.0、7.2、7.3と来ていますね。 7.4では、スナップショットリストアがKibanaから簡単に行えるようになりました。これまではKibanaのConsoleでJSONを見ながら管理されていたかもですが、GUIにより今どんなスナップショットがあるのか、どれをリストアするのかといった操作が簡単にできるようになっています。\nKibanaについてはPKI認証のサポートなども始まり、様々な認証方式でより便利にKibanaが使えるようになっています。\n12月? 12月ですし、Elasticsearch勉強会では「LT&忘年会」ということで、懇親会がメインの勉強会として12/6に開催します。悪路クエストの緑川さん、吉岡さんに主体となっていただき、マイクロソフトさんを会場に借りて開催予定です。興味のある方はぜひご参加ください。 LTもおまちしています!\nまとめ 駆け足でしたが今年を振り返ってみました。 今年も色々ありました。残すところあと1ヶ月です!\nさて、Elastic Stack Advent Calendar 2019は今日から25日まで続きます。今年はその2もできています!こらからの記事を楽しみにしています! 本日はその2で[kaibadash@github]さんが「5分でできるElastic stack環境構築」というのを書いてくれてるはずです!\nということで、次はKunihikoKidoさんの「 Elastic Cloud を使うようになって設計方針やら変わったことについて書きます。」になります。お楽しみに!\n","date":1575126000,"dir":"post/2019/","id":"78da47d61c91c82809a3c97a791d26d2","lang":"ja","lastmod":1575126000,"permalink":"https://blog.johtani.info/blog/2019/12/01/whats-happen-at-elastic-in-2019/","publishdate":"2019-12-01T00:00:00+09:00","summary":"Elastic stack (Elasticsearch) Advent Calendar 2019の1日目の記事になります。 まだ、1ヶ月を残してますが、簡単に今年起こったことを振り返ってみようと思います。毎年恒例ですね、","tags":["elasticsearch"],"title":"2019年のElastic StackとElastic"},{"contents":"Bonfire Data \u0026amp; Science #1にブログ枠で参加してきました。 ということで、メモです。\n日時 : 2019/10/25 19:00 - 21:30 場所 : Yahoo! Japan サイト : https://yj-meetup.connpass.com/event/148121/ ハッシュタグ: #yjbonfire 概要 Data \u0026amp; Scienceとは? データとサイエンスに関わる人達の情報共有のための勉強会/交流会\nサイトから引用です。\n第1回のテーマは「画像検索」です! 最近EC系のサイトで類似画像検索が出来るようになったけどどうやってるの? 画像検索のモデルってどうしてるの? 画像検索のインフラはどうしてるの? 私たちの会社でも画像検索を用いたサービスを構築できるだろうか? こういった疑問に答えたり、いま抱えている悩みを解決するヒントを得る場になればと思っています。 今回は、画像検索を行なっているヤフー, メルカリ, ZOZOテクノロジーズの3社に事例と基盤技術について登壇いただきます。 QAはこちら。https://app.sli.do/event/w3wayjmv/live/questions\nMercari画像検索について(仮) 発表者:荒瀬晃介(株式会社メルカリ / AIエンジニアリングチーム)\nAIエンジニアチーム\n写真検索プロジェクトのTech Lead\niOSのみで提供の写真検索\nシステムオーバービュー\nMobileNet v2で特徴抽出 ANNのインデックスを使ってDBに入れる 論文も発表済み(3本)\n今日の発表はこの内の2本を元に話をします。 C2Cでの問題点 商品は床やテーブル上で撮影 クエリは着用(着ている)画像が使われやすい。 人が写ってる写真が結果に多いと業者が出展しているように見えてしまう。 提案手法 人が写ってるものから人の代表ベクトルを抜き取る (クエリ時にのみ処理を実施しているので変更が容易) 特徴変換ベクトル トップスなど、分類ごとに学習させてからベクトルを構成 なんでMobileNet v2? エッジデバイスでの処理を見据えて選択 インフラ Docker + k8s\nCRDを使ってる?\ntraining\nコンテナベースパイプライン いくつかのバッチ処理を工程ごとにパイプライン化 バッチ実行情報をカスタムリソースとしている=再実行が簡単(復旧作業が容易) 画像を扱う=ダウンロードが時間がかかる -\u0026gt; 復旧しやすいようにPVにある程度キャッシュさせている Serving\u0026hellip;\nGCP側 なぜ2つに別れてるんだろう?実際のサービスも2つに分かれてたりするんだろうか?\n将来の展望 Realtime Image Search カメラでものを写している状態でそれが何かを検索できる。 物体検出+特徴抽出をエッジで行うためできる エッジの性能により違いが出てきたりするっぽい QA Q: 業者が想定されると、購入意欲を下げるというのは実験した結果?それとも想像? A: 実験はしていないが、e-commerceにおいての研究がある Q: どういう理由でマルチクラウドにしたんでしょう? A: 画像のマスターがAWS。メルカリのマイクロサービスはGKEなので、サービング環境がGCP Q: 画像の内、服のエリアが大部分で体の面積が少ない場合と、メガネや帽子のように、アイテムの方の面積が少ない場合で、トレーニングに必要なデータ数は変わりましたか? A: カテゴリによる性質の違うはある。ので、改善は必要。 ZOZO画像検索について(仮) 発表者:平田拓也(株式会社ZOZO / AIエンジニアリングチーム)\n(聞き逃した。。。)\nWEAR\nマルチサイズ\nチーム構成 研究所+ML Opsチーム 使用しているアルゴリズム 物体検出アルゴリズム 特徴量抽出アルゴリズム 近似最近傍探索(approximate nearest neighbor, ANN) インフラ GCPを採用。 BigQuery上にデータ基盤がある Managed GPUが必要 なんでk8s? コンテナ Cloud Runがなかった アーキテクチャ マイクロサービス化されている Google Cloud Next 2019 Tokyoでsonotsさんの発表があるよ 監視項目 CPUなどは見ていない レスポンスタイムとステータス監視 リクエスト数 APM 使ってるものStackdriver + Datadog + Sentry Warningが30分で続けたら通知などができるのがStackdriver 画像検索の改善のためにやっていること 課題 レイテンシーが大きい 推論が大変? 急激なトラフィックの増加に対応できない GPUのスケールアウトが問題 -\u0026gt; 先行投資が必要 流れ キャッシュありなし 物体検出 (GPU) 特徴量抽出 (GPU) 近似最近傍探索 DBから取得 2と3が問題\n2と3を特徴量DBという形でデータが登録された時点で特徴量などを計算してしまうことでGPUへの依存をなくした。 Apache AirFlowが便利? Cloud ComposerとApache AirFlow Cloud Composerに関するいくつかのTipsがありました。\nQA Q: 推論をCPUでやったらどれぐらい遅いんだろう A: GPUインスタンス代金 \u0026lt; それと同等の速度を出すためのCPUインスタンス代金 Q: k8sスケールアウト時のリソース割当を最適化する為、resource limit / request標準化 or 時系列分析などから自動調整するなどはされていますか? A: \u0026hellip;聞き逃した Q: (TCOを考慮したクラスタ構成) Cloud Composerの値段が高いようなパプリッククラウド利用の課題対策としてプライベートクラウドとのハイブリッド構成にされているのでしょうか?もしハイブリッド構成でしたら、パブリック or クラウドを切り分ける基準はございますか。 A: GKEオンリー Q: cloud composerでairflowを使う辛い点は? A: 不安定さ。。。 Yahoo!ショッピングにおける画像検索(仮) 発表者:佐藤 純一(ヤフー株式会社) 商品検索APIの開発とか検索エンジンの保守とか 類似画像検索システムの開発が直近の仕事 類似画像検索 ヤフーショッピング 3億の商品 ファッション系はビジュアルが重要=言語による表現が難しい iOSとAndroid Androidだとカメラで撮影してから検索みたいなことも可能 システム概要 物体検出 ノイズ除去 特徴抽出 インデックス(NGT) -\u0026gt; https://github.com/yahoojapan/NGT 1000万件を超える 検索 アプリの画像をAPIに投げてベクトルから、近いものn件を取得 ベクトル化/インデックス更新 GPUマシン Kafka使ってる クラウドストレージに日次?バックアップみたいに保存 差分更新の仕組みがある メンズとレディースは分けている 絞り込み検索のために分離(インデックスのメタデータとしてタグがある) システム構成 Python Kafka TensolflowServing 可視化?監視?はGrafana+Prometheus 開発を通しての学び 自動デプロイとかテスト 検索精度の確認ツールを作る コレ重要だよね。何が変更してるかとか、何が正しいかってのが必要だし。。。 復旧可能、早期復旧の仕組みを容易 今後の方針 対象商品の拡大 物体検出特徴抽出モデルの性能改善 NGTの検索システムをValdに移行 Vald k8s上で動作、分散検索、分散インデキシングなどの機能を提供予定 QA Q: iOS(既存の画像)とAndroid(カメラで撮る)で画像検索の方式が違うのはなぜ? A: アプリの違い Q: 1枚の写真に沢山写っている中で、対象の商品をどう識別しているんでしょう。靴もトップスもボトムスも写っていたら、かなり難しそう A: Yahooブラウザの場合は1番大きな領域のものを選択。Yahoo shoppingだと選択可能 NGTについて(仮) 発表者:岩崎 雅二郎(ヤフー株式会社) 類似画像検索を20年くらいやってる 近傍検索ライブラリ https://github.com/yahoojapan/NGT\n高次元ベクトルの近傍検索 ツリーとグラフによるインデックス 近傍検索とは?\n距離空間上でのクエリの近傍のオブジェクトを取得 k最近傍検索(通常はこっち) 範囲検索(あんまり使われない) NGTの特徴\n世界トップレベルの高速高精度な近似近傍検索 OSS 追加削除が可能(削除がとくに難しいらしい) 多様な利用形態(Python、C++、C、Go、コマンドライン) サーバ版NGT(ngtd、vald)を提供 共有メモリ版でメモリサイズ以上のデータ登録可能 量子化版NGT(NGTQ)により。。。 ANNベンチマークによりテスト\n実行環境が決められているらしい。誰が実行しても比較可能 グラフベースの検索の仕組みのほうが性能がいいというのがベンチマーク結果からわかる なんではやいの? インデックス生成 ツリー(グラフの探索起点の取得に利用する。DVP-tree) グラフ(ANNG) ノードを逐次追加しつつ、近傍ノードを検索してから接続するというのを繰り返している 検索 ツリーから絞り込みつつ、グラフを検索する ANNGに課題があるのでONNG(Optimized Nearest Neighbors Graph)に ノード単位の次数(入出)を最適化 データセットによって有効な次数が違う。。。 NGTを利用した深層学習で。。。 Yahoo!ラボ FavNavi 特徴量の構成(低次特徴量(300次元)、カテゴリ特徴量(128次元)、領域アスペクト比(1次元)) 個別の特徴量だけだとイマイチな結果になるが、組み合わせるといい感じになる モデル性西洋学習データ スライドがあればいいなぁ(表書くの大変だし。。。)\nQA Q: 実際のお客さまの利用を考えると、近似近隣の密度が異なるので、近いものばかりの検索結果や遠いものも含んでしまった検索結果が出ると思うのですが、遠いものが含まれてしまうと、閾値でフィルタしたりするのでしょうか? A: NGTは近いものしかないので、外れ値ってなんでしょう。。。 検索のフィルタリングをある程度している(カテゴリとか)。 まとめ 慣れない分野の話を聞きながらざっとメモを取ったものなので役に立つかはわかりませんが。。。\nアルゴリズムとかまでは得意ではないんですが、画像「検索」ということで参加してみました。 実際に画像検索の仕組みがどんな感じでできているのか、どんな技術がつかわれているのか?ってのがわかったのは 面白かったです。確かに検索のためのキーワードって出てこないことあるしなぁと。 あー、こんなかばんほしいとか、これなんだろ?みたいなのあるからなぁ。\n","date":1572000002,"dir":"post/2019/","id":"11b3a28b536f34d3606427f835bd3ddf","lang":"ja","lastmod":1572000002,"permalink":"https://blog.johtani.info/blog/2019/10/25/bonefire-01/","publishdate":"2019-10-25T19:40:02+09:00","summary":"Bonfire Data \u0026amp; Science #1にブログ枠で参加してきました。 ということで、メモです。 日時 : 2019/10/25 19:00 - 21:30 場所 : Yahoo! Japan サイト : https://yj-meetup.connpass.com/event/148121/ ハッシュタグ: #yjbonfire 概要 Data \u0026amp; Scienceと","tags":["勉強会"],"title":"Bonfire Data \u0026 Science #1に参加しました"},{"contents":"この間のElasticsearch勉強会でAcroquest Technologyの人たちが技術書展7で販売されていた書籍を頂いてしまいました。なので、軽く読んでの感想と宣伝です(これ、電子版とかで買えないのかな?)。\nElasticのパートナーとしても活躍していただいてますが、こういう感じでさまざまなところでElastic Stackを広めていただいていて感謝しかありません。\n章立てとしては以下の通りです。\nElasticsearchでエンタープライズサーチを実現する 同僚が作成、メンテナンスしているFSCrawlerを使った例も書かれています。ローカルのファイル(PDFやJSONとか)をサクッとElasticsearchにインストールしたりするのには便利です。 Kibana Canvasによる柔軟な可視化 Canvasについてどんなものなのか?というのとelasticcofeeというサンプルを元に、その変更の仕方などが説明されています。 Elastic APMによるアプリケーションパフォーマンス監視 Go AgentとAPM自体の使い方の説明です。最近強化されている他の機能との連携(AlertingやMachine Learning)についても触れてくれています。 Kubernetesクラスタのメトリクス・ログ・性能情報の可視化 Azure上でAzure Kubernetes Serviceの上で動いているアプリなどをBeats、APMでデータを取りつつ、他のAzure上にAzure Marketplaceのテンプレートを用いて起動したElasticsearchとKibanaの環境を用いて可視化する方法が説明されています。 ということで、薄い本ですが、手順をおって説明されていたり、7.3と新しいバージョンで書かれているのですばらしいなぁと。 前作の「Elasticsearch NEXT STEP」に引き続きインプレスさんから出たりするのかなぁ?\nちなみに、Elastic APMのRubyに関して興味がある方は、私が前に発表したときの資料がありますので、こちらを参考にしてみてください。\n","date":1570690589,"dir":"post/2019/","id":"d8041ae308961666b15aa1e57b0f9f35","lang":"ja","lastmod":1570690589,"permalink":"https://blog.johtani.info/blog/2019/10/10/review-es-next-step-2/","publishdate":"2019-10-10T15:56:29+09:00","summary":"この間のElasticsearch勉強会でAcroquest Technologyの人たちが技術書展7で販売されていた書籍を頂いてしまいました","tags":["書籍"],"title":"Elasticsearch NEXT STEP 2を頂きました"},{"contents":"Twitterで「Meetup.comに切り替えたらー」みたいな話があったので、 受付用アプリとかなくてという話になったので、普段Elasticsearch勉強会で使用している QRコード生成の仕組みを紹介してみようかと。\nHTMLだけで済むようにQRコードを生成するjquery.qrcode.min.jsってのを使用してます。\nHTMLコードはこちら。\n仕組み 1枚だけのHTMLを生成 MeetupのOAuth2の仕組みを利用(consumer keyを発行する必要あり。) Meetup APIを利用してユーザー情報取得 取得したユーザー情報をGoogle Formに埋め込んだ形で表示するURLを組み立てる 組み立てたURLをQRコードにしてHTMLに表示 受付で、QRコードリーダーを使って、QRコードを読み込むとGoogle Formが開くので、「送信」ボタンを押す 1. HTMLの作成 QRコードを表示するためのHTMLを作成します。Gistに貼り付けてあるので、参考にしてもらえれば。 いくつか埋め込まないといけないものがあるので、個別にそれは説明します。\n2. Google Formの準備 Elasticsearch勉強会では、出席者の情報として、IDと氏名をリストとして保存しています。 目的としては、何人実際に参加したかを計測するのが目的です。 ですので、参加者リストのGoogle Formを作成します。 で、作成した後に、プレビューを表示する。こんな感じ。\nこの時のプレビューのURLをQRコードのURLとして使いたいので、このURLをQRコード表示のHTMLに埋め込みます。\nfunction createGoogleFormURL(data) { var obj = { \u0026#34;entry.1744035444\u0026#34; : data.id, \u0026#34;entry.2031666715\u0026#34; : data.name }; return \u0026#34;https://docs.google.com/forms/d/e/\u0026lt;GOOGLE_FORM_ID\u0026gt;/viewform?\u0026#34; + $.param(obj); } ここら辺です。 returnに書いてあるhttpsで始まる文字列をまず、先ほどのURLで置き換えます。 次に、プレビューのHTMLの中から\u0026lt;input\u0026gt;タグを探して、nameの値を抜き出します。 それをobjのキーに利用します。entry.で始まる文字列が該当します。\nこれで、このURLをQRコードにすれば、値(ここだとIDと氏名)が埋め込まれた形のGoogle Formがスマホのブラウザで起動します。\n3. Meetup APIの準備 MeetupのAPIを利用できるようにします。Meetup.comにログインするとみれるAPIのページがあります。 https://secure.meetup.com/meetup_api\nまず、OAuthを利用するためのConsumer Keyを発行します。\nメニューのOAuth Consumersをクリックして、\n\u0026ldquo;Create New Consumer\u0026quot;をクリックします。 すると、次のような画面が開きます。\nConsumer nameとRedirect URIが重要です。\nConsumer nameはユーザーがMeetup経由で認証するときに、その認証画面で表示される名前になります。 わかりやすい名前を表示してあげると良いかと。\nRedirect URIが一番重要です。実際にOAuthで認証が通った後に表示するHTMLを提供しているURLを指定します。 Elasticsearch勉強会の場合は、私のドメインにwwwをつけた\u0026quot;https://www.johtani.info\u0026quot;を指定しています。 実際にQRコード表示用のHTMLを配置するHTTPサーバーのトップのURLを指定します。 (ちなみに、私のウェブサーバーはS3で運用してます。ですので、HTMLをS3のバケットにアップロードしてあるだけです)\n必須項目を入力したあと、最下部にあるRegister Consumerボタンを押せばキーが生成されます。 生成されたキーがOAuth2のURLのパラメータに必要になります。\nこれで、リダイレクトの準備が整いました。\nOAuth2のURLには、Implicit Flowを利用します。 これで、リダイレクト先のHTMLにトークンがわたるので、Meetup APIにこのトークンが使えるようになります。\n認証用のURLはこちらです。このURLを参加者宛のメールに入れて毎回送信しています。\nhttps://secure.meetup.com/ja-JP/oauth2/authorize?response_type=token\u0026amp;redirect_uri=\u0026lt;QRコード表示HTMLのURL\u0026gt;\u0026amp;client_id=\u0026lt;コンシューマーキー\u0026gt; 参加者はこのリンクをクリックすることで、次のような画面が出てきます。 ログインしていない場合はLog in画面が表示され、まずはログインを促されます。\nで、Allowをクリックすれば、redirect_uriに指定されているページが表示されるわけです。\nQRコード表示用のHTMLでは、次のAPIを使用して、ログインしているユーザーの情報を取得してきています。\nfunction getMemberId() { $.getJSON(\u0026#39;https://api.meetup.com/2/member/self/?only=id,name\u0026amp;access_token=\u0026#39;+ getToken(), displayQRCode); } ここで取れた値が、先ほどの「2. Google Formの準備」で説明したコードのdataの部分に渡ってくるわけです。\nfunction createGoogleFormURL(data) { var obj = { \u0026#34;entry.1744035444\u0026#34; : data.id, \u0026#34;entry.2031666715\u0026#34; : data.name }; return \u0026#34;https://docs.google.com/forms/d/e/\u0026lt;GOOGLE_FORM_ID\u0026gt;/viewform?\u0026#34; + $.param(obj); } 4. QRコードの表示 あとは、jquery.qrcode.min.jsを使用してURLを表示するだけです。\nfunction displayQRCode(data) { $(\u0026#39;#qrcode\u0026#39;).qrcode({width: 128,height: 128, text:createGoogleFormURL(data)}); } サイズとURLを指定するだけですね。\nまとめ あとは、受付で、参加者の方が表示してくれたQRコードをスマホのQRコードリーダーやカメラで読み込めばGoogle Formが開いて必要な情報は入っているので、「送信ボタン」を押せば参加者リストが出来上がっていくという形になります。\n毎回勉強会の前日に、前回のGoogle Formを「コピー」してから、各回の勉強会の登録者フォームを作成しています。 コピーすることにより、Google Formの\u0026lt;input\u0026gt;タグに使用されるnameもそのままコピーされるので、 QRコード生成用のHTMLを書き換える部分の手間が減る形になっています(気づくまで数回かかったw)。\nですので、QRコードのHTMLの中身としては、「勉強会のページへのリンク」、「Google Formへのリンク」の2つを書き換えてから毎回アップロードしているだけとなっています。\nこのやり方が、スマートかどうかはわからないですが、受付アプリがない中、Meetup.comから取得した参加者リストのExcelやプリントアウトしたリストを元に参加者をチェックするよりは、手間が省けてるんじゃないかなぁと。\n残念ながら、QRコードの存在を知らないでそのまま勉強会にくる人がいるので、受付で最低一人はMeetup.comの参加者リストから、 名前を検索してチェックするという作業もやってもらってます。 QRコードを持ってきた方がすんなり受付を通過できるようになってますので、ぜひQRコードを持って勉強会にきてもらえればと。\n","date":1560939044,"dir":"post/2019/","id":"d96f80f23543850a2ee9fff8cd2cc53f","lang":"ja","lastmod":1560939044,"permalink":"https://blog.johtani.info/blog/2019/06/19/qr-code-with-meetup-dot-com/","publishdate":"2019-06-19T19:10:44+09:00","summary":"Twitterで「Meetup.comに切り替えたらー」みたいな話があったので、 受付用アプリとかなくてという話になったので、普段Elasti","tags":["勉強会"],"title":"勉強会の受付自作?アプリ?HTMLについて"},{"contents":"Elasticsearch勉強会や検索技術勉強会やってるんだけど、独学で勉強会やってるなーと思い、みんなはどうやってるんだろうとツイートしてみたところ。\nあー、勉強会運営座談会したい。\n\u0026mdash; Jun Ohtani (@johtani) 2019年4月2日 面白そう\n\u0026mdash; 機械の体を手に入れるのよ鉄郎 (@tetsuroito) 2019年4月2日 やってみるか。\n\u0026mdash; Jun Ohtani (@johtani) 2019年4月2日 やりましょう\n\u0026mdash; 機械の体を手に入れるのよ鉄郎 (@tetsuroito) 2019年4月2日 ってことで、何人か釣れたので、勉強会運営座談会をやってみました。 会場提供していただいた、Classiさんありがとうございました!\n参加してくれた人たちはまぁ、勉強会のサイトを見ていただければなんとなくわかるかなと。 自己紹介とどんな勉強会、読書会運営してますってとこから始めて、次のようなトピックについてピザ食いながら3時間くらい話しました。\nスピーカーの募集方法 運営側から声かけてる?それとも公募してる? 登壇時間とかどうしてる? スピーカーになってもらうためになんかやってる? スケジュール管理 会場探し、スピーカー探し、イベントページ作るタイミングは? 複数拠点開催したことある? ハンズオンとかはどうしてる? 土日開催?平日開催? アンケートとってますか? 使用してるイベントサイトは? ドタキャン対応どうしてる?出欠とったりしてる?懇親会の規模とかどうやって見積もってる? 運営費用関連はどうしてる? グッズとか、ツールとか、スピーカーへの謝礼とか 運営って複数でやってる? その時のツールは? 運営メンバーにはどうやってなってもらう? 録画配信とかまで手が回る? 会場探すの大変じゃない? 会場の部屋の使い方はどうしてる? 行動規範とかどうしてる? 読書会の場合に人が減ってったりしない? まぁ、こんな感じです。色々話してメモしてたんですが、まぁトピックくらいで。\nそもそもは、勉強会の運営って本業ではない(はずな)ので、いかに楽をしつつうまく運営できるかってのを知りたいのと、 他の人どうやってるかってのからアイデアもらえるといいなーと思ったんでやってみました。 他のツールがどんなものかとか知れたし、あー、そういうやり方すればいいのねーみたいなのも知れたので、次回以降の勉強会に活かせればなーと。 自分がやってるやり方とかもブログ書くといいのかなぁ?\n残念です!次回もやるかもしれないので、 @johtani さんに期待してください!\n\u0026mdash; 機械の体を手に入れるのよ鉄郎 (@tetsuroito) 2019年4月25日 次回やるのかなぁ?興味ある人いるのかなぁ?\n","date":1556204526,"dir":"post/2019/","id":"538e38fbc3f78cd61e1841d8141ddcc1","lang":"ja","lastmod":1556204526,"permalink":"https://blog.johtani.info/blog/2019/04/26/meetup-organizer-drinkup/","publishdate":"2019-04-26T00:02:06+09:00","summary":"Elasticsearch勉強会や検索技術勉強会やってるんだけど、独学で勉強会やってるなーと思い、みんなはどうやってるんだろうとツイートして","tags":["勉強会"],"title":"勉強会運営座談会ってのをやってみた"},{"contents":"どーも、johtaniです。\nSearch Engineering Tech Talkという勉強会に運営として参加して、第1回の勉強会を開始しました。 本日(2/26)は第1回目だったので、ブログを残しておこうかと。\n勉強会自体の資料については第1回の勉強会のページにあるし、勉強会の感想とかブログはツイートやみんながブログを書いてくれると思うので、勉強会開催の経緯などについてブログを残しておこうかと。\nなんで始めたの? 私自身が古くはFAST Searchに始まり、何か縁があって、 検索のシステムに長く携わってきたこと(Apache Solrの本書いたり、Elasticsearch勉強会始めたり)もあり、 検索が面白いなと日々思ってます(思ってるだけかもしれないが)。\nで、これまでElasticsearch勉強会をやっているのですが、検索エンジン固有の話ではない、 いわゆる検索の共通の課題というのがあるなぁと。 そういう課題やノウハウって、製品に限らず共有できれば面白いことがもっとできるんじゃないだろうか? と感じることが多々ありまして。 オープンソースのコミュニティをソースコードをベースではなく、共通の課題・話題を中心としたコミュニティが あってもいいんじゃないかなぁと。\nまぁ、要は、私がみんなの検索で困ってることとか、どうやって検索システム考えてるのかが聞きたかったわけですよ。\nということで、一人でやっても面白くないので、興味ありそうな人を募ってやってみようということを始めたのが2018年12月くらいです。\n運営とかどうしてるの? まずは、共同主催者(コアメンバー)を募集してみようということで、Googleフォーム作って、 興味ありそうな人がいる場所に投稿してみました。(TwitterとかFBとか) で集まったのが今回紹介したメンバー(スライド参照)です。 ユーザー企業の人もいれば、私みたいな検索エンジンの人もいるので面白い感じにできたかなぁと。 で、スピーカーを運営や知り合いに声をかけて第1回をやってみたという感じです。\n今後どうするの? 残念ながら次回はまだ未定です。 2ヶ月に1回くらいのペースで開催できればなーと思ってますが、スピーカーが集まるかなどによるかなぁと。 ということで、勉強会のグループのページにスピーカー応募フォームのリンクがありますので、スピーカーに興味がある方は入力していただければと。\nもちろん第2回はやりたいので、勉強会のページからの連絡をお待ちください!!\n","date":1551191880,"dir":"post/2019/","id":"b27bdabd8e1a6b7dc06886867331ceb3","lang":"ja","lastmod":1551191880,"permalink":"https://blog.johtani.info/blog/2019/02/26/start-search-engineering-tech-talk/","publishdate":"2019-02-26T23:38:00+09:00","summary":"どーも、johtaniです。 Search Engineering Tech Talkという勉強会に運営として参加して、第1回の勉強会を開始しました。 本日(2/26)は第1回目だったの","tags":["勉強会","検索"],"title":"Search Engineering Tech Talk(検索技術勉強会)の運営として参加して始めてみました。"},{"contents":"今年も振り返りブログをかけてます。よかったw\n振り返り(2017年に書いた抱負から) まずは去年の抱負を元に。\nもっと英語の継続&TOEIC まぁ、継続してます。英会話も続けてますし、海外TVドラマや映画見てます。 ただ、昨年書いたTOEICはイベントが被りまくってて受けれてないです。。。 来年は受けれればいいが。 ちなみに見たドラマはこの辺。あんまり見てないなぁ。 「はじまりのうた」は飛行機の中で見たんですが、よかったです。 最近は音楽系の映画が好きなのかなぁ。グレーテストマンショー(ミュージカル風)とかもハマったし。\nGame of Thrones はじまりのうた BEGIN AGAIN (映画) 24 シーズン4まで 今は、ボキャブラリのなさに苦しんでる感じです。キクタンとかするべきなのかもなぁ。 基本勉強が下手だからなー。\n継続的にイベントに登壇 & CfPもっと出すぞ! OSCには出てました。あとは、いくつかに呼ばれて出たりでしょうか。 CfPはJJUGしか出せてない気がするんで、もっと出さないとですね。。。 春のJJUGでは20分で短すぎた「オープンソースとビジネスモデル」の話(同僚のネタ)が 今年面白かった内容かなぁと。 もっと話を作るのをうまくしないとだろうなぁ。 ユースケースが増えてるんで、もっといろんなところに出ていかないとなぁと。 ブースの出し方とかもちょっと考えないといけないかもなーと思ってたり。 マンネリになってきてる気がするんで、なんか取り入れないとなぁ。\nもっとブログ! 出だしはよかったんですが、途中でRustネタのブログも止まってしまいましたね。。。 業務が忙しくなったのを言い訳にして時間が取れなくなってるんで、 もっと習慣つけないとなぁ。\n雑誌やWeb系雑誌で記事を。 できてないです。。。どうすっかなぁ。 重い腰上げないのが問題なんですけどね。。。 自社のウェビナーとかはそこそこやってましたが。\nコミュニティを別の方法で盛り上げ フォーラムは皆さんのおかげで盛り上がってきてる気がしてます。 別の方法ではなく、勉強会を9月から毎月開催にして、ユースケースごとに切り替えてみました。 あとは、スピーカー登録用のフォームの用意とかして、継続的に楽にスピーカーの人たちが見つけられるようにと。 私は「全然」関わってないんですが、技術書典でいろんな方に書籍を書いていただきました。 また、Elasticloverという毎週いろんな記事をまとめていただけ助かりました。 少しでも感謝をということで、コミュニティランチというイベントで、フォーラムで回答していただいてる方や、書籍を出していただいた方を招いてCEOのShayとランチするというイベントもやってみました。 少しは盛り上げられたかなぁ。 次は、ハッカソンみたいなのとかやってみるのもありなのかなぁ?(サポートしきれない気がするんだよなぁ)\nElasticsearchなど検索系の開発にも参加 開発。。。 Analyzer向けのKibanaのプラグインの開発は継続してますが、あんまり開発してないですねぇ(GitHubの草をみながら)。 ちょっとしたPRはやったりしてますが、もっとやりたい。。。 とりあえず、来年しょっぱなは、検索系じゃないですが、KibanaのプラグインのReact化をやらないとなぁと。\n振り返り(今年あったできごと) さて、反省が多かったですが、ここからは今年の出来事を。\n初スノーシュー in US オフィス引越し パリで料理w K8sとde:code QNAPとか IPO! 初のオンライン登壇 初アイルランド! Pixel3 XL 今年も初モノがちらほら。\nアメリカでスノーシューやりました。昨年は釣りでしたが、今年はスノーシューでした。 スノーシューはすごくよかったんですが、サンフランシスコから社内ミーティングのある場所までの 移動に10時間バスに缶詰という変な初モノもありました。。。 スノーリゾートのある山の上にバスで移動だったんですが、前日までの天候の生でチェーン規制が出てしまい、登りかけた山を降りて、違う経路で登り直すという長旅でした。。。 途中からずっとゲームオブスローンズみてました。。。\nオフィスが引っ越しました。人数が増えてきたのもあり、銀座のWeWorkに引っ越しました(私はあんまり行かなかったりしますがw)。 ただ、すでに手狭になってきて、来年はまた引っ越してるかもなぁ。 今年の終わりで日本のメンバーが22名に増えました!すごい!4年半前の22倍!\nパリで料理もしましたwセールスのキックオフミーティングがパリで開催され、なぜか参加してきました。 そこで、DevRelチームのミーティング&ディナーがあったんですが、ディナーがアクティビティ付きで、チームのみんなとパリで料理やカクテル作ってきました。 まさか、パリで手巻き寿司作るとは思わなかった(怖くて食べてないですw)\n今年はイベントが連続することが多かったです。パリから帰ってすぐにde:codeでMSの川崎さんと登壇したりしました。Kubernetesを触る機会ができたんでよかったですが、時差ボケは辛かったw今年は他にもカンファレンス直後にトレーニングだったりと、夏に喉やられちゃいました。喉に負担をかけない話し方の練習すべきなんだろうなぁ。\n自宅の環境もちょっと整えました。10年前から使ってた、TeraStationをQNAPに刷新。快適に検索できるわ、クラウドにバックアップとれるわで、すごく快適です。 あとは、自室のディスプレイをディスプレイアームにつけたり、壊れたモニタースピーカーをYamahaのパワードスピーカーに買い替えたりと。 ちょこちょこ自宅で作業したりするんで、快適です。\n今年はめでたいことに会社がIPOしました。ニューヨーク証券取引所で株式公開しました。 転職して4年、初体験なんで何がどうってのはいまいち実感わかないんですが、順調にきてるのは嬉しい限りです。今後も頑張りますよ!\n自社のウェビナーでは、オンライン登壇してたんですが、インフラ勉強会でオンライン登壇させていただきました。 Elastic Stackの入門的な話をさせていただいたので、興味があればみていただければと。 こういうのにはマイクが非常に重要だなというのが結論です。ウェビナーで使ってるShureのマイクで話したので聞き取りやすかったです。 来年はもっと手軽にちょっとしたウェビナーとかポッドキャストやろうかな、ということで、持ち運び用にSAM SONGo Micを購入してみたのでどっかで試してみたいなー。\nアイルランド(ダブリン)にも行きました。これまた、社内のミーティングなんですけどね。半年に1度エンジニアが集まる社内イベントがあるので、いろんなところに旅をさせてもらっていて、すごく楽しいです。 みんなにも会えるし。ただ、アイルランドの英語はきつかった。。。\n最後はPixel3です。SonyのXperiaをここ数年は使ってたんですが、電池の持ちなどが悪くなったんで、気になってたPixel3に変えました。すごくいい。いらないものが入ってないのもいい。あとカメラがすごくいい。他の機能をまだちゃんと調べてないんで、誰か便利機能知ってたら教えてくださいw\nとまぁ、こんな感じでした。\n来年の抱負 最後は来年の抱負を。\nTOEIC CfP見つけて応募 \u0026amp; いろんな場所に顔を出す もっとブログ! Rustの継続 開発の継続 日本でエンジニア獲得! まぁ、英語ですね。これは地道にやるしかないんだろうなと思いつつ、コツコツが苦手でw とりあえず、今年はどこかでTOEIC受けないとな。\nいつも行かないけど、弊社プロダクトに関係のあるカンファレンスのCfPを見つけ出して、 応募しまくって、少しでもしゃべらないとなぁ。喋れなくても、Elasticsearchがらみで登壇していただいてる方がいるカンファレンスには顔を出していきたいなぁと。 登壇される方いたら、ぜひ連絡ください!あとは、CfPのサイトを探す仕組みを作らないとなぁ。 検索サイト作るかなぁ。 あとは、カンファレンスではなく、いろんな会社に遊びにいきたいと思ってます。 入門的な話をしてほしいような方、こんな使い方してますっていう話をしていただける方、大募集です。 これもGoogle Formでも作ってみるか。\nブログなぁ。小さな習慣を読んだのに、習慣化できてないので、なんとかしないとという意味で。。。が、頑張ります。。。\nRustの継続&開発の継続もですね。Java歴が長いので、他の言語を勉強しようと思ってRustやってますがなかなか身についてないというか、時間を取れてない。これもコツコツやらないとなー 検索関連の開発もちょっとずつやりたいなと思ってるんで、LukeへContributeしようかな。\n切実なんですが、日本に弊社のエンジニアを増やしたいなと。特に人前で喋ってもらえる人が増えると助かるんです。弊社最近、ユースケースが増えてきてて、追いつかなくてwダレカタスケテーw\nさーて、そろそろ紅白のサザンが始まるんで終わりです。\n今年も様々な方々に様々な面で助けていただきました。本当にお世話になりました。 この場を借りてお礼申し上げます。\n来年ももちろん、助けてもらうんで、よろしくお願いいたします! あと、話聞きたい方、声かけてくださーい。\n","date":1546240485,"dir":"post/2018/","id":"6c226ee1519fbf910197cc1d5c5a5756","lang":"ja","lastmod":1546240485,"permalink":"https://blog.johtani.info/blog/2018/12/31/looking-back-2018/","publishdate":"2018-12-31T16:14:45+09:00","summary":"今年も振り返りブログをかけてます。よかったw 振り返り(2017年に書いた抱負から) まずは去年の抱負を元に。 もっと英語の継続&TOEIC まぁ、","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2018)"},{"contents":"Elastic stack (Elasticsearch) Advent Calendar 2018の25日目の記事になります。 今年最後のAdvent Calendarです!来年も忘れてなければやるはず!\n今日は、すでにalpha2までリリースされた7系でどんな変更が入るのかをちょっとだけ紹介します。 ほんとにちょっとだけですよ。\nKibanaのk7 design (kibana) Kibanaの新デザインです。K7って呼ぶのかな?\nまだ、メニューと一部が実装されているだけですが、7.0.0でガラッと変わりそうです。 そのほかの画面のIssueはこちらです。 \u0026ldquo;k7\u0026quot;で検索しただけですが。メタIssueが見つからなかったんで。例えば、こんな感じでアプリとかのスイッチとかがこんな感じになるよというデザイン案が観れたりします。\nZen2 (elasticsearch) Elasticsearchの新しいクラスター管理機構アルゴリズムになります。 Zenと呼ばれる独自実装のものを6系までは使っていましたが、7系向けに変更がかかりました。 実際には、Nodeを探す仕組み、Masterの選出アルゴリズム、クラスター状態の管理などを行います。 上記のリンクにあるようにドキュメントも詳しくなりました。 信頼性をさらに向上し、設定ミスを起こしにくくして、より使いやすくという目的で様々な変更が加えられています。 これが、メタIssueかな? アルゴリズムの変更や、クラスターの状態の管理の方法などの変更に関するIssueやPRにリンクが貼ってあります。\n新しいデータタイプ (elasticsearch) Feature/Feature vector datatype ドキュメントはこちらとこちら\nfeature queryと合わせて使用するためのフィールドで、しかもクエリのスコア計算「のみ」に使用するフィールドになります。 検索条件やソート、Aggregationの対象ではなく、クエリのスコアに影響させたい値を入れておくためのフィールドです。 6から追加された機能の「track_total_hits」をfalseにした時と合わせると、function_scoreなどで計算をしていた場合よりも、検索性能が上がるという利点まであります。 ちなみに、「track_total_hits」は検索ヒット数を計算しないで、上位のデータを取得する時にクエリを早くするといったことができる機能になります。 Index Sortingと組み合わせることで威力が発揮できる仕組みになるはずです。\nFilebeat supports NetFlow (beats) NetFlowが入力として追加されます。 Filebeatと言いつつ、File以外の入力が徐々に増えてきてますね(UDPやTCPにも対応しましたし)。 ネットワーク機器などの監視を行う方などにはさらに便利になってくるのではないでしょうか? (私はこの辺りは不得手なので、誰か使ってみてもらえればと!)\nまとめ まだ、序の口って感じですが、今年はこの辺で。7系ではここであげた以外にも様々な機能が追加されています(もしくは予定です)。 Elasticのドキュメントの良いところは、masterブランチのドキュメントも公開されていることです。 ドキュメントのバージョンを7.0.0-alpha2にすれば、masterブランチで追加されたページが見れるので、 興味のある方は眺めてみていただければと。物によって、リリースノートが書かれていなかったりするので注意は必要ですが。\n今年もあと数日になりましたが、Advent Calendarへの参加ありがとうございました! 来年ももちろんやりますので、年始からネタを考えてくださいね。\n来年一発目は、第28回Elasticsearch勉強会 - 6.5機能紹介 -になります。ウェビナーでも紹介しましたが、6.5で入った様々な新機能をデモありで紹介する予定です。 興味のある方はぜひご参加ください。\nでは、来年もよろしくお願いいたします。\n","date":1545663601,"dir":"post/2018/","id":"ee62cb0b9a97f990df1ed0266a7027e2","lang":"ja","lastmod":1545663601,"permalink":"https://blog.johtani.info/blog/2018/12/25/whats-new-in-elastic-stack-7/","publishdate":"2018-12-25T00:00:01+09:00","summary":"Elastic stack (Elasticsearch) Advent Calendar 2018の25日目の記事になります。 今年最後のAdvent Calendarです!来年も忘れてなければやるはず! 今日は、すでにalp","tags":["elasticsearch"],"title":"Elastic Stack 7.0で入ってくる新機能をちょっと紹介"},{"contents":"Elastic stack (Elasticsearch) Advent Calendar 2018の1日目の記事になります。\nちょっと遅れちゃいました。。。 まだ、1ヶ月を残してますが、簡単に今年起こったことを振り返ってみようと思います。毎年恒例ですね、ここ数年。\nElastic Stack 6.2.0リリース(2月) リリース記事はこちら\nAPMがGAリリースされ、Beats monitoring UIも追加されました。Stackとしての統一度がちょっとずつ上がってきた感じですね。 Kibanaのホーム画面(左メニューのKibanaアイコンをクリックした時)にデータ登録のチュートリアル的な画面が追加されています。 特にBeatsを利用する時の流れが簡単にわかるのがいい感じです。Metricsなどはローカルでちょっと試すのにも簡単な流れですので、ぜひ一度やってみてもらいたいなと。 個人的にはtermsを使ったパイチャートで、その他の数値がどのくらいあるかといった表示ができるようになって、やっと帰ってきた!(Kibana 3の頃にはあった機能)という印象でした。\nElastic{ON}18開催(2月) 第4回目のユーザーカンファレンスがSFで開催されました。 今年のキーノートが今年最大のニュースですね。 X-Packのコードの公開が発表されたのがこの時でした。 個人的に今後もオープンソースに携わっていきたいと思いながら日々働いていますが、 Elasticのオープンソースへのこだわりと、シンプルな考え方を再確認して素晴らしい会社で働けてるなーと。 商用のソースコードを公開してユーザーや顧客の皆さんとより良いものを作っていきたいという形ですので、今後もよろしくお願いします! キーノートの動画はこちらからご覧いただけます。\nそのほかにも次のような発表が行われました。\nSQL for elasticsearch Canvas Elastic App Search(旧Swiftype) Elastic Stack 6.3.0リリース(6月) リリース記事はこちら\n2月末のElastic{ON}で発表されたX-Packのコードの公開にはやはり時間がかかりました。 有償コードのリポジトリとの統合やライセンスの変更、テスト環境などなど、色々大変だったみたいです。 ようやく公開され、ベーシックのライセンスの扱いなども変わり、より使いやすくなったのがこのタイミングです。\nX-Packをプラグインとしてのインストールが不要に ベーシックライセンスがデフォルトでONに。6.3から登録などが不要に。 Apache 2.0ライセンスの部分のみのディストリビューションも別途ダウンロードできるようになどなど 日本でもリリースウェビナーをやりました。ご覧いただけましたかね?\nElastic Cloud Elasticsearch Serviceがより使いやすく(8月) リリース記事はこちら\nこれまでは、メモリとストレージの比率だけしか指定できなかったのですが、 このリリースで様々なユースケースに応じた組み合わせが可能になりました。 CPUやメモリリソースよりもストレージを大きくしたりなどです。 専用マスターノードを追加できたり、待望の機械学習(Machine Learning)が提供されたりと色々と変更があり使いやすくなったかと。 昔からよく聞かれる、Kuromojiなどのカスタム辞書を登録する機能もあるので、Elastic Cloud便利です。 ご存知ない方は、14日間のトライアルもありますので試していただければと!\nElastic Stack 6.4.0リリース(8月) リリース記事はこちら\nフィールドエイリアスや韓国語のアナライザーがElasticsearchに追加されました。 Kibanaはデザインがここからさらに少しずつ変更が入ってたりします。 Elastic UIフレームワークと呼ばれるデザイン用のライブラリが、ElasticのプロダクトのUIに取り込まれていってる感じです。統一感が取れてきてますよね。私が開発しているAnalyze UIのプラグインにも取り込みました。 あとは、マイクロソフトのde:codeで話をさせていただいた、Logstash向けのAzure Moduleがリリースされたのもこのバージョンでした。AzureのEvent Hubからデータを取り込んで、SQLデータベースのモニタリングや、ユーザーの認証などをとってKibanaで可視化するものです。\nもっとも気に入っているのはサンプルデータの登録が簡単になったことです。これまでは、KibanaとElasticsearchを用意した後に、データを入れるためにFilebeatなどを使ってから、ようやくKibanaで遊べるという形でした。 6.4からは、ElasticsearchとKibanaを立ち上げて、Kibanaのホーム画面の「Sample Data」のリンクを押した後に、「Sample flght data」の「Add」ボタンを押せばKibanaからデータが登録されます(サンプルデータについてはこちら)。とりあえず触ってみたいという方への敷居がさらに下がったのではないかなぁと。\nElastic認定エンジニア第1号(8月) ブログ記事はこちら\n認定制度も始まりました。Elasticsearchの知識、経験を問われるテストを受けていただき、合格すると認定されるというやつです。 なんと、社外で世界初の認定エンジニアがアクロクエストの吉岡さんでした(上記ブログ参照)。 私もトレーナーやってるのもあり、慌てて認定をとったりしましたw。 認定テストは筆記ではなく、実際に作業をするテストなので実践的です。 トレーニングの受講が必須ではないのも面白いなぁと思いました。 トレーニングや認定エンジニアに興味がある方は、Elasticのトレーニングのサイトをご覧ください。 1月末にはまた、日本語でElasticsearchのトレーニングも開催されます!\nElastic Cloud Enterprise 2.0リリース(9月) リリース記事はこちら\nElastic Cloud Enterpriseをご存知ない方もいらっしゃるかもしれません。 Elastic Cloudの裏側で利用しているクラスターの起動などの仕組みを製品として提供しているのがこちらになります。 Elastic Cloudで機械学習や様々な構成ができるようになったものがリリースされたのがこの2.0です。 複数のElasticsearchクラスターを管理したい場合には、こちらが便利なツールになってるんじゃないかなぁと。 部署ごとにクラスターを提供するといったことが可能になるので、乱立する前に利用するのも便利かなーと。\nニューヨーク証券取引所で株式を公開(10月) ブログ記事\n日本語でブログ(10月) Elasticsearchの運用に関する典型的な4つの誤解というブログを書きました。4年も働いてるのに、会社のブログに翻訳以外で書いたことなかったので。。。 Twitterや勉強会、ブログ記事などで見かけるよくある誤解に関する記事を書いてみました。 Elasticは英語のブログも活発に書かれているのですが、今後もこのような形で日本語でのブログも頑張りますので、 読んでみたいものなどあればコメントいただければと。\nまぁ、弊社の大輪は色々書いてるんで、私がもっと頑張れって話ですかね。。。\nElastic Stack 6.5.0リリース(11月) リリース記事はこちら\n昨日(11/30)のウェビナーでも話をさせていただきましたが、Elastic Stack 6.5は「本当にマイナーリリース???」と思うほど盛りだくさんの機能がリリースされました。\nインフラUI、ログUI Elastic APMの分散トレーシング対応 Java \u0026amp; Go APM Agent GAリリース Cross Cluster Replication ODBCドライバー Kibana Canvas Kibana Spaces Data Visualizer for files Functionbeat LogstashのApp Search output リストアップしただけでもこれです。45分のウェビナーでは伝えきれてないなぁとも思ってますので、何か検討しようと思います!\nElasticsearch勉強会(3月から12月) Elasticsearch勉強会ページ\n今年は、6回の勉強会を開催(1つは12月19日開催)しました。 9月からは、ユースケースなど、もっと参加者の皆さんの興味があることにフォーカスしながら開催をしてみ始めました。 参加しやすくなってればいいのですが。。。 そろそろまたアンケートをとったりして、参加しやすいか、どんな改善がしてほしいかなどを聞きたいなと思っています。\n12月はもっと皆さんと喋りたいなということで、スピーカーなしの「LT\u0026amp;忘年会」にしてみました。 私やElasticのものも参加するので、ぜひ色々聞いたり、他のコミュニティの方達の使い方を聞き出して、 新しい発見をしていただければなーと思います。LTでスピーカーの練習をするってものありですよ!(まだ誰も応募してくれてない。。。) 発表することで、フィードバックがもらえて、自分の使い方に自信が持てたり、その他の視点を得ることができると思いますので、 ぜひ発表してみていただければと。\n12月のjohtani出没イベント 12月は以下のイベントにブースを出してます。イベントに参加される方ははぜひブースにお立ち寄りください!!\n12/4-5 : Japan Container Days - 東京 12/8 : OSC福岡 - 福岡 12/15 : JJUG CCC 2018 Fall - 東京 12/19 : 第27回Elasticsearch勉強会 - 東京 なんか、忙しそうだな。。。\nまとめ 駆け足でしたが今年を振り返ってみました。 今年も色々ありましたが、今後もよろしくお願いいたします。\nさて、Elastic Stack Advent Calendar 2018は今日から25日まで続きます。こらからの記事を楽しみにしています!\nということで、次はkaibadash@githubさんの「ぼくの考えた最強のElasticsearch index設定を最強にわかりやすく書くぞ!!!」になります。お楽しみに!\n","date":1543628918,"dir":"post/2018/","id":"ba45ddd3042dad59a12e5937644f7246","lang":"ja","lastmod":1543628918,"permalink":"https://blog.johtani.info/blog/2018/12/01/whats-happen-at-elastic-in-2018/","publishdate":"2018-12-01T10:48:38+09:00","summary":"Elastic stack (Elasticsearch) Advent Calendar 2018の1日目の記事になります。 ちょっと遅れちゃいました。。。 まだ、1ヶ月を残してますが、簡単に今年起こったことを振り返ってみよ","tags":["elasticsearch"],"title":"2018年のElastic StackとElastic"},{"contents":"(転職する少し前までパスポートすら持ってなかったのに)今の会社に転職してから、半年に1度の割合で海外への出張が発生する生活を送っています。 4年目になりますが、今回いくつか新しいガジェット?アイテム?を出張用に導入したので感想を書いておこうかなと。\nとりあえず、以下の4つです。\nFelimoa ネック ピロー これまでは、無印で購入した「フィットするネックピロー」を使ってました。 特に使ってる間は問題ないのですが、どうしてもかさばります。。。 そんな時、FBで見かけたのがこちら。\n厚みがないので、持ち運びが便利でした(商品紹介の中にありますが、リュックにつけると邪魔にならない)。 飛行機の中で使うので、それほど暑くない場所なので、ムレる感じでもなく。 ただ、ヘッドフォン+真横にフレームがくる形になるとヘッドフォンに干渉するので、 私はフレームを顎の下の方に寄せた形で使ってました。 軽さと場所を取らないのがよかったです。\nノイズキャンセリングヘッドフォン これまでは、SONYのNW-A847という ノイズキャンセリング機能付きのウォークマン+アクセサリーで外部入力を取り込む形で、飛行機で映画を見ていました。 これ自体が8年前の製品ですね。。。 これとは別に、冬の寒い時期は防寒も兼ねてヘッドフォンを使用しています。 MDR-10Rを使ってたんですが、昨年こんな感じになりまして。。。\n応急処置 pic.twitter.com/uDErZWpPVC\n\u0026mdash; Jun Ohtani (@johtani) 2017年11月10日 で、ヘッドフォンの買い替えを検討してたんです。 そこへ飛び込んできたのがSonyの新しいノイズキャンセリングヘッドフォンでしたと。\nせっかく買い換えるし、今度はいいものを長くということでフライト前日に購入してしまいました。 結論としては高いけど買ってよかったと。よかった点はこんな感じです。\n軽い イヤーパッドが耳を抑えることがないので長時間でも気にならない 人の声だけノイズキャンセリングをオフにする(騒音などはキャンセルしてくれる) バッテリーが長時間 ヘッドフォンを外さないでも案内を聞くことができる「クイックアテンションモード」 などなど。行きのフライトで5時間も遅れが出ましたが、空港、飛行機内で非常に快適に過ごせました。 大事に使おう。。。\ncw-x 知り合いがFBにアップしてて、立ちっぱなしの仕事だったり、長時間のフライトでも足が疲れないという噂を聞いて購入しました。\n長時間のフライトの後に、ホテルで1泊しても足の疲れって結構残ってるんです。 今回、12時間のフライトでズボンの下に履いて行きましたが、足の疲れがほぼありませんでした。 デブになりつつあり、足太くなって来てるので、履くのはちょっと苦労しますが。。。もともときつめに作ってるんじゃないかなぁ(希望的観測)。 帰りも使用しましたが、帰りはフライト前に1万歩ほどダブリンの街中を歩き回ってたので、流石に疲れが出てます。。。 今度は、カンファレンスのブースなどで立つことが多いシーンでも使ってみて、疲れがどうなるかを試してみようと思います。\n携帯ウォシュレット 初めて購入しました。海外のホテルで1週間とか連泊するんですが、トイレットペーパーがやはり硬めなのが気になって。。。\n世界に誇る日本の技術の一つだと確信してますw ドイツに長期出張してた友人が便利だよと言ってたので、思い切って購入して持って行きました。 硬めのトイレットペーパーも気にならなくなるのでとても幸せな気分ですw\nまとめ とりあえず、今回はこんな感じです。 総じて導入してよかったなという感じでした。 他にもおすすめ出張グッズとかあればコメントいただけると嬉しいです。\n普段使ってるものとか、どういうものを持っていってるとか興味ある人いるかなぁ? ではでは。\n","date":1539794095,"dir":"post/2018/","id":"3fd9052870778e14ab4a5acbc8c24af4","lang":"ja","lastmod":1539794095,"permalink":"https://blog.johtani.info/blog/2018/10/18/items-for-long-businesstrip/","publishdate":"2018-10-18T01:34:55+09:00","summary":"(転職する少し前までパスポートすら持ってなかったのに)今の会社に転職してから、半年に1度の割合で海外への出張が発生する生活を送っています。 4","tags":["misc"],"title":"新規導入した長期出張用のアイテムをいくつか紹介"},{"contents":"毎月開催の2回目になります。 今回は日経さんの会場をお借りしての開催となりました。\n前回から、スピーカーの募集をhttp://bit.ly/SpeakerElasticTokyoMeetup で行なっております。 ぜひ皆さんのノウハウを共有していただけると助かります。 また、次回もすでにスケジュール済みです。次回は「ログ/メトリック分析」回になります。\n以下は、個人的なメモになります。\nメディアコンテンツ向け記事検索DBとして使うElasticsearch / Future Architect 株式会社 村田 靖拓さん (twitter: @famipapamart) メディア記事コンテンツ検索 全ての情報が1indexに入っているようにすること。 typeは少し悩んだ。 範囲検索にはならない場合がある。(文字列で登録してWildcard検索できるようにした) kuromojiで基本対応 異体字についてはchar filterでマッピング 細かな設定とかもスライドにて公開予定。 基本的なプラグインだけで対応した Dynamic Field mappingを有効にしたまま対応 パフォーマンス検証 初回のインデックスのロードはこの辺かなぁ?。 自力でQueryのoffset-limitを構築するのかぁ。 ソート条件が固定らしいのでできる方法 minne での検索運用(仮) / @_shiro16 さん ハンドメイドなものをマーケットプレイスがminne SolrからElasticsearchに切り替えた話 2016/02以降はEs 昔は、DBからSolrへ同期 Es版ではDBからの同期ではなく、Workerに対してリクエストを入れる 現状は独自にEC2で運用中 ユーザーが求めているものがきちんとでているかを計測している 行動ログはどんな感じ? TDにログを入れて、CTRとかを計算してre:dashで可視化 A/Bテストも実施 指標はキャンペーンなどが実施されている場合にブレる場合もある トレンドをログから知ることができる Function Scoreでスコアを変更してる 季節的な単語でスコアを変更したりする ドリンクの対応などをして聴けてないところが。。。 query_stringのはなし / 加藤遼さん (日本経済新聞社) 電池が切れそう+ピザとかの手配をしていたらメモが取れず。\n苦労が滲み出る感じのセッションでした。 query_string queryが実際にどんなクエリになっているかの説明を交えて説明してもらえたのはすごくよかったんじゃないかと。 まとめ 検索は話してくれる人が多いし話題に事欠かないなぁという印象でした。 今回も、スピーカーの皆さん、会場提供をしていただいた日経さんありがとうございました。\n他のユースケースのスピーカーも募集してます。ぜひMeetup.comの概要に記載してあるリンクからスピーカーの応募をお願いします!\n","date":1539765230,"dir":"post/2018/","id":"d3fa23c9066f943f10e8883de9340dea","lang":"ja","lastmod":1539765230,"permalink":"https://blog.johtani.info/blog/2018/10/17/26th-elasticsearch-tokyo-meetup/","publishdate":"2018-10-17T17:33:50+09:00","summary":"毎月開催の2回目になります。 今回は日経さんの会場をお借りしての開催となりました。 前回から、スピーカーの募集をhttp://bit.ly/Sp","tags":["elasticsearch","勉強会"],"title":"第25回Elasticsearch勉強会を開催しました。"},{"contents":"7/25にJJUGナイトセミナーでElastic Stackの紹介とAPMのJava Agentの紹介をしたので、補足のブログです。 (久々に書くな。。。)\nスライドとサンプルアプリのリポジトリはこちら。\nスライド:https://speakerdeck.com/johtani/intro-elastic-stack-and-elastic-apm-java リポジトリ:https://github.com/johtani/apm-beats-kubernetes-demo/tree/master サンプルアプリ 勉強会の頭でサンプルアプリへのアクセス用QRコードを用意して質問してもらう感じにしました。\nアプリ自体が質問の受付と、そこにある質問に対して聞きたいかどうかのVoteができる仕組みになっています。 セッション最後にこの画面をみながら答えました。 手を挙げていただくよりも、匿名(名前入れるようになってますが、実名である必要はない)で登録できるし、 みんなが聞きたいかどうかもわかるので便利だなぁと。\n元は、Elastic{ON} 2018であった「Docker \u0026amp; Kubernetes Log Collection and Monitoring with Beats and Elasticsearch」のサンプルアプリです。 これをSpring Bootに移植して、ちょっとだけサンプルコードを追加したものになります。\n構成とかの補足 スライド、GitHubのリポジトリのREADMEにある図は、k8s上のサンプルアプリケーションの構成だけでした。 ElasticsearchとKibanaを含めた図はこんな感じです。\nk8s上の各種Beats、APM Serverは一旦Elastic CLoud Elasticsearch Service(AWS Tokyoリージョンにデプロイ)に対してデータを投げます。 で、KibanaはGKE(k8s on GCP)で動かして、実際に勉強会ではkubectl proxyで接続してから表示していました。 この構成にしている理由は次の理由です。\nElastic CloudのElasticsearchクラスターにデータを投げている理由 クラスターの起動が簡単。 データを永続化したい。k8sのアプリは必要がなくなったらデータを削除したいから。 k8sのdeploymentを書く手間を省く 普段使ってるので。。。 KibanaをGKEで動かした理由 Elastic Cloudでは*「現時点(7/29現在)」*で、KibanaでAPM専用のUIを起動できない ローカルである必要はない といったところです。 Elastic Cloudのインスタンスを起動したままにしておけば、デモをしなくても、このタイミングのログ、メトリクスを 再利用して話をすることも可能です。\nまとめ ということで、簡単ですが、構成の補足でした。 勉強会では告知したのですが、今後の勉強会はトピックスごとでやりたいなと。ということで、どんなトピックスに興味があるのか、スピーカーの応募にはどんなツールが話しやすいかなどといったことのアンケートを集めております。ぜひご協力ください! また、アンケート、このブログに関する質問がある場合は、@johtani、もしくはブログへのコメントでお願い致します。\n今後の勉強会のやり方などについてアンケートを実施中です。https://t.co/XU15CHro0n 皆さん是非ご協力ください。ここにない項目については返信をお願いします。 #elasticsearchjp\n\u0026mdash; Jun Ohtani (@johtani) 2018年7月23日 ","date":1532843130,"dir":"post/2018/","id":"10ae016e19fff6ae9cfaeb8534fa47f9","lang":"ja","lastmod":1532843130,"permalink":"https://blog.johtani.info/blog/2018/07/29/apm-java-at-jjug/","publishdate":"2018-07-29T14:45:30+09:00","summary":"7/25にJJUGナイトセミナーでElastic Stackの紹介とAPMのJava Agentの紹介をしたので、補足のブログです。 (久々に書く","tags":["勉強会"],"title":"JJUGナイトセミナーで話しました"},{"contents":"第2回から少し間が空いてしまいましたが、templateで作成したプラグインのディレクトリ構成とどういう流れでデータがやり取りされるかについてみていきます。 (2018/02月時点で作成したディレクトリ構成にしたがって説明します) ちなみに、JavaScriptの優れた開発者ではないので、誤解している点や、効率の悪い書き方などがあるかもしれません。見つけた場合は、連絡をいただければと思います。\nでは、まずは作成したディレクトリ構成についてみていきましょう。\nディレクトリ構成 simple-sample-kibana-pluginがプラグインのプロジェクトのトップディレクトリになります。このディレクトリに次のような構成でサブディレクトリが存在します(なお、画像はIntelliJに取り込んだ後のディレクトリになっているので、.imlなど、不要なファイル/ディレクトリが存在しています)。\n主要なディレクトリ、ファイルについて簡単に一覧で説明します(順不同)。\nファイル/ディレクトリ名 説明 index.js プラグインの本体。Kibanaはこのファイルのオブジェクトを読み込みプラグインを起動。設定などの読み込みもこちら。 package.json npm/yarnのパッケージに関する情報を定義するファイル README.md README。プラグインの説明などを記載する。インストール方法なども記載すると便利 public ブラウザ側に配布されるプログラムや画像一式 public/less/main.less LESS用のファイル。アプリ固有のスタイルなどを記載 public/app.js ブラウザ側で読み込まれるプラグインのモジュールなど。 public/template/index.html HTMLのテンプレート。ブラウザ上での描画に利用 server/routes Kibanaサーバー側で動作するプラグイン。hapi.jsを利用してREST APIを実装する 重要なファイルについて少しだけ説明します。\npackage.json npmやyarnでビルドなどをするときに使用するパッケージ情報を記載するためのファイルです。 プラグインの名前、バージョン、説明などを記載します。 Kibanaのバージョンについてもこちらで管理します。この情報を また、ライブラリなどの依存関係についてもこちらで記載しています。 以下、抜粋。\n{ \u0026#34;name\u0026#34;: \u0026#34;simple-sample-kibana-plugin\u0026#34;, \u0026#34;version\u0026#34;: \u0026#34;0.0.0\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Sample plugin for explaining how to make kibana app\u0026#34;, \u0026#34;main\u0026#34;: \u0026#34;index.js\u0026#34;, \u0026#34;kibana\u0026#34;: { \u0026#34;version\u0026#34;: \u0026#34;6.2.1\u0026#34;, \u0026#34;templateVersion\u0026#34;: \u0026#34;7.2.4\u0026#34; }, \u0026#34;scripts\u0026#34;: { \u0026#34;lint\u0026#34;: \u0026#34;eslint **/*.js\u0026#34;, ... }, \u0026#34;devDependencies\u0026#34;: { \u0026#34;@elastic/eslint-config-kibana\u0026#34;: \u0026#34;^0.14.0\u0026#34;, \u0026#34;@elastic/eslint-import-resolver-kibana\u0026#34;: \u0026#34;^0.9.0\u0026#34;, \u0026#34;@elastic/plugin-helpers\u0026#34;: \u0026#34;^7.1.3\u0026#34;, ... \u0026#34;expect.js\u0026#34;: \u0026#34;^0.3.1\u0026#34; } } ちなみに私は、versionなどをリリースするたびに変更しています。\nindex.js 最初にKibanaに読み込まれるオブジェクトになります。 Kibanaのアプリの名前や、必要なモジュールなどを記載します。\nまた、kibana.ymlから設定など読み込む処理なども書くことができます。\n2行目のexampleRouteはサーバー側のAPIとして利用するhapi.js用のファイルのパスになります。\nuiExportsはこのアプリの画面に関する設定などの記載になります。 appの部分が実際にアプリの情報で、 mainがあとで説明するこのプラグインのUIのためのJavaScriptファイル(public/app.js)になります。mainですので、最初に読み込まれる処理が記載されているものを指定します。app.jsというファイル名を変更する場合は、こちらのappの部分を変更したファイルに合わせましょう。\nconfig(Joi)の関数が設定ファイルの読み込みなどの処理を記載する場所です。\ninit(server, options)の関数が初期化処理を記載する場所になります。 このサンプルアプリでは、2行目のimportで読み込んだhapi.js用のファイルの関数を呼び出しています。引数で渡しているserverがhapi.jsのserverオブジェクトになります。 routeメソッドを使用して作成しているプラグイン用のREST APIを追加しています。\nimport { resolve } from \u0026#39;path\u0026#39;; import exampleRoute from \u0026#39;./server/routes/example\u0026#39;; export default function (kibana) { return new kibana.Plugin({ require: [\u0026#39;elasticsearch\u0026#39;], name: \u0026#39;simple-sample-kibana-plugin\u0026#39;, uiExports: { app: { title: \u0026#39;Simple Sample Kibana Plugin\u0026#39;, description: \u0026#39;Sample plugin for explaining how to make kibana app\u0026#39;, main: \u0026#39;plugins/simple-sample-kibana-plugin/app\u0026#39; }, ... }, config(Joi) { return Joi.object({ enabled: Joi.boolean().default(true), }).default(); }, init(server, options) { // Add server routes and initialize the plugin here exampleRoute(server); } }); }; public/app.js 画面用のモジュールです。 uiRoutesという機能を使用して、アプリの呼び出しURLを定義します。テンプレートで作成したばかりの場合は、/というURLが追加されるのみです。\n実際に画面を表示する際に動くコントローラーの部分はその下の uiModules.controllerに指定してあるfunctionが画面描画の 処理を書く部分になります。 templateで作成したプラグインでは、\u0026ldquo;title\u0026quot;など表示に必要なデータを$scopeというオブジェクトに詰め込んでいます。 これはAngularJS(1系)でのモデルオブジェクトになります。\nimport moment from \u0026#39;moment\u0026#39;; import { uiModules } from \u0026#39;ui/modules\u0026#39;; import uiRoutes from \u0026#39;ui/routes\u0026#39;; import \u0026#39;ui/autoload/styles\u0026#39;; import \u0026#39;./less/main.less\u0026#39;; import template from \u0026#39;./templates/index.html\u0026#39;; uiRoutes.enable(); uiRoutes .when(\u0026#39;/\u0026#39;, { template, resolve: { ... } }); uiModules .get(\u0026#39;app/simple-sample-kibana-plugin\u0026#39;, []) .controller(\u0026#39;simpleSampleKibanaPluginHelloWorld\u0026#39;, function ($scope, $route, $interval) { $scope.title = \u0026#39;Simple Sample Kibana Plugin\u0026#39;; $scope.description = \u0026#39;Sample plugin for explaining how to make kibana app\u0026#39;; ... $scope.$watch(\u0026#39;$destroy\u0026#39;, unsubscribe); }); server/routes/example.js hapi.jsというNode.jsのためのサーバーフレームワークです。 このフレームワークをKibanaは使っており、Kibanaのサーバーとブラウザとのやり取りに使用するREST APIを記述するために使用しています。 例えば、Elasticsearchとのやり取りを実際に行うAPIなどをこのREST API内部で記述します。\nexport default function (server) { server.route({ path: \u0026#39;/api/simple-sample-kibana-plugin/example\u0026#39;, method: \u0026#39;GET\u0026#39;, handler(req, reply) { reply({ time: (new Date()).toISOString() }); } }); } pathの部分がブラウザ側からアクセスするURLになります。 実際にElasticsearchとやり取りする処理の書き方については、次回の記事で説明します。\nアーキテクチャ(簡易版) ざっくりですが、ファイルやディレクトリについて説明しました。 簡単なデータのやり取りについての流れを説明します。\nKibana自体はNode.jsで実装されサーバーとして動作していますが、ブラウザでアクセスすることで画面を描画しています。 簡単なコンポーネントを並べるとデータのやり取りはこのような形です。\nすごく簡易で大雑把な絵ですが。。。\n実際のプラグインとしては大きく、2つの処理があります。\nブラウザ上の処理 クリックなどのイベント処理 HTMLなどのレンダリング処理 Kibanaサーバー上の処理(Elasticsearchなどとの通信が必要な場合) 外部との通信処理 ブラウザ上では重い処理 絵に記載しましたが、ブラウザ上の処理についてはAngularJSが主なフレームワークで、サーバー上の処理についてはhapi.jsがフレームワークとなっています。\nまとめ ということで、今回はディレクトリ構造とファイルの説明、どういったフレームワークが使われ、データのやり取りがどのように行われているか説明しました。\n次回からは、実際に私が作成したAnalyze UIを元にElasticsearchとのデータのやり取りなどについて紹介していきます。\n","date":1524205801,"dir":"post/2018/","id":"04d818cbaac08b2915db15e0bffdcb5b","lang":"ja","lastmod":1524205801,"permalink":"https://blog.johtani.info/blog/2018/04/20/directory-layout-and-architecture/","publishdate":"2018-04-20T15:30:01+09:00","summary":"第2回から少し間が空いてしまいましたが、templateで作成したプラグインのディレクトリ構成とどういう流れでデータがやり取りされるかについ","tags":["Kibana","plugin"],"title":"Analyze UIとKibanaのプラグインの作成方法(第3回)"},{"contents":"#MANABIYA のブースでセッション時間の合間はお客さん少ないので、ブログを書いてみたり。 ここ数年、スポンサーとして色々なカンファレンスに参加してるんですが、それについてちょっと気なることがあったので。\nスポンサー情報ってどうやって探してます? 職業柄、カンファレンスにCfP出してセッションしてみたり(落ちること多いけど)、スポンサーとしてブースを出したりしています。\nで、疑問があるんですが、みなさんどうやってカンファレンスの情報をゲットしてます?\n数年やって来て、検索したりして見つけてスポンサーした結果、 これまでスポンサーしていたので、情報が流れてくるという感じになりました。 それ以外だと、@yusuke さんに教えてもらったりと言うのがあったんですが。。。\n自分が知らない、自分のTwitterで流れてこないという情報をどうやったら集められるかな?と言うのが今の課題になってます。 と言うことで、ブログを書いてみました。\nカンファレンスを検索できるサイトとか便利? で、私の会社は検索エンジンの会社なんで、検索できると便利では?と考えるんです。\nCfPの応募期間で絞り込みできたり、場所で検索できたり、スポンサー情報を取得する方法が載ってたりすると便利なのではないかなと。 便利に思うのが自分だけでは?と言うのがあるんですが。。。\nあると嬉しい人、データを掲載したいなと言う人いますでしょうか? Google Formなどで入力してもらえるようにして何か作るのもありかなぁと考えているところです。 それとも、スポンサーを募っているカンファレンスのスタッフや企業の人は、こういう情報は特定の人にだけ知ってもらったりしたいでしょうか?\n自分だけではわからないことが多いので、懸念事項や、それダメでしょ? あると便利!などのフィードバックをいただけると助かります。\nそれ以外に、カンファレンス自体の場所、開催日程、サイトへのURLなどが検索できると便利だったりするかも?というのもあります。\nとりあえず、自分が知ってるものだけ、個人的に検索できるようにしたりするのがいいかなぁ。。。 コメントお待ちしてます!\n","date":1521867012,"dir":"post/2018/","id":"8cc6b19cd410e638f4beaf1642f4f52a","lang":"ja","lastmod":1521867012,"permalink":"https://blog.johtani.info/blog/2018/03/24/how-to-find-conferences/","publishdate":"2018-03-24T13:50:12+09:00","summary":"#MANABIYA のブースでセッション時間の合間はお客さん少ないので、ブログを書いてみたり。 ここ数年、スポンサーとして色々なカンファレンスに参加してるんです","tags":["カンファレンス","スポンサー"],"title":"カンファレンス情報の探し方(CfP、スポンサー応募、開催期間など)?"},{"contents":"Rustで言語処理100本ノックの続きで、05と06です。\n05. n-gram 問題はこちら。\nみんな大好きn-gramです。単語と文字があるので、それぞれ別関数として実装しました。問題はbi-gramとn=2だったのですが、一応、nを引数に取る形にして実装しました。\nまずは、単語です。\n前に実装した時は、自分で頑張って、先頭から数えたりしてたんですが、Rustにはwindows(n)という便利なメソッドがsliceにあり、これを利用したらこんな簡単になりました。 sliceは特定のシーケンス(配列)に対してある特定のサイズのViewを作ってくれます(説明あってる?)。 ということで、文字列から、単語の配列(スペース区切りで単語にしている)を作り出して、windows(n)メソッドを通すと、 nで指定した数字の個数だけの単語の配列を先頭から、1単語ずつずらして作ってくれます。まさに、n-gram! 戻り値は配列の配列です。 1点だけ疑問点があるのは、「空白で区切ったものが単語」という考え方で良いかどうか?という点です。特に問題文にはそれが明示されていなかったので、このような前提を置いてあります。\ninvalid_n(text, n)はnの値や入力された文字列をチェックする関数です。入力チェックですね。nが1よりも小さい場合、入力文字列が空文字の場合は、warningでメッセージを出して、空の配列を返す仕組みになっています。\n次は、文字です。\n単語とほぼ一緒ですが、入力文字列を、1文字ずつの配列にしているところが異なります。 また、windowsメソッドで取り出された、1文字ずつのn個の配列を文字列に修正してから、結果の配列に入れています。 ここでも疑問は空白をどう扱うか?になります。 現時点では、空白も1文字とカウントして扱うことにしてあります。 どっちがいいのかなぁ?\n06. 集合 問題はこちら。\nまずは、文字n-gramで出てきた文字列をSetに入れる関数から。\nn-gramの問題で実装した文字n-gramの関数の戻り値を配列ではなく、BTreeSetに変えたものになります。比較などがしやすいように?と思い、BTreeSetを利用していますが、実装としてはHashSetでも問題ないかと。 この関数の集合(Set)を元に、和集合、積集合、差集合を求める関数を実装しました。\nSetのメソッドとして、それぞれ、union=和集合、intersection=積集合、difference=差集合のメソッドが用意されているので、特に困ることはなかったです。 差集合については、1-2と2-1で結果が異なるはずなので、それぞれをテストケース、main.rsで出力するようにしてあります。\n所感 今回は、Rustがすでに実装してくれているメソッドがあったので楽ができました。 やりたいことに相当するメソッドがあるかどうかを調べるためにリファレンスを探さないといけないのがちょっと苦労しましたが。。。 ということで、今日はこの辺りまで。\n","date":1521549285,"dir":"post/2018/","id":"d791eaca9375ca1b36a987af22ee71dd","lang":"ja","lastmod":1521549285,"permalink":"https://blog.johtani.info/blog/2018/03/20/nlp100-ch01-05to06/","publishdate":"2018-03-20T21:34:45+09:00","summary":"Rustで言語処理100本ノックの続きで、05と06です。 05. n-gram 問題はこちら。 みんな大好きn-gramです。単語と文字があるので、それぞれ別関","tags":["Rust","nlp100"],"title":"第1章の05から06までやってみた(言語処理100本ノック)"},{"contents":"Rustで言語処理100本ノックの続きで、03と04です。\n03. 円周率 問題はこちら。\n入力文字列を.split_whitespace()で分割しておいて、単語ごとのベクタを作り出し、そこに対して文字を数えました。「アルファベットの」という注意書きがあるので\u0026quot;,\u0026ldquo;や\u0026rdquo;.\u0026ldquo;は含めずに数えるのかなということで、 charの.is_alphabetic()でA-zまでの判定をしつつ、文字のベクタを作ってから、そのベクタの長さを詰め込むという感じでやりました。\nこれ、ひょっとして、collectでベクタにしなくても、i32とかの変数でカウントするとベクタ作らなくてもいいなじゃにか?というのに書きながら気づいた。。。 必要じゃないオブジェクトを作ってるよなぁ。\n.filter().mapとかかな?この辺りの操作がイマイチ苦手。Javaでもまだ馴染めてないところなんだよなぁ。頭固すぎ。\n04. 元素記号 問題はこちら。\n大作ですね。何だろう、大作。。。 最終的に連想配列(辞書型もしくはマップ型)」ということだったので、BTreeMapに詰め込んでます。 HashMapでもいいんですが、文字列で出力した時にキーが並んで見やすいからという理由で、BTreeMap使いました。それ以上の理由はないです。普通にやるなら、HashMapかな?\n入力として、1文字だけの出力をする場所(インデックス番号)の配列を受け取ってます。1点だけ、チェックしていない、けど入力値の想定をしていて、idx_one_symbolsがソートされていて、小さいものから順番に出てくるものとしてます。関数作って、チェックすべきかな?\nで、指定された場所の最後のものが入力文字列よりも大きいかどうかというチェックもしています。(あー、テストケース書いてないな)この辺りのせいでちょっと長めになってます。\n単語の配列を作るのは03の時と同じやり方です。 回しかたがちょっと違って、.iter().enumerate()で回して、添字と値をタプル?でとりだしてます。添字を見ながら1文字取り出すのか、2文字取り出すのかの判断が必要だからです。あとは一緒ですね。1文字取り出すときは、.first()を使って見ました。 実は、2文字取り出す時と、1文字の時と同じロジック使った方が共通化できて、短くなった???\nということで、こんな感じでした。いつものようにツッコミお待ちしてます。\n所感 問題それぞれについてではなく、 やってて思ったのですが、問題に対して想定される結果が記載されていると嬉しいなと思いました。 ロジックについては、各自実装者に寄ったり、言語によって違いが出たりするし、議論するベースになっていいかなと思うんですが、 問題で想定されている結果(出力)があると、自分の実装にケアが足りないところがないのか?とか、ケアしなくていい点とかがわかるのかもなぁと。 ユニットテスト相当のものがあると楽かなぁと。\nこのケースどうするんだろ?みたいなのが、ところどころコメントに残ったりしてます。 出題の意図としては、その部分も議論の対象ということなのかな?\n","date":1519032848,"dir":"post/2018/","id":"e6684944c37dbdd4c08d978af9e47bed","lang":"ja","lastmod":1519032848,"permalink":"https://blog.johtani.info/blog/2018/02/19/nlp100-ch01-03to04/","publishdate":"2018-02-19T18:34:08+09:00","summary":"Rustで言語処理100本ノックの続きで、03と04です。 03. 円周率 問題はこちら。 入力文字列を.split_whitespace()で分割して","tags":["Rust","nlp100"],"title":"第1章の03から04までやってみた(言語処理100本ノック)"},{"contents":"「鉄は熱いうちに打て」ということで、言語処理100本ノックの第1章の00から02を実装してみました。\nさて、これが効率がいいのかどうかはさておき。\n00. 文字列の逆順 問題はこちら。\n最初、Vecのreverse()で逆順にして0からlen()まで回してたんですが、pop()がいい感じに後ろから取れることがわかったんで、切り替えました。 シンプルかな?\n01. 「パタトクカシーー」 問題はこちら。\n1文字ずつ取り出して、インデックスの番号が2で割ってあまりが0なら文字列に追加していくってのでやってみました。 (ブログ書いてるところで、i in 0..char_array.len()じゃなくて、(i, x) in char_array.iter().enumerate()に切り替えました。) matchとか使って綺麗に書けたりするのかなぁ?\n02. 「パトカー」+「タクシー」=「パタトクカシーー」 問題はこちら。\nだいぶ思考錯誤してる感じがソースに現れてます。 とりあえず、両方の文字列をcharsの配列にして個々のイテレータを回しながら、next()の戻り値があれば追加していく感じにして、 終了条件が両方Noneを通ったらにしてるけど、、、 なんか、もっと綺麗にできないのかなぁ。。。 next()のタプル返す関数作って、とかでなんかできたりするかなぁ?\ngist-it 関係ないですが、GitHubのコードを貼り付けるのに便利なサービスがあるみたいです。\nhttp://gist-it.appspot.com\nこれほんと便利だな。行数指定もできるし。 説明するのが簡単だ。\nとりあえず、今日はこの辺まで。なんか、いい知恵あれば教えてください!\n","date":1518699541,"dir":"post/2018/","id":"bbe1deec11d459bdb348051b970abdaf","lang":"ja","lastmod":1518699541,"permalink":"https://blog.johtani.info/blog/2018/02/15/nlp100-ch01-00to02/","publishdate":"2018-02-15T21:59:01+09:00","summary":"「鉄は熱いうちに打て」ということで、言語処理100本ノックの第1章の00から02を実装してみました。 さて、これが効率がいいのかどうかはさてお","tags":["Rust","nlp100"],"title":"第1章の00から02までやってみた(言語処理100本ノック)"},{"contents":"ども。新しいもの始めないと頭が退化する。。。ということで、こちら( happy new year and new language - katsyoshiのめもみたいなもの)のブログに触発されて、言語処理100本ノックをはじめてみました。\n言語処理100本ノックとは、自然言語処理になるのかな、東北大学の研究室の先生が公開している言語処理に関する実践的な課題をベースにプログラミングなどのスキルを学んでいくための問題集です。 元々はPythonを対象とされているようですが、Rustでやってみようかと。 まぁ、先ほどあげたブログの二番煎じです。。。 ちなみに、インスパイアされた元のブログの方はRust book 2nd editionを読み終えたらしいですが、私はかじった程度です(ダメかも?)。\nNLPもRustもかじった程度なので、苦戦しそうですが、ちょっとずつやっていこうかなと。 ということで、準備運動の第1章から始めようかと。 GitHubにちょっとずつあげていく予定です。 https://github.com/johtani/nlp100-rust\nまぁ、まずは宣言のブログを書いてみただけです。 続いてなかったら、叱咤激励してください。叱咤だけかも?\n","date":1518605551,"dir":"post/2018/","id":"a673b3829e62477e01abc75465416b86","lang":"ja","lastmod":1518605551,"permalink":"https://blog.johtani.info/blog/2018/02/14/start-nlp100-with-rust/","publishdate":"2018-02-14T19:52:31+09:00","summary":"ども。新しいもの始めないと頭が退化する。。。ということで、こちら( happy new year and new language - katsyoshiのめもみたいなもの)のブログに触発されて、","tags":["Rust","nlp100"],"title":"言語処理100本ノックはじめました(Rust)"},{"contents":"第1回では、Analyze UIというプラグインの紹介をしました、ごく簡単にですが。\n第2回では、Kibanaのプラグインの作成方法を順を追って見ていこうと思います。今回は、プラグインのプロジェクトの作り方を説明します。 どんなファイルがあるのかなどについては第3回で説明します(2018/02月現在の方法になります。残念ながら、Kibanaのプラグイン作成自体はまだExperimentalな話になっていますので、変更がある可能性があります)。\n実はそれほど難しいというわけではありません。Kibanaのプラグインを作成するためのテンプレートが用意されています。template-kiban-pluginです。 テンプレートのリポジトリのREADMEに作業手順の記載があります。\nKibanaのリポジトリをClone、Checkout Node.jsの環境を用意する Kibanaを起動できるようにする SAOのインストール テンプレートによるプロジェクトファイルの生成 順を追って説明します。 PLUGIN_DEV_DIRというディレクトリ配下で作業をしている想定になります。\n1. KibanaのリポジトリをClone、Checkout 開発環境として、Kibanaが必要です。Kibanaのプラグインを作るので。 手順などはKibanaのCONTRIBUTING.mdに記載があります。 ということで、まずはKibanaのリポジトリをCloneします。\ncd PLUGIN_DEV_DIR git clone git@github.com:elastic/kibana.git このままだと、masterブランチなので、開発したい対象のKibanaのバージョンのブランチもしくはタグをcloneします。今回は6.2.1向けということで、次のようになります。\ngit checkout v6.2.1 これで、ソースが6.2.1向けになりました。\n2. Node.jsの環境を用意する Node.jsをインストールします。 Kibanaのリポジトリに.node-versionというファイルがあります。 こちらにNode.jsのバージョンが記載されています。 Kibanaが使用しているNode.jsを利用できるようにします。ローカルではnvm利用してインストールしました。後から、切り替えが可能だからです。 nvm自体のインストールについてはnvmのサイトをご覧ください。 nvmがインストールできたら、次のコマンドで、Kibanaが使用しているバージョンをインストールします。\ncd kibana nvm install \u0026#34;$(cat .node-version)\u0026#34; すでにnvmを利用している場合などは、Kibana起動時にKibanaのバージョンに合わせたNode.jsに切り替えるようにしてください。\n3. Kibanaを起動できるようにする Kibanaではyarnというjavascript向けのパッケージマネージャーを利用して起動やビルドなどを行います。まずはyarnをインストールします。最近npmからyarnに切り替えたようです。 私はMacだったので、brewでインストールしました。 インストールできたら、次のコマンドを実行します。\nyarn これにより、package.jsonから必要なライブラリなどをダウンロードして来てくれます。 問題なければ「✨ Done in 439.30s.」というような表示がされます(結構時間かかりますね)。 では、Kibanaを起動できるか確認してみましょう。 さらに、Elasticsearchも起動してみます。 Kibanaのpackage.jsonの中にはElasticsearchを起動するためのスクリプトも用意されています。実際にはgruntを利用してタスクを実行しているようです。Elasticsearchの起動にはJavaが必要になります。 今回は6.2.1なので、JDK 8以降がインストールされている必要があります。 こちらはインストールされているものとします。\nyarn elasticsearch で起動できます。\n\u0026gt;\u0026gt; Started 1 Elasticsearch nodes. という表示が出てればOKです。 次にKibanaです。別のTerminalを起動して、以下のコマンドで起動できます。\nyarn start これだけです。\nserver log [06:58:56.930] [info][listening] Server running at http://localhost:5603 この辺りが出てればKibanaのServerは起動済みです。また、Elasticsearchに接続できていれば、次のログが出ているはずです。\nserver log [07:02:18.010] [info][status][plugin:elasticsearch@6.2.1] Status changed from red to green - Ready Elasticsearch接続用のKibanaのプラグインの状態になります。 これで、Kibanaの環境が整ったことが確認できました。 もちろん、Elasticsearchに関しては、yarnで起動せずに、tar.gzなどでダウンロードして来たElasticsearchを起動しておき、アクセスするといったことも可能です。プラグインなどをElasticsearchにもいれてテストしたい場合などはそちらの方が便利かもしれません。\n4. SAOのインストール では、一度、ElasticsearchとKibanaを停止しましょう。フォワグラウンドで起動しているので、それぞれのTerminalでCtrl+Cで停止できます。 Kibanaのプラグイン作成むけに、テンプレートが作られています。sao.jsというGitHubのリポジトリやnpmのパッケージをテンプレートとして使うことができるツールを利用してプラグインのプロジェクト(リポジトリ)を作成します。 実際にテンプレートとなるリポジトリはtemplate-kibana-pluginになります。 まずはSaoのインストールです。\nnpm install -g sao プラグインのテンプレートのページには上記のようにnpmを利用したインストール方法になっていますが、次のようにyarnでも可能です。\nyarn global add sao これで、saoがインストールできました。\n5. テンプレートによるプロジェクトファイルの生成 あとは、テンプレートを元にプロジェクトを作成します。 PLUGIN_DEV_DIRディレクトリ配下に、kibanaと同じ階層で作成するプラグイン用のディレクトリを作成します。\nmkdir simple-sample-kibana-plugin 以下のような構成になります。\nkibana simple-sample-kibana-plugin 次にテンプレートを適用していきます。\ncd simple-sample-kibana-plugin sao kibana-plugin@7.2.4 2行目がsaoを利用してプロジェクトを作成しているコマンドになります。 すると、次のような質問が出て来ます。 これらに答えるとプロジェクトに必要なファイル(package.jsonやREADME.mdなど)に入力した情報を適用したものを作ってくれます。\n? Name of your plugin? ? Provide a short description ? What Kibana version are you targeting? ? Should an app component be generated? ? Should translation files be generated? ? Should an hack component be generated? ? Should a server API be generated? 実際に答えた内容はこちら。\n? Name of your plugin? simple-sample-kibana-plugin ? Provide a short description Sample plugin for explaining how to make kibana app ? What Kibana version are you targeting? 6.2.1 ? Should an app component be generated? Yes ? Should translation files be generated? Yes ? Should an hack component be generated? Yes ? Should a server API be generated? Yes プラグインの名前などは、ディレクトリ名と同じものを入力補完してくれているので、そのままEnterでもOKです。 Descriptionについてはわかりやすいものを入力しましょう。 バージョンは、先ほどのKibanaのリポジトリに合わせて、6.2.1にしてあります。 あとは、作るプラグインの種類に応じて、必要なコンポーネントを作るかどうかの質問にYes/Noで答えます。 今回はサンプルの説明ということもあるので、全てYesで答えました。 ちなみに、私が実際に作成したanalyze-api-ui-pluginでは、appとtranslationとserverの3つを作成しました。 ただし、translationについては現在はテンプレートで作成したままのファイルが入っており、実際には利用してないです。\n完了したら、プラグインのサンプル入りのプロジェクトが完成です。 もう一度、Elasticsearchを立ち上げて、プラグインのプロジェクトからKibanaを起動してアクセスしてみます。まずは、PLUGIN_DEV_DIR/kibanaディレクトリの下で、Elasticsearchを起動します。\nyarn elasticsearch 次に、PLUGIN_DEV_DIR/simple-sample-kibana-pluginディレクトリの下で、以下のコマンドを実行し、プラグインが入った状態のKibanaを起動します。\nyarn start 問題なく起動すれば、ブラウザでアクセスすると次のような画面が表示されるはずです。\n左側にメニューが1つ増えています。 クリックすると、上記画像のような画面が表示されるはずです。\nこれで、カスタムプラグインの開発ができる環境ができました! 次回は、プロジェクトのディレクトリ構成や、どんなツールが内部で使用されてデータのやり取りが行われているかについて説明します。お楽しみに。\n","date":1518167857,"dir":"post/2018/","id":"7b6cb59a177abe9767fd22da5a03b1e6","lang":"ja","lastmod":1518167857,"permalink":"https://blog.johtani.info/blog/2018/02/09/getting-started-template-kibana-plugin/","publishdate":"2018-02-09T18:17:37+09:00","summary":"第1回では、Analyze UIというプラグインの紹介をしました、ごく簡単にですが。 第2回では、Kibanaのプラグインの作成方法を順を追って","tags":["Kibana","plugin"],"title":"Analyze UIとKibanaのプラグインの作成方法(第2回)"},{"contents":"あけましておめでとうございます。今年はサボりがちだったブログをちょっとずつ復活させようかと。 ということで、第1弾として、昨年少し作っていたKibanaのプラグインを何度かに分けて紹介したいと思います。\n今回はAnalyze UIというプラグインの紹介です。\n今回はインストール方法と簡単な機能紹介です。 細かな紹介は個別にやりたいと思います。\nAnalyze UI pluginとは? Elasticsearchの_analyzeというAPI\u0002(個人的に好きなAPIです)をご存知でしょうか?\nElasticsearchは全文検索エンジンで、データの検索には転置インデックスというものを使用します。 Elasticsearchにデータを登録する際に、text型のデータの場合、この転置インデックスのキーとなる単語を決める処理のことをAnalysisと呼びます(Analysisの詳細については割愛します。後日説明するかも?)。 このAnalysisの処理が、入力されたデータの文字列に対してどのように行われて、結果としてどんな単語がキーとして用いられているかを確認できる機能が_analyze APIです。検索で単語がうまくヒットしないな?とか、なんで、こんなので検索結果に出てくるんだ?といった場合、このAPIを利用すると、どのような単語で転置インデックスが作られているかがわかるので、検索にヒットしない/する理由を見つけることができます。\nElasticsearchの便利な点はRESTfulなAPI+JSONでやりとりができる点なのですが、_analyze APIの結果をJSONで受け取っても、見るのにちょっと苦労します。。。こんな感じ。\nリクエスト:\nPOST _analyze { \u0026#34;analyzer\u0026#34;: \u0026#34;kuromoji\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;今年はブログをいっぱい書きますよ!\u0026#34; } レスポンス:\n{ \u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;今年\u0026#34;, \u0026#34;start_offset\u0026#34;: 0, \u0026#34;end_offset\u0026#34;: 2, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 0 }, { \u0026#34;token\u0026#34;: \u0026#34;ブログ\u0026#34;, \u0026#34;start_offset\u0026#34;: 3, \u0026#34;end_offset\u0026#34;: 6, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 2 }, { \u0026#34;token\u0026#34;: \u0026#34;いっぱい\u0026#34;, \u0026#34;start_offset\u0026#34;: 7, \u0026#34;end_offset\u0026#34;: 11, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 4 }, { \u0026#34;token\u0026#34;: \u0026#34;書く\u0026#34;, \u0026#34;start_offset\u0026#34;: 11, \u0026#34;end_offset\u0026#34;: 13, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 5 } ] } このくらいの量であればまだなんとかなりますが、文章が長くなると辛いですよね。\nということで、GUIがあると便利だろうなぁと。で、作ってみましたというのが今日紹介するKibana用のAnalyze UIプラグインです。 こんな感じで、Kibanaのアプリの一部として動作しブラウザ上で、入力テキストの文字列がどのようにanalyzeされて、単語になるかがわかります。\n(先ほどのAPIのサンプルと同じものを画面で入力した結果になります)。\nインストール方法 現時点の最新版Kibana(6.1.2)に対応しています。 Kibanaのディレクトリでkibana-pluginコマンドを利用してインストールします。\n./bin/kibana-plugin install https://github.com/johtani/analyze-api-ui-plugin/releases/download/6.1.2/analyze-api-ui-plugin-6.1.2.zip これだけです。 で、Kibanaを起動していただくと、左のメニューに「Analyze UI」という項目が増えています。\nクリックすると、Analyze UIが表示されます。\n初期画面は入力された文字を特定のAnalyzerで処理した場合の結果を見るための画面です。綱目の説明は画像をご覧ください。\n先ほどのJSONよりは見やすくなったかと思います。 そのほかにもいくつか画面や機能があるのですが、今日はこの辺りで。 「_analyze API便利なんだけど、JSONは。。。」とか「検索うまくできないなぁなんでだろう?」と思っている方は、ぜひ試して見ていただければと。 問題点などありましたら、GitHubのIssueを登録してください。\n","date":1516343806,"dir":"post/2018/","id":"4afcb20d4d95bcd1bde3aa6b7f552660","lang":"ja","lastmod":1516343806,"permalink":"https://blog.johtani.info/blog/2018/01/19/how-to-make-kibana-plugin-example-analysis-ui/","publishdate":"2018-01-19T15:36:46+09:00","summary":"あけましておめでとうございます。今年はサボりがちだったブログをちょっとずつ復活させようかと。 ということで、第1弾として、昨年少し作っていたK","tags":["Kibana","plugin"],"title":"Analyze UIとKibanaのプラグインの作成方法(第1回)"},{"contents":"今年は紅白を見ながら書いてます。 今年はいろんなところに出張に行ったなぁ。\n振り返り(2016年に書いた抱負から) まずは去年の抱負を元に。\nもちろん英語の継続 もちろん継続してます。英会話しながら海外TVドラマや映画を見てます。 ちょっとずつ英語字幕でも見ようとしてますが、まだまだだなぁ。 あと、TOEICを受けてないんで、それは受けないと。 見たドラマはこの辺です。\nER ウォーキング・デッド Agent of Shield SUITS Mr.Robot(いまいち話の展開についていけなかった) 継続的にイベントに登壇 OSCに今年もブース出してセッション持ってました。 勉強会ももちろんやりました。 あと、外部のカンファレンス(FOSS4G、BigData Analytics、db tech showcaseなど)や 勉強会(monitoring勉強会やCA.ioなど)にも登壇させていただきました。 もっと外部から読んでいただいたり、CfPに応募して通過できるようにしないとなぁ。\nもっと開発&ブログ ブログはすみません。。。来年頑張ります。。。 ブログの代わりに書籍を出せました。データ分析基盤系の書籍になるので、興味のある方はのぞいて見ていただければ。\n開発はちょっとやってます。今年後半はKibanaのプラグインとかをちょっと書いてました。 Ingest-CSVもちょこちょこバージョンアップに追従してたりします。\nサポートエンジニア獲得! 獲得しました!(自分の成果かどうかはわかりませんが。。。) 今は3名体制でサポートしてもらってます。おかげさまでだいぶサポートする機会が減ってきました。 開発は世界各地どこでも募集中だったりしますので、ぜひ連絡いただければと。\n個人的な検索勉強会の再開 再開しました。検索エンジン自作入門を知人と隔週くらいで読んでます。読んでるだけではあれなんで、実装もしてたり。全然違う言語でトライして見ようと思ったのでRustで書き始めてます。まずは、単純なところからと思ったんですが、 Rustの書き方の違いにだいぶ戸惑ってます。。。\n振り返り(今年あったできごと) ここからは今年の出来事を。\n初アメリカで釣り Nintendo Switch! 初Japanチームオフサイト チーム変更 初Berlin Buzzword! 母校(大学)訪問 Kibanaプラグイン開発 今年も初モノがちらほらとありますね。 今年もカレンダー振り返ってたら「え?これ今年だったの?」ってのがちらほらありました。。。\nアメリカで釣りやりました。自社のカンファレンスElastic{ON}のあとに、エンジニアが集まるミーティングがあるんですが、そこで1日Fun Dayがあって、そこで釣りをやりました。 魚群探知機とかで魚探すんですね、最近のは。2、3匹釣ったので非常に楽しかったです。 来年はスノーシューにチャレンジする予定。\nNintendo Switch買って、ゼルダやりました。今はイカやってます。 イカ欲はちょっと減ってるかもなぁ、1に比べると。 あとは、子供に買ったマリオやったりしてるかな。\nここ10年くらい行きたいと思っていたカンファレンス、Berlin Buzzwordに行ってきました! これが今年一番嬉しかった出来事です。Luceneコミッターの方々にも会えたし。特にPoliceman JenkinsのUweさんに会えたのが本当に感激でした。。。 来年も行けるといいなぁ。。。\n今年も出張が多めだったのであちこち飛び回ってたなぁ。 そんな飛び回っている中で、故郷である広島(出身地?)に出張で行ったので、母校に顔を出してきました。 変わってなかった。。。自分が一期生なので、自分が入学した時はまだクレーンとか立ってるような新校舎だったんだけど、それが20年くらい経て、だいぶ古くなってました。。。 広島市内は港近くに高速道路とか出ててだいぶ様変わりしてました。 ただ、小学校も高校も変わってなかったなぁ。久々に高校の同級生にも会えたし。 また、機会があればぜひ行きたいなと。帰省する場所ではなくなったので、行く機会がないんですよね。。。\n開発もちょっとやってます。Kibanaのプラグインに挑戦して見てます。 いまだにJavaScriptは苦手なんですが。。。 ちょっとずつ改良して、ひょっとすると本体とかに取り込めるかな? あとは、今年始めたRustをちょっとずつ継続して行きたいなと。\n来年の抱負 最後は来年の抱負を。\nもっと英語の継続&TOEIC 継続的にイベントに登壇 CfPもっと出すぞ! もっとブログ! 雑誌やWeb系雑誌で記事を。 コミュニティを別の方法で盛り上げ Elasticsearchなど検索系の開発にも参加 英語はもちろんですね。今年は12月の自社イベントに合わせて多くのAPJチームの人が来て、 チームで会話できたし、もっと英語やらないとなぁと。前よりもちょっとは喋れるようになった気がしてます(気がしてるだけで、喋れてるかどうかは不明)。あとは、TOEIC受けて、実力チェックしてみないとなぁ。\nイベント登壇はまぁ、DevRelですから、一応。 来年もとりあえず、3月までは毎月どこかでブース出してます。 Ask Me Anything的なブースの出し方を今年はしてみようかなと思ってるので、 ちょっと使い始めたけど、この辺よくわからないと思ってる方、ぜひ質問しに来てください。 ブース出すだけじゃなくて、スピーカーとしていろんな場所で喋れるようにしないとなぁと。 もっと幅広く知ってもらえるように雑誌とかで連載できるようにしたいなぁと思ってます。 また、日本語の入り口の情報を増やすためにブログも書かないとなぁ。\n勉強会も継続しますが、別の方法でも盛り上げて行きたいなぁと。 勉強会はどうしても聞く人が多くて、ユーザーの間での交流や情報交換とまでは行ってない気がするし、discuss.elastic.coというフォーラムで質問は増えて来てるけど、もう少し交流しやすい場があると使ってもらえるかなぁ?と思っていたり。 何かおすすめとかあれば、連絡ください。 meetup.comの勉強会のページにも掲示板はついてるんだけど交流しにくそうだし。\n来年は自分が最も興味のある検索系の開発にも参加したいなぁと。 Elasticsearchをちょっとずつ時間見つけてやってたりはしますが、もう少し首を突っ込んで行きたいなぁと。Swiftypeもジョインしたし。もっと検索やって行きたい気持ちが強いので。\nさて、ということで、今年もあと1時間なくなりました。 今年も様々な面で色々な方々に助けていただけました。本当にお世話になりました。 この場を借りてお礼申し上げます。\n来年ももちろん、色々な方に助けてもらうと思いますが、よろしくお願いいたします!\n","date":1514723443,"dir":"post/2017/","id":"7c21b70f9e9c782c1f5153268e0cc1c1","lang":"ja","lastmod":1514723443,"permalink":"https://blog.johtani.info/blog/2017/12/31/looking-back-2017/","publishdate":"2017-12-31T21:30:43+09:00","summary":"今年は紅白を見ながら書いてます。 今年はいろんなところに出張に行ったなぁ。 振り返り(2016年に書いた抱負から) まずは去年の抱負を元に。 もちろ","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2017)"},{"contents":"Merry Christmas! Elastic Stack Advent Calendar 2017の24日目の記事になります。\nちょっとですが、2018年のElasticについて書いてみようかと思います。\nイベント いくつか出展が決まっているイベントがあるのでまずは宣伝を。\nOSC Osaka 2018 まずは、1月25日、26日にOSC Osaka 2018に出展し、話をします。参加者がいそうであれば、25日や26日の夜に勉強会もありかなぁと思っています。 セッションでは入門的な話をする予定です。ブースにいますので、色々質問がある関西の方はぜひご参加ください。\nDeveloper Summit 2018 2月15日、16日はDeveloper Summit 2018に出展します。 こちらでもブースにいますので、AMA(Ask Me Anything)的に使っていただくのもいいかなと。 デブサミに参加される方はぜひお立ち寄りください。\nManabiya 3月23日、24日はManabiyaに出展します。 こちらでもAMAのつもりでブースを出す予定です。質問がある方はぜひお立ち寄りください。 こちらのイベントは初めての開催になるようなので、どんなイベントになるか楽しみにしています。\nイベント回りはこの辺りで。 また、1月末に勉強会を予定しています。決まり次第またMeetup.comの方々にメールを出す予定です。\nElastic Stackの2018年は? Canvas! 昨年のElastic{ON}でみなさんをCanvasがリリースされるかなぁと。 現在、みなさんにテストしてもらえるようにcanvas.elastic.coというサイトを公開中で、実際にインストールして試すことができるようになっています。 ぜひ、触って、全く新しいUIを体験して見てください。\nSQL? こちらも昨年のElastic{ON}でみなさんから反響があったものです。 もう直ぐでてくるのではないかなぁと。\nその他は? いくつか面白そうで、取り込み済みのものをピックアップしておきます。\nAdd ranking evaluation API 検索クエリなどに対して検索結果のランクのクオリティを評価するためのAPIの追加(7.0予定) JDK9サポート? 6.2でサポートされそうです。が、LTSのJDK8が推奨のままの予定です。 High-level REST ClientでいくつかAPIが追加 https://github.com/elastic/elasticsearch/pull/27574、https://github.com/elastic/elasticsearch/pull/27351 APM正式リリース? ベータ版がリリースされているので、秒読み段階? ということで より詳しく知りたい方は、サンフランシスコで開催されるElastic{ON} 2018に参加するのが一番です!(ステマ) 私も参加予定ですので、ぜひ、現地でお会いし、色々な情報をゲットしましょう。\n明日で、今年のAdvent Calendarも最後です。micci184さんの記事を楽しみにしましょう!\n","date":1514124616,"dir":"post/2017/","id":"f3a9b931b7f552a4f9dfa61ce4f39f0e","lang":"ja","lastmod":1514124616,"permalink":"https://blog.johtani.info/blog/2017/12/24/elastic-2018/","publishdate":"2017-12-24T23:10:16+09:00","summary":"Merry Christmas! Elastic Stack Advent Calendar 2017の24日目の記事になります。 ちょっとですが、2018年のElasticについて書いてみようかと思います。 イベント いくつか","tags":["elasticsearch"],"title":"2018年のElasticは?"},{"contents":"Elastic stack (Elasticsearch) Advent Calendar 2017の1日目の記事になります。\nまだ、1ヶ月を残していますが、簡単に今年起こったことを振り返ってみようかと思います。思った以上に色々ありましたね。。。\nElastic Stack 5.2.0リリース (1月) リリース記事はこちら\nHeatmapがKibanaで追加されたり、Heartbeatがベータですが追加されました。 個人的には、Terms aggregationのFiltering Valuesによるパーティションが便利になったと思います。Terms Aggsでページングに似たことができるようになりました。\nElastic{ON}17開催 (3月) 第3回目のユーザカンファレンスが開催されました。 バレーダンサーの踊りから始まったキーノート、様々なユーザ企業によるユースケース発表などいろいろありました。 セッションはこちらのサイトからから録画を見ることができます。 SQL for ElasticsearchやAwardが目を引いたと思います。SQL対応まだ出てきていないですが、もうすぐじゃないかと!\nElastic Stack 5.3.0リリース (3月) リリース記事はこちら\nFilebeat moduleが導入され、ログファイルを取り込んでKibanaで可視化するまでの手順がより簡単になりました。Elasticの目指しているものの一つに、シンプルな使い方、簡単にはじめられることといったものがあります。KibanaのTimepickerもより便利になったのも、このバージョンからです。\nShayがCEOに (5月) 2月にすでに発表されていましたが、Elasticsearchの生みの親のShay BanonがCEOに正式に就任しました。CEOになってさらに、精力的に様々なことをやっていて、本当にすごいなと思います。\nElastic Stack 5.4.0、6.0.0-alpha1リリース (5月) 5.4.0リリース記事はこちら、6.0.0-alpha1リリース記事はこちら\n5.4.0は節目になるリリースでした。Machine Learningがベータリリースとして、X-Packに追加されましたし、ElasticsearchではCross Cluster Searchの改善が進みました。LogstashではPersistent QueueがGAになりましたし、KibanaにはTime Series Visual BuilderやEvent Contextなどが追加されますます使いやすくなりました。\nまた、6.0.0のalpha版も同時にリリースされ、様々な方からのフィードバックが集まり始めました。\nElastic Cloud Enterprise GAリリース (5月) Elastic Cloudのバックエンドの技術を製品に採用したものになります。 多くのElasticsearchクラスタを管理しないといけない方には朗報でした。\nOpbeatがJoin (6月) Opbeatチームがジョインしたのが6月です。Elastic StackがAPM\u0002(Application Performance Monitoring)でも活躍することになりそうです。APMの仕組みとしては、APM Agentをアプリ側に配置し、APM Serverへデータを送信し、Elasticsearchに保存、Kibanaで可視化するという流れになります。\nElastic Stack 5.5.0リリース (7月) リリース記事はこちら\nMachime LearningがGAリリースになったのが5.5.0です。色々な方から質問を受けました。それ以外にも、ElasticsearchのWindows MSI InstallerやKibanaのFilter editorなどが追加されました。Filter editorはこれまで検索条件を記述するのが難しいと感じていたKibanaユーザにとても喜んでもらえたものじゃないかなと。 GrokDebuggerが導入されたのもこのタイミングです。\nElastic Stack 5.6.0リリース (9月) リリース記事はこちら\n5系最後のマイナーリリースであり、6へのアップグレードが楽になる様々な仕組みが用意されたのがこのバージョンです。ElasticsearchのJava High level REST clientが導入されたのもこのバージョンです。本当に様々な機能が次のメジャーバージョンとの互換性のために組み込まれています。。。\nElastic Cloud on GCP (9月) リリース記事はこちら\nこれまで、AWS上のみで展開していたElastic CloudがGCP上でも展開されることになりました。残念ながら、日本リージョンはまだありませんが、問い合わせなどが増えれば今後サポートされる可能性が高くなると思います!\nElastic APM alpha (9月) リリース記事はこちら\nOpbeatチームによりElastic StackのAPMがAlphaですがリリースされました。APMがOpen Sourceで利用できるんです!Agentがもっと増えてくると色々なことに使えるようになると思います。ぜひAgentを作成してみてください!\nElastic Stack 6.0.0リリース (11月) リリース記事はこちら\n待ちに待った6.0.0のリリースです。新機能については本日(12/1)の昼に行われるウェビナーをご覧ください!\nSwiftypeがJoin (11月) ニュースリリースはこちら\nSwiftypeと呼ばれる検索のSaaSを提供している会社がジョインしました。 個人的には今年一番嬉しいニュースです。やはり、検索が好きなので。 簡単にSite Searchを構築できる仕組みは非常に面白いものです。 興味のある方は、ぜひ触ってみてください。日本語固有の機能などはまだないので、今後関わっていければなーと。\nElastic{ON} Tour Tokyo開催 (12月) まだ開催前ですが、今年も東京で1dayイベントを開催します。 残念ながら、もうSold outなので、キャンセル待ちになってしまっているみたいですが。私もスピーカーとして喋りますし、AMAブースにも立っています。 参加される方はぜひ声をかけていただければと思います。\nOSC 2017.Enterprise (12月) オープンソースカンファレンスで今年も様々な都市に出張しました。 今年の締めくくりということで、12/8に渋谷で開催されるカンファレンスに出展します。時間のある方は、ぜひブースに遊びに来てください。入門者向けのセッションもあるので、こちらもお待ちしております。\nまとめ 超駆け足ですが、今年を振り返ってみました。 今年もいろんなことがありました。書くのが大変だったw。 OSCなどイベントで声をかけていただいた皆様、ありがとうございました。\nさて、Elastic Stack Advent Calendar 2017は始まったばかりです。これからの記事を楽しみにしています!\nということで、 次はaeroastroさんの「Elasticsearchのインデックスを本当の意味で無停止再構築する方法」(Advent Calendarのページはこちら)になります、お楽しみに!\n","date":1512054000,"dir":"post/2017/","id":"fa0486610d8a02cea245c13c85b6de27","lang":"ja","lastmod":1512054000,"permalink":"https://blog.johtani.info/blog/2017/12/01/whats-happen-at-elastic-in-2017/","publishdate":"2017-12-01T00:00:00+09:00","summary":"Elastic stack (Elasticsearch) Advent Calendar 2017の1日目の記事になります。 まだ、1ヶ月を残していますが、簡単に今年起こったことを振り返ってみようかと思います。思った以上に","tags":["elasticsearch"],"title":"2017年のElastic StackとElastic"},{"contents":"Swiftypeでサイト内検索? プレスリリース:Elasticがサイト内検索サービス最大手のSwiftypeを買収が出ましたが、SwiftypeチームがElasticにジョインしました!\n自分のブログ検索に導入してみる? SwiftypeはSite Searchをサービスとして提供しています。 実際に指定したサイトのデータをクロールして、インデキシングし、検索できるようになります。 ものは試しということで、自分のブログを登録してみました。検索窓はつけてないですが。 14日間のFree trialがあるのでそちらで試してみましょう。 検索窓はデモとか作れたらかな。\nということで、Free trialへ まずはユーザ登録です。Googleのアカウントと連携するか、Swiftypeにメルアドを登録するかが選択できます。 登録できたら、次にどちらのプロダクトを使うかという選択画面が出てきます。 今回はサイト検索して見たいので、「Site Search」の「START FREE TRIAL」をクリックします。\nEngineの指定 Web Crawlerを利用するか、独自にSwiftypeのAPIを利用してデータを登録するかを選択します。\n今回は、お手軽な方のCrawlerを選択します。 すると次に、クロールしたいURLの指定画面が出てきます。\n今回は自分のブログなので、\u0026lsquo;http://blog.johtani.info\u0026rsquo;を指定します。\nで少し待つと、URLのチェック(存在チェックとか、接続チェックとか)が終わり、今回作成するEngineに名前をつける画面が出てきます。 「My Blog search」という名前にしてみました。\nsitemapがあるかどうかをCrawlerがチェックしています。 私のBlogはOctopressでできていて、sitemap.xmlも作ってくれているので、これを元にCrawlerはクロールをしてくれます。そのほかにもRSSやAtomサポートもあるみたいですね。 「COMPLETE SETUP」を押すと、Engineの管理画面が出てきます。\n「CRAWLING」という表示が出ています。クロールしている最中です。これが終われば、「PREVIEW」に代わり、検索できる準備ができたことになります。 実際にPREVIEWして見ると、次のような検索ができるようになります。\nそのほかにはWeightの調整画面などもありますね。フィールド毎に重み付けを変えて見たりもできます。\n日本語独自のAnalyzerなどはまだないので、そのあたりができてくるともっと便利になりそうです。 とりあえず、気になる方は触って見てはいかがでしょうか? 個人的は検索に関するサービスが出てきたのですごく楽しみにしています!\n","date":1510280089,"dir":"post/2017/","id":"c20d71627e66a044b21780f56f2f9504","lang":"ja","lastmod":1510280089,"permalink":"https://blog.johtani.info/blog/2017/11/10/welcome-swiftype/","publishdate":"2017-11-10T11:14:49+09:00","summary":"Swiftypeでサイト内検索? プレスリリース:Elasticがサイト内検索サービス最大手のSwiftypeを買収が出ましたが、Swifty","tags":null,"title":"Swiftypeがジョインしたので触ってみました"},{"contents":"久々に執筆しました。といっても、以前の書籍の更新版です。 まぁ、更新版といっても、私以外の方々は結構な量を書き直しor新規書き起こしされてますが。。。\nということで、みなさん「買って」から感想をいただけるとうれしいです!\u0002(以下の画像でAmazonにジャンプできます!Kindle版も発売中です。)\n今回もElasticsearchの章を担当しました。 5.4ベースで書きましたが、ちょっとずつ6でどう変わるかなども記載してあります。 また、付録ではLogstashやBeatsにもちょっと触れています。 また、自分が一番好きなKibanaの機能であるDev ToolsのConsoleについても記載してあります。こちらも合わせて目を通していただければと。\nみなさんのフィードバック(ツイート、ブログ、Amazonのコメントなどなど)をお待ちしております!\n","date":1505955750,"dir":"post/2017/","id":"4f88f3eebe44285ded812939553ef94c","lang":"ja","lastmod":1505955750,"permalink":"https://blog.johtani.info/blog/2017/09/21/release-intro-logging-analysis-system/","publishdate":"2017-09-21T10:02:30+09:00","summary":"久々に執筆しました。といっても、以前の書籍の更新版です。 まぁ、更新版といっても、私以外の方々は結構な量を書き直しor新規書き起こしされてます","tags":["elasticsearch","kibana","本"],"title":"データ分析基盤構築入門 を一部執筆しました。"},{"contents":"久々のブログ。 Elasticsearch勉強会を主催してますが、 プロダクトを超えて、検索で共通してある課題とか、悩みとか、あるかなぁと。 その辺りを話す場所を考えてみるのいいかもと思い、検索座談会ってのを5人でやってみた。\nとりあえず、初めてなので、5名ほどで。プロダクトはかぶってない感じでした。\n話した議題はこの辺り。 形態素解析の辞書は何を使ってる?有償のもの? そもそも形態素解析? 辞書の更新とかは? シノニムってどうしてる? サジェストとかのデータはどう作ってる?どうしてる? 検索ログとかから作ってる? 検索結果のランキングって検索結果だけで決めるの? 検索漏れとかキーワードのミスマッチとかどうしてる? 今後話したい内容はこの辺かな? 緯度経度系の検索 画像検索、音声検索 検索のキーワードの調査とかしてる人とかいるかな? どんな機能が欲しい? 前処理としてはどんなことをしてる? このあとどうしていくかはまだ考え中。知り合いを捕まえて、どんなことしてるかを聞きにいくのもいいし、議題みたいなことを決めて、それを話してくれそうな人にコンタクトして議論するのもありかなぁ。 普通の勉強会みたいなのにするかもしれないし。 とりあえず、どのくらい興味を持ってる人がいるのかがわからないので。。。\nもちろん、Elasticsearch勉強会は別でやっていきますよ。\n","date":1495639453,"dir":"post/2017/","id":"29b4c2b5adcd80ced1612128b3ca95a9","lang":"ja","lastmod":1495639453,"permalink":"https://blog.johtani.info/blog/2017/05/25/search-meetup/","publishdate":"2017-05-25T00:24:13+09:00","summary":"久々のブログ。 Elasticsearch勉強会を主催してますが、 プロダクトを超えて、検索で共通してある課題とか、悩みとか、あるかなぁと。 その","tags":["勉強会"],"title":"検索座談会ってのをやってみた"},{"contents":"今年はRioのプレイバック\u000e見ながら書いてます。 今年はなんか長い一年だった気が。\n振り返り(2015年に書いた抱負から) まずは去年の抱負を元に。\n英語の継続 継続してます。まぁ当たり前ですが。もう少し話す機会増やさないとだなぁと思いつつ。英会話しながら、海外TVドラマ見ながら。 見たドラマはこの辺かな?\nER SUITS メンタリスト Numb3rs エレメンタリー Agent of Shield あと、映画も見てます。とりあえず、耳を慣らすために字幕ありで見てるので、 英語だけでとは行きませんが。。。 そろそろ同じ映画を英語字幕で見るとかしたほうがいいのかもなぁ。\nもっとElasticsearchの開発に参加 一応参加してます。ちょっとずつですが。 イベントが重なるとできなくなるので、小さなPRとかを細々とって感じですが。。。\n人員の倍増? 倍増したかな?現時点で日本は8名になりました。そのうち1人は完全リモートです。 来年も倍増とは行かないだろうなぁ。取り急ぎ、サポートエンジニアが足りてないのでそこを埋めないと。。。\n日本語情報発信 これはちょっと足踏みしてるかも。ブログの翻訳とかはやってるんですが、もう少しなんとかしないとなぁ。ブログも書かないと。。。\nSplatoon S+? なりました!とりあえずS+とSを行ったり来たりしてる感じです。 メインはノヴァネオですが、Sに落ちたら違う武器でS+に上がるまでチャレンジするってのをやってます。わかば、バケスロソーダ、プライム、ワサビくらいはやったかな? そろそろまた違う武器かなぁ。S+99は無理そうなんで。。。\n振り返り(今年あったできごと) その他の今年の出来事。\n初香港 初プラハ OSCなど、東京以外でのカンファレンス参加 厄年 東京オフィス! BBLとかトレーニング lucene-gosenをちょっとメンテ Podcastデビュー? 初モノ今年も多いかな。 今年は、昨年よりは長く感じた一年でした。 月1くらいで出張してたのもあるのかなぁ? 香港、プラハはもちろん会社のイベントです。 香港はジャッキーチェンの映画を彷彿とさせるところがちょくちょくあって面白かったです。 ビルとかの補修の足場が竹竿とか。 プラハも面白かったです。やっぱりヨーロッパの古い町は歴史のある建物が多くて楽しいです。\nOSCなどのイベントも色々行きました。福岡、名古屋、大阪、京都、札幌と回りました。 それとは別に大阪、福岡も行ったかな。 来年は沖縄と広島に行きたいなぁ。。。 出張のついで?じゃないですが、御朱印集めし始めました。神社仏閣もいいですよねぇ。\n厄年はきつかった。。。たまたまだとは思うけど、お祓いに行ったのが効いたのかなぁ。後半は特に問題なかったかな。腕時計無くしたと思ったら見つかったりしたし。\n弊社東京オフィスができました。(あんまり行ってないけど) ときどきアクロクエストさんがセミナーを開いたりしてます。 昨年のTour Tokyo後のMeetupでもイベントスペースを使って、Drinkup(勉強会の懇親会だけバージョン)もやりました。 今後もちょこちょことイベントをやってみようかな?\nBBLも始めました。あまりきちんと宣伝してないからそれほど依頼は来てないですが。 あとは、今年も2回日本語でトレーニングしました。 前回はほぼ満席にまでなりました。 来年も頑張りたいかな。ショートカットするためにもいいと思うんで、トレーニングを受けて欲しいんです。。。\nlucene-gosenのメンテもしました。 といってもプログラムではなく、ビルドシステムをAntからGradleに変更したんですが。 来年もちょっとずつ触りたいな。機能面で拡充するかはわからないですが。。。\nPodcastにもデビューさせていただきました。 wyukawaさんのPodcastです。「johtaniさんとElasticsearchについて話しました」楽しかったです。 また出たいなぁというか、喋るの面白かった!\n来年の抱負 もちろん英語の継続 継続的にイベントに登壇 もっと開発&ブログ サポートエンジニア獲得! 個人的な検索勉強会の再開 英語はまぁ、当たり前ですね。会社の人つかまえてもっと喋る時間増やさないとだな。\n来年もいろんなカンファレンスなどに出てブース出したり、セッション持ったりして もっともっと広めていかないとなぁ。 あとは、勉強会とMeetupもやっていかないと。入門編と上級編みたいに分けてみるのもありかなぁと考えて見たり。 スピーカー、ご意見募集しております。\n開発に時間をさくための時間の活用をしていかないとなぁと。 どうも時間の使い方がまだ上手くないので。ブログも一緒ですね。。。 月1くらいのペースではかきたいな。。。 ブログもそうだけど書籍もかな???? あと、外資系の他の会社の人ともまた飲みたいなー。\n開発の時間を確保という面ではサポートエンジニアも募集中です。 最近、クライアントが増えて来てチケットが増えて来てるんで、サポートしたりもしてるんです。。。 自分の時間を増やすためにもサポートエンジニアを確保しないと。誰かいい人いないかなぁ。\n個人的にやってた勉強会を忙しいって言って中断してるので、再開しないと。。。\nということで、今年もあと數十分になってしまいました。 今年も色々な方に助けていただけました。お世話になりました。 この場を借りてお礼申し上げます。\n来年もいろんな方々に助けてもらうと思いますが、よろしくお願いいたします。\n","date":1483190534,"dir":"post/2016/","id":"16f1046144ad9ee7bb96214ba7ae7516","lang":"ja","lastmod":1483190534,"permalink":"https://blog.johtani.info/blog/2016/12/31/looking-back-2016/","publishdate":"2016-12-31T22:22:14+09:00","summary":"今年はRioのプレイバック\u000e見ながら書いてます。 今年はなんか長い一年だった気が。 振り返り(2015年に書いた抱負から) まずは去年の抱負を元に","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2016)"},{"contents":"Merry Christmas! Elastic stack Advent Calendar 2016 最終日の記事になります。\n簡単に今年の変遷を振り返ってみます。\nElasticsearch 2.2 (2月) Elasticsearch 2.2.0、2.1.2、1.7.5リリース クエリプロファイラやGeo系の性能改善などが取り込まれました。 また、同時期にリリースされたKibana 4.4ではColor pickerやShare用のURLの短縮化機能なども追加されました。\n第2回目のユーザカンファレンス、Elastic{ON}開催(2月) サンフランシスコで、弊社第2回目のカンファレンスが開催されました。 2015年の会場よりも大きくなり、多数の方に参加いただきました。 ここで、以下の発表がありました。\nElastic StackとX-Packの紹介 これまで、ELK stackと呼ばれて意味明日が、Beatsチームの参加により、ELKだけではなくなったこともあり、Elastic Stackと呼び名を変える事になりました。 また、Marvel、Shield、Watcherなどの商用の拡張機能についても、 単体の名称ではなく、X(Extension)-Packと1つの名前になる事に。 詳細については公式のブログをご覧ください。\nElastic CloudとElastic Cloud Enterpriseの発表 2015年にElasticにジョインし、 これまでFound.no(Found)と呼ばれていた弊社のElasticsearch as a ServiceがElastic Cloudと名称変更しました。 また、Elastic Cloudで培っているノウハウを詰め込んだElastic Cloud Enterpriseも発表しました。実際に利用可能になるまでには まだもう少しかかってしまいますが、アルファ版が公開されていますので、興味のある方は触ってみてください。\nElastic{ON}2016で撮影された、「Elasticsearchがないあなたの人生はどうなりますか?」 といった面白い動画も公開されています。\nElasticsearch 2.3リリース(3月) Elasticsearch 2.3.0および2.2.2をリリース Reindex APIが登場し、Mappingの変更やShard数の変更など、色々とデータの更新などがやりやすくなりました。 また、Task Managementの機能も追加され、長時間かかる処理を間違った場合などの対処が楽になりました。 個人的には、Deprecation Loggingの機能が導入されたことが嬉しいこととなります。次期メジャーバージョンで廃止される機能についてログに出力されるようになりました。 実際に運用されているアプリで利用している機能が今後なくなるかどうかをログを見るとわかるという仕組みです。\nRally登場(4月) Rally登場:Elasticsearchのベンチマークツール Elasticsearchのベンチマークツールがリリースされました。 定期的にElasticsearchの性能を計測することは問題点を見つける事に役に立ちます。そういった手助けをしてくれるツールが公開されることは非常に便利なことかと。\nElastic Stack 5 alpha1 リリース(4月) Elastic Stack 5.0.0 alpha 1 リリース Ingest NodeやLucene 6、新しいKibanaのUIなど多くのものが詰まっていました。ここから多くのユーザにテストしてもらい、5.0の正式リリースを迎えることができました。\nElasticsearch 2.4.0リリース(8月) 2.xの最後のマイナーバージョンリリースです。 Reportingなどの追加とドットつきフィールド名の復活がありました。\nElastic Stack 5.0.0 beta1 リリース(9月) Elastic Stack Release - 5.0.0-beta1 ついにベータです。Painlessがスクリプトのデフォルトになったり、TimelionがKibanaに取り込まれるなど、正式リリースまであと少し!\nPrelertチームジョイン(9月) Welcome Prelert to the Elastic Team Machine Learningエンジンを開発し、Elasticsearch,Kibanaとの組み合わせの製品をリリースしていたPrelertという会社がジョインしました。 Elasticsearchに保存された多くのデータをより活用していただくことができるかと思います。 Elastic{ON} Tour 2016 Tokyoで弊社SAの大輪の発表も人気があるものでした。まだベータ段階ですが、利用して見ることも可能です。 ビデオなどが公開されたらまたツイートしようと思います。\nElastic{ON} Tour Tokyo 2016開催(12月) 今年で2回目のTokyoローカルの1日イベントでした。 ブログは「まだ」書いてませんが、、、今回も盛りだくさんのイベントになりました。 早朝のトレーニング(ハンズオンではない)にも80名近くの方に参加していただけましたし、私はKibanaのキーノート+デモという大役をもらいましたし、ちょっと大変でした。 今年もAMA(Ask Me Anything)ブースが大盛況でした。 色々な方から、弊社のサポート、開発者が色々な質問を受け、それに答えるという形です。楽しんでいただけたかと思います。 来年もぜひ開催したいなと思っています。\nまた、Elastic{ON}17のセッションもいくつか発表されています。 ぜひ、サンフランシスコで行われる本場のカンファレンスにもご参加ください!\n来年は? 1月後半か2月にElasticsearch勉強会を検討しようと思っています。スピーカーに興味のある方は連絡いただければと。\n会社としては、Elastic{ON}2017が3月にまた開催されます。これで3回目となります。もちろん私も参加予定なので、参加される方は、現地で会いましょう!\nそのほかにもBIG DATA ANALYTICS TOKYOやオープンソースカンファレンス(大阪)、デブサミといったカンファレンスに参加(登壇・ブースなど)予定です。 参加される方は、ぜひブースまでお越しください。\nでは、また来年のAdvent Calendarでお会いしましょう!\n","date":1482591830,"dir":"post/2016/","id":"002d980d74d19b43ff4e2446665e2fe5","lang":"ja","lastmod":1482591830,"permalink":"https://blog.johtani.info/blog/2016/12/25/elasticsearch-6-features/","publishdate":"2016-12-25T00:03:50+09:00","summary":"Merry Christmas! Elastic stack Advent Calendar 2016 最終日の記事になります。 簡単に今年の変遷を振り返ってみます。 Elasticsearch 2.2 (2月) Elasticsearch 2.2.0、2.1.2、1.7.5リリース クエリプロ","tags":["elasticsearch"],"title":"2016年のElastic Stack"},{"contents":"Elastic stack Advent Calendar 1日目の記事になります。\nElasticsearch 5.0が10月末にリリースされました。 リリースのブログでいくつか紹介されているのですが、そこでは紹介されていない機能について2、3紹介しようと思います。\nその前に、5.0、あれ?その前は2.xじゃなかったっけ??と困惑されている方もいるかと思うので、簡単に5となった経緯の紹介をしようかと。\nバージョン番号 なぜ2から5に飛んだのかという話ですが、このスライドがその紹介になっています。\nhttps://speakerdeck.com/johtani/elastic-stack-5-dot-0-alpha1-alpha5?slide=5\nElastic{ON} 2016のキーノートでも紹介がありましたが、KibanaやLogstashとElasticsearchを組み合わせて使うときにバージョンのミスマッチで動かないというユーザの声が上がっていました。 2.xのリリースから、同じ日にKibana、Logstash、Beatsもリリースするようになったのですが、 やはり、バージョン番号が異なるため、ミスマッチで動かないというユーザが時々いました。\nElastic Stackという名称にもなったため、バージョン番号をそろえようという事になり、 Elasticsearch、Kibana、Logstash、Beats全てが5.0.0としてリリースされ、 今後は同じバージョン番号になります。\nちなみに、「5」になった理由はKibanaのメジャーバージョンが「4」だったためです。\nさて、では、いくつか機能の紹介を。\nReindex from remote cluster Reindexが2.3から導入されました。データの再登録ができるようになり、マッピングの変更や Shardの数の変更などが柔軟に行えるようになりました。 便利でしたが、あくまでも同一のクラスタでデータを登録し直す形でした。\n5.0からはこの機能に加えて、異なるクラスタからデータを取得してReindexを行うことができるようになりました。 こんな形になります。\nPOST _reindex { \u0026#34;source\u0026#34;: { \u0026#34;remote\u0026#34;: { \u0026#34;host\u0026#34;: \u0026#34;http://otherhost:9200\u0026#34;, \u0026#34;username\u0026#34;: \u0026#34;user\u0026#34;, \u0026#34;password\u0026#34;: \u0026#34;pass\u0026#34; }, \u0026#34;index\u0026#34;: \u0026#34;source\u0026#34;, \u0026#34;query\u0026#34;: { \u0026#34;match\u0026#34;: { \u0026#34;test\u0026#34;: \u0026#34;data\u0026#34; } } }, \u0026#34;dest\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;dest\u0026#34; } } usernameとpasswordはリモートのクラスタに認証の気候が存在する場合に利用できるオプションです。 また、ReindexのAPIはクエリを使用して、必要なデータだけを取得することが可能です。 この機能により、1.xや2.xのクラスタからデータを移行することが可能になります。\nCustom analyzer test using Analyze API もう一つ、ちょっとだけ便利な機能を紹介します。 独自にAnalyzerを定義(TokenizerとToken Filterなどを個別に設定)して、その挙動を確認するとき、2.xまでは、インデックスを作成してそのインデックスに対して_analyze APIを呼び出す必要がありました。\n5.xからは_analyze APIの読み出しのパラメータで指定できるようになりました。 こんな感じです。ここでは、lowercaseフィルタのあとに、{...}でstopフィルタを パラメータの中で、指定しています。\ncurl -XGET \u0026#39;localhost:9200/_analyze\u0026#39; -d \u0026#39; { \u0026#34;tokenizer\u0026#34; : \u0026#34;whitespace\u0026#34;, \u0026#34;filter\u0026#34; : [\u0026#34;lowercase\u0026#34;, {\u0026#34;type\u0026#34;: \u0026#34;stop\u0026#34;, \u0026#34;stopwords\u0026#34;: [\u0026#34;a\u0026#34;, \u0026#34;is\u0026#34;, \u0026#34;this\u0026#34;]}], \u0026#34;text\u0026#34; : \u0026#34;this is a test\u0026#34; }\u0026#39; ちょっとだけですが、Analyzerなどを試すのが楽になるのではないでしょうか?\nということで、以上が1日目の記事でした。 Logstashなど、他の5.0.0に関する記事もAdvent Calendarに空きがあるようなので、個別にかこうかなと思います。お楽しみに!\n","date":1480581270,"dir":"post/2016/","id":"550becdd08d00fb1e7fd00c2adc3d3d6","lang":"ja","lastmod":1480581270,"permalink":"https://blog.johtani.info/blog/2016/12/01/elasticsearch-5-dot-0-highlight/","publishdate":"2016-12-01T17:34:30+09:00","summary":"Elastic stack Advent Calendar 1日目の記事になります。 Elasticsearch 5.0が10月末にリリースされました。 リリースのブログでいくつか紹介されているのですが、そこでは紹介されて","tags":["elasticsearch"],"title":"Elasticsearch 5.0の便利機能紹介?"},{"contents":"久しぶりに、技術的なブログ書いてます。\nIngest Processorのプラグインを作ってみたくなったので、書いてみました。 ただ書いてみるんじゃ3番煎じになりそうなので、cookiecutterを使ってみました。\nと言っても、同僚のAlexがcookiecutter-elasticsearch-ingest-processorと言うテンプレートを作ってくれているのを使っただけですが。(https://discuss.elastic.co に投稿された記事で、使い方がアニメgifで説明されててわかりやすいです)\ncookiecutterとは、コマンドラインで質問に答えると、テンプレートからプロジェクトが生成できるツールです。 Elasticでは、カスタムBeatを作る時に利用する例がいつかの日本語ブログや発表資料で話題になっていました。 これのIngest Processorのプラグインバージョンです。\n今回は、NEologdも使ってみたかったので、Lucene Kuromoji for NEologdを利用して 指定した品詞の単語だけを抽出するProcessorを作ってみました。\nGitHubのプロジェクト:https://github.com/johtani/elasticsearch-ingest-kuromoji-pos-extract\nCookiecutterの使い方 Cookiecutterのインストールはサイトをご覧ください。\ncookiecutter gh:spinscale/cookiecutter-elasticsearch-ingest-processor あとは、出てくる以下の項目を指定するだけです。\nprocessor_type : Ingest Processorのタイプ名です。kuromoji_part_of_speech_extractとしました。(Alexのだと_を使うとちょっと問題があるので後述) description : readme.mdに利用されます。 developer_name : 名前を記載。Javaのファイルのヘッダに利用 elasticsearch_version : デフォルトで5.0.0-alpha4が指定されているので、特に指定せず 以上の質問に答えたら、プロジェクトのディレクトリ構造が出来上がってます。 プロジェクトのビルドなどにはGradleを利用します。\nプロジェクトのIntelliJ IDEA用のファイルを生成 build.gradleファイルでGradleのideaプラグインがapplyされているので、以下のコマンドを叩けばIntelliJ IDEAのプロジェクトファイル(?)が生成され、IntelliJで開けばすぐに開発ができる状態にできます。\ngradle idea コーディング あとは、必要処理をコーディングします。 実際にコーディングするクラスはorg.elasticsearch.plugin.ingest.kuromoji_part_of_speech_extractのパッケージにある以下の2つです。(パッケージ名にはprocessor_typeの名前が指定されている)\nIngestKuromojiPartOfSpeechExtractPlugin KuromojiPartOfSpeechExtractProcessor IngestKuromojiPartOfSpeechExtractPlugin Pluginというクラスは、プラグインをNodeのModuleとして登録する処理を書くクラスとなります。 生成してすぐは、次のような形になっています。(※importやクラス定義の部分は省略しています。)\n... public static final Setting\u0026lt;String\u0026gt; YOUR_SETTING = new Setting\u0026lt;\u0026gt;(\u0026#34;ingest.kuromoji_part_of_speech_extract.setting\u0026#34;, \u0026#34;foo\u0026#34;, (value) -\u0026gt; value, Setting.Property.NodeScope); @Override public List\u0026lt;Setting\u0026lt;?\u0026gt;\u0026gt; getSettings() { return Arrays.asList(YOUR_SETTING); } public void onModule(NodeModule nodeModule) throws IOException { nodeModule.registerProcessor(KuromojiPartOfSpeechExtractProcessor.TYPE, (registry) -\u0026gt; new KuromojiPartOfSpeechExtractProcessor.Factory()); } ... YOUR_SETTINGプロパティとgetSettings()メソッドはelasticsearch.ymlで指定したい設定を記述する場合の例になります。今回は特に必要ないので両方削除しました。 最終系はGitHubのコードをご覧ください。\nKuromojiPartOfSpeechExtractProcessor Processorは実際にIngest Nodeで行う処理を書くところです。\npublic static final String TYPE = \u0026#34;kuromoji_part_of_speech_extract\u0026#34;; private final String field; private final String targetField; public KuromojiPartOfSpeechExtractProcessor(String tag, String field, String targetField) throws IOException { super(tag); this.field = field; this.targetField = targetField; } @Override public void execute(IngestDocument ingestDocument) throws Exception { String content = ingestDocument.getFieldValue(field, String.class); // TODO implement me! ingestDocument.setFieldValue(targetField, content); } @Override public String getType() { return TYPE; } public static final class Factory extends AbstractProcessorFactory\u0026lt;KuromojiPartOfSpeechExtractProcessor\u0026gt; { @Override public KuromojiPartOfSpeechExtractProcessor doCreate(String processorTag, Map\u0026lt;String, Object\u0026gt; config) throws Exception { String field = readStringProperty(TYPE, processorTag, config, \u0026#34;field\u0026#34;); String targetField = readStringProperty(TYPE, processorTag, config, \u0026#34;target_field\u0026#34;, \u0026#34;default_field_name\u0026#34;); return new KuromojiPartOfSpeechExtractProcessor(processorTag, field, targetField); } } TYPEがIngest APIのPipelineでProcessorを指定するときに使う名前になります。ここは、cookiecutterの時にprocessor_typeに入力した文字列になっています。 kuromoji_part_of_speech_extractだと長いので、kuromoji_pos_extractに変えました。\nexecute()メソッドに// TODO implement me!とあります。 この部分に実際の処理を記述していきます。\nあとは、FactoryクラスでIngest APIで指定された設定項目を読み込みます。 今回作成したelasticsearch-ingest-kuromoji-pos-extractでは品詞を指定する必要があるので、pos_tagsを指定できるように処理を追加しました。\n私が実装したものの説明をするとちょっと長くなりそうなので、GitHubのコードをご覧ください。\nテストのコーディング テストのクラスもテンプレートで生成されています。\nKuromojiPartOfSpeechExtractProcessorTests KuromojiPartOfSpeechExtractRestIT KuromojiPartOfSpeechExtractProcessorTests Processorクラスのテストになります。生成直後は次のような感じです。\npublic void testThatProcessorWorks() throws Exception { Map\u0026lt;String, Object\u0026gt; document = new HashMap\u0026lt;\u0026gt;(); document.put(\u0026#34;source_field\u0026#34;, \u0026#34;fancy source field content\u0026#34;); IngestDocument ingestDocument = RandomDocumentPicks.randomIngestDocument(random(), document); KuromojiPartOfSpeechExtractProcessor processor = new KuromojiPartOfSpeechExtractProcessor(randomAsciiOfLength(10), \u0026#34;source_field\u0026#34;, \u0026#34;target_field\u0026#34;); processor.execute(ingestDocument); Map\u0026lt;String, Object\u0026gt; data = ingestDocument.getSourceAndMetadata(); assertThat(data, hasKey(\u0026#34;target_field\u0026#34;)); assertThat(data.get(\u0026#34;target_field\u0026#34;), is(\u0026#34;fancy source field content\u0026#34;)); // TODO add fancy assertions here } テストメソッドも実装されていますが、パラメータの追加の設定処理やアサーションが書かれてません。 実装に合わせて、アサーションや設定処理を追加しましょう。\nKuromojiPartOfSpeechExtractRestIT こちらはIntegration Testになります。 実際にElasticsearchに対して外部からAPIを叩くような感じです。 APIを叩くときに利用するJSONの設定やアサーションはsrc/test/resourcesにyamlファイルがあります。\n10_basic.yaml 20_kuromoji_part_of_speech_extract_processor.yaml 10_basic.yamlはプラグインがインストールされているかの確認のテストです。特に変更する必要はないです。\n20_kuromoji_part_of_speech_extract_processor.yamlは実際にコーディングしたProcessorが動くかどうかのテストです。\nテストの内容については、GitHubのコードをご覧ください。\nテストの実行とZipの生成 テストの実行とZipの生成は次のコマンドを実行すればOKです。\ngradle check テストに問題があった場合は、コケますし、問題なければSUCCESSと表示が出ます。 成功した場合はbuild/distributions/というディレクトリにzipファイルができています。 これをElasticsearchのpluginコマンドでインストールすれば動きます。\nbin/plugin install file:///path/to/elasticsearch-ingest-kuromoji-pos-extract/build/distribution/ingest-kuromoji_part_of_speech_extract-0.0.1-SNAPSHOT.zip kuromoji_pos_extractの利用方法 Ingest APIには便利なSimulate Pipeline APIがあります。\nということで、mecab-ipadic-NEologdにあったサンプルの文章を使って、使い方の説明です。\nPOST _ingest/pipeline/_simulate { \u0026#34;pipeline\u0026#34; : { \u0026#34;description\u0026#34; : \u0026#34;kuromoji neologd extract test\u0026#34;, \u0026#34;processors\u0026#34; : [ { \u0026#34;kuromoji_pos_extract\u0026#34; : { \u0026#34;field\u0026#34; : \u0026#34;body\u0026#34;, \u0026#34;target_field\u0026#34; : \u0026#34;noun_field\u0026#34;, \u0026#34;pos_tags\u0026#34; : [ \u0026#34;名詞-固有名詞-組織\u0026#34;, \u0026#34;名詞-固有名詞-一般\u0026#34;, \u0026#34;名詞-固有名詞-人名-一般\u0026#34;, \u0026#34;名詞-固有名詞-地域-一般\u0026#34;, \u0026#34;名詞-固有名詞-地域-国\u0026#34; ] } } ] }, \u0026#34;docs\u0026#34; : [ { \u0026#34;_index\u0026#34;: \u0026#34;index\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;type\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;id\u0026#34;, \u0026#34;_source\u0026#34;: { \u0026#34;body\u0026#34; : \u0026#34;10日放送の「中居正広のミになる図書館」(テレビ朝日系)で、SMAPの中居正広が、篠原信一の過去の勘違いを明かす一幕があった。\u0026#34; } } ] } 結果はこちら。\n{ \u0026#34;docs\u0026#34;: [ { \u0026#34;doc\u0026#34;: { \u0026#34;_index\u0026#34;: \u0026#34;index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;id\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;type\u0026#34;, \u0026#34;_source\u0026#34;: { \u0026#34;noun_field\u0026#34;: [ \u0026#34;10日\u0026#34;, \u0026#34;中居正広のミになる図書館\u0026#34;, \u0026#34;テレビ朝日\u0026#34;, \u0026#34;SMAP\u0026#34;, \u0026#34;中居正広\u0026#34;, \u0026#34;篠原信一\u0026#34; ], \u0026#34;body\u0026#34;: \u0026#34;10日放送の「中居正広のミになる図書館」(テレビ朝日系)で、SMAPの中居正広が、篠原信一の過去の勘違いを明かす一幕があった。\u0026#34; }, \u0026#34;_ingest\u0026#34;: { \u0026#34;timestamp\u0026#34;: \u0026#34;2016-07-22T06:18:49.007+0000\u0026#34; } } } ] } noun_fieldに固有名詞の単語が抜き出せているのがわかるかと思います。\nAlexのテンプレートで困った点 テンプレートは便利だったのですが、processor_typeに_を使用したタイプ名を指定すると次のような問題(?)が発生しました。\nクラス名がKuromoji_part_of_speech_extractProcessorとなってしまう 深刻な問題ではないのですが、JavaだとCamel Caseが普通なのでちょっと気になって。 ということで、プルリク作って出してみました。まだ取り込まれてないかな。\n取り込み前に使いたい方は以下のコマンドを実行してください。 processor_class_nameという項目が増えています。 デフォルトだとprocessor_typeの_の部分を取り除きつつCamel Caseにしたものが入ります。\ncookiecutter gh:johtani/cookiecutter-elasticsearch-ingest-processor まとめ ということで、とりあえず作ってみましたというものになります。 特徴的な単語(固有名詞だけ)を抜き出して、別のフィールドにできるので、タグみたいなものをこれを使って前処理で作れるようになるかなぁと。\n参考ブログ(元ネタ?) インスパイア元となったブログです。\nUser Agentを解析するIngest Pluginを書いてみた Elasticsearch 5.0.0のIngest Node用プラグインを書いた話 ","date":1469161616,"dir":"post/2016/","id":"a62186ea292d6db03a087bd5dfcc3f1e","lang":"ja","lastmod":1469161616,"permalink":"https://blog.johtani.info/blog/2016/07/22/making-ingest-processor-plugin-with-cookiecutter/","publishdate":"2016-07-22T13:26:56+09:00","summary":"久しぶりに、技術的なブログ書いてます。 Ingest Processorのプラグインを作ってみたくなったので、書いてみました。 ただ書いてみるんじゃ3番煎じ","tags":["elasticsearch","plugin"],"title":"Lucene Kuromoji for NEologdで指定した品詞の単語を抜き出すIngest Pluginを書いてみた #elasticsearchjp"},{"contents":"なんか、今年はよく物が壊れる、厄年だからかなぁ?\nということで、記念に何が壊れたかをブログに残しておこうかと。\n腕時計(壊れてないかな) 電波腕時計を使ってたんだけど、電池がへたってたのでオーバーホールしてもらった。 Moto 360(壊れたというか。。。) 何度かバージョンアップしてるんだけど、数ヶ月前から、ちょっと触っただけで電源が落ちる現象が。ファームウェアのせいかAndroid Wearのバージョンアップのせいかわからないけど。。。挙げ句の果てに、電源を入れるために充電器にセットしないといけないと言う酷い仕様。。。 自転車前輪 自転車で車道を横切る側溝の蓋の間に前輪がはまってすっ転んでしまい、タイヤのスポークがちょっと曲がってしまう ジーンズその1 自転車で転んだ時に、膝とかこすって破れる ジーンズその2 福岡出張中に雨で滑って派手に転んで、膝に大きな穴が。。。 リュック あー、怪しいなと思ってたんだけど、やっぱりこわれた、、、 pic.twitter.com/CD2Y7t6AOD\n\u0026mdash; Jun Ohtani (@johtani) 2016年6月16日 怪しいとは思ってたんだけど。。。 ということで、リュックを新調しつつ修理に出してるところ。 5. Xperia Z3 * 先週金曜日にカメラのレンズが結露してるなぁと思ったら、電源が入らなくなった。補償サービスに入ってたんで、新しいZ3を次の日に送付してもらい復旧。いろいろなアプリがログインしないといけないのでかなり大変だった。。。\nまだ、半年残ってるので他にも壊れるのかなぁ。。。 お祓いしてもらったので、何もなければいいんだけど。\nということで、なんとなく欲しいものリストを貼っておきますね。\n","date":1467251858,"dir":"post/2016/","id":"167e2a6833d49ce198cb3b88f521991e","lang":"ja","lastmod":1467251858,"permalink":"https://blog.johtani.info/blog/2016/06/30/broken-something-in-this-year/","publishdate":"2016-06-30T10:57:38+09:00","summary":"なんか、今年はよく物が壊れる、厄年だからかなぁ? ということで、記念に何が壊れたかをブログに残しておこうかと。 腕時計(壊れてないかな) 電波腕時","tags":["misc"],"title":"よく物が壊れる年"},{"contents":"第16回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 今回は、司会だけに注力してみました()。\nチェックイン数など チェックインした人:141名 キャンセルしなかった人:67名 でした。\n今回は、参加希望者が多くて、当日にも100名近いキャンセル待ちの方がいたので、 240名まで、参加者枠を増枠(会場キャパ190名程度)して対応しました。 まぁ、読み通り、1/3の方はキャンセルしない形でした。 天気も良く電車の遅延などもなさそうだったので、ちょっとドキドキしてたのですが。\n以下は簡単なメモです。\n「LogstashとElasticsearchで作るEnterprise Search Platform」/ Elastic Kosho Owa スライド:https://speakerdeck.com/kosho/enabling-enterprise-search-platform-with-elastic-stack\n使ってるLogstashの設定ファイルを elastic-japan at elastic dot co に送るとTシャツがもらえるらしい。 Logstashのfilter-rubyはここで、evalしてcallしてるから、特にforkとかしてないかと。 「企業・業界情報プラットフォームSPEEDAにおけるElasticsearchの活用」 / 株式会社ユーザベース 北内 啓さん スライド:http://www.slideshare.net/tau3000/speedaelasticsearch-63510388\nアルゴリズム関連の開発担当 企業データをいろんな軸で検索したい データ数が約70億レコードになりそう(通貨 x MySQL) 300万企業データ+Nestedとかで持ってる。 11万フィールド??? 10台の物理サーバに24仮想マシン 企業名の検索 recall重視 NewsPicksの検索機能 「日本 化粧品 売上高」業界のデータとかも観れるのかな?有料会員向け機能 登録済みキーワードかどうかをRDB+Esに検索して、ID化するっぽい ID(Analyze必要ない)検索だから、termクエリだった、サンプルが。 ノードの役割分担 更新はMasterNode経由でDataNodeへ。 検索はClientNode経由でDataNodeへ。 1.xかぁ。。。 「Elasticsearchベースの全文検索システムFess」 / 株式会社エヌツーエスエム 菅谷信介さん スライド:http://www.slideshare.net/shinsuke/elasticsearchfess\n10.xからSolrをやめてElasticsearchへ。 日本語検索 bigram+形態素(1文字検索とかに対応するため) NeologDに対応したkuromojiを利用 DBFluteをESFluteとしてEs対応 KOPFを組み込んで使ってる configをREST API経由で更新できるプラグインあり LT 「ElasticsearchとGCPのネットワークでハマった話」 株式会社サイバーエージェント 平田大地 さん @daichild スライド:https://speakerdeck.com/daic_h/gcpfalsenetutowakudehamatutahua\nhhkb2 2刀流! networkのKeep-alive周りで困ったよというお話。 後で聞いたけど、GCE Cloud Pluginは使ってるそうです。 06/28 17:00追記\nPingを定期的に実行させることで回避も出来るようです。 transport.ping_scheduleに時間を指定します。通常のNode(Transport以外)は\u0026rsquo;-1\u0026rsquo;が指定してあり、動作してません。 「スクリプトフィールドで作るランキングみたいな何か」iwag さん スライド:https://speakerdeck.com/iwag/elasticsearch-dezuo-rurankingu\n1.xかぁ。。。 あとは、function_scoreとかも面白いですよ! その他、感想などのブログ 第16回elasticsearch勉強会に参加してきた 第16回Elasticsearch勉強会に参加してきた まとめ+宣伝? 1.xがまだまだいますねぇ、早く2.xにアップしましょう!(5.0ももう直ぐだし)。懇親会でも色々と話しましたが、https://discuss.elastic.co というフォーラムあるので、ぜひ活用してください。\n次回は8月末か9月頭かでしょうか。 7月末にOSC京都に出没するので、京都で勉強会やりたいと思ってます! 会場とかスピーカーとか興味ある人連絡ください。\n東京の勉強会のスピーカーも随時募集中ですので、連絡ください。\n","date":1467089755,"dir":"post/2016/","id":"993e58f132740b464ecf06ee289dc7b2","lang":"ja","lastmod":1467089755,"permalink":"https://blog.johtani.info/blog/2016/06/28/16th-elasticsearch-meetup/","publishdate":"2016-06-28T13:55:55+09:00","summary":"第16回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズ","tags":["elasticsearch","勉強会"],"title":"第16回Elasticsearch勉強会を開催しました。 #elasticsearchjp"},{"contents":"第15回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 今回は、Elastic{on} 2016開催直後ということで、大半はElastic{on}に関する話でした。\nチェックイン数など チェックインした人:114名 キャンセルしなかった人:62名 でした。 今回は、少しおそめで1時間前にキャンセル待ちがいない状態にしました。 まぁ、いつもの感じでしょうか。数値も安定してきた感じですかね。\n\u0026ldquo;Elasticsearchと機械学習を実際に連携させる\u0026rdquo; / Preferred Networks America, Inc. CTO 久保田展行(Kubota Nobuyuki) さん スライド:Elasticsearchと機械学習を実際に連携させる\n前回の続きの話で、今回が本題でした。\n勉強会直前に発表されたSensorBeeをElasticsearchと一緒に使うとどんなことができるかというお話です。 まぁ、前処理重要ですよねというのが、いつものことですが、印象的でした。 いつものようにわかりやすい説明だったので、使ってブログを書いて欲しいなと。\n発表の中で、説明に出てきたデモとか。\nCES2016でロボットカーのデモを展示してきました \u0026ldquo;Elastic{ON} 2016レポート\u0026rdquo; / Elastic Jun Ohtani スライド:elastic{on} 2016 レポート\n写真多めで、キーノートをメインに話をしました。\n簡単なまとめとしては\nプロダクトロゴができました。ロゴ画像などはこちら 次のメインバージョンは全て5.0。(5.0に関する通知が欲しい人はこちらで登録できます) elastic{on} 2016のビデオなどはこちら BBL始めます。連絡ください \u0026ldquo;Elastic{ON}の過ごし方\u0026rdquo; / クラスメソッド株式会社 藤本 真司 さん スライド:Elastic{ON}の過ごし方\n印象に残ったのは\n「自他共に認めるブログの会社」 4/12にSAPさんに会場を借りてElastic&クラスメソッドでイベントやります。 やっぱりご飯が美味しいんですねぇ。 早速ブログが書かれてました。\n\u0026ldquo;Elastic{ON} 2016 見るべきセッション資料 7選\u0026rdquo; / Acroquest Technology株式会社 谷本 心 さん スライド:Elastic{ON} 2016 見るべきセッション資料 7選 #elasticsearchjp\n印象に残ったのは\n東京でハンズオンやる会場提供者募集中! Ingest Node(参考:Ingest Nodeのドキュメントは公開中。) Reindex API(参考:Backport reindex to 2.x ) その他、感想などのブログ 第15回elasticsearch勉強会にLTで登壇しました #elasticsearch #elasticsearchjp 第15回elasticsearch勉強会に参加してきました #elasticsearch #elasticsearchjp まとめ+宣伝 来年のElastic{ON}に参加したいと思っていただけたらよかったなと。\n4/12にクラスメソッドさんとイベントを行います。また、ツイートすると思います。\n次回はいつも通りだと5月中旬になるかと思います(大丈夫かな?OSC 2016 Nagoyaでしゃべったり、ブース出したりとかするけど)。 5末に名古屋に出没します。名古屋で勉強会できればやりたいと思ってます。会場とかスピーカーとか興味がある方は連絡ください。\n","date":1458186180,"dir":"post/2016/","id":"c56a76ef8f604a8d87be2a32b1f81fac","lang":"ja","lastmod":1458186180,"permalink":"https://blog.johtani.info/blog/2016/03/17/15th-elasticsearch-jp/","publishdate":"2016-03-17T12:43:00+09:00","summary":"第15回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズ","tags":["elasticsearch","勉強会"],"title":"第15回Elasticsearch勉強会を開催しました。 #elasticsearchjp"},{"contents":"久々のポスト。。。\n久々に、技術書読んでます。「自然言語処理の基本と技術」という本です。\n監修の方のツイートを見て気になったので、買ってみました。 書籍のサイトの説明はこんな感じでした。\n本書は、この未来に不可欠となるに違いない自然言語処理の、技術的、ビジネス的基礎知識をくまなくコンパクトに図解した一冊です。 著者陣もそれぞれの分野の第一線で活躍するエキスパート揃い!\n確かに著者陣がすごいです。\nまだ、「はじめに」と自分に関係のある「情報検索」の章を流し読みしただけなんですが、次のような特徴がある本です。\n平易な単語で説明してある(難しい専門用語が少ない) 数式が出てこない(多分。少なくとも読んだ部分では見てない) 説明には例と図解がある 情報検索の章で言うと、全文検索でよく使われる転置インデックス(索引という単語が使われてる)がなぜ必要なのか、どういう感じで作られるのか、 転置インデックスに利用する索引の単語をどうやって作るのか(文字N-Gramや形態素解析)、単語の正規化(ステミングやストップワード)などの説明が 本当にわかりやすく書かれています。 スコアリングについても触れられています。\nElasticsearchも転置インデックスを用いた検索を行っており、 MappingでAnalyzerの指定をしている理由などの理解に役に立つと思います。\n全文検索システムがどのように検索を処理しているかをざっくり理解するのにはもってこいじゃないかと。 1点残念だなと思ったのは、書籍に「索引」がありませんでした(本の索引を思い浮かべてくださいっていう説明あったんだけど)。。。 Kindle版を購入すれば「検索」できるのかな?\nということで、まだ、流し読みしただけなんですが、「すごく」オススメです。 購入はこちらから!\n","date":1457962452,"dir":"post/2016/","id":"3fc7462a83fa55885067fee629287e8a","lang":"ja","lastmod":1457962452,"permalink":"https://blog.johtani.info/blog/2016/03/14/review-basics-and-tech-of-nlp/","publishdate":"2016-03-14T22:34:12+09:00","summary":"久々のポスト。。。 久々に、技術書読んでます。「自然言語処理の基本と技術」という本です。 監修の方のツイートを見て気になったので、買ってみました","tags":["本"],"title":"「自然言語処理の基本と技術」を読んでる"},{"contents":"あけましておめでとうございます、johtaniです。\n第14回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 今年もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\nチェックイン数など チェックインした人:122名 キャンセルしなかった人:58名 でした。 今回も当日の昼の時点でキャンセル待ちがない状態にしていました。 いくつか電車が止まっていたという話を聞いていたので、開始を5分遅らせ、 受付は45分くらいまで開けておくという対応をしてもらいました。\n\u0026ldquo;ココが辛いよelasticsearch\u0026rdquo; / 株式会社リクルートテクノロジー @tatakaba さん スライド:ココが辛いよelasticsearch\n実際にいくつかのサービスで運用されている内容とどういった機能を利用しているか、 どういったものを独自に作っているかという話をしていただきました。\n独自PluginでA/Bテストしてる Snapshotの活用 Index作成は環境に合わせて行っている。 バージョンは混在 PusnaRSのバージョンアップの話。 2つのバージョンのクラスタを用意してリアルタイムに切り替え。 Elasticsearchの活用 QueryのRewrite: SolrのリクエストをEsで受け付けたり。 辛い話。 バージョンアップが辛い Riverなくなるのつらい データずれるのつらい 補足:\nバージョンアップについて 1.x系から2.x系にアップされるのであれば、こちらを必ず試してください。\nhttps://github.com/elastic/elasticsearch-migration\n「.」が使えなくなるという話は、Solrとの大きな違いになるのかもなぁと。 ネスト構造のデータの表記を「.」で行うというのを厳密に行えるように、 「.」を使えなくしたというのがあるかと。\nRiverについて Riverがなくなった理由については、https://www.elastic.co/blog/deprecating-rivers で記載があります。 便利なのですが、負荷が偏ったり、スケールしないとかいう問題点があるかなと。\n良いサンプルとしては、JDBC Riverなどは、Javaのプログラムとして起動できるように変更されていたりします。\nhttps://github.com/jprante/elasticsearch-jdbc/wiki/jdbc-plugin-feeder-mode-as-an-alternative-to-the-deprecated-elasticsearch-river-api\n(個人的 には、SolrのDIHもRiverもあんまり好きではなかったです。データの変換処理と、ロード処理は別々にしたい人だったので。)\nデータのズレなど 耐障害性とか信頼性に関しては、どういった問題点があるのか、どういった対応をしているのかというのがまとめられたページが用意されています。\nhttps://www.elastic.co/guide/en/elasticsearch/resiliency/current/index.html\n「機械学習を利用したちょっとリッチな検索」 / Preferred Networks America, Inc. CTO 久保田展行(Kubota Nobuyuki) さん スライド:機械学習を利用したちょっとリッチな検索\n来日していただき、機械学習と検索の話をしてもらいました。 本編は次回の発表かもw\n機械学習を元に、検索対象の情報を元の情報から増やしてあげる。 増えた情報を検索できるようにする 今日のゴール: 機械学習とはどういうものか? データの集め方とか、アノテーションとか 学習の方法(ツールやライブラリに依存) Esでの活用方法 オフラインで学習させて、情報を付与した後に、Elasticsearchに入れる Jubatus+fluentdで ChainerサポートのOSSのツールを公開予定 「ここからが本当の地獄だ。。。」ってのが聴きたいw\n「Lucene Query 再考 - Domain Specific Query 実装 -」 / Supership株式会社 インフラ事業開発本部検索グループ 大川真吾 さん スライド:Lucene Query 再考 - Domain Specific Query 実装 -\nLuceneのクエリに関する話と、クエリパーサーに関する話でした。 こういった濃い話も勉強会でしてもらえると、色々な参加者に楽しんでいただけるかなぁと。 次回も続きを話してもらう予定です。\n補足:\n参考までにですが、Elasticsearchに入門したての人向けに、 Analyzerとか転置インデックスとかの話をした時のスライドになります。 https://speakerdeck.com/johtani/lucenetori-ben-yu-falsejian-suo\nLT: Fluentd meets Beats / @repeatedly さん スライド:http://www.slideshare.net/repeatedly/fluentpluginbeats-at-elasticsearch-meetup-14\n参考Qiita:http://qiita.com/repeatedly/items/77af41788f0b3ccdefd2\nBeatsの説明をTDの人からしてもらうなどw FluentdにBeatsからのデータを流し込めるようにしたプラグインが出たという話でした。\nfilebeatの性能の件は社内で聞いてみようかと。\nElasticsearchインデクシングのパフォーマンスを測ってみた / 日本IBM 黒澤亮二さん スライド:Elasticsearchインデクシングのパフォーマンスを測ってみた\n参考Qiita:http://qiita.com/rjkuro/items/e79eec7ffb0511b7c678\n細かな性能測定の結果を駆け足で話してもらいました。 皆さんもこの指標をもとに、手元の環境を計測してみたりしてみてもらえればと。\nあとは、2.x系になってるので、同じ方法で計測してもらってまた 発表してもらえると嬉しいなー(棒)\nその他、感想などのブログ Elasticsearch勉強会 第14回フィードバック まとめ+宣伝 久々に(初めてかな?)、ゲストがいないのに自分が喋りませんでした。 次回は3月中旬を予定してます。 次回は、Elastic{ON}16の報告をする予定です。いろいろと発表あるだろうし。\nあと、今月末の1/29にオープンソースカンファレンス 2016.enterprise@Osakaにブース出展します。 セミナー枠でも弊社OSSプロダクトの概要を話しする予定です。 関西の方は、ぜひ参加していただければと。ブースでお待ちしております。\nまた、スピーカーや場所が用意できたら、出張勉強会もまたやりたいなと思っています。 興味ある方は、連絡ください!\n","date":1452220496,"dir":"post/2016/","id":"4b0a768585da8f9f8f8db1ca409e7ebd","lang":"ja","lastmod":1452220496,"permalink":"https://blog.johtani.info/blog/2016/01/08/14th-elasticcsearch-jp/","publishdate":"2016-01-08T11:34:56+09:00","summary":"あけましておめでとうございます、johtaniです。 第14回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆","tags":["elasticsearch","勉強会"],"title":"第14回Elasticsearch勉強会を開催しました。 #elasticsearchjp"},{"contents":"今年は紅白見ながら書いてます。 早い一年だったなぁ。\n振り返り(2014年に書いた抱負から) まずは去年の抱負を元に振り返りをば。\n英語の継続 海外のイベントへの参加 多岐にわたるイベントでのスピーカー 日本の人員の倍増!? Elasticsearchに関する日本語の情報発信 Elasticsearch座談会みたいなものの開催 英語はまぁ、継続してます。亀の歩みですが。。。\n海外のイベントへの参加は、自社のイベントだけでした。来年のElastic{ON}ももちろん参加です。来年こそBerlin Buzzwords行きたいな。。。\n多岐にわたるイベントとまではいってないですかね。。。来年はOSC(大阪や東京)に出没予定です。参加される方は、声をかけていただければと。\n人員は倍増しました!営業の方が参画されたのがかなり助かってます。 今現在で4名です!来年も倍増できるかなぁ?\n日本語の情報発信はリリースブログの翻訳が多めでした。来年は独自コンテンツも増やさないとなぁ。 あとやっぱ書籍かなぁ。。。座談会は来年の課題に。。。\n振り返り(今年あったできごと) その他の今年の出来事。\n初渡米 初バルセロナ 東京以外で勉強会 初自社イベント(日本で) 初トレーナー 不惑 今年も初モノ多いですね。今年も楽しい一年でした。 自社イベントでアメリカやバルセロナなどに行きました。40年近く、海外に行ったことないせいか、海外に行って経験することが面白いです。\n東京以外での勉強会もやりました。名古屋、大阪、京都、北海道と。 来年もOSCで訪れた場所で勉強会を開催したいなぁと。\n自社のイベント(Elastic{ON} Tour Tokyo)も東京でやりました。 どうなることかと思っていましたが、朝から大勢の方に来ていただけてホッとしました。 自分のトークがどうだったのかという反応も気になりますが。。。 せっかくShayたちが来ていたので、もっとブースに話しに来てもらえるともっと嬉しかったかもなぁと。\nTour Tokyoを挟んで自社の公式トレーニングのトレーナーもやりました。 日本で3回目にして、初の日本語でのトレーニングでした。前の2回は逐次通訳だったんですが。 トレーニングって大変だなぁと思ったのと、やはり日本語でトレーニングを受けられるとだいぶ違うだろうなという実感がありました。 来年もできればいいなと。トレーニング自体があったことを知らない人もいたのかなぁ?\n来年の抱負 英語の継続 もっとElasticsearchの開発に参加 人員の倍増? 日本語情報発信 Splatoon S+? 英語あいかわらず出来てないので、頑張らないと。 もっと喋ったりしないとなんだろうなぁ。\n来年は開発をもっとやりたいなと。 来年1月にはセールスのエンジニアが加入するので、開発にもっと時間を割きたいなと。\n人員は倍増できるように頑張りたいです。少なくとも、2人が1月に入ることは決まってるんで、後二人!\nブログももっと書かないとですね。新機能とかこんな使い方できるよとか。 どんな記事が欲しいかとかコメントもらえると楽なので、突っ込みくださいw\n最後は、完全に私用ですね。Splatoonにはまってますw SとA+を行ったり来たりで。。。\nということで、今年はあと、数時間ですが、色々とお世話になりました。 この場を借りてお礼申し上げます。\n来年も、いろんな方に絡んでいくとは思いますが、よろしくお願いいたします。\n","date":1451565182,"dir":"post/2015/","id":"c54909ecf4fb3e9afeea36200fe95dce","lang":"ja","lastmod":1451565182,"permalink":"https://blog.johtani.info/blog/2015/12/31/looking-back-2015/","publishdate":"2015-12-31T21:33:02+09:00","summary":"今年は紅白見ながら書いてます。 早い一年だったなぁ。 振り返り(2014年に書いた抱負から) まずは去年の抱負を元に振り返りをば。 英語の継続 海外の","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2015)"},{"contents":"今年最後のAdvent Calendarとなります。\nこの記事はElasticsearch Advent Calendar 2015の最終日のエントリです。\n簡単に今年の変遷を、Elasticsearchをベースに振り返ってみようかと思います。\nKibana 4リリース(2月) Kibana 4(日本語訳) いきなり、Elasticsearchではない話題ですが。 AggregationベースのKibanaがリリースされました。 画面が黒くないというので、話題になりましたw 12月末時点では、4.3.1になっています。 Sub Aggregationによる強力なグラフ表示や異なるインデックスに対するグラフを 一つのダッシュボードに表示できるといったことができるようになりました。\nセキュリティ向けプラグインShieldのリリース(2月) セキュリティ向けプラグインShieldのリリース(日本語訳) 商用向けのプラグインの第2弾です。 セキュリティ強化のためのプラグインで、いろいろなところで引き合いがあったりします。\n初のユーザカンファレンス、Elastic{ON}開催(3月) #elasticon に参加中 サンフランシスコで、弊社初のカンファレンスが開催されました。(来年(2016年)もサンフランシスコで開催されます。) また、ここで、以下の2点の発表がありました。\nロゴ及びドメイン名などの変更 Foundのジョイン 約1300名が参加する大イベントでした。 初の渡米で楽しんできましたが、ドメインの切り替えなどは大変でした。。。 まだ、ロゴを変えて1年経ってないということが実感できてないです。\nFoundのジョインはまだまだ、日本で知名度が出てないかもなぁと。 もっと広めないと。 利点としては以下の通りです。\n新バージョンがすぐに利用可能に。また、バージョンアップも画面で指定可能 公式プラグイン+その他いくつかのプラグインが利用可能 Elasticsearch 1.5 リリース(4月) Elasticsearch 1.5.0リリース(日本語訳) 主に、resiliencyに関する改良になります。 毎リリースで信頼性向上につながる改良が含まれる形になっています。 このリリースの近くで初の東京の外での勉強会を名古屋で開催したりもしました。\ndiscuss.elastic.coをオープン(5月) https://discuss.elastic.co これまでは、Google Groupsを使っていましたが、Elasticが提供しているプロダクトが 別々のグループであったために、プロダクトにまたがった質問がやりにくかったり、検索がしにくかったりという問題点がありました。 今では、過去のGoogle Groupsのデータも移行されているので、是非参加して、質問・回答してみてください。 日本語でやりとりできるカテゴリもあるので、どんどん、やりとりしていただければ。\nElasticsearch 1.6 リリース(6月) Elasticsearch 1.6.0リリース(日本語訳) 2.0に向けたUpgrade APIが含まれるなど、次期リリースに向けた準備が整いつつあるリリースでした。 他にもsynced flushの取り込みやレスポンスのJSONのフィルタリングなど細かな改善も取り込まれています。\nFound PremiumとStandardリリース(7月) さらに進化したFound(日本語訳) Foundに弊社のサポートチームがサポートできるプレミアムが追加されました。 これにより、商用プラグインとして提供しているShieldが(現在はWatcherも)利用できるなど、 より便利になりました。また、Kibana 4も無料で提供されていたりします。\n小さなサイズのものですと、無料で試していただけるものもあるので、試してみてもらえればと。\nElasticsearch 1.7 リリース(7月) Elasticsearch 1.7.0 および 1.6.1リリース(日本語訳) 1.x系、最後のリリースでした。 小さい改善ですが、セキュリティフィックス、クラスタの安定化に寄与する機能改善が含まれています。\nこのリリース直前に大阪、京都で勉強会も開催してみました。\nElasticsearch 2.0.0-beta1 リリース(8月) Elasticsearch 2.0.0-beta1リリース(日本語訳) 待ちに待った、Lucene 5ベースのElasticsearchの登場でした。 doc_valuesがデフォルトになったり、エラーが構造化されて見やすくなったり、 Pipeline Aggregationが導入されたりしています。 また、問題点の洗い出しも兼ねて、ベータリリースとして、本リリースまでに多くのIssueをあげていただきました。\nElasticsearch 2.0.0 リリース(10月) 2.0の本リリースです。リリースまでに、beta1、2及び、rc1がリリースされました。\n追加された機能や目玉の改善については「Elasticsearch 2.0の紹介」のスライドを参考にしていただければと。\nまた、Elasticsearch 2.0のリリースに合わせて、商用プラグインやLogstash、Kibanaの新しいバージョンがリリースされました。 Kibanaなどは、プラットフォームとしての機能を備え、SenseやTimelionと言ったプラグインアプリもリリースされています。\nLogstash 2.0.0リリース(日本語訳) Kibana 4.2.0リリース(日本語訳) Senseの歴史 - Sense 2.0.0-beta1の紹介(日本語訳) Shield、Watcher、Marvel 2.0.0 GAリリース(日本語訳) Elasticsearch 2.1.0 リリース(11月) Elasticsearch 2.1.0 and 2.0.1 released Beats 1.0.0のリリース(11月) The Beats 1.0.0 Go言語で書かれた軽量データシッパーになります。 パケットをキャプチャしてElasticsearchに送るPacketbeat、 topコマンドで取れるデータなどをTopbeat、 ログファイルなどを取り込み配送するFilebeatがリリースされました。\nlibbeatと呼ばれる、 ベースとなるライブラリを元にしたプロダクトで、Logstashのエージェントのような使い方もできるようになっています。\nGo言語に興味のある方などは、調べてみてはいかがでしょう?\n来年は? 日本では、1/7に第14回Elasticsearch勉強会を開催します。 すでに、38名のキャンセル待ちとなっていますが、おそらく、年明けにキャンセルがそこそこ出ると思うので、まだ間に合うんじゃないかなぁと。\n会社としては、Elastic{ON}16が控えています。参加される方は、ぜひ現地で声をかけてください!!\nその他にもイベント、オープンソースカンファレンス(まずは、大阪、東京)などに出没する予定ですので、こちらも参加していただければと。\nでは、また来年のAdvent Calendarでお会いしましょう!\n","date":1451017794,"dir":"post/2015/","id":"d819cea5197e9b8673d6c0b16659a5ea","lang":"ja","lastmod":1451017794,"permalink":"https://blog.johtani.info/blog/2015/12/25/about-elasticsearch-in-2015/","publishdate":"2015-12-25T13:29:54+09:00","summary":"今年最後のAdvent Calendarとなります。 この記事はElasticsearch Advent Calendar 2015の最終日のエントリです。 簡単に今年の変遷を","tags":["elasticsearch"],"title":"2015年のElasticsearch"},{"contents":"こんにちは、@johtaniです。\n早いもので、師走です。今年もあと少しとなりました(今月が一番忙しかったりしますが。。。)。 ということで、Advent Calendarの季節が始まりました。\nこの記事はElasticsearch Advent Calendar 2015の1日目のエントリです。\n今日は、最近公開されたTimelionの紹介をしたいと思います。\nTimelion? 11/12に公開されたばかりのアプリになります。(公式のブログはこちら。ブログでは動画による説明もあり)\nKibanaにプラグインとしてインストールすることで使用することができるようになるアプリです。 Timelionと書いて「Timeline」と読むようです。 Kibanaとは異なるグラフ描画のプラグインになっています。\nKibana 4.2からプラットフォーム化 Kibana 4.2から、Kibanaにプラグイン機構が導入されました。 Kibanaとしての機能以外にも、プラグインとして、アプリを追加できるようになっています。 Timelionもその一つです。\nインストール Timelionを試してみるには、ElasticsearchとKibanaが必要になります。(こちらは、すでにインストールされているとして。。。)\nKibanaのコマンドを利用して、プラグインをインストールします。\nbin/kibana plugin -i kibana/timelion インストールしたら、Kibanaにアクセスして、Timelionを呼び出します。\nTimelionへアクセス ブラウザでlocalhost:5601にアクセスすると、Kibanaが出てきます。 Kibanaのプラグイン選択のアイコンをクリックし、Timelionのアイコンをクリックします。\nすると、初期画面はこんな感じです。 直近15分のElasticsearchに入っているデータがが全部出てきます。 チュートリアルも出てきてます(初回起動時に出たはず)\nKibanaでの検索窓の部分に関数を指定していくことで、グラフが描画できるツールになっています。\nサンプル:気温データを可視化 百聞は一見に如かずということで、 気象庁のデータを使って、 ちょっとしたグラフを書いてみました。 1年間の気温の推移と日照時間になります。\n上のグラフが那覇、下グラフが札幌の気温のグラフになります。\n赤いライン:最高気温 青いライン:最低気温 黄色い棒グラフ:日照時間 最低気温と日照時間はグラフは次のような式で描画しています。\n青いラインの最低気温 気温のグラフになります。\n.es(index=\u0026#39;tenki2\u0026#39;, q=\u0026#39;city:naha\u0026#39;, metric=\u0026#39;avg:temperature_min\u0026#39;).label(\u0026#39;min\u0026#39;), .es()がelasticsearchに対するデータ取得の関数です。 引数は次のような意味になります。\nindex:対象とするインデックス名 q:検索クエリ。ここでは、cityというフィールドにnahaで検索。 metric:描画対象となっているデータの入ったフィールド。temperature_minというフィールドの1日毎の平均値を取得 最低気温と最高気温は別々のフィールドに格納してあります。最高気温の場合は(temperature_max)を指定します。\n.label(min)で、グラフの凡例の指定です。 残念ながら、日本語の指定は現時点(2015年12月01日時点)ではうまくいかなかったです。(https://github.com/elastic/timelion/issues/17)\nデフォルトでは、線グラフが選択されているので、グラフの種類は特に指定はしていません。 明確に指定する場合はlines()を指定します。\n黄色い棒グラフの日照時間 .es(index=\u0026#39;tenki2\u0026#39;, q=\u0026#39;city:naha\u0026#39;, metric=\u0026#39;avg:sunlight\u0026#39;).label(sunlight).bars() .es()に関しては最低気温のグラフとほぼ一緒です。異なるのは、metricの取得対象のフィールド名です。\n.label()で凡例を指定しています。先程と同様です。\n最後に、棒グラフにしたいため、.bars()を指定しています。\nその他に用意されている関数について知りたい場合は、Timelionのヘルプを表示すると説明が出てきます。 cusum()のような値を累積して表示するような関数も用意されています。\nまとめ Kibanaとは少し違うアプローチで時系列データを描画するためのツールとなっています。 線グラフと棒グラフを一つのグラフに描画したりもできますし、 累積のグラフなんかも描画できるようになっています。\n実験的なプロジェクトである、Timelionの紹介でした。 ここでのノウハウがkibanaにフィードバックされると色々と面白いことになるんじゃないかなと。\nということで、 明日は、zoetroさんの「Kibanaのプラグインの話」になります。 お楽しみに!\n","date":1448936891,"dir":"post/2015/","id":"1b56132638912a1ca54fcf7cd38b8e23","lang":"ja","lastmod":1448936891,"permalink":"https://blog.johtani.info/blog/2015/12/01/introduction-timelion/","publishdate":"2015-12-01T11:28:11+09:00","summary":"こんにちは、@johtaniです。 早いもので、師走です。今年もあと少しとなりました(今月が一番忙しかったりしますが。。。)。 ということで、A","tags":["kibana","timelion"],"title":"Timelionの紹介 - Elasticsearch Advent Calendar 2015 1日目"},{"contents":"第13回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 来年もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\n7月同様、サムライズムの@yusukeさんに テキスト翻訳していただき、大変助かりました。\nチェックイン数など チェックインした人:100名 キャンセルしなかった人:36名 でした。 今回は当日の時点でキャンセル待ちがない状態にしていました。 雨もあって、これなかった人もいるのでしょうか。\n\u0026ldquo;Beyond the basics with Elasticsearch\u0026rdquo; / Honza Král / Elastic スライド:https://speakerdeck.com/elasticsearch/beyond-the-basics-with-elasticsearch\n参考ビデオ(別のカンファレンスで話した時のビデオ):https://www.youtube.com/watch?v=yIixWzjTNog\nPycon HKでアジアに来ていたHonzaに、ついでに日本で話をしてもらうという企画で、 前回から1カ月足らずでの開催となりました。 Elasticsearchの基本的な検索機能とは別の機能に関して少し話をしてもらった感じです。 PercolatorとAggregationの話でした。\n詳しくはビデオやスライドを見てもらうのがいいかなと。\n\u0026ldquo;How did we use Found.no for our services?\u0026rdquo; / 株式会社アイリッジ Takuya Noguchi さん @tn961ir スライド:未定\nFoundユーザー。1.7までの話。 社内で独自にクラスタを構築していたが、managed serviceを利用したいと思っていた。 Found用のACLがShieldに マルチバイトのインデックス名とかも使いたいが、Nginxとの連携でちょっと。。。 セキュリティ関連の話も。Securityに関する報告はこういうものも用意されてるので、こちらに相談してもらうのがいいかも。https://www.elastic.co/community/security 要望がいくつか。 \u0026ldquo;ログ収集の仕組みを再考しよう! あとマウンテンビューに行ってきました。\u0026rdquo; / Acroquest Technology株式会社 谷本 心さん @cero_t スライド:http://www.slideshare.net/shintanimoto/lets-reconsider-about-collecting-logs-plus-visiting-elasticmoutain-view\nログの小話から始まり、ログに関する考え方とかを披露してもらいました。 さらに踏み込んだログの活用の方法の話になるかと思いきや、 思いっきり話が飛んで、マウンテンビューのElasticオフィスに遊びに行った写真が出てきましたw\n写真の後は、弊社のTanya(来月のElastic{ON} Tour Tokyoで来日予定)から 聞いた弊社製品に関する話をしていただきました。 きっと、Beatsに関して次は話してくれるんだろうなぁ(棒)。 流れ的には、来年の2月にサンフランシスコで開催されるElastic{ON}16につながりそうだったので、ここで宣伝しときますね。 今年3月に開催されたイベントには残念ながら日本の方はいなかったので、次回は日本の方がいると嬉しいなぁと。\nLT \u0026ldquo;「Elasticsearch を使った単語共起頻度の計算」\u0026rdquo; / 株式会社はてな id:takuya-a さん スライド:未定\n一風変わったElasticsearchの使い方的な話でした。 検索用にデータを登録してあるElasticsearchから単語の頻度情報を抜き出して、 別のインデックスに登録するという感じでしょうか。 こういうのが、実は、Elasticsearchに機能としてあると便利だったりするのかもなぁと思ってみたり。\nLTよりはちょっと長かったですかねw\nその他、感想などのブログ elasticsearch勉強会 まとめ+宣伝 今回も@yusukeさんのテキスト翻訳に助けていただきました。ほんとありがとうございます。 今年の勉強会はこれがラストになります。 来月は、トレーニングとElastic{ON} Tour Tokyoがあるので忙しくなりそうですが、 参加予定の方は楽しみにしていてください!\nOperations : http://training.elastic.co/class/Operations/Japan/Dec Developer : http://training.elastic.co/class/Developer/Japan/Dec ","date":1447143778,"dir":"post/2015/","id":"2ea86ae5093670df1d4502ea82efa1ac","lang":"ja","lastmod":1447143778,"permalink":"https://blog.johtani.info/blog/2015/11/10/13th-elasticsearch-jp/","publishdate":"2015-11-10T17:22:58+09:00","summary":"第13回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズ","tags":["elasticsearch","勉強会"],"title":"第13回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:The Story of Sense - Announcing Sense 2.0.0-beta1\n誕生 よくある良いプロジェクト同様、Senseもビールを飲みながら考えつきました。 Amstelでの手漕ぎボートのセッションの後で。 友人のJasperと私はJasperの会社で毎年行われる ハッカソンについて話をしていました。 このハッカソンはどのようなアイデアでどんなチームで行うかを聞き取りされる、厳密なハッカソンです。 その時、私とJasperはChromeブラウザに別のヒストリーを表示するという作業をやるとAnne Velingに話をしていました。\nJasperと私はElasticsearchのユーザでしたが、リッチなREST APIにリクエストを送信するための 便利なツールがないと知っていました。 恥ずべきことに、cURLコマンドを利用するターミナルがその時の一番良いツールでした。 皆さん、ターミナルでボディつきのリクエストをサブミットするのがどのくらい不便かというのをわかるために、 5秒ほどターミナルで実行してみてください。 タイプミスのような単純なことでさえ、すべてのコマンドを再タイプしなければならなかったり、 複数行サポートのターミナルと戦ったりです。 ウェブベースのJSONエディタを見つけ出して、それをベースにすることが必要でした。\n終わりなきウィークエンド リサーチをして、Anneに電話しました。 私は彼に、History Pageのプロジェクトにもコミットするが、 Elasticsearchユーザなので、便利なコンソールを開発する時間も欲しいという話をしました。 私たちは、Aceオンラインエディタを利用して、 自動でAPIを認識するナレッジベースを構築し、 コンテキストに沿ったサジェストを大なうようにしました。 Anneはすぐに、それが素晴らしいと同意してくれました。 しかし、彼は、ハッカソンの基本的なルール(週末にそれが終わる必要がある)に違反しているので、 そのアイデアを却下するしかありませんでした。 確かに、私たちが提案していたものは行えませんでした。 最後に、私たちは、ChromeのHistory Pageの素晴らしい置き換えについて実装しました。\nそれでも、私はチャレンジし、それが終わるであろうことを終わるであろうことを証明しなければなりませんでした。 次の週末(といくつかの終業後 :))に、私はそれを作りました。 Senseの誕生です。 それは、まだバグだらけでしたが、動きました。 これを見せるとみんな興奮しました。\n初期 Knowledge Baseの拡張とバグのフィックスで数日を過ごしました。 Senseは広まり始め、ずっと古いバグのあるバージョンを利用しないといけないのかと私は恐れました。 SenseをChromeのExtentionとしてリリースすることを決め、リリースすると自動的に更新されるようにしました。 History Panelのような機能を一つづつ追加するようにしました。\nElasticにジョインしてから、会社の人たちがSenseを使用しているということを聞き、とても幸せでした。 特に、Clintと話をしたときのことを覚えています。 彼は、\u0026ldquo;You know what Sense should do? It should use this format and allow you to have multiple requests in the editor\u0026rdquo; 「Senseになにをすべきかわかる?フォーマットを使うべきだし、エディタで複数のリクエストを持つようにするべきだ」 と言いました。 もちろん、その他のチャレンジも行いました。これは、簡単なものではなく、Aceの詳細を知る必要がありました。 それは新しいAceモード(Aceによって利用されているハイライティングロジック)です。 これは、Senseのサジェストエンジンに密に統合されました。\n次のものが古いSenseのスクリーンショットです。\n画像あり。Figure 1. Sense 0.7 ※画像に関しては原文をご覧ください。\nAPIのURLを入力すると、JSONのボディが入力されます。 うまく切り離すことができ、AceのスタンダードJSONモードを使っていました。 しかし、ここで、次のようなフォーマットをどうやってサポートするか考える必要がありました。\nGET _cluster/health POST index/_settings { \u0026#34;index\u0026#34;: { \u0026#34;number_of_replicas\u0026#34;: 3 } } これは、Aceが3つの異なるものをどうやってパースするかを知る必要があるということです。 HTTPメソッドとURLとJSONボディです。 また、困ったことに、前に説明した前に説明した通り、明らかに別々にはならないものでした。 JSONボディが完全であることを知る唯一の方法はかっこを数えることです。 それは、いくつかの作業とAceのカスタマイズが必要でしたが、それらを切り離すことができました。 そして、Senseのシンタックスが生まれたのです(Thanks Clint!)\nMarvel時代 就業時間中、私の優先すべき仕事はMarvelの開発になりました。 これは、Elasticsearchのための管理と監視のためのソリューションです。 (side note: Marvelは生まれ変わっています。(\u0026quot;Shield, Watcher, and Marvel 2.0.0 GA Released\u0026quot;)) Marvelは開発環境ではフリーなので、MarvelにSenseを組み込むことにしました。 これにより、Senseの開発が日中も行えるようになり、多くのユーザに利用され始めました。 また、Senseは実際に真のJavaScript開発者によって開発されました。 彼は、コードをクリーンにし、ブラウザにおける最新の技術を私に教えてくれました。\nこの期間のSenseは数回書き換えられています。 最も顕著なものは、個別のURLとJSONのサジェストエンジンを書き換えて、 1つのサジェストエンジンにしこれらのコンテキストで動作するようにし、さらに3つ目のコンテキスト(URLパラメータ)を追加したことです。\n新しいエンジンはまた、複数のサジェストコンテキストをメンテナンスするのが簡単になりました。 例えば、_search APIのソートパラメータを考えます。\nGET _search { \u0026#34;sort\u0026#34;: [ \u0026#34;timestamp\u0026#34;: \u0026#34;desc\u0026#34;, \u0026#34;price\u0026#34;: { \u0026#34;order\u0026#34;: \u0026#34;desc\u0026#34;. \u0026#34;missing\u0026#34;: \u0026#34;last\u0026#34; }, \u0026#34;nested_filter\u0026#34;: { \u0026#34;term\u0026#34;: { ... }}, \u0026#34;_score\u0026#34; ] } ユーザがどこにいるかによって、Senseは単純な値(_scoreのような)か、 複雑な構造(orderとmissingのような)やフィルタ(nested_filterのような)も サジェストする必要があります。 これらのサジェストのパスが一度に処理され、無関係なものは除外されます。\nSense 2.0の紹介! Marvel 1.xはKibana 3.0をベースにしていました。 これは、データの探索やダッシュボードツールとして素晴らしいものでした。 しかし、Kibanaチームはさらに素晴らしいものを出しました。 Kibana 4.xはElasticsearchをバックエンドとするUIアプリを簡単に構築することができる プラットフォームとして設計されています。 実際に、Marvel 2.0はKibanaの プラットフォームで利用できる最初のアプリです。\nSenseの話に戻します。 ElasticsearchのAPIとやりとりする一般的なコンソールです。 これをKibanaのアプリぴったりだと気付きました。 ということで、Sense 2.0をKibanaアプリとしてオープンソースで公開しました。 開発及び本番環境で利用してください。\nFigure 2. Screenshot Sense 2.0 ※画像に関しては原文をご覧ください。\nリリースのハイライト Sense 2.0の新しい機能をここで簡単に紹介します。 (すべての変更点についてはこちらをご覧ください。)\nElasticsearch 2.0 SenseのナレッジベースをElasticsearch 2.0サポートに更新しました。 新しいPipeline aggregationにも対応しています。\n複数リクエストの実行 テストやいくつかの一連のコマンドを繰り返し実行したい時があるでしょう。 その時に、それら全てをSenseに記述し、 実行したいリクエストを選択状態にしてElasticsearchにリクエストできます。\nFigure 3. Submit multiple requests ※画像に関しては原文をご覧ください。\nSenseは、Elasticsearchにリクエストを一つずつ送信し、それぞれの出力結果を右のパネルに表示します。 これは、問題のデバッグや複数のシナリオでのクエリの組み合わせの実行に非常に便利です。\n複数リクエストのコピーペースト 複数リクストを選択し、フォーマットしたり、cURLのコマンドとしてコピーすることも可能です。\nFigure 4. Copy multiple requests as cURL ※画像に関しては原文をご覧ください。\n# Delete all data in the `website` index curl -XDELETE \u0026#34;http://localhost:9200/website\u0026#34; # Create a document with ID 123 curl -XPUT \u0026#34;http://localhost:9200/website/blog/123\u0026#34; -d\u0026#39; { \u0026#34;title\u0026#34;: \u0026#34;My first blog entry\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;Just trying this out...\u0026#34;, \u0026#34;date\u0026#34;: \u0026#34;2014/01/01\u0026#34; }\u0026#39; もちろん、複数のcURLコマンドをコピーしてSenseにペースとすると、Senseはそれらをパースしてくれます。\nまとめ Sense 2.0.0のベータリリースです。 実際に多くの作業が終わった認識です。すぐにGAが出るでしょう。\nSense 2.0を知り、試していただくために、新しいドキュメントを参考にしてください。 バグやリクエストがある場合は、フォーラムやGitHubのIssueに登録をお願いします。\n","date":1446195306,"dir":"post/2015/","id":"5912529cfd6ce14c5ede5c6c83dae7e8","lang":"ja","lastmod":1446195306,"permalink":"https://blog.johtani.info/blog/2015/10/30/sense-2-0-0-beta1-ja/","publishdate":"2015-10-30T17:55:06+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:The Story of Sense - Announcing Sense 2.0.0-beta1 誕生 よくある良いプロジェクト同様、Senseもビールを飲みながら考","tags":["elasticsearch","sense"],"title":"Senseの歴史 - Sense 2.0.0-beta1の紹介(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Shield, Watcher, and Marvel 2.0.0 GA Released\n本日(10/28)Shield、WatcherおよびMarvel 2.0をリリースしました。 これが、Elasticsearch 2.0に対応したこれらのプラグインの最初のリリースです。\nElasticsearch 2.0対応のほかに、ShieldとWatcher 2.0は、 セキュリティとアラートを拡張するいくつかの新しい素敵な機能も備えています。\nShield 拡張可能なレルム - Sheild 1.xはユーザ認証のコア的なものを定義するのにフォーカスし 3つの認証メカニズム(esusers、LDAP/AD、PKI)を提供しました。 これらを提供することで、多くのユーザおよびユースケースをカバー出来ましたが、 追加の認証メカニズムを統合する必要があることもわかっていました。 ということで、Shieldのレルムベースの認証システムをユーザが利用、拡張できるようにオープンにし、 ユーザ認証を扱うためのレルム実装をプラグインとして拡張できるようにしました。 特定もしくはプロプライエタリな認証メカニズムが必要なユーザもShieldの強力な セキュリティ機能(ロールベースの認証、セキュアな通信など)をフルに活用できるようになりました。 カスタムレルムの詳細については、こちらをご覧ください。\nフィールドとドキュメントのACL - Shield 2.0はフィールドとドキュメントレベルのアクセス制御機能を提供します。 これは、ロールごとにアクセス可能なフィールドやドキュメントを定義できます。 この新しい機能は、設定の変更するよりも便利です。 このアクセス制御はElasticsearchのLuceneインデックスという最も低レベルで実装されています。 その結果として、このメンテナンスがより簡単であるだけでなく、より良くなっています。 詳細についてはこちらをご覧ください。\nユーザなりすまし - Shield 2.0で、ユーザなりすましの機能が実装されました。 これは、ユーザ(適切なパーミッションを持った)が、他のユーザになることができ、 それらのユーザのためにリクエストを実行できます。 これは、Elasticsearch上に構築されたアプリケーションがすでにユーザ認証を行いますが、 認可はElasticsearchサイドで行う必要があるような場合に有用です。 このシナリオで、アプリケーションの\u0026quot;main\u0026quot;ユーザを設定でき、正しくなりすましを割り当て、 ElasticsearchにアプリケーションユーザとしてリクエストをElasticsearchに実行させることができます。 詳細については、こちらをご覧ください。\nWatcher SlackとHipChatインテグレーション - SlackとHipChatはチーム/グループコラボレーションツールです。 これらは、急速に主流になり、組織の主な内部コミュニケーションハブとなっています。 Watcher 2.0はチャンネル/ルームやユーザにこれらのコミュニケーションチャネル経由で、Watchの通知を行うことができるアクションを 実装しました。 slackやhipchatアクションについてはドキュメントをご覧ください。\nArray Compare Condition - 新しいconditionはタイムシリーズのデータのスパイクを検知するのを簡単にします。 compare conditionは1.xで導入されましたが、このコンディションはElasticsearchのダイナミックスクリプト機能を有効にする必要がアンク使えます。 詳細についてはarray_compare conditionをご覧ください。\nWatchの有効・無効化 - ユーザからの多かったリクエストとして、Watchの無効化がありました。 1.xには、登録済みのWatchを無効にする機能がありませんでした。 これは、Watchを消すか、Watchのトリガーを変更することで回避していました。 これは、全体としてはWatchを管理するのを難しくする回避方法でしかありません。 2.0では、APIを呼び出すだけで、Watchの変更をすることなく、簡単にWatchの有効化・無効化が可能になりました。 これは1.0からあるべき基本的な機能でしたが、ついにこの問題を解決しました。 詳細はこちらをご覧ください。\nMarvel Marvel 2.0を紹介するのに興奮しています。 Kibana 4をベースとした、再設計されたUIを持っています。 Marvel 1.xで学んだ多くのことを導入し、より使いやすく監視しやすいUIになっています。 ShieldとWatcherと同様に、最初のMarvelのリリースは将来的な成長の基盤となり Elasticsearch2.0を効率的に管理するための主要なメトリックにフォーカスしています。\n画像あり。 ※画像に関しては原文をご覧ください。\n再設計により、インタフェースを6ページに減らしています。\nCluster list 画像あり。 ※画像に関しては原文をご覧ください。\nユーザやカスタマーの多くは複数のクラスタを利用しています。 新しいMarvelはそれらを集中的にモニタリングする一つのクラスタからそれらを簡単に監視できます。 各クラスタのデータ送信先をこのモニタリングクラスタにするだけです。\nCluster Overview 画像あり。 ※画像に関しては原文をご覧ください。\nクラスタオーバービューはある一つのクラスタの主要な性能メトリックを見ることができ、 素早くスパイクを発見できます。 このページはまた、アクティブなシャードのリカバリやリロケーションも見ることができます。\nIndices List 画像あり。 ※画像に関しては原文をご覧ください。\nインデックスのリストにはクラスタにあるすべてのインデックスとその属性が表示されます。 テーブルはライブでアップデートされ、フィルタリングやソートも可能です。 一番大きなインデックスは?といったことも調べられます。\nIndex Detail 画像あり。 ※画像に関しては原文をご覧ください。\nインデックス詳細ページはインデックスの主な性能メトリックを見ることができ、シャードの配置についても表示します。\nNodes List 画像あり。 ※画像に関しては原文をご覧ください。\nノードリストはクラスタにあるノードとその主な性能メトリックを見ることができます。 テーブルはライブでアップデートされ、フィルタリングも可能です。 高いCPU利用率やディスクの残り容量なども簡単にわかるようになっています。\nNode Detail 画像あり。 ※画像に関しては原文をご覧ください。\nノード詳細ページは個別のノードに関する主な性能メトリックを見ることができ、ノードにあるシャードのリストも見ることができます。\n新しいMarvelはKibana 4の上に構築されたので、管理方法が変わっています。 Marvelのインストールは2つのステップがあります。 marvel-agentとmarvel user interfaceです。\nMarvel Agent marvel-agentはElasticsearchクラスタにプラグインとしてインストールします。 主なパフォーマンス情報を取得し、ローカルもしくは分離されたモニタリングクラスタにデータを保存・送信します。\nMarvel User Interface Marvel UIはKibanaのプラグインとしてインストールします。 これは、Kibana 4.2の新しいプラグインインフラを利用し、 Marvel Appとして、Kibanaのインタフェースとは個別に提供されます。 Kibanaのアプリの切り替えは次の画像の通りです。\n画像あり。 ※画像に関しては原文をご覧ください。\n2.0リリースは私たちのプロダクトの大きな一歩です。またユーザの意見を常にお待ちしています。 ぜひ、Webフォーラム(https://discuss.elastic.co)やメール(info@elastic.co)でご意見を。\n","date":1446189691,"dir":"post/2015/","id":"15700442e957951307bbcec5fff8643d","lang":"ja","lastmod":1446189691,"permalink":"https://blog.johtani.info/blog/2015/10/30/shield-watcher-and-marvel-2-0-ga-released-ja/","publishdate":"2015-10-30T16:21:31+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Shield, Watcher, and Marvel 2.0.0 GA Released 本日(10/28)Shield、WatcherおよびMarv","tags":["elasticsearch","shield","watcher","marvel"],"title":"Shield、Watcher、Marvel 2.0.0 GAリリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 2.0.0 GA released\nElasticsearch 1.0.0のリリース以降、 477のコミッター2,799のpull requestがあった、 **Elasticsearch 2.0.0 GA(Lucene 5.2.1ベース)**をリリースしました。\nそれだけでなく、Shield(セキュリティプラグイン)とWatcher(アラーティングプラグイン)、 新しくなったMarvel(モニタリングプラグイン)(プロダクション環境でフリー!)、 また、新しくオープンソースとなったSense editorの2.0.0もリリースしました。\nElasticsearch 2.0.0のダウンロードはこちらから。 また、2.0.0での重要な変更点についてはこちらをご覧ください。 全ての変更点については、次をご覧ください。\nChanges list for Elasticsearch 2.0.0 Changes list for Elasticsearch 2.0.0-rc1 Changes list for Elasticsearch 2.0.0-beta2 Changes list for Elasticsearch 2.0.0-beta1 商用プラグインについてはこちらです。\nShield 2.0.0 change logs Watcher 2.0.0 change logs Elasticsearchの新機能 Elasticsearch 2.0.0には素晴らしい新機能があります。\nPipeline Aggregations Aggregationsで導関数や移動平均のような他のAggregationの結果に対する計算が可能となります。 この機能はクライアントサイドで実装しなければなりませんでしたが、 Elasticsearchに計算させることで、より強力な解析のクエリを簡単に組み立て、クライアントのコードを簡略化できます。 これは、予測解析や予測解析や例外検知といった可能性をもたらします。 Pipeline Aggregationについては次をご覧ください。\nOut of this world aggregations. Staying in Control with Moving Averages - Part 1. Staying in Control with Moving Averages - Part 2. Query/Filter merging フィルタはもうありません。 全てのフィルタ条件はクエリとなりました。 クエリコンテキストで使用した場合、関連度のスコアに影響し、フィルタコンテキストで使用した場合、 これまでのフィルタのように、ヒットしなかったドキュメントを除外するだけとなります。 この変更はクエリの実行時に自動的に最も効率的な順序で実行するように最適化されることを意味します。 例えば、遅いクエリ(フレーズやgeo)の最初の実行は速い近似フェーズで実行され、 それから、遅い正確なフェーズで結果を修正します。 フィルタコンテキストでは、直近でよく使われた条件が自動的にキャッシュされます。 詳細については、\u0026quot;Better query execution coming to Elasticsearch 2.0\u0026ldquo;をご覧ください。\n設定可能な圧縮率 _sourceのようなStored fieldsは高速なLZ4(デフォルト)で圧縮するか、インデックスサイズを小さくできるDEFLATE で圧縮できます。 これは、特にロギングのケースで便利です。 古いインデックスをオプティマイズする前にbest_compressionに変更することができます。 詳細については\u0026rdquo;Store compression in Lucene and Elasticsearch\u0026ldquo;をご覧ください。\n堅牢に 新しいElasticsearchはJava Security Managerの元で実行されます。 これは、セキュリティの観点で大きな前進です。 Seciruty ManagerはElastcsearchにより制限をかけ、ハッカーによりシステムに対して何でもできるようなものを制限します。 Elasticsearchはまた、インデキシングの観点でも堅牢になっています。\nドキュメントはインデキシングリクエストに答える前に、耐久性のためにディスクにfsyncされます。 すべてのファイルはチェックサムにより、早期に障害を検知します。 すべてのファイルはどんなファイルへの書き込みもアトミックです 最後に、システム管理者から要請の多かった変更として、 設定されて居ないノードがパブリックなネットワークから参加しないようになりました。 Elasticsearchはデフォルトではローカルホストのみにバインドします。マルチキャストは無くなりました。(プラグインとして残っています。)\nパフォーマンスと信頼性 上記以外にも細かな修正がElasticsearchとLuceneにはあります。 より安定し、信頼性をあげ、簡単に設定できるようにするものです。例えば、次のようなものです。\nヒープの使用率の低減(doc valuesがデフォルト、マージ時のメモリ使用率の削減、 roaring bitsetsによるフィルタキャッシュ) 構造化され読みやすくなった例外 設定の代わりに、フィードバックループを使用した自動調整 安全で明確で信頼性のあるタイプマッピングの大きな修正 クラスタ状態の差分変更による伝搬の高速化および、大きなクラスタでのより安定的に normsの圧縮の改善。これまではヒープスペースを大きく利用していた。 マージの自動的な調整(不可解な設定の微調整が必要ない) より詳細なLuceneのメモリリポート 最適化されたクエリ実行を活用するためにParent/childを書き換え コアプラグイン 公式にサポートされたコアプラグインはElasticsearchと同じバージョン番号で同じタイミングでリリースされます。 インストールするプラグインとElasticsearchの複雑なバージョンの対応表に悩まされる必要はもうありません。 コアプラグインのインストールは次のように簡略化されています。\nbin/plugin install analysis-icu ShieldとWatcherの新機能 商用プラグインも新しい機能をリリースしました。\nShield フィールドおよびドキュメントレベルのアクセス制御 ユーザのなりすまし カスタム拡張可能な認証レルム Watcher 個別のWatchを有効/無効に SlackやHipChatへの通知 これらの詳細については“Shield, Watcher, and Marvel 2.0.0 GA Released”をご覧ください。\nコアプラグイン同様、商用プラグインもElasticsearchのバージョンと同じものが同時にリリースされます。 インストールは次の通りです。\nbin/plugin install license bin/plugin install shield bin/plugin install watcher Marvel 2.0.0はプロダクションでの利用もフリーに Marvelモニタリングプラグインはカスタマに非常に価値のあるもので、 ユーザの発展とともに問題を診断したり見つけたりするのに役に立ってきました。 私たちは、何を改善でき、Mαrvelを一から書き直すことで、いろいろとわかったことがあります。\nMarvel UIを新しいKibanaプラットフォーム上に構築 ダッシュボードにはより簡単に問題を発見するために、最も重要なメトリックを可視化 1つのインストールで、複数のクラスタのモニタリングをサポート(商用サポート対象) 一番良い点はMarvelがすべてのElasticsearchユーザに対してプロダクション環境でフリーになったことです! ライセンスが必要ですが、課金の必要はありません。 もし、マルチクラスタモニタリングサポートが必要な場合、それは商用サポート対象となります。\n詳細に関しては“Shield, Watcher, and Marvel 2.0.0 GA Released”をご覧ください。\nSense editorがオープンソースに Sense(ブラウザベースのElasticsearchリクエストとDSL向けのエディタ)を Kibanaプラットフォームのアプリとして、オープンソースにしました。 また、このリリースで新しい機能が追加されています。\n複数のcURLリクエストをペースとすると、Sense表記に変更 複数のSenseリクエストをcURL表記にしてコピー 複数のリクエストを一度に実行可能 Elasticsearch 2.0サポートとなった自動補完機能 SenseはKibanaのアプリとして次のようにインストールします。\n./bin/kibana plugin --install elastic/sense Senseの詳細については、\u0026quot;The Story of Sense - Announcing Sense 2.0.0-beta1\u0026ldquo;をご覧ください。\nElasticsearch Migration Plugin Elasticsearch Migration PluginはElasticsearch 1.xから2.0にアップグレードする時の良い出発点となります。 1.xのElasticsearchクラスタにサイトプラグインとしてインストールすると、 アップグレードする前に解決すべき問題があるかどうかを検知してくれます。 (例えば、Lucene 3のような古いインデックスや、2.0.0にした場合に動作しない問題のある マッピング(The Great Mapping Refactoring)のような問題)\nプラグインに関してElasticsearch Migration repositoryをご覧ください。\nまとめ ぜひ、Elasticsearch 2.0.0をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)やWebフォーラムなどで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1446103243,"dir":"post/2015/","id":"018e32a8010960eb17e368a6fdd5a51b","lang":"ja","lastmod":1446103243,"permalink":"https://blog.johtani.info/blog/2015/10/29/elasticsearch-2-0-0-released-ja/","publishdate":"2015-10-29T16:20:43+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 2.0.0 GA released Elasticsearch 1.0.0のリリース以降、 477のコミッター2,79","tags":["elasticsearch"],"title":"Elasticsearch 2.0.0リリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Kibana 4.2.0 released\nElasticsearch 2.0 + Kibana 4.2 = 💚 Elasticsearch 2.0サポートのKibanaの最初のリリースです。 これが何を意味するでしょう? 速さ、安定さ、新しい機能。 試してみたい方は、いますぐダウンロードしてください。 そうでない方は、Kibana 4.2の楽しい機能について読んでみてください。\n暗黒面は怖い? そんなことありません。 私たちは常にチャートチャートとダッシュボードを組み立てている組み立てている間は明るいバックグラウンドを使うことを推奨してきましたが、 時々、巨大なスクリーンで暗い部屋で誰も明るい画面から目を背けないようにしたいでしょう。 その影響を小さくするためにダークモードを導入しました。 あなたは、NOCや天文台、その他の暗い場所でKibanaのダッシュボードを楽しむことができます。\n画像あり。 ※画像に関しては原文をご覧ください。\n地図のカスタマイズ Kibanaの地図は素晴らしいですが、もっと多くのオプションが望まれていると聞きました。 もし地図に関して知識があるなら、Kibana 4.2のWMSバックグラウンド地図サポートを試してみてください。 WMSは非常に強力で、US Geological Surveyを含む多くの無料サービスがあります。 http://viewer.nationalmap.gov/example/services/serviceList.html\n画像あり。 ※画像に関しては原文をご覧ください。\nシナリオは? 何かおかしい時、何が起こっているかを正しく知ってもらいたいので、Kibanaがそのタイミングで注目したいコンポーネントがあるなら、 どのように動いているかという概要を知るためのサーバステータスページを作りました。 もちろん、全てがOKであるというのを知りたいだけの場合でも、settingメニューのStatusタブからいつでも呼び出せます。\n画像あり。 ※画像に関しては原文をご覧ください。\n全てにおいて速く ブラウザリフレッシュはKibana 4.2の新しいコードビルディングシステムのおかげで、さらに早くなりました。 また、メモリを覚えてます?Pepperidge FarmKibanaが覚えています。 Kibana 4.2は小さな小さな小さなメモリフットプリントを管理している間、長い長い長い時間実行されているダッシュボードを見ることができるような 大きなメモリのクリーンアップも含んでいます。\nもっとありますが。。。 小さな微調整がいくつもあります。また、今後紹介する本当に刺激的なものの基礎を気づき上げてきました。 これからもElasticのブログ、Twitter、KibanaのGitHubリポジトリに注目し、モンスタートラックアナリティクスの瞬間に立ち会ってください。\n","date":1446103219,"dir":"post/2015/","id":"e159a35d1b9a46e03072a3d54780edcb","lang":"ja","lastmod":1446103219,"permalink":"https://blog.johtani.info/blog/2015/10/29/kibana-4-2-0-ja/","publishdate":"2015-10-29T16:20:19+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Kibana 4.2.0 released Elasticsearch 2.0 + Kibana 4.2 = 💚 Elasticsearch 2.0サポートのKibanaの最初のリリースです。 これ","tags":["elastic","kibana"],"title":"Kibana 4.2.0リリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Logstash 2.0.0 released\nLogstash 2.0.0が本日(10/28)リリースされました。 このリリースは いくつかの設定に関する重要な変更があります。 詳細については、changelogまたは、新しいbreaking changesドキュメントをご覧下さい。\nこれまでの2.0.0直前のリリースに関する変更点はこちらをご覧ください。\nbeta1 beta2 beta3 RC ここでは、2.0の主な変更点の概要を説明します。\nElasticsearch 2.0との互換性 多くの機能および改善を含んだElasticsearch 2.0がリリースされました。 Logstash 2.0はこのリリースに対応しています。 Logstashのこれまでのリリースでは、デフォルトで、Javaの node clientをElasticsearchとの通信として 使用してきました。 2.0では、HTTPクライアントがデフォルトになります。 これにより、シームレスにユーザのデータを取り込み、付加価値をつけ、Elasticsearchに保存して解析することができます。\nHTTPは他のプロトコル(nodeやtransport)同等の機能を持っていますが、 単一のクライアントに接続する時に、少しだけ遅いですが、管理や動作がより簡単です。 HTTPプロトコルを使うことで、Elasticsearchのバージョンのアップグレードが、Logstashのアップグレードすることなく 行うことができます。 デフォルトをHTTPに変更したさらに詳しい情報についてはbeta1のブログをご覧ください。\n他のプロトコル(nodeとtransport)もサポートしますが、これらを利用する場合には、 プラグインを別途インストールする必要があります。\nbin/plugin install --version 2.0.0 logstash-output-elasticsearch_java 互換性のマトリックス LogstashとElasticsearchのバージョンの互換性は次のようになります。\n画像あり。 ※画像に関しては原文をご覧ください。 #Image https://www.elastic.co/assets/bltde5b69e2164aa82f%2Fcompat_matrix.png\nShield 2.0との互換性 このリリースはShield 2.0リリースにも対応しています。 HTTPプロトコルで、追加のプラグインは必要ありません。 こちらのドキュメントをご覧ください。 transportプロトコルでは、Shield 2.0対応のプラグインを個別にインストールする必要があります。\nbin/plugin install --version 2.0.0 logstash-output-elasticsearch_java_shield パフォーマンスの改善 このリリースはまた、多くの部分のパフォーマンスの改善を含んでおり、Logstashを利用してデータをより早く処理することができます。 いくつかをここで説明します。\nUserAgentとGeoIPフィルタ:これらのフィルタで、LRUキャッシュを追加して改善しています。 これにより、IPとユーザエージェントがまとまって現れるというWebリクエストの特性を用いています。 ユーザエージェントフィルタのケースでは、サンプルデータセットにおいて3.7倍ほど早くなりました。 GeoIPでは、1.69倍早くなっています。\nJSONプロセシング:LogstashでJSONのsiriaraizu/でシリアライズに利用しているJrJacksonを新しいバージョンにしました。 これにより、JSONの処理が改善されています。\nフィルタワーカーのより良い値をデフォルトに:以前のリリースでは、filter_workersの設定は1がデフォルトでした。 これは、フィルタの処理を行うワーカーが1つであるという意味です。 filter_workersの設定のデフォルト値はCPUコア数の半分の値を設定します。フィルタ実行の並列性が上がります。 ですので、複雑なgrokパターンやuseragentフィルタの処理がにとっては重要です。\nFilebeat Support Filebeatのベータバージョンを先日リリースしました。 これは、Logstash Forwarderの次期バージョンです。 Filebeatはファイルベースのログをさらに処理するためにLogstashに送るためのエージェントです。 2.0.0はlogstash-input-beatsプラグインを使えばFilebeat 1.0.0-beta4とすぐに動作します。\nシャットダウン操作 これまでのLogstashでは、シャットダウンが開始した時に、例外の機構でシャットダウンが開始したことを プラグインに通知していました。 この処理はサードパーティのコードを使ったプラグインで問題を起こしていました。 Logstashはどの例外を処理するか知らないため、予期しない動作をしていました。 これを修正するためにAPI呼び出し(例えばstop)を各プラグインにシャットダウンのイベントを通知し、 プラグイン自身がきちんと停止するようにしました。 これは、200以上のプラグインに新しいAPIを利用するように修正しないといけないことを意味しました。 しかし、Logstashの停止についてはまだ完全にはフィックスしていません。 とちゅうでおわっているoutputがシャットダウンを遅らせる可能性があるからです。 2.0でAPIの破壊的な変更は適切なリリースでの変更を繰り返すことができる出発点です。\nプラグインの開発者へ:もし、Logstash 1.5のプラグインを開発しているなら、 シャットダウンに関する新しいAPIのリストに関するbreaking changesのドキュメントに助言をください。 また、example inputリポジトリにて、新しいシャットダウンメカニズムの使い方のサンプルコードを提供しています。\nドキュメント 2.0に更新されたドキュメントはこちらです。設定の変更についてもこちらをご覧ください。\n2.0へのアップデート 2.0へアップデートする前に、アップデートガイドもご覧ください。\nフィードバック 2.0のリリースできたことに、多くのコントリビューター、ユーザに感謝しています。 このリリースに含まれている多くのパッチと全てのプレリリースのテストにも感謝しています。 将来の修正やリリースなどについてはロードマップをご覧ください。 2.0は今日リリースされました。 ご意見ご感想はWebフォーラムで!\n","date":1446103197,"dir":"post/2015/","id":"cc64c2fcdecdb505b3797e1aaaa59adc","lang":"ja","lastmod":1446103197,"permalink":"https://blog.johtani.info/blog/2015/10/29/logstash-2-0-0-released-ja/","publishdate":"2015-10-29T16:19:57+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Logstash 2.0.0 released Logstash 2.0.0が本日(10/28)リリースされました。 このリリースは","tags":["elastic","logstash"],"title":"Logstash 2.0.0リリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Relase, we have ※画像に関しては原文をご覧ください。\nElasticにとって大きな1日(社内では「release bonanza」と呼んでいる)です。 多くの主要なプロダクトを新たにリリースしました。 そして、本日、それらを一緒に利用する時にそれらを一緒に利用する時にユーザの体験についてまとめてみました。\n次の通りです。\nElasticsearch 2.0リリース。 大きなマイルストーン、チームによる改善、そして、コミュニティからの素晴らしい貢献。 Pipeline Aggsと呼ばれる新しいタイプのaggregations、 クエリとフィルタのコンセプトを統合することにより簡素化されたクエリDSL、 better compressionオプション、 JavaのSecurity Managerを有効にすることによる強化されたセキュリティ、 FSの挙動に関する強化(fsync、checksum、atmicなリネーム)、 パフォーマンス、マッピングの挙動の一貫性などなどです。 また、我々のチームによる改善も含まれているLucene 5ベースにアップグレードしています。\nKibana 4.2リリース。 Elasticsearch 2.0対応、ダークテーマ、カスタマイズ可能な地図、多くの改善。 Kibana 4.2の多くに作業については外部プラグインサポートといった、内蔵に関するものでした。 この後の説明に続きます。\nMarvel 2.0リリース。 Elasticsearch 2.0対応、合理化されたメトリックス、簡素化されたUI、 多くはKibanaプラグイン(Kibanaプラットフォーム上に構築)としての書き換えです。 このKibana拡張の最初の努力は、Kibanaのプラグインをどうやって書くか、 Kibanaユーザに公式に何をする必要があるかといったものを特定するのに役立ちました。 おっと、忘れるところでした、Marvelを全てのユーザにフリーで使えるようにしました。 マルチクラスタサポートについては有償となります。\nSense 2.0リリース。 2つ目のKibanaプラグインがこれです。 SenseをKibanaプラグインとして書き換えました。 Elasticsearch 2.0サポート、複数リクエストの実行、 curlへのコピーなどです。 おっと、忘れるところでした。オープンソースとすることにしました!\nShield + Watcher 2.0リリース。ElasticsearchのためのセキュリティプラグインであるShieldと、アラート管理のためのプラグインであるWatcherにも 多くの結果が入っています。 最も要求のあった機能である、フィールドお呼びドキュメントレベルでのセキュリティについて、Luceneに落とし込んで実装しました。 また、セキュリティの操作についてプラガブルに実装できるように変更しました。 Watcherは監視の無効化、SlackやHipChatへの通知(bot ops向け)が可能です。\nLogstash 2.0リリース。 Elasticsearch 2.0のサポート、クリーンな停止、全面的なパフォーマンス改善、Beatsサポート。\nご覧の通り、すべてのプロダクトに関する大きな結果です。 チーム間およびFoundの開発者との間での密な連携に感謝します。 これらが私たちが公式にElasticsearch / KibanaをホストしているFoundで 利用可能です。\nひゅう、息切れしました。 チームがしてきたことは、感動的で、謙虚で、刺激的です! Elasticが会社として、全てのユーザ、コントリビュータがどのように私たちの大きなミッションに対する結果をもたらしたかという素晴らしい良い例です。 ユーザに愛され、楽しまれ、成功に導き、革新させる製品を是非ご利用ください。ありがとうございます。\n\u0026ldquo;A Lion, in Africa?\u0026rdquo; - まだまだ終わりではありません。この文言で終わりにしますが、すぐに(本当にすぐに)戻ってきます。;)\n","date":1446095939,"dir":"post/2015/","id":"4cc08ca51ecf0f963035f039de6194c5","lang":"ja","lastmod":1446095939,"permalink":"https://blog.johtani.info/blog/2015/10/29/release-we-have-ja/","publishdate":"2015-10-29T14:18:59+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Relase, we have ※画像に関しては原文をご覧ください。 Elasticにとって大きな1日","tags":["elasticsearch","kibana","logstash"],"title":"Release, we have(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 2.0.0-beta2 released\n本日(9/17)、Lucene 5.2.1ベースのElasticsearch 2.0.0-beta2をリリースしました。 本リリースが2.0.0のRCの前の最後のベータリリースになります。\n注意事項 本リリースはベータリリースであり、テストを目的としたものとなります。 Elasticsearch 2.0.0-beta2はElasticsearch 2.0.0-beta1と互換がありません。 また、Elasticsearch 2.0.0 GAと互換性があるかどうかの保証はありません。\n本番環境には利用しないでください。\nElasticsearch 2.0.0-beta2のダウンロードおよび、すべての変更についてはリンクをごらんください。\n2.0.0-beta1をテストし、問題点を報告していただいた皆様、ありがとうございます。 2.0.0-beta1のあとのElasticsearchのコアの部分の修正のほとんどはバグフィックスになりますが、 geo_shapeフィールドのpoints_only最適化のようなちょっとした改善も含んでいます。\nまた、本リリースでは、商用プラグインの重要な新機能もあります。 こちらについてはShield and Watcher 2.0.0-beta2 releasedをごらんください。 簡単な紹介は次の通りです。\nShieldの新機能 ドキュメントおよびフィールドレベルのセキュリティ Shieldは、クエリを利用したインデックスにあるドキュメントへのアクセスを制御するためのロールを定義できるようになりました。 また、ドキュメントにある特定のフィールドに関するアクセス制限も可能です。 フィルタされたエイリアスのような形ではなく、ドキュメントを検索したり、IDで取得したりする場合にこれらの制限が利用できます。 詳細はField- and Document-level Securityをごらんください\nユーザなりすまし 特定のユーザーに他のユーザーに扮して、彼らのためにリクエストを実行する能力を与えることが、現在できます。 これは、認証がアプリケーションによって実行される場合に便利です。 そして、それは、ユーザの許可レベルを考慮するようにElasticsearchにリクエストします。 詳細はSubmitting Requests for Other Usersをごらんください。\nプラガブルな認証レルム このリリースで、サードパーティの拡張のための認証レルムのインフラを公開しました。 もし、特定の認証要求があり、Shieldがサポートしていない(が、内部の認証管理システムを使いたいような)場合、 これらの要求に見合う新しい認証レルムを利用するプラグインを作成可能です。 詳細はCustom Realmsをごらんください。\nWatcherの新機能 監視の一時 新しく、active / inactive の状態がwatchに追加されました。 これらは、Watchを中断したり、要求に応じて再開させたりできます。 詳しくは、Active Stateをごらんください。\nチャットのための新しいアクション slackとhipchatアクションが追加されました。 これは、Watcherが通知を、SlackやHipchatのユーザに直接送ったり、 チームのチャットルームに送ったりすることが出来るようにします。 詳細については、Slack actionおよび、Hipchat actionをごらんください。\n2.0に関するこれまでのブログ記事 これまでのリリースについての情報はこれらのブログ記事をごらんください。\n\u0008* Elasticsearch 2.0.0.beta1 released\nElasticsearch 2.0.0.beta1 coming soon! The Great Mapping Refactoring Store compression in Lucene and Elasticsearch Better query execution coming to Elasticsearch 2.0 Out of this world aggregations Staying in Control with Moving Averages - Part 1 Staying in Control with Moving Averages - Part 2 The Delete by Query API Is now a plugin Elasticsearch unplugged - Networking changes in 2.0 また、Elasticsearch 2.0.0-beta2のドキュメントや2.0のbreaking changesのリストもごらんください。\nElsticsearch Migration Plugin Elasticsearch Migration Pluginは、既存のインデックスをアップグレードする 必要があるか、他に必要な行動がないかについて、Elasticsearch 2.0.0-beta2を試す前に確認する助けとなります。 Lucene 3のような古いインデックスや、2.0.0にした場合に動作しない問題のある マッピングのような問題を発見できます。\nプラグインの動作に関しては[Elasticsearch Migration repository](Elasticsearch Migration repository)をごらんください。\nテストしましょう! Elasticsearch 2.0.0 GAをすぐにリリースできるようにより多くのベータテスターをお待ちしています。\nぜひ、Elasticsearch 2.0.0-beta2をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)やWebフォーラムなどで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1442565101,"dir":"post/2015/","id":"4b227d61f33182579cd3edd0ac6c7c44","lang":"ja","lastmod":1442565101,"permalink":"https://blog.johtani.info/blog/2015/09/18/elasticsearch-2-0-0-beta2-released-ja/","publishdate":"2015-09-18T17:31:41+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 2.0.0-beta2 released 本日(9/17)、Lucene 5.2.1ベースのElas","tags":["elasticsearch"],"title":"Elasticsearch 2.0.0-beta2リリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch unplugged - Networking changes in 2.0\nElasticsearchをローカルのマシンで起動します。 そして、昨日試したデータを削除するためにDELETE *を実行します。 すると、悲しそうな叫びを同僚が発していることに気づき、なぜそんなことになっているのか不思議に思うでしょう。。。\nElasticsearchはいつも、親しみやすいものでした。 複数ノードのクラスタがどのように機能するのかをテストするには、 ローカルのマシンでいくつかのElasticsearchのインスタンスを起動するだけでした。 起動したインスタンスはマルチキャストを利用して自動的にお互いを見つけて、1つのクラスタになり、負荷を共有し始めます。 しかし、これは親しみやすすぎました。 カンファレンスなどで、ローカルのマシンでElasticsearchを起動してみてください。 すると100ノードのクラスタに参加しているのがすぐにわかるでしょう。\nもうすぐリリースされる、2.0.0-beta1では、Elasticsearchが通信先を選択するネットワークの機能に関する変更があります。 ただし、これまで通り、簡単に開発者が経験できる機能も残っています。\nlocalhostへのバインド 以前、Elasticsearchはデフォルトで、利用可能なネットワークインタフェース全てにバインドしていました。 そこから、一番適したインタフェースをpublish_hostとして選択しようとします。 このアドレスはElasticsearchがクラスタの他のノードとやりとりするためのアドレスです。\nElasticsearch 2.0では、デフォルトでは、localhostにのみバインドします。 127.0.0.1(IPv4)と[::1](IPv6)の両方にバインドしようとします。 また、どちらかのみの環境でも動作します。 この変更は、特に指定がない限り、Elasticsearchがネットワーク上の他のノードと接続しません。 本番環境に移行する場合は、network.hostパラメータを使って設定しましょう。 設定は、elasticsearch.ymlに記述するか、コマンドラインで指定します。\nbin/elasticsearch --network.host 192.168.1.5 bin/elasticsearch --network.host _non_loopback_ network.hostの全てのオプションについては、network settingsのドキュメントをごらんください。\nマルチキャストは廃止 Elasticsearch 1.xはネットワークの他のノードに接続・探索するためにマルチキャストを使用しました。 マルチキャストは魔法のような挙動です。。。 残念ながら、マルチキャストのサポートは良くも悪くもあります。 Linuxはローカルホストでマルチキャストの待ち受けをしていません。 OS/Xは構成されたアドレスの全てのインタフェースにマルチキャストで配信できます。 また、ネットワークによってはマルチキャストはデフォルトでは使用できなくなっています。\nElasticsearch 2.0は異なるアプローチを採用しました。 マルチキャストを廃止します(ただし、新たにプラグインとして提供します)。 代わりに、ローカルホストでは、Elasticsearchはtransport.tcp.portで指定されている範囲(デフォルトは9300-9400)の最初の5ポートに対してユニキャストを使用できるようにします。\nこれは、開発者のための、設定することなく自動的にクラスタを組むという機能を残しています。 しかし、本番に移行するときは、unicast hostsで次のようにリストを指定する必要があります。\ndiscovery.zen.ping.unicast.hosts: [ 192.168.1.2, 192.168.1.3 ] unicast hostsとしてクラスタにあるノードの全てのリストを指定する必要はありません。 少なくとも、マスタノードとして選出されるべきものを指定します。 巨大なクラスタでは、3つの専用のマスタノードを持っており、この3つをunicast hostsとして設定することを推奨しています。\nこれにより、開発の知識・経験が、私たちの推奨する本番でのネットワーク設定に、より近いものとなります。\nノード情報の変更 最後に、inet[/127.0.0.1:9200]といったシンタックスを廃止します。 これは、Elasticsearchがnodes-info APIなどで、使用していたIPアドレスのためのシンタックスです。 今は、RFCに準拠した形で表示します。 127.0.0.1:9200(IPv4)や[::1]:9200(IPv6)のようにです。\n質問がある場合は、ElasticsearchのWebフォーラムで質問してください。ベータはもうすぐです!(翻訳した時点で、すでにベータリリースされています。)\n","date":1440730890,"dir":"post/2015/","id":"0de0edbf2a506143c1739b12e94c0ef9","lang":"ja","lastmod":1440730890,"permalink":"https://blog.johtani.info/blog/2015/08/28/elasticsearch-unplugged-ja/","publishdate":"2015-08-28T12:01:30+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch unplugged - Networking changes in 2.0 Elasticsearchをローカルのマシンで起","tags":["elasticsearch"],"title":"Elasticsearch unplugged - 2.0におけるネットワークの変更(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 2.0.0-beta1 released\n本日(8/26)、Lucene 5.2.1ベースのElasticsearch 2.0.0-beta1をリリースしました。 本リリースは469名のコミッターからの2,500以上ものpull requestを含んでいます。 pull requestのうち、約850が2.0のための新規のものとなります。\n注意事項 本リリースはベータリリースであり、テストを目的としたものとなります。 Elasticsearch 2.0.0-beta1は Elasticsearch 2.0.0 GAと互換性があるかどうかの保証はありません。\n本番環境には利用しないでください。\nElasticsearch 2.0.0-beta1のダウンロードおよび、すべての変更についてはリンクをごらんください。\nElasticsearch 2.0.0-beta1には次の新しい変更が含まれています。\nPipeline Aggregations:これは、他のaggregationsの結果に対するAggregationを実行できます(導関数、移動平均、Holt Winter予測アルゴリズムなども含む) ディスクやファイルシステムキャッシュにより適したより良いデータの圧縮 doc-valuesがデフォルトになったこと、マージ実行時のメモリ使用量の低減、フィルターキャッシュのためのroaring bitsetsなどにより、ヒープの使用率がより効率的に。 構造化された例外 最適化されたクエリ実行順序、フィルタの自動キャッシュ、より高速なクエリに書き換えられたparent-child 設定の代わりに、フィードバックループを使用した自動調整 トランザクションログへの書き込みがデフォルトで、アトミックでかつ冗長に 安全で明確で信頼性のあるタイプマッピング デフォルトでローカルホストでのみクラスタを構成 クラスタ状態の差分によりより高速に変更を伝搬 上記の変更以外にも、多くのElasticsearchおよびLuceneに対する継続的な変更が含まれています。 これらは、Elasticsearch 2.0をより安全に、より簡単に、より良いものにしています。 本リリースに関するより詳しい情報が次のブログにあるので、参考にしてください。\nElasticsearch 2.0.0.beta1 coming soon! The Great Mapping Refactoring Store compression in Lucene and Elasticsearch Better query execution coming to Elasticsearch 2.0 Out of this world aggregations Staying in Control with Moving Averages - Part 1 Staying in Control with Moving Averages - Part 2 The Delete by Query API Is now a plugin Elasticsearch unplugged - Networking changes in 2.0 また、Elasticsearch 2.0.0-beta1のドキュメントも参考になります。 特に、2.0での重大な変更点については必ずごらんください。\nCore plugins コアプラグインの開発の方法を変更しました。 公式にサポートしているプラグインは、現在elasticsearchのリポジトリに含まれています。 これにより、コアと一緒にテストされ、Elasticsearchと同じタイミングでリリースされます。 コアプラグインはElasticsearchと同じバージョン番号隣ます。 インストールは次のようになります。\nsudo bin/plugin install analysis-icu プラグインの新しいドキュメントは私たちのWebサイトのGuideにあります。\nCommercial plugins 私たちの商用プラグインもElasticsearchと同じバージョン番号となり、Elasticsearchと一緒にリリースされます。 ShieldやWatcherはすでに2.0.0-beta1が利用可能です。 インストールのコマンドはは次のようになります。\nsudo bin/plugin install license sudo bin/plugin install shield sudo bin/plugin install watcher MarvelおよびSenseに関する新しい情報もありますが、もう少しお待ちください。\n2.0.0-beta1の商用プラグインに関するドキュメントは次のリンクからごらんください。\nShield 2.0.0-beta1 Watcher 2.0.0-beta1 Elasticsearch Migration plugin Elasticsearch 2.0.0-beta1を試す前に、 既存のインデックスのアップグレードするためになにか行う必要があるかどうかを確認するためのElasticsearch Migration Pluginもリリースしました。 2.0.0では機能しない、問題のあるマッピングなどを見つけるために便利なプラグインです。\nこのプラグインの利用方法についてはElasticsearch Migration repositoryをごらんください。\n既知の問題 同じインデックスの異なるタイプに、同じ名前のipタイプのフィールドを追加した時に、問題があることがわかっています。 この問題は次のリリースでフィックスされます。詳細は#13112をごらんください。\nテストしましょう! Elasticsearch 2.0.0 GAをすぐにリリースできるようにより多くのベータテスターをお待ちしています。\nぜひ、Elasticsearch 2.0.0-beta1をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)やWebフォーラムなどで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1440638952,"dir":"post/2015/","id":"744554499cb7880086fbd9b1f080e7e1","lang":"ja","lastmod":1440638952,"permalink":"https://blog.johtani.info/blog/2015/08/27/elasticsearch-2-0-0-beta1-released-ja/","publishdate":"2015-08-27T10:29:12+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 2.0.0-beta1 released 本日(8/26)、Lucene 5.2.1ベースのElas","tags":["elasticsearch"],"title":"Elasticsearch 2.0.0-beta1リリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:The Delete by Query API Is now a plugin\nElasticsearchの2.0.0-beta1では、これまであった Delete by Query APIが削除され、 新しく Delete by Query pluginに置き換えられています。\nもし、Delete by Query を利用する場合、2.0にアップグレードしたあとは、プラグインをインストールし、ドキュメントに従ってください。\nbin/plugin install delete-by-query なぜプラグインに? ElasticsearchのコアなAPIの品質を保つためであり、以前のDelete by Queryの実装は簡単にはフィックスできない大きな問題がありました。\n各リクエストのあとに、refreshを実行します。これは、削除されたデータが想定外に検索に出てこないようにするためです。\nまた、セグメントが大量にでき、マージが大量に発生し、ヒープが大量に消費されてインデキシングが劇的にスローダウンし、クラスタの複数のノードがクラッシュしてしまう状況も引き起こしました。 このクエリは、プライマリ、レプリカの両方で実行されるため、ことなるドキュメントを削除し、矛盾したレプリカ(データの破損)を引き起こしました。 アップグレードが不安定になります。これは、Delete by Queryリクエストがトランザクションログの中にクエリとして残るためです。そのため、アップグレードのあとに正確にパースされなかったり正確に実行されないかもしれません。例えば、インデックスエイリアスに対するリクエストで、それが削除された後の場合にこのようなバグが発生します。 対照的に、新しいプラグインは、安全な実装です。 scanとscrollリクエストでクエリにマッチしたIDを見つけ、そのIDを使って、bulk indexing APIで削除します。\nこの実装は、遅い必要があります。特に、クエリが多くのドキュメントを削除する場合です。 もし、多くのドキュメントをこのAPIを利用して削除する場合、アプリケーションをテストしてください。 そして、代わりにインデックス全体を消すようなアプローチに切り替えることができないか検討してください。\nDelete by Query pluginのドキュメントに、新しい実装についての違いなどのより詳しい説明があります。\nElasticsearch coreを最小限に プラグインに切り替えることは、簡単な決断ではありませんでした。 多くのユーザは問題なく、Delete by Queryを利用していました。 しかし、危険が常にそこにあり、些細とは言い切れない数のユーザが上記のような深刻な問題に遭遇していました。\nさらに、Elsticsearchのコアは信頼できるものでなければなりません。 他のコアAPIを利用して実装できる機能は、コアに含みません。特に、それがバグを含んでいる場合。 コアのすべての機能は強固であるべきで、Delete by Queryは人気があり、高性能ですが、そうではありませんでした。\n必要に応じて、このような難しいトレードオフの末、信頼性と品質を選びます。\nマッピングの削除の廃止 タイプのマッピングを削除する機能も2.0で廃止されます。 これは、同じフィールド名を、異なるフィールドのタイプで再利用した場合に、インデックスの破損を引き起こす可能性があるためです。\nしかし、Match All Queryで、Delete by Queryプラグインに対してタイプを指定することで、タイプのすべてのドキュメントを削除することはできます。 または、1つのインデックスに異なるタイプを複数含める代わりに、個別のインデックスに分割するようなアプローチに変更することを検討してください。\n","date":1440044644,"dir":"post/2015/","id":"5a9e950f4ac186925e5de978c5f72062","lang":"ja","lastmod":1440044644,"permalink":"https://blog.johtani.info/blog/2015/08/20/core-delete-by-query-is-a-plugin-ja/","publishdate":"2015-08-20T13:24:04+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:The Delete by Query API Is now a plugin Elasticsearchの2.0.0-beta1では、これまで","tags":["elasticsearch"],"title":"Delete by Query APIはプラグインへ(日本語訳)"},{"contents":"第11回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズさん、そして、Shayありがとうございました! 次回もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\n今回は、CTOのShayが来日していたので、英語でいろいろと喋ってもらいました。 4月同様、サムライズムの@yusukeさんに テキスト翻訳していただき、大変助かりました。 今回はQAベースのトークだったのでちょっときつかったですね、申し訳ない。。。\nチェックイン数など チェックインした人:141名 キャンセルしなかった人:51名 でした。 今回はあらかじめ220名(全員が来たらキャパオーバー)としていたので、キャンセル待ちの人は 当日の午後にはいなくなっていた状態です。まぁ、こんなもんかな。結構入りましたね。ありがたいです。\nLT 今回は、少し趣向を変えて、4社の方達にLTをしていただきました。 Shayが来日しているのもあり、事前に英語でスライドを作っていただけると助かりますとお願いさせていただきました。 英語でスライドを作っていただいていたので、伝わりやすくて助かりました、スピーカーの方々ありがとうございました!\n(海外のユーザにもリンクを紹介しやすいので、英語でスライド作ってもらえるといろいろと知ってもらえるのかも。)\nElasticsearch and Recruit Technologies Co., Ltd. / 株式会社リクルートテクノロジーズ 守谷 純之介さん スライド:未定\nN-Gramと形態素のハイブリッドの話などをしていただきました。 @ITで連載もされてますね。ありがとうございます。\nリクルート全社検索基盤のアーキテクチャ、採用技術、開発体制はどうなっているのか (1/2) ElasticsearchとKuromojiを使った形態素解析とN-Gramによる検索の適合率と再現率の向上 (1/3) Shayからは、elasticsearch-hadoopがあるから検討してねと質問(お願い?)がありましたw。\nElasticsearch as a DMP / 株式会社インティメート・マージャー 松田和樹さん @mats116 スライド:Elasticsearch as a DMP\nいくつかのデータソースからAEROSPIKE経由でelasticsearchにデータを登録しているようです。 Data Management Platformのエンジンの一部として、elasticsearchを利用しているようです。\nShayからの質問:「どの機能を使って関心のある単語を抽出していますか?」\n回答:「Significant Term Aggregation」です。\nShay:「おぉ、チェックしてみますw」。\nReal-time social big data analytics using elasticsearch / 株式会社ホットリンク宮田洋毅さん @kakka_jp スライド:未定\nソーシャルメディアのデータを解析するのにelasticsearchにデータを入れて解析。 時間軸での解析やテキストマイニングなんかをしているみたいでした。 いろいろと独自のプラグインを作ってるようです。(興味あるなぁ)\nShayからの質問:「ノード数は?」「30ノードで30シャード」\nElasticsearch in Hatena Bookmark / 株式会社はてな id:skozawa スライド:Elasticsearch in Hatena Bookmark\nはてなブックマークの検索の歴史(MySQL -\u0026gt; Sedue -\u0026gt; Solr -\u0026gt; Elasticsearch) はてなブックマークの検索(ユーザが利用)と社内利用と、ログ解析で利用してる Shayからの質問:「昨年会いましたよね?今はクラスタのサイズはどのくらいのサイズですか?」「メインクラスタは9データノード」\nOpen QA with Shay 思い出せるものだけ。。。(あとで追記します)\nElasticsearch 2.0の話 Pipeline Aggregationとか。 Spark Streaming対応してる? まだ検討中 elasticsearch-hadoopってどんなもの?HDFSにインデックス作ったりするの? いえ、Hadoopの入出力先としてelasticsearchが使える感じ 個人的にAWSのCloudSearchとAWSでElasticsearchはどっちがいい? 時系列データはCloudSearchだと難しいだろうし、AWS上ならfound.noがあるよ! PostgreSQLみたいに信頼性の高いデータストアを目指してる(まだ、プライマリデータストアには使わないで) その他、感想などのブログ Elasticsearch勉強会でLTしてきました | Intimate Merger Engineer Blog 『第11回elasticsearch勉強会』のまとめ #elasticsearchjp \u0008* [Elasticsearch] 第11回 Elasticsearch 勉強会へ参加してきた - 雑文発散(2015-07-28) 第11回 Elasticsearch 勉強会に参加したら英語力に危機感を覚えて最高だった まとめ 今回はShayが来日したので特別バージョンでした。 もっと英語を翻訳するサポートしないとですね、反省してます。。。ぜんぜん流暢じゃないしw\n次回は9月に開催予定ですが、12月にまたShayが再度来日する予定です。 丸1日のイベントを検討中で、Shay以外にも開発者が来日すると思います。 どんな話が聞きたい、どんな人と話をしたいなどあれば、コメントいただければ(対応できるかは。。。)\n勉強会のスピーカーは随時募集中ですので、コメント、メール、ツイートなど、コンタクトしていただければと思います。 よろしくお願いいたします。\n","date":1438321313,"dir":"post/2015/","id":"73b8194ad8fce0cabb01cd21d5e18500","lang":"ja","lastmod":1438321313,"permalink":"https://blog.johtani.info/blog/2015/07/31/11th-elasticsearch-jp/","publishdate":"2015-07-31T14:41:53+09:00","summary":"第11回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズ","tags":["elasticsearch","勉強会"],"title":"第11回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 1.7.1 and 1.6.2 released\n本日(7/29)、Lucene 4.10.4ベースのElasticsearch 1.7.1およびElasticsearch 1.6.2 のバグフィックス版をリリースしました。 これらのリリースは稀ですが、データの欠損が発生する重要なバグのフィックスを含んでいます。 すべてのユーザにアップグレードを推奨します。\nダウンロードおよびすべての変更については次のリンクをごらんください。\n最新安定版:Elasticsearch 1.7.1 1.6系バグフィックス:Elasticsearch 1.6.2 問題のバグ(#12487)は、 同時に複数のノードが故障またはリスタートをした場合の非常にまれな状況で、 シャードのすべてのコピーがクラスタから削除されてしまう状況を発生させます。 このバグは1.5.0から含まれています。\nこのリリースはまた、IPv4アドレスのCIDRマスクのバグのフィックス、 Shieldユーザがmore-like-this APIを利用できないバグのフィックスなど、 いくつかの変更も含んでいます(詳細は更新リストをごらんください)。\nぜひ、Elasticsearch 1.7.1をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1438173353,"dir":"post/2015/","id":"100c0a69bea7f02a0f4540ecaa37d0e3","lang":"ja","lastmod":1438173353,"permalink":"https://blog.johtani.info/blog/2015/07/29/elasticsearch-1-7-1-and-1-6-2-released-ja/","publishdate":"2015-07-29T21:35:53+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 1.7.1 and 1.6.2 released 本日(7/29)、Lucene 4.10.4ベースのE","tags":["elasticsearch"],"title":"Elasticsearch 1.7.1 および 1.6.2リリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 1.7.0 and 1.6.1 released\n本日(7/16)、Lucene 4.10.4ベースのElasticsearch 1.7.0およびElasticsearch 1.6.1 のバグフィックス版をリリースしました。 これらのリリースはセキュリティフィックスを含んでおり、すべてのユーザにアップグレードを推奨します。\nダウンロードおよびすべての変更については次のリンクをごらんください。\n最新安定版:Elasticsearch 1.7.0 1.6系バグフィックス:Elasticsearch 1.6.1 1.7.0が1.x系の最後のリリースとなります。 今後の新機能については、Elasticsearch 2.0以降で取り込まれる予定です。\nElasticsearch 1.7.0は小さなリリースですが、2つの重要なセキュリティフィックスと クラスタの安定化とリカバリに関する2つの重要な機能を含んでいます。\nセキュリティフィックス シャードアロケーションを遅らせる インデックスリカバリの優先度 セキュリティフィックス Elasticsearch 1.6.1 と 1.7.0 は次の2つのセキュリティフィックスを含んでいます。\nリモートコード実行の脆弱性 Elasticsearch 1.6.1より前のバージョンには、transport protocol(ノードとJavaクライアント間での通信に利用)により、 リモートでコードが実行される脆弱性があります。 これは、CVE-2015-3253でのGroovyに関係しています。\nGroovyのダイナミックスクリプティングがオフでも脆弱性があります。 アップグレードをしないユーザは、transport protocol のポート(デフォルトで9300)信頼したエージェントからのみの アクセスに限定することで、脆弱性から保護できます。\nこの問題をCVE-2015-5377としました。\nディレクトリ探索の脆弱性 Elasticsearch 1.0.0から1.6.0までのバージョンで、ElasticsearchのJVMプロセスによって読み込みが可能なファイルを 取得することができるディレクトリ探索攻撃の脆弱性があります。 アップグレードをしないユーザは、信頼できない場所からのSnapshot-Restore APIの呼び出しを防ぐためにファイアウォール、リバースプロキシやShieldを使用することができます。\nこの問題をCVE-2015-5531としました。\nシャードアロケーションを遅らせる Elasticsearch 1.6.0でSynced Flushingが導入されました。 これは、ノードのリスタート時に、更新が止まっているシャードのリカバリを劇的にスピードアップします。 しかし、この変更は、シャードの配置を無効にしている環境でのみうまく実行されます。 ノードが一時的にクラスタから外れている場合や予期せぬリブートの場合には役に立ちません。\nこのシナリオとは次のようなものです。\nノードの想定外のシャットダウン マスタがたのノードにシャードを再配置 各シャードが新しい場所にネットワーク越しにコピー その間に、外れていたノードが再度クラスタにジョイン マスタは新しいノードにシャードを再配置。新しいノードに存在する既存のシャードが全く再利用されない可能性がある ノードレベルとクラスタレベルの両方の並列的なリカバリを抑制しても、 この\u0026quot;シャードシャッフル\u0026quot;がクラスタに対して負荷をかける可能性があります。 これは、外れたノードが再度ジョインするのを単に待つことにより防げるかもしれません。\n待ちましょう! Elasticsearch 1.7.0はindex.unassigned.node_left.delayed_timeout設定を追加しました。デフォルトでは1分です。 これは、ノードがクラスタから外れたとき、ほかのノードにこれらのノードを再配置するまでマスタが1分待つということです。 ノードがこの1分の間に復帰した場合、マスタはローカルにあるシャードを再度配置します。\nなぜ1分? ノードがシャットダウンし、リスタートし、復帰するために十分な時間が1分だからです。 しかし、ノードが復帰しない場合にはまだ再配置が発生することを意味します。 デフォルト値を決定するのは難しいです。 この設定をどのくらいに減らすか、増やすかを決める必要があるかもしれません。\nこのデフォルト値は、config/elasticsearch.ymlファイルに設定できますが、インデックス設定の更新APIを使って設定することも可能です。\nこのデフォルトに関する知見をぜひフィードバックしてください。\nインデックスリカバリの優先度 1.7.0の2つ目の重要な機構はフルクラスタリスタートのような後に、 どの順番でインデックスをリカバリするかという優先度をつけることができるという機能です。\n電源故障による、ロギング用のクラスタのダウンを想像してください。 クラスタが普及した場合、500個のインデックスをリカバリするような場合、499個のインデックスのデータは古く、 500番目のインデックスが重要です。 もっとも最近作成されたインデックスがリカバリされるまで、インデキシングを待つというようなことはできません。\nこれまでは、インデックスはランダムな順序でリカバリされ、重要なインデックスがリカバリされるまで待つしかありませんでした。 1.7.0では、インデックスは優先度の順番でリカバリされます。 この優先度は次のプロパティで指定できます。\nindex.priority設定(大きな値が優先度が高い) インデックス作成日(新しいものが優先度が高い) インデックス名 既存のクラスタについて特に変更せずとも、最も最近作成されたインデックスが古いものよりも復旧されます。 古いインデックスの優先度を上げるためには、index.priority設定に0よりも大きな値を設定します。\nPUT important_index/_settings { \u0026#34;index.priority\u0026#34;: 5 } この設定は、存在するインデックスに対して更新できます。リカバリ中にもです。\nまとめ ぜひ、Elasticsearch 1.7.0をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1437546817,"dir":"post/2015/","id":"809925e891b0456231c374b09cbe4a90","lang":"ja","lastmod":1437546817,"permalink":"https://blog.johtani.info/blog/2015/07/22/elasticsearch-1-7-0-and-1-6-1-released-ja/","publishdate":"2015-07-22T15:33:37+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 1.7.0 and 1.6.1 released 本日(7/16)、Lucene 4.10.4ベースのE","tags":["elasticsearch"],"title":"Elasticsearch 1.7.0 および 1.6.1リリース(日本語訳)"},{"contents":"東京以外での勉強会の第2弾として、関西で勉強会を開催してきました。\nElasticsearch勉強会 in 大阪 Elasticsearch勉強会 in 京都 会場提供をしていただいた、Yahoo!大阪、はてなのみなさん、ご協力ありがとうございました!\nここからはいつものメモです。 ちなみに、大阪の勉強会に、@takuya_aさんと@5kozawaさんの両名にお越しいただき話をしていただきました。 なので、勉強会の内容はほぼ同一になります。\nIntroduction Elastic @johtani スライド:Introduction Elasticsearch\n初めての関西での勉強会ということで、ElasticsearchのOSSおよび商用プラグインの紹介をしてきました。 もちろん、Kibanaのデモもちょっとだけ。スプラトゥーンに関するデータをKibanaでちょっとだけ。 突貫でデータをかき集めたのでもう少し改良しないとですが。\nElasticsearch での類似文書検索と More Like This API 詳解 / 株式会社はてな id:takuya-a スライド:Elasticsearch での類似文書検索と More Like This Query API 詳解\nElasticsearchのMore Like Thisのソースコードリーディングみたいな感じで、 内部でどうやって処理されているかの説明を詳しくしてもらいました。\n前のはてなエンジニアセミナーで話をされていた検索精度の件に絡んだ内容になっているかと。 (大阪で発表してもらった時より京都での発表が分かりやすくなってました。1日で改善されたのすごい!) MoreLikeThisだとチューニングつらいので、自分で作るためにTermVectorAPIでやってみたという流れかと。\n以下は発表後に出てきた質問のいくつかです。\nQ:MoreLikeThisに対してTermVectorで柔軟にできる? A:TermVectorのAPIで統計情報が取れるので、それを使うことでさらなるデータの更新ができる。\nQ:TFとかの統計情報が必要なら、すべてインデックスをしたあとじゃないとちゃんとした値はとれないのでは? A:TermVectorで取得したものをどうやって使うか\nQ:TermVectorAPi\u0026hellip;聞こえなかった A:。。。\nElasticsearchを用いたはてなブックマークのトピック生成 / 株式会社はてな id:skozawa スライド:Elasticsearchを用いたはてなブックマークのトピック生成\nSignificant Terms Aggregationを活用してる話。 トピックページの生成のために、Significant Terms Aggregationをどうやって利用しているかなどのお話でした。\nトピックの集合の重複だったり、精度の判定方法とかいろいろ詳しく説明していただきました。\nQ:2011年と12年で11年の方が多いのは? A:ブックマークの件数に比例\nQ:Significant terms aggsのsizeはいくつをつかってますか? A:20を指定してます。\nQ:Yahooとかニュースをストップワードとしてますが、Yahoo自体のニュースに関してはどーしてるんですか? A:本文とタイトルから別々に作っていて、タイトルからは弾かれますが、本文から作った時に出てきます。\nはてなブックマークにおける Elasticsearch の運用まわりの話 / 株式会社はてな id:hagihala スライド:未定(おそらく公開される)\n体調が回復しきっていない中の発表ありがとうございました。 大幅に修正された資料が出てくるかなと。(ツイートできない数値がちらほらあったので)\nElasticsearchのクラスタの構成、どういった点で困ってたのでどういう調べ方をしたのか、どういった対処をしたのか。 どのあたりが次の課題かなどの話もありました。\n感想・反省点など 大阪、京都ともに30名弱の方の参加をしていただきました。ありがとうございました。 反省点としては、ハッシュタグを告知し忘れてました。。。\n勉強会はやはり、東京が異常に活発で、大阪や京都はまだそれほどでもないのかなぁとも。 大阪はエンジニアの人や会社も多い気がするんですが。私の告知の仕方もあるかもなぁと。 次回があれば、大阪での事例も聞きたいので、スピーカーをもっと探さないとなと。\n関連ブログなど 見つけたら、リンク追加していきます。\nElasticsearch勉強会 in 大阪/京都で発表しました \u0008* 「Elasticsearch での類似文書検索と More Like This Query API 詳解」というタイトルで発表しました その他(余談) 大阪のYahoo!さんは立地条件(梅田のすぐそば)がよく、\n夜景も綺麗でした。大阪城とかも見えてました。(夜景じゃないけど。。。)\n京都は祇園祭の真っ最中。\n水曜日はお休みをいただいて、観光してました。ちょっと日焼けが。。。 おかげで、リフレッシュできました。三十三間堂とか良かった:)\nあまり、関西に縁がない(大阪15年ぶり、京都10年ぶり)ので、 もっとユーザが増えて勉強会の機運が高まると嬉しいなと。:)\n","date":1437010857,"dir":"post/2015/","id":"dd6c32a722dc815273cd9ed8cd6c671b","lang":"ja","lastmod":1437010857,"permalink":"https://blog.johtani.info/blog/2015/07/16/kansai-1st-elasticsearch-jp/","publishdate":"2015-07-16T10:40:57+09:00","summary":"東京以外での勉強会の第2弾として、関西で勉強会を開催してきました。 Elasticsearch勉強会 in 大阪 Elasticsearch勉強会 in 京","tags":["勉強会","elasticsearch"],"title":"大阪と京都でElasticsearch勉強会を開催しました。 #elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:The Great Mapping Refactoring\nElasticsearchのユーザの悩みの最も大きなものの一つは、 タイプとフィールドのマッピングに関する多義性です。 この多義性は、インデックス時の例外やクエリ時の例外、 正しくない結果、リクエストからリクエストへ変化する結果、 また、インデックスの故障やデータのロスを結果として引き起こします。\nElasticsearchをより強固で予測可能な振る舞いをするようにする作業において、 フィールドやタイプのマッピングをより厳格でより信頼性を高くするかといったことに 多くの変更を費やしました。 多くのケースで、Elasticsearch v2.0で新しいインデックスを作るときにのみ、 新しいルールを強制し、これまでのインデックスに関しては後方互換性を保つようにします。\nしかし、幾つかのケースでは、先ほど説明したようなフィールドマッピングの コンフリクトなどが存在するため、それらを利用できないです。\nコンフリクトしたフィールドのマッピングをもつインデックスはElasticsearch v2.0にはアップグレードできません。\nもし、これらのインデックスのデータが必要ない場合は、インデックスを消せばいいです。 そうでない場合はマッピングを正しくして再度インデックスする必要があるでしょう。\nマッピングを正しく変更することは、私たちが簡単に決めることではありません。 ここからは、現在ある問題点と、私たちがどのように実装して解決したかについて説明します。\nフィールドマッピングのコンフリクト あいまいなフィールドのルックアップ タイプのメタフィールド アナライザ設定 index_nameとpath 同期的なマッピングの更新 マッピングの削除 2.0のための準備 フィールドマッピングのコンフリクト これまで、わたしたちはドキュメントのタイプは「データベースのテーブルのようなもの」と説明していました。 タイプの目的を説明する簡単な方法だったからです。 しかし、残念なことにこれは、真実ではありません。 「同じ」インデックスの「異なるタイプ」にある同じ名前のフィールドは、 内部的に、Luceneのフィールド名が同じものになります。\nもしerrorフィールドとして、ドキュメントタイプがapacheのものには数値(integer)を、 ドキュメントタイプがnginxのものには文字列(string)を割り当てた場合、 Elasticsearchは同じLuceneのフィールドに数値と文字列のデータをもつことになります。 このフィールドに対して、検索やaggregationを行う場合、おかしな結果を受け取るか、例外が帰ってくるか、 インデックスが破損することになります。\nこの問題を解決するために、まず、ドキュメントタイプの名前をフィールドの名前の前に追加することを考えました。 各フィールドは完全に別のものとなります。 このアプローチの利点はドキュメントタイプが実際のテーブルのようになることです。\nしかし、この方法には多くの欠点があります。\nフィールドは常に、他のタイプとは異なるものであると区別するためもしくは、複数のタイプに同じフィールドのクエリのためにワイルドカードをつけた場合、 ドキュメントタイプを前につける必要があります。 複数のドキュメントタイプに対して同じフィールド名で検索する場合、クエリを個別に発行しなければならなく遅くなります。 多くの検索で、既存の多くのクエリを壊してしまうために、単純なmatchやtermクエリの代わりに、multi-fieldクエリを使う必要があります。 圧縮の効率の悪さから、ヒープ利用量、ディスク使用量、I/Oなどが、増加します。 複数のドキュメントタイプに対するaggregationは、global ordinalの利点を利用できなくなるために、遅くなり、メモリの使用量も増えます。 解決方法 最終的に、同じインデックスの同じ名前を持つ全てのフィールドは、同じマッピングを持つ必要があるというルールを採用することに決めました。 ただ、copy_toやenabledのようなパラメータはタイプごとに指定することができるようになっています。 これにより、データの破損、クエリ時の例外そして、おかしな結果が発生する問題を防ぎます。 クエリとaggregationは現在でも高速なままで、圧縮率を最大化し、ヒープ使用量やディスク使用率の低減させます。\nこの解決方法の欠点は、個別のテーブルとしてタイプを扱いたいユーザが彼らの考え方を変える必要があるということです。 これは、思ったよりも問題ではありません。 実際には、多くのフィールド名はデータの明確なタイプを表現しています。 created_dateは常に、日付ですし、number_of_hitsフィールドはいつも数値です。 フィールドマッピングがコンフリクトしているユーザはデータを失ったり、おかしなデータを受け取ったり、データを欠損させています。 ベストプラクティスにユーザが従っているかどうかによらず、インデックス時に正しい振る舞いを強制することが現在の違いです。\nユーザの多くがコンフリクトしていないフィールドマッピングをもっていれば、 コンフリクトが起きた場合、技術がこれらのシチュエーションを扱うことが可能になると思いませんか? そこにはいくつかの解決方法があります。\nタイプの代わりにインデックスを別々に 最も簡単な解決方法です。インデックスを別々のインデックスとし、実際のデータベーステーブルのようにします。 インデックスをまたいだ検索はタイプをまたいだ検索のように動作しますし、 ソートやaggregationも同じデータタイプへのクエリのように動作します。これまでと同じ制限です。\nコンフリクトしたフィールドの名前の変更 コンフリクトがごくわずかな場合、(Logstashやアプリケーションで使っているものも一緒に)よりわかりやすいフィールド名に変更することで解決できます。 例えば、2つのerrorフィールドがあった場合に、error_codeとerror_messageに変更します。\ncopy_toもしくはmulti-fieldsを利用 異なるドキュメントタイプのフィールドは別々のcopy_toを設定できます。 元のerrorフィールドはindexの設定にnoが設定してあり、全てのドキュメントタイプで無効化されていますが、 特定のタイプだけ、errorフィールドの値を数値のerror_codeフィールドにコピーすることができます。\nPUT my_index/_mapping/mapping_one { \u0026#34;properties\u0026#34;: { \u0026#34;error\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;no\u0026#34;, \u0026#34;copy_to\u0026#34;: \u0026#34;error_code\u0026#34; }, \u0026#34;error_code\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34; } } } 他のタイプでは文字列のerror_messageにコピーします。\nPUT my_index/_mapping/mapping_two { \u0026#34;properties\u0026#34;: { \u0026#34;error\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;no\u0026#34;, \u0026#34;copy_to\u0026#34;: \u0026#34;error_message\u0026#34; }, \u0026#34;error_message\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } } 同様の解決方法としてmulti-fieldも使えます。\n各データタイプに対してネストしたフィールドに ときどき、Elasticsearchに送ったドキュメントやドキュメントがもっているフィールドを制御できない場合があります。 部分的なコンフリクトに加え、闇雲に、ユーザが送ってきたフィールドを受け入れると、マッピングが肥大化します。 タイムスタンプやIPアドレスをフィールド名に使うようなドキュメントがあると考えてください。\nnested フィールドにすることで、str_val、int_val、date_valというような各データタイプを利用できます。\nこのアプローチによって、次のドキュメントは\n{ \u0026#34;message\u0026#34;: \u0026#34;some string\u0026#34;, \u0026#34;count\u0026#34;: 1, \u0026#34;date\u0026#34;: \u0026#34;2015-06-01\u0026#34; } アプリケーションによって、次のようにフォーマットしなおす必要があります。\n{ \u0026#34;data\u0026#34;: [ {\u0026#34;key\u0026#34;: \u0026#34;message\u0026#34;, \u0026#34;str_val\u0026#34;: \u0026#34;some_string\u0026#34; }, {\u0026#34;key\u0026#34;: \u0026#34;count\u0026#34;, \u0026#34;int_val\u0026#34;: 1 }, {\u0026#34;key\u0026#34;: \u0026#34;date\u0026#34;, \u0026#34;date_val\u0026#34;: \u0026#34;2015-06-01\u0026#34; } ] } この解決方法は、アプリケーションサイドでより多くの作業が必要ですが、コンフリクトの問題とマッピングの肥大化の問題を同時に解決します。\nあいまいなフィールドのルックアップ 現在、フィールドの指定には\u0026quot;short name\u0026quot;、フルパス、ドキュメントタイプを前につけたフルパスが利用できます。 これらのオプションがあいまいさをもたらしています。 サンプルとして次のマッピングをご覧ください。\n{ \u0026#34;mappings\u0026#34;: { \u0026#34;user\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;title\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, \u0026#34;blog\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;title\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;user\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;fields\u0026#34;: { \u0026#34;title\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } } } } } } titleはuser.title、blog.title、blog.user.titleのどれでしょう? user.titleはuser.titleまたはblog.user.titleのどちらでしょう? 答えは「場合によります。」です。Elasticsearchが最初に見つけたものになります。 フィールドはリクエストごとに変わるため、各ノードでマッピングがどのようにシリアライズされたかに依存します。\n2.0では、フィールドを指定する時に、ドキュメントタイプを除いたフルパス名を使用するべきでしょう。\nuser.titleは、blogタイプのuser.titleを意味します。 titleは、userとblogタイプのtitleフィールドを意味します。 *titleはuser.titleとtitleフィールドの両方にマッチします。 userタイプのtitleフィールドとblogタイプのtitleの違いはどのように指定するのでしょう?\n指定できません。フィールドマッピングのコンフリクトで説明した変更により、 titleフィールドは両方のタイプで同じフィールドになります。 本質的にtitleと呼ばれる1つのフィールドになります。\nuser.やblog.のようなタイプのプレフィックスはタイプを指定することによるフィルタリングで効果があります。 クエリのblog.titleフィールドはblogタイプのドキュメントだけを検索し、userタイプのドキュメントを検索しません。 このシンタックスは誤解を招きやすいです。なぜなら、いつでも動作するわけではないからです。 aggregationやsuggestionはすべてのタイプに関する結果を含みます。 この利用のため、上記の例のあいまいさがあるので、タイプのプレフィックスはサポートしません。\n重要 short nameやタイププレフィックスを利用したpercolatorは更新する必要があります。\nタイプのメタフィールド すべてのタイプはメタフィールドを持っています。_id、_index、_routing、_parent、_timestampなどです。 これらのほとんどはindex、store、pathのような幾つかの設定をサポートしています。 これらの設定について次のようにシンプルにしました。\n_idと_typeは変更不可 _indexは、ドキュメントのもつインデックスを保存するためにenabled _routingはrequiredのみを指定 _sizeはenabledのみ _timestampはデフォルトで保存される _boostと_analyzerは廃止。古いインデックスのものは無視される ドキュメントのフィールドから_idと_routingと_timestampの値を抽出することができました。 この機能は廃止されます。これは、ドキュメントのパースとコンフリクトを起こすためです。 代わりに、これらの値はURLもしくはquery stringで指定可能です。\n_boostと_analyzerフィールドは例外で、すでにあるメタフィールドの設定は古いインデックスのものが採用されます。\nアナライザ設定 これまで、indexとsearchのアナライザがインデックス、タイプ、フィールド、ドキュメント(_analyzerフィールドで)の それぞれのレベルで指定可能でした。 同じフィールドに対して異なるanalysis chainの組み合わせができることにより、おかしな関連度を引き起こしていました。 フィールドマッピングのコンフリクトを解消することに加え、アナライザの設定も簡略化します。\nAnalyzedな文字列フィールドは、analyzer設定とsearch_analyzer設定(analyzer設定の値をデフォルトとする)を指定できます。index_analyzer設定はanalyzerとなります。 複数のタイプで同じ名前のフィールドがある場合、フィールドはすべて、同じアナライザの設定を持たなければなりません。 タイプレベルのデフォルト設定のanalyzer、index_analyzer、search_analyzer設定は廃止されます。 デフォルトアナライザはインデックスごとにインデックスのanalysis設定で設定します。これらはdefaultもしくはdefault_searchという名前で設定します。 ドキュメントごとの_analyzerフィールドはサポートしません。既存のインデックスのものは無視されます。 index_nameとpath index_nameとpath設定は(Elasticsearch v1.0.0から利用できる)copy_toによって置き換わりました。 既存のインデックスについてはこれらは機能しますが、新しいインデックスでは指定できません。\n同期的なマッピングの更新 現在、これまで存在していないフィールドを含むドキュメントをインデキシングするとき、 フィールドはローカルのマッピングに追加され、それから、マスターに変更(新しいマッピングをすべてのシャードに適用する更新)が送信されていました。 同時に2つのシャードに同じフィールドを追加することができます。 また、そのとき、異なる2つのマッピングがある可能性があります。 1つはdoubleでもう1つはlongだったり、stringとdateだったりと。\nこのような場合、マスターに最初に届いたマッピングが採用されます。 しかし、「負けた」マッピングをもつシャードでは、すでに異なるデータのタイプを利用しているため、 これを利用し続けます。 そのご、ノードをリスタートしたときに、シャードが別のノードに移動し、マスターにあるマッピングを適用します。 このとき、インデックスが破損したりデータを失ったりします。\nこれを防ぐために、シャードはインデキシングを続ける前に、新しいマッピングがマスターによって採用されるかどうかを待つようになりました。 これはすべてのマッピングが安全に更新されます。 新しいフィールドをもっているドキュメントをインデキシングすると、前よりも処理が遅くなるでしょう。 受け入れられることを待つ必要があるためです。 しかし、クラスタの状態の更新処理のスピードが次の2つの新しい機能によって大きく改善されています。\nクラスタ状態の差分:可能であれば、クラスタの状態の変更はクラスタ状態全体の変更ではなく、部分的なものとする。 シャードへのリクエストの非同期化:シャードアロケーション処理中に、マスタノードは、 割り当てられていないシャードのコピーの日付が最新のものを持っているかを見つけるために、リクエストをデータノードに対して送信します。 ここで、クラスタ状態を変更する呼び出しがブロッキングで行われていました。v1.6.0から、このリクエストはバックグラウンドで非同期で実行されます。 これにより、マッピング更新のようなペンディングタスクをより早く処理できるようになります。 マッピングの削除 (そのタイプのドキュメントがある場合)タイプマッピングを削除できないようにします。 マッピングを削除した後に、削除されたフィールドの情報は、Luceneレベルでは存在し続け、 もし、後から同じ名前のフィールドが追加されたときにインデックスの破損を引き起こします。 そのようなマッピングは残しておくか、新しいインデックスに再インデックスすることができます。\n2.0のための準備 マッピングがコンフリクトしているかどうかを決めることは、手動で行うには慎重に行う必要があります。 私たちは、Elasticsearch Migration Pluginを提供します。 これは、2.0で非推奨になったり廃止された機能を利用しているかどうかを見つけるために役に立つでしょう。\nもし、コンフリクトしたマッピングを持っている場合、 正しいマッピングを持つ新しいインデックスにデータを再インデックスするか、 必要ないなら削除します。 これらのコンフリクトを解決しない限り2.0にはアップグレードできないでしょう。\n","date":1436346691,"dir":"post/2015/","id":"ee4ff9e4e8a1948795e26af2f3f8a30f","lang":"ja","lastmod":1436346691,"permalink":"https://blog.johtani.info/blog/2015/07/08/great-mapping-refactoring-ja/","publishdate":"2015-07-08T18:11:31+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:The Great Mapping Refactoring Elasticsearchのユーザの悩みの最も大きなものの一つは、 タイプと","tags":["elasticsearch"],"title":"Mappingのすばらしいリファクタリング(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 2.0.0.beta1 coming soon!\nElasticsearch 2.0.0.beta1のリリースの準備をしています。 これは、Lucene 5.2.1に含まれる多くの改善が利用できるようになります。 このリリースに関するいくつかの機能は次のようなものです。\nPipeline Aggregations 差分や移動平均、他のAggregationsの結果に対する series arithmeticのようなaggregationが利用可能になります。 この機能は、これまでは、クライアントサイドで実行する必要がありました。 しかし、この計算をより強力な解析クエリを構築してElasticsearchで 実行することができるようになります。 クライアントのコードをより簡潔にすることができます。 これにより、予測解析や異常検知のようなことができるようになります。\nQuery/Filter merging Filterはなくなります。全てのフィルタは、クエリになります。 クエリコンテキストで利用されると、効率的に関連度スコアを計算し、 フィルタコンテキストで利用されると、単に、 マッチしていないドキュメントを除外する(今のフィルタのようなもの)だけです この変更は、クエリ実行が自動的に、より効率的な順番で実行されるように 最適化されることを意味します。 例えば、フレーズやgeoクエリのような遅いクエリは まず、近似フェーズを実行し、それから、より遅い実際のフェーズが 結果に対して行われます。 フィルタコンテキストにおいて、頻繁に利用される条件は自動的にキャッシュされます。\nConfigurable store compression index.codec設定により、高速化のためのLZ4圧縮(default)か インデックスサイズを小さくするためのDEFLATE(best_compression)を 選択できます。これは、ロギングでとくに役に立ちます。 これにより、古いインデックスオプティマイズする前にbest_compressionに 変更できます。\nこれらに関するブログ記事がすぐに公開されるでしょう。\nPerformance and resilience 以降では、新しいメジャーリリースに関して簡単に紹介します。 2.0の変更の多くは内部の機能に関するものであり、 直接ユーザに関連するわけではないからです。\n新しいメジャーバージョンのテーマは、パフォーマンス、安定性、 堅牢性、予測可能性、そして使い勝手の良さです。\n物事が予測した通りに動作する 何か問題があった場合に、Elasticsearchから役立つフィードバックがある ローレベルの設定を扱う必要はなく、Elasticsearchが良い設定を決定する これらに加え、データがより安全に これらの目標は完全ではありません。 まだ、多くの改善があります。しかし、2.xブランチで、 すでに500コミットを超える大きな改善が実施されています。\non-diskの doc valuesをデフォルトで利用(これまではfielddata)。 ヒープ使用量を減らして、スケーラビリティを向上 セグメントマージ処理中のメモリ使用量の削減 normsの圧縮率の改善。ヒープスペースを利用している大きな処理のひとつだったため。 全てのリクエストの後に、transaction logをfsyncすることで、デフォルトで耐久性を向上 全てのファイル変更をアトミックに(部分的なファイルの書き出しはなし) マージを自動で制限 フレーズクエリやスパンクエリを高速化 フィルタキャッシュをより効率化するための圧縮されたビットセット クラスタ状態の差分更新 構造化されたJSON形式の例外 よりきめ細かいLuceneのメモリレポート デフォルトではlocalhostにのみバインド。開発のノードが他のクラスタにジョインするのを防ぐ parent/childのクエリ実行最適化のためにリライト Java Security Managerで必要最小限なパーミッションで実行 全てのコアなプラグインをelasticsearchリポジトリに移行し、Elasticsearchのバージョンに同期してリリースされる予定 アップグレード前に メジャーバージョンのアップグレードは問題のあるものを一掃する機会を与えてくれます。 できる限り、これらの変更をアップグレードするために、簡単な方法を提供しようとしています。 しかし、Elasticsearch 2.0にアップグレードする前に、必要な処理が2つあります。\n1つ目は、フィールドとタイプマッピングに関することです。 mapping APIは、現在、それほど厳密ではありません。 内蔵された保護機構を提供する代わりに、ユーザがベストプラクティスを知っていると信頼していました。 2.0では、mappingはより厳密で安全ですが、いくつかの変更では、後方互換性を保っていません。 詳細についてはThe Great Mapping Recatoringをごらんください。\n2つ目はElasticsearch 0.20以前のユーザに関する変更です。 これは、Lucene 3.xを使っています。 Elasticsearch 2.xはLucene 5をベースにしています。 Lucene 5はLucene 4.xによって作成されたインデックスの読み込みはサポートしていますが、 Lucene 3.xに関してはサポートしていません。\nElasticsearch 0.20以前のバージョンによって生成されたインデックスを持っている場合、 Elasticsearch 2.xのクラスタをスタートすることはできません。 これらの古いインデックスを削除するか、Elaticsearch 1.6.0以上に含まれている upgrade APIを使用してアップグレードする必要があります。\nupgrade APIの実行は2つのジョブを実行します。\n古いLuceneフォーマットのセグメントを最新のフォーマットで書き換えます Elasticsearch 2.xによって読み込めるようという印をインデックスに追加します 全てのセグメントを最新バージョンにアップグレードするのも良い案ですが、 アップグレード前に必要な処理を最小限に抑えることも可能です。 (Lucene 3.xのセグメントだけをアップグレード) その場合は、only_ancient_segmentsパラメータを指定します。\nElasticsearch Migration Plugin Elasticsearch 2.0 に移行する前に、インデックスがアップグレードが必要なのか、 ほかになにかするべきことがあるのかをチェックする助けになる Elasticsearch Migration Pluginをリリースしました。\nまず、プラグインをインストールします\n./bin/plugin -i elastic/elasticsearch-migration プラグインのインストール後はノードのリスタートは必要ありません。\n以下のリンクをブラウザで開きます。\nhttp://localhost:9200/_plugin/migration\n(localhost:9200はインストールしたホスト名に変更してください。)\nMigration pluginに関してバグやご意見がある場合は、GitHubのIssueにお願いします。\n","date":1436250300,"dir":"post/2015/","id":"f887e1aabf801e351bfb39698f208af1","lang":"ja","lastmod":1436250300,"permalink":"https://blog.johtani.info/blog/2015/07/07/elasticsearch-2-dot-0-0-dot-beta1-coming-soon-ja/","publishdate":"2015-07-07T15:25:00+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 2.0.0.beta1 coming soon! Elasticsearch 2.0.0.beta1のリリースの準備をしています。","tags":["elasticsearch"],"title":"Elasticsearch 2.0.0.beta1リリース間近(日本語訳)"},{"contents":"4ヶ月前に、Found joined our team at Elasticをアナウンスしました。 Foundの素晴らしいチームと一緒に仕事をしていますが、彼らによって、より素晴らしい hosted Elasticsearchを提供することになりました。\n私たちがともに密接に働くことにより、本日(2015/7/1)、 新しい2つのFoundを提供することになりました。 Found StandardはこれまでのFoundの機能に加え、さらに低価格を提供します。 Found Premiumは、SLAサポートと、ShieldやWatcherを将来Found上で提供します。\nFound Standard Foundは素晴らしいです。専用のElasticsearchクラスタ、簡単なスケール、 ビルトインのセキュリティそして、時間単位での課金などを持っています。 私たちは、hosted Elasticsearchを探している方に、 Foundが適したソリューションであると思っていますし、 すべての方に利用できて手頃な価格であるということを確信したいと思っています。\n本日(2015/07/01)からFoundの価格をかなり低価格にし、 月額50ドル以下でhosted Elasticsearchを簡単に試してもらえるようにしました。\n価格を下げることは正しい重要なステップですが、 Foundを利用している全ての人に、より良い経験を持っていただきたいと考えています。 低価格化と一緒に、free backupsとbuilt in SSDもFoundで提供を始めることになります。\nFoundの重要な特徴の一つが、高可用性のために、クラスタをいくつのデータセンターに持つかを 選択できることです。 データは重要です。これが正しい選択でユーザの助けになると考えています。 これにより、私たちの価格は、複数のデータセンターにより安価に配置することができます。\nまた、KibanaもElasticsearchのデータを可視化する素晴らしい方法だと考えています。 Kibana 4が最新バージョンですが、 これは、サーバサイドコンポーネントを持っています。 これは、サービスとしてこれを提供するために、追加の料金がかかることを意味します。 Foundチームが築いた素晴らしい基盤とKibanaチームの努力により、 hosted Elasticsearchクラスタで無料のKibana 4を7月15日より提供することになりました。\nFound Premium また、私たちは、オープンソースプロダクトに関してサブスクリプションを提供していますが、 Found Standardに対しても提供することになりました。 これが、Found Premiumです。\nフォーラムベースのサポートよりもSLAベースのサポートを望んでいる場合、 プロダクトを開発しているチームからのサポートを受けることができるオプションを 提供し始めました。 クリティカルなイベントを持っていたり、私たちのプロダクトに関する 問題を予測するためのベストなヘルプやガイダンス、アドバイスを探しているような場合にサポートします。\nさらに近い将来、サブスクリプションの一部として、Shield(Elasticasearchのセキュリティプラグイン)やWatcher(アラーティングプラグイン)が利用できるようになります。\n私たちのチームがともに働き、多くのことを可能にし、すばらしい仕事をユーザに提供したかを 将来も楽しみです。 私は非常に誇りに思っていますし、気に入っていただけたらと思っています。 ぜひ、7/15のWebnarに参加してくわしい話を聞いていただき、疑問を解消してください。\n","date":1436250000,"dir":"post/2015/","id":"9cc2a0b6c8be1405cddcdeb4487c59fe","lang":"ja","lastmod":1436250000,"permalink":"https://blog.johtani.info/blog/2015/07/07/we-just-made-found-more-awesome-ja/","publishdate":"2015-07-07T15:20:00+09:00","summary":"4ヶ月前に、Found joined our team at Elasticをアナウンスしました。 Foundの素晴らしいチームと一緒に仕事をしていますが、彼らによって、より","tags":["elasticsearch","found.no"],"title":"さらに進化したFound(日本語訳)"},{"contents":"JustTechTalk#02 形態素解析のあれやこれや@ジャストシステム\nに参加してきました。 ジャストシステムさんの形態素解析器JMATの話とKagome、Janome、Kuromoji.js、ssslaの開発者の パネルディスカッションでした。\nということで、いつものメモです。\nジャストシステムの形態素解析その2(機械学習編) JMATの話\n前回は辞書の話 今回は学習の話 教師あり/教師なし\nJMATは教師あり 教師なしは研究段階 ラティス構造を辞書ベースで構築して、コストの総和が最小の経路を求める\n連接、単語生成とか。 学習は3フェーズ\nベース、能動、部分アノテーション ベース 300万文のコーパスから1万文のみを利用(なぜ?今から説明) 64GBマシン買ってみたけど、複数実験するには追いつかない オンライン学習がメジャーでない時代に作り始めたので、つかってない CRF学習器を改善 結果として50万文くらいで精度が良くなる 辞書チームからNGがでて、方向転換 方向転換した結果が3つのフェーズらしい ピタジョブに採用? 疑問 \u0008* JMATって、Webの検索の前処理とか分類とかに主に利用するのかな?\nATOKでもこのノウハウって利用してるんかな? 辞書もあるらしいけど、辞書更新されると学習器のデータとかどーなるんだろ? 形態素解析器の実装言語Talkについて kuromoji.jsの@takuya_aさん\nTyped Arrayサポートが高速にできてる理由でもあるらしい Kagomeの@ikawahaさん\nGoはいろいろないらしい Janomeの@moco_betaさん\nsssla(茶筌のRuby clone)\nなんで作ったの?\n形態素解析のライブラリ「解析部分」はNLPのHelloWorldだから なんで、その言語?\nPython 3系は文字列とバイト配列の扱いがすごく楽! その言語で困った点は?\nGoだと、辞書を内包するのが大変 JSは苦労したところしかない(1hくらいしゃべれるぞ!)。基本的なデータ構造とかもない Pythonはパフォーマンスを考えないと Ruby(1.6だったので)もパフォーマンスが その言語を開発するときに必須のものは?\nGoはとくにない。エディタはどれでもOK browserifyが便利 \u0008* ほかの人たちの言語をdisってください * JSは論外。Pythonのコードフォーマッターが揺れるのが。。。Rubyはバージョンが。。。 * Goはブラウザで動かない。Pythonもブラウザで動かない。Rubyも(ry * ほかのは触ったことないので。。。 * Pythonは2.xか3.xか決めてくれ!\nなんで、Kuromojiベースなの? Java読みやすいから。 MeCabとKuromojiの違いは? 未知語の処理が結構違う 感想 きれいなロビーで良かったのですが、マイクがあると嬉しかったかもしれません。 前回の辞書の話も聞いてみたかったかも。\n","date":1436147341,"dir":"post/2015/","id":"18b7998a871950ebc36c415a53630477","lang":"ja","lastmod":1436147341,"permalink":"https://blog.johtani.info/blog/2015/07/06/attend-justsystem-techtalk-no2/","publishdate":"2015-07-06T10:49:01+09:00","summary":"JustTechTalk#02 形態素解析のあれやこれや@ジャストシステム に参加してきました。 ジャストシステムさんの形態素解析器JMATの話とKagome、Janome、","tags":["勉強会"],"title":"JustTechTalk#02 形態素解析のあれやこれや@ジャストシステムに参加しました。"},{"contents":"ひさびさに、勉強会メモ。 Hatena Engineer Seminar #5 @ Tokyoに当選したので行ってきました。\nいつもは近寄らないオシャレな街をドキドキしながら行ってきました。\nということで、簡単なメモです。\nはてなブックマーク全文検索の精度改善 id:takuya-a 問題:検索精度がよくない 京都で検索 → 「ポーランドの京都」「京都大学のまるまる教授」のようなもんがヒット 京都っぽいエントリが出て欲しい。 京都っぽい??? 問題点をブレイクダウン 課題 クエリ考えるの大変だよね 順序が新着順なのが辛い 適合率と再現率の両立 そして(ドラムロール)、できました!(さすが)\nアイデア:はてブのタグを利用する。 関連キーワードを抽出して、クエリ拡張する。\n関連キーワードとは? タグ検索する 検索にヒットしたTerm Vectorsを取得 特徴語をTop25件取得 もっともスコアが高いタームを特徴語とする 英語のストップワードとかが問題点となってたり。 →Dynamic stop word listというのを利用して排除(IDF、RIDF、Gain) 今後の課題 再現率の向上 解析用のフィールド・辞書を追加(精度向上や解析ミスなど) トークに出てきた機能など トークに出てきたElasticsearchの機能については、こんなツイートをしてたので、参考にしてもらえれば。\nこれのkuromoji_stemmerを使ってるっぽい? #hatenatech / elastic/elasticsearch-analysis-kuromoji - https://t.co/3F2sBYXLPH\n\u0026mdash; Jun Ohtani (@johtani) 2015, 6月 16 #hatenatech Term Vectors APIのドキュメントはこちら - https://t.co/HhBmTDr46i\n\u0026mdash; Jun Ohtani (@johtani) 2015, 6月 16 #hatenatech min_score - https://t.co/Sc0exzJRC1\n\u0026mdash; Jun Ohtani (@johtani) 2015, 6月 16 個人的な疑問 Q:クエリにヒットするタグがそもそもなかったら?\nはてなブックマークに基づく関連記事レコメンドエンジンの開発 id:skozawa 課題:一部のエントリに対して関連記事が出ない タグがない記事について関連エントリが出ない=既存はタグを利用している 例:レシピで考える\n現行システム ユーザがつけたタグ情報を利用してMoreLikeThisで計算 新規システム 類似記事検索 特徴語の抽出 特徴語を分類 関連記事検索 関連記事をスコアリング 個人的な疑問 Q:毎回計算してるのかな?記事登録とかされたタイミングでやってるのかな? Q:Termの精度などどうなんだろ?\n『BrandSafe はてな』のアドベリフィケーションのしくみ id:tarao BrandSafeはてな:とか。 広告の配信先をフィルタリング\n複数の素朴なフィルタの組み合わせ→AdaBoost\n個人的な疑問 Q:海外とかもいけるのかな?\nまとめと感想 ということで、簡単なメモでした。ピザごちそうさまでした! 聞いてて少し思ったのは、データ量があるサイトだからうまくいく手法だというのもあるんだろうなというところでした。 あとは、クエリを暗に改善するのとは別に、サジェスト的に表示するのにも使えたりするかも?と思ってみたり。 できるかどうかはわからないですが。。。\nElasticsearchをいろいろと活用してもらってるのがわかって、楽しい勉強会でした。 もっともっといろんなところで宣伝してくださいw\n今日の勉強会を聞いて、俄然、京都・大阪でElasticsearch勉強会を開催したい気になってきました。 特に大阪に知り合いがいないので、だれか紹介してもらえると嬉しいです。 お待ちしてます。\n","date":1434468093,"dir":"post/2015/","id":"ddab6357ff522c0c956ebd7669e83454","lang":"ja","lastmod":1434468093,"permalink":"https://blog.johtani.info/blog/2015/06/17/attend-hatena-engineer-seminar-5/","publishdate":"2015-06-17T00:21:33+09:00","summary":"ひさびさに、勉強会メモ。 Hatena Engineer Seminar #5 @ Tokyoに当選したので行ってきました。 いつもは近寄らないオシャレな街をドキドキしながら行ってきました。 と","tags":["勉強会"],"title":"Hatena Engineer Seminar #5 @ Tokyoに参加しました。 #hatenatech"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 1.6.0 released\n本日(6/9)、Lucene 4.10.4ベースのElasticsearch 1.6.0をリリースしました。 このリリースはElasticsearchの最新の安定バージョンとなります。 また、素晴らしい新機能がいくつか追加されています。\nsynced flushによるリスタートの高速化 \u0008* シャード配置は保留中のタスクをブロックしない レスポンスボディのJSONのフィルタリング 共有ファイルシステムリポジトリに対するセキュリティフィックス 古いインデックスのためのUpgrade API Kibanaユーザのためのハイライトの強化 Windowsユーザのためのmlockall より詳細なスクリプト設定 すべての変更リストとダウンロードはこちらをごらんください。\nsynced flushによるリスタートの高速化 1.6.0より前のバージョンでは、メンテナンスやローリングアップグレード時の ノードの再起動で、必要であるかどうかに関わらず、多くの場合、 ノードのすべてのシャードのすべてのデータを再度コピーする必要がありました。 この新しいsynced flush機能により、 sync-flushされたインデックスに対して、既存のデータを再利用し、 より早くクラスタを正常な状態にすることができるようにします。\nここで、この変更以前にどのように動いていたかを説明します。 すでにあるレプリカシャードは、ノードがリスタートした後に、 プライマリから復元するときに、 最初のステップはプライマリにあるセグメントとレプリカにあるセグメントを 比較することです。そして、セグメントに違いがあった場合にコピーされます。 問題は、セグメントプライマリのセグメントのマージと レプリカのセグメントのマージが別々に起こっており、 各シャードのセグメントが完全に異なるが、 それらが同じデータを持っているという点です。\n新しいsynced-flush機能では、sync_idがプライマリと レプリカシャードに、シャードのコンテンツが同一であるという判別するために、 書き込まれます。これは、リカバリがセグメントの比較のステップを スキップできることを意味します。 リカバリのスピードを高速にします。\nsynced flushはアイドル状態のインデックスで自動的に実行されます。 直前の5分間でデータが登録、更新削除されていないインデックスに対してです。 これは、ロギングのユースケースで特に役に立ちます。 機能のインデックスはインデキシングがストップしたあとの5分で自動的に syncされるでしょう。\nノードのリスタートやクラスタのリスタートが必要で、 自動的に発生するsyncを待てない場合は次のようなことが可能です。\nインデキシングを停止(実行中のリクエストが停止するのも待つ) シャードのアロケーションを停止 synced-flushリクエストの発行 ノードのリスタート シャードのアロケーションの再開 クラスタの状態がグリーンになるまで待つ インデキシングの再開 NOTE: \u0026ldquo;シャードのアロケーションを停止\u0026quot;のステップが必要です。 これがない場合、Elasticsearchはノードの再起動が始まると、 異なるノードにシャードの再配置を始めます。 これは、新しいノードにシャードデータの全てをコピーする必要があります。\nドキュメントのインデキシング、更新、削除のあとに最初のフラッシュが 発生したときに、 シャードのsync_idが自動的に無効化されます。 詳細については#11336と#11179をごらんください。\nシャード配置は保留中のタスクをブロックしない 多数のノードやインデックスを持っているユーザは クラスタ全体のリスタートのあとのシャードのリカバリで、 長い間、リカバリが止まって見えることに気づいたかもしれません。 これらのリカバリが止まって見える間は、クラスタ設定の更新のような軽微なアクションでさえ、 例外が発生したり、その設定が反映されるまでに長時間かかるといったことが起きていました。 この問題の兆候は保留中のタスクのキューが大きくなることです。\nこれらの遅延の原因はシャードの配置のプロセスにあります。 配置されるべきシャードのコピーを 持っているのがどのノードかを全てのデータノードに聞きます。 多くのシャードや遅いディスクを持ったデータノードは 反応するのに時間がかかります。 特に、シャードのリカバリがすでにI/Oを利用しているような時です。 このバージョン以前のものは、シャード情報のためのリクエストを 同期的に処理していました。 クラスタ状態の更新はアロケーションプロセスを続けるために 必要な情報を待っている間、ブロックされます。\n#11262での変更は この情報のためのリクエストを非同期にします。 クラスタ状態の更新はこのタスクによってブロックされません。 これは、保留中のタスクがより早く処理でき、 クラスタが変更に対してより早く反応できます。 処理中のshard infoリクエストの数は number_of_in_flight_fetchキーとしてcluster-health APIで取得できます。\nさらに、シャードがある理由で復旧に失敗すると、 クラスタは、シャードのリカバリが成功するまで、同じノードに対して シャードをアロケーションしないようにします。\nレスポンスボディのJSONのフィルタリング Elasticsearchは全ての情報を返します。 例えば、検索リクエストは_index、_type、_id、 _score、_sourceを返します。 しかし、全ての情報が必要でない場合があります。 また、これらのデータを遅いネットワークで転送することは 遅延の原因となります。\nユーザはこの検索メタデータを無効にするための特殊な設定を 行ったり、他のAPIのレスポンスのフォーマットを コントロールするための設定があります。 #10980の変更で、任意のレスポンスボディのJSONに対して、 必要な要素だけを取得する機能が追加されました。 filter_pathパラメータを使用します。\n例えば、検索リクエストからはtotal数と、各要素のhitsの配列を欲しい場合、 次のように指定します。\nGET _search?filter_path=hits.total,hits.hits nodes-info APIから各ノードのhttp_addressだけを取得したい場合は、 ノード名の部分にワイルドカード(*)を使用します。\nGET _nodes?filter_path=nodes.*.http_address 単一の*がJSON階層の1つの階層に対しての ワイルドカードとして機能します。 2つの**は複数階層に対してとなります。 複数のフィルタはカンマ区切りで指定可能です。 詳細についてResponse filteringをごらんください。\n共有ファイルシステムリポジトリに対するセキュリティフィックス 本リリースはsnapshot-restoreで使われる 共有ファイルシステムリポジトリに関するセキュリティ強化の変更が含まれます。 現在、Elasticsearchのユーザは、Elasticsearchプロセスによって書き込み可能 任意のディレクトリに.snapshotファイルを書き込むことができます。 #11284の変更で、リポジトリのために使用できるディレクトリを 強制的に指定できるようになりました。 適切なディレクトリがconfig/elasticsearch.yml設定ファイルの path.repoに指定される必要があります。\n次のように設定されたElasticsearchインスタンスはこのセキュリティ問題に対して影響を受けにくいです。\nrootではなくelasticsearchユーザとしてElasticsearchを実行 elasticsearchユーザがdataディレクトリに対してのみ 書き込み権限を持っていて、共有ファイルシステムリポジトリに対しても利用できる ファイアウォールやプロキシ、Shieldを使って、snapshot APIの実行を任意のユーザから実行されるのを防いでいる この問題をCVE-2015-4165としています。\n古いインデックスのためのUpgrade API Elasticsearch 2.0以降では、 Lucene 5ベースとなり、Lucene 3 (Elasticsearchのバージョンでは0.90以前) によって書き出されたセグメントを含んだインデックスを読み込むことが できなくなります。 これらの「古いインデックス」はLucene 4にアップグレードする必要があり、 2.0-compatibleとして印をつける必要があります。 そうしなければ、Elasticsearch 2.0に以降できないでしょう。\nupgrade APIは 、最新のLuceneフォーマットにインデックスにある全てのセグメントを アップグレードするためにすでに利用できます。 また、最新のフォーマットは性能向上やバグフィックスといった利点もあります。 さらに、2.0-compatibleとして古いインデックスをマークする設定も 書き込むことができます。 さらに、upgrade_only_ancient_segmentsオプションが Lucene 3のセグメントだけをアップグレードするために利用でき、 移行前の必要な処理を減らすことができます。\nKibanaユーザのためのハイライトの強化 KibanaユーザはElasticsearchのハイライトについて2つの点で問題を見つけていました。\nワイルドカードでフィールド名を指定した場合に、ハイライトに適さないフィールドも帰ってくる(日付や数値のフィールドなど) 古いインデックスが非常に大きなターム(\u0026gt; 32kB)を含んでいて、ハイライトが失敗する。 最近のバージョンでは、これらの大きなタームはインデックス時に除去される #11364の変更で これらの問題が修正されました。 ワイルドカードを利用したフィールド名では、stringフィールドのみを返し、非常に長いタームによる例外は無視するようになります。\nWindowsユーザのためのmlockall 速いGCはノードの安定性と性能について重要です。 小さなバイトのヒープでさえ、ディスクにスワップすることを許可してしまうと、GCに対して大きな影響が出てしまいます。 ですので、これらのコストは排除されるべきです。\nLinuxユーザはbootstrap.mloclall設定による恩恵を受けています。 これは、RAMにJVMのヒープを起動時にロックします。 #10887では、同様の機能をWindowsユーザにも提供します。\nより詳細なスクリプト設定 Scriptsはリクエストにインラインで指定できます。 .scriptsインデックスにインデックスもでき、config/ディレクトリ配下にファイルとして保存もできます。 これまでは、インラインかインデックスされたスクリプトの両方を同時に有効無効にすることが選択できましたが、 .scriptsインデックスをプロキシやShieldで保護することもできました。\n#10116で追加されたより詳細なスクリプトの設定で、インラインか、インデックスされたものか、ファイル化を個別に言語ごとに設定できるようになりました。 また、例えば、search APIではスクリプトを許可するが、update APIでは許可しないといったような設定も可能です。\n最後に ぜひ、Elasticsearch 1.6.0を試してみてください。 そして、感想をTwitter(@elastic)やWebフォーラムなどで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1433910662,"dir":"post/2015/","id":"55188a318c5998989255253e15ccc1f6","lang":"ja","lastmod":1433910662,"permalink":"https://blog.johtani.info/blog/2015/06/10/elasticsearch-1-6-0-released-ja/","publishdate":"2015-06-10T13:31:02+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 1.6.0 released 本日(6/9)、Lucene 4.10.4ベースのElas","tags":["elasticsearch"],"title":"Elasticsearch 1.6.0リリース(日本語訳)"},{"contents":"第10回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 次回もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\n今回も新規の方が結構いたような気がしました。 最終的に、124人がアプリでチェックインした形になりました。 直前にキャンセル待ちから繰り上がると来れない人がいますよねぇ。 多少キャパシティオーバーするくらいの人数で募集するのがいいのでしょうか。 あと、カードが2枚不明で。。。心あたりある人いないでしょうか?\nさて、いつもの通り簡単なメモです。\nElastic{ON}報告+有償プラグインの紹介 Elastic Jun Ohtani @johtani スライド:elastic{ON}報告と商用プラグインの紹介\n少し時間が経ってしまいましたが、弊社初のカンファレンスelastic{ON}の紹介をしました。 約1300名の方に参加していただいたカンファレンスで、非常に盛り上がりました。 Microsoft、GitHubなど、いろいろな会社の方が話をしたり、弊社のエンジニアが濃い話をしたりと。 今回は、日本の方はいなかったですが、次回は日本からも参加してもらえると嬉しいです!\nあとは、5月に弊社にも日本の営業の人が入社したので、有償プラグインについて簡単ですが説明をしました。 プラグインなどに興味があるかたがいらっしゃいましたら、Twitterなどで連絡いただければと。 もちろん、弊社サイトからの問い合わせでも大丈夫です。\nカンファレンスの資料やビデオが弊社サイトで公開されています。 ぜひ一度見ていただければと。\nAWSで実現するelasticsearchの大規模運用 株式会社インティメート・マージャー 松田和樹さん @mats116 スライド:第10回elasticsearch勉強会 公開用資料\nパブリックDMPのサービスの裏側でElasticsearchを利用しているというお話でした。 AWS Auto Scalingに詳しくないので、勉強しないといけないんですが、 リバランスがどのくらいの頻度で発生するのかはちょっと気になります。\nSSDを利用したり、doc valuesを利用したりと、性能を気にしながら利用されている点、負荷試験を行って検証されていたりと、 参考になる話でした。 今回はインフラ側の話に寄っていたので、今度はアプリ側でどんな使い方をしているかといった話を聞いてみたいですね!\nSpark in small or middle scale data processing with Elasticsearch 株式会社ビズリーチ 島本 多可子さん @chibochibo03 スライド:Spark in small or middle scale data processing with Elasticsearch\nScalaとSparkとElasticsearchで検索サービスを作っている話でした。 サービスのアーキテクチャの選別についての説明を順を追って説明していただきました。 失敗と言われていたアーキテクチャを見た時に、「あー、それは。。。」と思っていたら、 思った通りの改善案のアーキテクチャが出てきたので少しホッとしましたw\nJSONのクエリが辛いという話がありましたが、validate APIなどを利用してもらって、事前にチェックをしてもらうと 少しは改善できるかもなぁと。\nSparkをぼんやりとしかわかってないので、もう一度話を聴きたいなぁと思ったので、 押しかけて話を聴きたいと思います。\n話の中で出てきた自作のScalaのElasticsearchクライアントがHTTPのクライアントになった理由が知りたかったです。\nLT Elasticsearchのサジェスト機能を使った話 株式会社アイスタイル 渡邊 紘太朗さん @ktaro_w スライド:Elasticsearchのサジェスト機能を使った話\nぴったり5分でしたwまだ2年目なのにこんなにうまく話をしていただけるとは。。。\nGatling便利そうですね。サーバが1台しかないので、単一インデックスの方が性能が出るだろうなと。 Elasticsearchは1インデックスに対してデフォルトだと5シャードで、シャード単位でLuceneのインデックスが作成されます。 この話で行くと、18インデックスを作ると、かなりの数のファイルI/Oが発生するので、いろいろなインデックスに検索をすると キツいだろうなと。\nサジェストについての日本語の資料が少ないという事だったので、ブログを書いてもらえると嬉しいですw\nElasticsearchで作る形態素解析サーバ 株式会社エヌツーエスエム 菅谷信介さん スライド:Elasticsearchで作る形態素解析サーバ\nいつも発表ありがとうございます。私以外の最多発表者じゃないかという話でした。 今回はElasticsearchを形態素解析サーバにしてしまおうという話で、ちょっと面白い話でした。 Elasticsearch以外の場所で形態素解析したい場合には手軽に使えるかもしれないですし、Elasticsearchと同じ解析結果を別の場所で欲しい場合にも便利かも。\nextended analyze APIの紹介までしていただいて。。。\nちなみに、今は、extended analyze プラグインも指定したAttributeの情報だけ返せるようになってたり、 マルチバリューへの対応もしていたりします。 そのうち本家のanalyze APIに機能を取り込む予定です。(早くしないと)\n開発効率UP! Elasticsearch Client Tool 作ってみた ナレッジワークス株式会社 木戸国彦さん @9215 スライド:開発効率アップ!Elasticsearch Client Tool 作ってみた\nHello Elasticsearch!にはお世話になっている人が多いんじゃないかなと。 今回はSublime Textのプラグインのお話でした。(すみません、Sublime Text使ってなくて。。。) AtomとかIntellijのプラグインもあるとうれしいなー\n変わり種プラグインの作り方 日本IBM 黒澤亮二さん スライド:変わり種プラグインの作り方\nElasticsearchの拡張ポイントの話と、簡単なプラグインの作り方と少しElasticsearch内部の話をしていただきました。 Foundの資料が上がってました。さすが。あそこのブログは面白い話が多いんですよね。 社内で実際に使われてる話とかも聞いてみたい!\nその他、感想などのブログ 第10回 Elasticsearch 勉強会へ参加してきた昨日の話 第10回elasticsearch勉強会 #elasticsearch #elasticsearchjp 第10回elasticsearch勉強会に行ってきました elasticsearch勉強会に登壇してきました まとめ 懇親会で24Fに移動していただくということで、少し手間をかけてしまいました、すみませんでした。 今回も初参加の方がそこそこいたんじゃないかなと。 あとは、AWSサミットがあるために上京してて参加しましたという方もいらっしゃいました。 大きなカンファレンスの期間の前後に行うとこんなメリットもあるんですね、今後の参考にしたいと思います。 次回は7/27を予定しています。CTOのShayが来日予定です!\nあと、東京以外の勉強会も検討しつつあります。興味のある方はコメントやTwitterで反応をいただけると嬉しいです。\nスピーカーは随時募集中ですので、コメント、メール、ツイートなど、コンタクトしていただければと思います。 よろしくお願いいたします。\n","date":1433225196,"dir":"post/2015/","id":"75d9268739fe7787ac02d389ac605feb","lang":"ja","lastmod":1433225196,"permalink":"https://blog.johtani.info/blog/2015/06/02/10th-elasticsearch-jp/","publishdate":"2015-06-02T15:06:36+09:00","summary":"第10回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさ","tags":["elasticsearch","勉強会"],"title":"第10回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Reindex Elasticsearch With Logstash\nThanks David!\nマッピングを変更したり、インデックスの設定を変更したり、あるサーバから他のサーバや、 あるクラスタから他のクラスタ(例えば複数のデータセンターのような場合)にデータを再インデックスしたくなることがあるでしょう。\n後者のような場合はSnapshotやRestoreの機能を利用することもできますが、インデックスの設定を変更をしたい場合は その他の方法が必要になります。\nLogstash 1.5.0で、 elasticsearch inputとelasticsearch outputを使うことで、とても簡単に再インデックスができます。\nではやってみましょう。\n古いクラスタ elasticsearch 1.5.2 はすでにダウンロード済みとして、localhost:9200でoldという名前のクラスタを起動します。\nbin/elasticsearch --cluster.name=old クラスタにpersonという名前のインデックスが存在します。 これは、5シャードで、100万件のドキュメントを持っています。\n新しいクラスタ 次に新しいクラスタを起動します。 localhost:9201でnewという名前のクラスタを起動します。\nbin/elasticsearch --cluster.name=new こちらは、空です。\ncurl -XGET \u0026#34;http://localhost:9201/person\u0026#34; { \u0026#34;error\u0026#34;: \u0026#34;IndexMissingException[[person] missing]\u0026#34;, \u0026#34;status\u0026#34;: 404 } Logstashのインストール 次に、Logstash 1.5.0をダウンロードして、インストールします。\nwget http://download.elastic.co/logstash/logstash/logstash-1.5.0.tar.gz tar xzf logstash-1.5.0.tar.gz cd logstash-1.5.0 logstashの設定ファイルlogstash.confを次のように設定します。\ninput { # We read from the \u0026#34;old\u0026#34; cluster elasticsearch { hosts =\u0026gt; [ \u0026#34;localhost\u0026#34; ] port =\u0026gt; \u0026#34;9200\u0026#34; index =\u0026gt; \u0026#34;person\u0026#34; size =\u0026gt; 500 scroll =\u0026gt; \u0026#34;5m\u0026#34; docinfo =\u0026gt; true } } output { # We write to the \u0026#34;new\u0026#34; cluster elasticsearch { host =\u0026gt; \u0026#34;localhost\u0026#34; port =\u0026gt; \u0026#34;9201\u0026#34; protocol =\u0026gt; \u0026#34;http\u0026#34; index =\u0026gt; \u0026#34;%{[@metadata][_index]}\u0026#34; index_type =\u0026gt; \u0026#34;%{[@metadata][_type]}\u0026#34; document_id =\u0026gt; \u0026#34;%{[@metadata][_id]}\u0026#34; } # We print dots to see it in action stdout { codec =\u0026gt; \u0026#34;dots\u0026#34; } } 実行と修正 実行します。\nbin/logstash -f logstash.conf ドキュメントのチェックと修正 何が起きたでしょう?\ncurl -XGET \u0026#34;http://localhost:9200/person/person/AU1wqyQWZJKU8OibfxgH\u0026#34; { \u0026#34;_index\u0026#34;: \u0026#34;person\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;person\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;AU1wqyQWZJKU8OibfxgH\u0026#34;, \u0026#34;_version\u0026#34;: 1, \u0026#34;found\u0026#34;: true, \u0026#34;_source\u0026#34;: { \u0026#34;name\u0026#34;: \u0026#34;Tali Elyne\u0026#34;, \u0026#34;dateOfBirth\u0026#34;: \u0026#34;1955-05-03\u0026#34;, \u0026#34;gender\u0026#34;: \u0026#34;female\u0026#34;, \u0026#34;children\u0026#34;: 2, \u0026#34;marketing\u0026#34;: { \u0026#34;cars\u0026#34;: null, \u0026#34;shoes\u0026#34;: null, \u0026#34;toys\u0026#34;: null, \u0026#34;fashion\u0026#34;: null, \u0026#34;music\u0026#34;: null, \u0026#34;garden\u0026#34;: null, \u0026#34;electronic\u0026#34;: null, \u0026#34;hifi\u0026#34;: null, \u0026#34;food\u0026#34;: 846 }, \u0026#34;address\u0026#34;: { \u0026#34;country\u0026#34;: \u0026#34;Germany\u0026#34;, \u0026#34;zipcode\u0026#34;: \u0026#34;0099\u0026#34;, \u0026#34;city\u0026#34;: \u0026#34;Bonn\u0026#34;, \u0026#34;countrycode\u0026#34;: \u0026#34;DE\u0026#34;, \u0026#34;location\u0026#34;: [ 7.075943707068682, 50.72883500730124 ] } } } もう一方のクラスタと比較してみましょう。\ncurl -XGET \u0026#34;http://localhost:9201/person/person/AU1wqyQWZJKU8OibfxgH\u0026#34; { \u0026#34;_index\u0026#34;: \u0026#34;person\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;person\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;AU1wqyQWZJKU8OibfxgH\u0026#34;, \u0026#34;_version\u0026#34;: 1, \u0026#34;found\u0026#34;: true, \u0026#34;_source\u0026#34;: { \u0026#34;name\u0026#34;: \u0026#34;Tali Elyne\u0026#34;, \u0026#34;dateOfBirth\u0026#34;: \u0026#34;1955-05-03\u0026#34;, \u0026#34;gender\u0026#34;: \u0026#34;female\u0026#34;, \u0026#34;children\u0026#34;: 2, \u0026#34;marketing\u0026#34;: { \u0026#34;cars\u0026#34;: null, \u0026#34;shoes\u0026#34;: null, \u0026#34;toys\u0026#34;: null, \u0026#34;fashion\u0026#34;: null, \u0026#34;music\u0026#34;: null, \u0026#34;garden\u0026#34;: null, \u0026#34;electronic\u0026#34;: null, \u0026#34;hifi\u0026#34;: null, \u0026#34;food\u0026#34;: 846 }, \u0026#34;address\u0026#34;: { \u0026#34;country\u0026#34;: \u0026#34;Germany\u0026#34;, \u0026#34;zipcode\u0026#34;: \u0026#34;0099\u0026#34;, \u0026#34;city\u0026#34;: \u0026#34;Bonn\u0026#34;, \u0026#34;countrycode\u0026#34;: \u0026#34;DE\u0026#34;, \u0026#34;location\u0026#34;: [ 7.075943707068682, 50.72883500730124 ] }, \u0026#34;@version\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;@timestamp\u0026#34;: \u0026#34;2015-05-20T09:53:44.089Z\u0026#34; } } Logstashは@versionと@timestampフィールドを追加してしました。 これらを除去したいので、Mutate filter pluginのremove_fieldを使います。\nfilter { mutate { remove_field =\u0026gt; [ \u0026#34;@timestamp\u0026#34;, \u0026#34;@version\u0026#34; ] } } マッピングのチェックと修正 実際に、logstashは_sourceフィールドを既存のドキュメントから読み込み、 それらを新しいクラスタに直接投入しています。 しかし、logstashはマッピングについてはケアしていません。\n古いマッピングと新しいマッピングを比較するために、マッピングを取得してみましょう。\ncurl -XGET \u0026#34;http://localhost:9200/person/person/_mapping\u0026#34; { \u0026#34;person\u0026#34;: { \u0026#34;mappings\u0026#34;: { \u0026#34;person\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;address\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;city\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;country\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;countrycode\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;location\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;geo_point\u0026#34; }, \u0026#34;zipcode\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, \u0026#34;children\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;dateOfBirth\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;date\u0026#34;, \u0026#34;format\u0026#34;: \u0026#34;dateOptionalTime\u0026#34; }, \u0026#34;gender\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;marketing\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;cars\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;electronic\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;fashion\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;food\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;garden\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;hifi\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;music\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;shoes\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;toys\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; } } }, \u0026#34;name\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } } } } } curl -XGET \u0026#34;http://localhost:9201/person/person/_mapping\u0026#34; { \u0026#34;person\u0026#34;: { \u0026#34;mappings\u0026#34;: { \u0026#34;person\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;address\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;city\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;country\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;countrycode\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;location\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;double\u0026#34; }, \u0026#34;zipcode\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, \u0026#34;children\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;dateOfBirth\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;date\u0026#34;, \u0026#34;format\u0026#34;: \u0026#34;dateOptionalTime\u0026#34; }, \u0026#34;gender\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;marketing\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;cars\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;electronic\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;fashion\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;food\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;garden\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;hifi\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;music\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;shoes\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;toys\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; } } }, \u0026#34;name\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } } } } } これにより、いくつかの相違を発見できます。\n\u0026#34;location\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;geo_point\u0026#34; } \u0026#34;location\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;double\u0026#34; } データをインデックスする「前」に、実際に利用したいマッピングでインデックスを作成しておくことで、 この問題に対処できます。 この時点で、オリジナルのマッピングを望んだ形に変更することができます。例えば、アナライザを変更したりです。 また、インデックスの設定を新しく定義することもできます。 デフォルトでは、Elasticsearchは5つのシャードと各シャードに対して1つのレプリカを作成します。 しかし、この時点でもう一度変更することが可能です。\ncurl -XDELETE \u0026#34;http://localhost:9201/person\u0026#34; curl -XPUT \u0026#34;http://localhost:9201/person\u0026#34; -d\u0026#39; { \u0026#34;settings\u0026#34;: { \u0026#34;number_of_shards\u0026#34;: 1, \u0026#34;number_of_replicas\u0026#34;: 0 } }\u0026#39; curl -XPUT \u0026#34;http://localhost:9201/person/person/_mapping\u0026#34; -d\u0026#39; { \u0026#34;person\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;address\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;city\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;country\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;countrycode\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;location\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;geo_point\u0026#34; }, \u0026#34;zipcode\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, \u0026#34;children\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;dateOfBirth\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;date\u0026#34;, \u0026#34;format\u0026#34;: \u0026#34;dateOptionalTime\u0026#34; }, \u0026#34;gender\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;marketing\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;cars\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;electronic\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;fashion\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;food\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;garden\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;hifi\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;music\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;shoes\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;toys\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; } } }, \u0026#34;name\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } } }\u0026#39; さて、もう一度再インデックスしましょう!\nbin/logstash -f logstash.conf インデックスやタイプ名の変更 もちろん、インデックス名やタイプ名、IDを変更したい場合も変更が可能です!:)\nelasticsearch { host =\u0026gt; \u0026#34;localhost\u0026#34; port =\u0026gt; \u0026#34;9201\u0026#34; protocol =\u0026gt; \u0026#34;http\u0026#34; index =\u0026gt; \u0026#34;europe_people\u0026#34; index_type =\u0026gt; \u0026#34;someone\u0026#34; document_id =\u0026gt; \u0026#34;%{[@metadata][_id]}\u0026#34; } ","date":1432624090,"dir":"post/2015/","id":"23a22d1411afb787810d68210e6fad4f","lang":"ja","lastmod":1432624090,"permalink":"https://blog.johtani.info/blog/2015/05/26/reindex-elasticsearch-with-logstash-ja/","publishdate":"2015-05-26T16:08:10+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Reindex Elasticsearch With Logstash Thanks David! マッピングを変更したり、インデックスの設定を変更したり、あるサ","tags":["logstash","elasticsearch"],"title":"Logstashを使ったElasticsearchの再インデックス(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Join the Conversation: Discuss.Elastic.Co\n3つのOSSプロジェクトの開発をスケールアップし始め、 コミュニティサポートのために必要なやりとりに対してメーリングリストでは難しいということがわかってきました。 私たちは複数のメーリングリストを持っています。Elasticsearch、Logstash、そして英語以外の様々な言語のメーリングリストです。 このような状況では、あたらしい人たちはどこで質問をするのが良いのか混乱します。\nまた、メーリングリストの流量が増え、「参考になる話題」を見つけるのが難しくなってきました。 様々なユーザに採用してもらい、様々なユースケースが出てくることで、様々な質問が出てきています。 汎用的なメーリングリストではノイズの中から望んだ情報を見つけるのは難しいです。 また、ユーザ全てがメーリングリスト満足しているわけではありません。\nElasticは、ユーザの問題を解くことが大好きです。 コミュニティのメンバー皆さんに気に入っていただけるであろうソリューションを見つけ、フォーラムを https://discuss.elastic.co に移すことにしました。 ぜひ参加して、この新しいツールについてのご意見を聞かせてください。\nメーリングリストは好きだけど、ウェブフォーラムは苦手?問題ありません。 フォーラムにユーザプロファイル(GitHub、Facebook、Twitter、Google Appsのアカウントと連携するか、emailアドレスを利用すれば簡単に作れます)を作り、 email通知の設定をすればOKです。 これで、emailでのやりとりができるようになります。\n利用して、議論を楽しんでください。 もちろん、改善案などにかんするご意見もお待ちしています!\n","date":1432197903,"dir":"post/2015/","id":"615db1a24f36d19a8eaf18d4dceed6b2","lang":"ja","lastmod":1432197903,"permalink":"https://blog.johtani.info/blog/2015/05/21/join-the-conversation-ja/","publishdate":"2015-05-21T17:45:03+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Join the Conversation: Discuss.Elastic.Co 3つのOSSプロジェクトの開発をスケールアップし始め、 コミュニティサポー","tags":null,"title":"discuss.elastic.co にぜひ参加を"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 1.5.2 Released\n本日(4/27)、Lucene 4.10.4ベースのElasticsearch 1.5.1およびElasticsearch 1.4.5 をセキュリティバグフィックス版をリリースしました。 ダウンロードおよびすべての変更については次のリンクをごらんください。\n最新安定版:Elasticsearch 1.5.2 1.4系バグフィックス:Elasticsearch 1.4.5 本リリースはディレクトリトラバーサルの脆弱性のフィックスです。すべてのユーザにアップグレードを勧めます。\n過去のリリースに関するブログは以下のリンクを参照してください。\n1.5:1.4.1, 1.5.0 1.4:1.4.4,1.4.3, 1.4.2,1.4.1, 1.4.0, 1.4.0.Beta1 すべての1.5.2および1.4.5の変更についてはリンクをごらんください。以下では、セキュリティの問題について紹介します。\nディレクトリトラバーサル脆弱性の発見 1.5.2および1.4.5以前の全バージョンのElasticsearchで、ディレクトリトラバーサル攻撃に対する脆弱性がみつかりました。 攻撃者はElasticsearchを実行しているサーバからファイルを取得することができます。 この脆弱性はインストールしたばかりのElasticsearchには存在しません。 この脆弱性は\u0026quot;site plugin\u0026quot;がインストールされると露呈します。 ElasticのMarvelプラグインおよびコミュニティサポートの多くのプラグイン(例:Kopf、BigDesk、Head)がsite pluginです。 Elastic Shield、Licensing、Cloud-AWS、Cloud-GCE、Cloud-Azure、analysis pluginおよびriverプラグインはsite pluginではありません。\nこの問題をCVE-2015-3337としました。\nバージョン1.5.2と1.4.5はこの脆弱性に対して対策済みで、私たちはすべてのユーザにアップグレードを勧めています。\nアップグレードを望まないユーザはいくつかの方法でこの脆弱性に対して対応可能ですが、これらの方法はsite pluginを動作させなくします。\nsite pluginをインストールしているノードのelasticsearch.ymlのhttp.disable_sitesをtrueに設定し、Elasticsearchのノードを再起動 ファイアウォールもしくはプロキシを利用して、/_pluginへのHTTPリクエストをブロック すべてのsite pluginをすべてのElasticsearchノードからアンインストール この問題を報告していただいた、DocuSignのJohn Heasmanに感謝いたします。\n他の変更について インデックスされたスクリプトおよびテンプレートを上書きもしくは削除時に、キャッシュからも完全に削除する。 geo-shapeの多数のフィックス(distance_error_pctを利用した場合の、重要なprecisionに関するフィックスを含む) インデックステンプレートのデフォルトマッピングがバルクインデキシング中にも考慮するように修正 Shadowレプリカがファイルシステムの遅延に対する対障害性を向上し、プライマリシャードのよりスムーズなリロケーションをサポート geo-contextsをcompletion suggesterで使用した場合のマッピングのリフレッシュループを改善 いくつかの重要な変更がv1.4.5にバックポートされています。\n大きなシャードのリカバリを早くするためのシャードリカバリ中のマージを可能に \u0008* truncated translogsの操作をグレースフルに マージが遅くなる場合に、delete-by-queryを減速 ぜひ、Elasticsearch 1.5.2をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1430201648,"dir":"post/2015/","id":"8d7caf84b3a51cca27291c1f7cfc2d40","lang":"ja","lastmod":1430201648,"permalink":"https://blog.johtani.info/blog/2015/04/28/elasticsearch-1-5-2-and-1-4-5-released-ja/","publishdate":"2015-04-28T15:14:08+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 1.5.2 Released 本日(4/27)、Lucene 4.10.4ベースのEla","tags":["elasticsearch"],"title":"Elasticsearch 1.5.2 および 1.4.5リリース(日本語訳)"},{"contents":"第9回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 次回もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\n今回はトレーニングで来日していたIgorとNathanによる特別公演でした。 昨年同様、サムライズムの@yusukeさんに テキスト翻訳していただき、大変助かりました。ほんとうにすごかった。。。\nチェックイン数など 今回はチェックインした人:119名 キャンセルしなかった人:45名 でした。今回はキャンセル待ちのまま当日を迎えた人もいなかったので良かったかなと。 今回から懇親会ページを別にしてみました。本編の勉強会に参加登録していた方には何度かメールを出していたので、 見つけていなかった人は以内とは思うのですが、勉強会のページと間違える人がいたらしいという話を聞きました。 Doorkeeperで1イベントで複数のチケットにそれぞれの参加者数を設定できるようになると嬉しいかもなぁ。\nさて、いつもの通り簡単なメモです。 本当に簡単にですが。\nResiliency in Elasticsearch and Lucene / Igor Motov スライド:https://speakerdeck.com/elastic/resiliency-in-elasticsearch-and-lucene\n※上記スライドは少し古いバージョンです。公開されたら差し替える予定です。\nサンフランシスコで行われたElastic{ON}(弊社初のカンファレンス)で行われたセッションの 改良版といったところでしょうか。 話の中で登場した機能などのリンクをざっとアップしておきます。\nFielddata Doc Values Resiliency Status Kibana4: What\u0026rsquo;s New ? / Nathan Zamecnik スライド:未定\nKibana4の紹介をデモを交えてという感じでした。 こちらは、スライドよりもデモを見てもらうのが一番いいのですが。。。\nいくつかQAがあったので補足を。ちなみに、Issueのラベルに実装される予定のバージョンが付与されてたりします。\nQ:グラフをPDFでエクスポートとかできますか? A:4.3.0で実装される予定です。関連Issueはこちら。https://github.com/elastic/kibana/issues/509 Q:巨大な数値の場合にKB、MBなどといった表示は可能ですか? A:4.1.0で実装される予定です。関連Issueはこちら。https://github.com/elastic/kibana/issues/1543 Q:地図のズームを固定することはできますか? A:4.1.0で実装される予定です。関連Issueはこちら。https://github.com/elastic/kibana/issues/1442 その他、感想などのブログ [Elasticsearch] 第9回 Elasticsearch 勉強会へ参加してきた まとめ 今回は特別バージョンでした。かなり詳しい話だったので面白かったと思います。 Kibanaはデモを見ていただけましたし。また、海外から人を呼べるといいなぁ。\n次回は6月ごろをめどに計画しようかと。 スピーカーは随時募集中ですので、コメント、メール、ツイートなど、コンタクトしていただければと思います。 よろしくお願いいたします。\n","date":1429249314,"dir":"post/2015/","id":"7249710187cc2d983709e044dbc78d9d","lang":"ja","lastmod":1429249314,"permalink":"https://blog.johtani.info/blog/2015/04/17/9th-elasticsearch-jp/","publishdate":"2015-04-17T14:41:54+09:00","summary":"第9回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん","tags":["elasticsearch","勉強会"],"title":"第9回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 1.5.1 Released\n本日(4/9)、Lucene 4.10.4ベースのElasticsearch 1.5.1 をリリースしました。 このリリースはElasticsearchの最新の安定バージョンとなります。\nすべての変更についてはdownload Elasticsearch 1.5.1 hereをごらんください。\n本リリースはシャードを新しいノードに配置するスピードを改善するためのバグフィックスを含んでいます。 シャードのリカバリーの最初のフェーズで、コピー元のノードからコピー先のノードへすべてのセグメントをコピーします。 このフェーズ中には登録、更新削除のリクエストはトランザクションログに記録され、リカバリが終了したあとに コピー先のノードでトランザクションログが再生されます。 シャードが大きい場合、トランザクションログに多数のイベントがたまってしまいます。\n以前では、新しいセグメントのマージはリカバリ中のコピー先のノードでは、実行できませんでした。 大きなトランザクションログは結果として、小さな新しいセグメントを多く生成し、リカバリのスピードに非常に影響を与えます。 Issue #10463は リカバリ中のコピー先のシャードのマージを可能にする変更です。\nその他の注目すべきバグフィックスは次のものになります。\n多くの削除によりバージョンマップがいっぱいになった場合にrefreshを実行するように変更(#10312) 多数のスナップショットを含んだリポジトリの管理の改善(#10366) 実験的な機能であるinner hitsのバグフィックス(#10388, #10353, #10309, #10235) 最後に、Riverが非推奨となりました、まだ見ていない場合は記事をご覧ください。\nぜひ、Elasticsearch 1.5.1をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1428892471,"dir":"post/2015/","id":"563864a949924c505985a168191dcb84","lang":"ja","lastmod":1428892471,"permalink":"https://blog.johtani.info/blog/2015/04/13/elasticsearch-1-5-1-released-ja/","publishdate":"2015-04-13T11:34:31+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 1.5.1 Released 本日(4/9)、Lucene 4.10.4ベースのElas","tags":["elasticsearch"],"title":"Elasticsearch 1.5.1リリース(日本語訳)"},{"contents":"Elasticsearch勉強会 in 名古屋を開催しました。 初の東京以外での勉強会です。 企画、セッションなどお手伝いいただいた@smogamiさん、@mzpさんありがとうございました!\nElasticsearch/ELK stack紹介 @johtani スライド:Introduction Elasticsearch\n初回(次回があるかはわかりませんが。。。)ということもあり、Elasticsearchの説明を行いました。 あと、LogstashとKibanaも。 Kibanaについては、手元の環境でいつものアクセスログのデモやなどを行いました。 また、LTの後に時間があったので、前回の勉強会で利用したチェックリストの説明なども。\nスタンドファームにおけるElasticsearch導入事例 @mzp さん スライド:後日アップ?\n\u0008* 使ってるのはKibana3\nアクセスログが保存されてたけど、活用できてなかった。 Fluentd、Elasticsearch、Kibanaをいれて、可視化してみた。 普通にログ検索が簡単にできて嬉しい システムのレスポンスの性能値などを可視化できるようにして性能改善中 Kibanaでログ分析を1年続けてみたら業務システムの保守と運用が捗った(仮) @smogami さん スライド:「Kibanaでログ分析を1年続けてみたら業務システムの保守と運用が捗った」\n名古屋でJavaの勉強会を主催してみたり(最近できてないけど) 導入するのになかなか大変だった(ファイアウォールだったりが)。。。 Kibanaを使ってどんなことをしてるのか?\n既存システムなどの機能の実行回数やレスポンス時間の推移 曜日ごとにもチェック どの機能がよく使われるのか? 対象となっているシステムはJavaのシステム。 QA\nQ:ログの出力は新規に追加したのか? A : ログの出力自体はLog4Jの設定を変更しただけ。もともと、各メソッドの開始と終了にそれぞれ時間が出力される仕組みがある。\nログの読み込み自体は自作ツールを利用。 飛び込みLT @dabits さん スライド:未定\nKibanaの使い道\nKPIツール エゴサーチツール - Twitterや2chなどのデータを解析ソーシャル分析みたいな感じ? \u0008* ダッシュボードを用意してあげる場合もあるが、触っていろんな機能を試す人も。 感想・反省点など 30名弱の方に参加していただきました。ありがとうございました。 東京の勉強会でもそうですが、半分くらいが検索、半分くらいがログ解析関連に興味がある感じでした。 飛び込みLTもしていただけましたし。会場内限定の話もいくつか。\n場所 場所が少しわかりにくかったかなと。。。建物の入り口に看板がないので、1名に看板役として立っていただきました。 ただ、設備は充実していましたし、室内も綺麗でよかったです。\n懇親会 11名(+私)でした。美味しい手羽先などをいただきながら、Elasticsearch以外のことでも盛り上がりましたw。 また、名古屋の観光名所なども教えてもらったりと有意義な時間でしたw。\nということで、少しでもElasticsearch、Kibana、Logstashなどのユーザが増えてくれればうれしいかなと。 私抜きでも勉強会はできると思うので、今後も開いてもらえるとうれしいかぎりです。 初めての東京以外での勉強会でどんな感じの方が利用しているのか、興味があるのかといったことも知ることができました。\n関連ブログなど Kibana4活用事例を話しました その他(余談) コンパルという喫茶店のアイスコーヒー。ちょっと新鮮な体験でした。 あとは、日曜日に観光場所として教えてもらった、トヨタ産業技術記念館にも行ってみました。 一人だったけど、非常に楽しめました。実演とかあって、わかりやすいし。 トヨタが自動織機の会社が始まりだってのは知らなかった。\n","date":1428108439,"dir":"post/2015/","id":"24357fe145c869ec82fdfc8134a1a6d1","lang":"ja","lastmod":1428108439,"permalink":"https://blog.johtani.info/blog/2015/04/04/elasticsearch-study-session-at-nagoya/","publishdate":"2015-04-04T09:47:19+09:00","summary":"Elasticsearch勉強会 in 名古屋を開催しました。 初の東京以外での勉強会です。 企画、セッションなどお手伝いいただいた@smogamiさ","tags":["elasticsearch","勉強会"],"title":"Elasticsearch勉強会 in 名古屋を開催しました。#elasticsearch #elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 1.5.0 Released\n本日(3/23)、Lucene 4.10.4ベースのElasticsearch 1.5.0 をリリースしました。 このリリースはElasticsearchの最新の安定バージョンとなります。 多くのresiliency(復元性、弾力性) enhancementとバグフィックスを含んでおり、 すべてのユーザにアップグレードを推奨しています。\nすべての変更についてはdownload Elasticsearch 1.5.0 hereをごらんください。\n460PRという大量の変更を含む本リリースは、Elasticsearchをよりresilient(弾力のあるもの)にするために 費やされています。\nInner hits 本リリースで追加された、Elasticsearchに最もリクエストされたものの一つがinner hitsです。 これは、has_childもしくはnestedクエリにマッチした子のドキュメントを、各親ドキュメントと一緒に返すことができます。\n例えば、blogという親ドキュメントとcommentという子ドキュメントを持っているとします。 この時、\u0026ldquo;full text search\u0026quot;というコメントを持ったブログ記事を検索したいとします。\nGET /my_index/blog/_search { \u0026#34;query\u0026#34;: { \u0026#34;has_child\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;comment\u0026#34;, \u0026#34;score_mode\u0026#34;: \u0026#34;sum\u0026#34;, \u0026#34;query\u0026#34;: { \u0026#34;match\u0026#34;: { \u0026#34;body\u0026#34;: \u0026#34;full text search\u0026#34; } } } } } 上記のリクエストは、親のblogドキュメントを返します。 しかし、どのコメントが関係しているのかはわかりません。 関連しているコメントを検索して親ごとにグルーピングするために、 少し手間のかかる2回目のクエリを実行する必要があります。\nInner hitsがこれを変えてくれます。 inner_hitsパラメータを次のように、上記のクエリに追加するだけです!\nGET /my_index/blog/_search { \u0026#34;query\u0026#34;: { \u0026#34;has_child\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;comment\u0026#34;, \u0026#34;score_mode\u0026#34;: \u0026#34;sum\u0026#34;, \u0026#34;query\u0026#34;: { \u0026#34;match\u0026#34;: { \u0026#34;body\u0026#34;: \u0026#34;full text search\u0026#34; } }, \u0026#34;inner_hits\u0026#34;: {} } } } 検索結果の各blog記事に、inner_hitsという項目があり、そこに検索にヒットしたコメントの 上位3件(デフォルト値)が返ってきます。\n... \u0026#34;hits\u0026#34;: [ { \u0026#34;_index\u0026#34;: \u0026#34;my_index\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;blog\u0026#34;, \u0026#34;_id\u0026#34;: 1, \u0026#34;_score\u0026#34;: 3.68, \u0026#34;_source\u0026#34;: { ... }, \u0026#34;inner_hits\u0026#34;: { \u0026#34;comment\u0026#34;: { \u0026#34;total\u0026#34;: 16, \u0026#34;hits\u0026#34;: [ { \u0026#34;_type\u0026#34;: \u0026#34;comment\u0026#34;, \u0026#34;_id\u0026#34;: 5, \u0026#34;_score\u0026#34;: 2.79, \u0026#34;_source\u0026#34;: { \u0026#34;body\u0026#34;: \u0026#34;Full text search is the bomb\u0026#34; } }, { ... }, { ... } ] } } } ] ... inner_hits部分は、第2の検索リクエストに似ています。 sizeやfromパラメータを含めるくことで、挙動をカスタマイズできます。 また、検索から想像するであろう、ページネーション、ソート、ハイライト、_sourceフィルタリングなどといった機能もサポートします。\nInner hitsはparent-childおよび、nestedドキュメントをサポートします。 この機能は、現時点ではexperimentalラベルが付与されています。 このラベルは、この機能が将来変更されたり、削除されたりする可能性があるかもしれないことを意味します。 詳細については、Inner Hits documentationをごらんください。\nShadow replicas Elasticsearchはそれ自身の冗長性に常に気をつけています。 それは、レプリカシャード(各プライマリシャードの冗長なコピー)を持っています。 これは、プライマリシャードを失った時に、データをロスしないようにするためのものです。 レプリカシャードはまた、検索のスループットをスケールアウトするためにも利用できます。 多くのレプリカ(ノードを伴うことで。)はスループットを増加させます。\nしかし、ユーザによってはElsticsearchを分散ファイルシステム上でホスティングしており、すでに、 ファイルシステムがレプリケーションと冗長性を担当しています。 ファイルシステムが同じことしているので、各シャードのコピーを複数持つことはあまり意味がありません。\nShadowレプリカはノードを追加することによる検索スループットをスケールアウトすることが、 余分なストレージやインデキシングのコストを払うことなく、可能になります。 代わりに、各シャドーレプリカはプライマリシャードを持っている共有ファイルシステムにread-onlyでアクセスします。 Shadowレプリカは定期的にファイルシステムのビューをリフレッシュし、プライマリシャードのどんな変更も検知するでしょう。\nプライマリシャードが失敗したら、Shadowレプリカがプライマリに昇格し、 失敗したプライマリによって書き込まれたトランザクションログを読み込みリプレイできます。\nこの機能はexperimentalマークが付いています。詳細についてはShadow Replicas documentationをごらんください。\nResiliency improvements Elasticsearch 1.1 から 1.3では、インデックスのすべてのファイルのチェックサムを追加し、 それらのファイルが壊れているかどうかをチェックするために利用することにフォーカスしました。 1.4では、Zen discoveryと分散モデルについて大きな改良を加えました。\nこれらの変更にともなう、より詳細な統計情報やより詳細なロギングがElasticsearchやLuceneの以前のバージョンに存在した 未知の問題を明るみに出しました。 Elasticsearch 1.5.0では、これらの問題の多くに対処しています。\nElasticsearchとLuceneの以前のバージョンにあるバグがインデックスの故障を引き起こしていました。\nチェックサムコードのおかげで、これらを発見できました。現在は、Elasticsearchの起動時に自動的にLucene3.x\n(Elasticsearch 0.20.x以前)が作成したセグメントを検知して、シャードをオープンする前に、新しいフォーマットを使って、 新しいコミットポイントを書き出します。(#9899)\n1.3.xもしくは以前のバージョンからローリングアップグレードは、ローカルのシャードデータを再利用しようとせずに、\nシャード全体をコピーしようとします。1.3.2と以前のバージョンが実行されているノードからローリングアップグレードすることは 圧縮をオフにしない限りできなくなりました。(#9925)\n1.3.xやそれ以前のバージョンからアップグレードする場合、ローリングアップデートする代わりにクラスタの再起動を考えたほうがいいかもしれません。\n非同期環境は予測することが難しいです。時に、最も予測していないことが起きるからです。\nシャード配置、リカバリ、削除のコードの多くが単純化され、状態変更をよりアトミックで決定的にするための変更によりリファクタリングされました。\n(#8720, #9799, #9784, #9801, #9083, #8579, #8436, #8092, #9902, #6644, #8350, #9770, #9616, #9439, #8350, #8494)\n同様に、変更はクラスタ状態の更新が常に前進するということを確実にしました。更新の受け取り順序が順不同であったり、\nマスターだったノードからの更新を受け取った場合に混乱させていました。 (#9632, #9541, #9503)\nチェックサムとチェックサムのバリデーションの強化(#8723,\n#8599, #8587, #8407, #8010, #8018)\ndisk threshold allocation deciderを速く(#8803)、賢く(#7785)、自動化(#8270)\nauto-generated IDの利用時のインデキシングのスピードアップのためのに追加された最適化を除去。\nたまにドキュメントを重複して登録するため(#7729)\nDownload now ぜひ、Elasticsearch 1.5.0をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1427859496,"dir":"post/2015/","id":"19ecbaa5e12f7a9ebcff703c79534a52","lang":"ja","lastmod":1427859496,"permalink":"https://blog.johtani.info/blog/2015/04/01/elasticsearch-1-5-0-released-ja/","publishdate":"2015-04-01T12:38:16+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 1.5.0 Released 本日(3/23)、Lucene 4.10.4ベースのEla","tags":["elasticsearch"],"title":"Elasticsearch 1.5.0リリース(日本語訳)"},{"contents":"サンフランシスコからこんにちは。\n今、私は、弊社初のユーザカンファレンスelastic{ON}に 参加するために、初のアメリカ出張中です。 初のユーザカンファレンスですが、世界各国から約1300人!の登録がありました。\n本日が初日(Welcome Receptionが昨晩開催されましたが)です。 初日のキーノートで重要な発表が2つありました。\nブランド名の変更(Elastic: For - You Know, More Than Search) Found.noの加入(Welcome Found) です。\n昨日までは、elasticsearchでした。 本日からは、elasticになります。 ブランド名の変更と同時にサイト、ロゴなども変更されました。\nもう一つのビッグニュースがFoundの加入です。 found.noはElasticsearchをクラウドサービスとして提供している会社です。 彼らがジョインすることで、elasticsearchをより気軽に利用できるような環境ができてきます。\nKeynoteでの驚きのニュースこれらでした。 もちろん、このカンファレンスはそれだけには止まりません。\nNetflixやGitHub、Verison Mobile、WikimediaといったElasticsearch,ELKスタックのユーザの話や、 弊社の人たちによる今後のロードマップや私たちの考え方など多岐にわたる話を聞くことができます。\nこのような機会を今後も提供できるような会社になれるよう、頑張っていきたいなと思っています。\nちなみに、弊社のカンファレンスは私がこれまで経験したことのないカンファレンスになっています。 DJや各種ゲーム(ビリヤードとかパックマンとか)が楽しめるようなパーティが 懇親会として開催されたり、スポンサーブースでウェルカムレセプションが行われたりと、 面白い取り組みにあふれています。 次回開催されることがあれば、ぜひ日本の方達にも参加してもらえたらうれしいなと。\n","date":1426059991,"dir":"post/2015/","id":"ced9df0d8c8ed14de91c509b31b4c4ae","lang":"ja","lastmod":1426059991,"permalink":"https://blog.johtani.info/blog/2015/03/11/attend-elasticon/","publishdate":"2015-03-11T16:46:31+09:00","summary":"サンフランシスコからこんにちは。 今、私は、弊社初のユーザカンファレンスelastic{ON}に 参加するために、初のアメリカ出張中です。 初のユ","tags":["elastic","elasticon"],"title":"#elasticon に参加中"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:you know, for security: shield goes ga\n1/27にShield 1.0 をリリースしました。 Elasticsearch向けの私たちのセキュリティプラグインの最初のリリースです。 11月にShieldについてアナウンスしてから、Elsaticsearchのためのセキュリティの機能は、 一般的に望まれているものから始まり、具体的な考えと実行できる計画へと変遷し、それが、いま現実となりました。\n十分にセキュアな環境に、Elasticsearchクラスタをセキュアな状態でデプロイできるようにするため、 私たちは継続的にカスタマーやユーザーからのリクエストを受け取り、統合されたソリューションになるようにしてきました。\n私たちは、そのようなプロダクトがどうあるべきか調査することから始め、 カスタマーとユーザが必要とするセキュリティとはどんなものかを理解するために多くの時間を費やしました。 その結果がShieldです。 Shieldは、ElasticsearchクラスタをセキュアにするElasticsearchの有償プラグインです。 私たちは、ShieldをDev、Gold、Platinumサブスクリプションの一部として、追加料金なしで提供します。\n最初のリリースでは、基本的な機能と基盤にフォーカスしています。 Elasticsearch自身に対しても、セキュリティに対して準備してきました。 拡張性の側面だけでなく、Elasticsearchにあるデータフローについても再考してきました。 Elasticsearchクラスタをセキュアにする場合に、具体的な価値を即座に届けるだけでなく、素早く拡張できるようにも開発しました。\n機能 Shield 1.0は次の5つにフォーカスしています。\n認証(Authentication) 認可(Authorization) 暗号化通信とノードの認可(Encrypted Communication \u0026amp; Node Authentication) IPフィルタリング 監査証跡(Audit Trail) 認証(Authentication) セキュリティの大部分はアイデンティティについてです(例えば、だれがこのAPIを呼び出したのか?システムに何のサービスが接続するか?など) サービスのライフタイムのある時点で、サブジェクト(例えばユーザー)を現在実行中のサブプロセスなどに結びつけることです。 この関係性を持つためには、サブプロセスを実行する前にユーザの身元を確認するように命じます。 ユーザの身元の確認のプロセスをAuthenticationと呼び、ElasticsearchのすべてのAPIコールでそれが実行されます。\n認証の手法は多くの異なるものがあります。 それぞれの手法は、ユーザが認証されたという資格(Authentication Token)を、それぞれのタイプで提供するようにユーザに要求します。 Shield 1.0ではシンプルに、必要なauthentication tokenをユーザ/パスワードペアとしています。 (これは、Shieldの認証基盤が簡単に拡張でき、将来は異なるauthentication tokenもサポートできることを意味します。)\nユーザの資格を受け取ることだけでは不十分で、次に、それらをチェックする必要があります。 Shieldでは、これはレルムの責務です。 レルムは認証プロバイダ/サービスとしてみることができます。 妥当なユーザであると判断/解決されたか、 authentication tokenが適切な資格を持っていない/単に知らないユーザであるということで、拒否されたかです。 Shieldの認証メカニズムでは、複数のレルムを設定でき、さらに、あるレルムの戻り値を扱う他のレルム、というようなchainとすることもできます。 Shield 1.0は3つのレルムをサポートします。\nesusers - Elasticsearchによって管理されるファイルベースのレルムです。 これは、ファイルにユーザを定義することができます。(Apacheサーバのhtpasswdファイルのようなもの) このレルムは外部への依存はなく、Shieldをインストールすれば、デフォルトで使用できます。 このレルムは配置が簡単で、マルチテナントなElasticsearchクラスタに対して使用できます。 マルチテナントなElasticsearchクラスタとは、クラスタを複数のアプリでシェアすることをテナントと言います。 また、すべてのユーザがパスワードを忘れてしまうような\u0026quot;emergency\u0026quot;な代替レルムも対応可能です。 (誰もシステムに入れないような状況のことです) LDAP - 外部のLDAPサーバでユーザを認証するレルムです。 このレルムは組織のLDAPサーバで管理/保存されているユーザをすでに持っている組織を対象としています。 Active Directory - LDAPのタイプの1つで、Active Directoryに対する設定になります。 レルムはelasticsearch.yml設定ファイルで、次のように設定可能です。\nshield.authc realms:\nesuser: type: esusers order: 0 ldap: type: ldap order: 1 url: ldaps://url/to/ldap1/server ldap_fallback: type: ldap order: 2 url: ldaps://url/to/ldap2/server 上記のようにrealmsが一つのチェインとして参照されます。 レルムごとに、設定された順序で、それらは参照されます。\nNOTE : Shieldには、esusersファイルに保存されたユーザを管理するためのコマンドラインツールもあります。\n認可(authorization) 認可(Authorization)は保護されたリソースにアクセスするユーザを許可するか拒否するかということです。 モダンなシステムは、ユーザのパーミッションのために、ロールベースのアクセスコントロール(RBAC)モデルを利用します。 このモデルでは、各ユーザはロールの集合に関連していて、それぞれのロールには、パーミッションの集合が定義されています。 これは、洗練された設定で、パーミッションを機能的なグループで共有させることができます。 例えば、次のようなロールを定義したとします。\nemployee - すべての従業員は部門をまたいだ会社のデータへアクセスできます(例えば、コンタクトやディレクトリ情報など) sales - すべての営業職は営業データにアクセスできる(例えば、流通ルート、ルート、顧客) finace - すべての財務の従業員は財務データにアクセスできる(例えば、予算、経費、伝票) 財務部門のAnnは従業員と財務のロールを持っており、会社のディレクトリと財務データにアクセスでできます。\n認可プロセスはユーザがリクエストに関連したユーザが必要で、このプロセスのために、認証フェーズの後に直接実行されます。\nShieldは2つのタイプのリソースを定義します。クラスタとインデックスです。 これらは、すべてのAPIコールで保護されます。 さらに、それらに関連したパーミッションとロールも定義できます。 一度定義をすると、ロールはユーザもしくはLDAP/ADのグループに関係します。 ロールはroles.yml設定ファイルで定義されます。 設定のサンプルは次のようになります。\nadmin: cluster: all indices: \u0026#39;*\u0026#39; : all monitor: cluster: monitor indices: \u0026#39;*\u0026#39;: monitor employee: indices: \u0026#39;company_directory\u0026#39; : read sales: indices: \u0026#39;opportunities\u0026#39; : read, write \u0026#39;accounts\u0026#39; : read, write finance: indices: \u0026#39;expenses\u0026#39; : read, write \u0026#39;purchases\u0026#39; : read, write 上記のサンプルで、次の5つのロールを定義しています。\nadmin - 管理者のロールで、すべてのクラスターレベルの操作とすべてのインデックスに対してすべてのインデックスレベルの操作を実行可能です。 (¥*インデックスはすべてのインデックスにマッチするワイルドカード) monitor - システム/クラスタのモニタリングのためのロール。このロールのユーザはすべてのクラスタとインデックスレベルの情報の読み取りの APIにアクセス可能だが、インデックスのデータへの読み書きや設定の更新は不能 employee - compnay_directoryにあるすべてのデータへの読み取りアクセスを与えられたロール。このロールはクラスタレベルへのアクセスやデータの書き込みアクセスは持っていない (特にcompany。洗濯されたグループの人々はcompanyディレクトリの更新は可能だが、employeeは読み取りのみが可能) sales - opportunitiesとaccountsインデックスの読み書きができるロール finance - expensesとpurchasesの両方に読み書きができるロール 上記のサンプルで定義されているallとreadとwriteとして名前がつけられた権限です。 これらは、予約語で、Elasticsearchのローレベルのアクションを複数含んだ権限です。 (writeはindex, delete, delete_by_query, bulk, updateの操作を含んでいます。) 多くのケースで、これらのハイレベルの名前が付けられた権限で十分ですが、特定のロールに特定のアクションを明示的に指定することもできます。 次のようになります。\nhr: indices: \u0026#39;company_directory\u0026#39; : indices:data/write/index, indices:data/write/update ここまで説明した認可のレルムは、各ユーザに関連するロールを識別するためのものです。 内部のesuserレルムでは、提供されるesuserコマンドラインツールを使ってロールはユーザに割り当てたり変更したりもできます。 LDAPやActive Directoryでは、LDAP/ADグループにShieldのロールを割り当てることができます。\n認証と認可の両方を用いることで、ユーザリクエストに対して、ユーザごとに許可/不許可をすることができます。\n暗号化通信 認可はElasticsearchのデータを機能的な観点(許可されたユーザだけが操作を可能にする)で保護しますが、 クライアントからElasticsearchクラスタへ、もしくはクラスタのノード間では暗号化されていないデータを送るためまだ危険があります。 第三者が登頂したり、オンザフライでデータを書き換えたりといった可能性やクラスタを壊すことができます。\nShield 1.0はElasticsearchのすべての通信チャネルをセキュアにすることができます。 クラスタ内のノード間のチャネルやクライアントに公開されているチャネルです。 これは、SSL/TLS通信を導入して実現します。\nShieldで使えるSSLはElasticsearchのtransportサービスをSSL/TLSで通信できるものに置き換えます。 これは、ノード間通信チャネルと、HTTP transport(REST APIを提供するもの)のそれぞれに設定可能です。\nShieldのSSL/TLSは、スタンダードなJavaのものとkeystoreとtruststoreを基本にしたものが利用可能です。 SSL/TLSを設定すると、各ノードのキーストアに証明書をインポートする必要があります。 CAがサインした証明書を使うことも、CAが信頼したものとして許可許諾されたものを使うことが可能です。 これは、信頼されたすべてのCAとして知られているtrust storeが必要です。 新しいノードをクラスタに追加するときに、すべての必要な少なくとも一つの信頼されたCAから発行されてサインされたものが必要になります。 クラスタで個別のノードがすべてのkeystore/truststoreを更新する必要性なしに。??\n通信チャネルを安全にする方法やSSL/TLS設定をどのように行うかはShieldのドキュメントをご覧ください。\nノード間認証 強く推奨しますが、許可されたノードだけがクラスタに接続できるようにするために、ノードの認証をSSL transportに設定することができます。 これは、shield.transport.client.authにtrueを設定することで可能です。 設定した場合、ノード間でSSLハンドシェイクが行われ、接続されたノードが接続に来たノードのクライアント認証を要求しチェックします。 もし、チェックに失敗した場合は、SSLシェイクハンドが失敗し接続が拒否されます。\nSSLクライアント認証 transportレベルでノード認証が必要なようなら、次のような疑問がわくでしょう。 Elasticsearchはクラスタに接続するTransportクライアントを使うときはどのように振る舞うのか? Transportクライアントはクラスタの他のノードと同じチャネルを使うため、コネクションを確立するときに、ノードが他のノードと異なるかどうかを見極めることはできません。\nこの時、もっとも単純な解決は、Transportクライアントも同様に許可を与えることです。 それは、認証を解決するときに、他の問題(潜在的な悪意)を引き起こします。 Transportクライアントが他のクラスタのノードを偽装しようとすることです。これは望んでいません。\n幸いなことに、良い解決方法があります。 トランスポートプロファイルです。 Elasticsearch 1.4で導入されたトランスポートプロファイルは、トランスポートレイヤー(異なるホスト/ポートにバインドされる)のために複数のネットワークチャネルを設定することができます。 Shieldはこのサポートを、プロファイルごとに異なるSSL設定をできるように拡張します。 また、ノードのタイプとクライアントプロファイルタイプの間に明確な違いを設定することも可能です。 これを用いると、2つのプロファイルを設定できるようになります。 ひとつは、クライアントのためのもので、もうひとつはクラスタのノードのためのものです。 これにより、クライアントのための認証の問題が必要なくなり、Shieldはクライアントプロファイルをもった限定されたクライアントからのリクエストを保証します。\nIPフィルタリング これは、厳密には、認証カテゴリではありませんが関係しています。 Shieldはそれ自身がIPフィルタリングのメカニズムを持っています。 これは、許可/不許可のIPのリストを設定することができます。 これらのフィルタリングのルールは複数のレベルで設定可能です。 transportチャネル、transportプロファイルレベル、そして、HTTPチャネルです。 次の設定は、それらの設定のサンプルです。(設定ファイルはelasticsearch.ymlになります)\nshield: transport.filter: allow: - \u0026#39;127.0.0.1\u0026#39; - \u0026#39;2001:0db8:1234:0000:0000:8a2e:0370:73 deny: - \u0026#39;10.0.0.0/8\u0026#39; - \u0026#39;2001:0db8:1234::/48\u0026#39; - \u0026#39;*.google.com\u0026#39; http.filter: allow: [ \u0026#39;10.0.0.0/8\u0026#39; ] deny: [ \u0026#39;127.0.0.1\u0026#39; ] transport.profiles: client: shield.filter.deny: [ \u0026#39;_all\u0026#39; ] このように、IPv4とIPv6、CIDR、ホスト名、ワイルドカードが利用できます。 また、この機能はホストOSのIPテーブルに設定することで追加できるが、Shieldにそれを保持し、それらの設定を単純化し、 デプロイの全体から除去できることにも注意してください(詳細はドキュメントのIPフィルタリングをご覧ください)。\n監査証跡(Audit Trail) セキュアなシステムの必須機能の一つで、監査硝石により、Elasticsearchに発生した重要なイベントをトラッキングすることが可能です。 これらのイベントを保存することは、Elasticsearchクラスタの重要なアクティビティの証拠を提供でき、 不審な/悪意のある可能性のあるイベントを追跡するときの診断ツールにもなります。\nShield 1.0.0で、監査証跡は監査/アクセスlogを一般的なElasticsearchのログとは個別に保存します。 それらは、構造化されているため、読んだりパースするのが容易で、イベントのタイプも分類されています。 また、情報のレベルを設定することができ、各イベントをlogレベルの設定で書き出すことができます。 以下が、イベントのリストです。\nanonymous_access_denied - 認証トークンがないユーザからのリクエストがあった時のログ authentication_failed - リクエストされたユーザの認証に失敗した時のログ access_denied - 認証されたユーザが許可されていない操作を実行した時のログ access_granted - 認証されたユーザが許可された操作を実行した時のログ tampered_request - 不正に書き換えられたリクエストが到着したのを検知した時のログ connection_granted - ノードもしくはtransportクライアントがIPフィルタのルールにパスした時のログ connection_denied - ノードもしくはtransportクライアントがIPフィルタリングルールの制限により却下された時のログ Shieldの監査証跡についてより詳しく知りたい方は、ドキュメントをごらんください。\n次のバージョンでは? ここまで紹介したように、これはまだ始まりにすぎません。 Shieldに追加される多くの機能があり、しっかりとした基盤を構築したところです。 Shieldの次のバージョンでは、以下の機能の追加にフォーカスするでしょう。(これらだけに限ったわけではありません。)\nAPIによる設定、管理 より拡張され、柔軟なLDAP/Active Directoryサポート レルムタイプの追加(kerberos、anonymous、certificatesなどなど) セッションベースの認証 ShieldはElasticsearch社の2番目の(Marvelに続く)商用プロダクトです。 ダウンロードして開発環境で評価してください。 インストールは他のプラグインと同様の方法です(インストール方法についての詳細はこちら)。 一度インストールすると、30日の試用ライセンスが始まります。 もし、さらに時間が必要な場合は、sales@elasticsearch.comまで連絡してください。\n私たちのすべてのプロダクトについてフィードバックをお待ちしています。 Shieldの商用利用、機能、ロードマップ、その他のセキュリティに関するトピックなど、質問がありましたら、 サイトからご連絡ください。\n","date":1425030596,"dir":"post/2015/","id":"cb13b64d0127c13bb466c4d4677a7b8a","lang":"ja","lastmod":1425030596,"permalink":"https://blog.johtani.info/blog/2015/02/27/you-know-for-security-shield-goes-ga-ja/","publishdate":"2015-02-27T18:49:56+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:you know, for security: shield goes ga 1/27にShield 1.0 をリリースしました。 Elasticsearc","tags":["elasticsearch","shield"],"title":"セキュリティ向けプラグインShieldのリリース(日本語訳)"},{"contents":"4月13日から3日間、ElasticsearchのCoreトレーニングが東京で開催されます。 Early Birdということで、3/14までに申し込みすると割引があります。 興味のある方は、見ていただければと。\nまた、4/15にElasticsearch勉強会を開催します。 トレーニングに弊社のエンジニアが来日しますので、なにか話をしてもらう予定です。\n募集は後日、Elasticsearch勉強会のDoorkeeperで行います。 興味のある方は、登録しておいていただければと。\nトレーニングや勉強会でお待ちしております。\n","date":1425024629,"dir":"post/2015/","id":"f2cbe07bf2ff16d5a5860b4d6edbc5e8","lang":"ja","lastmod":1425024629,"permalink":"https://blog.johtani.info/blog/2015/02/27/2nd-tokyo-training/","publishdate":"2015-02-27T17:10:29+09:00","summary":"4月13日から3日間、ElasticsearchのCoreトレーニングが東京で開催されます。 Early Birdということで、3/14までに申し込みす","tags":["elasticsearch"],"title":"Elasticsearch Coreトレーニング開催"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:kibana 4. literally.\nKibana 4は現在、文字通り、抽象的に、概念的に、精神的に、そしてとても楽しく、プロダクションレディになりました。 1週間前に準備はできていましたが、満足できるものであるという確信を得たいと思っていました。 そして、Kibana 4.0.0 GAをリリースしました。 次のものはサンプルのスクリーンショットと前日譚です。 これらに興奮してしまった方のために、2ステップのプランを用意しました。\nダウンロードする:Kibana 4 downloadsページからダウンロードします。 理解する:Kibana 4 docsページを読んで理解します。 Tip : もし、まだ、あなたのクラスタがElasticsearch 1.4.4でない場合は、アップグレードする必要があります。\nTip2 : Kibana 4 RC1からアップグレードする場合は、configを移行する必要があります。こちらのgistを参照\n前日譚 - the back story Kibanaはすでに問題解決のためのツールになっています。 なぜ、毎晩2時に呼び出されるんでしょう? そのコードがプロダクションに入ったのはいつですか? その結果、何を壊しました? 私たちはそれらを解決しました。 世界的に、長い間、だれも夜中の2時に呼び出されませんでした。知ってます?。\n*しかし、ここには落とし穴があります。*答えが簡単になれば、問題が難しくなります。 楽な勝利は簡単でした。では、難しい問題(深さが3層の問題)を解きましょう。 複数の要素、複数のフィールドそして、複数のデータソースを分析する必要がある問題を解きましょう。 Kibana 4は少ない時間と労力で最も難しい問題を解決してくれます。\nKibana 3で学んだことをKibana 4に取り込みました。 なぜ10億のデータを持っているのに、地図には1000個しかプロットできないのでしょう? 1つのチャートに1つのフィールドなんでしょう? なぜ、1つのパネルに1つのチャートなんでしょう? なぜ、1つのダッシュボードに1つのインデックスなんでしょう? 5つのシナリオを用意し、2つのフィールドにまたがったデータを比較し、 1つのダッシュボードに3つのインデックスのデータを表示してみましょう。 さぁ、やりましょう。終わったらアイスクリーム(トッピング付きの)を取りに行きましょう。\nthe plot アイスクリームのように、問題には多くの種類があります。 そのために、Kibanaをナポリ風アイスクリーム(3色アイス)のように分割しました。 嫌いな種類は除いて。 もし、あなたがKibanaのユーザ歴が長い場合、最初のタブのDiscoverがホームであることが正しく感じるでしょう。 これにより、短時間で、検索し、レコードを見つけ、簡単な問題を解決できます。 簡単な問題とは、すべてを物語る1行のデータを見つけることによって解決する問題です。\n物事が簡単な検索で説明できるものよりも複雑になった時、チャートとグラフで魔法を作る時間です。 Visualizeタブを開き、Elasticsearchのaggregationの力を利用してデータを解析しましょう。 Visualizeは複数の次元の性質のデータを見せ、今まで尋ねたことがないような質問に対して素早く回答するチャートやテーブル、 地図を作成できます。 あなたが最初に尋ねる質問は「先週サイトが遅かったのはなぜ?」でした。 しかし、データによって明らかにされた質問は「なぜ、クリスマスに東京からの平均ファイルサイズリクエストがスパイクしたのか?」です。\n最後に、Dashboardでこれらを1つにします。\n大きなスクリーンに配置して、こう言います。 「あなたの答えはこのリンクにあります。また、Wikiに埋め込んで、データをCSVにエクスポートしてメールしました。 アイスクリームを食べた後に、自叙伝の第1章を書きました。もっとアイスを持ってきてください。かき混ぜますから。」\nそれぞれのタブで見てきた詳細については、Kibana 4 Beta 1 : Releasedをごらんください。\nto be continued\u0026hellip; 居眠りをする時間はあります?いいえ、Kibana 4.1についてすでに作業中で、将来の大きなプランを持っています。 多くの労力はKibana 4の土台の安定と実用性を構築することに使われました。 また、Elasticsearchアプリケーションの将来を構築するプラットフォームを作りました。 すべてのものは拡張できるように設計されています。 例えば、可視化はより良くなるように構築されています。 オープンソースは私たちのGitHubアカウント以上のものです。 それは、新しく素晴らしいものを誰もが作ることができる構造を作ることが私たちの約束です。\nKibanaでグラフなどを構築したり、Elasticsearchを利用したアプリケーションを作成するために、 私たち開発者のブログを参考にしてください。 ちょっと見てみたいですか? Elastic{ON}15のSpencer Algerのトークをチェックしてください。\nあなた方なしでは、私たちはここにはいないですし、あなた方の助けがなければ何もできません。 ぜひ、GitHubでのissueや提案、貢献をお待ちしています。 もしくは、IRCでFreenodeの#kibanaに参加してください。\nextra credit Kibana 4のすべての話に興味がありますか?私たちのKibana 4ベータに関する過去のブログをチェックしてください。\nKibana 4 Beta 1: Released Kibana 4 Beta 2: Get it now Kibana 4 Beta 3: Now more filtery Kibana 4 RC1: Freshly baked 最後に、Kibanaの利用に関する話をお持ちなら、ぜひ聞かせてください。 stories at elasticsearch dot comもしくは@elasticsearchに連絡をください。 あなたの話を世界にどのようにシェアしているかごらんください。\n","date":1424408752,"dir":"post/2015/","id":"eee039f49a5b570599cf459c55c649f3","lang":"ja","lastmod":1424408752,"permalink":"https://blog.johtani.info/blog/2015/02/20/kibana-4-literally-ja/","publishdate":"2015-02-20T14:05:52+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:kibana 4. literally. Kibana 4は現在、文字通り、抽象的に、概念的に、精神的に、そしてとても楽しく","tags":["elasticsearch","kibana4"],"title":"Kibana 4(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:elasticsearch 1.4.4 and 1.3.9 released\n本日(2/20)、Elasticsearch 1.4.4とElasticsearch 1.3.9をリリースしました。 これはバグフィックスリリースとなります。 主に、Lucene expression scriptsを使う場合のRPMとDEBパッケージの パッケージング問題のフィックスをしたものです。 1.4.4のダウンロードこちらのリンクからアクセスできます。\nfixes 1.4.3のRPMおよびDEBパッケージにはAntlrとASMの依存関係の不足がありました。 この依存はElasticsearchでLucene expression scriptsを利用する場合に必要になります。 Groovyに関する1.4.3の変更により、多くのユーザがLucene explression scriptsを利用することが予想されるため、すぐに、1.4.4をリリースしました。\nまた、このリリースには、クラスタの保留タスクに関するいくつかのバグフィックスも含まれています。 さらに、date histogramで負のインターバルの場合にOutOfMemoryErrorを引き起こすバグも 修正されています。\nすべての変更については1.4.4のリリースノートおよび1.3.9のリリースノートをごらんください。\nフィードバック 私たちはフィードバックをお待ちしています。 Twitter(@elasticsearch)もしくはGitHub issues pageで教えてください。\n","date":1424408734,"dir":"post/2015/","id":"ddd3e6f6e298d3884abc4d888a043664","lang":"ja","lastmod":1424408734,"permalink":"https://blog.johtani.info/blog/2015/02/20/elasticsearch-1-4-4-and-1-3-9-released-ja/","publishdate":"2015-02-20T14:05:34+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:elasticsearch 1.4.4 and 1.3.9 released 本日(2/20)、Elasticsearch 1.4.","tags":["elasticsearch"],"title":"Elasticsearch 1.4.4および1.3.9リリース(日本語訳)"},{"contents":"来る、4月4日の土曜日の午後に名古屋でElasticsearch勉強会を開催予定です。 「初」の東京以外の勉強会です。\nTwitterでこのようなツイートを見かけまして。\n名古屋でElasticsearchの勉強会やりたい機運(今のところ2人)。\n\u0026mdash; mogami (@smogami) 2015, 2月 4 これは!ということで、名古屋で勉強会をやろうかと思います。30名程度の場所を借りて実施予定です。 募集はいつもの、elasticsearch勉強会のDoorkeeperで行う予定です。 ページの準備まで少々待ちください。(おそらく、3月中旬くらい) 私自身はElasticsearchやELKについて話をしようと思っています。そのほかに、2,3名のスピーカーの方を予定しています。 LTなど興味がある人がいたら、連絡ください。\nこれを機に(?)他の場所でも勉強会を開催したいと考えています。 ニーズがどのくらいありそうなのかが、まだよくわかっていませんが、関西などでニーズがあるんじゃないかと期待していたり。\n興味のある方は、コメント欄、Twitterなどでコンタクトしてもらえればと。 (連絡来るとうれしいなぁ。)\n","date":1424240573,"dir":"post/2015/","id":"5b97ead91c0dd0bad57b4f43a89149a2","lang":"ja","lastmod":1424240573,"permalink":"https://blog.johtani.info/blog/2015/02/18/preparing-elasticsearch-meetup-in-nagoya/","publishdate":"2015-02-18T15:22:53+09:00","summary":"来る、4月4日の土曜日の午後に名古屋でElasticsearch勉強会を開催予定です。 「初」の東京以外の勉強会です。 Twitterでこのよう","tags":["elasticsearch","勉強会"],"title":"名古屋でElasticsearch勉強会を開催します"},{"contents":"第8回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 次回もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\n今回は出足が好調で、早々に180人の枠を超えるという嬉しい事態でしたが、 キャンセル待ちが残っているにもかからわらず、来られていない方が67名もいるということで、キャンセル待ちの方には申し訳なかったです。 もうすこし、キャンセルをしてもらえると嬉しいんですが。。。 今回はメールを当日に1度しか打ってないからかなぁ。\nさて、いつもの通り簡単なメモです。 本当に簡単にですが。\n「Elasticsearch導入チェックリスト?」 Elasticsearch株式会社 Jun Ohtani @johtani スライド:Elasticsearch導入チェックリスト?\nElasticsearchを開発環境や本番に導入する前に気にかけて欲しいことについて発表しました。 元ネタはelasticsearch pre-flight checklistです。 少々古いのですが、私が今回話した内容以外にもモニタリングなどについての話も盛り込まれています。 時間がある方は、見ていただければと。\n「Elasticsearch クエリとスキーマ定義のすごい細かい話」株式会社ドワンゴ 藤堂淳也 さん スライド:Elasticsearch クエリとスキーマ定義のすごい細かい話\nフィールドのチェックを別途インデキシングするアプリで行っている。利用できるものだけElasticsearchに投げる 実際に本番環境で利用しているマッピングに対してフィールドを追加する手順について 「これもドキュメントに書いてあるんですが」という感じでドキュメントに色々書いてあるので読みましょうというありがたい発表でした。 実際に試行錯誤したり検証するときに行ったことを喋ってもらえたので、どういった点を気にしながら運用、設計するかというのがわかりやすかったです。\n「ElasticsearchとKibanaで実現する、30億req/dayのリアルタイム分析」株式会社サイバーエージェント 山田直行さん @satully スライド:ElasticsearchとKibanaで実現する、30億req/dayのリアルタイム分析\n会場が21時までしか抑えられていないという失態で、ドタバタしてて前半は聞けてないです。。。\n前回の発表では30日分Elasticsearchに入れていたが、今は3日分のみ保存 レポートなどにはRedshift+Tableauを利用 Kibana3をメインに使っているが、Kibana4も検討予定? QA\nQ:なぜ、ELBを挟んでいるのか? A:特に考えておいているわけではない。 Q:インデックスの構成は? A:1日に2つのインデックス。Bitされたもの、入札されないもの Q:searchのnodeをやめたのは? A:前回発表した勉強会での懇親会で話を聞いたり、他の方と話を聞いて、不要と判断したため 「はてなのメディア面を支えるElasticsearch」株式会社はてな 山家雄介さん @yanbe スライド:未定。おそらく、開発者ブログに公開されるかと。\n\u0008* アドテク系にもやってるらしい。BrandSafeはてな\nはてなブックマークのデータを魅せ方を変える機能などで大活躍。B!KUMAとか その日の話題の見出し自動生成機能。Significant Terms Aggregationsを利用。 こちらの「自然言語処理技術を用いたはてなブックマークの新機能「トピック」をベータリリースしました」エントリに関係あるのかな? 記事の魅せ方を検索できる管理画面ではElasticsearchのクエリDSLを活用されているとのことでした。 検索専門の人でなくても検索式を簡単にくみたてられる画面を用意して、ElasticsearchのクエリDSLに変換するようにしていると。 確かに、クエリをそのまま組み立ててもらうよりも利用しやすい画面がある方がいいですよね。バックエンドはJSとPerlのライブラリとのことでした。\nその他、感想などのブログ 2015-02-13 第8回 elasticsearch 勉強会 @ 丸の内 リクルート 41Fアカデミーホール [Elasticsearch] 第8回 elasticsearch 勉強会へ参加してきた 第8回elasticsearch勉強会 #elasticsearch #elasticsearchjp 第8回 Elasticsearch 勉強会に行ってきた #elasticsearch #elasticsearchjp 勉強会メモ - 第8回elasticsearch勉強会 まとめ 今回も検索からログまでいろんな話になったので、面白かったかと。 参加された方は新しい方が多かったんじゃないかなぁと。(集計結果で見れないのかな、Doorkeeper)。\n今回は、みなさんに21時に41Fから33Fへ移動していただくという大失態があったので、大変申し訳なかったです。 次回(4月中旬)は、このようなことがないように気をつけますので、今後もよろしくお願いいたします。\nあと、東京以外の勉強会も検討しつつあります。興味のある方はコメントやTwitterで反応をいただけると嬉しいです。\nスピーカーは随時募集中ですので、コメント、メール、ツイートなど、コンタクトしていただければと思います。 よろしくお願いいたします。\n","date":1424066543,"dir":"post/2015/","id":"997acc135d01b54f7de77a432fb9133f","lang":"ja","lastmod":1424066543,"permalink":"https://blog.johtani.info/blog/2015/02/16/8th-elasticsearch-jp/","publishdate":"2015-02-16T15:02:23+09:00","summary":"第8回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん","tags":["elasticsearch","勉強会"],"title":"第8回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:running groovy scripts without dynamic scripting\nElasticsearch1.3.8と1.4.3のリリースにより、デフォルトで、リクエストに含まれるGroovyスクリプトや インデックスに保存されたスクリプトを動的に実行する機能をオフにしました。 しかし、Groovyはまだデフォルトのスクリプト言語です。 本ブログ記事では、少しだけダイナミックだが、サンドボックスではない言語のためのスクリプトを どのように使い続けるかを説明します。\n本ブログ記事は、それが何を意味し、さらに重要なのは、安全に重要なタスクを実行させるためにスクリプトを どのように使用し続けるかを理解する助けとなるはずです。\nダイナミックスクリプトとは? Elasticsearchに詳しくない方のために、Elasticsearchでは、 さまざまなリクエストの一部としてスクリプトを送信することができます。 search、aggregation、update、upsert、delete by queryなどです。 あなたのユースケースのために、通常の動作よりも拡張した動作をさせるためにスクリプトを追加できます。\n例えば、以下のリクエストは、ダイナミックスクリプトを含んでいます。 field1とfield2 + shiftが同じ値を持っている時だけドキュメントを返します。\nGET /_search { \u0026#34;query\u0026#34;:{ \u0026#34;filtered\u0026#34;:{ \u0026#34;filter\u0026#34;:{ \u0026#34;script\u0026#34;:{ \u0026#34;script\u0026#34;:\u0026#34;doc[\u0026#39;field1\u0026#39;].value == (doc[\u0026#39;field2\u0026#39;].value + shift)\u0026#34;, \u0026#34;lang\u0026#34;:\u0026#34;groovy\u0026#34;, \u0026#34;params\u0026#34;:{ \u0026#34;shift\u0026#34;:3 } } } } } } 言語を変えることもできます。 それは、当然、シンタックスが変わったり、制限が追加(例えば、Groovyスクリプトの代わりにLucene Expressionsに変更)されることもあります。 langパラメータによって言語を指定できます。\nなぜそれはダイナミック? 上記の例はダイナミックスクリプトです。 それは、実際のスクリプトの部分はサーバサイドで動的に解釈されコンパイルされる必要があるからです。 ダイナミックスクリプトはElasticsearchのAPIによってデータノードに送信されます。 これは、インデックスされたスクリプト(indexed script)も含みます。\n言い換えると、もし、スクリプトがデータノード全てに保存されていなければ、 それは、ダイナミックスクリプトとして扱われます。\ndynamic scriptingをオフにするとどうなるか? 最新のリリースでの変更により、Groovyのdynaic scriptingはデフォルトでオフになりました。 先ほどのスクリプトについても同様で、もし、先ほどのリクエストを実行すると、次のようなエラーが発生します。 (一部省略してあります。)\n{ \u0026#34;error\u0026#34;:\u0026#34;SearchPhaseExecutionException[Failed to execute phase [query], all shards failed; shardFailures {[8FJ02MofSnqVvOQ10BXxhQ][test][0]: SearchParseException[[test][0]: from[-1],size[-1]: Parse Failure [Failed to parse source [{...}]]]; nested: ScriptException[dynamic scripting for [groovy] disabled]...\u0026#34;, \u0026#34;status\u0026#34;:400 } エラーメッセージの重要な箇所は「ScriptException[dynamic scripting for [groovy] disabled]」です。\nスクリプティングを使い続けるには? Elasticsearchでスクリプトを実行するには3つの方法があります。 2つのダイナミックな方法は、リクエストごとのスクリプト(上述)かインデックスされた スクリプト(indexed script)を使う方法です。 インデックスされたスクリプトを使うことは、Elasticsearch自身にGroovyスクリプトを保管することで 利用で、それらを要求に応じて利用することです。 (これは、実際には十分機能しますが、これではまだ、信頼できないユーザに対して彼らのスクリプトを実行できます) RDBのように保存されたプロシージャとして同じ方法で実行させるものと同様です。 前もって、スクリプトを記述しておき、リクエストの一部として後から、名前で呼び出して実行可能です。\nGET /_search { \u0026#34;query\u0026#34;:{ \u0026#34;filtered\u0026#34;:{ \u0026#34;filter\u0026#34;:{ \u0026#34;script\u0026#34;:{ \u0026#34;script_id\u0026#34;:\u0026#34;your_custom_script\u0026#34;, \u0026#34;lang\u0026#34;:\u0026#34;groovy\u0026#34;, \u0026#34;params\u0026#34;:{ \u0026#34;shift\u0026#34;:3 } } } } } } あまり変わっていないことに気づくでしょう。 scriptの部分が、前もって記述されたスクリプトの名前script_idに変更されただけです。\nElasticsearchにスクリプトを提供するダイナミックではない方法はインデックスに保存する代わりに、 ディスクにファイルとしてスクリプトを保存することです。 そうすることで、各スクリプトを設定として保存します。 これは、どのようなスクリプト言語に対してもダイナミックスクリプティングをオフにしたまま、 サンドボックス化されないスクリプトを使い続けることができる方法です。\n最初のサンプルで、Groovyスクリプトはdoc['field1'].value == doc['field2'].value + shiftでした。 これを、.groovy拡張子を持ったファイルとして書き出すことができます。\ndoc[\u0026#39;field1\u0026#39;].value == (doc[\u0026#39;field2\u0026#39;].value + shift) もし、このファイルにyour_custom_script.groovyちう名前をつけて、 Elasticsearchのすべてのデータノードのconfig/scriptsディレクトリに保存すると、 Elasticsearchは60秒(elasticsearch.ymlのwatcher.intervalで変更可能)でこのスクリプトを認識し、今後のリクエストに利用できるようにプリコンパイルするでしょう。 そのファイルはElasticsearch実行ユーザによって読み込みができる必要があります。 これをディスクに書き込んだ後、あなたの設定ディレクトリは次のようになっています。\nconfig/ elasticsearch.yml logging.yml scripts/ your_custom_script.groovy これは、各リクエストやインデックスされたスクリプトをスクリプトとして動的に送信しませんが、 信頼された環境にスクリプトを追加することでダイナミックスクリプトとなることを許します。\nディスクに書かれたスクリプトを使用する スクリプトは、ロードされたスクリプトになるまでは、利用できません。 ログファイルに次のようなログが表示されるまではです。\n[2015-02-11 11:14:47,066][INFO ][script ] [Sergei Kravinoff] compiling script file [/path/to/elasticsearch-1.4.3/config/scripts/your_custom_script.groovy] すべてのElasticsearchのデータノードでスクリプトが読み込まれたら、 それを利用することができます。 利用するために、file(script_idではありません!)としてスクリプト名を指定します。\nGET /_search { \u0026#34;query\u0026#34;:{ \u0026#34;filtered\u0026#34;:{ \u0026#34;filter\u0026#34;:{ \u0026#34;script\u0026#34;:{ \u0026#34;file\u0026#34;:\u0026#34;your_custom_script\u0026#34;, \u0026#34;lang\u0026#34;:\u0026#34;groovy\u0026#34;, \u0026#34;params\u0026#34;:{ \u0026#34;shift\u0026#34;:3 } } } } } } Note:langは必須ではありません。Groovyがデフォルトの言語のためです。 もし、違うスクリプト言語を使いたい、もしくは、デフォルトの言語を(例えば、Lucene Expressionsへ) 変更したい場合、言語が正しいスクリプトを見つけるために提供されている必要があります。 一番良い方法は、アプリケーションがlangパラメータを含んでいることを勧めます。 これは、将来、デフォルトのスクリプト言語が変更されても、問題ないからです。\n質問? もし、質問があれば、遠慮なくTwitter(@elasticsearch)で教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1423721589,"dir":"post/2015/","id":"1fed22e99b0e11a50eb7b92cb1644e8a","lang":"ja","lastmod":1423721589,"permalink":"https://blog.johtani.info/blog/2015/02/12/running-groovy-scripts-without-dynamic-scripting-ja/","publishdate":"2015-02-12T15:13:09+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:running groovy scripts without dynamic scripting Elasticsearch1.3.8と1.4.3のリリースによ","tags":["elasticsearch"],"title":"Groovyスクリプトをダイナミックスクリプトなしで実行(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:elasticsearch 1.4.3 and 1.3.8 released\n本日、Lucene 4.10.3をベースにしたElasticsearch 1.4.3と、セキュリティとバグフィックスリリースである、Elasticsearch 1.3.8をリリースしました。 ダウンロードおよび変更リストはそれぞれ次のリンクからアクセスできます。\n最新ステーブルリリース:Elasticsearch 1.4.3 1.3.x系バグフィックス:Elasticsearch 1.3.8 過去のリリースに関するブログ(公式)はこちら。\n1.4:1.4.2, 1.4.1, 1.4.0, 1.4.0.Beta1 1.3:1.3.7, 1.3.6, 1.3.5, 1.3.4, 1.3.3, 1.3.2, 1.3.1, 1.3.0. すべての変更については1.4.3のリリースノートおよび1.3.8のリリースノートをごらんください。 以下では、セキュリティの問題について紹介します。\ngroovy scripting の脆弱性 Elasticsearchのバージョン1.3.0から1.3.7および1.4.0から1.4.2で、Groovyスクリプトエンジンに脆弱性が発見されました。 脆弱性は、攻撃者がGroovyスクリプトをサンドボックスを避けて構築でき、 ElasticsearchのJava VMを実行しているユーザとしてシェルコマンドを実行できます。\nこの問題をCVE-2015-1427として報告済みです。\nバージョン1.3.8と1.4.3では、デフォルトで、Groovyに対してのサンドボックスをオフにしました。 結果として、ダイナミックスクリプトの実行はGroovyに対してもオフとなります。\nもし、脆弱性のあるバージョンで実行している場合、v1.3.8かv1.4.3にアップグレードするか、ダイナミックなGroovyスクリプトをクラスタの すべてのノードに対して次の設定を追加することで、オフにします。\nscript.groovy.sandbox.enabled: false これは、Groovyのサンドボックスをオフにし、リクエストの一部としてインラインで受け付けるダイナミックなGroovyスクリプトや 特殊な.scriptsインデックスに保存されているスクリプトを実行しません。\nそれまでは、各データノードのconfig/scriptsディレクトリにファイルとして保存されたGroovyスクリプトは まだ、利用可能です。詳細の情報についてはRunning scripts without dynamic scriptingをごらんください。\nfuture scripting plans 安全なダイナミックスクリプティング言語としてGroovyを失うことは、Elasticsearchにとって痛手です。 update APIやsearch APIやaggregationsフレームワークの一部としてScriptを使います。 それらは、静的なAPIでは簡単に表現できない、カスタムなトリックをユーザに実行できるようにします。\n残念ながら、Groovyチームとこの問題を議論した後、Groovy言語もサンドボックスによってきちんと保護されている というにはあまりにもダイナミックであるという結論に達しました。 Groovyは、デフォルトでは利用できなくなります。 利用可能なダイナミックスクリプト言語としてはLucene Expressions言語のみとなります。 Expressionsははやいですが、それらは非常に限定されています。数値のフィールドでのみ実行可能で、ループをサポートしていません。\nより強力で(しかし安全な)ミニ言語になるようにExpressionsを拡張することを調査しています。 これは、Scriptユーザが現在持っている最も一般的なユースケースを少なくとも助けるでしょう。 この拡張は長期間のプロジェクトであり、進化には時間がかかるでしょう。\nぜひ、Elasticsearch 1.4.3をダウンロードして、試してみてください。 そして、感想をTwitter(@elasticsearch)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1423712393,"dir":"post/2015/","id":"5badf61ecb9cfadd7d6af58712fa5f6f","lang":"ja","lastmod":1423712393,"permalink":"https://blog.johtani.info/blog/2015/02/12/elasticsearch-1-4-3-and-1-3-8-released-ja/","publishdate":"2015-02-12T12:39:53+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:elasticsearch 1.4.3 and 1.3.8 released 本日、Lucene 4.10.3をベースにしたElas","tags":["elasticsearch"],"title":"Elasticsearch 1.4.3および1.3.8リリース(日本語訳)"},{"contents":"今年もCROSS参加しました。そして、話もしてきました。 今年は横浜の大さん橋でした。横浜はあんまりこないので、乗り換えでおたおたしてしまいましたが。。。\nなかなかいい景色でした。(寒いけど) 「おおさんばし」って読むんですね。「だいさんばし」だと思ってた。。。\n以下はいつもの、自分用メモです。\n俺はどうしてそのデータストアを選択したのか 〜銀河と小宇宙を語る会〜 http://2015.cross-party.com/program/c1\n遅れて入ったので、ちゃんと聴けてないです。\n最近注目しているデータストアは? Postgresql。JSON型が気になってる。 AiroSpike。データ型のあるデータストアが気になってる。 MongoDB。JSON使いたいなら、これじゃないの? AWSのAurora。インスタンスタイプを選ばなくていい(選ばないといけないらしい)とか、勝手にスケールしてくれるし、MySQL互換。 今こそ語るエンジニアの幸せな未来 http://2015.cross-party.com/program/x3\n「無職初日です。」 Web系の人?とか質問されて、自分が何系かいつもわからなくなるなぁ。 「働きがいは会社が提供するのか、個人が見つけるのか?」 個人かなぁ。会社がなにをやってるかにもよる気がするかなぁ。 「辞めると伝えると、やりたいようにやれって言われるw」 リモートできるかできないか。 「働きがい」というキーワードが出てると普通は怪しい会社w 今は、働きやすさを高くしないと人が雇えなくなってきている。 欧米のミドルウェアだと、35歳定年説はない。→日本でもそうじゃないですか? 漫然と進んでるとダメ。→そりゃそうだ。 全文検索エンジン群雄割拠〜あなたが使うべきはどれだ!〜 http://2015.cross-party.com/program/c4\nスライド:https://speakerdeck.com/johtani/elasticsearchfalseshao-jie-tote-zheng-cross-2015\n楽しんでいただけましたでしょうか? ちょっと話が長くなってしまい、あとの方の時間が少なかった気がしますが。。。\nKibanaのバックエンドとして認識されている人もいたので、検索エンジンですよというのをアピールするいい機会になったので良かったです。 もちろん、Kibanaとの組み合わせも面白いので、少しでも興味をもっていただき、触っていただけたらなぁと。\n話をする機会を用意していただいた、やまかつさん、その他のスピーカーのみなさん、ありがとうございました!。\nElasticsearchに関して何か興味質問などありましたら、気軽にコンタクトしてください。Twitterとかブログコメントなどで。\nプレモルタイム以降 プレモルの写真撮るの忘れてました。。。重要なのに。。。\n美味しくプレモルをいただきながら、何人かの方に声をかけていただき、話をすることができました。 こういう時間がとってあるのがいいですよね。 色々なところでElasticsearchを使っていただいているようで、うれしい限りです。 DMMの方とも話ができたし。\nまとめ 今年はプレモルを飲みに行くだけかなぁと思っていたのですが、話をする人になってました。(おかしいなぁ) 来年もあれば、きっと参加するかなぁと。ではまた来年!\n夜景きれいですね。(端っこに写ってる船は飛鳥IIでした。)\n","date":1422500368,"dir":"post/2015/","id":"fe6ba10cc6c9509b4b22e9d59e029775","lang":"ja","lastmod":1422500368,"permalink":"https://blog.johtani.info/blog/2015/01/29/talk-at-cross2015/","publishdate":"2015-01-29T11:59:28+09:00","summary":"今年もCROSS参加しました。そして、話もしてきました。 今年は横浜の大さん橋でした。横浜はあんまりこないので、乗り換えでおたおたしてしまいま","tags":["勉強会","elasticsearch"],"title":"CROSS 2015で話をしてきました #cross2015"},{"contents":"今年は大晦日になってしまいました。しかも、ちょっと飲んでたり。。。 第9流しながら書いてます。\n振り返り(2013年に書いた抱負から) まずは昨年書いた抱負からの振り返りです。\nElasticsearch勉強会の継続、Solr勉強会の継続+ミックスした検索勉強会の開催 IDEAのさらなる活用 もっと開発(プラグインとか) AWSをもう少し活用 海外のイベントに行ってみたい 読書と英語を継続 AWS活用できてないです、、、 ミックスした勉強会は、ドタバタしててできませんでした。\nIDEAはさらなる活用までいってるかは不明ですが、最近は隣にとても詳しい人が座っているので色々と教えてもらってます。 開発については、ちょっとずつですが、PR書いたりしてます。\n振り返り(今年あったできごと) 初海外(ベルリンとアムステルダム) Elasticsearchに転職 初献本? Elasticsearch勉強会の定期開催 ElasticSearch Serverの翻訳 サーバ/インフラエンジニア養成読本の執筆 勉強会以外でもスピーカー 英語の継続(切実) 初ものが多かったです。 初の海外の会社、初の海外旅行(仕事)、初の献本(著者の人から、多分、初)、初の翻訳本、初のムック本執筆などなど。\n初の海外でした。なのに、夏には海外の会社に転職してみてるとか、ちょっと自分でも信じられません。 ベルリンでは、海外の勉強会にも参加できて非常に有意義でした。 ヨーロッパの街並みは、日本では経験できない雰囲気で、向こうの方には普通の街並みも自分にはとても新鮮でした。\n転職自体は2回目ですが、海外の会社というのは初めてです。日々、英語\u0008の勉強になりますし、いろんな刺激を受けています。 英語の勉強自体も継続中です。英語力が不足しているのは自覚してるので、少しでも英語に触れるようにDLifeで海外ドラマを録画して、通勤時間帯にみるなどを試みてます。\n書籍には、昨年につづき関わることができました。来年も何かしらの書籍に関われることができればなと。 (\u0008気になる人は以下のリンクから。。。)\n分かりきったことですが、Elasticsearchな1年でした。 転職してあっという間の半年です。まだまだやりたいことがいっぱいあるので、来年もバランスよく頑張らないと。\n来年の抱負 英語の継続 海外のイベントへの参加 多岐にわたるイベントでのスピーカー 日本の人員の倍増!? Elasticsearchに関する日本語の情報発信 Elasticsearch座談会みたいなものの開催 英語の継続については書くまでもないですね。 海外のイベントへの参加もかなぁ。3月にサンフランシスコに行くとは思います。 そのほかには、今度こそBerlin Buzzwordsに行きたいです。\nElasticsearch勉強会以外のイベントでもElasticsearchを広めるべく色々なところでスピーカーをしたいなと思っています。 検索、ログ解析で少しは知名度が上がってきていますが、別の言語のコミュニティやイベントでは、まだまだ、elasticsearch自体を知らない人もいると思います。まずは知ってもらうところからかなと。\n日本の人員の倍増については、今年も達成してます(一人が二人になりましたw)。 来年も倍増できればうれしいなと。同じ母国語の同僚がいるのはやっぱりうれしいし、心強いですから。\n来年は(も)、日本語での情報をどんどん発信していきます。サイトやガイドなども 日本語にしたいなと。 あとは、これまで、勉強会でスピーカーをしていただいた人だけを集めた座談会のようなものも開催したいなと考えています。 私自身も色々と聞きたいことがありますし。 そのほかにも色々と要望をお待ちしています。Twitterやブログのコメント欄などで気軽にコンタクトしていただければと。\n最後は、いつものようにですが、来年も勉強会やいろんなイベントに参加する予定です。 ブログも週1程度で書く努力しないとなぁ。 こんな話を書いてくださいとかのリクエストもお待ちしています。\n今年はあと、数時間ですが、色々とお世話になりました。 この場を借りてお礼申し上げます。\n来年も、いろんな方に絡んでいくとは思いますが、よろしくお願いいたします。\n","date":1420026086,"dir":"post/2014/","id":"b36abffbe5d6a0de73a9968604a1a3f9","lang":"ja","lastmod":1420026086,"permalink":"https://blog.johtani.info/blog/2014/12/31/looking-back-2014/","publishdate":"2014-12-31T20:41:26+09:00","summary":"今年は大晦日になってしまいました。しかも、ちょっと飲んでたり。。。 第9流しながら書いてます。 振り返り(2013年に書いた抱負から) まずは昨年","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2014)"},{"contents":"この記事はElasticsearch Advent Calndar 2014の25日目のエントリです。\nあっという間に最終日です。来年につなげるという意味で、Elasticsearchの2系のIssueをいくつかピックアップして紹介してみます。\n現在、ElasticsearchのGitHubリポジトリは、大きく3つのブランチで作業しています。 master、1.x、1.4です。masterと1.xの大きな違いとしては、masterはLuceneの5.x系を採用している点です。\nなお、これから紹介するIssueは現在、確定していない項目も含んでいます。実際に2.0がリリースされるタイミングでは 採用されない場合もあります。\nUpgrade master to lucene 5.0 snapshot #8347 (closed) https://github.com/elasticsearch/elasticsearch/pull/8347\n先ほど書きましたが、Luceneの5に対応するためのPRです。 Lucene 5に関してはLuceneのコミッターのMikeさんのブログ記事も参考になります。\nLucene 5に変更することで、BitSetに関する改善が多く含まれることになります。 メモリの利用量、圧縮などの改善が多く含まれています。 もう1点大事な点としては、Lucene 5系ではLucene 3系のインデックスを読み込むことができなくなる点です。 Luceneの下位互換の範囲は1つ前のメジャーバージョン(5.x系の場合は4.xまでが対象)となっています。\nFilter cache: add a _cache: auto option and make it the default.(closed) https://github.com/elasticsearch/elasticsearch/pull/8573\nFilter cacheは、trueもしくはfalseの設定が利用できますが、filterの種類にも依存します。 その辺りの条件を加味しつつ、よしなにCacheをコントロールしてくれます。\nRemove and/or/not in favour of bool filter #8960(open / discuss) https://github.com/elasticsearch/elasticsearch/issues/8960\n似ているが少し異なるand、or、notフィルタとboolフィルタが存在しています。 これらをわかりやすくするために、boolフィルタに統一しましょうという話し合いをしています。\nInput validation #9059(open / discuss) https://github.com/elasticsearch/elasticsearch/issues/9059\n色々な入力に関するチェックを追加しようというIssueです。 たとえば、ディレクトリ名やファイル名、URLのパスやクエリストリング、フィールドのパスやスクリプトなどです。 Validationがあると、変な設定をして頭をかかえることもなくなるかなぁと。\nRefactor analysis framework #8961(open) https://github.com/elasticsearch/elasticsearch/issues/8961\n新しくAnalyzerを作った場合に、色々な場所に登録必要があったりします。インデックスレベルとノードレベルです。(Kuromojiプラグインなどが参考になります。) また、インデックスごとにカスタムのAnalyzerを設定するので、1つのノードに同じAnalyzerを何度も設定しないといけません。 よりシンプルにするために、Analyzerをノード単位で設定しようという提案です。\nRemove possibility for conflicting field definitions and ambiguous field resolution #8870(open) https://github.com/elasticsearch/elasticsearch/issues/8870\n同じインデックスに、異なるtypeで、同じフィールド名があった場合、いろいろと良くないことがあったりします。 たとえば、フィールドのタイプがintegerとstringと異なる場合に、インデックスレベルで検索を行うとうまく検索できなかったりと。 この問題を解消するために、より明確にしようというIssueです。 たとえば、フィールド名を指定するためには、フルパスで記述をするだとか、フィールドマッピングに関してはインデックスレベルで内部で保持をするなど。\nValidation of mappings request to reject unsupported fields #7205(closed) https://github.com/elasticsearch/elasticsearch/issues/7205\n1.xでも取り込まれますが、嬉しい機能なので紹介します。 これまでは、mappingsでスペルミスをした場合(たとえば、field設定で\u0026quot;indexx\u0026quot;といったミス)には、その項目は単に無視されるだけでした。 これが、v1.xでは、エラーに\nまとめ ということで、簡単ですが、v2.0.0に向けたIssueをピックアップして紹介してみました。 上記以外にも多くの改善、提案が2.0に向けて行われています。 興味のある方は、v2.0.0ラベルでIssueを検索してみてはいかがでしょうか?\n今年もあとわずかとなりました。 今年の2月にElasticsearchの1.0がリリースされ、あっという間に1.4なりました。まだまだ改善しています。\n来年もElasticsearchに興味をもっていただければ嬉しいです。 Elasticsearch初のユーザカンファレンスのサイトもオープンしました。 Elasticsearchに関するいろいろな話が聞ける機会だと思います。登録をお待ちしています。\n","date":1419490380,"dir":"post/2014/","id":"cb9649eca3dfbd356527ffc88f1dcb94","lang":"ja","lastmod":1419490380,"permalink":"https://blog.johtani.info/blog/2014/12/25/pickup-elasticsearch-2-0-0-labels/","publishdate":"2014-12-25T15:53:00+09:00","summary":"この記事はElasticsearch Advent Calndar 2014の25日目のエントリです。 あっという間に最終日です。来年につなげるという意味で、Elasti","tags":["elasticsearch"],"title":"Elasticsearch 2.0系のIssueの紹介"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:marvel 1.3.0 released\n12/17に、Elasticsearch Marvel 1.3.0をリリースしました。 Marvelの以前のリリースから、Elasticsearchでは様々なことがありました(Elasticsearch 1.4のリリースなど)。 このバージョンでは、モニタリングにクエリキャッシュや新しいcircuit breakerなどのような機能を追加してあります。 Senseのナレッジベースは最新のAPIを含むものに拡張されています。 また、Shieldのリリースに向けた準備として、HTTPsのサポートも追加しました。\nアップグレードのために、Elasticsearchの全てのノードに最新版のMarvelプラグインをインストールする必要があります。 また、他のJavaプラグインと同様に、Marvelの新バージョンを有効にするために、各ノードを(1台ずつ)リスタートする必要があるでしょう。 アップグレードプロセスについての詳細は、Marvelドキュメントをごらんください。\nまとめとして、ここに本リリースに関する改善点をいかにリストアップしておきます。\nagent 追加: httpsのサポート デフォルトのMarvelの設定(以前は常に9200)ではなく、ローカルノードのポートを自動的に検出 改善: marvelインデックステンプレートに関するエラーチェックと耐障害性(それに対するチェックと追加時のチェック) エラーログに関するくり返しの抑制 URLパラメータによるインデックス名を指定する_bulk exportコマンド。これは、rest.action.multi.allow_explicit_indexがfalseに設定されているときに有用 修正: ES 1.4.0のtribe nodeがMarvelのインストール時に初期化されない問題 削除: UIで表示されないoptional shard level statsを除去 monitoring ui 追加: ES 1.4.0で導入された新しいcircuit breakerを追加 circuit breakerのlimitをグラフにプロット QueryCacheのグラフを追加 index throttlingのグラフの追加 Index writerとバージョンのmapのメモリ使用量のグラフの追加 修正: Network Transport Bytes Receivedグラフに実際の送信量を表示 Node Statsダッシュボードでいくつかのスレッドプールの不足 sense 追加:\nmappingsをインデックスでオートコンプリートするしないの設定を可能に Cluster Reroute API Search APIのQuery Cacheパラメータ Analyze API Validate Query API Put Percolator API cluster.routing.allocation.*設定 Function Scoreクエリのweightパラメータ Flush API Terms Aggregationのshow_term_doc_count_errorパラメータ Update API _geo_distanceソートオプション Significant Terms aggregationを1.4.0にアップデート Mapping APIにメタデータフィールドを追加 Get Index API Scripted Metric Aggregation simple_query_stringクエリ More Like Thisクエリを1.4.0にアップデート has_childクエリ/フィルタのmin_childrenとmax_childrenオプション terms aggs/significant terms aggsのヒントオプション Mappings APIのtransform インデックスされたscriptとtemplate \u0008* Geo Bounds aggregation Top Hits aggregation Terms aggregationのcollect_modeオプション Percentiles Rank aggregation Disk Threshold Allocator設定 修正:\nURLオートコンプリートの挙動(プロトコルとホストのような組み合わせ) nested typeマッピングのinclude_in_parentとinclude_in_rootの不足 Rangeフィルタでのgt、gte、lt、lte Existsフィルタのオートコンプリート Snapshot、Restore APIのリポジトリ設定の時オートコンプリートの失敗 いつものように、Elasticsearch Marvelを改善するために、フィードバックをお待ちしています。 ElasticsearchユーザMLやTwitterに質問や意見お送りください。\n","date":1418890008,"dir":"post/2014/","id":"7dea465ad52758b10cbceb08c81d1760","lang":"ja","lastmod":1418890008,"permalink":"https://blog.johtani.info/blog/2014/12/18/marvel-1-3-0-released-ja/","publishdate":"2014-12-18T17:06:48+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:marvel 1.3.0 released 12/17に、Elasticsearch Marvel 1.3.0をリリースしました","tags":["elasticsearch","marvel"],"title":"Marvel 1.3.0リリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:elasticsearch 1.4.3 and 1.3.8 released\n本日、Lucene 4.10.3をベースにしたElasticsearch 1.4.3と、セキュリティフィックスとバグフィックスリリースである、Elasticsearch 1.3.8をリリースしました。 ダウンロードおよび変更リストはそれぞれ次のリンクからアクセスできます。\n最新ステーブルリリース:Elasticsearch 1.4.3 1.3.x系バグフィックス:Elasticsearch 1.3.8 過去のリリースに関するブログ(公式)はこちら。\n1.4:1.4.1, 1.4.0, 1.4.0.Beta1 1.3:1.3.6, 1.3.5, 1.3.4, 1.3.3, 1.3.2, 1.3.1, 1.3.0. すべての変更については1.4.2のリリースノートおよび1.3.7のリリースノートをごらんください。 以下では、重要な変更について紹介します。\nbug fixes Elasticsearchに対して広範囲にわたってランダムなテストを行っています。以下の問題を見つけ、修正するのに役立っています。\nプライマリシャードを持つnodeがレプリカシャードをプライマリから復旧している間に、リスタートした場合に、プライマリ上のトランザクションログが削除されデータをロスする(#8917) scriptインデックスが普及した場合に、ScriptService全体がデッドロック(#8901) Index Writerのロックを強制的に解放することによるシャードの破損(#8892) パフォーマンス改善 複雑な設定をもつ大きめのクラスタをもつユーザは、小さなスケールではわからない性能ボトルネックに直面します。 彼らの報告が次の改善をもたらす助けとなりました。\n使用可能なディスク空間に基づいてシャードの配置を決定する、disk allocation deciderの速度改善とクラスタリスタート後のリカバリ速度の改善(#8803) 以前よりも高速な共有ファイルシステムでのSnapshot生成(#8749) 不要なクラスタ状態変更の削減とそれによるネットワークトラフィックの削減およびリカバリの速度向上(#8933, #8413) index stats APIはシャードリカバリによるブロックしない(#8910) 試してみてください。 ぜひ、Elasticsearch 1.4.2をダウンロードして、試してみてください。 そして、感想をTwitter(@elasticsearch)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1418880374,"dir":"post/2014/","id":"bce2fa6458f39a75e2713f3d687271a1","lang":"ja","lastmod":1418880374,"permalink":"https://blog.johtani.info/blog/2014/12/18/elasticsearch-1-4-2-released-ja/","publishdate":"2014-12-18T14:26:14+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:elasticsearch 1.4.3 and 1.3.8 released 本日、Lucene 4.10.3をベースにしたElas","tags":["elasticsearch"],"title":"Elasticsearch 1.4.2および1.3.7リリース(日本語訳)"},{"contents":"「【東京】JJUG ナイト・セミナー「機械学習・自然言語処理特集!」12/17(水)開催」でLuceneの話をしてきました。 本当にごく簡単な入門です。 Luceneをさわるきっかけにしてもらえたら嬉しいです。\nそのほかにも面白い話が聞けましたので、簡単ですがメモを。\nJJUGの2014年振り返り だいたい、毎月ナイトセミナーかCCCを開催 イベント系に、のべ3100名が参加 Java でカジュアルにはじめる機械学習 小宮 篤史さん(スマートニュース株式会社) スライド:#JJUG - Java でカジュアルにはじめる機械学習\nブログ:#JJUG ナイトセミナー「機械学習・自然言語処理特集!」で Java でカジュアルに機械学習する話をしてきました\nガチの人は寝ててください。 機械学習でできること 分類・識別 予測・回帰 パターンマイニング・アソシエーションルール クラスタリング 上2つは教師あり学習/下2つは教師なし学習 データとしては、日構造では扱えないので、「特徴量」を抽出して「特徴ベクトル」を作って、処理をするのが機械学習 得られた結果の正しさの測定などなど\n機械学習の実装は辛いので、車輪の再発明をやめましょう! \u0008Javaで使える機械学習\nWeka:とりあえず使ってみるならこれ? MLlib:Sparkで使われてる Mahout:オワコン? SAMOA:Stormの上で利用できる Jubatus:Javaクライアントあり。 h2o:Deep learningをJavaでやるなら、これ。 ほかにもあったけど、スライド見ていただければ。 機械学習をはじめるのに使えるデータセット\nUCI Machine learning repository\nIris(アヤメデータ)は機械学習界のHello world Wekaを使ったサンプルコード\nSpark/MLlibではじめるスケーラブルな機械学習 猿田 浩輔さん(株式会社エヌ・ティ・ティ・データ) スライド:(後日、リンクがあれば更新予定)\n\u0008* Spark+MLlibを語る上で外せない話題\nHadoopとの違い?\nまずはHadoopの話\nHadoopによるK-meansのデモ\nHadoopの問題点に対するSparkの解決策\nSpark 1.0系からJava8で書ける\nQA:\nQ: データをキャッシュできるという話でしたが、キャッシュするということは、ジョブが途中で失敗した場合は最初からやり直しになるのでしょうか? A: キャッシュしたデータが残っている場合は、途中から再開出来ます。キャッシュしたデータを持ったマシンがこけたら、最初からやり直しです。\nLuceneと日本語の検索 自分 スライド:Luceneと日本語の検索 サンプルのリポジトリ:jjug-example\n自然言語処理にからめて何か話をしてくださいと話を受けていたのですが、自然言語処理については「形態素解析」くらいしか出てこなかったですけど。。。 Luceneがどんなものかを超概要で話をしてみました。少しでもLuceneがどんなものかをわかってもらえたら嬉しいです。\nもっと詳しく知りたい方は、スライドにある参考資料などを見ていただければと。\nJavaで書くのもいいんですが、もっと簡単に検索したい場合はElasticsearchを使うのが便利ですよ!で締めくくりたかったのですが、発表では失敗してしまいました。。。 Elasticsearchの起動からデータ登録、検索まではこちらのスライドを見ていただければ簡単さがわかると思います。\nまた、Kuromojiを利用した時に、Tokenizerなどが出力するTokenの品詞情報を見たい場合に便利なElasticsearch用プラグインも作っています。 こちらも、Elasticsearchと一緒に使ってみてください。\nまとめ 機械学習に関していろんなツールがあるのだなぁと。 懇親会でもちょっと話しましたが、アルゴリズムの選定とか、アルゴリズムに適したデータの作成など、前処理のノウハウとかが大変そうだなぁといつも思います。 機械学習はいつもぼやーっとしか理解してないので。。。\nJJUGさんはYouTubeの動画もあるようなので、過去の面白そうなセミナーも合わせてみてみると面白いと思います。\n毎度のことですが、なんでも良いので、発表した後のフィードバックをいただけるとうれしいです。 今後の励みや改善につながるので。\n","date":1418809314,"dir":"post/2014/","id":"e5390751969ab21df280b7591854b89f","lang":"ja","lastmod":1418809314,"permalink":"https://blog.johtani.info/blog/2014/12/17/jjug-night-seminar-dec-2014/","publishdate":"2014-12-17T18:41:54+09:00","summary":"「【東京】JJUG ナイト・セミナー「機械学習・自然言語処理特集!」12/17(水)開催」でLuceneの話をしてきました。 本当にごく簡単な入","tags":["elasticsearch","jjug"],"title":"JJUG ナイトセミナーでLuceneの簡単な紹介をしてきました。#JJUG"},{"contents":"たまには、他愛のないブログを。\n仕事しながら、コーヒーを飲んでます。\n最近は、サムライズムさんのオフィスに入り浸って仕事してます。 オフィスには、コーヒーミル付きのコーヒーメーカーがあるんです。\n↓こんな感じ(現物は違うけど)\nで、近所のコーヒー問屋で豆を買ってきてます。 そこのマスターに、いつもサジェストされるんです。\n「この豆は、日が経つにつれて、細かく挽いて飲んでください。」\n「この豆は、細かめに挽いて飲むのがオススメです。」\nなどなど。 オススメされるんですが、全自動のコーヒーメーカーは残念ながらここまでやってくれません。\nということで、手動のミルを買ってみました。家でも使えるし。\nちょっと考え事しながらとか、頭の切り替えに、ミルを回すのもいいかなと。 気持ち、美味しいコーヒーな気がします(気のせいかも)\n","date":1418698892,"dir":"post/2014/","id":"05330c3703d0e2c96cfe657ab33f130c","lang":"ja","lastmod":1418698892,"permalink":"https://blog.johtani.info/blog/2014/12/16/a-coffee-break/","publishdate":"2014-12-16T12:01:32+09:00","summary":"たまには、他愛のないブログを。 仕事しながら、コーヒーを飲んでます。 最近は、サムライズムさんのオフィスに入り浸って仕事してます。 オフィスには、","tags":["misc","coffee"],"title":"コーヒーブレイク"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:exciting logstash plugin ecosystem changes\nLogstash 1.5.0 Beta 1(お試しはこちら)のリリースで、 プラグインのインストール、管理、公開の方法を変更しています。 ユーザやコミュニティからフィードバックをもらいました。 その目的は、プラグインの利用や開発をより簡単にすることです。 このプロジェクトは始まったばかりです。プラグインのコミュニティを探し、 共有するためのワンストップソリューションを提供するこのアイデアを改善していく予定です。 このブログで、この決定を行った理由を説明し、新しいワークフローをと今後のロードマップを説明します。\nプラグインがあります! Logstashは、プラグイン(input、filter、output、codec)が豊富にあります。 これらは、Elasticsearchにより開発されたものと、コミュニティからコントリビュートされたものです。 Logstashの主な特長の1つは、これらのプラグインの有効性と動作を拡張するプラグインを追加するのが簡単なことです。 現在、165以上のプラグインがエコシステムにあり、これらは、2つのプロジェクトに分かれています。\nlogstash-coreは最もよく使われるプラグインで、Logstashにデフォルトで含まれます logstash-contribはコミュニティにより開発されたプラグインを含み、別途ダウンロードできます 新プラグインエコシステムの変更 1.5.0では、全てのプラグインは、Logstashコアから分離され、rubygemsを使って個別にパッケージングされます。 rubygemsを選択したのは、依存関係のあるライブラリの配布とパッケージングがパワフルで一般的なものだからです。 さらに、rubygems.orgプラットフォームは配布や探索に影響があります。 また、Logstashにプラグインをインストール、アップデート、削除するのが簡単な基盤も追加しました。 contribプロジェクトは徐々に終了します。全てのプラグインは個別のプロジェクトになります。\nプラグインエコシステム変更の理由 多数のプラグインをもっていると、配布と公開に関して難題が出てきます。 私たちが変更するに至った理由は次のようなものです。\n現在は、プラグインの更新に伴い、Logstashの新バージョンのリリースが必要 開発者は、Logstashのリリース間隔とは別に、新バージョンをリリースをしたい プラグイン開発者は、外部依存を記述できるようにしたい Logstashコアの配布パッケージのダウンロードサイズを小さくし、ユーザは必要なプラグインのみインストール logstash-contribを1つのリポジトリとして管理するのは難しい 詳細: ソースコードの場所 Logstashのソースコードは、今後も現在のGitHubのリポジトリのままです。 しかし、プラグインに関するコードやテストコードは含まなくなります。 この分離により、個別のプラグインの改善と同様にコアの改善に集中できます。 これにより、Logstashプロジェクトの全体の品質も向上します。\n全プラグインのソースコードは、新しいGitHub organization、logstash-pluginsにて管理します。 各プラグインは個別のリポジトリとして、ここに配置されます。 一見すると、これはメンテナンスが難しくなるように思えます。しかし、テスト、Issue、依存関係を明確にすることができます。 私たちの目的は、テスト、ドキュメント、gemの公開の自動化であり、これを簡単にするためのツールを追加します。\nしかし、プラグインの開発者はプラグインのソースコードソースコードをlogstash-pluginsに置く必要はありません。 ー コミュニティで利用可能にするために、rubygems.orgでそれを公開するだけで良いです。\nワークフロー ここで、新プラグインエコシステムのやりとり/ワークフローについて、いくつかの観点から説明します。\nlogstashユーザ: ユーザは、これまでのリリース同様にLogstashのバイナリをダウンロードします。 Logstash 1.5.0は、1.4.2でパッケージされていたプラグインと同等のものが含まれています。 新しいシステムに簡単に移行できるようにです。 そして、ユーザは、最初のデプロイの後に、Logstashプラグインのをインストール、アップグレードできるようになります。\n$LS_HOME/bin/pluginスクリプトがプラグイン操作に関連するコマンドになります。\nプラグインのインストール プラグインのほとんどはgemとしてrubygems.orgにアップロードされます。 例えば、もしユーザがApache Kafka outputプラグインをインストールする場合、次のコマンドを実行します。\nbin/plugin install logstash-output-kafka または、ファイルをダウンロード済みの場合は次のコマンドとなります。\nbin/plugin install /path/to/logstash-output-kafka-1.0.0.gem プラグインの削除 bin/plugin uninstall logstash-output-kafka 1つまた全プラグインのアップデート bin/plugin update bin/plugin update logstash-output-kafka プラグインのリストアップ bin/plugin list bin/plugin list elasticsearch ( List all plugins containing a name ) bin/plugin list --group output ( list all outputs ) ドキュメント プラグインが個別に管理されても、全プラグインのドキュメントは1カ所です。\nlogstash plugin開発者: プラグイン開発者と作者は、Logstashエコシステムのためにプラグインを公開することができます。 プラグインは、gemやJavaライブラリの依存関係を宣言できます。 より重要なのは、Logstashのリリース間隔に関係なく、プラグインの改善版をリリースできます。\nRubygemsテクノロジはパッケージングシステム、依存関係管理、ホスティングのために選択されてきました。 Rubyのgemを公開することに慣れている開発者は、Logstashプラグインを簡単に公開することができます。 Elasticsearchはこれらの機能に関して開発者を支援するために、ツールを提供、メンテナンスします。\n開発およびローカルでのテスト JRuby 1.7.16がプラグインを開発するための唯一の前提条件です。 プラグインにパッチを提供するのは以前と同様です。 例えば、logstash-output-kafkaにパッチを送るのは次のようになります。\ngit clone https://github.com/logstash-plugins/logstash-output-kafka.git 変更 プラグインをローカルでテスト bundle install bundle exec rspec Logstashの他のバージョンもしくはローカルでテストする場合、Gemfileを編集し、 次のように別のロケーションを加えます。gem \u0026quot;logstash\u0026quot;, :github =\u0026gt; \u0026quot;elasticsearch/logstash\u0026quot;, :ref =\u0026gt; \u0026quot;master\u0026quot; 新しいPull Requestをlogstash-output-kafkaに対して作成 コミュニティでコードレビューを受け、Elasticsearchがパッチを受け入れ バージョン バージョン情報は、それぞれのプラグインの.gemspecで管理します。 例えば、Apache Kafka outputのgemspecはこちらです。 バージョニングはsemantic versioningのルールに従い、 Logstashのバージョニングとは別に、プラグインの開発者によって管理されます。 Logstash 1.5.0がリリースされると、マイルストーン1のプラグインはバージョン1.0.0となり、マイルストーン2のプラグインはバージョン2.0.0となるでしょう。\n公開 開発者が変更を加えプラグインを公開したいと思った時、.gemspecのバージョン番号を変更します。 全テストが成功した時、Elasticsearchはrubygems.orgにプラグインを手動で公開します。 もし、テストが失敗した場合、プラグインは公開されません。 長期的には、プラグインの公開の自動化を行いたいと思っています。 この変更は新しいため、公開の自動化を提供する前に、自動化についてより理解し、プラグインのテスト基盤を改良したいと思っています。\nIssue Issueは、各プラグインのGitHubリポジトリに対してオープンなければなりません。 Logstashコアのリポジトリは、コアのパイプラインや共通的な機能に関連するIssueについて扱います。\nドキュメント プラグインのドキュメントはソースコード自体から生成されます。 それぞれのプラグインのドキュメントは、そのプラグインのリポジトリに含まれます。 Elasticsearchは elasticsearch.org/guideに全てのプラグインのドキュメントを集め生成できる基盤を提供します。\n移行 全ての新しいpull requestとissueはlogstash-plugin organisation配下にある各プラグインのリポジトリに対してオープンする必要があります。\nすでにあるPRはどうすれば良いですか? 気にしないでください。すでにあるpull requestは開発者によって移行する必要はありません。 LogstashチームがLogstashコアリポジトリに対してのPRを、個別の関連するプラグインのリポジトリに対してマージします。\ngit clone … # clone the specific plugin repo # now apply the patch curl -s https://github.com/elasticsearch/logstash/pull/XXXX | git am --3way git push Note:このプロセスはすでにあるPRに対してgit historyを管理します\nGitHub Issue 現在、LogstashリポジトリにオープンされているIssueは、それぞれのプラグインのリポジトリに移行します。 Logstashチームがgithub.com APIを利用してこの処理を自動的に行います。 安心してください。私たちが個別のプラグインに対する既存のIssueを移行します。\n今後のロードマップ これは、最初のステップであり、これらの変更は、ユーザや開発者に対してエコシステムをよりよくするために、 しっかりとした基盤を提供します。\n短期的には、開発者のためにpull requestのフィードバックでテスト自動化を提供する基盤を追加していきます。 プラグインリポジトリのブートストラップや管理のためのツールも提供していきます。\n長期的には、すべてのLogstashプラグインを探し、公開するためのコミュニティポータルを提供したいと思っています。 このアイデアは、Puppet ForgeやAWS marketplaceのようなものです。\nLogstash 1.5.0 Beta 1をリリースし、これは新しいエコシステムを提供します。 ぜひ、試していただき、これらの変更に関して感じたことを教えてください。 あなたのフィードバック(TwitterもしくはGitHub)はとても貴重です!\n","date":1418486440,"dir":"post/2014/","id":"4a3c42c9c5ac29db268010bbebf4f579","lang":"ja","lastmod":1418486440,"permalink":"https://blog.johtani.info/blog/2014/12/14/plugin-ecosystem-changes/","publishdate":"2014-12-14T01:00:40+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:exciting logstash plugin ecosystem changes Logstash 1.5.0 Beta 1(お試しはこちら)のリリースで、 プラグインのインストー","tags":["logstash"],"title":"Logstashプラグインのエコシステムの変更(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:logstash 1.5.0.beta1 released\nLogstash 1.5.0 Beta1をリリースしました。こちらのページからダウンロードできます。\nNote: ベータリリースです。本番環境では使用しないでください。\n1.5.0の主な変更点は? 1.5.0の主なテーマはプラグイン管理、パフォーマンス改善、Apache Kafkaインテグレーションです。Logstashの主な特徴の1つは プラグインを利用できることであり、パイプラインの動作を拡張するためにプラグインを追加するのが簡単なことです。 このリリースで、プラグインの開発、管理、公開がより簡単になります。 また、Logstashの速度をより良くしたため、より多くのデータを短時間に処理することができます。 興味ありませんか?では、詳細を見ていきましょう。\nplugin ecosystemの変更 Logstashは165ものプラグイン(inputs、filters、outputs、codecs)を持っており、 これらはElasticsearchとコミュニティからのコントリビュートで開発されています。 多くのプラグインを管理することは、使いやすさと素早さの間のトレードオフがあります。 Logstashの全てのプラグインをまとめることは使いやすさがある一方、プラグインの更新を取り込むために Logstashの新しいリリースを待ってもらうことになります。 Logstashからプラグインを分離して個別に配布する場合、更新は簡単になりますが、使いやすさ(特に新しいユーザに)に影響が出ます。\n私たちは、プロジェクトを前進させるために、これらのバランスをとることを考えました。 これまで、全ての利用可能なプラグインは’core’と\u0026rsquo;contrib\u0026rsquo;の2つに分割していました。 \u0026lsquo;core\u0026rsquo;にあるよく使われるプラグインは、Logstashに含めていました。 コミュニティによりコントリビュートされたプラグインは\u0026rsquo;contrib\u0026rsquo;パッケージとして分離して配布していました。 1.5.0のリリースで、ユーザに対してより良いプラグイン管理をできるように変更しました。 全てのプラグインは、それ自身によるパッケージに移行しました。 パッケージングフレームワークとしてrubygemsを使い、rubygem.org経由でこれらのプラグインを配布、公開します。 また、Logstashにプラグインのインストール、更新、削除を簡単にするための構造も追加しました。\n例えば、S3 output pluginをインストールするには、以下のコマンドを実行します。\n$LS_HOME/bin/plugin install logstash-output-s3 それだけです!Logstashがgemと依存するgemをrubygems.orgからダウンロードし、インストールします。 あなたは、S3にデータを送ることができるようになります。\nダウンロード可能なLogstashリリースはプラグインをまだ多く含んでいますが、 いつでも、個別にプラグインをアップグレードし、インストールすることができます。 プラグインエコシステムの変更に関する詳細のブログ記事をお待ち下さい。\nパフォーマンス改善 Logstash 1.5.0はより高速になっています。パフォーマンスが改善された2カ所について説明します。\ngrok filter Grok filterはLogstashで、構造化データを抽出するためにパターンを記述するのに使われます。 本リリースで、人気のある幾つかのパターンのgrok filterのスループットを100%に改善しました。 言い換えると、grok filterを使うときに、Logstashを通してより多くのデータを処理することができます。\n私たちのベンチマークテストで、1.5.0と1.4.2のスループットの比較をしました。 利用したデータは690万件のApache Webアクセスlogで、COMBINEDAPACHELOGのgrok patternです。 1.5.0で、スループットは34,000 event per sec(eps)から50,000 epsに増加しました。 両方のテストを8コアのマシンでLogstashで8つのワーカーを実行しました。 これらのテストで、一つのgrok filterを実行し、 stdinとstdoutを使ったパイプラインでイベントのスループットを計測しました。 全体的なパフォーマンスは、様々なハードウェアやLogstashのコンフィグによって変化することに注意してください。\njson serialization / deserialization JSONのシリアライズ/でシリアライズをJrJacksonライブラリを利用して実装しました。 これにより、100%以上のスループットの改善がありました。 先ほど説明したパフォーマンステストにおいて、1.3KBのサイズの500,00 JSONイベントを送信し、 16,000 epsから30,000 epsにスループットが改善しました。 45,000サイズのイベントで、850 epsから3500 epsにスループットが増加しました。 すばらしいです。\napache kafka integration いまでは、Apache Kafkaが大規模スケールデータ処理システムでよく利用されます。 Logstashの配備のスケーリングにおいて、Kafkaもまた、shippingインスタンスとindexingインスタンス間の データを保存するための中間メッセージバッファとして使うことができます。\n1.5.0で、Logstash Kafkaのinputとoutputのプラグインのビルトインサポートを追加しました。 これは、Joseph Lawsonによって最初に開発されました。 私たちは、これらのプラグインにインテグレーションテストとドキュメントを追加することにより改良し、 新しいKafkaの機能を開発し続けます。 また、Apache Avro codecを追加することで、Kafkaに保存されたイベントを 簡単に取得でき、ELKスタックを使ってそれらを解析できるようにしました。\nKafka inputを追加するのは次のコマンドです。\n$LS_HOME/bin/plugin install logstash-input-kafka Kafka outputは次のコマンドです。\n$LS_HOME/bin/plugin install logstash-output-kafka セキュリティに関する改善 認証と経路暗号化のサポートを追加し、Elasticsearchのoutput、input、filterのセキュリティを改良しました。 例えば、HTTPプロトコルでSSL/TLSにより暗号化を有効にでき、 HTTPベーシック認証をユーザ名とパスワードをリクエストに与えることで設定できます。 これらの機能は、時期にリリースされるElasticsearch ShieldセキュリティプロダクトとLogstashを統合できます。\nドキュメント これまで、Logstashのドキュメントは[logstash.net])(http://logstash.net/)に置いてあり、 他のELKスタックと一緒に動かす時に、情報を探すのが厄介でした。 1.5.0および、今後のバージョンのドキュメントはelasticsearch.orgのLogstash Guideに移行します。 この移行でelasticsearch.org/guideにELKスタックを利用、 学習するためにドキュメントが1つになりました。 このベータリリースのイテレーションで、私たちはプレゼンテーションとドキュメントの品質を改善することに活発に取り組んでいきます。 (過去のLogstashのドキュメントの全てはいままでのlogstash.netで引き続き公開していく予定です。)\nバグフィックスと改善 ここまでの新しい機能に加えて、Logstash 1.5.0では、多くのバグフィックスと多くの機能改善があります。 ここで、これらのいくつかを紹介します。\n出力しない\u0026rsquo;metadata\u0026rsquo;をイベントに格納可能に。これは、例えば、date filterに使う中間フィールドのために必要。(#1834, #LOGSTASH-1798) HTTPを利用しているときのファイルデスクリプタリークの修正。Logstashがストールするのを防ぎ、OOMエラーからクラッシュするケースも防ぎます。(#1604) Twitter input:full_tweetオプションの追加、Twitter rate limitingエラーのハンドリング(#1471) イベントを生成するfilter(multiline、clone、split、metrics)により、 後続の条件文にこれらのイベントを正しく伝搬(#1431) Elasticsearch output:Logstashはデフォルトでmessage.rawフィールドを作成しない。messageフィールドはElasticsearch によりnot_analyzedでマルチフィールドとして追加される。マルチフィールドはディスクスペースが2倍必要だが、利点がない。 bin/logstashの複数のサブコマンドを除去(#1797) これらの機能、改善、バグフィックスについては、Logstash 1.5.0.Beta1 のchangelogをごらんください。\n試してみてください! ぜひ、Logstash 1.5.0 Beta 1をダウンロードして試してみてください。 そして、感想をTwitter(@elasticsearch)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1418372246,"dir":"post/2014/","id":"1bc36080b2493aab78c26e4f2152542c","lang":"ja","lastmod":1418372246,"permalink":"https://blog.johtani.info/blog/2014/12/12/logstash-1-5-0-beta1-released-ja/","publishdate":"2014-12-12T17:17:26+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:logstash 1.5.0.beta1 released Logstash 1.5.0 Beta1をリリースしました。こちらのページからダウンロードで","tags":["logstash"],"title":"Logstash 1.5.0 Beta1リリース(日本語訳)"},{"contents":"早いもので、師走です。今年もあと少しとなりました。ということで、Advent Calendarの季節が始まりました。\nこの記事はElasticsearch Advent Calndar 2014の1日目のエントリです。\n1日目ということで、簡単に今年の変遷を振り返りつつ、今年導入された新機能についてピックアップしてみようかと思います。\n1.0リリース(Lucene 4.6.0) 今年一番の目玉と思いますが、1月にRCが公開されて、1.0.0が2月にリリースされました。 (ElasticSearch Serverの翻訳が昨年末に終わってレビューをしていた段階での発表だったので個人的にはきついタイミングでした) 1.0の主な変更点はこちら。\nElasticsearch(Sが小文字に) 1.0からSが小文字になりました。(#4634) 0.90以前のバージョンについては、Sが大文字になっています。 ややこしいですが、今年の3月に出版された黒いElasticSearch Server日本語版は原著が0.20で日本語版にするタイミングで0.90に対応しました。 このため、こちらの書籍のタイトルはSが大文字となっています。 (なお、原著の2nd Editionは小文字になっています)\nSnapshot/Restoreの導入とGatewayの廃止 0.90以前のバージョンでは、gatewayというモジュールで、S3などにインデックスのメタデータなどを保存する機能がありました。 この機能は、0.20からlocal以外はdeprecatedとなりました。\nインデックスのバックアップ、リストアのために、1.0で実装されたのがSnapshot/Restoreです。 Snapshot/Restoreでは、インデックスごと、もしくはクラスタ全体をリモートにあるリポジトリにスナップショットを取ることが可能となりました。 初期リリースの段階では、共有ファイルシステムのみでしたが、現在は、S3やHDFSなどに保存が可能となっています。\nAggregation Facetをより強力にしたものです。Facetでは、指定したフィールドの集計のみでした。 データの解析などを行うには、独自で集計する必要がありました。 この機能をより柔軟に行えるように実装したのがAggregationです。\nたとえば、アクセスログを日毎に集計し、さらに日毎の集計に対して国別の集計やユーザエージェントごとの集計をさらに行うといった感じです。 Facetの場合は、日毎の検索結果に対して個別に集計するのみでしたが、Aggregationを使うことで、1週間の検索結果に対して、 日毎に国別の集計を行うといったことが可能になっっています。\ncat API \u0026ldquo;=^.^=\u0026ldquo;猫が出てくるAPIです。(違う)\nElasticsearchでは、クラスタの状態などが全てREST APIで取得でき、JSONで結果が帰ってきていました。 JSONはプログラムなどで処理を行う場合は便利ですが、コンソールで確認したり、管理系のツールでメールで通知する場合などは見にくいことがあります。 これを解消したのが_cat APIです。(公式の紹介ブログはこちら)\nCircuit Breaker OOMが発生しそうなfielddataの読み込みを検知して、事前に防ぐ機構になります。 初期段階ではFielddataに対してのものから実装されました。\n1.1リリース(Lucene 4.6.1) 3月にリリースされました。Elasticsearchはまだまだ発展しているため、リリースのサイクルが短いのが特徴です。\n1.x系では、Rolling Upgradeが導入されました。このため、クラスタ全体を停止することなく、クラスタのアップグレードが可能になりました。\nsearch templates 検索クエリをテンプレートとして登録することができるsearch templatesです。 JSONでクエリを記述できるのは便利ですが、毎回組み立てるのは大変かもしれません。 特に、固定のクエリをプログラムから利用するような場合などです。 テンプレートとして登録しておくことで、検索時に値を埋め込むだけで検索ができるようになりました。\nAggregationの強化 Aggregationの種類が増えました。\ncardinality:ユニークユーザ数の集計などが行えるaggregationです。HyperLogLog++アルゴリズムを利用した実装になっています。 significant_terms:単語の数による集計ではなく、コレクション全体に対する単語の頻度と、検索結果に対する単語の頻度を計算することで、重要度を計ることができます。 percentiles:パーセンタイル値を計算できます。 1.2リリース(Lucene 4.8系) Java 7必須 利用しているLuceneがJava 7必須となったためです。また、Java 6のEOLも切れてますし。\ndynamic scriptingがデフォルトオフ 採用していたMVELがサンドボックス化に対応していないため、危険を回避するためにオフとなりました。\nインデキシングとマージング インデキシングとマージ処理に関するさまざまな改善。\nflushのthreasholdを操作回数ではなく、サイズや時間によるものに変更 デフォルトをConcurrentMergeSchedulerに変更 1.3リリース(Lucene 4.9.0系) セキュリティ関連 JSONPのデフォルトオフ MVELの非推奨化(1.4で削除)+script.disable_dynamicのデフォルト値がsandbox aggregationの強化 top hits:Field Collapsing/combiningと呼ばれる機能です。たとえば、いくつかのサイトのHTMLを収集して検索機能を提供する場合に、ドメインごとに1件ずつ検索結果に出したい場合などに利用できる機能です。 その他にも以下のaggregationが追加されています。\npercentile ranks geo bounds mappingのtransform Mappingにtransform機能が追加されました。 mappingにドキュメントの値を元に、インデキシング時に変換処理を記述できます。 たとえば、特定のフィールドにある値がある場合にだけ、あるフィールドに値を入れるなどといったことが可能になります。\nディスク関連 disk based shard allocation deciderが導入されました。ノードのディスクの使用率を元に、シャードを配置しても良いかといった決定を行う機構です。 チェックサムによるファイルのチェック(Lucene4.9で導入されたコードへの切り替え) 1.4リリース(Lucene 4.10系) ベータ版が出されるほど、多くの改善が入っています。\nresiliency メモリ使用量の低下によるノードの安定性向上 DocValues、リクエストごとのcircuit breakerなど discoveryアルゴリズムの改善によるクラスタの安定性向上 チェックサムの導入による破損したデータの検知 セキュリティ関連 CORSをデフォルト無効 Groovyがデフォルトのスクリプト言語に。 Aggregationの強化 以下のaggregationが追加されています。\nfilter、children、scripted_metric Upgrade API インデックスを最新のバージョンのものにアップグレードするためのAPIです。 Luceneは下位互換を保ってくれているため、古いバージョンのインデックスも読み込むことが可能です。 ただ、最新バージョンで使える機能が制限されていたりということもあります。 クラスタにあるインデックスをアップグレードするのにかかる時間や必要かどうかといったことを取得できる仕組みも提供します。\nまた、Lucene自体は、1つ前のメジャーバージョン(4.x系だと3.x系まで)までの互換性は提供していますが、 2つ前のメジャーバージョンの互換性がなくなります。 Luceneも5.x系のブランチが作成されており、5系のリリースにより、3系との互換性がなくなります。 5系のリリースに対応する場合にも、こちらのAPIが助けになるかと。\n1.4.1 11\u0008/27に1.4.1がリリースされました。 シャードの配置やparent/child、nestedドキュメントの改善などが行われています。\nまとめ ということで、駆け足で、1月から11月までのElasticsearchの流れを追ってみました。 1.0で大きな機能追加、改善が行われ、その後も活発に開発が行われています。 要望などがあれば、MLで聞いてみたりやGitHubに登録するなどを行っていただければと。\nあと、今年から来年にかけての大きなイベントとして、 Elasticsearch初のユーザカンファレンスのサイトがオープンしました。 Elasticsearchに関するいろいろな話が聞ける機会だと思うので、興味のある方は見ていただければと。\nでは、また次のAdvent Calendarで!(最終日の予定ですが、空きがあるのでなにか書くかも)\n","date":1417424748,"dir":"post/2014/","id":"2de582c67fca31500621ecd6d3917a07","lang":"ja","lastmod":1417424748,"permalink":"https://blog.johtani.info/blog/2014/12/01/about-elasticsearch-in-2014/","publishdate":"2014-12-01T18:05:48+09:00","summary":"早いもので、師走です。今年もあと少しとなりました。ということで、Advent Calendarの季節が始まりました。 この記事はElastics","tags":["elasticsearch"],"title":"2014年のElasticsearch"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:elasticsearch 1.4.1 and 1.3.6 released\n本日、Lucene 4.10.2をベースにしたElasticsearch 1.4.1と、バグフィックスリリースである、Elasticsearch 1.3.6をリリースしました。 ダウンロードおよび変更リストはそれぞれ次のリンクからアクセスできます。\n最新ステーブルリリース:Elasticsearch 1.4.1 1.3.x系バグフィックス:Elasticsearch 1.3.6 過去のリリースに関するブログ(公式)はこちら。\n1.4:1.4.0, 1.4.0.Beta1 1.3:1.3.5, 1.3.4, 1.3.3, 1.3.2, 1.3.1, 1.3.0. すべての変更については1.4.1のリリースノートおよび1.3.6のリリースノートをごらんください。 以下では、重要な変更について紹介します。\nshard allocation Elasticsearch 1.3.0で、disk based shard allocationが デフォルトで有効になっています。 もし、ノードのディスクの使用量がlawで指定された値(85%)を超えた場合、ノードにはシャードが配置されません。 また、highで指定された値(90%)を超えた場合、シャードを他のノードへ移動します。\nElasticsearch 1.4.1では、disk based shard allocationに3つの改良が追加されました。\nディスク使用量のチェックはシャードがクラスタに配置されるタイミングでのみ実施していた。現在は60秒ごとに使用量をチェック。(#8270) ディスクフルメッセージはDEBUGレベルでログに出力されていました。なぜ、新しいシャードが配置されないのかを説明するのが困難でした。現在はWARNレベルで30秒ごとにログに出力されます。(#8382) 以前は、シャードをもう一つのノードへ動かすべきかどうか決めるとき、allocation deciderはノードにあるシャードのサイズを考慮するだけでした。現在は、動かされるシャードのサイズも考慮します。これにより、必要最小限のシャードの移動量となります。(#8569) parent/child and nested documents Elasticsearch 1.4.0で、parent/childとnestedドキュメントに対して(新しいセグメントを開くときに)固定長ビットセットフィルタを構築しキャッシュしました。クエリ、フィルタおよびAggregationを常に速くするためにです。 多くのnestedフィールドを持つユーザにとっては、以前のバージョンよりもヒープの使用量が大きくなってしまいました。\nnested aggregationによって処理されるドキュメントの順序を変更すること(#8454)によって、固定長ビットセットフィルタが子のドキュメントに対して必要でなくなりました。 現在は、親のドキュメント(つまり、nestedではないドキュメント)を表すフィルタのみをキャッシュしています。これにより必要なキャッシュ空間のサイズを減少しました。(#8414、#8440)\ndate ranges 2つの日付範囲に関する問題がこのリリースで修正されました。 1つ目は、日付を丸めるかというものです。例えば、timestampフィールドに1秒の解像度の値があるとします。 {\u0026quot;lt\u0026quot;: \u0026quot;2014/11/26||/d\u0026quot;}というrangeフィルタは2014/11/26 00:00:00未満のタイムスタンプのデータを結果として返しました。 しかし、ltをlteに変更した場合、2014/11/27 00:00:00以外の値も含めたいです。\n以前は、lteは2014/11/27 00:00:00のタイムスタンプも含めてしまっていました。現在は、想定通りの動作をします。(#8556)\n2つ目のバグは日付の範囲条件にnow()を利用したaliasとpercolatorフィルタです。 now()の値を、フィルタが作成したタイミングで決定していました。フィルタが実行されるたびに更新せずにです。 #8534で、now()はaliasとpercolatorで想定通りの動作をします。\n試してみてください。 ぜひ、Elasticsearch 1.4.1をダウンロードして、試してみてください。 そして、感想をTwitter(@elasticsearch)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1417056212,"dir":"post/2014/","id":"0a8183ced0e9e3e895b41286e54e8e4d","lang":"ja","lastmod":1417056212,"permalink":"https://blog.johtani.info/blog/2014/11/27/elasticsearch-1-4-1-released-ja/","publishdate":"2014-11-27T11:43:32+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:elasticsearch 1.4.1 and 1.3.6 released 本日、Lucene 4.10.2をベースにしたElas","tags":["elasticsearch"],"title":"Elasticsearch 1.4.1および1.3.6リリース(日本語訳)"},{"contents":"前回の「Logstashを利用したApacheアクセスログのインポート」の続きです。 前回の記事では、Logstashの設定ファイルについて説明しました。 今回は「Elasticsearchに設定するインデックステンプレート」について説明します。\nテンプレートの設定 Elasticsearchでは、登録するデータの特性に合わせてMappingを定義する方がデータを効率良く扱うことができる場合があります。 この場合、通常ですと、インデックス作成時にMappingを指定します。\nただ、今回は、インデックス名に「年」を含める形で指定してあります。 「年」はLogstashで処理したデータによって決まります。このため、あらかじめMappingを指定してインデックスを作成するのは難しいです。\nこのような場合に便利な機能として、「インデックステンプレート」があります。\nインデックステンプレートとは 実際のテンプレートの説明に入る前に、少しだけ説明を。 インデックステンプレートとは、インデックスが作成されるタイミングで自動的に適用される設定をテンプレートとして登録できる機能のことです。 実際にテンプレートが適用されるかどうかは、インデックス名で判断されます。\n例えば、大して重要でもなく、データ量も少ないインデックス用のテンプレートとして、シャード数が1、レプリカ数が0、\u0026quot;_source\u0026quot;を保存しない設定のテンプレートを登録する場合、 次のようになります。\ncurl -XPUT localhost:9200/_template/template_1 -d \u0026#39; { \u0026#34;template\u0026#34; : \u0026#34;te*\u0026#34;, \u0026#34;settings\u0026#34; : { \u0026#34;number_of_shards\u0026#34; : 1, \u0026#34;number_of_replicas\u0026#34; : 0 }, \u0026#34;mappings\u0026#34; : { \u0026#34;type1\u0026#34; : { \u0026#34;_source\u0026#34; : { \u0026#34;enabled\u0026#34; : false } } } } \u0026#39; _templateがインデックステンプレートを登録するためのエンドポイントです。 template_1がこのテンプレートのIDです。削除などについては、このIDを利用します。\nそして、重要なのは、\u0026quot;template\u0026ldquo;の設定です。 \u0026ldquo;template\u0026ldquo;には、このテンプレートが適用されるべきインデックス名を記載します。 上記サンプルではte*となっているため、teで始まる名前のインデックスを作成した場合にテンプレートにある設定が適用されます。\n今回利用するテンプレート 私がJJUG CCCや第7回Elasticsearch勉強会のKibana4のデモで利用したインデックスのテンプレートは次のものになります。 \u0026ldquo;template\u0026ldquo;には、前回の記事で紹介したoutput/elasticsearchの設定 に合致するnew_demo_access_log-*を指定しています。\ncurl -XPUT localhost:9200/_template/new_access_log_for_demo -d \u0026#39; { \u0026#34;template\u0026#34;: \u0026#34;new_demo_access_log-*\u0026#34;, \u0026#34;settings\u0026#34;: { \u0026#34;number_of_shards\u0026#34;: \u0026#34;2\u0026#34;, \u0026#34;number_of_replicas\u0026#34;: \u0026#34;0\u0026#34; }, \u0026#34;mappings\u0026#34;: { \u0026#34;_default_\u0026#34;: { \u0026#34;dynamic_templates\u0026#34;: [ { \u0026#34;string_template\u0026#34;: { \u0026#34;mapping\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;match_mapping_type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;match\u0026#34;: \u0026#34;*\u0026#34; } } ], \u0026#34;properties\u0026#34;: { \u0026#34;path\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;multi_field\u0026#34;, \u0026#34;fields\u0026#34;: { \u0026#34;no_analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, \u0026#34;referer\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;multi_field\u0026#34;, \u0026#34;fields\u0026#34;: { \u0026#34;no_analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, \u0026#34;agent\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;multi_field\u0026#34;, \u0026#34;fields\u0026#34;: { \u0026#34;no_analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, \u0026#34;geoip\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;location\u0026#34;: { \u0026#34;geohash\u0026#34;: true, \u0026#34;geohash_precision\u0026#34;: 10, \u0026#34;type\u0026#34;: \u0026#34;geo_point\u0026#34;, \u0026#34;lat_lon\u0026#34;: true, \u0026#34;geohash_prefix\u0026#34;: true } } }, \u0026#34;response\u0026#34;: { \u0026#34;copy_to\u0026#34;: \u0026#34;response_int\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;bytes\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;response_int\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34; } } } } } \u0026#39; settings設定 デモ用であり、手元で2台のノードを起動するということもあり、number_of_shardsに2を、number_of_replicasに0を指定してあります。\nmappings設定 インデックスのタイプ Mappingsの指定は通常、特定のタイプを指定します。 今回のデモでは、1種類しかないのですが、タイプ名を特に意識しないために、_default_を使用しました。 この場合、任意のタイプに適用されることとなります。 タイプを指定してMappingの設定を行う場合は_default_の部分に特定のタイプ名を記入します。\n\u0026#34;mappings\u0026#34;: { \u0026#34;_default_\u0026#34;: { ... ダイナミックテンプレート 次はダイナミックテンプレートです。 インデックステンプレートはインデックスの設定をテンプレート化しました。ダイナミックテンプレートはフィールドに対してテンプレートを設定できます。\n以下のダイナミックテンプレートでは、stringタイプのフィールドのデフォルト設定を変更しています。 通常、stringタイプのフィールドはanalyzedとなりますが、not_analyzedに変更してあります。 詳しく検索したいフィールドの方が少ないためです。\n... \u0026#34;dynamic_templates\u0026#34;: [ { \u0026#34;string_template\u0026#34;: { \u0026#34;mapping\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;match_mapping_type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;match\u0026#34;: \u0026#34;*\u0026#34; } } ], ... multi_field指定 検索もしたいし、Terms Aggregationでも利用したいフィールドについては、multi_fieldを利用して、 analyzedとnot_analyzedの2種類のフィールドを用意しています。 multi_field設定を用いることで、1つのJSONのデータから、異なる形のフィールドを用意することが可能です。\n今回のテンプレートでは、path、referer、agentにmulti_fieldを指定しました。\n... \u0026#34;path\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;multi_field\u0026#34;, \u0026#34;fields\u0026#34;: { \u0026#34;no_analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, ... 例えば、上記の設定の場合、入力のJSONはpathというデータのみですが、インデックス上にはpath.no_analyzedと path.analyzedというフィールドができあがります。 実際に検索する場合は、path.analyzed:検索したい文字列という形で検索をすることで、いわゆる部分一致のような検索が可能です。 また、完全一致をしたい場合はpath.no_analyzed:検索したい文字列という指定になります。 用途を考えると、requestも指定したほうが良いかもしれません。\ngeoip Logstashでgeoipデータを付与していました。 このgeoipのデータをKibana4で利用するために、geoデータとして登録する必要があります。\n\u0026#34;geoip\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;location\u0026#34;: { \u0026#34;geohash\u0026#34;: true, \u0026#34;geohash_precision\u0026#34;: 10, \u0026#34;type\u0026#34;: \u0026#34;geo_point\u0026#34;, \u0026#34;lat_lon\u0026#34;: true, \u0026#34;geohash_prefix\u0026#34;: true } } }, 上記の設定がgeoデータの指定です。 typeにobjectが指定してありますが、これは、geoipのデータがネストしているためです。 geoipオブジェクトのうち、緯度経度のデータはlocationに入っているため、こちらに緯度経度関係の設定を指定します。\n\u0026quot;type\u0026quot;: \u0026quot;geo_point\u0026quot;:geo_pointタイプであることを指定 \u0026quot;geohash\u0026quot;: true:緯度経度のデータをもとに、geohashの値もインデックス \u0026quot;geohash_precision\u0026quot;: 10:geohashの精度の指定 \u0026quot;lat_lon\u0026quot;: true:緯度経度を個別の.lat、.lonというフィールドにもインデックス \u0026quot;geohash_prefix\u0026quot;: true:該当するgeohashのみでなく、その親にあたるgeohashについてもインデックスする response、response_int、bytes 最後は、response、response_int、bytesです。\nresponseには、HTTPステータスコードが入ります。 文字列としても扱いたいですが、integerとして、Renge Aggregationなどを行いたいので、 response_intというフィールドにも値を入れています。 multi_fieldでも可能ですが、ここでは、copy_toを利用しました。 copy_toを用いることで、異なるフィールドに値をコピーすることができます。\nbytesについては、longで扱いたいとういう理由だけです。\n\u0026#34;response\u0026#34;: { \u0026#34;copy_to\u0026#34;: \u0026#34;response_int\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;bytes\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;response_int\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34; } まとめ 今回はデモに利用したインデックスてプレートについて説明しました。 前回の、Logstashの設定とこのインデックステンプレートを用いることで、Kibanaで解析するデータの準備ができます。 実際の操作などについては、また次回の記事で説明しようかと思います。\n不明な点、誤植などありましたら、コメント欄へお願いします。\n","date":1416900346,"dir":"post/2014/","id":"4d8f5e581eee602c7fd21da8eb68df9a","lang":"ja","lastmod":1416900346,"permalink":"https://blog.johtani.info/blog/2014/11/25/import-apache-accesslog-using-logstash-2/","publishdate":"2014-11-25T16:25:46+09:00","summary":"前回の「Logstashを利用したApacheアクセスログのインポート」の続きです。 前回の記事では、Logstashの設定ファイルについて説","tags":["logstash","kibana","elasticsearch"],"title":"インデックステンプレートとLogstash"},{"contents":"JJUG CCCや第7回Elasticsearch勉強会のKibana4のデモにアクセスログを利用しました。\nただ、セッションでは、どうやってElasticsearchに投入したのかという詳しい話をしていませんでした。 本記事では、データ取り込み時に利用したLogstashの設定ファイルについて説明します。\nLogstashの設定の説明に入る前に、全体の流れを。 「ApacheアクセスログをKibana4により可視化」です。\n材料の準備 「ApacheアクセスログをKibana4により可視化」に必要な材料は次の通りです。 (今回は起動するところまでいかないので、実際に必要なのは次回以降になります。)\nJava 7(u55以上を1つ) Logstash 1.4.2(1つ) Elasticsearch 1.4.0(1つ) Kibana4 Beta2(1つ) Apacheのアクセスログ(適量) Apacheのアクセスログ以外は、公式サイトからダウンロードできます。 それぞれをダウンロードして、起動できるようにしておきましょう。\n※1台のマシン上で行う場合は、アクセスログの量を少なめにするなどの対策をとりましょう。 ※今回は、1台のマシン(Mac)上で、VMなどを利用せず、それぞれ直接起動するものとします。\n可視化の手順と流れ 可視化の流れとしては、\nLogstashでファイルを読み込み、各種処理(パースしたり、情報を追加したり、切り出したり) Elasticsearchに保存 Kibanaでグラフを作ったり、検索してみたり です。\n今回は、1のLogstashでファイルを読み込んだりする設定ファイルの説明です。\nLogstashの設定 Logstashの基本 まずは、Logstashの設定ですが、簡単にLogstashの説明を。 Logstashは大きく3つのパーツに分かれています。\ninput:データの入力処理 filter:inputで読み込んだデータに対する操作など output:データの出力処理 inputでデータを読み込み(複数可)、filterでデータに対して各種処理を行い、outputでデータを指定されたところに出力(複数可)します。\nアクセスログの読み込み設定 アクセスログの読み込み処理は大まかに次のようなものとなります。\nアクセスログを読み込む(input/file) 読み取ったアクセスログを各フィールド(IPアドレス、ユーザエージェントなど)に分割(filter/grok) 日付のパース(filter/date) クライアントIPアドレスにgeoipの情報を付加(filter/geoip) リクエストのパスの第1階層の抽出(filter/grok) ユーザエージェントのパース(filter/useragent) Elasticsearchへの出力(output/elasticsearch) 設定ファイルは次のようなものになります。\ninput { file { path =\u0026gt; \u0026#34;/Users/johtani/demo_access_log/*/*.log\u0026#34; start_position =\u0026gt; \u0026#34;beginning\u0026#34; } } filter { grok { match =\u0026gt; { \u0026#34;message\u0026#34; =\u0026gt; \u0026#34;%{COMBINEDAPACHELOG}\u0026#34; } break_on_match =\u0026gt; false tag_on_failure =\u0026gt; [\u0026#34;_message_parse_failure\u0026#34;] } date { match =\u0026gt; [\u0026#34;timestamp\u0026#34;, \u0026#34;dd/MMM/YYYY:HH:mm:ss Z\u0026#34;] locale =\u0026gt; en } geoip { source =\u0026gt; [\u0026#34;clientip\u0026#34;] } grok { match =\u0026gt; { \u0026#34;request\u0026#34; =\u0026gt; \u0026#34;^/%{WORD:first_path}/%{GREEDYDATA}$\u0026#34; } tag_on_failure =\u0026gt; [\u0026#34;_request_parse_failure\u0026#34;] } useragent { source =\u0026gt; \u0026#34;agent\u0026#34; target =\u0026gt; \u0026#34;useragent\u0026#34; } } output { elasticsearch { host =\u0026gt; \u0026#34;localhost\u0026#34; index =\u0026gt; \u0026#34;new_demo_access_log-%{year}\u0026#34; cluster =\u0026gt; \u0026#34;demo_cluster\u0026#34; protocol =\u0026gt; \u0026#34;http\u0026#34; } } 1. アクセスログを読み込む(input/file) inputのfileモジュール(a)を使用してアクセスログのファイルを読み込みます。 pathでアクセスログのファイルのパスを指定します。 今回利用したアクセスログはdemo_access_log/2010/access20100201.logといった日毎のファイルに分割されていたため、 *を利用してファイルのパスを指定しました。 また、今回は既存のファイルの読み込みだけのため、start_positionにbeginningを指定してあります。 デフォルトではendが指定されるため、Logstashを起動後に追記されたログから対象になってしまうためです。 その他の設定については、公式ガイドをご覧ください。\ninput { file { # a path =\u0026gt; \u0026#34;/Users/johtani/demo_access_log/*/*.log\u0026#34; # b start_position =\u0026gt; \u0026#34;beginning\u0026#34; # c } } Logstashでは、ファイルをどこまで読み込んだかという情報を保持するために、sincedbを利用しています。 設定変更後に同じファイルを最初から読み込みたい場合などは、こちらのファイルを一旦削除するなどの対応が必要です。\nちなみに、読み込んだデータは次のようなJSONになっています。\n{ \u0026#34;message\u0026#34;: \u0026#34;読み込んだアクセスログ\u0026#34;, \u0026#34;@version\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;@timestamp\u0026#34;:\u0026#34;2014-11-21T06:16:21.644Z\u0026#34;, \u0026#34;host\u0026#34;:\u0026#34;jupiter.local\u0026#34;, \u0026#34;path\u0026#34;:\u0026#34;/Users/johtani/demo_access_log/2010/access20100201.log\u0026#34;} } 特に指定がない場合は、messageに読み込んだデータが入ってきます。 @timestampがLogstashが読み込んだ時刻、hostはLogstashが動作しているホスト名です。 pathはfileモジュールが読み込んだファイルのパスを設定しています。 この後の処理で、どこの項目に対して処理を行うかといったことが重要になるので、\n2. 読み取ったアクセスログを各フィールド(IPアドレス、ユーザエージェントなど)に分割(filter/grok) 2.〜6.の処理は、inputで読み込んだ1アクセスログに対する処理となります。\nここでは、grokフィルタを使用して Apacheのアクセスログを各フィールドに分割します。 Logastashでは、簡単に使えるようにいくつかのパターンが用意されています。 Apacheのログのために、COMBINEDAPACHELOGというのが用意されています。 今回はこちらを使用しています。その他にも日付などパターンが用意されているので、試してみてください。\nmessageにアクセスログが入っているので、こちらの項目に対してCOMBINEDAPACHELOGのパターンを matchで適用してフィールドに抜き出します。 tag_on_failureは、matchでパースに失敗した場合に、tagというフィールドに指定した文字列を出力する機能になります。 デフォルトだと_grokparsefailureが付与されますが、ここでは、どの処理で失敗したがを判別するために文字列を変更しています。\nfilter { grok { match =\u0026gt; { \u0026#34;message\u0026#34; =\u0026gt; \u0026#34;%{COMBINEDAPACHELOG}\u0026#34; } break_on_match =\u0026gt; false tag_on_failure =\u0026gt; [\u0026#34;_message_parse_failure\u0026#34;] } ... clientip、ident、auth、timestamp、verb、request、httpversion、response、bytes、referrer、agentがgrokフィルタにより抜き出された項目です。\n{ \u0026#34;message\u0026#34;:\u0026#34;アクセスログ\u0026#34;, \u0026#34;@version\u0026#34;:\u0026#34;1\u0026#34;, \u0026#34;@timestamp\u0026#34;:\u0026#34;2014-11-21T07:20:54.387Z\u0026#34;, \u0026#34;host\u0026#34;:\u0026#34;jupiter.local\u0026#34;, \u0026#34;path\u0026#34;:\u0026#34;/Users/johtani/demo_access_log/2010/access20100201.log\u0026#34;, \u0026#34;clientip\u0026#34;:\u0026#34;クライアントのIPアドレス\u0026#34;, \u0026#34;ident\u0026#34;:\u0026#34;-\u0026#34;, \u0026#34;auth\u0026#34;:\u0026#34;-\u0026#34;, \u0026#34;timestamp\u0026#34;:\u0026#34;01/Feb/2010:00:00:26 +0900\u0026#34;, \u0026#34;verb\u0026#34;:\u0026#34;GET\u0026#34;, \u0026#34;request\u0026#34;:\u0026#34;/images/favicon.ico\u0026#34;, \u0026#34;httpversion\u0026#34;:\u0026#34;1.1\u0026#34;, \u0026#34;response\u0026#34;:\u0026#34;200\u0026#34;, \u0026#34;bytes\u0026#34;:\u0026#34;318\u0026#34;, \u0026#34;referrer\u0026#34;:\u0026#34;\\\u0026#34;-\\\u0026#34;\u0026#34;, \u0026#34;agent\u0026#34;:\u0026#34;\\\u0026#34;Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)\\\u0026#34;\u0026#34; } 3. 日付のパース(filter/date) Logstashは特に指定がない場合、inputでデータを取り出した日付が@timestampとなります。 そして、このフィールドが特に指定がない場合は、Elasticsearchのデータの日付となり、Kibanaで利用する日付となります。\nリアルタイムにアクセスログを読み込む場合は、読み込んだ日時でもほぼ問題はありませんが、過去データの場合はそうもいきません。 そこで、dateフィルタを使用して、@timestampの値を書き換えます。\ndate { match =\u0026gt; [\u0026#34;timestamp\u0026#34;, \u0026#34;dd/MMM/YYYY:HH:mm:ss Z\u0026#34;] locale =\u0026gt; en } 上記では、timestampという項目に対してdd/MMM/YYYY:HH:mm:ss Zという日付パターンの場合に値を書き換える設定となります。 なお、日付の月の部分がFebとなっているため、localeにenを指定しています。Logstashが動作するマシンのlocaleがjaなどの場合にパースに失敗するためです。\n4. クライアントIPアドレスにgeoipの情報を付加(filter/geoip) どの国からのアクセスかなどを判別したいので、IPアドレスを元にgeoipを利用してより詳細な情報を付与します。 Logstashでもこの機能が用意されており、簡単に利用ができます。\ngeoip { source =\u0026gt; [\u0026#34;clientip\u0026#34;] } これだけです。対象とするIPアドレスのフィールドを指定しているだけです。 geoipというフィールドが追加され、次のような情報が付与されます。 国名、緯度経度、タイムゾーンなどです。\n{ ... \u0026#34;geoip\u0026#34;: { \u0026#34;ip\u0026#34;: \u0026#34;IPアドレス\u0026#34;, \u0026#34;country_code2\u0026#34;: \u0026#34;JP\u0026#34;, \u0026#34;country_code3\u0026#34;: \u0026#34;JPN\u0026#34;, \u0026#34;country_name\u0026#34;: \u0026#34;Japan\u0026#34;, \u0026#34;continent_code\u0026#34;: \u0026#34;AS\u0026#34;, \u0026#34;latitude\u0026#34;: 36, \u0026#34;longitude\u0026#34;: 138, \u0026#34;timezone\u0026#34;: \u0026#34;Asia/Tokyo\u0026#34;, \u0026#34;location\u0026#34;: [ 138, 36 ] } ... } 5. リクエストのパスの第1階層の抽出(filter/grok) リクエストされたURLはrequestフィールドにありますが、個別のURLだと、大まかな集計が大変です。 もちろん、クエリで処理することもできますが、Logstashで処理するついでに、第1階層のディレクトリ名を抽出しておくことで、 検索や集計を行いやすくしておきます。\ngrok { match =\u0026gt; { \u0026#34;request\u0026#34; =\u0026gt; \u0026#34;^/%{WORD:first_path}/%{GREEDYDATA}$\u0026#34; } tag_on_failure =\u0026gt; [\u0026#34;_request_parse_failure\u0026#34;] } また、grokフィルタの登場です。 今回は、WORD:first_pathという記述方法で、WORDパターンにマッチした文字列をfirst_pathというフィールドに展開する指定をしています。\n例えば、サイトのスクリプトなどがscriptsというディレクトリにある場合は、first_pathの値を利用して、 後続のフィルタでログデータを出力しないといった処理にも使えます。\n6. ユーザエージェントのパース(filter/useragent) Logstashではユーザエージェントの文字列から、いくつかの情報を付与するフィルタも用意されています。 useragentフィルタです。\nuseragent { source =\u0026gt; \u0026#34;agent\u0026#34; target =\u0026gt; \u0026#34;useragent\u0026#34; } agentというフィールドにユーザエージェントの文字列があるので、このフィールドに対してフィルタを適用します。 元の文字列も取っておきたいので、useragentという別のフィールドに出力するように指定してあります。\n\u0026#34;useragent\u0026#34;: { \u0026#34;name\u0026#34;: \u0026#34;Firefox\u0026#34;, \u0026#34;os\u0026#34;: \u0026#34;Windows XP\u0026#34;, \u0026#34;os_name\u0026#34;: \u0026#34;Windows XP\u0026#34;, \u0026#34;device\u0026#34;: \u0026#34;Other\u0026#34;, \u0026#34;major\u0026#34;: \u0026#34;17\u0026#34;, \u0026#34;minor\u0026#34;: \u0026#34;0\u0026#34; }, このように、OS名やバージョン名などが抽出できます。\n7. Elasticsearchへの出力(output/elasticsearch) 最後は、Elasticsearchへのデータの出力設定です。\nindexにて、出力するindex名を指定してあります。 また、年毎のインデックス名にするために%{year}を利用しています。 sprintf formatです。\nelasticsearch { host =\u0026gt; \u0026#34;localhost\u0026#34; index =\u0026gt; \u0026#34;new_demo_access_log-%{year}\u0026#34; cluster =\u0026gt; \u0026#34;demo_cluster\u0026#34; protocol =\u0026gt; \u0026#34;http\u0026#34; } まとめ ということで、今回はアクセスログをLogstashにて読み込む時の設定について説明してきました。 次回は、実際にLogstashを起動してElasticsearchにデータを登録するところまでを説明します。\nJJUG CCCや勉強会のデモに用いたデータは、 Elasticsearchにデータを登録する前にテンプレートも設定してありました。こちらについても、次回説明しようと思います。\n不明な点、誤植などありましたら、コメント欄へお願いします。\n","date":1416558639,"dir":"post/2014/","id":"937a597a8b399fd32caba88a3c1c7bc4","lang":"ja","lastmod":1416558639,"permalink":"https://blog.johtani.info/blog/2014/11/21/import-apache-accesslog-using-logstash/","publishdate":"2014-11-21T17:30:39+09:00","summary":"JJUG CCCや第7回Elasticsearch勉強会のKibana4のデモにアクセスログを利用しました。 ただ、セッションでは、どうやってElas","tags":["logstash","kibana","elasticsearch"],"title":"Logstashを利用したApacheアクセスログのインポート"},{"contents":"第7回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 次回もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\n昨日も紹介しましたが、Elasticsearch Advent Calendar 2014を用意してみました。まだ、空きがありますので、登録お待ちしております!\n今回は出足が好調で、早々に180人の枠を超えるという嬉しい事態でした。 最終的な参加人数は130名程度で、懇親会参加者が50名弱といったところです。\n「Kibana4」 Elasticsearch Inc. Jun Ohtani @johtani スライド:Kibana4\nということで、Kibana4の紹介と、Kibana4のBeta2を利用したデモを行いました。 デモの開始のところで少し環境がうまく動いてなくて手間取ってしまいましたが。。。\n発表で1点だけ修正があります。JRubyを選択しているのがElasticsearchのライブラリを使用するためという説明をしましたが、 こちらは、Logstashに関する話でした。Kibana4は現時点では、ElasticsearchへのProxyとしての動作が主なものとなります。Rubyでも動作可能です。 bin/kibanaについてはJavaを使った起動になります。 参考:https://github.com/elasticsearch/kibana/tree/master/src/server\n発表でも主張しましたが、ダウンロードして、Elasticsearchを用意すれば簡単に動作させることが可能です。 ぜひ、ローカルで試して見てもらえればと思います。 今回のデモのデータを入れるのに利用したLogstashの設定などについては、ブログで記事を書こうと思います。\nniconicoの検索を支えるElasticsearch 株式会社ドワンゴ 伊藤 祥 さん スライド:niconicoの検索を支えるElasticsearch\nリアルタイム検索の実現、新しい検索への対応 検索のアーキテクチャとか。 Capistranoでデプロイとかを管理 1.4.1が出たら、クラスタを更新予定 ということで、実際に導入した話から、現在の運用の仕方、クラスタのアップグレードなど多岐にわたる内容でおもしろかったです。 遭遇した問題点とかもあったので。 Marvel便利なのでぜひ導入を検討してもらえればw\nElasticsearch at CrowdWorks\u2028株式会社クラウドワークス 九岡 佑介 さん @mumoshu スライド:Elasticsearch at CrowdWorks\n会社の紹介 仕事が検索対象 検索時間が1桁減少! Graceful Degradationで失敗したら、InnoDB FTSで代替:Gracefully found.noのサービスを利用 elasticsearch-modelの拡張を作成してOSSとして公開:elasticsearch-model-extensions Gracefullyで切り替えとかは面白いなと思いました。 検索での利用の話でしたが、他のシーンでも使えそうですよね。 日本にFoundユーザがいるのも初めて知りました。 彼らの開発者ブログも質の良い情報が載っているので、参考になりますよね。\n次は、どんなMappingで運用しているのかとか、どういった工夫をしているかといった点を詳しく聞きたいなと思いました。 またお待ちしております。\n1分で作るElasticsearchプラグイン 株式会社エヌツーエスエム 菅谷 信介 さん スライド:Elasticsearchプラグインの作り方\n\u0008\u0008* プラグインの作り方とか。\n十数個のプラグインの紹介。プラグインはこちらで公開中。https://github.com/codelibs/ 実際に、業務で必要なものから作成 まだまだ作りたいものがある コミュニティ還元できるものはPR送ってもらえるとうれしいです。 前よりは体制も増えてるので、PRも目にとまるようになってるはずです。\nあとは、使ってみたいと思う方も多数いると思うので、ぜひ、OSSなので、貢献しましょう! フィードバックがあるだけで、OSS活動やってるものにとってはやる気につながると思いますし。\nLT:GISとして活用するElasticsearch\u2028船戸 隆さん スライド:GISとして活用するElasticsearch\u2028java-jaからIngressの青(Registance)の勧誘に来られた方w APIをハックして、情報を取得し、Kibanaで可視化 残念ながら、APIが変更されて見れなくなったらしい。 Ingress実際にやったことはないのですが、おもしろそうでした。 発表される方の会社の採用紹介ではなく、Ingressの勧誘をされるとは想定外でしたw\n興味のあるデータをKibanaで可視化するのも面白い例だと思うので、活用してもらえればと思います。\nその他、感想などのブログ 適当に見つけたブログを列挙してあります。これもあるよ!などあれば、教えてください。\n勉強会メモ - 第7回elasticsearch勉強会 第7回elasticsearch勉強会 #elasticsearch #elasticsearchjp まとめ JJUGの時とは違い、Elasticsearch勉強会ではさすがに、企業としてのElasticsearchの知名度が高かったのはありがたいことでした。 自分の発表のために始めた勉強会でもありますが、まだまだ、発表するときは緊張しますし、分かりにくいんじゃないかなぁと思うことも多々あります。 この辺がわかりにくかった、この辺をもっと知りたいなど、フィードバックをお待ちしております。\n冒頭にも書きましたが、Elasticsearch Advent Calendar 2014の登録をお待ちしております。どんなことでも歓迎なので、Elasticsearch、Kibana、Logstashなどについて書いてもらえるとうれしいです。\n次回ももちろん2ヶ月後くらいに行います。 スピーカー募集中ですので、コメント、メール、ツイートなど、コンタクトしていただければと思います。 よろしくお願いいたします。\n","date":1416363547,"dir":"post/2014/","id":"2a8412aa50d07330f1298f0243fa79d3","lang":"ja","lastmod":1416363547,"permalink":"https://blog.johtani.info/blog/2014/11/19/hold-on-7th-elasticsearch-jp/","publishdate":"2014-11-19T11:19:07+09:00","summary":"第7回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん","tags":["elasticsearch","勉強会"],"title":"第7回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:elasticsearch-1.4.0 and 1.3.5 released\n本日、Lucene 4.10.2をベースにしたElasticsearch 1.4.0と、バグフィックスリリースである、Elasticsearch 1.3.5をリリースしました。 ダウンロードおよび変更リストはそれぞれ次のリンクからアクセスできます。\n最新ステーブルリリース:Elasticsearch 1.4.0 1.3.x系バグフィックス:Elasticsearch 1.3.5 1.3ブランチに関する過去のリリースについてのブログは次のとおりです:1.3.4, 1.3.3, 1.3.2, 1.3.1, 1.3.0.\nBeta1リリースでも言及しましたが、1.4.0の主なテーマは*resiliency(復元性、弾力性)*です。 Elasticsearchをより安定し信頼性のあるものにし、メモリ管理を改善し、ディスカバリアルゴリズムを改善し、破損したデータの検知を改善しました。 Beta1リリースからのハイライトも含んでいます。\nDoc values (インデックス時にディスクに保存されるfielddata)がヒープ利用率を激減 Request circuit breaker: メモリを消費しすぎる検索リクエストの中断 Bloom filterのデフォルト無効、高速なインデキシングのためにもはや必要とされないため。 ノードディスカバリ、シャードリカバリの数多くのバグフィックス及び改善 データ破損の早期検知のためのチェックサムのさらなる利用 GroovyをMVELの代わりにデフォルトスクリプト言語に CORSをデフォルト無効に。XSS攻撃防止の為。 クエリキャッシュ、変更されていないシャードからすぐにaggregation結果を返す 新しいAggregation:filter(ドキュメント)、children(ドキュメント)、scripted_metric(ドキュメント) 新しいGET /indexAPI。インデックスのsettings、mappings、warmers、aliasesを1回のリクエストで返却(ドキュメント) 自動付与ドキュメントIDのためのFlake ID。プライマリキーの探索パフォーマンスの改善。 ドキュメントに変更のない更新によるドキュメントの再インデックスの防止 function_scoreクエリの関数でweightパラメータによる個別の改善を可能に。(ドキュメント) 詳細については1.4.0.Beta1のブログ(英語)(日本語訳)をご覧ください。\nBeta1以降の1.4.0の変更の全てについては、1.4.0 release notesでご覧いただけます。 以下では、2つの主な変更について紹介します。\nHTTP Pipelining HTTP pipeliningは複数のリクエストを1回のコネクションで、関連するレスポンスを待つことなく送信することができます。 そして、レスポンスは、受け取ったリクエストと同じ順序で返却されます。 HTTP/1.1の仕様で、pipeliningのサポートが必要です。ElasticsearchはHTTP/1.1であるとしてきましたが、pipeliningはサポートしていませんでした。この問題は.NETユーザで問題を引き起こしました。\n現在、HTTP pipeliningは公式にサポート済みで、デフォルトで利用できます。#8299をご覧ください。\nUpgrade API Luceneのすべてのリリースではバグフィックスや最適化が提供されます。しかし、多くのユーザは古いバージョンのLuceneで作成されたインデックスを持っており、より最新の改善による利点を利用できないことがあります。 新しいupgradeAPIは、あなたのインデックスすべてもしくは一部を最新のLuceneフォーマットに透過的にアップグレードできます。\nGET _upgradeリクエストは、インデックスのアップグレードが必要かどうかを提示し、アップグレードに必要なセグメントのサイズをリポートすることによって、どのくらいの時間が必要かの目安を提供します。 POST _upgradeコマンドはバックグラウンドでインデックスを最新のLuceneフォーマットに書き換えます。\nより詳しい情報はupgradeAPIドキュメントをご覧ください。\n試してみてください。 Beta1リリースを利用し、経験・体験を報告していただいたベータテスターの方々に感謝します。 1.4.0がこれまでの最高のリリースになると確信しています。 ぜひ、Elasticsearch 1.4.0をダウンロードして、試してみてください。 そして、感想をTwitter(@elasticsearch)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1415205033,"dir":"post/2014/","id":"d266a2023c67b7a20c3bd01055b223bc","lang":"ja","lastmod":1415205033,"permalink":"https://blog.johtani.info/blog/2014/11/06/elasticsearch-1-4-0-ja/","publishdate":"2014-11-06T01:30:33+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:elasticsearch-1.4.0 and 1.3.5 released 本日、Lucene 4.10.2をベースにし","tags":["elasticsearch"],"title":"Elasticsearch 1.4.0および1.3.5リリース(日本語訳)"},{"contents":"久しぶりに翻訳ではないブログを。書こうと思いながらかけてなかったので。。。\n今回はvalidate APIの紹介です。\n背景 ElasticsearchのクエリはQuery DSLというJSONで クエリを定義できるものを提供しています。 これは、様々なクエリ、フィルタを定義するために必要です。\n自分の望んでいる条件を記述するために、JSONのネストと格闘することも必要となります。。。 また、クエリ、フィルタには様々なパラメータが用意されています。 これらのパラメータをすべて覚えるのは無理でしょうし、タイプミスなどもありますよね。 タイプミスやカッコのミスマッチなどで格闘して1時間が経過してしまったなどもあると思います。\nそんな時に便利なAPIとして用意されているのがvalidate APIです。\n利用方法 APIが用意されています。\nhttp://ホスト名:ポート番号/インデックス名/タイプ名/_validate/query インデックス名やタイプ名は省略可能ですが、マッピングが異なると思うので、タイプ名まで指定するほうが良いと思います。 上記のAPIに対してクエリを送信するだけです。\nクエリの確認 たとえば、こちらのGistにあるようなマッピングのインデックスに対して 検索クエリを組み立てていて、エラーが出るとします。 ※このクエリはmatch_allのところをmatch_alと、lが1文字足りないクエリになっています。\n検索クエリのリクエスト(エラーあり)\nGET pref_aggs/_search { \u0026#34;query\u0026#34;: { \u0026#34;match_al\u0026#34;: {} } } 実行結果のレスポンス\n{ \u0026#34;error\u0026#34;: \u0026#34;SearchPhaseExecutionException[Failed to execute phase [query], all shards failed; shardFailures {[rwkb01chTZq2V7FD0Tlwrw][pref_aggs][0]: SearchParseException[[pref_aggs][0]: from[-1],size[-1]: Parse Failure [Failed to parse source [{\\n \\\u0026#34;query\\\u0026#34;: {\\n \\\u0026#34;match_al\\\u0026#34;: { }\\n }\\n}\\n]]]; nested: QueryParsingException[[pref_aggs] No query registered for [match_al]]; }{[rwkb01chTZq2V7FD0Tlwrw][pref_aggs][1]: SearchParseException[[pref_aggs][1]: from[-1],size[-1]: Parse Failure [Failed to parse source [{\\n \\\u0026#34;query\\\u0026#34;: {\\n \\\u0026#34;match_al\\\u0026#34;: { }\\n }\\n}\\n]]]; nested: QueryParsingException[[pref_aggs] No query registered for [match_al]]; }]\u0026#34;, \u0026#34;status\u0026#34;: 400 } とこんなかんじで、エラーが帰っては来るのですが、非常に読みづらいです。\nそこで、validate APIを利用します。 リクエスト先を/_searchから/_validate/queryに変更します。\nvalidate API\nGET pref_aggs/_validate/query { \u0026#34;query\u0026#34;: { \u0026#34;match_al\u0026#34;: {} } } validate APIのレスポンス\n{ \u0026#34;valid\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;failed\u0026#34;: 0 } } すると、非常にシンプルな結果が返ってきます。 \u0026quot;valid\u0026quot;: falseとなっているため、クエリに問題があることがわかります。\nエラーの詳細 問題がある事自体はわかりましたが、エラーの内容も知りたいですよね? その場合は、explainというパラメータを追加します。 (正しくはexplain=trueを追加しますが、=trueを省略可能です。)\nvalidate API(explainあり、クエリ自体は省略)\nGET pref_aggs/_validate/query?explain {...} validate APIのレスポンス\n{ \u0026#34;valid\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;explanations\u0026#34;: [ { \u0026#34;index\u0026#34;: \u0026#34;pref_aggs\u0026#34;, \u0026#34;valid\u0026#34;: false, \u0026#34;error\u0026#34;: \u0026#34;org.elasticsearch.index.query.QueryParsingException: [pref_aggs] No query registered for [match_al]\u0026#34; } ] } explanationsという項目が追加されました。 ここにerrorという項目として、エラーの詳細が返ってきます。_searchの時よりも見やすいですね。 今回のエラーは、match_allが正しいクエリですの、match_alというクエリは登録されていないというエラーでした。 では、クエリを修正して実行しましょう。\nvalidate API(エラー無し)\nGET pref_aggs/_validate/query?explain { \u0026#34;query\u0026#34;: { \u0026#34;match_all\u0026#34;: {} } } validate APIのレスポンス\n{ \u0026#34;valid\u0026#34;: true, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;explanations\u0026#34;: [ { \u0026#34;index\u0026#34;: \u0026#34;pref_aggs\u0026#34;, \u0026#34;valid\u0026#34;: true, \u0026#34;explanation\u0026#34;: \u0026#34;ConstantScore(*:*)\u0026#34; } ] } 今度はクエリに問題はありません。\u0026quot;valid\u0026quot;: trueです。 そして、explanationsの項目には、errorの代わりにexplanationという項目が返ってきました。 これが、実際にElasticsearch内部で実行されるクエリになります。\n実際のクエリに利用される単語の確認 この機能はこの他に、クエリの解析にも利用できます。 思ったとおりに検索にヒットしない場合があって、困ったことはないですか? フィールドに指定されたアナライザによっては、単語を変形したりするものが存在します。\nサンプルマッピング\nPUT /validate_sample { \u0026#34;mappings\u0026#34;: { \u0026#34;several_analyzer\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;title\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;body_ja\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;kuromoji\u0026#34;}, \u0026#34;body_en\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;english\u0026#34;} } } } } 例えば、このようにkuromoji、english、デフォルト(standard)アナライザを利用したマッピングがあるとします。 このフィールドに対してpowerfulという単語で検索したとします。\nvalidate API\nGET /validate_sample/_validate/query?explain { \u0026#34;query\u0026#34;: { \u0026#34;multi_match\u0026#34;: { \u0026#34;fields\u0026#34;: [\u0026#34;body_en\u0026#34;,\u0026#34;body_ja\u0026#34;,\u0026#34;title\u0026#34;], \u0026#34;query\u0026#34;: \u0026#34;powerful\u0026#34; } } } この場合、レスポンスは次のとおりです。\nvalidate APIのレスポンス\n{ \u0026#34;valid\u0026#34;: true, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;explanations\u0026#34;: [ { \u0026#34;index\u0026#34;: \u0026#34;validate_sample\u0026#34;, \u0026#34;valid\u0026#34;: true, \u0026#34;explanation\u0026#34;: \u0026#34;(title:powerful | body_en:power | body_ja:powerful)\u0026#34; } ] } title、body_jaについては入力された単語がそのままクエリとして利用されています。 body_enについては、powerという単語に変換されて実行されています。 これは、englishアナライザがステミングを行った結果がクエリとして利用されるという意味です。 また、powerfulを秋葉原といった日本語に変更して実行すると次のようになります。 日本語はstandardアナライザなどでは、1文字ずつ区切られてしまうことがわかります。\nvalidate APIのレスポンス\n{ \u0026#34;valid\u0026#34;: true, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;explanations\u0026#34;: [ { \u0026#34;index\u0026#34;: \u0026#34;validate_sample\u0026#34;, \u0026#34;valid\u0026#34;: true, \u0026#34;explanation\u0026#34;: \u0026#34;((title:秋 title:葉 title:原) | (body_en:秋 body_en:葉 body_en:原) | ((body_ja:秋葉 body_ja:秋葉原) body_ja:原))\u0026#34; } ] } このように、クエリの単語がどのような単語に変換されてクエリに利用されているかなども知ることが可能です。\nまた、クエリを組み立てて、ヒットするはずが、0件となってしまうという場合にも、どのようなクエリが組み立てられているかを確認するという点で、 validate APIが役立ちます。 検索がヒットするが、望んだクエリになっていないのでは?という場合は_search APIのexplainパラメータを 利用すれば、クエリの構成がわかるのですが、検索結果が0件の場合はクエリの構成は表示されません。\n解決できない問題は? 便利なvalidate APIですが、以下の問題に対しては残念ながら確認できません。\nquery以外の項目のvalidate不可 たとえば、_search APIのsizeなどの項目についてはチェックできないです。 存在しないフィールドの指定 上記validate_sampleのマッピングの例でクエリにbody_engという存在しないフィールドを指定してもエラーとはなりません。 まとめ 書いたクエリがうまく動かない、JSONのタグがおかしいといった場合は、 まずはこのvalidate APIで確認してみるのがオススメです。\n","date":1414402951,"dir":"post/2014/","id":"bc2709406a9bb19e8d83a78f81e36244","lang":"ja","lastmod":1414402951,"permalink":"https://blog.johtani.info/blog/2014/10/27/how-to-use-validate-api/","publishdate":"2014-10-27T18:42:31+09:00","summary":"久しぶりに翻訳ではないブログを。書こうと思いながらかけてなかったので。。。 今回はvalidate APIの紹介です。 背景 Elasticsear","tags":["elasticsearch"],"title":"validate APIの利用"},{"contents":"Elasticsearch 1.4.0.Beta1がリリースされました。\n個人でelasticsearch-extended-analyzeというプラグインを開発してます。 こちらも1.4.0.Beta1に対応するべく作業をしてて、少し戸惑ったことがあったので、メモをば。\nここ最近はプラグインのバージョン番号をElasticsearchのバージョン番号と同じものを利用していました。 (プラグインの機能追加をサボってる??) その時に、1.4.0.Beta1という番号を指定したのですが、意味不明なエラーに悩まされてしまいまして。\nプラグインのリリースでは、以下のコマンドを実行します。\n$ mvn release:prepare $ mvn release:perform 最初のコマンド(prepare)で、パッケージングを実施し、Githubにリリースタグを打ったバージョンがpushされます。 次のコマンド(perform)で、パッケージングされたzipファイルがsonatypeのサイトに公開するためにアップロードされます。\n1.4.0.Beta1というバージョン文字列を利用した場合、prepareは問題なく実行できたのですが、 performで以下の様なエラーが返ってきました。\nReturn code is: 401, ReasonPhrase: Unauthorized. バージョン番号が1.3.0では特に問題はなかったのですが、、、 結局、バージョン番号を1.4.0-beta1に変更すると問題なくリリースが完了しました。\nmike_neckさんと話をしていて、Semantic Versioningに関係しているのかなぁという話にはなったのですが、 詳しく調べていません。。。\nそのうち調べようかなぁ。。。。\n","date":1413354368,"dir":"post/2014/","id":"998eda745d07fd8608f251138384a0b9","lang":"ja","lastmod":1413354368,"permalink":"https://blog.johtani.info/blog/2014/10/15/versioning-of-sonatype/","publishdate":"2014-10-15T15:26:08+09:00","summary":"Elasticsearch 1.4.0.Beta1がリリースされました。 個人でelasticsearch-extended-analyzeというプラグインを開発してま","tags":["Elasticsearch","plugin","sonatype"],"title":"Sonatypeのバージョン番号で困ったので"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:elasticsearch 1.4.0.beta1 released\n本日、Lucene 4.10.1をベースにした、Elasticsearch 1.4.0.Beta1をリリースしました。 Elasticsearch 1.4.0.Beta1からダウンロードできます。 また、すべての変更点に関してもこちらをご覧ください。\n1.4.0のテーマは*resiliency(復元性、弾力性)*です。 resiliencyとはElasticsearchをより安定し信頼性のあるものにすることを意味します。 すべての機能が正常に機能している場合は信頼することは簡単です。 予想外のことが発生した時に難しくなります:ノードでout of memoryの発生、スローGCや重いI/O、ネットワーク障害、不安定なデータの送信によるノードのパフォーマンス低下など。\n本ベータリリースは、resiliencyの主な3つの改善を含んでいます。\nメモリ使用量の低下によるノードの安定性向上 discoveryアルゴリズムの改善によるクラスタの安定性向上 チェックサムの導入による破損したデータの検知 分散システムは複雑です。 決して想像できないような状況をシミュレーションするために、ランダムなシナリオを作成する広範囲なテストスイートを持っています。 しかし、無数のエッジケース(特殊なケース)があることも認識しています。 1.4.0.Beta1はこれまで私たちが行ってきた改善のすべてを含んでいます。 これらの変更を実際にテストしていただき、何か問題があった場合は私たちに教えてください。\nメモリ管理 ヒープ空間は限られたリソースです。 上限を32GBとし、利用可能なRAMの50%をヒープの上限にすることを推奨します。 この上限を超えた場合、JVMは圧縮したポインタを使用することができず、GCが非常に遅くなります。 ノードの不安定性の主な原因は遅いGCです。それは、次のようなことから発生します。\nメモリプレッシャー スワップ(参照:memory settings) 非常に大きなヒープ 本リリースは、メモリ管理の改善し、(結果として)ノードの安定性を改善するいくつかの変更を含んでいます。\ndoc values メモリの利用の最も大きなものの1つはfielddataです aggregation、ソート、スクリプトがフィールドの値に素早くアクセスするために、フィールドの値をメモリにロードして保持します。 ヒープは貴重なため、1ビットも無駄にしないためにメモリ内のデータは高度な圧縮と最適化を行っています。 これは、ヒープスペース以上のデータをもつまでは、非常によく動作します。 これは、多くのノードを追加することによって常に解決できる問題です。 しかし、CPUやI/Oが限界に達してしまうずっと前に、ヒープ空間の容量に到達します。\n最近のリリースは、doc valuesによるサポートがあります。 基本的に、doc valuesはin-memory fielddataと同じ機能を提供します。 doc valuesの提供する利点は、それらが、非常に少量のヒープ空間しか使用しない点です。 doc valuesはメモリからではなく、ディスクから読み込まれます。 ディスクアクセスは遅いですが、doc valuesはカーネルのファイルシステムキャッシュの利点を得られます。 ファイルシステムキャッシュはJVMヒープとはことなり、32GBの制限による束縛がありません。 ヒープからファイルシステムキャッシュにfielddataを移行することによって、より小さなヒープを使うことができます。これは、GCがより早くなり、ノードが更に安定することを意味します。\n本リリースより前は、doc valuesはin-memory fielddataよりもかなり遅かったです。 本リリースに含まれる変更は、パフォーマンスをかなり向上させ、in-memory fielddataとほぼ同じくらいの速度になっています。\nin-memory fielddataの代わりにdoc valuesを利用するために必要なことは、次のように新しいフィールドをマッピングすることです。\nPUT /my_index { \u0026#34;mappings\u0026#34;: { \u0026#34;my_type\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;timestamp\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;date\u0026#34;, \u0026#34;doc_values\u0026#34;: true } } } } } このマッピングで、このフィールドに対するfielddataの利用は、メモリにフィールドをロードする代わりに、自動的にディスクからdoc valuesを利用します。 *注意:*現時点で、doc valuesはanalyzedなstringフィールドはサポートしていません。\nrequest circuit breaker fielddata circuit breakerはfielddataによって利用されるメモリの上限を制限するために追加され、OOMEの最も大きな原因の1つを防ぎました。 そして、リクエストレベルのcircuit-breakerを提供するために、コンセプトを拡張しました。 これは、単一のリクエストによって使用されるメモリの上限を制限します。\nbloom filters Bloom filters はインデキシング(前のバージョンのドキュメントが存在するかどうかのチェックのため)や、 IDによるドキュメントの検索(ドキュメントを含むセグメントがどれかを決定するため)に関する重要な性能最適化を提供しました。 しかし、もちろんそれらはコスト(メモリ)を必要とします。 現在の改善は、bloom filterの必要性を取り除きました。 現在では、Elasticsearchはまだ、インデックス時にそれらを構築します(実世界の経験がテストシナリオにそぐわない場合に備えて)。 しかし、デフォルトではメモリにはロードされません。 すべてが予定通りに運べば、将来のバージョンで完全にこれらは除去します。\nクラスタの安定性 クラスタの安定性向上のために私たちができる最も大きなことは、ノードの安定性の向上です。 もし、ノードが安定しておりタイミングよく反応すれば、クラスタが不安定になる可能性が大いに減少します。 私たちは不完全な世界に住んでいます。- 物事は予想外にうまく行きません。クラスタはデータを失うことなくこのような状況から回復できる必要があります。\n私たちは、improve_zenブランチ上で、Elasticsearchの障害からの復旧するための能力の向上に数ヶ月費やしてきました。 まず、複雑なネットワークレベルの障害を繰り返すためのテストを追加しました。 次に、各テストのための修正を追加しました。 そこには、より多くの行うことが存在します。しかし、私たちは、issue #2488(\u0026ldquo;分割が交差している場合、minimum_master_nodesはsplit-brainを防げない\u0026rdquo;)に含まれる、ユーザが経験してきた大部分の問題を私たちは解決しました。\n私たちはクラスタのresiliencyを非常に真剣に取り組んでいます。 私たちは、Elasticsearchが何ができるか、その上で何が弱点であるかを理解してほしいと思っています。 これを考慮して、私たちはResiliency Status Documentを作成しました。 このドキュメントは、私たち(または私たちユーザ)が遭遇したresiliencyの問題の、何が修正済みで、何が修正されないまま残っているかを記録します。 このドキュメントを慎重に読み、あなたのデータを保護するために適切な方法を選択してください。\nデータ破損の検知 ネットワークをまたいだシャードリカバリのチェックサムは、圧縮ライブラリのバグを発見する助けとなりました。 それは、バージョン1.3.2で修正済みです。 それ以来、私たちはElasticsearchのいたるところにチェックサムとチェックサムの確認を追加しました。\nマージ中に、あるセグメント内すべてのチェックサムの確認(#7360) インデックス再オープン時に、あるセグメント内の最も小さなファイルの完全な確認と、より大きなファイルの軽量な打ち切りチェック(LUCENE-5842) トランザクションログからイベントを再生するとき、各イベントはチェックサムを確認される(#6554) シャードのリカバリ中もしくは、スナップショットからのリストア中にElasticsearchはローカルファイルとリモートのコピーが同一であるか確認する必要がある。ファイルの長さとチェックサムのみを使うのは不十分であることが確認された。このため、現在はセグメントのすべてのファイルの同一性を確認(#7159) その他のハイライト Elasticsearch 1.4.0.Beta1のchangelogに本リリースの多くの機能、改善、バグフィックスについて読むことができます。 ここでは、特筆すべきいくつかの変更について述べます。\ngroovyによるmvelの置き換え Groovyは現在、デフォルトのscripting languageです。 以前のデフォルトはMVELで、古くなってきており、サンドボックス内で実行できないという事実は、セキュリティ問題でした。 Groovyはサンドボックスであり(それは、ボックスの外へは許可が必要)、メンテナンスされており、速いです! 詳しくはscriptingについてのブログ記事をご覧ください。\nデフォルトでcorsはオフ Elasticsearchのデフォルト設定はクロスサイトスクリプティングに対して脆弱でした。 私たちはデフォルトでCORSをオフにすることで修正しました。 Elasticsearchにインストールされたサイトプラグインはこれまで同様に機能します。 しかし、CORSを再度オンにすることがない限り、外部のウェブサイトがリモートのクラスタにアクセスすることはできません。 ウェブサイトがあなたのクラスタにアクセス可能に制御できるように、さらにCORS settingsを追加しました。 詳しくはsecurity pageをご覧ください。\nクエリキャッシュ 新しい試験的なshardレベルのクエリキャッシュは、静的なインデックスのアグリゲーションをほとんど即座に反応できます。 ウエブサイトのアクセスの日毎のページビュー数を見るダッシュボードを持っていると想像してみてください。 これらの数値は古いインデックスでは変更がありません。しかし、アグリゲーションはダッシュボードのリフレッシュのたびに再計算されます。 新しいクエリキャッシュを利用すると、シャードのデータが変更されない限り、アグリゲーションの結果はキャッシュから直接返却されます。 キャッシュから古い結果を決して取得することはありません。それは、常に、キャッシュされていないリクエストと同じ結果を返します。\n新しいaggregations 3つの新しいaggregationsがあります。\nfilters\nこれはfilter aggregationの拡張です。複数のバケットを定義し、バケット毎に異なるフィルタを利用できます。 children\nnestedアグリゲーションの親子版。children aggは親のドキュメントに属する子のドキュメントを集計できる scripted_metric\nこのaggregationは、データによって計算されたメトリックを完全にコントロールできます。これは、初期化フェーズ、ドキュメント収集フェーズ、shardレベル結合フェーズ、global reduceフェーズを提供します。 get /index api 以前、ある1つのインデックスのaliases、mappings、settings、warmersを取得出来ました。しかし、それらを個別にです。 get-index API はこれらのすべてもしくは一部を、複数もしくはひとつのインデックスに対して一緒に取得できます。 これは、既存のインデックスと同一もしくはほぼ同一であるインデックスを作成したいときに非常に役に立ちます。\n登録と更新 ドキュメントの登録と更新にいくつかの改善があります。\n現在、ドキュメントIDの自動生成のためにFlake IDを使用しています。これは、プライマリキー探索時に素晴らしい性能向上を提供します。 detect_noopにtrueを設定すると、ドキュメントに変更を与えない更新が軽量になります。この設定を有効にすると、_sourceフィールドのコンテンツを変更する更新リクエストだけ、ドキュメントの新しいバージョンを書き込みます。 更新はスクリプトから完全に操作できます。以前は、スクリプトはドキュメントがすでに存在しているときだけ実行可能で、それ以外は、upsertドキュメントで登録しました。script_upsertパラメータでスクリプトから直接ドキュメントの作成が操作できます。 function score すでに非常に便利なfunction_scoreクエリが、新しくweightパラメータをサポートします。 これは、それぞれの指定された関数の影響をチューニングするのに使われます。 これは、人気度よりも更新日時により重みをかけたり、地理情報よりも価格により重みをかけるといったことを可能にします。 また、random_score機能はセグメントマージによる影響を受けません。これにより、より一貫した順序が提供されます。\n試してみてください。 ぜひ、Elasticsearch 1.4.0.Beta1をダウンロードして、試してみてください。 そして、感想をTwitter(@elasticsearch)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1412244840,"dir":"post/2014/","id":"853cac0f2d1f90b7c986e7d1dcdbbfde","lang":"ja","lastmod":1412244840,"permalink":"https://blog.johtani.info/blog/2014/10/02/elasticsearch-1-4-0-beta-released-ja/","publishdate":"2014-10-02T19:14:00+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:elasticsearch 1.4.0.beta1 released 本日、Lucene 4.10.1をベースにした、Elast","tags":["Elasticsearch"],"title":"elasticsearch 1.4.0.Beta1のリリース"},{"contents":"第6回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 次回もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。 今回は、スタッフが私を含めて3,4名ということで、ドタバタしてしまってスミマセンでした。\n今回はキャンセルが多く、最終的には90人弱の参加となりましたが、今回も多数の方にお集まりいただきありがとうございました。 同じ日に他の勉強会もあった影響でしょうか?\n「Aggregationあれこれ」Elasticsearch Inc. Jun Ohtani @johtani スライド:Aggregationあれこれ\nちょっと長かったですかね。。。 Aggregationの概要、内部動作、種類などを簡単に紹介してみました。 個々のAggregationもいろいろなオプションなどがあるので、色々と試してみていただければと思います。 アニメーション入りのスライドになってましたが、UpしてあるスライドはPDF版になります。 「秒間3万の広告配信ログをElasticSearchでリアルタイム集計してきた戦いの記録」 株式会社サイバーエージェント 山田直行さん @satully スライド:秒間3万の広告配信ログをElasticSearchでリアルタイム集計してきた戦いの記録\nディスプレイ広告配信DSPの話 システム: Fluentd、S3、Elasticsearch、Redis、MySQL 7月に秒間3万〜4万のリクエストをさばいている。 なぜElasticsearchを選んだのか、今の構成など 実際に苦労された点なども交えて話していただき面白かったです。 7月時点のお話ということで、現時点ではまた違う構成っぽかったので、また話を聞きたいなぁ。 「Elasticsearch 日本語スキーマレス環境構築と、ついでに多言語対応」ナレッジワークス株式会社 木戸国彦さん @9215 スライド:Elasticsearch 日本語スキーマレス環境構築と、ついでに多言語対応\nDynamic TemplateやIndex Templateの説明 日本語や多言語化するときのMappingのサンプルになりそうなものがゴロゴロ紹介されてました。 いくつかの例があって、後で見直したいなと。 途中で出てきた、fielddata(インデックスに入っている単語区切りのデータ)を見るのに使ってたクエリはfield data fieldsだったかな。 「elasticsearchソースコードを読みはじめてみた」@furandon_pig さん スライド:elasticsearchソースコードを読みはじめてみた\nリクエストを受けて検索してる部分から読むといいって言われたらしいが、起動スクリプトから読み始めてみた。 時間かかりそうw ただ、人がどんな感じでソースを読んだり理解してるかがわかりやすかったので面白かったです。 定期的に続きを聞いてみたいです。 LT 「reroute APIを使用してシャード配置を制御する」 株式会社富士通ソフトウェアテクノロジーズ 滝田聖己さん @pisatoshi スライド:reroute APIを使用してシャード配置を制御する\nシャードの再配置が自動で行われるので、それをオフにしないと、せっかく移動しても無駄になることがというあるあるネタ Bonsaiロゴを作成するLT 実際にいくら掛かったのかが知りたかった。 「検索のダウンタイム0でバックアップからIndexをリストアする方法」株式会社ドワンゴモバイル 西田和史さん スライド:検索のダウンタイム0でバックアップからIndexをリストアする方法\n擬似無停止のやりかた。 aliasを活用して、かつ、Restoreで再構築するという方法。 aliasまで一緒にリストアされるので注意が必要っていうのは、実際にやってみたからわかることという感じですね。 その他、感想などのブログ 適当に見つけたブログを列挙してあります。これもあるよ!などあれば、教えてください。\n第6回elasticsearch勉強会に行ってきましたのでそのメモ elasticsearch 勉強会 第6回 まとめ 今回も、ためになる話がいっぱい聞けたかなと。 個人的な印象としては、いつものメンバーよりも新しい方が多かった印象です。 また、ほとんどの方が、Elasticsearchをご存知でした。 そこそこ知名度は上がってきているようで嬉しい限りです。(東京以外での知名度なども知りたいかなと。)\nあと、懇親会の部屋の案内が遅くなってしまってスミマセンでした。 さすがにスタッフ3名はきつかったです。。。\n19時半開始にしてみましたが、懇親会の時間がやはり短めになってしまうなぁという印象でした。\n次回ももちろん2ヶ月後くらいに行います。 スピーカー募集中ですので、コメント、メール、ツイートなど、コンタクトしていただければと思います。 よろしくお願いいたします。\n","date":1410927720,"dir":"post/2014/","id":"4616fbea6a6dbc1074bc3f1016bbc73b","lang":"ja","lastmod":1410927720,"permalink":"https://blog.johtani.info/blog/2014/09/17/hold-on-6th-elasticsearch-jp/","publishdate":"2014-09-17T13:22:00+09:00","summary":"第6回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん","tags":["elasticsearch","勉強会"],"title":"第6回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"先日2014年9月9日(火)に『サーバ/インフラエンジニア養成読本 ログ収集〜可視化編』 出版記念!執筆者が語る大講演会!で、 「elasticsearch.もうちょっと入門」というタイトルで発表してきました。 会場のGMOのみなさま、Treasure Data、技術評論社のみなさま、どうもありがとうございました。\n書籍に興味のある方は、右のリンクから購入してもらえるとうれしいです。Kindle版も用意されています。\n提供のTDの方に目をつぶってもらいながらLogstashについての発表となってしまいましたが、楽しんでいただけたかなぁと。 書籍では主にKibana3をメインにしたElasticsearchの使い方だったので、それ以外の機能ということで、Aggregationについて説明してみました。\nそのあとは、おそらく初めてですが、パネルディスカッションにも参加しました。 @naoya_itoさんをモデレーターに、rebuild.fm風に進めていただき、話しやすかったかなと。 (少なくとも私は楽しめました!) ただ、私だけバックグラウンドが少し異なることもあり、話をうまく繋げられなかったかもと気にしていたりもしますが。。。\nパネルディスカッションでもありましたが、エンジニアが「趣味」で入れて試してみるのにはもってこいのツール群だと思います。 ちょっと入れてみて、可視化をしてみるといろいろと発見があると思います。 何かを発見するためにもまず試してみるのが何事も重要かなと最近思ってるのもあるので、気軽に試してみてもらえればと。\n不明点などあれば、著者陣に気軽に聞いていただけると良いかと思います(いいですよね、みなさんw)。 Fluentd(もちろん、Logstashも)、Elasticsearch、Kibanaを利用して、データについて試行錯誤してもらって、 システムやビジネスに必要なものを探索して見てください。\n参考 他の方々のブログをメモとして。\nサービス改善とログデータ解析について発表してきました Kibanaではじめるダッシュボードについて発表してきました #gihyo_efk Fluentdのお勧めシステム構成パターンについて発表しました ","date":1410841260,"dir":"post/2014/","id":"f15702ae9e55bad42182cf18724d1863","lang":"ja","lastmod":1410841260,"permalink":"https://blog.johtani.info/blog/2014/09/16/book-publication-event/","publishdate":"2014-09-16T13:21:00+09:00","summary":"先日2014年9月9日(火)に『サーバ/インフラエンジニア養成読本 ログ収集〜可視化編』 出版記念!執筆者が語る大講演会!で、 「elastics","tags":["勉強会","本"],"title":"elasticsearch.もうちょっと入門という話をしてきました #gihyo_efk"},{"contents":"Elasticsearchのインデキシングに関するパフォーマンス検討\n原文:performance considerations for elasticsearch indexing\nElasticsearchユーザは様々な楽しいユースケースを持っています。小さなログを追加することから、Webスケールの大きなドキュメントの集合をインデキシングするようなことまでです。また、インデキシングのスループットを最大化することが重要で一般的な目標となります。 「典型的な」アプリケーションに対して良いデフォルト値を設定するようにしていますが、次のちょっとした簡単なベストプラクティスによってインデキシングのパフォーマンスをすぐに改善することができます。それらについて記述します。\n第一に、制御できないならば、巨大なJavaヒープを使用しない:必要なサイズ(マシンの持つRAMの半分以下)のheapだけを設定しましょう。Elasticsearchの利用方法のために必要な全体量を設定します。これは、OSにIOキャッシュを制御するためのRAMを残すことを意味します。OSがjavaプロセスをスワップアウトしていないことも確認しましょう。\n最新バージョン(現時点では1.3.2)のElasticsearchにアップグレードしましょう:多数のインデキシングに関連する問題点が最新リリースで修正されています。\n詳細に入る前に警告:ここで述べるすべての情報は現時点での最新(1.3.2)の情報です。しかし、Elasticsearchの更新は日々行われています。この情報をあなたが見た時点では最新ではなく、正確ではなくなっているかもしれません。自信がない場合はユーザメーリングリストで質問してください。\nクラスタのインデキシングスループットをチューニングする場合、Marvelは非常に有用なツールです:ここで述べている各設定を継続的に試し、変更の影響がクラスタの挙動をどのように変更されたかを簡単に可視化することが可能です。\nクライアントサイド bulk APIを常に使いましょう。1リクエストで複数のドキュメントをインデキシングでき、各バルクリクエストで送るのに良いドキュメント数を試しましょう。最適なサイズは多くの要因に依存しますが、最適サイズからずれるならば多すぎるよりも少なすぎる方が良いでしょう。クライアントサイドのスレッドで並列にbulkリクエストを使うか、個別の非同期リクエストを使ってください。\nインデキシングが遅いと結論付ける前に、クラスタのハードウェアの性能を引き出せているかを確認して下さい:すべてのノードでCPUやIOが溢れていないかを確認するためにiostatやtop、psといったツールを使いましょう。もし、溢れていなければ、より多くの並列なリクエストが必要です。しかし、javaクライアントからのEsRejectedExecutionExceptionや、RESTリクエストのHTTPレスポンスとしてTOO_MANY_REQUESTS (429)が返ってきた場合は並列リクエストを多く送りすぎています。もしMarvelを利用しているなら、Node Statistics DashboardのTHREAD POOLS - BULKにリジェクトされた数が表示されます。bulkスレッドプールサイズ(デフォルト値はコア数)を増やすのは得策ではありません。インデキシングスループットを減少させるでしょう。クライアントサイドの並列度を下げるか、ノードを増やすのが良い選択です。\nここでは、1シャードに対してインデキシングスループットを最大化する設定に注目します。1つのLuceneインデックスのドキュメントの容量を測定するために、単一ノード(単一シャード、レプリカなし)で最初にテストをして最適化し、クラスタ全体にスケールする前にチューニングを繰り返します。これはまた、インデキシングスループットの要件を見つけるために、クラスタ全体にどのくらいのノードが必要かをラフに見積もるためのベースラインを与えてくれます。\n単一シャードが十分機能したら、Elasticsearchのスケーラビリティの最大の利点や、クラスタでの複数ノードによるレプリカ数やシャード数の増加の利点が得られます。\n結論を導き出す前に、ある程度の時間(60分)くらいクラスタ全体の性能を計測しましょう。このテストは、巨大なマージ、GCサイクル、シャードの移動、OSのIOキャッシュ、予期しないスワップの可能性などのイベントのライフサイクルをカバーできます。\nストレージデバイス 当然ながらインデックスを保存するストレージデバイスはインデキシングの性能に多大な影響を及ぼします:\nSSDを利用する:これらは最も速いHDDよりも速いです。ランダムアクセスのための消費電力が低いだけでなく、シーケンシャルIOアクセスも高いです。また、同時に発生するインデキシング、マージや検索のための並列的なIOも高速です。 インデックスをリモートマウントされたファイルシステム(例:NFSやSMB/CIFS)上に配置しない:代わりにローカルストレージを使う 仮想化されたストレージ(AmazonのElastic Block Storageなど)に注意:仮想化されたストレージはElasticsearchで十分に動作します。また、十分早く簡単に用意できることから魅力的です。しかし、残念なことに、ローカルストレージと比較すると本質的に遅いです。最近の非公式なテストでは、最高の性能を持つプロビジョニングされたIOPSのSSDオプションのEBSでさえ、ローカルインスタンスにあるSSDよりも遅いです。ローカルインスタンスにあるSSDは物理マシン上のすべての仮想マシンから共有されてアクセスされます。もし他の仮想マシンが急にIOが集中した場合に不可解なスローダウンとなることがあることを覚えておいてください。 複数のSSDを複数のpath.dataディレクトリにインデックスをストライピング(RAID0のように):2つは同様で、ファイルブロックレベルでストライピングする代わりに、個別にインデックスファイルレベルでElasticsearchの\u0026quot;stripes\u0026quot;となります。これらのアプローチは、いづれかのSSDの故障によりインデックスが壊れるという、1シャードが故障する(IO性能を高速化することとトレードオフ)というリスクを増加させることに注意してください。これは、一般的に行うのに良いトレードオフです:単一シャードで最大のパフォーマンスを最適化し、異なるノード間でレプリカを追加すると、ノードの故障への冗長化ができます。また、snapshotやrestoreを使って保険のためにインデックスのバックアップを取ることもできます。 セグメントとマージ 新しくインデキシングされたドキュメントは最初にLuceneのIndexWriterによってRAMに保存されます。RAMバッファがいっぱいになった時もしくは、Elasticsearchがflushもしくはrefreshを実行した時など定期的にこれらのドキュメントはディスクに新しいセグメントとして書き込まれます。最後に、セグメントが多くなった時に、Merge PolicyとSuchedulerによってそれらがマージされます。このプロセスは連続的に生じます:マージされたセグメントはより大きなセグメントとなり、小さなマージが幾つか実行され、また、大きなセグメントにマージされます。これらがどのように動作するかをわかりやすく可視化したブログはこちらです。\nマージ、特に大きなマージは非常に時間がかかります。これは、通常は問題ありません。そのようなマージはレアで全体のインデックスのコストと比べればささいなものです。しかし、マージすることがインデキシングについていけない場合、インデックスに非常に多くのセグメントがあるような深刻な問題を防ぐために、Elasticsearchはやってくるインデキシングリクエストを単一スレッド(1.2以降)に制限します。\nもし、INFOレベルのログメッセージにnow throttling indexingと表示されていたり、Marvelでのセグメント数が増加しているを見た場合、マージが遅れているとわかります。MarvelはIndex Statistics dashboardのMANAGEMENT EXTENDEDの部分にセグメント数をプロットしており、それは、非常にゆっくりと指数対数的に増加しており、大きなマージが終了したところがのこぎりの歯のような形で見て取れます。\nセグメント数 なぜマージが遅れるのでしょう?デフォルトでElasticsearchはすべてのマージの書き込みのバイト数をわずか20MB/secに制限しています。スピニングディスク(HDD)に対して、これはマージによって典型的なドライブのIOキャパシティを飽和させず、並列に検索を十分に実行させることを保証します。しかし、もし、インデキシング中に検索をしない場合や、検索性能がインデキシングのスループットよりも重要でない場合、インデックスの保存にSSDを使用している場合などは、index.store.throttle.typeにnoneを設定して、マージの速度制限を無効化するべきです(詳細はこちらをご覧ください)。なおバージョン1.2以前には期待以上のマージIO制限の発生といったバグが存在します。アップグレードを!\nもし、不幸にもスピニングディスク(それはSSDと同等の並列なIOを扱えません)をまだ使っている場合、index.merge.scheduler.max_thread_countに1を設定しなければなりません。そうでない場合は、(SSDを支持する)デフォルト値が多くのマージを同時に実行させるでしょう。\n活発に更新が行われているインデックスでoptimizeを実行しないでください。それは、非常にコストの高い操作(すべてのセグメントをマージ)です。しかし、もし、インデックスにドキュメントを追加が終わった直後はオプティマイズのタイミングとしては良いタイミングです。それは、検索時のリソースを減らすからです。例えば、時間ベースのインデックスを持っており、新しいインデックスに日々のログを追加している場合、過去の日付のインデックスをオプティマイズするのは良い考えです。特に、ノードが多くの日付のインデックスを持っている場合です。\n更にチューニングするための設定:\n実際に必要のないフィールドをオフにする。例えば_allフィールドをオフ。また、保持したいフィールドでは、indexedかstoredかを検討する。 もし、_sourceフィールドをオフにしたくなるかもしれないが、インデキシングコストは小さい(保存するだけで、インデキシングしない)、また、それは、将来の更新や、前のインデックスを再インデキシングするために非常に価値があり、それはディスク使用率の懸念事項がない限り、オフにする価値はあまりない。それは、ディスクが比較的安価であるので価値がない。 もし、インデックスされたドキュメントの検索までの遅延を許容できるなら、index.refresh_intervalを30sに増やすか、-1を設定して、オフにする。これは、巨大なセグメントをフラッシュし、マージのプレッシャーを減らすことができる。 Elasticsearch 1.3.2(稀に、フラッシュ時に過度のRAMを使用するという問題を修正した)にアップグレードすることで、index.translog.flush_threshold_sizeをデフォルト(200mb)から1gbに増加し、インデックスファイルのfsyncの頻度を減らす。 MarvelにIndex Statistics dashboardのMANAGEMENTにフラッシュの頻度がプロットされている。 インデックスバッファサイズ 巨大なインデックスを構築中はレプリカ数を0にし、あとから、レプリカを有効にする。レプリカが0ということは、データを失った(ステータスがred)時に冗長性がないので、ノードの故障に注意すること。もし、optimize(ドキュメントの追加をすることがないので)を計画するなら、インデキシングが終わったあとで、レプリカを作成する前に実行するのが良いでしょう。レプリカはオプティマイズされたセグメントをコピーするだけになります。詳細はインデックス設定更新を参照。\nもし、ノードがヘビーなインデキシングを行っているだけなら、アクティブなシャードのインデキシングバッファに多くてい512MBをindices.memory.index_buffer_sizeに与えてください。(超えてもインデキシングのパフォーマンスは一般的には改善されません。)Elasticsearchはその設定(Javaヒープのパーセンテージもしくはバイト数)を受けて、min_index_buffer_sizeとmax_index_buffer_sizeの値を前提にノードのアクティブシャードに均等に割り当てます;大きな値はLuceneが最初のセグメントをより大きくし、将来的なマージのプレッシャーを減らすことを意味します。\nデフォルトは10%で、それで十分です;例えば、もし、5つのアクティブなシャードがノードにあり、ヒープが25GBの場合、各シャードは25GBの10%の1/5=512MB(すでに最大値)を持っています。ヘビーなインデキシングのあと、この設定をデフォルトに下げましょう。検索時のデータ構造のために十分なRAMを確保するために。この設定はまだ動的な設定変更はできません。Issueがここにあります。\nインデックスバッファによって現在利用されているバイト数は1.3.0のindices stats APIに追加されています。indices.segments.index_writer_memoryの値を見ることができます。これはMarvelではまだプロットされていませんが、将来のバージョンで追加される予定です。しかし、自分でグラフに追加することもできます。(Marvelはデータは収集しています)\n1.4.0では、indices.segments.index_writer_max_memoryとして、indices stats APIにアクティブシャードにどのくらいのRAMバッファが割り当てられているかも表示されます。これらの値はインデックスのシャード事の値として見ることができ、http://host:9200/\u0026lt;indexName\u0026gt;/_stats?level=shardsを使ってみることができます;これは、全シャードに対する合計と、各シャードごとのstatsを返すでしょう。\nオートIDの利用もしくは良いIDの利用 もし、ドキュメントのIDがなんでも良い場合、Elasticsearchで採番することができます:これは、(1.2以降)ドキュメントIDをバージョンを探さずに保存できるように最適化され、Elasticsearchの日毎のベンチマークで異なるパフォーマンスを見ることができます。(FastとFastUpdateのグラフを比較)\nもし、IDを自身が持っていて、自分の支配下でLuceneに対して素早く選ぼうとしているなら、1.3.2にアップグレードしましょう、IDのルックアップがさらにオプティマイズされています。JavaのUUID.randomUUID()はやめましょう。それは、セグメントに対してどのようにIDを割り当てるかという予測やパターン性がないため、最悪のケースでセグメントごとのシークが発生します。\nFlake IDsを利用した時のMarvelによるインデックス性能の違い:\nflakeIDsPerf ランダムUUIDを利用した場合:\nuuidsPerf 次の1.4.0では、ElasticsearchのID自動採番をUUIDからFlake IDに変更します。\nもし、Luceneのローレベル操作がインデックスに対してなにをやっているかについて興味があるなら、lucene.iwをTRACEログレベルで出力できるようにしてみましょう(1.2から利用可能)。これは、多くの出力がありますが、LuceneのIndexWriterレベルで何が起きているかを理解するのに非常に役に立ちます。出力は非常にローレベルです:Marvelがインデックスに何が起きているかをよりリアルタイムにグラフを描画してくれます。\nスケールアウト 我々は、単一シャード(Luceneインデックス)性能のチューニングに注目してきました。しかし、一旦それに満足できたならば、Elasticsearchはクラスタ全体にわたってインデキシングや検索を簡単にスケールアウトすることに長けています。シャード数(デフォルトでは5)を増やすのは可能です。それは、マシン全体に対して並列度、巨大なインデックスのサイズ、検索時のレイテンシの低下など得ることができます。また、レプリカを1位上にすることは、ハードウェア故障に対する冗長性を持つことを意味します。\n最後に、このドキュメントを見ても問題解決しない場合はコミュニティに参加しましょう。例えば、ElasticsearchのユーザMLに投稿するなど。おそらく、修正すべきエキサイティングなバグがあるでしょう。(パッチも常に歓迎です!)\n","date":1410250260,"dir":"post/2014/","id":"77d965afaebd7193badc746d52b4173f","lang":"ja","lastmod":1410250260,"permalink":"https://blog.johtani.info/blog/2014/09/09/performance-considerations-for-elasticsearch-indexing/","publishdate":"2014-09-09T17:11:00+09:00","summary":"Elasticsearchのインデキシングに関するパフォーマンス検討 原文:performance considerations for elasticsearch indexing Elasticsearchユーザは様","tags":["Elasticsearch"],"title":"Elasticsearchのインデキシングに関するパフォーマンス検討"},{"contents":"懲りずにまた、執筆してみました。みなさん「買って」から感想をいただけるとうれしいです!\n本書について 共著者の方々のブログが詳しいので、そちらを読んでもらいつつ。 実際にログを収集して解析されている方々と一緒に書かせていただくことで色々と勉強させていただいています。\n共著者の方々のブログ @suzu_vさん:サーバ/インフラエンジニア養成読本 ログ収集~可視化編 を書きました @yoshi_kenさん:ログ収集や可視化で話題のFluentd、Elasticsearch、Kibanaを徹底解説したムック本が発売となります @harukasanさん:書きました: サーバ/インフラエンジニア養成読本 ログ収集~可視化編 どの辺を書いたの? 「特集3:Elasticsearch入門」(なんか、入門ばっかりだなぁ)を書かせていただきました。 データストア入門ということで、ほんとうに簡単な他のデータストアを説明し、Elasticsearchってどんなものかを単語の説明をしつつ紹介してみました。\nElasticsearch自体は多くの機能を持っており、それ単体で分厚い書籍がかけるので、ログ検索に関係ありそうな部分をピックアップしてみました。 あとは、運用時に気をつける点や便利なツール(Curatorなど)の紹介をしています。\nまた、Hadoopと合わせて利用してみたい、すでにHadoopにあるデータも活用してみたいという話もありそうだということで、elasticsearch-hadoopについても簡単ですが紹介してあります。\nその他感想 個人的に、忙しい時期(参考記事)だったので、あんまり力になれてないので大変申し訳なく思っています。。。 ただ、素晴らしい出来(カラーでKibanaの解説が日本語で読めたり、Fluentdの逆引きのリストがあったり、ログを貯めて可視化する意義を説明してあったり)です。\nぜひ、読んだ感想をいただければと!\n","date":1407156840,"dir":"post/2014/","id":"bdea71d64cdfcc405e65e750fe8d9b86","lang":"ja","lastmod":1407156840,"permalink":"https://blog.johtani.info/blog/2014/08/04/release-magazine-book-of-log-aggs-and-viz/","publishdate":"2014-08-04T21:54:00+09:00","summary":"懲りずにまた、執筆してみました。みなさん「買って」から感想をいただけるとうれしいです! 本書について 共著者の方々のブログが詳しいので、そちらを","tags":["elasticsearch","kibana","本"],"title":"サーバ/インフラエンジニア養成読本 ログ収集~可視化編 を手伝いました"},{"contents":"Proxy環境で働いている方も結構いると思います。 Twitter上で、Elasticsearchのpluginコマンドでプラグインがインストールできなくて困っている方がいたので、 調べてみたのでメモしておきます。\nプラグインコマンド Elasticsearchでは、プラグインという形でいくつかの便利な機能が公開されています。 形態素解析ライブラリのKuromojiを使うためのプラグインや、クラスタの管理がGUIで可能なkopfプラグインなどがあります。 公式、サードパーティいろいろです。\nこれらのプラグインをElasticsearchにインストールする場合、以下のコマンドを実行すれば 自動的にダウンロードしてpluginsディレクトリにインストールしてくれます。\n./bin/plugin -i elasticsearch/elasticsearch-analysis-kuromoji/2.3.0 ここで、elasticsearch/elasticsearch-analysis-kuromoji/2.3.0がプラグインのパスになります(例では、提供元/プラグイン名/プラグインバージョンとなっています。)。\nこのpluginコマンドがダウンロード元にアクセスに行くのですが、プロキシ環境だとプロキシの設定が必要になります。\nプロキシの指定(Mac/LinuxとWindowsでの違い) Mac/Linux(shコマンド) 以前の記事でプロキシのポート番号などの指定方法を 以下のように説明していました。 (※昔の記事のため、kuromojiプラグインのバージョンが古いです)\nElasticsearchのpluginコマンドはJavaで実装されています。(org.elasticsearch.common.http.client.HttpDownloadHelper) プラグインのダウンロードには、java.net.URL.openConnection()から取得URLConnectionを使用しています。\nですので、pluginのインストールを行う際に、Proxy環境にある場合は以下のようにコマンドを実行します。\n./bin/plugin -DproxyPort=ポート番号 -DproxyHost=ホスト名 -i elasticsearch/elasticsearch-analysis-kuromoji/1.5.0 LinuxやMacの環境であれば、こちらのコマンドでプロキシの指定が可能です。 ただし、Windows環境ではうまくいきません。\nElasticsearchは、環境の違いにより、ダウンロードするファイルが異なります。 Windows環境の方は、zipファイルをダウンロードしてもらうようになっています。 elasticsearchコマンドおよびpluginコマンドがbat形式で提供されているのがzipファイルとなるからです。\nWindows(batコマンド) Windows環境では次のように指定します。\nset JAVA_OPTS=\u0026#34;-DproxyHost=ホスト名 -DproxyPort=ポート番号\u0026#34; bin\\plugin -i elasticsearch/elasticsearch-analysis-kuromoji/2.3.0 コマンドの実装方法が少し異なるために、このようになっています。\nまとめ プロキシ環境で利用される場合は、プラグインコマンドは上記のように実行していただければと。\n公式ガイドには、これらの情報を追記するPRを送る予定です。 また、WindowsのコマンドでもMac/Linuxと同様にできたほうがいい気がするので、Issueをあげようと思います。\n不明点などあれば、コメントいただければと。\n","date":1406874240,"dir":"post/2014/","id":"7cc605e721fdd1d2ccc16f5b6490e830","lang":"ja","lastmod":1406874240,"permalink":"https://blog.johtani.info/blog/2014/08/01/plugin-using-under-proxy-env/","publishdate":"2014-08-01T15:24:00+09:00","summary":"Proxy環境で働いている方も結構いると思います。 Twitter上で、Elasticsearchのpluginコマンドでプラグインがインスト","tags":["elasticsearch","plugin"],"title":"プロキシ環境でのpluginコマンドの実行"},{"contents":"原文:Elasticsearch 1.3.1 Releasedを日本語に翻訳したものです。\nバグフィックス版のElasticsearch 1.3.1をリリースしました。 ダウンロードおよび変更履歴はElasticsearch 1.3.1からお願いいたします。\nこのリリースはインデックスリカバリ時の後方互換性バグ(#7055)への対応です。 このバグはデータの欠損は起こりません。 Elasticsearch 1.3.1へアップグレードすることで問題を回避できます。 このバグは、以下のElasticsearchのバージョンで作成されたセグメントを含むインデックスを1.3.0へアップグレードしようとすると発生します。\nElasticsearch 0.90.7 Elasticsearch 0.90.2 Elasticsearch 0.90.0以前のバージョン このバグは、これらの古いインデックスをレプリカからリカバリできなくします。 これらのバージョンのセグメントを持つインデックスが、レプリカは可能ですが、 ステータスがYellowのままGreenに決してなりません。 ログには次のようなExceptionが発生します。\nIllegalArgumentException[No enum constant org.apache.lucene.util.Version.x.x.x]\nLuceneの特定のバージョンではLuceneのマイナーバージョンを含んでおらず、誤ったバージョン番号がセグメントに記録されました。 LUCENE-5850のチケットがこの問題に対処するためにオープンされています。 この問題は我々の後方互換テストで見つかるべき問題ですが、Luceneで不足しているため発見されませんでした。 テストスイートは今後の可能性のために改良されます。\nこのリリースはその他に、Aggregationのマイナーバグフィックスも含まれています。 詳細はリリースノートをご覧ください\nElasticsearch 1.3.1をダウンロードし、試してください。 もし問題を見つけた場合はGitHubのIssuesへご報告をお願いいたします。\n","date":1406604120,"dir":"post/2014/","id":"fb1da4a6ed74705ad98bb60ad4badaf2","lang":"ja","lastmod":1406604120,"permalink":"https://blog.johtani.info/blog/2014/07/29/elasticsearch-1-3-1-release/","publishdate":"2014-07-29T12:22:00+09:00","summary":"原文:Elasticsearch 1.3.1 Releasedを日本語に翻訳したものです。 バグフィックス版のElasticsearch 1.3.1をリリー","tags":["elasticsearch","release"],"title":"Elasticsearch 1.3.1 リリース(日本語訳)"},{"contents":"Curatorの1.2.0がリリースされました。\n前回のCuratorの記事が古くなってしまった(1.1.0からコマンドのI/Fが変更された)ので 1.1.0および1.2.0に関する記事を翻訳しておきます。\nちなみに、Curatorとは、Elasticsearchに時系列のインデックス(例:LogstashやFluentdでログを保存)を保存している場合にそれらのインデックスを管理(削除したり、クローズしたり)するための便利なツールです。 Curatorの概要については、GitHubリポジトリか前回の記事をご覧ください。\nCurator 1.1.0リリース (2014/06/13公開) 元記事:elasticsearch curator - version 1.1.0 released\nElasticsearch 1.0.0がリリースされ、新しい機能、Snapshot \u0026amp; Restoreが利用できるようになりました。 Snapshotはある時点でのインデックスの写真を撮るように、バックアップを作成することができます。 1.0.0が発表されてすぐに、この機能に関するリクエストが寄せられるようになりました。 「Curatorにスナップショットを追加して!」もしくは「いつCuratorでスナップショットが使えるようになる?」といった感じです。 これがあなたの要望なら、それはついに叶えられました。しかも他の追加機能も一緒にです。\n新機能 Curatorの新機能は以下のとおりです。\n新CLI構造 スナップショット(Snapshot) エイリアス(Aliases) パターンによる除外インデックス指定 配置ルーティング(Allocation Routing) インデックスとスナップショットの表示 リポジトリ管理(個別のスクリプトによる) ドキュメントWiki 新コマンドライン構造 注意:コマンドライン構造の変更とは、Curator 1.1.0以前のcron記述が動作しないことを意味します。Curator 1.1.0にアップグレードする場合はコマンドも修正が必要となるので注意してください。\nシンプルにするために、commandsという概念を追加しました。 また、ヘルプの出力もわかりやすくなっています。 前のバージョンと同じタスクをCuratorは実行できますが、異なるフォーマットを用いるようになりました。\n旧コマンド:\ncurator -d 30 新コマンド:\ncurator delete --older-than 30 コマンドは、フラグとは異なりハイフンを前に付けないことに注意してください。 また、似たような名前のフラグがあることに気をつけてください。 例えば、--older-thanフラグは多くのコマンドに利用できます。 指定される値は各ケースにおいて同一です。「指定された数よりも古いインデックス」となります。\n新しいコマンドのリストは次のとおりです。\nalias allocation bloom close delete optimize show snapshot コマンドのヘルプは次のコマンドで表示されます。\ncurator [COMMAND] --help コマンドに関係あるフラグがすべて表示されます。\nスナップショット(snapshots) snapshotコマンドで、存在しているリポジトリにインデックスのスナップショットを保存することができます。\nCuratorはインデックス毎に1つのスナップショットを作成し、インデックスから名前をつけます。 例えば、インデックスの名前がlogstash-2014.06.10の場合、スナップショットの名前はlogstash-2014.06.10となります。 指定した条件を元に、シーケンシャルに、1つずつインデックスのスナップショットを作成していきます。\ncurator snapshot --older-than 20 --repository REPOSITORY_NAME このコマンドは、20日以上古いインデックスすべてのスナップショットを作成し、REPOSITORY_NAMEで指定されたリポジトリに保存します。\nes_repo_mgrと呼ばれるリポジトリ作成を支援するスクリプトがCuratorには含まれています。 ファイルシステムおよびS3タイプのリポジトリ両方の作成を支援します。\nさらに、古いインデックスのスナップショットを取ることができることに加えて、Curatorは最新のインデックスをアップロードする方法も提供します。 これは、Elasticsearch Marvelのインデックスをアップロードするときに便利です。 トラブルシューティングを目的として、パフォーマンスデータを他の人に見せる場合などです。\ncurator snapshot --most-recent 3 --prefix .marvel- --repository REPOSITORY_NAME このコマンドでは、最新の3つのMarvelインデックスのスナップショットを指定されたリポジトリに保存できます。\nエイリアス(aliases) Curatorはすでに存在するエイリアスにインデックスを追加することも、削除することもできるようになりました。 ただし、エイリアスがすでに存在している必要があります。エイリアスの作成はできません。\nlast_weekという前の一週間のインデックスのエイリアスを保持していること想像してください。 この場合、次の2つのコマンドを利用することで、エイリアスを管理できます。\ncurator alias --alias-older-than 7 --alias last_week curator alias --unalias-older-than 14 --alias last_week 新しく作られたインデックスがインデックステンプレートによって 自動的にエイリアスの一部となるようにElasticsearchに設定しておくと、さらに便利です。 この場合、新しいインデックスが自動的にthis_weekというエイリアスの一部になるようにしてあれば、以下のコマンドのみとなります。\ncurator alias --unalias-older-than 7 --alias this_week this_weekとlast_weekのエイリアスのアップデートを保持できます。\nパターンによる除外(exclude pattern) 時には、指定したインデックスを操作から除外したくなる場合もあるでしょう。 ここまでは、プレフィックスや日付によって選択されたインデックスのみを対象にしてきました。 そこで、--exclude-patternオプションです。これは、指定したインデックスを除いて処理を行うことができます。\nlogstash-2014.06.11というインデックスを決して削除したくないとします。 この場合、次のコマンドのようになります。\ncurator delete --older-than 15 --exclude-pattern 2014.06.11 Curatorはデフォルトでlogstash-というプレフィックスにマッチしますが、2014.06.11というインデックスは対象外となります。\n配置ルーティング(allocation routing) Elasticsearchはノードにタグを付けることができます。 これらのタグはインデックスやシャードをクラスタのどこに配置するかをコントロールするために役立ちます。 一般的なユースケースだと、高性能なSSDドライブを持ったノードをインデキシングのために、ハードディスクを持った性能の低いマシンは検索頻度が低い古いインデックスを配置するといった場合です。 この場合、HDDノードには、elasticsearch.ymlにnode.tag: hdd、SSDノードにはnode.tag: ssdと設定されているべきです。 Curatorはこの時、インデックスをタグに基づいてオフピークの時間帯に再配置させることができます。\nコマンド:\ncurator allocation --older-than 2 --rule tag=hdd index.routing.allocation.require.tag=hddという設定が2日よりも古いインデックスに適用されます。 これは、インデックスのシャードがnode.tag: hddというノードに再配置される必要があると、Elasticsearchに伝えます。\nインデックスとスナップショットの表示(show indices and snapshots) これは、単にあなたの持っているインデックスやスナップショットがどんなものかを表示します。\ncurator show --show-indices これは、デフォルトプレフィックスのlogstash-にマッチするすべてのインデックスを表示します。\ncurator show --show-snapshots --repository REPOSITORY_NAME これは、指定されたリポジトリにある、デフォルトプレフィックスのlogstash-にマッチするすべてのスナップショットを表示します。\nリポジトリ管理(repository management) 前に説明したとおり、es_repo_mgrと呼ばれるヘルパースクリプトをCuratorは含んでいます。 現時点では、fsとs3タイプをサポートしています。 リポジトリを作る前に利用したいタイプのドキュメントを読むようにしてください。 例えば、fsタイプのリポジトリを各ノードで使う場合は、同じ共有ファイルシステムに、同じパスでアクセスできなければなりません。 パスの指定は--locationです。\nfsタイプリポジトリの作成\nes_repo_mgr create_fs --location \u0026#39;/tmp/REPOSITORY_LOCATION\u0026#39; --repository REPOSITORY_NAME 削除\nes_repo_mgr delete --repository REPOSITORY_NAME ドキュメントWiki Curatorのドキュメントが更新され、オンラインにWiki形式でだれでも更新できるようになっています。 コマンドやフラグのより詳細の情報はこちらで見つけることができます。また、もし、興味があれば、ドキュメントを追加することもできます。\nインストールと更新 Curator 1.1.0はPyPiリポジトリにあります。 インストールは以下のとおりです。\npip install elasticsearch-curator バージョン1.0.0からアップグレードする場合は以下のとおりです。\npip uninstall elasticsearch-curator pip install elasticsearch-curator バージョン1.0.0よりも古いバージョンからのアップグレードは以下のとおりです。\npip uninstall elasticsearch-curator pip uninstall elasticsearch pip install elasticsearch-curator pip uninstall elasticsearchで、古いパイションモジュールをを削除します。 適切なバージョンが依存関係により再インストールされます。\nまとめ Curatorの新機能は素晴らしいです!このリリースは大きな改善です。 もし、トラブルや足りないものを見つけた場合はGitHub Issueに報告してください。 また、Curatorが便利だと思ったら、私たちに伝えてください。#elasticsearchタグを付けてツイートしてください!\nCuratorはまだ、始まったばかりです。Curator 2.0のロードマップを作業中です。ここまで読んでいただきありがとうございます。 Happy Curating!\nCurator 1.2.0リリース(2014/07/24) 元記事:curator 1.2.0 released\nCurator v1.1.0のリリースから、数週間が経ちました。 私たちは、Curator 1.2.0をリリースしました。\n新機能(new features) ユーザ指定の日付パターン:長い間リクエストされていた機能 ウィークリーインデックスのサポート:これも長い間リクエストされていた機能 複数のログフォーマットオプション:Logstashフォーマットが利用可能 これらの変更はCuratorドキュメントにも記載されています。\n更新(updates) ログ出力の整理:デフォルトのログ出力を整理しました。デバッグログはすべて表示されます。 ドライランのログ出力の詳細化:テスト実行時に何が起きたかをわかりやすくしました。 日付パターンと--timestring(date patterns and \u0026ndash;timestring) 前のリリースで、セパレータ文字を利用して、インデックス名のエレメントを分離することで、日付を計算しました。 この設計の決定は、プログラムが管理するために設計されたLogstashのインデックスを使うのには簡単でした。 しかし、Curatorは時系列インデックス管理に成長しています。これは、異なる命名規則のインデックスを意味しています。\nまた、インターバルによって、日付の計算が必要になる場合もあります。 --time-unitオプションが残っており、weeksという単位を指定することもできます。 デフォルトの--timestringオプションは、以前のコマンドと同様の動作をしなければなりません。次のようになります。\nTime Unit Timestring days %Y.%m.%d hours %Y.%m.%d.%H weeks %Y.%W これが意味するものは、もし、単位にhoursをした場合、--timestringを指定しなかった場合は%Y.%m.%d.%Hとなります。 これは、Pythonのstrftimeフォーマットで\u0026quot;年.月.日.時\u0026quot;を意味します。 同様に、weeksを単位に指定した場合、Curatorはデフォルトの--timestringは%Y.%Wとなります。\nこの機能は、日付の間にセパレーター文字のないインデックスでも機能します。 例えば、production-20140724のような日時インデックスがある場合、2日よりも古いインデックスに対するブルームフィルタっキャッシュのオフのコマンドは次のようになります。\ncurator bloom --prefix production- --older-than 2 --timestring %Y%m%d この例で、デフォルトの単位はdaysであることに注意してください。hourly-2014072414のような時間インデックスの場合は次のようになります。\ncurator bloom --prefix hourly- --older-than 2 --time-unit hours --timestring %Y%m%d%H --separatorの置き換え もし、Curatorの前のバージョンでカスタムセパレータ文字を利用していた場合、次のように変更すべきです。 前のコマンドでcerberus-2014-07-24のようなインデックスがある場合、コマンドを--separator -の用に置き換える必要があります。 新しいコマンドは次のとおりです。\ncurator delete --prefix cerberus- --older-than 30 --timestring %Y-%m-%d 年(%Y)と月(%m)と日(\u0026rsquo;%d\u0026rsquo;)の間にセパレータ文字を置くだけです。\nこれは、また、Curatorで以前は不可能であったことをできるようにもします。 異なるセパレータ文字の混在です。 logs-2014.07.24-14というようなインデックスを処理するときに--timestringは%Y.%m.%d-%Hのようになります.\n--timestringの詳細はCuratorのドキュメントをご覧ください。\nフィードバック これらの新しい機能はユーザのコメントやリクエストから来ています。もし、機能のリクエストやバグを発見したら、こちらまで連絡してください。\nまた、Twitterでもお待ちしています。私たちのTwitter IDは@elasticsearchです。\nHappy Curating!\n","date":1406524740,"dir":"post/2014/","id":"0c1821d1069578551d0e3c7d9275f16b","lang":"ja","lastmod":1406524740,"permalink":"https://blog.johtani.info/blog/2014/07/28/curator-2-0-and-1-1/","publishdate":"2014-07-28T14:19:00+09:00","summary":"Curatorの1.2.0がリリースされました。 前回のCuratorの記事が古くなってしまった(1.1.0からコマンドのI/Fが変更された)","tags":["elasticsearch","curator"],"title":"Curator 1.2および1.1について"},{"contents":"第5回Elasticsearch勉強会を開催しました。 遅くなってしまいましたが、まとめてみました。\n今回は、Elasticsearchに入って初の勉強会でした。タイミングが良いことに、Honza、Igor、Shayの3名がトレーニングのために 来日していたため、特別回ということにして、話をしてもらいました。\nそして、サムライズムの@yusukeさんにテキスト翻訳してもらいました。 早くて正確なタイピング+翻訳、本当にありがとうございました。\n開場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 次回もよろしくお願いします! 参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\namazing turnout to the elasticsearch at Tokyo #elasticsearchjp pic.twitter.com/Aa88eVf5dF\n\u0026mdash; Shay Banon (@kimchy) 2014, 7月 14 動画があとで、アップされる予定です。お楽しみに。\nHonza\u0026rsquo;s talk djangoの開発者!であり、ElasticsearchのPythonクライアント、Curatorの開発者 Python Clientを利用しながら、ライブコーディングのような形で説明する方法が新鮮 Aggregationの便利さについての説明 Python Clientがクエリを組み立てるのにすごく便利そうだった Pythonユーザが結構いたので助かりましたw Igor\u0026rsquo;s talk スライド:elasticsearch data/\nSnapshot/Restoreの開発などを行っている開発者 Elasticsearchのデータ、ディレクトリ構造に関するお話 シャードの話から、ディレクトリ構造、メタデータに関する説明 transaction logの挙動の説明 検索のフェーズの説明 Igorは、実は私がElasticsearch社の人とコンタクトがとれた最初の人だと思います。 第1回Elasticsearch勉強会が開催する当日に帰国されるという不運だったのですが、1年越しでトークしてもらえました!\n@johtani I am so bummed! I am leaving Tokyo Thursday morning.\n\u0026mdash; Igor Motov (@imotov) 2013, 8月 27 QA ShayをメインにいくつかのQAをしてもらいました。 NetflixなどのMeetupの動画で見てたのですが、こんな形で日本でも実現できるとは。\nQ: なんで、ファイルデスクリプタの設定を大きくするの? A: Luceneのインデックスは複数のセグメントから構成されている。メモリに作られたあと、ファイルにfsyncされる。 Q: KibanaでAggregation使いたいんだけど? A: Kibana 4で対応するよ!異なるフィールドの値を1つのグラフにすることも出来るよ! Q: なんでElasticsearch作ったの? A: 暇だったからw奥さんのレシピ検索を作ってみようと思って作り始めて、Luceneを触って感動して。。。検索すげー、Compassってのを触ってこれもすごいと思いつつ、もっとLucene活用できるんじゃないかということでElasticsearch作ったんだ。奥さんのレシピ検索?まだ完成してないよw Q: 2000くらいスナップショット撮ったらパフォーマンスが悪くなっててなんで? A: 差分でスナップショットを作るんだけど、差分の計算に昔のスナップショットを見るので、定期的に新しくしたほうがいい。もし、気になることがあったらIssue上げたりMLに投げてくれるとうれしい。\n(あとでちょっと聞いたけど、古いスナップショットを消すのも有効っぽい。差分でスナップショットを作るけど、昔のを消した場合は、新しいスナップショットが利用しているファイルは残る仕組みになっているから。) Q: Relevancyのチューニングってどうすればいい?ドキュメントが少なくない? A: ドキュメンテーションは頑張ってるので、応援してねwあとは、definitive guideも参考になるよ。スコアはfunction_scoreクエリがすごいのでいろいろ使ってね。MVELをGroovyに帰る予定。性能もだけど、サンドボックス的な意味もあります。 Q: 次のVisionは?現時点は検索だけど。(最後の質問がとてもナイスで、助かりましたw私がしたほうがいい気がするww) A: 今後はアナリティクスのプラットフォームに向かってる。Aggregationとかね。メモリ効率よくしたりしてるよ。あとは、Field-collapsionも実装中だよ。あと、マシンラーニングとかもね。データを探索するための機能を色々作ってくよ。障害性にも。チェックサム機能をLuceneに入れて、ESにも入れていく予定。Zenの機能も改善している。 まとめ 今週は、トレーニングがあったり、いろいろな打ち合わせがあったりと、テンパってたので至らない点が多かったかもしれないですが。。。 楽しんでいただけと思います。 数日、Shay、Honza、Igorと行動を共にして、本当に情熱のあるチームでユーザのことを気にかけているなと感じることができました。 少しでもその片鱗を勉強会で感じてもらえたんじゃないかと。特に、QAでのShayによる情熱が伝わったんじゃないかと。\n懇親会でも数人の方から、日本語のサポートを望んでいるという声も頂きました。 興味のある方は私までコンタクトいただければと。\nあと、@yusukeさんのテキスト翻訳が素晴らしくて、参加してもらった方たちも絶賛してました。 次回も英語スピーカーの場合に助けてもらえると嬉しいです(私もそこまで出来るように頑張ります)\nその他のブログ ブログ記事ありがとうございます!\n第5回elasticsearch勉強会にいってきました - はやさがたりない。 感想戦:aggrigation から見える検索エンジンの次 - 第5回 Elasticsearch勉強会 - よしだのブログ 「第5回elasticsearch勉強会 #elasticsearch #elasticsearchjp」(2014年07月14日)の参加メモ - uchimanajet7のメモ ","date":1405774320,"dir":"post/2014/","id":"e3e146469ed4318eaa2ffbca3510c054","lang":"ja","lastmod":1405774320,"permalink":"https://blog.johtani.info/blog/2014/07/19/hold-on-5th-elasticsearch-jp/","publishdate":"2014-07-19T21:52:00+09:00","summary":"第5回Elasticsearch勉強会を開催しました。 遅くなってしまいましたが、まとめてみました。 今回は、Elasticsearchに入って","tags":["elasticsearch","勉強会"],"title":"第5回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"ということで、転職しました。 どーしてもやりたいことが出てきたので、無理を言って転職することにしてみました。\nサムライズムではなく、Elasticsearchにジョインします。(というか、しました。)\n初出社 #サムライズム\n\u0026mdash; Jun Ohtani (@johtani) 2014, 7月 1 冗談でツイートしたのですが、その前に英語アカウントのツイートがRTされてしまっていまいちでした。。。\nスキポール空港 先週、アムステルダムに行っていたのも退職前に休みをいただき、Elasticsearchの全社会議に参加していたためです。 とてもエキサイティングな経験(英語漬けとか)ができ、もっと精進しないとなという気持ちにもなり、ますます頑張らないとなと。\nということで、今後は日本中にElasticsearchやLogstash、Kibanaを広めるべく、いろいろな場所で話をしたいと思います。 興味のある方は、声をかけていただければと。\nあと、東京でElasticsearchのCoreトレーニングが行われます。 通常は2日間ですが、通訳の方が付く関係で3日間の開催となっています。 開発者2名がトレーナーとして来日します。開発者に質問をできる良い機会ですので、興味のある方は参加してみてはいかがでしょうか。 また、CTOのShay Banonも来日する予定です。\nトレーナー2名とShayは7/14の勉強会でも話をしてくれます。 こちらも興味のある方は参加してみてください。(参加登録はこの後、すぐに開始します。)\nまだまだ、勉強しなければいけないことだらけですが、ElasticsearchのいろいろなプロダクトやOSSについて広めていきたいと思いますので、よろしくお願いいたします。\nおまけ ということで、一度やってみたかったのでリンクを貼ってみます。\nほしい物リストはこちら\n","date":1404181800,"dir":"post/2014/","id":"21a8e6324e9330d4f8ebade604c62b6e","lang":"ja","lastmod":1404181800,"permalink":"https://blog.johtani.info/blog/2014/07/01/join-elasticsearch/","publishdate":"2014-07-01T11:30:00+09:00","summary":"ということで、転職しました。 どーしてもやりたいことが出てきたので、無理を言って転職することにしてみました。 サムライズムではなく、Elasti","tags":["転職"],"title":"転職しました"},{"contents":"退職しました。\n色々と書きたいんですが、時差ボケで頭痛いので、このくらいです。 余裕出たら書くかも。\nほしい物リストはこちら\n新天地についてはまた明日。\n","date":1404137940,"dir":"post/2014/","id":"40abea0a87a64bd832a1fad69458b293","lang":"ja","lastmod":1404137940,"permalink":"https://blog.johtani.info/blog/2014/06/30/resignation/","publishdate":"2014-06-30T23:19:00+09:00","summary":"退職しました。 色々と書きたいんですが、時差ボケで頭痛いので、このくらいです。 余裕出たら書くかも。 ほしい物リストはこちら 新天地についてはまた明","tags":["転職"],"title":"退職しました"},{"contents":"Elasticsearch server 2nd editionが発売されています。\n私が翻訳したのは前のバージョンですが。。。 まずは、目次を元にどのくらい変わってるかを見てみました。 (全部まだ読んでなくて。。。)\n1章 Getting Started with the Elasticsearch Cluster 冒頭に、全文検索とは、転置インデックスとはどんなものか、 Luceneの簡単なアーキテクチャの仕組みについて説明が追加されています。 検索の仕組みを知らない人が読んでもわかりやすくなっています。\nインストール方法なども少し追記されています。 バージョニングと簡単なデータ登録と検索方法についてもここで触れられています。 検索結果の構造の説明もちょっとあります。 まず簡単に触ってみるというところまでが1章でまとめられた感じです。\n2章 Indexing Your Data 新しく、切りだされた形です。 前のバージョンでは1章で説明されていた、Mapping周りが切りだされています。 シャードやレプリカの説明もこちらです。\nIPアドレスタイプ(IPv4のみ)とtoken_countタイプの説明も追加されてます。 similarityやpostingsフォーマットなどは新しく追記されています。 また、メタフィールドと呼ばれる_typeなどはこちらに移動しているようです。 マージ処理などの説明も追記されています。このあたりは、Mastering ElasticSearchに 記載されているものが移植された感じでしょうか。\n3章 Searching Your Data 前のバージョンでは2章だった章です。 クエリについては1.0で追加されたsimple_query_stringなどが追記されています。 constant_scoreやdismaxなどもです。\nまた、前のバージョンの3章で説明されていたハイライトや8章で触れられていたvalidate APIについても 移動しています。\n4章 Extending Your Index Structure 前のバージョンの3章で触れられていた、データの構造に関する部分がこの章になります。 親子や配列、ネスト等のデータのインデックスや検索の方法です。\n5章 Make Your Search Better スクリプティングや言語判定などの仕組みが記載されています。 また、ブーストについても同様です。Synonymについてもここです。 スパンクエリについては省略されたのかな?\n6章 Beyond Full-text Searching 1.0の目玉機能の一つであるAggregationの説明から始まります。 その後、ファセットやPercolatorについてです。メモリに関する注意点もありそうです。 また、Geoについての説明がこちらに移動されていました。 scroll APIについてもこちらで説明されています。\n7章 Elasticsearch Cluster in Detail 前の7章で記載されていたElasticsearchの分散の仕組み(Node Discovery)についての記載があります。 また、1.0で追加されたcircuit breakerやスレッドプール、インデックスのリフレッシュレートなど、Mastering ElasticSearchの 内容も追記されている気がします。\nインデックスやマッピングのテンプレート機能についてもここで説明があるみたいです。\n8章 Administrating Your Cluster 1.0で追加されたsnapshot/restoreの説明から始まります。 あとは、前のバージョンの7章で説明されていたクラスタ管理用のAPIについての説明です。 いくつか(例えばcat API)、1.0で追加されています。\nまた、シャードのリバランスの話も追加されているようです。 エイリアスやプラグインの話はこちらに移動してるみたいです。\n感想 ということで、とりあえず、駆け足で目次ベースで違いを見てみました。 Mastering ElasticSearchでの 知見がフィードバックされ、しかも1.0(すでに1.3が出そうな勢いですが。。。)にバージョンアップされた内容になっています。 冒頭がわかりやすくなっているので、検索をやったことのない方にもおすすめな書籍になった気がします。 英語が苦にならなければ、おすすめの一冊だと思います。\n来月から読み進めるつもりなので、また、面白い内容があったら感想を書いていこうと思います。 (また翻訳できるといいかもなー)\n","date":1402908420,"dir":"post/2014/","id":"916bda59bc7621d5c1790c040572a3c0","lang":"ja","lastmod":1402908420,"permalink":"https://blog.johtani.info/blog/2014/06/16/first-impression-elasticsearch-server-2nd-edition/","publishdate":"2014-06-16T17:47:00+09:00","summary":"Elasticsearch server 2nd editionが発売されています。 私が翻訳したのは前のバージョンですが。。。 まずは、目次を元にどのくらい変わってるかを見てみました。 (","tags":["elasticsearch","本"],"title":"Elasticsearch server 2nd editionのファーストインプレッション"},{"contents":"可視化ツール現状確認会に参加して、カジュアルウォーターじゃなくて可視化ツールの現状を確認してきました。\nということで、いつものメモです。\nMackerel と Graphite について (y_uuk1さん) Graphite 時系列 工夫すればスケーラブル SensuやCollectdと組み合わせたり GrafanaとGrapheneでGUI Mackerel素敵だよと。 架空のわかりやすいグラフが見れた Kibana \u0026amp; Grafana \u0026amp; Influga (hakoberaさん) Kibana\nかっこいい。 JVM大変。 Grafana\nGraphiteがカッコ悪いのでKibanaをフォーク なぜか、ESが必要。 InfluxDBに浮気しそう Influga\n@haoberaさん作 InfluxDB Queryサポート 迷ったら、Kibana入れとけ。\nDistinctがKibana出できないけど、それ以外はある程度行けるらしい。\naggregationがサポートされたら、できると思う。 Kibana以外は、バックエンドがタイムシリーズなので、縛りがある\n可視化ツール紹介(仮) (showyouさん) 誰がチャートを作るの? 誰が見るの? 一覧化されてて、あとで眺めたい IPython Notebookのデモ R shiny Serverのデモ Pentaho CE+Saikuのデモはネットワークがダメだったので割愛 分析側の視点を見せたかったので。 可視化とは何だったのか (harukasanさん) インフラ モニタリング、アナライズ、可視化どれ? 可視化は目的ではないよねと。 熱く、ユーザとサービスプロバイダ間の距離のお話。 ログ 生ファイルで残すのが重要 トータルで必要とか考えないといけないことがわかって面白かったw\nあなたの知らないrrdtool (shoichimasuharaさん) すげー! いろいろできるらしい(ノートPCの前にいなかったw) D3.jsとジオマッピング (Takaki_さん) 時空間推進課!すげー! ジオデータのおはなし。 TopoJSONとかGeoJSONとか Zipkinについて (synkさん) ものすごい数のJVMがThriftで殴りあってるらしい。 ZipkinはTwitterが作ったもの Brave、HTraceというのが、PureJava用のZipkinトレーシングプラグイン 見積もりする必要がないくらいでかいHBaseがあるので、そこにためてる。 まとめ LINEはエンジニアを大募集中 Graphiteについて (mickey19821 さん) ドリコムさんのGraphiteのおはなし Metricsの収集はCollectd Graphite-webがスケールできなくて困ってるらしい。 Graphiteで可視化ツラいw まとめ RRDTool最高\nあと、クックパッドの技術力がすごいという発表なんかもありました。\n","date":1401884100,"dir":"post/2014/","id":"5bb6f8322cdbda7a21e4aecbe04462b7","lang":"ja","lastmod":1401884100,"permalink":"https://blog.johtani.info/blog/2014/06/04/attending-visualize-study/","publishdate":"2014-06-04T21:15:00+09:00","summary":"可視化ツール現状確認会に参加して、カジュアルウォーターじゃなくて可視化ツールの現状を確認してきました。 ということで、いつものメモです。 Mackerel と Graphite","tags":["勉強会"],"title":"可視化ツール現状確認会に参加してきました。#可視化"},{"contents":"今月2回目の目黒で、初のドリコムさんです。 「最新インフラエンジニア技術勉強~Fluentd, Elasticsearch,Chefの実践実例~」に参加してきました。 もちろん、Elasticsearchってキーワードがあったからです。\nざっくりメモです。\nドリコムのInfrastructure as Code/ひらしーさん CM:jojoss、トレクル、など サーバ300台、クラウド○○台。月30〜50台の割合で増加中。 少人数でいかに回すか。 Chef Rubyが書ける人が多いから。 serverspec テストだよと。 すみません、色々と聞き逃しました。。。\nWinning the metrics battle/mickeyさん Graphiteとかを触っている。 1300台超えたら、色々大変だった。 失敗談 Cactiを利用して、色々と運用が大変だった。DCが別なのでProxyとか。 成功例?現行システム? 最大値、平均値、最小値などをプロット collectdを収集、送信に採用して、独自で開発? 受信して保存するのに、Graphite(carbon-relay、carbon-cache、DRBD、graphite-web)ってなってる。 1300台程度のサーバから、5分間隔で、問題ない。 Graphite良いツールだよ。 Q:過去データはどのくらい? A:5分間隔で1年分。\nQ:移動平均とかを使ったグラフとか時間かかりませんか?100台だと A:100台でもほとんど時間はかからない。\nFluentd プラグイン開発講座/外山 寛さん Fluentdプラグインを作ることができると威力倍増 Elasticsearchの勉強会の話までしてくれました! 勉強会スペース貸出しています。 未公開だけど、sedueのプラグインもあるらしい。 CHUNKとBUFFERとか覚えときましょう プラグインの作り方的なのがなかった気がしたので、今回の発表です。 gem作らなくてもディレクトリにおけば使えるよと。 td-agent使ってる人が大多数だよね。(fluentdを素で使ってる人は会場にはいなかった) エンジニア募集中 Q:エラー処理どうしてますか? A:今は、スルーしています\nQ:単体テストの書き方は? A:人によってバラバラみたいですね。\nMySQLと組み合わせて始める全文検索エンジン「elasticsearch」/yoshi_ken スライド:http://www.slideshare.net/y-ken/introduce-elasticsearch-mysql-importer\nElasticsearch歴は1年位です。\nMySQLを使っていて、モダンな検索がほしいですよね?ね?\nサジェスト、ファセット、位置情報、ネスト検索などなど。\nGoogleトレンドだとSolrに迫る勢いと。\n実データを用いて、手軽にElasticsearchと連携。\nBinaryLogではなく、SQLの結果を同意する方式。yamabiko\n今日は、新しいものを公開します。\nbulk import file generator as well as nested document from MySQL for elasticsearch bulk api 東京トレーニング\nElasticsearch本については、右にあるリンクをクリックしてくれるとうれしいなぁ。\n","date":1400840280,"dir":"post/2014/","id":"a578acf825a595ce95fe8f804b7208f0","lang":"ja","lastmod":1400840280,"permalink":"https://blog.johtani.info/blog/2014/05/23/attending-drecom-infra-study/","publishdate":"2014-05-23T19:18:00+09:00","summary":"今月2回目の目黒で、初のドリコムさんです。 「最新インフラエンジニア技術勉強~Fluentd, Elasticsearch,Chefの実践実例~","tags":["勉強会","elasticsearch"],"title":"最新インフラエンジニア技術勉強に参加しました。"},{"contents":"どうやら、中身がSolrベース?Luceneベース?になったらしいということで、 今日は「AWSプロダクトシリーズ|よくわかるAmazon CloudSearch」に行ってきました。\n※ElasticSearchではありません!\nということで、いつものメモ。\nCloudSearch Overview Amazon Web Services, Inc. Pravin Muthukumar(Product Manager) / Vivek Sriram (Business Development) Introduction to Search 検索の紹介。アイアンマンのDVD?のページにいろんな項目(フィールド)があるよねと。(もちろん、Amazonのページ) ファセット、Geo、テキスト処理(Analysis処理)、Postings listとか。とかとか ランキングも Amazon CloudSearch 独自実装orRDB拡張もある。 OSSもあるよね。 Legacy Enterprise SearchとしてFASTとかもある。 Building with CloudSearch 他のサービス同様、コンソールとかあるし、色々できるし、すぐ起動できるよと。 自動で、データが増えたら、パーティションが増えると。\n日本語の形態素解析があるらしい。何を使ってるのかな? ICUのノーマライズとかもやってくれるらしい。これかな?http://lucene.apache.org/core/4_8_0/analyzers-icu/index.html ユーザが辞書を指定できるのかな? 備えてる機能の説明\nファセット SimpleQuery Autocomplete Highlight などなど\nMulti-AZにも対応 QA Q:NGramありますか? A:今はないです。 Q:ユーザ辞書対応してますか? A:今はないです。 Q:lang-detectあるか? A:今はないので、自分で判定して、適切なフィールドに入れてね。 Expectation for CloudSearch Apache Solr contributor 大須賀 稔氏 Solr本の宣伝ありがとうございます!(右のアイコンから買ってもらえると更に嬉しいですw) Kinesisとかとの組み合わせとか、自然言語処理とか、いろいろとあるAWSのコンポーネントと組み合わせる例が欲しいと。 すばらしい、最後はManifoldCFがらみに持っていくとは。ACLがらみのクローリングとかあるといいじゃないでしょうかと。 Impression of using CloudSearch 吉田 匠氏 (@yoshi0309 http://blog.yoslab.com/) スライド:https://speakerdeck.com/yoshi0309/impression-of-using-cloudsearch\nお見かけしたことある気がするなぁ。 全部置き換えできる!わけではなさそう。。。 いいところ。 UIがいいし、セットアップが簡単 auto scaleがうれしい マルチドメイン、マルチスキーマがいい Luceneのdismaxサポートがいい。(edismaxじゃないのかな?) dismaxって書いてあるな。\nhttp://docs.aws.amazon.com/cloudsearch/latest/developerguide/search-api.html\nフィードの仕方に気をつけて!\nバッチサイズで課金されるので、1件ずつじゃなくて、複数件送ったほうがいい。 いきなりスケールアウトできるわけじゃない?\nウォームアップ機能がない。インスタンス上限がデフォルト50件\nVPC対応してほしい。\nインターネット経由になってしまう フィードのスピードが セキュリティグループ機能が使えない CloudSearch UseCase - SnapDish Vuzz Inc. 清田 史和氏 独自辞書をもって、Tokenizeは独自でやって、空白区切りでデータ登録している。 インデックス更新はSQSを使ってる。 古いAPIを使ってるらしい。 移行が結構大変らしい。 感想 使ったことないんですが、きめ細かい検索したい場合はちょっとテクニックが要るかもと思いました。 AWS初心者なんで、なんとも言えないんですが。。。\nといあえず、テキスト処理(アナライズ処理)で、単語がどうやって区切られるのかってのがわからないのはキツイんじゃなかろうかと。 ただ、簡単に起動できて、オートスケールできるのは素晴らしいと思います。\n","date":1400143800,"dir":"post/2014/","id":"706c033b4483b6d062b66d6e4ea0236a","lang":"ja","lastmod":1400143800,"permalink":"https://blog.johtani.info/blog/2014/05/15/amazon-cloud-seaarch-study-session/","publishdate":"2014-05-15T17:50:00+09:00","summary":"どうやら、中身がSolrベース?Luceneベース?になったらしいということで、 今日は「AWSプロダクトシリーズ|よくわかるAmazon Cl","tags":["勉強会","CloudSearch","AWS"],"title":"「よくわかるAmazon #CloudSearch 」に行ってきました!"},{"contents":"酔っ払ってなんとなく書きたくなったスピリチュアルなブログなので、流していただければと。\n最近、勉強会やTwitterで知り合いになって話をする人が増えたりで、 その方たちに色々と教えてもらうことが多いなぁと感じてます。 また、知り合いに恵まれてきたなぁとも。\nそもそも私が勉強会に参加し始めたきっかけはSolr勉強会(第1回から参加してて、気づいたら主催者になってた)で、 そのころは、Solr初心者で色々とやってる人、知ってる人がいて無料で話が聞けるのすごいと興奮したのを覚えてます。 (もちろん、ぼっちでしたが)\nSolr勉強会が定期的に開かれて、それに参加しているうちに少しずつ知り合いもできて、 面白そうな勉強会(Hadoopとか)が他にもあるんだ、参加してみようかって思うようになってと。\nそこにプラスで、関口さんと知りあえてSolr本を書く話が出てきて、本を書いてみたら、 今度は勉強会で話してみませんかとなって。\nスピーカーやると、顔を覚えてもらえるようで、また知り合いが増えてと。\n人のつながりって大事だし、自分が発信することで教えてもらえることもあるしと。 前にも書いた気がするけど、Solr勉強会(当時の主催の方)や関口さんやElasticsearch勉強会のスタッフの方や スピーカーやってくれた方、会場提供を心よくしてくれてるVOYAGE GROUP、リクルートテクノロジーズさん、という具合にどんどん頭が上がらなくなってきてるなぁと。\nということで、外の世界を知ると色々とつながりが出来て面白いですよという、個人的な感想でした。 ま、自分が思ってるだけで、違う意見もいっぱいあると思うけど。\nあー、なんか、酔って勢いで書いてしまった。。。 脈略のない文章なきがするけど、エイヤで公開しちゃおう。\n","date":1399999440,"dir":"post/2014/","id":"72df0bf7853e05560d94208817b83468","lang":"ja","lastmod":1399999440,"permalink":"https://blog.johtani.info/blog/2014/05/14/spiritual-entry1/","publishdate":"2014-05-14T01:44:00+09:00","summary":"酔っ払ってなんとなく書きたくなったスピリチュアルなブログなので、流していただければと。 最近、勉強会やTwitterで知り合いになって話をする","tags":["スピリチュアル"],"title":"外の世界を知るということ"},{"contents":"「アジャイルデータサイエンス」の見本をいただいてしまいました。\nなので、感想文でも書いてみようかと。\nどんな本? 想像以上に薄かったです、物理的に。 なのに、とても幅広い範囲をカバーしています。\nデータの分析にどんな人が関わっているのか、アジャイルにデータを分析する目的から始まり、 データから何かを見つけるための手順、考え方などをさらっとですが、 システムに取り込む流れから取り込んだあとに改良するという流れまで紹介してくれます。 流れはこんな感じ。\nイベント:ログとかのイベントの発生 コレクタ:イベントの収集 バルクストレージ:イベントの一時保存 バッチ処理:ストレージにあるデータに対して処理 分散ストア:処理結果をWebアプリなどで表示するために保存 Webアプリ:処理結果をユーザに提供 Webアプリでデータを見えるようにして、そこから更にフィードバックを受けることで、データの分析などを進めていくという流れです。\n私はデータサイエンス系の人ではないのでこの流れで作業をされているかはわからないのですが、 検索のシステムについてもこの流れに似ているなと感じました。\n検索システムでも、検索したいデータを収集して、加工(検索したい項目の洗い出しやファセットにする項目の選定とか)して、 インデックスを生成するといった処理が必要になるからです。\nこの本では、Python、Hadoop(Pig)、MongoDB、ElasticSearch(バージョンが0.90だから)、d3.jsなどが出てきます。 また、日本語版の付録では、Fluentd、Kibana+Elasticsearchといった組み合わせの紹介もあります。\nコードも書かれていますが、すみません、そこまでちゃんと読んでません。。。\n後半では、データを活用して行くためには順序があるという話が書かれています。\nレコード:レコード1件のアトミックな処理と表示 グラフ:レコードを元に集計したりグラフ作ったり レポート:関係性やトレンドを抽出し、インタラクティブに探求 予測:構造を利用して、推論やレコメンドとか 行動:上記の結果を元にユーザに行動を促す 前のステップがおろそかだと次のステップがうまくいかないという話です。 後半はこの流れに沿って、先ほどのシステムの流れを変更していく方法が展開されます。\n注意点 ちょっとだけ気になる点があったので。\nElasticsearch周りについては少し注意が必要かと。(Pigとかは詳しくないので不明です。) 紹介されているElasticsearchのバージョンが0.90と少し古いのと、 Hadoopとの統合(Pigで処理したデータをElasticsearchに出力)に利用されているWondordogというツールも最近更新がされていないみたいです。 おそらく、1.0系では動かないのではないかと。\n1.0系の場合は、Elasticsearchが提供しているelasticsearch-hadoopを利用するのが良いと思います。\n付録については1.0系で記載されているので問題ないかと。ただし、Elasticsearchは更新が早いので、公式サイトで最新情報を入手するのが良いと思います。\n感想 データを解析するシステムってどんなことやってるの?という全体像を 俯瞰するのに良い本なのではないかと思います。 また、データの解析を活かすために、必要な順序と疎かにできない点もあって面白かったです。\n紹介されているツール類については、OSSのトレンドや開発速度が早いので、参考程度にとどめておいて、 自分たちで使いやすいものを探してきて検討するのがいいと思います。\n付録がとても豪華です。FluentdやKibanaがわかりやすく解説されてます。\nあと、薄いのでさらっと読めます。w\n","date":1399563900,"dir":"post/2014/","id":"91fe03f994e8e85cede4e3bd62f4d6b7","lang":"ja","lastmod":1399563900,"permalink":"https://blog.johtani.info/blog/2014/05/09/reading-agile-data-science/","publishdate":"2014-05-09T00:45:00+09:00","summary":"「アジャイルデータサイエンス」の見本をいただいてしまいました。 なので、感想文でも書いてみようかと。 どんな本? 想像以上に薄かったです、物理的に","tags":["感想文","オライリー"],"title":"アジャイルデータサイエンスが届きました"},{"contents":"こんなツイートを見つけたので、Aggregationのサンプルでも書こうかなと。(前から書こうと思ってたんですが。。。)\n@elasticsearch Hi, Would you please tell me the way to do \u0026quot;Pivot Faceting\u0026quot; like Solr-4.0 in elasticsearch-1.1.1 or prior version? Thank you.\n\u0026mdash; Y.Kentaro (@yoshi_ken) 2014, 5月 2 ちなみに、Aggregationは1.0.0から導入された機能なので、ElasticSearch Server日本語版には掲載されていない機能になります。(ごめんなさい)\n公式ガイドのAggregationsのページはこちらになりますが、実例があったほうがいいかなと。\n@yoshi_ken さんから実例のサンプルの指定もいただいたので、ブログを書くのが非常に楽です。ありがとうございます。\n問題 元ネタ(gist)\n次のような不動産系のデータがあるとします。\nid 物件名 都道府県(東京、神奈川、\u0026hellip;..) 物件種別(賃貸、売買、\u0026hellip;..) この時、都道府県別に、物件種別ごとの件数を取得したいという趣旨です。\n東京 賃貸: xxx件 売買: yyy件 神奈川 賃貸: xxx件 売買: yyy件 \u0026hellip; これを、Elasticsearchでどうやって取得するかという問題です。\nインデックスとデータの登録 まずは、インデックスを作ります。 あくまでもサンプルなので、全部not_analyzedにしてますが、そのへんは適宜変更してください。\n# create index PUT /pref_aggs { \u0026#34;settings\u0026#34;: { \u0026#34;number_of_shards\u0026#34;: 2 }, \u0026#34;mappings\u0026#34;: { \u0026#34;japan\u0026#34; : { \u0026#34;_id\u0026#34; : { \u0026#34;path\u0026#34; : \u0026#34;id\u0026#34; }, \u0026#34;properties\u0026#34;: { \u0026#34;id\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;}, \u0026#34;name\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;}, \u0026#34;pref\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;}, \u0026#34;type\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;} } } } } _idを使用して、データ登録時にidフィールドにある文字列をそのままIDとして登録できるように指定してあります。\n登録するデータは次のようなものを適当に100件程度作ってりました。\n{\u0026#34;id\u0026#34;: \u0026#34;id0\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;name0\u0026#34;, \u0026#34;pref\u0026#34;: \u0026#34;01_北海道\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;売買\u0026#34;} {\u0026#34;id\u0026#34;: \u0026#34;id1\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;name1\u0026#34;, \u0026#34;pref\u0026#34;: \u0026#34;09_栃木県\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;売買\u0026#34;} {\u0026#34;id\u0026#34;: \u0026#34;id2\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;name2\u0026#34;, \u0026#34;pref\u0026#34;: \u0026#34;38_愛媛県\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;賃貸\u0026#34;} {\u0026#34;id\u0026#34;: \u0026#34;id3\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;name3\u0026#34;, \u0026#34;pref\u0026#34;: \u0026#34;40_福岡県\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;賃貸\u0026#34;} {\u0026#34;id\u0026#34;: \u0026#34;id4\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;name4\u0026#34;, \u0026#34;pref\u0026#34;: \u0026#34;35_山口県\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;売買\u0026#34;} {\u0026#34;id\u0026#34;: \u0026#34;id5\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;name5\u0026#34;, \u0026#34;pref\u0026#34;: \u0026#34;12_千葉県\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;賃貸\u0026#34;} ... データの登録には、前に紹介した方法「stream2esと複数データの登録」を用いました。\nファセット このようなデータがある場合に、まず思いつくのはファセットによる取得です。 いささか強引ですが。。。\nGET /pref_aggs/japan/_search { \u0026#34;size\u0026#34;: 0, \u0026#34;query\u0026#34;: { \u0026#34;match_all\u0026#34;: {} }, \u0026#34;facets\u0026#34;: { \u0026#34;type_賃貸\u0026#34;: { \u0026#34;terms\u0026#34;: { \u0026#34;order\u0026#34;: \u0026#34;term\u0026#34;, \u0026#34;field\u0026#34;: \u0026#34;pref\u0026#34;, \u0026#34;size\u0026#34;: 50 }, \u0026#34;facet_filter\u0026#34;: {\u0026#34;term\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;賃貸\u0026#34; }} }, \u0026#34;type_売買\u0026#34;: { \u0026#34;terms\u0026#34;: { \u0026#34;order\u0026#34;: \u0026#34;term\u0026#34;, \u0026#34;field\u0026#34;: \u0026#34;pref\u0026#34;, \u0026#34;size\u0026#34;: 50 }, \u0026#34;facet_filter\u0026#34;: {\u0026#34;term\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;売買\u0026#34; }} } } } facet_filterを使用して、typeフィールドによる個別の絞込を行っています。 あとは、prefフィールドのファセットを取得すれば、出力は次のようになります。\n{ \u0026#34;took\u0026#34;: 6, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 2, \u0026#34;successful\u0026#34;: 2, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 100, \u0026#34;max_score\u0026#34;: 0, \u0026#34;hits\u0026#34;: [] }, \u0026#34;facets\u0026#34;: { \u0026#34;type_賃貸\u0026#34;: { \u0026#34;_type\u0026#34;: \u0026#34;terms\u0026#34;, \u0026#34;missing\u0026#34;: 0, \u0026#34;total\u0026#34;: 52, \u0026#34;other\u0026#34;: 0, \u0026#34;terms\u0026#34;: [ { \u0026#34;term\u0026#34;: \u0026#34;00_北海道\u0026#34;, \u0026#34;count\u0026#34;: 1 }, { \u0026#34;term\u0026#34;: \u0026#34;01_青森県\u0026#34;, \u0026#34;count\u0026#34;: 2 }, { \u0026#34;term\u0026#34;: \u0026#34;03_宮城県\u0026#34;, \u0026#34;count\u0026#34;: 3 }, ... }, \u0026#34;type_売買\u0026#34;: { \u0026#34;_type\u0026#34;: \u0026#34;terms\u0026#34;, \u0026#34;missing\u0026#34;: 0, \u0026#34;total\u0026#34;: 48, \u0026#34;other\u0026#34;: 0, \u0026#34;terms\u0026#34;: [ { \u0026#34;term\u0026#34;: \u0026#34;00_北海道\u0026#34;, \u0026#34;count\u0026#34;: 2 }, { \u0026#34;term\u0026#34;: \u0026#34;02_岩手県\u0026#34;, \u0026#34;count\u0026#34;: 1 }, { \u0026#34;term\u0026#34;: \u0026#34;04_秋田県\u0026#34;, \u0026#34;count\u0026#34;: 1 }, ... } 望んでいた形式とは少し異なりますが、facet_filterする回数を少なくするため、 ファセットは都道府県のフィールドを指定したためです。 アプリで頑張って入れ替えてください。。。\nこの場合、\u0026rsquo;type\u0026rsquo;の個数がわかっているので、頑張ってこのような記述ができました。 ただ、typeが増えた時にアプリの修正とかが必要になりますよね。\nAggregations ということで、Aggregationsの出番です。 ファセットよりも柔軟に、検索結果に対していろいろな集計が行える機能になります。 一見に如かずということで、クエリを紹介します。\nGET /pref_aggs/japan/_search { \u0026#34;size\u0026#34;: 0, \u0026#34;query\u0026#34;: { \u0026#34;match_all\u0026#34;: {} }, \u0026#34;aggs\u0026#34;: { \u0026#34;pref\u0026#34;: { \u0026#34;terms\u0026#34;: { \u0026#34;order\u0026#34;: { \u0026#34;_term\u0026#34;: \u0026#34;asc\u0026#34; }, \u0026#34;field\u0026#34;: \u0026#34;pref\u0026#34;, \u0026#34;size\u0026#34;: 50 }, \u0026#34;aggs\u0026#34;: { \u0026#34;type\u0026#34;: { \u0026#34;terms\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;type\u0026#34;, \u0026#34;size\u0026#34;: 10 } } } } } } ファセットよりもシンプルですし、賃貸といったような値を指定していません。 aggsというのがaggregations機能を指定している部分になります。 検索結果は次のように出力されます。\n{ \u0026#34;took\u0026#34;: 4, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 2, \u0026#34;successful\u0026#34;: 2, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 100, \u0026#34;max_score\u0026#34;: 0, \u0026#34;hits\u0026#34;: [] }, \u0026#34;aggregations\u0026#34;: { \u0026#34;pref\u0026#34;: { \u0026#34;buckets\u0026#34;: [ { \u0026#34;key\u0026#34;: \u0026#34;00_北海道\u0026#34;, \u0026#34;doc_count\u0026#34;: 3, \u0026#34;type\u0026#34;: { \u0026#34;buckets\u0026#34;: [ { \u0026#34;key\u0026#34;: \u0026#34;売買\u0026#34;, \u0026#34;doc_count\u0026#34;: 2 }, { \u0026#34;key\u0026#34;: \u0026#34;賃貸\u0026#34;, \u0026#34;doc_count\u0026#34;: 1 } ] } }, { \u0026#34;key\u0026#34;: \u0026#34;01_青森県\u0026#34;, \u0026#34;doc_count\u0026#34;: 2, \u0026#34;type\u0026#34;: { \u0026#34;buckets\u0026#34;: [ { \u0026#34;key\u0026#34;: \u0026#34;賃貸\u0026#34;, \u0026#34;doc_count\u0026#34;: 2 } ] } }, ... Aggregationsの結果は、望んでいた通りの出力になっています。\nクエリの構成を見てみましょう。\n\u0026#34;aggs\u0026#34;: { \u0026#34;pref\u0026#34;: { #1 \u0026#34;terms\u0026#34;: { \u0026#34;order\u0026#34;: { \u0026#34;_term\u0026#34;: \u0026#34;asc\u0026#34; }, \u0026#34;field\u0026#34;: \u0026#34;pref\u0026#34;, \u0026#34;size\u0026#34;: 50 }, \u0026#34;aggs\u0026#34;: { #2 \u0026#34;type\u0026#34;: { \u0026#34;terms\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;type\u0026#34;, \u0026#34;size\u0026#34;: 10 } } } } } 最初の#1のprefは出力を扱いやすくするためにつけているラベルになります。好きな名前をつけることが可能です。 次のtermsがAggregationのタイプ(どのような集計をして欲しいか)になります。 今回は、prefフィールドにある単語(term)毎に、集計をしたいので、termsを指定します。 その他にどんなタイプがあるかは、公式ガイドをご覧ください。\n次に、さらにtypeフィールドで集計したいので、#2の部分で後続のAggregationを指定しています。 都道府県同様、typeフィールドにある単語毎に集計するために、termsを指定します。\nこれで、先ほどのような結果が出力できます。 ちなみに、さらにtypeの中に他の種別で集計したいという場合は、さらにaggsを追加していけばOKです。\nAggregationは非常に柔軟な集計を可能にする機能です。ただし、検索結果に対して集計処理を行っているため、 メモリやCPUなどのリソースを消費するので注意が必要です。\nAggregationの説明については、こちらのFound.noのブログ(英語)がわかりやすかったので参考にしてみてください。\nまとめ 非常に簡単ですが、Aggregationsについて紹介しました。 その他にもAggregationsでできることがあるので、後日別のサンプルを用意して説明しようかと思います。\n100件のデータやここまでの操作については、gistにあるので、興味がある方はご覧いただければと。 stream2esの操作以外は、Marvelに付属のsenseを利用しています。\n","date":1399456620,"dir":"post/2014/","id":"ed4f5a398056eef1cf6caa90786b340a","lang":"ja","lastmod":1399456620,"permalink":"https://blog.johtani.info/blog/2014/05/07/aggregation-example/","publishdate":"2014-05-07T18:57:00+09:00","summary":"こんなツイートを見つけたので、Aggregationのサンプルでも書こうかなと。(前から書こうと思ってたんですが。。。) @elasticsearch Hi, Would you please tell me the way to","tags":["elasticsearch"],"title":"Aggregations - ファセットよりも柔軟な集計"},{"contents":"今日はelasticsearch-kopfのAnalysis画面の紹介です。\n(簡単なところから。。。その3)\nちょっとあいだが開いてしまいましたが、再開です。 メニューのaliasesを選択すると、次のような画面が表示されます。\nAliases画面 Elasticsearchのaliasを画面で確認できます。\nエイリアスは、インデックスに別名をつけることができるElasticsearchの機能です。 1エイリアス=1インデックスでも良いですが、1エイリアスに対して複数のエイリアスを付与することもできます。 この機能を利用することで、次のようなことが可能となります。\nインデックスの切り替えをアプリ側に意識させずに実施(アプリはエイリアス名に対して検索すればOKなので) 直近1週間のログを検索するためのエイリアスの作成(複数のインデックスを1つのエイリアスに割り当て可能) 特定のルーティングによる検索(特定のデータに対する検索だけに絞るためにfilterを指定する) エイリアスについて詳しく知りたい方は公式ガイドをご覧いただくのが良いかと。\n画面は非常にわかりやすい作りになっているので、特に説明必要ないんですよね。。。\n","date":1399132860,"dir":"post/2014/","id":"2824bef72110575c78aeb979170212b8","lang":"ja","lastmod":1399132860,"permalink":"https://blog.johtani.info/blog/2014/05/04/intro-elasticsearch-kopf-alias-percolator/","publishdate":"2014-05-04T01:01:00+09:00","summary":"今日はelasticsearch-kopfのAnalysis画面の紹介です。 (簡単なところから。。。その3) ちょっとあいだが開いてしまいまし","tags":["elasticsearch","plugin"],"title":"elasticsearch-kopfの紹介(aliases画面)"},{"contents":"kopfの記事の続きも書く必要があるんだけど、こんなツイートを見つけてしまったので。。。\nElasticsearchのBulk APIの仕様、JSONファイルをいい感じに加工して置かなければならないしハマりどころ多い。 http://t.co/hmfycqZlqk\n\u0026mdash; Kenta Suzuki (@suzu_v) 2014, 4月 24 前に思いついたけど、放ったらかしにしてた疑問が再浮上してきたので、せっかくだから調べてみようかなと。\n複数JSONデータがある場合にもっと楽にデータを入れる方法ないかなぁと思って、これかな?というのがあったのですが、 そのまま手を動かさずに放置してたので、一念発起してブログ書いてます。\nBulk APIって? ElasticsearchはURLにアクセスしてデータを登録できます。 基本的には次のように1件毎の登録になります。\n$ curl -XPUT http://localhost:9200/bookshop/books/1 -d \u0026#39; { \u0026#34;book_id\u0026#34; : 1, \u0026#34;title\u0026#34; : \u0026#34;ElasticSearch Server Japanese Edition\u0026#34;, \u0026#34;price\u0026#34; : 3024, \u0026#34;publisher\u0026#34; : \u0026#34;KADOKAWA\u0026#34; }\u0026#39; これでもいいのですが、大量のデータを登録するときは、Elasticsearch側での効率が悪いです。 そこで、Elasticsearchは大量データを登録するためにBulk APIというものを用意しています。\nこれは、次のような形式のJSONを作ってデータを登録します。\n{ \u0026#34;index\u0026#34; : { \u0026#34;_index\u0026#34; : \u0026#34;bookshop\u0026#34;, \u0026#34;_type\u0026#34; : \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34; : \u0026#34;1\u0026#34; } } { \u0026#34;book_id\u0026#34; : 1, \u0026#34;title\u0026#34; : \u0026#34;ElasticSearch Server Japanese Edition\u0026#34;, \u0026#34;price\u0026#34; : 3024, \u0026#34;publisher\u0026#34; : \u0026#34;KADOKAWA\u0026#34;} { \u0026#34;index\u0026#34; : { \u0026#34;_index\u0026#34; : \u0026#34;bookshop\u0026#34;, \u0026#34;_type\u0026#34; : \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34; : \u0026#34;2\u0026#34; } } { \u0026#34;book_id\u0026#34; : 2, \u0026#34;title\u0026#34; : \u0026#34;Introduction of Apache Solr\u0026#34;, \u0026#34;price\u0026#34; : 3888, \u0026#34;publisher\u0026#34; : \u0026#34;gihyo\u0026#34;} これは、次のような構成になっています。\nコマンド データ コマンド データ ... これで効率よくデータが登録できるのですが、このようなJSONデータを別途作って上げる必要が出てきます。 結局、複数のJSONがあるのに、特殊なJSONを生成しないといけないということでプログラム書いて実行することになります。 これだと、Elasticsearchへのアクセスをプログラムで書くのとあまり大差がないかもしれません。\nstream2es もっとお手軽に複数のJSONを登録できないかな?と目をつけていたのが、stream2esです。\nどんなもの? Clojureで作られた、Elasticsearchにデータを流し込むためのツールです。 Java 7がインストールされていれば、ダウンロードしてくれば動作せることができます。\nインストール 公式ページに載っている方法そのままです。\n$ curl -O download.elasticsearch.org/stream2es/stream2es; chmod +x stream2es 実行したディレクトリにコマンドがコピーされます。 あとは、コマンドを実行すればOKです。\n実行 データは次のような形式でsample.jsonに保存してあるとします。\n{ \u0026#34;book_id\u0026#34; : 1, \u0026#34;title\u0026#34; : \u0026#34;ElasticSearch Server Japanese Edition\u0026#34;, \u0026#34;price\u0026#34; : 3024, \u0026#34;publisher\u0026#34; : \u0026#34;KADOKAWA\u0026#34;} { \u0026#34;book_id\u0026#34; : 2, \u0026#34;title\u0026#34; : \u0026#34;Introduction of Apache Solr\u0026#34;, \u0026#34;price\u0026#34; : 3888, \u0026#34;publisher\u0026#34; : \u0026#34;gihyo\u0026#34;} 先ほどのBulk APIで利用したJSONよりも、スッキリしていますね。 1行1ドキュメント1JSONです。\nあとは、次のコマンドを実行するだけです。\n$ ./stream2es stdin --target http://localhost:9200/bookshop/books \u0026lt; sample.json ファイルをstream2esに流し込んで、stream2esが1行ずつパースして、Elasticsearchに投げ込んでくれます。\n登録されたデータは次のようになります。 IDは自動で付与されています。\n{ \u0026#34;_index\u0026#34;: \u0026#34;bookstore\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;0Hvy4IJCRkKrvGb4Dgam_w\u0026#34;, \u0026#34;_version\u0026#34;: 1, \u0026#34;found\u0026#34;: true, \u0026#34;_source\u0026#34;: { \u0026#34;book_id\u0026#34;: 1, \u0026#34;title\u0026#34;: \u0026#34;ElasticSearch Server Japanese Edition\u0026#34;, \u0026#34;price\u0026#34;: 3024, \u0026#34;publisher\u0026#34;: \u0026#34;KADOKAWA\u0026#34; } }, { \u0026#34;_index\u0026#34;: \u0026#34;bookstore\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;b9M6TooFQzGYyJeix_t_WA\u0026#34;, \u0026#34;_version\u0026#34;: 1, \u0026#34;found\u0026#34;: true, \u0026#34;_source\u0026#34;: { \u0026#34;book_id\u0026#34;: 2, \u0026#34;title\u0026#34;: \u0026#34;Introduction of Apache Solr\u0026#34;, \u0026#34;price\u0026#34;: 3888, \u0026#34;publisher\u0026#34;: \u0026#34;gihyo\u0026#34; } } せっかく、book_idがあるんだし、_idをインデックスの設定に指定します。\n$ curl -XDELETE http://localhost:9200/bookshop $ curl -XPUT http://localhost:9200/bookshop -d \u0026#39; { \u0026#34;mappings\u0026#34;: { \u0026#34;books\u0026#34; : { \u0026#34;_id\u0026#34; : { \u0026#34;path\u0026#34;: \u0026#34;book_id\u0026#34; } } } }\u0026#39; あとは、登録すればbook_idが_idに採用されます。\n{ \u0026#34;_index\u0026#34;: \u0026#34;bookshop\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;_version\u0026#34;: 1, \u0026#34;found\u0026#34;: true, \u0026#34;_source\u0026#34;: { \u0026#34;book_id\u0026#34;: 1, \u0026#34;title\u0026#34;: \u0026#34;ElasticSearch Server Japanese Edition\u0026#34;, \u0026#34;price\u0026#34;: 3024, \u0026#34;publisher\u0026#34;: \u0026#34;KADOKAWA\u0026#34; } }, { \u0026#34;_index\u0026#34;: \u0026#34;bookshop\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;2\u0026#34;, \u0026#34;_version\u0026#34;: 1, \u0026#34;found\u0026#34;: true, \u0026#34;_source\u0026#34;: { \u0026#34;book_id\u0026#34;: 2, \u0026#34;title\u0026#34;: \u0026#34;Introduction of Apache Solr\u0026#34;, \u0026#34;price\u0026#34;: 3888, \u0026#34;publisher\u0026#34;: \u0026#34;gihyo\u0026#34; } } 複数ファイル ディレクトリに複数のJSONファイルが有った場合は、次のようなコマンドでOK\n$ cat sample_data/*.json |./stream2es stdin --target http://localhost:9200/bookshop/books まぁ、catして流してるだけですが。。。\nダメだったケース JSONが複数行になっているようなデータだとエラーが出てしまいました。\n(jqコマンドで1行に整形したりできるかなぁ?)\nまた、1行に2つのJSONが書いてある場合は、1つ目のJSONをパースしたら、そこでおしまいみたいで、その後に記述されたデータは登録されませんでした。\nインデックスがない場合 stream2esで登録するインデックスがElasticsearchに存在しない場合、stream2esがインデックスを作成してくれるのですが、 この時、シャード数などはstream2es内部に記述があるので注意が必要です。 以下がその設定です。\nindex.number_of_shards : 2 index.number_of_replicas : 0 index.refresh_interval : 5s 課題? 内部的にはおそらく、Bulkでデータを登録していると思うのですが、まだよくわかっていません。 Clojureが読めないので、せっかくだから、Clojureの勉強も兼ねてちょっとソースを読んでみようかなと思います。 それほど量があるわけでもないので。\nあとは、その他にWikipediaのデータやTwitterのデータ登録、 ElasticsearchからデータをScrollで読み出しつつ、別のElasticsearchに流しこむといったこともできそうなので、そちらも試してみようかと。 他にもオプションがいくつかありそうです。\n今回は2件ほどでしたが、大量データを流し込んだ時にどうなるか(stream2esが悲鳴を上げるのか、Elasticsearchで詰まることがあったらどうなるか)なども 気になるので、なんか適当なデータで試してみるのもいいかなぁと。 (ということで、だれか、いろいろ試してみてもらえると楽できるなぁ。)\n","date":1398341460,"dir":"post/2014/","id":"e396cbf9274b590a1d94ee43d823a0bd","lang":"ja","lastmod":1398341460,"permalink":"https://blog.johtani.info/blog/2014/04/24/usage-stream2es/","publishdate":"2014-04-24T21:11:00+09:00","summary":"kopfの記事の続きも書く必要があるんだけど、こんなツイートを見つけてしまったので。。。 ElasticsearchのBulk APIの仕様、J","tags":["elasticsearch","stream2es"],"title":"stream2esと複数データの登録"},{"contents":"第4回Elsticsearch勉強会を開催しました。 今回から、遅刻厳禁にしてみました。 それほど困った人もいないと思うので、次回からも遅刻厳禁で。\nということで、今回も多数の方にお集まりいただきありがとうございました。\nスタッフの皆さん、スピーカーの皆さん、プレゼント用に書籍を用意してくれたKADOKAWAさん、開場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 次回もよろしくお願いします! 参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\nさて、ブログですが司会業とかやってたので、あんまり書けてないけど。。。\n134番までチケットがはけていたので+スタッフで140〜150名くらいの参加者だったのではないかと思います。 懇親会まで残っていただいた方々も片付けなどありがとうございました。\nさて、感想とか補足です。\n「アナライズ処理の仕組みとクエリDSL」株式会社シーマーク 大谷 純 @johtani スライド:アナライズ処理の仕組みとクエリDSL※スライドはPDFです。\nプラグイン:elasticsearch-extended-analyze\nプラグインの紹介記事:http://blog.johtani.info/blog/2013/10/25/developing-es-extended-analyze-plugin/\nMarvel:http://www.elasticsearch.com/marvel/\n日本語版メーリングリスト:https://groups.google.com/forum/#!forum/elasticsearch-jp\nなんか、宣伝(本+プラグイン)ばっかりですみません。 「プラグインの紹介記事」に簡単な使い方が書いてあります。が、情報が古いので、Elasticsearchのバージョンに合わせたバージョンを使ってください。\nまだまだ発表に慣れてないので、頑張ろ。\nアンケート取ってみましたが、ログ検索と全文検索と半々くらいで興味がある人がいるみたいでした。 あと、有料トレーニングは人気ないっすね。。。\n「elasticsearch-hadoopを使ってごにょごにょしてみる」 株式会社マーズフラッグ R\u0026amp;D部 やまかつ さん @yamakatu スライド:elasticsearch-hadoopを使ってごにょごにょしてみる\nelasticsearch-hadoop:https://github.com/elasticsearch/elasticsearch-hadoop\nQAとして、Elasticsearchにプライマリデータを保存するのは的な話が出てました。 ESにのみデータを入れるのは個人的には考えたことないかなぁ。 どうしても、ElasticsearchのWriteが遅いんじゃないかという懸念事項を持ってる人がいるなぁと。(実際ツラいという話もちらほら)\nお腹痛い中の発表ありがとうございました。。。 次回はMapRの方に紹介してもらえそう(交渉中)なので楽しみです。やまかつさんの続きも聞きたいなぁ。\n「CouchbaseとElasticsearchが手を結んだら」株式会社アットウェア 佐竹雅央さん @madgaoh 河村康爾さん @ijokarumawak スライド:CouchbaseとElasticsearchが手を結んだら\nCouchbaseのElasticsearchに関するページ:http://docs.couchbase.com/couchbase-elastic-search/\nCouchbaseに入れたら、自動的にElasticsearchにもデータを入れてくれる。 デモがあるの、いいっすね。\n最新版はmasterを落としてきてビルドしないとダメらしい。確かに、上のページには0.90.5って書かれてる。 ここでも、やはり、Elasticsearchが詰まった時にどうするの?みたいな話が出てました。 CouchbaseのXDCRだと、後ろが詰まってる時によしなに?データを流すのを制御してくれるってのがあるみたいですが、 Elasticsearchだと悲鳴を上げているのがわかりにくいと。\nあと、Elasticsearchがインデキシングでキューを取りこぼしているのがログからわかりにくいってのも出てました。 (なにか、分かる方法があるかとかも調べてみようかなぁ。)\n自分の宿題:Transportプラグインって何かについて調べてブログに書くこと。\n「Elasticsearch at Wantedly」(タイトルあってるか不安) Wantedly, Inc 内田誠悟さん @spesnova スライド:Elasticsearch at Wantedly\n参考文献:Elasticsearchチュートリアル\n参考文献:Elasticsearch Workshop\n参考文献:elasticsearch-rails\nWantedlyでどうやって使ってるのか。 あと、オートコンプリートでも使ってます。(この話は次回聞けるといいなぁw)\nデータ数は少ないので、参考にまだならないかも。\n公式のサイト見難いですよねと。 ペンギン先生のブログが素晴らしかった! マッピングすごいw\n最後は、苦労して作ってもらったautocompleteの資料は放ったらかしにして、質疑応答してもらいました。 辞書とか、検索漏れとかの話は今後の課題っぽかったですね。\n「Elasticsearchのみに決めてました!」ってセリフがカッコ良かったw\nアクセスコントロール周りのノウハウもブログで共有してくれそうなので楽しみにしています!\nあと、「tireがretire」の話が出てましたが(この発表だっけ?)参考文献にあげてある、elasticsearch-railsが今は本流なんじゃないかなぁ?\nLT ###「ElasticsearchのScripting」株式会社富士通ソフトウェアテクノロジーズ 滝田聖己さん @pisatoshi\nスライド:ElasticsearchのScripting\n参考文献:elasticsearch-native-script-example\n色々とScriptがあるという話を説明してもらい感謝です。 もちろん、ElasticSearchServerにも書いてあるので、そちらも参考にしてください!\n「Elasticsearch 向け多言語解析プラグイン」ベイシス・テクノロジー株式会社 江口天さん スライド:Elasticsearch 向け多言語解析プラグイン\n参考文献:Elasticsearchで使えるRosette基本言語解析モジュール\n参考文献:Elasticsearch-inquisitorプラグインの紹介\nベイシステクノロジさんが提供しているRosetteをElasticsearchで活用できるモジュールみたいです。 いまなら、無料で体験できるみたいなので、どんなものか触ってみると面白いかもしれません。\nあと、デモで使用されていたプラグインについて、私が昔に書いた記事があるので、興味のある方は参考にしていただければと。 このプラグインはクエリがどのように内部でLuceneのクエリになっているか、どのフィールドでどうトークンが生成されるか? といったものが見ることができるプラグインになっています。\n関連ブログ 適当に見つけたブログを列挙してあります。これもあるよ!などあれば、教えてください。\n勉強会メモ - 第4回elasticsearch勉強会 2014/04/21\ntogetter 第4回elasticsearch勉強会 #elasticsearchjp\n参加レポート:第4回elasticsearch勉強会 #elasticsearchjp\n第4回elasticsearch勉強会に参加しました\nまとめ しつこいくらい宣伝してしまいましたが、「ElasticSearch Server日本語版」よろしくお願いします!\n今回も楽しい話が聞けました。メモがちょっと少ないんですが。。。\n次回は6末を目処に、MapRの方などと調整して開催しようと思います。 聞きたい話とか、発表したい方とかあれば、連絡くださいー!\n","date":1398077040,"dir":"post/2014/","id":"50562b09417cd8c4a2348a0a5aabe754","lang":"ja","lastmod":1398077040,"permalink":"https://blog.johtani.info/blog/2014/04/21/hold-on-4th-elasticsearch-jp/","publishdate":"2014-04-21T19:44:00+09:00","summary":"第4回Elsticsearch勉強会を開催しました。 今回から、遅刻厳禁にしてみました。 それほど困った人もいないと思うので、次回からも遅刻厳禁","tags":["elasticsearch","勉強会"],"title":"第4回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"今日はelasticsearch-kopfのAnalysis画面の紹介です。\n(簡単なところから。。。その2)\nメニューのanalysisを選択すると、次のような画面が表示されます。\nAnalysis画面 Elasticsearchの_analyze APIを画面で確認できます。 画面で動作の確認ができるのは嬉しいですよね。\n入力文字列:入力となるドキュメントに含まれる文字列や検索キーワードを入力 フィールドの指定:対象とするインデックス名、タイプ名、フィールド名を選択 analyze:ボタンを押す トークナイズされた結果:入力文字列がどのようなトークンに分割されるか start、end:入力文字列中の文字列の位置 pos:トークンの位置 という形でElasticsearchが指定されたフィールドで入力文字をどのようにトークナイズしたかを確認することができます。\nElasticsearchは内部でこのトークナイズされた単語を元に転置インデックスを作成し、検索に利用します。 ですので、特定のデータが検索に上手くヒットしないときに、この画面でデータの文字列をトークナイズしてみるといった用途に使えます。\nフィールドの設定がどのようにして入力文字列をトークンにしているかといった点については、今度のElasticsearch勉強会で話す予定です。\nフィールドの設定を利用する以外に、アナライザを指定してどのようにトークナイズされるかを見ることもできます。 「ANALYZE BYANALYZER」をクリックすると利用できます。\nANALYZE BY ANALYZER トークナイズしたい文字列を入力し、インデックス名と、インデックスに設定されているアナライザ名を選択してanalyzeボタンを押すと 結果が表示されます。 (例では、kuromojiアナライザを利用して出力になっています。また、出力結果のposの表示位置がFIELD TYPEの時と違うのが少し気になりました。)\nただ、残念ながら、インデックスのマッピングで指定したアナライザしか利用できないみたいなので、 どのアナライザがどんな挙動かを調べたい場合は、以前紹介したelasticsearch-inquisitorを 利用したほうが良さそうです。\nということで、今日はanalysis画面の説明でした。\n","date":1397011260,"dir":"post/2014/","id":"76a1fb7f21fda9eddb95426b65124517","lang":"ja","lastmod":1397011260,"permalink":"https://blog.johtani.info/blog/2014/04/09/intro-elasticsearch-kopf-analysis/","publishdate":"2014-04-09T11:41:00+09:00","summary":"今日はelasticsearch-kopfのAnalysis画面の紹介です。 (簡単なところから。。。その2) メニューのanalysisを選択","tags":["elasticsearch","plugin"],"title":"elasticsearch-kopfの紹介(analysis画面)"},{"contents":"JVM Operation Casual Talksに参加しました。 あんまり、運用とかやってないので、ついていけるか不安ですが、楽しそうだったので。 懇親会は予定されてないらしい。\n@stanaka\t15分でわかるJVMのメモリ管理 スライド:https://speakerdeck.com/stanaka/understanding-memory-management-of-javavm-in-15-minutes\nJVMの基礎知識\n某研究所で。。。\nElasticsearch、Solrの名前が!\nJVM困りどころ。ネットの情報が古いのが多いとか。\n使いこなすにはきちんと知識が必要。\nMemory Model 困ったらJava8に。。。\nHeapのチューニングが重要\nHeapの構成やGC処理の説明\nCMSでもすべて並列ではない\nOlgGenがフラグメントして確保が遅くなっていく G1GCの概念図。YoungやOld、Survivorの区別がない?\nリージョン? リファレンスリストすばらしい。\n@oranie\tCassandra運用で実施しているJVM監視について スライド:http://www.slideshare.net/oranie/jvm-operation-casual-talks-33218856\nCassandra(1.1)で運用中。 35TBとか エンジニアブログ読め。 Cassandraの監視って何すればいいの? GC頻度とかグラフで見れる VisualVM便利って教えてもらった。 VisualVMでどんな値があるか見ながら調べて、取りたい値を考える。 SNMPで頑張るの辛い=JMXかな?=Javaで叩くの?=Jolokia どんなことやってる? Nagios+Jenkins+。。。あとでスライド yohoushi+GrowthForecastも便利。 @waysaku\tSpray(Akka)運用でJVMをCPUスケールさせるために行った事 スライド:http://www.slideshare.net/waysaku/jvm-operation-casual-talks\nSpray Akkaアプリケーションの運用を任されちゃった人 カットオーバー直前の負荷試験でびっくりするくらいスループットでない。。。 いろんなActorが特定のActorに処理を投げた状態で待ってるという状況。。。 スレッドダンプ追っかけてる様子を追体験してる。 ログ出力がBLOCKしてた I/Oを伴う処理は非常にセンシティブ 以下、LT @oinume\t運用に効く!JVMオプション三選 スライド:http://www.slideshare.net/oinume/jvm-operationcasualtalks20140407\nサーバに入らなくても見れるのは VisualVM 最終形Java Mission Control Flight Recorder(商用だと有償) @y_uuki1\tなにもわからないところから始めるJVMモニタリング スライド:https://speakerdeck.com/yuukit/nanimowakaranaitokorokarashi-merujvmmonitaringu\nブログ:http://yuuki.hatenablog.com/entry/2014/04/08/074507\nなんでここにいるかわかりませんが。 色んな所記事とかのリンクがある。 Graphiteに放り込んでるらしい。 @tagomoris\tNorikraのJVMチューンで苦労している話 スライド:http://www.slideshare.net/tagomoris/norikrajvm\nNorikraで困ったので開催したらみんなしゃべりに来てくれてありがたい世の中ですね。 デフォルト設定で運用。mx4096mで4ヶ月は元気に動いてた 年末に崩壊 -\u0026gt; harukaさんのQiita見ながら設定してほったからした。 3月にまた崩壊OOM SoftRefが悪さしてるのか? nekopさんのブログにヒントが。 @shot6\tJVM的なナニカを話す、GC戦略をそえて スライド:http://www.slideshare.net/shot6/jvm-33248312\n某A社からきました。 CMSを中心が良い CPUコア少ないとCMS Incremental G1GCは6GB以上とかもっと大きい場合のほうが良さそう(雑感) 基本的に、ドキュメントに書いてあるけど、つらいので、まとめてみました。 後で見たいな、このスライドも。 @kazeburo\tWebアプリケーションとメモリ スライド:http://www.slideshare.net/kazeburo/jvm-casual\nJavaは1行も書いたことありません。 Java運用したけど、まぁ、ひどい目にあってます。 ということで、PerlとApacheの話? bumpyなんとかってのは頭良くプロセスの処理回数とかをなんとかしてくれる JVMとかどうなの? ということで、CA社の人が釣れたので良かったですね。 TBD\tJVMの運用について話す会(パネル) なんでJVM?\n全文検索だとJVMだなぁ。SolrとかElasticsearchとか 入社したらあった。 JVMこまったところは?\n突然Dioが出てくる JVMいいところは?\nうーん、あえて言うと。。。スレッド処理 型がある言語を調べるとJVM。というよりScala。 飛び入り参加。落ちないところ。人殺しは良くないw 簡単には殺せないところに使えるのは良いのでは。 チューンはどこまでやる?\n7,8割でやめたほうが良い? そんなに突き詰めなくてもいいのかな。 Cassandraだと、FullGCが走ってる時点で再起動しかない場合が多いです。 言語のランタイムについてチューンすることってJVMの他ある?\nRubyくらい? 自分たちで何とかできないものを相手にしている人たちは苦労してるんじゃないか\nCaなんとかさんとかHBなんとかさんは困ってる人が多い 最後に一言\nモニタリングツール参考にしたい 最後に 「やりたくなったら誰かやってください。」ということみたいです。\n基礎から監視まで結構幅広くキーワードが出てきたので楽しかったです。\nその他に話に出てきてた方のブログもリンクしとこうかな。\nnekopの日記\n","date":1396866240,"dir":"post/2014/","id":"299abcee56b05b312ed5700f686f79b8","lang":"ja","lastmod":1396866240,"permalink":"https://blog.johtani.info/blog/2014/04/07/attend-jvm-casual-1/","publishdate":"2014-04-07T19:24:00+09:00","summary":"JVM Operation Casual Talksに参加しました。 あんまり、運用とかやってないので、ついていけるか不安ですが、楽しそうだったので。 懇親会は予定されてないらしい","tags":["JVM","Java","勉強会"],"title":"JVM Operation Casual Talksに参加しました #jvmcasual"},{"contents":"今日はelasticsearch-kopfのREST画面の紹介です。\n(簡単なところから。。。)\nメニューのrestを選択すると、次のような画面が表示されます。\nElasticsearch自体が、さまざまな操作をRESTでできる仕組みになっています。 検索にも利用しますが、それ以外の設定などにつてもリクエストを送ればOKです。\nですので、リクエストや設定を自分で組み立てて送ることができる画面が用意されているととても便利です。 (もちろん、curlコマンドでもいいのですが、画面があると便利ですよね)\nREST画面 History 履歴表示画面です。 これまで、kopfのrest画面を利用して送信したリクエストが一覧で表示されます。\nHistoryという文字をクリックすることで、表示/非表示の切り替えが可能です。(最初は非表示) マウスオーバーすると、リクエストボディがポップアップで表示されます。\nHistory 履歴にあるURLはクリック可能で、クリックすると実行されます。 履歴はlocalStorageに保存されるみたいです。(ブラウザの仕様?あんまり詳しくないので。。。) たぶん、30件が上限かと(ソースで確認しただけ)\nURL rest画面でリクエストを送信する先のURLを指定します。 メソッドは右側のSELECTで選択可能です。\nリクエストパラメータも指定が可能です。\nリクエストボディ 検索や設定のJSONを記述するところです。 一応、JSON的にエラーがある場合は行数の左側にバツ印が出てきておかしなところもわかるようになっています。\nインデントなどは行ってくれますが、senseみたいな補完などはないので、少し辛いところです。\nレスポンス 送信したリクエストに対するレスポンスが返ってきます。 インデントされた状態で表示されるので読みやすいかと。 また、入れ子になっているJSONについては、閉じたり開いたりすることも可能です。 (開始のカッコの右側に-が表示されていて、クリックすると閉じることができます。閉じると+に変わります)\n簡単ですが、rest画面の説明でした。 KOPFを使っていて、ちょっとしたクエリを送ったりするのには便利だと思います。\n複雑な検索クエリなどについては、やはりsenseを使うのが良いかと思いますが。。。\n","date":1396837440,"dir":"post/2014/","id":"670744b945088de05866864f7d57bee7","lang":"ja","lastmod":1396837440,"permalink":"https://blog.johtani.info/blog/2014/04/07/intro-elasticsearch-kopf-rest/","publishdate":"2014-04-07T11:24:00+09:00","summary":"今日はelasticsearch-kopfのREST画面の紹介です。 (簡単なところから。。。) メニューのrestを選択すると、次のような画面","tags":["elasticsearch","plugin"],"title":"elasticsearch-kopfの紹介(rest画面)"},{"contents":"なんだか、ドタバタしてて久しぶりの更新です。 ベルリンの旅行記みたいなのも書きたいのですが、まずはこちらかと。\nelasticsearch-kopfプラグインの紹介です。\n今回は概要の説明だけになります。機能が結構多いので。\nelasticsearch-kopfとは? _siteプラグインの一つで、クラスタ管理用のプラグインになります。 headプラグインやHQプラグインと同様です。\nプラグインの画面 このようにシンプルな画面で、スッキリとしています。 緑を基調にした画面構成はElasticsearchの緑色を意識してるんでしょうか?\n上記の画像に簡単なコメントを入れてあります。\nメニュー KOPF:KOPF自体の設定(接続先とリフレッシュインターバルの変更) cluster:クラスタ管理、情報(デフォルト表示画面) rest:RESTリクエスト送信、結果表示画面 aliases:エイリアス管理 analysis:analysis API percolator:パーコレータ管理 warmup:ウォームアップクエリ管理 上記のようなメニューです。各メニューについては、今後のブログで少しずつ紹介しようかと。 このメニューの色が、クラスタの状態も表しています。ステータスがYELLOWなら黄色、REDなら赤色に変わります。\nインデックス インデックスは列として表示されます。先ほどの画像では、2つのインデックスが表示されている状態です。 インデックス毎に、シャードも表示されます。これは、各ノードがどのシャードを保持しているかという情報です。 色の濃いシャードがプライマリでしょう。 インデックス名やシャードの箱はクリックできるようになっていて、それぞれの情報がJSONで表示されます。 その他にもドキュメント数、サイズなども表示されます。 インデックスの各種操作(closeやdeleteなど)もここからメニューが表示されます。(これも次回詳しく)\nノード ノードの情報が行として表示されます。ノードが増えると下に追加されていきます。 node1というのが、ノード名です。(ヒーローの名前とかが出てくるやつです。)\nその他に、IPアドレス、ポート番号、負荷、ヒープサイズなども表示されています。 電源ボタンはノードのシャットダウンを行うためのボタンです。(確認用のダイアログが表示される)\nその他 その他に、クラスタの概要として、ノード数、インデックス数、シャード数、ドキュメント数なども表示されます。 インデックスの作成などは、アイコンから操作が可能です。 大規模なクラスタを管理している場合、検索ボックスを利用することで、インデックス名やノード名による絞込もできるようになっています。\n感想 シンプルな構成の画面で、個人的にはheadよりも好きな画面です。 HQよりもシャードの分散具合がわかりやすいので、今後はこのプラグインを利用していこうと考えています。\nまずは、簡単な紹介です。今後、各画面についてもう少し説明をブログに書いていこうかと考えています。 待てない方は、触ってみてもらうのが良いかと。 もちろん、続きを書いてもらってもいいですよ!!\n","date":1396707480,"dir":"post/2014/","id":"c1241374502f200cf9fc49c8d6fb5822","lang":"ja","lastmod":1396707480,"permalink":"https://blog.johtani.info/blog/2014/04/05/intro-elasticsearch-kopf-1/","publishdate":"2014-04-05T23:18:00+09:00","summary":"なんだか、ドタバタしてて久しぶりの更新です。 ベルリンの旅行記みたいなのも書きたいのですが、まずはこちらかと。 elasticsearch-ko","tags":["elasticsearch","plugin"],"title":"elasticsearch-kopfの紹介(概要)"},{"contents":"先日、「ElasticSearch Serverを翻訳しました」という記事を書きました。\nこの中で電子版も出ますよと書いていましたが、電子版も発売されたので、再告知も兼ねてブログを書いています。\nなお、最近よく「ElasticsearchのSは小文字」とツイートしていますが、本書は原著のタイトルが「ElasticSearch Server」となっているため、Sは大文字になっています。原著が出版された時期にはまだSが小文字に統一されていなかったためです。\n紙の書籍はすでに書店に並んでいたり、Amazonでも発送されているようです。\n私自身が電子書籍が場所を取らなくて好きというのもあり、電子版も出版していただけるようにお願いしていました。\n電子版についてはAmazonでKindle版、達人出版会からEPUBとPDFが購入可能です。\n達人出版会のElasitcSearch Serverのページ AmazonのKindle版ページ こちらのリンク(Amazonはアフィリンク)を参考にしていただければと。\n書籍の写真入りツイートしたら、原著者の方からレスを頂きました。\n@johtani Thanks for the great work out there :)\n\u0026mdash; Rafał Kuć (@kucrafal) 2014, 3月 23 また、原著者のサイトでも紹介してもらいました(結構うれしい)。 私が窓口をやっていた関係で、私の名前しか入っていませんが。。。 編集者と翻訳者の方々のお陰で良い本が出版できたと思っています。\nThanks for sharing! / ElasticSearch Server book in Japanese | ElasticSearch Server Book Blog http://t.co/fhCP1vVBd3\n\u0026mdash; Jun Ohtani (@johtani) 2014, 3月 24 ということで、Elasticsearchの導入の手助けになればと。 感想(賛否問わず)など、あればコメント、ツイート、ブログなど書いていただければうれしいです。 (その際に、連絡してもらえるとさらにうれしいです)\n","date":1395722580,"dir":"post/2014/","id":"d51032bef3e7117a94336fea18a3fad7","lang":"ja","lastmod":1395722580,"permalink":"https://blog.johtani.info/blog/2014/03/25/release-elasticsearch-server-ja-ebook/","publishdate":"2014-03-25T13:43:00+09:00","summary":"先日、「ElasticSearch Serverを翻訳しました」という記事を書きました。 この中で電子版も出ますよと書いていましたが、電子版も発","tags":["elasticsearch"],"title":"ElasticSearch Server日本語版(電子版も)が発売されました"},{"contents":"GOTO Night elasticsearchに参加しました。 初の海外の勉強会です(海外自体が初だし)。\nベルリンにあるWoogaという会社で開催された勉強会です。\nFull house at the #gotonight about @elasticsearch in the auditorium of @wooga pic.twitter.com/r2Vx2aMcEn\n\u0026mdash; GOTO Berlin (@GOTOber) 2014, 3月 18 会場はこんな感じで、とってもおしゃれです。(なんか、写ってますね、最前列にw) ベルリンの古い建物をリノベーションしたオフィスみたいで、そこにこういったひな壇を用意して発表するスペースにしているみたいです。\n内容としては、Elasticsearch1.0の新機能の話として、snapshot/restore、cat、aggregationなどの話題でした。簡単にどういったものかの説明です。\n一人目の発表が終わったら、ブレイクタイムとして上のフロアに用意されている軽食+ドリンクで軽く交流の時間が用意されていました。 ベーグルなどのサンドイッチとハイネケンやクラブマテ?と呼ばれるチープなレッドブルとかが飲めました。\nちょっと食べて談笑したあとに、次はLogstashとKibanaのお話でした。Logstashってどんなもの?という話がメインで、Kibanaは簡単な紹介という感じでしょうか。最後に、ライブデモがありました。 Kibanaを使ったライブデモはインパクトがあるなというのが感想です。 フィールド名の補完をしてくれたりと便利な機能が操作をしているところでわかるので。\nYoutubeなどでも見てても思っていた感想ですが、こちらの勉強会は質問が結構出てきます。 今日参加した勉強会も質疑応答が結構されてました。\nelasticsearchの方たちと少しだけ話しをできたので、かなり興奮気味でブログを書いています(ミーハー)。\nただ、やっぱり英語のヒアリングがまだまだだなぁとも実感出来ました。 場数踏むしかないと思うので少しずつ耳にしてなれるしかないかなぁと。 はぁ、ちゃんと高校とか大学の頃に単語を覚えとくんだったと軽く後悔。\nこんなツイートもしてもらって、興奮気味です。明日早起きしないといけないので寝ないといけないのにw\nMeeting @johtani finally in #berlin watching @spinscale talking about #elasticsearch\n\u0026mdash; Simon Willnauer (@s1m0nw) 2014, 3月 18 ","date":1395151860,"dir":"post/2014/","id":"65453a1ae403679bd2e47398a04205ca","lang":"ja","lastmod":1395151860,"permalink":"https://blog.johtani.info/blog/2014/03/18/attend-goto-night-elasticsearch/","publishdate":"2014-03-18T23:11:00+09:00","summary":"GOTO Night elasticsearchに参加しました。 初の海外の勉強会です(海外自体が初だし)。 ベルリンにあるWoogaという会社で開催された勉強会","tags":["elasticsearch","勉強会"],"title":"GOTO Night elasticsearchに参加しました"},{"contents":"Berlinからおはようございます。\nということで、人生で初めての海外に来ています。\n人生初の海外なのに、一人で乗り換えがあるようなBerlinに来ています。 今年はチャレンジの年になりそう。初めてづくしですが、楽しみたいなと。 会社に感謝です。ESのトレーニングを受けに来たのがメインなのです。 ついでに、Berlinでの勉強会にも参加してみようかなと。\n幸いにも時差ボケはなさそうなので、色々と見て回ろうと思います。 ただ、日曜日はお店が軒並みしまってそう。。。\n","date":1394916660,"dir":"post/2014/","id":"abc5ca9856a61831fd4ed06b402875d2","lang":"ja","lastmod":1394916660,"permalink":"https://blog.johtani.info/blog/2014/03/16/post-from-berlin/","publishdate":"2014-03-16T05:51:00+09:00","summary":"Berlinからおはようございます。 ということで、人生で初めての海外に来ています。 人生初の海外なのに、一人で乗り換えがあるようなBerlin","tags":["misc","travel"],"title":"Berlinからおはようございます"},{"contents":"elasticsearchに、このへん入れるときっと幸せになれるはず・たぶん。\u0026#10;elasticsearch/elasticsearch-analysis-kuromoji/1.6.0\u0026#10;oyrusso/elasticsearch-HQ\u0026#10;mobz/elasticsearch-head\n\u0026mdash; toshi_miura (@toshi_miura) 2014, 3月 5 こんなツイートを見かけたので、普段入れてるプラグインを簡単に紹介してみようかと。\nローカルの環境に普段入れているプラグインの紹介です。 ちゃんとクラスタを管理しているというよりは、最新版の動作などを確認するための環境になります。なので、ちょっと視点が異なるかもしれませんが参考になればと。\nelasticsearch-analysis-kuromoji URL : elasticsearch-analysis-kuromoji\nKuromojiという日本語形態素解析のTokenizerなどを使えるようにするためのプラグインです。 今度、発売される「ElasticSearch Server」日本語版には付録として、利用方法を執筆しました。参考にしていただければと。 READMEにもサンプルは掲載されてるので、こちらを参考にするのもありですが。\nelasticsearch-extended-analyze URL : elasticsearch-extended-analyze\n私が開発しているプラグインです。 ElasticsearchにはanalyzeというAPIが用意されています。 文章を渡すと指定したanalyzerなどでどのような単語に区切られるかがわかるAPIです。\nただ、analyzerの内部ではchar filter、tokenizer、token filterという個別のパーツがそれぞれ入力された文字列に対して処理を実施します。 この過程がanalyze APIではわかりません。 それをわかるようにしてみたのがelasticsearch-extended-analyzeプラグインになります。\n詳細については過去の記事を見ていただければと。 画面があると便利だよなぁと思いつつ、作ってない。。。\npolyfractal/elasticsearch-inquisitor URL : elasticsearch-inquisitor\nクエリのデバッグとかに便利なプラグイン。\nこちらも詳細は過去の記事を見ていただければと。\nmobz/elasticsearch-head URL : elasticsearch-head\nクラスタ管理に便利なプラグインです。クラスタに存在するノードに対してインデックスのデータ(シャード)がどこに配置されているかなどが一目瞭然になる便利なプラグインです。 プライマリシャードやレプリカなどもわかります。 インデックスの削除もできるし、クエリを投げることもできるし、全部入りな感じのプラグインです。\n私個人は、シャードの配置を見るのに主に利用しています。クエリを投げたりインデックスを消したりするのには殆ど使っていません。\nroyrusso/elasticsearch-HQ URL : elasticsearch-HQ\nこれも管理系のプラグインです。こっちのほうが個人的にスッキリしていて好きなプラグインです。 インデックスの管理やノードの停止などはこちらを主に使用しています。 あくまでもローカルの簡易クラスタを管理する目的というのもあります。\npolyfractal/elasticsearch-segmentspy URL : elasticsearch-segmentspy\nこちらはモニタリングでしょうか。 ElasticSearch Serverで紹介されていたのが主な理由で、入れてますがあんまり見てないかも。 インデックスのSegment単位の情報が見ることが可能です。 あと、ちょっと更新されてない感じがしますね。\nelasticsearch/marvel Elasticsearch社から提供されている、モニタリングなどに使えるプラグインです。 開発環境では無償提供という感じです。 渡しの場合、モニタリング目的ではなく、senseと呼ばれるクエリの補完をしてくれるツールの目的のために使用しています。 モニタリング部分を停止する方法とかないかなぁ。\n詳細については過去の記事を参考にしていただければと。\nまとめ? ということで、簡単にローカルに入っているプラグインの紹介でした。 他にもいっぱいあるので、おすすめがあれば、教えてもらえると助かります。\n","date":1394515380,"dir":"post/2014/","id":"386dc9d1b647a9f3965f1fbe29c7dfb9","lang":"ja","lastmod":1394515380,"permalink":"https://blog.johtani.info/blog/2014/03/11/es-plugin-installed-to-my-env/","publishdate":"2014-03-11T14:23:00+09:00","summary":"elasticsearchに、このへん入れるときっと幸せになれるはず・たぶん。\u0026#10;elasticsearch/elasticsearc","tags":["elasticsearch","plugin"],"title":"いつも入れているElasticsearchのプラグイン"},{"contents":"第3回Elasticsearch勉強会で、軽く触れていましたが、ElasticSearch Server日本語版が発売されます。 ツイートなどもちらほらとして頂いているみたいで嬉しい限りです。\n本書は、私自身、初の翻訳本となります。\nなお、ElasticSearchはAWSのサービスではなく、全文検索・解析サーバのOSSです\n内容、概要 PacktPublishingから発売されているElasticSearch Serverの日本語版となります。 以下の点が、原著とは異なる点になっています。\n0.90.xに対応(原著は0.20) Kibana、Kuromojiに関して追記 もちろん日本語 残念ながら、つい最近、Elasticsearchについては1.0がリリースされました。 1.0で追加された機能(SnapshotやRestore、Aggregatorなど)については触れていませんが、Elasticsearchの機能を網羅的にカバーした良書となっています。 どんな機能があるのか、どんなプラグインがあるのか、どういったことに使えるのかなど、幅広くまとめられた本になっていますので、 Elasticsearchに興味がある方はぜひ読んでいただければと思います。\nまた、現段階では予定ですが電子版の出版も予定されています。電子版が気になる方は、少しお待ちいただければと。\nElasticSearch?Elasticsearch? 1.0.0がリリースされた現在は、Elasticsearch(SearchのSは小文字)が正式な名称となっています。 ただ、原著が発売された当初(2013年2月時点)では、まだSは小文字と大文字が混在した状況でした(コミットログなどを見るとわかります。) このため、日本語版でもElasticSearchという表記に統一してあります。\n翻訳に関して 初の翻訳書ということもあり、大変でした。英語に精通しているわけではないので(むしろ苦手)。。。 他の翻訳者の方々には大変助けていただきましたし、勉強になりました。 また、監修社であるリクルートテクノロジーズにも色々とサポートしていただき、感謝の限りです。 (Elasticsearch勉強会の開場提供にも協力して頂いています。)\nわかりにくい日本語となっている部分などありましたら、ご指摘いただければ今後の参考にさせていただきます。 英語やElasticsearchについて、学ぶという目的もあって、本書の翻訳を買って出たのが本音です。\n翻訳作業について Githubのリポジトリを編集の方に用意してもらい、翻訳原稿を管理、校正していきました。 Github自体をあまり触っていなかったので、作業をしながらGithubも覚えられ一石二鳥でした。 Issueやプルリクエストによる校正、チェックも便利ですね。 他の原稿を書くようなことがあれば、またこの経験を活かしていきたいなと。 (翻訳の進め方や原稿のチェックなどについてはまた後日何か書こうかと。)\n原著について 原著のサイトが用意されています。 http://elasticsearchserverbook.com/elasticsearch-server-errata/\n原著を翻訳するにあたって見つけた、誤植などを報告し、掲載して頂いています。 原著をお持ちの場合はこちらも参考にしていただければと思います。\nご購入はこちらから ということで、簡単ですが書籍の紹介(というより宣伝!?)でした。 Elasticsearchに関する何かしらの助けになる書籍であれば嬉しい限りです。\n「ElasticSearch Server日本語版」をよろしくお願いします。 (もちろん、購入は下のリンクからですよね!)\n","date":1393836900,"dir":"post/2014/","id":"9ad72c2a5157f21741bd4581a562dfc7","lang":"ja","lastmod":1393836900,"permalink":"https://blog.johtani.info/blog/2014/03/03/release-elasticsearch-server-japanese-edition/","publishdate":"2014-03-03T17:55:00+09:00","summary":"第3回Elasticsearch勉強会で、軽く触れていましたが、ElasticSearch Server日本語版が発売されます。 ツイートなども","tags":["elasticsearch"],"title":"ElasticSearch Serverを翻訳しました"},{"contents":"今年初の「突撃!隣のElasticsearch」ということで、Wantedlyさんにおじゃましました。\n※写真を自分でも撮ったのですが、画像が壊れてたので、一緒に行ったペンギン先生の写真を拝借しました。\n第3回のElasticsearch勉強会を開催中にES使ってるってツイートを見つけたので、アタックかけて遊びに行きました。 交渉に快諾いただきありがとうございました!\nWantedlyさんがどのようにElasticsearchを使用されているかはきっと、ブログを書いてくれると思うので期待しておくとして、書いてくれました!! 「実践!Elasticsearch」 そこで、nestedでハイライトがなんかうまくいかないって話があったので、ちょっと調べてみました。 (※まだ、調査中です)\n前提条件 再現する手順はgistにあります。(Senseに貼り付ければ動作します。ただし、elasticsearch-analysis-kuromojiが必要です。)https://gist.github.com/johtani/9184287\nなお、このマッピングやデータはWantedlyさんとは全く関係ありません。\nnestedフィールド内部のデータに対して、検索しハイライトしようとするとうまく動作しないという状況です。 マッピングは以下のとおり。\n\u0026#34;books\u0026#34; : { \u0026#34;properties\u0026#34;: { \u0026#34;book\u0026#34; : { \u0026#34;type\u0026#34;: \u0026#34;nested\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;title\u0026#34; : { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;kuromoji\u0026#34;, \u0026#34;store\u0026#34;: \u0026#34;no\u0026#34;}, \u0026#34;contents\u0026#34; : {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;kuromoji\u0026#34;, \u0026#34;store\u0026#34;: \u0026#34;yes\u0026#34;} } } } } } このマッピングの特徴は以下のとおり。\n_sourceは保存される(デフォルト値) bookがnestedなオブジェクト titleはstore : no contentsはstore : yes 動作の挙動をわかりやすくするため、titleとcontentsのstore属性に違いを持たせてあります。\n問題点 nestedクエリを使って、検索した時にハイライトが返ってきません。 次のクエリを実行するとわかります。\nGET /bookstore/books/_search { \u0026#34;_source\u0026#34; : [\u0026#34;book.title\u0026#34;,\u0026#34;book.contents\u0026#34;], \u0026#34;fields\u0026#34;: [ \u0026#34;book.title\u0026#34;, \u0026#34;book.contents\u0026#34; ], \u0026#34;query\u0026#34;: { \u0026#34;nested\u0026#34;: { \u0026#34;path\u0026#34;: \u0026#34;book\u0026#34;, \u0026#34;query\u0026#34;: { \u0026#34;query_string\u0026#34; : { \u0026#34;query\u0026#34; : \u0026#34;Solr\u0026#34;, \u0026#34;fields\u0026#34; : [\u0026#34;book.title\u0026#34;, \u0026#34;book.contents\u0026#34;] } } } }, \u0026#34;highlight\u0026#34;: { \u0026#34;pre_tags\u0026#34;: [\u0026#34;\u0026lt;b\u0026gt;\u0026#34;], \u0026#34;post_tags\u0026#34;: [\u0026#34;\u0026lt;/b\u0026gt;\u0026#34;], \u0026#34;fields\u0026#34;: { \u0026#34;*\u0026#34;: {} } } } 結果はこちら。 ハイライトがありません。\n{ \u0026#34;took\u0026#34;: 3, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 5, \u0026#34;successful\u0026#34;: 5, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;max_score\u0026#34;: 0.5, \u0026#34;hits\u0026#34;: [ { \u0026#34;_index\u0026#34;: \u0026#34;bookstore\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;_score\u0026#34;: 0.5, \u0026#34;_source\u0026#34;: { \u0026#34;book\u0026#34;: { \u0026#34;title\u0026#34;: \u0026#34;Apache Solr入門\u0026#34;, \u0026#34;contents\u0026#34;: \u0026#34;Apache Solrについて日本語で書かれた唯一の書籍です。SolrはLuceneをコアにした検索サーバです。\u0026#34; } } } ] } } 次に、ハイライトが帰ってくるパターン。 nestedクエリではなく、_allを対象としたクエリを投げます。\n{ \u0026#34;_source\u0026#34; : [\u0026#34;book.title\u0026#34;,\u0026#34;book.contents\u0026#34;], \u0026#34;fields\u0026#34;: [ \u0026#34;book.title\u0026#34;, \u0026#34;book.contents\u0026#34; ], \u0026#34;query\u0026#34;: { \u0026#34;query_string\u0026#34; : { \u0026#34;query\u0026#34; : \u0026#34;Solr\u0026#34;, \u0026#34;fields\u0026#34;: [ \u0026#34;_all\u0026#34; ] } }, \u0026#34;highlight\u0026#34;: { \u0026#34;pre_tags\u0026#34;: [\u0026#34;\u0026lt;b\u0026gt;\u0026#34;], \u0026#34;post_tags\u0026#34;: [\u0026#34;\u0026lt;/b\u0026gt;\u0026#34;], \u0026#34;fields\u0026#34;: { \u0026#34;book.title\u0026#34; : {}, \u0026#34;book.contents\u0026#34;: {} } } } この場合の結果は次の通り。\n{ \u0026#34;took\u0026#34;: 2, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 5, \u0026#34;successful\u0026#34;: 5, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;max_score\u0026#34;: 0.27063292, \u0026#34;hits\u0026#34;: [ { \u0026#34;_index\u0026#34;: \u0026#34;bookstore\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;_score\u0026#34;: 0.27063292, \u0026#34;_source\u0026#34;: { \u0026#34;book\u0026#34;: { \u0026#34;title\u0026#34;: \u0026#34;Apache Solr入門\u0026#34;, \u0026#34;contents\u0026#34;: \u0026#34;Apache Solrについて日本語で書かれた唯一の書籍です。SolrはLuceneをコアにした検索サーバです。\u0026#34; } }, \u0026#34;highlight\u0026#34;: { \u0026#34;book.title\u0026#34;: [ \u0026#34;Apache \u0026lt;b\u0026gt;Solr\u0026lt;/b\u0026gt;入門\u0026#34; ] } } ] } } ハイライトが返ってきています。\n考察(原因は未特定) 残念ながら、まだ調査してません。 まずは、現象が理解できたというだけです。 問題点が実は2つありそうです。\n問題点1:nestedクエリの場合に、ハイライトされない。 nestedクエリではハイライトが動作していないようです。 想像ですが、検索に利用されたクエリで指定されているフィールドをハイライタ(ハイライトを実行するモジュール)が認識できてないのではないかと。 なぜ認識できていないのかという点を調査する必要がありそうです。\n考察(試してみたパターン) nestedではないクエリで、ハイライトが動作しているのですが、 \u0026quot;book.title\u0026quot; : {\u0026quot;require_field_match\u0026quot; : true},にした場合は、ハイライトが返ってこないです。 このオプションは、検索対象のフィールドでマッチした文字列だけがハイライトされるオプションになります。 したがって、book.titleフィールドに対する検索でSolrという文字を検索していないことになります。 _allに対するクエリであるためです。 このため、例えば、titleだけを検索対象にしたのに、contentsにSolrという文字が入っていてもハイライトされてしまうという状況が発生します。\n問題点2 store : yesのデータがハイライトできない。 GithubにIssueをあげました。https://github.com/elasticsearch/elasticsearch/issues/5245 (2014/02/25追記)\nnestedオブジェクトにあるデータのうち、store : noのものだけがハイライト結果として返ってきました。\n考察 なぜ、store : yesのデータがハイライトされないかを調べるために、fieldsパラメータをリクエストに追加してみました。\n{ \u0026#34;_source\u0026#34; : [\u0026#34;book.title\u0026#34;,\u0026#34;book.contents\u0026#34;], \u0026#34;fields\u0026#34;: [ \u0026#34;book.title\u0026#34;, \u0026#34;book.contents\u0026#34; ], ... } すると、fieldsの戻り値は次のとおりです。\n... \u0026#34;fields\u0026#34;: { \u0026#34;book.title\u0026#34;: [ \u0026#34;Apache Solr入門\u0026#34; ] }, ... このことから、store : noのデータの場合、_sourceから値を取得して返却しているというのがわかります。 ハイライトがされない原因も、fieldsで値が取れていないのも同じ原因であると思われます。 なぜなら、ハイライトは、保存された文字列を内部で取り出し利用して、ハイライトタグを埋め込むという動作をするためです。\n参考? これらの問題点についてですが、次のIssueが関係あるかもしれません。\nReturn matching nested inner objects per hit #3022\n今後? 残念ながら、現時点では、問題点がどんなものかというのを理解しただけとなります。 デバッグしたりソースを追っかけたりして何が問題なのかを調べて行ってみようかなぁと。\nなにか、気づいたことなどあればコメントしてもらえると助かります。\n","date":1393231920,"dir":"post/2014/","id":"f55d33371dcff207fd7d201128df2ea3","lang":"ja","lastmod":1393231920,"permalink":"https://blog.johtani.info/blog/2014/02/24/strange-behavior-of-field-in-nested-obj/","publishdate":"2014-02-24T17:52:00+09:00","summary":"今年初の「突撃!隣のElasticsearch」ということで、Wantedlyさんにおじゃましました。 ※写真を自分でも撮ったのですが、画像が","tags":["elasticsearch"],"title":"Nested Objectのフィールドの奇妙な動作"},{"contents":"今回はたまたま日本にいたElasticsearchの人をスペシャルゲストに呼べたので、大満足ですw 英語の通訳とかちゃんと勉強しないとなぁ。。。\nとりあえず、てきとーなメモですが、残しておきます。 参加者数は130人+スタッフ+リクルートテクノロジーズ社内の人。という感じでした。アンケート集計はもう少々おまちを。\nスライドがそろったら、また、更新すると思いますが、第一報という感じで公開しておきます。 懇親会にも50名も参加していただけて、非常に楽しかったです。 話ができてない方が多数いるかもしれませんが、次回以降、声をかけていただければと。 (物覚え悪いんで、あれですが。。。) 盛り上がってきてて楽しいなぁ。 スタッフの人達の練度も上がってきてるので、すごく楽ができてます。\n至らない点とかあれば、こちらにコメントしてもらったりしていただければと。\nGeohashing with Elasticsearch Florian Schilling, Elasticsearch Inc, スライド:https://speakerdeck.com/chilling/tokyo-es-study-session-iii-geohashes\n自己紹介 Geoのスタッフ Elsticsearchの概要 転置イデックスやREST APIなどの説明 マイクの調子が良くなくて申し訳なかったっす。。。 平賀さん、通訳ありがとう! Solr本もよろしくお願いします!!\nAWSで構築するsharding 株式会社イプロス 外山 寛さん @toyama0919 スライド:http://toyama0919.bitbucket.org/elasticsearch.html\nAWS対応の話 ルーティングが重要だよ。(宣伝ありがとうございますw) type指定しないとルーティングできない。(内部でtypeも使ってハッシュ値取ってたかなぁ?) 苦労話とかいくつか。 tireはre-tire\u0026hellip; 実サービスでのElasticsearch設定・使用例(仮) 株式会社じげん 多田 雅斗さん @tady_jp スライド:https://speakerdeck.com/tadyjp/tesutoqu-dong-jian-suo-falsesusume-at-tady-jp\n検索とは的な話がわかりやすい。 全文検索のお話。ログ検索じゃないよと。 書籍ないですよねー(ふふふ) specで検索条件記述しといて、ってのいいですよね。絶対必要だと思う Mapping変更した時にテストやり直す方法とかどうしてますか? 特にフレームワークは使ってないです。\nMySQLユーザ視点での、小さく始めるElasticsearch 株式会社リブセンス 吉田 健太郎さん @yoshi_ken スライド:http://www.slideshare.net/y-ken/introducing-elasticsearch-for-mysql-users\nやっぱりkuromoji便利だよね MySQLとかと連携したい。 river-pluginもいまいち安定しない なので、Yamabiko作ってみました。 Geo検索とKuromojiの話をしてくれました。(作者とか開発者がいるってのを狙ってたのかすごいなぁ。) Mappingとかはちゃんと指定したほうがいろいろいいですよ。 nodeJS+DynamoDB+Elasticsearchで全社基盤を作った話 株式会社リクルートテクノロジーズ 相野谷 直樹さん @naokiainoya スライド:http://www.slideshare.net/recruitcojp/elasticsearchnodejsdynamodb-7\nちょっと変わった使い方のElasticsearchで面白いです。 Scroll/Scanについては、Solrでもない機能なので、そういう意味でもElasticsearchなのかもしれないですね。 参加していただいた方々のブログ 第3回elasticsearch勉強会 [2014/02/07(Fri.)]に参加してきました - ほわいとぼーど\nhttp://a3no.hatenablog.com/entry/2014/02/09/022405\n第 3 回 elasticsearch 勉強会に行ってきた - ようへいの日々精進\nhttp://inokara.hateblo.jp/entry/2014/02/07/233057\nhttp://www.smokeymonkey.net/2014/02/3elasticsearch.html\n第3回elasticsearch勉強会でトークしました #elasticsearchjp\nhttp://y-ken.hatenablog.com/entry/elasticsearch-meetup-vol3\n第3回elasticsearch勉強会にいってきました #elasticsearchjp\nhttp://blog.livedoor.jp/ashibuya0128/archives/52058766.html\n","date":1391787720,"dir":"post/2014/","id":"229b7fc784707b1d2c702fbeba080e86","lang":"ja","lastmod":1391787720,"permalink":"https://blog.johtani.info/blog/2014/02/08/hold-3rd-elasticsaerch-meetup-in-tokyo/","publishdate":"2014-02-08T00:42:00+09:00","summary":"今回はたまたま日本にいたElasticsearchの人をスペシャルゲストに呼べたので、大満足ですw 英語の通訳とかちゃんと勉強しないとなぁ。。","tags":["elasticsearch","勉強会"],"title":"第3回elasticsearch勉強会を開催しました! #elasticsearchjp"},{"contents":"すずけんさんがVagrant+puppet使って、VM起動してElasticsearchのクラスタを組んでる記事を書いているのを見て、試してみたくなりました。 ということで、VagrantとかPuppetなに?くらいの私ですが、クラスタを起動するところまで行ったので、その時のメモを残しておきます。\n元記事とか参考 Vagrant環境にpuppet moduleを利用してさくっとelasticsearchをインストールする Vagrant環境にpuppetを利用してさくっとelasticsearchのclusterを作成する puppet-elasticsearch なんとなくの理解 VagrantやPuppetについては、何度か勉強会で話を聞いてはいたのですが、 想像していたレベルだったので良い機会でした。 今のところの認識はこんな感じです。\nVagrant VMを起動したり、VM周りの設定をあれこれできるツール。 VMのネットワーク設定や、インスタンス名?などを指定できる。\nPuppet 起動後のVM(VMとは限らないか。)のゲストOS側の設定周りやアプリのインストールなどを 実行できるツール。\n詰まった箇所 すずけんさんのブログを元に作業をしましたが、自分がVagrantやPuppetに疎いため、以下の部分で躓いたので、備忘録のために残しておきました。\nその1:Puppetのファイルの場所 search01.vm.localのVMを設定(というか、elasticsearchのインストール?)するときに、manifests/search.appとroles/search/manifests/init.ppファイルが必要で作成します。\nこのファイルの配置場所は/vagrant配下に作成する必要がありました。 ssh search01.vm.localでVMにログインした場合は/home/vagrantにログインしており、この場所でファイルを作ってもPuppetがエラーを吐いたためです。\nと思ったのですが、あれ?これひょっとしてVagrantfileがあるところにディレクトリとファイル作ると勝手にVMにコピーしてくれるんですか?destroyして、upしたら、ファイルが勝手にコピーされてる。ひょっとして、/vagrantってディレクトリはVagrantfileがあるディレクトリを共有してたりするのかな?そのうち、Vagrantについても調べてみようかな。\nその2:ネットワーク周り curl http://192.168.10.114:9200/ をホストOSから実行してみましたがうまく行きませんでした。。。 ネットワーク周りの設定だと思うんですが。 少なくとも「sshによるログイン」「ping」コマンドの応答は返ってきてます。\nまた、VM内でcurlコマンドを実行したらレスポンスが返ってきました。\nなんで?ってツイートしたら各所から「iptables」という単語が飛んできて、 service止めたら大正解でした。まぁ、そうですよね。基本ですよね。。。\nということで、Puppetがよくわかっていませんが、ググって変更してみました。\nmanifests/search.appに以下を追加\ninclude iptables roles/iptables/manifests/init.pp\nclass iptables { service { \u0026#39;iptables\u0026#39;: enable =\u0026gt; false, ensure =\u0026gt; stopped, } } iptablesを停止するmanifests?です(良くないことなんですが、よくわかってない)。\nということで、ローカルで1個のVM起動して、elasticsearchにアクセスできることは確認できました。\nと、書いてるそばから、元記事が修正されてしまいましたw\nクラスタ編(変更点) クラスタを組むときに、追加でプラグインを入れたのでroles/search/manifests/init.ppは次のようにしました。\nclass search { class { \u0026#39;elasticsearch\u0026#39;: package_url =\u0026gt; \u0026#39;https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.0.0.RC2.noarch.rpm\u0026#39;, java_install =\u0026gt; true, config =\u0026gt; { \u0026#39;cluster\u0026#39; =\u0026gt; { \u0026#39;name\u0026#39; =\u0026gt; \u0026#39;test-es-cluster\u0026#39; }, \u0026#39;network.host\u0026#39; =\u0026gt; \u0026#39;_eth1:ipv4_\u0026#39;,, \u0026#39;marvel.agent.exporter.es.hosts\u0026#39; =\u0026gt; [\u0026#39;192.168.10.114:9200\u0026#39;,\u0026#39;192.168.10.115:9200\u0026#39;] } } elasticsearch::plugin{\u0026#39;elasticsearch/marvel/latest\u0026#39;: module_dir =\u0026gt; \u0026#39;marvel\u0026#39; } elasticsearch::plugin{\u0026#39;mobz/elasticsearch-head\u0026#39;: module_dir =\u0026gt; \u0026#39;head\u0026#39; } elasticsearch::plugin{\u0026#39;royrusso/elasticsearch-HQ\u0026#39;: module_dir =\u0026gt; \u0026#39;HQ\u0026#39; } elasticsearch::plugin{\u0026#39;elasticsearch/elasticsearch-analysis-kuromoji/2.0.0.RC1\u0026#39;: module_dir =\u0026gt; \u0026#39;analysis-kuromoji\u0026#39; } elasticsearch::plugin{\u0026#39;info.johtani/elasticsearch-extended-analyze/1.0.0.RC1\u0026#39;: module_dir =\u0026gt; \u0026#39;extended-analyze\u0026#39; } elasticsearch::plugin{\u0026#39;polyfractal/elasticsearch-inquisitor\u0026#39;: module_dir =\u0026gt; \u0026#39;inquisitor\u0026#39; } } とりあえず、今日はクラスタ組んでMarvelやプラグインの動作確認でおしまいです。\n疑問点 いくつか疑問点が。試してみてもないんでなんとも言えませんが。気が向いたら、調べて追記するかも。\n:private_networkはVirtualBox内で完結する(Macから外には影響しない)ネットワークが構築される?たぶん、VagrantというよりはVM、仮想化周りの知識なんだろうけど どこから再開可能?elasticsearch.ymlの設定を書き換えた場合に、最後のコマンドだけ実行するとちゃんとやりなしてくれたりするのかな? VMのディスク増やすのもVagrantでできるんかな?まぁ、できると思うけど。 :forwarded_portのauto_correctとかわかってない。 JVMをSunのJVMでかつ、7u25に変更したいのだがどうしたものか?(現時点での推奨バージョン) 感想 Vagrantって便利ですね。あれ?って思ったら、destroyして、やり直すのがすごく簡単です。 元記事があるので、なんとなくですが、構成とかどうすればいいかがわかるのは本当に助かりました。 これで、あれこれと検証する環境が簡単に構築できることがわかったので、色々と楽できるかも。ありがとうございます、すずけんさん!\n","date":1391695740,"dir":"post/2014/","id":"c98cbc333fb7d95c6c9fc4924b0526e1","lang":"ja","lastmod":1391695740,"permalink":"https://blog.johtani.info/blog/2014/02/06/es-cluster-start-using-vagrant-and-puppet/","publishdate":"2014-02-06T23:09:00+09:00","summary":"すずけんさんがVagrant+puppet使って、VM起動してElasticsearchのクラスタを組んでる記事を書いているのを見て、試して","tags":["elasticsearch","vagrant","puppet","marvel"],"title":"すずけんさんのメモを元にVagrantでElasticsearchクラスタを起動してみた"},{"contents":"改訂新版Solr入門出版記念ということで、第13回Solr勉強会 #SolrJP 新Solr本出版記念を開催しました。\n出版記念なので、技術評論社様より、プレゼント用にSolr本を用意していただきました!ありがとうございます!! 書籍をゲット出来た方は、ツイートしたりブログ書いたり書評書いたりして、宣伝してください!!!\n今回は、私は手を抜いて他の人に喋ってもらいました!\n今回は、著者陣(関口さんは特別ゲスト)でスピーカーを固めてみました。 以下は、いつもの簡単なメモです。 スライドが集まったらまた更新していきます。\n1. 「はじめての検索エンジン&Solr」 株式会社NTTデータCCS 鈴木 教嗣さん スライド:はじめての検索エンジン&Solr 第13回Solr勉強会\n鈴木さんの発表初めて聞きましたw。 趣味が多いなぁ。 ちょこちょこと、宣伝を入れてるのが流石ですw\n入門らしい概要 クエリの概要とかも。 スコア計算とか 導入するとうれしいところとか Solr盛り上げましょう! 2. 「Solr SearchComponent 再訪」 株式会社ロンウイット 関口 宏司さん スライド:公開待ち\nベン図で検索の評価指標の説明 理論的なお話 Solrのサーチコンポーネントを使って何ができるか。ベン図で。 サーチコンポーネント以外にも NGramTokenizerも SynonymFilterも パーソナライズ検索 いきなり話をふられたのでちょっとびっくりしましたw\n3. 「自動補完(Autocomplete)ともしかして?(Did You Mean?)」 株式会社 ロンウイット 大須賀 稔さん スライド:Solr AutoComplete and Did You Mean?\nデモ:https://github.com/mosuka/solr-suggester-demo-ui\n職歴が相変わらずおもしろい 編集距離のお話 素晴らしいCM! 候補のランキングを変更できる? SpellcheckComponentのパラメータで指定できるものなら楽ですが。。。\n4. 「Lucene Revolution 2013 Dublin振り返り」 楽天株式会社 平賀 一昭さん スライド:公開待ち\nダブリンどこ?(間違ってベルリンって言っちゃいましたw) スタジアムで開催。グランドにも入れるのかなぁ? まずはTwitter Luceneの改良版 ちょっと特殊。140文字とか 青いRさんのライバル。Careerbuilder 元FASTユーザ 企業向けに検索キーワードとかの解析画面を用意 検索精度の改良の話とか 転職で引っ越す意思があるかとか。 最後はLinkedIn Luceneのユーザ まとめ ということで、スピーカーの方々のスライドにもありましたが、 改訂新版Apache Solr入門は良い本なので、購入していただけると嬉しいです。\n感想、コメントなど、いつでもお待ちしています!\n","date":1390988760,"dir":"post/2014/","id":"c6107ff57e96a1373c019d252c00ad84","lang":"ja","lastmod":1390988760,"permalink":"https://blog.johtani.info/blog/2014/01/29/hold-to-japan-solr-meetup/","publishdate":"2014-01-29T18:46:00+09:00","summary":"改訂新版Solr入門出版記念ということで、第13回Solr勉強会 #SolrJP 新Solr本出版記念を開催しました。 出版記念なので、技術評論社様より、プレ","tags":["Solr","勉強会"],"title":"第13回Solr勉強会を開催しました"},{"contents":"昨晩、Elasticsearchから初のプロダクトとなるMarvelがリリースされました。ということで、さっそく触ってみて、簡単な紹介と感想を書いてみました。\nMarvelって? Elasticsearch社が初のプロダクトとしてリリースした、Elasticsearchクラスタモニタリングツールです。 次のような特徴があります。\nplugin形式で提供 GUIがKibana メトリックスはElasticsearchに保存 SenseがChrome以外でも使える プロダクション環境で利用する場合は有料ですが、開発用途では無料で利用できます。 現時点(2014/01/29)では、0.90.9以上のバージョン(1.0.0.RC1含む)で利用が可能です。\nなにができるの? Elasticsearchクラスタに関するメトリックスを保存、可視化できるプロダクトです。 ドキュメント数やJVMの状況、クラスタの状態など、いろいろなメトリックスが保存されます。\n保存先は、別のElasticsearchクラスタにすることも可能です。 お試しでインストールして見る場合は、同一クラスタにサービスに利用するインデックスとMarvel用のメトリックス保存先インデックスを入れても良いです。\nただ、プロダクション環境では、Marvel用インデックスはあくまでもモニタリングに使用するため、サービスのクラスタへの影響を最小にしたくなります。\nこのような場合、Marvelのプラグインの設定を変更することで、メトリックス送信用のエージェントとして動作させることができます。\n詳しくは、Marvelのドキュメントにあるinstalling a secondary monitoring clusterを御覧ください。\n1/29 16時時点で、上記ドキュメントのエージェントの送信先の設定に関する部分に誤記がありました。 おそらく、configuration optionsの記述が正だと思います。 もう、なおってました。(1/30朝時点)\nキャプチャいろいろ 日本語WikipediaのデータをRiverで登録しながら各画面の動作などを見てみました。\nMarvel Overview 日本語WikipediaをRiverで登録してる途中。Loadが高くなってることなどがわかります。\nOverview (クラスタの状態が変化) クラスタの状態が変化したところに、タグが付くみたいです。 ここでは、ノードの一つを停止、起動しました。\nインデックス終了後に、クラスタを再起動してしまい、クラスタ内のシャードの再配置が実行されてしまったため、クラスタの状態がYellowになってしまうとこんな感じ。ちょっとわかりにくいです。\nSense Chromeプラグインとしてリリースされていたクエリ実行コンソールがMarvelのサイトプラグインとして提供されています。これがあるだけで、Elasticsearchへのクエリの実行が格段に効率良くなります。\nIndex Statistics インデックスに関する情報のグラフが見れるページです。ドキュメント数の他に、容量やリクエスト数なども見れます。\nインデックス終了後のグラフはこんな感じ。\nインデックス終了後のOverviewはこんなかんじです。\nCluster Pulse クラスタで発生したイベントとイベントの詳細を見ることができるページです。各種インデックスがYELLOWからGREENに変わっていっているのがmessageで分かります。\nすべて再配置が終わったらGREENになりました。\nNode Statistics 各ノードに関する情報を見ることができる画面です。 ノードごとにグラフの色を分けることもできます。\nその他 Marvelプラグインにブラウザから接続できなくなるとこんなメッセージが出ました。\n参考までに、elasticsearch-headの画面も。こちらのほうが、シャードの再配置中であるのがひと目で分かります。\n感想 綺麗です。まぁ、Kibanaが綺麗ですから。 クラスタ内で発生したイベントが時系列で保存されるため、あとからどんなことが発生したのかといった原因の追求などには非常に役に立ちそうです。\nただ、インデックスの状態や状況(クラスタ再起動やノード追加時にshard再配置などが実行されている状況とか)はelasticsearch-headのほうがわかりやすかったです。 インデックス単位でのStatusがMarvelの画面ではわからないため、shard再配置が完了したかどうかなどのタイミングがわかりにくかったです。\nある程度、多くのノードを利用したクラスタを利用する場合に、モニタリングツールとして利用するのは便利なのではないでしょうか? 時系列でログやイベントが保存されるので、ノードが追加されたり外れたりといった状況があとからでも追跡可能なのが便利です。\n疑問点 インデックスの情報などは、5s毎にMarvelのインデックスに保存されているようです。ただ、GUI上では5分毎のデータしか表示されません。 どうやって変更するんだろう?\nまた、Marvelのクラスタへの接続が切れた時のデータはどうなるのか?という部分も気になります。Marvelのクラスタを更新している時や、ネットワークが遮断されてしまった場合のデータがどうなるのかという点です。\n疑問点への回答(2014/01/30追記) 疑問点に対して中の人から回答を頂いたので、追記です。\nQ:GUI上で5分毎のデータしか表示されないんですが? A:ブラウザの負荷を高くしないようにするために、1つのグラフに20のプロットしてるだけです。ズームしたりすると、もっと細かなデータが見れますよ。 Q:Marvelのクラスタへの接続が切れた時のデータはどうなるんだろう? A:接続が切れた場合は、ローカルに保存されるけどデータは無視されます。接続が戻ると、戻った後のデータは記録されていきます。将来的には改善するかも。 ちなみに、昨日試してた環境が、足元Linux環境(監視対象のクラスタ)+手元Mac環境(Marvelモニタリングデータ格納クラスタ)という環境でした。 確かに、出社してから、手元Mac環境を起動すると、データが流れてくるようになりました。 ただ、監視対象のクラスタでは、socket timeoutのログがずっと出てましたが。\n参考文献 リリースブログ プロダクトページ ドキュメント ","date":1390983240,"dir":"post/2014/","id":"f6debed350f20a2b3aa4d970e3227411","lang":"ja","lastmod":1390983240,"permalink":"https://blog.johtani.info/blog/2014/01/29/simple-introduction-and-first-impression-es-marvel/","publishdate":"2014-01-29T17:14:00+09:00","summary":"昨晩、Elasticsearchから初のプロダクトとなるMarvelがリリースされました。ということで、さっそく触ってみて、簡単な紹介と感想","tags":["elasticsearch","marvel"],"title":"Elasticsearch Marvelの紹介と第一印象"},{"contents":"Lucene/Solr 4.6.1がリリースされそう(バイナリ配布待ち)lucene-gosenの4.6.1対応版をリリースしました。\nライブラリのインタフェースなどは特に変更はないのですが、ライブラリのダウンロード先が変更になっているため、注意喚起です。\nGoogle Project Hostingの仕様変更により、Downloadsに新規ファイルがアップロードできなくなっています。(2014年から)\nこのため、プロジェクトの選択肢としては以下の3点となっています。\nGoogle Driveにファイルをアップロードしてダウンロードしてもらう 他のソースコード管理サイトなどを利用する。 他のダウンロードサイトを利用する 1.と3.は場所が違うだけで、方法は一緒です。 今回は、暫定的に1.を利用してダウンロードするように対応しました。\nダウンロード先はプロジェクトのページにリンクが有りますが、わかりにくいのでキャプチャを撮ってみました。\nダウンロード先 これまでのFeatured - Downloadsとは異なり、Links - External linksの下に Downloads lucene-gosen 4.6.1というリンクを用意してあります。\nフォルダとなっており、各種jarファイルがリストされていますので、こちらからダウンロードをお願いします。 今後は、この下にダウンロードリンクを追加していく予定です。\nただし、2.で述べたように「別のソースコード管理サイト」も検討中です。\n","date":1390880040,"dir":"post/2014/","id":"c4e7199a586a308352b7a881add7e356","lang":"ja","lastmod":1390880040,"permalink":"https://blog.johtani.info/blog/2014/01/28/release-lucene-gosen-4-dot-6-1/","publishdate":"2014-01-28T12:34:00+09:00","summary":"Lucene/Solr 4.6.1がリリースされそう(バイナリ配布待ち)lucene-gosenの4.6.1対応版をリリースしました。 ライブラリのインタフェースな","tags":["Solr","Lucene","lucene-gosen"],"title":"lucene-gosen 4.6.1のリリースに関する注意点"},{"contents":"Elasticsearchのcuratorのブログ記事を読んで、日本語でツイートしたところ、Aaron Mildensteinさんから日本語(ローマ字)で返信を頂きました。 せっかくなので、ブログ記事を翻訳してもいいかを尋ねたところ、快くOKを頂いたので、翻訳してみました。参考になればと。(誤訳など見つけたらコメントください。)\n@johtani Kore no hou ga ii. Nihongo de no Curator RT, arigatou gozaimasu! #elasticsearch #curator #logstash\n\u0026mdash; Aaron Mildenstein (@theuntergeek) 2014, 1月 22 curator: 時系列インデックスの管理 原文:curator: tending your time-series indices\n背景 数年前、Elasticsearch、Logstash、Kibana(ELK)を管理し、ここ30日よりも古いインデックスを自動的に削除する方法を必要としていました。 APIドキュメントを読み、#logstashや#elasticsearchのIRCチャネルのコミュニティの助けを借りて、簡単なスクリプトとcronを用意するのが簡単であることを知りました。\ncurl -XDELETE \u0026#39;localhost:9200/logstash-2014.01.01?pretty\u0026#39; もちろん、これも動作しますが、日付を生成するのがめんどくさいのでもっとエレガントな方法が欲しかったです。\n最初に pythonでスクリプトを書き始めました。特定の日数のインデックスを管理するだけのコマンドラインクリーナーを書いてコミュニティにシェアしました。他の人が、新しい機能を追加してくれました。私は、古いインデックスをoptimizeすることができる他のスクリプトも書きました。これは、シャードごとにnセグメント以上存在しないように各シャードのセグメントをマージすることです。これらのスクリプトで1つになるようにマージしたりエンハンスし、古いインデックスを管理する助けになるツールです。\ncuratorの紹介 Curatorで可能なインデックスオペレーション\n削除(日付もしくは、トータル容量による制限) インデックスのクローズ(Close) bloom filter cacheの無効化 Optimize(LuceneのforceMerge) curatorのインストール この記事を書いている時点で、Curator は0.5.1がリリースされ、0.90.10に対応しています。Curatorはまた、Elasticsearchの1.0(現在はRC1)へも対応しています。各リリースへの互換性の保証のためのテストも行っています。\n現時点では、gitリポジトリで配布しています。近い将来、pipによるインストール可能なパッケージにする予定です。利用することを恐れないでください。もし、pythonとpipがあなたのマシンにインストールされていれば、次のようにインストールは簡単です。\ngit clone https://github.com/elasticsearch/curator.git pip install -r requirements.txt インストール後の確認は次のコマンドです。\n$ ./curator.py -v curator.py 0.5.1 利用方法とサンプル サンプルを示す前に、オプションを見ておくとよいでしょう。このリストは長いですが(この記事の最後に含まれています)、どのようなことがコントロールできるかを説明しています。デフォルトがどうなっているかに注意してください。もし、デフォルト値で良い場合は、フラグを指定する必要はありません。\nでは、簡単なサンプルを見ながら、CuratorがELKスタックをどうやって管理するかを見て行きましょう。\n削除(delete) 90日以上のインデックスを保存したくないとしましょう。コマンドは次のようになります。\n$ curator.py --host my-elasticsearch -d 90 -dで日数を指定しているだけです。簡単でしょ?\n容量による削除(delete by space) これは、指定したギガバイト数を超えたインデックスを場合に(最も古いものから)削除を行う特殊なケースです。\n$ curator.py --host my-elasticsearch -C space -g 10024 -Cでspaceによるcurationであること、-gでギガバイト数(10024、10TB)であることを指定しているのがわかります。-gは1.5や0.5という数値を指定できます。\nその他のCuratorオプションはspaceによる削除と組み合わせて使用できないことに注意してください。\nクローズ(close) Open/Close Index APIにより、インデックスをクローズすることができます。\nopen/close index APIを利用すると、インデックスをクローズしたり、あとでオープンしたりすることができます。クローズされたインデックスはクラスタのオーバヘッドにほとんどならず(メタデータの管理を除く)、読み書き操作の妨げにもなりません。クローズされたインデックスは、リカバリプロセス時に、オープンされます。\nインデックスをクローズすることは、存在はするが検索できないという意味です。何が便利なのでしょう?\n90日のインデックスを保存する義務があるが、検索は過去30日のインデックスを対象にする以外は稀であるような場合を想像してください。このような状況で、価値のあるリソース(ヒープスペースなど)を節約するためにインデックスをクローズすることができます。これは、クラスタに検索やインデキシングのためのメモリを与えることができることを意味します。そして、もし、クローズしたインデックスのデータが必要になったら、APIを呼び出してインデックスをオープンすれば検索できます。\nこのような場合、今オープンしているインデックスが再び、クローズされないように、一時的にCuratorのスケジュール実行をオフにしておくのが懸命です。\n$ curator.py --host my-elasticsearch -c 30 -d 90 先ほど説明した例の実行方法です。これは、30日よりも古いインデックスはクローズし、90日より古いインデックスを削除します。本当に簡単でしょ?\nbloom filterの無効化 これは、0.90.9以降のバージョンで利用可能な機能です。(リンク先はIssue #4525)\n心配しないでください。このスクリプトは操作を行う前に、elasticsearchが利用可能なバージョンであるかをチェックします。\nbloom filterとは何でしょう?なぜ、無効化したくなるのでしょう?\nbloom filterはインデキシング操作を高速化するためにリソースを割り当てられます。時系列データで、インデキシングしている間もこれは有用です。インデックスは2日後には、日付が変わると新しいデータはおそらくインデックスされません。そのインデックスにはもはや必要のないリソースをbloom filterはまだ持っています。Curatorはこれらのリソースを開放することができます!\n$ curator.py --host my-elasticsearch -b 2 -c 30 -d 90 これで、bloom filterのリソースは少なくとも2日(1にもできます)よりも古いインデックスについては利用せず、30日より古いインデックスはクローズし、90より古いインデックスは削除します。\noptimizeというよりもforcemerge コマンドの説明をする前に、Elasticsearch APIのoptimizeを見ることは、生きているインデックスや\u0026quot;cold\u0026quot;インデックス(インデキシングがアクティブではないという意味)に実行する必要があるということを理解するために重要です。実際、optimizeはLuceneではforceMergeと名前が変えられ、インデックスを改善するためにoptimizeを呼び出す必要はなくなりました。Elasticsearchのセグメントをマージすることは利点がありますが、coldインデックス全てに対してoptimizeを開始する前に、コストを理解する必要があります。\nforceMerge操作はインデックスにある各シャードのセグメントの数を少なくします。各セグメントはオーバヘッドがあるため、セグメントが多いということは、より多くのリソースを使うという意味です。良さそうですね?リソースが少ない?\nそれは、可能ですが、merge操作を実行するには多くのディスクやネットワークI/Oが必要で、ディスクやクラスタの通常の書き込み操作に悪影響を及ぼします。もし、これが必要なら私のアドバイスを良く考えてください。(数%ほど)検索を速くし、リソースの使用量も減らすことができます。また、管理しているセグメント数が小さくなるということは、クラスタのリカバリを速くすることにもなります。1つのインデックスをoptimizeするためにはおそらく1時間以上の時間がかかります。「使用する前に目立たない場所で試してください」というクリーニングボトル(訳注:洗剤とか漂白剤かな?)の注意書きと同様に、ディスクI/Oが低い時にテストし、もし操作とリソースがあなたのクラスタのユースケースにあっているかを見てください。デフォルトでは、シャードごとに2つのセグメントにマージしますが、--max_num_segmentsフラグで変更可能です。\nここまでのサンプルは次のようなコマンドになります。\n$ curator.py --host my-elasticsearch -b 2 -o 2 -c 30 -d 90 これで、bloom filterは2日より古いインデックスでは向こうにし、2日より古いインデックスは\u0026quot;optimize\u0026quot;し、30日より古いインデックスはクローズし、90日より古いインデックスは削除されます。\n操作の順序 スクリプトは操作が衝突するのを防ぐために次の順序で実行されます。なぜ、クローズされたインデックスはoptimizeしないのでしょう?なぜ、削除予定のインデックスはクローズされないのでしょう?\nDelete (by space or time) Close Disable bloom filters Optimize 使用の検討 最後の例で、3つの操作を1つのコマンドで実行していますが、それらが連続ですべて実行されるのを望んでいないかもしれません。\n$ curator.py --host my-elasticsearch -b 2 -o 2 -c 30 -d 90 これは、次の操作と同様です。\n$ curator.py --host my-elasticsearch -d 90 $ curator.py --host my-elasticsearch -c 30 $ curator.py --host my-elasticsearch -b 2 $ curator.py --host my-elasticsearch -o 2 これらのコマンドを異なる時間に実行したり、異なるその他のオプション(特に、optimize実行で--timeout 3600を追加したり)を指定して実行するのは簡単です。\nまた、デフォルトのlogstash-とは異なるプレフィックスのインデックスを持っているかもしれません。\n$ curator.py --host my-elasticsearch --prefix logstash- -d 30 $ curator.py --host my-elasticsearch --prefix othername- -d 30 最後に Curatorは時系列インデックスの保存ポリシーを管理するのに役立ちます。豊富な設定オプションがインデックスを管理することを簡単にします。クラスタに存在するノードの数に関係なく。https://github.com/elasticsearch/curatorへのフィードバックやコントリビューションをお待ちしています!\n参考(全引数とオプション) $ curator.py -h usage: curator.py [-h] [-v] [--host HOST] [--port PORT] [-t TIMEOUT] [-p PREFIX] [-s SEPARATOR] [-C CURATION_STYLE] [-T TIME_UNIT] [-d DELETE_OLDER] [-c CLOSE_OLDER] [-b BLOOM_OLDER] [-g DISK_SPACE] [--max_num_segments MAX_NUM_SEGMENTS] [-o OPTIMIZE] [-n] [-D] [-l LOG_FILE] Curator for Elasticsearch indices. Can delete (by space or time), close, disable bloom filters and optimize (forceMerge) your indices. optional arguments: -h, --help show this help message and exit -v, --version show program version number and exit --host HOST Elasticsearch host. Default: localhost --port PORT Elasticsearch port. Default: 9200 -t TIMEOUT, --timeout TIMEOUT Elasticsearch timeout. Default: 30 -p PREFIX, --prefix PREFIX Prefix for the indices. Indices that do not have this prefix are skipped. Default: logstash- -s SEPARATOR, --separator SEPARATOR Time unit separator. Default: . -C CURATION_STYLE, --curation-style CURATION_STYLE Curate indices by [time, space] Default: time -T TIME_UNIT, --time-unit TIME_UNIT Unit of time to reckon by: [days, hours] Default: days -d DELETE_OLDER, --delete DELETE_OLDER Delete indices older than n TIME_UNITs. -c CLOSE_OLDER, --close CLOSE_OLDER Close indices older than n TIME_UNITs. -b BLOOM_OLDER, --bloom BLOOM_OLDER Disable bloom filter for indices older than n TIME_UNITs. -g DISK_SPACE, --disk-space DISK_SPACE Delete indices beyond n GIGABYTES. --max_num_segments MAX_NUM_SEGMENTS Maximum number of segments, post-optimize. Default: 2 -o OPTIMIZE, --optimize OPTIMIZE Optimize (Lucene forceMerge) indices older than n TIME_UNITs. Must increase timeout to stay connected throughout optimize operation, recommend no less than 3600. -n, --dry-run If true, does not perform any changes to the Elasticsearch indices. -D, --debug Debug mode -l LOG_FILE, --logfile LOG_FILE log file ","date":1390542480,"dir":"post/2014/","id":"15f501351d482ffd73985a50f5c89d1f","lang":"ja","lastmod":1390542480,"permalink":"https://blog.johtani.info/blog/2014/01/24/curator-tending-your-time-series-indices-in-japanese/","publishdate":"2014-01-24T14:48:00+09:00","summary":"Elasticsearchのcuratorのブログ記事を読んで、日本語でツイートしたところ、Aaron Mildensteinさんから日本語(","tags":["elasticsearch","curator"],"title":"Curator: 時系列インデックスの管理(日本語訳)"},{"contents":"あけましておめでとうございます。今年もSolrやElasticsearchについて色々と頑張っていく所存です。 とまぁ、お決まりの挨拶はおいておいてと。(もう、新年も22日ですが。。。)\nElasticsearchの1.0.0RC1がリリースされました。 ということで、私が作っているExtended-Analyzeプラグインも1.0.0RC1向けに修正してリリースしました。\n1.0.0RC1向けに修正したこと コミットログを見てもらえば、いいのですが、ロジック自体は変更しなくても良かったです。\nただ、正式に、Elasticsearchのつづりが決定したようで、クラス名が「ElasticSearchほげほげ」から、「Elasticsearchほげほげ」と、SearchのSが小文字になりっています。 この影響で、例外クラスなどの名称を幾つか変更しました。 また、バージョン番号を1.0.0RC1とし、0.x系をElasticsearchの0.90系向けのバージョンにしていく予定です。\n今後は、UIを追加したいと思っているので、Elasticsearchのバージョン番号とはずれてくるとは思いますが。。。\nElasticsearch 1.0.0RC1を利用してみて 1点だけですが。 これまでは、-fオプションを指定すると、デーモンではない動作で起動できていました。(デフォルトがデーモン起動)\nこれが、1.0.0から(0.90の最新もかな?詳しく見ていない)デフォルトの挙動が変更され、デーモン起動ではなくなりました。 代わりに、-dオプションを指定することで、デーモン起動ができるようになりました。\nこれで、手元でうっかりデーモン起動することがなくなって、ひと安心です。(他の人は困るかもしれないけど)\nということで 1.0.0RC1が出たので、少しずつ1.0系で追加されたAPIや機能について、ブログで紹介していけたらと思います。\nこんなこと調べてよ?、これわかんないんだけど?などありましたら、コメントいただければと。 気が向いたら記事を書くので。\nあと、Extended-Analyzeプラグインの感想などもお待ちしています!\n今年もよろしくお願いします!\n","date":1390317360,"dir":"post/2014/","id":"6425af51edead39c0e439073986043fb","lang":"ja","lastmod":1390317360,"permalink":"https://blog.johtani.info/blog/2014/01/22/release-extended-plugin-for-1-0-0rc1/","publishdate":"2014-01-22T00:16:00+09:00","summary":"あけましておめでとうございます。今年もSolrやElasticsearchについて色々と頑張っていく所存です。 とまぁ、お決まりの挨拶はおいて","tags":["elasticsearch"],"title":"Extended-Analyze 1.0.0RC1をリリースしました"},{"contents":"昨年は、大晦日に書いてました。 ちょっと進歩したかも。\n振り返り(2012年に書いた抱負から) ということで、まずは昨年書いた抱負からの振り返りです。\nIntelliJ IDEAをメインに使う JIRAを継続して活用 ブログの継続 elasticsearch Luceneのソースコードリーディング 何かOSSのソースを読む Macでもっと開発 読書と英語を継続 お。思ったよりもできてるかも。 IntelliJ IDEAについては、メインになりました。Eclipseを開くことはまずないです。 Macがメインの開発マシンにもなってきてるので。(開発してないんじゃないかという話も。。。)\nJIRAは一応、継続しているという感じです。\n唯一Luceneのソースコードリーディングができてないですね。。。 言い訳をすると、明示的にソースコードリーディングをしているわけではないですが、Luceneのソース自体は時々見ています。 SolrやElasticsearchを調べるとそのままLuceneにたどり着くことがあるので。\nポモドーロのタスク管理用に使っていますが、時々忘れていたり。あと、振り返りがまだちゃんとできてないので、そこをやらないとかなぁと。 読書と英語は今後も継続です。もっと習慣づけないと。\n振り返り(今年あった出来事など) CROSSでモデレータやりました Xperia Zに機種変 メニエール病 リクルートテクノロジーズさんのお手伝い Lucene In Action輪読やってる MIR輪読も継続 Solr勉強会を不定期開催 Elasticsearch勉強会を始めた Solr本の改訂版を執筆 AWSちょっと触った Elasticsearchプラグイン作ってみた Githubの活用 Octopressでブログ こんなかんじです。\nCROSSでは、モデレータをやらせていただきました。すこしは検索を面白いと思ってもらえたかなと思います。 来年のCROSS 2014ではスタッフとして盛り上げていく予定ですので、スタッフに興味ある方は声をかけてください! 面白い話がいっぱい聞けますし、おいしい物も飲み食いできるかも!?\nXperia Zは良い買い物でした。ただ、すでに2回電源部分が故障してますが。。。 それ以外は非常に快適です。\n2月末から3月は少し休んでました。難聴→めまい→メニエール病という流れで、ちょっとしんどかったです。 ほぼ回復しましたが、原因は不明みたいなので、長く付き合ってくのかなぁと。\n4月からリクルートテクノロジーズさんの仕事を手伝っています(Solr本の著者紹介にも書いてます)。 色々と面白いことをしているATLという部署で面白い人達と仕事させて頂いてます。 来年もよろしくお願いします!(もっと価値を出さないとなぁ。。。)\nその一環で、Lucene In Actionの輪読を社内でやっていたりも。バージョンが3.x系で書かれているので、 ちょっと大変ですが、4だとどう違うかなどの話を交えつつ少しずつ読んでいます。\n輪読会といえば、MIR(Modern Information Retirieval)の輪読も続いています。 私は深いところまでわからないのですが、色々と詳しい方たちとボチボチ読んでます。教えてもらってばかりですが、来年も頑張りますよと。\nSolr勉強会も、引き継いでぼちぼちやっています。来年は1/29に開催します。Solrの入門的な話をしてもらうので、 ぜひ、触ったことがない方や興味がある人に参加していただきたいと。\nElasticsearch勉強会も主催し始めました。興味ある人がいるだろうとは思ったのですが、想像以上でびっくりしてます。 自分が理解を深め、発表するためにも、2ヶ月程度のスパンで来年も開催する予定です。 スピーカーに興味のある方は、elasticsearch-jpのMLや私にコンタクトしてください。\nSolr入門のSolr4対応版も執筆しました。今回は全体のコーディネートもやらせていただきました。 Solr活用のお役に立てていただければと。まだ購入してない方はぜひ、以下のリンクから!(PDF版もあります。) 質問などあれば、ブログにコメントをいただくか、ツイートしていただくか、技術評論社のサポートページに問い合わせていただければと思います。\nAWSをちょっとだけ触りました。 S3にバックアップ取ってるだけですが。。。来年はもう少し。。。 JIRA(さくらVPSに立ててる)のバックアップなどをやってます。\nあとは、Elasticsearchの勉強会も始めたこともあり、Elasticsearchを色々と触っています。 elasticsearch-analysis-kuromojiプラグインのREADMEを記述してコントリビュートしてみたり、 elasticsearch-extended-analysisプラグインを作ってみたり。\n勉強会のスピーカー探しも兼ねて、いろんなところに、「突撃!隣のElasticsearch」と称してElasticsearchの話を聞きに行きたいと思っていますので、使ってるよ!とか使いたいんだけど、どうすればいい?みたいな話があれば、声をかけてください。Twitterでツイート見たら勝手に、アタックすることもあるかもですが、その時はよろしくお願いします。\n来年はSolrやElaticsearchにもっと貢献できればと。\nGithub(git)もようやくまともに触り始めました。 某データの管理やプラグインの開発などでやっと触り始めました。 まだ、チーム開発ってほどではないので、チームで開発するときのやり方なども少しずつ勉強していこうかと。 プルリクとかも少しずつやってみたりしてます。\nあとは、Octopressでブログ始めました。その前はjugemだったのですが、なんとなく。 Markdownに慣れるためというのもありOctopressにしてみました。 (Solr本の原稿もMarkdownで書いてました) 昔のブログもこっちにコピーするプログラムも書いてみようかな。\n来年の抱負 Elasticsearch勉強会、Solr勉強会の継続+ミックスした検索勉強会の開催 IDEAのさらなる活用 もっと開発(プラグインとか) AWSをもう少し活用 海外のイベントに行ってみたい 読書と英語を継続 勉強会の開催は今後も継続していく予定です。会場を毎回提供して頂いているVOYAGE GROUPさん、リクルートテクノロジーズさんには、 今後もお手数をお掛けしますが、よろしくお願い致します。勉強会の開催を通じて、色々な人のノウハウがうまく共有できて、 もっと本質的な作業(サービスの改善とか)に注力できる環境ができると面白いなぁと思ってるので。\nあと、Elasticsearch、Solrと別々の勉強会になっていますが、検索エンジン勉強会という形でそれぞれのメリット・デメリットを 共有できる勉強会も面白いかもと思っているので、春とかに開催したいなぁと考えてもいます。(まだ考えているだけで何もネタがないですが)\nIDEAは、年貢(13のサブスクリプション)を収めたので、もっと活用しないとという意味で。プラグインの開発、gitやsvnのクライアントとしては 活躍していますが、もっと開発に活用していかないとなぁと。まだ、10%くらいしか活用できてない気がするので。\nもっと開発しないとなと。毎年言ってますが。今年は書籍に注力したのもあり、ソースを読んだり英語を読んだりが多くなってました。 偉そうにしてるためか、開発する機会が減ってきているので、細かなことでもいいので、すこしずつコードを書いていこうかと。 (もっと自分で問題点を見出してそれを補完するようなコードなりプラグインなり書けばいいんだろうな。)\n開発と合わせて、AWSをもう少し触りたいなと。これも数年言っていますができてないです。。。 ネタ探すのが下手なのかなぁ。\n海外イベントにも行ってみたいです。まだ、海外行ったことないんですが。。。 Lucene Revolutionとか。その訓練も兼ねて英語でメール書いたり、プラグインのREADME書いたりしてみてます。\n最後は、毎年恒例ですが、読書と英語です。 Packtのキャンペーンで買ってしまった英語の本とか貯まっているので、読まないと。 nasneが便利で通勤時間にドラマ見てるからなぁ。ま、必要なときにボチボチと読んでいく予定です。\n最後は、いつものようにですが、来年も勉強会やいろんなイベントに参加する予定です。 ブログも週1程度で書く努力しないとなぁ。 こんな話を書いてくださいとかのリクエストもお待ちしています。\n今年もまだ、大晦日が残っていますが、色々とお世話になりました。 この場を借りてお礼申し上げます。\n来年も、いろんな方に絡んでいくとは思いますが、よろしくお願いいたします。\n","date":1388406000,"dir":"post/2013/","id":"10c715f70de25ccb493bbbb532b78ced","lang":"ja","lastmod":1388406000,"permalink":"https://blog.johtani.info/blog/2013/12/30/looking-back-2013/","publishdate":"2013-12-30T21:20:00+09:00","summary":"昨年は、大晦日に書いてました。 ちょっと進歩したかも。 振り返り(2012年に書いた抱負から) ということで、まずは昨年書いた抱負からの振り返りで","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2013)"},{"contents":"昨夜、Elasticsearchの0.90.8がリリースされました。\nリリースされた内容などについては、本家のブログ「0.90.8 released」をご覧いただくこととして。 1点注意したほうが良い点があります。\nelasticsearch-analysis-kuromojiを利用している場合は、0.90.8に対応したバージョンがリリースされるのを待つ必要があります。\nelasticsearch 0.90.8はLuceneのバージョンが4.6.0に変更されています。 Lucene 4.6.0では、TokenStreamというTokenizerのI/Fに変更があり、Tokenizerの実装を変更する必要があります。\n現時点(2013年12月19日現在)のelasticsearch-analysis-kuromojiの1.6.0にはlucene-analyzers-kuromoji-4.5.1.jarが含まれており、この部分でI/Fが異なるためエラーが発生してしまいます。 プラグインをインストールする時点ではエラーは発生せず、実際にKuromojiのTokenizerやAnalyzerを利用するタイミングでエラーが出ます。 以下、0.90.8にanalysis-kuromojiの1.6.0をインストールした状態で_analyzeを実行した時のエラー。\ncurl -XPOST \u0026#39;localhost:9200/_analyze?tokenizer=kuromoji_tokenizer\u0026amp;filters=kuromoji_baseform\u0026amp;pretty\u0026#39; -d \u0026#39;寿司が美味しかった\u0026#39; { \u0026#34;error\u0026#34; : \u0026#34;IllegalStateException[TokenStream contract violation: reset()/close() call missing, reset() called multiple times, or subclass does not call super.reset(). Please see Javadocs of TokenStream class for more information about the correct consuming workflow.]\u0026#34;, \u0026#34;status\u0026#34; : 500 } ということで、1.7.0がリリースされるのを待つか、自分でmvn packageしてビルドする必要があります。 他にも独自でTokenizerなどを造られている方は注意が必要かと。\nたぶん、すぐにリリースされるんじゃないかなぁと。\n2013/12/20追記\nとりあえず、masterブランチが0.90.8に変更されたみたいです。(と書いてるそばから、1.7.0がリリースされました) ということで、0.90.8では1.7.0を使うとエラーが出ないです。 (あと、踊り字対応のcharfilterも追加されたみたいです)\n","date":1387524240,"dir":"post/2013/","id":"c18b12fff24dc87e7f1039bd17c0c6aa","lang":"ja","lastmod":1387524240,"permalink":"https://blog.johtani.info/blog/2013/12/20/release-elasticsearch-0-90-8/","publishdate":"2013-12-20T16:24:00+09:00","summary":"昨夜、Elasticsearchの0.90.8がリリースされました。 リリースされた内容などについては、本家のブログ「0.90.8 releas","tags":["elasticsearch","kuromoji"],"title":"Elasticsearch 0.90.8がリリースされました&注意点(2013/12/20追記)"},{"contents":"Solr本が出てから、質問を受けてブログ書くと言いながら書いてなかったことを思い出しました。。。\nプラグインの配置方法についてこんな質問を受けてたので、それっぽいエントリを書いておきます。(想像と違ってたらツッコミ入れてください)\n@johtani 追加でプラグインの配置方法とかあると便利かなと思いました\n\u0026mdash; Tsubosaka (@tsubosaka) 2013, 12月 2 改定前のSolr本では、日本語の形態素解析器をjarファイルとして追加する方法が書かれていました。 ただ、改定後のSolr本では、KuromojiがLuceneで実装されているためサンプルとしてjarファイルを追加するような方法の記載が明確にはありません。\n19ページのcollection1の説明ですこしだけ、libディレクトリについて触れています。\n独自のTokenizer(lucene-gosenなど)はjar形式でSolrに追加し、schema.xmlなどに利用するFactoryを指定してから利用します。\nこのとき、追加のjarファイルを配置する先がlibディレクトリです。\nlibディレクトリは2つの種類のスコープのディレクトリが存在します。\nSolr全体で利用可能なlibディレクトリ コア単位で利用可能なlibディレクトリ Solr全体で利用するlibディレクトリ これは、起動しているSolrにある全てのコアで利用するようなjarファイルを配置するディレクトリになります。 場所は$SOLR_HOME/libです。ここにjarファイルを配置することで、この$SOLR_HOMEを利用するすべてのコアで同じjarファイルを利用することができるようになります。\nですので、例えば、lucene-gosenはすべてのコアで利用するという場合にはここに配置すれば、1つのjarファイルを配置するだけで済むことになります。\nコア単位で利用するlibディレクトリ これは、コアごとにlibディレクトリを用意する場合です。 19ページにも記載されていますが、$SOLR_HOME/コアディレクトリ名/libとなります。\n特定のコアのみで利用するライブラリについてはこちらに配置する形になります。 他のコアで利用してほしくないjarファイルなどを配置するのに利用すればよいかと。\n簡単ですが、補足記事でした。 UIMAやlangidの利用方法などもあるとうれしですかね? そのうち気が向けば書くかもしれません。(他の人に書いてもらうのもありかも。)\n","date":1387447740,"dir":"post/2013/","id":"cb5b6f7ab4d36e90d2619cb907ebb956","lang":"ja","lastmod":1387447740,"permalink":"https://blog.johtani.info/blog/2013/12/19/add-jar-file-to-solr/","publishdate":"2013-12-19T19:09:00+09:00","summary":"Solr本が出てから、質問を受けてブログ書くと言いながら書いてなかったことを思い出しました。。。 プラグインの配置方法についてこんな質問を受け","tags":["Solr"],"title":"Solrへのプラグインの配置方法について"},{"contents":"ども。 プラグインのインストールに長いURL入れるの辛いですよね?ね?\nということで、MavenでリリースしてMaven Repositoryからダウンロードできるようにしてみました。\n流れとしては\nSonatypeにリリースできるように申請する Sonatypeにリリースする SonatypeからMavenにSyncしてもらう という流れです。\nSonatypeにリリースするための方法はイケメンの人(@yusuke)がブログに簡単ですが残してくれてました。 あと、こちらの@vvakameさんのブログも参考にしながら作業しました。\n【最新版】Maven Central Repository へのライブラリ登録方法 #maven JsonPullParser が Maven Central Repository に入るようです pom.xmlについては、プラグインのpom.xmlを参考にしてもらえればと。 1.の作業が終わったら、リリースを実行します。\nこの時、\u0026lt;scm\u0026gt;タグにgithubの情報が記載されているため(?)、githubにタグを打つ作業もmavenコマンドがやってくれるみたいです。\nmvn release:prepare を実行すると、リリースするバージョンやタグ名などを聞いてくれます。 それらに答えると、pom.xmlにバージョンを指定してcommit\u0026amp;pushしてくれ、タグも打ってくれます。(なんて便利)\nその後、release:performにてSonatypeへのリリースが完了します。 あとは、Sonatypeの画面で作業したら、Mavenのリポジトリにそのうち同期してくれます。\nということで、次のコマンドを実行すればプラグインがインストールできるようになりました。0.6.0と0.7.0の違いは実装には差異はありません。リリース方法が変更されただけということになります。\nbin/plugin -i info.johtani/elasticsearch-extended-analyze/0.7.0 これで少しは活用してもらえるようになるかなぁ? (どのくらいの人が使ってくれてるのかは不明。。。)\n","date":1387249860,"dir":"post/2013/","id":"a0a00c23556fcc5dbfb7b7f43fbbb61d","lang":"ja","lastmod":1387249860,"permalink":"https://blog.johtani.info/blog/2013/12/17/release-es-extended-analyze-plugin-to-maven-and-sonatype/","publishdate":"2013-12-17T12:11:00+09:00","summary":"ども。 プラグインのインストールに長いURL入れるの辛いですよね?ね? ということで、MavenでリリースしてMaven Repositoryから","tags":["elasticsearch"],"title":"elasticsearch-extended-analyzeプラグインをMavenとSonatypeにリリース"},{"contents":"少し遅くなってしまいましたが、12/05に電子書籍も発売されました。\n技術評論社の電子書籍サイトから購入可能です。\n書籍のページへのリンク PDF版となっております。 購入の際は、技術評論社の電子書籍サイトに会員登録後購入可能となります。\n個人的には電子書籍が便利なので、こちらを普段活用しようと思っています。\nもちろん、紙の書籍も発売中です!購入の際は右の書影をクリックしていただければと!\n","date":1386554880,"dir":"post/2013/","id":"d9560caeb797b302191f667b4264da40","lang":"ja","lastmod":1386554880,"permalink":"https://blog.johtani.info/blog/2013/12/09/release-introduction-solr-ebook/","publishdate":"2013-12-09T11:08:00+09:00","summary":"少し遅くなってしまいましたが、12/05に電子書籍も発売されました。 技術評論社の電子書籍サイトから購入可能です。 書籍のページへのリンク PDF","tags":["Solr"],"title":"改訂版Solr入門のPDF版も発売"},{"contents":"勉強会で宣伝もしましたが、改めて。\nSolr入門の改訂版を執筆しました。 考えてみれば、もう3年も前なんですね、Solr入門は。 Solr勉強会などでも何度も新しいのは出ないのですか?と聞かれていましたが、やっと出ました。(お待たせしました。)\n時が立つのは早いものです。前回のSolr入門はバージョン1.4にて執筆していましたが、今回は4.4をベースにし、4.5.1への対応を行っています。\n月曜日には手元に見本が届き、今週金曜日に発売予定です!\nSolrCloud、SoftCommit、Spatial、Joinなど、多彩な機能についても記載してあります。 また、ManifoldCFというSolrにデータを登録するのに 利用できるコネクタフレームワークについても書いてあります。\nより多彩になったSolrの機能を活用するための一助となれればと思います。 (電子版も出る予定です。詳細についてはもう少々お待ちください)\nまた、出版を記念して少し時期が先になりますが、Solr勉強会を開催しようと思います。\n日時:2014年01月29日 第13回Solr勉強会 #SolrJP 新Solr本出版記念 今回はせっかくのSolr入門の書籍の出版記念ということで入門的な話をしてもらう予定です。 Solr初心者の方、Solrに興味のある方などに来ていただきたいと思っています。 (プレゼントも用意できるかも!?)\nということで、「改訂版Apache Solr入門」をよろしくお願いします。 (もちろん、購入は下のリンクからですよね!)\n","date":1385436420,"dir":"post/2013/","id":"a2012a3c9cdb1d6fd69afdbadc1e76b6","lang":"ja","lastmod":1385436420,"permalink":"https://blog.johtani.info/blog/2013/11/26/introduction-to-solr-new-edition/","publishdate":"2013-11-26T12:27:00+09:00","summary":"勉強会で宣伝もしましたが、改めて。 Solr入門の改訂版を執筆しました。 考えてみれば、もう3年も前なんですね、Solr入門は。 Solr勉強会な","tags":["Solr"],"title":"改訂版Solr入門を執筆しました"},{"contents":"どーも。以前の記事で開発中としていたプラグインですが、とりあえず、pluginコマンドでインストール出来る形にしてみました。\nインストールなどについては、READMEに記載したのでそちらを参照してもらうことにして、試行錯誤した話をメモとして残しておきます。\nプラグインの開発はしいてたのですが、やっぱりpluginコマンドでインストール出来ないと使ってもらえないよなということで、勉強会も終わったのでちょっと調べてました。\nプラグインコマンド コマンドが用意されてますが、実態はJavaで実装されてて、通常はこんなかんじでプラグインをインストールします。\n./bin/plugin -i elasticsearch/elasticsearch-analysis-kuromoji/1.6.0 この「elasticsearch/elasticsearch-analysis-kuromoji/1.6.0」という文字列ですが、「ユーザ名/リポジトリ名/バージョン」という意味になります。\nで、ダウンロードするURLは以下のものの中から選ばれます。\nelasticsearch.orgのダウンロード用サイト search.maven.org oss.sonatype.org Githubのarchive これらのサイトに先ほどのユーザ名、リポジトリ名、バージョンを利用したURLを組み立てて、ダウンロードしてくれるという仕組みになっています。\nelasticsearch.orgについては、本家の人しかアップロードできないと思うので、なし。\nmaven、sonatypeについては、Mavenのリポジトリにリリースする必要があるんじゃないかなと。 で、昔調べてググって途中で挫折したんですが、挫折してます。手順が結構手間で。。。 (参考記事:【最新版】Maven Central Repository へのライブラリ登録方法 #maven)\nということで、Githubにアップしたらなんとかなるんじゃん?ということで色々と調査して試してみました。(結果はイマイチなんですが。。。)\nその1:mvn release:prepare せっかくGithubだし、せっかくMavenなんだしなんか、pom.xmlに便利な設定したらコマンド一発でリリースできるんじゃない?という甘い気持ちで調査したググったらそれっぽい記事が見つかりました。 「MavenとGitHubの連携」って記事です。\nで、pom.xmlの設定にも他のプラグインを真似してコピペしたものに\u0026lt;scm\u0026gt;ってタグがあったなぁと。このコマンドでついでにGithubにアップロードできるんじゃないの?ということで、試してみました。\nmvn release:prepare このコマンドを叩くと、記事にあるとおりにいくつか質問をされます。 タグについては、プロジェクト名-バージョン番号という文字列がデフォルトだと指定されているので、v0.5と変更して実施してみると、Githubのreleaseにv0.5ってのができてるじゃないですか。\n※pluginコマンドはGithubを見に行く時に次のファイルをダウンロードしに行きます。\nhttps://github.com/ユーザ名/リポジトリ名/archive/vバージョン名.zip やった!と思い、早速pluginコマンドを実行してみましたが、エラーが出ました。。。\nTrying https://github.com/johtani/elasticsearch-extended-analyze/archive/v0.5.zip... Downloading ...DONE Installed johtani/elasticsearch-extended-analyze/0.5 into /Users/johtani/projects/tmp/ess_env/second_node/elasticsearch-0.90.7/plugins/extended-analyze Usage: -u, --url [plugin location] : Set exact URL to download the plugin from ...省略... Message: Error while installing plugin, reason: IllegalArgumentException: Plugin installation assumed to be site plugin, but contains source code, aborting installation. あらら、なんで?と。\nで、実際にgithubにアップされてたzipファイルをダウンロードしてみたら、githubのリポジトリにあるディレクトリ構成がそのまま入ってるじゃないですか。。。 そうですか、そうですよね。prepareだし、タグ打ってzipにかためてくれるだけなんですねと。。。\nおそらく、siteプラグインだけの場合はこの方法でpluginコマンド叩けばOKなんでしょうが、私がダウンロードしてもらいたいのは.jarファイルが入ったzipファイルなんです。\nということで、断念しました。(タグ消したりをgitコマンドで叩いて綺麗にし直すとか虚しい作業をしてました)\nその2:github.comのWebでリリース おとなしく、Sonatypeのサイトにアップロードする方向でがんばればいいんですが、とりあえず使えるようにするのが先だと思い、 github.comのページでアップロードしてしまおうと。\n「release」というタブをクリックすると、画面からアップロードできるようになります。\nzipファイルを作ってアップロードしました。(zipファイル自体はmvn packageコマンドを実行したらtarget/releaseというディレクトリに作成されてる)\nこれで行けるだろということで、またpluginコマンドを実行すると\nTrying https://github.com/johtani/elasticsearch-extended-analyze/archive/v0.5.zip... Downloading ...DONE Installed johtani/elasticsearch-extended-analyze/0.5 into /Users/johtani/projects/tmp/ess_env/second_node/elasticsearch-0.90.7/plugins/extended-analyze Usage: -u, --url [plugin location] : Set exact URL to download the plugin from ...省略... Message: Error while installing plugin, reason: IllegalArgumentException: Plugin installation assumed to be site plugin, but contains source code, aborting installation. あれ?同じエラー?なんで?jar入りのzipファイルアップロードしたのに???\nと。で、https://github.com/johtani/elasticsearch-extended-analyze/releasesにreleaseのページができてたので見てみると、あら。 アップロードしたファイルについては次のようなURLになってるじゃないですか。\nhttps://github.com/johtani/elasticsearch-extended-analyze/releases/download/v0.5/v0.5.zip で、よく見ると「Source code(zip)」というボタンもあるぞ?このリンクは?\nhttps://github.com/johtani/elasticsearch-extended-analyze/archive/v0.5.zip 。。。あぁ。そうですか。そういうことですか。理解してない私が悪いんですねと。\n結論? ということで、とりあえず、releaseにjar入りファイルはアップロードできた(手動で)ので -uオプションで直接URL指定すればインストールできるだろ!と諦めました。 いい勉強になりました。。。\nREADME見ていただくとインストール方法が分かりますが、長いです。。。\n時間をとって本腰入れてSonatypeにMavenコマンドでアップロードできるようにしようかな。。。\n","date":1384419300,"dir":"post/2013/","id":"13684d16fdd07d5f0584e29265a270e7","lang":"ja","lastmod":1384419300,"permalink":"https://blog.johtani.info/blog/2013/11/14/release-elasticsearch-extended-analyze-0-dot-5/","publishdate":"2013-11-14T17:55:00+09:00","summary":"どーも。以前の記事で開発中としていたプラグインですが、とりあえず、pluginコマンドでインストール出来る形にしてみました。 インストールなど","tags":["elasticsearch","plugin"],"title":"elasticsearch-extended-analyzeを公開?"},{"contents":"第2回を開催しました! すごい、140人くらいくらいの参加登録者(参加者は100人ちょっと!)がいて、びっくりです。 ステキな会場を提供していただいた、リクルートテクノロジーズさん、運営していただいた方々、スピーカーの皆さん、参加者の皆さん本当にありがとうございました。 今回も素敵な看板ありがとうございます。\n今回もしっかり楽しめたので、次回も頑張ります!\n今回は、elasticsearch-jpMLの紹介とかをできたのでよかったかなぁと。 ぜひ、活用してください!どんな質問でもいいので。\nあと、スライドに入ってた例の本もよろしくです。\nということで、懇親会も盛り上がったし楽しかったです。 今後も場の提供+自分の勉強のトリガーとして、開催していくので、ご協力お願いします! 聞きたい話など、MLや@ツイートしていただければと。\nelasticsearchのRouting機能:株式会社シーマーク 大谷 純 (@johtani) スライド:Routing機能※スライドはPDFです。\nド緊張で、大した発表ではなかったですが。。。 どちらかと言うとSolr本の紹介だったかもなぁ。スミマセン。\n※スライドが一部文字が消えてるので、作りなおすかも。\nElasticSearchを使ったBaaS基盤の開発(仮):株式会社富士通ソフトウェアテクノロジーズ 滝田聖己さん(@pisatoshi) スライド:https://speakerdeck.com/pisatoshi/elasticsearch-trial-and-error\n本日はお越しいただきありがとうございました!しかも静岡から!今後もよろしくお願い致します。\nEnchantMoonでシステム構成w\n0.17.0から利用されていると。(スゴイ)\nプライマリのデータストア!ただし、登録元データはMySQLにもある。\n階層も深く、大きめのドキュメント。\nレプリカ1、インデックスのバックアップも取ってないと。。。\nルーティングの機能\nDynamicMappingの問題点\nマッピング定義が肥大、型がコンフリクト。。。苦労しっぱなし\nデータ登録は1台にして、1台で一気に登録してから再配置\n実際に運用とかされてるので、いろんなノウハウがまだまだありそう!\nKibana入門:水戸祐介さん(@y_310) スライド:https://speakerdeck.com/y310/kibanaru-men\n(やっぱりru-menになってるw)\n実は、押しかけて話してもらうように説得したのでした。今後もよろしくです。\nCOOKPADの方によるKibanaのお話。 Kibanaの利点とかなんで?とか。 画面構成の説明から ダッシュボードは必ず保存して!リロードしたら悲しい思いをしてしまうので。 sparkline便利そうだなぁ。ほんとに、データサイエンティスト系のツールを目指してるのかな 一通り、ダッシュボードに配置できるパネルの説明してもらえたのですごく参考になりました! Tips周りが役に立ちそう。not_analyzedは重要ですよね。 LT 「データ集計用ダッシュボードブラウザとしても使えるElasticSearch+Kibana v3を利用する際の運用ノウハウ紹介」:株式会社リブセンス Y.Kentaro さん (@yoshi_ken) さん スライド:http://www.slideshare.net/y-ken/elasticsearch-kibnana-fluentd-management-tips\nKibanaの紹介とかFluentdの紹介。 Tips満載すばらしい。 JDBC riverは0.90.6ではうまく動かないので、気をつけてと。 「Fluentd as a Kibana」:@repeatedly さん スライド(gist)?:https://gist.github.com/repeatedly/7427856\nKibanaがfluentdの中で動くと!?\n「Authプラグインでアクセスコントロール」:株式会社エヌツーエスエム 菅谷信介さん (@shinsuke_sugaya) スライド:http://www.slideshare.net/shinsuke/es-auth-plugin\nAPI毎?インデックスごと?にアクセス制御ができるプラグイン\n","date":1384247760,"dir":"post/2013/","id":"66f43ab4b823d67f52735bbbe6ba65b0","lang":"ja","lastmod":1384247760,"permalink":"https://blog.johtani.info/blog/2013/11/12/elasticsearch-japan-user-meetup-no2/","publishdate":"2013-11-12T18:16:00+09:00","summary":"第2回を開催しました! すごい、140人くらいくらいの参加登録者(参加者は100人ちょっと!)がいて、びっくりです。 ステキな会場を提供していた","tags":["elasticsearch","kibana","fluentd","勉強会"],"title":"第2回elasticsearch勉強会を開催しました! #elasticsearchjp"},{"contents":"Cloudera World Tokyo 2013に参加してきました。\n午前中はあいにくの雨でしたが、それでも結構な人数が最初の基調講演から参加されてました。 私が参加したセッションは大盛況な感じでした。\nおみやげとしてカステラも頂いちゃいました!\nまた、色々なセッションに現れたこんなメッセージ画像も見つけました!\n昨日の写真データの整理をしていたら、こんなものが・・・ @shiumachi さんよ・・・ #cwt2013 pic.twitter.com/S0JsxSYXIx\n\u0026mdash; Kenichiro HAMANO (@hamaken) November 8, 2013 やっぱり、スーツの人が多いなという印象。\n名刺を毎回回収されるのはちょっとつらかったです。なにか、いい方法ないですかねぇ。\n以下はいつもの個人メモです。\n「ビッグデータプラットフォームとして進化するHadoop」 Cloudera株式会社 代表取締役 ジュセッペ小林氏 Costcoなどの写真を元にビッグデータを可視化 BigDataとHadoopの関係 検索、SQL、機会学習、数理処理、データ管理などにもHadoopの活用されつつある。 セキュリティ、データ管理、クラスタ上でのツールの実行なども増えてきてる。\n「今日ビッグデータは明日のスモールデータ」\nアーキテクチャとしてのビッグデータ 多種多様なデータを一箇所に集約し、生データを直接活用できる。 OSSとしての責任も。\nデータサイエンス Opsだけでないデータ解析にも活用\n「Clouderaのビッグデータプラットフォーム戦略」(仮) 講師:Cloudera, Inc. CTO Dr.Amr Awadallah レガシーな情報アーキテクチャ→スケールできない、可視化の限界、硬直したスキーマなどなど。\nエンタープライズデータハブとしてのHadoopとか。\nビッグデータの歴史と将来展望 講師:国立情報学研究所 アーキテクチャ科学研究系 教授 佐藤一郎氏 ビッグデータの歴史的経緯とか 最初の事例はアメリカの1880年国勢調査。\n「ビッグデータがコンピュータを生み出した」。コンピュータがビッグデータを生み出したんじゃない。\n少量データにもHadoopを\nバッチ処理のリアルタイム化とか(一晩から10分へ) 原点は検索データのインデクシング\nHadoopを使うのが目的じゃないんだから、構築には手を掛けないのがいいよね。\nプラットフォームと発展している\n分散システム研究者から見たHadoop 分散ししテムの難しさを、処理範囲を限定することで巧みに回避 データの近くで処理 研究レベルではリアルタイム化や逐次処理化が活発 全工程で逐次・リアルタイムが必要とは限らない 聞いてばかりじゃなくて、動かしてみましょう。 データサイエンス:超並列分散処理を活用した新たなビジネス価値の創出 講師:アクセンチュア株式会社 工藤卓哉氏 「日経BPのビッグデータ総覧2013」に記事書いてる。 多様化するデータ(社外のデータも)をどうやってうまく活用していくか。 データが教えてくれたこと→まず、データありき、まずデータためましょう。それから解析とかすればいいのでは?というはなし? 競合他社さんはNGだけど、ブースでデモ?実機?が見れますと。 Hadoopデータプラットフォーム Cloudera株式会社 嶋内 翔氏 まずは宣伝 Cloudera Implaraのフリーブックの日本語版 Hadoop Operationの書籍でるよ プラットフォームを構成するもの Flume Sqoop HBase Hive Impala データ登録してBIアナリストのお仕事にどうやって役立てる? 外部テーブル:Hiveからはテーブルのように見える仕組み。元ファイルは消えない SerDe(さーでぃー):データをHiveレコードに変換する仕組み 生データを少し加工しましょう 圧縮したりファイル結合したりはしときましょう。 Hadoop活用のポイント 富豪的プログラミング。リソースケチるな。 ローカルでできることはローカル。むりにHadoopでやんなくてもいいですよねと。バランス重要 スケジューリング実行などはOozie使うと便利。(日次集計とか) Cloudera Searchで元データにインデックス貼れるぞと。検索しながら分析ができる クラスタ管理とか Cloudera manager便利ですよ ストレージリソースの管理。 声掛け、管理者が容量チェック、Cloudera Managerのレポート 少数精鋭でHadoop使おう=手が回らなくなる。 みんなで使おう=Kerberos認証とか管理をちゃんと考えないと。けど、文化が根付けば強力。Sentry、Cloudera Navigatorとか。 Hadoopシステムの全体構成図。データの流れと各製品のつながり。 We are hiring!ということで、興味のある方は@shiumachiさんにコンタクトをとりましょうとのこと。 SQLで実現するバッチ処理とストリーム処理 LINE株式会社 田籠 聡氏 資料:Batch and Stream processing with SQL\nLINEのキャラがちらほら出てきた。\nSQL好きですか?\nログの量とか。2.1TB/Day\nバッチ処理とストリーム\n速い集計のためにHadoopが重要 エラー系のログとかはストリームで処理したい\nアーキテクチャ説明\nデータ解析する人って色々。\n管理者 プログラマ サービスディレクタ 経営陣 みんなが集計用処理を理解、編集ができるほうがいい。\n顔あげたらHiveアイコンだらけだったw\nShibとか。\nなんでHiveに限るの?\nHiveに着目したバージョンアップだけを考えれば良くなる。 スケジュールクエリが増えてきて、つらい。\nTimeWindowを固定して集計処理をすることで、回避できる。 Norikra!! スキーマレス\nOSS。Esperベース。\nインストールが楽\nクエリの動作のお話。\nhttp://norikra.github.io\nWe Are Hiring!\nHadoop コミュニティと YARN の現状 日本電信電話株式会社 小沢 健史氏 なんでHadoop? PostgreSQLでやってたけど、大きなデータにはHadoopを使おうという感じになってきた。 なんで使い分けるの? スキーマ後付け NTTDocomoのモバイル位置情報の統計処理とか? 技術的な話をするので、HiveTに着替えます!w YARNのなにが嬉しいの? ImpalaとMapReduceが同時に動くような環境の時に、リソースをうまく管理できないのがV1 そこでYARN Apache Mesosとだいたい一緒。 Apache MesosとYARNの比較 ","date":1383786660,"dir":"post/2013/","id":"a106d7c1b1b277538367f9c8140e3a75","lang":"ja","lastmod":1383786660,"permalink":"https://blog.johtani.info/blog/2013/11/07/cloudera-world-tokyo-2013/","publishdate":"2013-11-07T10:11:00+09:00","summary":"Cloudera World Tokyo 2013に参加してきました。 午前中はあいにくの雨でしたが、それでも結構な人数が最初の基調講演から参加されてました。 私が参加したセッショ","tags":["Cloudera","Hadoop","Norikra"],"title":"Cloudera World Tokyo 2013に参加しました! #cwt2013 "},{"contents":"またまた、Riak Meetup Tokyo #3に参加してきました。Riak2.0のYokozunaの話があると聞いたので。\nということで、いつものように個人メモです。\n今日は自重して、懇親会はアルコールなしにしました。思いがけずfluentd+elasticsearch+kibanaという組み合わせの話も聞けて大満足です。 Yokozunaのデモが見れなかったのがちょっと残念だったかなぁ。\n少しだけSolr本の宣伝もしてきちゃいました。\n古城さん@Mixi 「RiakCSとmixi プライベートクラウド環境」 プライベートクラウドとは? 計算リソースが安い(ストレージは微妙) 開発者が好きに使える環境+運用側のチケットに追われる毎日からの開放 Riak CSの概要 S3互換の分散ファイルストレージ 検証とか 検証時はRiak CS 1.3\n5ノードで2Mファイルを40万個\n削除は遅延で削除される\nPUT性能とか。\nRiak CSの死活監視にはRiakのstatsとか\n障害対応とか\nクラスタ クラスタは3つ。ログ、サービス(画像) 、バックアップ保存用 ログの収集にfluentd、解析にelasticsearchやkibanaを使っているらしい。 篠原@Basho 「Riak 2.0: 分散データ型、セキュリティ、そしてより容易な運用へ」 riak 2.0 pre5をリリース アプリ向け機能強化、運用の容易性 設計ポリシーとか、1.xとか 運用、高可用性、水平拡張性 Capabilityネゴシエーションとか 2.0の機能強化 バケットタイプ キーの名前空間としてバケットがあったけど、同種のバケットをまとめて管理とかしたくなった。 データ型の導入(CRDT) Setデータ型 セキュリティとか 強い整合性\u0026hellip; 鈴木@Basho 「Yokozuna: Riak 2.0の新しい全文検索機能」 YokozunaやSolrの概要 1ノードにRiakとSolrが1プロセスずつ SolrプロセスはRiakが管理してくれる SolrCloudは使ってません。 Riakのノードに届いたデータをSolrに裏で書き込んでくれる。 検索時にはRiakのノードが分散検索をしてくれる X-Riak-Metaもインデクシングしてくれる。jsonやxmlの各要素をSolrのフィールドとして認識してくれる。 Extractor Solrは4.4で、JVMは1.7をユーザが入れるらしい。\n","date":1383746460,"dir":"post/2013/","id":"9dca844d353efed03fbaddfc0fab7c76","lang":"ja","lastmod":1383746460,"permalink":"https://blog.johtani.info/blog/2013/11/06/riak-meetup-tokyo-no3/","publishdate":"2013-11-06T23:01:00+09:00","summary":"またまた、Riak Meetup Tokyo #3に参加してきました。Riak2.0のYokozunaの話があると聞いたので。 ということで、いつものように個人メモで","tags":["Riak","Yokozuna"],"title":"Riak Meetup #3 #riakjp に参加しました。"},{"contents":"開発中ですと書きました、elasticsearch-extended-analyzeですが、改良しました。\n改良と変更は以下のとおりです。\nソースのパッケージをorg.elasticsearchからinfo.johtaniに。MLで気になったので質問したら、変えたほうがいいよとのこと。ダウンロード化については、もう少々お待ちを。 出力形式を変更。可能な限りCharFilter、Tokenizer、TokenFilterそれぞれが出力する内容を返すようにしました。 ただし、既存のAnalyzer(JapaneseAnalyzerクラスとか)に関しては、現時点では出力しません。CharFilterなどを取得するI/Fが見えないためです。(改良できるかの調査は未着手) 現時点でできてないのは以下の項目\npluginコマンドでインストール 出力したいAttributeの指定 TokenizeChainで変更されたTokenの追跡(現状はどのTokenがStopFilterで消されたかなどが不明) 画面の用意(簡単に確認できる画面) ということで、README.mdに出力サンプルは貼り付けてるので、興味のある方は試してみてください。 不明点などあれば、コメントかIssueかツイートでも。\n","date":1383570720,"dir":"post/2013/","id":"b5c628b0c1dbf857a475c4be5de4690d","lang":"ja","lastmod":1383570720,"permalink":"https://blog.johtani.info/blog/2013/11/04/improve-output-extended-analyze/","publishdate":"2013-11-04T22:12:00+09:00","summary":"開発中ですと書きました、elasticsearch-extended-analyzeですが、改良しました。 改良と変更は以下のとおりです。 ソー","tags":["elasticsearch","plugin"],"title":"elasticsearch-extended-analyzeの改良"},{"contents":"お久しぶりです。 気づいたらまた、結構ブログを書いてなかったです。。。\n今回は、今開発しているElasticsearchのプラグインに関するお話です。\nいやぁ、名前決めるの難しいですね。これで英語的に合ってるか不安ですが、elasticsearch-extended-analyzeというプラグインを作っています。\nどんなもの? Solrの管理画面のanalysisに相当する機能が欲しくて作り始めました。\nElasticsearchにはanalyze APIというAPI(名前あってるのかなぁ?)が存在します。\nこれは、文字列を投げると、指定したアナライザやトークナイザでどのようなトークンに分割されるかを調べることができるAPIです。\n例えば、elasticsearch-analysis-kuromojiをインストールしたElasticsearchに対して、以下のcurlコマンドを実行します。\ncurl -XPOST \u0026#39;localhost:9200/_analyze?tokenizer=kuromoji_tokenizer\u0026amp;filters=kuromoji_baseform\u0026amp;pretty\u0026#39; -d \u0026#39;寿司が美味しい\u0026#39; すると、トークナイズされた結果が次のようなJSONで返ってきます。\n{ \u0026#34;tokens\u0026#34; : [ { \u0026#34;token\u0026#34; : \u0026#34;寿司\u0026#34;, \u0026#34;start_offset\u0026#34; : 0, \u0026#34;end_offset\u0026#34; : 2, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 1 }, { \u0026#34;token\u0026#34; : \u0026#34;が\u0026#34;, \u0026#34;start_offset\u0026#34; : 2, \u0026#34;end_offset\u0026#34; : 3, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 2 }, { \u0026#34;token\u0026#34; : \u0026#34;美味しい\u0026#34;, \u0026#34;start_offset\u0026#34; : 3, \u0026#34;end_offset\u0026#34; : 7, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 3 } ] } トークナイズの結果がわかるのは嬉しいのですが、どんな品詞なのかといったKuromoji固有のTokenの属性情報がなくなってしまいます。\nSolrでは、こんな画面が用意されていて、品詞情報とかが出力されます。あとは、各TokenFilterでどのトークンがなくなっているかなどもわかるようになっています。\nこれって結構役立つと思うんですよ。 ということで、Pluginも作ってみたかったので、いい機会だから作ってみようかと。\n出力サンプル まずは、その他のAttribute(品詞とか)を表示するところを実装してみました。\ncurl -XPOST \u0026#39;localhost:9200/_extended_analyze?tokenizer=kuromoji_tokenizer\u0026amp;filters=kuromoji_baseform\u0026amp;pretty\u0026#39; -d \u0026#39;寿司が美味しい\u0026#39; 先ほどとほぼ一緒のcurlコマンドを実行します。違う点は**「_analyze」が「_extended_analyze」**となっている点です。\nで、実行結果はこんな感じです。(長いですがそのまま載せてます。続きの文章がしたにあります。)\n{ \u0026#34;tokens\u0026#34; : [ { \u0026#34;token\u0026#34; : \u0026#34;寿司\u0026#34;, \u0026#34;start_offset\u0026#34; : 0, \u0026#34;end_offset\u0026#34; : 2, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 1, \u0026#34;extended_attributes\u0026#34; : [ { \u0026#34;org.apache.lucene.analysis.tokenattributes.TermToBytesRefAttribute#bytes\u0026#34; : \u0026#34;[e5 af bf e5 8f b8]\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.tokenattributes.PositionLengthAttribute#positionLength\u0026#34; : 1 }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.BaseFormAttribute#baseForm\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.PartOfSpeechAttribute#partOfSpeech\u0026#34; : \u0026#34;名詞-一般\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.PartOfSpeechAttribute#partOfSpeech (en)\u0026#34; : \u0026#34;noun-common\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#reading\u0026#34; : \u0026#34;スシ\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#reading (en)\u0026#34; : \u0026#34;sushi\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#pronunciation\u0026#34; : \u0026#34;スシ\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#pronunciation (en)\u0026#34; : \u0026#34;sushi\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionType\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionType (en)\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionForm\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionForm (en)\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.tokenattributes.KeywordAttribute#keyword\u0026#34; : false } ] }, { \u0026#34;token\u0026#34; : \u0026#34;が\u0026#34;, \u0026#34;start_offset\u0026#34; : 2, \u0026#34;end_offset\u0026#34; : 3, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 2, \u0026#34;extended_attributes\u0026#34; : [ { \u0026#34;org.apache.lucene.analysis.tokenattributes.TermToBytesRefAttribute#bytes\u0026#34; : \u0026#34;[e3 81 8c]\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.tokenattributes.PositionLengthAttribute#positionLength\u0026#34; : 1 }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.BaseFormAttribute#baseForm\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.PartOfSpeechAttribute#partOfSpeech\u0026#34; : \u0026#34;助詞-格助詞-一般\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.PartOfSpeechAttribute#partOfSpeech (en)\u0026#34; : \u0026#34;particle-case-misc\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#reading\u0026#34; : \u0026#34;ガ\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#reading (en)\u0026#34; : \u0026#34;ga\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#pronunciation\u0026#34; : \u0026#34;ガ\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#pronunciation (en)\u0026#34; : \u0026#34;ga\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionType\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionType (en)\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionForm\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionForm (en)\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.tokenattributes.KeywordAttribute#keyword\u0026#34; : false } ] }, { \u0026#34;token\u0026#34; : \u0026#34;美味しい\u0026#34;, \u0026#34;start_offset\u0026#34; : 3, \u0026#34;end_offset\u0026#34; : 7, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 3, \u0026#34;extended_attributes\u0026#34; : [ { \u0026#34;org.apache.lucene.analysis.tokenattributes.TermToBytesRefAttribute#bytes\u0026#34; : \u0026#34;[e7 be 8e e5 91 b3 e3 81 97 e3 81 84]\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.tokenattributes.PositionLengthAttribute#positionLength\u0026#34; : 1 }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.BaseFormAttribute#baseForm\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.PartOfSpeechAttribute#partOfSpeech\u0026#34; : \u0026#34;形容詞-自立\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.PartOfSpeechAttribute#partOfSpeech (en)\u0026#34; : \u0026#34;adjective-main\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#reading\u0026#34; : \u0026#34;オイシイ\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#reading (en)\u0026#34; : \u0026#34;oishii\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#pronunciation\u0026#34; : \u0026#34;オイシイ\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#pronunciation (en)\u0026#34; : \u0026#34;oishii\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionType\u0026#34; : \u0026#34;形容詞・イ段\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionType (en)\u0026#34; : \u0026#34;adj-group-i\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionForm\u0026#34; : \u0026#34;基本形\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionForm (en)\u0026#34; : \u0026#34;base\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.tokenattributes.KeywordAttribute#keyword\u0026#34; : false } ] } ] } 先ほどの結果に**「extended_attributes」**という配列のオブジェクトが追加された形になっています。 ちょっと長くなってしまいましたが。。。\nSolrの処理を真似して作ったので大したことはやってないんですが、少しは便利になるかもなぁと。\n現時点では、最終的な結果しか取得できないですが、今後は次のような機能を作っていこうかと思っています。 できるかどうかは、やってみてって感じですが。\npluginコマンドでインストール pom.xmlはありますが、まだMavenとかに登録はされていません。ですので、mvn packageしてからjarファイルをpluginsフォルダに配置しないといけません。pluginコマンドでインストールできるともっと使ってもらえるはず? 出力したいAttributeの指定 リクエストパラメータで、出力したいAttribute名を指定するとか。 出力形式の変更 今は、Solrの真似をしていますが、せっかくJSONだったりするので、もう少し検討しようかと(同じAttributeの異なる値も1オブジェクトとして出力されてる) TokenizeChainの出力 Solr同様、CharFilter、Tokenizer、TokenFilterが動作して、最終的なTokenがインデックスに登録されます。ですので、各処理の直後のTokenがどうなっているかもわかったほうが嬉しいと思うので、それらも取得できるようにしたいなぁと 画面の用意 せっかくプラグインなんだし、画面で見れると嬉しいかなと。これは当分先になっちゃうと思いますが、Webページで確認できるような画面を作ると確認しやすくなるかなぁと。上記対応が終わってから取替かかると思いますが。 とりあえず、思いつくのはこんなかんじです。\nElasticsearchの_analyze APIを真似しただけのコードだし、テストも実装もまだまだですが、とりあえず公開してみました。\n要望などあれば、コメント、Issue、ツイート(もちろん、テストコードなども!)なんでも受け付けてますので、お気軽に。\n","date":1382695560,"dir":"post/2013/","id":"0302e8a57a5e8604342a925b2dc60737","lang":"ja","lastmod":1382695560,"permalink":"https://blog.johtani.info/blog/2013/10/25/developing-es-extended-analyze-plugin/","publishdate":"2013-10-25T19:06:00+09:00","summary":"お久しぶりです。 気づいたらまた、結構ブログを書いてなかったです。。。 今回は、今開発しているElasticsearchのプラグインに関するお話","tags":["elasticsearch","plugin"],"title":"elasticsearch-extended-analyzeプラグインを開発中"},{"contents":"不定期開催ですが第12回Solr勉強会を主催しました。\n今回は、前回ほどの過熱ぶりでは無かったですが、70人ほどの参加者の方がいらっしゃったかと。 ありがとうございます!\n今回は聞きたかったYokozunaの話をしてもらいました。あと、リベンジManifoldCF。 一部、追記しました。Bashoさんからツッコミがあったので。あと、4.5.1の話とか。\nManifoldCFのとSolrの組み合わせ(仮)株式会社 ロンウイット 大須賀 稔さん 前回お休みだったのでリベンジですw。\n英語だ。。。やっぱ英語がいいですか、スライド。。。\nManifoldCFの概要から。 最新版は1.3です。色々サポートしてるなぁ。\nデモもありました。(やっぱりちゃんと動かないので、鬼門みたいですが)\nデモ ManifoldCFのGUIで操作しながら。 いまいちちゃんと動かなかった。。。\nQA Q:Zipはうまく動かなかった A:Solr側で処理してくれてる。 Q:Notes対応するの? A:いまのところない。 Q:ExcelとかPDFはTika? A:Tika次第です。 Q:認証周りどこから取ってくるの? A:クローラ側にはなくて、SharePointとかの権限をみてる。 Q:Web系の認証は? A:まだないのでは。。。(調査します) あー、デモの続き忘れてましたね。。。\nSolrを組み込んだRiak 2.0の全文検索機能 -Yokozuna- Bashoジャパン株式会社 鈴木 一弘さん Riak色々使われてるよ!アングリーバードとか、Y!とか。 Riakで提供されている1機能としてのYokozuna。単独製品ではないですよと。\nRiakの説明。スケールするよ、いつでもRead/Writeできるよ、運用にフォーカスしてるよと。 マスターレスですよ。 Riak2.0のリリースは2013年末。Yokozunaもかな?\nダイナミックフィールド使ってるので、Yokozunaをonにするだけで簡単に使えるよ。\nRiakがSolrのプロセスを管理。\nインデックスの不整合の検知とかってどうやってるのかなぁ? インデックス比較用のハッシュツリーをノード間でコピーしつつ検査してる。(Active Anti-Entropy)\n(デモには魔物がいるようだ。。。)\nQA Q:JSONの属性を元にしてフィールドにインデックス可能か? A:可能です。IIJさんの発表で話が出ます。 Q:ProtocolBufferでSolrにアクセス可能? A:そのうちできそうです。リリース時にはできるようになっています。 Q:コアのスワップは?スキーマの変更は? A:事前に設定するのは可能。 Q:RiakのデータとSolrでデータがずれるってのはあるの? A:可能性はありますが、極力ずれAAEで修復。 Q:復旧中のインデックスにアクセスが行かないようにする仕組みなどはある? A:今はないです。 Yokozuna ベンチマークしました 株式会社インターネットイニシアティブ 曽我部 崇さん、田中 義久さん いいとこ取りで楽だなぁと。いうことで、試してみてます。 デモが動いてる。\nextractorでXMLやJSONをパースできる。 ベンチマーク結果。\nRiak Meetup Tokyo #2の時のQAも入ってるので助かります。素晴らしい。\nQA Q:スナップショットは両方取れるの? A:Riakは取れますが、インデックスは今は無理です。 フォロー:0.8はYokozunaにボトルネックがあったので、0.9以降だともっと性能が出るはずですとのこと。また次回とかに発表してもらうのもありですかねぇ。 Solr 4.5の新機能など @johtani 発表資料のPDFです。\nツイート見てて誤解を招いたなと思ったのですが、7u40は4.5限定ではなく、すべてのバージョンと考えてください。 チケットを見ると分かりますが、影響バージョンの記載はありません。\n※あ、4.5のChangesを紹介しましたが、4.5.1が出るかも。このへんが困ってるらしいです。\nSOLR-5306: can not create collection when have over one config SOLR-5317: CoreAdmin API is not persisting data properly LUCENE-5263: Deletes may be silently lost if an IOException is hit and later not hit (e.g., disk fills up and then frees up) LT @haruyama さん 資料:http://haruyama.github.io/solr_20131009/#(1)\n記号が捨てられるTokenizer困るので、捨てないのを作ってみました。\nKuromojiの困ったこと。全角数字を分解しちゃう。→MappingCharFilterFactoryで全角から半角にしましょう。 lucene-gosenデフォで半角記号が未知語になってしまい、半角カナと混ざるので、記号を全角にしましょう。\n","date":1381372500,"dir":"post/2013/","id":"76e127a44931bfefab991be3dd7a08b7","lang":"ja","lastmod":1381372500,"permalink":"https://blog.johtani.info/blog/2013/10/10/solr-meetup-memo/","publishdate":"2013-10-10T11:35:00+09:00","summary":"不定期開催ですが第12回Solr勉強会を主催しました。 今回は、前回ほどの過熱ぶりでは無かったですが、70人ほどの参加者の方がいらっしゃったか","tags":["Solr","Riak","Yokozuna","ManifoldCF"],"title":"第12回Solr勉強会を主催しました。#SolrJP"},{"contents":"今日は、ElasticSearchのMLで見つけたelasticsearch-inquisitorプラグインの紹介です。\nElasticSearchはREST API形式で簡単にコマンドラインからいろいろな処理を実行できて便利ですが、 GUIがあったほうが楽なこともまた事実です。 今回紹介する、inquisitorプラグインもSiteプラグイン(Webブラウザでアクセスできるプラグイン)の1つです。 (ただし、ローカルにインストールしてローカルのElasticSearchにしか接続できませんが。。。)\nインストール プラグインですので、以下のコマンドでインストールが出来ます。インストール後はElasticSearchの再起動が必要です。\nbin/plugin -install polyfractal/elasticsearch-inquisitor ElasticSearch再起動後に、以下のURLにアクセスすればOKです。 ※ローカルでのみ動作可能なプラグインです。(内部で呼び出しているJSにlocalhostと記載があるため)\nhttp://localhost:9200/_plugin/inquisitor/#/ 何ができるの? 自分の書いたQueryが正しく動作するかや、Analyzerによって文章がどのように、Term(Token)に分割されるかといった挙動をWebブラウザ上で確認することができます。用意されている画面は「Queries」「Analyzers」「Tokenizers」の3種類です。\nQueries クエリの確認、実行が可能な画面です。\n「Index」「Type」はプルダウンになっており、現在ElasticSearchに存在しているものが選択可能です。 その下のテキストエリアがクエリを入力する画面です。\nクエリを入力していると、入力しているクエリがValidかどうかをクエリのコンソール部分(右側上部)に表示してくれます。\n少し残念なことに、Tabを押すと、フォームのフォーカスが切り替わってしまうので、クエリを入力するのがちょっと面倒です。。。(私は通常の検索には、ChromeプラグインのSenseというものを利用してます。)\nクエリに問題がない場合は、「Query」ボタンを押すことで実際の検索が実行されます。 この時、画面真ん中のブルーのテーブル(内部で実行されるクエリ)の部分に、QueryがElasticSearch内部で解釈されたあとの、Luceneで実行されるレベルのクエリに変換されたクエリが表示されます。\nこれが便利です。JSONで記述したり、色々なタイプのクエリがElasticSearchでは実行できますが、望んだ形に単語が区切られているかなどを確認することができるため、非常に便利です。\nElasticSearchのQuery DSLではexplainをtrueにすることで、ヒットしたドキュメントのスコア計算に用いられた単語などがわかるのですが、そもそもヒットしないクエリの場合は、explainでは単語の区切られ方などがわかりません。\nその場合に、このプラグインで確認すると、想定と違う単語の区切られ方やクエリの造られ方がわかるかと思います。\nAnalyzers Analyzerによる文章のアナライズ結果の確認が出来る画面です。 ElasticSearchやSolrにあまり詳しくない場合、どんなAnalyzerが文章をどのように単語に区切って、転置インデックスのキーワードとして利用しているかがわからないと思います。\nこのAnalyzerが文章をどのように単語に区切っているかを確認することができるのがAnalyzers画面です。 こんなかんじの画面になります。\n一番上のテキストエリアが文章を入力する場所です。 文章を入力していくと、その下のテーブルの「Analyzed Text」の部分が変化していくのが分かります。 このグレーの単語が転置インデックスのキーワードとなります。\n予め用意されているAnalyzer以外に、用意されているTokenzier+Filterの組み合わせも簡単ですが確認可能です。(Tokenizer、Filtersとあるテーブル) ただし、ここまでのどちらも細かな設定は画面上ではできません(Filterの細かな引数の指定など)\n一番下の部分が、ElasticSearchに存在しているインデックスごとに定義されたAnalyzerやフィールドを元にした解析結果を表示することができる領域です。\n自分でマッピングを記述してフィールド定義したものの動作確認や、インデックスを適当に作ったけど、うまくヒットしない場合など、ここで、単語の区切れ方を確認することで、検索になぜヒットしないのかといった問題のヒントを得ることができると思います。\nAnalyzerによっては、インデックス対象の文字として扱わない文字があったりしますので。 先ほどのQueries画面のLuceneに投げられる直前のクエリと、Analyzersでの単語の区切られ方を確認することで、検索がうまくヒットしていないことが判明すると思います。\nTokenizers 最後はTokenizers画面です。Analyzersとほぼ同様ですが、ちがいは、デフォルトで用意されているTokenizerの挙動の確認ができるというだけになります。\n簡単な確認ならここで可能かと。\n注意点は? まだ開発途中のようで、つぎの部分が課題かと。\nローカルでのみ実行可能 Queries画面の結果の「Explain Result」リンクが未実装 Queries画面のクエリ入力が使いにくい(タブが打てないので) カスタム登録のAnalyzersはインデックスを用意しないと確認できない。(Kuromojiのプラグインを登録しただけでは確認できなかった) 細かな設定のフィールドも用意しないと、Analyzers画面では利用できない まとめ ということで、Inquisitor(読みがわからない)プラグインの簡単な説明でした。 検索にうまくヒットしないという理由は大体の場合、 クエリに入力した文字列が単語に区切られたものと、登録したデータが単語に区切られたものが異なるために検索にヒットしないというものです。\nそのクエリ、データの単語の区切られ方を確認するのに役に立つプラグインじゃないでしょうか。\nちなみに、このプラグイン自体はHTML+JSで作成されており、実際にはElasticSearchが持っているREST APIをキックしているだけになります。 ですので、Web画面なんか要らないという方は、このプラグインが実際に送信しているリクエストを参考にするとcurlコマンドでどういったリクエストを投げればいいかというのがわかると思います。\n私は軟弱者なので画面があったほうがいいですが。\n","date":1379906820,"dir":"post/2013/","id":"e1870dde155be1a375f155dd1f7ead13","lang":"ja","lastmod":1379906820,"permalink":"https://blog.johtani.info/blog/2013/09/23/intro-elasticsearch-inquisitor/","publishdate":"2013-09-23T12:27:00+09:00","summary":"今日は、ElasticSearchのMLで見つけたelasticsearch-inquisitorプラグインの紹介です。 ElasticSea","tags":["elasticsearch","plugin"],"title":"elasticsearch-inquisitorプラグインの紹介"},{"contents":"river-wikipediaの前々回の記事で書きましたが、bulk_sizeに関連して登録件数がやけにきりが良いのが気になると書いていました。\nで、Riverの仕組みを勉强がてら、elasticsearch-river-wikipediaのソース(1.2.0)を読んでみました。\nRiverの作り Riverはorg.elasticsearch.river.Riverというinterfaceを実装することで作らています。 ただ、Riverがinterfaceとなっていますが、o.e.river.AbstractRiverComponentというクラスを継承して作られています。\nAbstractRiverComponentにはRiverの名前や設定などが用意されています。 ま、ここはそれほど重要じゃないので、軽く流してと。\nRiverの設定関連は実装したRiverクラス(ここでは、WikipediaRiverクラス)のコンストラクタで、設定値の読み取りなどの記述を記載します。 このコンストラクタが、_river/hogehoge/_metaをPUTした時のJSONを元にElasticSearchから呼ばれて、Riverのインスタンスが作成されます。(たぶん、このへんがその処理だと思う。。。このあたりはまた今度)\n実際のRiverの処理はWikipediaRiverクラスのstart()メソッド内部に記述されています。\n@Override public void start() { logger.info(\u0026#34;starting wikipedia stream\u0026#34;); try { ① client.admin().indices().prepareCreate(indexName).execute().actionGet(); } catch (Exception e) { if (ExceptionsHelper.unwrapCause(e) instanceof IndexAlreadyExistsException) { // that\u0026#39;s fine } else if (ExceptionsHelper.unwrapCause(e) instanceof ClusterBlockException) { // ok, not recovered yet..., lets start indexing and hope we recover by the first bulk // TODO: a smarter logic can be to register for cluster event listener here, and only start sampling when the block is removed... } else { logger.warn(\u0026#34;failed to create index [{}], disabling river...\u0026#34;, e, indexName); return; } } ② currentRequest = client.prepareBulk(); ③ WikiXMLParser parser = WikiXMLParserFactory.getSAXParser(url); try { ④ parser.setPageCallback(new PageCallback()); } catch (Exception e) { logger.error(\u0026#34;failed to create parser\u0026#34;, e); return; } ⑤ thread = EsExecutors.daemonThreadFactory(settings.globalSettings(), \u0026#34;wikipedia_slurper\u0026#34;).newThread(new Parser(parser)); thread.start(); } 内部では\nインデックスの作成 バルクアップデート用クライアントの設定 WikiXMLのパーサの初期化 ページごとにキックされるコールバック処理の登録 デーモンスレッドの起動と起動 といった処理の流れになっています。\nで、このスレッドの起動後は、4.で用意したparser.parse()処理がグルグル回ります。\n1ページがパースされるたびに、WikipediaRiver.PageCallbackクラスのproess()メソッドが呼ばれます。 このメソッドの最後で、processBulkIfNeeded()メソッドが呼ばれています。ここで、実際にパースしたページをインデックスに登録する処理が実行されます。\nこのメソッドの1行目が鍵でした。 bulkSize以上の件数がバルクのリクエストに貯まった時だけ、実際にインデックスに登録する処理が実行されます。 このため、スレッドが回っている間は、bulkSize以上のデータが貯まらないと、インデックスへの登録は行われないわけです。\n次に、このスレッドを止めるには、前々回書いたように、_riverにPUTした、Riverの設定をDELETEするしかありません。(あとは、ElasticSearchを停止するとかでしょうか。)\nで、DELETEが実行される呼ばれるのが、WikipediaRiverクラスのclose()メソッドです。\n@Override public void close() { logger.info(\u0026#34;closing wikipedia river\u0026#34;); closed = true; if (thread != null) { thread.interrupt(); } } 見ていただくと分かりますが、スレッド止めて終了です。\n問題点は? ということで、\nWikipediaのXMLを読み込んでもRiverは停止しない Riverの停止を行ってもスレッドが止められるだけ。 bulkSize以下の件数がcurrentRequestに残っているけど、破棄される とまぁ、こんな流れになっているので、最後の端数のドキュメントがインデックスに登録されないようです。 (まだ、ちゃんと確認してないんですが、備忘録のため先に書いちゃいました。。。)\nじゃあ、全部うまく登録するにはどうしたもんかなぁと。 いまのところ思いついたのはこんな感じです。 他にいい案があったら教えて下さい。\n案1:close()処理の中で、スレッド停止後に、currentRequestに貯まっているデータをインデックスに登録しちゃう 案2:bulkSize以外に、定期的(指定された時間)で登録処理を実行してしまう。 簡単なのでとりあえず、案1を実装してみるかなぁと。 (さっさとコード書けよって話ですね。。。スミマセン) その前にMLで質問ですかねぇ、英語で。\nWikipediaのRiverをざっと眺めてみた感じですが、わかりやすい作りだなぁと。 他のRiverがどうなってるかをちゃんと見てませんが、他にもbulkSize指定をするRiverの場合は、このように件数がbulkSizeに満たない状態ではデータが登録されないといったことがあるかもしれません。\nElasticSearchのソースを読み始める取っ掛かりとしては面白いかと思いますので、興味ある方は読んで作ってみるといいかもしれません。(私は読んだだけですがw)\n追記(2013/09/13 21:00) MLで質問してみました。とりあえず、案1を。\nriver-wikipedia does not index all pages\n他のRiverでは対応してるしバグだね、Issue上げてとのことで、あげときました。 ついでにプルリクも出せばいいんでしょうが、プルリクまだやったことないヘタレです。。。\nあと、案2についても同じトピックで質問してます。 どうやら、BulkProcessorにその機能があるよと。 flushintervalというプロパティがありそうです。どうやって設定して、どうやって動くのかとか見てないので、 調査してブログorLTかな。\nbulk udpにはその値を設定できそうなのがあるんだよなぁ。\n追記その2(2013/09/16 23:50) さっそく修正版がコミット(コミットログ)されてました。 結構変わってます。BulkProcessorにflush_intervalの設定をすれば、よしなにやってくれる仕組みがすでに実装されているようです。 bulkSizeについても同様に、BulkProcessorに設定すれば良いようです。 Riverの仕組みが結構スッキリしています。 もともと実装されていた、bulkSizeごとの処理も消されています。 確かに、BulkProcessorの仕組みとして実装されている方がしっくりきますね。\nということで、考える暇もなくコミットされてしまいました。 こうやって質問しつつ、少しずつソースを読んでいこうかなと思ってるとこです。\n","date":1378921080,"dir":"post/2013/","id":"d2e805472f79f0b558f75b90b5e7b4ee","lang":"ja","lastmod":1378921080,"permalink":"https://blog.johtani.info/blog/2013/09/12/question-river-wikipedia/","publishdate":"2013-09-12T02:38:00+09:00","summary":"river-wikipediaの前々回の記事で書きましたが、bulk_sizeに関連して登録件数がやけにきりが良いのが気になると書いていまし","tags":["elasticsearch","wikipedia"],"title":"elasticsearch-river-wikipediaの疑問点"},{"contents":"前々回紹介した、日本語Wikipediaのデータをインデックス登録する記事の続きです。\n今回は、Kuromojiのアナライザを利用してインデックス登録してみます。\n余談(Proxy環境でのプラグインインストール) ElasticSearchのpluginコマンドはJavaで実装されています。(org.elasticsearch.plugins.PluginManager) プラグインのダウンロードには、java.net.URL.openConnection()から取得URLConnectionを使用しています。\nですので、pluginのインストールを行う際に、Proxy環境にある場合は以下のようにコマンドを実行します。\n./bin/plugin -DproxyPort=ポート番号 -DproxyHost=ホスト名 -i elasticsearch/elasticsearch-analysis-kuromoji/1.5.0 elasticsearch-analysis-kuromojiのインストール WikipediaのデータをKuromojiを使って、形態素解析ベースの転置インデックスを作成していきます。 まずは、Kuromojiを利用するために、Analysisプラグインのインストールです。 ElasticSearchのバージョンに対応したプラグインのバージョンがあります。(プラグインのページに対応したバージョンの記載あり) 今回はElasticSearchの0.90.3を利用しているため、1.5.0をインストールします。\n./bin/plugin -i elasticsearch/elasticsearch-analysis-kuromoji/1.5.0 インストール後は再起動しておきます。 なお、Kuromojiを利用して、Wikipediaのデータを登録するばあい、デフォルトの設定では、ヒープが足りなくなるおそれがあります。 ElasticSearchの起動時に以下のオプションを指定して、最大ヒープサイズを2Gとしておきます。\nexport ES_HEAP_SIZE=2g;./bin/elasticsearch Indexの作成(デフォルトでKuromojiのAnalyzerを利用する) Wikipediaのデータを登録する際に、Kuromojiのアナライザを利用したいのが今回の趣旨でした。 一番ラクな方法として、Wikipediaデータのインデックスの設定として、デフォルトのアナライザをKuromojiにしてしまいます。 (きちんと設計する場合は、必要に応じてフィールドごとに指定しましょう)\ncurl -XPUT \u0026#39;localhost:9200/ja-wikipedia-kuromoji\u0026#39; -d \u0026#39;{ \u0026#34;settings\u0026#34;: { \u0026#34;analysis\u0026#34;: { \u0026#34;analyzer\u0026#34;: { \u0026#34;default\u0026#34; : { \u0026#34;type\u0026#34; : \u0026#34;kuromoji\u0026#34; } } } } }\u0026#39; これでkuromojiのアナライザがデフォルトで利用される形となります。 あとは、Riverを起動して登録するだけです。\nRiverの実行 前回と一緒です。 インデックス名(_river/\u0026lt;インデックス名\u0026gt;/_meta)だけは、先ほど作成した「ja-wikipedia-kuromoji」に変更してください。\ncurl -XPUT localhost:9200/_river/ja-wikipedia-kuromoji/_meta -d \u0026#39; { \u0026#34;type\u0026#34; : \u0026#34;wikipedia\u0026#34;, \u0026#34;wikipedia\u0026#34; : { \u0026#34;url\u0026#34; : \u0026#34;file:/home/johtani/src/jawiki-latest-pages-articles.xml\u0026#34; }, \u0026#34;index\u0026#34; : { \u0026#34;bulk_size\u0026#34; : 10000 } }\u0026#39; あとは、インデックスされるのを待つだけです。\nデータ量とか 5.8gbになりました。Kuromojiを利用したため、形態素解析により単語にきちんとトークないずされた結果でしょう。 Uni-gramだと、転置インデックスのボキャブラリも単語に対してヒットするドキュメント数も大きくなるため、 インデックスサイズも大きくなっているのかと。\n検索クエリのサンプルなどはまた後日。(夜遅いので。。。)\n","date":1378138500,"dir":"post/2013/","id":"79e647a3f8b36a1221897f5837c84aff","lang":"ja","lastmod":1378138500,"permalink":"https://blog.johtani.info/blog/2013/09/03/ja-wikipedia-with-kuromoji/","publishdate":"2013-09-03T01:15:00+09:00","summary":"前々回紹介した、日本語Wikipediaのデータをインデックス登録する記事の続きです。 今回は、Kuromojiのアナライザを利用してインデッ","tags":["elasticsearch","kuromoji","wikipedia"],"title":"日本語Wikipediaをインデクシング(Kuromojiバージョン)"},{"contents":"ElasticSearch勉強会 第1回を主催しました。 昨年のpyfesでなんちゃって資料で喋って、1年たちました。\nElasticSearchの書籍(英語)も出てきて、今年はElasticSearchが面白くなりそうだし、使ってる人たちから話も聞きたいなぁということで、主催しました。\n思った以上に興味のある方がいらっしゃったようで、100人応募のところ、チケットがすぐ完売してしまうほど。。。 しかも、当日もほぼ満員ということで、大変な盛況ぶりでした。\nスピーカーの皆様、参加された皆様、会場を提供していただいたリクルートテクノロジーズさん、ありがとうございました!(たぶん、90人くらいいらっしゃってたかと。)\nこんなステキな案内板も用意してもらいました。スタッフのみなさんありがとうございます! トゥギャっても頂きました。まとめていただいてありがとうございます!\n自分の発表や個々の発表に関する感想は以下のメモに。\nElasticSearch入門 @johtani スライド:ElasticSearch入門※スライドはPDFです。\n緊張しまくりでわかりにくかったですかね。。。 とりあえず、AWSのサービスじゃないってのだけでも覚えて帰っていただければ満足です。 途中で見せたChromeプラグインのSense わからなかった点や質問、ご意見などは、当ブログのコメント、私宛の@ツイート、なんでもいいので、反応ください。なんでもいいので反応があると、今後の励みになりますので! ということで、発表でも言いましたが、わからないことがアレば、@johtaniまで投げてもらえれば、「知らない」「ブログのネタにします」「ソレはこんなかんじですかねぇ?(テキトー)」みたいに答えると思います。 Elasticsearch in Actionは帰宅中に、4章追加されたよというメールが届きました。 宿題 クラスタへのノードの追加の処理方法とか、シャーディングの実装とか。 elasticsearchプラグイン入門 ~ mocksolrpluginでSolrと入れ替えてみよう 菅谷さん スライド:elasticsearchプラグイン入門 slideshare\nプラグイン構成とか(公式でまとまってるの見つけられないので助かります。) 作る上でのポイントうれしいです。 パッケージ名変えられるとか、つらい。。。 Solr APIプラグインについて(Solrの振りしてくれる便利なヤツ) 感想 まだ、プラグインを書いたことがないのですが、ちゃんとプラグインはどういう構成で書くんですよというまとまった資料って本家のサイトにもない気がしています。 なので、スライドが公開されたらすごく役に立つかと。 そのまえに、何かプラグイン書いてみます。。。\nDebugging and testing ES systems Chris Birchallさん スライド:Debugging and testing ES systems slideshare\nテストの方法とか便利なお話(最後のほうしか聞いてなかったですが。。。。) クエリのデバッグは色々とやらないと、なんでヒットしないのってよくあるので。とくに形態素解析を利用した検索の場合、短い文章(クエリ)と長い文章(ドキュメント)で切れ目が変わってうまくヒットしないとかありますよね。 最後に少しだけ話しましたが、n-gramとKuromojiを組み合わせてOR検索とかすると良い場合があります。 インデックスが大きくなったり、OR検索なので遅くなったりというデメリットもありますが。 感想 実際に使われているノウハウを元に話をしていただいたので助かりました。 最初に席を外してたのですが、戻ってきて日本語で普通に発表されててほんとにびっくりしましたw テスト用プラグインがあるのとかは知らなかったです。 あと、使われてたIDEがIntelliJ IDEAでしたね!私も使ってます!\nニコニコ動画データセット 25億件を検索可能にしてみよう @PENGUINANA_ スライド:ニコニコ動画を検索可能にしてみよう slideshare\nkibana@cookpadのお話 どういう挙動するかをやってみればいいじゃんってことで、やってみるのカッコイイ! http://goo.gl/FYtO5T bigdeskとか。プラグインいろいろ。 感想 さすがです、ペンギン先生。大きなデータセットつかって、構築した環境に関する数値も書かれてる資料ができて素晴らしすぎです。 思った以上にサクサク動いてて、4hでインデクシングできるのもすごいなぁと。 私も見習ってこのくらいがサクッとできるようになりたい。。。 あと、発表後にムチャぶりしましたが、次回はぜひ検索側の性能とかも話してもらえたらと。\n反省点 イベントアテンドだと、キャンセル待ちができない+どのくらいの方が興味をもっているのかわからない。 イベントページの主催者は複数指定できる方がいい。(土壇場の登録の人が管理できない。私が司会やってたから) マイクが聞こえにくかった(音量調節とかちゃんと調べないと) 懇親会は立食のほうがやはり動きやすい。 懇親会が1時間ちょっとしかできなかった 雑感 ということで、ES勉強会、主催の私が一番楽しめました。ありがとうございます。 (あと、気前よく調べて答えますと言ってしまいました。。。まぁ、いいトリガーになるので、ウェルカムですが)\nやっぱりKibanaについて興味を持ってる人も多いのかなぁという感触がしたので、次回はぜひKibana3の話をしてもらえるように頑張ります。 あと、elasticsearch-headを使われてるんだなぁと。私はelasticsearch-HQを入れて使ってみてます。大きなクラスタ管理まではまだやってないので。\nあとは、やはりいろんな人に助けられてるなぁと実感しつつ、今後も開催するので助けてください!ということで。 (もちろん、Solr勉強会もがんばりますよー)\n関連ブログ ElasticSearch勉強会 第1回 - Go ahead! タムタムの日記 - ElasticSearch勉強会 の参加メモ #elasticsearchjp 第1回ElasticSearch勉強会に行ってきた! #elasticsearchjp - #侍ズム 第1回 ElasticSearch 勉強会に参加 #elasticsearchjp - seratch 他にもブログを書かれた方がいらっしゃいましたたら、リンクしたいので連絡いただければ。\n","date":1377798120,"dir":"post/2013/","id":"5931f8e3acdac724742c4ee0960d8d40","lang":"ja","lastmod":1377798120,"permalink":"https://blog.johtani.info/blog/2013/08/30/hold-first-elasticsearch-meetup-in-japan/","publishdate":"2013-08-30T02:42:00+09:00","summary":"ElasticSearch勉強会 第1回を主催しました。 昨年のpyfesでなんちゃって資料で喋って、1年たちました。 ElasticSearch","tags":["elasticsearch","勉強会"],"title":"第1回ElasticSearch勉強会を開催しました! #elasticsearchjp"},{"contents":"久々のブログはElasticSearchネタです。勉強会開催する予定だったりすので、もう少し触っておきたいなと。 お手軽に検索するデータとして、よくWikipediaのデータを使っています。 ElasticSearchにはelasticsearch-river-wikipediaという便利なプラグインがあり、Wikipediaのデータを簡単に検索可能な状態にできます。このRiverを利用して日本語のWikipediaのデータを入れたので、メモを取っておきます。 まずは、river-wikipediaで日本語のデータをインデクシングしてみるまでの説明です。 日本語特有の設定(Kuromojiを利用したインデクシング)などはまた後日。\nプラグインのインストール 対象とするElasticSearchは現時点で最新版の0.90.3とします。 最新版でRiver動かないなぁとつぶやいた影響かどうかはわかりませんが、2013/08/19に最新版のElasticSearchで動作するプラグインが公開されました。\nまずはインストールです。 HPにも書いてありますが、以下のコマンドを実行すればインストールされます。\n$ ./bin/plugin -install elasticsearch/elasticsearch-river-wikipedia/1.2.0 -\u0026gt; Installing elasticsearch/elasticsearch-river-wikipedia/1.2.0... Trying http://download.elasticsearch.org/elasticsearch/elasticsearch-river-wikipedia/elasticsearch-river-wikipedia-1.2.0.zip... Downloading ..........DONE Installed river-wikipedia into /opt/elasticsearch/plugins/river-wikipedia ElasticSearchが起動している場合はプラグインをインストール後、認識させるためにElasticSearchを再起動します。\n日本語Wikipediaのインデクシング 通常は英語のWikipediaがインデクシングされますが、対象となるファイルを変更することで日本語のWikipediaもインデクシング可能です。 手元に日本語Wikipediaのダンプファイルがあるものとします。(ダウンロードはWikipediaデータベースダウンロードのページにあるpages-articles.xml.bz2のファイルです)\nファイルを指定してインデクシングするには、つぎのcurlコマンドを実行します。 コマンドを実行するとすぐにインデクシングが始まりますので注意が必要です。\ncurl -XPUT localhost:9200/_river/ja-wikipedia/_meta -d \u0026#39; { \u0026#34;type\u0026#34; : \u0026#34;wikipedia\u0026#34;, \u0026#34;wikipedia\u0026#34; : { \u0026#34;url\u0026#34; : \u0026#34;file:/home/johtani/src/jawiki-latest-pages-articles.xml\u0026#34; }, \u0026#34;index\u0026#34; : { \u0026#34;bulk_size\u0026#34; : 1000 } }\u0026#39; ここでURLに含まれる「ja-wikipedia」がインデックス名になります。 また、JSONの\u0026quot;url\u0026quot;にはファイルの場所を指定するため、file:で開始するパスを指定します。 例では、bz2を解凍したファイルを指定していますが、bz2のままのファイルでもOKです。\n上記コマンドを実行すると、_riverというインデックスにつぎのようなエントリが増えています。 (curl -XGET 'localhost:9200/_river/ja-wikipedia/_search?pretty)\n{ \u0026#34;took\u0026#34;: 5, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 2, \u0026#34;max_score\u0026#34;: 1, \u0026#34;hits\u0026#34;: [ { \u0026#34;_index\u0026#34;: \u0026#34;_river\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;ja-wikipedia\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;_status\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;ok\u0026#34;: true, \u0026#34;node\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;gdyvwpiAR52lqUCcRhVwsg\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Blitzschlag, Baron Von\u0026#34;, \u0026#34;transport_address\u0026#34;: \u0026#34;inet[/192.168.100.7:9300]\u0026#34; } } }, { \u0026#34;_index\u0026#34;: \u0026#34;_river\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;ja-wikipedia\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;_meta\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;wikipedia\u0026#34;, \u0026#34;wikipedia\u0026#34;: { \u0026#34;url\u0026#34;: \u0026#34;file:/home/johtani/src/jawiki-latest-pages-articles.xml\u0026#34; }, \u0026#34;index\u0026#34;: { \u0026#34;bulk_size\u0026#34;: 100 } } } ] } } \u0026quot;_id\u0026quot;: \u0026quot;_meta\u0026quot;というエントリがさきほど登録したWikipediaのRiverに関する設定です。 \u0026quot;_id\u0026quot;: \u0026quot;_status\u0026quot;というエントリが起動したRiverの状態になります。\nRiverの停止 日本語Wikipediaは結構サイズが大きく、手元のAirでインデクシングするのに30分程度かかりました。(bz2圧縮されていないファイルで、何もしていない状態)\n途中でRiverを停止したくなった場合は、以下のcurlコマンドを実行します。\n$ curl -XDELETE \u0026#39;localhost:9200/_river/ja-wikipedia\u0026#39; 先ほど設定した_river/ja-wikipediaの情報を削除すると、エントリが削除されたのを検知してRiverが停止します。ログにはつぎのようなメッセージが表示されます。\n[2013-08-26 18:26:50,130][INFO ][cluster.metadata ] [Blitzschlag, Baron Von] [[_river]] remove_mapping [ja-wikipedia] [2013-08-26 18:26:50,130][INFO ][river.wikipedia ] [Blitzschlag, Baron Von] [wikipedia][ja-wikipedia] closing wikipedia river Riverを停止してもそれまでインデクシングされたデータは検索できます。 データはちょっとだけで良いという場合は、先ほどの_riverのデータを削除してください。 (◯件だけ登録したいとかできるかは調べてないです。)\nサイズとかマッピングとか サイズ インデックス前のXMLのサイズが5.7Gのとき、ElasticSearchのインデックスサイズ(Optimize後)は7.2Gとなりました。すこし古いファイルを利用しているため、最新版とはサイズが異なるかもしれません。\nあと、データ数が、1540000件とやけにきりがいいのがちょっと気になっています。。。 bulkのサイズを10000で指定してインデックスしたので、切れてるのかなぁと。\nということは、データが欠落しているような気がするのでRiverの作りの問題なのか、ElasticSearchの問題なのかはちょっと調べてみないとわからないなと。\nマッピング 出来上がったインデックスのマッピング(Solrでいうスキーマみたいなもの)は次のようになっています。\n{ \u0026#34;ja-wikipedia\u0026#34;: { \u0026#34;page\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;category\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;disambiguation\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;boolean\u0026#34; }, \u0026#34;link\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;redirect\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;boolean\u0026#34; }, \u0026#34;special\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;boolean\u0026#34; }, \u0026#34;stub\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;boolean\u0026#34; }, \u0026#34;text\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;title\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } } } } Wikipediaの各種データが上記のフィールドに入っています。 また、マッピングタイプはデフォルトで「page」というタイプになっています。\n検索 先ほどのマッピングを元に検索すればOKです。例えばつぎのような感じです。\ncurl -XPOST \u0026#39;localhost:9200/ja-wikipedia/_search?pretty\u0026#39; -d \u0026#39; { \u0026#34;size\u0026#34; : 3, \u0026#34;script_fields\u0026#34;: { \u0026#34;title_only\u0026#34;: { \u0026#34;script\u0026#34;: \u0026#34;_source.title\u0026#34; } }, \u0026#34;query\u0026#34; : { \u0026#34;query_string\u0026#34;: { \u0026#34;default_field\u0026#34;: \u0026#34;title\u0026#34;, \u0026#34;query\u0026#34; : \u0026#34;千葉\u0026#34; } } }\u0026#39; 結果はこんな感じ。\n{ \u0026#34;took\u0026#34;: 51, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 5, \u0026#34;successful\u0026#34;: 5, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 8616, \u0026#34;max_score\u0026#34;: 5.8075247, \u0026#34;hits\u0026#34;: [ { \u0026#34;_index\u0026#34;: \u0026#34;ja-wikipedia\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;page\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;3582\u0026#34;, \u0026#34;_score\u0026#34;: 5.8075247, \u0026#34;fields\u0026#34;: { \u0026#34;title_only\u0026#34;: \u0026#34;千葉\u0026#34; } }, { \u0026#34;_index\u0026#34;: \u0026#34;ja-wikipedia\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;page\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;2352241\u0026#34;, \u0026#34;_score\u0026#34;: 4.94406, \u0026#34;fields\u0026#34;: { \u0026#34;title_only\u0026#34;: \u0026#34;千葉千枝子\u0026#34; } }, { \u0026#34;_index\u0026#34;: \u0026#34;ja-wikipedia\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;page\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;14020\u0026#34;, \u0026#34;_score\u0026#34;: 4.8754807, \u0026#34;fields\u0026#34;: { \u0026#34;title_only\u0026#34;: \u0026#34;千葉千恵巳\u0026#34; } } ] } } 結果を見やすくするため、タイトルだけを「title_only」という表示にしています。 ただ、この検索だと、一見「千葉」できちんとヒットしているように見えますが、ElasticSearchのフィールドの定義はstring型になっています。なので、実は「千」や「葉」だけのデータもヒットしています。 マルチバイト文字は1文字ずつインデックスされてしまい、query_stringというクエリでは、フレーズ検索などができていないためです。\nまとめ プラグインいれて、XMLファイルがあれば、検索できるデータが出来上がるので、 暇があったら、お試しで触ってみるデータを簡単に入れてみてはどうでしょうか。\nただ、いくつか気になる点も。\n日本語が検索しにくい(string型のフィールドなのでuni-gramっぽくなっている) bulk_sizeの影響で端数が登録できてない(バグ?どうなの?) ということで、ちょっと使いにくいかもなぁということで、つぎはKuromojiを利用してインデックスしてみてみようかなと。次回のエントリで書く予定です。\n","date":1377226920,"dir":"post/2013/","id":"3931327ed463d1568868c5ab8e839148","lang":"ja","lastmod":1377226920,"permalink":"https://blog.johtani.info/blog/2013/08/23/index-wikipedia-ja-to-elasticsearch/","publishdate":"2013-08-23T12:02:00+09:00","summary":"久々のブログはElasticSearchネタです。勉強会開催する予定だったりすので、もう少し触っておきたいなと。 お手軽に検索するデータとして","tags":["elasticsearch","wikipedia"],"title":"ElasticSearchにプラグインで日本語Wikipediaデータを入れてみました"},{"contents":"宿題その2?かな。Solr勉強会でCloudera Searchのスキーマ周りってどうなってるの?という質問が出てて、 なんか調べることになってたので、関係しそうなMorphlinesのLoadSolrコマンドを調べてみました。 こいつが、Solrへの書き込みを実行するコマンドみたいだったので。\n(※Cloudera Searchのスキーマの設定方法とかは調べてないです。)\n(※めんどくさかったので、パッケージ名すっ飛ばしてクラス名書いてます。githubへのリンクを代わりに貼ってます。)\nRecord=Solrのドキュメント convert()メソッドにて、MorphlinesのRecord(コマンドの処理するデータの1単位)に格納されているKey-ValueデータをSolrInputDocumentクラスのフィールドとして格納しています。 Recordにもフィールドという概念があり、Recordのフィールド=Solrのフィールドという事みたいです。\nということで、Solrのフィールドは事前に定義しておき、Morphlinesの処理内部でSolrのフィールド名に値を詰めていく感じでしょうか。 別途、sanitizeUnknownSolrFildsというコマンドが用意されていて、Solrのスキーマにないものはこのコマンドを使って、無視するフィールド名に変えたり、雑多なデータを入れるためのフィールド名にするといった処理ができるようです。このコマンド内部で、Solrのスキーマ設定を元に、Solrのフィールドに合致する物があるかをチェックして処理しています。\nSolrへの登録処理は? Solrへの登録処理自体はLoadSolrクラス内部でDocumentLoaderというクラスのload()メソッドを呼び出しているだけでした。ということで、DocumentBuilderクラスを少し調査。\nDocumentLoader IFでした。。。実クラスは次の条件\nSolrMorphlineContextにDocumentLoaderがあればそちらを採用(他の種類はなにがあるんだろ?) なければ、SolrServerDocumentLoaderをnewしたものを利用 2.の場合がおそらくMapReduceではないパターンのloadSolrだと思われます。SolrServerDocumentBuilderはSolrJのAPIを利用して、Solrへデータ登録していく普通のアプリです。(対象とするSolrは外部に起動しているもののはず=FlumeのSolrSinkではこちらを採用かな?)\nSolrへの接続情報とか設定ファイルとかSolrCloud用のZooKeeperとかはSolrLocatorクラスに設定される内容が利用されます。\n1.のパターンは、どうやら、Cloudera SearchのMapReduceIndexerToolのクラスにあるMyDocumentLoaderかなぁと。 こちらは、MapReduceを利用する場合に、利用されてるっぽいです(ちゃんと見てないけど) 内部処理は、HadoopのContext.writeメソッドにでSolrInputDocument(=MorphlinesのRecord)を書きだして、ReducerでSolrOutputFormatでインデックス作成の流れかなと。たぶん、MorphlineMapRunnerあたりを読みこめば解読できるかと。 ちなみに、こちらは、2.とは異なり、SolrLocatorの設定は無視されそう。\n感想+妄想? ということで、Morphlinesのデータ流れを考える上で、現時点ではSolrのスキーマを頭の片隅に置きつつ、 Recordの中にあるデータをゴニョゴニョしてデータを形成していくって感じになりそうです。 うまく処理できなかったものとかのカウントとかもとれたりするのかなぁ?とか、また色々と気になるところが出てきますが、一旦ここまでで。。。(だれか、続きを調べて書いてみてくれてもいいんですよ!コマンドもいっぱいあるし!)\nとまぁ、こんなかんじでMorphlinesをちょっとだけ読みました。 よくよく考えたら、こんなの作ったことあるなぁと(こんなに汎用的じゃないけど)。 みんな同じ事考えるんですねぇ。 コマンドパターン?みたいな感じで、I/F決めてSolrとか別のシステムとかにデータ入れる処理を順番に記述できる的なバッチ処理良くかいてます(書いてましたのほうが正解かなぁ)。\n","date":1375434120,"dir":"post/2013/","id":"33e01e2271be22b5ed330045fe6aff50","lang":"ja","lastmod":1375434120,"permalink":"https://blog.johtani.info/blog/2013/08/02/morphlines-loadsolr/","publishdate":"2013-08-02T18:02:00+09:00","summary":"宿題その2?かな。Solr勉強会でCloudera Searchのスキーマ周りってどうなってるの?という質問が出てて、 なんか調べることになって","tags":["Cloudera Search","Morphlines","Solr"],"title":"MorphlinesのloadSolrをちょっとだけ調べてみた"},{"contents":"今朝起きたら、Xperia Zが故障してしまいました。 電源ボタンを押してもスリープにならないんです。しかも、スリープからの復帰もできない。。。\nということで、ドコモショップに行って来ました。対応も良かったです。 やっぱり、ボタンがおかしく再起動してもNGでした。 ということで、トントン拍子で交換品に変更してもらえました。\n2、3回繰り返し言われましたが、データなくなりますよ&交換品なので、復旧はご自分でとのこと。 ドコモショップ行く前に「Sony Bridge for Mac」というSony製のアプリでバックアップ取ってたし問題ないですと回答して、交換してもらいました。 最後に使ってないオプションとか要らないのでやめたほうが安くなりますよなどの提案もいただき満足でした。 さらに、前の機種に貼ってたフィルムもきちんと張り替えてもらえたし。時間はちょっとかかったけど。\nで、先ほど帰宅して、朝とっておいたバックアップから復旧しようとしたら。\n**「そんなバックアップありません」**みたいなメッセージが表示されて復旧出来ません。。。\nえ?なにそれ?と思い、とりあえず現時点のデータをバックアップ取ってみるかと。 バックアップ取ったあとに、再度復旧しようとしたらちゃんとリストがでてくるじゃないですか。\nなんだこれ?ということで、ファイル探しです。。。\n「Sony Bridge for Mac」バックアップファイルは次の場所に保存されるみたいです。\n/Users/ユーザ名/Library/Application Support/Sony Ericsson Bridge for Mac/Backups/製品番号みたいな文字列/日付 この最後のディレクトリが製品番号?ごとのディレクトリっぽく、2つありました。 どうせ初期化された状態だしということで、古い日付フォルダを新しい製品番号のフォルダにコピーしたら復元は可能でした。 壁紙の設定は再起動したら復活しましたが、復活してないものも。。。 復活してないのは以下のものです。\nインストールしてたアプリ ホーム画面の配置 アカウント色々(Google Playとか) ということで、スマホでインストールするのもだるくなってきたので、PCで黙々とGoogle Playのサイトからインストールしてますが、これもだるいですね。。。\n必要なアプリインストールし直したら、またSonyのアプリで復旧してみて、設定が復活するのを祈って。。。\n続き インストールしなおして、ホーム画面での配置をがんばりました。 Google Playのサイトから既存アプリをインストールするときに、ブラウザバックで戻ってたのですが、 一覧から別タブにインストールしたいアプリのページを開きまくってから、インストールボタン押すのが楽でした(半分くらい終わった所で気づいた。。。)\n一通りインストールしたあとに、ホーム画面の配置をやり直して、「Sony Bridge for Mac」もう一回復元。 twiccaやブクログなど、個別にアカウントとか設定を管理しているアプリについては復活しました。\nけど、Androidがアカウントを管理するもの(例:Facebookなど)については、残念ながら、一部のものはアカウントを再登録しないといけませんでした。\n写真や音楽についてはもともとSDカードに入れていたのもあったので、まぁ、被害は少なかったかなぁと。\nただ、iPadやiPhoneの用に簡単にバックアップ(アプリの情報、配置まで)ができて復元できると助かるなぁと思いました。(今度はホーム画面のキャプチャ撮ってから修理に出すかなぁ。。。)\n","date":1375364280,"dir":"post/2013/","id":"cd9ba1f582642d9cbe500f018afab341","lang":"ja","lastmod":1375364280,"permalink":"https://blog.johtani.info/blog/2013/08/01/replace-xperia-z/","publishdate":"2013-08-01T22:38:00+09:00","summary":"今朝起きたら、Xperia Zが故障してしまいました。 電源ボタンを押してもスリープにならないんです。しかも、スリープからの復帰もできない。。。","tags":["Xperia Z"],"title":"Xperia Zが故障したので交換したのでメモ"},{"contents":"Morphlinesについてちょっとだけ、さらに調べました。\n誤解 Solr勉強会でなんとなく私の認識を話しましたが、ちょっと誤解してたみたいです。スミマセン。\n誤解:Morphlineというプラットフォーム/ミドルウェアがありそうなイメージ まぁ、書いてあるのでちゃんと読めって話ですが、Morphlineはあくまでライブラリだということでした。 私はなんとなくManifoldCFのようなミドルウェアorプラットフォームが存在して、 そこにFlumeのSinkとかMapReduceによるIndexerが動作するのかと思ってました。\nまぁ、これが間違いでした。正解のイメージはこっちですね。\n各プラットフォーム(FlumeとかHadoopとか)に組み込んむライブラリで、 それぞれ組み込んだ先でMorphlineの設定を記述することで、パイプライン処理ができるっぽいです。\nFlumeについては、MorphlineSolrSinkというクラスでMorphlineの設定ファイルを読み込み、いろいろ処理出来ます。\nMap/ReduceだとCloudera Searchに含まれてるMapReduceIndexerToolがMorphlineの設定を読み込んでコマンド実行してくれるみたいです。 MapReduceIndexerToolはまだちゃんと読んでないのですが、MapperとしてMorphlineのコマンドが実行されるのかなぁ?という感じです。 (結構入り組んでるので、ちゃんと読まないとわからない。。。)\nということで、Morphlineというプラットフォームがあって、一元的にFlumeやMap/Reduceに対するコマンドをパイプライン化するという話でありませんでした。\n※ちなみに、上の画像ですが、愛用しているNUBoardを使って書いてます。 考えをまとめるのにすごく役立つ一品です。持ち運び可能なノート型ホワイトボードです。\n疑問点 ただ、読んでてまだ不明な点があります。まぁ、ぼちぼち調べるかなぁと。。。\nSolrのschemaはどーなってんの? MorphlineにSolrへロードするコマンド(loadSolr)があるけど、FlumeのMorphlineSolrSinkってのもSolrに書き込みそうだけど? Map/ReduceでSolrに書き込むもMorphlineのコマンドとの違いは?(前にソースを見たときはSOLR-1301がベースになっていて、SolrOutputFormatってクラスがEmbeddedSolrServer起動してインデクシングしてた) GoLiveってなんだろ?(MapReduceIndexerToolに入ってて、M/Rでインデックス作ったあとにSolrのクラスタに配布+マージするやつっぽい) どんなコマンドがあるの?(Cloudera Morphlines Ref Guide) 以下は、参考資料と参考資料にあるSlideshareの資料を一部訳したものになります。\n参考資料 Using Morphlines for On-the-Fly ETL(slideshare) cloudera/cdk/cdk-morphlines(github) メモ 現在のコマンドライブラリ(スライド 18-19ページ) Solrへのインテグレートとロード フレキシブルなログファイル解析 1行、複数行、CSVファイル 正規表現ベースのパターンマッチと展開 Avro、JSON、XML、HTMLのインテグレーション Hadoop シーケンスファイルのインテグレーション SolrCellとApache Tikaパーサすべてのインテグレーション Tikaを利用したバイナリデータからMIMEタイプの自動判別 動的Javaコードのスクリプティングサポート フィールドの割り当て処理、比較処理 リストやセット書式のフィールド処理 if-then-else条件分岐 簡易ルールエンジン(tryRules) 文字列とタイムスタンプの変換 slf4jロギング Yammerメトリックとカウンター ネストされたファイルフォーマットコンテナの解凍 などなど プラグインコマンド(スライド 20ページ) 簡単に新しいI/Oや変換コマンドが追加可能 サードパーティや既存機能のインテグレード CommandインタフェースかAbstractCommandのサブクラスを実装 Javaクラスパスに新規作成したものを追加 登録処理などは必要ない 新しいプラグインコマンドとして考えられるもの(22ページ) RDBやKVSやローカルファイルなどの外部データソースをレコードにjoin DNS名前解決とか短縮URLの展開とか ソーシャル・ネットワークからリンクされたメタデータのフェッチ(??) レコードの感情分析とアノテーション? 31ページの図がわかりやすいかも\n以上。\n","date":1375265520,"dir":"post/2013/","id":"b875f24d3d444fdda82b6bbfb75a4c92","lang":"ja","lastmod":1375265520,"permalink":"https://blog.johtani.info/blog/2013/07/31/introduction-morphlines/","publishdate":"2013-07-31T19:12:00+09:00","summary":"Morphlinesについてちょっとだけ、さらに調べました。 誤解 Solr勉強会でなんとなく私の認識を話しましたが、ちょっと誤解してたみたいで","tags":["Cloudera Search","Morphlines","Solr"],"title":"Morphlines入門?"},{"contents":"不定期開催ですが第11回Solr勉強会を主催しました。\n今回も大入り90人くらい?の参加者の皆さんがいらっしゃいました。ありがたいことです!(20時時点で最終的に補欠17人でした。)\nとりあえず、第一報です。このあと懇親会なので。\nということで、帰りの電車でいくつか感想を(忘れちゃうから)。\n小林さんの苦労話は細かいですが、結構はまりがちな点を共有していただいたので良かったかなぁと。 Solrのexampleの設定とか、ManifoldCFとかちょっとずつ罠があったりするので、あるあるネタはありがたいと思いますw\nCloudera Searchについては、安定の嶋内さんの喋りに圧巻でした。検索だけの視点とは異なる観点についての 話は私には足りないしてんだったりするので参考になります。 なんか、気づいたらMorphlineやスキーマ周りを調べてブログ書くことになっちゃったけど。。。 一つ質問しそこねたのがあって、Cloudera社は基本的に公開したOSSについてのトレーニングも立ち上げているイメージです。Cloudera Searchについてもトレーニングが立ち上がるのかなぁと密かに期待をしてみたり(予算の関係上参加できるかは不明ですが。。。)\n牧野さんの話は画像系について、私は詳しくないので、また関口さんのalikeと比較とかしてもらえると面白いかなぁと。とりあえず、青いロボットがちゃんと検索できるようになるといいですねww\n秀野さんの空間検索は緯度経度以外のPOLYGONなどを利用した検索で、実は私も知らない機能でしたw\nなとなくは知ってたんですが、そこまでちゃんと検索できるとは!地図以外にも活用できるような気がします(想像つかないんだけど。。。)\n最後は私の発表で、簡単な資料ですみませんでした。しかも発表よりも宣伝が。。。(ブログの宣伝だったりとか。。。) 最後に宣伝した「「ビッグデータ活用を支えるOSS」特集への論文投稿のご案内」もご検討ください!\n懇親会も楽しかったです。また思いついたら開催しますー\n最後に、今回の発表者の皆様、会場提供していただいたVOYAGE GROUPの皆様ありがとうございました!\n以下はいつものメモです。\nManifoldCFのとSolrの組み合わせ(仮)株式会社 ロンウイット 大須賀さん 残念ながら、発熱のため発表は次回に持ち越しに。\n##社内ファイル及びWEBコンテンツの検索システム構築時に苦労したこと ソフトバンクBB㈱ 小林さん\nManifoldCF+Solrを使って社内ファイルの検索システム構築 約1000万ドキュメント さまざまなDCにドキュメントがある クロールジョブのハング。。。 ログをDEBUGにしたら。。。ログファイル150GB。。。 一定時間ごとにAgentをリスタートするバッチを。。。(力技) MCFエラーによるジョブの停止 CONNECTORS-590 エラーが発生して止まったジョブを起動するバッチをcronで。。。 自作リアルタイムインデクシングの問題 MCF使わないでSlaveにインデックス openSearcher=falseだとautoCommitが実行されてもSearcherを再起動しないので検索にでてこない リプリケーションのNW負荷 別DCからのレプリケーションが複数が一度に実施される→ネットワーク負荷が。。。 cronで別々にレプリすることでNW負荷を分散できてるかな。。。 Cloudera Search 入門(仮) Cloudera 株式会社 嶋内さん マサカリ画像がw SolrのコミッターMark Millerさんもジョインしてる ClouderaとHadoop入門とか。 いろいろあるよ、エコシステム 4つの分類。 データの取り込み データの保存 データの活用 Search 検索エンジンなら数十億人が使い方を知ってる(Clouderaのチャールズ・ゼドルースキ) Cloudera Search Hadoopのためのインタラクティブな検索\nCDHとSolrの統合\nOSS!\n利点とか。\nデータ解析にも使えるよね、検索 非構造化データの検索にもいいよね 単一プラットフォームによるコスパ Cloudera Searchの事例 バイオテクノロジー企業で画像検索とか 医療系企業でいろんなログイベントの管理とか Cloudera Searchのアーキテクチャ Flumeでストリーミングで登録 HBaseデータの登録 M/Rでバッチ登録 HueのWebインタフェース Morphlines、HBaseはLinyプロジェクトのもの\nSolr使うならCDH!!\nQA Q:デモで使われたTwitterの検索のデータ料とかは?\nA:デモ環境ですので小さい。\nQ:スキーマってどうするの?\nA:スキーマは。。。私が書こうかなぁ、ブログ。。。\nコンピュータビジョン 株式会社 Curious Vehicle 牧野さん 色々やってます コンピュータビジョンの説明(某ネコ型ロボットのいろんな画像がw) 画像検索の流れ 特徴情報の抽出 特徴情報のクラスタリングによるword化 Solrによる画像情報の検索 1. 特徴情報の抽出 SIFT特徴点解析 グレースケールしてからSIFT 注意!SIFTは商用ライセンスが必要です 2. 特徴情報のクラスタリングによるword化 K-meansでクラスタリング クラスタ情報をヒストグラム化してSolrへ 3. Solrによる画像情報の検索 物体認識ベンチマークセット(ケンタッキー大)を使って。 やっぱり良し悪しある。データセットに特化したチューニングしてます。 つぎのステップ 文字認識とか顔認識 つぎはドラえもんじゃねぇ、検索とかも。。。 ガウシアンによる画像ぼかしの例 QA マイク回しててメモ取れず。。。\n国土交通省のデータをSolrで検索 株式会社ネクスト 秀野さん スライドはこちら\n評価の関係で。。。 Spatial検索の話 デモの想定機能 地図上の小学校を起点に物件検索 地図上をクリックしたところを中心に検索 デモ環境 Solr4.3.0、PostGIS 2.0.3、東京都のデータ 事前知識 ジオメトリーデータ(点、線、面がある) WKB/WKT、Intersects(しらなかった。こんなのもあるのか) 環境 EC2上にPostGIS+Solrで構築 WKT形式でDIHでインポートできるらしい。 Solr+S3をJSでGoogleMapへ Solr 4.4新機能をちょっと紹介 @johtani 紹介というよりも宣伝。。。\n","date":1375107300,"dir":"post/2013/","id":"59d1b7206e7664e76672d3de4dc9a8ed","lang":"ja","lastmod":1375107300,"permalink":"https://blog.johtani.info/blog/2013/07/29/study-of-solr/","publishdate":"2013-07-29T23:15:00+09:00","summary":"不定期開催ですが第11回Solr勉強会を主催しました。 今回も大入り90人くらい?の参加者の皆さんがいらっしゃいました。ありがたいことです!(","tags":["Solr","Cloudera Search","ManifoldCF"],"title":"第11回Solr勉強会を主催しました。#SolrJP"},{"contents":"Hadoopとか離れちゃってるし、Hive触ったこと無いにもかかわらず参加しました!\n(たまたま近くにいるからって理由なのは内緒で)\n玉川さんの四方山話を聞くのが主目的で参加しました。(ちょっと翻訳が気になってるので)\nイベントページはこちら\n刊行記念イベントにも関わらず、想像以上の人の入りでびっくりしました。Hadoop、Hive界隈はまだまだ人気なんだなぁと。\nプレゼントじゃんけん大会もあったのですが、そうそうに負けてしまったのが悔やまれます。。。\nTeam Geek欲しかったなぁ。もちろん、懇親会まで参加しました。\n以下、いつものメモです。\nHiveの正しい使い方(Cloudera 嶋内さん) 残念ながら、マサカリは持ってなかったです。\nスライドの各所に本の章番号が書いてあるのがうれしい。 Hiveロゴが回ってたのでスライドの時に集中できなかったw Impalaの話も出てきた。 速いけど、色々足りない。Hiveの置き換えじゃないよと。 HiveとImpalaのおいしいとこ取り(セラン 須田さん) スライド:http://www.slideshare.net/sudabon/20130724-oreilly-org\nオンプレだとCDH便利だよと教えてもらう いくつかSlideshareにImpalaの性能評価の資料を上げてある(必要になったら検索で。。。) リリースされたその日に性能評価やってレポート書くとかすごすぎ! 翻訳の四方山話(玉川さん) 翻訳=写経です 締め切り駆動勉強法w 4page/day 自分から電突してオライリーさんに翻訳させてくださいと。 他の方の本が読めない(チェックしちゃうのでw) 動機があるから読めるってのはあるだろうなぁ。 選び方:わくわくするもの、仕事に活きるもの 今年もあと2冊やる予定(Hadoop Operations、Vagrantを翻訳中) 来年の候補(Chefとか) 高可用性HDFSのご紹介(Cloudera 小林さん) スライドにどの版で書いてあったかがわかりやすく書いてある。 3段階の開発フェーズを経てる QJMのお話 Cloudera UniversityとHadoop認定試験(Cloudera 川崎さん) Clouderaデータアナリスト向けトレーニング(3日間、10月日本語で開催予定) Hive、Pig、Impalaなど Data Science入門コースも準備中 出版記念! 8月管理者向け先着20 or 30名にHadoop第3版贈呈予定 先着20名にプログラミングHive贈呈予定 ","date":1374685860,"dir":"post/2013/","id":"1b9c5ae60ec46be64a1877f0c6920edc","lang":"ja","lastmod":1374685860,"permalink":"https://blog.johtani.info/blog/2013/07/25/hadoop-hive-publication-party/","publishdate":"2013-07-25T02:11:00+09:00","summary":"Hadoopとか離れちゃってるし、Hive触ったこと無いにもかかわらず参加しました! (たまたま近くにいるからって理由なのは内緒で) 玉川さんの","tags":["Hadoop","Hive","Cloudera","オライリー"],"title":"『プログラミング Hive』 『Hadoop 第3版』刊行記念セミナーに参加しました! #oreilly0724"},{"contents":"Yokozunaの気になる点というか、自分だったらこのへん調べるだろうなって観点を上げてみます。 別に調べるわけじゃないので、完全に自己満足なメモですけど。\nちなみに、分散システムとかRiakの仕組みは詳しくないので、ズレてる点がいっぱいあるかも。\nというか、分散システムでテストというか、検討する点とかってまとまってる資料とかあるのかなぁ?\nスキーマ変更時の挙動 フィールド型変更とか、フィールド追加とか 既存RiakクラスタにYokozunaの機能を追加する方法と制限 タイムラグとかも Riak+Yokozunaクラスタに対してノード追加時に発生するオーバーヘッド(ネットワークとかディスクIOとか) 性能検証のためのシナリオ(どっちが先に悲鳴をあげるかとか) Riakメインで、Yokozunaはおまけ程度に検索するというシナリオ Yokozunaメインで使うシナリオ 更新が多い場合のシナリオ Riakのみ、Riak+Yokozunaの各種統計情報(CPU、メモリ、ディスクサイズ、ネットワークIO) 運用系(監視とか)の手法とか機能?とか バージョンアップなどの対応方法 Solrがコケた時とかの対処 とりあえず、こんな感じかなぁ。\n","date":1373474580,"dir":"post/2013/","id":"50557b455cba1a3ce9b4555fc3fd5433","lang":"ja","lastmod":1373474580,"permalink":"https://blog.johtani.info/blog/2013/07/11/yokozuna-check-point/","publishdate":"2013-07-11T01:43:00+09:00","summary":"Yokozunaの気になる点というか、自分だったらこのへん調べるだろうなって観点を上げてみます。 別に調べるわけじゃないので、完全に自己満足な","tags":["Riak","Solr","Yokozuna"],"title":"Yokozunaの気になる点というかなんというか"},{"contents":"先日、Bashoさんにおじゃましたのもあり、Riak Meetup Tokyo #2に参加しました。\nYokozunaの話も聞けるということで。 懇親会も参加しました。Vさん&リピさんと話し込んじゃってあんまり他の人と話せなかったけど。。。\n以下はいつものメモです。\nFreakOut 久森さん 「Riak環境をプロダクションで構築&運用してみた(仮)」 FreakOutとRTB ディスプレイ広告の新しい配信の枠の話 この人には何出すの?いくらで?みたいな感じ 純広告:表示保証、期間保証など RTB:1回の広告表示ごとに買い付け DSP(デマンド・サイト・プラットフォーム) 広告表示は大体0.1秒で表示しないといけない。この間に色々やってる。 50ms or die.で戦ってます。 RTBはCPUバウンド 多コアを安く並べたい Tokyoなんとかとか使ってた。 スケーラビリティがキツイ(クライアント側でアルゴリズム分散してる) データ解析もしたいけど、検索ができない RTBに適したRiakがうまくハマるのではと。 構成とかとか アプリはPerlなので、PerlでRiakクライアントが必要。Memcached互換とかあると嬉しい。 ProtobufサポートもPurePerlしかなかった。 ないなら、作ろうと。githubに上がってます。このへんかな? 監視はcloudforecastとかでやってる。 課題 Redirectがつらい(haproxy?がつらい?) Setが詰まるとつらい(ケースがまだわからない) 対策1 memcached+Riak 対応2(案) hashからpartitionに直接取りに行くとか まとめ 素のままRiakはちょっとつらい QA 聞き取れたやつだけ\nQ:1台いくら位ですか? A:10万から11万くらい Q:どのくらいの性能ですか? A:同時1000くらいをさばいてる? Q:50ms以下を出すのに、ネットワーク周りで近さとかを考えることありますか? A:国内だと10msあればなんとかなる。それよりもアプリ側のチューニングのほうがまだ重要 Q:Cassandraとか候補に挙がらなかったんですか? A:苦しんでる人が知人にいるので。。。あと、用途的に違うので。 Q:バックエンドとしてはなにを? A:bitcaskにしてる Q:サーバ構成、ネットワーク構成がどうなってる? A:。。。 Q:Redirectとは?RiakがやってるRedirect? A:はい。 Q:他に候補にあがったのは? A:商用のaerospike(これかな?)がスケールできそうだったけど、クライアントがいまいち。。。 感想 広告業界のことをよくわかってないので、微妙にピンときてなかったりもするのですが、以下に素早く返すかって観点でどこに注力して、問題点を潰していくのかってのは面白そうだなぁと。 リクエスト処理の性能がクリアできたらつぎはスケールの観点(ノード追加時の挙動とか)で検証していくんだろうなと。次回の話も聞いてみたい感じです。\nIIJ 曽我部さん、田中さん 「Yokozuna 日本語検索性能を評価しました」 Yokozunaって? Riak+Solrでいいとこ取り データの登録とかはRiakのAPIで。 SolrのAPIが使える。 YokozunaがSolrの分散検索の部分を隠してくれる。 Yokozunaのインストールとか。 SolrのAPIっぽい形で検索できるし、戻りもSolrのXMLっぽいのが出てくるよ。 Wikipediaデータってstoreの性能とか。 Riakのノード32台。(Xeon、メモリ24GB、HDD。。。) yz_extractor:Riakのコンテンツタイプを見てSolrにデータを入れる処理が書いてある。 自分でschema.xmlを書いてYokozunaに指定することもできる。 スキーマの変更とか登録とか。 すでに指定済みスキーマを変更した場合の挙動ってどうなるの? デモではSolrからid取って、Riakからその他のデータを取り出していた。 Rubyでの性能評価 ベンチマークプログラム側の問題が先に影響が出てしまった。 QA Q:Riak単体とYokozunaつかった時でディスク容量がどのくらい増えた? A:ちゃんと調べてないが、10%くらい増えた気がする。 Q:Solr側の設定でstored=trueだけど、falseにしてもいいんじゃないの? A:デモはfalseにしてます。 Q:スキーマってあとから変更できるんですかね? A:まだ良くわかってないです。 Q:ノードの追加、削除時の挙動とかも気になります。 感想 今回はStore性能に関してでしたが、今後は検索性能やシナリオによる性能(KVSの処理メインで、時々全文検索とか、全文検索の処理も結構あるパターンとか)の測定とか、耐障害性とかの観点で調査を進めてもらってSolr勉強会で話をしてもらえると面白そうだなぁと勝手に思ってみたり。 Solr勉強会へのコンタクトお待ちしてます!w\n","date":1373450220,"dir":"post/2013/","id":"146e8ca40c0d37f36eecea822028dd9e","lang":"ja","lastmod":1373450220,"permalink":"https://blog.johtani.info/blog/2013/07/10/riak-meetup-tokyo-no2/","publishdate":"2013-07-10T18:57:00+09:00","summary":"先日、Bashoさんにおじゃましたのもあり、Riak Meetup Tokyo #2に参加しました。 Yokozunaの話も聞けるということで。 懇親会も参加しました。","tags":["Riak","Yokozuna","Solr"],"title":"Riak Meetup Tokyo #2に参加しました。#riakjp"},{"contents":"Solr 4.4に取り込まれる予定のチケットで、気になるものを見つけたのでいつものごとく調べてみました。\n元となるチケットはこちら。SOLR-4897。\nスキーマレス? Solrはschema.xmlにデータの定義(フィールドタイプやフィールドなど)を記述して、データを登録する全文検索システムです。 これまでのSolrではこの設定ファイルを元にデータを登録するフィールド名を決定しており、 変更を行う場合はSolrのコアを再起動するなどの手順が必要でした。(※ダイナミックフィールドはすこし特殊)\nそれだと、Solrを管理するのがめんどくさいですね?という感じで現れたのがSchemaREST APIです。(たぶん。)\nSchema REST API Solr 4.2から導入されたSolrのスキーマに関する情報を提供するためのREST APIです。 4.2で導入されたのはあくまでもschema.xmlの情報を取得するためのAPIでした。 たとえば、Fieldの一覧を取得するとか。\n4.4から、フィールドの追加(変更、削除はできない)ができるようになりました。あくまでも、フィールドの追加で、フィールドタイプなどの追加はまだできません。(できるようになるのかもわからないですが。) フィールドの追加方法などはWikiに記載がありました。\nということで、簡単に試してみることに。\n起動方法 exampleディレクトリの下にexample-schemalessというディレクトリが新設されています。 ここに、スキーマレスモード用の設定がされているファイルが入っているので、こちらを利用します。\ncd $SOLR/example java -Dsolr.solr.home=example-schemaless/solr -jar start.jar ログにいくつかWARNが出ますが、影響の内パス設定ミスなので無視してOKです。\n最初に定義されているフィールドは「id」と「_version_」のみになります。(Schema Browserなどで確認できます。あ、REST APIでもいいですね。http://localhost:8983/solr/schema/fields)\nスキーマの更新 さて、フィールドを追加してみます。 PUTを利用すると1フィールドの追加が可能です。 「fugatext」というフィールド名でフィールドを追加しています。今のところJSONのみ対応みたいです。\n$ curl -X PUT http://localhost:8983/solr/schema/fields/fugatext -H \u0026#39;Content-Type: application/json\u0026#39; -d \u0026#39;{\u0026#34;type\u0026#34;:\u0026#34;text_ja\u0026#34;,\u0026#34;stored\u0026#34;:false,\u0026#34;multiValued\u0026#34;:true}\u0026#39; { \u0026#34;responseHeader\u0026#34;:{ \u0026#34;status\u0026#34;:0, \u0026#34;QTime\u0026#34;:18}} 追加できたかどうかもREST APIで取得してみます。\n$ curl http://localhost:8983/solr/schema/fields { \u0026#34;responseHeader\u0026#34;:{ \u0026#34;status\u0026#34;:0, \u0026#34;QTime\u0026#34;:0}, \u0026#34;fields\u0026#34;:[{ \u0026#34;name\u0026#34;:\u0026#34;_version_\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;long\u0026#34;, \u0026#34;indexed\u0026#34;:true, \u0026#34;stored\u0026#34;:true}, { \u0026#34;name\u0026#34;:\u0026#34;fugatext\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;text_ja\u0026#34;, \u0026#34;multiValued\u0026#34;:true, \u0026#34;stored\u0026#34;:false}, { \u0026#34;name\u0026#34;:\u0026#34;id\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;string\u0026#34;, \u0026#34;multiValued\u0026#34;:false, \u0026#34;indexed\u0026#34;:true, \u0026#34;required\u0026#34;:true, \u0026#34;stored\u0026#34;:true, \u0026#34;uniqueKey\u0026#34;:true}]} 追加できました。 ちなみに、同じフィールド名を追加しようとするとエラーが帰ってきます。\n$ curl -X PUT http://localhost:8983/solr/schema/fields/fugatext -H \u0026#39;Content-Type: application/json\u0026#39; -d \u0026#39;{\u0026#34;type\u0026#34;:\u0026#34;text_ja\u0026#34;,\u0026#34;stored\u0026#34;:false,\u0026#34;multiValued\u0026#34;:true}\u0026#39; { \u0026#34;responseHeader\u0026#34;:{ \u0026#34;status\u0026#34;:400, \u0026#34;QTime\u0026#34;:1}, \u0026#34;error\u0026#34;:{ \u0026#34;msg\u0026#34;:\u0026#34;Field \u0026#39;fugatext\u0026#39; already exists.\u0026#34;, \u0026#34;code\u0026#34;:400}} 設定の違い example-schemalessのsolrconfig.xmlは以下の設定が通常のexampleとは異なるようです。\nschemaFactoryの設定 schemaをAPIから変更可能にする設定です。これまでの変更しない設定の場合はClassicIndexSchemaFactoryを指定します。\n... \u0026lt;schemaFactory class=\u0026#34;ManagedIndexSchemaFactory\u0026#34;\u0026gt; \u0026lt;bool name=\u0026#34;mutable\u0026#34;\u0026gt;true\u0026lt;/bool\u0026gt; \u0026lt;str name=\u0026#34;managedSchemaResourceName\u0026#34;\u0026gt;managed-schema\u0026lt;/str\u0026gt; \u0026lt;/schemaFactory\u0026gt; ... update.chainの設定 更新処理(update関連のリクエストハンドラ「/update」とか)には次のような設定が追加されていました。(1006行目あたり)\n\u0026lt;requestHandler name=\u0026#34;/update\u0026#34; class=\u0026#34;solr.UpdateRequestHandler\u0026#34;\u0026gt; \u0026lt;!-- See below for information on defining updateRequestProcessorChains that can be used by name on each Update Request --\u0026gt; \u0026lt;lst name=\u0026#34;defaults\u0026#34;\u0026gt; \u0026lt;str name=\u0026#34;update.chain\u0026#34;\u0026gt;add-unknown-fields-to-the-schema\u0026lt;/str\u0026gt; \u0026lt;/lst\u0026gt; \u0026lt;/requestHandler\u0026gt; 「add-unknown-fields-to-the-schema」というupdate.chainが指定されています。このchainの定義自体は1669行目くらいに存在します。 (長い。。。)\n\u0026lt;!-- Add unknown fields to the schema An example field type guessing update processor that will attempt to parse string-typed field values as Booleans, Longs, Doubles, or Dates, and then add schema fields with the guessed field types. This requires that the schema is both managed and mutable, by declaring schemaFactory as ManagedIndexSchemaFactory, with mutable specified as true. See http://wiki.apache.org/solr/GuessingFieldTypes --\u0026gt; \u0026lt;updateRequestProcessorChain name=\u0026#34;add-unknown-fields-to-the-schema\u0026#34;\u0026gt; \u0026lt;processor class=\u0026#34;solr.RemoveBlankFieldUpdateProcessorFactory\u0026#34;/\u0026gt; \u0026lt;processor class=\u0026#34;solr.ParseBooleanFieldUpdateProcessorFactory\u0026#34;/\u0026gt; \u0026lt;processor class=\u0026#34;solr.ParseLongFieldUpdateProcessorFactory\u0026#34;/\u0026gt; \u0026lt;processor class=\u0026#34;solr.ParseDoubleFieldUpdateProcessorFactory\u0026#34;/\u0026gt; \u0026lt;processor class=\u0026#34;solr.ParseDateFieldUpdateProcessorFactory\u0026#34;\u0026gt; \u0026lt;arr name=\u0026#34;format\u0026#34;\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd\u0026#39;T\u0026#39;HH:mm:ss.SSSZ\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd\u0026#39;T\u0026#39;HH:mm:ss,SSSZ\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd\u0026#39;T\u0026#39;HH:mm:ss.SSS\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd\u0026#39;T\u0026#39;HH:mm:ss,SSS\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd\u0026#39;T\u0026#39;HH:mm:ssZ\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd\u0026#39;T\u0026#39;HH:mm:ss\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd\u0026#39;T\u0026#39;HH:mmZ\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd\u0026#39;T\u0026#39;HH:mm\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd HH:mm:ss.SSSZ\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd HH:mm:ss,SSSZ\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd HH:mm:ss.SSS\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd HH:mm:ss,SSS\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd HH:mm:ssZ\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd HH:mm:ss\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd HH:mmZ\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd HH:mm\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd\u0026lt;/str\u0026gt; \u0026lt;/arr\u0026gt; \u0026lt;/processor\u0026gt; \u0026lt;processor class=\u0026#34;solr.AddSchemaFieldsUpdateProcessorFactory\u0026#34;\u0026gt; \u0026lt;str name=\u0026#34;defaultFieldType\u0026#34;\u0026gt;text_general\u0026lt;/str\u0026gt; \u0026lt;lst name=\u0026#34;typeMapping\u0026#34;\u0026gt; \u0026lt;str name=\u0026#34;valueClass\u0026#34;\u0026gt;java.lang.Boolean\u0026lt;/str\u0026gt; \u0026lt;str name=\u0026#34;fieldType\u0026#34;\u0026gt;booleans\u0026lt;/str\u0026gt; \u0026lt;/lst\u0026gt; \u0026lt;lst name=\u0026#34;typeMapping\u0026#34;\u0026gt; \u0026lt;str name=\u0026#34;valueClass\u0026#34;\u0026gt;java.util.Date\u0026lt;/str\u0026gt; \u0026lt;str name=\u0026#34;fieldType\u0026#34;\u0026gt;tdates\u0026lt;/str\u0026gt; \u0026lt;/lst\u0026gt; \u0026lt;lst name=\u0026#34;typeMapping\u0026#34;\u0026gt; \u0026lt;str name=\u0026#34;valueClass\u0026#34;\u0026gt;java.lang.Long\u0026lt;/str\u0026gt; \u0026lt;str name=\u0026#34;valueClass\u0026#34;\u0026gt;java.lang.Integer\u0026lt;/str\u0026gt; \u0026lt;str name=\u0026#34;fieldType\u0026#34;\u0026gt;tlongs\u0026lt;/str\u0026gt; \u0026lt;/lst\u0026gt; \u0026lt;lst name=\u0026#34;typeMapping\u0026#34;\u0026gt; \u0026lt;str name=\u0026#34;valueClass\u0026#34;\u0026gt;java.lang.Number\u0026lt;/str\u0026gt; \u0026lt;str name=\u0026#34;fieldType\u0026#34;\u0026gt;tdoubles\u0026lt;/str\u0026gt; \u0026lt;/lst\u0026gt; \u0026lt;/processor\u0026gt; \u0026lt;processor class=\u0026#34;solr.LogUpdateProcessorFactory\u0026#34;/\u0026gt; \u0026lt;processor class=\u0026#34;solr.RunUpdateProcessorFactory\u0026#34;/\u0026gt; \u0026lt;/updateRequestProcessorChain\u0026gt; 使ってるUpdateProcessorはこんな感じみたいです。最後の2つはこれ用じゃないので省略。\nプロセッサ名説明 RemoveBlankFieldUpdateProcessorFactory値がないフィールドは除去 ParseBooleanFieldUpdateProcessorFactoryスキーマに定義されていないフィールドで、値がBooleanとしてパースできたら、Boolean型とする。 ParseLongFieldUpdateProcessorFactoryスキーマに定義されていないフィールドで、値がLongとしてパースできたら、Long型とする。 ParseDoubleFieldUpdateProcessorFactoryスキーマに定義されていないフィールドで、値がDoubleとしてパースできたら、Double型とする。 ParseDateFieldUpdateProcessorFactoryスキーマに定義されていないフィールドで、値がDateとしてパースできたら、Date型とする。(パースの形式がformatで列挙されてる) AddSchemaFieldsUpdateProcessorFactory入力されたドキュメントの中でスキーマに定義されていないフィールド(静的、動的両方)を見つけた時に、フィールドの値の型を元にフィールド型をマッピングする。 とここまで見てきたところで、スキーマレスという名前の意図がちょっとわかったかも。\n定義されてないフィールドを持ったデータを登録 起動時には定義されてないフィールドをもったデータを登録してみます。 boolean型で試してみることに。以下のデータを管理画面のデータ登録画面から登録します。(http://localhost:8983/solr/#/collection1/documents) (タイトルでbooleanってわかりにくいですが)\n{\u0026#34;id\u0026#34;:\u0026#34;change.me\u0026#34;,\u0026#34;title\u0026#34;:true, \u0026#34;price\u0026#34;:1.25, \u0026#34;fuga\u0026#34;:\u0026#34;100,200\u0026#34;} エラーは出ません。で、またフィールド一覧を取得すると。\n$ curl http://localhost:8983/solr/schema/fields { \u0026#34;responseHeader\u0026#34;:{ \u0026#34;status\u0026#34;:0, \u0026#34;QTime\u0026#34;:1}, \u0026#34;fields\u0026#34;:[{ \u0026#34;name\u0026#34;:\u0026#34;_version_\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;long\u0026#34;, \u0026#34;indexed\u0026#34;:true, \u0026#34;stored\u0026#34;:true}, { \u0026#34;name\u0026#34;:\u0026#34;fuga\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;tlongs\u0026#34;}, { \u0026#34;name\u0026#34;:\u0026#34;fugatext\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;text_ja\u0026#34;, \u0026#34;multiValued\u0026#34;:true, \u0026#34;stored\u0026#34;:false}, { \u0026#34;name\u0026#34;:\u0026#34;id\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;string\u0026#34;, \u0026#34;multiValued\u0026#34;:false, \u0026#34;indexed\u0026#34;:true, \u0026#34;required\u0026#34;:true, \u0026#34;stored\u0026#34;:true, \u0026#34;uniqueKey\u0026#34;:true}, { \u0026#34;name\u0026#34;:\u0026#34;price\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;tdoubles\u0026#34;}, { \u0026#34;name\u0026#34;:\u0026#34;title\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;booleans\u0026#34;}]} おー、最後にtitleが追加されてます。他にもfugaやpriceも。(日付は手を抜きました。。。)\n感想 詳細までは追いかけてないですが、こんなかんじです。 フィールド追加が可能になるのはいいんじゃないでしょうか。SolrCloudの機能との関連もあるのかもしれません。ZooKeeperへの出力も実装されてそうなので。\nただ、機械的に出力されたschema.xml(exampleだとmanaged-schemaというファイル)には_「DO NOT EDIT」_との記述があるので、修正するとなにかおきてしまうかもしれないですねぇ。 現時点では、フィールドタイプの変更やフィールドの更新、削除に関してはSolrCoreの再起動などの手順が必要です。 あと、変なデータ(タイプミスとか)が登録されたりしないかってのは気になりますね。\n※ちなみに、別の人が気づいたんですが、ちょっとバグが有ったみたいで、代わりにチケットつくったらキリ番(SOLR-5000) ゲットしましたw\n","date":1372867920,"dir":"post/2013/","id":"a98d42be181c01b8077e060b1b5080ec","lang":"ja","lastmod":1372867920,"permalink":"https://blog.johtani.info/blog/2013/07/04/schemaless-example/","publishdate":"2013-07-04T01:12:00+09:00","summary":"Solr 4.4に取り込まれる予定のチケットで、気になるものを見つけたのでいつものごとく調べてみました。 元となるチケットはこちら。SOLR-4897","tags":["Solr"],"title":"スキーマレスモード?(SOLR-4897)を調べて見ました。"},{"contents":"SolrのチケットをML経由で眺めてるんですが、便利そうなチケットが流れてきたのでブログを書いてみみようかと。 元になってるチケットはこちらです。昨日だか、今朝にtrunkとbranch_4xにコミットされたみたいです。試してみたい方は、branch_4xかtrunkをチェックアウトすると触ることができます。\nデータ登録用の画面(JSON) branch_4xをチェックアウトしてexampleを起動し、Solrにアクセスします。\n管理画面に「Dcuments」という項目が追加されてます。開くとこんなかんじです。\nなんと、デフォルトはJSONになってます。これも時代の流れでしょうかw\nSolrでは、これまで設定ファイルやデータ登録もXMLがメインになっていました。(Apache Solr入門もXMLを基本に書いてます。このころはまだデフォルトでは対応してなかったので)\n登録するデータをテキストエリアに記述して、「Submit Document」をクリックすればデータは登録されます。基本的には単件登録の画面でしょうか。 (登録されたデータを確認するには「Query」画面を利用すればいいです。) また、JSONのデータ形式はSolrのWikiを参照してください。\nCSVやXMLも この管理画面ではJSON以外の形式でもデータの登録が可能です。 「Document Type」の項目をクリックすると以下のように選択肢があられます。\nCSV、XMLについては、先ほどのJSONの画面の用に、テキストエリアが表示されます。 テキストエリアにCSV(データの形式はこちら)やXML(データの形式はこちら)を入力してボタンを押せば登録できます。\nSolr Command形式も(JOSNかXML) Solr Command というのはXMLやJSONで登録、コミット、削除などを実行するための画面になります。 JSONのコマンドはこちら、XMLのコマンドはこちらをご覧ください。\nあと、便利なのがファイルアップロードです。 こんなかんじで、ファイルを選んでSubmitすればデータが登録出来ます。\nファイルのサイズが大きいとちょっと時間がかかりますが、コマンドを打つより簡単かもしれません。 post.jarツールと違って、デフォルトでコミットをしてくれるわけではないので、「Extracting Req. Handler Params」に「commit=true」をつけないと、データが登録されてない?と思ってしまうかもしれませんが。\n組立もできるみたい(Document Builder) 最後に紹介するのが「Document Builder」というタイプです。\nもっと簡易にデータを記述できるようにということで用意されているようです。 フィールドの情報はSolrに接続して利用できるフィールド?(ダイナミックはないのかな?)が表示されます。\n追記していくとこんなかんじになります。\n日本語のデータもちゃんと登録できました。 ただ、まだ、開発中なんでしょうがないかもしれませんが、以下の様な制約があるようです。\nmultiValuedなフィールドに値を追加できない(上書きされる) 改行が入ったデータをテキストエリアにいれると「Add Field」を押しても反応しない ダイナミックフィールドは自分で書きましょう ただ、これまでXMLでファイルを作ってコマンドで登録したり、curlコマンドでJSON書いたりして登録していたよりはお手軽にさわれるようになるかと思います。つぎの4x系のバージョンが出たときはこちらからデータを登録してみてください。\n","date":1372318080,"dir":"post/2013/","id":"ecf3ac80454654d990d9c07d33d35d1c","lang":"ja","lastmod":1372318080,"permalink":"https://blog.johtani.info/blog/2013/06/27/upload-docs-solr-admin/","publishdate":"2013-06-27T16:28:00+09:00","summary":"SolrのチケットをML経由で眺めてるんですが、便利そうなチケットが流れてきたのでブログを書いてみみようかと。 元になってるチケットはこちらで","tags":["Solr"],"title":"Solrの管理画面でデータ登録"},{"contents":"前回は3番煎じぐらいでしたが、今回は初記事かな?(だといいな)\nKibanaには、前回の記事で書いたものとは別に開発中のKibana3というのが存在します。\nKibana3って? Kibana2はRubyで書かれていましたが、Kibana3はHTML+JavaScriptで構成されています。 ですので、ApacheなどのWebサーバに配置することで、利用が可能となります。 ただ、HTML+JavaScriptのため、ブラウザ上で動作するためブラウザが動作するマシンからElasticSearch(通常だとhttp://マシン名orIPアドレス:9200/とか)にアクセスできなければいけないという制限があります。\nこの条件さえクリア出来れば、Kibana3ではKibana2よりも様々なパネルが用意されていて、色々できそうなのでお勧めです。\nインストール ElasticSearchやログについては、前回の記事の環境を利用しました。 ですので、Kibana3のインストールのみです。(ApacheもCentOSのサーバに入っていたので。)\nダウンロードして、Apacheの公開ディレクトリに置いただけです。(お試し環境のため、権限とかは大目に見てください。\n$ git clone https://github.com/elasticsearch/kibana.git kibana-javascript $ cp -R kibana-javascript /var/www/html 今回はApacheとElasticSearchが同一マシン(=同一IPアドレスでアクセス可能)で動作している+ElasticSearchへのアクセスのポートがデフォルト(9200)のため特に設定が必要ありませんでした。\nElasticSeachサーバとKibana3のApacheのサーバが別のサーバの場合やElasticSearchサーバのポートが異なる場合はkibana-javascript/config.jsファイルの編集が必要になります。 cloneしてすぐのconfig.jsは、以下のとおりです。\n/* elasticsearch: URL to your elasticsearch server. You almost certainly don\u0026#39;t want \u0026#39;http://localhost:9200\u0026#39; here. Even if Kibana and ES are on the same host kibana_index: The default ES index to use for storing Kibana specific object such as stored dashboards modules: Panel modules to load. In the future these will be inferred from your initial dashboard, though if you share dashboards you will probably need to list them all here If you need to configure the default dashboard, please see dashboards/default */ var config = new Settings( { // By default this will attempt to reach ES at the same host you have // elasticsearch installed on. You probably want to set it to the FQDN of your // elasticsearch host elasticsearch: \u0026#34;http://\u0026#34;+window.location.hostname+\u0026#34;:9200\u0026#34;, // elasticsearch: \u0026#39;http://localhost:9200\u0026#39;, kibana_index: \u0026#34;kibana-int\u0026#34;, modules: [\u0026#39;histogram\u0026#39;,\u0026#39;map\u0026#39;,\u0026#39;pie\u0026#39;,\u0026#39;table\u0026#39;,\u0026#39;stringquery\u0026#39;,\u0026#39;sort\u0026#39;, \u0026#39;timepicker\u0026#39;,\u0026#39;text\u0026#39;,\u0026#39;fields\u0026#39;,\u0026#39;hits\u0026#39;,\u0026#39;dashcontrol\u0026#39;, \u0026#39;column\u0026#39;,\u0026#39;derivequeries\u0026#39;,\u0026#39;trends\u0026#39;,\u0026#39;bettermap\u0026#39;], } ); ポート番号が異なる場合は、1つ目の「elasticsearch:」で指定されている「9200」を環境に合わせて編集するだけになります。 Kibana3とElasticSearchのホストが異なる場合は、1つ目の「elasticsearch:」の行をコメントアウトし、2つ目を有効にしてから環境に合わせたURLに修正して保存すればOKです。\n以上で、インストールは完了します。あとは、以下のURLにアクセスするだけです。\nhttp://hogehoge/kibana-javascript/ 画面構成 アクセスすると次のような画面が表示されます。\n初期画面 左上に赤い帯で、「 Oops! Could not match index pattern to any ElasticSearch indices」とエラーが表示されました。\nKibanaはElasticSearchに「logstatsh-年.月.日」という日付ごとのインデックスが存在することが前提となっています。 Kibanaに初めてアクセスした場合、「logstash-当日日付」で始まるインデックスを描画しようとします。 これは、私が前回利用したElasticSearchの環境に古いデータ(試したのが19日、データは10日のみ)しか入っていないために出たエラーです。\n日付は「Options」というエラーが出ている付近の「Absolute」というリンクをクリックすると、特定の日付をカレンダーで指定することができるようになります。データは6/10にしか入っていないので、6/10(12時くらいから20時くらいまで)のを指定します。\n日付指定 選択すると無事データが見えるようになりました。\nデータ描画 ダッシュボードの構成(初期) Kibana3では、この画面をダッシュボードというようです。 このダッシュボードは初期状態では、以下のパーツが表示されています。(子要素があとで説明するパネル名です)\nOptions:描画対象の日付の指定やダッシュボードの保存などを行うRow timepickerパネル:日付の指定 dashcontrolパネル:ダッシュボードの制御(保存とか) Query:ログ検索式を入れるところ stringqueryパネル Graph:ヒストグラムの描画(X軸:時間、Y軸:ログ件数) histogramパネル Events:検索にヒットしたログデータの描画領域 fieldsパネル:表示するフィールドの選択(左側。チェックを入れると右側のログ表示領域のカラムが増える) tableパネル:ログデータ(右側。左側でチェックが入ったカラムだけが表示される。) あくまで初期表示です。各パーツの設定アイコン(歯車のマーク)をクリックすると色々と設定が可能です。 また、「Events」など名称はクリック可能となっていて、クリックすると、そのパーツが折りたたまれた状態にすることも可能です。\n折りたたんだ状態 ダッシュボードの設定 ダッシュボードには独自のパネルを簡単に追加することができます。 ダッシュボードの構成はページの一番上にある「Logstash Search」の設定アイコンをクリックすると設定画面が開きます。\nダッシュボード設定 「New row」にタイトル名を適当にいれて「Create Row」するとあたらしくパネルを追加することができるRowが追加されます。「Rows」の「Move」にある矢印でRow自体の表示場所を上下に移動することも可能です。\nRowの設定 追加した「Hoge」にパネルを追加する場合はHogeの上にある設定アイコンをクリックすると設定画面が開きます。\nRowの設定 ここでKibana3で用意されているパネルの追加ができます。\nPanel追加ボタン パネルを選んでボタンを押せばすぐに表示されます。\nパネルの羅列 こんな感じです。とりあえず、ポコポコと追加してみました。\n利用できるパネルの種類は以下の様なパターンです。 適当ですが、表にしてみました。\nパネル名概要 columnRowの中にパネルを配置するコンテナを用意するためのパネル dashcontrolダッシュボードの保存、保存したダッシュボードの表示などの操作ボタン textmarkdown形式などで記述が可能な文章を表示できるパネル stringquery検索クエリ入力用パネル derivequeriesフィールドと検索式がわかれた形式の検索入力用パネル timepickerログ表示の期間を指定するパネル histogramログの件数のヒストグラム表示用パネル hitsヒット件数表示用パネル pieパイチャート表示用パネル trends指定された時間でデータの増減を%表示するパネル sortソート条件指定用のプルダウン表示用パネル(変更したらtableの内容がソートされる) tableログデータ表示用パネル fieldstableパネルに表示するフィールドを選択するための補助パネル bettermapなんか地図が出てきたパネルGeoJSONデータをゴニョゴニョ(表示かな?)できるみたい mapなんか世界地図が出てきたパネル2文字の国コード(jaとかか?)かU.S.の州コードのデータを元に地図に色をつけるのかな? これらのパネルは個々に色々と設定が可能です。他にもdebug、map2など有りそうでしたがまだ使えないみたいです。\n適当に触ってて気づいた注意点です。\ntableは1ダッシュボードで1つだけが良さそう。 2つあると、どちらかにしか描画されない。columnに入れるとグルーピングできたりするのかなぁ? stringquery、timepickerも1ダッシュボードで1つが良さそう。 これもtableと似たような理由です。 ダッシュボード保存し忘れて泣きそうになる JSで実装されてて、自分で色々とカスタマイズできるのですが、保存するのを忘れて泣きそうになりましたw カスタマイズしたダッシュボードについては、ローカルに保存する以外にElasticSearchにも保存ができるみたいです。チームで共有することもできそうです。 derivequeriesを表示するとグラフがカラフルに derivequeriesを追加したらグラフが急にカラフルになりました。 どうもderivequeriesのFieldの部分を変更すると、そのフィールドの値を元にグラフを細分化してくれるようです。色の数の上限はderivequeriesのLength属性の数値で制御出来ます。(5だと5個まで色が出る) histogramのパネルで自分でクエリを記載することも可能です。ただ、derivequeriesのフィールド変更すると書き換わっちゃいます。。。 derivequeriesを追加したらカラフルに ヒストグラムは色々なパターンのグラフを描画できました。ラインによる描画(histo1)、総数を100%としたパーセンテージでの表示(histo2)、ライン+点による描画(histo3)などです。\nヒストグラムのいくつかのパターン 感想 ということで、適当にですが触ってみました。 Kibana2はApacheのアクセスログとかの表示しかできない感じがしましたが、Kibana3だといろいろなデータを描画できそうだなと。 logstash形式のインデックスを用意するのが前提になってるので、時系列データをグラフ描画するのに向いてるんでしょうか。 お手軽にグラフ化できるし、自分でダッシュボードをカスタマイズできるのは素敵です。 ただ、クエリとグラフの関係などはちょっと癖があるかもしれないので、色々と試してみないといけないかもしれないです。 (たとえば、特定のフィールドの値について「A、B、その他」みたいなグラフの描画とかをどうするかとか)\n地図の描画は試してみたいかなぁ。\n","date":1371652980,"dir":"post/2013/","id":"26c47355cbe966a94826cbe2fbf2b355","lang":"ja","lastmod":1371652980,"permalink":"https://blog.johtani.info/blog/2013/06/19/introduction-kibana3/","publishdate":"2013-06-19T23:43:00+09:00","summary":"前回は3番煎じぐらいでしたが、今回は初記事かな?(だといいな) Kibanaには、前回の記事で書いたものとは別に開発中のKibana3というの","tags":["elasticsearch","kibana"],"title":"Kibana3というのもありまして"},{"contents":"ちょくちょく書こうと言いながら、前の記事が1週間以上前になってる。。。\n昨日は、Basho Japanに遊びに行って来ました。 (Riak触ったことないのに。。。Erlangも。。。ゴメンナサイ)\nRiakにSolrを組み合わせたYokozunaというものの名前を最近耳にしていたので、どんなものなのかなぁと興味がありまして。Solrがどんな使い方をされているのかってのが気になったので、 情報交換したいなぁと思っていたところ、Vの人が調整してくれたので色々と有意義な話ができたかなぁと。 (Yokozunaについての最新のスライドはBerlin Buzzword 2013のものがここに) Twitter上で見かけたことのある方々と話ができたり面白かったです。(やっぱ英語で会話できたりスラスラと読めるの必要だよなぁと痛感したりもしました。。。)\nということで、遊びに行ったのに美味しいピザやこんなおみやげまでもらってしまいました。 (ピザの写真撮るの忘れてたw)\nRiak&Bashoグッズ ちなみに、Yokozunaですが、Riakに登録したデータを裏で起動しているSolにデータを流しこんでくれるものになります。 Solrの機能としては分散検索(Distributed Search)と呼ばれる仕組みを利用しているようです。 YokozunaのI/Fとしては、Solrのインデックスの分散構成は隠してくれていて、かつ、Solr(っぽい?)リクエストを投げれば裏の分散構成に問い合わせた結果をSolrのレスポンスの形で返してくれます。 KVSに全文検索の機能がついてくるお得感が満載な気がしますw。\nRiak自身のデータの取り扱いがどんなものかをまだちゃんと理解していないので(ゴメンナサイ。Little Riak Bookは開いてるんですが読んでなくて。。。)またおじゃましてもう少し情報交換したいかなぁとw。\nCloudera Searchといい、Yokozunaといい、Solrを利用したものが少しずつ増えてきて嬉しい限りです。 Solrの作りがしっかりしている?活発?、だから取り込む形が多いんですかねぇ。 Solr本を書いてから数年たちますが、やっと検索のニーズが出てきたのかもしれないなぁと思ってみたり。 (流れのつながりはあまりないですが)ElasticSearchも少しずつ人気が出てきてるし、日本語の本とかのニーズあったりするかなぁ?\n","date":1371603780,"dir":"post/2013/","id":"33919e866426ce8e7b2ce06f19bbf889","lang":"ja","lastmod":1371603780,"permalink":"https://blog.johtani.info/blog/2013/06/19/visited-basho/","publishdate":"2013-06-19T10:03:00+09:00","summary":"ちょくちょく書こうと言いながら、前の記事が1週間以上前になってる。。。 昨日は、Basho Japanに遊びに行って来ました。 (Riak触ったこ","tags":["Riak","Basho","Yokozuna","Solr"],"title":"Basho Japanに遊びに行きました"},{"contents":"Lucene/Solr 4.3.1のRCのVoteが始まっていますが、そのMLできになったコトがあり、ちょっと調べたので メモを残しておきます。\nマルチコアの設定ファイルであるsolr.xmlの記述方法と、コアの探索ロジックが4.4(実装的には4.3から入っている)から変更されるようです。4.x系の最新版である、branch_4xのexampleディレクトリにあるsolr.xmlも新しい記述に変更されていました。\n参考URL 新しいCore探索(4.4以降) 新しいsolr.xml(4.4以降) 4.3までのsolr.xml ちなみに、最後のold styleと呼ばれる4.3までの記述方法はつぎの5.0ではDeprecatedになるようです。(5.0がいつ出るのかはわからないですが。)\nCore探索ロジック 4.4から、$SOLR_HOMEディレクトリ以下の探索ロジックは次のようになるようです。 以下では、「新スタイル」(4.4以降の書式)、「旧スタイル」(4.3以下の書式)として記述します。\nsolr.xmlファイルの存在チェック solr.xmlが存在しない場合→旧スタイルとして処理→3へ(旧スタイル) solr.xmlが存在し\u0026lt;cores\u0026gt;タグが存在しない場合→2へ(新スタイル) solr.xmlが存在し\u0026lt;cores\u0026gt;タグが存在する場合→3へ(旧スタイル) 新スタイルのロジック SOLR_HOMEディレクトリに存在するディレクトリについて以下の処理を繰り返す SOLR_HOME/ディレクトリ/core.propertiesファイルが存在する→後続処理へ。存在しなければ終了 SOLR_HOME/ディレクトリ/conf/solrconfig.xmlを読み込み、コアを起動 旧スタイルのロジック これまで同様、solr.xmlの\u0026lt;core\u0026gt;タグの記載内容を元にコアを起動(instanceDir以下のconf/solrconfig.xmlを使って) solr.xmlが存在しない場合はSOLR_HOME/collection1/conf/solrconfig.xmlが存在するものとしてコアを起動 このようなロジックになります。\nちなみに、以下の場合はエラーとなりSolrは起動しますがログや管理画面にエラーである表示がされます。\n2.3でsolrconfig.xmlが見つけられなかった場合 3.1で\u0026lt;core\u0026gt;タグが存在しなかった場合(この場合、ログにはエラーが出ません) propertiesに記述できる内容やsolr.xmlの記述内容については、Wikiを見てもらうということで。。。 CoreAdminHandlerでコアを生成したりした場合に、新スタイルの設定がどのように出力されるのかといった点が気になりますが、また今度にでも。\n","date":1370945460,"dir":"post/2013/","id":"78292d953eafbdf9e57cc4bbbe6e8964","lang":"ja","lastmod":1370945460,"permalink":"https://blog.johtani.info/blog/2013/06/11/new-solr-xml/","publishdate":"2013-06-11T19:11:00+09:00","summary":"Lucene/Solr 4.3.1のRCのVoteが始まっていますが、そのMLできになったコトがあり、ちょっと調べたので メモを残しておきます。 マルチコアの設定ファ","tags":["Solr"],"title":"新しいsolr.xmlとCore探索ロジック"},{"contents":"もう何番煎じだ?ってくらい書かれてますが、コリもせず書いてみました。 Elasticsearch+Kibanaの環境を作って、タムタムさんのログ生成ツールからApacheのダミーログを流しこんで入れてみました。\n参考URL memorycraftさんのブログ Kibana Elasticsearch fluentd apache-loggen インストールと起動 今回はCentOSへのインストールです。 基本的にはmemorycraftさんのブログの流れのままです。\nelasticserchのインストールと起動 ダウンロードして、起動するだけ。 お試しということで、-fオプションにてコンソールにログ出力。\ncurl -OL https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-0.90.1.tar.gz tar zxvf elasticsearch-0.90.1.tar.gz cd elasticsearch-0.90.1 ./bin/elasticsearch -f Kibanaのインストールと起動 git cloneしてbundleインストール\ngit clone --branch=kibana-ruby https://github.com/rashidkpc/Kibana.git cd Kibana bundle install ruby kibana.rb これで、Kibana+ESのインストール+起動が完了。 下地が完了。\ntd-agentのインストールと起動 ログの流し込みはlogstashなのですが、fluentdのelasticsearchプラグインにて流しこむこともできます。 td.repoとしてtd-agentのリポジトリを登録してから以下を実行します。\nyum install td-agent -y /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-elasticsearch vim /etc/td-agent/td-agent.conf /etc/init.d/td-agent start これで、td-agentがインストール出来ました。 次は設定です。\n\u0026lt;source\u0026gt; type tail format apache path /var/log/httpd/dummy_access_log tag dummy.apache.access \u0026lt;/source\u0026gt; \u0026lt;match *.apache.*\u0026gt; index_name adminpack type_name apache type elasticsearch include_tag_key true tag_key @log_name host localhost port 9200 logstash_format true flush_interval 10s \u0026lt;/match\u0026gt; 以上が設定です。td-agentはtd-agentというユーザで起動されるので、/var/log/httpdディレクトリにアクセスできるかだけ確認が必要です。\nいくつかの設定値について気になったので調べました。\nindex_name:adminpackとなってるが、elasticsearchではlogstash-xxxとなってる。 これは、logstash_formatがtrueの場合は、利用されないので、指定しなくてもいい。 type_name:Elasticsearchのタイプ名 * これはlogstash_formatを指定しても有効。ただし、Kibana側で画面からのtype指定は不可能。KibanaConfig.rbにて指定することは可能。 logstash_format:Kibana用にlogstashフォーマットで出力するオプション この指定があるときは、index名が「logstash-YYYY.mm.dd」となる record(ログ)に@timestampとして時刻が追加される。 tag_key:include_tag_keyがtrueと指定されているため、record(ログ)にtag_keyで指定した文字列をキー、値としてtagの値(上記例だとdummy.apache.access)が付与されて登録される。 apache-loggenのインストールと起動 タムタムさんが作成されたApacheのログのダミーを生成するツールです。\ngem化されてるので、インストールは非常に簡単です。\ngem install apache-loggen で、ログを出力します。出力先は先程設定したdummy_access_logです。\napache-loggen --rate=10 --progress /var/log/httpd/dummy_access_log 秒間10アクセスログを出力してくれます。 これで、Kibanaでログが見れるようになりました。 なんて簡単なんでしょう。。。 簡単なログの検索ができてしまいました。 他の形式のログがどうなるのかとかは、また時間があれば。。。\n感想とか 非常に簡単でした。素敵です。いくつかこうなるのかな?というのを試してみたのでメモを。\nいくつか疑問点です。\n溜まったログの削除は手動? おそらく。日付ごとにindexが出来上がっているので、削除は楽そう。「logstash-年月日」なので。 認証とかかけれるの? ログ検索は内部でするだろうから、まぁ、なくていいのかな。ログインすらないし。 複数行のログとかってどーすんだろう?(JavaのExceptionとかが混ざるやつ) 本格的に触るようになれば調べるかなぁ。。。\nあと、ログが増えてきた時にどういった分割構成ができるだろう?って思って考えてみたのが以下になります。\n構成パターン ログを複数扱う場合は次のようなパターンがありそうかと。\nタグ(fluentdのタグ)で識別 「@log_name」という名前=fluentdのタグにてログを識別することで、異なるログを検索することができそうです。 タグであれば、プラグインによってはログ出力時に制御も可能だと思うので、td-agentの設定を変更したりすることもなく対応が可能かと。 ただ、ログの種別ごとにKibanaのプロセスを別にして起動したいといった用途には向いてなさそうです。\ntype_nameによる識別 ElasticSearchの機能であるtypeを利用したログの識別パターンです。\nfluent-plugin-elasticsearchの設定でtype_nameを指定しました。 ここを別の名前にすることで、識別することも可能です。\nただし、この場合はKibanaの画面から指定して検索することができません。 →コメント頂きました。検索条件に「_type:タイプ名」と検索することでtypeを利用した検索が可能です。\nタグ(@log_name)でも識別できるようにするなどの工夫が必要です。 その代わり、タグ識別ではできなかったKibanaのプロセスを別にして起動することは可能になります。\nKibanaConfig.rbのTypeに値を設定することで、起動したKibanaが対象とするログを絞り込むことが可能です。 こうすることで例えば、apache用のKibanaとtomcat用のKibanaは別プロセスにして、ElasticSearchのクラスタは1つという構成も可能になります。\nElasticSearchサーバを別立て ElasticSearchサーバをそもそも別のプロセスor別のサーバで起動し、Kibanaも別々にすればログの識別も可能です。 可能ですが、色々と管理するものが増えてめんどくさそうですね。。。\nインデックス名変更 最後は、fluent-plugin-elasticsearchの設定で「logstash_format」をfalseにすれば、好きなindex_nameを付与できるので、 ログ種別ごとに名前を変更することで識別できます。\nただ、logstash形式でないインデックス名の場合、日付ローテーションができなかったり、Kibana内部で検索時に日付で検索対象を絞り込んで検索することで高速化するといった処理など、使えない機能が多々出てきてしまうのであまりおすすめじゃないかと。。。\nということで、流行りものは触っておこうということで、さわってブログ書いてみました。\n開発中に立てておいて、各サーバのログを流しこんでおくなどにも利用できるかもしれないです。 アラート通知などの機能が出てくるともっと便利かもしれないです。\n","date":1370874840,"dir":"post/2013/","id":"c4d3a917f623f58646ce93015d79e8e0","lang":"ja","lastmod":1370874840,"permalink":"https://blog.johtani.info/blog/2013/06/10/fluent-es-kibana/","publishdate":"2013-06-10T23:34:00+09:00","summary":"もう何番煎じだ?ってくらい書かれてますが、コリもせず書いてみました。 Elasticsearch+Kibanaの環境を作って、タムタムさんのロ","tags":["kibana","elasticsearch","fluentd"],"title":"apache-loggen + fluentd + elasticsearch + kibana = ログ検索デモ"},{"contents":"昨日に引き続き、AWS Summit Tokyo 2013に行ってきました。\n@ryu_kobayashiさんからパシリを仰せつかるなどあり、忙しかったのですが楽しかったです。\n今日もすごい人出で、昼時の展示ブースは人だかりで、TDの方たち忙しそうでした。 後半はちょっとつかれたなぁ。 1日目よりも空調の温度が上がってたので快適でした。 飲物忘れたので、ちょっと喉がやられ気味でしたが。\nAWSはやっぱり勢いがあるんだなぁってのを実感しました。JAWS-UGまで残った感想です。 あとは、セルフハンズオンに参加するんだったかなぁというのもちょっとあります。あんまり触ったことないんで。\n以下はいつものメモです。\nAmazon Redshiftが切り開くクラウド・データウェアハウス 自己紹介と流れとニュース 6/5からTokyoリージョンでも利用可能に! Redshiftどんなもの? Redshift=クラウド型データウェアハウス オンプレの課題 初期投資、運用管理、費用対効果 EMRと同じで、分析処理向けのサービス 簡単な利用例 各種データストア→S3→Redshift 各種データストア→EMR→Redshift Data Pipelineでデータの流れの処理がかける。 データロードはパラレルに実行可能 バックアップは管理コンソールからボタンででも可能。 クラスタのリサイズも管理コンソールからできるよ。 NRIでの評価 2012年末の限定公開してすぐに先行評価に参加\nRedshiftの性能は?\n500億件からの検索処理(1週間分のデータを抜き出して処理するSQL) 8XLノード2ノードで43秒、4ノードで27.8秒、8ノードで19秒 データロドも線形に性能が上がる 1.2億件の検索処理は4ノードより8ノードのほうが性能劣化 EMRとRedshiftの比較。1.5TB、500億件でのJOIN+集計処理でRedshiftのほうが早かった。 Redshiftのチューニングポイント\nインデックスが存在得ず、Distribution Keyでノードに分散 Sort Keyも重要。データロード時間はSort Keyをつけると遅くなる ニガテなデータ形式もあるよ。EMRとかの組み合わせにすると安く済むこともあるよ\n簡単につくれるので、気をつけましょう。セキュリティとか。統制されないものが乱立してくるんで。\nそこでNRIですよ!(宣伝) 出てきた性能に関するものだけど、「ケース1」「ケース2」とかってなってるので、その部分の詳細が書かれたレポートが公開されないとどんなのがニガテなのかとかわからなかった。\n事例紹介とか オンプレのデータをどうやってRedshiftに持ってくの? インフォテリアのASTERIA WARP GUIツールでデータの変換とかして、S3に持って行って、Redshiftと連携できるよと。 無料セミナーの紹介 6/21、8/2にRedshiftの無料セミナーやりますよ。 インターネット上のユーザーの行動の可視化を実現したAWSによるビックデータ解析基盤 C-Finderのサービス紹介 元オプトの方。C-Finderの紹介。 10万ユーザの行動履歴の可視化。\nサイトに来たけど、行動せずに他サイトに移動したとか、サイトに来る前の状態ってのがわからない。これをC-Finderで可視化。\n例1:自動車業界 ライバル企業の動向を自社と比較したい。 Audi、BMW、ベンツで可視化。 例2:化粧品業界 Web上での化粧品のトレンドが見たい。 @cosmeサイトのPVとかから。 ユーザって会員登録とかしてる人を追っかけてるってことなのかなぁ? よくわかってない。。。\nレポーティングサービスしてたけど、納品まで1ヶ月かかってた。 リアルタイムにみたいという要望が多かったのでASPをTISと開発 ASPサービスの開発したよ AWSで。 可視化というタイトルだったんだけど、期待してた可視化の話ではなかった。。。\nネット選挙クラウド ~オバマ大統領選挙の事例:データ解析からネット募金まで~ ボランティアで構成ってすごいな。 本番まで1年 みんな髭の人だw GoogleとかFacebookとかの人がボランティアで開発に参加。 予算は抑えながら、スケールアップダウンがすぐ出来てとか。 秒間10万回のI/OのDB SQSとEC2のSoftware queueの比較。Softwareキュー選ぶと、さらにドレがいいのかってのを選ばないとい。 AWSにあるサービスなら、造らなくてもいいのではとか。 CloudSearchはつかわなかったのかなぁ? tsunami S3に静的ページをおいて、最後のとりでにしたり。 コードとか、ノウハウってどこまで公開されてるんだろ? 同時通訳もあったんですが、英語を聞いてみようと聞いてましたが、まだまだダメですねぇ。\nパネルディスカッション「ウェブテクノロジーをエンタープライズで活かすには?」 趣旨 B2B、B2C間でのトレンドのやり取りが加速されてるよねと。 ICTはもはやコモディティ? TD太田さん Consumerization Of IT 色々なものがSaaSになってきてる TD:Consumerization of Data Infrastructure オンプレ<AWS<TD 三井物産黒田さん 三井クラウド(プライベート&パブリック) ユビキタス これまで使ってきたものがクラウドで動くのかとかが観点 電通平川さん マーケティングダッシュボードはsalesforceでは厳しかった? ビジネスに注力したいので、柔軟で、質実剛健なICT基盤がほしい。 ディスカッション 新しい技術に対するスタンスは?\nいかにダメな部分を潰していくか(太田さん) R\u0026amp;Dを予算化して評価して取り組んでいく。評価でダメならつぎ。(黒田さん) 消費者の方たちがネットですごい勢いで活動してる。その人達へのアプローチが重要。(平川さん) コンシューマ系技術の懸念事項は?\nセキュリティ面。レベルがある。自分の所だけじゃなく、クラウドベンダーと二人三脚が必要。丸投げはNG(黒田さん) セキュリティ面の攻撃を受けたつぎの手をどう打つかが重要。堅牢性上げると、ユーザビリティが下がる。(平川さん) 法規制的に出せないとかもある。持ちきれないデータもあるよね。(太田さん) 何を見分けてどうやって取り組むか?\nとりあえず、やってみる。そこで見える課題に対応していく。見極めるのは難しい(平川さん) ということは、すぐに出来る環境ってのは当たり前になってますよね。\n尖った技術=セキュリティ面が弱い?みたいな印象があるのかなぁ?\nJAWS-UG AWSアップデート AmazonのCTO登場 Game Day Game Day。土曜日にやるよ。 障害を発生させて、それを復旧させる。 最もひどい壊し方をしたらかちw 最後はかるくボッチでした。。。 AWSあんまり使ってないからなぁ。。。\n","date":1370527200,"dir":"post/2013/","id":"d12c1c2a68be4c7fda5a7737d5493b4d","lang":"ja","lastmod":1370527200,"permalink":"https://blog.johtani.info/blog/2013/06/06/aws-summit-tokyo-day2/","publishdate":"2013-06-06T23:00:00+09:00","summary":"昨日に引き続き、AWS Summit Tokyo 2013に行ってきました。 @ryu_kobayashiさんからパシリを仰せつかるなどあり、忙しかったのですが楽しか","tags":["AWS","勉強会"],"title":"AWS Summit Tokyo 2013に行って来ました。(Day2) #awssummit"},{"contents":"ざっとインストールガイドとかCloudera Searchのソース眺めて、テキトーにメモを書いてみました。 (ユーザガイドはまだ読んでないです。)\nざっくりメモ ストリーム処理でインデックス作るときはFlume経由でSolrに SinkとEventの両方が用意されてる?(Flumeを良く知らないので、違いがわからない) FluemeからはリモートのSolrに対してインデックス登録するクラスがある。SolrServerDocumentLoaderがソレだと思う。 バッチ処理でインデックス作るときはMapReduceIndexerToolsってのを使ってSolrに SOLR-1301がベースになっている。色々と改良されてるようだけど、コアとなってる処理はSOLR-1301。 GoLiveってクラスの処理の中で、現在動作してるSolrに配布したバッチで作成されたIndexをマージする処理が書いてある。 HDFSへ出力されたインデックスはリモートのSolrからアクセスするとオーバヘッドとかどーなるのかなぁ? 検索処理自体はHueでもできるけど、基本的にSolrCloud任せ インデキシングの処理のフローについてはCloudera Mrophlinesで定義 ということで、 2つの流れがありそう。\nHDFS→Flume→Solr HDFS→MapReduce→Solr で、まだ、わかってないですが、構成要素として\nHadoop(HDFS):データソース Hadoop(MapReduce):データ変換処理、バッチインデキシング Zookeeper:SolrCloudのクラスタ管理 Solr:インデキシング、検索エンジン Flume:データをストリーミングでSolrへ Coudera Morphlines:HDFSからSolrまでのETLデータ処理を定義実行する環境 って感じでしょうか。 SolrCloudのクラスタとHadoopのクラスタが同一マシン上なのか、別なのかとか。組み合わせがどんなものができるのかがまだわかってないです。 ユーザガイド読んでみたらなにか出てくるかなぁ。\nちなみに、Cloudera SearchのgithubリポジトリにあるソースはCloudera Morphlinesのコードがメインで、SolrのHDFS対応版のソースがあるわけでは無かったです。\nSolrのHdfsDirectoryってのがClouderaのリポジトリにあるSolrには追加されていて、これが、HDFSのインデックスを読み込んだりする処理が出来る仕組みっぽい。 一応、SolrCloud以外(分散検索)も考慮された形になってるっぽい。 ってとこでしょうか。\n感想 読んでて思ったんですが、Cloudera Searchの肝はじつは、検索じゃなくて、Morphlinesにあるんじゃないかなぁと。今はSolrが出力先ですが、 その他のデータ変換処理とかが増えてくると、処理の流れがMorphlinesで定義できてデータ変換処理が簡便になりそうな気が。\nその他に気になる観点 CDH経由でSolrCloudのクラスタの管理するのかな? SolrCloud用のクラスタとCDHのクラスタって同一マシンに載るの?別マシンにもできるの? 併存したらIOがキツそうだけど Hueで検索アプリとか組めるの?(そもそもHueがわかってないんだけど。。。) ま、とりあえず、こんなとこで。 つぎは余力があれば、ユーザガイドかなぁ。 英語力。。。\n","date":1370489160,"dir":"post/2013/","id":"f45069216cd934b80ce882c9a2f2a08a","lang":"ja","lastmod":1370489160,"permalink":"https://blog.johtani.info/blog/2013/06/06/cloudera-search-memo2/","publishdate":"2013-06-06T12:26:00+09:00","summary":"ざっとインストールガイドとかCloudera Searchのソース眺めて、テキトーにメモを書いてみました。 (ユーザガイドはまだ読んでないです。","tags":["Cloudera Search","Hadoop","Solr"],"title":"Cloudera Searchメモ(妄想版)"},{"contents":"AWS Summit Tokyo 2013に行って来ました。\n@cocoatomoさんに行き掛けに出会ったので、アンデルセンの講演を一緒に聞いてました。 TDブースの@ryu_kobayashiさんに挨拶に伺ったりも。\nすごい人で、セッション間の入れ替え時には会場前のスペースが大変なことになってました。もう少し余裕のある建物のほうが良かったのかもしれないですねぇ。\nいつものように以下はメモです。\nRoad to AWS アンデルセンサービス とてもおいしいランチボックスでした。\n広島(ここ重要!)に本社のあるパン屋さん。\n2003年に汎用機からOpenシステムに 内製ではなく外注に。複数のSIerにお願いしてるとデータセンタに マスタ管理と生産管理はオンプレ 2004年に稼動時のネットワーク整備。店舗はISDNで、設定ミスとかを防ぐためにIIJのSMFサービスに PCはレンタル契約にしたので入れ替えを強制できる→レガシーシステムの対応が必要なくなる ネットワーク広帯域化→基本システムにデータセンターに。 2009年にリース満了などで、OSの変更とかミドルの変更という移行SI費用だけで結構な値段が。ものによっては会社もない。 データセンターの月額手数料にして、機器変更などの費用を平準化。仮想化など。 けど、サイジングにどうしても安全係数をかけてしまうことに。結構値段がかかる そこで、今後の方向性 SIerどっぷりのOLTP受発注基幹システムはSIerのホスティングで それ以外のシステムは外に出したい バッチの計算を早くすることができるとノーチラスさんから提案された バッチを外部化するか、性能あげるか。IOネックなどもありスペック上げるとコストになるから、外部化したい Hadoopを組むけど、オンプレじゃなくてAWSにした。ノウハウがないので、ノーチラスさんにお任せした。 AWSのEMRを利用。4時間かかっていたものが40分で。 EDIのサーバを6ヶ月でAWSに移行 S3絡みで2度の問題が。性能劣化があった。 パッケージ開発環境がAWSにあるなら、AWSでも動くでしょ?(NTTイントラマートとか) SIerどっぷりの部分もAWSに持っていく? アンデルセンサービスの部長さんからのAWSへの要望 メールサーバなどの基本サビスとか、コントロールパネルを充実して欲しい。 クラウド技術を活用したリアルタイム広告\u0026quot;Logicad\u0026quot;の入札・配信・ログ解析 Web広告の歴史 最初は広告主がWebサイト単位で契約 アドネットワークによる仲介 聞きそびれた。。。DSP? アドネッエクスチェンジ SSP(Supply Side Platform) リアルタイムビッティング(RTB) RTPの仕組みを説明。 AWSとオンプレでシステムを構築してる。\nSSP事業者との取引はオンプレ 配信はAWS オンプレとAWSはAWS Direct Conectで接続 S3とHadoopの接続が安くなったり速くなったりするらしい。 オンプレミス側 Bidリクエスト:秒間数万件。。。 KVSのユーザ数は3億件。。。 AEROSPIKEというSSD向けのKVSを利用してる AWS側 ログはS3に。溜まったデータは定期的にEMRで解析。DynamoDBに入れてレポート作成 RabbitMQを使ってる。 ELBで外部からのリクエストはバランシング データセンタ間通信 遅延を複数コネクションを貼る方法で回避? 非同期で、複数のMsgとAckをやり取りする。RabbitMQがこれに相当する機能を持ってる QueueとConsumerで多重送信が可能。 配信結果をオンプレ側に送るのにRabbitMQを使ってるのかな? ハイブリッド構成を支えるAWSテクノロジー 聞くつもりだったんだけど、すごい人だったので、諦めて充電してた。\nAWSクラウドで構築する、ワールドクラスの分散クラウドアーキテクチャ エマージングソリューション部の部長のshot6さん。\nマルチAZ(アベイラビリティゾーン)モデル AWS固有のコンセプト。 ELBやDynamoDBやRDS、S3とか。\nマルチリージョンとは違うよと。マルチリージョンは結構難しいので。 マルチリージョンがどんなに大変かをこれから説明。\nマルチリージョンアーキテクチャ(これは別物) 複数のリージョンを利用して作る。 AWSのビルディングブロックではカバーしない範囲をカバーしないとダメとか。 リージョン間の通信は基本的に非同期 ディザスタリカバリ コストバランス見てから決めるよね。 CAP定理とかもいろいろと出てくるよね。 合意プロトコル。正確性、生存性(時間が制限されても大丈夫)、理論的にパフォーマンス出る? 非同期レプリケーションになる(1トランザクション当たりのオーバヘッドが大きいから)けど、復旧の難しさがある。 GlusterFSとかでやってるとこもある。 NetflixはCassandraをクオラム+Geo-Replicationでマルチリージョンを構成してる。 マルチリージョンでのデータ一貫性は維持がむずい 注意点 必要になるまで分散させない。 まずは、マルチAZを考えましょう 物理制限を考慮する 同期型だとタイムラグあるし。 複合障害の伝搬をどう抑えるか。 NetflixはHYSTRIXというのがいて遮断できるようにしている 自動化が重要。ロールバックとかロールアウトとか。 テストをどーするの? 本番環境でアクティブ/アクティブ構成でのテスト。 ちゃんとフェイルオーバするかなどを実環境でやってる。DB落としたり。。。 障害は避けられないので、受け入れて日常に取り込むべきだよねと。\nAmazon.comではGameDay NetflixはChaos Monkey(OSS) Obama for America リカバリーオリエンテッドコンピューティングパターン\nボーアバグ:再現可能なソフトウェバグ ハイゼンバグ:通常ではありえないパターンで発生するバグで、調査が大変 ということで、マルチAZがいいよ 同期式レプリケーションを前提にできる。 アプリ開発者がアプリにフォーカスできる。分散系の難しいところはAWSが隠蔽してくれるから。 ","date":1370424600,"dir":"post/2013/","id":"1fe14e2e02b6e65e6e6e2ae3d8ddcc9f","lang":"ja","lastmod":1370424600,"permalink":"https://blog.johtani.info/blog/2013/06/05/aws-summit-tokyo-day1/","publishdate":"2013-06-05T18:30:00+09:00","summary":"AWS Summit Tokyo 2013に行って来ました。 @cocoatomoさんに行き掛けに出会ったので、アンデルセンの講演を一緒に聞いてました。 TDブースの@ry","tags":["勉強会","AWS"],"title":"AWS Summit Tokyo 2013に行って来ました。(Day1) #awssummit"},{"contents":"Cloudera Searchは次のようなモジュールから構成されています。 これはCloudera Searchのモジュールで、さらにこれらがSolrとかを使ってるみたいですね。pom.xmlを見たら何を使ってるかがわかるかな。\ncdk-morphlines search-contrib search-core search-flume search-mr search-solrcell てきとーに、README.mdみながらメモを残してみました。ソースとかはまだ読んでないです。 ざっと眺めたけど、インデキシング処理の話がメインで、検索側がどうやって動くかってのがわからなかったなぁ。 ユーザガイド(注:PDF)ってのがあるから、これを読んでみるか。。。\n各モジュールについては、以下。\ncdk-morphlines(Cloudera Morphlines) Cloudera Morphlinesという名前みたい。 検インデキシングアプリの構築、変更をラクにするためのフレームワーク。 ETLの処理チェインを簡単にCloudera Searchにデータを入れる設定(Extract/Transform/Load処理)がかけると。 バッチ処理、Near Real Timeのために使えるみたい。検索結果をさらに入れるとかもできるんかなぁ。?\nUnixパイプラインのの進化版みたいなもので、一般的なレコードに対するStream処理から、Flueme、MapReduce、Pig、Hie、SqoopのようなHadoopコンポーネントも使えるみたい。\nHadoop ETLアプリケーションのプロトタイピングにも使えて、リアルタイムで複雑なStreamやイベント処理やログファイル解析とかに使えるの?\n設定ファイルのフォーマットはHOCONフォーマット。AkkaやPlayで使われてる。\ncdk-morphlines-core Cloudera Morphlinesのコンパイラ、実行環境、コマンドのライブラリを含んでる。 ログファイル解析やsingle-lineレコード、multi-lineレコード、CSVファイル、正規表現パターンマッチ、フィールドごとの比較とか条件分岐とか、文字列変換とか色々なコマンドを含んでる。\ncdk-morphlines-avro Avroファイルやオブジェクトの抽出、変換、読み込み処理コマンド\ncdk-morphlines-tika バイナリデータからMIMEタイプを検出して、解凍するコマンド。Tikaに依存\n雑感 Cloudera Searchへのデータの流し込みを設定ファイルに記述して実行するとデータの変換処理とかが記述できるって感じかな? Morphlinesのコマンドとして独自処理や使えそうな処理を作ることで、いろんな処理ができるって感じかなぁ。\nsearch-core Solrに対するMorphlineコマンドの上位モジュール\nsearch-solrcell Tikaパーサを使ったSolrCellを使うためのMorphlineコマンド。 HTML、XML、PDF、Wordなど、Tikaがサポートしてるものがサポート対象。\nsearch-flume Flueme Morphline Solr Sink。 Apache Flumeのイベントから検索ドキュメントを抽出、変換し、SolrにNearRealTimeで読み込むためのコマンド\nsearch-mr HDFSに保存されたファイルに含まれる大量データをMapReduceで処理してHDFS上の検索インデックスに焼きこむモジュール。\nMapReduceIndexerToolは入力ファイルの集合からSolrのインデックスシャードの集合を作るためのmorphlineのタスクで、MapReduceのバッチジョブドライバー。 HDFSにインデックスを書き込む。 動作してるSolrサーバに対して出力されたデータをマージするのもサポートしてる。\nとりあえず、Near Real Time検索するにはFlueme使って、バッチ処理でインデックス焼くのはMapReduceIndexerToolみたいだなぁ。\n","date":1370412720,"dir":"post/2013/","id":"e30258aeb8475d4c27f7935945671856","lang":"ja","lastmod":1370412720,"permalink":"https://blog.johtani.info/blog/2013/06/05/cloudera-search-modules/","publishdate":"2013-06-05T15:12:00+09:00","summary":"Cloudera Searchは次のようなモジュールから構成されています。 これはCloudera Searchのモジュールで、さらにこれらがSolrとかを使っ","tags":["Cloudera","Hadoop","Solr","Cloudera Search"],"title":"Cloudera Searchのモジュールたち"},{"contents":"AWS Summitに来ていたのですが、TLでは、Cloudera Searchが賑わってました。 ということで、軽くどんなものか読んだり調べたりしたメモを残しとこうかと。 英語力はあやしいので、おかしいとこがあったらツッコミを。\nCloudera Searchとは? CDH4.3に対応したCDHユーザ向けの検索システム(beta版)なのかな? CDHに統合された検索フレームワークなのかな?\n基本はLucene/Solr 4.3でHadoopのペタバイトデータを検索することができるようになるみたいです。\nどんな仕組み? 次のものを利用しているようです。(GithubのREADMEから。)\n使ってるもの Apache Solr(4.3.0+α?) Apache Lucene(Solrつかってるからね) Apache SolrCloud(うーん、Solrに含まれるのに別に出してるのなんで?) Apache Flume Apache Hadoop MapReduce \u0026amp; HDFS Apache Tika SolrCellとしてSolrにも組み込まれてる、いろんな文書(WordとかHTMLなどなど)からメタデータと本文データとかを取り出せるライブラリラッパー。実際にはさらにpdfboxとかを使って各文書からのデータを取り出してる。 何ができるの? HBaseやHDFSの用にZookeeperを使ってインデックスのシャーディングや高可用性ができる。(SolrCloudがZookeeperを使ってるからね。) MapReduceのジョブの出力から自動的にSolrのインデックスにデータをマージできるらしい。 Cloudera Managerを使って、デプロイ、設定モニタリングなどが可能。\nFlumeのフィードをつかって、ストリーミングしてインデックスを作れる。FluemeがデータをSolrに流しこむのかな? 将来的にはHiveやHBaseのテーブルをインデックスすることも可能になるらしい。Impalaクエリの結果もフィードできるのか?\nApache Blurってキーワードも出てきた。HDFSのデータからLuceneのインデックス作るのかな? NGDataのチームがSolr/HBaseの統合とかしてるみたい。\n参考URL Cloudera社のブログ Cloudera SearchのFAQ(注:PDF) Githubのリポジトリ ","date":1370412300,"dir":"post/2013/","id":"cd90bce912f5743226af94c1efaaa4a7","lang":"ja","lastmod":1370412300,"permalink":"https://blog.johtani.info/blog/2013/06/05/what-is-cloudera-search/","publishdate":"2013-06-05T15:05:00+09:00","summary":"AWS Summitに来ていたのですが、TLでは、Cloudera Searchが賑わってました。 ということで、軽くどんなものか読んだり調べたりした","tags":["Cloudera","Hadoop","Solr","Cloudera Search"],"title":"Cloudera Searchってのが出たらしい(とりあえず、雑感?)"},{"contents":"憧れ?のfluentを使ってみました。 こちらの記事で紹介したZoomdataを最近触っているのですが、お試しにfluentdでデータ流し込むプラグインを作ってみようかなぁと。(今は、Javaでの接続も書いていて、主にそっちを使っています。) ということで、作ってみました。fluent-plugin-zoomdata。\n基本的にはtagomoris先生のfluent-plugin-growthforecastを参考(パクリ?)にさせてもらいました。 作っている最中もここわからんってツイートに反応していただき、大変助かりました。 私はベースがJavaの人間なので、手探り状態でRubyを書いています。そこおかしいんじゃないの?とかあればコメントもらえると嬉しいです。\nZoomdataのAPI ZoomdataのAPIはこんなかんじで、JSONをHTTPSでPOSTするものになります。\n指定する必要があるものは、以下の項目です。\nsource:Zoomdataのデータ保存先(Zoomdataでのデータを保存する単位。) user:Zoomdataのユーザ名 password:Zoomdataのユーザのパスワード JSONデータ:Zoomdataでグラフ化するデータ sourceはデータ保存先の名称で、この単位でZoomdataはデータを保存、描画します。fluentdのタグをこれにするとわかりやすいかなぁ?と考えていったん、実装してみています。\nで、作成したプログラムを使いつつ、Zoomdataの検証をしたかったので、つぎのような簡単なプログラムを作って動かしてみました。\nサンプルプログラムの構成 基本的にJavaの人なので、クライアントはJavaで書いてます。 CLIプログラムで適当なJSONを作って、fluent-loggerを使って、fluentdに投げ込みます。\nfluentdにfluent-plugin-zoomdataを設定して、localのZoomdataサーバに対してHTTPSでJSONをPostする仕組みです。(初keynote)\n利用しているライブラリなどのバージョンは次の通り\ntd-agent.x86_64:1.1.12-0 fluent-logger:0.2.8 Zoomdata:1.0.3 バグ? で、Zoomdataにいろんなデータを流し込んでみたのですが、つぎのようなエラーが出て、エラーが出力されたあとはZoomdataにデータが流れ込まなくなってしまいました。\n2013-06-03 14:42:33 +0900 [warn]: emit transaction failed error=\u0026#34;SSL_connect returned=1 errno=0 state=SSLv3 read finished A: sslv3 alert handshake failure\u0026#34; 2013-06-03 14:42:33 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/1.9.1/net/http.rb:799:in `connect\u0026#39; 2013-06-03 14:42:33 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/1.9.1/net/http.rb:799:in `block in connect\u0026#39; 2013-06-03 14:42:33 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/1.9.1/timeout.rb:54:in `timeout\u0026#39; 全ログはこちら。\nまだきちんと問題を調査しないでブログを書いています、すみません。\n現象 ログが発生した時の症状です。\nクライアントプログラムは送信が続いており、エラーは出ない td-agent.logに先ほどのエラーが出力 別途type fileにて出力しているログも停止 想像 とりあえず、ログを見た想像、所感です。\n問題の箇所はfluent-plugin-zoomdataからZoomdataサーバへのデータ送信部分 emit処理内部で、HTTPSでデータをPOSTする処理でエラーが起きて リトライ処理とか書いてないので、emitがコケて、その後データが送信されなくなる emitで例外をつかみそこねてるのがあるから止まってる? とまぁ、ちゃんと仕組みを理解しないでRubyとか書くからこうなるんですねぇ。 あとでちゃんと調べて考えて、改良してブログ書きます。\n悩んでいる点、今後手を入れたい点 上記バグとは別に作りの点でいくつか悩んでる点も書いてみます。\nBufferedOutputにしてみたい fluentdのバッファリングを使って、Zoomdataが落ちていても使えるようにしたいと思っているのでBufferedOutputで書くのがいいのかなぁとか。 ちょうどいいスライドがあったので、読みながらまずは中身を理解してみよう。\nZoomdataのsource、userなどの扱い 基本的には設定ファイルで切り替えるのが妥当かなぁと思っています。\nただ、Zoomdataのsourceやuserが増えるたびにfluentdの設定を書き換えて再起動するのかなぁと。userはしょうが無いにしても、sourceは設定じゃない所で切り替えたいなぁと。\nで、切り替えるのにつぎの案があるかなぁと。\nタグで指定(今実装してるもの) メッセージにメタ情報とボディ構造を設ける 設定をどんどん増やす(やりたくない) 1と3はまぁ、いいかと。2.のパターンはどうなのかなぁと。 毎回のメッセージでヘッダ部分が送信されるのはなんだか無駄だなぁというのが否めないので悩ましいところです。1、2の両方対応できるように作るのもありか。\n{ \u0026#34;header\u0026#34;: { \u0026#34;source\u0026#34;: \u0026#34;source_name\u0026#34;, \u0026#34;user\u0026#34;: \u0026#34;userid\u0026#34;, \u0026#34;password\u0026#34;: \u0026#34;userid\u0026#34;, }, \u0026#34;body\u0026#34;: { \u0026#34;label\u0026#34;: \u0026#34;label1\u0026#34;, \u0026#34;count\u0026#34;: 1 } } ということで、fluent触って遊ぶの楽しいですね。Rubyの勉強にもなりそうだし。 ちょっとずつ頑張ってみようかなぁと。 まぁ、まだ私以外にニーズは無さそうなプラグインですが。\n","date":1370234580,"dir":"post/2013/","id":"494557db52824555864d1106278cd1f0","lang":"ja","lastmod":1370234580,"permalink":"https://blog.johtani.info/blog/2013/06/03/fluent-plugin-zoomdata-0-0-1/","publishdate":"2013-06-03T13:43:00+09:00","summary":"憧れ?のfluentを使ってみました。 こちらの記事で紹介したZoomdataを最近触っているのですが、お試しにfluentdでデータ流し込む","tags":["Zoomdata","fluentd"],"title":"fluent-plugin-zoomdata作りました+悩み事とか"},{"contents":"最近、Markdownで文章を書くのに慣れてきました。 ということで、ブログをMarkdownで書けないかなぁと思い、TLの人たちのブログを見たりしていると 「Octopress」というキーワードがあるじゃないですか。 ということで、Github Pages作って、Octopressを使ってブログを書いてみました。 こちらです。\n独自ドメインは昨年から使っているものがあったので、ついでに独自ドメインの設定もしてみました。 ケチなので、.comなどではなく、.infoですが。。。\nということで、徐々にOctopressに移行していこうと考えているところです。 こちらのブログも当面は残しておく予定です。(有料会員は解約して、広告が出る形になると思いますが。。。)\nOctopressでこんなの便利だよとかアレば教えてもらえると助かります。\n","date":1370228038,"dir":"post/2013/","id":"16f10764f0ccce42d5be8cfeac36b446","lang":"ja","lastmod":1370228038,"permalink":"https://blog.johtani.info/blog/2013/06/03/octopress%E3%82%92%E8%A9%A6%E3%81%97%E4%B8%AD/","publishdate":"2013-06-03T11:53:58+09:00","summary":"最近、Markdownで文章を書くのに慣れてきました。 ということで、ブログをMarkdownで書けないかなぁと思い、TLの人たちのブログを見","tags":["misc"],"title":"Octopressを試し中(Jugemより移植)"},{"contents":"昨年から、ブログをどうしようかって話をしていて、そのままになっていたのですが、Octopress+Github Pagesというのがあるらしいと聞きつけて(Twitterで見かけたのかなぁ?)ちょっとやってみました。\n最近は、ドキュメントをMarkdownで記述しようとして癖をつけているのもあり、 ちょうどいい練習になるかなぁと。\nということで、まずは手始めのエントリーでした。 いくつか書きたいこともあるので、調べながら書いていこうかと。 まだ、イメージできてないこと\n画像をどうやって貼るの? About meみたいなのも貼り付けたい bitbucketやTwitterのリンクとかも アフィリエイトも貼る(とりあえずSolr本を) 検索とかは? デザインは? などなど。ちょっとずつ調べていこうかなぁと。 あ、調べたことも書いてくのもありか。\n","date":1370098620,"dir":"post/2013/","id":"dbcc4002c15afefef853a08a0804ba3a","lang":"ja","lastmod":1370098620,"permalink":"https://blog.johtani.info/blog/2013/06/01/first-octopress/","publishdate":"2013-06-01T23:57:00+09:00","summary":"昨年から、ブログをどうしようかって話をしていて、そのままになっていたのですが、Octopress+Github Pagesというのがあるらしい","tags":["octopress","misc"],"title":"Octopress始めました"},{"contents":"Lucene/Solr 4.3.0がリリースされた(LuceneのChanges、SolrのChanges)ので、lucene-gosen 4.3.0をリリースしました。(ダウンロードはこちら) なお、lucene-gosen 4.3.0ですが、Lucene/Solr 4.2.1以下のバージョンのLucene/Solrでは利用できません。 注意してください。 また、lucene-gosen 4.2.1もLucene/Solr 4.3.0では動作しませんので注意が必要です。\n現時点(2013/05/06)では、lucene-gosen 4.3.0はLucene/Solr 4.3.0でのみ利用できます。 これは、先日のエントリにも書きましたが、LuceneにてAPIの変更が行われたためとなります。 いくつかのクラスおよびメソッドが廃止されたため、下位互換が保てない変更が入っているためです。\n独自のTokenizerやTokenizerFactory、TokenFilterFactory、CharFilterFactoryを作成されている方は、Lucene/Solrのバージョンアップを行う際は注意が必要です。\n","date":1367850324,"dir":"post/2013/","id":"11d4726484be418849e1f4200ade9535","lang":"ja","lastmod":1367850324,"permalink":"https://blog.johtani.info/blog/2013/05/06/lucene-gosen4-3-0%E3%82%92%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E3%81%97%E3%81%BE%E3%81%97%E3%81%9Flucene-solr4-3-0%E4%BB%A5%E4%B8%8A%E3%81%A7%E3%81%AE%E5%88%A9%E7%94%A8%E3%81%8C%E5%8F%AF%E8%83%BD%E3%81%A7%E3%81%99/","publishdate":"2013-05-06T23:25:24+09:00","summary":"Lucene/Solr 4.3.0がリリースされた(LuceneのChanges、SolrのChanges)ので、lucene-gosen 4.3.0をリリースしま","tags":["lucene-gosen"],"title":"lucene-gosen4.3.0をリリースしました。(Lucene/Solr4.3.0以上での利用が可能です)(Jugemより移植)"},{"contents":" アジャイルな時間管理術 ポモドーロテクニック入門 ポモドーロテクニック入門という本を読みました。 きっかけは、Twitter上で何度か「ポモドーロ」という単語を何度か見ていたためです。 最初は、なんだろう?というのが発端です。 「ポモドーロ=トマト」なのですが、実際にはトマト型のキッチンタイマーが元になっているらしいです。 このタイマーを使った時間(タスク)管理術がポモドーロ・テクニックです。\n私は、ここ数年、複数の仕事がパラで走ることが時々ありました。 このような場合に、日によって異なる複数のタスクが存在します。 このとき、異なるタスクにスイッチするのに結構な時間を取られます。。。 また、急な割り込みが入った時も同様に、以前のタスクに戻るのになにしてたっけ?となることが多々あります。 普通に自己管理ができている方なら問題ないのでしょうが、私は結構ニガテでした。 そのようなときに、Twitter上で「ポモドーロ」という単語を見かけて、軽くググってみたところ、 タスク管理、時間管理によさそうな本だったので、その点を矯正するのも兼ねて、読んだ次第です。 また、タスクに集中できるという利点もあるそうです。\n本については、少し読みにくいところがありました。 ポモドーロテクニックとはどんなものかという全体像や単語に関する説明がないままに、話が進んでいくので。。。 1度読み終わったあとに実践しながらパラパラめくっているような状況です。 実際には、個々人のやり方などを考慮しながら、改善していくべきなのもあり、型を説明してないのかもしれないですが、もうすこし概観がわかる感じのほうが良かったです。\nで、4月初旬くらいから実践してみています。 効果が実際にあるかというと、まだわからないです。\n私がポモドーロテクニックに利用しているのはキッチンタイマーではなく、pomodairoというAdobeAIR上で動くアプリになります。 ほかにもPomodoroAppというのもあるのですが、Free版だと登録できるタスクの上限があったので、pomodairoを選びました。(今見たら、3.0にバージョンが上がって、Limitがなくなってるかも) AIRだと、WinでもMacでも動作するのというも決定した要因です。\nまだ、1ヶ月経ってませんが、私が実践してきて良かった点、できてない点、うまくいってない点はつぎのような感じです。\n良かった点 目の前のタスクに集中できる。(25分スパンなので、Twitterを意識的に見なくできる。。。) 適度な休憩が挟める。25分に5分の休憩が入るので、適度な没頭になる(没頭し過ぎない) 自宅で作業するときにかなり有効。(5分の休憩時にTwitterやFB以外に漫画をパラパラ読んだりもできるので) ということで、自宅で作業するときには結構いいです。 自宅ですと、pomodairoを使っていてタイマーの音を気兼ねなく出せるので、きちんとポモドーロが回せます。\nできてない点 アクティビティ在庫管理。個人的にJIRAを使っていて、そこで管理しようと思っているのですが、うまくできてないです。pomodairoのアプリにもタスクを登録しているのもあり2重登録などを手間に思ってしまって。。。 レコーディングと今日のTodo作成。 インタラプトの記録 アクティビティ在庫管理ができてないのは、レコーディングがきちんと出来てないためでしょう。。。 二重管理になっている+pomodairoで統計情報が出るが、当日分の統計情報がレコーディングできてないというのが痛いです。 また、このレコーディングが出来てないので、効果が出ているかがわからないという問題かと。。。 きりが悪かったりして、どうしても、仕事時間ギリギリまでタスクをこなしてしまい、レコーディング+アクティビティ在庫の管理の時間が取れていません。 ここは意識してちゃんとやらないと意味がないよなぁと。今後の大きな課題です。\nうまくいってない点 できてない(やろうとしてできてない)点とは別に、どうもしっくり来ていないのがつぎのような点です。\nプログラミングしていると、25分のタイマーで区切りがすごく悪い時がおおい 自宅以外でのタイマー音が出せない 自宅以外での休憩の取り方 プログラミングをやっていて、乗ってきたタイミングでタイマーが鳴ってしまったり、 ちょっと頭のなかで整理していたあとの今まさに、頭のなかにある処理の流れをコードに落としている途中でタイマーがなってしまったり。 このような状況だと、休憩に入れなくて、ずるずるとコーディングを続けてしまうということが多々あります。 メモ(ソース上のコメントや手元)を残して休憩すればいいのでしょうが、どうしても今までの癖もありズルズルとやってしまい、すごく時間が経ってることが何度もあります。 ポモドーロテクニック的にはやはりNGなんでしょうが、なかなか治らない+治したくない気もしています。 また、自宅以外の場合、基本的には自社ではなく客先に出ていることが多いのでどうしても音を出すことができません。 これもまた、切り替えができない要因になっています。 タイマーだけ携帯のアプリを使用しするという手もあるのでしょうが、この場合さらにレコーディングが出来ない状況に陥りそうで。。。 また、スマホだと電池が持たないのも問題点です。(Twitterを見るのに利用してるから電池が持たないという話もあるのですが。。。) レコーディングに関しては、手描きのメモを使うのがいいのかなぁと。本では+や◎などの印を付けるだけにしておけば良いとありますが、アプリのタイマーだと自動でそれができるので、悩みどころです。 最後の休憩の取り方も、ネットやTwitterを見るのもありなのですが、画面から離れる休憩を取りたいなぁと思うところもあり。。。 職場だと技術書やWEB+DBのような雑誌はあるのですが、休憩にはあまり向いていないなぁと。\nつらつらと書いて来ましたが、本を読んで、1ヶ月実践してきた(できてないとこも多いが)現状をメモしておきます。 こうやってるよ、こうしたら良かったよ、こうしてみれば?などありましたら、コメントいただけると助かります。\n来週以降はとりあえず、JIRAできちんとアクティビティ在庫管理をしながら、1日の結果をレコーディングしていくのを意識していこうと思います。\n","date":1367592139,"dir":"post/2013/","id":"db97311c24809f103575d8a7fee19680","lang":"ja","lastmod":1367592139,"permalink":"https://blog.johtani.info/blog/2013/05/03/%E3%83%9D%E3%83%A2%E3%83%89%E3%83%BC%E3%83%AD%E5%9B%9E%E3%81%97%E3%81%A6%E3%81%BE%E3%81%99%E3%83%9D%E3%83%A2%E3%83%89%E3%83%BC%E3%83%AD%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF%E5%85%A5%E9%96%80%E8%AA%AD%E3%81%BF%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2013-05-03T23:42:19+09:00","summary":"アジャイルな時間管理術 ポモドーロテクニック入門 ポモドーロテクニック入門という本を読みました。 きっかけは、Twitter上で何度か「ポモドーロ","tags":["読書"],"title":"ポモドーロ回してます。(ポモドーロテクニック入門読みました)(Jugemより移植)"},{"contents":"まだ、Vote公開されていない、Solr 4.3(2013/04/25 11:00現在)ですが、 ひさびさに訳してみた。詳細まで追っていないので、誤訳があるかもしれないですが。 おかしいとこあったらツッコミを。\n○Solr 4.3.0のChanges ・Upgrading from Solr 4.2.0 1.schema REST APIのcopyFields、dynamicFieldsの出力パスをCamelCaseに。他も同様。(SOLR-4623) 2.Slf4j/logging jarをSolrのwarに含めないことに。すべてのlogging jarはexample/lib/extに。(SOLR-3706、SOLR-4651) 3.SolrCloudでハードコードされてたhostContextとhostPortをdeprecatedに。Solr5.0で削除する。(SOLR-4622)\n・New Features 1.SOLR-4648 PreAnalyzedUpdateProcessorFactoryでPreAnalyzedFieldの機能をほかのフィールドタイプでも使えるようにした。詳しくはJavadocとexampleを見て。 2.SOLR-4623 REST APIで現在のschemaのエレメントをすべて読めるように。REST APIの返却の形式として、XMLとJSONとschema.xmlの形式を追加REST APIのパッケージを変更。 クラス名も変更しschemaにフォーカスした機能も除去。今後のschema以外のREST APIのために。 copyFieldsとdynamicFieldsの出力パスをすべてlowercaseのものからCamelCaseに変更。他のREST APIも同様。 3.SOLR-4658 REST APIリクエストでschemaを変更できるようにするために、「managed schema」を導入。solrconfig.xmlに「\u0026lt;schemaFactory class=\u0026ldquo;ManagedSchemaFactory\u0026rdquo; mutable=\u0026ldquo;true\u0026rdquo;/\u0026gt;」を追加。REST APIリクエストでスキーマ変更が可能にするために。 4.SOLR-4656 2つのハイライトパラメータ(hl.maxMultiValuedToMatch、hl.maxMultiValuedToExamine)を追加。 hl.maxMultiValuedToMatchは指定された数のsnippetが見つかったらそれ以降の探索を停止する設定。multiValuedフィールドがどんなに離れてても探索する。 hl.maxMultiValuedToExamineは指定された数のmultiValuedのエントリ数を調査したら探索を停止する設定。 両方を指定した場合、最初のlimitに達したら停止する。ドキュメント全体をハイライトするためにコピーされるのを削減する。これらの最適化はmultiValuedフィールドに大量のエントリが存在する時に効く。。。 5.SOLR-4675 PostingsSolrHighlighterでper-field/クエリ次のパラメータ指定のサポート 6.SOLR-3755 既存のshardを動的にsplitしてshardを追加するための新コレクションAPI(shard splitting) 7.SOLR-4530 DIH:TikaのIdentityHtmlMapperを使う設定の提供 8.SOLR-4662 solr.xmlにあるSolrCoreの定義よりもディレクトリ構造で見つける。また、solr.xmlのフォーマットを変えて、solrconfig.xmlに近くする。Solrのこのバージョンは旧スタイルの例で提供するが、新しいスタイルも試すことができる。Solr 4.4では、新しいスタイルで提供し、Solr 5.0では旧スタイルは廃止する予定。 SOLR-4347 Adminハンドラで新しく生成されたコアがsolr.xmlに永続化される SOLR-1905 Adminリクエストハンドラで生成されたコアもsolr.xmlに永続化される。また、solr.solr.datadirのようなプロパティの用にsolr.xmlに永続化される問題のfix。 9.SOLR-4717/SOLR-1351 SimpleFacetで同じフィールドに異なるファセットを適用出来るlocalParamsを追加 10.SOLR-4671 CSVResponseWriterのpseudoフィールドのサポート 11.SOLR-4358 HttpSolrServerでuseMultiPartPostでstream名を送信できる ・Bug Fixes 1.SOLR-4543:solr.xml/solr.propertiesでshardHandlerFactoryの設定が動作しない 2.SOLR-4634:Java 8\u0026quot;Nashorn\u0026quot;JavaScript実装の動作に関するscripting engineのテストのfix 3.SOLR-4636:SolrIndexSearcherをオープンする時に何かの理由でreaderがオープンできない時に、ディレクトリがリリースされない 4.SOLR-4405:Admin UIのadmin-extraファイルでcore-menuが表示されない 5.SOLR-3956:group.facet=trueでfacet.limitがマイナスの時の動作 6.SOLR-4650:copyFieldでダイナミックフィールドや暗黙的なフィールドがsourceでマッチしない。4.2で入ったバグ 7.SOLR-4641:Schemaで、illegalなフィールドパラメータで例外が発生するようにする。 8.SOLR-3758:SpellCheckComponentが分散groupingで動作しない。 9.SOLR-4652:solr.xmlプラグインのresource loaderで共有ライブラリの挙動がおかしい 10.SOLR-4664:ZkStateReaderがaliasを更新しても見えない 11.SOLR-4682:CoreAdminRequest.mergeIndexが複数コアやindexDirが複数の場合にマージできない 12.SOLR-4581:Solr4.2で数値フィールドのファセットでマイナスの値があるとソートがおかしい 13.SOLR-4699:Admin Handlerでデータディレクトリの場所がファイルシステムだと思い込んでる。(RAMの場合もある) 14.SOLR-4695:non-cloudセットアップでもコア管理のSPLITが使えるように 15.SOLR-4680:exampleのspellcheck設定のqueryAnalyzerFieldTypeの修正 16.SOLR-4702:exampleの/browseの「Did you mean?」のサジェストをFix 17.SOLR-4710:Zookeeperから全ノードをアップせずにコレクションを削除できないのを修正 18.SOLR-4487:HttpSolrServerからのSolrExceptionがリモートのサーバから戻るHTTPステータスコードを含んでない 19.SOLR-4661:Admin UIのレプリケーションで現在のレプリカ可能なマスタのバージョンを正確に表示 20.SOLR-4716,SOLR-4584:SolrCloudリクエストプロキシがTomcatなどJetty出ないコンテナで動作していない 21.SOLR-4746:Distributed groupingのトップレベルグループコマンドでSimpleOrderedMapの代わりにNamedListを使う。non-distributed groupingと出力形式が異なるため。 ","date":1366856040,"dir":"post/2013/","id":"286a9a4ee373398d7d2c93862c5f6661","lang":"ja","lastmod":1366856040,"permalink":"https://blog.johtani.info/blog/2013/04/25/solr4-3-0%E3%81%AEchanges%E3%82%92%E8%A8%B3%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F/","publishdate":"2013-04-25T11:14:00+09:00","summary":"まだ、Vote公開されていない、Solr 4.3(2013/04/25 11:00現在)ですが、 ひさびさに訳してみた。詳細まで追っていないので、","tags":["solr"],"title":"Solr4.3.0のChangesを訳してみた。(Jugemより移植)"},{"contents":"現在、RC3のVoteをやっている最中(2013/04/24 16:00時点)で、まだリリースされていない、4.3.0についてです。 開発者MLでChangesの書き方を考えないとね、みたいなエントリーが流れてて気になっていたので、訳してみた。 lucene-gosenの実装を変更しないといけないっぽいなぁ。Lucene/Solr 4.2.1以前と4.3.0でI/Fとかが変わることになりそうです。(3.とか8.とか) (ここで力尽きて、それより下はまだ読んでないです。。。)\n○Changes in backwards compatibility policy 1.LUCENE-4810:EdgeNGramTokenFilterが同じ入力tokenから複数のngramを生成した時にpositionを増加させていないのを修正 2.LUCENE-4822:KeywordMarkerFilterがabstractクラスで、サブクラスがisKeyword()メソッドを実装する必要がある。新しく、SetKeywordTokenFilterというクラスにすでにある機能を分解した。 3.LUCENE-4642:TokenizerとサブクラスのAttributeSourceのコンストラクタを削除。代わりにAttributeFactoryをもつコンストラクタを追加。 4.LUCENE-4833:IndexWriterConfigがsetMergePolicy(null)の時にLogByteSizeMergePolicyを使っているのをデフォルトmerge policyをTieredMergePolicyに。また、nullが引数に渡されたらExceptionを返す。 5.LUCENE-4849:ParallelTaxonomyArraysをDirectoryTaxonomyWriter/Readerのためのabstractとして作成。あと、o.a.l.facet.taxonomyに移動。 6.LUCENE-4876:IndexDeletionPolicyをInterfaceではなく、abstractクラスに。IndexDeletionPolicy、MergeScheduler、InfoStreamでCloneableをimplement。 7.LUCENE-4874:FilterAtomicReaderと関連するクラス(FilterTerms、FilterDocsEnumなど)でフィルタされたインスタンスをforwardしないように。メソッドが他のabstractメソッドを実装している場合に。(?) 8.LUCENE-4642, LUCENE-4877:TokenizerFactory、TokenFilterFactory、CharFilterFactoryの実装者は、少なくともMap\u0026lt;String,String\u0026gt;(SPIフレームワーク(Solrとか)によってロードされる)を引数にするコンストラクタを提供する必要がある。さらに、TokenizerFactoryはcreate(AttributeFactory,Reader)メソッドを実装する必要もある。\n","date":1366786800,"dir":"post/2013/","id":"99f5219da22485d0872a2529599c8440","lang":"ja","lastmod":1366786800,"permalink":"https://blog.johtani.info/blog/2013/04/24/lucene-4-3-0%E3%81%AEchanges%E3%81%AB%E3%81%82%E3%82%8Bchanges-in-backwards-compatibility-policy%E3%81%8C%E6%B0%97%E3%81%AB%E3%81%AA%E3%81%A3%E3%81%9F%E3%81%AE%E3%81%A7%E8%A8%B3%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F/","publishdate":"2013-04-24T16:00:00+09:00","summary":"現在、RC3のVoteをやっている最中(2013/04/24 16:00時点)で、まだリリースされていない、4.3.0についてです。 開発者ML","tags":["solr"],"title":"Lucene 4.3.0のChangesにあるChanges in backwards compatibility policyが気になったので訳してみた。(Jugemより移植)"},{"contents":"第2回目も参加しました。 とりあえずメモ。 自分には欠けてる視点の話しなので面白かった。 ちょっと寒かったなぁ。\nエンジニアのためのスキルアップ勉強会『Tech Compass』 #tecomp ― Vol.2 「人気Webサービスの作り方教えます!」 ― 日時:2013/04/23 19:00 場所:パレスサイドビル9F マイナビルーム ◎自己紹介 ●株式会社Zaim/閑歳孝子 小学校3年からFMVで草の根チャットとかにつないでた。(すげー) これがいい記事ですよ。http://www.1101.com/umeda_iwata/ テレビとかで紹介されてるZaimやってます。 3つの基準 ・日常的に使うもの ・普通の人が使うもの ・少なくとも自分は使うもの サービスの良さの基準 縦軸:影響の深さ 横軸:影響する人数 この面積が大きいのがいいんでは。 ●株式会社ワディット/和田裕介 いろいろ作ってます「カウントダウンチューブ」とか「君のラジオ」とか30~40くらい作ってます。 ・「ボケて」ってのやってます。 600万ボケ。アプリ120万DL 僕らがつくるための5Wについて ・なぜ? ・サービスの根本となる「哲学」をみんなで共有できるかが重要 ・内向けのビジョンも大事 ・何を? ・ユースケースで整理する ・いつ? ・つくろう!すぐ作れるようにしようねって感じ ・誰と? ・最強のチーム。意思決定がはやい。 自分主体でサービス設計して、作りなおすのをためらわない ◎ディスカッション Q:どうしてサービス作ったの? A:エンジニアへのあこがれから、サービスを作った(閑歳さん) ものづくりという意味では、Webサービス以外もあるけど?(馬場さん) 学内のSNSのようなものを作ってて、アクセスが伸びるのが面白かった。(閑歳さん) 大学でlastfmみたいなものを研究してて。。。(和田さん) 社会に出てサービスを作るまでの話は?作って稼ごうって思ったのは?(馬場さん) あんまりなかった。(閑歳さん) すでに起業してた。サービス作ると実績として認められて仕事が入ってきてた。(和田さん) 直接あった時に反応がもらえるのが楽しい。(和田さん) Q:どうやって、チームを組み立てたりして開発とかしてきたのか?(馬場さん) A:「ボケて」まとめサイトでブレイクしたけど、アクセス数が落ちてない。 同年代の知人で色々とチームが組めてて楽しい(和田さん) はじめは一人でやってて、しかも構想とか。あとロゴだけ最初に作ってた。 ノマド的に作業してました。(閑歳さん) Q:チームがバラバラですが、困らないですか? A:今のところ困ってないです。もっと人が増えると困るかもしれないですけど。(閑歳さん) それぞれが他に職を持ってるので特に困ってないです(和田さん) 向き不向きはあるんじゃないかなぁ。10人とかになるとどうなるか不明(閑歳さん) GoogleのMLでレスが早ければ問題ないかな。(和田さん) あとは、チームが大きくならないように上手く分割してる(?)(ふたりとも) Q:ユーザの声の吸い上げ方、サービス改善の判断材料は? A:ユーザの声は聞くけど、全部取り込むものではない。 細かな点はユーザの声を取り込むけど、軸はブレないようにしてる(閑歳さん) 古参ユーザよりも新しいユーザを取り込むのが大事。(和田さん) nanapiのけんすうさん Q:品質はどうしてる? A:セキュリティは絶対。(閑歳さん) 品質を気にするってのは難しい。品質を担保できる仕組みを作るとこまでいけるようにしたい。 投稿される画像はチェックしている。(和田さん) ","date":1366717542,"dir":"post/2013/","id":"36ff37ced0d3211db95a5ac0daac0c35","lang":"ja","lastmod":1366717542,"permalink":"https://blog.johtani.info/blog/2013/04/23/%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%82%B9%E3%82%AD%E3%83%AB%E3%82%A2%E3%83%83%E3%83%97%E5%8B%89%E5%BC%B7%E4%BC%9Atech-compass--tecomp--vol-2-%E4%BA%BA%E6%B0%97web%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%81%AE%E4%BD%9C%E3%82%8A%E6%96%B9%E6%95%99%E3%81%88%E3%81%BE%E3%81%99%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2013-04-23T20:45:42+09:00","summary":"第2回目も参加しました。 とりあえずメモ。 自分には欠けてる視点の話しなので面白かった。 ちょっと寒かったなぁ。 エンジニアのためのスキルアップ勉強","tags":["勉強会"],"title":"エンジニアのためのスキルアップ勉強会『Tech Compass』 #tecomp ― Vol.2 「人気Webサービスの作り方教えます!」に参加しました。(Jugemより移植)"},{"contents":"だいぶ、ブログを書くペースが落ちてきてて、危機感を感じている今日このごろです。。。 今回は、個人的に利用しているJIRAのバックアップについて、ブログに残しておこうかと。\nさくらVPSのサーバを借りてJIRAを運用しています。 運用といっても、自分の備忘録のためというのが大半の理由です。 タスクを忘れないように管理するのと合わせて、その作業を行ったときのメモも残したいなと。\nバックアップといっても、同じサーバ内に保存しても意味がない+AWSを触ると言いつつ1年以上経ってしまったので、 このへんで本腰を入れるという意味も込めてAWSのS3(ゆくゆくはGlacier)にバックアップを取る仕組みを作りました。 「作りました」というと凄そうですが、Cronとシェルだけで終わりました、なんて便利な世の中。 ということで、以下は作業の備忘録です。\n1.AWSのアカウント作成 アカウントを作ってください。ここは特に説明しなくてもいいかと。。。クレジットカードの登録が必要なのが注意点でしょうか。 アカウント作成後の1年間は無料枠と呼ばれる仕組みが用意されており、いろんなことが無料で行えます。 (まだ、S3しか使ってないので、他にももっと使わないと。。。)\n2.S3のバケット作成 AWSのアカウントが作成できたら、Amazon S3(Simple Storage Service)のバケットと呼ばれる、データの保存先を作成します。 作成手順はこちらの公式入門ドキュメント(英語)をそのまま行いました。 簡単な手順はこちら\nAWS Management Consoleと呼ばれるところから、S3のコンソールにアクセス 「Create Bucket」ボタンをクリック 「Bucket Name」を入力し、リージョンを選択したら「Create」ボタンをクリック 以上でバケットが作成されました。これだけです。WebのConsoleからファイルをアップロードすることも可能です。 ただ、今回はさくらVPSから定期的にバックアップしたいのでシェルでアクセスできるようにします。\n3.AWSのアクセスキーとシークレットアクセスキーの取得 次に紹介するs3cmdというツールを利用するのに、AWSのアクセスキーとシークレットキーが必要になります。 取得方法はこちらを参考にしましたが、今は日本語のページが用意されています。 セキュリティ証明書(Security Credentials)のページで、「アクセス証明書」というタブで、「新しいアクセスキーを作成する」リンクをクリックしてください。 アクセスキーIDが新しく表示されます。このアクセスキーIDとシークレットアクセスキー(表示リンククリック後に表示される)をメモしておきます。\n4.s3cmdのインストール 世の中には便利なものを作ってくれる方がいるもので。 s3cmdと呼ばれるS3へアクセスできるコマンドラインツールが存在します。 ということで、こちらをインストール。これまた、便利なものでインストール手順を書いてくれれてるブログもありました。(あれ、なんか、見たことある名前がURLにはいってるなぁ) インストールはこちら。\n# yum -y --enablerepo epel install s3cmd インストール後に、先ほど取得したアクセスキーIDを設定します。\n$ s3cmd --configure Access Key: xxxx Secret Key: xxxx 以上で、s3cmdが使えるようになりました。\n5.バックアップスクリプトの作成 つぎは、本題のJIRAのバックアップです。 バックアップ方法はこちらを参考にしました。ちょっと古いみたいですが。 おもなデータは「JIRAのXMLバックアップユーティリティ」にてバックアップするか、「データベースのバックアップツール」を利用する方法があります。 推奨は「データベースのバックアップツール」のようなので、私の場合は「pg_dump」にてJIRAのデータベースをまるごとバックアップすることにしています。 また、データベースには添付ファイルが保存されていないようなので、別途「/var/atlassian/application-data/jira/data」というディレクトリをtarコマンドで圧縮して保存すようにしました。 あとは、pg_dumpの結果と添付ファイルの保存先の圧縮したデータをまとめてディレクトリに保存して圧縮します。 さいごは、S3にアップロードすればおしまいです。 一応、ファイルが連綿と残り続けるのは嫌だなぁということで、ファイル数で世代管理することにもしました。 これまた、ググって見つけてきたサイトを参考にしただけですが。。。 ということで、こんなかんじのスクリプトを日時でcronに設定して動かしてます。\n#!/bin/sh TODAY=`date +%Y%m%d` BACKUP_HOME=\u0026#34;/var/atlassian/backups\u0026#34; S3SYNC_DIR=\u0026#34;/var/atlassian/backups/s3sync\u0026#34; AGE=7 mkdir -p ${BACKUP_HOME}/${TODAY}/ /usr/bin/pg_dump -U postgres -Fc jiradb \u0026gt; ${BACKUP_HOME}/${TODAY}/jiradb_backup.dump tar zcvf ${BACKUP_HOME}/${TODAY}/attachment.tgz /var/atlassian/application-data/jira/data tar zcvf ${S3SYNC_DIR}/jira_backup_${TODAY}.tgz ${BACKUP_HOME}/${TODAY} rm -rf ${BACKUP_HOME}/${TODAY} NUM=`ls ${S3SYNC_DIR} | wc -l` while [ ${NUM} -ge ${AGE} ] do DEL_FILE=`ls -lt ${S3SYNC_DIR} | tail -1 | awk \u0026#39;{print $9}\u0026#39;` rm -r ${S3SYNC_DIR}/${DEL_FILE} NUM=`ls ${S3SYNC_DIR} | wc -l` done s3cmd sync --delete-removed ${S3SYNC_DIR}/* s3://my_jira_backup/s3sync/ そこへんだよとかあれば、ツッコミを。 今のところ、S3へのsyncだけなので、このあとは、月1くらいでGlacierに落とすとかの仕組みも考えるかなぁ。これまた何かあるんだろうけど。 あとは、この応用で家のNASに溜まっている写真をS3経由もしくは直接Glacierにバックアップする仕組みを考える予定です。\n","date":1366639648,"dir":"post/2013/","id":"1ca04e5339ed1826c12fe61fd984e949","lang":"ja","lastmod":1366639648,"permalink":"https://blog.johtani.info/blog/2013/04/22/jira%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92s3%E3%81%B8%E3%83%90%E3%83%83%E3%82%AF%E3%82%A2%E3%83%83%E3%83%97/","publishdate":"2013-04-22T23:07:28+09:00","summary":"だいぶ、ブログを書くペースが落ちてきてて、危機感を感じている今日このごろです。。。 今回は、個人的に利用しているJIRAのバックアップについて","tags":["備忘録"],"title":"JIRAのデータをS3へバックアップ(Jugemより移植)"},{"contents":" HerokuではじめるRailsプログラミング入門 heroku気になってるのに使ってなくて、TDのアカウント作ってデータアップしてない軟弱者ですが、参加して来ました。。。 とりあえず、大事なことです。まずは、上記の書籍を買ってください(って中の人が言ってました。) イベントページはこちら。\n総じて、herokuの中のエンジニアの方たちがすごく情熱があって、ユーザと会話をしたがっているという感想だったようで、まだまだ、よくなりそうだなぁと。 私は、ベースがJavaなので、JavaやScala、Playで使ってる方の感想とか聞きたいかなぁ。 あと、herokuとS3の組み合わせだと思うんですが、料金とかはAmazonとheroku両方に別々に払うのかな?とかはちょっと気になりました。 AWSのアカウントも作ってS3にバックアップあげるの作ろうと思って手をつけてない軟弱者ですが。。。 今月は余裕がありそうなので、TDとか触ってみようと思います。。。\n懇親会ではTDのmuga-sanとお話できて、いくつか気になってた話ができたのでスッキリしました。 あと、株式会社サムライズムの名刺頂きました。写真載せろって言われたけど、また今度w\n最後に、大事なことです。まずは、上記の書籍を買ってください(って中の人が言ってました。)\n以下は、いつものようなメモです。最後の方はちょっとくたばってたのでメモがおざなりになってます、すみません。\n日時:2013年04月04日(木) 18時30分 - 21時00分 場所:日本創生ビレッジ 事業開発支援オフィス 東京21cクラブ コラボレーションスペース ◯Ayumu Aizawa(Heroku, Inc.) ・■ PostgreSQLが9.2になりました。 ・◆ メモリが2倍。βテスタ向けにスケールアップ。 JavaとかJavaとかJavaとかデプロイしてもいいよね。 けど、メモリ2xは価格も2x! ・● Heroku OAuthを提供。Experimentalだけど。 heroku-bouncer使うとOAuthが楽になる。 ◯Treasure Data and heroku Masahiro Nakagawa(TreasureData) ・会社紹介 ・フロントエンド部分の担当(fluentd) ・1500億レコード!? ・投資家の中にHerokuの方がいる。 ・ターゲットは? Cloud + Big Dataが対象 Hadoopは立ち上げるのはいいんだけどメンテナンスコストが。 Hadoopの処理基板を提供 ・Hadoop生ではなく、Plazmaを使っていたりする。 ・Viki herokuにtd-agent入れて、TDにデータ送って、Postgresに書き出して使ってる。 ・TDはどうやってheroku使ってるの? Webコンソール。 http://console.treasure-data.com Webサイトは大体heroku fluentdとかも ・herokuのaddonとしてtd-agentを提供してる。 ・STDOUTからTDにデータ送るのもできるよと。 ◯Waza Report ◯吉田雄哉さん(co-meeting) ・まずは、co-meetingの紹介。 1文字ずつ送信してるよと ・Chief Talk Officerらしいw ・MongoDB使ってるって言ったら、herokuのPostgreSQLの人と話して、鼻で笑われたw ・すごく熱意のある人達がエンジニアとして働いてる ・ユーザの声をきちんと聞いてくれる体制ができてるミーティングだった。 ・「クラウド」って単語を聞いてない。勉強会のレベルもすごい。 ◯山本裕介さん(株式会社サムライズム) ・ニッチなブログ書いてます。 ・Java屋が見るWaza Tシャツプレゼント! ・OSS好きが多い。 Java/Scala系の話が少なかった。Scala界隈では人気みたい ◯岡村純一さん(株式会社シャノン) ・スライド1枚も作らずに喋る人とかいました。 (すごい。。。) ・Django Playに似てて面白いかもと ・Ruby2.0 Matzが喋ってたとか ・クロージングはビールが出てきてた。 交流パーティみたいになってた。CROSSがそれに似てますね。日本でやってるイベント ◯小西俊司さん(株式会社フレクト) ・バックエンドの性能とかを収集して見ることができるツールがあるらしい。 ・クエリを登録しておくと監視ができるツールとか。(TDとかぶってる?) ・やっぱり、情熱的だし、OSS好きでオープンな感じのエンジニアが多い。 ◯Heroku LT 無慈悲なLTです。3分たったらケーブル引っこ抜きます。 (最後はくたばっててあまり聞けてない。。。) ◯山本 裕介(株式会社サムライズム) ・herokuでJava7! Java6終わってますからherokuも移行してね! ◯竹野 淳(Grow!) ・BoxTo? ・コラボレーター募集! ◯小西 俊司(株式会社フレクト) ・ExcelのテンプレートをアップロードしてGETでパラメータわたせばいいよみたいなの作ってる。 ◯大久保英樹(Job-Hub) ・CarrierWaveとかの注意点 ","date":1365128443,"dir":"post/2013/","id":"73d2fce4efa52675b35a11ee97bc2db0","lang":"ja","lastmod":1365128443,"permalink":"https://blog.johtani.info/blog/2013/04/05/heroku-meetup--8-treasuredata--waza-report-%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-herokujp/","publishdate":"2013-04-05T11:20:43+09:00","summary":"HerokuではじめるRailsプログラミング入門 heroku気になってるのに使ってなくて、TDのアカウント作ってデータアップしてない軟弱者","tags":["勉強会"],"title":"Heroku Meetup #8 TreasureData + Waza Report!! に参加しました。#herokujp(Jugemより移植)"},{"contents":"記念すべき!?第10回のSolr勉強会です。\n発表者が無事あつまり(本当にありがとうございました!)、今回も盛況な感じでほぼ満員でした。 ツイートのおかげか、キャンセル処理もちゃんと行なってもらえて助かりました。 開場直後にドタバタしてしまい、すみませんでした。。。\nとりあえず、第一報の記事をアップしておきます。 懇親会での話とか感想はまたあとで。\n関口さんの資料は実は、前もって見たことがある資料でした。 最初の発表にしては、少しむずかしいと思った方もいるかなぁと。 ただ、類義語の辞書は結構作るのが大変だし、探しても出てこないものなので、面白い話だったんではないかなぁと。 「ミスチル」はできないけど、「マツケン」ができるのは読みがあるからとかなんですかねぇ?って質問するの忘れてた。\n尾形さんの話は結構、みんな通ってきた道かもなぁと思いました。他の方も同じ経験してるんじゃないかなぁと。 ただ、一人でやるのはすごいですよね。検索って結構人数が割かれてない場合が多いのかなぁ。 あんまり使われていないというのが少し悲しい話でしたが。。。 サーバを要求すれば結構なスペックが用意してもらえるのはうらやましい限りですねぇ。 スキーマ変更については、レプリケーション機能を使うと追加などならうまくいくんじゃないでしょうか。(そんなツイートもありましたよ。togetter読み返すと出てきます。) フィールド名を変更しないで型を変更するなどしたらおかしくなると思いますが。\n野口さんの話はなかなかチャレンジングでいいなぁと思いました。よく挫けずに頑張られているなぁとw 試行錯誤した仮定も発表してもらえると同じ轍を踏んだ人が助かると思います。 大きな企業で本格的に横断的な社内検索が出来る仕組みが出来上がっているって話はなかなかきかないかなと。 どうしても、社内検索とかお金が出なくて手を付けられないといいう悲しい話が多いので、こういう話は共有したい情シスの方がいっぱいいるんじゃないかなぁと。 ManifoldCFが結構地雷を多く含んでいるのは大変そうですね。。。 SolrにもTikaが入っていたりしますが、個人的にはTikaがやるべき処理は前処理と思っているので、Solrとは別の場所でやりたいとか考えていたりします。 ManifoldCFがその辺りまでやってくれるかまではちゃんと調べてないんですが。 Solrは検索だけに注力させることで、役割を分割できるので、性能の対処とかを行うのが楽になるんじゃないかなぁとか。 ManifoldCFで困ってる人は他にもいるようなので、ジャンジャン使って、どんどんチケット上げて貢献してもらうといいかと。 また、定期的に発表してもらうと面白そうだなぁと。\n弘瀬さんの話は結構興味ある方がいたんじゃないかなと。 SolrCloudは壮大だなぁと思いつつ、手を出しづらいと思ってる方が多いと思います。 実際のサービスに投入して試行錯誤された話を細かな数値も上げて発表してもらえるのは検証をやる方の助けになります。 残念ながら、私もSolrCloudは興味有りつつちゃんと追っかけてないので、途中でnodeとshardとcoreの関係がわからなくなってしまいましたので。。。 もう一度勉強して、スライドを見たいと思います。。。 分散検索(1つのインデックスが複数のcoreやshardに分割された状態)が絡んでくると、複数台の検索の性能のうち、一番遅い性能が最終的な検索性能に響いてくるので、検索リクエストの偏りとかも影響が出たりするかもしれないなぁと。 そういった意味でも試行回数を3以上で計測した結果で再度発表してもらうと面白そう!(なんか、下心見え見えですがw)\n前回、今回も感じたのですが、もう少し質問をしてもらえると発表された方も励みになるかなぁと思いました。 質問しにくい雰囲気になってるのでしょうか?参加者が結構いるから質問しにくく感じたりするのでしょうか? そのあたりをもう少しうまくやれるようになにかコメントもらえると嬉しいかなぁと。 運営で気になった点などもコメントやツイートをいただけると今後の改善にも役立てますので気兼ねなく連絡いただけると助かります。 開場がドタバタしすぎとか、ハッシュタグがわからなかったとか。\n今回は思ったよりも懇親会に残る方が少なめでした。 コミッターの方(LuceneやManifoldCFとかlucene-gosenとか)が複数いたり、Solrを結構触ってる方がいたりと面白い話が聞けそうだったのですが。。。 Kuromojiのユーザ辞書の改良点をチケットにあげるって約束したのでやらないとなぁ。 早く帰るつもりだったのに気づいたら23時でしたwやっぱり色々と話ができるのが楽しくて。。。 駅前の機動隊とかびっくりしながら帰りました。 今回、お話ができなかった方もいらっしゃるかと思いますが、気兼ねなく、ツイートしてもらったり、声をかけていただければと。\nあと、常に発表していただける方は歓迎しておりますので、連絡いただけると非常に助かります! こんな話が聞きたいなどでもいいかと思いますので、連絡いただければと。\n#SolrJPもtogetterにまとめてもらいました。ありがとうございます。 以下は、いつものメモになります。\n日時:2013/03/26 19:00 to 21:00 場所:VOYAGE GROUP 会議室 1. 株式会社 ロンウイット 関口 宏司さん タイトル:Wikipediaからの類義語知識の自動獲得について 発表資料はこちら\n・「辞書型コーパス」という単語は造語かもしれません。 ・なんでこんなことを? →類義語辞書を自動生成したいから。 ・自賠責保険、自動車賠償責任保険を例にSynonymFilterの説明。 ・Wikipediaを入力として、類義語辞書を作成するときにLuceneのインデックスを活用してる。 ・類義語候補の見つけ方 いくつかヒューリスティクスな処理とかも入れてます。 日本語Wikipedia固有なもの。 ・実際に導出された単語も載ってる。 FTPなども導出で来てる。 丸ビルとかも。 ・導出できなかったものもあります。 「十六進法」が「十進法」になってる 「ミスチル」も無理。 ・ミスもあるけど、類義語が存在しない場合になんとなく、使う辞書としては採用できるのでは? 類義語検索対象のブーストを小さくするなどをすれば役に立つ Q:類似度にしきい値を用意したりしてますか? A:min.scoreという値を用意し、足切りをしている。 Q:ベクトルを作るという話があったが、品詞でフィルタリングとかしてる? A:名詞に限って処理してます。名詞に限らなくてもいいかも。。。(若干聴き逃しました) 重みの高いn件をベクトルの対象にしてます。 2. グリー株式会社 尾形 暢俊さん タイトル:GREEにおける全文検索の歴史 発表資料はこちら\n・GREEさん、検索はないがしろにされてる。。。 一人でつくって、一人でメンテナンスしてる。 ・GREEの検索は右上の検索ボックスが ・2007年はSennaつかってました。 Tritonnに移行。2009年くらいまで。 やっぱり安定しない+MySQLのバージョンアップしたいけど、追従できない ・2012年初頭までLuceneでやってた。(結構古い) フラグメントが発生してOptimizeすると、検索サーバが使えなくなる。。。 検索しにくるサーバが1000台いるので、Optimizeかけるときに、1000台のサーバの設定を書き換えるとかしてた。。。 ・現在まではSolrをつかってる。 Luceneのバージョンも古かったので100倍くらい速くなった。 ・Solr本が必須ですよ!!! ・Lucene+Tomcatから移行。 移行に気をつける点として、I/FをそのままSolrに置き換えると。 Solr返却のXMLをカスタマイズしたり、クエリをSolr向けに書き換えたり。 あと、メンテナンスが楽になるように。 40数台のインデックスサーバがあると。 一人でメンテナンスしてるから、楽になる方法が重要 ・レプリケーションで、Optimizeの影響が出ないように。 キューをつかって、マスタに登録して、スレーブにレプリカを配布 ・スキーマが7つ あんまり使われてなくてかなしい。。。 ・負荷のグラフもありました。 ・RangeQueryを結構使う。 ・作りこんだ部分 インデックスのMasterへ分散させる処理とか クエリの変換とか人力監視処理とかNGワードとか サーバ監視のための仕組み ・今でも大変なこと スキーマ変更が大変 スレーブをマスタに昇格とかが手動 ・今後改善したいこと 精度を上げたい 辞書を使ってみたいけど、各国語対応 あと、自動化とか 3. ソフトバンクBB株式会社 野口 勝義さん タイトル:企業内の大規模ファイルサーバ検索事例 ・情シスの企画版?という立場のかた。 ・売上に貢献したいのでクラウドサービスとして検索をオプションとして立ち上げてみた! ・Solr+ManifoldCFで作ってみたよと ・なんでSolr? OSSだし、機能が充実 ・なんでManifoldCF? Active Directory連携が使いたかったと。 社内検索ってやっぱりアクセス権がうるさいので。 ・ManifoldCFの説明はロンウイットさんの画像を使わせてもらいましたw ・ファイルサーバが、70TB。。。 ・困ったこと。 ・その1 ・クローラージョブの構成の最適化どうする? ・マルチコアで、クローラーとファイルサーバを1対1の構成にしてみた。 ・その2 ・ファイル数が増えるとまた問題が。。。 ・ファイルサイズが大きい→Heapが足りないエラーとか、MCFのタイムアウトとか。。。 ファイルサイズのリミットを設けてみた。 mp4とかでエラーがでるとか。既知のエラーでしたとか。 ulimitがたりないとか。 MCFの稀に出るバグとか。。。 ファイルサーバの不良ブロックとか。。。 ・その3 ・クロールに時間がかかる ・MySQLでスロークエリとか MySQLよく知らないとか言われながらコミッターに対応してもらうなど。 SSDつかうとか考え中 ・フルクロールで1週間 差分でも1日強かかる。 ManifoldCFだけで対応できないから、ファイルの特徴を元に →ManifoldCFを経由しないリアルタイムインデックス更新のAPIを経由してMasterじゃなくて、更新かけると。(特定のクライアントからの方法) ・その4 ・本文データをstored=falseに けど、ハイライトできないから、どうにかしたい ・ユーザの要望 ・もしかして検索 類義語?じゃないよねぇ。テザリング、tezaringuとか フロント側で頑張った。(Solr諦めました) ・検索スコアも弄りたいとか 外部データでブーストとかもしたい。External Fieldとか使うといいのでは?とか。 4. 株式会社サイバーエージェント 弘瀬 健さん タイトル:SolrCloudの導入事例 発表資料はこちら\n・Webエンジニアだったのに、検索エンジニアに! ・SolrCloudもサービスインしてると。 ・SolrCloud概要 4.0以降の機能とか。 ・SolrCloudの構成要素 概念的なもの。Collection、Shard 物理的なもの。Node、Core ・ Simplogってサービスに導入済み。 ZooKeeperが3台、6Shard、3nodeという形式 ・性能 平均レスポンスタイム50msec 思ったより出てないので、調べてみた。node数とかshard数を変えてみて調べてみた(まだ、模索中。) ・色々テストケース試したけど、試行回数が1回だけです。 詳細なデータが出てるのありがたい(全部はまだ理解できてないですw) ・検証まとめ ノード当たりのcore数が少ないほうが検索、更新性能がいい 1コレクション当たりのshard数が少ないほうが検索性能がいい ・まとめ ・SolrCloudの利点 クライアントが色々意識しなくていいのがうれしい。 ・SolrCloudの注意点 shardの分割機能がまだないので、大変。 コレクション情報が壊れると検索更新できないとか。4.0だとバグが有った ・性能的には素のSolrのほうがいいよと。 ","date":1364300160,"dir":"post/2013/","id":"26d0c0d8c465087cf160a3bdc479f2b4","lang":"ja","lastmod":1364300160,"permalink":"https://blog.johtani.info/blog/2013/03/26/%E7%AC%AC10%E5%9B%9Esolr%E5%8B%89%E5%BC%B7%E4%BC%9A%E3%82%92%E4%B8%BB%E5%82%AC%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-solrjp/","publishdate":"2013-03-26T21:16:00+09:00","summary":"記念すべき!?第10回のSolr勉強会です。 発表者が無事あつまり(本当にありがとうございました!)、今回も盛況な感じでほぼ満員でした。 ツイー","tags":["勉強会"],"title":"第10回Solr勉強会を主催しました。#SolrJP(Jugemより移植)"},{"contents":"なんか、とても久しぶりにイベント参加メモ以外の投稿です。 elastic searchのMLを見てたら、KuromojiのAnalyzerを使うときにユーザ辞書使うのどうするの?という投稿を見かけました。\nKuromojiのユーザ辞書にもちょうど興味があったり、elasticsearchもちょっとずつ触りたかったのでちょっと試してみました。(返信もしてみましたが、テキトーな英語です。。。)\nelasticsearch-kuromoji-pluginのインストールなどはElasticSearch で kuromoji を使う (ES 0.90.Beta1 + kuromoji 1.2.0篇)を参考にしてください。 私もこちらに記述のある組み合わせ(elasticsearch-0.90.0Beta1 + elasticsearch-analysis-kuromoji/1.2.0)を利用しました。 KuromojiのAnalyzerはデフォルトで「kuromoji」として登録済みですが、こちらはユーザ辞書の指定がありません。 ということで、「kuromoji_user_dict」というユーザ辞書指定をしたtokenizerと、それと使う「my_analyzer」というanalyzerを登録したIndexを作成します。 定義する前に、「userdict_ja.txt」を用意して、elasticsearch-0.90.0Beta1/config/ディレクトリに配置しておきます。 (以下のサンプルでは、SOLE_HOME/example/solr/collection1/conf/lang/userdict_ja.txtをコピーして使いました)\n$ curl -XPUT \u0026#39;http://localhost:9200/kuromoji_sample/\u0026#39; -d\u0026#39; { \u0026#34;index\u0026#34;:{ \u0026#34;analysis\u0026#34;:{ \u0026#34;tokenizer\u0026#34; : { \u0026#34;kuromoji_user_dict\u0026#34; : { \u0026#34;type\u0026#34;:\u0026#34;kuromoji_tokenizer\u0026#34;, \u0026#34;user_dictionary\u0026#34;:\u0026#34;userdict_ja.txt\u0026#34; } }, \u0026#34;analyzer\u0026#34; : { \u0026#34;my_analyzer\u0026#34; : { \u0026#34;type\u0026#34; : \u0026#34;custom\u0026#34;, \u0026#34;tokenizer\u0026#34; : \u0026#34;kuromoji_user_dict\u0026#34; } } } } } \u0026#39; 「user_dictionary」というのがユーザ辞書の定義ファイルになります。 注意点としては、6行目で指定した名前「kuromoji_user_dict」を14行目の「tokenizer」に指定しないとちゃんと動かないという点でしょうか。\n上記で指定したAnalyzerを利用して「朝青龍」という単語をを解析してみます。\n$ curl -XGET \u0026#39;http://localhost:9200/kuromoji_sample/_analyze?analyzer=my_analyzer\u0026amp;pretty\u0026#39; -d \u0026#39;朝青龍\u0026#39; { \u0026#34;tokens\u0026#34; : [ { \u0026#34;token\u0026#34; : \u0026#34;朝青龍\u0026#34;, \u0026#34;start_offset\u0026#34; : 0, \u0026#34;end_offset\u0026#34; : 3, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 1 } ] 「朝青龍」という単語がユーザ辞書に登録されているので、1単語として出力されます。 ちなみに、デフォルトの「kuromoji」のanalyzerを指定すると以下の様な出力です。\n$ curl -XGET \u0026#39;http://localhost:9200/kuromoji_sample/_analyze?analyzer=kuromoji\u0026amp;pretty\u0026#39; -d \u0026#39;朝青龍\u0026#39; { \u0026#34;tokens\u0026#34; : [ { \u0026#34;token\u0026#34; : \u0026#34;朝\u0026#34;, \u0026#34;start_offset\u0026#34; : 0, \u0026#34;end_offset\u0026#34; : 1, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 1 }, { \u0026#34;token\u0026#34; : \u0026#34;青龍\u0026#34;, \u0026#34;start_offset\u0026#34; : 1, \u0026#34;end_offset\u0026#34; : 3, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 2 } ] とまぁ、こんなかんじです。 ユーザ辞書を書き換えたあとは「close/open」しないと読み込めないのかなぁ?そのへんはまたあとで調べようかな。\nちなみ、以下のページを参考にさせてもらいました。 elasticsearch kuromoji plugin - natural days ElasticSearch で kuromoji を使う (ES 0.90.Beta1 + kuromoji 1.2.0篇)\n","date":1363765380,"dir":"post/2013/","id":"f5f28f42ad234b4389af4cbea54ff60d","lang":"ja","lastmod":1363765380,"permalink":"https://blog.johtani.info/blog/2013/03/20/elasticsearch-analysis-kuromoji%E3%81%A7%E3%83%A6%E3%83%BC%E3%82%B6%E8%BE%9E%E6%9B%B8%E3%81%AE%E5%88%A9%E7%94%A8%E6%96%B9%E6%B3%95/","publishdate":"2013-03-20T16:43:00+09:00","summary":"なんか、とても久しぶりにイベント参加メモ以外の投稿です。 elastic searchのMLを見てたら、KuromojiのAnalyzerを使うときにユーザ","tags":["elasticsearch"],"title":"elasticsearch-analysis-kuromojiでユーザ辞書の利用方法(Jugemより移植)"},{"contents":"久々にブログ+イベント参加です。 知り合いが開催+出演したので参加してみました。 「スマホ」ってキーワードはあまりなかったけど、面白かったです。\nとりあえず、メモ。 余力があれば感想追加します。\n日時:2013/03/19 19:00 場所:パレスサイドビル9F マイナビルーム (東京都千代田区一ツ橋1-1-1) URL:http://atnd.org/events/36966 登壇者:@naoya_ito @yusuke ◯@naoya_itoさんの発表 最近、感心してること。 ・RubyMotionやってます。 今年5月に ・AWSもやってるよ。 ・「継続的デリバリー」の話 GREEでは毎日デリバリーしてるよと。 ・Chefの話 DevOpsとか。 ・Obama for Americaの話 GitHubとか使ってた。 身に付けるべきものは? 「変化に適応する力」が必要だよね。 最近は Ruby、クラウド、AWS、iOS開発とかやってる、どうしてこうなったw 先は予測してないけど、変化に適応するには5分でいいからやり続けること。 ◯@yusukeさんの発表 自己紹介が難しい ・今やってること ブログ執筆 刺さるツイート研究 ソフトウェア販売代理店 思わぬ収穫。InDesign/Illustratorのスキル、ビジネスの仕方w 会社設立中。 Webサイト構築・運用 ・ハッタリが大事 ・プログラム好き プログラミング以外を仕事にしてる。 ・人と違うことがしたい。市場がない場所での差別化はしない=トレンドに逆行し過ぎない。バランス。 ・今は種まき中。 ◯ディスカッション ・2,3年後とか何やってると思いますか? @naoya_itoさん ドラクエやってると思ってるかもしれませんが、サービス作るコード書いてます。 将来的な見通しでやってるのか?って言われるとそうでもない。 ツールとかよりは、コミュニティとかのサービスを作るほうが好き。 @yusuke 一定の収入がありつつ、プログラミングしてたい。あわよくばサービス作ったのが当たるといいなぁ ・そもそもフリーランスをどう捉えているか? @naoya_ito いいところ。自由に自分の時間をコントロールできる。 悪いところ。自分でコントロールしないといけない。 自分をコントロールしないと厳しい。 フリーになってわかったのは、会社は人間を働かせるための仕組みをよく考えて出来てる。 フリーでいいのは、選択した結果に自分が責任を持つというのがいい。 @yusuke セフルマネージメントできたほうがいい。 しがらみを捨てるためにフリーになるのはおすすめしない。 ・情報発信を継続してるけど、必要なことか? @naoya_ito 必要とは思わないけど、みんな書いたらいいと思う。 検索すれば自分が助かるからw セルフブランディングのために重要?かなぁ。あまりそれが唯一の方法ではないと思う。 @yusuke 発信することで、何に興味を持ってるかをわかってもらえるから、便利かな。 ブログに残したほうがググって引っかかるよと。 ・技術の方向性?見つけ方?は? @naoya_ito 直近は、クラウド流行るしiOSはまだ伸びてるしと。 そっから先はどうするの? わからないよね。じゃあ、どうするの?って変化に対応してボトムアップで見つけてくのがいいんじゃないかなぁ。 人がやってないところを先にやらないと武器にならないけど、どうやって見つけるのか? プログラミングやってる時に、その先に必要なこととか、気付きがあるので、手を動かさないとだめだよねと。 @yusuke トレンドを追いかけつつ、知ったかぶりするのは重要 ある程度ハッタリ+手を動かす ","date":1363692480,"dir":"post/2013/","id":"5412fb82160d0f6093e4b6670f505c13","lang":"ja","lastmod":1363692480,"permalink":"https://blog.johtani.info/blog/2013/03/19/%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%82%B9%E3%82%AD%E3%83%AB%E3%82%A2%E3%83%83%E3%83%97%E5%8B%89%E5%BC%B7%E4%BC%9Atech-compass%E7%AB%B9%E6%A9%8B--vol1-%E3%82%B9%E3%83%9E%E3%83%9B%E6%99%82%E4%BB%A3%E5%88%B0%E6%9D%A5%E3%81%93%E3%81%AE%E5%85%88%E7%94%9F%E3%81%8D%E3%81%AE%E3%81%93%E3%82%8B%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E3%81%AF%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-tecomp/","publishdate":"2013-03-19T20:28:00+09:00","summary":"久々にブログ+イベント参加です。 知り合いが開催+出演したので参加してみました。 「スマホ」ってキーワードはあまりなかったけど、面白かったです。","tags":["勉強会"],"title":"エンジニアのためのスキルアップ勉強会『Tech Compass』@竹橋 ― Vol1 「スマホ時代到来、この先生きのこるエンジニアとは!?」に参加しました。#tecomp(Jugemより移植)"},{"contents":"技術ブログから離れていってますが。。。 Xperia Zを購入しました。\n前に使っていたのはXperia arcになります。 もうすぐ2年だったのですが、容量不足に悩まされていたため+芸の肥やし(仕事の足し)という名目で Xperia Zの購入に踏み切りました。 予約しての購入です。\nいくつか戸惑いなどを感じているので備忘録としてブログに残しておきます。 サイズが大きい___ まぁ、わかっていたことですが、5インチと大きいです。 ステータスバーを表示するのがちょっときついくらいです。 私は手が大きい方なのですがそれでもキツイので、普通の人は両手じゃないと厳しいんじゃないかと。。。 一応、ステータスバーを表示するためのアプリなんかもあるようなので、その辺を検討するのもいいかなぁと(まだインストールもしてませんが。) また、Angry Birdを演ってびっくりしたのですが、解像度が大きいため、startボタンなどが小さくて押しづらいですw\n移行がめんどくさい___ iPadも持っていて、ソレと比較するとひどくめんどくさかったです。 実は方法を知らないだけかもしれないんですが。。。 iPadだと、初期化したりしてもiTunesにインストールしたアプリなども覚えていてくれます。 ですので、すぐに同じ環境が出来上がります。 Xperiaに関しては、arcでインストールしてたアプリをインストール履歴を元に一つずつインストールして、 それぞれのアプリやアカウントを設定して行きました。 これが結構面倒で、まだ完全にはアプリがインストールできてないかも(他にも新しいものを入れたいなぁと思いつつ、探す手間を惜しんでます。。。おすすめアプリお待ちしてます。)\nZite、Angry Bird star warsがインストールできない___ Ziteは英語の勉強も兼ねて入れていたのですが、対応していないバージョンですと言われます。 AngryBirdもいっしょですね。 starwarsじゃない奴はインストールできたのですが、肝心のやってみたいstar warsがインストールできなくて。。。\nドコモアプリがいっぱい___ ドコモのアプリやプリインストールアプリがいっぱいあったので、どうしようか悩んでいます。 いくつかはアンインストールしました。HotpepperBeautyとか間違いなく使わないし SFA-QRというよくわからないアプリも入っていたのでこれまたアンインストールしました。\n通知に出さないアプリとか選択できない?___ 容量不足だったのも有り、TwitterクライアントにはTwiccaのみをインストールしていたのですが、今回はTwitter純正のクライアントもインストールしました。 お気に入り登録されたりといった状況も見れるので重宝するのですが、基本的にはtwiccaを使うつもりです。 ですが、通知バー(ステータスバー)に@ツイートが届いたなどといった通知は見なくてもいいと思っているんですが、なにか方法あるんでしょうか。\ndビデオが危険___ いわゆる携帯ショップで機種変更したため、いくつかのサービスに登録しないといけませんでした。 で、dビデオ(月額525円で映画とか見放題)に登録したので、せっかくだからと映画をダウンロードしてみたのですが、危険です。。。 ただでさえ、本読むのが遅かったり、コーディングしてないのにビデオ見ると更に時間ががが。。。 けど、面白くて。。。危険です。(スターシップ・トゥルーパーズ見ちゃいました。。)\nクレードルがもう一つほしい___ 防水なので、あまりキャップを開けたくないんです。 そして、dビデオとか見てるとやっぱり電池の減りがはやいんです。(ディスプレイが大きいのもあるのかなぁ。要らないサービス切るとかしないと) 結局、出先でも充電をしないといけなくて。 ただ、純正のクレードルが2100円と結構な値段でして。。。 あと、イヤホンを指すところもキャップがあるので、Bluetoothレシーバーも気になってたりします。 こちらも結構な値段でして。。。\nとまぁ、新しいものを手に入れて、色々悩んでますが、楽しいですね。購入したての色々と悩む時間がw おすすめアプリとかあったらコメントください\n","date":1360687980,"dir":"post/2013/","id":"b051fd352847c06e748b345e8ed0738b","lang":"ja","lastmod":1360687980,"permalink":"https://blog.johtani.info/blog/2013/02/13/xperia-z%E8%B2%B7%E3%81%84%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2013-02-13T01:53:00+09:00","summary":"技術ブログから離れていってますが。。。 Xperia Zを購入しました。 前に使っていたのはXperia arcになります。 もうすぐ2年だったのですが、容量不","tags":["備忘録"],"title":"Xperia Z買いました(Jugemより移植)"},{"contents":"金曜日に引き続き、イベントに参加して来ました。(仕事。。。これも仕事だよ。)\n「Hadoop Conference Japan 2013 Winter」です。 普段、Hadoopを触るのも少ないのですが情報を仕入れときたいなぁということで。 今年はビッグサイトですよ。そろそろ無料のカンファレンスもキツイのではないでしょうか。。。 こちらの写真はセッション会場。今回もすごいです。。。 簡単ですが、聞いていた感想です。 全体的に、Hadoop本体の話ではなく、エコシステムと呼ばれる周辺のプロダクトの話や実際に運用している実例が増えていました。 だいぶ普及期に来たのかなぁと。そして、自分の不勉強を実感できたなぁと。 (あと、TreasureDataに絡む話が多いなぁと言うのも印象です。そういうセッションを選んで出ていたのかもしれませんが) 懇親会まで残っていたのですが、結構、すごい方たちの顔ぶれだなぁというのを今更ながらに実感するとか。 (ハチ象Tシャツを着ているすごい集団でもありましたが。。。)\n以下はいつものメモになります。だいぶ金曜日のイベント後で腑抜けてるのでメモが雑ですが。\n◯ご挨拶 Doug Cuttingさんのビデオ(あんまり聞けてない) さすがのhamakenさんのトークの安定感。 後援はリクルートテクノロジーズさんが大半。 リクルートテクノロジーズの米谷さんが軽く発表 ◯LINEのHBaseを利用した大規模なメッセージストレージ:NHN Japan 中村 俊介 まずは、LINEの紹介が続く。 New Yearのメッセージは3倍位だったけど、何とかなっったよと。 データロスがない。 サーバ故障からのデータリカバリも自動でやってくれる 書き込み1ms、読み出し1-10msでできてる ・IDC onine migration クライアントベースで2つに書き込み Incremental replication(新データ)、BulkMigration(旧データ) 元のHBaseのレプリケータは利用してない(pushだったから。スループットコントロールしたかったから) ・NN failover 2012.10にNameNode障害発生 HA構成にしてたから問題が発生。 VIPはHDFSにつかうとリスキー 現在: 少ないダウンタイムを許容する ・Stabilizing LINE message cluster ※あとでHBase触るときに資料見直すくらいで。。。 Case1:Too many HLogs Case2:Hotspot問題 まぁ、けど1億ユーザのインフラとして使えるってすごいよな。。。 ◯Hadoop meets Cloud with Multi-tenancy: Treasure Data 太田 一樹 TDもFluentdも有名だなぁ Hadoopのメンテナンスとか、つらいよねというのを見てきたのでTD作った ・なぜ、BigData+Cloud? Hadoopだけみてもバージョンが混在してる+ディストリビューターも多くなってる 十徳ナイフみたいになってきてるけど、必要なのはナタだよね。というのを提示するためにTD立ち上げた。 ・なぜCloud? ・IaaSベンダーの対象としてるのはSCM。 オンプレだとHWが陳腐化してくよね→HWはクラウドが主流に ・PaaS、SaaSの対象は時は金なり バージョンアップとか大変だよねと ・TDのご紹介 唯一の解析用DBを目指して ・哲学とアーキテクチャ 解析とか運用をいかに楽にしていくかというのを主体においたサービスを提供したい? いかに速くレポーティングシステムを簡単に構築していくかとかの話 簡単なインタフェースと目的に集中することで、価値を提供 ・AWSとの違いは? ・アーキテクチャとか技術的な話 データを集める処理がデータ解析に実際には重要なフェーズ ・カラム指向でデータ保存 実装がどーなってるのかとか、TD内部のHadoopクラスタの運用、バージョンアップとかがどうなってるのかもきになる。(企業秘密だろうけど) ◯Amazon Elasti MapReduceとHadoopコミュニティの関わり:Amazon Web Services Peter Sirota ・3つのV Volume、Velocity、Variety ・yelpのAuto-suggestの例 カスタマーのレコメンデーションにElasticMapReduce使ってるよと。 ・razorfishの広告インプレッションの解析に使ってる ・Amazon.comでの話 AWS Public Datasetsの話 http://aws.amazon.com/jp/publicdatasets/ IonFluxのDNA解析の話 ・いろんな分野でのBig Data 事例がちらほら ※わかりやすい英語なんだけど寝不足が。。。 ◯ランチ! サンドイッチと豚汁とあとなんとかライス。 TDブースにて、fluentdのTシャツもらったよ! ◯Hadoop\u0026#39;s Power to Transform Business:MapR Ted Dunning ・Mahaut+Solrの単語が。8時間のレコメンデーションデータの作成が3分に?? ・Stormにてリアルタイム処理と連携。バッチ処理はMRで。 ・バッチ処理とリアルタイム処理の間としてのDrill ・Drillの概観とできるところの話。 (あとでスライドで)データ解析のために機会学習の処理とかも投げられそう。 Q:ImplaraとDrillの違いは? コミュニティベースかなどが違うよね(あまり聞き取れず) Q:Drillの開発はどのくらいすすんでるの? A:。。。 Q.クエリ言語としてSQLがいいの? A.No。というのも、単独の言語ですべてにベストというのはないから。SQLはわかりやすくて良いが、実行が非効率な場面も。 ◯Introduction to Impala~Hadoop用のSQLエンジン~:Cloudera 川崎 達夫 ・Impalaとは 分析に特化した低レイテンシクエリ実行基盤 Apacheライセンス バッチ処理要ではなく、データサイエンティストが試行錯誤するときに利用するのを想定 パフォーマンスが良い 実行エンジンはC++とかで実装されてる MapReduceに依存してない ・MapReduceの問題点 MR直接は難しい→Hiveとか、M/Rの実装を隠して使いやすくするものが増えてきた Hiveを例に説明。MRがベースなので高レイテンシ ・Impalaのアーキテクチャ 機能制限やGA版について言及されてる資料なのが良い ・GA以降の話もあり ピンチヒッターなのに落ち着いて発表とか凄すぎです。 jdbcサポートも入ると。 プランナーはjava実装 Hiveとの互換性は?→完全互換を目指す。 開発のプロセスが見えにくいのでは?開発主体がcloudera ◯Flumeを活用したAmebaにおける大規模ログ収集システム:CyberAgent 飯島 賢志 立ち見。 Flumeのコミッターの人がCAにいたんだ。 ◯Log analysis system with Hadoop in livedoor 2013 Winter:NHN Japan 田籠さん@tagomorisさん ・NHNJapanのお話 ・Webサービスのログ解析について話していく 400+Webサービス ・2011年8月にLTしました。 ・1.5TB/day。。。 ・batchとstream Batch集計も重要だし、Stream処理も重要なので、ハイブリッドシステム ・システムーバービュー FluentdClusterを中心にして各種ツール、保存先に転送してる。 これが結構重要。だけど、今日はFluentdの話ではない ・Fluentd周りを一人でやってるのか。。。 ・処理の流れ ・ログの収集と、生ログ保存 ・パース(主にHive用に)、変換、フラグ追加(分類しておくとあとで集計したいとか、保存すべきかを処理可能に) ・Hiveにロード ・第1世代のはなし すべてbatch処理、Scribe 遅延が1時間ちょっとあるため、Hiveクエリで結果が見れないとか。 ・第2世代の話 Fluentdのstream処理にHadoop Streamingを呼び出せるようなプラグインを書いた Fluentd+HoopServerの構成 ・第3世代 HoopをWebHDFS Fluentdでのオンライン集計 GrowthForcast、HRForcast ・第4世代(ここ1週間でやったこと) CDH4でQJMベースのNameNode(Failoverは手動) Hiveのスキーマを変更(これはブログに今度書くよ) とりあえず、現時点で改善点が思いつかない ・総括 HTTPベースでRPCベースにしたのでコンポーネント切り替えが結構楽 OSSで公開されてるからいいよね 公開することにより色々とドライブするよ! ◯いかにしてHadoopにデータを集めるか:Treasure Data 古橋 貞之 ・自己紹介 ・ビッグデータ収集の問題点 ・壊れたデータが入ってる ・読み書きの時間がかかる ログはサブケースである。メインはサービスとかだから。 ・トライ&エラー処理が時間かかる ・データを分割するのが基本的なアイデア 失敗した時のリトライが楽になる。さらに、それをStream処理すれば良いよねと。 ・flumeのお話 ・fluentdのお話 バッファリングは性能アップも兼ねてる 設定のクラスタへの伝搬とかインストールはpuppetとか使おうねと。 プラグインのインストールが楽 ・いくつかのプラグインの紹介 ・TDへのデータ投入のお話 ・最後にmuddydixonさんのプラグインの宣伝がw ◯Hadoopの次に考える分散システム技術:Microsoft 萩原 正義 ・CAP定理の克服をどうしていくか ・CAPのおさらい ・Lease クライアント主導、サーバ手動とか (理論重視の話で最後のセッションには辛かった。。。頭が疲れててついていけませんでした) おまけ 今回頂いたノベルティなどを写真に撮ってみました。(ランチはお腹すいてて写真取らずに食べちゃいました。。。) Hiveロゴへの愛を語ってHive Tシャツをゲット。 FluentdのTシャツももらいました! Hiveステッカーなどもゲット あと、メッセージボードなるものがあったので書いてみました。一応、Hadoopに絡んだことですよね!?\n","date":1358783400,"dir":"post/2013/","id":"bf4f86812812dab8d39db9aaefe94a78","lang":"ja","lastmod":1358783400,"permalink":"https://blog.johtani.info/blog/2013/01/22/hadoop-conference-japan-2013-winter%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-hcj13w/","publishdate":"2013-01-22T00:50:00+09:00","summary":"金曜日に引き続き、イベントに参加して来ました。(仕事。。。これも仕事だよ。) 「Hadoop Conference Japan 2013 Winter」です。 普段、Hadoopを触る","tags":["勉強会"],"title":"Hadoop Conference Japan 2013 Winterに参加しました。#hcj13w(Jugemより移植)"},{"contents":"1/18(金)に開催された、エンジニアサポートCROSS 2013で「検索CROSS」セッションのセッションオーナー(モデレータ)をやって来ました。\n@muddydixonさんに昨年の夏くらいに声をかけていただいたのがきっかけです。 こういったイベントの運営のお手伝い(ほとんど何もしてない)も初めてでしたし、セッションオーナー(モデレータ)も初めての経験で色々といい勉強をさせて頂きました(自分の足りない所とか、考慮すべき点がどういったところにあるとか)。本当にありがとうございます。\nスピーカーとして登壇していただいた久保田さん、佐藤さん、安田さんほんとうにありがとうございました。 頼りないオーナーで、モヤッとした内容を提示したにもかかわらず、意図を汲み取って話の内容をふくらませていただいてすごく助かりました。 また、会場にお越しいただいたみなさん、ありがとうございました。すこしでも検索に興味をもっていただければ、セッションは成功だったと思っています。 朝一だったのと、私の認知度の低さもあったのとで残念ながら満席とはいきませんでしたが。。。\n後日、録画されたセッションの内容を見て色々と反省しようかなぁと。。。 緊張していたので、うまくモデレートできてたのか、話ができていたのか不安ですが。 忌憚ない感想をお待ちしています。\nということで、反省終わり!ここからは、イベントの感想と聞いたセッションに関する感想です。\n###聞いたセッション\n####企業CROSS DeNA x グリー x Aiming: 大企業・ベンチャーが語る「スクラム」開発 (仮)\nGoogleの及川さん見たさで参加しました。 スクラム自体は名前くらいは聞いたことある程度だったのですが、その程度の私でもわかりやすいディスカッションで楽しかったです。 聞いていて感じたのは、次のようなこと。\n「スクラム」という開発手法の話しなんだけど目的はそこじゃなくて、どうやってうまくプロジェクトを回して(ドライブして)、目的(サービスを作るとか顧客の要望を叶えるとか)を達成するかというのが重要だなぁと。 「スクラムマスター」の仕事は子育てに似てる 「スクラムマスター」になりたい人はなかなかいないらしい 「スクラムマスター」の人は、俯瞰してプロジェクト全体を見渡して落穂拾いをしていく人なのかもなぁと 個人的には「スクラムマスター」の仕事がちょっとおもしろそうと思いました。(いつもいろんなことを面白そうと思う自分なのでなんともいえないですが。。。)\n####データ理解を助けるビジュアライゼーション\n昨年からビジュアライゼーションには興味だけ(実践とかできてない)は持っていたので、参加しました。 スピーカーの方々の対立軸がはっきりしていたのが面白かったかと。 聞いていて感じたのは、次のようなこと\nビジネスの視点からのビジュアライゼーションはコスパがどうなのかというのがまだ不明 可視化できたらおしまいじゃなくて、お金につながる可視化に心がけるのが重要そう 可視化して楽しむのも有りだとは思うけど、それは趣味だったり芸術の話かもなぁ 異なるコンテキストの人にでも誤解を与えない可視化というのが重要 何をどう可視化するかというのが実は統計学知ってると必要ないこともある 基本的にはCAの方の内容が一番しっくり来ました。やっぱりビジネス的な視点と学術的な視点は違うのかもなぁと。\n####継続的システム運用のゲンバのハナシ\n面白かったです。のっけから燃料がテーブルにならんでるしw 運用とかインフラはそこまで詳しくないのですが、少しは作業したりするので気になってましたが、ぶっ飛んだ話が聞けて楽しめました。 聞いていて感じたのは、次のようなこと\nサービス内容によっては夜中にアクセス数が低いものもある(cookpadは夜中はアクセス数が低い) アプリを修正することでインフラを楽にするという考えもある インフラエンジニアは実はリア充 cookpad面白い人多いw このあとは、おまちかねのプレモルタイムだったので、プレモル片手(失礼だろw)にTech10の池本さんに挨拶してきました。(Solr本のときはお世話になりました!) あとは、RedBull片手に知り合いの方々(Twitter上のみやいつもお世話になってる人)に挨拶をして回ってました。(プレモルも美味しかったのですが、プレモルおつまみも美味しかったです!) また、ちょっとつかれて座るために入った「体系的に学ぶ安全な利用規約の作り方」でも、面白い話を聞けました。 (利用規約をきちんと考えて変更している企業のほうが炎上をしてしまうとか無駄だしおかしいよねとか)\nイベント終了まで、会場にいて(いただけで大した手伝いしてないです、すみません。)その後打ち上げに向かって楽しみました。\n####さいごは、イベント通じて感じたことと気になったこと。(若干、意図的なものが入り込んでますが。。。)\n題材にもなってる「CROSS」ですが、ここ数年特に、エンジニアとして複数の技術や考えなどを身につけないといけないなぁと 有名人に会える!(ミーハーです。。。) プレモル美味しい!(いつも飲んでるビールが「え?」って思った) ケンタッキー美味しい! RedBull美味しい! いろんな技術分野に触れられる機会ができそう Wi-fiは用意してもらえると助かる。(参加者の方々が一斉にLTEとかでつなごうとするのでみんなが繋がらなくなってツイートされないとかちょっとつらいかも) 各会場が覗けるようになってたのは良かった(ただ、会場の後ろの人はざわつきを感じるためスピーカーの声が聴こえないことも) スクリーンはもう少し高い位置にあると良かった(後ろに座ると下のほうが見えないことも) 飲食の配布は会場内でできたほうが良かったのかも(NGなのかな?)。プレモルやRedBullは配ってくれたので良かったのだが、食べ物を取りに行くために入口付近が混雑してた気がした。 (これで、メッキ剥がれたかなぁ) 会場入り口の写真とか撮ってくるんだった。。。 ということで、総じて楽しかったので来年もあるならまた、手伝いたいです!\nおまけ\nプレモル! Amebaウォーター プレモル+プレモルおつまみ+RedBull いただいたスタッフTシャツとプレモル!\n","date":1358600940,"dir":"post/2013/","id":"322264a17ef7182eb1475bd2eaebc2eb","lang":"ja","lastmod":1358600940,"permalink":"https://blog.johtani.info/blog/2013/01/19/%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88cross-2013%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%8A%E6%89%8B%E4%BC%9D%E3%81%84%E3%83%A2%E3%83%87%E3%83%AC%E3%83%BC%E3%82%BF%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F--cross2013/","publishdate":"2013-01-19T22:09:00+09:00","summary":"1/18(金)に開催された、エンジニアサポートCROSS 2013で「検索CROSS」セッションのセッションオーナー(モデレータ)をやって来ま","tags":["勉強会"],"title":"エンジニアサポートCROSS 2013に参加(+お手伝い+モデレータ)しました #cross2013(Jugemより移植)"},{"contents":"いまさら感満載ですが、今週の金曜日(1/18)に開催されるCROSS 2013というイベントで「検索CROSS」のセッションを担当することになってます。\nここ数年、検索に携わっていますが、検索は色々な技術の組み合わせ(検索用インデックス、自然言語処理、機械学習などなど)でなりったていて奥が深いなぁと感じる毎日です。 そこで、実際のサービスで検索をやられている方、検索プラットフォーム製品を開発している方、自然言語処理や検索に長けた方を招いてつぎのような話をしてもらおうかと。\n・現在の事例(検索とその周辺技術) ・今後の検索にクロスすると面白い技術\nがっつり検索をやられている方々に登壇していただきますので、検索に興味のある方はぜひ、ご参加を! 登壇者の方々についてはこちらを御覧ください。\n検索CROSS以外にも楽しみなセッションが多数ありますので、参加をご検討いただければと。 あと、実はこっちがメインなのですが、夕方からのプレモルタイムも期待できるのでこちらへの参加だけでもぜひ!!\n","date":1358267340,"dir":"post/2013/","id":"20110c8f8da8304b6d9d3c2845a38128","lang":"ja","lastmod":1358267340,"permalink":"https://blog.johtani.info/blog/2013/01/16/%E3%81%84%E3%81%BE%E3%81%95%E3%82%89%E3%81%A7%E3%81%99%E3%81%8Ccross-2013%E3%81%A7%E6%A4%9C%E7%B4%A2cross%E3%81%A8%E3%81%84%E3%81%86%E3%82%BB%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E6%8B%85%E5%BD%93%E3%81%97%E3%81%BE%E3%81%99/","publishdate":"2013-01-16T01:29:00+09:00","summary":"いまさら感満載ですが、今週の金曜日(1/18)に開催されるCROSS 2013というイベントで「検索CROSS」のセッションを担当することにな","tags":["勉強会"],"title":"いまさらですが、CROSS 2013で検索CROSSというセッションを担当します(Jugemより移植)"},{"contents":"年末から年始にかけて、「コード・シンプリシティ」を読みました。\n先日の記事にも書きましたが、Kindle paperwhiteを思いかけず入手できたので、eBookを読みたいなぁと思いまして。 Kindleのお試しも兼ねて読んでみました。\nまずは、本の感想。 短めの書籍+読み物なので、サクっと読めました。 題名に「コード」と書かれていますが、コードの実例が出てくる書籍ではありません。 「ソフトウェア」を以下にシンプルに保って、管理しやすくするか、機能追加、テストをやりやすくするかといった指針について書かれています。 機能追加に関して検討しないといけないバランス(先読みしすぎずと実装しすぎないとか)の話や定期的なデザインの見直しなどについても書かれています。 ソフトウェアに関しては動くこともだが、デザインが重要であること。(確かに。) すでにあるソフトウェアについて、どのように簡潔にしていくかという話もありました。 ただ、読んでいて一番重要だと思ったのは、「悪いプログラマーと良いプログラマーの違いは理解力だ」という一文です。 何をしているかを「理解」していないと、根本的な問題点の解決もできないですし、どうすればコードが簡潔になるかといったこともわからないです。 また、やっている作業がどんなもので、何のためにやっているのか、それを行うことで今後にどのような影響があるのかといったことも理解しておく必要があるかと。 ま、ある程度考えながら作業とかしましょうってことですかね。(強引なまとめかも。。。)\nで本題です。 Kindle paperwhiteとiPadの使い分けを検討するのも兼ねて本を読んでました。 iPadを持っているのもあり、Kindleはそもそも眼中になかったのですが、めっけ物でした。 やはり実際に使ってみないとわからないことありますねぇと。 paperwihteはつぎのような利点があるかと。\n読書に没頭できる。→本を読むというシンプルな目的を達成するものだけが実装されている 目が疲れない→Twitterでも話に上がったのですが、液晶とは異なり字が読みやすいです 軽いし小さい→電車で立っていても楽に持てるし、カバンからの出し入れも楽です(iPadに比べて) 複数の端末のKindleアプリで同期できる。→あまり異なる端末では読まないですが、paperwhiteで読んだところが、iPadでも同期されるのですんなり続きが読めます 電池長持ち ということで、本を読むのに没頭できるし目が疲れないと。 ただ、つぎの点では不満もあります。\nPDFは読みにくい。→画面のサイズが小さいので大きめの書籍のPDF版は読みにくいです。 PDFは読みにくい。→文字のサイズを変更できないのもキツイです。Kindle専用のmobi形式の書籍が読みやすいです ページめくりに一定時間がかかる→紙の書籍やiPadで書籍を読むのとは異なり、ページをめくるのに時間がかかります。e-inkの再描画の問題かと。パラパラと書籍を読みたい場合は厳しいです 白黒。カラーの電子書籍は読めないですねぇ ソースコードなどもキツイ→長めのコードが書いてある本だとコードが頭に入ってこないです。。。 という感想でした。 今後は基本Kindle paperwhiteを持ち歩きmobi形式の本を読むようにすると思います。 iPadは自炊本やカラーの本を読むとき、映像、ネットを見るような場合に持ち歩くことになりそうです。 私は基本的にMBAを持ち歩いているというのもあるので、paperwhiteのほうが主流になりそうです。 ネットを見るときなどは最悪、MBAを開くでしょうし。 小説とかをメインに読むのであれば断然、paperwhiteだと思います(最近読んでないなぁ)\n","date":1357658880,"dir":"post/2013/","id":"992a00c30242b6217243f3c387ea18b7","lang":"ja","lastmod":1357658880,"permalink":"https://blog.johtani.info/blog/2013/01/09/%E3%82%B3%E3%83%BC%E3%83%89%E3%82%B7%E3%83%B3%E3%83%97%E3%83%AA%E3%82%B7%E3%83%86%E3%82%A3%E3%82%92%E8%AA%AD%E3%81%BF%E3%81%BE%E3%81%97%E3%81%9Fkindle-paperwhite%E3%81%AE%E4%BD%BF%E3%81%84%E5%8B%9D%E6%89%8B%E3%81%AE%E7%A2%BA%E8%AA%8D%E3%82%82%E5%85%BC%E3%81%AD%E3%81%A6/","publishdate":"2013-01-09T00:28:00+09:00","summary":"年末から年始にかけて、「コード・シンプリシティ」を読みました。 先日の記事にも書きましたが、Kindle paperwhiteを思いかけず入手で","tags":["読書"],"title":"「コード・シンプリシティ」を読みました。(Kindle paperwhiteの使い勝手の確認も兼ねて)(Jugemより移植)"},{"contents":"書こうと思いながら、気づいたら大晦日。 よくないですね、思いついた時に書かないと。\n昨年も書いたので、昨年書いた抱負から振り返りをと。\nMongoDB触ってみる Scala触ってみる なんかWebサービス作ってみる(Amazonとかで) elasticsearch、IndexTankを調べてみる NewSolrCloudDesignを読み込んで自分なりにまとめる Junsaiに参加する 「7つの言語7つの世界」の続き えーと。。。できてないことばかりですねw MongoDBはインストールすらしてないですし、Webサービスも作ってないです。(さくらVPSは借りたんですが) Junsaiは参加したけど何もできてないし。7つの言語もそのままですね。。。 SolrCloudDesignはまとめられてないですしね。 Scalaは少しだけ触りました。結局Javaみたいな記述をしてしまうという良くないくせが出てしまうので、 見送ってしまいましたが。。。 elasticsearchは少しだけやりました。#pyfesで話をさせて貰える機会があったので。\n興味がコロコロ変わってしまうのが問題点かもしれないです。少しは地に足をつけてなんかやったほうがいいのになぁ\n###今年の振り返り 今年はこんなかんじでしょうか。\nいろんな勉強会に出没 #pyfesでelasticsearchのさわりを紹介 個人的にJIRA導入 MIR輪読会開始 Solr勉強会の主催を引き継ぐ Kindle paperwhite当たった 相変わらずいろんな勉強会に出てました。最近は勉強しに行くのもありますが、人に会いに行ってるような気がします。 勉強会から帰ってきて復習したりしないとすぐ忘れちゃうんですよね。。。\n#pyfesではelasticsearchの入門中という話をしてきました。 人の多さに緊張しまくりでよくわかりにくい発表になってしまったのが反省点かと。。。 もっと話をする機会を増やすとなれるのでしょうか。\nJIRAの導入はパラで仕事をしているとタスク管理がおろそかになってくるので導入しました。 フリーのredmineを考えていたのですが、インストールが簡単なJIRAを導入しました。 有料ですが、1-10人までなら、ダウンロード版が$10ですし。いろんな時間を買ったと考えると安いかと\n検索に関してもまだまだ初心者に近いということでModern Information Retrievalという英語の本の輪読を主催しました。 Twitterでの呼びかけに答えてくれた方々に感謝です。 まだ、半分も行ってないですが、何周かしたいと思っています。\nSolr勉強会の主催者も引き継ぎました。Atnd立てるの手伝おうか?って言ったら主催者になってましたw 来年も開催するので、喋りたい方、こんな話を聞きたいなどTwitterやブログでコンタクトいただければと。\nあと、会社の忘年会で思いがけずKindle paperwhiteが当たりました!(やったー!) iPadを持っていることもあり、完全に購入する気も無かったのですが。。。 使ってみると結構いいです。画面のギラツキがないのと、他のソフトがないのがいいです。 読書に没頭できます。通常はKindleを持ち歩くことになるかと。(没頭できるけど、読むスピードが遅い+すぐ忘れるのが難点。。。)\n###来年の抱負 来年の抱負も書いておきます。 昨年の前科があるのでどこまでできるかわかりませんが。 すぐに興味が変わってしまうのもありますし\nIntelliJ IDEAをメインに使う JIRAを継続して活用 ブログの継続 elasticsearch Luceneのソースコードリーディング 何かOSSのソースを読む Macでもっと開発 読書と英語を継続 IDEA(アイデア)は11をインストールしてたのですが、使えていませんでした。 イメケンが主催したJetBrainsユーザー会で洗脳されて+タイミング良い75%オフセールにやられて購入しました。 普段はEclipseを使っているのですが、これを機にチャレンジしようかと。 少し変化をしてかないとすぐ取り残されちゃうので。。。\nJIRAはまだタスクを登録してクローズするという初歩段階の使い方しかできてないので、少しずつ研究してフィールド追加したり、ワークフローを変更してみたりと研究したいです。\nブログは、今年後半が勉強会参加ブログしかないのを反省して来年は、もう少しSolrやLucene、lucene-gosenについて書いて行きたいです。 (すくなくとも、4.0で動かす話を書かないと。。。)\nelasticsearchはまぁ触れる環境を維持しようという話です。 どこかで導入できればいいんでしょうが、なかなか。 (勉強会開いてみるのも面白いかな?)\nLuceneソースコードリーディングは誘われてるのに、ちゃんと返事をしていなかったので。 来年2月のどこかの土日を候補日にする予定です。\n何かOSSのソースも読もうと思ってます。 「何か」はまだ決めてないですが、人のソースを実はあまり読んでないなぁと。 Vさんと話をした時に人のソースを読むのがいいですよという話になったので。 真似をするためにもなんか読みたいなぁと。Javaになるのかなぁ。\nとある事情で週4はWindowsで開発してます。 Macはちょっとしか触ってないのでMacの環境が成長していないのが難点です。 できれば、Macで開発を継続できる環境を作りたいなぁと。Kobitoとか入れてるけど触ってないし。。。 IntelliJも入れたのでMacで開発したいものです。\n最後は毎年のことですが、本を読むスピードが買うスピードに追いついてないと。。。 英語の本もかってるんですが、これまた読むスピードが。。。 ということで、ざっくり目を通す読書をもっとやりたいなぁと。 買うのはいいのですが、必要にならないと呼んだ内容を忘れてしまうので、読んだあとに実践する機会も設けたいと思ってます(思ってるだけかもしれないですが)\nあと、来年もいろんな人に会うためにいろんな勉強会に出没すると思いますので、声をかけていただければと また、不抜けているのを見かけたらカツを入れてください。(技術内容のブログ書けとか、本読んだ感想をブログにかけとか) 来年もTwitterなどで絡みまくると思いますが、よろしくです。\n","date":1356908460,"dir":"post/2012/","id":"4c08b67e0c1fdeef50b1fdcc32cdcee2","lang":"ja","lastmod":1356908460,"permalink":"https://blog.johtani.info/blog/2012/12/31/%E4%BB%8A%E5%B9%B4%E3%81%AE%E6%8C%AF%E3%82%8A%E8%BF%94%E3%82%8A%E3%81%A8%E6%9D%A5%E5%B9%B4%E3%81%AE%E6%8A%B1%E8%B2%A02012/","publishdate":"2012-12-31T08:01:00+09:00","summary":"書こうと思いながら、気づいたら大晦日。 よくないですね、思いついた時に書かないと。 昨年も書いたので、昨年書いた抱負から振り返りをと。 Mongo","tags":["備忘録"],"title":"今年の振り返りと来年の抱負(2012)(Jugemより移植)"},{"contents":"Atlassian Advent Calendar 2012の20日目。(急遽参戦) (某イケメンにMT(改変リツイート)されたので書いてみました) 久々に、勉強会以外のエントリです。(Solrとかlucene-gosenじゃないんだが。。。)\n私は、最近忘れっぽくなってきてしまったので、さくらVPSを借りてJIRAを立てて、タスク管理とかに使い始めました。 有料ツールなので、まずは、評価版から入れましたと。 評価版をインストールするときに、楽なのでHSQLDBを選択していました。が、 インストール時に「HSQLDBは評価版だけで使用してください。正式版ではサポートしてないです」みたいなことを言われていたので、PostgreSQLに切り替えようかと。 ちなみに、MySQLも選択肢としてはあったのですが、PostgreSQLのほうが触ってるし(つかいこなせてるわけではない)、補完機能になれてるというのもありPostgreSQLを選んでみました。\n作業のログとして、ブログ書いとこうと思いたったのでメモ的に残しておきます。\n作業の流れはこんなかんじでした。 (基本的にはサポートサイトのここに載ってます。サポートいいね。) この手順通りでいいみたい。\n###1. JIRAのデータのバックアップ(JIRAの管理画面からバックアップ)\nまずは管理画面へ。ページ右上に管理へのリンクがあるのでクリック。 開いた管理画面の右下あたりにエクスポート(バックアップ)へのリンクがあります。 クリックしたあとに、エクスポートのファイル指定画面が現れるので、ファイル名を指定してバックアップボタンを押します。 バックアップが完了するとバックアップファイルの場所が表示されます。 ###2. JIRAの停止\nバックアップが終わったのでJIRAを停止します。\n###3. PostgreSQLのインストール(yum) PostgreSQLが入ってないので、yum installします。(軟弱者なので)\nyum install postgresql-server ####initdbで四苦八苦 PostgreSQLはインストールしただけでは起動できません。なので、初期化をします。 yumでインストールしたPostgreSQLだとつぎのコマンドでinitdbできるようです。(これが罠でした)\nservice postgresql initdb このコマンドでinitdbすると、encodingが指定できませんでした。(私がしらないだけという話も。。。) encodingを指定できていないと、このあと4.を実行するときにエラーが出ました。(これも回避方法あるのかも。) ということで、結局、昔とった杵柄なやり方でinitdbコマンドで\u0026ndash;encoding=UTF8 \u0026ndash;no-localeを指定しました。\ninitdb --encoding=UTF8 --no-locale -D/var/lib/pgsql/data service postgresql start これで初期化が完了するので、PostgreSQLを起動します。\n###4. JIRA用DBとユーザの作成\nまずは、ユーザの作成。そして、DB作成\ncreateuser jirauser createdb -E UNICODE jiradb テーブルなど作成しません。あとの処理がやってくれます。\n###5. JIRAにJDBCドライバを入れる(必要なかった。)\nwarじゃないJIRAをインストールした場合はすでに入ってるみたいです。 ここを見るとわかります。JIRA Installation Directoryの下のlibですかね。\n/opt/atlassian/jira/lib ###6. マニュアルでPostgreSQLの接続設定(あれ、これいらないのか。)\n~~ コンソールオンリーなので、JIRAが提供してくれているツールが使えないため、手で設定。 /var/atlassian/application-data/jira にあるdbconfig.xmlを修正~~ ちゃんと英語読めってことですね。。。必要なかったです。。。\n###7. JIRAのdbconfig.xmlを削除\nDB接続の設定を初期セットアップウィザードで再設定するため、dbconfig.xmlを消します。 (一応、インストールディレクトリとホームディレクトリとかバックアップしたほうがいいみたい) 場所はここ。 中身はdbcpとかのデータソースの設定に似てました。 今は、HSQLDBのJDBCドライバが記載されてました。\nrm /var/atlassian/application-data/jira/dbconfig.xml ###8. JIRAの起動\n7.のファイルを消したあとにJIRAを起動します。\nservice jira start ###9. JIRAにアクセスとDB接続設定\nアクセスすると、インストールした時と同じDB接続の指定を行うセットアップウィザードの画面が現れます。 今回はJIRAサーバの外にあるPostgreSQLなので、「外部」を選んで四角で囲んだ部分を入力します。 入力したら、「接続テスト」を押して接続できることを確認したら「次へ」を押します。 マシンのスペックにもよると思いますが、ここでJIRAサーバがDBに接続してテーブルのCREATEなどDBのセットアップを実行してるのでちょっと時間がかかります。\n###10. バックアップしたデータのインポート\nDBのセットアップが終わったら、アプリケーションのセットアップ画面が出てきます。 新規インストールではないので、「ここ」にある「既存のデータをインポート」リンクをクリックします。 すると、インポートファイルの指定画面が現れるので、1.でバックアップしたファイル名を指定してインポートします。 すると、インポート中画面が出てきます。 で、インポートが完了すると無事JIRAにログインできますと。\nとこんなかんじです。 私の場合は、まだJIRAをインストールしてから間もないため、チケットの数が少なかったり、添付ファイルが無かったりなので、すぐにインポートが完了しました。 添付ファイルがある場合は、別途添付ファイルが保存されているディレクトリのバックアップと復旧などもあるみたいです。 最初にも書きましたが、ドキュメントのサイトに「Switching Databases」という項目があり、そのページの手順で問題なく切り替えできました。 次は、定期的にデータをバックアップするのを考えないとですかね。\nいやぁブログ書くのが、思いの外、手こずりました。 手こずった原因はスクリーンショットだったんですけどね。。。 safariでページ全体のスクリーンショットがとれなかったので、結局ChromeでAwesome Screenshotプラグイン使いました。 safariの拡張もあるんですが、ページ全体のスクリーンショットがうまく動かないみたいです。。。 ということで、備忘録でした。(次はちゃんとSolrとかの記事書かないとなー。その前に忘年ブログかな)\n","date":1356002280,"dir":"post/2012/","id":"4a30eeb083acec8460150068ba0c6743","lang":"ja","lastmod":1356002280,"permalink":"https://blog.johtani.info/blog/2012/12/20/jira%E3%81%AEdb%E7%A7%BB%E8%A1%8Chsqldb%E3%81%8B%E3%82%89postgresql%E3%81%B8-augj/","publishdate":"2012-12-20T20:18:00+09:00","summary":"Atlassian Advent Calendar 2012の20日目。(急遽参戦) (某イケメンにMT(改変リツイート)されたので書いてみました) 久々に、勉強会以外のエントリです。(So","tags":["JIRA"],"title":"JIRAのDB移行(HSQLDBからPostgreSQLへ)#augj(Jugemより移植)"},{"contents":"イケメンが主催した「第一回 JetBrainsユーザーグループ #jbugj」に参加してきました。\nいろんな製品があるんだなぁと。入り口には良いイベントだったと思います。 個人的に、WebStorm、IntelliJが気になっていたので、参加しました。(あとは、イケメンがやってるイベントだからというのもあるかも) ちなみに、MBAにしてからインストールはしていたのですが、ほぼ触っていなかったのでこれを機会にちょっと触ってみようかなぁと。\n発表は、全般的な製品紹介、ライセンスの紹介から、ライブコーディングあり、ここがいいよ!という話ありという感じでした。\nMTLさんのおしゃれな空間で発表を聞いたので、いつもとは少し違った感じでしたでしょうか。\n私自身は、発表を聞きつつ、IDEAのCEで色々やってました。 一応、Lucene/SolrのSVNからチェックアウトしたり、lucene-gosenのtrunkをチェックアウトしたり、個人のbitbucketからlucene-gosen-wikiparseとかcloneしてました。 Eclipseで作ったプロジェクトなので、cloneとかチェックアウトしたあとに、Eclipseと並行開発するとどうなるのかなぁ?というのがちょっと気になります。(普通は移行しておしまいなんだろうけど。。。) ちなみに、lucene-gosenのプロジェクトもSVNからチェックアウトしたらすんなり使えそうでした。 こんな感じ。(lucene-gosenのプロジェクト) とりあえず、見た目がカッコイイw\nいくつか触ったり、聞いていて気になったのはつぎのような点です。ちょっとずつ触る機会を作った時に調べてみようかなぁと\nEclipseのワーキングセット相当の機能はどうするのか?→モジュールとかでやればいいらしい。 プラグインってどんなものがあるの?探す方法とインストールの仕方 JDKの複数の切り替え方とか Eclipseでやってる人とIntelliJでやってる人の混在チームでの開発とか で、いつものごとく、懇親会に参加しました。 @mike_neckさんや@sue445さんとお話できたのですが、VCSにEclipseの設定ファイルとか挙げないほうがいいですよねとか、テストが無いプロジェクトってないわーなどの話を聞いて、やっぱり自分はまだまだなんだなぁと認識できるとか面白かったです。 lucene-gosenのSVNにはEclipseの設定ファイルとかアップされてるからなぁ。ホントはAntとかMavenのターゲットでこれらの設定ファイルができるようにしとくのがいいんでしょうねぇ。 まだまだ勉強することだらけですが、コツコツ教えてもらいます\nちなみに、イベント参加者にはショートカットキーが印字されたキートップシールや2ヶ月有効な評価ライセンスがあとからもらえるなどの特典もありました。 普段はEclipseなのですが、運良くライセンスが当たったら本気で乗り換えようかなぁw\nちなみに、Eclipseでもそうですが、私自身はショートカットキーをほとんど覚えてない軟弱者ですので、メニューの場所などを覚えれば乗り換え自体はこんなんじゃないかと。 Mac自体にKeyRemap4MacBookを入れていて、Emacsっぽいショートカットを使うので、覚えられないというのもありますが。 ライセンス当たらないかなぁー\n以下はいつもの通り、聴きながら自分用にメモしたものになります。\n日時:2012/12/11(火)19:00-21:00 場所:メディアテクノロジーラボ イベントサイト:http://www.zusaar.com/event/450003\n◎JetBrains製品群、ライセンス形態などの紹介 - @yusuke ・日本でヤル気あるの!?→あるある!→じゃあ、ユーザグループ立ち上げるぜー ・あくまで情報交換の場を設けるだけ。 ・アンケート結果 IntelliJが1番人気 WebStromが2番 ・ステッカー(ちょっとかっこ悪いかも。。。) ・2名限定でIDEAのライセンスプレゼント! ブログ書いて、応募用フォームに登録してランダム抽選 ◎IntelliJの基本(インストール~プロジェクト作成、テスト、実行までのウォークスルー) @yusuke ・JetBRAINSはチェコの会社 ・IntelliJはなんでもできる(AppCodeは違うけど) ・.Net系もある(書きそびれた) ・YouTrack:課題追跡 ・TeamCity:継続インテグレーション ・読み方は「イデア」じゃなくて「アイデア」だよ! ・Community Editionはあんまり機能がない。 OSSライセンスだと、Ultimateの機能が使えるよと。 ・仙台の人が一人アドベント・カレンダーやってます。 http://d.hatena.ne.jp/masanobuimai/20121201\n・ライブデモ 黒いインタフェースにするのどーすんだろう? →Preferences→AppearancesでThemeで「Darcula」を選択すると黒くなる。 ・やべ、時間過ぎてたw終わり! ◎IntelliJのここが気持ちいい!→普通IntelliJでしょ? @mike_neck ・DQXやってます。 ・僕とeclipse ・新規クラス作成:3ステップかかる ・補完の素早さ: ・SprintFramework:Ultimateなら対応してるよ。 関係ないけど、TLで質問したので。 Eclipseのワーキング・セットに相当するもの。 http://d.hatena.ne.jp/masanobuimai/touch/20121024\n◎LT ◯WebStormとRubyMineについて @sue445 ・JavaScriptのIDEとして最強 jsの補完が素晴らしい。(外部のJSはプロジェクトに入れないと難しい。) jsTestDriver pluginがデフォルトで入ってる! ・RubyMine RubyのIDE ソースを追うのが楽。 erbのインポートしたものも追っかけられるの便利。 viewからhelperクラスにも飛べる。 QA UMLとか出せるの?→出せるよ。 DBクライアントもあるよ。 ◎JetBrains発のJVM言語Kotlinの紹介 - @ngsw_taro アドベントカレンダー(一人)http://atnd.org/events/34627\n・社畜してます ・Androidアプリとか作ってる。 ・Kotlinな活動 Pull Requestしてる ・マイルストーンなど。 M4が3時間前に出た! ・どんな言語? 静的型付け、オブジェクト指向、関数型プログラミング的、JSへコンパイル可 産業利用目的(初めて聞いたかも、この言葉w) ・Java大変だよね。 互換性問題とか ・ライブコーディング 大変そうだwKUnitってのもあるらしい。 (ゴメンナサイ、IDEA触ってて、流してました。。。Eclipseで作ってたプロジェクトをBitbucketから落としてきて四苦八苦してた) (参考にしたサイト(ググった):http://d.hatena.ne.jp/waman/20100506/1273166533)\n◎AppCodeについて ・IDEAには含まれないので、別途ラインセンス購入が必要。 ・XcodeとAppCodeの違いをライブコーディングで説明。 ・XCodeよりも補完が良くできてるっぽい。 GUIはXCodeで作って、コーディングはAppCodeでやるってのがいいですよ。 ※私が、iOS系のアプリの開発ってやったこと無いからよくわかってないです。。。 XCodeはコードフォーマットがないのが辛い by @yusuke ","date":1355228520,"dir":"post/2012/","id":"898d25a2ab9c0ba1fa9bad462405e475","lang":"ja","lastmod":1355228520,"permalink":"https://blog.johtani.info/blog/2012/12/11/%E7%AC%AC%E4%B8%80%E5%9B%9E-jetbrains%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%82%B0%E3%83%AB%E3%83%BC%E3%83%97--jbugj-%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%A6%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-12-11T21:22:00+09:00","summary":"イケメンが主催した「第一回 JetBrainsユーザーグループ #jbugj」に参加してきました。 いろんな製品があるんだなぁと。入り口には良いイ","tags":["勉強会"],"title":"第一回 JetBrainsユーザーグループ #jbugj に参加してきました(Jugemより移植)"},{"contents":"ヒカリエに行ってみたいという不純な理由で参加してきました。 新しいということもあり、おしゃれで綺麗なカフェでした。 入り口にはおっきな人形も立ってたし。 渋谷の夜景も見下ろせて素敵な場所でした。\nで、内容です。残念ながら、本編の3回めには参加していなかったのですが、 今回も濃い話が聞けたので楽しかったです。 論文読まなかったり、基礎を勉強したのに忘れてたりと抜けてる部分が多いので、 こういう機会が与えてもらえるというだけで目からうろこです。\n@kumagiさんの「あなたの知らないハッシュテーブルの世界」はハッシュテーブルの基本的な話から、最近の論文で発表されてる内容までをカバーする幅広いお話で面白かったです。 (大学でやってると思うんだけどすっかり抜けてる自分がなんとも。。。) こういうコアな中身も知ってると、色々とプログラム書いたりするときの見方や考え方も変わってきますよね。 (そんなプログラム書いてないけど。。。) で、随分おとなしい内容だなぁ?と思いきや、途中からちゃんとLock-Freeの話も出てきてさすがと感心させられましたw 最後はJubatusの宣伝まで入ってたし。(某氏のすごい写真入りで。。。)\n@hitoshi_niさんの文書要約の話は、NLPに興味があるので、楽しみにしていた内容でした。 今回もなめらかによどみなく喋られる発表にただただ感心させられるばかりでした。 内容は中級編ということで、文書要約のキモになる処理の文章の短縮の話です。 係り受け木を元にする手法をわかりやすく説明されて、もうなんか、すぐに実装できちゃうんじゃないかと錯覚してしまう始末でした。 係り受け解析というと、CaboChaを思い浮かべてしまうんですが、きっと違う実装なんだろうなぁ。 入門編と次回の重要文抽出の話も聞きたいなぁと。\n最後に、技術評論社さんから「Emacs実践入門」など3冊の書籍のプレゼントまでありました。 その他の2冊は購入済みだったのですが、Emacs本は購入したいリストに入れたままでした。 ということで、欲しいですというアピールをしてゲットしてきました! Emacsはなんだかんだで、もう10年以上使っていますが、そこまで深入りしないような使い方をしていました。 これを機に、再入門してもっと使いこなせるようになろうかと。 また、読了したタイミングでブログに感想かきます。\nということで、以下はいつもの自分用のメモになります。おかしいところ、それ書いちゃダメでしょ的なところのツッコミをいただければ。\n日時:2012年11月28日(水) 19:00 場所:渋谷ヒカリエ27F NHN Japan カフェ ◎開会、諸注意など @overlast 人材募集、会場説明など。 前回、本をもらった人はブログ書いてね。オライリー様より 今回も本のプレゼントあり。技術評論社様より ◎あなたの知らないハッシュテーブルの世界(30分 + 質疑応答10分) @kumagi さん ・まずは前提。 データの集合を扱いたいよね 配列でもできるね。けど、データ増えるとキツイね。 ・ハッシュ関数の話から。 リハッシュとかの話 ・ClosedAddressingとOpenAddressingの話 ・ClosedAddressingの場合、ポインタ使ってるからキャッシュミスあり。 メモリとかの話 ・OpenAddressingメモリに乗るのでキャッシュミスは少ないけど、削除データの扱いがちょっと大変 →削除がいっぱい有ると処理が面倒 ・RubyはClosedAddressing、PythonはOpenAddressing memcachedはClosedAddressing ・Cuckoo Hashing(2001) 密度50%以上になると急にコストが高くなる。 挿入がすごく遅くなる。追い出し操作が増えるから? ・そこで、Hopscotch ググった参考ページ:http://shnya.jp/blog/?p=639 http://en.wikipedia.org/wiki/Hopscotch_hashing 密度が上がっても性能劣化がない。 ・C++でHashtableが欲しくなったら、google_sparse_hashとdense使うよと。 ・ConcurrentHashmapのお話 テーブル部分がvolatile、Chain部分はfinal insertはChainの先頭に。 削除は遅い。ReadCopyUpdate。 空でも1.7M(K?)持ってく ・ここからはLock-free系 ・Lock-Free Hash Table http://www.azulsystems.com/events/javaone_2007/2007_LockFreeHash.pdf HotSpot VMの人のもの?こんなのやってる。http://www.0xdata.com/faq.html ・(聞きそびれた) ・日立謹製Lock-free hashtable 日立のDBで使ってる部品? ベンチマークが胡散臭い ・最後はJubatusのCM ◎文書要約入門 中級編(40分 + 質疑応答10分) @hitoshi_ni ・画数が少ないです。 ・ヒカリエ綺麗ですね。 ・文書要約とは? 「機械に」要約させる。 ・なんで要約? 長い文章読みたくない。人件費の削減 ・どうやって要約? 1.文分割:文書を文に分割 2.文短縮:就職説を削除するなどして、原文より短い文の亜種を出す。 3.重要文抽出:要約にふさわしい文を選び出す。 ・今回は文短縮について ・動機 長い文は文抽出で扱いにくい 文の中にも重要なところとそうでないとこがある ・係り受け木の剪定すると短くできると。 剪定のルール 中間ノードは落としちゃダメ 除去の時に考えること 重要度 言語 ・重要度? 文節に点数を付ける 文書集合中の出現頻度とかを採用。訓練データからでもいいよ(ロジスティック回帰とか)。 ・言語尤度 言語としての尤もらしさ 典型的にn-gram言語モデルを使う ・そして探索 基本的には2値ラベリング ビタビアルゴリズムではだめ。係り受け制約が考慮できない ナイーブいはビームサーチをする。 ・文短縮の評価 ・人間が書いた短縮文と比較 ・ROUGE-Lという尺度などで評価(これしらないなぁ。) ・幾つかの論点 係り受け解析しない 文節じゃなくて、単語単位でもいいよねとか。 Q:硬い文章以外の要約ってやってるの? A:あります。 技術的な話だと、係り受け解析がうまく出来ればできる。 係り受け解析がうまくいけば、そこまで大変じゃない。 Q:短さが短くなるほど難易度があがるけどどこまでやってます? A:短くすればするほど難しい。これは情報の欠落が激しくなるから。 文法性を担保するのも難しい。 10文字くらいならできそう。 Q:実例としてどのくらいの長さをどのくらい短くしてる? A:ある程度の長さを20文字にしてくれとか。Twitterに入るくらいにしてくれとか。 頂いちゃいました! Emacs実践入門 ~思考を直感的にコード化し、開発を加速する (WEB\u0026#43;DB PRESS plus) ","date":1354122000,"dir":"post/2012/","id":"e01e01d18582c7f69e1b0db7e1b111a0","lang":"ja","lastmod":1354122000,"permalink":"https://blog.johtani.info/blog/2012/11/29/dsirnlp-3-5%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9Femacs%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80%E3%82%92%E9%A0%82%E3%81%84%E3%81%A1%E3%82%83%E3%81%84%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-11-29T02:00:00+09:00","summary":"ヒカリエに行ってみたいという不純な理由で参加してきました。 新しいということもあり、おしゃれで綺麗なカフェでした。 入り口にはおっきな人形も立っ","tags":["勉強会"],"title":"#DSIRNLP 3.5に参加しました。&「Emacs実践入門」を頂いちゃいました!(Jugemより移植)"},{"contents":"第9回Solr勉強会に参加しました。 皆勤賞です!というか、主催者になってしまいました。 まだ不定期の開催になると思いますが、話をされたい方などいらっしゃいましたら連絡いただければ助かります。\n今回も面白い話が聞けました。\n最初はKuromojiの開発者でSolrのコミッターでもあるChristianの発表です。 Solr勉強会では初の英語の発表だったんじゃないでしょうか。 Atilikaでやってることの紹介から、Kuromojiの紹介、今後の改良に関する話とひと通り話してもらいました。 途中でKuromoji使ってる人?などの質問があったのですが、残念ながら反応が薄かったです。 漢数字をアラビア数字でも検索できるようにするチケットなど、今後のKuromojiの発展も楽しみです。 (コメントとかパッチを送れというプレッシャーもあったので、パッチ頑張って書きます。。。)\nつぎはニコ生でのSolrのお話。結構、赤裸々(前任者がいない状態で引き取ったとか)に語っていただき、ハラハラしながら聞いてました。 やはり、新語や略語で苦労されてるんだなぁと。 複数のサービスや開発者に対してSolrの環境を提供するという話はなかなか興味深かったです。 いろんな人がSolrを触るような状況になってきてるんだなぁと。 基盤となるラッパーのようなフレームワークとかも作ってるのかなぁ? 今後は台湾語や英語への展開も考えられているようなので、Language Detectionなどを利用してみた感想とその内容を今度発表してもらいたいですねw\nつぎはFacetPivotの話です。 昔から要望が出ていたのですが、4.0系でやっと使えるようになりました。 ファセットはSolrの売りの一つだと思います。 最初はこの考え方がしっくりこない人もいるかもなぁと。特にデータをどのように作れば、いいのかって悩むこともあります。 その悩んだ内容について発表してもらいました。 実際にどうやって使うかを悩んだ内容を発表してもらうのもいいなと思いました。\n最後はSolr勉強会なのに、elasticsearchの洗脳会になってましたw elasticsearchはSolrと同じ、Luceneをコアに採用した検索エンジンサーバーになります。 Solrとは別のアプローチでLuceneをラップし、REST APIでアクセスしやすくしたプロダクトです。 Luceneのコミッターの方もelasticsearchの開発に参加しています。 分散インデックスを念頭においた設計や、インストールが簡単なプラグイン構造といったSolrとは違ったアプローチがなされており、面白いものになっています。 残念ながら日本で利用されているという話はまだ聞いた事ないですが、だからこそ、触ってみて事例を紹介してみるのも面白いのではないでしょうか。 今回紹介したKuromojiも使えるようになっていたりしますので、日本語でもある程度使えると思います。\n以上が簡単ですが感想です。主催者だったのに、@hirotakasterさんや@ajiyoshiさんに受付などをやっていただいたので、いつもの様にしっかり話を聞いてしまいました。 発表者の方、会場提供いただいたVOYAGE GROUP、お手伝いいただいた皆さんに感謝です!\n今回初の主催でしたが、本当に助かりました。たどたどしい説明や紹介など至らない点も多々有ったかと思いますが、今後もよろしくお願いいたします。\n主催者的な立場として感じたことも書いておこうかと。 無料の勉強会で、ATNDという参加しやすい環境というのもあるかもしれないのですが、キャンセルをきちんとしていただくほうがいいなと思っています。 幸いにもSolr勉強会はここ数回は盛況で、キャンセル待ちの方が結構いらっしゃいます。 ギリギリまで業務との兼ね合いを見つつ、参加しようと思っていらっしゃる方もいると思うのですが、キャンセル待ちで行けるかな?どうかな?と思っている方もいらっしゃいます。 ドタキャンは問題ないのですが、キャンセルせずに欠席は出来れば避けていただけると助かるなぁと。 (残念ながら、きちんと集計をとれなかったので、次回からは集計取ってみようかなぁと)\n次回の開催は今のところ未定です。発表してみたい方、こんな話を聞いてみたいなど、気兼ねなく連絡いただければと思います。 このブログにコメントを頂いてもいいですし、ツイートしていただいてもいいので、反応をいただけると嬉しいです。 また、今回至らない点があったなどのツッコミ、批判も気兼ねなく言っていただければと思います。 今後の反省点にもしたいので、ぜひ反応をいただければと!\n懇親会でも色々な方とお話できました。(もう少し、Christianと英語で話す努力とかしないとなぁ。。。)\nとりあえず、メモをアップしときます。 リンクとか感想とかはまた(飲んだ)後で。。。\ntogetterでまとめてももらったみたいです。ありがたいです。\n第9回Solr勉強会 場所:VOYAGE GROUP 会議室 日時:11/26(月) 19:00~21:00 1. Atilika Inc. Christian Moenさん タイトル:Who we are, what we do, and a little bit about Kuromoji ◎Atilikaの紹介。 会社の目指すもの ・BigData、検索、NLP ◎プロダクト Kuromoji:形態素解析エンジン Akahai:日本語クエリサジェストエンジン Keywords:日本語キーフレーズ抽出 ◎Kuromojiの紹介 3.6からデフォルトで使える。 ◎将来の改良の話。 ・踊り字対応(コミット済み) ・漢数字に関するチケット&パッチのお話。 ・ユーザ辞書の重複エントリ改良とか(すみません、パッチ書きます。。。) 2. 株式会社ドワンゴ 吉村総一郎さん(@sifue) タイトル:Solr@ニコニコ生放送 ◎ニコニコ生放送の紹介 ・1日に10万番組。。。 ・10/17にバージョンQをリリースしたら、トップはひどい叩かれようでした。。。 ◎これまで。 Jackrabbit→Lucene→Solr→ニコ生のSolr ◎退職者と入れ替わりでSolr担当。。。 今回は資料と環境を調べて発掘した機能のお話。。。 ◎機能 キーワード検索。論理クエリ、などなど。 ◎利用してる環境 3.4ベース+Jetty マスタスレーブ構成(スレーブ2台) 途中は分散インデックスを自分で実装? ボトルネック自体がDBからのデータ収集だった ◎インデックス対象 ・見れるのは過去1週間と過去の公式番組すべて。 この部分だけ検索可能。 ・更新頻度の高い情報に「来場者数」「コメント数」 ◎インデックス作成 ・バッチにて更新 ◎アナライザ CJKTokenizerFactoryを利用 HTMLStripCharFilterFactory Bi-gramなので、「FF」とか「DQ」に弱い(FF1でFF13とかヒットしちゃう) 検索精度は悪いと言われてるみたい。 ◎1日のリクエスト ピーク時40QPS程度 5分おきにスパイクがある。(ユーザが作ったツールによる検索とか。。。) ◎UPDATEリクエスト ピーク時は80QPS ◎開発用のJettyのマルチテナント機能を利用したSolr環境の提供 ◎台湾語とか英語もやりたいなぁ。 3. 株式会社マーズフラッグ 柳吾朗さん(@hitode7456) タイトル:ドリルダウン色々 ◎Facetの紹介から ◎楽天でのドリルダウン例(これはFacetの紹介での例であり、実際にSolrが利用されているかはわからないです。) ◎多段ドリルダウン(ファセット)のお話。 アプリを実装するときの考え方とか。 ◎実直形、工夫形、PivotFacet Q\u0026amp;A Q:3つの性能系のコストは? A:まだ調べてないです。残り2つは工夫形がいいですよ。と 次回、調べた結果の発表もやってほしいなぁ。 4. 兼山元太さん (@penguinana_) https://speakerdeck.com/penguinco/solrtoelasticsearchfalsebi-jiao タイトル:SolrとElasticsearchの比較 ◎クックパッド! ◎elasticsearchの紹介 ◎比較サイトもあるよ! http://solr-vs-elasticsearch.com ◎サンプルデータ・セット(ライブドアグルメ)でサンプル実装。 https://github.com/penguinco/ld_gourmet_search ◎APIの紹介 REST APIがちゃんと造られてますよと。 設計時点でコレクションなどがURLに含まれてるのがいいよねと。 ◎_analyzeによりアナライザーもAPIとして公開されてるよと。 ◎Kuromojiも対応してるよ! ◎DynamicFieldよりも便利だよ。 ◎クエリのDSLが違うのでちょっとアレ。 ◎スコアリングも色々できるよ。 ◎感想 ・機能面の不足なし ・APIがいい コア追加とか、curlだけでできるのがいい。 ・習得が容易(Solrやってると機能とか似てる) ・大規模じゃなくても使えそう ◎分散検索がデザイン時に組み込まれてるのがいいよね。 write consistencyなどがインデックスごと(コレクションごと?)に設定可能なので便利。 ◎multi-tenant open/closeなどができる(時系列データとか) shard allocationなどの細かな制御も可能ですよと。 ◎plugin 色々プラグインがあるよ。管理画面もプラグインであります。 プラグインもコマンド一発で追加可能。 ◎クエリキャッシュがないので、自前でnginx、varnishなどでキャッシュが必要。 ","date":1353923040,"dir":"post/2012/","id":"7e23419e4fc69b5b533815681c9bb1a9","lang":"ja","lastmod":1353923040,"permalink":"https://blog.johtani.info/blog/2012/11/26/%E7%AC%AC9%E5%9B%9Esolr%E5%8B%89%E5%BC%B7%E4%BC%9A%E3%82%92%E4%B8%BB%E5%82%AC%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-solrjp/","publishdate":"2012-11-26T18:44:00+09:00","summary":"第9回Solr勉強会に参加しました。 皆勤賞です!というか、主催者になってしまいました。 まだ不定期の開催になると思いますが、話をされたい方など","tags":["勉強会"],"title":"第9回Solr勉強会を主催しました。#SolrJP(Jugemより移植)"},{"contents":"初目黒(たぶん)で、初Amazonな感じで、流行りの「ビッグデータ」のセミナーに参加してきました。\nとりあえず、いつもの自分用のメモを残しておきます。 感想はまた後日。。。(たぶん、頑張れ私。。。)\nAWS ビッグデータ活用事例セミナー 日時:2012/11/09 [ 金 ] 9:30 - 12:00 場所:アマゾンデータサービスジャパン目黒オフィス ★AWSビッグデータ概要 @understeer ○Amazonの紹介 ○Amazon Web Serviceの紹介 ・オンプレミスと比べ、初期費投資が不要 ・コストダウンを促進 過去6年で21回の値下げを実施 ・IaaSだけじゃなく、PaaSもやってますよ。 ・OSより上の層は好きに選べるよ。 ○AWSのサービスだけで20ある。 ○3つのV Volume 2012年で1.2ZB。95%が非構造データ。今後も非構造データが増加 Velocity デバイスの増加、パーソナライゼーション系の増加 Variaty 素粒子のデータの解析とか、地質学、気象予報とかいろいろやってるみたい。 ○BIG DATAの4つのプロセス。 収集、保存、分析、共有を繰り返しやりましょう。 そこで!AWS使いましょう。 ○収集 AWSへのデータアップロード オンプレにあるデータをAWS(S3)にアップロード ・インターネット経由 ・専用線サービス(AWS Direct Connect、1/10Gbps)も可能 ・AWS Import/Export(HDDを送りつけてS3にアップロードしてくれる。Tokyoリージョンにはだない) ・インターネットVPN経由も可能 ・EC2上のデータももちろんできる。 ※WAN高速化ソリューションも利用可能。 ○保存 ・AmazonS3 99.999999999%の耐久性。 同一リージョン内の3箇所以上のDCに自動複製 容量無制限で低コスト(1G 約10円/月) ・Amazon Glacier データの利用準備に3.5~4.5時間かかる。 S3の約1/10という低コスト ○分析 オンプレミスだと運用が大変。 ・Amazon EC2 スケールアップ/ダウン、アウト/インが即座に可能。ライセンス持ち込みや従量課金に対応 スペックの種類が豊富(SSDとかもあるよと) ・Elastic MapReduce Hadoopをサポートしたの仮想サーバが簡単に用意可能。 S3、Dynamoとの連携も可能 ディストリビューションも選択可能(Apache、MapR) 追加のアプリ(Hive、Pig、HBase)なども利用可能。 ジョブの大きさに合わせてクラスタサイズを適切にすることでコスパがよくなる。 →HadoopのMRのデータのローカリティとかはどうなってるんだろう? ○共有 ・AWS RDS MySQL、Oracle、SQLServerをサポート(PostgreSQLはないのかな?) 自動バックアップ、フェイルオーバー、パッチ適用機能があるよ ・Amazon DynamoDB AmazonオリジナルなNoSQLデータベース。論文有るよ。 運用管理は気にしなくていい。 性能については客指定の性能が出せるようになる。しかも変えられるよと。 ※データサイズに応じて以下を選択しましょう RDS、HBase on EMR、DynamoDB、S3 他にもEC2上で、CassandraやmongoDB、GlusterFSを使ってる事例もありますよ。 ○以上を繰り返すのが意味があります。そこで! ・Simple Queue Service マネージド分散キューサービス 最低1度のメッセージ到達の保証。複数DC間で複製保存 ・Simple Workflow Service 進捗などの管理も可能 NASAのCURIOSITYの制御に利用?10m前進するのに10時間のバッチ処理がある。。。 データがなくて試せない!そんなあなたに! ○AWS Public Data Sets すぐ使えるPublic Dataが用意されてるよ。 http://aws.amazon.com/jp/publicdatasets/ ★AWSのビッグデータ事例紹介 @shot6 ○NETFLIX ・どんな会社? 2500万人以上のストリーミング会員 500億以上のイベント ・AWSの利用は?(保存) 8TB/日のイベントデータを収集しS3に。 Cassandra上の顧客データもS3に。 1PB以上のデータがS3に保存。 ・AWSの利用は?(解析) EMRでレコメンデーション、アドホック分析、パーソナライゼーションなど。 本番クラスタ(ずっと動かしている) アドホック分析用クラスタ(必要に応じて構築) 解析用のアルゴリズムをAPIで叩けて、ジョブとして定義されてるらしい ・Cassandraを使ってるよ。 Cassandraのクラスタをマルチリージョンで対応したりもしてる。 CassandraのBackupもやってる。OSSで公開されてる? ※HBaseのものもあるよ。 ※AWS上のCassandra事例もいくつか広告系で出てるみたい。 ・High I/O Instances for EC2(SSDのインスタンスまだ東京に無いらしい。) ・AWSスケールアウトだけでなく、スケールアップも徐々に増えています。 ○yelp ・どんな会社? 口コミサイト。 スペルミスの自動修正、検索ワード自動補完、 ・AWSの利用は? WebサイトのログをS3に保存。 EMRを利用してHadoopClusterで解析してS3に保存している。 EMRは処理終了後にシャットダウンしてる。 ・データ解析が日常になった ○SHAZAM ・どんな会社? 広告配信、モバイル系の配信をやってる会社。 Super Bowlの広告配信でAWS、DynamoDBを利用。 ※マイネット・ジャパンでもDynamoDBを利用している ○CLIMATE Corporation ・どんな会社? 天候保険の会社 ・AWSの利用は? 200TBの地質、天候データを解析して ○THOMSON REUTERS ・どんな会社? 情報提供の会社。データの提供が元だけど、解析した結果の情報も提供してるみたい。 ・AWSの利用は? MarketScanという18年分の個人の医療データ(個人情報自体はないみたい)を販売する、販促ールとして利用。 1500万人分の患者データを提供。 マーケットの分析に使えるデータの提供。 KARMASPHEREとEMRの組み合わせで、ソリューションを提供していますよと。 ・事例 1.MarketScanをS3にアップロード。 2.分析官が、KARMASPHERE経由でEMRにアクセス。 3.EMRにS3からデータロードされ、結果がRDS(Oracle)に保存 4.RDSに他の人達もアクセスして使ってるよと。 ○RANGESPAN ・どんな会社? ECサイト向けのPaaSサービスを提供してるロンドンの会社。 ・AWSの利用は? NLP、機械学習にEMRを利用? mongoDBのクラスタを構築してる。 ※mongoDBの日本の事例としてCAがあるらしい。 ★Huahin Framework活用事例 on AWS @ryu_kobayashi ○Cassandra本とかもやられてるみたい。 ○EMRとは PaaSなんだけど、中身を自分でいじれるらしい。 Management Consoleでは3つのバージョンが使えるが、コマンドラインからだと他にも使えるみい。 ・HBaseはAmazonのDistributionのものだけ。 ・EMRのメリットは? インフラの面倒を見なくていい。 クラスタの立ち上げも複数あげられるので簡単。本番実行と同じ環境 ・EMRのデメリット オンプレミスにすでにデータがあるとアップロードが大変。実際に物理HDDを送ったこともある(2,3日でAWS上にアップロードされた) 外に出せないデータがあると。。。 ○EMRのTips(EMRの連載に載ってますよ!http://gihyo.jp/dev/serial/01/emr) ・Bootstrapを設定 EMRのクラスタの起動前にメモリ設定とかHadoopの設定が可能にできる。 ・ファイルサイズを適切に Map数=splitを決めるコード を指定することで、処理が早くできるのかな? ○EMRの起動には いろいろあるけど、HuahinEManagerを使うと使いやすいよ? ○Huahin Frameworkの構成 ・Huahinの名前の由来は? 社内のコードはワインの産地にするという決まり。 タイの観光地Hua Hinがワインの産地。 ・他のHadoop関連のマスコットより可愛いでしょ!? ・Huahin Core MRのプログラムを簡易化 WritableとかSecondary Sortとか書かなくていい 考え方がSQL寄り 素のMRも書ける。Pig、Hiveだとパフォーマンスが難しい Huahin UnitというMRUnitをラップしたものもある ・Huahin Tools 汎用的な処理を集めたツール群だけど、Apache Logの成形のみ。 オンプレミスHadoop、スタンドアロン環境でも動かせるようになってる。 ・Huahin Manager Jobを管理するマネージャ Jobの実行 キューを持ってるので、複数の実行が可能だよ。 EMR対応してる。bootstrapに設定するとできるらしい。 ・Huahin EManager EMRのいろいろが管理できるみたい。 初期設定20までしかインスタンスが挙げられない上限があるらしいので気をつけましょうと。 キュー登録のPOST機能は便利そうだ。(EMR触る機会まだまだないけど。。。) EMRにはJobのkillがない→Job FlowをターミネートすればOK→実際にはEMRのマスタノードにSSHすればできるよ。→めんどくさいよね。。。 EManagerなら可能ですよと。これは必須だよなぁ。 ","date":1352477220,"dir":"post/2012/","id":"98c640616f997a323af625e34ba34850","lang":"ja","lastmod":1352477220,"permalink":"https://blog.johtani.info/blog/2012/11/10/aws-%E3%83%93%E3%83%83%E3%82%B0%E3%83%87%E3%83%BC%E3%82%BF%E6%B4%BB%E7%94%A8%E4%BA%8B%E4%BE%8B%E3%82%BB%E3%83%9F%E3%83%8A%E3%83%BC%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-jawsug/","publishdate":"2012-11-10T01:07:00+09:00","summary":"初目黒(たぶん)で、初Amazonな感じで、流行りの「ビッグデータ」のセミナーに参加してきました。 とりあえず、いつもの自分用のメモを残してお","tags":["勉強会"],"title":"AWS ビッグデータ活用事例セミナーに参加しました。#jawsug(Jugemより移植)"},{"contents":"##Lucene/Solr 4.0.0リリース ついに、Lucene/Solr4.0.0がリリースされました。 MLで流れていましたが、3年越しのリリースだったようです。 コミッターの方々、JIRAにバグ報告をした方々、お疲れ様でした。\nということで、ちょっと忙しくなりそうです。。。 4.0の機能を調べたりもしたいですし、すこしずつ紹介もしたいです。\n本家サイトのニュースはこちら\n##lucene-gosenの4.0対応版について lucene-gosenも4.0正式版のjarを利用したバージョンを公開する予定です。 branches/4xでは、すでに作業を行なっており、jarファイルの差し替えは終了しています。 お急ぎの方は、branches/4xをエクスポートして、ビルドしていただくと利用可能となっています。 なお、Lucene/Solrのバージョンが上がっているため、lucene-gosenのメジャーバージョンも変更し、lucene-gosen-4.0.0としてリリースする予定ですしました。。(順当に行けば、3.0.0ですが、Luceneのメジャーバージョンに合わせたほうがわかりやすいかと思いまして。) また、現在、trunkが3.6.x対応のソースになっていますが、このあと、現在のbranches/4xのソースをtrunkにする予定です。 3.6.x対応のlucene-gosenについては、branches/lucene-gosen-rel2.0にて作業を行うこととなります。 今後は注意してチェックアウトするようにお願いいたします。\nということで、ダウンロードできるようにしました。 lcuene-gosen-4.0.0*.jarとついているものがLucene/Solr 4.0.0に対応したライブラリになります。\n","date":1350031500,"dir":"post/2012/","id":"922cc71fd28b1dac8f407f1d517f5595","lang":"ja","lastmod":1350031500,"permalink":"https://blog.johtani.info/blog/2012/10/12/lucene-solr-4-0-0%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9lucene-gosen%E3%81%AE4-0%E5%AF%BE%E5%BF%9C/","publishdate":"2012-10-12T17:45:00+09:00","summary":"##Lucene/Solr 4.0.0リリース ついに、Lucene/Solr4.0.0がリリースされました。 MLで流れていましたが、3年越しのリリースだったようです。","tags":["lucene-gosen"],"title":"Lucene/Solr 4.0.0リリース&lucene-gosenの4.0対応(Jugemより移植)"},{"contents":"このイベントにウチダスペクトラムの枠でMahoutのコミッターである、Grant Ingersollさんが講演されるということで、興味があったので聞いて来ました。 (この枠だけ)\nLucidWorks社が現在展開している、LucidWorks BigDataの概要とコンセプトといった話の内容でしょうか。 LucidWorks社(元Lucid Imagination)はLucene/Solrのコミッターの方々が多く在籍している会社です。 検索システムに関するノウハウを元に、発見や解析といった部分にニーズが広がってきているという話の ざっくりした概要のはなしでした。 検索システムを中核にして、ログや検索で提供しているデータの解析などの重要そうなポイントが散りばめられて いるお話でした。\nもっと詳しい話を聞きたいなぁ。\n講演では日本語の資料でしたが、サイトに英語の資料がアップされているとのことでした。 原文が読めるのは非常に助かります。他のイベントなどでもこのように英語の資料も見れるようになると嬉しいです。\n以下は、いつものメモになります。\n場所:富士ソフト アキバプラザ5Fホール 日時:16:10- ◯サーチ技術による情報の可視化 通常、検索と言うとWebサーチだけど、ウチダスペクトラムのやっている部分はエンタープライズ向け ナイスガイ=Grant S. Ingersollという紹介 ◯サーチからSDAへ LuceneやSolrのお陰で、検索自体は簡単になってきている。 ◯サーチの進化 ユーザとデータを結びつける意味での検索の進化が必要 ユーザインタラクションや、アクセスの方法とか ◯SDA Search, Discovery and Analytics ・ユーザからのニーズ 検索、優先順序付け、新たな気づき、フィードバックによる学習 ・ビジネスからのニーズ ナレッジの有効活用 ◯ユーザ事例 保険会社での請求に関する不正利用分析を含んだクレーム処理と分析 ◯事例:個人に最適化された医薬品 DNAをベースに検索やファセットで医薬品を検索したり。 ◯事例:通信会社における通話記録処理 ログを元に検索して、不正通話などを解析 ◯SDA基盤に必要な要素 高速で拡張性のある、検索 大規模でのコスト効率が高いストレージと処理 NLPとMLにより解析などが向上 ◯SDAのアーキテクチャ 基盤 LucidWorks Search、Hadoop、HBase、ApachePig、Mahout、 NLP、 管理 Zookeeper インフラ ZABBIX、AWS、Chef データの流し込み Twitterからのデータとか ◯検索部分にフォーカス ・LucidWorks Search SolrCloudによる簡単なshard処理 ・Hadoop ログ、生データ、中間ファイルの保存 WebHDFS 小さなファイルには向いていない ・HBase メトリック、ユーザ履歴などのストレージ 課題 どこに正式に保存する? リアルタイム処理 vs バッチ処理 分析はどこで行われるべきか? ◯検索の実装に関連すること 3つのポイント 性能と拡張性 関連性 オペレーション(モニタリング、フェイルオーバーなど) ビジネス側では検索結果の適合性を重要視する 開発側は性能を重視する傾向がある。 ◯適合性に関して テストが重要。 クエリ、クリック、表示したドキュメントなど、すべて保存すべき! ◯Discoveryにフォーカス ◯MahoutによるDiscovery 3つのC ・協調フィルタリング ・クラシフィケーション ・クラスタリング 追加事項 課題 収束を伴う計算コストの高い機械学習アルゴリズム Mahout ◯余談:Experiment Management ◯Analyticsにフォーカス Rとか、うまく活用 検索エンジン自体でもできることがある。ファセット、TF、DF/IDF SearchとDiscoveryの定量化 ログ、ナビゲーション分析 ","date":1348650492,"dir":"post/2012/","id":"43501cdf0de25278a208cbb9aad80012","lang":"ja","lastmod":1348650492,"permalink":"https://blog.johtani.info/blog/2012/09/26/lucid%E3%81%AEgrant-ingersoll%E3%81%95%E3%82%93%E3%81%AE%E8%AC%9B%E6%BC%94%E3%82%92%E8%81%9E%E3%81%84%E3%81%A6%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-09-26T18:08:12+09:00","summary":"このイベントにウチダスペクトラムの枠でMahoutのコミッターである、Grant Ingersollさんが講演されるということで、興味があった","tags":["勉強会"],"title":"LucidのGrant Ingersollさんの講演を聞いてきました(Jugemより移植)"},{"contents":"PFIオープンセミナー2012に参加してきました。 対象から微妙に外れてたり、話の内容についていけるか自信がありませんでしたが、参加してきました。 PFIさんは前から面白そうなことやってる会社だなぁと思っていたので。\n面白い話がいっぱい聞けました。 電池が切れそうなので、とりあえず、まずはメモをアップしときます。 かろうじてついていけたという感じですが。 丸山先生の話はアーキテクチャの話に入る前のビッグデータの光と影の話がよかったです。 ビッグデータと言っても、まずは、サンプリングなどで小さなデータで処理できるかもしれないと考えるのも必要なのでは?という話や、相関があるからといって、因果が有るわけではないとか、おそらく、統計やってる人や、数学やってる人にしてみれば、当たり前の事なんでしょうが、その部分に警鐘を鳴らす話が聞けたのは良かったです。 もちろん、ビッグデータでなければ意味が無い解析などもありますという話もきちんと出ていました。\n伊藤さんの話は、Screwと呼ばれる、多言語解析基盤のお話です。その前にSedueの紹介で、SolrとSedueの比較の話も出ていました。(若干、強引な感じもしましたが。。。) 多言語解析基盤は、Solrでも少し入ってきています。ただ、それよりも汎用的な作りになるようなので、今後Solrと組み合わせて使うといったことも可能になるかもしれません。 まだ、対応言語などが少ないので今後に期待という感じでしょうか。 複数の言語が混ざった時の挙動がどうなるのかや、身近な文章での言語判定の正確さは少し気になります。\nサイバーセキュリティの話も面白かったのですが、話が多岐にわたるのと、スライドの情報量の多さに少しついていけませんでした。 資料が公開されたら、もう一度見直したいかなぁと。\n比戸さんの話は、Jubatusと関連のある話でした。機械学習の実際の利用の話が特に興味深かったです。 最近になって、ようやく、実際のデータを利用した話が出てきているみたいで、もっと事例が出てくると機械学習も身近になりそうだなぁと。\n最後は、日経BPの中田さんの話でした。これが、一番想像していたものと内容が違って、驚きつつ、楽しめた話でした。 ビッグデータというバズワードがいかにして生まれたのかがよく分かりました。 私は、バズワードだなぁと思う程度だったのですが、出てきた背景にある程度意味があるという考察に感心して聞き入ってしまいました。\nということで、思っていたよりも話の内容についていけたので、講演された方々の話しのされ方が良かっただと思います。\n少し無理をして参加してよかったと。\n残念だったのは、会場が地下だったため、携帯が入らなかったことでしょうか。 私はe-mobileで接続していたので大丈夫でしたが、docomoの携帯は圏外でした。 ツイートがもう少し盛り上がれば、もっと質問も出たのかもしれないです。\nhttp://preferred.jp/news/seminar/\n資料が公開されたので、リンクを貼っておきます。 PFIの方たちの資料へのリンク: http://preferred.jp/news/?id=1139\nゲスト講師の資料へのリンク: http://preferred.jp/news/?id=1159\n◯「多様化する情報を支える技術」 講師:西川徹(株式会社プリファードインフラストラクチャー 代表取締役) ・PFIの説明 VCに頼らない。製品につながるビジネスにこだわる(受託開発しない)、技術の多様性を重視 ・PFIの技術領域、ビジネス 製品開発(Sedue/Bazil/Jubatus)、自然言語処理、機械学習、分散システムなど ・”人”が生み出すデータと\u0026#34;機械\u0026#34;が生み出すデータ ビッグデータの発端はGoogleが元じゃないか?→最後の公演で解説があるよ 人:質が高いけど、量が少ない 機械:質は低いけど、量が多い ・検索システムについてのお話 社内の資料とか情報が、人によって、まちまちなデータの保存(形式、場所など)が実施されてしまう。 情報検索技術と大規模データ ・人のデータへ必要なアプローチ より検索システムを活用してもらうために、楽に整理できる仕組みなどをどう提供するか 質の高いデータなのに、形式的な共有しかできていないのはもったいない ・機械のデータへ必要なアプローチ 大量データと高度な解析が重要(CEPとか) デバイスが性能向上→流れてくるデータが大量に→蓄積するだけでも問題になってくる →蓄積したデータを扱うだけでも処理コストが高くなる 分析をオンライン化、ストリーム化すること→Jubatusで貯めずに高度な解析をしましょう。 Edge-Heavyになりつつある。 ◯「ITアーキテクチャはどこへ向かうのか」 講師:丸山宏氏(統計数理研究所 副所長 モデリング研究系教授 工学博士) ・ビッグデータの光と影 「その数学が戦略を決める」という本がオススメ ・大量データでも、ランダムサンプリングでとければ、ビッグデータじゃなくてもいいよね。 もちろん、ランダムサンプリングだけじゃダメな場合もある。 ・Hadoopが解ける問題領域って少ないのでは。 ・TVを見る時間が長い人ほど、方言の使用率が高い 因果関係と相関関係の違いをきちんと理解しましょう。 ・データをきちんと理解して意思決定などをしたほうがいいよと。 ・つぎのアーキテクチャは何か? ・コンピュータ・アーキテクチャの歴史 ConnetionMachine CM-1(1985) SPARC Transputer(CSPによる並列性、Occam) SymbolicsLispMachine Intelアーキテクチャの台頭により、アーキテクチャの研究が廃れてくる ・クラサバ、スマホ・クラウドなどのアーキテクチャの話 ・じゃあつぎは? Edge-Heay Data=スマホなどデータが保存される場所がEdgeになりつつある ビッグデータのほとんどが廃棄されるデータ ・Edge-Heavy Dataに特化したアーキテクチャとは? 分散マッチング・プロトコル→サマリ情報を交換することで、絞り込みが可能 X=3とした場合、センサーとかなら、ピンポイントな値ではなく、範囲では。 分布表現を1stクラスオブジェクトとするプログラミング言語が必要では? ・アーキテクチャの変節点を見極めよう QA: Q:スパースネス問題がランダムサンプリングやフィルタリングじゃ解けないんでは? A:はい。ただ、その前にやることがあるはずですよねという注意喚起の意味での発表です。 価値に応じて、EdgeにあるデータをCenterに持ってくるという考え方が必要。 今は価値が見いだせないのなら、Centerにまで持ってこなくてもいいのでは。 ◯「グローバル化する情報処理」 講師:伊藤敬彦(株式会社プリファードインフラストラクチャー 研究開発部門 リサーチャー) ・Sedueの説明 NHKニュースなどで ・提供する機能 ・検索補助 レコメンド、サジェストなど ・レコメンド機能の紹介 ・Sedue/Solrの比較 サポート体制:開発チームがサポートしてくれる 安定性:GCがないのがいい 付加機能: 検索の完全性:接尾辞配列による検索 ・多言語処理の話 ・翻訳ではなく、任意の自然言語言語で動作・精度を向上させる処理の話。 ・背景 サービスのグローバル化、会社組織のグローバル化 ・複数言語を扱う場合の難しさ 多言語解析基盤Screwの開発。 1.必要な処理を順番に適用する 処理の順序は設定で。出力はJSONで。 例:言語同定、単語分割、単語正規化 →言語同定処理で 2.言語ごとに必要な処理を適用 ・疑問 ScrewはSolrとの組み合わせもできる? 複数言語が混ざった文章の場合にどういう形で動作する? 言語判定は独自実装? ◯「BigData処理技術とサイバーセキュリティ」→題名変更されてた 講師:桑名栄二氏(NTTセキュアプラットフォーム研究所 所長) ・経歴 Jubatusプロジェクト立ち上げに参画 ・攻撃に関する話 原因のわかっていないケースが多い。 ・端末の初期設定のパスワードとかが狙われるケースも多い ・変化する攻撃、変化するシステム・サービス、変化するデータ ・マルウェアの分類にJubatus ・不正IPアドレスを機械学習して ・ABC 「あたりまえ」のことを「ばかみたいに」「ちゃんとやる」 ◯「先進ビッグデータ応用を支える機械学習に求められる新技術」 講師:比戸将平(株式会社プリファードインフラストラクチャー 研究開発部門 リサーチャー) ・ビッグデータ分析はより深い地検を得られるビッグデータ「解析」へ ・ビッグデータ分析プロセス Volume、Variety、Velocity 蓄積(NoSQL系)、分析(CEP)、両方やるのがHadoop ・分析から深い解析へ 予測、カテゴリ分類、レコメンド、異常検知 これを機械学習で解決する方向で ・機械学習を応用している例 クレジットカードの不正利用検知:FICO ネットワーク攻撃/侵入検出 Jeopardy!でクイズ王に勝利 医療診断支援 ・データ解析技術への過度な期待と現実とのギャップ いろいろできるみたいだけど、何が必要? ・ビッグデータ処理系を使える人 ・データサイエンティスト ・機械学習ツール ・ビッグデータ処理系での機械学習への対応状況 Hadoop本体(YARN) MapReduce系(Mahout、AllReduce or Vowpal Wabbit、SystemML) 非MapReduce系(Spark) ・機械学習からビッグデータへの歩み寄り ベンチマーク性能への固執とか、応用との乖離を批判する論文もあるらしい。 ・機械学習の応用例 Machine Lerning for the New York City Power Grid[Rudin et al., TPAMI, 2012] 電力配電設備の障害予測・検知 実データを用いた例が今後増えていくのでは。 ・今後重要になる技術とPFIの取り組み ・データ解析の敷居を下げるためのトレーサビリティ 機械学習向けスクリプト言語は敷居が高い WekaやSPSSのようなアイコンベースのデータ処理プロセスの記述は前処理には強力だけど、機械学習とは相性が良くない 結果が見える化部分との統合が不十分。 ・Bazil Farm学習結果分析例 Tweet年齢推定、Tweet性別推定 ◯「“ビッグデータ”が話題になった理由」 講師:中田敦氏(株式会社日経BP社 記者) ・自己紹介 ・バズワードができるまで まずは、「クラウド」のバズワードの歴史 「バズワードはIT企業やThe Economist誌の煽りでなく一般企業の経営陣が納得すると生まれる」 ・なぜ経営者がビッグデータに興味を? 「ザ・クオンツ」という書籍に金融業界のルールの変化が書かれてる。面白いよ。 Google/Amazonに対する警戒心から。 破壊的な新規産業者へ対抗して行かないといけない思うところからビッグデータが流行ってるのでは。 「買ってきたIT」は差別化要因にならないのでは?→自分で作ったITなら差別化できる。 ・競争力は自分で作るしか無い 日本のとある特殊事情 ITエンジニアの所属先が日米で割合がぜんぜん違う。米国はユーザ企業が75%、日本は25%くらい ・ビッグデータの次はなに? 3次元プリンタがあれば、好きなモノが作れちゃう。=消費地の近くで作成しちゃえば良くなるのでは。 ","date":1348214700,"dir":"post/2012/","id":"89abaa7f21cf788ce4744e3e61173291","lang":"ja","lastmod":1348214700,"permalink":"https://blog.johtani.info/blog/2012/09/21/pfi%E3%82%AA%E3%83%BC%E3%83%97%E3%83%B3%E3%82%BB%E3%83%9F%E3%83%8A%E3%83%BC2012%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%A6%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F--pfiopen2012/","publishdate":"2012-09-21T17:05:00+09:00","summary":"PFIオープンセミナー2012に参加してきました。 対象から微妙に外れてたり、話の内容についていけるか自信がありませんでしたが、参加してきまし","tags":["勉強会"],"title":"PFIオープンセミナー2012に参加してきました。 #pfiopen2012(Jugemより移植)"},{"contents":"友人にお値打価格で購入したMac miniはMountain Lionにアップデートしてたのですが、手元のAirはまだアップデートしていませんでした。\n夏休み中にバックアップ+アップデートをしてしまおうと思いMountain Lionにアップデートはしていたのですが、 本格的に触り始めると色々と動かないものがあったので、備忘録としてブログを書いておきます。 (まだ途中ですが。)\n###1.Eclipseが起動しない Java6が未インストール状態になったみたいで、Eclipseを起動すると、Java6をインストールしなさいと言われました。 で、私の記憶が確かなら、前はJavaコマンドを実行するとインストールされたんですが、ターミナルでjavaコマンドを実行するとjavaはすでにインストールされてる模様。。。 あれ?と思い、-versionを実行すると、JDK7u4と出るじゃないですか。 どうやら、Java7u4は別途入れてたものが残ってる模様。 さて、どーする?ということで、ツイートしたりぐぐってみて、「Java Preferences」なる設定用のアプリ?が有ることに気づき、とりあえず開いてみたらJava6ないからインストールしたら?と言われました。 結果オーライということで、インストール開始。 無事、インストールも終了。Eclipseも起動しました。(ただし、今度はMercurialのプラグインがPythonのライブラリが無いとエラーを出すことに) ###2.Xcodeが起動しない。 使ってはいないんですが、Javaの件を調べるのに、起動したらLionじゃないと駄目だよと。 ということで、Xcodeもインストールしなおし。 ###3. homebrewが動かない 1.で書いた方法で、Eclipse自体は起動したんですが、Mercurialのプラグインがエラーを吐き始めました。 で、見てみると、hgコマンドを実行しようとしてなんか、壊れていると。 で、hgコマンドってどうやってインストールしたか思い出さないまま、とりあえず、homebrewだっけ?と勘違いしたまま、「brew update」を実行したらエラーがでて、「brew install git」でしょ?って言われてしまいました。 コメントにもいただいていたように、Xcodeをインストールしたのだが、コマンドラインツールが入ってないというのが影響しているみたいです。。。 で、ググってみると、こんな情報が。[http://labs.torques.jp/2012/07/04/2830/](http://labs.torques.jp/2012/07/04/2830/) ただ、そこに有るようにPreferenceのダウンロードを開いてもなーんにも表示されません。 で、更にググってこちらの情報に。[http://qiita.com/items/9dd797f42e7bea674705](http://qiita.com/items/9dd797f42e7bea674705)(なんだか、TLで見かける人のお名前が!) AppleのDeveloperサイトからダウンロードかぁと思いつつダウンロード用のリンクを踏んだら、アカウント登録しろとのページが。。。 なかなか遠い道のりですね。。。 Appleのアカウント自体は持ってるので、Developerへの追加登録なんですが、日本語が文字化けしまくりの確認ページが出る始末。 もう、めんどくさいので、そのまま登録しちゃいました。 で、ダウンロードする前にもう一回XcodeのPreference見てみたらなんか、ダウンロードする候補が出てきてるじゃないですか! 結局、XcodeのPereference画面からダウンロードすることにしました。 AppleのDeveloperに登録したからなのか、Xcodeのプロジェクトを作ろうとしてXcodeをきちんと起動したからなのかは結局わかっていません。。。 良くないよなぁ。(ご存知の方いたらコメントもらえると嬉しいです。) で、やっと「homebrew」を入れようかなぁと。 一応その前に「sudo brew update」ってやってみたらどうなる?と挑戦したら今度は動きました。 homebrewが何を判断してinstallでしょ?って言ってたのかもわかっていませんが、updateで良かったみたいです。 ついでに、upgradeもしときました。(こっちは後からインストールしたもののバージョンが上がってるものがあったら更新してくれるコマンドかなぁ?)\n###4. pipの更新 ただ、brewをupdateしても相変わらず、EclipseのMercurialのPluginはエラーを出してました。 で、ターミナルからhgコマンドを実行してみたら同じエラーが。まぁ、そうですよね。 エラーメッセージを頼りにこれまたググってみたら、同じ状況のひとがいました。[https://groups.google.com/forum/#!msg/mercurial-ja/MxY6lejLXxo/OgJA_knXV6cJ](https://groups.google.com/forum/#!msg/mercurial-ja/MxY6lejLXxo/OgJA_knXV6cJ)(ここにもTLでお世話になってる方のお名前が!!) で、書いてあるように「とりあえず pip install mercurial で解決しました. 」ということで、コマンドを実行して見ることに。 これが、また失敗します。。。(日頃の行いが悪い??てか、日頃MBAをメンテできてないのが悪いのか。。。) そういえば、過去のMBAセットアップのメモを残してたなぁと思い出して「johtani mercurial」でググってみるとちゃんと[書いてある](http://johtani.jugem.jp/?eid=34)じゃないですかー(偉いぞ、自分) ということで、「sudo easy_install pip」でpipを更新してから「sudo pip install Mercurial」で無事、hgコマンドもインストールし直せました。 Eclipseを起動してもエラーが出ない。(まだbitbucketに接続確認まではできてないですが。。。眠さに勝てず寝てしまいました。) ","date":1346650440,"dir":"post/2012/","id":"7604edf307a5e96120606c8dda06458f","lang":"ja","lastmod":1346650440,"permalink":"https://blog.johtani.info/blog/2012/09/03/%E3%83%A1%E3%82%A4%E3%83%B3mba%E3%82%92mountain-lion%E3%81%AB%E3%82%A2%E3%83%83%E3%83%97%E3%83%87%E3%83%BC%E3%83%88%E3%81%84%E3%82%8D%E3%81%84%E3%82%8D%E7%A2%BA%E8%AA%8D%E4%B8%AD/","publishdate":"2012-09-03T14:34:00+09:00","summary":"友人にお値打価格で購入したMac miniはMountain Lionにアップデートしてたのですが、手元のAirはまだアップデートしていませんで","tags":["備忘録"],"title":"メインMBAをMountain Lionにアップデート(いろいろ確認中)(Jugemより移植)"},{"contents":"興味をもちつつ、触っていない軟弱者ですが、興味があるので今回も話を聞きに行って来ました。\nまずは、作者古橋さんによるFluentdの魅力や次期バージョンのお話。 あいかわらずわかりやすいスライドで話もわかりやすくてよかったです。 どうしても実績という点を懸念事項として上げる人が多いというアンケートを元に、各社が使ってるし導入もしやすいですというお話。 ここまでしてもらってるのに触ってないなんてほんと申し訳ないです。。。\n次は楽天の方によるCloud Foundryのログの問題点解消のためのFluentd導入のお話。 EC2でもそうですが、ファイルが永続化されない?のでログが消えてしまうという問題があるので、 集約しましょうと。 いままでとは少し違う問題点からの話でした。\n次はドリコムの方(浴衣?甚平?でかっこ良く発表)のIDCをまたいだFluentdの活用と、Fluentd自体の監視などについてのお話。 実際にログが増殖して苦労された点を解決するために考えられた監視項目など、あとで見返したくなる資料でした。 実際に試行錯誤されたあとの話はやはりありがたいです。 あと、お子さんが可愛かったw\nつぎのCROOZの方のPCがWindowsだったため(?)プロジェクターに繋がらず、急遽QAタイム。 このあたりの@doryokujinの話のつなぎの旨さとかほんとすごいなぁと感心します。\nで、Macに乗り換えてCROOZの方の発表。 Fluentd+TreasureDataのお話。少人数(というか一人?)でも簡単にログ収集の仕組みが作れて、しかも保存先のサーバを用意せずに簡単な解析もできるというお話。 これは、ちょっとやってみようと思う人(少なくとも、私はやろうと思った)が増えたんじゃないかなぁという発表でした。 スライドがなぜか最後のほうが見えなくなってしまったので、第3回でも発表されるということになってましたw 最後は新大阪から文字通り駆けつけた玉川さんのHBase本+そのた今後の翻訳本の紹介。 つぎはHiveの本も出てくるみたいでした。 日本語の資料ってホント助かります。購入しないと翻訳本が出る機会もないみたいなので皆さん買ってくださいとのこと。 HBaseはまだ触りそうにないから9月に出るAWSの本でも買おうかなぁ。 あ、日本語で解説してあるSolrの本もあるので是非買ってください!\nその後は懇親会でした。今回もTL上でズケズケと私が勝手に絡んでいる方たちにリアルにお会いできたので楽しかったです。\n自分もフロントよりも、バックエンドに興味があるし、実際に運用されてる人の話が多く聞けるので次回も参加したいです。 それまでにどこかで触るかplugin作るかしないとなぁ。\nということで、以下はいつもの適当メモです。\n開催日時:2012/08/22 18:00 ~ 22:00 場所:グリー株式会社 14F セミナールームYosemite ◎「Fluentdの現在と未来」 Treasure Data, Inc. 古橋 貞之 (@frsyuki) ◯アンケートの内訳 ◯ドキュメント欲しい? ※思ったより日本語のドキュメントじゃなくてもよさそうだった。 ◯loggingってなんでいるの? いろいろな解析ってあるよね。 ◯ログの集約、保存、などの問題点について フォーマットが混在 集約するのもいろんなスクリプトが混在 ◯メリット ・プラグインアーキテクチャ in/outに合わせてプラグインが用意/開発可能 ・フォーマットがJSON アプリでの解析が楽 ・HA構成が可能 ◯実績がない?→ 誰が使ってる? COOKPADとか、NHNとか ◯次期バージョンの構想 ・設定ファイルで色々とらくできるよ。 ・MessagePackのv5に対応 ・td-agent-lite などなど ◯QA Q:時刻にミリ秒を持つことは可能? A:互換性も気になりますが、検討します。 Q:JSONで構造化が売りだが、Flumeとかはテキストだけど、テキスト A:ログのパース時にやるというスタンス。 Q:日本語ドキュメントがやっぱり欲しい。手伝います! A:別ブランチで翻訳しながら公開して欲しいし、バラバラにやるよりいいので。 Q:Windowsでも動かしたいけど、cool.ioの移植とか考えてないですか。 A:次期で、fluentdのコアからはcool.ioを外す予定です。 ◎「Logging Infrastructure in PaaS by Fluentd」 Rakuten, Inc. Yohei Sasaki (@yssk22), Waldemar Quevedo (@wallyqs) ◯Cloud Foundryの説明 ◯Cloud Foundryの問題点 解析しようにもログが消えてしまう。。。 なので、Fluentdでログを集める仕組みを作ったよと。 これかな? https://github.com/rakutentech/dea/ ◎「Fluentdを優しく見守る監視事例」 株式会社ドリコム 外道父 ( @GedowFather ) ◯概要: Fluentdをより穏やかに安定稼働させるための監視項目と自動処理について。また,その実運用における障害例なども紹介したいと思います。 ◯目次 ◯動作環境 ・IDCもバラバラな環境のログを一箇所に集約。 グローバルなネットで、圧縮、暗号化し、VPN使ってない ・tailのプラグインを改良して利用 copy、flow counterを利用 forwardも改良 Flume OGとは比較にならないし、FlumeNGはOGと全然違うから論外だった。 ◯ローカル監視 ・monit使って監視してる。 ログを記録してるか、内容が正しいか td-agentが正しく起動してるか、Collectorに送っているか 重複起動してないかとか、起動してるかとか。 ※重複起動でログが増えてた(@mazgi濡れ衣事件) HDFSに送ってるか、保存されてるか ◯リモート監視 アラート/グラフ作成の集約 状態の可視化 Collectorのキャパシティ管理 Agentにキャパシティの心配はほぼないが、Collectorは足りなくなる可能性がある。 ◯野望 CollectorでAgentを把握したい ◯QA Q:圧縮はどうやって? A:forwardを改造してやっている。 ◎QAタイム Q:秒間どのくらい出るの? A;秒間8000メッセージくらいらしい。 Q:ハートビートの取りこぼしは? A:案1:UDPじゃなくて、TCPにする。案2:TCP接続してたらハートビートのカウントとしてしまう。 Q:CollectorのCPUに影響があるのってなに? A:ロックがCPUを食う=ロックが影響→リクエスト量を減らす Q:Windows対応はいつ?(発生源がWindows) A:td-agent-liteをWindows対応にしたいと思ってる。 Q:F#の実装とかテストは? A:性能値の測定までは行ってない。メッセージが送れたなぁくらい。 Q:設定のDSL化はv11ではなくなったの? A:ホスト名は入れたい。設定はやっぱり設定だけにしたい(プログラムは入れたくない) プラグイン側がDSL対応してればDSLできるようなものは入れようかと思ってるが、 DSLは延期したい。 A(tagomoris):DSL化したいパターンが幾つかに絞れるなぁと思ってて、それに合わせたプラグインをいくつか作ってるよー。 ◎「Fluentd \u0026amp; Treasure Data でこっそり始めるログ集計」 CROOZ 株式会社 池田 朋大( @mikeda ) ◯概要: FluentdとTreasureDataプラットフォームを使って、1インフラエンジニアが勢いでログ集計システムを作ってみたお話です ◯アクセスログ、エラーログ、メールログ(試験中)を集めてる。 ◯TreasureData 500Gまで無料なのかー。 ◯ダマで入れてもばれないぞ! ◯最後は心の目で見えるスライドでした。 ◎祝・O\u0026#39;Reilly HBase 訳本発売。訳者本人によるPR。 Sky株式会社 玉川 竜司 ※ O\u0026#39;Reillyの新刊「HBase 」 http://www.oreilly.co.jp/books/9784873115665/ ◎懇親会 そうそう、ステッカーもらったのでアンケート書きましたw ","date":1345657200,"dir":"post/2012/","id":"775894425f5a7436f56fc5a3b4a2cfaa","lang":"ja","lastmod":1345657200,"permalink":"https://blog.johtani.info/blog/2012/08/23/fluentd-meetup-in-japan--2--fluentd-%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-08-23T02:40:00+09:00","summary":"興味をもちつつ、触っていない軟弱者ですが、興味があるので今回も話を聞きに行って来ました。 まずは、作者古橋さんによるFluentdの魅力や次期","tags":["勉強会"],"title":"Fluentd meetup in Japan #2 #fluentd に参加しました。(Jugemより移植)"},{"contents":"またまた飲みに行って参加してきました。 今回は、Rails、iOSでのTwitter連携の話から、ツイート分析、クライアントアプリの開発の苦労?楽しい話と、 幅広い話題でこれまた面白かったです。\nRailsはあとで、もう一回資料+ビデオがみたいかも。あと、発表者の方が言ってたけど他の言語の似たようなサンプルがあると面白いかも。(Solr入門みたいに同じ題材で違う言語のサンプルとか)\nツイート分析は、私の使い方とは異なる分析結果がちょっと意外でした。土日はあんまりツイートしないからなぁ。 利用時間帯とかは、他のSNS(Facebookとかmixiとか)の分析と比較してみると面白いのかも。 まぁ、深夜帯はそれほど利用は無いだろうけど。\nAttaccaは自社や自宅でコーディングするときに利用させてもらってます。 どうしても自分のお気に入りのリストを作ってそれを聞くので満足しちゃうんで、 他の人のお気に入りも一緒にシャッフルして再生とかできると面白いかもなぁ。 もう少し、他にも曲を発見したいんだけど、その導線がもう少しうまく行くと嬉しいかも。\nチャーハン諸島の話は開発者の原点みたいな話で面白かった。やっぱり、自分で作るの大事だよなぁと。 作りたいと思うものがあるのはいいことだし、実際作ってみないとわからないこともいっぱいありますよねぇ。 ただ、何か作ろうかなぁと思うものがあるのはちょっとうらやましいとも思いました。 なかなかサービスとか、ほしいものを作ろうと思うところまで行かないからなぁ。年取ったのかなぁ。\n懇親会では、いつものように@twtrfkさんと喋って、あと Lytroを触らせてもらいました! 思ったよりも大きいのが第一印象。 ぱっと見で、何の変哲もないところがズームするところだったりと、インタフェースがちょっとおもしろかったです。 ピントが後から合わせられるということで、どうしても同じ構図になっちゃうのがなぁという話も聞けましたw けど、ちょっと欲しいかもなぁ。動くものを撮るとどんな感じなのかも聞くんだった。\n次回は9月中旬!らしいので、余力がありそうだったらまた遊びに行きます。\n日時:2012/08/01 19:00 ~ 21:00 場所:デジタルハリウッド東京本校 1Fセミナールーム\nいつもの自己紹介タイム\n@i7a16k(@_gifteeの中の人) スライドはこちら\n「RailsでTwitter連携アプリをサクっと作る」 ・まずは、Railsの紹介 MVC+routes.rbの紹介 ・Dev Twitterの登録する必要なとことか。 ・Railsのインストールから起動まで。 ・実際にログイン画面を作成するまでの紹介 コーディングするコマンドの紹介。動画付き omniauth_twitter ってのを使うみたい。 ・サインイン、サインアウトまで。 ツイートは次回! 録画がよくできてて、それに合わせてしゃべるのもうまいなぁ。 @teapipin(ツイッター分析シリーズ の方) スライドはこちら\n「約173万ツイートを調査して分かったTwitterの利用動向」 ・ハンドル名は午後の紅茶からきてる?+ピピン@ ・ブログで色々公開してます。 ・サービス作るのに、下調べをしてみましたというお話 情報が無かったから、自分で調べてみたよと。(すばらしい) ・Streaming APIで取得 タイムゾーンとか言語設定の取得でもうまく取れない。。。 ということで、UnicodeBlockで判定してみたけど、、、 最後は手作業で不要データを除去(すごい!) ・4日間で172万ツイート (金環日食とかスカイツリーのイベントがあったので、4日間で我慢) ・上位5個で50%を占めるクライアントみたい ・日曜日が多いらしい ・携帯が60%くらい ・位置情報(Geoタグつき) 日本が多い。4sqが40%占めてる。 店舗情報や天気情報などもあるらしい。 人口と関係した相関が散布図でわかった。 そこで、ツイート内容との関係を分析 あとで資料みたいなー @i2key(#attacca の関係者) スライドはこちら\n「iOSのTwitterFrameworkを使ってみたら・・・・」 ・Twitter4Jのほうが楽だったよー デモがいいね! ・アーキテクチャ play!をバックエンド。Amazonとか。 iOS Twitter framework ・Reverse Authの使い方とか。 申請してから、20日間かかった。 @Mocel(チャーハン諸島 開発者) スライドはこちら\n「(仮)Twitter クライアントの開発とかについて」 ・趣味プログラマー ・「ラーメン大陸」のクローン:「チャーハン諸島」を開発 Excel溶けこむGUI Javaで実装 コマンドライン風のTL画面もある(自分では使ってないけど) 「電力会社の電力使用量モニター」もクライアント初搭載! ラーメン大陸のバージョンチェックも可能w ・開発したことで 自分のニーズにジャストフィット 優しい気持ちになれる(苦労がわかる) Twitter APIのテストとかもすぐ試せる ・GUIアプリ開発のノウハウも手に入るからオススメ ・API利用規約は読んどこうね ・自動アップデート機能がいるよ。→バージョンごとのサポートがなくなるよ。 ・通信エラー前提で作りましょう ・鍵付きの非公式RTはやめなさい。 ・Twitterクライアントの作成はおもしろいよ! 反応がプレッシャーになることもあるけど。 おもしろ機能をつけるのがいいよーと 話が上手で聞きやすかった。 ","date":1343875800,"dir":"post/2012/","id":"8a29f62d1bebfe7b8008d7f264b56b4e","lang":"ja","lastmod":1343875800,"permalink":"https://blog.johtani.info/blog/2012/08/02/twitter-%E5%8B%89%E5%BC%B7%E4%BC%9A--twtr_hack-%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-08-02T11:50:00+09:00","summary":"またまた飲みに行って参加してきました。 今回は、Rails、iOSでのTwitter連携の話から、ツイート分析、クライアントアプリの開発の苦労","tags":["勉強会"],"title":"Twitter 勉強会 #twtr_hack に参加しました。(Jugemより移植)"},{"contents":"ということで、ステッカー欲しさ?に勉強中の話を恥ずかしげもなく偉そうにしゃべってきました。 #pyfesは以前から、気になっていたんですが、タイミングがあわず初の参加になりました。 TwitterのプロフィールにSenseiDBに興味あると書いていたら、@voluntusさんに声をかけていただけて、 さらになぜかelasticsearchの話をすることにして話をしてきました。 まだまだ、いろんな意味(プレゼン的にも内容的にも)で至らない所だらけだったので反省しまくりですが、 これでまた経験値が稼げたかなと。次回に活かしたいと思いますです。 やっぱり、しっかり勉強して、シナリオを練ってから発表しないとダメですね。。。\n発表のスライドは一番最後にリンクを用意しておきましたので、興味があれば見てもらえればと思います。\nということで、いつものメモを残しておきます。\n日時:日本オラクル青山センター 場所:2012/07/28 10:00 - 20:00 概要:こちらにページあり\n前半(10時から15時)はハンズオンなどをやられてました。参加せずにスライドを微調整して、他の勉強会のスライドをいじったりしてました。 以下は、15時から行われたスライドのメモになります。\n◯PyConJP の宣伝 @shomah4a(LT) 9/15-17 PythonカンファレンスJapan App Engine、Django、Sphinxなどのカンファレンスも併設 遠方参加者支援制度があるらしい。 ◯elasticsearch 入門 @johtani わかりにくい話でしたかねぇ。。。 ◯たのしいうぇっぶくろーら @tokoroten(LT) index.htmlをクロールしまくってる社畜2.0の人らしい。 ◯Sphinxを使って翻訳してたら本が出てた話 @ymotongpoo(LT) OSSでもドキュメント翻訳でお手伝いできるよ。 そしたら、いつのまにか書籍も出せたよ。 スライド\n◯iOS関連のお話 @Seasons バイナリ解析をしてゴニョゴニョする話。 解析するのに何を使ったとか思考の遷移を説明してくれるのでわかりやすい。 スライドが大きなマインドマップを切り出した形。 ◯HBaseのお話 @shiumachi HBase 分散DB 列ファミリ思考 HBaseなんで? RDB→シャーディング→だるい。。。 シャーディング→スケールできねー nandeHBase? 書き込みスケールできるよ。 KVS HBaseのデータ構造 キーがいろいろな情報を含んでる キーがソートされてる HBaseのテーブル構造 リージョンがシャーディングの情報もと? リージョン見つけなど スライド\n◯PythonではじめるGit @mkouhei GitPython LXCホスト? GitもPythonも初心者だわー ◯勉強会を成長させる参加者になろう @sawonya イラストレーター(スタートアップRubyのイラスト書いた人。サインもらいましたw)。 参加者が増えるとなにがいいの?など。 勉強会参加に向けた勉強会の講師とかやられてるらしい。 スライド\n◯IT 系勉強会ネタ(仮) @tmmkr アジャイルサムライを読んだ情報を共有したくなって読書会を開催してみた! ビアバッシュのケータリングとかは楽天デリバリーとか、カクヤスがいいよ。 かなり、いいスライドなので、あとで見返す。 今、読書会やったりしてるし、Solr勉強会の役にも立てそうだし。 スライド\n◯Do not invent your RNG... @kenji_rikitake Androidの乱数のコードがすごいらしい(ひどい) Pythonの乱数ではos.urandomを使うのが安全です。 オレオレ乱数は作っちゃ駄目! ◯分散ファイルシステム(LeoFS) @yosukehara LeoFSの開発者の方。 Erlangで98%書いてある。 Masterノードは存在しない。SPOFになるから。 分散システムとして元にした概念とか論文ってあるんだろうか? ◯継続的デリバリー @troter CIとデリバリーの話。 いいこと書いてあるんだけど、実際のツールの話しがないのが辛いこともある ということで、Python周りのツールをこうして見たよというお話。 Rubyの方がものがいろいろ揃ってるらしい ◯クライアントサイドのみで作ったダッシュボード @takufukushima RESTアクセス用のUIのフロントエンドの話? JSのお話の?node.jsとかの話。 MVCにしたり、CSSフレームワーク使ったり。 backbone.jsつかってるらしい。 実際の画面がみたいなぁ。 現状の話なので、 ◯Meinheld @mopemope Python3対応とかLoggerとかやってから秋くらいに出るみたい。 このあたりは未知の領域です。。。 ◯3分間で開発環境構築 @tk0miya Vagrant+Chefみたい。 VeeWeeってのでIOSイメージからVMイメージを作ってくれる。 (githubから持ってこないといろいろ古いらしい) これ、重要だと思う。 実践するようにしよう。 手順書がわりにChefのレシピを書こうよと。 環境マニア募集中! 継続的デリバリー座談会やってます ◯筋トレ講座 @hiroki_niinuma ジムに通い続けるのはキツイ。 成功率5% 以下の条件に ・10時間以下の仕事時間 ・ジムが近い ・ジムという環境が好き ベンチマークw先入観を捨てましょうとw ジムで筋トレとかよりも歩くのが全然いいよと。 togetterがあったのでリンク。 http://togetter.com/li/346242 http://togetter.com/li/346270\nスライドはこちら。\n** [Elasticsearch入門 pyfes 201207](http://www.slideshare.net/JunOhtani/elasticsearch-pyfes-201207) ** from **[Jun Ohtani](http://www.slideshare.net/JunOhtani)** それにしても発表するといういい機会を与えてもらえて良かったです!。 継続的にelasticsearchも調べていきたいので、興味ある人は声をかけてくださいー\n","date":1343466900,"dir":"post/2012/","id":"7fa2f0877831b4c924438396760f1841","lang":"ja","lastmod":1343466900,"permalink":"https://blog.johtani.info/blog/2012/07/28/python-developers-festa-2012-07%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%A6%E3%81%97%E3%82%83%E3%81%B9%E3%81%A3%E3%81%A6%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F--pyfes/","publishdate":"2012-07-28T18:15:00+09:00","summary":"ということで、ステッカー欲しさ?に勉強中の話を恥ずかしげもなく偉そうにしゃべってきました。 #pyfesは以前から、気になっていたんですが、タ","tags":["勉強会"],"title":"Python Developers Festa 2012.07に参加してしゃべってきました #pyfes(Jugemより移植)"},{"contents":"今日はSolr 4.0 ALPHAの興味深い機能があったので紹介です。 数日前に「Solr 4.0: Partial documents update」という記事を見つけました。\nSolrには、ドキュメント(RDBで言うレコード)のデータを更新したい場合には、特定のフィールドだけを更新するという機能がありませんでした。 ですので、特定の項目(例えば、priceなど)を更新したい場合、ドキュメントの全データをSolrに再度上書き登録するという処理をしなければなりませんでした。 RDBを触っていた方が、Solrを始めた場合に必ず使いづらいと思われる点だと思います。\nで、4.0でその機能がありますという、「Solr 4.0: Partial documents update」の記事を見つけました。 ただ、SolrのWikiや4.0 ALPHAの紹介のページには「partial update」という記述が見当たりません。 (あれ、これかな?Update semantics) あと、まだ完成していないので、載っていないのかもしれないです。(このチケットSOLR-139が部分更新に関するもののはず。チケット番号をみても古くから望まれている機能だということがわかります。)\nということで、調べてみました。\n###機能概要\nSolrの機能として、特定のフィールドのみを更新するという機能です。 あくまでも、Solrレベルでの機能となり、Luceneの機能を利用したものではありません。 つぎのような流れになっています。\nSolrに対して特定フィールドを更新したいという形のドキュメントを投げる Solrはドキュメントを受け取ると、内部のインデックスに保存してあるデータを取り出す 取り出したドキュメントオブジェクトに対して、更新対象フィールドの値だけデータを更新する ドキュメントオブジェクトをインデックスに保存する このような流れです。 まぁ、言われてみれば当たり前な処理です。 ただし、この機能を使う場合はいくつかの前提条件があります。\n###前提条件\n前提条件はつぎのとおりです。\nすべてのフィールドをstored=\u0026ldquo;true\u0026quot;にする 「version」という特殊なフィールドを用意する 1点目は、データの保存方法についてです。 先ほど流れに書きましたが、Solrが内部に保存してあるデータを取り出して、更新対象以外のデータを保存しなおしてくれます。 このため、stored=\u0026ldquo;true\u0026quot;にしておかないと、元のデータがSolr内部で取得できません。\n2点目の「version」というフィールドは4.0から導入されたフィールドです。 SolrCloudに必要な機能としてドキュメントのバージョン管理を行うために導入されたフィールドだと思います。(あまり詳しく調べていない。。。) SolrCloud内でレプリカの更新などに使ってるのかなぁと(そのうち調べます。) 以上の2点が前提条件です。すべてのデータをstored=\u0026ldquo;true\u0026quot;としなければならない点は、インデックスのサイズや性能に関わってくるので考えて利用するほうがいいかと思います。\n###利用方法\nSolrのサンプルデータ(exampledocs/mem.xml)を例として利用します。 部分更新を行うにはつぎのような形のデータを投げると部分更新が可能です。 (JSONでの更新のサンプルについては、こちらの記事を参考にしてください。) ####XMLのサンプル(partial_update.xmlというファイルで保存する)\n\u0026lt;add\u0026amp;gt; \u0026lt;doc\u0026amp;gt; \u0026lt;field name=\u0026#34;id\u0026#34;\u0026amp;gt;VS1GB400C3\u0026lt;/field\u0026amp;gt; \u0026lt;field name=\u0026#34;_version_\u0026#34;\u0026amp;gt;バージョン番号\u0026lt;/field\u0026amp;gt; \u0026lt;field name=\u0026#34;cat\u0026#34; update=\u0026#34;add\u0026#34;\u0026amp;gt;cats_and_dogs\u0026lt;/field\u0026amp;gt; \u0026lt;field name=\u0026#34;popularity\u0026#34; update=\u0026#34;inc\u0026#34;\u0026amp;gt;10\u0026lt;/field\u0026amp;gt; \u0026lt;!-- set empty for SOLR-3502 bug --\u0026amp;gt; \u0026lt;field name=\u0026#34;price_c\u0026#34; update=\u0026#34;set\u0026#34;\u0026amp;gt;0.0,USD\u0026lt;/field\u0026amp;gt; \u0026lt;/doc\u0026amp;gt; \u0026lt;/add\u0026amp;gt; 上記サンプルのうち、バージョン番号の部分は、現在Solrに登録してある値を指定します。(Solrの管理画面で検索すれば表示されます。) 上記ファイルを「SOLR_HOME/example/exampledocs」に保存し、同フォルダにてつぎのコマンドを実行すると、部分更新されるのがわかります。 Solrに更新であるというフィールドがわかるように、fieldタグにupdateという属性を指定してあります。\njava -Durl=http://localhost:8983/solr/update?versions=on -Dout=yes -jar post.jar partial_update.xml ちなみに、上記post.jarのオプションで、「-Durl」「-Dout」を追加してあります。 「-Durl」はverions=onというパラメータを追加したいためです。 「-Dout」はPOSTした結果をターミナルに表示するために追加しています。 これらのオプションを指定すると、データ更新後のバージョンが取得できるようになります。\n####更新に利用できるコマンド? 部分更新にはつぎの3つのコマンド?(正式名は不明)が用意されています。fieldタグのupdate属性に指定します。\nコマンド? 説明 add 値を追加します。multiValuedのフィールドでない場合はエラーが出ます。 set 値を新規に登録しなおします。現在入っているデータは無くなります inc 指定された数値を加算(数値形式のみ) 以上が、部分更新の機能になります。 ちなみに、登録されているバージョンと更新データに入っているバージョンが異なる場合はエラーが発生する仕組みになっているようです。 それとは別に、この機能を調べていて、copyFieldのバグにぶつかってしまいました。。。 multiValuedでない、copyFieldを利用しているしている場合には注意が必要です。\n###copyFieldのバグ(SOLR-3502)\n4.0-ALPHA(3.6.0でも再現しました。)のexampleのデータで部分更新の機能を確認できると言いました。 ただし、「price_c」というフィールドのせいで、2回部分更新を行うと2回目にエラーが発生します。 根本的な問題は、部分更新ではなくcopyFieldのバグのようです。(部分更新の処理にも問題は有るような気がしますが。。。)\nバグの内容はつぎのとおりです。\nmultiValued=\u0026ldquo;false\u0026quot;のフィールドをdestに指定 srcに指定されたフィールドに値を設定(exampleのpriceフィールドに「1」を指定) destに指定されたフィールドに値を設定(exampleのprice_cフィールドに「2,USD」を指定) 上記のように設定した場合、「price_c」フィールドに、指定された値+「price」の値がcopyにより追加されます。 通常は「price_c」フィールドはmultiValued=\u0026ldquo;false\u0026quot;なのでエラーが出るはずなのですが、エラーが発生せず2つの値が登録されてしまいます。\nこのバグのため、exampleのデータを利用して部分更新を行うとつぎのような状態が発生します。 更新を行う対象のデータはprice、price_cフィールド以外のフィールドとします。\n1回目の登録後:priceフィールド「\u0026ldquo;185.0\u0026rdquo;」、price_cフィールド「\u0026ldquo;185.0,USD\u0026rdquo;」 2回目の登録後:priceフィールド「\u0026ldquo;185.0\u0026rdquo;」、price_cフィールド「[\u0026ldquo;185.0,USD\u0026rdquo;,\u0026ldquo;185.0,USD\u0026rdquo;]」 3回目の登録:エラーが発生 部分更新の処理で、すでに登録済みのデータをSolrが自動で取り出すため、2回目の登録処理にて「price_c」の登録済みの値がSolrから取り出され、さらにcopyField設定により、「price」の値が追加されます。 本当は2回目の登録でエラーが発生すべきなのですが、バグのためエラーが発生せずに登録できてしまいます。 部分更新の処理としては、copyフィールドのdestに指定されているフィールドの値を取り出さないほうがいいような気もしますが、きちんと考えてないのでなんとも言えないです。(制約事項とする形のほうがいいかもしれません)\n","date":1342177320,"dir":"post/2012/","id":"68a8f34c240a42ab521d2f885f7aa33c","lang":"ja","lastmod":1342177320,"permalink":"https://blog.johtani.info/blog/2012/07/13/partial-update%E3%81%A8copyfield%E3%81%AE%E3%83%90%E3%82%B0solr-4-0-alpha/","publishdate":"2012-07-13T20:02:00+09:00","summary":"今日はSolr 4.0 ALPHAの興味深い機能があったので紹介です。 数日前に「Solr 4.0: Partial documents update」という記事を見つけました。 Solrには、","tags":["solr"],"title":"Partial UpdateとcopyFieldのバグ【Solr 4.0 ALPHA】(Jugemより移植)"},{"contents":" Modern Information Retrieval: The Concepts and Technology behind Search (2nd Edition) (ACM Press Books) いやぁ、蒸し暑くてなかなか寝れない日がはじまりましたね。(あんまり関係ないですね。。。)\nModern Information Retrieval 2nd Editionを輪読会という形で読み始めました。 Solrに関わって数年ですが、昔から検索をやっていたわけではありません。 なので、そろそろ基礎的、理論的なところも勉強して行かないとなと思い、この本を買いました。 ただ、約1000ページある英語の本でして。。。 一人で読むと間違いなく挫折するし、理解不能になりそうだなと。。。\nということで、Twitterで呟いたら賛同してくれる方が現れ、輪読会を開催することにしました。 イベントの開催とか初めてなので、手さぐりしながらです。(それにしても、ほんと、Twitterは素晴らしい。賛同してもらえる人が見つかったのもTwitterのおかげだし。)\nさすがに細かく読んでいくと終わらなそうなので、1周目(できれば、2周目もやりたいなぁと思ってる。1週目が1年でも終わりそうにない感じだけど)は公開されているスライドを元に進めようと思ってます。 それにしても検索周りはいろんな技術が必要なのだなぁと分厚い書籍を見て、途方に暮れつつ、楽しみでもあるなと思いながら、輪読会後の飲みを楽しんでましたw\nということで、各分野の専門家もいそうなので、特別ゲストとして読んできて話に混ざってもらうのも面白いかもと夢想しつつブログを書いています。 だれかいないかなーw\n参考URL: 書籍のHPで公開されているスライドのページです。 http://grupoweb.upf.es/WRG/mir2ed/contents.php\n","date":1342111298,"dir":"post/2012/","id":"9ac7bb94e60dc30a023ce433de027364","lang":"ja","lastmod":1342111298,"permalink":"https://blog.johtani.info/blog/2012/07/13/mir%E8%BC%AA%E8%AA%AD%E4%BC%9A%E5%A7%8B%E3%82%81%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-07-13T01:41:38+09:00","summary":"Modern Information Retrieval: The Concepts and Technology behind Search (2nd Edition) (ACM Press Books) いやぁ、蒸し暑くてなかなか寝れない日がはじまりましたね。(あんまり関係ないですね。。。) Modern Information Retrieval 2nd Editionを","tags":["勉強会"],"title":"MIR輪読会始めました(Jugemより移植)"},{"contents":"Lucene/Solrの4.0.0-ALPHAが7/3にリリースされました。\nこれに伴い、lucene-goenの4xブランチのjarファイルも4.0-ALPHAのものに置き換え、現在のtrunkの修正もマージしました。 こちらにあります。チェックアウトしてビルドしてから利用してください。\n※さすがに、jarをダウンロードできるようにすべきかもなぁ。 あと、Maven登録も。。。\n","date":1341457909,"dir":"post/2012/","id":"dcc2e24df32287e89ee3b0f64d617f57","lang":"ja","lastmod":1341457909,"permalink":"https://blog.johtani.info/blog/2012/07/05/lucene-gosen%E3%81%AElucene-solr4-0-alpha%E5%AF%BE%E5%BF%9C/","publishdate":"2012-07-05T12:11:49+09:00","summary":"Lucene/Solrの4.0.0-ALPHAが7/3にリリースされました。 これに伴い、lucene-goenの4xブランチのjarファイル","tags":["lucene-gosen"],"title":"lucene-gosenのLucene/Solr4.0-ALPHA対応(Jugemより移植)"},{"contents":"またまた参加しました。いまだ皆勤賞です。 感想などはあとで。とりあえず、メモとったので第一弾です。\nということで、感想です。 まずは、参加人数。 今回は今までで一番、ATND登録した人が多かったんじゃないかなぁと。 埋まるのも早かったですし。やっとSolrというキーワードが多くの方に触れられるようになってきたんですかねぇ。\nmixiの事例はやはり、SSDを使った11億文書のインデックスが圧巻です。 実際にマイニングに利用していて、ネガポジ分析なども行われているようで楽しそう。 TLにもありましたが、「ヤバイ」はネガ?ポジ?など、そのへんの分析方法をもう少し詳しく聞いてみたい感じもしました。 あとは、Luceneソースコードリーディングの開催が楽しみです!(候補日知らせないと。。。)\nLucene Revolution 2012の参加レポートは、自己紹介がおもしろかったですw ずっと検索をやらてているのもあり、色々と理論ではなく、実践的なノウハウを持っていそうで、つぎはそのあたりの話を聞いてみるのも面白そうです(発表してくれないかなーw) 残念ながら、私はまだスライドを見ていないので、事例を中心にピックアップして見てみようかなぁと(時間がトレない。。。)\n最後は阿部さんの4.0の紹介です。タイムリーに、前日に4.0-ALPHAがリリースされたので、 資料がすごく参考になりそうです。 SolrCloudについても詳しく書かれてたし。(ちゃんと動くのかなぁ?)\n最後は懇親会です。最近知り合った方から、発表者、昔からの勉強会の参加者といろいろな方と今回も話ができて楽しかったです。 TL上で知り合った方にもお会いできたし。 次回もしゃべってもらえそうな人を捕まえつつあるので、また企画してもらうようにつついてみようかな。\n※そういえば、毎度のことながら4.0ベースで、書籍は出さないのかって言われましたw\n※ちなみに、4.0-ALPHAが出たので、lucene-gosenも4xブランチの更新作業をしています。 終わったらまたブログに書くと思います。\n第8回Solr勉強会 場所:VOYAGE GROUP 会議室 日時:7/4(水) 19:00 ~ 1. @haruyamaさん mixi での Solr の利用 ・mixiの全文検索 2011年以前:Hyper Etraier、Tokyo Dystopia、Senna 2011年以降:Solrを利用して新規案件の検索システムの構築、入れ替えを行なっている。 ・Anuenueの論理構成など。 ・物理構成 1マスター、2スレーブ インデックスが小さい、QPSが100以下 インデックスサイズが大きいものは今後構築予定 ・今後やりたいこと ・ログ分析 ・パーソナライズ ・外部ストレージ参照のカスタム関数 ・外部ストレージをファンクションカスタム関数クエリ FunctionQueryを活用したい。 ・上記のデモ(検討中のもの?) 現在はjar内部のファイルを読んでるよと。 速度的な面がどうなるかがきになるところ。 ・テキストマイニング mixiボイス haruyamaさん入社前:ダンプして解析してた haruyamaさん入社後:Solrに載せちゃえば 600GのSSD 約11億文書 約450GB 利用してるもの:Solr 4.0(2012/01) lucene-gosen 1.2.1 自作フィルタ haruyama/solr-filter - GitHub ・利用統計の説明。 女性が多い。 「AKB」だと20代前半が多い。男性はおっさんも頑張ってる。 ・mergeindex機能を利用して、過去データとマージしてる。 1日分だけ集計したいこともあるかもしれないから。 updateじゃなくて、mergeindexなのは、ソッチのほうが早かったから。 ・拡張してる分析 ・ポジネガ分析 形容詞>絵文字>顔文字でスコアが効く 機械学習して辞書を調整してる ・Luceneソースコードリーディングまたやりますよ! 2. 楽天株式会社 大須賀 稔さん Lucene Revolution 2012 in Boston参加レポート(仮) ・まずは自己紹介。 infoseekに転職→楽天→Ask.com→楽天(そして英語) ・Lucene Revolutionってなに? ・トレーニング Scaling Search with Big Data \u0026amp; Solr Hadoopの紹介 SolrとHadoopのMapReduceを利用したインデキシングのハンズオン Solrのスケーリング(Sharding、Replication)、マルチテナント ※http://www.lucidimagination.com/services/training/big-data-training-scaling-solr 日本ではやってない、残念。 ・カンファレンス スライドとかはlucidimaginationのサイトで見れるよと。 http://www.lucidimagination.com/devzone/events/conferences/lucene-revolution-2012 ・Lucidworks Big Dataの紹介 Hadoopとかいろいろ組み合わせて使えるよと ・Microsoftの人がAzureでSolrの紹介 IEとかWindows8の話ばっかり。 ・Kuromojiの紹介 やはり、マイノリティ。 内容は日本語勉強会w 中国語とかは対応するの?日本語しか知らないです。。。 ・ErickさんのSolrCloudの話 4.0は2012年にリリースする予定 スコアリングをプラガブルに。 管理系画面がリッチだよと。 ・一番重要だなぁと思ったのは。。。 「英語」!(会社的な感想ではありません。。。) Q:これはみとけ的なスライドは? A:Hadoop上でインデキシングして、ビットトレントとかで連携してるという例が面白かった。 Q:FASTとかと比べてSolrってどーなの? A:ESPは洗練されてる。クローラーとか、ベイシスのトークナイザーを内包してるとか。 Solrは言語処理系が弱かったとかあるけど、そろってきてるのでは。 4.0は互角になるんじゃないかなぁ。 ESPがWindowsオンリーになるので、LinuxユーザがSolrに行きつつある。 3. 株式会社 ロンウイット 阿部さん Solr 4.0の紹介 ・Solr 4.0の主な機能の紹介 3.xは3.6が最後4.0-ALPHAが7/3に出た ・プラガブルなスコアリング BM25、Language Models、Divergence from Randomness、Information-based Models 関口さんがスライド作ってる ・FST対応 Finite State Automata/Transducer オートマトン理論を活用したもの。 TokenStreamはFSAで実装 SynonymFilterがFSTになると、オフセットが変わってくるらしいと。 ・Codecプラグイン Luceneレベルのお話。 ドキュメントをファイルに保存するときの形式をプラガブルに変更可能。 SimpleTextなどもあるらしい。テストに利用できそう。 APIレベルで、マイグレーションの必要があるかも。 ・NRT Near Real Time Search softCommitのお話 Realtime-get:IDを入れたらGETできるよと。 KVSとしても活用できるぞ~と。 ・PivotFacet Facetが階層的(?)な感じで取れる ・JOIN、pseudo-join ローカルパラメータでできるよーと。 ・SolrCloud インデックスの分散配置をやってくれる(3.6まではやってくれない) shardがダウンしたらフェイルオーバーしてくれそう Master/Slave環境 リアルタイムインデクシングとリアルタイム検索とか ・ZooKeeperIntegration実装 リーダー選出、コンフィグの管理などなど ・ManifoldCFの近況 5月にトップレベルに昇格! http://manifoldcf.apache.org/ja_JP/index.html 0.6は7月に出そう。日本語にもなってる。すげー Alfresco Connector、ElasticSearch Connectorなども Solr Plugin for Enterprise Searchとか ","date":1341402000,"dir":"post/2012/","id":"8acc78be63e27e938ee53ec2c0b90c61","lang":"ja","lastmod":1341402000,"permalink":"https://blog.johtani.info/blog/2012/07/04/solr%E5%8B%89%E5%BC%B7%E4%BC%9A%E7%AC%AC8%E5%9B%9E%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F--solrjp/","publishdate":"2012-07-04T20:40:00+09:00","summary":"またまた参加しました。いまだ皆勤賞です。 感想などはあとで。とりあえず、メモとったので第一弾です。 ということで、感想です。 まずは、参加人数。 今","tags":["勉強会"],"title":"Solr勉強会第8回に参加しました。 #SolrJP(Jugemより移植)"},{"contents":"Hadoopからはちょっと離れているのに、面白そうなネタなので参加しました。 Data Science Summit、HBaseCon、Hadoop Summitのイベント参加レポートです。\n最初の草薙さんの発表が実は一番興味を惹かれていたので、参加しました。 データの解析に関するサミットというのはなかなか聞いたことが無いのでどんな内容なのかなぁと。 ちょうどVisualizeなどに興味を持っていたり、データ解析、今後重要ですよねという話が出ていたりしていたので。 実際にデータ解析が今後重要で、どんなことに使えるのかなど、製品に偏らない内容のようで色々とためになりました。 この内容をずっと聞くのは私には無理ですw英語も数学もイマイチなので、ついていけない自信がありますw。 「データ分析の結果をビジネスに結び付けられる人とかが今後重要になります」という話が一番気になったキーワードでした。\nHBaseConもかなり濃い内容だったようです。 私は残念ながら、HBaseの概要の概要くらいしか知らないので、内容にはついていけてないですが。。。 Facebookがかなり活用しているようですが、残念ながらスライドが上がっていないようです。 Solrに関連する話もあったようです。HBaseとSolrを組み合わせたLilyプロジェクトに関連する話のようでした。 スライドは登録しないと見れないみたいです。\n最後はHadoop Summitの参加レポートです。 まずは、ユーザ寄りの内容を@muddydixonさんから。個人的に、Twitterの話が多いのかなぁと。 ここでも、Visualizeの話が出ていたとか。 Lucidの話もあったようです。LucidWorks BigDataの話かな?\n最後は@shiumachiさんのHadoopのプロダクト寄りのお話。 YARN(Map/Reduce2.0?)やHBaseの今後の展望など。YARNはキーワードだけ知っていたので、わかりやすい解説で、やっと理解できました。 全体を通して、HBaseが今後もっといろんな局面で使われそうだなぁと。日本語の本も7/24に出るし。(まだページが無いみたいなので、英語のほうを。)\nいつものごとく、途中でビールが入ったので後半はメモが適当ですが、楽しかったです。皆さんお疲れ様でした。\n帰り着いたら、さっそくスライドが上がってました。すごい! スライドはこちら(2012/06/26 0時現在)\nData Science Summit / EMC Worldレポート HBaseCon 2012 参加レポート』の発表スライドをアップしました。(NTTデータ 猿田 @raspberry1123 /岩崎) @muddydixonさんのHadoopSummit2012参加レポート @shiumachiさんのHadoopSummit2012参加レポート @muddydixonさんのブログ いろんなキーワード、特に、データサイエンス寄りの話が面白かったです。 次回はJenkins関連のようで、7/30開催みたいです。\n以下はいつものメモです。\n日 時: 2012年6月25日(月) 19:00~21:00 (受付開始 18:40) 場 所: 豊洲センタービルアネックス(NTTデータ、豊洲駅直通) ◯ Data Science Summit / EMC World レポート (EMC Japan 草薙) ・Data Science Summitのレポート 揃ってるようで揃ってないスロットの写真w EMC World2012と併設 今回2回目。 ・OpeningKeynote: What We Can Predict About Prediction by Nate Silver 研究者は不確実性やリスクを包含した、現実的な予測モデルを開発すべき いろいろ ・Roundtable: Economic, Political, \u0026amp; Societal Roles of Social Data ユーザの「query-like intent」を自然言語解析と機械学習で捉える 属性だけじゃなく、活動を コンテンツからコンテキストへ、コンバージョンからカンバセーション ・Big Data Transformation - HealthMap ウィルスのアウトブレイクの検知(160日→20日)に。 ウィルス=コンピュータじゃない方 ・Big Data Transformation - Intuit int.com? データがあるから、こういうことが知りたいなどの新しいプロセスが 「https://www.mint.com/」 ・Big Data Transformation - InfoMotion Sports Technologies バスケのボールにセンサーつけて、試合や選手の解析に利用して、 チームが強くなったりしてるらしい。 ・Big Data Transformation - Decide.com アメリカ?の価格比較サイト ソーシャルデータを元に、買い時、売り時を予測して教えてくれる。 もうすぐ新しいモデル出るかもよ?などの噂を利用してる。 ・Analytics Maturity: Master or Novice? 2010年のアメリカの教育事情のレポート データサイエンス系の統計とかがもっと必要なんじゃないか。 ・Keynote: Navigating the Road from Business Intelligence to Data science Piyanka Jain BIの限界とか、データサイエンスの恩恵を受け入れるのに必要なもの?など システムじゃなくて、人やスキルに投資しましょう。 データ分析の結果をビジネスに結び付けられる人とか。 Panel: From Raw Data とValue Data プライバシー問題 データ品質の問題 異常値を除外するなと。最も興味深いデータになることもある。 \u0026#34;Data exhaust\u0026#34;の問題 個人が日々インターネット上で行う様々なインタラクションに関するデータの集合 相関と因果関係の区別が大変難しい。 Panel: Tapping Into the Pulse of the Data Science movement ストーリを持ってデータを語れるのが重要。 Keynote: Data Visualizeation at the Point of Influence by Adam Bly Closing Keynote: The Promise and Peril in the Human / Technology Relationship by Jonathan Harris TEDで有名な人 まとめ アメリカはこの分野での投資は回り始めている. http://www.greenplum.com/datasciencesummit/ ◯ HBaseCon レポート (NTTデータ 猿田/岩崎) ・GeneralSession HBaseの開発に参加してね。 ・レプリケーション、セキュリティ、セカンダリインデックス、スナップショット、バックアップなど特に貢献して欲しいと。 ・HBaseによりカバーできるアプリケーション領域 メッセージング、位置ベースアプリケーション、リアルタイムレコメンデーション、広告最適化 ・開発者への要望 メッセージをちゃんとして 解析用メトリクス 管理ツール ・M/Rジョブとの連携の改善 ・自動チューニングなど ・Applications ・GAPの事例 色々試してHBaseにした。 クラスタ構成、16Slave、3Master、NN Failover via NFS ※ZKはスレーブに置くと、アウト。 ・Tumblr 最初は失敗した。 OpenTSDBを経験して、Motherboy V1に。 テストフェーズまでが目的 →幾つかの知見が得られたよーと。 Motherboy V2を構築中。 ・Facebook ひと月250TBペースで増加中。。。 なんで、HBaseにしたの? 低レイテンシ、水平スケール、一貫性重視の設計、M/Rとの親和性とか Schema V1=Snapshot Schema Schema V2=Split Snapshot Schema Schema V3=Hybrid Schema HBaseのデータにさらにインデックス作ったりとか。 Schema Vertion Current=Finer grained schema and Indexer 読み書きの単位を分析して、スキーマを分割して細かくして行っていた。 ・Operations ・HBaseで困ったよ at Facebook ・リージョンサーバに特定データ入れると連鎖的に死亡 ・サーバが死に切らないとか。 ・HBaseは落ちるときは落ちるので、しぶとく生き残れるアプリを作ってねと。 ※Facebook関連のスライドなどがあがってませんと。 ・HBaseバックアップについて Clouderaの人とFacebookの人 ・選択肢 DistCP /hbaseディレクトリまるごとコピー。一貫性が保証されない exportツール MRジョブ。1度に1つのテーブルのみ copytableツール データを別クラスタに保存 exportツールに似てる。 レプリケーション 。。。 アプリケーションから複数クラスタへの書き込み 。。。 ・ユースケース ・HBASE-5509を利用したバックアップ ・開発中バックアップ HBASE-6055スナップショット、HBASE-4618など ・Development ・HBase Schema Design Salesforce.comの人 非正規化でやりなさいと。Joinはおすすめしないと 最後にデザインパターンが載ってると。 0.行キーの設計がすべて 1.Design for the questions, not the answers. 2.データサイズは2種類しかない。大きすぎるか、そうじゃないか。 3.コンパクトに詰め込め 4.行単位の原子性を活用する。 5.属性は行キー内に移動することができる。(Lars Georgeがfoldingと読んでいる手法) 6.エンティティをネストさせると、データを事前に集計できる。 ・HBase Performance Tuning And Organizations Facebookの中の人 テーブルの事前スプリット オフピーク時間を設定する。(0.94で入った) コンパクション設定が効いてくるよ ・SolrのバックエンドにHBase??? ◯ Hadoop Summit レポート (@muddydixonさん) ・オープニングビデオは必見 ・ショーケース ・Datameerを注目した。Visualizationの専任チームがいる。 UIじゃなくて、解析部隊だけで60名 お値打価格。$2900/年 ・Azure Big Data JavaScriptで ・ショーケースLucid Solr、HBaseとかいろいろ組み合わせて。 ・Session Hadoop... 2015までにApache Hadoopに世界のデータの半分が乗るらしいと。 ・Session Realtime analytics with Storm and Hadoop フォロワのフォロワをunique処理したり。 ・Session Scalding Twitter\u0026#39;s new DSL for Hadoop ※Zipkinにも出てきたな、名前。 ・Hadoop Plugin for MongoDB ・Hadoop and Vertica The Data Analytics Platform at Twitter Twitter社でのHadoop周りのデータフローとか。 Verticaは速度がいるものの処理に利用 80-100TB/dayとか。。。 ・Keynotes ・Big data analyzing system is censor of company. ・It is difficult in blind and deaf. ・Session Large Scale Search, Discovery and Analytics with Hadoop, Mahout and Solr ※@muddydixonさんのブログにセッションに対応するスライドのリンクを公開中。http://d.hatena.ne.jp/muddydixon/20120617/1339919125 ◯Hadoop Summit レポート (@shiumachiさん) ・Hadoop1.x MapReduce 非常に安定 ・課題。。。 ・YARN(Yet Another Resource Negociator) ターゲット:6000~10000ノード 100,000以上のタスクの同時実行 10,000ジョブの同時実行 性能は倍以上 Q:これは同じプログラムを動かして? A:。。。倍以上です!(わかんないっす。) 今後の予定 幾つかのJIRAの紹介 MAPREDUCE-4327とかHBASE-4329とか まとめ YARNは「汎用」分散処理基盤に向けて一歩踏み出したもの! 更なる進化に注目と ・HBaseの可用性とリペア ダウンタイムを短くしよう。 障害停止7割くらい。 設定ミスが44% 不安定な機能は使うな、推奨構成を推奨! HBase 0.92+Hadoop 2.0 HDFS HAによる高可用性とか 将来:HBase 0.96+Hadoop 2.x 計画停止時間削減:オンラインスキーマ変更(HBASE-1730) ローリングアップデート:バージョン間互換性が必須 HBase本読みなさい。 金があれば、サポート買ってください。 日本語HBaseトレーニング開催予定(来月) ・HBase NameNode HighAvailability ``` ","date":1340642460,"dir":"post/2012/","id":"9f29c6d9719fc6bc09a2981057642b69","lang":"ja","lastmod":1340642460,"permalink":"https://blog.johtani.info/blog/2012/06/26/hadoop%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89%E3%83%AA%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0%E7%AC%AC10%E5%9B%9E%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-hadoopreading/","publishdate":"2012-06-26T01:41:00+09:00","summary":"Hadoopからはちょっと離れているのに、面白そうなネタなので参加しました。 Data Science Summit、HBaseCon、Hadoop Summitのイ","tags":[],"title":"Hadoopソースコードリーディング第10回に参加しました。#hadoopreading(Jugemより移植)"},{"contents":"Issue 32で上がってきたlucee-gosenのUniDic対応の最初のパッチを書いたので、ブログに残しておきます。\n###UniDicとは___ UniDicとは、日本語テキストを単語に分割し,形態論情報を付与するための電子化辞書です。 UniDicの詳細や特長についてはHPを御覧ください。\n残念ながら、UniDicは利用者登録をして、利用規約に従うと利用が可能となります。 ですので、lucene-gosenでは、Ipadicやnaist-chasenの辞書とは異なり自動で辞書をダウンロードする機能はありません。\n###利用手順___ 以下が、Unidicの辞書を利用したjarファイルの作成方法となります。\n1. lucene-gosenをダウンロードし、パッチを当てる lucene-gosenのリポジトリからソースをエクスポートし、パッチをダウンロードし、パッチを適用します。 コマンドは以下のとおりです。\nsvn co . lucene-gosen-trunk-readonly cd lucene-gosen-trunk-readonly patch -p0 \u0026amp;gt; ...patch (パッチに関しては今後正式版をリリースされたら手順からは必要なくなります。)\n2. Unidic辞書生成のためのディレクトリを作成「$GOSEN_HOME/dictionary/unidic」\nmkdir dictionary/unidic 3. 対象となるUnidicの辞書のソースファイルをダウンロード 利用者登録をし、利用規約に同意の上、以下のファイルをダウンロードします。 「/」に添ってダウンロードページから遷移してダウンロードしてください。\n1.3.12個別ファイル/unidic-chasen/unidic-chasen1312src.tar.gz 4. ダウンロードしたtar.gzファイルを「dictionary/unidic/」にコピー\ncp .. lucene-gosen-trunk-readonly/dictionary/unidic/ 5. Antを実行してjarファイルの作成\nant -Ddictype=unidic 成功すれば、lucene-gosen-trunk-readonly/dist/lucene-gosen-2.1-dev-unidic.jarファイルが生成されます。 あとは、通常通り、SolrやLuceneで利用することが可能です。\n以上がjarファイルの作成手順となります。\n###制約事項(2012/06/18現在)___ 現在(2012/06/18)時点で公開しているパッチは、以下の制約が存在します。\nCOMPOUNDエントリー未対応 品詞情報(発音)の内容の制限 COMPOUNDエントリー未対応 Unidicの辞書のエントリーの中に1件だけ、COMPOUNDと呼ばれるエントリーが1件だけ存在します。 別々の単語を組み合わせて1単語として扱うことができるようになっているようです。 lucene-gosenでは、残念ながら、このような辞書の形式には対応していません。 1件しか存在しないデータでもあることを鑑みて、今回の辞書構築処理では、スキップするようにしました。\n品詞情報(発音)の内容の制限 lucene-gosenの実装上、単語の読みのバリエーション数と発音のバリエーション数には以下の制限が存在します。\n「読み」バリエーション数 < 「発音」バリエーション数 「読み」に対応する形で、「発音」がlucene-gosenでは品詞情報としてデータ登録されています。 UniDicのデータには上記制約を満たさないデータが5件ほど存在します。 現在、これら5件のデータについて、「読み」に対応した「発音」データには空文字が表示されるようになっています。\nまだ、簡単に動作確認をしただけです。UniDicを利用していて問題など有りましたら連絡、Issueへのアップをしていただけると助かります。\n","date":1340028180,"dir":"post/2012/","id":"d13aa56e27fe71ef40ff153c093ecdf8","lang":"ja","lastmod":1340028180,"permalink":"https://blog.johtani.info/blog/2012/06/18/lucene-gosen%E3%81%AEunidic%E5%AF%BE%E5%BF%9C/","publishdate":"2012-06-18T23:03:00+09:00","summary":"Issue 32で上がってきたlucee-gosenのUniDic対応の最初のパッチを書いたので、ブログに残しておきます。 ###UniDicとは___","tags":["lucene-gosen"],"title":"lucene-gosenのUniDic対応(Jugemより移植)"},{"contents":"「鉄は熱いうちに打て」ということで、残りも勢いでメモ。 まだ、見直しとかしてない状態なのでおかしいところとかありますが。。。 図とか入れるのはまた今度。\nTransport(転送)\nZipkinとHadoopに異なるサービスからのトレースを送信するのにScribeを利用します。 ScribeはFacebookにより開発されました。 システムの各サーバで実行できるデーモンとして作成されています。 ログメッセージをListenし、カテゴリごとのcorrectレシーバーに配送します。 Zipkin collector daemon\nトレースデータがZipkinコレクターデーモンに配送されたらvalidかどうかをチェックしてから保管し、インデックスを作成します。 Storage\nストレージにはCassandraを選びました。 スケーラブルで、柔軟なスキーマをもっており、Twitter内部で大変使われています。 このコンポーネントをプラガブルにしようと試みましたが、困難なため、ここでは公開しません。 Zipkin query daemon\n保存、インデックスされたデータを探す方法が必要です。 クエリーデーモンはユーザに対して簡単なThriftAPIを公開しており、トレースを探すことが可能です。Thrift fileを見て下さい。\nUI\n多くのユーザはUI経由でデータにアクセスします。 VisualizeにD3を利用したRailsアプリケーションです。 UIの認証は実装していないことに注意してください。\nモジュール Zipkin内部のモジュール関連図\n##インストール___ Cassandra\nZipkinはCassandraをストレージにしています。Cassandraクラスタが必要になります。 1. Cassandraサイトを参考にしてクラスタを構築してください。 2. Zipkin Cassandraスキーマを利用します。つぎのコマンドでスキーマが作成できます。 bin/cassandra-cli -host localhost -port 9160 -f zipkin-server/src/schema/cassandra-schema.txt Zookeeper\nZipkinは協調のためにZooKeeperを利用します。 これは、保存すべきサーバをサンプルレートで決定し、サーバを登録します。? 1. ZooKeeperのサイトを参考にインストールしてください。 Scribe\nScribeはトレースデータを配送するのに利用するロギングフレームワークです。 ネットワーク保存先としてZipkinコレクターデーモンを指定する必要があります。 Scribeの設定は次のようにします。 \u0026lt;store\u0026amp;gt; category=zipkin type=network remote_host=zk://zookeeper-hostname:2181/scribe/zipkin remote_port=9410 use_conn_pool=yes default_max_msg_before_reconnect=50000 allowable_delta_before_reconnect=12500 must_succeed=no \u0026lt;/store\u0026amp;gt; 注意:上記設定は、カテゴリーにより送信ホストを見つけるためにZooKeeperを利用するサポートのScribeのTwitterバージョンを使用する方法です。 コレクターのためのDNSエントリーを利用したりもできます。 Zipkinサーバ ZipkinサーバはScala 2.9.1、SBT 0.11.2そしてJDK6で開発しました。\n1. git clone https://github.com/twitter/zipkin.git 2. cd zipkin 3. cp zipkin-scribe/config/collector-dev.scala zipkin-scribe/config/collector-prod.scala 4. cp zipkin-server/config/query-dev.scala zipkin-server/config/query-prod.scala 5. Modify the configs above as needed. Pay particular attention to ZooKeeper and Cassandra server entries. 6. bin/sbt update package-dist (This downloads SBT 0.11.2 if it doesn\u0026#39;t already exist) 7. scp dist/zipkin*.zip [server] 8. ssh [server] 9. unzip zipkin*.zip 10. mkdir -p /var/log/zipkin 11. zipkin-scribe/scripts/collector.sh -f zipkin-scribe/config/collector-prod.scala 12. zipkin-server/scripts/query.sh -f zipkin-server/config/query-prod.scala SBTでコレクターとクエリサービスを起動します。 Scribeコレクターサービスの起動方法は次の通り。 bin/sbt \u0026#39;project zipkin-scribe\u0026#39; \u0026#39;run -f zipkin-scribe/config/collector-dev.scala\u0026#39; クエリサービスは次の通り bin/sbt \u0026#39;project zipkin-server\u0026#39; \u0026#39;run -f zipkin-server/config/query-dev.scala\u0026#39; Zipkin UI\nUIはRails3アプリです。 1. 設定をZooKeeperサーバでアップデートします。これはクエリデーモンを見つけるのに利用します。 2. Rails3アプリケーションサーバにデプロイします。テストの場合は次のようにすることもできます。 bundle install \u0026amp;amp;\u0026amp;amp; bundle exec rails server. zipkin-tracer gem\nzipkin-tracer gemをトレースしたいRailsアプリケーションにRack Handlerで追加します。 config.ruにつぎの記載をします。 use ZipkinTracer::RackHandler run \u0026lt;YOUR_APPLICATION\u0026gt; もし、アプリケーションのstatic assetsがRailsで提供されれば、リクエストがトレースされます。 ## Running a Hadoop job\nScribeからHadoopにログを保存する設定をすることも可能です。 これをすると、Zipkin自身でオンザフライで簡単に作れないデータから様々なレポートが作成可能です。 ScalaでHadoopのジョブをかけるScaldingというライブラリを利用します。\n``` 1. Hadoopジョブを実行するためのfatなjarを作成します。 2. scald.rbをjarをコピーしたいホスト名とjobを実行するホスト名に書き換えます。 3. 必要なら、scald.rbのjarファイルのバージョンを更新します。 4. scald.rbスクリプトを利用してジョブを実行できます。\n./scald.rb \u0026ndash;hdfs com.twitter.zipkin.hadoop.[classname] \u0026ndash;date yyyy-mm-ddThh:mm yyyy-mm-ddThh:mm \u0026ndash;output [dir]\n##計測ライブラリの利用方法\u0026lt;hr\u0026gt; 計測のためのライブラリとプロトコルがちょっとだけあります。 しかし、もっと計測するための役に立つものを望んでいます。 開始する前にトレースデータがどんな構造なのかを知る必要があります。\n・Annotation - 値、タイムスタンプ、ホストを含みます。 ・Span - 特定のRPCに相当するAnnotationの集合 ・Trace - あるルートSpanにぶら下がるSpanの集合\nZipkinに送信するトレースデータです。\nこれらの詳細な記述は[こちら](https://github.com/twitter/zipkin/blob/master/zipkin-thrift/src/main/thrift/zipkinCore.thrift)を見て下さい。 その他にトレースデータの重要なものは、トレースされたサービス間でやり取りされる情報である、軽量なヘッダーです。 トレースヘッダは次のものから構成されます。\n・Trace Id - トレース全体のID ・Span Id - 個々のリクエストのID ・Optional Parent Span Id - このリクエストが他のリクエストの一部として生成されたら付与される ・Sampled boolean - トレースすべきかどうかを表すフラグ\nデータタイプについて、理解したので、どのように計測が行われるかを順をおってみてみましょう 例はFinagleのHTTPがどのようにトレースされるかを示しています。 他のライブラリやプロトコルはもちろん、異なりますが、基本的な部分は一緒です。\n\u0026lt;b\u0026gt; サーバサイド\u0026lt;/b\u0026gt; 1. 到達したリクエストのトレースヘッダー存在するかどうかを調べます。存在すれば、なら、このリクエストに対して関連するIDとします。トレースヘッダーがなければ、サンプリング対象かどうかを決めて、新しいTrace Id、Span Idを生成します。参考には[HttpSererTracingFilter](https://github.com/twitter/finagle/blob/master/finagle-http/src/main/scala/com/twitter/finagle/http/Codec.scala)を見て下さい。 2. もし、現在のリクエストがサンプリングされる場合、サービス名、ホスト名、スパン名(例えば、http get/put)、その他のAnnotationのような情報を集めます。 リクエスト受信時には「server received」というAnnotationを生成し、処理が終了して結果を返すときに「server send」というAnnotationを生成します。 参考には[HttpServerTracingFilter](https://github.com/twitter/finagle/blob/master/finagle-http/src/main/scala/com/twitter/finagle/http/Codec.scala)を見てください。 3. 生成されたトレースデータはServerBuilderにより設定されたトレーサーに渡されます。 デバッグのためのConsoleTracerが例としてありますが、ZipkinTracerになります。 トレースデータを[ZipkinTracer](https://github.com/twitter/finagle/tree/master/finagle-zipkin)が受け取った時、Span Idにより集約されます。 4. ZipkinTracerが\u0026#34;end of span\u0026#34;イベント(\u0026#34;server received\u0026#34;アノテーションやタイムアウトのような)を受け取ると、Thrift構造としてデータを集約してScribeに送ります。もし、そのようなイベントが発生しない場合、ZipkinTracerはいつかそのデータを送信します???おかしい?。データ送信のための他の方法も追加します。 ThriftやScribeのようなものですが、JSONやHttpかもしれません? \u0026lt;b\u0026gt; クライアントサイド\u0026lt;/b\u0026gt; 1. リクエストを送る前にそれがトレースの一部かどうかをチェックします。 サーバで利用されているとします。 サーバは、リクエストを処理してすでに付与されているトレースIDを割り当てます。 トレースIDを再利用しますが、この新しいリクエストには新しいスパンIDを生成します。 また、親のスパンIDが存在すれば、前のスパンIDに設定します。 [ここ(TracingFilter)](https://github.com/twitter/finagle/blob/master/finagle-core/src/main/scala/com/twitter/finagle/tracing/TracingFilter.scala)や[ここ(Trace)](https://github.com/twitter/finagle/blob/master/finagle-core/src/main/scala/com/twitter/finagle/tracing/Trace.scala)が参考になります。 2. サーバサイドと同様に、送信されるHttpリクエストにトレースヘッダーを追加するための[HttpClientTracingFilter](https://github.com/twitter/finagle/blob/master/finagle-http/src/main/scala/com/twitter/finagle/http/Codec.scala)があります。 3. リクエスト送信前の「client send」やサーバからの返信を受信した「client receive」のようなアノテーションを生成します。 4. サーバサイドと同様に、データがZipkinにデータを送るZipkinTracerに到達します。 ","date":1339772520,"dir":"post/2012/","id":"9ccda414c322ebcdf875eacbba2e4b7e","lang":"ja","lastmod":1339772520,"permalink":"https://blog.johtani.info/blog/2012/06/16/zipkin%E3%81%AEreadme%E8%AA%AD%E3%82%93%E3%81%A7%E3%82%8B%E3%81%9D%E3%81%AE%EF%BC%92%E6%AE%8B%E3%82%8A/","publishdate":"2012-06-16T00:02:00+09:00","summary":"「鉄は熱いうちに打て」ということで、残りも勢いでメモ。 まだ、見直しとかしてない状態なのでおかしいところとかありますが。。。 図とか入れるのはま","tags":["Zipkin"],"title":"ZipkinのReadme読んでる(その2、残り)(Jugemより移植)"},{"contents":"ZipkinのGithubにあるReadmeを読んでます。 せっかくというか、頭が悪いので読みながら内容をメモ。 まずは、アーキテクチャとトレースデータ送信のためのクライアント側あたりです。 (誤訳とかおかしいだろというツッコミ大歓迎です。) あとで、リンク貼ったり絵を入れたりするかもしれませんが、とりあえず。\n◯アーキテクチャ(図はこちら)\n・対象とするサービスからScribeでデータを収集し、ZipkinのCollectorに投げる ・CollectorはCassandraにデータを格納 ・WebUIからはQueryでCassandraに問い合わせを行なってデータ取得 ・Scripe、CollectorはZookeeperと連携している(妄想) ◯計測用ライブラリ(図はこちら。図のSと書かれた青い箱)\n・各ホストの計測用ライブラリがトレースデータを集めてZipkinに送信する。 ・ホストは他のサービスへリクエストを飛ばすときに、リクエストにトレース用のIDを付与してます こうすることで、データをあとで、束ねることが可能となります。 ◯計測ライブラリの利用方法 ・Finagle\nJVMのための非同期ネットワークスタックである。 それは、JVMベース言語(JavaやScalaなど)で非同期RPCのクライアント・サーバを構築するのに利用できる。 FinagleはTwitterの内部ですごく利用されていて、トレースサポートを実現するのに当然のポイントです。 現時点で(Finagleは)ThriftやHTTP、Memcache、Redisのクライアント・サーバサポートも持っています。 ScalaでFinagleサーバをセットアップするのはつぎのようなコードになります。 トレースを追加するには、finagle-zipkinを追加して、ServerBuilderのtraceFactory関数を呼ぶだけです。\nServerBuilder() .codec(ThriftServerFramedCodec()) .bindTo(serverAddr) .name(\u0026#34;servicename\u0026#34;) .tracerFactory(ZipkinTracer()) .build(new SomeService.FinagledService(queryService, new TBinaryProtocol.Factory())) クライアント側も同様です。 上記のようにサンプリングしたリクエストにZipkinトレーサーを指定することで 自動的にトレースできるようになります。 サービスやホストでのリクエストの開始と終了を記録できます。 さらに付加的な情報を記録したい場合は、つぎのようなコードを追加します。 Trace.record(\u0026#34;starting that extremely expensive computation\u0026#34;) 上記コードは、上記コードが実行された時間に文字列を付加できます。 キーバリュー情報を付加したい場合は次のようになります。 Trace.recordBinary(\u0026#34;http.response.code\u0026#34;, \u0026#34;500\u0026#34;) Ruby Thrift\nリクエストのトレースに利用できるgemもあります。 リクエストに対してトレースIDを生成し、リクエストに付与し、トレーサーにプッシュするのにRackHandlerのgemを利用できます。 トレーサをトレースするサンプルはzipkin-webを参照。\nRubyからトレースクライアントをコールするのに、Twitter Ruby Thrift clientを使います。 つぎのようなコードを書きます。\nclient = ThriftClient.new(SomeService::Client, \u0026#39;127.0.0.1:1234\u0026#39;) client_id = FinagleThrift::ClientId.new(:name =\u0026gt; \u0026#34;service_example.sample_environment\u0026#34;) FinagleThrift.enable_tracing!(client, client_id), \u0026#34;service_name\u0026#34;) Querulous\nQuerulousはScala用のSQLデータベースのインタフェースライブラリです。 SQLクエリの実行のタイミング情報をトレースに追加できます。 Cassie\nCassieはFinagleベースのCassandraクライアントライブラリです。 CassieのトレーサーはFinagleの例とほぼ一緒ですが、 CassieではKeyspaceBuilderに設定します。 cluster.keyspace(keyspace).tracerFactory(ZipkinTracer()) とりあえず、ここまで。___ 2012/06/22 リンクを貼って体裁を修正\n","date":1339721820,"dir":"post/2012/","id":"69f755dd5b9e90a99c3086543790541c","lang":"ja","lastmod":1339721820,"permalink":"https://blog.johtani.info/blog/2012/06/15/zipkin%E3%81%AEreadme%E3%82%92%E8%AA%AD%E3%82%93%E3%81%A7%E3%82%8B%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E5%91%A8%E3%82%8A%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/","publishdate":"2012-06-15T09:57:00+09:00","summary":"ZipkinのGithubにあるReadmeを読んでます。 せっかくというか、頭が悪いので読みながら内容をメモ。 まずは、アーキテクチャとトレー","tags":["Zipkin"],"title":"ZipkinのReadmeを読んでる(クライアント周りについて)(Jugemより移植)"},{"contents":"久々にSolrの話です。 といっても、結構前からの話でして。。。\nschema.xmlのfieldTypeの設定に「autoGeneratePhraseQueries」という属性があります。 Solr3.1で導入されました。動作に関しては関口さんのブログで説明されています。 Solr 1.4までは、Analyzerがトークンを複数返してくる場合(例:lucene-gosenで「Solr入門」という文字列を入れた場合など)にフレーズクエリとして処理していました。 Lucene 3.1.0から、この処理がデフォルトfalse(つまり、フレーズクエリにならない)という挙動になりました。(詳しくは関口さんのブログで。) ただ、Solr 3.1.0では、下位互換性を考慮して、autoGeneratePhraseQueriesの設定値はデフォルトが「true」でした。\nこのデフォルト値がSolr 3.3以降で提供されているschemaのバージョン(1.4以上)からデフォルト値が「false」に変更されています。 schemaのバージョンを1.3以前のものから1.4以上に移行する場合は注意が必要です。\nとまぁ、偉そうに書きましたが、私もちゃんと追えてませんでした。 Solr勉強会第6回で、関口さんの発表できちんと説明されていて、参加してたのに聞けてなかったですし。(メモ取ってるのに、書いてない。)\nということで、Solr入門のサンプルschemaも少し修正しました。 こちらとこちらの記事に追記してありますので、参考にしてください。\n","date":1339603740,"dir":"post/2012/","id":"277f7f2177e2a265a62680ea0158f9b9","lang":"ja","lastmod":1339603740,"permalink":"https://blog.johtani.info/blog/2012/06/14/autogeneratephrasequeries%E3%81%AE%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88%E5%80%A4%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/","publishdate":"2012-06-14T01:09:00+09:00","summary":"久々にSolrの話です。 といっても、結構前からの話でして。。。 schema.xmlのfieldTypeの設定に「autoGeneratePh","tags":["solr"],"title":"autoGeneratePhraseQueriesのデフォルト値について(Jugemより移植)"},{"contents":"すでに読まれた方もいるかも知れませんが、気になったのでメモを書いてみようかと。\n先週の木曜日にTwitterのエンジニアブログでZipkinというOSSを公開したという記事がでました。 非常に興味深いシステムだったので、ちょっとずつ読み解いていきたいなという宣言(というか、ハッパをかけてもらうため)も兼ねて、まずはブログの内容をメモ程度に残しておきます。\nZipkinは分散トレースシステム(distributed tracing system)です。Twitter APIの1リクエストを構成する様々なサービスのタイミングデータ(計時データ)を集めるために作りました。 Firebugのような性能プロファイラのよなもので、しかもバックエンドのサービスもプロファイル可能です。 ZipkinはAPLv2ライセンスでOSSとしてGithubで公開しています。\nZipkinはWebのユーザインタフェースを持っています。(元記事参照) 各サービス(縦軸)でどのくらい時間がかかっているか(横軸)がわかり、クリックすることでより詳細な情報が得られます。 Zipkinはパフォーマンス改善の余地のある部分(遅いMySQLのSELECTなど)を見つけるのに役立ちます。\nZipkinはどのように動くの? Twitterに届いたリクエストからサンプリングしたリクエストに対してトレース可能なIDを付与して、すべてのサービスに渡していきます。 全リクエストの一部をサンプリングすることで、トレースのオーバヘッドを減らし、常に本番環境で利用できるようにしています。 Zipkinコレクタ(collector)が、Scribe経由でタイミングデータを受け取り、Cassandraに保存してインデックスを作成します。 Zipkinクエリデーモンがインデックスを利用して、WebUIにトレースデータを見つけます。\nZipkinはHack Weekで開始されました。 最初はThriftに対するGoogle Dapperの論文の基本的な部分の実装から始まり、現在ではHttp、Thrift、Memcache、SQL、Redisリクエストをサポートしています。 これらはFinagleライブラリで経由で動作します。Rubyのgemも用意してあります。\nということで、ほぼ直訳ですが、何かの役に立てればと。 ちょっとずつですが、Githubのページやソースを読みながら記事を書いていこうと思っています。\n","date":1339515600,"dir":"post/2012/","id":"ee48516e57684c5a4c22adccac34be92","lang":"ja","lastmod":1339515600,"permalink":"https://blog.johtani.info/blog/2012/06/13/twitter%E3%81%8C%E5%85%AC%E9%96%8B%E3%81%97%E3%81%9F%E5%88%86%E6%95%A3%E3%83%88%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%B3%E3%82%B0%E8%BF%BD%E8%B7%A1%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0zipkin/","publishdate":"2012-06-13T00:40:00+09:00","summary":"すでに読まれた方もいるかも知れませんが、気になったのでメモを書いてみようかと。 先週の木曜日にTwitterのエンジニアブログでZipkinと","tags":["OSS"],"title":"Twitterが公開した分散トレーシング(追跡?)システム、Zipkin(Jugemより移植)"},{"contents":"lucene-gosenの最新版(2.0.1)をリリースしました。\nプロジェクトページよりダウンロードが可能です。\n今回の修正では、@haruyama さんからいただいていたパッチの取り込み(リソース周りの改善など)が主な対応となっています。 また、コンパイルに利用するjarファイルがLucene/Solr3.6.0に変更になっています。(Issueはこちら) 3.6.0から追加されたテストケースにて、発生する問題への対処も施したものとなっています。\n","date":1339059234,"dir":"post/2012/","id":"216db319052b5742fc68862cb2f39905","lang":"ja","lastmod":1339059234,"permalink":"https://blog.johtani.info/blog/2012/06/07/lucene-gosen-2-0-2%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9%E5%91%A8%E3%82%8A%E3%81%AE%E6%94%B9%E5%96%84%E3%81%AA%E3%81%A9/","publishdate":"2012-06-07T17:53:54+09:00","summary":"lucene-gosenの最新版(2.0.1)をリリースしました。 プロジェクトページよりダウンロードが可能です。 今回の修正では、@haruy","tags":["lucene-gosen"],"title":"lucene-gosen 2.0.2リリース(リソース周りの改善など)(Jugemより移植)"},{"contents":"昨晩に引き続き、情けない内容のブログになってしまいますが。。。\n昨晩、書いた記事の調査をしていた時に気づいた、問題になるケースがあったので調査をしていました。 Issue32に登録した内容になります。 拙い英語を振り絞って書いた英語なので、伝わらないかもしれないのでブログに残しておきます。 昨晩の問題点となったクラス(StreamTagger2.java)の内部処理についてです。 lucene-gosenのLucene向けのTokenizerの内部処理では入力文字列の処理を行うのに、「char buffer[]」を用いて 入力文字列をReaderから読み込むときにバッファリングしています。 このバッファリングにて、特定のケースにて、想定していない場所を単語の切れ目と認識してしまう問題が実装上存在しました。 Issue32に記載した内容は次のようになります。\n上記バッファは4096文字というサイズで固定になっています。 StreamTagger2クラスでは、この4096文字をオーバーするような文字列の場合に、つぎの処理により、4096文字以下の場所に文章の区切りを探そうとします。\n4096文字以上の文字列が入力される バッファに入れられるだけの文字(4096文字)をバッファにコピーする。 バッファの後ろから、つぎの5種類の文字を探索し、見つかった場合(場所をkとし、k>0の場合)は、その場所を文章の切れ目と判定して、0からk+1文字目までの文字をStringTaggerを利用して形態素解析する。 あとは、繰り返し 上記条件に合致しない場合は、4096文字を文章とみなして形態素解析を行います。 ここで、5種類の文字は以下のとおり。\n0x000D:CARRIAGE RETURN(CR) 0x000A:LINE FEED(LF) 0x0085:NEXT LINE (NEL) 0x2028:LINE SEPARATOR 0x2029:PARAGRAPH SEPARATOR 見ての通り、制御文字ばかりです。 この5文字以外は切れ目と判断してくれません。 ということで、4097文字の文字列が存在し、上記5種類の文字が一度も出てこない場合、バッファのサイズで文字列が途切れてしまい、想定しない区切り位置で区切られた文章に対して形態素解析が実行されてしまいます. HTMLから文字列を抜き出して解析したり、長い文書を解析する場合に、改行文字を削除して処理するといったことも考えられます。 上記5種類の文字列のみで文章の区切り位置を判断してしまうのは問題ではないかと。 まずは、4096文字内に「。」句点が存在した場合に、その部分を区切り位置として認識するようなパッチを記載して、Issue32に添付しました。\n「。」句点を採用した理由はつぎのとおりです。 StreamTagger2では、上記バッファリングした文字列を更に、BreakIterator.getSentenceIterator(Locale.JAPANESE)にて取得したBreakIteratorにて文節単位に区切ってから、各文節ごとに形態素解析を実施しています。 ということは、BraekIteratorにて分節の区切りとして判断される文字については、上記の文字種に追加しても問題無いという判断からです。 ただし、この修正でも、純粋に4096文字以上、句点が出てこない場合には区切り位置がおかしなことになってしまいますが。。。 もう少し、BreakIteratorの挙動を調べて、他にも利用可能な区切り文字が存在しないかを調査していく予定です。。。\n1年以上コミッターをやっているのに、こんなことも理解していないのかよいうツッコミを受けてしまいそうでなんとも情けない話です。。。 まずは、現状報告でした。\n","date":1338913260,"dir":"post/2012/","id":"cbf9587a8187985725963b8bfc67004d","lang":"ja","lastmod":1338913260,"permalink":"https://blog.johtani.info/blog/2012/06/06/issue32%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A64096%E3%81%AE%E5%A3%81/","publishdate":"2012-06-06T01:21:00+09:00","summary":"昨晩に引き続き、情けない内容のブログになってしまいますが。。。 昨晩、書いた記事の調査をしていた時に気づいた、問題になるケースがあったので調査","tags":["lucene-gosen"],"title":"Issue32について(4096の壁)(Jugemより移植)"},{"contents":"久々にlucene-gosenを触っています。 trunkのlibにある、jarファイルが3.5ベースだったので、3.6ベースにしてテストをしたところ、 いくつかある、ランダムテストで結果の不整合が検出されたので、調査していました。 先程、trunkに対応版をコミットしました。もう少しテストケースを追加してからリリースします。 おそらく、通常の使い方では問題無いと思います。\nLuceneでは、ランダムな文字列を利用したテストが実装されています。 lucene-gosenでもこのテストを利用してランダムなテストをしています。 実際にはtest/以下のorg.apache.luceneパッケージにテストケースがあります。 今回、jarファイルを差し替えた時に、このランダムなテスト実施にて、assertが失敗するケースが発生しました。\n原因究明までに、いくつかフェーズがあったので、忘れないように書いておきます。\n1.ランダムテストのテストケースにてエラーがassertが失敗するケースが発生 ※ただし、成功する場合もあり。 2.該当のテストを再現しつつデバッグ+該当のテストがどんなものかを解読(勉強不足。。。) ※テストは、失敗した場合につぎのようなメッセージが表示され、同じテストが再現可能です。 以下、エラーの出力例。「NOTE: reproduce with: 」のあとにあるantコマンドを実行すれば、同じテストが再現可能です。\n[junit] ------------- Standard Error ----------------- [junit] TEST FAIL: useCharFilter=false text=\u0026#39;wgxznwk\u0026#39; [junit] [junit] ===\u0026gt; [junit] Uncaught exception by thread: Thread[Thread-3,5,main] [junit] org.junit.ComparisonFailure: term 0 expected:\u0026lt;w[gxznwk]\u0026gt; but was:\u0026lt;w[]\u0026gt; [junit] at org.junit.Assert.assertEquals(Assert.java:125) [junit] at org.apache.lucene.analysis.BaseTokenStreamTestCase.assertTokenStreamContents(BaseTokenStreamTestCase.java:146) [junit] at org.apache.lucene.analysis.BaseTokenStreamTestCase.checkAnalysisConsistency(BaseTokenStreamTestCase.java:565) [junit] at org.apache.lucene.analysis.BaseTokenStreamTestCase.checkRandomData(BaseTokenStreamTestCase.java:396) [junit] at org.apache.lucene.analysis.BaseTokenStreamTestCase.access$000(BaseTokenStreamTestCase.java:51) [junit] at org.apache.lucene.analysis.BaseTokenStreamTestCase$AnalysisThread.run(BaseTokenStreamTestCase.java:337) [junit] \u0026lt;=== [junit] [junit] NOTE: reproduce with: ant test -Dtestcase=TestGosenAnalyzer -Dtestmethod=testReliability -Dtests.seed=4ad9618caecb9fb2:d5476c03b8172df:-9c569f70013ffbb -Dargs=\u0026#34;-Dfile.encoding=SJIS\u0026#34; [junit] ------------- ---------------- --------------- [junit] Testcase: testReliability(org.apache.lucene.analysis.gosen.TestGosenAnalyzer):\tCaused an ERROR 3.デバッグの結果、Luceneのtest-frameworkにある「MockReaderWrapper」というクラスの影響を確認 LuceneのJIRAのLUCENE-3894にて追加されたクラスであるとわかる。 このクラス、Readerのreadメソッド内部で、ランダムな値を元に長さを途中で返すという実装のReaderになっている。 (全部で18文字の文字列なのだが、ランダムな値を元に、12文字として結果を一旦返すという仕組みが実装されている) 4.lucene-gosenの問題箇所を特定。 Readerが途切れた部分を分節として扱ってしまう実装になっていた。 該当の部分に修正をいれてコミット。 という具合です。 一応、テストを数回走らせてランダムテストが問題なく終了するのを確認はしてあります。 今回の問題に対する、個別のテストケースを追加してから近日中リリースする予定です。 対応が遅くなって申し訳ないです。。。\n","date":1338827340,"dir":"post/2012/","id":"0dcb6d0f17794bbca56b6cdb9e20b932","lang":"ja","lastmod":1338827340,"permalink":"https://blog.johtani.info/blog/2012/06/05/trunk%E3%81%AE%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E5%B7%AE%E3%81%97%E6%9B%BF%E3%81%88lucene-solr3-6-0%E3%81%A8%E3%83%A9%E3%83%B3%E3%83%80%E3%83%A0%E3%83%86%E3%82%B9%E3%83%88%E3%81%AE%E5%A4%B1%E6%95%97%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/","publishdate":"2012-06-05T01:29:00+09:00","summary":"久々にlucene-gosenを触っています。 trunkのlibにある、jarファイルが3.5ベースだったので、3.6ベースにしてテストをし","tags":["lucene-gosen"],"title":"trunkのライブラリ差し替え(Lucene/Solr3.6.0)とランダムテストの失敗について(Jugemより移植)"},{"contents":"録画してたEテレのスーパープレゼンテーションを見ててふと書きたくなったので、書いてます。 あとから読んだら恥ずかしくなりそうだけど。。。 「\u0026ldquo;知力の余剰\u0026quot;が世界を変える」というClay Shirkyさんの話を見て思ったことです。 社会的に貢献できる仕組みが最近増えているという話の内容でした。そこで、OSSについても同じことが言えるよなぁと思った次第でして。\n昔からいろんなかたが言ってると思うし、今さら何をとおもわれるかもしれないですが、なんとなく書きたくなってしまったので。\n私はシステム開発を生業にしています。特にOSSにはお世話になっています。 実際に、OSSを利用している方はかなりいると思います。 幸いにも、私はOSSのコミッターもやっています。 OSSに色々と関わってきて常々思っていることがありまして。\nOSSは基本は有志の方々が開発やメンテナンスを行なっています。(最近では会社で行なっているところもありますが。) そんなOSSに貢献する方法はいくつかあるのかなぁと。\nバグを発見したら報告したり、こんな機能を作ってみたけどどうですか?とパッチを送ってみたりするのは素晴らしい貢献だと思います。 ただ、なかなかアクションを起こすのって勇気がいるかなぁと。 実際、私もパッチ書いたりバグ報告するのは気後れすることがありしました。 ただ、貢献する方法ってこれだけじゃないよなぁと、コミッターをやり始めて思いました。\nもちろん、バグ報告してもらえるともっとありがたいですし、新機能とかリクエストを送ってもらえるともっと嬉しいです。 MLに質問するのもありです。ただ、ちょっとハードルが高いと思うこともあります。\nそんな時は、ただ使っているよと、ツイートしたりブログを書いてくれるだけでもありがたいし、ヤル気が出るものです。 使い勝手が悪いなぁというツイートでも、なんでこんなに使いにくいんだというブログでもいいんです。 気になるなぁという形でもいいと思っています。 githubでフォローするだけでもいいかと。 反応があれば、使ったり触ってもらえていることがわかります。 なので、使っているよとかアピールしてもらえると嬉しいよなぁと。\nなんか、締りのない感じになっちゃいましたが、反応があるとうれしいので、お気楽に反応しましょうよというお話です。\n","date":1338394320,"dir":"post/2012/","id":"ffdbd6a7d28c9a63976e9eec38cab0f5","lang":"ja","lastmod":1338394320,"permalink":"https://blog.johtani.info/blog/2012/05/31/%E3%82%AA%E3%83%BC%E3%83%97%E3%83%B3%E3%82%BD%E3%83%BC%E3%82%B9%E3%81%B8%E3%81%AE%E8%B2%A2%E7%8C%AE%E3%81%AE%E3%82%B9%E3%82%B9%E3%83%A1/","publishdate":"2012-05-31T01:12:00+09:00","summary":"録画してたEテレのスーパープレゼンテーションを見ててふと書きたくなったので、書いてます。 あとから読んだら恥ずかしくなりそうだけど。。。 「\u0026l","tags":["misc"],"title":"オープンソースへの貢献のススメ(Jugemより移植)"},{"contents":"JJUG CCC 2012 Springに参加してきました。 昨年のFallに続き、2回目です。 概要や、タイムテーブルはこちらを御覧ください。 今回は、午後一から参加しました。 色々と迷いましたが、つぎのを聞いて来ました。\nHotSpot vs JRockit ~ HotRockit到来の前に予習しよう! Play! Framework - モダンで高速なWeb開発 Grails/Groovyの開発活用術 Scala 最新状況報告 From Swing to JavaFX SwingからJavaFXへのマイグレーションガイド JRockitは使ったことがなく(たぶん)、新鮮でした。いろいろなコマンドが用意されているなぁと。 あと、jvisualvmの使い方も知らないこともあったのでいい話が聞けました。 プレゼンに慣れているようで、プレゼン中に、コマンドラインの拡大+コマンドのオプションに赤い下線を入れるなど、どうやってやっているのか、プレゼンの内容よりも気になってしまったのが本音です\nPlayは今回の目玉の一つでした。まだ、手元でPlayを触り始めたばかりだったので、概観がつかめたのが良かったです。 あとでスライドを見なおさないと。 頭がどうしてもServlet、JSPのため、未だにPlayに切り替えができてないので、もっと触ってみないとなぁと。 ちなみに、紆余曲折してまして、Play 1.2.4→Play 2.0(Javaアプリ)→Play 2.0(Scalaアプリ)と心変わりしまくりで、まだ完全に作ってないのに、ふらふらしてます。。。\nGrailsはGrailsを現場にどのように投入していくのがいいかという、技術よりは、政治的な話でしたが面白かったです。 実際に、あまり有名でないプロダクトを現場に導入するのに、Javaだからと無理やり説得してみたりw、開発コストがこれくらい下がりますという話をしてみたりと、いろいろやられているようでした。 あと、PlayのあとにGrailsということもあり、すこしPlayを意識した話もされていました。\nScalaはScalaDaysの話+Scalaの最近の動向ということで、ある程度Scalaを知っている人がターゲットのようでした。 少し触っただけなので、何となく分かる部分もありましたが、最後の方はついていけてないです、すみません。。。 一番感じたのは、発表者の水島さんのScalaに対する愛情でしょうか。\n最後は桜庭さんのJavaFXのお話です。 一応、昔、JFreeChart+Swingでちょっとしたものを作ったことがあるので面白かったです。 プレゼン自体もJavaFXで作成されていたり、オープニングがStarWars風だったりと凝ったプレゼンでした。 JavaFXとしては、JavaOneでも聞いたのですが、グラフやHTMLがリッチに書けるようになったことがびっくりです。\n実際のSwingアプリからJavaFXへの移行に関して、注意する点などがわかりやすく聞けました。 FXMLは確かに便利ですよねぇ。レイアウトをJavaで組むのがすごくめんどくさかったもんなぁ。\nさて、簡単ですが、感想でした。 今回一番残念だったのは、長丁場の割に電源の確保が難しかったことでしょうか。 ツイートしたり、メモ取ったりしたかったのですが、電源が乏しいので、Wi-fiオフにしてメモ取るのが限度でした。。。\n場所:オリンピック記念青少年総合センター 日時:2012/05/28 10:00 - 19:00 ◎13:10 - 14:00 C-1 HotSpot vs JRockit ~ HotRockit到来の前に予習しよう! 谷本 心 @cero_t ◯HotSpot from Sun ◯JRockit from BEA 今は、どちらもOracle ◯違いは? 1.歴史 2.プラットフォーム JRockitはMacではNG。Solarisは一部。 2.1Oracleさん曰く Solaris/Mac → HotSpot Windows/Linuxのサーバ → JRockit Windows/Linuxのクライアント → HotSpot 2.2谷本さんは? WebLogic → JRockit 1.4、5の時の開発環境はJRockit 当時はJRockitの解析ツールがカッコ良かった 3.解析ツール 3.1コマンドラインツール プロセス HotSpot : jps JRockit : jrcmd スレッドダンプ HotSpot :jstack JRockit : jjrcmd \u0026lt;pid\u0026gt; print_threads ヒープ解析 HotSpot:jmap -histo \u0026lt;pid\u0026gt; JRocket:jrcmd \u0026lt;pid\u0026gt; heap_diagnostics HotSpot: JRockit:jrcmd \u0026lt;pid\u0026gt; 他にもJRockitは色いろある。 print_utf8poolとか(内部の文字列が出てくる) 3.2GUIツール HotSpot:jvisualvm NetBeansベース JRockit:Mission Control Eclipseベース メモリリークの解消をツールを使ってみてみましょうデモ。 ・hprofファイルを吐き出して、jvisualvmで読みこむのが楽な方法 ・jrmcはヒープダンプファイルを読み込む機能がない。 memleakというツールがある。アプリを起動してから、プロセスを右クリックして選択可能。 タイプグラフや割当てトレースみたいなものが使えるよ。 フライトレコーダーというのもあるよ。 4.HotRockitの紹介 まだいつ出るのかなぁという状態だけど、HotSpotにJRockitのツールも使えるようになるVMが出る模様。(2013?) ※デモ中に画面拡大した時に、赤線でラインを引いているのがすごく気になった。(便利なツールなのかな?そこだけ?) ◎14:15 - 15:05 C-2 Play! Framework - モダンで高速なWeb開発 池田尚史 @ikeike443 ◯自己紹介 Play!Frameworkコミッター 日本Playframeworkユーザ会 ◯アンケート メイン言語は?Java多数 触ったことある?半分くらい? Play1?Play2?半々くらい プロダクションで使ってる人?3人 ◯Playframeworkって? JEEではないよ。 Webだよ。 ServletとかXML使ってないよ。 ◯JEEは難しいよね。RailsとかDjangoから流れてくると。 ◯Webフレームワーク なので、Webアプリが作れればいいよね。 開発すべきものに注力して、抽象化とかを頑張らないようにと。 ◯ライブコーディング! Play2.0のScalaアプリみたい。 プロジェクト作成~編集して起動まで。 エラーを起こして、エラーがどのように表示されるか。 エラーのリンクをクリックして、エディタを起動するということも可能みたい。 TODOとかで、まだ終わってないのも記述可能。 パラメータとControllerの関数の引数が勝手にひもづけられますよと。 ◯歴史 Servletとかもあった。 1.2からNetty、Websocket、Scalaサポート 2.0.1:Scalaで書き直し。Netty+Akkaで非同期 ◯1と2のちがいは? ・Play1 Javaで書かれたJavaのフレームワーク。Scalaはプラグインサポート ・Play2 Scalaで書かれたScala/Javaのフレームワーク ◯Playの特徴 ステートレスとかノンブロッキングとかリアクティブとか ・高生産性 XMLがないし、unzipするとすぐ使えるよ。 ホットスワップできるよ。 CoffeeScript、LESSサポートも。assetsに入れとくとコンパイルしてくれて静的コンテンツにしてくれる。(Railsにも似たようなのあったっけか?) ・ステートレス HttpSessionがない→必要ならMemcachedとかで管理してね。 「デプロイ→ニーズ・状況に応じて即時スケールアウトという時代じゃないか?」という主張 Playはステートレス養成ギブスであり、時代の要請にマッチ ・広範囲な型安全 コンパイルしてエラー検知 ・ノンブロッキングI/O 非同期処理が手軽に書けるように考えられている。 →リアルタイムWebの時代 NettyやAkkaにより実現されてるのがいい Akkaを使ったアプリを書くと、長い処理のActorを別サーバにするなども設定で変更が可能。 ◯テスタビリティ BDDフレームワーク(Specs2?) Viewもテストできるぞと。 ◯事例 Klout:ソーシャルスコアリング イギリスのガーディアン:コンテンツAPIの実装がPlay2 MinecraftのWebサイト ◎15:20 - 16:10 C-3 Grails/Groovyの開発活用術 ~Java EE資産を活かして開発を加速する~(仮) 上原潤二 山本剛 ◯充電中のためお休み ◎16:25 - 17:15 C-4 Scala 最新状況報告 ~或いはScala Days 2012リポート~ 水島宏太 ◯自己紹介 言語を作るのが夢みたい。 ◯Scala最新状況報告 ScalaDaysの雰囲気を伝えるよと。(どっちかというと、旅行記かも) ◯Scala? ・オブジェクト指向関数型言語 ハイブリッドじゃなくて、統合したもの ・強力な静的型付け NullPointerExceptionなども起きにくい ・超強力なコレクションフレームワーク ・Javaと同等の実行速度 ・コードが簡潔(1/4くらい) ◯Scala採用企業 Twitter、Amazon.com(どこに使ってるかは不明)、Foursquare、LinkedIn、VMWare、Klout、Tumblrなど ◯Scalaのバージョンは? 2.10が開発版。2.9.2がステーブル版。 ◯開発体制 Typesafe+世界のContributor Typesafeメンバの議決でいろいろ決定 githubでオープンに開発 ◯ScalaDays2012の目玉 豪華ゲスト(私は、わからなかった) Scala2.10の新機能紹介 今後のScala、多数の応用例 ◯ScalaDays2012を見ての方向性 ・All-in-oneパッケージの提供 Typesafe Stackの提供 重要なツール sbt(Simple Build Tool) gitter8(プロジェクトテンプレート生成ツール。githubを元に色々取ってくる?) Akka Play 2.0 Framework ・学習コストの削減 言語機能のモジュール化 高度な開発者が使う昨日はデフォルトOff ・バイナリ互換性問題への対処 ・Minor Release間での互換性を維持 MIMAでジドウテキに非互換性を検出 ・Major Release間では互換性は保証しない。 No more java.util.Date ソース互換性は「概ね」保証される deprecatedは次期メジャーバージョン時に削除される。 ・Scala IDEへの注力 インクリメンタルにコンパイルしてくれるから、遅いのも気にならなくなるかも。 デバッガとか、できるよと。 ・さらなるパフォーマンス改善 Value classes AnyValを継承したクラスが作成可能 該クラスのオブジェクトがインライン化 Pimp my libraryによるヒープ使用料が0に! ◯2.10最新機能紹介 \u0026#34;1+2=#{1+2}\u0026#34;ができない s\u0026#34;1+2=${1+2}\u0026#34;ができるように String = 1 + 2 = 3 f\u0026#34;1=${1}%03d\u0026#34;もできるようにSring = 1 = 001 自分でStringコンテキストにメソッド追加できるらしい(聞き取った日本語が合ってるか?) とか。(かなり不安。。。まだまだわかってない。。。) ◎17:30 - 18:30 BOF-B-1 From Swing to JavaFX SwingからJavaFXへのマイグレーションガイド 櫻庭 祐一 ◯JavaFX 次世代のJava GUI Library Swing+Java2D+α JavaSE8から標準(JavaFX3.0) ◯サンプル クラス名がいろいろ変わってる。 ◯はまりそうなところ コンテナへの追加がちょっと違う イベントリスナは1種類のみになった。(Genericsを使うようになったよと。) ◯Bind 値が変わるとModelが勝手に検知して変わるみたい。 双方向もあり。これだとEventを書かなくても良くなりつつ有るよと。 ◯シナリオベースでマイグレーション考えましょう 1.JavaFX in Swing JavaFXにSwingを埋め込むことはできないぞと。 SwingでできないことをJavaFXでやりますよと。 おー、グラフが動く。JavaDocのHTMLも綺麗に出てる。 使い方:JFXPanelを使う シーングラフを記述可能 データのやり取りが大変。Threadが違うから。 パフォーマンスが落ちます。Java2Dで画像を書くので遅いですよと。 新規のものはJavaFXで書きましょうと。 2.Swing to JavaFX w/o FXML SwingをJavaFXに置き換える。 使い方が違うものはTableViewなど、◯Viewとついてるもの。 ちょっと考えるのはLayout Swing:コンテナ+レイアウトマネージャー JavaFX:コンテナがレイアウトを含む BorderPaneクラスとか。 問題はTableとか Swing:TableModel JavaFX:BeanをColumnにバインド 3.Swing to JavaFX w/ FXML ・FXML GUIの構造をXMLで表す。 シーングラフを表現。 スキーマレス クラス:要素 プロパティ:属性 or 要素 アノテーションバリバリです。これで、FXMLとJavaのバインディングができるよと。 ツール Java :NetBeans e(fx)clipseってのがあるかも。 FXML:Scene Builder ","date":1338259500,"dir":"post/2012/","id":"de734259dfb9addebe2b226d96b4f744","lang":"ja","lastmod":1338259500,"permalink":"https://blog.johtani.info/blog/2012/05/29/jjug-ccc-2012-spring%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%A6%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-05-29T11:45:00+09:00","summary":"JJUG CCC 2012 Springに参加してきました。 昨年のFallに続き、2回目です。 概要や、タイムテーブルはこちらを御覧ください。 今回は、午後一から参加","tags":["勉強会"],"title":"JJUG CCC 2012 Springに参加してきました。(Jugemより移植)"},{"contents":"PlayFramework2.0を触ってみてます。 ちょっとコーディングしたくなったのと、最近のアプリの作成の調査も兼ねて。 まぁ、せっかくなので、Solr検索のアプリでも作ってみようかと言うことで触ってます。 ただ、Solr検索アプリでしかなく、今のところDBを使わないので、実はPlay Frameworkじゃなくてもいいのではないかという疑問も。。。\nまだ、触り始めたばかりなので、なんともですが。感想を。 たぶん、Ruby on Railsに似ているのかなと。 RoRは仕事で少し関わったので、なんとなく知っていますが、アプリの作成手順や、ディレクトリ構成などが似ている気がします。\nコントローラーの生成のタイミングとか、内部でオブジェクトをSingletonで保持する方法とかのイメージがまだ良くつかめていない状態で、まずは、Solr検索部分(Palyにあんまり関係ないところ)を実装しているところです。\n現状で一番の疑問点は、Eclipseプロジェクト化した時の参照ライブラリのパスに関するところでしょうか。 Play Frameworkは「play new ほげほげ」コマンドを実行するとアプリのディレクトリ構成が作成されます。 このあとに、eclipsfyというplayのコマンドを実行すると、Ecilpseのプロジェクトファイルが作成されます。 この時、PlayFrameworkが利用するjarファイルたちが参照ライブラリとしてクラスパスに設定されます。\nこのパスには、PlayFrameworkのインストールディレクトリが含まれた絶対パスが記述されるのですが、 複数人で開発するときにはどうしているのかなぁと。 あと、BitbucketやGitHubにアップするときもどうするのかなぁと。 以前、この疑問ツイートして、頂いた回答としては、環境変数として定義して、各自で設定してもらうというものでした。 私も同じ事を考えていたので、腑に落ちたのですが、他にもっといい方法があったりするんでしょうか? クラスパスやEclipseプロジェクトのファイルをアップしないというのもあると思いますが、それもちょっとなぁと。 なにか、オススメとかあれば、教えていただけると嬉しいです。\n最近、ブログ更新してなかったのもあったので、まずは、導入編でした。\n","date":1337151314,"dir":"post/2012/","id":"78f002cc3d512ea302c900d1da4dfeec","lang":"ja","lastmod":1337151314,"permalink":"https://blog.johtani.info/blog/2012/05/16/playframework-2-0-java%E3%81%AE%E6%96%B9-%E3%82%92%E8%A7%A6%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%A6%E3%82%8B/","publishdate":"2012-05-16T15:55:14+09:00","summary":"PlayFramework2.0を触ってみてます。 ちょっとコーディングしたくなったのと、最近のアプリの作成の調査も兼ねて。 まぁ、せっかくなの","tags":["備忘録"],"title":"PlayFramework 2.0(Javaの方)を触ってみてる(Jugemより移植)"},{"contents":"lucene-gosenの最新版(2.0.1)をリリースしました。\nプロジェクトページよりダウンロードが可能です。\n今回の修正では、Java7でUnicodeのバージョン変更に伴う対応(詳細はこちらを参照)を行なっています。\nリソース周りの対応はまた後日。。。すみません。2012/05/16 遅くなりましたが、昨晩、JavaDocをアップしました。\n","date":1336494900,"dir":"post/2012/","id":"c4b418764dca70aebfc965899a3fa7e5","lang":"ja","lastmod":1336494900,"permalink":"https://blog.johtani.info/blog/2012/05/09/lucene-gosen-2-0-1%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9java7%E5%AF%BE%E5%BF%9C/","publishdate":"2012-05-09T01:35:00+09:00","summary":"lucene-gosenの最新版(2.0.1)をリリースしました。 プロジェクトページよりダウンロードが可能です。 今回の修正では、Java7で","tags":["lucene-gosen"],"title":"lucene-gosen 2.0.1リリース(Java7対応)(Jugemより移植)"},{"contents":" IDの秘密 (丸善ライブラリー―情報研シリーズ) 非常に面白く読めました。 バーコードの話に始まり、最後はシステムで付与するIDに関する考慮点まで幅広くIDについて語られています。\n適度に配置されたコラムがまた面白く、ここまで書いてもいいのかな?と思いながらも楽しく読ませて頂きました。 2次元バーコードが汚れに強いのも知らなかったし、チロルチョコの話は知らなかったし、指コレクションとか面白すぎです。 また、JRのSuicaの導入に7年もかけている点などは、やはりすごい技術なのだなぁというため息混じりの感想です。 それほど長い期間のテストや設計は想像がつかないです。\n最後の2章(7,8章)については、エンジニアの以外のシステムに関わる方やエンジニアになられたばかりの方たちにぜひ読んで欲しいと思いました。 もちろん、エンジニアの方にも読んでほしい内容です。\nいくつか疑問点や気になる点もあったので。\n「静脈や指紋が人によって異なるって確率はどうやって決めたんだろう?」 Twitterの説明文のあとにFBの画面の図番号が書いてある。 日本語がデコードされたけど、QRコードの文字コードって、この中に含まれてるのかな?それとも規格で決まってるのかな? 最後に、書影がNIIに合ったので撮影しました。写真へのリンクです。\n","date":1335794635,"dir":"post/2012/","id":"95c0a5b8a66950b5f22dd82a8dfe0ce5","lang":"ja","lastmod":1335794635,"permalink":"https://blog.johtani.info/blog/2012/04/30/id%E3%81%AE%E7%A7%98%E5%AF%86%E3%82%92%E8%AA%AD%E3%81%BF%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-04-30T23:03:55+09:00","summary":"IDの秘密 (丸善ライブラリー―情報研シリーズ) 非常に面白く読めました。 バーコードの話に始まり、最後はシステムで付与するIDに関する考慮点まで","tags":["読書"],"title":"「IDの秘密」を読みました。(Jugemより移植)"},{"contents":"WebSolrの話があるらしいというのを嗅ぎつけて、初めてHeroku JP Meetupに参加しました。 herokuもWebSolrも知りつつ、手を出していなかったので、いい機会でした。 (SignUpだけ、勉強会直前に済ませましたw)\nHerokuはAWS上に構築されたアプリケーションプラットフォームで、簡単にアプリをデプロイして動作させることができるようです。 Ruby on Railsを使うのが多いみたいですが、他の言語も利用できると。 で、herokuの面白いところは、アドオンとして、開発が簡単にできるようなしくみが用意されていることみたいです。 今回発表のあった、IronMQ、WebSolr、PaperTrailもアドオンとして用意されており、簡単に利用することが可能です。 IronMQはメッセージキューとして利用できます。\nWebsolrはSolrを簡単に利用できる形で提供しているものになります。 今、利用できるのは3.5.0のようで、最新版(3.6.0)になるのはまだ未定のようです。 今回の発表はWebSolrの話しもありましたが、基本は全文検索の仕組みとKuromojiの説明でした。 ただ、残念ながら、Kuromojiは3.6.0からの提供となるので、現時点では利用できないようです。 あとで、聞いた話だと、schema.xmlを自分で変更できるようです。 ただ、jarファイルを置いたりはできないようなので、lucene-gosenを利用するとかはできないみたいですが。。。 ほかにも、bonsai.ioとして、ElasticSearchの提供も行うようです。 まだ、利用はできないようですが。\n最後がPapertrailです。 こちらは、ログを保存して、検索、グラフ化(視覚化)してくれるアドオンです。 まだ、ベータのようですが、ログを保存してくれるようです。無料版もあるようです。 アドオンとしての機能もそうですが、利用しているグラフ化のツールなど、面白そうなものが利用されていました。\nLTはRuby使いの方が多かったです。\nRuby使いではないのですが、いろいろなアドオンが用意されており、サービスを簡単に提供することができそうだという印象をうけ、ちょっと使ってみたいなぁと思いました。 普段参加していない勉強会だったので、普段では知りえない興味ある話が聞けて面白かったです。\n余談ですがPapertrailの人が利用していた、slideshareのようなサービスのSpeaker Deckもよさそうなので登録してみました。 次に何か発表があった時には資料はこっちにアップしてみようかなぁと\n以下は、いつものように自分用のメモです。\n日時2012/04/20 19:00 to 21:00 会場:パソナグループ本部 呉服橋 ◎オープニング – Ayumu AIZAWA (Heroku Evangelist) ◎新入社員からの挨拶 – Koichi SASADA (Ruby Developer) 前職:大学教員 仕事:CRuby開発 Heroku使った事無いですwRailsもよく知らないですw RUby2.0のリリースがゴール。2013/Feb 性能アップのことやってます。 ◎IronMQ – Chad Arimura (Iron.IO)\n「メッセージキューは涼しいです。」 (Google翻訳による日本語訳付きのスライド) Aggregation、Distribution。。。 IronMQ Elastic、RESTful heroku addon ironmq:rust 簡単にheroku上にキューが用意できるアドオンです。 Q:メッセージがキューに到達したのを確認する方法か? A:ステータスコードが帰ってくる。 Q:データのサイズのリミットは? A:postのリミットはある。S3とかに巨大データをおいて、ポインタを渡すとかしてほしい。 Q:キューへの到達の成功の保証は? A:アプリケーション側で判断してください? ◎Search \u0026amp; Indexing on Heroku – Nick Zadrozny (Websolr) スライドはこちら。\n※ツイートしてて、メモとってなかったので、ツイートをコピペ。 次はWebsolrのお話 Bonsai.io? Bonsai by onemorecloud - http://bit.ly/JjCuaE SQLのLIKE検索はO(n)でおそいねぇと。 クエリのパースについての話。 今度は転置インデックスのお話。 Termへの分割ってどーすんの?というお話。Tokenizeのお話。 その1:N-GramというTokenizeの方法。N文字ずつ先頭からTermを切り出す。開始位置は1文字ずつずらしていくと。 N-Gramはノイズがのるし、多くのTermがでてきちゃうよと。 その2:そこで、次は形態素解析ですね。 先週、Lucene/Solr 3.6.0がリリースされて、Kuromojiという日本語向けの形態素解析器がでましたよ。 Kuromojiはこちら。(Lucene版とは少し違うけど。)http://atilika.org/ Kuromojiのサーチモードのお話。 通常は、「関西国際空港」という単語になってしまうのを、Kuromojiでは「関西」「国際」 「空港」という切り方の単語も出してくれると。 ちなみに、lucene-gosenでは、サーチモードはないんですねぇ。。。 「の」はどこに消えたんだ??そこの説明は? ElasticSearchやSolrのコアの部分でLuceneを使ってるよ。 ElasticSearch http://bit.ly/qjjvWp Kuromojiはユーザ辞書をサポートしてるよ。 Q:まだ、3.5.0では? A:もうすぐやります ◎log analysis for your Heroku app – Eric Lindvall (Papertrail)\nheroku上にログを貯めて、検索したりグラフ化したりできるようになりそうなもの。 [スライドはこちら](http://speakerdeck.com/u/lindvall/p/log-analysis-for-your-heroku-app) ログを貯めて、検索や可視化できるようにするサービスみたいです。 まだ、アイデアレベルのものも発表資料には含まれていました。 内部で利用しているツールなど、資料の最後に出てきますが、色々と面白そうなものがありました。 ◎Lightning Talks ◯Receibo ( @shu_0115 ) デザイナーxエンジニアハッカソンでの成果らしい。 Webベースの家計簿アプリ。 買ったものの名称と料金を入れるだけ。 ◯Heroku + Pusherで作る!リアルタイムアプリケーション ( @satococoa ) WebSocketみたいなことが、Pusherでできるらしい。 http://www.slideshare.net/satococoa/heroku-pusher ◯Herokuアドオンを作ってみてわかったこと ( @takkam ) ◯heroku client のちょっと進んだ使い方 ( @hsbt ) ◯love heroku? – we love herokuのご紹介 ( @ppworks ) ","date":1334935380,"dir":"post/2012/","id":"c92c12a28fa219ad1aab60865046ff05","lang":"ja","lastmod":1334935380,"permalink":"https://blog.johtani.info/blog/2012/04/21/heroku-jp-meetup-4%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-herokujp/","publishdate":"2012-04-21T00:23:00+09:00","summary":"WebSolrの話があるらしいというのを嗅ぎつけて、初めてHeroku JP Meetupに参加しました。 herokuもWebSolrも知りつつ、","tags":["勉強会"],"title":"Heroku JP Meetup #4に参加しました。#herokujp(Jugemより移植)"},{"contents":"先日、Solr入門のサンプルschema.xmlの3.6.0対応版の作成をしていて、気になったことがあったので、 メモとして残しておきます。\nSynonymFilterFactoryの属性「tokenizerFactory」に関連する話です。 (「Apache Solr入門」の36-37ページに記載があります。)\nSynonymFilterFactoryでは、類義語設定ファイルを読み込む際に利用するTokenizerFactoryを「tokenizerFactory」という属性で指定できます。(以下は書籍の記述を抜粋)\n\u0026lt;filter class=\u0026#34;sold.SynonymFilterFactory\u0026#34; synonyms=\u0026#34;synonyms.txt\u0026#34; ... tokenizerFactory=\u0026#34;solrbook.analysis.SenTokenizerFactory\u0026#34;/\u0026gt; このように、TokenizerFactoryが指定できます。\nただ、こちらの記事で書いたように、 Solr 3.6.0のexampleのschema.xmlではCJKのフィールドは次のように設定されています。\n\u0026lt;!-- CJK bigram (see text_ja for a Japanese configuration using morphological analysis) --\u0026gt; \u0026lt;fieldType name=\u0026#34;text_cjk\u0026#34; class=\u0026#34;solr.TextField\u0026#34; positionIncrementGap=\u0026#34;100\u0026#34;\u0026gt; \u0026lt;analyzer\u0026gt; \u0026lt;tokenizer class=\u0026#34;solr.StandardTokenizerFactory\u0026#34;/\u0026gt; \u0026lt;!-- normalize width before bigram, as e.g. half-width dakuten combine --\u0026gt; \u0026lt;filter class=\u0026#34;solr.CJKWidthFilterFactory\u0026#34;/\u0026gt; \u0026lt;!-- for any non-CJK --\u0026gt; \u0026lt;filter class=\u0026#34;solr.LowerCaseFilterFactory\u0026#34;/\u0026gt; \u0026lt;filter class=\u0026#34;solr.CJKBigramFilterFactory\u0026#34;/\u0026gt; \u0026lt;/analyzer\u0026gt; \u0026lt;/fieldType\u0026gt; 3.6.0以前は、solr.CJKTokenizerFactoryを利用していましたが、3.6.0からはCJKTokenizerFactoryがdeprecatedになってしまい、代わりにStandardTokenizerFactory+CJKBigramFilterFactoryの組み合わせになっています。 exampleのCJKのフィールドタイプ設定を利用して、かつ、そのフィールドにSynonymFilterを利用する場合に、 StandardTokenizerFactoryを指定してしまうと、類義語が展開できなくなってしまうので注意が必要です。\nCJKのフィールドでSynonymFilterを利用する場合は、類義語の設定ファイル内の記述を自力でCJKTokenizerが分割する形で記述する(まぁ、やらないでしょうが)か、deprecatedですが、CJKTokenizerFactoryを利用するのが現時点での対応でしょうか。\nなお、これに絡んで、このようなチケットもできています。\nSyntaxHighlighterを導入してみました。 ちょっとはみやすくなってますかね? まだ、SyntaxHighlighterの設定を調べながら使っているので、コロコロ変わるかもしれないですが、気にしないでください。 ","date":1334592971,"dir":"post/2012/","id":"12d1e0cf7396dd33a9bbbca8da4cbc68","lang":"ja","lastmod":1334592971,"permalink":"https://blog.johtani.info/blog/2012/04/17/solr-3-6-0%E3%81%AEcjk%E3%81%AE%E8%A8%AD%E5%AE%9A%E3%81%A8synonymfilterfactory%E3%81%AE%E6%B0%97%E3%81%AB%E3%81%AA%E3%82%8B%E7%82%B9/","publishdate":"2012-04-17T01:16:11+09:00","summary":"先日、Solr入門のサンプルschema.xmlの3.6.0対応版の作成をしていて、気になったことがあったので、 メモとして残しておきます。 S","tags":["solr"],"title":"Solr 3.6.0のCJKの設定とSynonymFilterFactoryの気になる点(Jugemより移植)"},{"contents":"先日の続きです。「Apache Solr入門」の2章から4章の説明について、Solr3.6.0で動作させる時の変更点を以下に書いていきます。 なお、前回も説明しましたが、3.6.0からKuromojiという形態素解析器がSolrに同梱されるようになりました。 これから説明する2章の変更点の手順ですが、Kuromojiとlucene-gosenそれぞれの利用方法について説明します。 添付のschema.xmlについては、基本的にKuromojiを利用する形に変更してあります。 それに加えて、lucene-gosen用のフィールドを別途追加で定義しました。 これらのフィールド名については、次の表の用になります。 適宜、書籍のフィールド名と置き換えながら読み進めたり、試したりしてください。\nKuromojiフィールド lucene-gosenフィールド title title_gosen author auther_gosen summary summary_gosen intended_reader intended_reader_gosen from_author from_author_gosen toc toc_gosen 2章 2.1.3 schema.xmlのバージョン(27ページ) Solr3.xではschema.xmlのファイルの最新バージョンは**1.5**になっています。\n2.2.3 代表的なトークナイザ(35ページ) solrbook.analysis.SenTokenizerFactoryは必要ありません。 Solr 3.6.0からはKuromojiと呼ばれる形態素解析器が用意されています。 solr.JapaneseTokenizerFactoryがそれに該当します。 これとは別に、lucene-gosenを利用する場合、Solr向けのトークナイザが用意されています。 solr.GosenTokenizerFactoryがそれに該当します。\n2.2.4 代表的なトークンフィルタ(37ページ) 以下の2つについてはKuromojiが同等のトークンフィルタを提供しています。 また、lucene-gosenを利用する場合は、lucene-gosenに同等のトークンフィルタが存在します。\nsolrbook.analysis.KatakanaStemFilterFactory solrbook.analysis.POSFilterFactory 次のものがSolr 3.6.0に用意されているので、こちらを利用します。\nsolr.JapaneseKatakanaStemFilterFactory solr.JapanesePartOfSpeechStopFilterFactory それぞれ、次のものがlucene-gosenにあるので、こちらを利用します。\nsolr.GosenKatakanaStemFilterFactory solr.GosenPartOfSpeechStopFilterFactory 2章向けのschema.xmlはこちらです。その他のtxtファイルについては、特に変更はありません。\n3,4章は特に変更はありません。Solrの起動の仕方にだけ注意してください。(-Dsen.homeは必要ありません)\n以上が4章までの修正点になります。\n昨日に引き続き、眠い目をこすりながら修正したので、おかしいかも。 動かない、意味がわからないなどあれば、コメントorツイートいただければと思います。\n2012/06/14提供しているschema.xmlに関して修正を加えました。こちらの記事で説明しているautoGeneratePhraseQueriesの値をtext_gosen、text_cjkのフィールドに対してtrueを設定する記述を追記しました。\n","date":1334339880,"dir":"post/2012/","id":"d77cdb466c5063b99c5aea58e6da4d32","lang":"ja","lastmod":1334339880,"permalink":"https://blog.johtani.info/blog/2012/04/14/apache-solr%E5%85%A5%E9%96%80%E3%81%AE%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%81%AEkuromoji%E3%81%A8lucene-gosen%E5%AF%BE%E5%BF%9C2%E7%AB%A04%E7%AB%A0/","publishdate":"2012-04-14T02:58:00+09:00","summary":"先日の続きです。「Apache Solr入門」の2章から4章の説明について、Solr3.6.0で動作させる時の変更点を以下に書いていきます。 な","tags":["solr"],"title":"「Apache Solr入門」のサンプルのKuromojiとlucene-gosen対応(2章~4章)(Jugemより移植)"},{"contents":"以前より、アナウンスしていた、Kuromojiという日本語形態素解析が含まれるLucene/Solr 3.6.0がリリースされました。\n以下、各リリース内容について簡単に説明されているページへのリンクです。\nSolrリリースのお知らせ\nLuceneリリースのお知らせ\nSolr 3.6.0の変更の目玉は各言語のAnalyzer/Tokenizerの設定がexampleのschema.xmlに含まれるようになったことです。 Kuromojiという日本語用の形態素解析器もexampleを起動すればすぐに利用できる形になっています。 Kuromojiを利用する場合は、exampleのschema.xmlが参考になるでしょう。\nあと、大きな変更は、Ivyに対応した点です。ソースをダウンロードするとわかりますが、依存するjarファイルが含まれない形に変更されています。 SVNからチェックアウトした場合も同様です。ビルドにはネットワークに接続している環境が必要になりました。\nまた、このリリースに合わせて、以前書いた「Apache Solr入門」のサンプルについての記事も変更が必要かと思い、 前回の記事をベースに以下に変更した記事を書いたので、参考にしてください。 今回は、Kuromojiという日本語形態素解析がデフォルトで含まれるようになったので、 Kuromojiの利用方法とあわせて、lucene-gosenの利用方法も記載します。 サンプルのschema.xmlについては、Kuromoji、lucene-gosenが同時に利用できる形のものを用意しました。\nサンプルのschema.xmlを最新版(Solr 3.6 + lucene-gosen-2.0.0-ipadic)のものを用意しました。 なお、あくまでも、3.xでlucene-gosenを利用する場合の「Apache Solr入門」のサンプルプログラムの変更点(とりあえず、4章まで)の違いについて記述します。 申し訳ございませんが、1.4と3.xの違いについての説明はここでは行いません。\n以下では、各章でschema.xmlに関連する記載のある部分を抜粋して、変更点と変更したschema.xmlのリンクを用意しました。参考にしてもらえればと思います。\n1章 1.6.1 N-gram(17ページ) 1.6.1の手順に変更はありません。 サンプルプログラムが入っているZip「solrbook.zip」のintroduction/ngram/schema.xmlファイルの代わりに こちらのschema.xmlを利用してください。 ※なお、Solr 3.6.0から、SOLR_HOME/example/solr/conf/schema.xmlにデフォルトでN-gramで利用しているCJKTokenizerの設定が入るようになっています。 (実際にはCJKTokenizerではなく、CJKBigramFilterとCJKWidthFilterに変更されています。)\n1.6.2 形態素解析(18ページ~20ページ中盤まで) CJKと同様、exampleにKuromojiを利用した設定がすでに記述されています。text_jaというフィールドタイプになります。書籍の21ページ1行目に記載のある、 「Field」のテキストボックスに入力する文字列を「text_ja」とすると、Kuromojiを利用した形態素解析結果が表示されます。exampleですでに幾つかのフィルタも設定されているため、書籍の出力結果とは異なる表示となるはずです。\nlucene-gosenを利用する場合は手順が大きく変わります。 Senを利用する場合、Senの辞書のビルド、Senのjarファイルの配置、Senを利用するためのTokenizerクラスを含んだサンプルjarの配置という作業があります。 lucene-gosenではコンパイル済みの辞書がjarファイルに含まれています。 また、Solr向けのTokenizerもlucene-gosenのjarファイルに含まれています。 lucene-gosenを利用して形態素解析を体験するための手順は次の流れになります。 なお、schema.xmlについては上記N-gramでダウンロードしたschema.xmlに形態素解析の設定もあわせて記載してあります。\njarファイル(lucene-gosen-2.0.0-ipadic.jar)をダウンロードして、$SOLR/example/solr/lib(libディレクトリがない場合は作成)にコピーします。 コピーが終わりましたら、次のように$SOLR/exampleディレクトリでSolrを起動します。 (-Dsen.homeは必要なし)\n$ java -jar start.jar あとは、書籍の記述にしたがって管理画面のAnalysis画面で動作を確認します。 ほぼ、図1-6と同じ結果になっていると思います。 (lucene-gosenで出力される情報には本書のサンプルよりも多くの情報が含まれています。また、サンプルでは、形態素解析の後の単語に基本形を採用しているため、「な」が「だ」として出力されています。基本形を出力する場合は後述するこちらで紹介したTokenFilterを利用すれば可能です。)\n2章については後日説明することにします(眠くなってきた。。。)\n動作しないなどあれば、コメントください。\n2012/06/14追記提供しているschema.xmlに関して修正を加えました。こちらの記事で説明しているautoGeneratePhraseQueriesの値をtext_gosen、text_cjkのフィールドに対してtrueを設定する記述を追記しました。\n","date":1334339100,"dir":"post/2012/","id":"904b07170a0ce481b7491e7fecce4f79","lang":"ja","lastmod":1334339100,"permalink":"https://blog.johtani.info/blog/2012/04/14/lucene-solr-3-6-0%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9---apache-solr%E5%85%A5%E9%96%80%E3%81%AE%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%81%AEkuromoji%E3%81%A8lucene-gosen%E5%AF%BE%E5%BF%9C1%E7%AB%A0/","publishdate":"2012-04-14T02:45:00+09:00","summary":"以前より、アナウンスしていた、Kuromojiという日本語形態素解析が含まれるLucene/Solr 3.6.0がリリースされました。 以下、各","tags":["solr"],"title":"Lucene/Solr 3.6.0リリース / 「Apache Solr入門」のサンプルのKuromojiとlucene-gosen対応(1章)(Jugemより移植)"},{"contents":"Twitterでこのブログ流れてきて、気になったので、流し読みして簡単にメモ。 Amazonのサービスでスケールする検索サービスみたい。\n主に、機能面です。価格とかはみてないです。\nデータと検索トラフィックに対して自動でスケール(※automaticってのがどういう感じかは調べてないです) CloudSearch APIsでアクセス可能。AWS管理コンソールからオペレーションできる。コマンドツールもある データ登録にHTTPSも使えますよ。データ形式はJSON、XML、SDF(Search Document Format)と呼ばれるものに準拠したもの near real-timeで検索可能になる。RAMにインデックスを保持して更新処理が早くなる(Lucene/Solrと一緒か?) ステミングとかストップワードの設定変えたらre-index ファセット、フィールド指定検索が可能。(ファセットはファセットクエリみたいなのもできるのかな?) データ量が増えたら、サーチインスタンスを追加するか、インスタンスタイプを大きくしてスケールする? トラフィックが増えたら新しいインスタンスにデータをレプリケートしてインスタンスを追加する 簡単に実現できるよ。ファセット検索、全文検索、And/OR検索式、ランキングのカスタマイズ、フィールド指定ソート、フィールド指定検索、テキスト処理オプション(ストップワード、類義語、ステミングのような) ここから詳細のドキュメントが見れるみたいなので、また、見てみます。\nあと、WikipediaをCloudSearchで動かしてるデモとそれに関する記事もあるみたいです。これも暇を見つけて眺めてみます。\n","date":1334241069,"dir":"post/2012/","id":"bed3b7fcc1294e23639057435ac8756a","lang":"ja","lastmod":1334241069,"permalink":"https://blog.johtani.info/blog/2012/04/12/%E3%83%A1%E3%83%A2amazon-cloudsearch%E3%81%8C%E5%87%BA%E3%81%A6%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F%E3%82%88/","publishdate":"2012-04-12T23:31:09+09:00","summary":"Twitterでこのブログ流れてきて、気になったので、流し読みして簡単にメモ。 Amazonのサービスでスケールする検索サービスみたい。 主に、","tags":["備忘録"],"title":"【メモ】Amazon CloudSearchが出てきましたよ(Jugemより移植)"},{"contents":"JavaOne Tokyo 2012に参加してきました。 4/4-4/5の2日間開催されていたのですが、子供が体調を崩してしまい、4/5のみの参加となりました。 4/4はTwitterのTLを眺めて、羨ましがってました。\n7年ぶりに日本で開催されたJavaOneみたいです。 そういえば、7年前くらいに参加した記憶があるなぁと。\n会場入りして最初の感想は年齢層が高いなぁと。 最近、勉強会によく顔を出すようになったのですが、勉強会とは年齢層が少し異なりました。 まぁ、私も年齢層を上げている一人ではあるのですが。。。 Javaも熟成してきてるなぁというのが最初の感想でした。 あと、思ったよりもスーツ率は低かったと思いました。(5割はいましたが) 一番違和感を感じたのは、会場の所々の色が「赤い」ことです。。。\n以下は私が参加したセッションのカンタンな感想です。\nJava EE6 Modeling JS2-01 #jt12_s201\nJavaEEから離れてはや数年。私が関わっていた頃はEJB2.0が出たくらいのタイミングだったので、 色々と変わってきているなぁというのが第一印象です。 CDI、Singleton EJBなど、知らない単語もちらほらと。 earではなく、warファイル1つで済む、jQueryをリソースjarとしてパッケージングしてwarファイルに入れられるなどは簡易になっていいなぁと。 web.xmlがアノテーションで記述できて要らなくなるという話は一長一短だと思いました。 一覧性があるからいいと思うこともあるので。 中国の方?の英語だったので少し特徴的でした。すこしは頑張ってみたものの、やはり同時通訳を聞いてしまって反省しています。。。\nマルチコアCPU時代のJavaプログラミング JS2-14 #jt12_s214\nF社の方が実際に経験されてきた性能関連のプログラミングについての話でした。 現時点のJavaでマルチコアCPUで気をつけるべきプログラミングの観点をわかりやすく説明されたいいセッションでした。 詳細は下のメモを見ていただけるといいですが、色々とプログラミングで気をつけるべき点を説明されていました。 いいおさらいになりましたし、忘れていることや知らないこともあって勉強になりました。 TLでも見かけましたが、モダンJavaプログラミングみたいな、今のJavaでのプログラミングの気をつけるべき点を書いた書籍があるといいかもなぁと思いました。 あと、もうひとつ私が好印象だと思ったのは、F社の製品の紹介などがなかったからかもしれませんw\nサービス維持・発展を踏まえた楽天オークションのJava EEによる開発と運用 JS2-23 #jt12_s223\n楽天オークションの開発をサれている方の立ち上げから現在に至るまでの開発メンバーの管理の仕方や 実際に利用している開発手法、気をつけている点のお話です。 スライドに書いてあること以外のことを発表者の方が話をされており、もう少し、喋る内容に関連した図などを入れてもらえるとわかりやすかったかもしれません。 あとは、WebLogicの管理画面が使いやすくていいという話のあとに、GlassFishに移行していますという話があったりと、少し「?」が浮かぶ部分がありました。。。\nJSR 353: Java API for JSON Processing JS2-33 #jt12_s233\n最近、Twitterで遊んでもらっている(勝手に絡んでいるだけという話も。。。)@yusukeyさんの発表です。 結構な数の立ち見が出るほどの盛況ぶりで、発表者の@yusukeyさんもびっくりしていました。 JSRがどういった形で実際の仕様として公開されていくのかという話がわかりやすく紹介されていて勉強になりました。 所々で笑いが入るなど、さすがの安定感でした。立ち見が出るはずです。 ようやく、JavaもJSONに関する処理を仕様として取り入れようとしているのはいい傾向かと。 ※残念ながら資料は公開されないようです。\nUI Controls and Charts: Drag-and-Drop, Filtering, Sorting, Table Hookup with Charts JS2-42 #jt12_s242\n最近、Chartに興味を持っていたので、登録したセッションです。 内容としてはJavaFXのコンポーネントをリストアップして紹介していくというお話でした。 グラフ(Chart)周りも数種類が用意されるようです。 JavaFXをあまり知らないのですが、Swingをすこしやっていたのでなんとかついていくことが出来ました。 発表者の方が、実際にJavaFX内部の実装を行われている方だったようで、QAでいくつかこんなコンポーネントはないのか?という質問に、「私のPCでは動いているのですが、ドキュメントなどの整備が追いついていないので公開できていないです」という回答が出て、なかなか大変なのだなぁとw Chartに関しては、グラフの重ね合わせなどがまだできないということで、JFreeChartを触ったことがある身としてはすこし物足りなさそうだなぁというのが印象です。\nLearn how the JVM is fundamental to our architecture. BoF2-03 #jt12_b203\n今回JavaOneに参加した一番の理由がこのセッションです。 Twitterのアーキテクチャに関するセッションでした。 思った以上に濃い内容で、ツイートしたデータがどんな流れで登録されるのか、登録されたデータを各ユーザのTimelineにどのようにアクセスして表示しているのかが説明されました。 今回は主にFinagleについての話でしたが、非同期処理をどのように活用しているかというお話でした。 負荷分散を行なっているポイントやキャッシュについての考え方などです。 メモを取るのに夢中になってしまい、英語をヒアリングするという目的を見失ってしまいましたが。。。 期待以上の話が聞けて満足しています。\nパネルディスカッション\n最後はJavaに関連するコミュニティを運営されている方々のコミュニティ運営に関するディスカッションです。 コミュニティの運営の苦労している点や、心がけている点など、運営も大変そうだなぁと。 どうしても長くやっているとメンバーが固定化してしまうという話なども出ていました。 これは難しいですよね。会社も同じことが言えますし。 一番印象に残ったのは桜庭さんの「動くものが作れるのが楽しい」という一言でした。 エンジニアをやってるのは確かにそこが面白いからだなぁと。最近忘れかけているので、もっと色々と作っていきたいですね。\n以上がカンタンな感想です。 少し残念なのですが、事前に参加登録していたセッションについては、マイページと呼ばれるところから資料がダウンロードできるものもあるみたいですが、参加登録してないものについてはダウンロードが出来ない様でした。(4/6現在) 参加できなかったセッションの資料こそ見たいと思うのが普通だと思うのですが、どうでしょう?そのうちどこかに公開されるのかなぁ。\n以下は、いつもの通り個人のメモです。\n場所:六本木ヒルズ アカデミーヒルズ49F 日時:2012/04/05 ○Java EE6 Modeling JS2-01 #jt12_s201 スーツ禁止。Eva好き? ・特徴 Web Profile Pruing POJO、Annotation、Less XML Java EE6の半分のAPIは変更なし。新規が11% ・JavaEE6 Web Profile CDI、Interceptors、JSR 250 Singleton EJB JPAはEntityBeanの代わりかな? ・パッケージングがearではなく、war一つで済むように。 war(ウォーファイル) web.xmlはアノテーションで行えるようになり、要らなくなる。 ◯マルチコアCPU時代のJavaプログラミング JS2-14 #jt12_s214 HotSpotVM依存のお話ですよ。 ・GCとか ・java.util.concurrent.ForkJoinPool デフォルト並列数は論理CPU数 ・メモリアロケーション TLABが非効率に。先にある程度大きめにスレッドに割り当てを行うため、 スレッド数が上がるとTLABが非効率になる-\u0026gt;Eden全体では未使用領域があるんだけどGC発生とか ・JNIでの問題 GetStringCriticalとReleaseStringCritical間はGCが抑止されるため。 ・無意識のロック HashTableやStringBufferなど。 String#getBytes()も。 InetAddress#getAllByName()が内部でキャッシュを持ってる=ロック File#renameTo()も内部でキャッシュ(ExpiringCache)持ってる。 Javaでは時間がかかる処理にはキャッシュを利用するという仕組みなので。スレッド数を増加させる場合は注意が必要 ・フェアネスロック lock = new Object(); for (int i=0;i\u0026lt;100;i++0{ synchronized(lock){ System.out.println(\u0026#34;i=\u0026#34;+i+\u0026#34;tid=\u0026#34;+Thread.currentThread().getId()); } } 上記を実行してもかたよることがあるよ。=フェアじゃない モニターによるスレッド割り当ての説明。 RentrantLockでフェアネスになるよ。 ・性能分析 println()で区間分析。複数スレッドで実行したら実行時間にずれが。 println内部でもsynchronizedを利用している。=ロックのせいで処理時間が遅くなるスレッドが出てきたりする。 JVMTIで性能分析する場合RawMonitorEnter,RawMonitorExitでロックとりあいなるのでもマルチスレッッドだと正しい値がでない。GetThreadLocalStrage使え。 ・まとめ: ハードウェア更改時にプログラムの変更が必要になることもあるよ。 わずかのロックが命取りに(ロックをあんまり使わない、無意識なロックを見極めなさい) ロックポリシーの選択(レスポンス重視なのか、スループット重視なのか) QA Q:事例が合ったという話でしたが、コードの修正しかないんですか? A:はい。やっぱり治すのがいいです。あとは、チューニングですが。。。 Q:ReentrantLockが昔はスレッドダンプにでなかったのですが、今は? A:今は出ます。 Q:各世代とJavaのバージョンのマッピングは? A:第3世代が1.5くらいから。第2世代が1.3とか1.4? ◯サービス維持・発展を踏まえた楽天オークションのJava EEによる開発と運用 JS2-23 #jt12_s223 ・短期で人材が参加できるようにしているというお話 ・楽天オークションの成り立ち(郵政とdocomoと楽天) ・商品、コミュニティ系(出品とか検索とか)と流通系(入出金、配送など)の2軸 ・メンバー30人くらい ミドルエンジニア エンジニア プロデューサー ・楽天市場をベースとして機能追加 ・巨大でリリースが大変に。 ・この5年で機能分解して機能ごとのリリースをめざして改善している ・JavaEEを使う理由 WebLogic上にバッチが動いているなどの仕組みをしている? 管理機能が充実している(WebLogic) ・GlassFishへ移行中 あれ?Weblogicの管理機能がいいんじゃなかったっけ? EJB実装はWebLogicに依存してるのでWebLogicもバージョンアップしてる。 ※メモはここまで。電池の持ちを気にして ◯ JSR 353: Java API for JSON Processing JS2-33 #jt12_s233 ・JSONとは JavaScript Object Notation 「軽量な」データ交換フォーマット ・JSON仕様のグラフ ・XMLもあるのになんで? シンプルで可読性が高い 属性がなく、複雑なスキーマ仕様がない。 ・コンパクト ・Twitter、GoogleMaps、YahooWebServicesなど ・JCP、JSRのお話 JSRの役割とか。 リファレンス実装の話。 ・JSR-353 http://jcp.org/en/jsr/detail?id=353 StAXやDOMに対応するよ。 ・ゴールではないもの JSONをJavaのドメインオブジェクトにバインドするとかもどすとか。 ・メンバー @yusukeyも一人 ・参加になったきっかけ 2011/10にTwitterがJCPに参加 2012/12/6にJSON JSR提出 年越しに採択 @yusukey「これTwitterで重要じゃない?」 @cra 「やりましょう」 ・JSRのコミュニケーション 世界各地の人なので、基本メールベース(今は自己紹介したくらい。。) ・既存のJSONライブラリ json.org、jackson、google-gson ・なんで、いろいろあるのにJSR? 標準化、クラスパスにデフォ、シンプル、ライセンスで悩まないとか。 ・ロードマップ エキスパートグループ作成→アーリードラフト→パブリックレビュー→ファイナルリリース いま、アーリードラフト ・最新仕様 javax.json.* javax.json.spi.* javax.json.stream.* javax.json.tree.* メソッドチェインできるみたい。 JsonObject.create(reader);みたい JsonObject obj = …; JsonWriter writer = obj.accept(writer.) ・改善案 JSON***にしたいな。 spiはらないんじゃないかな?(いま、一個しか無い) treeもいらないんじゃないかな?(そんなに増えないし) parseじゃないかな? メソッド追加(asStringで文字列化とか、create(String)とか) QA Q:JSONのスキーマ決めないの?バリデータとか A:JSONスキーマはあんまりもてはやされてない。一応あるのはある。 さすがの安定感。適宜笑いが入ってて楽しかったです。 ◯UI Controls and Charts: Drag-and-Drop, Filtering, Sorting, Table Hookup with Charts JS2-42 #jt12_s242 ◯JavaFX 2.0のControls ◯Label、Button、ToggleButton、RadioButton、Hyperlink、CheckBox ◯Slider、ScrollBar、ScrollPane、ProgressIndicator、ProgressBar ◯TextField、PasswordField、TextArea ◯新しい機能 TitledPaneとAccordion TabPaneとSplitPane ◯Charts XYChartとPieChart XYChartにはLineChart、AreaChart、BarChart、ScatterChart、BubbleChartがある。 ◯Menu MenuItemの下に色々ある。 CheckMenuItem、RadioMenuItem、CustomMenuItem(SeparatorMenuItemとか) ◯ChoiceBox、ContextMenu、ToolTip ◯ListView ◯2.1の新機能 ComboBox、http://fxexperience.com/2012/03/new-in-javafx-2-1-combobox/ StackedBarChart、 StackedAreaChart MenuBarのMac OSへの対応(窓の中じゃなく、画面上部にちゃんと出る。) LCD Text QA: Q:テキストエリアの日本語入力とかは? A:JavaFX3.0で対応 Q:FXML(Scene Builder)を使ってコードが生成されるのか? A:ドラッグ・アンド・ドロップでやる場合はScene Builderでもできるでしょう。私はNetBeansとかでやりますけどね。 Q:Dialogはいつ対応されるんでしょうか? A:私は使ってるんですけど、JavaFXに入れてもらえませんwコードは出来てますw Q:Chartがありますが、pngやsvgでの出力は可能? A:できません。そのうちできるかも。 Q:Chartの結合はできる?Axisの時間を便利に使うツールはありますか? A:できないです。ありません。 Q:FX2.0でカスタムコントロール作るの大変? A:私のマシンでは動いてるんですがw Q:ChartにCSSを適用することは可能? A:可能です。データはJavaから出力されたものだけですけどね。 Q:JavaFX2.0の起動速度が上がったけど、どういう仕組? A:私は上の方のエンジニアなのでよくわからないですが、GPUをうまく使ってるみたいです。 ◯Learn how the JVM is fundamental to our architecture. BoF2-03 #jt12_b203 Java、Scala、Linuxのカーネルまで担当してます。 ・Twitterのアーキテクチャ ・スパイクが急にあがる場合にも対応できるスケールの話。 なでしこ、#バルス、大震災など ・Twitterはプラットフォーム ・最上位層:HTTP Proxy(Routing) ・中層:Twitter App(Models/Biz Objects、Composition) UserService、TweetService、TimelineServiceに分解(Models/Biz Objects) API(Composition) ・最下層:TimelineStorage、TweetStorage、SocialGraph、UserStorage(Storage/Retrieval) ・NEEDS サーバ負荷をハンドルできる必要がある。 言語のフレキシビリティ(JavaとかScalaとか) 成熟したコンカレンシーモデル ・Java が提供してるもの 開発者のエコシステムが素晴らしい。例:Nettyを使っている。Non-blocking I/O world class JITとコンカレンシーモデル メモリ管理 利点:メモリ管理を意識しなくていい 課題:GC。OpenJDKのコミュニティで参加してる。 複数の言語が実行可能な環境 ・OpenJDKについて ・Finagleのお話。 Netty上に作られた非同期なRPCサーバクライアントのライブラリ http://twitter.gthub.com/finagle/ ・TimelineServiceのお話 340M/day 10K/sec(イベント時) ・ツイートが入ってくる仕組み HTTP Proxy → tweet API → queue → tweet daemon → fanout (social graph)→ delivery → timeline cache → redis ・fanout 4000フォロワーごとにdeliveryにツイートが渡される。 ・Timelineを見る仕組み HTTP Proxy → timeline API(user service、) →timeline service →timeline cache ・timeline、tweets、users ・timeline serviceとtimeline cacheの関係 Finagleで負荷分散している ・timeline serviceからtimeline cacheへのリクエストを監視して、 高頻度のリクエストについては、timeline serviceのin-process cacheに入れる仕組み ・Service[Request, Response] Scalaの記述 service(request).onSuccess {response =\u0026gt; println(\u0026#34;got response! \u0026#34; + response) } ・Finagleのコンポーネント コネクション管理 プロトコルデコード ThriftでService以降がつながってる。 分散トレース オーバーヘッドを抑えて全体を監視(RPCトレース(呼び出しと処理時間のタイムラインチャート)) サービスディスカバリ observability ◯パネルディスカッション ・JGGUG、JRuby、Scala、Groovyのコミュニティ運営に関係している方々によるディスカッション。 ","date":1333698660,"dir":"post/2012/","id":"56d5711303378bd333ddb611a53ece94","lang":"ja","lastmod":1333698660,"permalink":"https://blog.johtani.info/blog/2012/04/06/java-one-tokyo-2012-%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-javaonejp/","publishdate":"2012-04-06T16:51:00+09:00","summary":"JavaOne Tokyo 2012に参加してきました。 4/4-4/5の2日間開催されていたのですが、子供が体調を崩してしまい、4/5のみの参加となりました。 4/4","tags":["勉強会"],"title":"Java One Tokyo 2012 に参加しました。#JavaOneJp(Jugemより移植)"},{"contents":"先日、2.0.0リリースの記事にも記載しましたが、Java7でテストケースが失敗する問題がありました。\n@haruyamaさんと@hideaki_tさんの協力により問題を解消し、trunkと4xブランチにコミットしました。\nissueにも記載しましたが、Java6からJava7にバージョンアップするタイミングで変更されたUnicodeのバージョンが原因でした。 Java6ではUnicodeのバージョンが4.0です。Java7ではUnicodeのバージョンが6.0に変更されています。 今回の問題は「・」(0x30FB)の文字列のCharacter.getType()がCONNECTOR_PUNCTUATIONからOTHER_PUNCTUATIONに変更されたのが原因です。(この変更自体はUnicode 4.1で変更されたみたい) カタカナ文字種の判別をlucene-gosenのnet.java.sen.tokenizers.ja.JapaneseTokenizerのgetCharClass(char c)メソッドで行なっています。 修正前は、ここで、charの範囲が0x30A0~0x30FFにある文字でかつ、Character.getType()がCONNECTOR_PUNCTUATIONでないものがカタカナとして判別されていました。 issueの添付ファイルにJava6とJava7で上記範囲の文字のCharacter.getType()のリストを生成して、該当する文字を探した所、「・」(0x30FB)のみであることがわかりました。 ということで、このコードの意図としては、「・」はカタカナではないと判別したかったのだと。 上記の確認を行えたので、ソースコードを修正してコミットしました。 2.0.1としてリリースするかは、Issue29のボリュームを見て考えますので、もう少しお待ちください。\n参考にしたサイト: JavaSE 7でメソッド名に使えなくなった文字 UNICODE CHARACTER DATABASEのHistory\n","date":1333552800,"dir":"post/2012/","id":"c7937b6b4bde2a96191dc31db913e1ab","lang":"ja","lastmod":1333552800,"permalink":"https://blog.johtani.info/blog/2012/04/05/lucene-gosen%E3%81%AEjava7%E3%81%A7%E3%81%AE%E3%83%86%E3%82%B9%E3%83%88%E5%A4%B1%E6%95%97%E5%95%8F%E9%A1%8C%E3%81%AE%E5%AF%BE%E5%BF%9C/","publishdate":"2012-04-05T00:20:00+09:00","summary":"先日、2.0.0リリースの記事にも記載しましたが、Java7でテストケースが失敗する問題がありました。 @haruyamaさんと@hideak","tags":["lucene-gosen"],"title":"lucene-gosenのJava7でのテスト失敗問題の対応(Jugemより移植)"},{"contents":"先日、宣言したとおり、lucene-gosenのパッケージ名+クラス名の変更を行ったlucene-gosen 2.0.0をリリースしました。 Lucene/Solr 3.6.0のリリースを待つつもりだったのですが、なかなか出ないので先にリリースを行いました。 現時点では、branches/4xについては、パッケージ名、クラス名の修正が追いついていません。 明日までに4xブランチについても修正を反映する予定です。\n参考までに、1.2.1から2.0.0への変更点について以下にまとめました。 また、変更に伴い、Solrのschema.xmlに記述するクラス名も変更になります。 schema.xmlのサンプルについてはこちらをご覧下さい。\n変更点 まずは、パッケージ名の変更点です。 左が旧パッケージ名、右が新パッケージ名となります。\n旧パッケージ名 新パッケージ名 org.apache.lucene.analysis.ja org.apache.lucene.analysis.gosen org.apache.lucene.analysis.ja.tokenAttributes org.apache.lucene.analysis.gosen.tokenAttributes また、パッケージ名とは別に、以下のクラス名も変更になっています。 まずは、org.apache.lucene.analysis.gosenのクラス名の変更点です。\n旧クラス名 新クラス名 JapaneseAnalyzer.java GosenAnalyzer.java JapaneseBasicFormFilter.java GosenBasicFormFilter.java JapaneseKatakanaStemFilter.java GosenKatakanaStemFilter.java JapanesePartOfSpeechKeepFilter.java GosenPartOfSpeechKeepFilter.java JapanesePartOfSpeechStopFilter.java GosenPartOfSpeechStopFilter.java JapanesePunctuationFilter.java GosenPunctuationFilter.java なし GosenReadingsFormFilter.java JapaneseTokenizer.java GosenTokenizer.java JapaneseWidthFilter.java GosenWidthFilter.java 次は**org.apache.solr.analysis**です。 旧クラス名 新クラス名 JapaneseBasicFormFilterFactory.java GosenBasicFormFilterFactory.java JapaneseKatakanaStemFilterFactory.java GosenKatakanaStemFilterFactory.java JapanesePartOfSpeechKeepFilterFactory.java GosenPartOfSpeechKeepFilterFactory.java JapanesePartOfSpeechStopFilterFactory.java GosenPartOfSpeechStopFilterFactory.java JapanesePunctuationFilterFactory.java GosenPunctuationFilterFactory.java なし GosenReadingsFormFilterFactory.java JapaneseTokenizerFactory.java GosenTokenizerFactory.java JapaneseWidthFilterFactory.java GosenWidthFilterFactory.java また、上記クラスに関連するテストクラスの名前も変更になっています。\n以上がクラス名、パッケージ名の対応に関する修正ついてでした。\nまた、現在、Java7にてテストケースが失敗する問題が見つかっています。 こちらの問題の対応版についても近日中にリリースを行う予定です。\n問題点、質問などありましたら、コメントしていただくと回答いたします。\n2012-04-03追記 忘れてました、すみません。今回のリリースで、以下の機能が追加されています。\nAntのパラメータにproxy.user、proxy.passwordの追加 GosenReadingsFormFilterの追加 TokenAttributeの修正(PronunciationsAttributeImpl、ReadingsAttributeImpl) Antは認証が必要なプロキシ環境で辞書のビルドを実施するときにユーザ名、パスワードを指定できるようにしました。\nGosenReadingsFormFilterは単語を読みに変換するTokenFilterになります。 よみは、辞書に登録してある読みになります。オプションとして、romanizedが指定可能です。指定をすると、よみをローマ字に変換します。\nTokenAttributeの修正は、バグフィックスになります。Issueはこちらです。\n","date":1333362120,"dir":"post/2012/","id":"06731164684f90f33ce4017eca9d8ec1","lang":"ja","lastmod":1333362120,"permalink":"https://blog.johtani.info/blog/2012/04/02/%E9%87%8D%E8%A6%81lucene-gosen-2-0-0%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9/","publishdate":"2012-04-02T19:22:00+09:00","summary":"先日、宣言したとおり、lucene-gosenのパッケージ名+クラス名の変更を行ったlucene-gosen 2.0.0をリリースしました。 Lucene/Solr","tags":["lucene-gosen"],"title":"【重要】lucene-gosen 2.0.0リリース(Jugemより移植)"},{"contents":"lucene-gosenを利用して頂いてる皆様に連絡があります。\n連絡事項 次期lucene-gosenのリリース(2.0を予定)にて、org.apache系のパッケージ名および、クラス名の変更を行います。 Lucene/Solrの次期リリース版である3.6.0以降では、lucene-gosen 2.0(予定)を利用するようにしてください。\n経緯 Twitterでは少しずつツイートしていますが、Lucene/Solr 3.6から日本語の形態素解析器がLucene/Solrにて用意されることになりました。 ベースとなっているのは、Atilika社が開発したKuromojiという形態素解析器です。 Lucene/SolrにコントリビュートされたタイミングではKuromojiAnalyzerなど、Kuromojiという名称が残った形で取り込みが行われました。 その後、LUCENE-3909にて、Kuromojiではなく、一般的な名称(Japanese*)に変更する提案が行われました。 この提案で、luene-gosenが利用しているクラス名、パッケージ名と大半のクラスが衝突してしまうこととなりましす。 今後も、lucene-gosenを利用していただけるように、lucene-gosenのIssueを発行し、 現在、lucene-gosenのtrunkにてパッケージ名の変更及びクラス名の変更作業を行なっています。 正式にリリースするタイミングになりましたら、再度連絡いたします。\nブランチなどについて 現時点ではパッケージ名、クラス名の変更はリポジトリの以下のものについてのみ作業を行う予定です。\ntrunk branches/4x 現時点でのリリース版(1.2系)のソースについてはbranches/rel-1.2にて、これまで同様のクラス名、パッケージ名のまま変更を行いません。 1.2系についてはこちらをご覧下さい。\nまた、当ブログにて、提供しているSolr入門のサンプルに利用可能なschema.xmlなどの記事についてもLucene/Solr3.6がリリースされた際には再度修正して掲載いたします。 Kuromojiの利用方法もあわせて記載したいです。\n参考: lucene-gosenとKuromojiの機能などの比較についてはこちらを参考にしてください。\n","date":1332783540,"dir":"post/2012/","id":"f8327953a0f0b80011b939111807999a","lang":"ja","lastmod":1332783540,"permalink":"https://blog.johtani.info/blog/2012/03/27/%E9%87%8D%E8%A6%81lucene-gosen%E3%81%AE%E6%AC%A1%E6%9C%9F%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/","publishdate":"2012-03-27T02:39:00+09:00","summary":"lucene-gosenを利用して頂いてる皆様に連絡があります。 連絡事項 次期lucene-gosenのリリース(2.0を予定)にて、org.","tags":["lucene-gosen"],"title":"【重要】lucene-gosenの次期リリースについて(Jugemより移植)"},{"contents":"子供の寝かしつけしてたら、寝かしつけされてしまって、2時に目が覚めてしまいました。 TSUTAYAでCD借りてきてウォークマンに入れようと思っていたのに。。。 ということで、今作業してます。\nMBAを買う前から使っている、もう9年目のWindows自作デスクトップで基本的にはCDの取り込みをしています。 ファイルサーバ(BuffaloのTeraStation)がLionから接続できないというのと、 X-アプリで曲管理していたのでという理由です。 あと、ウォークマンなのでMac用のソフトがなかったりというのも理由です。\nで、眠い目をこすりながらWindowsマシンを起動すると、ネットワークにつながらないじゃないですか。。。 再起動してもダメでした。\nとなってしまったので、せっかく、譲ってもらったMac miniも活用しないといけないなと思い、iTunesでアルバムを取り込んでみています。 ここ数年はWAV形式でデータを取り込んでいたので、WAVでの取り込みを設定して、iTunesで取り込みました。\nとまぁ、ここまでやってから、件のWindows機を再度、再起動したらネットワークに繋がってしまいました。。。 なので、残りのCDはWindows機で取り込みしてます。 けど、そろそろこのPCも危なそうなので、データをサルベージして、Mac miniで作業できるようにしないとなぁ。 Macでウォークマンを運用している人はどうやってるんだろう? ちなみに私が利用しているウォークマンはNW-A847です。 エンコードはWAV形式で取り込んで、X-アプリでウォークマンに入れています。 iTunes使ってる人は、アップルのロスレスエンコードをつかってるのかなぁ? ということで、調査・検討したい項目はこんなところですか。\n調査:TeraStationにMacからつなぐ方法(Lionで利用できそうなソフトなにかないかな?) 調査:iTunesでウォークマンに曲転送(やってみればすぐわかるだろう。。。) 調査:iTunesの曲をCDに焼く方法(車で曲聞くのにCDだから) 検討:ファイルサーバのリプレース対象となる機種(ファイルサーバは導入してまだ5年だから余裕がないと買い換えない) 検討:iPodに鞍替え(Sony好きだし、ウォークマン好きだし、買ったばっかりだからまず無い選択肢) 検討:Mac miniにVirtualBox入れて、WindowsからX-アプリ使うとか。(ファイルサーバが見えるようになるかな?) 検討:Mac miniをWindowsとして運用(もったいなさすぎる気がする) とまぁ、まだ悩んでるだけで、取り留めもない事を書いて、しかも結論が出ないままですが、ご容赦ください。 ご意見、提案を大募集してます!!\n","date":1332618420,"dir":"post/2012/","id":"8b76101d185700a8efed148d8722d926","lang":"ja","lastmod":1332618420,"permalink":"https://blog.johtani.info/blog/2012/03/25/%E4%B9%85%E3%80%85%E3%81%ABmac-mini%E3%81%AE%E3%81%93%E3%81%A8%E3%81%A7%E3%82%82/","publishdate":"2012-03-25T04:47:00+09:00","summary":"子供の寝かしつけしてたら、寝かしつけされてしまって、2時に目が覚めてしまいました。 TSUTAYAでCD借りてきてウォークマンに入れようと思っ","tags":["備忘録"],"title":"久々にMac Miniのことでも(Jugemより移植)"},{"contents":"はい。またまた、Twitter API勉強会に参加してきました。(今回から開催回数の記載がなくなった?) 今回は直前でタイムテーブルが変わってしまう波乱がありましたが、個人的には楽しめる内容でした。 Twitterの国際化や形態素解析などの話が聞けたのがすごく面白かったです。 アーキテクチャや利用されている形態素解析器の話など、また、現状の問題点なども話が聞けました。 日々、進化しているんだなぁと。 残念ながら、発表者の方が懇親会にいらっしゃらなかったので、詳しく聞けませんでしたが、挨拶だけは出来ました。 実際のテスト環境や導入方法、A/Bテストとかやってるのかなど、ブログをかきながら色々と気になることが出てきてしまいますw 頭の回転がよくないので、話を聞いてる間は質問があんまり思い浮かばなかったなぁ。。。\nその他にも(使ったことなくてすみません。。。)「昼会」のサービスの話、他の言語でのTwitterの活用の話も聞けました。\n途中で帰ってしまいましたが、懇親会でも数人の方とお話できて、楽しかったです。 (今回の懇親会会場はちょっと人数の割に手狭だったかもなぁ)\n次回は4月末を予定しているようでした。今度こそ、利用規約の話になるんですかね? 忙しさを見つつ、また参加しようかと思います。\nということで、いつものメモです。\n開催日時:2012/03/21 19:00 ~ 21:00場所:ハロー会議室shibuya Zusaarのページ\n◎Twitterの日本語検索、ハッシュタグについて @keita_f\n◯アーキテクチャ ・Twitterバックエンドの国際化 Before 各言語ごとに独自実装。 After 共通テキスト処理ライブラリ:Penguin ・アーキテクチャ:検索 Firehose → ingester → Earlybird ⇔ Blender ← ユーザの検索 Firehose:ツイートの受信 ingester:ツイート解析 Earlybird:Luceneベースのインデクサ Blender: ・アーキテクチャ:トレンド TrendsはGeo(ユーザ位置情報)を利用してるっぽい。 Term Statisticsは過去ツイートからHadoopで頻出フレーズを解析する。 今頻出しているフレーズ+過去頻出しているフレーズ ◯日本語関連 ・ツイートの言語判定 言語判定にはIndigenous Tweets(Kevin Scannell)をベースに実装。 50言語サポート、Javaで実装 ・文字種チェック ・エンコーディングチェック ・Ngram(the→英語、das→ドイツ語) 問題点: 2つ以上の言語が混じってる場合 絵文字が入ってる場合 Unicodeアルファベット ・形態素解析 日本語:Gomoku 中国語:LuceneのSmartCN その他:N-Gram 問題点: 形態素が小さすぎる →そのままだと細かすぎるので品詞情報を元に大きめに区切るようにしている iPhone4Sなどが数字で区切られる →ASCIIの数字とアルファベットは連結しなおす ・フレーズ抽出 他の言語もあったけど、キー入力間に合わず 日本語の場合: トークンに分割 トークンでNgramを生成 品詞情報を使ってフィルター 最初、最後が助詞はNG、接頭詞で終わるのはNG ・やりたい事はまだまだたくさん ・形態素解析の品質向上 辞書への単語追加 韓国語、タイ語のトークなイザー ・同義語、類義語、翻訳、音訳、略語などのサポート ・フレーズ・トピックのクラスタリング ・Sentiment Analysis ・日本語のできるエンジニア募集中w QA Q:顔文字を手動で抜き出すと言われたんですが、どのくらいあるんでしょうか? A:正規表現なので、なんとも言えませんが、パターンを Q:Gomokuの選択の理由は? A:Javaだから。jarに辞書が入るから。スピードが出るから。 ◎ランチタイム共有サービス「昼会(http://www.hirukai.jp/)」のご紹介 @setomits\n◯前提 ・ネットワーキングは重要 ・出会いも重要 ・飲み会だとコスパが悪い ◯ランチだと ・金額が限られる ・必ず食べる ということで、昼会だ! ◯画面でサービスの説明 パブリックな昼会、プライベートな昼会がある。 ◯なんでTwitter? LinkedInのOAuthを使ったログイン検討してた。 ビジネス目的+ 敷居が高いのでTwitterに変更 ◯Twitterのapiで利用しているものなど ◯ユーザの声 ・DMを使ってる=自分からのDMが気持ち悪い APIの使用制限やフォローしてもらう必要があるのが辛い。 - スパムかと思った - 乗っ取られたかと思った。 - エンジニアからは、「まぁ、こうするよね」 ・OAuthについて - ユーザ登録しなくていいのは嬉しい - イベント参加のためにOAuthでの書き込み権限まで与えたくない ◯8ヶ月経って ・新しい出会いがあった ・昼会を開催する敷居が高い =なかなか使ってもらえない ◯今後の計画 募集中! QA Q:AppEngineで月額どのくらい? A:料金改定前:数千円/1ヶ月、料金改定後:2万円くらい/1ヶ月 処理数を減らして、現時点では数千円/1ヶ月に最適化した Q:夜会はないんですか? A:設計していたら、出会い系サイト?になりそうなので、昼にした。 ドメイン的になぁ。まだ悩み中 Q:GAE特化したもの?AWSに移行できる作り? A:できない作りです。(pythonで書いてます。) GAEが楽なので、移行可能な作りにするのがつらい。 ◎LT ◯Twitter 4 contact @inda_re ・広告!アジャイルサムライの道場\n・問い合わせフォームをTwitterにしちゃう 今あるHTMLにフォームを入れる方法(MySQLとPHP) githubにサンプルあるよ。 ◯PerlのTwitterモジュールについて @xtetsuji\n・前回出席したら、ムチャぶりが! ・いまどきのPerl 進化してるよ、古い情報が検索で出てきてしまうのがネック ・perlbrewってのがある http://perlbrew.pl/ ・AnyEvent::Twitter::Streamをよく使ってます。 ・gistにサンプルあげてあるよ! ◯KotlinでもTwitter4J @ngsw_taro ・Kotlinの説明 ・以下のサイトでインストールしなくても動かせるよ! http://kotlin-demo.jetbrains.com/ ・NULL安全 Nullを許容する型、許容しない型がある。 ・一応、Twitter4Jのサンプルも作ったけど、ブログ見てね http://d.hatena.ne.jp/ngsw_taro/\n◯締め Twitter API勉強会ではスピーカーを常に募集中です。登録はこちら!\n","date":1332343680,"dir":"post/2012/","id":"16b3c9445539e9274282a612dea354c2","lang":"ja","lastmod":1332343680,"permalink":"https://blog.johtani.info/blog/2012/03/22/%E7%AC%AC5%E5%9B%9E-twitter-api%E5%8B%89%E5%BC%B7%E4%BC%9A--%E6%B8%8B%E8%B0%B7--twtr_hack/","publishdate":"2012-03-22T00:28:00+09:00","summary":"はい。またまた、Twitter API勉強会に参加してきました。(今回から開催回数の記載がなくなった?) 今回は直前でタイムテーブルが変わってし","tags":["勉強会"],"title":"第5回 Twitter API勉強会 @渋谷 #twtr_hack(Jugemより移植)"},{"contents":"TLで面白いと見かけて、Amazonで買ってしまいました。 SEやってるのに、つい最近Amazonを使い始めた軟弱者です。 それにしてもAmazon危険です。スマートフォンにAmazonの Androidアプリを入れたのですが、これがまた、レコメンドに面白そうな本が出てきて危険です。\n話がそれてしまいましたが、面白い本でした。 久々に、小説でも技術書でもない本を短期間で読みました。 「箱」と呼ばれる概念の中と外について、とある会社に転職した管理職の人が学んでいくという物語風の作りです。 いくつか、自分の経験にカブるシーンがあったので、サクサク読めました。 今までの自分になかった考えである「箱」という視点が得られたのがよかったです。\nただ、いくつか気になる点もあるので、また少し時間を開けてからサラっと流し読みしたいと思います。\nあと、すこしだけ、キリスト教チックな考え方でもあるかなぁと思う部分もありました。(キリスト教をちゃんと勉強してるわけではないので認識が間違ってるかもしれないです)\n人によっては共感出来なかったり、読みにくかったりすると思いますが、私は面白いと思った本でした。 なんとなく、人間関係に違和感を感じていることがある場合は目を通してみるといいかもしれません。\nTwitterで読み終えたというツイートをしたら、「自分を変える気づきの瞑想法」を読むとまた面白いですという@ツイート(これがmentionの日本語の正式名称らしい?)を@ledsunいただきました。 箱に入る原理が別の視点で書かれているようです。 読んでみたいです。(本会過ぎてる気がするので、図書館で探そうかなぁ。。。)\n自分を変える気づきの瞑想法【増補改訂版】 自分を変える気づきの瞑想法【増補改訂版】 ","date":1332253920,"dir":"post/2012/","id":"ee623aaa99b429863f89da313fffed97","lang":"ja","lastmod":1332253920,"permalink":"https://blog.johtani.info/blog/2012/03/20/%E8%87%AA%E5%88%86%E3%81%AE%E5%B0%8F%E3%81%95%E3%81%AA%E7%AE%B1%E3%81%8B%E3%82%89%E8%84%B1%E5%87%BA%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%E3%82%92%E8%AA%AD%E3%81%BF%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-03-20T23:32:00+09:00","summary":"TLで面白いと見かけて、Amazonで買ってしまいました。 SEやってるのに、つい最近Amazonを使い始めた軟弱者です。 それにしてもAmaz","tags":["読書"],"title":"「自分の小さな「箱」から脱出する方法」を読みました。(Jugemより移植)"},{"contents":"えーと、ブログ更新してないなぁとふと思ったので。 1年前くらいからずーっと、つぶやいてましたが、やっとScalaを始めました。 長かった。。。 とある、サンプルデータを作成するので、ついでにScalaを勉強してしまえという感じで始めました。\nScalaで学ぶ関数脳入門を買ってもう1年以上経ってました。。。 とりあえず、CSVデータからInsert文を作ってます。 書籍を見ながら、四苦八苦してるところです。 今日は、csvファイルを読み込んで適当に出力した所で終了でした。 現状を忘れないようにというのと、いくつか気になった点があったので、備忘録のため上げておきます。\nscala IDE for Eclipseを利用(もっさりしてる) classとは別にobjectというものがある点に慣れない セミコロンいらないのに、ついつい打ってしまう usingを利用しようとしたが、Eclipseに怒られた(なんで?) メソッドの戻り値を省略出来る場合とできない場合がよくわかってない Javaが混ざる(ファイル出力にBufferedWriterを使う)のがまた戸惑う ということで、四苦八苦してますw 7つの言語、7つの世界も参考にしつつ、コップ本をパラパラしながら、ググって書くといった感じです。 Javaだととっくにできていると思うのですが、まだ、読み込んで出力できただけです。\n新しいものに触れるのは頭を使って面白いのですが、思い通りに行かず(とくにIDEがもっさりしてたり、上手く使えなかったり)イライラもしていますw まぁ、ちょっとずつ勉強していきます。\n(ほかにもいろいろやらないとなぁ。。。)\nScalaスケーラブルプログラミング第2版 Scalaスケーラブルプログラミング第2版 ","date":1331652421,"dir":"post/2012/","id":"116c9be6d760b4befa6d51ce9e96604c","lang":"ja","lastmod":1331652421,"permalink":"https://blog.johtani.info/blog/2012/03/14/scala%E5%A7%8B%E3%82%81%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-03-14T00:27:01+09:00","summary":"えーと、ブログ更新してないなぁとふと思ったので。 1年前くらいからずーっと、つぶやいてましたが、やっとScalaを始めました。 長かった。。。 と","tags":["Scala"],"title":"Scala始めました(Jugemより移植)"},{"contents":"森ビルに行ったことなかったので、参加してみました。 あと、最近まともにコーディングしてないので、そのへんを矯正するためにもと思って。 (まぁ、遊びに行きたかっただけなんですけどね)\nすこし遅刻して参加です。 会場は、Twitter Japanさんの@yakitoriでした。ここだけ、撮影可でした。 で、肝心のハッカソンの中身です(ハッカソン自体、初参加!)。 Twitter APIもTwitter4Jも触ったことがありません。 なので、ソファーに座ってMac Book AirでTwitter4Jのサンプルを眺めながら、とりあえず、Solrに流しこむってのを作ってみました。 今回、Solrに用意したのはlucene-gosenによる形態素解析を行うフィールドとあとは、Solrのexampleについてるダイナミックフィールドたちです。 Twitter4Jからどんなデータが取れるかわからないので、ダイナミックフィールドで型だけ指定してSolrを起動しておきます。 次に、Twitter4Jにあるsample()にてパブリックなツイートの1%を取得(適当なのがこれくらいしか思い浮かばなかったから)。 あとは、SolrJのStreamingUpdateSolrServerを利用して、流し込みです。 あんまり時間がなかった(準備とかウォーミングアップで時間かかった)ので、結局、Screan名とツイート本文を SolrInputDocumentに無理やり詰め込んで登録しただけでした。 ほかにも色々と情報が取れるはずなので、そのへんも格納してファセットとかで遊びたかったなぁ。 とまぁ、こんな感じでタイムアップです。(コードは大したことないので文章だけでw) 画面も用意出来なかったので、発表はSolrのダサい管理画面で検索でした。 次回は、もう少し中身を勉強して画面もbootstrapで作ってとかやってみたいですね。 あと、自己紹介スライドに書きましたが、Scalaから使ってみるのもやってみたいです。(その前に、Scalaに入門しないといけないんですけど。。。)\nということで、個人的にいろいろと反省点があるハッカソンでした。 反省点:\n立ち上がりに時間がかかった(普段からコーディングしてないから) Twitter4Jについて事前に勉強してない(ごめんなさい) 環境面が整備しきれてない Twitter API ポケットリファレンス(右の本)を忘れた。。。 スターウォーズのピザの箱の写真取り忘れた>< 普段、コーディングをしていない仇が出てしまいました。 もっと、すぐにコーディングをできる環境、体質を日頃から鍛えておかないといけないなぁと。 (SolrやTwitter4JのJavaDocをオロオロしながら探すとか情けないです。。。)\n場所や雰囲気は全然問題ありませんでした。 ピザを@yusukeyさんからごちそうになったり、飲み物、お菓子が用意されていたりと至れり尽くせりでした。 iPadで音楽も流してくれてたし。 他のハッカソンに参加したことないので比較はできないですが、集中できてよかったです。 あと、ソファーでコーディングもなかなかいいなぁと実感出来ました。(初めて!) 人数的にもこのくらいのほうが話がしやすくていいかなぁと。発表も時間かからないですし。 ただ、帰り道に誰かが言っていましたが、「マラソンというよりは短距離走だったね」というのは否めないかなぁと。 時間は限られちゃうので、準備をしっかりしないとなぁと。 私としては、土日のハッカソンだと参加しづらいので、平日開催がうれしいのですが。 いやぁ、楽しかったです。みなさんの面白いネタも見れたし。(自分のやったのは普通すぎて少し恥ずかしかったです。。。) あと、GoogleDocsの使い方(自己紹介スライドとかアンケートの集計とか)も学べたのが収穫でした。 @yusukeyありがとうございます! 次回もありそうなので、懲りずに参加しようかな。\nさて、他の方たちのブログやtogetterは@yusukeyさんのページからたどってくださいw。 第0回Twitterハッカソンを開催しました #twtr_hack\n今日購入したCD聴きながらブログ書いてます。 タワレコで視聴して購入したCDです。 なかなか大人な雰囲気でオススメです。 Heaven ","date":1331230200,"dir":"post/2012/","id":"4d6c95b0b3ea2ddb30fdd3edf3b82391","lang":"ja","lastmod":1331230200,"permalink":"https://blog.johtani.info/blog/2012/03/09/%E7%AC%AC0%E5%9B%9E-twitter-hack--twtr_hack-%E3%81%AB%E9%81%8A%E3%81%B3%E3%81%AB%E8%A1%8C%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-03-09T03:10:00+09:00","summary":"森ビルに行ったことなかったので、参加してみました。 あと、最近まともにコーディングしてないので、そのへんを矯正するためにもと思って。 (まぁ、遊","tags":["勉強会"],"title":"第0回 Twitter Hack #twtr_hack に遊びに行きました。(Jugemより移植)"},{"contents":" Clean Coder プロフェッショナルプログラマへの道 Clean Coderを読みました。 理由はTwitterで「Clean Code」がいい本だと流れてきたためです。 「Clean Code」はまだ読んでいないのですが、クリーンなコード(メンテナンスしやすく、修正などもやりやすいコード?)を書くために必要な話が書いてあるのだと思います。(まだ妄想)\nそして、何も考えずに、「Clean Code”r”」という本が新しく出ていたので、新しい方に手を出しました。 まぁ、軽い勘違いですw(コードの構造の話などは出てこなかったです。) それほど分厚くなく、軽く読めそうだということで読み進めると軽い衝撃を受けました。 Clean Coderはプロのプログラマとして、どのような意識を持つべきか、立ち居振る舞いをするべきかなどが書かれています。 「~したい」はまず守らない約束だという話、ユニットテストを書くことはプロとして当たり前の行為だ、目的意識を明確に持つことなどなど、耳の痛いことが色々と書かれています。 これは、著者の方(パンチカードのころからコーディングをされている!)の実体験を元に、失敗した経験から導きだされているようです。 ところどころ、古くてよくわからない話やちょっとだけしっくりこない表現(ビジネス、QAといった単語)もありましたが、概ねわかりやすい話でした。\n基本的にはアジャイルなスタイルの開発を行うプログラマ(設計書に基づいてコーディングするだけの人ではない)について書かれています。 この本を読んでいて、昨年、仕事をご一緒させていただいたRubyistの方たちの開発スタイルを思い出しました。 私よりもこの本に書かれているプロに近いなぁと。 ペアプロやったり、実装方法について相談していたりと。\n勘違いでしたが、良い本に出会えて本当によかったです。 私もこの本に書かれているようなチームでのプログラミングをやりたい、またなにかコーディングをしたいという気にさせてくれました。(「~したい」じゃダメって書いてあったのに。。。) 自分を戒めるためにも、定期的に読み返したい本です。 プログラマでいたい方、ある程度プログラミングができるようになってきた方にはぜひ読んでいただきたい本です。 (この流れで、アジャイルサムライやClean Codeを読んだら理解が深まりそうだなぁ)\n参考URL: 35歳定年説をブチ破れ!「Clean Coder プロフェッショナルプログラマへの道 Robert C. Martin」 - ledsunの日記 ","date":1330704840,"dir":"post/2012/","id":"10eb415a232ad4be7d05c57eb850036c","lang":"ja","lastmod":1330704840,"permalink":"https://blog.johtani.info/blog/2012/03/03/clean-coder%E3%82%92%E8%AA%AD%E3%82%93%E3%81%A0/","publishdate":"2012-03-03T01:14:00+09:00","summary":"Clean Coder プロフェッショナルプログラマへの道 Clean Coderを読みました。 理由はTwitterで「Clean Code」がいい本だと流れてきたためです。","tags":["読書"],"title":"Clean Coderを読んだ(Jugemより移植)"},{"contents":" 親子で楽しめる 絵本で英語をはじめる本 Twitterでこの本について書かれたブログ記事が流れてきて、購入しました。\n最近、英語を身につけておいたほうがいいなと思うことが多々あり、子供にも英語を勉強してもらいたいなと思っていたところでした。 あとは、私自身が英語が苦手というのもあり、子供をダシにして勉強したいというのもありまして。。。 サラっと読んでみましたが、参考になりました。 特に「多読」というキーワードが面白かったです。こちらが元のようですが。 多読とは、文章を分析しないで大意を把握する読書法だそうです。\n辞書を引かずに楽しめるものを読む わかるところをつなげて読む 自分が面白いと思う本を選んで読む という原則があるようで、確かにいいなと思いました。 絵本だと絵が書かれているので、辞書を引かなくても想像できそうですし、楽しめそうだなぁと。 また、多読は先日読んだ、速読の本に書かれていた本の読み方にも通じるものがあるなと。(まだ、実践できてないんですけどね)\nどうしても英語を勉強させたい!、勉強しないと!と思ってしまいがちですが、この本にも書いてあるように楽に楽しんでやったほうがやっぱいいなぁと。 楽しくないと続かないですからねぇ(実際、何度も挫折してるし、押し付けられるとヤル気がなくなるので。。。)\nということで、実践してみようと思います。(平日は子供が寝てしまってから帰宅なので、まずは土日から)子供のためというよりは、自分の英語の勉強のために。 まずは、簡単な絵本を購入して。 この本の後半半分は、著者の方の感想や説明がついた、オススメの絵本50冊が書かれています。 英語の絵本を入手するのは、結構大変(実際に売ってる店もなかなかないし、手にとって見る機会も少ない)だと思うのですごく参考になりそうです。 いくつかピックアップして、あわよくば本屋で手にとってみようかと。なければ、Amazonで購入しようかなぁと思ってる所です。\n","date":1330186800,"dir":"post/2012/","id":"627a0c45dd07150343c81d856855590e","lang":"ja","lastmod":1330186800,"permalink":"https://blog.johtani.info/blog/2012/02/26/%E8%A6%AA%E5%AD%90%E3%81%A7%E6%A5%BD%E3%81%97%E3%82%81%E3%82%8B-%E7%B5%B5%E6%9C%AC%E3%81%A7%E8%8B%B1%E8%AA%9E%E3%82%92%E3%81%AF%E3%81%98%E3%82%81%E3%82%8B%E6%9C%AC/","publishdate":"2012-02-26T01:20:00+09:00","summary":"親子で楽しめる 絵本で英語をはじめる本 Twitterでこの本について書かれたブログ記事が流れてきて、購入しました。 最近、英語を身につけておいた","tags":["読書"],"title":"親子で楽しめる 絵本で英語をはじめる本(Jugemより移植)"},{"contents":"今週も勉強会に参加しました。 @yusukey さんが開催してるTwitter API勉強会です。 前回とは会場が異なりましたが、広くて大画面で良い会場でした。駅も近いし。(デジタルハリウッドさいこー!) 今回はLT枠のbootstrapの話が聞きたくて参加しました。(ムチャぶり駆動勉強会の現場をTLで目撃してたのでw) あと、バーチャファイター(昔、VF目当てでセガサターンを買ったなぁ、懐かしい)の話も聞きたかったので。 (ごめんなさい、Twitter APIはまだ触る機会がなさそうです。。。) 今回も途中で参加者同士を数グループ(座席が近い人)に分けて自己紹介タイムがあり素敵でした。 ちょっと残念だったのはネームプレートが今回はなかったことでしょうか。 自己紹介でツイッターID教える+聞くのがちょっと辛かったです。(やっぱり個人名刺作ったほうがいいかなぁ) 私はPCを開いていたのでTwitterのページを見せることで対応出来ましたが。 (次やるときはお手伝いするのでこえかけてください。)\n内容はメモをとってあり、下に書いてますので見ていただければ。\nTwitter APIの説明はいろいろ新鮮でした。今回はWebページに貼るリンクやボタンの話でした。 カスタマイズも出来るようになってるってのは知りませんでした。Webサイトやってる人は簡単にカスタマイズできるのは便利ですよね。\nバーチャファイターのTwitter連携の話は結構詳細な話が出てきてびっくりでした。(テーブル名とかまで出てきましたw) ゲーム筐体の前のユーザの動きまで考えてシステム作るとかすごいなぁとか。違う業界の話って面白いです。\nBootstrap入門はbootstrapの紹介だけじゃなく、Tips(bootstrap弊害とかw)やその他の便利なサイトの紹介までありました。 スライドもあとから読んでもわかるのがすごく嬉しいです。時間を見て試してみます。 TwitterSphereは懇親会でもデモが見れました。Groovyは名前を知ってるだけだったのですが、Swingとかまで動くんですね。(JVMだから当たり前なんだけどなんか新鮮。) 最後はAndroidのAPI Demoのお話。こちらも普段Android携帯使ってるのに知らないことが多くて。。。 Macでもデモが動くんですね。やっぱり動くものを作ってLTするのって素晴らしいですねぇ(なんか作るかー)\nとまぁ、最近はキーワードだけ知ってて、いろいろ触れてもいないものが多いなぁと思ってたところに、 今日の勉強会で色々見れて面白かったです。 Twitterがいろんな人に興味を持たれているのがわかります。 (けど、Twitterってどうやって儲かってるんだろう???) 懇親会は、入り口からは想像できない貸パーティースペースで素敵でした。 開始の乾杯の音頭を取ることもできましたし(もちろん、ムチャぶり)。 学生が多かったのですが、声をかける暇なく懇親会が終わってしまったのが少し心残りですかねぇ。 毛色が違うメンバーが居て面白いので、次回も空きがあれば参加しようと思います。 スタッフとかお手伝いもしますので。\nということで、いつものメモです。\n開催日時:2012/02/23 19:00 ~ 21:00 場所:デジタルハリウッド東京本校 1Fセミナールーム Zusaarのページはこちら。他にも学生枠とかありました。\n◯ Webサイト向けAPI @yusukey\n・Webサイト向けAPI フォローボタン、ツイートボタン、Web Intents、@Anywhere サーバサイドの実装扶養、htmlのみで構成可能 ・Twitterボタン Twitterのサイトで色々カスタマイズ可能なボタンが作れます。 ツイートのカウント表示とか。 ・Web Intents @ツイート、リツイート、お気に入りが簡単にできるものが作成可能。 ツイートの埋め込み用リンクがTwitterのWeb版のツイート詳細から生成可能。 「このツイートをサイトに埋め込む」リンクをクリックするとダイアログが出てきます。 ・@Anywhere あんまりフォローされてないけど、JavaScriptでサーバサイドなしにTwitterと連携可能。 ユーザIDを辞書的に検知してTwitterの情報をホバーで出してくれる。 ・ウィジェット(検索、プロフィール、お気に入り、リストなど) これもTwitterサイトでカスタマイズ可能。 ・ツイートボタンには公式ロゴを利用しましょう ・注意点 charsetを必ず指定しましょう。 IE/Firefoxで問題が発生します。 ◯ グルーブに分かれて簡単に自己紹介\n◯ デジタルハリウッドよりご挨拶\n◯ 「Virtua Fighter5 Final ShowdownのTwitter連動機能について」@twtrfk\n部内にAmitterというSNSを構築して自由に使ってもらって、Twitterを疑似体験してもらった。 VF5FSでの開発中はTwitter4JにAmitterのラッパーを追加してテストしてたらしい。(おもしろいなー) 当時は、筐体にツイート機能を入れることも考えていたらしい。 ツイート自体はバッチで処理してます。 ゲーム筐体にお客さんが座ってる時間もシステムの性能として考慮しないといけない。 苦労した点: テストアカウントを100個地道に作成(連番、内容がバレるアカウント名はNGだから) Twitter4Jがうまく動かなかった。。。 今後の展開: まだ未定 QA Q:FB連携とかは? A:今は考えてないです。 ◯ LT ・ @making「Twitter Bootstrap入門」 スライドはこちら\n・Bootstrapとは? Twtter者が提供するWebアプリケーションのフロントエンド 一般的にCSSフレームワークと呼ばれるもの 簡単にかっこいいデザインにするための枠組み ダウンロードしてきてHTMLで読み込むだけ。 ・Bootstrapのコンポーネント紹介 いろいろおしゃれなコンポーネントあるよ。(スライド見ましょう) ・Tips examplesがあるので、それをベースに作るのが簡単です! Initializrも対応してて、こっちで作るのもいいよ! bootstrap簡単すぎて、みんな同じデザインのサイトに(弊害) 差別化のサービスが出てきてます。 ・ @kimukou_26 「TwitterSphere of Twitter4J」\nGriffon? codehausで作られてるGroovy製のMVCイメージのGUIフレームワーク codehausはJetty作ってるとこですね 地球儀にツイートを乗っけることができるアプリ。 Groovyの記述がちょっと新鮮。 ・ @bina1204 「ApiDemos of Twitter4J for Android」\nAPI DemosというAndroidのデモがあり、ここにTwitter4Jを仕込んでみた? Android系は持ってるのに知らない。。。 ","date":1330015800,"dir":"post/2012/","id":"966fe8d32b86121f8a465a21b95f7e5c","lang":"ja","lastmod":1330015800,"permalink":"https://blog.johtani.info/blog/2012/02/24/%E7%AC%AC4%E5%9B%9E-twitter-api%E5%8B%89%E5%BC%B7%E4%BC%9A--%E3%83%87%E3%82%B8%E3%82%BF%E3%83%AB%E3%83%8F%E3%83%AA%E3%82%A6%E3%83%83%E3%83%89--twtr_hack-%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-02-24T01:50:00+09:00","summary":"今週も勉強会に参加しました。 @yusukey さんが開催してるTwitter API勉強会です。 前回とは会場が異なりましたが、広くて大画面で良い会場でした。駅","tags":["勉強会"],"title":"第4回 Twitter API勉強会 @デジタルハリウッド #twtr_hack に参加しました。(Jugemより移植)"},{"contents":"久々にlucene-gosenの話です。 しかも、あんまり嬉しくない話しです。\nすでにissueをアップしていますが、lucene-gosenとSynonymFilterを併用する場合に、特定の条件下でNullPointerExceptionが発生してしまいます。\n条件は以下の組み合わせになります。\nSolr 3.5.0以前 lucene-gosen1.2.0 - 1.2.1の辞書なしjar SynonymFilterFactoryにてtokenizerFactoryを指定 根本的にはSolr側の問題のようです。SOLR-2909としてissueが上がっています。\nSynonymFilterFactoryでは、類義語の設定ファイルの単語を読み込むときにtokenizerFactoryを指定できます。 このとき、SynonymFilterFactory内部でtokenizerFactoryに指定されたFactoryのクラスが読み込まれ、 インスタンス化されて、Tokenizerが作成されます。 この、Tokenizerのインスタンス化の処理シーケンスに問題があります。 schema.xmlの\u0026lt;tokenizer\u0026gt;タグで指定されたTokenizerFactoryでは、ResourceLoaderAwareインタフェースのinform(ResourceLoader loader)メソッドが実行されます。 このinform()メソッドがSynonymFilterFactoryのToeknizerのインスタンス化の場合に実行されません。 lucene-gosenのJapaneseTokenizerFactoryではこのinform()メソッドでdictionaryDirのパスの読み込みを行なっています。(このへん)\n上記の条件では、NullPointerExceptionが発生すると書きました。 辞書を内包したjarファイルを利用している場合、NullPointerExceptionが発生しなくても次のような問題点があります。こちらの問題は見た目は動いているように見えてしまうので注意が必要です。 すべて、SynonymFilterを利用する時点でも問題点になります。\ncompositePOS設定が類義語辞書読み込み時に無効 dictionaryDir設定が類義語辞書読み込み時に無効(=jarに内包されている辞書で動作する) 一見動いているように見えるかもしれませんが、望んでいてる動作になっていない可能性があるので注意が必要です。\n解決策(まだ途中) 先程書きましたが、基本的にはSolr側の修正をするのが妥当です。 SolrのJIRAにパッチもアップされました。 こちらのパッチをSolrに適用し、SynonymFilterFactoryを次のように指定することで問題を回避することが可能になります。\n\u0026lt;tokenizer class=\u0026#34;solr.JapaneseTokenizerFactory\u0026#34; compositePOS=\u0026#34;compositePOS.txt\u0026#34; dictionaryDir=\u0026#34;dictionary/naist-chasen\u0026#34;/\u0026amp;gt; ... \u0026lt;filter class=\u0026#34;solr.SynonymFilterFactory\u0026#34; synonyms=\u0026#34;synonyms.txt\u0026#34; ignoreCase=\u0026#34;true\u0026#34; expand=\u0026#34;true\u0026#34; tokenizerFactory=\u0026#34;solr.JapaneseTokenizerFactory\u0026#34; **compositePOS=\u0026#34;compositePOS.txt\u0026#34; dictionaryDir=\u0026#34;dictionary/naist-chasen\u0026#34;**/\u0026amp;gt; ... SynonymFilterFactoryの設定にcompositePOS、dictionaryDirを追加します。 ここの設定は\u0026lt;tokenizer\u0026gt;タグで指定された設定と同じ物を指定します。以上で問題なく動作することになります。\nただし、この方法はSolrにパッチを当てなければいけません。 Solrにパッチを当てるのもなかなかな作業だと思います。 ということで、どうにかlucene-gosen側だけでも対応出来る形にしたいなぁと考えているところです。 残念ながら、まだ考えているだけですので、もう少し提供できるのは先になってしまいますが。。。 現時点では、次の方法を考え中です。\ninformメソッドを呼ぶフラグを追加して、どうにかしてinformメソッドを呼び出す SynonymFilterの修正版をlucene-gosenに内包して提供する できれば、a.にて対応できればと思っています。 最悪、b.の方法かと。 悩んでいる間にSolrの次のバージョンが出てしまわないように出来るだけ早く対応しようと思っています。 他にも問題点や気になる点があれば、日本語、英語を問わないので、気兼ねなくissueに上げてもらうか、Twitterで私宛にメンションしてもらえればと。 (あ、issue23へのパッチでもいいですよ!)\n追記: まだ、SOLR-2909のパッチを適用してからの確認はできていません。(ソース見て大丈夫だと思ってるレベル) あと、現時点での対応方法としては、「lucene-gosenとは別のjarにSynonymFilterFactoryなどを入れて提供」が妥当かなぁと考えているところです。(無理やりinformメソッド呼び出すのは骨が折れそう+パッチが思いの外早く出て、導入されたのでlucene-gosen本体に特殊処理を入れるのはあまりメリットを感じない。)\n","date":1329756060,"dir":"post/2012/","id":"4e7b945feca199bd486653fea1d0e39c","lang":"ja","lastmod":1329756060,"permalink":"https://blog.johtani.info/blog/2012/02/21/lucene-gosen%E3%81%A8synonymfilter%E3%82%92%E5%88%A9%E7%94%A8%E3%81%99%E3%82%8B%E3%81%A8%E3%81%8D%E3%81%AE%E6%B3%A8%E6%84%8F%E7%82%B9%E5%95%8F%E9%A1%8C%E7%82%B9%E7%B7%A8/","publishdate":"2012-02-21T01:41:00+09:00","summary":"久々にlucene-gosenの話です。 しかも、あんまり嬉しくない話しです。 すでにissueをアップしていますが、lucene-gosenと","tags":["lucene-gosen"],"title":"lucene-gosenとSynonymFilterを利用するときの注意点(問題点編)(Jugemより移植)"},{"contents":"また、勉強会ログです、すみません。。。 直接業務とは関係ないのですが、今回はリクルートの中野さんが話しをされるというので顔を出してきました。 もちろん、内容も気になりましたというのもありますが。 実際には中野さんは2分くらいしか喋らなかったんですけどね。。。\n今回は、最初のセッションはちゃんとしたソースコードリーディングでした。 Hadoopの入力としてデータをHDFSじゃなくて、MongoDBから取得するときに利用するMultipleInputの実装をしてみたというお話でした。 MongoDBやHadoopを知らないと(私はあんまり知らない。。。)少しきつかったかもしれないです。 幸い、HadoopのMultipleInputについては以前、すこしだけ見たことがあったので、かろうじてついていけました。 最初の部分を聞きのがしてしまったので合っているか自信がないのですが、10genから出ているmongo-hadoopの使い勝手、効率の悪そうなところに手を入れた話しがベースになっているんでしょうか?(ツッコミあるとうれしいです) 気になったのは、MongoDBのデータをHadoopから直接取りに行くというユースケースがどういう場合に出てくるのかという点です。 ネットワークやMongoDBの負荷がHadoop処理へのボトルネックになるんじゃないかしらという懸念がありそうだなと。 発表を聞いていて感じたのは、やっぱりソース書いて動かさないとダメだよねぇ、自分も手を動かそうというところです。 リクルートさんの発表は波乱万丈(?)でした。 最後まで話しを聴いたあとに思った感想は「こんなに話して大丈夫なのかな?」「いろんな人を敵に回してない?」というものです。 実際に昨年の夏くらいからEMCの草薙さんも検証メンバーに入って、リクルート社内での活用シーンをベースにMapRの検証をいろんな項目でやられたようです。(ある程度の詳細は以下のメモ参照) で、最終的な結論はまだ出ていないのですが、最後に出てきた検討中の比較対象が某C社のCDH。 どちらかというとCDHの方に傾いてる感じに取れる終わり方で心配になりました。。。 会場が会場だからというのもあったのかなぁ? mesosというキーワードが出てきたのが気になりました。単語だけは以前Twitterで流れてきたのを目にしてたのですが、どんなものかという概要がわかったのは収穫でした。 リクルートさんの資料はどこまで公開されるかわからないですが、もう一度見たい気がします。(mesosの部分だけでも公開して欲しい)\nということで、以下はいつもの自分用メモです。\n日時: 2012年2月8日(水) 19:00~21:30 (受付開始 18:40) 場所: 豊洲センタービルアネックス(NTTデータ、豊洲駅直通)\n◎日本OSS貢献者賞・奨励賞のご案内 @hamaken 日本OSS貢献者賞・奨励賞\n◎『オレオレMultipleInputを作る方法(仮)』@muddydixon さん http://www.slideshare.net/muddydixon/multipleinput\nhadoopからMongoDBを利用する方法を紹介 CDH3u2かu3で試しました。 10genからも出てるけど使いにくい?から作った? MongoMultipleInputs.addInputPath で色々簡単に使えるようにしたかった。 絞り込みしてデータをMapperにとり込みたかったため。 =絞り込みできないと必要なデータ以外も取得できてしまいJSONのパース処理がオーバヘッドになるから。 com.mongodb.hadoop.input.DelegatingInputFormat mongodbの環境にあわせて多くのsplitを生成する。 mongosへのアクセスはメタ情報の取り出しだけ。 あとは、個々のサーバにアクセスしてるのでデータ取り出しが高速? ◎『MapRってどうよ? - 実際に使ってみた感触を紹介します』 - リクルート 中野さん、高林さん、大坪さん\nMapRの説明資料がなかったので、EMCの草薙さんが出てきて説明を開始。 Greenplum MRはMapRテクノロジが開発した実装のOEM版。 EMCは特に手を加えず。 ※MapRについては前回のMapR勉強会の記事を御覧くださいな。 Q:JavaのAPI互換と言われている部分はHadoopのどのバージョン? A:CDH3u2に近いパッチが当たってるらしい。 Q:DFSIO性能の比較対象のHadoopはどのバージョン? A:手元に資料は残念ながらないです。 ここからリクルートさん。 検証内容:性能検証 中古車サイトで利用されている3つのHiveに置き換えてみた。 結果(パーティション圧縮) MapRのほうが約1.3倍高速に(そこまで速くならなかった?) 結果(非パーティション圧縮) MapRのほうが約1.7倍高速に(そこまで速くならなかった?) ビルドイン圧縮はGzip圧縮と比較して高速 ※チューニング次第では結果変わるかもね。 機能検証:マルチテナント検証 目的: 複数ユーザに対して1つのクラスタを提供する セキュリティの担保() 余剰リソースの有効活用 複数ユーザのJobの並列実行? 結果1(ユーザ権限まわり) MapRのユーザはLinuxユーザに準拠。 同じmaprユーザでもUIDがずれてるとエラーが起きる。 MapR内のPermissionは内部のクラスタ、ボリュームの権限定義が可能 ※Volumeは管理者に付加的な情報を与えるような存在 Job実行はHadoopと一緒のアクセス権。 結果2(FairScheduler) MapRではデフォルトとなっている。 複数テナントからの同時ジョブ実行の動作を確認。 poolをベースにタスクを割り当ててく。 min/max値にあわせてslotが利用される模様 結果3(Load処理(Hive)、Job実行(HiveのSelect)) じゃらんPVデータ1ヶ月分をロード。 NFS→MFS 結果4(フェイルオーバー) HA機能 ノード切り替え時間、タスクの復旧までの時間とか。 結果5(DirectNFSでの転送) NFSGatewayをクライアント側にした場合との違いなど。 クライアント側に載せた場合、通信量が減るから速度が出てる。 Mesos概要 Apache IncubatorのOSS。C++により実装 効率的なリソース分離、リソース共有機能を提供するクラスタマネージャ。 Mesosでの検証 マルチテナント(ユーザ権限)硬い。 リソース制限ができない。などなど。 MapRとMesosの比較 資料期待! リクルートとしてのMapRの評価 保守/サポート/教育が充実してるのが重要。速度だけじゃない。 けど、まだ検討中です。 Q:クラスタに対するパーミッションの権限情報はどこで管理されてるの? どこが落ちたときにそのパーミッションの情報がとれなくなる? A:CLDBで管理されてます。 Q:CLDB内部でのデータはバイナリ?DBを別途持ってる? A:HDFS上にボリュームが作られてそこに吐き出されてる。 Q:Jobのスケジュールの情報とかはどこに? A:Job管理データはJobTracker用のボリュームに保存されてる。 それを別の人が引き継ぐ。 Q:ボリュームが壊れたら? A:さすがに壊れたら引き継げない。 けど、壊れにくくしてあるのが売り? Q:MapRのチューニングのポイントはどんなものがあるの? A:チューニングに関しては256Mのchunkサイズを64Mに減らした場合の化粧しかしてない。Apache Hadoopの方は若干チューニングした。 Q:DFSのシリアライズは?ボンディングとかでもできるんじゃないの? A:そこはやってないのでやってみます。 Q:MapRでの8台構成で全部のせてみた場合、CLDBのリソースはどのくらいもっていってるの? A:結構使ってる。CLDBを3台以上にしたらサポート対象外。 Q:CLDBを3台に制限してる理由は? A:わからない。 Q:本番MapR、検証CDHというのはあり? A:M3を開発環境で利用して欲しいですね。(ステマ?)開発目的だとM5を無償提供してほしいなー(EMCへのお願い?) Q:Pigの検証は? A:リクルートではHiveを利用してたので検証してない。 次回は3月ころかなぁ?だそうです。 ","date":1328716980,"dir":"post/2012/","id":"fa16213d24273d386d22332cd01ce774","lang":"ja","lastmod":1328716980,"permalink":"https://blog.johtani.info/blog/2012/02/09/hadoop%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89%E3%83%AA%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0%E7%AC%AC8%E5%9B%9E%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-hadoopreading/","publishdate":"2012-02-09T01:03:00+09:00","summary":"また、勉強会ログです、すみません。。。 直接業務とは関係ないのですが、今回はリクルートの中野さんが話しをされるというので顔を出してきました。 も","tags":["勉強会"],"title":"Hadoopソースコードリーディング第8回に参加しました。#hadoopreading(Jugemより移植)"},{"contents":"Fluentd meetup in Japanに参加しました。いつも面白そうな話を聞いてばっかりなので、役に立つためにスタッフとしても参加してみました。 まずは、会場が綺麗でびっくりしました。しかも電源タップまで用意されていてかなり充実してました。Ustはまだ見ていないのですが、Ustも録画までされていて素晴らしい運営メンバーでした。\n開発者の古橋さんほか、Treasure Data Inc.の方たち(太田さんはいなかった)が集まり、 Fluentdの仕組みから、プラグイン開発の方法、実際にプラグイン開発してしかも本番で利用してる実例まで 「パーフェクトFluentd」という本ががそのまま書けてしまうのではというくらい密度の濃い話が聞けました。 私個人は、いつものごとく興味を持ってるんだけど、仕事、私用では触っていないという腰抜けなので話についていくのが大変でしたが。。。 各セッションごとに、しっかりとしたQA時間が取られていて、質問者も質が高く、中の人や発表者の方も誠実に回答されている感じがすごく良かったです。 (残念ながらLTの時は懇親会の準備を手伝っていたので聞けてないです) 基本はログの中継サーバとして利用するという話でした。 個人的には性能系のデータやログ(遅いクエリのログに関するプラグインの話などもあった)をストレージに保存して、時間を軸にログとグラフを表示するとかいう仕組みに使うと面白いかもなぁと感じました。 今回はFluentdがメインなので、ログを集める部分の話が主だったところでしたが、懇親会直前の@doryokujinさんのスライドでも上がっていた集計後のビジュアライゼーションに関する部分のはなしも聞いてみたいなぁと思ってるところです。\nあとは、いくつか知りたかったことが。 Treasure Data Serviceというサービスをやってるみたいで、SQLライクな問い合わせやビジュアライゼーションされた画面があるみたいな話があがっていたんですが、画面が見てみたかったです。 また、@just_do_neetさんの構想図のその後を聞いてみたいですねぇ。\nそれにしても実例も構成から性能値まで上がっていたので、実際に利用する場合に参考になる資料だらけで普及にはずみがつきそうです。 Ust録画が上がっているようなので復習したいと思います。 (あ、内容とは関係ないけど、Ust録画にハッシュタグつきのツイートを時間軸で重ねて表示するサービスとか機能ってないのかな?)\nということで、以下はいつものメモ書きです。\n2012/02/04 12:30 ~ 19:00\nフューチャーアーキテクト セミナールーム\n参考URL:http://fluentd.org\n◎13:00~14:00 「What\u0026rsquo;s Fluentd? - The missing log collector」 http://www.slideshare.net/treasure-data/fluentd-meetup-in-japan-11410514 Treasure Data, Inc. 古橋 貞之 (@frsyuki)\nまずは、Fluentdの概要。syslogdみたいなもの Fileのtailで流すことが基本。 Clientライブラリから流すことも可能。 他との比較 ScribeとFluentd 構造化されたデータを扱う gemとかapt-get,yumでインストールあg可能 Rubyで書かれてるからカスタマイズもプラグインの追加も簡単。 FluentdとFlume FlumeはZKやマスタノードが必要=セットアップが面倒 JVMだから面倒、設定も簡単。 Fluentdのアーキテクチャ Bufferプラグイン:スレッドセーフ、バッファ処理など Outputプラグイン:出力だけ out_forwardプラグイン:Cassandraと同じアルゴリズムでHeartBeatしてる out_copyプラグイン:同じ出力を別の出力先にコピー bof_fileプラグイン:バッファ先をファイルにする。Fluentdがこけても大丈夫 out_exec_filterプラグイン:外部プログラムからの入出力を使える in_tailプラグイン:ログのパーサーが内蔵されてるみたい。 開発者用API Unitテストフレームワーク(MRUnitに似てる) TailInput(パーサカスタマイズも簡単) ドキュメントとか http://fluentd.org にあります。 会社紹介! Treasure Data Service Fluentdでは出力先がいろいろできるけど、自分で解析しないといけない !ここで、Treasure Data Service(クラウド)に保存すると。。。 データのVisualizationとかがリアルタイムで出来る。 QA: Q:ログ転送にUDP使ってますか? A:TCPです。UDPはハートビートに利用してます。 Q:文字コードはどういう扱い? A:バイナリ形式であつかってます。 文字列で扱う場合はプラグインで対応しましょう。 Q:性能大丈夫? A:Twitterで議論があがって、いろいろ対応しました。 Q:TreasureDataServiceはクラウド対応だけなの? A:データはクラウド上で管理してるので上げても大丈夫なものだけが現在は対応。暗号化などは行なっている。 Q:TreasureDataServiceはどこで動いてる? A:AWS上(S3にデータ保存) Q:解析プラットフォームを提供している?SQLだけ? A:HiveのSQLで解析可能。Visualizationのツールもある。 Q:コンサルタントもあるの?ログ出力系とか。 A:あとから解析できるように。 Q:in_tailでログローテート(iノードが変わって)も大丈夫? A:大丈夫。動かなかったら連絡ください。 Q:ファイルバッファリングされるデータの順序は保証される? A:キュー形式なので、保証される。けど、S3とかだと出力先が遅いので、 パラレルモードで対応が可能。だけど、パラレルだと順序は保証されない。 Q:実際のシステムが投げるときにFluentd側で認証とかできる? A:認証はないです。推奨は同一アプリサーバでFluentdを起動。 Q:Fluentd間のデータ通信のセキュリティ対応は? A:今はない。プラグインとか作ればOK。 Q:中間層のFluentdを置くのは推奨?なしで直接ストレージ保存も可能? A:柔軟な対応(送信先、バッファリングとか)が可能にできるように中間層を置くほうがいい。直接出すことも可能。 Q:TDAgentでのセットアップが推奨?gemは? A:gemはOSS版でtrunkに近い。TDAgentはテストとかしっかりやってる。 バージョンの対応表はリリースノート見ないとわからない。 Q:Flumeのほうが優れているのは? A:設定ファイルが一元管理ができる。大規模はFlumeのほうがいいかも ただし、includeでHTTPサーバ経由で設定ファイルを取得可能な機能あり。 Q:バッファサイズは指定可能? A:可能。 Q:ストレージがずっと停止している場合にログがあふれるのを防ぎたい場合の対処法は? A:セカンダリという機能がある。(ただし、対応できてないプラグインもある) Q:フェイルオーバーでローカルファイル出力とかはできる? A:out_forwardは対応してる? Q:Fluentdからのbuf_fileに出力してる部分で遅延、書き込み不可が発生したら? A:入力と出力がスレッドで分かれてる。 入力スレッドでのエラーはinput_plugin側にException上がる ◎14:15~15:00 「Dive into Fluent Plugin」 http://www.slideshare.net/repeatedly/fluentd-meetup-dive-into-fluent-plugin Preferred Infrastructure, Inc. Masahiro Nakagawa (@repeatedly)\n好きなプラグインとか言いましょう(発表者さん) MongoDBのプラグインをベースにプラグイン開発の説明 http://bit.ly/fluentd-with-mongo プラグイン名はfluent-plugin-xxxで統一されてます。 fluent-plugin-mongoがダウンロード数が1位に! (scribeのプラグインがデイリーでテストが走ってダウンロード数が増えるという卑怯なカウント稼ぎしてたらしいw) fluentd.confの説明 fluentdの起動は以下のとおり。開発中は-vつけるといいよ fluentd -c fluentd.conf プラグインをどう作る? Fluentdの構成図による説明 Cool.io、MessagePack、Rubyなど。 それぞれの説明を簡単に。 Cool.ioがファイル監視とかをやってくれるみたい。 プラグイン開発に関する詳細な説明 テスト、gem構成などを書いてくれてる。 QA: Q:複数行のログを扱うのはどこを作ればいい?tailプラグインの正規表現だとうまく行かなかった。 A:tailをoverrideしてparserLineを実装する。複数行のparserは難しいけどね Q:ログのアグリゲーションをやってみたいのだが、どう?CPU利用率とかを1分間バッファしてからアグリゲーションして平均出すとか。 A;fluent-plugin-aggregateってのがあって、forward-pluginを書き換えて作ってる。 TimeSlicedOutputでやると時間の期間指定とかが可能。 管理画面つくろうと思ってるので手伝ってください!@repeatedly Q:fluentd自体が処理した統計データの出力とかある? A:古橋さんが頑張ります!協力して!=\u0026gt;@tagomoris先生が書いてる! ◎15:15~16:00 「fluent を使った大規模ウェブサービスのロギング」 http://www.slideshare.net/hotchpotch/20120204fluent-logging COOKPAD, Inc. 舘野 祐一 (id:secondlife, @hotchpotch)\nCOOKPADでの基盤全般を見てる部署の人 PVログ+MySQL 1日分はオンメモリにのるから高速。けど、1週間前とかになると遅くなる blackholeエンジン(MySQLの一部?)だと速い(ときどきおそくなる) データ保存でも問題 直近データしか保存できない。大きすぎて。 今後スケールしないときつくなる(1日分もメモリに載らなくなる可能性も出てくる) 他のログはMySQLへJSONでシリアライズして出力とかもしてた。 アプリでDBにログ出力はinsertのコストが厳しい。PVとかなら、1リクエスト=1insertだけど、1リクエストで多数ログ出力とかが厳しい。 そこにFluentd登場!!! 出力先が色々使える。(MySQL以外もOK) パフォーマンス バッファリング+転送をやってくれるし、非同期で処理可能なのでレスポンスタイムへの影響が最小限にできてる。 安定性 プラグインはちょっと注意が必要。 バッファリングしてくれてるので、一時的に停止もできるのがうれしい。 6時間止めてもOKだったよ(テヘッw) 今後 PV系のログをMySQLから移行検討中 具体例!! td-agentをrpmで入れてるし、Rubyまで入ってくれる。 構成管理はpuppetを利用してる。 td-agentの設定の注意点 「retry_limit 9」に変更してる。標準だと17なんだけど、2の16乗=大体1日かかる。9だと大体10分くらい 中央転送用サーバ gitで設定ファイル管理してる。 よく変更するため。 gemfileで各種fluentd/pluginを利用してる。 自分たちで手を入れたソースを利用できるようにもしたいため。 テスト時にテストが書けるのが嬉しい(Rubyで出来てるアプリからもいじりやすいし、アプリのテストでも簡単に使える) ロガーへの実装追加もできる。 Tips バッファからすぐ処理させたい場合とかの説明 こんなのあったら嬉しいな。 設定ファイルの柔軟な設定記述方式 DSLにならないかなぁ(けど、やり過ぎも厳しいし。。。) ログの重要性 統計を考えられるエンジニアが重要。 どのデータにどんな価値があってそれを仕事(お金)に結び付けられるか? QA: Q:障害対応のノウハウとか? A:nagios、muninでサーバとか監視してる。 アラートチェックもしてる。 Fluentdの安定性は2ヶ月実際に導入してみて特に問題は出てない。 Q:MongoDBの構成は? A:master/slave構成。PVログはS3に保存してEMRで処理。 Q:パフォーマンスの測定は? A:40Mbit/sが処理できてたのは見てる。あとは、後ろの発表ですごいのがある! Q:設定ミスの防止とかをどうやった? A:今回はpuppetの設定後のリロードをチェックするような仕組みを入れた。 本来なら、データが流れてるかどうかのチェックを入れるプラグインを書いて欲しいw Q:データマイニングエンジニアの定義は? A:データの価値を見いだせるエンジニア。あとは、きちんと統計学を学んできてるエンジニア。両方募集中!! Q:DynamoDBは検討は? A:西海岸でしか動かないのでデータ転送の時間がかかってしまった+RESTで1件ずつ登録なので今回は見送った。スキーマレスなのでうまく使えそう。 A2(古橋さん):バルクインポートがないので使いにくい。 Q:ログ出力の形式をFluentdにあわせて変更したとかありますか? A:もともとアプリで出力してたから特に変更なかった。 ◎16:15~17:00 「fluentをサービスで使ってみた」 http://www.slideshare.net/naverjapan/20120204fluent-public NHN Japan株式会社 Tetsuya Ohira (@just_do_neet)\n自己紹介が面白かったw 実例の話。 事例1: 社内向けのログ解析に利用 Fluentd+Hadoop データノードにFluentdで出力して、データノードからHDFSに書き込んでる。 事例2: NAVERまとめのまとめ作成者へのデータ解析 Fluentd+Hadopo+Azkaban Azkaban(個人的にはオススメできないw) flutendの負荷は全然上がってない。 監視 tcp portの監視 転送されたデータサイズのチェック。HDFS側のデータ量でチェックしてる。 なぜか半死半生の状態になった(よくわからない。) プラグインを自分で直せるので対応が楽。(Ruby力は必要だけど。) demo 準リアルタイム解析基盤の構成案(おもろそう) fluentd、MongoDB、Hadoop、Jubatus、node.js 地図にアクセス解析結果をのっけて見せる。(maptail.js?) 提案or相談: 動的に設定ファイルの内容を変更できるようにしたい log rotateのタイミングでshell実行でfluentd再起動 必要な情報だけrelayしたい フィルタープラグインみたいなものが書きたい。 fluentd自体のメトリクスを出して欲しい jubatusプラグインはー? QA: Q:log rotateへの対応はどーしてる? A:今はログローテートのタイミングでfluentd再起動してる Q:Apps側のFluentdがコケたときにaccess_logをcopyしてるらしいけど、重複しないの? A:失敗した対象のログをストレージから一旦廃棄して、再送してる。 Q:Rubyがそこまで得意じゃないのにFluentdを選んだ理由は? A:他のモノが使いにくかった+既存システムに手を入れなくて済む+タイムリーだったという理由。 Q:構成案のデータの流れは? A:MongoDB、Hadoopへは同一ログを流して、リアルタイムが重要な場合はMongoDB、大量データ回すのはHadoop? ◎17:15~18:00 「Distributed message stream processing on fluentd」 http://www.slideshare.net/tagomoris/distributed-stream-processing-on-fluentd-fluentd NHN Japan株式会社 ウェブサービス本部 Tagomori Satoshi (@tagomoris)\nsed | grep | wc がメイン。 Hiveで集計してます。 なんでFluentd?(not Storm、Kafka or Flume?) Rubyが好き(ライブドアはJavaが入ってない環境もあるし) プラグインやTimeSlicedOutputがあるのも採用理由 ログ収集の構成図 ブログに別の勉強会の資料があるので見てください。 まだ10日間しか動いてないので実績は少ない? 127サーバからのログを流してる。 7万行/sec、ピーク120Mbpsが流れてる。 89 fluentd インスタンスが12ノード(4コアHT)で動いてる。 1行のログを1行のタブ区切りで出力する(Hiveでインポートしやすいから) Apacheのログに幾つか追加したデータなどが出力されてて、それをタブ区切りにするため設定一発では変換できない。 TimeSlicedOutputが重要 時刻単位でログ出力できないとキツイ(ログの流量が半端ないから) ログローテートでは時刻単位できちんと出力されてない。 ログから解析までの流れ図 以前は生ログをHadoopに書き出してたので25分くらいのタイムラグが出てしまっていた。(ノード数が少ないという理由もあるけど、お金的に増やしたくない)+Hadoopで他のジョブが実行されてるとさらに遅くなる。。。 fluentd でログを流しながらコンバートもかけられ、Hadoopでのデータコンバートの処理遅延が少なくなってハッピーに! ストリーミング処理の重要な点 バッチでもストリーミング処理でも同じことが可能。(out_exec_filterとHadoop Streaming) SPOFがないこと トポロジ、Fluentdの構成 ログエージェント(scribeline:お手製) pythonで書かれたscribelineというものを利用してる。 フェイルオーバーの処理(primary、secondary構成)が可能 fluentdは入れてない。(ログを拾い上げて流すだけには重い) workerノード serializerノードが必要なのは出力先の競合を減らす必要があるため。 出力先が大量のアクセスに向いてない場合があるから。 あと、ログの流れを元に監視したい項目にもここで対応可能。 watcherノード deliver、serializerからのデータを見ながら監視、統計処理を行える。 設定は自動生成してる。800行くらいになっちゃうから。 workerへの分散具合をよしなにしたいから。 remove_prefix 、add_prefixでデータの流れ先の交通整理してるのか。 GrowthForecastでグラフを出力してる。 https://github.com/kazeburo/GrowthForecast QA Q:大規模環境での移行はどうやったの? A:もともと流すような仕組みはあって、流し先を変えたので それほど大変ではなかった。ただ、アプリ側で動いてた部分に手を入れたときは配備が大変だった。 Q:workerが1サーバ8の理由は? A:4コアHT=8というので8としている。 Q:deliverのカーネルパラメータをいじってたりしない? A:ライブドア標準の設定がされてる。CentOSのデフォルトでもそれほどきびしくないかな? Q:deliverノードでラウンドロビン+out_forwardになってる理由は?out_forwardだけじゃだめ? A:バッファのタイミングでの切り替えだと溢れてしまうので、最大でも1秒でラウンドロビンしてworkerを切り替える必要がある。 ※懇親会設営の手伝いのためあんまり聞けず。 ◎18:15~19:00(Plugin紹介LT)(各10分) @shun0102: 「fluent-plugin-dstatを使ったリアルタイムクラスタモニタリング」 http://www.slideshare.net/shun0102/fluent-plugindstat\n@ixixi: 「fluent-plugin-couch」 http://www.slideshare.net/ixixi/fluent-plugins-for-couchdbamazon-sqssns\n@chobi_e: 「Fluentd \u0026amp; PHP」 http://www.slideshare.net/shuheitanuma/fluentd-and-php\n@railute:「Fluent Output Plugin for Cassandra」 https://skydrive.live.com/view.aspx?cid=D105615A0F594518\u0026amp;resid=D105615A0F594518%21333\n","date":1328367780,"dir":"post/2012/","id":"a2679a7d860a0bfb2645809ed92ce138","lang":"ja","lastmod":1328367780,"permalink":"https://blog.johtani.info/blog/2012/02/05/fluentd-meetup-japan%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-02-05T00:03:00+09:00","summary":"Fluentd meetup in Japanに参加しました。いつも面白そうな話を聞いてばっかりなので、役に立つためにスタッフとしても参加してみました。 まずは、会場が綺麗","tags":["勉強会"],"title":"Fluentd Meetup Japanに参加しました。(Jugemより移植)"},{"contents":"昨年末に今年の抱負について書いたのですが、 他にも興味あるものが増えたので備忘録&公約?を兼ねてブログに書いておきます。 (興味あるものがあれば、シェアしたりできると楽しいので、ツイート、コメント待ってます。)\nZooKeeper SolrCloud SenseiDB Lucene 検索システムのアジャイル開発? まずは、ZooKeeper。このなんとも言えないアイコンでお馴染みのヤツです。 こんな顔してますが(顔関係ない。。。)、いろんな所に出没します。 Katta、Lilly、SolrCloudにも出てくるんです。SenseiDBにも出てくるんです。分散処理にことごとく絡んできます。 で、これは、知っとかないとまずそうだと。\nSolrCloud。まぁ、妥当です。一応、Solrな人なんで。 昨年、NewSolrDesignを訳してみてもいます。訳しただけでほったらかし。。。 elasticsearchとかSenseiDBとかSolrに似たLuceneを利用している検索サーバがチラホラ話題になってます。 できれば、このあたりの分散の仕組みを比較しながら調べたいなと思ってみたり。 すべてをカバーするのはキツイので、SolrCloudかSenseiDBあたりを調べていきたいなぁと。\nで、SenseiDBです。先日、Publickeyで記事が出て飛びつきました。 Zookeeper使ってるし、分散だし、全文インデックスにLucene使ってるし。 なんだか興味あること、全部入りな感じです。\nLuceneも興味津津です。 Solrがコアとして使ってますし、昨年、Solrと同時にリリースされるようになりました。 Luceneも奥が深く、時々、Solr調べててLuceneのソースも見るのですが、本格的に全体像を把握したりは残念ながらできていません。 そのくせ、Zookeeper同様、いろんな所に出没するんです、これが。 ということで、足元を固めるためにもLuceneに入門しないとなぁと。\nで、最後に検索システムのアジャイル開発です。 lucene-gosenのコミッターをやらせてもらってたり、Solrに絡んだ仕事もしてますが、長期にわたってフィードバックをもらいながら検索システムを育てていくというのが最近興味が出てきてることです。 検索システムは作ったらおしまいとは行かないのが厄介なところです。 データは増加しますし、検索されるキーワードも変わってきます。 また、検索される方法も変わってきたりもします。 ユーザが検索したいものも変化があります。 思ったように検索にヒットしない場合とユーザが離れて行ってしまいますし、検索しにくい場合も同様です。 今日、クックパッドの方の話しを聞いて思い出した次第です。(前に、Solr勉強会でも同じ話しをされて、同じ思いに至ったのですが、いかんせん忘れやすくてw) また、ログ解析の話などをTwitterで見てることもあり、検索という側面でのログ解析ってのも重要だよなぁと。 いくつか思いつくこともあるのですが、実践出来る場も限られてます。 色々と話しをする場を設けるのも面白いかもなぁと妄想してる次第です。\n取り留めもなく、現時点で気になってることを書きだして見ました。 また、数ヶ月したら気が変わってるかもしれないですが、とりあえず書き残してみます。 興味がある方がいらっしゃったら声をかけてもらえるとうれしいですね。\n","date":1327596641,"dir":"post/2012/","id":"58e83fb33c120db338132d23b9112805","lang":"ja","lastmod":1327596641,"permalink":"https://blog.johtani.info/blog/2012/01/27/%E4%BB%8A%E8%88%88%E5%91%B3%E3%81%8C%E3%81%82%E3%82%8B%E3%81%93%E3%81%A8/","publishdate":"2012-01-27T01:50:41+09:00","summary":"昨年末に今年の抱負について書いたのですが、 他にも興味あるものが増えたので備忘録&公約?を兼ねてブログに書いておきます。 (興味あるものがあれば","tags":["備忘録"],"title":"今興味があること(Jugemより移植)"},{"contents":"ということで、いつものように勉強会に参加したメモです。\nhttp://atnd.org/events/23608 日時 :2012/01/26 19:00 to 22:00 会場 :アカデミーヒルズ(六本木ヒルズ内) 49階(タワーホールA) (港区六本木6-10-1) ハッシュタグ :#mnlgy\n■タイムテーブル 司会:CROOZLabs株式会社 研究所 所長 代表取締役社長 小俣 泰明 モーションノロジーの説明があったけど、他のことしてました。すんません。 1. 発表者: 有限会社未来検索ブラジル 森 大二郎 概要:groongaの索引構築の実装 全文検索とは。歴史から 1971:full-text。。。というキーワードが。 現代の全文検索の課題はあんまり変わってない 全文検索の手法 いくつかあるけど、転置索引の説明だけ。groongaも転置索引 groongaはインデックスの動的構築が得意 静的構築も考慮してます。 2. 発表者:CROOZ株式会社 長谷川 博紀 概要:MeCabからの脱出?(仮 CROOZ MALLの解説 MySQLとMeCabでやってます。 Tritonnつかってるのか? groongaとの性能比較検証やってみました。 MeCabが問題じゃなくて、辞書ありの形態素解析が問題。 辞書にない単語もうまく検索したい 辞書に単語登録したら形態素やり直し ソート用のデータが。。。(ここはわからなかった) QA Q:MeCabの代わりとなっているものは? A:MeCabを改善してみる? 3. 発表者 : グリー株式会社 一井 崇 概要:全文検索のちょっとちがった使い方(仮) グリーでの数値指標管理 事前集計してKVSに登録してみてみる 1億パターンのキーが存在する。。。 キーがわからなくなる問題とか事前集計できてる?とか迷子になる。 キーも全文検索に入れてみては? 「富士山の標高は何メートル?」とかでデータが取れる。 構造化されたキーをkey stringとして全文検索する。 構造化Keyに対応したKVSがあればいいんだけど。 データストアとしての全文検索もいいのでは。 4. 発表者:株式会社クリアコード 須藤 功平 概要:rroongaによる検索サービスの実装 groongaとRubyの組み合わせでrroonga。Rubyによるインタフェース? groongaとのつながり部分をRubyで書いたライブラリ 多段ドリルダウン機能 絞り込みによる検索結果の比較とかに利用可能 メタデータ抽出にドリルダウンが便利 例:番組説明から出演者を抽出 サジェスト機能もある コンテンツベース すぐできる。候補の精度がいい 統計情報ベース 元データがある程度必要 候補が増えるけど、精度の問題あり 5. 発表者: 株式会社ぐるなび 塩畑 公一 概要: groongaの位置情報検索関連について。 2010年4月からgroongaを利用し始めた レストラン検索、地図検索など 円形、矩形の緯度経度検索が可能。 距離算出もやってる。ソートとか用かな。 球面近似もやってる。 geoの検索速度についてパフォーマンステストしました。 Q:近似手法をいくつもサポートされてるけど必要? A:距離計算を正確にしないと不利になるお店が出てきちゃうから 6. 発表者: クックパッド株式会社 兼山 元太 概要: Solrを使ったレシピ検索のプロトタイピング クックパッドとは? 女性多いよ AWS上でRubyで組んであるよ プロトタイピングって? ユーザの問題を発見してから、プロトタイピング 本番デプロイ(一部ユーザに公開) 問題を抱えているユーザーに向けてそれぞれ数十のバージョンが動いている インタビューとかしてフィードバック受ける。 本番の検索エンジンのフィールドをいっぱい追加 Solrの紹介(MySQL(Tritonn)から移植しました) ダイナミックフィールドやレプリケーションの話。 JSON型でHTTP経由で検索できるのが便利。 Solr本の紹介して頂きました!あざっす! 気になってるSolrの新機能 not to cache SurroundQuery BloomFilter Q:全部AWS? A:全部AWSに移行しました。 とまぁ、参加してきました。 初六本木ヒルズで、おしゃれな場所、雰囲気にやられてしまって、あんまりちゃんと聞けてないところがありますが。。。 メモを取りましたので。参考までに。 groongaについては勉強不足のため、いまいちついていけませんでした。 ちょっと英語の記事を読んでいたのもありまして。(内職良くない。。。) MeCabに関する発表に興味があり、勝手にMeCabの代わりorMeCabよりいいものを使ってます!みたいな発表かと想像していました。(ちょっと違ったみたい、妄想は良くないですね。。。)\nグリーの方の発表は興味深かったです。ログ解析とかにも確かに全文検索の技術使えるし。 検討が進んだ次の話も聞いてみたいです groongaの位置情報の話やrroongaでのgroongaの色々な機能のはなしも出てきてgroongaの理解もちょっと進んだのはありがたかったです。\n最後のクックパッドさんの話は、今回もわかりやすくて面白かったです。 検索を成長させていくという姿勢と、実際にどんな形でそれを実施されているかが楽しそうに話されててとても羨ましかったです。 次はSolrで困ってる点とか、検索のログとか利用され方をどのように解析してるのかといった話も聞きたいですね。\nどうしてもSolrに思い入れがあるので、感想が偏ってるかもしれません、すみません。 気になる点やいや、こうなんだよ!ってツッコミがあれば、ぜひコメントやTweetしてもらえるとありがたいです。\n","date":1327593155,"dir":"post/2012/","id":"c6dc6e6567d673436ac41ebc8e79a9ec","lang":"ja","lastmod":1327593155,"permalink":"https://blog.johtani.info/blog/2012/01/27/%E3%83%A2%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%8E%E3%83%AD%E3%82%B8%E3%83%BC2012-1%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-01-27T00:52:35+09:00","summary":"ということで、いつものように勉強会に参加したメモです。 http://atnd.org/events/23608 日時 :2012/01/26 19:00 to 22:00 会場 :アカデミーヒルズ(六本木ヒルズ内) 49階(タワーホールA) (港区六","tags":["勉強会"],"title":"モーショノロジー2012#1に参加しました。(Jugemより移植)"},{"contents":"日時:2012/01/19 18:30-20:30 場所:ベルサール三田Room2シアター\nInside MapR デモ+内部のお話。 ・自己紹介 Susheel Kaushik 元YahooのHadoop系の人。製品担当責任者。 草薙さん 3台のベアボーンでMapRが動いてるデモが開始。 クラスタ管理画面の説明。 なぜか、NFSのサービスが1台落ちてますがw MapReduceなんかの実行結果なども出てくるのか。 ボリューム管理も画面から操作 レプリケーション、スナップショットも管理画面で操作、動作確認できますよ。 ミラー先はリードオンリーでボリュームの同期が可能。 スナップショットによりMapRのクラスタ内部にバックアップが保持可能。 NFSのHA構成可能。VIPの機能などもあるよ。 事前定義された各種Alertの発行も可能。 JobTrackerもMapRで拡張された表示がある。 例:MapTaskPrefetchCapacity:次のジョブのMapperを起動する準備可能な仕組み MapR内で独自に出力してる測定値をGangliaで見ることができるよ。 MapRはHadoopの置き換えとなる製品。 HDFS部分を重点的に性能アップさせるために主に置き換えた製品。 MapReduce部分にも手を入れてる。例:Direct Shuffle(HTTPじゃなくて、RPCでShuffleの通信を行ってるとか)ボリューム活用してるらしい。 分散NameNode、JavaGCの影響の排除、ビルトイン圧縮によるI/O削減など。 Mapperの出力をHDFSに置くと、メタデータ更新が多くなり、NameNodeがパンクする。(Apache Hadoop) Q:中間データもレプリケーションすると性能劣化しないんですか? A:中間データボリュームは特定ノードしか保持されない(=レプリカ数は1) ストレージプール(SP) ソフトウェアでストライピング。RAIDしなくてよい。 コンテナ(データ、ネームがある。) データブロックをグループ化したもの ※ストレージプールの数と同数のボリュームを作成すべき。 CLDBがコンテナを管理してる。 Q:トランザクション失敗するのは? A:どこかにかければトランザクションは成功。 コンテナが復旧してきたら、データがコピーされる。復旧されない場合は別途コンテナを割り当てることもある? Q:ノードが追加される場合の挙動は? A:。。。聞き逃した。 トポロジ ノードを階層的にグループ化してデータ配置をコントロール。 Q:トポロジ設定などの権限設定は? A:Permission画面があるよ。 Q:ボリューム単位のファイルシステムアクセスに関する設定は? A:???聞き逃した? ボリューム いろいろな設定が可能。 スナップショット Copy-on-Write方式による差分格納 ミラー ソースからミラーにコピー。手動orスケジュールによる起動が必要。 ミラー側はRead-only ※誤解を招きやすいので注意 読み出しが多い場合にミラーを利用することで対応が可能。 ビルトイン圧縮 LZZFの一種を高速化してる ネットワークIOにも効いてくる JobTracker HA 最大3ノードで構成可能。アクティブスタンバイ NFS HA すべてのノードで稼働可能。 NFS機能 NFSv3相当 クライアント側にNFSサービスをインストールするという構成も可能に。 Q:NFSマウントして作成したファイルもブロックサイズ分のファイルサイズになるの? A:8Kバイト単位で内部的にはファイルを作成してる。8KB単位で圧縮して管理してるので、小さいサイズでもいい。(アロケーションサイズが8KB) Q:8KBにしてしまったために大きなブロックサイズの利点がなくなるのでは? A:オーバーヘッド内容な構成になってる。シーケンシャルに8KBに並んでるから? Q:NFSによるとMapReduceによるアクセスの排他制御とかは? A:独自で頑張らないといけない。Job起動時に効果的にスナップショット取ったりはしてない。 リバランスもバックグラウンドで実行可能 Apache Hadoopが備えるJava APIは100%語幹 Q:なんで、HDFSをがりっと書き換えたの? A:運用性も、ノード管理も。。。全部です。 なくなっても良いデータなら、別にHadoopでもいいですよね。 けど、基幹システムとかだと、信頼性が必要だし、運用の効率も必要だしいろいろ必要。 Q:実績が必要なんですが、どのような試験を行われているのかという情報が公開される?EMCでやられてるテストのプロセスを適用しているなどの裏付けは公開されないの? A:内部で6ヶ月利用してデータロスはない。 品質については強化していく。 Q:MapRとしてHadoopコミュニティへの還元していく内容ってどんなもの? A:Apacheコミュニティに対して1000台のクラスタを提供してスケーラビリティテストとかやってくださいとしている。 Q:このクラスタを実際にはどう使ってもらうの? A:品質アップするためにテスト環境として使ってもらう? Q:ApacheのAPIの互換性を死守するのが必ずしもいいとは思えない場合にどうするの?MapR独自APIとかは出さないの? A:ApacheのAPIに準拠するのは非常に重要。他のHadoop上のアプリが動作しなくなるから。 Q:MapRを容量の大きなファイルシステムとしてだけ利用するなんて想定はありますか?MapReduceを利用しないパターンです。 A:いや、それはw Q:MapRはエンタープライズがターゲットだけど、Amazonはパブリッククラウドが対象。マルチテナントなパブリックサービスでMapRを利用するとかは? A:。。。 Q:ジョブ管理にも手を入れてるの? A:あんまり手を入れてません。 Q:EMCのストレージ製品でMapRのMapReduceない版みたいの出てない? A:中身はMapRじゃないですよ。 想定とは異なり、日本の草薙さんが主に説明されたのですごくわかりやすかったです。 しかもかなり内部まで理解されている方だったので突っ込んだ質問にもきちんと回答されてるので更に理解が進みました。 今回利用された資料は現時点では公開の予定はないという話でした。 ただ、かなりまとまってる資料なので、後悔して欲しいものです。 普通にviとかしてるだけなのに、すごいと思うデモってなんか新鮮でした。 MapR自体を触る機会はまだまだないと思うのですが、MapRとしてHadoopに対する思想が垣間見えたのが面白かったです。 すごいメンツが質問を投げまくるのでいろいろな側面で話が聞けました。 ただ、やっぱり英語のヒアリングがダメダメだというのが露呈しました。。。今年は少し頑張らないと、先が思いやられますね。。。 あと、疑問と言うか、感想ですが、MapR自体が結構多機能で、その機能をどう扱うか、どのようなノード構成やボリューム構成を取るかといった設計が結構大事でしかも大変なんじゃないかなぁという印象を受けました。 特にマルチテナントで利用する場合などは、想定されないミラーの利用などでデータ容量が足りなくなったりといった側面も出てくるのかなぁと。\n説明会のあと、Hadoopにあんまり絡んでないのに図々しくも飲み会にまで参加してきました。 これまた濃いメンバーだったので話についていくのも大変でしたが、面白い話が聞けました。やっぱり懇親会重要ですよねぇ。\n事前にこのブログを読んでいたので話しを聞くのが楽でした。 MapR勉強するために必須のページです。(どうやら今日説明した人がかいてるきがしますが。。。)\n追記: トゥギャってくれた人に感謝。 ","date":1326988680,"dir":"post/2012/","id":"7198e10ebcf1bb88dc479b5c5b9f2c15","lang":"ja","lastmod":1326988680,"permalink":"https://blog.johtani.info/blog/2012/01/20/mapr%E4%B8%AD%E8%BA%AB%E8%AA%AC%E6%98%8E%E4%BC%9A%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-01-20T00:58:00+09:00","summary":"日時:2012/01/19 18:30-20:30 場所:ベルサール三田Room2シアター Inside MapR デモ+内部のお話。 ・自己紹介 Susheel Kaushik 元YahooのHadoop系の人。製品","tags":["勉強会"],"title":"MapR中身説明会に参加しました。(Jugemより移植)"},{"contents":"お久しぶりです。インフルエンザで一家全滅という最悪の状況に陥っていた我が家でした。 流行してるみたいなのでみなさんも気をつけてください。\nさて、そんな中、OSSAJのミニセミナーでSolrについて簡単に話しをしてきました。 人生初Ustだったのですが、ぶっ倒れている中作成した資料だったためなんとも情けない発表だった気がします。(言い訳カッコ悪いですね。。。) 関係者の皆様、申し訳ございませんでした。\n内容としては、Solrの機能を簡単に紹介する程度の資料となっています。デモなどもないのでスライドだけ見てもなんだこれという感じかもしれませんが。\nということで、恥ずかしながら、録画もされているようなので、後で見て反省しようと思います。。。\n[オープンソースソフトウェア検索サーバ Solr入門](http://www.slideshare.net/JunOhtani/solr-11146713)** View more [presentations](http://www.slideshare.net/) from [Jun Ohtani](http://www.slideshare.net/JunOhtani) ","date":1326941184,"dir":"post/2012/","id":"a4462529ab493676987d946019a14945","lang":"ja","lastmod":1326941184,"permalink":"https://blog.johtani.info/blog/2012/01/19/ossaj%E3%81%AE%E3%83%9F%E3%83%8B%E3%82%BB%E3%83%9F%E3%83%8A%E3%83%BC%E3%81%A7%E8%A9%B1%E3%81%97%E3%82%92%E3%81%97%E3%81%A6%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-01-19T11:46:24+09:00","summary":"お久しぶりです。インフルエンザで一家全滅という最悪の状況に陥っていた我が家でした。 流行してるみたいなのでみなさんも気をつけてください。 さて、","tags":["勉強会"],"title":"OSSAJのミニセミナーで話しをしてきました(Jugemより移植)"},{"contents":"先日のSolr勉強会でLucene/Solr4.x系のlucene-gosenについて質問を受けていたのを忘れないように(年越しちゃいました、すみません。)先週金曜日(1/6)にissueに登録しました。 まずは忘れないようにと思って、登録だけして3連休に突入したのですが、Robertさんが1/7に対応してくれました。 Lucene/Solr 4.x系では3.x系とはパッケージやメソッドが変更されるなど少し異なる部分があります。 lucene-gosenでは、プロジェクトのページにもあるとおり、4.x系にも対応しています。 ただ、この4x系に対応したブランチが、2011年5月から放置されていました。\nということで、Lucene/Solr 4.0系でlucene-gosenを利用されている方、これから利用される方は、この4x系に対応したブランチを利用してください。 なお、このブランチにはLucene/Solrのtrunk (r1228509)のSNAPSHOT版のjarファイルが利用されています。\n今後はlucene-gosen側でバグ修正や機能追加を行った場合にも4xブランチを更新していく予定です。 ※ただし、Lucene/Solr 4.0が正式リリースされていないため、頻繁にSNAPSHOTのjarファイルを入れ替えることはこなわないと思います。\n","date":1326033660,"dir":"post/2012/","id":"f7df7b85af230b2623d3a827b0cbddd2","lang":"ja","lastmod":1326033660,"permalink":"https://blog.johtani.info/blog/2012/01/08/lucene-gosen%E3%81%AElucene-solr4-0%E5%AF%BE%E5%BF%9C%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E6%9B%B4%E6%96%B0/","publishdate":"2012-01-08T23:41:00+09:00","summary":"先日のSolr勉強会でLucene/Solr4.x系のlucene-gosenについて質問を受けていたのを忘れないように(年越しちゃいました","tags":["lucene-gosen"],"title":"lucene-gosenのLucene/Solr4.0対応ブランチ更新(Jugemより移植)"},{"contents":"あけましておめでとうございます。(もう5日ですが。。。) 今年もlucene-gosenを中心に色々と記事を書いていきますので、ツッコミ、コメント待ってます。\nたまには会社のブログを書かないとイカンということで、会社のブログにNearRealTime検索についての記事をアップしました。 読んでやってください。\nということで、今年もいろんな勉強会に出没しますので、よろしくお願い致します。\n","date":1325735817,"dir":"post/2012/","id":"cc573488dec311655890a205aad4fb65","lang":"ja","lastmod":1325735817,"permalink":"https://blog.johtani.info/blog/2012/01/05/%E3%81%82%E3%81%91%E3%81%BE%E3%81%97%E3%81%A6%E3%81%8A%E3%82%81%E3%81%A7%E3%81%A8%E3%81%86%E3%81%94%E3%81%96%E3%81%84%E3%81%BE%E3%81%99%E4%BC%9A%E7%A4%BE%E3%81%AE%E3%83%96%E3%83%AD%E3%82%B0%E6%9B%B4%E6%96%B0/","publishdate":"2012-01-05T12:56:57+09:00","summary":"あけましておめでとうございます。(もう5日ですが。。。) 今年もlucene-gosenを中心に色々と記事を書いていきますので、ツッコミ、コメ","tags":["misc"],"title":"あけましておめでとうございます+会社のブログ更新(Jugemより移植)"},{"contents":"他の方たちよりひと足はやいですが、今年の仕事が終わりました。 せっかくブログを始めたので、振り返りと来年の抱負など書いてみようかなと。\n今年の振り返り まずは、今年1年を振り返ってみます。 今年の出来事はこんな感じでした。\n3月に仕事が一区切り lucene-gosenに参加 ブログを始める 色々な勉強会に参加 Twitterでつぶやきまくり Mac Book Airの購入 PSVita買いました 3月に一昨年から参加していた仕事が一区切りつきました。 もう少し色々とやり残した感がある中で区切りがついたのが少し心残りでした。 あと、3月は震災もあり、色々と大変でした。ただ、自分の中では震災の記憶が少し薄れつつあるのが気がかりです。 良くも悪くも忘れて行ってしまうのだなと。今でも頑張っている方々もいるので、少しでも心に留めておきたいものです。\n個人的に一番大きな今年の変化は「lucene-gosenへの参加」です。 関口さんとここ数年ずっと仕事をご一緒させていただいていることもあり、コミッターとして参加させてもらうことが出来ました。 英語が苦手な中、Robertさんへ自己紹介のメールを書いたり、Issueを英語で書いたりと苦労もしていますが、OSSに参加できることがとても楽しいです。 また、使っていただいている方たちからのフィードバックもいただけているのがすごく励みになります。 やはり、OSSは使ってもらってさらに良いものになっていくのかなぁという感想です。 ただ、自分の腰が重いため、なかなか対応が遅かったりといったところもあるなと反省するところも。\n勉強会にも色々と参加しました。Solr勉強会を始めとして、かねてより興味があるHadoopのカンファレンスやソースコードリーディング。MongoDBの勉強会やDSIRNLPといった少し研究よりの勉強会にも参加しました。 Solr勉強会に参加してきた経験もあり、他の勉強会にも気負わずに参加できたので本当にSolr勉強会には感謝しています。 おかげで、社外のいろいろな方と話ができ、様々な刺激をうけることが出来ました。\n勉強会以外にもTwitterで色々な方に絡みまくったのもまた社外の方とのつながりが出来るいい機会でした。 Twitter依存症じゃないかというくらい、つぶやいたり、人に絡んだりしてます。。。(迷惑だったら言ってください。) お陰で@doryokujinさんや@wyukawaさんが主催してくれたログ解析の飲み会に誘ってもらえたり、@nobu_kさんや@ IjokarumawakさんにSolr勉強会で講演してもらえたりしました。 あと、Twitterを通じて勉強会やHadoop関連の情報、lucene-gosenへのフィードバックなどももらえていてかなり助かってます。 @yusukeyさんや@repeatedlyさんに遊んでもらってるのも楽しいですw\n最後の大きな変化はApple製品の購入でした。 これまでもブログで書いてきましたが、私は今年の中頃までアンチApple派でした。 それがここ半年足らずでAir、Mini、iPadと3つのApple製品に囲まれています。 Emacsのショートカットが使えるのが最大の要因ですが、何ごとも毛嫌いせずためしてみるのがいいなと思いましたね。 今では、Windowsで開発したくないくらいになってきています。\n2012年の抱負 さて、来年の抱負です。 今年いくつかチャレンジしようとして挫折してるものがあります。\nMongoDB触ってみる Scala触ってみる なんかWebサービス作ってみる(Amazonとかで) elasticsearch、IndexTankを調べてみる NewSolrCloudDesignを読み込んで自分なりにまとめる Junsaiに参加する 「7つの言語7つの世界」の続き 最初の3つはセットですかね。コップ本買ったり、NoSQLの本を買ったりしてるのですが、手付かずです。。。 電子書籍の検索サービスでもつくってみようと思いつつ、腰が重い状態です。 来年は余裕を見ながらちょっとずつやりたいですね。\nelasticsearchやIndexTankは仕事がらみです。 Solr入門を書いたこともあり、検索関連には興味があります。Solrだけでも2ヶ月おきに新バージョンがリリースされたり、4.0系でいろんな機能が実装されているのですが、それ以外にもOSSの検索サーバがいくつかあります。 気になってはいるものの英語が障壁でなかなか手を出して来ませんでした。 来年はSolr以外についてももう少し知識をつけていきたいです。 個人的ですが、分散処理にも少々興味を持っています。 慣れ親しんでいるSolrでもSolrCloudという壮大な計画が上がっていて、少しずつ実装もされています。 ブログでWikiページを翻訳してもみたのですが、翻訳に注力しすぎて理解ができていないです。 このあたりをもう少し理解しつつどのような実装がされているかも調べたいところです。\nJunsaiはSolr入門の著者である武田さんが最新のMeCab(今はMeCabが新しくなってしまったので、少し前のMeCabになってしまいました)をJavaに移植したプロジェクトです。 今年頭のSolr勉強会でお披露目があり、私も一応参画しているのですが、手が出せていない状態です。 lucene-gosenで少しは経験を積んできたので、その部分を生かしつつ、こちらももっと活性化させたいところです。 最後は夏ごろにやっていた「7つの言語7つの世界」の再開です。序盤で止まってしまっています。。。 新しい技術に触れる題材としてちょうどよいので、余裕をつくって続きを再開します。 なんか、抱負と言うよりも積み残しですね。。。 他にもTwitterで情報を仕入れるとやりたいことも変わってくるかもしれませんが、それも含めてブログに少しずつでも書きためていこうと思います。\n先ほども書きましたが、今年はTwitterを通じて色々な方たちと知り合いになれた一年でした。 ここには書ききれていませんが、フォローしてもらっている方々や勝手に絡んでも相手をしてくれている方々に感謝しています。 今後も絡みますのでよろしくお願いしますw あと、様々な勉強会に今後も顔を出していくので、かまってやってください。 いやぁ、色々書いたけど恥ずかしいですね。。。 まぁ、何事も経験なので、恥ずかしいと思いつつ今後も色々書いていきます。\n","date":1325006100,"dir":"post/2011/","id":"7164823f504286e3a762ee612ff0a988","lang":"ja","lastmod":1325006100,"permalink":"https://blog.johtani.info/blog/2011/12/28/%E4%BB%8A%E5%B9%B4%E3%81%AE%E6%8C%AF%E3%82%8A%E8%BF%94%E3%82%8A%E3%81%A8%E6%9D%A5%E5%B9%B4%E3%81%AE%E6%8A%B1%E8%B2%A0/","publishdate":"2011-12-28T02:15:00+09:00","summary":"他の方たちよりひと足はやいですが、今年の仕事が終わりました。 せっかくブログを始めたので、振り返りと来年の抱負など書いてみようかなと。 今年の振","tags":["misc"],"title":"今年の振り返りと来年の抱負?(Jugemより移植)"},{"contents":"@yusukeyさんにサインをもらう目的で勉強会に参加してきました。前回もらいそびれたのでw 残念ながら、まだTwitter APIを触ってないし、利用したサービスも思いついてないんですが。。。 けど、勉強になりました。 といことで、いつものごとく、自分メモです。\n◎APIの基本と最新動向について @yusukey 資料:http://www.slideshare.net/yusukey/21twitter-api-api\n・検索APIについて http://search.twitter.com/search.json?q=*** %3Aは「:」 詳しくはリファレンスを買ってね。 ・ページ処理のベストプラクティス Pageじゃなくて、MaxIdを利用して取得すると1500件以上のデータも取れるよ。 ・最近のTwitterAPIアップデートについて - ポケリファでの変更点 ストリーミングのエンドポイントがSSLのみに。(twitter4jは2.2.5以上) - ユーザ名が検索APIのスキーマに追加(12月以降) - in_reply_toの追加(12月以降) =\u0026gt;検索結果から会話を追える。 ・include_entitiesが追加 t.coの展開したリンクも取得可能。 けど、t.coリンクの飛び先はt.coリンクにしてね。パトロールとかしてるから。 ・本当にあった怖いt.co - URLのつもりじゃないのにリンクになる。 →仕様です - 日本語を含むURLがおかしくなる。 →少しずつ治ってきてる。 - リンク先のURLがわからない(クライアント依存) そのたいろいろ? ◎Zusaarについて何か @knj77 資料:\n・特徴 - SNSアカウントでログイン トラブル抑制など - 事前決済可能。最小催行人数が決められて、払い戻しも可能。 ・利用例 旅行とか合宿に使う例がないんだけど、できるんじゃないかな? ・イベントを依頼する機能 欲しいイベントを提案可能 http://www.zusaar.com/idea/ ・アーキテクチャ GAE/Java、Twitter4j、Yahoo APIのテキスト解析 ・SNS連携 TwitterのDMが送れない。他のSNSのアカウントが主催者とか。 なので、自分からDMが届く。 ・PayPal連携 小さいアプリほど相性がいい 固定費ゼロ、マイクロペイメント(100円とか可能) 銀行口座の登録不要、返金可能。部分返金も可能。 ・トラブル - SNS側のエラーが適当 ステータスコードは信用できないw - PayPalの実装を3回変更 - GAE料金体系の変更 9$/month。追加料金はほとんど使ってない。Googleのアナウンスが下手。 - ブルーオーシャンのはずが... Q:Zusaarで返金できるポイントは? A:主催者が主導(手動?)で返金可能。 Q:無料イベントで約束手形的に課金するのはできる? A:やろうと思えば出来ます。ただ、システム的には100円は手数料としてもらっている。 Q:新しいATNDに対抗意識はありますか? A:ZusaarはCtoCをターゲットにしてる。ATNDはBtoCなので、補完できる関係だと思ってる。 Q:APIでTwitterIDとかで検索したいんですが。 A:対応予定あります。 Q:できればATNDのAPIと共通化してほしい。 A:追加してるだけのつもりです。 ◎グループに分かれて自己紹介 6人中、懇親会参加者が5人もいたw\n◎LT - OAuth Echoについて@tkawa 資料:http://www.slideshare.net/tkawa1/oauth-echo-20111221-10657954\ntwitpicで使ってる。 認証をServiceProviderに委譲する仕組み。 クライアントがOAuth登録してあれば、。。。 ・問題点 非公式仕様 OAuth1.0に基づいてて2.0では変わってそう。 ・Railsで実装してみたよ。 - GroovyとQuartzとTwitter4Jの甘い生活G @mike_neck 資料:\nベトナムから緊急来日らしい。 しかもむちゃぶりされたらしい。 - 認証なしで使えるAPIまとめ?@ts_3156 えごったーの作者で学生!\n- TDD (Twitter4J Driven Development) @sue445 資料:\nAZusaarの作者! テストドリブンなはなし。 Twitter4Jを利用するときのTDDの簡単に実装できる仕組みの話。 ここにソースがあるのかな? http:/github.com/sue445/twtrhack/ - 放射線を自動計測してTwitterにつぶやくimaocandeの紹介 @imaoca 松山の方。 とまぁ、APIの話だけでなく、実際にAPIを利用している方のサービスの話など色々と面白い話が聞けました。 厚かましくも懇親会にも参加して、そこでも今までのイベントとは違うクラスタの方たちの話が聞けたのが楽しかったです。 やはり、APIを利用して色々とやってみようと思っている方が多かったのでいつもと違う話が聞けたんですかね。 私自身はサービスを思いついたりしないタイプなので、いい刺激になりました。(まだ、特になにか作る気にはなってないですがw) ということで、次回も余力があれば参加したいなー。 ","date":1324485660,"dir":"post/2011/","id":"da67e2f049b5b6babcf7906b85653399","lang":"ja","lastmod":1324485660,"permalink":"https://blog.johtani.info/blog/2011/12/22/%E7%AC%AC2-1%E5%9B%9E-twitter-api-%E5%8B%89%E5%BC%B7%E4%BC%9A--%E6%9D%B1%E4%BA%AC%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-12-22T01:41:00+09:00","summary":"@yusukeyさんにサインをもらう目的で勉強会に参加してきました。前回もらいそびれたのでw 残念ながら、まだTwitter APIを触ってない","tags":["勉強会"],"title":"第2.1回 Twitter API 勉強会 @東京に参加しました。(Jugemより移植)"},{"contents":"lucene-gosenの最新版(1.2.1)をリリースしました。\nプロジェクトページよりダウンロードが可能です。\n今回の修正では、特定文字列でメモリの使用量が爆発してしまうバグへの対処となっています。 1.2.1以前のバージョンを利用している場合は最新版を利用するようにしてください。\n","date":1324437339,"dir":"post/2011/","id":"584b2b145f362098fc5fc1e634d57de5","lang":"ja","lastmod":1324437339,"permalink":"https://blog.johtani.info/blog/2011/12/21/1-2-1%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-12-21T12:15:39+09:00","summary":"lucene-gosenの最新版(1.2.1)をリリースしました。 プロジェクトページよりダウンロードが可能です。 今回の修正では、特定文字列で","tags":["lucene-gosen"],"title":"1.2.1リリースしました(Jugemより移植)"},{"contents":"いつものようにSolr勉強会に参加してきました。 皆勤賞を継続中です。(暇人というはなしも。。。) 今回は話しを聞きたいですねぇといったら、いやいや、話もしてくださいと言われてしまったので、 発表もしてきました。 発表資料はブログの最後に掲載してあります。\n日時:2011/12/19(月) 19:00~21:00 場所:Voyage Group 8階\n1.Fessについて N2SM菅谷さん 資料:http://www.slideshare.net/shinsuke/solr-fess\nマルチコアで構成されてる。 S2Robotでクロールしてますよ。 ※ごめんなさい、あまり聞けなかった。。。あとで資料を読んで質問します! 2.lucene-gosenについて @johtani 発表しました。 3.ApacheConに参加しました @Ijokarumawak 資料:http://www.slideshare.net/KojiKawamura/apache-con-2011report\n日本-\u0026gt;カナダ-\u0026gt;ベルリン-\u0026gt;カナダ-\u0026gt;日本 50万円。。。 キーノート1: セキュアな開発について。 キーノート2: Hortonworksのコミュニティ運営大変だよねぇ、頑張るよという話。 キーノート3: 本題:Lucene 4.0の話:Simonさん ヨーロッパの方? PostingsFormatの話。 Document内部の情報を使うためにどうする? StoredField:あんまり効率よくないね。 FieldCache(on RAM):インデックス作る動作の逆を行う。これも効率よくないね。 IndexDocValue:インデックス作成時に作られるので読み込み性能が100倍!(DocValue) Document Writer Per Thread! Automaton Query あいまい検索の処理に利用。 Solr Flair Solr同梱 Prism LucidImaginationが出してるJRubyのラッパー GitHubで公開されてるらしい。 Blacklight RoR 図書館むけのパッケージじゃなかったっけ? VUFind PHP これも図書館向け? TwigKit JSPのタグリブ おぉ。これ直接読んでるのかな? Ajax Solr Ajax用 QA Q:TwigKit、Ajax Solrは直接Solrを呼んでるんですかね? A:たぶん、そうですね。JSPのはSolrJかもしれないですが。 4.サフィックスアレイの話 @nobu_k 資料:http://www.slideshare.net/nobu_k/suffix-arraysolr\nSuffix Arrayの話 全文検索インデックスの話。 Suffix Array=検索漏れがない。 Suffix=接尾辞 RedBullがどの文書に入っているか! SuffixArrayのメリット 検索漏れがない=n-gramと同様 仕組み上n-gramよりも早くなるケースが多い。 長いクエリに対して速い THIS IS IT:全部ストップワード SuffixArrayのデメリット インデックス構築系 アルゴリズムが難しい。 メモリ上での構築はちょっとだけ楽(けど、簡単ではない) SAISなど。けど、これだとメモリがいっぱいないとキツイ HDDでの構築 ランダムアクセスを排除したアルゴリズムが必要(dc3,dc7) インデックス更新、差分更新できない。 頑張って1台100GB/day Sedueでは? SA&インメモリn-gramのハイブリッド 更新分はn-gramに 検索時にはn-gram+SAの内容をマージして出力 検索 二分探索はHDDとは相性が悪い。 メモリ上で検索できればOKだけど、サイズが大きいからきびしい。 圧縮接尾辞配列なら可能だけど、低速。。。 SSDだとはやいよ! SSD対応のクラウドはまだないけど。。。 Sedueでは最初の20段でキャッシュしてる。 VSストップワード ストップワード込でインデックス作るみたい。 1.SAを二分探索 2.該当区間から出現位置をロード 3.出現位置をソート O(n)だけど、CPUのキャッシュミスが激しく影響 4.ソートした出現位置からヒット文書を求める。 同じくキャッシュミスがやばい ・実際にはmallocした領域のページフォルトが一番やばい SAが超活躍する場面 遺伝子の検索 n-gramとか死ぬ。形態素解析も無理。区切りがわからんw 5.P2P検索 ORBIS @ceeflyer 資料:http://www.slideshare.net/ceeflyer/p2p-search-engine-orbis\nORBISとは?ラテン語で「目」 ORBISとは? リアルタイム検索エンジン 自律分散検索エンジン もともとはAmebaなうの検索のため ノード構成 比較的小規模(~1000台)\u0026lt;=しょ、小規模ですか。すごいな。 Master-Slaveの差がなし MessagePack利用 フルメッシュネットワークを構築 インデックス フィールド: Content(形態素解析対象) Appendix(形態素解析しない) Flag(属性) ハッシュレプリケーションで登録。近いハッシュ値に登録(レプリカ数を指定できるのかな?) 単語に対して転置インデックスを一定数で固定 投稿日時が新しいものだけ検索するため。 検索: マージして結果を返す。 壊れてたら取れたものだけ返す。 QA: Q:ハッシュ値が大きくて1台しか選ばれないとかあるのでは? A:ハッシュ値は循環しているという形で3台とか選ぶ。 Q:最大何台で稼働させてる? A:現在はまだ5台程度 Q:障害時にレプリケーションの維持はするのか? A:現時点はしてない。 Q;Cassandra、Lucendraとかあるけど、それをしなかった理由は? A:単純にConfigurationができるから、1から作った。 今回はSolr以外の話も聞けたのがとても面白かったです。 やはり、Solr以外の検索エンジンについても知見があると、色々と比較の話しとかしやすいので。 それにしても、一からP2Pの検索エンジンを作っているのにはびっくりしました。 他にもSuffixArray(Sedue)の話も気になっていたのが少し氷解したし、海外旅行のノウハウがApacheConの話で聞けたしw やはり、発表をすると話しをしてもらえるのもあって、いい機会だなと再認識しました。 今回も紹介ネタだったので、ちゃんと事例とか測定したものも発表できるようにならねばと。。。\nということで、私の発表資料はこちらになります。疑問点とか質問事項とか、指摘事項など、コメントorTwitterで連絡いただけるとすごく嬉しいです。\n[Lucene gosenの紹介 solr勉強会第7回](http://www.slideshare.net/JunOhtani/lucene-gosen-solr7)** View more [presentations](http://www.slideshare.net/) from [Jun Ohtani](http://www.slideshare.net/JunOhtani) ","date":1324311660,"dir":"post/2011/","id":"c6696a730f7498efb66f5ba3a8b35d08","lang":"ja","lastmod":1324311660,"permalink":"https://blog.johtani.info/blog/2011/12/20/solr%E5%8B%89%E5%BC%B7%E4%BC%9A%E7%AC%AC%EF%BC%97%E5%9B%9E%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F%E7%99%BA%E8%A1%A8%E3%82%82%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-12-20T01:21:00+09:00","summary":"いつものようにSolr勉強会に参加してきました。 皆勤賞を継続中です。(暇人というはなしも。。。) 今回は話しを聞きたいですねぇといったら、いや","tags":["勉強会"],"title":"Solr勉強会第7回に参加しました。(発表もしました)(Jugemより移植)"},{"contents":"ということで、懲りずに#DSIRNLPに参加してきました。 基礎的な部分をおろそかにしたくないけど、TokyoNLPとかWebMiningではついていけないので。。。 今回もしがみつくのが精一杯かもしれないと思いつつ、聞いて来ました。\n0. DSIRNLPについて @overlast 講演者が可能なら実装に関して言及する。 「こうやって作って結果を出す」系の発表をしましょう。 開催に際して協力してくださったみなさんへの感謝の辞。 1.自然言語処理はじめました @phyllo 資料:http://www.slideshare.net/phyllo/ngram-10539181 ブログ:http://d.hatena.ne.jp/jetbead/20111210/1323499634 某Web企業の新入社員!(すごい) で、入って自然言語処理をはじめたらしい。 N-Gramの説明 Perl? 1.ナイーブな方法 Perlでハッシュ使って数えてみたよ。これでOK? いやいや、Nが大きくなったりデータが大きくなるとキツイでしょ 2.SuffixArrayを使う ということで、Suffix Arrayを使ってみた。 SuffixArrayのデータを作ってから、上からN文字数えれば数えられる! (数式出てきたけど目も取れなかったw) これでいいじゃん?いやいや、更に大規模だとどーすんの。1TBのメモリ 3.近似カウント法 いくつかある中からLossy Countingを説明します。 ストリームデータから数えてみよう。 C++の実装? 4.分散処理を使う方法 近似じゃダメ!正確な頻度が欲しい! =>Hadoopつかえ! 色々やってみた感想が良かった。 SuffixArrayのメモリ使用量という話がありましたが、ディスクを使う方法もあります。 by ? 新人から自然言語やり始めたというが、自分が新人の頃にはこんなに出来なかった気がするなぁ。 発表とかもってのほかだったし。 2.AI で AI 創ってみた(LT) @uchumik 資料: Luaプログラミングが出てきたので、 多クラスロジスティック回帰とListNetを書いて見ました。(ただし、本は読んでないよ。) 学習器のお話。 ラグナロクオンラインのAIがLuaでかけることを思い出した。 動画の途中で終了w GitHubにあげなさい。ブログ書きなさい。動画もあげなさい。 by @overlast 資料の割に時間がw 2.5.CMコーナー 技評の方からWEB+DBのCM!(ただし、商品なし) 読者層の95%が男性w 総集編買ってね!WEB+DB plusシリーズも買ってね! 書いてor買ってね。 技評さんつぎはオライリーさんに負けないように賞品持ってきてねw 3.Mahout にパッチを送ってみた @issay 資料:http://www.slideshare.net/issaymk2/mahout-10539755 人がやめていく会社で検索やHadoopやってます。 ※今日は皆既月食です。 機械学習関連 SGDはMapReduceでの分散に対応していないので、パッチを送ってみた。 MapReduce、Shuffleなどの説明 これをベースにナイーブベイズの説明をあわせて実装を見てみる。 ・単語wのカテゴリcにおける確率 ・文書dのカテゴリcにおける確率 -文書dに出てくる単語wの確率の積と定義 単語の相関を見ない。 ゼロ頻度問題の解説 文書頻度の逆数(IDF) カテゴリ毎の文書数のばらつきに対応するために、Complement Naive Bayes BayesFeatureDriver 次はランダムフォレスト 決定木とは? ランダムフォレストとは? ここでは素性。 Mahoutでの実装は? 決定木の数だけ処理分散が可能。 Reducerは使ってない。=Mapperで計算が終わっちゃうから? 次はロジスティクス回帰 尤度関数、損失関数、確率的勾配降下法(SGD) 先程まではオンライン。バッチ学習もある。 Mahoutでの実装はオンラインで、MapReduceに向いてない! Adaptive Logistic Regrettion(アダプティブロジスティクス回帰)というのも実装されてる。 送ったパッチの概要 Iterative Parameter Mixisngというのがあるので、それをSGDに適用するパッチ 今後 MapReduce以外も増えるかも。 Q:パッチがはいったバージョンはいつでる?A:3日前に送ったのでまだです Q:ナイーブベイズのMapReduceが一段ムダでは?(文書数のカウントは同時に出来るよね)A:そうですね、ぜひパッチを送ってみてください。 Q:Mahout、Hadoopの未来は明るいんでしょうか?A:HDFSのデータをMapReduce以外のフレームワークで使えるといい。 Q:Hadoopのパッチ送るの大変ですか?どのくらいかかりました?A:4,5ヶ月かかりました。 すみません、途中から頭がパンクしてしまいました。。。 ただ、MahoutがHadoopに乗っかってるからといって、MapReduce活用できてるわけじゃないという話がわかりました。 4.GraphDBのデータ構造 @kimuras 資料:http://www.slideshare.net/skimura/graphdatabase-data-structure LTみたいな資料にになっちゃいました。すみません。 mixiではMySQLだけど、いろんなDB触ってます。 なので、GraphDBに興味持ちました。 Luceneを教科書的に読んでます。 Neo4jモダンな作りでよかった。 http://www.slideshare.net/skimura/ss-8787632 ノードデータの構造 NodeManagerというのがいて、Cache系を管理してる。 プロパティのインデックス、トランザクションManagerもいて、PersistenceManager ここからNodeにアクセス(探索、)。 キャッシュとかいいね。 Soft LRU Cacheってのもあるよ。 その他色々w Q:トランザクション周りでLRUのキャッシュはどうなるんでしょうか@kumagi A:きちんとロックしてました。 Q:分散はネットワーク、HDDどちらがキツイ?A:HDDがかなりきつい Q:プロパティもキャッシュに乗ってたほうがいい?A:プロパティも必要なら載せたほうがいい。メモリのしてはできたはず。 Luceneがほめられてました。Neo4Jの 5.冬のLock-free祭り @kumagi 資料:https://docs.google.com/viewer?a=v\u0026amp;pid=explorer\u0026amp;chrome=true\u0026amp;srcid=0B72X9w6tG5q0NzMyODgwNDYtNjY4Yy00ZDgwLTliZDMtMjQwYmViMWE5NGU5\u0026amp;hl=en_US ※資料がうまく見れないのは、アニメーションガチガチって話だからかな? http://twitter.com/#!/kumagi/status/145363169718697984 辻Lock-free活動してます。 Lock-freeとツイートすると補足されるらしい。 CPUの系譜のおさらい ポラックの系譜 最新のIntelManyCoreとか東大とかに配られてるらしい。 なんで、マルチコアのCPUがTSUKUMOとかで売ってないの? 僕らが使いこなせてないから。=マルチスレッドの対応がうまくできてないから。 CAS=Compare And Swap まずは、Lock-free stack ABA問題? Lock-free Queue QueueのEnqueueの場合は2回のCASが必要になる。 不変条件を守る。ロックだと守りやすい。 2回のCAS処理の間が危険領域 Lock-free List 色々なロックの説明。 Lock-free hash map これも気が狂ってるアルゴリズム? ConcurrentHashMapなども話が出てきたが、説明しない=Lock-freeじゃないからw Lock-free SkipList SkipList: 順序関係のあるデータをO(log n)で検索・挿入・削除ができるデータ構造(2分木ともろかぶり) DougLea先生がjava.util.concurrentに入っています。 Lock-free Btree 論文ないんですよ。簡単すぎて。 SoftwareTransactionalMemory The Art of Multiprocessor Programmingを読みましょう! 論文のお話。 http://labs.gree.jp/Top/OpenSource/Flare.html を利用しているらしい。 The Art of Multiprocessor Programming関連サイト http://www.cs.brown.edu/courses/cs176/lectures.shtml すごくわかりやすかった。資料をもっと見たいなぁ。 Q:STMはメモリ使用量が2倍になる?A: Q:STM(Clojure)使ってみたけど残念な性能しか出なかったけど、なんで?A:Clojureのものはロックベース。でうーむ。。。 6.機械学習と最適化の基礎(仮) @tkng PFIの徳永さん 日本語入力を支える技術(技評)2012年2月発売予定 最適化の話、機械学習の話、学習率の話。 大域的最適、局所的最適の説明。(言いにくそう、大域的最適w) 凸最適化問題=最適解が1つしかない? 大域的最適解=局所的最適解 機械学習なはなし。 スパムメールの例で説明 淡々と語られてましたが、わかりやすい説明でした。もっと昔にこんな形で数学の説明聞きたかった。。。 7.機械学習・言語処理技術を用いた誤り検出・訂正(LT) @mamoruk 資料: スペル誤り訂正とかに機械学習とか使われてます。 8.神の言語による自然言語処理(LT) @AntiBayes 資料:http://www.slideshare.net/AntiBayesian/ss-10539347# Lispさいこー Clojureさいこー lucene-gosenもいいよーw 9.言語判定へのいざない(LT) @shuyo 資料: Solrで採用されたlanguage-detection libraryの紹介。 アゼルバイジャン語とか大変みたい。 12.作ろう!簡潔ビットベクトル @echizen_tm 資料:http://www.scribd.com/doc/73565169/Lets-Impl-Sbv 入門編: 簡潔データ構造 データサイズをほぼ情報量的下限にまで小さくしたデータ構造 データは小さいし、速度速いというのがこれ。 実用化されてる。 mozc(LOUDSが使われてます) Sedue(圧縮接尾辞配列(デフォルトではなくなった by @tkng)) 種類: ビット列:ここの説明がこのあと 木構造:トライ木をLOUDSが結構で実装するケースが多い。データサイズが小さくなる 文字列:ウェーブレット木が有名。全文検索、転置インデックスにウェーブレット木を使う研究が多い。 中級編 簡潔ビットベクトル: rank(i)関数:i番目より前の立っているビットの数。 疎なデータ列の効率的な実装に使える。検索結果が少ない場合のFacetとかに使える? select(i)関数:? 可変長データ列の効率的な実装 上級編 ダメでした。。。ごめんなさい。。。 体力的に厳しかったです。。。けど面白いし、わかりやすい。どういった所でこれらを使うべきかを取捨選択するのがすこし難しそうです。Luceneとかの内部ソース見ると実はこのあたりで実装されてる部分があったりするのかも。 11.類似文字列検索の仕組み @overlast 資料: 使い所のはなし 例:辞書メンテナンスコストを軽減したい 架空の事例から類似検索を適用できるというストーリー 既存データが活用されるうれしさの例? Apporoのデータ構造とかの話かな? 11.5.審査委員長から賞品持って帰る人の発表 @kumagi @tkng @echizen_tm の方たちでしたー 12.懇親会 いやぁ、前回も感じましたが、基礎ができてないなぁと実感できた勉強会です。 そして幅も広い。やはり、数学的な要素が時々出てくるのでその部分をもっと身につけないといけないなぁと。。。 ついていけなかったところも多々ありましたが、頭の中にキーワードが入ってればなんとかなるかなぁと。 Neo4jやLuceneのソースコードリーディングをやるのが仕事に役立ちそうなので、少しずつでもやろう。 これから懇親会なので、とりあえず、このへんで。 あとで、見返しながら、リンク貼り直したりすると思います。\n","date":1323529475,"dir":"post/2011/","id":"16fa0e4aefe18e1446bf6baefd3ba400","lang":"ja","lastmod":1323529475,"permalink":"https://blog.johtani.info/blog/2011/12/11/%E7%AC%AC2%E5%9B%9E-%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0%E3%81%A8%E6%83%85%E5%A0%B1%E6%A4%9C%E7%B4%A2%E3%81%A8%E8%A8%80%E8%AA%9E%E5%87%A6%E7%90%86%E5%8B%89%E5%BC%B7%E4%BC%9A%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-12-11T00:04:35+09:00","summary":"ということで、懲りずに#DSIRNLPに参加してきました。 基礎的な部分をおろそかにしたくないけど、TokyoNLPとかWebMiningでは","tags":[],"title":"第2回 データ構造と情報検索と言語処理勉強会に参加しました(Jugemより移植)"},{"contents":"ひさびさに、MBAのお話です。 セットアップといっても、物理的な方ですね。 以前、ケース(カバー)について記載しました。 この記事にも書いてあったのですが、付属の滑り止めが簡易なシールで、カバンの中から出し入れすると剥がれるは、作業をしてるとずれるわで、悩んでいました。 今日、たまたま、東急ハンズに行くことがあったので、店員さんに相談してすべり止め対策のグッズを購入しました。 相談した所、カバーは傷がつきにくくなるような素材ですから、シールもつきにくいとのこと。(言われてみればそりゃそうか。) 対策としては紙ヤスリで傷つけたところに薄手のシールゴムをつければはがれにくくなりますよとのこと。 ということで、やってみました。まぁ、ゴムにホコリはつくかもしれませんが、今のところ滑らず快適! いやぁ、ハンズの店員さんすごいですわ。 MBAについてはこんなとこです。最近また、出先に行っていてMBA使えないので、ブログを書くかメールにしか使ってないです。。。\nで、もう一つはMac Mini(2009 late:Core2Duo 2.26GHz、メモリ4G、HDD250G)です。 前職の同期から安く譲ってもらいました。音声が出力されないという問題点があるとFacebookでつぶやいているのをみて、興味を持ったらゲット出来ましたw で、セットアップをしたのです。 大変でした。まずつまずいたのが、キーボードとマウスでした。 これまで使っていたデスクトップのキーボードがあるのですが、これがPS/2ということで使えません。(軽いジャブ) MBAのキー配列にも慣れてきていたので、ビックカメラで悩みながらもApple純正のワイヤレスキーボードとまじっくトラックパッドを購入。 で、まずは、付属のLeopardで初期化。 このときは、ワイヤレスキーボードは認識したのですが、マジックトラックパッドはこの時代に無かったらしく、反応せず(さらに軽いジャブ) さすがに前のPCのマウスはUSBだったので、これを利用してセットアップ再開 次にSnow Leopard(これもつけてくれた)にアップグレードして最後にLionです。 Snow Leopardでソフトウェアアップデートしたところでようやくトラックパッドが認識できたと。 で、やっと使い始めたのですが、MBA(2011)に慣れていたので、思いの外もっさりした動きをしているMacMiniに 戸惑ってます。(トドメのストレート。現在ここ) ということで、どうやれば快適に使えるかアイデア募集中です。 とりあえず、Lionの設定のウィンドウ復元機能やアニメーションをオフにするなど対策してます。 HDDのSSD化とかメモリ増設とか考えないとダメかなぁ。 あと、ついでにBootcampも興味があるので、せっかくだから実験する予定です。 Windowsが前のデスクトップより快適に使えるようになるなら、Windowsマシンとするのもありかなぁと。。。\nセットアップ系はこのへんで。 あとは、最近興味が有ること2点です。(技術系ではありません) 1つ目は最近発売されたゼルダ。夜な夜なやってます。 もともとゲーム好きでゼルダも欠かさずやってきてますが、ゼルダらしさを残しつつ新しい要素やアクションも取り入れとなかなか楽しいです。 ただ、Wii全般に言えることですが難しい!まぁ、楽しんでますけどね 2つ目は前からつぶやいてるのですが、電子書籍を読むためのタブレットがすごく気になってます。 最初は財布に優しく、MBAを普段持ち歩いてるのもあるから、LenovoのA1(7インチ)で決まりだと思っていたのですが、技術書を読むのは少しキツイかもという印象。 どうしてもオライリー本などの大きめのサイズになるため、7インチの画面でPDFを表示したところ、字が小さくなってしまい拡大しないと見づらいのです。 ただ、拡大してしまうと今度はパッと見るという一覧性が下がってしまいます。。。 少々重くなってもいいので10インチにしたほうがいいのかな、けど、電車で立って読むの辛いかもなどなど考えているところで最終的な決断ができない次第です。。。 最初は毛嫌いしていたiPad2もいいかもと思う始末で困ってるとこです。 安い中華パッド(2万ちょっと)に手を出すか、7インチで我慢するか、Galaxy Tab 10.1のWifi版を輸入業者から購入するかと悩んでるところ。 ただ、長く使うのを考えると、OSのバージョンアップなどを保証してくれるiPad2が実はいいじゃないかなぁなど。 皆さんからしてみればくだらないなぁと思われるかもしれないけどずーっと悩んでつぶやいたりしております。 はぁ、こまった。(そもそもそんなにスペックいらないんじゃないかというのもあるからなぁ。メインはPDF読むことだから。) ゼルダの伝説 スカイウォードソード (期間限定生産 スペシャルCD同梱) ","date":1322668828,"dir":"post/2011/","id":"6e970d0818d58ff2d50c5bf037b1a565","lang":"ja","lastmod":1322668828,"permalink":"https://blog.johtani.info/blog/2011/12/01/mba%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97%E5%82%99%E5%BF%98%E9%8C%B2%E3%81%9D%E3%81%AE%EF%BC%95%E3%81%A8mac-mini2009late%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97%E3%81%A8%E3%81%9D%E3%81%AE%E4%BB%96%E3%81%8F%E3%81%A0%E3%82%89%E3%81%AA%E3%81%84%E8%A9%B1/","publishdate":"2011-12-01T01:00:28+09:00","summary":"ひさびさに、MBAのお話です。 セットアップといっても、物理的な方ですね。 以前、ケース(カバー)について記載しました。 この記事にも書いてあった","tags":["備忘録"],"title":"MBAセットアップ備忘録その5とMac Mini(2009late)セットアップとその他くだらない話(Jugemより移植)"},{"contents":" どんな本でも大量に読める「速読」の本 Twitterで知り合った方がこの本について書かれていたブログ記事を読んで興味を持ち、読みました。 書籍(特に技術書)が山になっていたこともあり、速読に興味を持っていたところちょうど記事を目にしたのは きっと何かのタイミングなんだろうなと。\n悪い癖で、電車で読もうと本を常に持ち歩くのですが、ついついスマートフォンやゲームで遊んでしまい、今回も読むのに時間がかかってしまいました。 3章の途中までを今月頭に読んでいたのですが、そこから少しほったらかしで、読み終わったのが昨日でした。\n本の内容ですが、先ほどのブログにも書かれていますが、速読は技術ではない。 ### 速読 = 速読技術 X ストック(知識、経験、情報) であると。あとは、わからなくてもいいから、ざっと目を通す感じで繰り返し読みなさいと。 さらに、1回でわからんくてもいいから、とにかく繰り返し読むことが重要だということでした。\n確かに「速読=1回で速く読む」、「読書=1回で理解する」という意識がどこかにあったなぁと気付かされました。 プログラム組んだり、あることを覚えるときは繰り返しを意識してたのに、読書は1回読んで「はい、おしまい。」という気になってました。(マンガは繰り返し読むんですけどねぇ)\n他の速読の本は胡散臭いし、絶対無理だよなぁと思ってたのですが、この本に書かれている話は筋が通っているように感じました。 ただ、考えずにサラサラ読みなさいという部分の実践はなかなか難しいかな。どうしても頭の中で音読してしまうので。 私は間を開けてしまったせいで、時間がかかってしまいましたが普通なら1日あれば読める内容なので速読に関してちょっとと思ってる方は読んでみると面白いかと思います。\nちょっとだけショックだったのは、この本の論理だと電子書籍は速読に向いていないというところです。 せっかく溜まった書籍をPDF化して、タブレット購入して(まだ買ってない。。。)読もうと思っていたところなのに。。。\n","date":1322542620,"dir":"post/2011/","id":"0ebe78077c8b48410cf52a0bccdff866","lang":"ja","lastmod":1322542620,"permalink":"https://blog.johtani.info/blog/2011/11/29/%E3%81%A9%E3%82%93%E3%81%AA%E6%9C%AC%E3%81%A7%E3%82%82%E5%A4%A7%E9%87%8F%E3%81%AB%E8%AA%AD%E3%82%81%E3%82%8B%E9%80%9F%E8%AA%AD%E3%81%AE%E6%9C%AC%E3%82%92%E8%AA%AD%E3%81%BF%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-11-29T13:57:00+09:00","summary":"どんな本でも大量に読める「速読」の本 Twitterで知り合った方がこの本について書かれていたブログ記事を読んで興味を持ち、読みました。 書籍(","tags":["読書"],"title":"「どんな本でも大量に読める「速読」の本」を読みました(Jugemより移植)"},{"contents":"Hadoopソースコードリーディング第7回に参加しました。 いつものごとく、自分用のメモをとっていたので。 第6回(2010/12)には参加してたのですが、あれからそういえば、話が無いなぁと思っていたところに 再開するという話がTwitterに流れてきたので、即申し込みしました。 思い返せば、Hadoopに興味をもって少し触っているところで参加したのだったなぁと感慨深い思いを思い出しました。\n今回は場所を変えて豊洲のNTTデータさんで開催されました。\n日時:2011/11/28(月)19:00~22:00 場所:豊洲センタービルアネックス NTTデータ\n◎アジェンダ+導入(NTTデータ 濱野さん) ちょっと間が空きましたが隔月で行う予定。 2012/01/12くらいに次回を予定。ネタ募集中。 ◎Hadoop World NYC 2011 参加レポート - NTTデータ 下垣 徹さん (Hadoop徹底入門著者の一人です!) ・イベント概要:2011/11/08~09にNYで開催 スポンサー企業の数がどんどん大きくなってる。 ・会場の様子 最初のキーノートは立ち見が出るほど。 個別に5並列でセッションが開催されてましたと。 ・キーノート紹介 1.Hadoop World(Michael Olson) アンケートからの概観 HadoopはNext Generation DataCenterだそうで。 2.JP Morgan(Larry Feinsmith) コスト削減+収入増加のためにHadoopつかうぞと。 BigData分析の戦略 ユースケース1:ETL(Extract/Transfer/Load)ツールとして ユースケース2:共通データ基盤 検索頻度が低いデータの低コストストレージなどなど。 ユースケース3:データマイニング 異常値検出とか。 3.eBay(E. Williams) Cassini:オークション情報の検索エンジン 柔軟な検索+協力なランキング機能 Hadoopで転置インデックス作成=Luceneは使ってるってことかな? HBaseも利用。データはHBaseに登録してる。 4.Informatica(James Markarian) データとプロセス Hadoopが賑わうからRDBMSも活気づく Hadoopはプラットフォームになるよと 5.Cloudera(Doug Cutting) Hadoopの背景と今後について BigDataを分散処理するためのカーネルになりつつあるよと。 Apacheプロジェクトの良さ 類似するプロジェクトも共存させてるよと。 Hadoopの今とこれから(0.20(今)、0.23(将来)) 0.23はHDFSの性能面改善、スケーラビリティの強化、HA MapReduce2.0 CDH4のはなし。 Hadoopコミュニティはまだまだ若い ・HadoopWorldの傾向 HBaseの利用増加 利用理由? 小さいレコードにも強い。 ランダムアクセス 大手ベンダ参加 Oracleすげー。Hadoopの周りを固めていくぞと。 Hadoopの周りを各社がどう固めていくかというはなし。 事例が多い WibiData:HBaseの利用事例。Fonedoctor Walt Disney:Big Dataに対する機会損失があるから、導入するよと。 テーマパークの交通流解析にも使うぞ! イケメンによる来年(2012年)のHadoop Worldの動向!? 参加者3000人! ラスベガスで開催? スポンサー拡大で食事が美味しく!? 全方位戦略vs.特化型 BIツールベンダの巻き込み 利用事例のアピール合戦 HBaseの利用事例が続々!(Salesforce.comあたりがセッション持つんじゃね?) Hadoop対抗アプリケーション、業界特化型キラーアプリケーションがますます増える? Mahout事例の増加 データマイニング+Web勉強会 - NTTデータ 政谷さんのHadoopNYでの発表のダイジェスト まずは印象。深く使っている人は去年より減っている。バズワードになってるからかな? 今後もHadoopコミュニティは健全なコミュニティになりそう。(いろんな所が出てきたけど、大丈夫そうだなぁ) ・発表スライドのダイジェスト版 日本でのHadoopの盛り上がりの話。 Hadoopと他との住み分けの話。 Sqoopのお話。PostgreSQLに向けたインテグレーションの話。これはPostしてコミット待ち。 Low-Latency Serving Systemへの受け渡し(前処理はHadoopでGPGPU使ってデータをクラスタリングして処理速度をあげる) FujitsuのETERNUSにHDFS APIが用意されたという話。 MapRの話に似ているよと。小さめのクラスタの場合に有効?セッションの後に少し話題になった。 扇子を配りましたよと。 ※ビールが配られ始めた!(ビールじゃないという声もチラホラw) ◎『Hadoop Troubleshooting 101』 セッションレポート - Cloudera 嶋内さん (@shiumachi) Hadoopを壊す7つの方法 Hadoop設定したりしたことある人?=結構いた。さすがソースコードリーディング Clouderaでは木曜日に重要なミーティング(ボードゲームするかFPSするか)というのがあるらしい。 チケット分析 設定ミス? HadoopやOSの設定ファイルの変更を必要とするあらゆるチケットの事 35%が該当 問題の原因別のグラフ 1番は設定ミス 2番はバグ(これはベータ版リリースからチケット管理してるから) メモリの管理ミス Task Out Of Memory Error io.sort.mb \u0026lt; mapred.child.java.optsとなるように設定すること io.sort.mb = mapバッファのサイズ mapperとreducerを減らす。 mapper=ノード上のコア数 これは机にはっとけ! Total RAM = (Mappers + Reducers) * Child Task Heap + DN heap + 3GB + RS heap + ? JobTracker Out Of Memory Error JTのメモリ使用量の合計 > 割り当てRAM 原因は? タスクが小さすぎ jobヒストリが多すぎ 解決は? maximumを減らしなさい? Unable to Create New Native Thread どういう意味? プロセスが起動中にもかかわらずDNが障害ノードとして表示されている。 原因は? nprocのデフォルト値が低すぎる 対応は? /etc/seurity/limits.confの値を考えろ Too Many Fetch-Failures 元スライドの発表者はこれが大好きらしい どういう意味? Reducerのfetch操作がmapperの出力の取得に失敗 ブラックリスト入りのTTで発生するらしい 原因は? DNSの問題 対応は? mapred.reduce.slowstart.completed.maps = 0.80 reducerの開始を遅らせることで対応 tasktracker.http.threads = 80 Jetty 6.1.26は使うな!CDH3u2に上げましょう。 Not Able to Place Enough Replicas 。。。きっとどっかにスライドあるからメモはこのへんでいいか。。。 ◎Hadoop World NYC 2011 参加レポート - Acroquest Technology 阪本 雄一郎さん (@frutescens) 落合 雄介さん (@taro_x) ・RとHadoopの融合(Revolution AnalyticsのDavid Champagneさん) R言語の紹介 Rとの接続点(rmr、rhdfs、?) R言語の利点がHadoopで使えるから、記述が少なくて済むよと。 統計処理がわからなくてもRが使えると分析ができるよ。(そう言われても、その分析で正しいのかとかは結局統計とかをある程度理解してないと厳しいんじゃないか?) ・Hadoopを使った衛星画像解析 スケールとかしたいからHadoopにしたけど、ジョブ起動遅いし、科学計算ライブラリが不十分 ・Hadoopをクラウド上に展開(vmware) Hadoopだけじゃなく、NoSQLとかもスケールしてから使いたいよねぇ。 ということで、vmwareの色々なものを使ってHadoopと他をうまく構築しますよ事例紹介。 マルチテナントのHadoopの話とかもありますよねと。 ◎最後はHadoopには関係ないのが多かったけどおみやげ争奪戦。 なぜか、MongoDBのシールをもらいました。 ということで、HadoopWorld2011の総括+各スライドの紹介でした。 これまでのHadoopWorldの傾向などから、参加者などのトレンドがどうなっているかなどの話が聞けたのが面白かったです。 ClouderaのスライドはHadoopのトラブルシューティングとして必見になりそうな感じでした。 内容が濃くて、それほど触っていない私にはわからないところもチラホラ。(日本語資料の公開されるかなぁ?) 案の定、ビール(発泡酒)を飲んだので、途中から一部が飲み会状態になってたし、ピザ食べてたので、私のメモも途中から適当になってしまいました。 あとは、とある件についていろんなかたからの知見を入手できたのが良かったですね。 他にもLilyプロジェクト(Solrが利用されているOSSの話)の話もあったようなのですが(HPの方が教えてくれました)、今回の参加レポートでは含まれてなかったです。(話聞きたかったなぁ。余力があれば、スライド読むかなぁ。誰か発表してくれないかなぁ) 今日もまた、Twitterで絡んでいた方たち数人と面識が得られました。 今後は定期開催の流れになるようなので、これからもHadoopにしがみついていくためにも参加するようにがんばりますよと。\n会場提供のNTTデータのみなさん、発表者の皆さんお疲れ様でした。次回も期待してます!!\n2011/12/01追記 Togetterのまとめ\n","date":1322499060,"dir":"post/2011/","id":"924727b6f380cf3cdfe5650163e92054","lang":"ja","lastmod":1322499060,"permalink":"https://blog.johtani.info/blog/2011/11/29/hadoop%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89%E3%83%AA%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0%E7%AC%AC7%E5%9B%9E%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-11-29T01:51:00+09:00","summary":"Hadoopソースコードリーディング第7回に参加しました。 いつものごとく、自分用のメモをとっていたので。 第6回(2010/12)には参加して","tags":["勉強会"],"title":"Hadoopソースコードリーディング第7回に参加しました。(Jugemより移植)"},{"contents":"先週末から勤労感謝の日まで風邪で寝こんでました。。。 みなさん、朝晩、冷え込みが激しいので風邪には気をつけてください。\n季節の言葉も入れたので本題です。 つい最近、「Apache Solr入門」のサンプルをlucene-gosenでどうやって動かすんですかー?という質問を受けました。 確かに、「Apache Solr入門」を書いたのはSolrのバージョンが1.4が出る直前でしたし、lucene-gosenは存在せず、 当時はSenを元にした日本語の形態素解析のサンプルとなっていました。 そのSenも入手しづらくなってきており、私もlucene-gosenのプロジェクトに携わるようになってきてある程度時間が 経ちました。 せっかくなので、サンプルのschema.xmlだけでも最新版(Solr 3.4 + lucene-gosen-1.2.0-ipadic)のものを用意しました。 なお、あくまでも、3.xでlucene-gosenを利用する場合の「Apache Solr入門」のサンプルプログラムの変更点(とりあえず、4章まで)の違いについて記述します。 申し訳ございませんが、1.4と3.xの違いについての説明はここでは行いません。\n以下では、各章でschema.xmlに関連する記載のある部分を抜粋して、変更点と変更したschema.xmlのリンクを用意しました。参考にしてもらえればと思います。\n1章 1.6.1 N-gram(17ページ) 1.6.1の手順に変更はありません。 サンプルプログラムが入っているZip「solrbook.zip」のintroduction/ngram/schema.xmlファイルの代わりに こちらのschema.xmlを利用してください。\n1.6.2 形態素解析(18ページ~20ページ中盤まで) 手順が大きく変わります。 Senを利用する場合、Senの辞書のビルド、Senのjarファイルの配置、Senを利用するためのTokenizerクラスを含んだサンプルjarの配置という作業があります。 lucene-gosenではコンパイル済みの辞書がjarファイルに含まれています。 また、Solr向けのTokenizerもlucene-gosenのjarファイルに含まれています。 lucene-gosenを利用して形態素解析を体験するための手順は次の流れになります。 なお、schema.xmlについては上記N-gramでダウンロードしたschema.xmlに形態素解析の設定もあわせて記載してあります。\njarファイル(lucene-gosen-1.2.0-ipadic.jar)をダウンロードして、$SOLR/example/solr/lib(libディレクトリがない場合は作成)にコピーします。 コピーが終わりましたら、次のように$SOLR/exampleディレクトリでSolrを起動します。 (-Dsen.homeは必要なし)\n$ java -jar start.jar あとは、書籍の記述にしたがって管理画面のAnalysis画面で動作を確認します。 ほぼ、図1-6と同じ結果になっていると思います。 (lucene-gosenで出力される情報には本書のサンプルよりも多くの情報が含まれています。また、サンプルでは、形態素解析の後の単語に基本形を採用しているため、「な」が「だ」として出力されています。基本形を出力する場合は後述するこちらで紹介したTokenFilterを利用すれば可能です。)\n2章 2.1.3 schema.xmlのバージョン(27ページ) Solr3.xではschema.xmlのファイルの最新バージョンは1.4になっています。\n2.2.3 代表的なトークナイザ(35ページ) solrbook.analysis.SenTokenizerFactoryは必要ありません。 先ほども説明しましたが、lucene-gosenにはSolr向けのトークナイザが用意されています。 solr.JapaneseTokenizerFactoryがそれに該当します。\n2.2.4 代表的なトークンフィルタ(37ページ) 以下の2つについてはlucene-gosenに同等のトークンフィルタが存在します。\nsolrbook.analysis.KatakanaStemFilterFactory solrbook.analysis.POSFilterFactory それぞれ、次のものがlucene-gosenにあるので、こちらを利用します。\nsolr.JapaneseKatakanaStemFilterFactory solr.JapanesePartOfSpeechStopFilterFactory 2章向けのschema.xmlはこちらです。その他のtxtファイルについては、特に変更はありません。\n3,4章は特に変更はありません。Solrの起動の仕方にだけ注意してください。(-Dsen.homeは必要ありません)\n以上が4章までの修正点になります。 動作しないなどあれば、コメントください。 サンプルアプリについてはまた後日余裕があれば。。。\n","date":1322244000,"dir":"post/2011/","id":"26d48d68b28f927bfebad454658f9425","lang":"ja","lastmod":1322244000,"permalink":"https://blog.johtani.info/blog/2011/11/26/apache-solr%E5%85%A5%E9%96%80%E3%81%AE%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%81%AElucene-gosen%E5%AF%BE%E5%BF%9C1%E7%AB%A0%E3%81%8B%E3%82%894%E7%AB%A0/","publishdate":"2011-11-26T03:00:00+09:00","summary":"先週末から勤労感謝の日まで風邪で寝こんでました。。。 みなさん、朝晩、冷え込みが激しいので風邪には気をつけてください。 季節の言葉も入れたので本","tags":["lucene-gosen"],"title":"「Apache Solr入門」のサンプルのlucene-gosen対応(1章から4章)(Jugemより移植)"},{"contents":"今回は、触ろうと思って触れていないMongoDBの勉強会に行って来ました。 2週連続の渋谷で、さすがに今回は出口をすんなりでれました。 今回は初のGMOさんのビルへの潜入です。 ということで、いつものごとく自分のメモを残しておきます。\n日時 :2011/11/15 14:30 to 20:00 定員 :140 人 会場 :GMO Yours (セルリアンタワー(11階)) ハッシュタグ :#mongotokyo\n1.fluentd plugins for MongoDB @doryokujin スライドはこちら。\nFluentとMongoDBのコラボレーション ・Fluentとは? 解析対象のログについて。データ量が膨大 これまでのログの扱い方。日次でS3に送信して、ログ解析サーバにて前日分を解析する。 これではリアルタイム性がないのが問題!しかも1日分なので、データ量が半端ない。 そこでFluentにてストリーミングアプローチ。 リレーサーバ(Fluentd)にログを流すと、適宜、解析サーバに流れていく仕組みが可能。 これにより、ネットワークに負荷をあまりかけずにログを定期的(時次とか)で流せる。 ※splunkに近い考えかな。 ここで、Fluentのスライドで説明が入りました。http://www.scribd.com/doc/70897187/Fluent-event-collector-update ・Out Mongo For Local Back-Up MongoDBへの出力。 信頼性をあげるためにローカルにmongoDBを置いておき、スプールしておく。 リレーサーバにも配置してみるという仕組み。 バッファリングにMongoDBを使うので Aggregation Mongoってのを作ったらしい。そのせいで、スライドの作成が遅れたらしいw ・Aggregation Mongo Map/Reduceの集約のようなプラグイン。 fluentdのアプリを通して、特定のキーをベースに集計してから、outputする仕組み。 更に、キーに対してshufleが行われて、次のfluentdにデータが集まる。 fluentdを使ってM/Rっぽいことが可能なのかな。 QA 最終的な流れ込み先のMongoDBはCappedCollectionじゃなくしたほうがいい。検索とかしたくなるから。 2.about Server Density and MongoDB @davidmytton スライドはこちら\nQueuingシステムで利用。 MongoDBとRabbitMQとの比較? MongoDB関連のノウハウかな。 データ量に関する話。メモリに載せたほうがいいのかとか、ログ出力の設定とか、ジャーナルとか。 HDDの見積もりに関連しそう。 健康状態の監視方法。 コネクションプールの話とか。 rs=ReplicaSet? mongostatってコマンドがあるのか。 ServerDensityのツールとダッシュボードなどについて。 ※英語のスライド見ながら話聞くとメモがとれない。 まとめ: Keep it in Ram インデックスはメモリに載せましょう。 Watch your Strage ストレージのサイズは監視しましょう。(ログ、データ、ジャーナルなどなど) db.serverStatus() コマンドあるよ。これで見れるデータが重要なのかな? rs.stats() コマンドあるよ。これで見れるデータが重要なのかな? QA:残念ながら聞き取れなかったっすw Q:MongoDBのクエリログの統計の質問。DBごと?=コレクションごと?のクエリ統計のとり方は? A:MongoDBにはないので、ログレベルを下げて統計取ったりする方法しかないかなぁ。 3.MongoDB: Case Study for AMN @koyhoge スライドはこちら\nサービス(アジャイルメディア・ネットワーク)で利用している実例について 広告配信に関連して利用してる。 最初にPostgreSQLにて実装。5分おきにCronで再起動するはめに。。。 PostgreSQLの次にSimpleDBへ(インサートが遅い。分散インサート) SimpleDB+SQSに変更。1日130$で断念。 SaaSなKVSはやめてMongoDBに移行してみる。 負荷も軽いし、インサートも速い! EC2でMongoDB。しかもレプリカを東京A、B、シンガポールAにしてみよう。 shardingは残念ながらうまく行かず。 ストレージはEBSの1TB 4.「MongoDBとHadoopの蜜月関係」 @muddydixon スライドはこちら\nお父さんエンジニアなので、土曜日の勉強会は無理です!=同じく辛いです! HadoopとMongoDBのつなぎについて。 MongoDBからデータを読み込んで、Hadoopで計算してMongoDBに戻すものがmongo-hadoop データロストがニュースになってて心配してる。データロストはめったにない(by @doryokujin) Hadoopを計算だけに利用できるのでクラスタが落ちても気にせず立ち上げができそう。 MongoDBからデータを取得する時点でフィルタリングが可能なので、Hadoopでの演算が楽。 AdHocなクエリをMongoDBに投げれるのがうれしいのかな? HBaseとかHiveに入れてやったりはダメなんかな? QA Q:なんで、みんなMongoDBにログ入れるの?@kzk_mover A:様々な形式を入れやすいから。 Q:捨てるのどーするの? A:コンパクションが大変(ただし、2.0以降は良くなる予定) Q:MongoDBのMap/Reduceは? A:時間がかかった上に死ぬというひどい目にあったので。。。 5.Fusion-io @hasegaw\n340の仮想マシンが4台で動きます! すごそう。。。一回は触ってみたいかも。 Fusion-ioすげーーーって感じ。(Ustストップ) 6.MongoDB on Cloud Foundry @yssk22\nVMWare社のPaaSオファリングの名称 感想など: mongoDBに興味はあるのに、腰が引けてるおじさんになって結局触らずに会場入りしてしまいました。 会場に入っていきなり、Treasure Dataの太田さんがマグカップを売っているという場面に遭遇するというインパクトがあるスタート。(思わず1個購入) 最初はMongoDB JPの主催者でもある@doryokujinさんの話から。今熱いfluentdとmongoDBの組み合わせに関する話で、面白かったです。 途中でfluentdを作っている古橋さんのスライドを用いてfluentdの解説まで入りました。 TL上では、その古橋さんが時々フォローを入れているという贅沢な流れ。 なんとなく仕組みはスライドなどを見ていたのですが、更に理解が深まりました。 次が、イギリスから来日されていた@davidmyttonさん(なんと24歳という若さ!)のお話。 残念ながら英語のヒアリングは微妙な私なので、あまり理解できなかったのですが、どうやら、MongoDBの運用でのTipsのお話だったようです。スライドを後で見なおしたほうがいいかな。 次は、実際のMongoDBを利用した事例の紹介。PostgreSQLから試行錯誤してMongoDB+AWSの組み合わせのお話。 やはり実例があると面白いですね。試行錯誤された部分があるので、非常にわかりやすかったです。 次が、HadoopとMongoDBの組み合わせのお話。HadoopのMap/Reduceの部分だけを利用して、データ保存先はMongoDBにしましょうという割りきった話でした。 いくつか疑問点がメモにもありますが、残念ながら質問する勇気なしという腰抜けっぷり(もうちょっと積極的にならないと。。。) で、このあとFusion-ioとCloud Foundryの話になるのですが、体力切れ+lucene-gosenのjavadocが古いことに気づいてしまい、作業をしながら聞いていたのであまり頭に残っていません。(ほんとに申し訳ない。。。) とまぁ、最近、Twitter上でいろんな人に絡みまくってまして、@doryokujinにも絡みまくってたというのもあり、今回参加することにしたという次第でした。 懇親会にも多くの人が残っており、良いコミュニティができてるなぁというのが正直な感想です。 各セッションでも@doryokujinさんが適宜QAなどのフォローをされていて感心しっぱなしでした。 あとは、Twitter上で会話をしていた方たちとも顔合わせができたので、大収穫でした。\n次は、少しでもいいので、触ってから参加することにしようかと思います。 来年1月にはMongo Tokyo 2012というイベントも開かれるようで、ますます注目を浴びていきそうですね。主催者もミドルウェアもw\nあ、そうそう、そんなMongoDBの勉強会でしたが、CouchDBの話もちらほら出てまして、CouchConf TOKYOというチラシも@Ijokarumawakさんから頂きました。こちらも1月開催のようです。\n追記: 戦利品の画像です。マグカップ(500円)以外は貰い物です。 なんと、このUSBにはMongoDBのコマンドやクエリのチートシート(PDF)が入ってました。びっくり!\n","date":1321376880,"dir":"post/2011/","id":"bda9a5da86ec9790262e14f953bbadcb","lang":"ja","lastmod":1321376880,"permalink":"https://blog.johtani.info/blog/2011/11/16/mongodb%E5%8B%89%E5%BC%B7%E4%BC%9A%E7%AC%AC7%E5%9B%9E%E3%81%AB%E8%A1%8C%E3%81%A3%E3%81%A6%E6%9D%A5%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-11-16T02:08:00+09:00","summary":"今回は、触ろうと思って触れていないMongoDBの勉強会に行って来ました。 2週連続の渋谷で、さすがに今回は出口をすんなりでれました。 今回は初","tags":["勉強会"],"title":"MongoDB勉強会(第7回)に行って来ました。(Jugemより移植)"},{"contents":"Solr本の武田さんから教えていただいたSplunkの イベントに行って来ました。 Splunkとは様々な機器のログなどを一箇所に集めてリアルタイムに検索、分析できるようにするための製品です。(ざっくりした説明ですが。。。) ちなみに、データ量が小さければフリー版も用意されています。 以前、話しを聞いていて気になっていた所イベントが開催されるということだったので参加してきました。 以下に、その時取ったメモを記載しておきます。いつものごとく、自分用のメモなので、役に立つかはわかりませんが。\nSplunk Live! in toyosu\n日時:2011/11/02 10:00-12:00 場所:豊洲\n1.挨拶+アジェンダ紹介 2.ビッグデータ取り込み、ロードマップ(Splunk Inc.)CEO Godfrey Sullivan 英語でした。。。 データの種類と量が大きくなってきてるのに、ツールが追いつかないし、回答するのもはやくしろと言われる。 非構造化データの例としてApacheのログが出ていた。 TimeSeriesのフラットファイルがsplunkのデータのインデックス。(No RDB=スキーマいらないよと。) ※ここが重要な点かもしれない。 リアルタイムに解析できるのが売り。Jubatusとの違いとか聞くと面白いかも。 Machine Data Engine=Splunk データの関連付けの方法がどんなものか? 事前のスキーマが不要=流しこむ前には定義が必要?だよね? ?No need to filter/forward?? デベロッパーフレームワークってなんだ?? Splunkbaseと呼ばれる場所にSplunk Appsと呼ばれるアプリケーションがある。色々な場所、OS、アプリで利用できるものらしい。 ?自動監視も学習する仕組みがある?? それとも定義するのか? あくまでもMachine Dataと言っている。これは、ユーザのリレーションの解析などはないということか? Leading Social Gaming Company=Zynga Introscopeのログバージョンに似てるかもなぁ。 Cloudベースのアプリの解析にも利用(saleforce) 色々な利用シーンのお話。 3.適用事例(独立行政法人理化学研究所) 和光と神戸で利用。10G程度のデータを扱ってる? ログから情報基盤を監視するのに利用している。 syslogベースでsplunkにログを送信している。 事例1:VPNに接続できない(接続数上限がある?) CISCOのログから解析 どの研究室で発生しているかも検索。 事例2:DHCPの接続ミス?(IPアドレスロスト) ここまでは問題が発生してからログを漁るという使い方。 事例3:LINK FLAPのアラート 短時間にUPDOWNを繰り返す場合にスイッチがおかしくなってるんでは? 事例4:メール大量送信(ウィルス感染) 不特定多数のサーバに短時間でメールを配信している ※使い方としては情報基盤環境すべて(ネットワークとかサーバなど)のログを集めておいて監視+解析に利用して障害対応などに利用している?データセンターとかに入れるのか? あくまでも、ログを保存して、検索できる仕組みが1箇所にまとめられているという感じ。 そのログの解析について(どういった問題に対して、どういったクエリを投げるか?どういったトラップを仕込むか?)は利用する側の腕にかかっている印象。 ※実際に触ってみたいなぁ。500M/dayか。ご近所に入れてみるか?syslogで転送設定+入れるサーバが必要。 4.最新アプリなどの紹介(Splunk Inc.) GUIがきれいだなー(最近のgoogleっぽいが。。。) リアルタイムにデータが入っているのが見えるのか。おもろいな。 どこのフィールドにヒットしたかがファセットで表示できるらしい。おもろい。 flashでできたビューがすごくおもろかったぞ。(ドキュメントどこだ?) 5.最新の取り組み(NTTデータ先端) やっぱり武田さんだった。 複数の監視システムのメッセージを統合して検索、アラートを出せるようにする。 消費電力を算出するためにログを集めて集計する。 6.QA ロードマップ ・2年以内にビジネスサイドでの利用に向けての動きを見せていく予定。 ・アプリケーションフレームワークにして、他のパートナーのアプリを載せていきたい。 ということで、感想ですが、事例紹介などを聴いた感じだと今のところはインフラ系のログを一元化して検索、監視、アラートをあげるということに活用するためのツールの用に感じました。 当初の使い方がそういったところにあるためだとは思いますが。 開発者としての視点で話しを聞いていて、活用できそうだというのは次のシーンでしょうか。\n開発時の開発環境のログ集約 性能試験などでのログ、性能データ集約 開発時点もしくは性能試験時ですが、色々なサーバ(DBやアプリサーバ)の時間を横串にして表示検索などができると思うので、問題があった時の各種サーバの状態を一元的に見れるため、どのサーバにどういった負荷がかかっていたか、 どこに問題があったかなどをグラフ化して見ることが簡単にできるのではないかなぁという感想です。 あとは、ログが一元化されているので、問題があったときにまずログを検索すればいいのが楽ですかね。\n基本的にはログが集まってるからあとは、どう使うかはご自由にという印象でした。 どのようなログを集めておき、どういったトラップでアラートさせるか、どのような検索をすれば望んでいるログが出てくるか、どのような集計をしたいかなどについては、やはり導入してからノウハウを貯めていくか、導入時にコンサルしてもらうなどが必要かと。 また、このツールを入れることでどのようなフィードバックをどのように活用できるかをイメージしていなければ、 宝の持ち腐れになりそうです。 あとは、使い方次第ですが、サーバログ以外にアプリログ(ユーザの行動履歴とか)などを入れることで、インフラ以外での使い道もありそうです。 とりあえず、保存しておいて、あとから特定の傾向を見出すのに検索できるのはちょっと面白いかも。\nあ、そうそう、ストラップとUSBメモリ(4G)のノベルティをお土産にもらいました。無料セミナーなのに。\n","date":1320822000,"dir":"post/2011/","id":"cc1a3b2f107510ac664e491d5f2412aa","lang":"ja","lastmod":1320822000,"permalink":"https://blog.johtani.info/blog/2011/11/09/splunk-live%E3%81%AE%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%81%AB%E8%A1%8C%E3%81%A3%E3%81%A6%E6%9D%A5%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-11-09T16:00:00+09:00","summary":"Solr本の武田さんから教えていただいたSplunkの イベントに行って来ました。 Splunkとは様々な機器のログなどを一箇所に集めてリアルタ","tags":["misc"],"title":"Splunk Live!のイベントに行って来ました。(Jugemより移植)"},{"contents":"最近忘れやすいので、記録しておこうかと。 読んだスライドの簡単な内容と感想です。 ちなみに、スライドの一覧はこちらです。 ※スライドへのリンクはすべてPDFへのリンクになっていますので、注意が必要です。\nSolr 4 Highlights(PDF)\nSolrの次期バージョン4.0で採用される機能の紹介でした。 紹介されているのは次の機能。各機能について、JIRAの番号も記載があるので便利ですね。\nDirectSolrSpellChecker NRT (Near RealTime search) Realtime Get SolrCloud - search side SolrCloud - indexing side (WIP) これまでと異なるSpellChecker、Commit前のデータが検索できるNRT(なんでNRSじゃないんだろう?)、Commit前の登録済みデータを取得することが出来るRealtime Getなどの簡単な紹介です。 あと、個人的に興味のあるSolrCloud周りが絵付きで紹介されてます。ZooKeeperもちょっと出てきます。 まだ、ちゃんとまとめてないですが、NewSolrCloudDesignの翻訳したものも参考までに。(その1、その2)\nArchive-It: Scaling Beyond a Billion Archival Web-pages\nInternetArchiveの事例紹介。1996年からWebページのアーカイブを行なっているサイトですね。 その一部でSolrが利用されています。 「1,375,473,187 unique documents」との記述もあり、データ量が巨大です。 データ量が多いのに、ここでFieldCollapsing/Groupingも利用しているようで、インデックス作成、検索両方に対してカスタマイズしたものをgithubで公開している模様です。\n[**Scaling search at Trovit with Solr and Hadoop**](http://www.lucidimagination.com/sites/default/files/file/Eurocon2011/MarcSturlese_scalingsearchTrovit_eurocon2011.pdf) 次は、Trovitという会社のSolr+Hadoopの事例紹介です。 最初はLuceneをベースに検索サーバ作ってたけど、Solrが出てきたので、Solrを使うようになったようで。 データ保存先として最初はMySQLを利用してDataImportHandlerでSolrにデータ登録してたけど、 データ量が増加するが、MySQLのShardingが面倒なので、Hadoop(Hive)でデータをパイプライン処理してSolrのインデックスを作成しましょうという流れになったようです。 私が以前、Solr勉強会で紹介したSOLR-1301のパッチをベースにMap/Reduceの処理を2段階にして性能をアップさせたという話が記載されてました。 ただ、これで早くなるのかはよくわからないんですが。。。 一応、資料では、いきなり大きなSolrのインデックスを作らずに、最初のM/Rで小さなインデックスを作成し(TaskTrackerの数>>Solrのshardサーバ数だから小さくしたほうが速い?)、 2段目のM/Rでインデックスをマージしてshardサーバ数のインデックスに集約する?という形みたいです。 (英語力のなさが。。。) あとは、テキスト処理を幾つかHadoopでやってますよという紹介でした。 SOLR-1301の利用者が他にもいて、違うアプローチをとっていたのが印象的。 毎回全データインデックス生成するときは、SOLR-1301を利用してshard数が増えてもすぐに対応が可能になるので、 かなり便利ですよ。\nSolr @ Etsy\nEtsyは個人の作家(編み物とかシールとか)の方が出店するためのショッピングモールのようなサイトです。 実は、最近、MacBookAirのステッカーを購入したのがここでした。 で、検索にSolrを使っています。 面白いのが、検索サーバとWebアプリ(PHPで書かれている)の間のデータのやり取りにThriftを利用していること。 Solrの前にThriftを話すサーバを別途用意しているようです。ネットワークのデータ量を減らすことが目的らしいです。 そのあとは、少しThriftのサーバでのLoadBalancingの話が続きます。 次にレプリケーションの性能問題のはなし。定期的にレプリケーションに異様に時間がかかるのが問題になったようで、 Multicast-Rsyncを試してみたけどダメでしたというはなし。 Bit Torrent + Solrという組み合わせで回避したらしいのですが、いまいち仕組みがわからなかったです。。。 こちらもgithubに公開されている模様。 あとは、QParser、Stemmerをカスタマイズしたものの話です。\nArchitecting the Future of Big Data and Search\nLuceneのカンファレンスにHortonworksが出てきてびっくりしました。 まぁ、Luceneの生みの親=Hadoopの生みの親ですから、問題ないのかもしれないですが。 大半が予想通り、Hadoopに関する話でした。 知らないApacheのプロジェクト「Ambari」というのが出てきました。これは、HadoopConferenceJapan2011 Fallでの発表にもチラッと出てきたようです。 「Ambari is a monitoring, administration and lifecycle management project for Apache Hadoop clusters.」ということで、Hadoopクラスタの統合管理のツールになるんでしょうか? 最後の2枚くらいにLuceneが出てきます。絡めてみたって感じですかね。\nConfiguring mahout Clustering Jobs\n今度はMahoutが出てきました。はやりのものが満載です。 まぁ、MahoutもLuceneのインデックスを利用するという話もありますので。 スライドはクラスタリングとはどういうものか、Mahoutの説明とテキストクラスタリング処理のお話、最後はstuckoverflowでのMahoutとSolrの活用の仕方について。\nということで、英語力がない中、かなり流し読みな感じですが、あとで思い出すために書きだして見ました。 何かの役に立てれば幸いです。\n他に、こんなスライドが面白かったとか、このスライドについても書いてほしいなどあれば、コメントください。\n","date":1320724920,"dir":"post/2011/","id":"d9c6ab5c6630a4a84e242c5765103d2d","lang":"ja","lastmod":1320724920,"permalink":"https://blog.johtani.info/blog/2011/11/08/lucene-eurocon-2011-barcelona-%E3%81%AE%E3%82%B9%E3%83%A9%E3%82%A4%E3%83%89%E8%AA%AD%E3%81%BF%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-11-08T13:02:00+09:00","summary":"最近忘れやすいので、記録しておこうかと。 読んだスライドの簡単な内容と感想です。 ちなみに、スライドの一覧はこちらです。 ※スライドへのリンクはす","tags":["solr"],"title":"Lucene Eurocon 2011 Barcelona のスライド読みました(Jugemより移植)"},{"contents":"Bookscanというサービスがあります。 書籍を電子化(PDF)して原本を破棄してくれるサービスです。\n電子書籍にはずっと興味を持っていました。 技術書を購入するのですが、技術書は300ページ超の大きな書籍が大半です。 また、日本語の技術書については、なかなか電子書籍が見つからないもしくは、電子化されるのが遅いとうのが現状です。 海外では、Manningなど、電子書籍も同時に発売(もしくは、製本前から電子書籍が売られている)サイトがありますが、やはり英語の書籍はハードルが高いなぁと。\nそんな中、Bookscanの噂を耳にしました。 ということで、どんどん、積ん読になっていく技術書だったので、思い切って、電子化してみることにしました。 ※残念ながらまだタブレット(電子書籍端末)は持っていないのですが。。。もうすぐ発売されるlenovoの7inchタブレットを待ちかねているところです。\nBookscanでは、1冊100円で書籍をPDFにしてくれます。(ページ数により変わってくる) この場合、あくまでも書籍をスキャンするだけで、検索などはできません。 OCR処理については別途1冊100円(これもページ数による)のオプションが必要になります。 詳しいサービス内容はこちらを御覧ください。 基本的には書籍をBookscanに発送してから約3ヶ月ほど電子化するのに時間がかかります。 これでは、すぐに見たい場合に手元にないという状態になってしまいます。 この電子化までの時間を短くできる、「プレミアム会員」というオプションが存在します。 月額固定の費用(9980円)を支払うことで、50冊(※ページ数により1冊の単位が異なります)まで無料で、「スキャン+OCR+書籍名をファイル名」のPDFファイルを書籍到着後1週間以内で作成してもらうことができます。 また、プレミアム会員は月単位での契約が可能なようで、1ヶ月(=50冊)だけ早く電子化してもらうといった利用方法もできるようです。\nで、実際にプレミアム会員となって49冊の書籍を送付して電子化してもらいました。 先週金曜日に発送、Bookscanに書籍が到着したのが翌土曜日、電子化が完了したのが火曜日の夜という感じでした。 すごくはやい!かなり感動してます。自炊自体をしたことがないので、出来上がりが自炊と比べてという比較はできないのですが、ざっと見ている感じでは全然問題なく読めそうです。\nただ、1冊の2ページだけ、ページの端が文章の途中で切れているPDFがありました。 この書籍に関しては、サポートサービスにお願いして、再スキャンをしてもらいました。 昨日夜に頼んで今日の午後には問題なく電子化されているというサービスの質でとても満足しています。 なお、原本の破棄が電子化後から10日後に行われるため、問題ないかの確認はそれまでに行う必要があるようです。 大量の本を送る場合は小分けに送ったほうが確認するのが楽になると思います。(送料は小分けにした分、かかってしまいますが。)\n書籍の山になっていた机がすっきりして、とても満足しています。 せっかく電子化したので、早くタブレットが欲しいなと思う今日この頃。。。 基本的には今後は電子書籍を購入するようにしていく予定なので、プレミアム会員を継続することはないと思いますが、 家に溜まっている漫画を電子化するのもありかなぁと思っているところです 漫画の場合はOCRに掛ける必要もないですし。\n個人的にはBookscanさんには悪いのですが、もっと電子書籍が増えると助かります。 技術書はページ数が多く、重たいうえ、実際に利用するときは検索したくなることが多々ありますので。 あとは、電子書籍を検索できるサイトがあるといいなと思ってもいるところです。 現在は、各出版社が個別に電子書籍のHPを持っている状況で、会社によっては検索すらできないです。 電子書籍があるかないかだけでも簡単に検索できると、いいなと思っています。(小説などはまた別なのかもしれないですが。) みんなはどう思ってるんですかねぇ?検索したくないですか?\n","date":1320225060,"dir":"post/2011/","id":"7a9609a971a8f31685e88da563eea5ce","lang":"ja","lastmod":1320225060,"permalink":"https://blog.johtani.info/blog/2011/11/02/bookscan%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-11-02T18:11:00+09:00","summary":"Bookscanというサービスがあります。 書籍を電子化(PDF)して原本を破棄してくれるサービスです。 電子書籍にはずっと興味を持っていました","tags":["misc"],"title":"Bookscanを使ってみました(Jugemより移植)"},{"contents":"lucene-gosenの最新版(1.2.0)をリリースしました。\nプロジェクトページよりダウンロードが可能です。\n新規追加機能についてはこちらのエントリを御覧ください。\nバグなどありましたら、容赦なく報告をいただけると助かります。\n","date":1320043560,"dir":"post/2011/","id":"14cf6e75aec1ead888e7101d3d94d28a","lang":"ja","lastmod":1320043560,"permalink":"https://blog.johtani.info/blog/2011/10/31/1-2-0%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9/","publishdate":"2011-10-31T15:46:00+09:00","summary":"lucene-gosenの最新版(1.2.0)をリリースしました。 プロジェクトページよりダウンロードが可能です。 新規追加機能についてはこちら","tags":["lucene-gosen"],"title":"1.2.0リリース(Jugemより移植)"},{"contents":"すぐやりますと言いつつ、はや1ヶ月。。。 腰が重い、ダメエンジニアですね。。。\nすみませんでした。。。 ようやくtrunkにコミットしました。 すぐにリリース版を用意すると思います。\n1ヶ月もあいてしまったので、追加した機能に関するまとめと、 用途別の利用方法を記載しておきます。 (lucene-gosenのWikiにもそろそろ書かないとなぁ。日本語でもいいから。)\n追加した機能\nこれまでのlucene-gosenはjarに辞書を含む形でライブラリを提供していました。 ただ、この場合、カスタム辞書を利用している環境ではカスタム辞書を修正し、ビルドしなおすたびに、 jarファイルを作成しなければなりません。 また、jarファイルをSolrなどに配布する必要も出てきます。 この手間を考慮して、辞書を外部ディレクトリで指定することができるようにしたものが 今回の修正になります。 また、修正の過程で同一VM内で異なる辞書を使えるようにする機能も副産物として生まれました。 今回追加した機能は次のようなものになります。 辞書を含まないjarのビルドおよび提供 ディレクトリ指定による辞書の指定 同一VM内での複数辞書の利用 辞書リビルド用のAntターゲットの追加 Lucene/Solr jarファイルの最新化(3.4.0対応) ディレクトリ指定による辞書の指定ですが、以下のような形になります。 まずは、LuceneのTokenizerでの指定方法です。 「辞書のディレクトリ」という引数が追加になっています。 ここに、辞書ディレクトリ(*.senファイルが存在するディレクトリ)を相対/絶対パスで指定します。\n... Tokenizer tokenizer = new JapaneseTokenizer(reader, null, \u0026#34;辞書のディレクトリ\u0026#34;); ... つぎは、Solrでの設定の方法です。 schema.xmlにて次のような設定を行います。\n... \u0026lt;fieldType name=\u0026#34;text_ja\u0026#34; ...\u0026gt; \u0026lt;analyzer\u0026gt; ... \u0026lt;tokenizer class=\u0026#34;solr.JapaneseTokenizerFactory\u0026#34; compositePOS=\u0026#34;compositePOS.txt\u0026#34; dictionaryDir=\u0026#34;辞書のディレクトリ\u0026#34;/\u0026amp;gt; ... \u0026lt;/analyzer\u0026gt; \u0026lt;/fieldType\u0026gt; ... schema.xmlの設定については、example/schema.xml.snippetにも説明がありますので、こちらもあわせて参考に。 なお、Solrの設定については、先ほどのLuceneでの辞書のディレクトリの指定方法(絶対/相対パス)に加えて、 $SOLR_HOME/conf からの相対パスでの指定も可能になっています。\nAntのターゲットについて\n辞書なしjarファイルを作成するターゲットなどを追加しています。 実際に追加したターゲットは以下のとおりです。 ターゲット名 説明 nodic-jar 辞書なしのjarファイルを生成するためのターゲット。辞書のダウンロード、コンパイルは行いません。 rebuild-dic lucene-gosenのビルド済み辞書(.senファイル)を削除してから辞書のコンパイル(ビルド)を行います。-Ddictypeにより辞書のタイプ(ipadic|naist-chasen)の指定が必要です。また、-Dcustom.dicsによりカスタム辞書の指定もあわせて可能です。 build-dic-ipadic テスト用に追加。-Ddictype=ipadicを指定してbuild-dicを実行。 build-dic-naist-chasen ついでに追加。-Ddictype=naist-chasenを指定してbuild-dicを実行。 最後の2つはあまり関係ありません。内部的に有ると便利だったため、作りました。 重要なのは最初の2つです。 ひとつめの「nodic-jar」は辞書を含まないjarファイルをビルドします。 このjarファイル+辞書の入ったディレクトリを利用することで、辞書の外部化が可能となります。\nそして、「rebuild-dic」です。こちらは、以前記事に書きましたが、カスタム辞書のコンパイルが思いの外面倒だったので、ターゲットを追加しました。 次のように指定することで、辞書のリビルドが可能です。\n$ ant -Ddictype=naist-chasen -Dcustom.dcs=\u0026#34;custom1.csv custom2.csv\u0026#34; rebuild-dic 提供されるjarファイルについて\n提供されるjarファイルは次のようになる予定です。 1番目のjarファイルが今回追加になる、辞書なしのjarファイルになります。\nlucene-gosen-1.x.x.jar lucene-gosen-1.x.x-ipadic.jar lucene-gosen-1.x.x-naist-chasen.jar 用途別の利用方法 利用用途別に利用するjarファイルやantのターゲットを利用シーンを交えて想定を書いてみます。 Solrでの利用シーンを想定します。\nお手軽に使う。辞書ありjarファイルで一発インストール。 これまでどおりの使い方になります。 辞書込みのjarファイルを利用すれば、すぐに利用可能になります。\nカスタム辞書を使い倒す。定期的に辞書をメンテナンス。 定期的にシステム固有の単語が増える(例:製品名、新語など)場合です。\n利用するjar:lucene-gosen-1.x.x.jar 辞書のコンパイル+配置:ant -Ddictype=naist-chasen -Dcustom.dics=\u0026ldquo;custom1.csv\u0026rdquo; rebuild-dir Solrの該当コアのRELOAD Solrのマルチコア環境を利用します。なお、sharedLib設定にlucene-gosen-1.x.x.jarを配置すると、辞書の再読み込みができないので注意してください。 設定は、上記のようにTokenizerFactoryの設定でdictionaryDirにて辞書のディレクトリを設定しておきます。 カスタム辞書に単語を追加後、antにて、辞書のリビルドを行います。 リビルドした辞書ファイルを必要に応じて対象の辞書ディレクトリにコピーします。(ビルド後のディレクトリをそのまま利用している場合はコピーの必要はないです。) 最後に、Solrの該当コアのリロードを行います。(リロードの仕方はこちらを参考に。) コアのリロードにより、辞書の再読み込みが行われるので、リロード後から新しい辞書が適用されます。\n異なる辞書を使い倒す。TokenizerごとにdictionaryDir設定するぞ 1つのSolrで異なる辞書を使ったフィールドを使いたい場合です。 ipadicとnaist-chasenといった異なる場合はあまり想定できないですが、カスタム辞書の部分が異なるという形が想定できるでしょうか。(例:製品名のフィールド、企業名のフィールド。。。など)\n利用するjar:lucene-gosen-1.x.x.jar 設定:schema.xmlに異なるdictionaryDirを設定したTokenizerFactoryを設定 上記、カスタム辞書の定期更新も一緒に行うことも可能です。コアをリロードすれば、リロードしたコアで利用している 辞書がすべてリロードされます。\n最後に 遅くなってしまいましたが、ようやく、trunkにコミットしました。 できるだけ速く、リリースしますので、もう少々お待ちを。\nSolrのconfディレクトリからの指定については、@shinobu_aokiさんにパッチを提供してもらいました。 また、trunkにコミットしていないパッチを適用して記事を書いてくれた方もいらっしゃいました。こちらもあわせて参考に。私より説明が上手です。 Java製形態素解析ライブラリ「lucene-gosen」を試してみる\n","date":1319559120,"dir":"post/2011/","id":"14a6d294550c9760aec57ba29682a750","lang":"ja","lastmod":1319559120,"permalink":"https://blog.johtani.info/blog/2011/10/26/%E8%BE%9E%E6%9B%B8%E3%81%AE%E5%A4%96%E9%83%A8%E5%8C%96%E3%81%A8lucene-solr3-4%E5%AF%BE%E5%BF%9C/","publishdate":"2011-10-26T01:12:00+09:00","summary":"すぐやりますと言いつつ、はや1ヶ月。。。 腰が重い、ダメエンジニアですね。。。 すみませんでした。。。 ようやくtrunkにコミットしました。 すぐ","tags":["lucene-gosen"],"title":"辞書の外部化とLucene/Solr3.4対応(Jugemより移植)"},{"contents":"JJUG CCC 2011 Fallに参加してきました。 個人的にはかなり久々のJavaのカンファレンスです。(※あくまで「Javaの」という話で。SolrやHadoopとは別という意味です。)\n概要やタイムテーブルはこちら。 予定があったので、残念ながら最後の2つのセッション(Scala、Twitter)しか参加できませんでした。 Hadoopの話も聞きたかったのですが、しょうがないかと。 いつものごとく、メモを個人的に取ったので。\n★楽々Scalaプログラミング 浅海 ◎OOPからOFPへの道しるべ ・関数型の使い所、プログラミングのコツ ・つながりの部分 ◎最近の活動 モデリングからモデル駆動によるソース生成などに利用。 Scala、2008年から使い始めている ◎Scalaと他の機能との比較図 ◎Scalaの用途 ・高い生産性 体感で3倍。コード量が少なくなる。 IDEのサポートを考えるとまだ、Java+Eclipseのほうが高い! ・DSL ドメインモデルの記述 フレームワークAPI ・並行プログラミング Many Core 消費電力的に複数のコアで動かす=関数型のほうが並行性が上がる(スレッドさわるJavaだけだときつい) Parallel Everything Object指向+関数型が扱いやすい。 ◎関数型言語とは ・公開関数をあつかえる 関数を値として扱える、引数と返却地に関数を渡せる。(やさしめ) <=> 数学(ラムダ計算、圏論など)的にプログラムを記述できる(きびしめ) ある程度使えるはず。厳しめの部分も ◎関数型言語の長所と短所 長所 ・高階関数を使った技が使える List(???) 短所 ・メモリ、関数実行オーバーヘッド、スタックの大きさが読めない(再帰的) ◎関数型言語の系譜 純粋関数型言語 pure Lisp 伝統的関数型言語 OCaml 新世代関数型言語 Haskell Scala 型クラス 代数データ型、モナド Parametric polymorphism ◎関数型でしたいこと DSL(Domain Specific Lanuguage) 昨年の資料を参考に! ◎準備 scalaの文法 ◎並列コレクション スレッドを利用しないで並列に動作実行させるか? ※List().par.map(sitelen).sum これで並行実行させられる。 ◎Future (これってJavaでもあるよね?=あるよ) 処理を非同期で先行実行し、あとから結果を取得可能 Scalaではアクターライブラリでサポート(cala.actors) 関数合成するとFutureの実行結果を取り出す所でブロックされる!! ◎Promise Futureより強力 関数合成すると、合成関数全体が非同期実行される! scalazを利用してた ◎5つのコツ コツ1: y=f(x) 引数がひとつの関数が基本 関数合成のビルディングブロックになるよ 引数が複数ある関数は他の関数(map関数とか)で合成しにくい 対処方法:カリー化(関数の戻りを関数とする) addc(a: Int)(b: Int) : Int = a + b とすることで、 コツ2:分割統治 コツ3:演算は転換 flatMapとかfoldLeftとか ※永続データ構造 前に作ったデータ コツ4:オブジェクトの世界と関数の世界を分ける 更新指示書の形でObjectに渡す? 関数型データ構造 コツ5:新しいデザインパターン 関数型プログラミングの用語 ・Functor(関手) ・Subgroup(半群) ・Monoid(モノイド) ・Monad(モナド) OOPのデザインパターン的に考えれば、数学的なところまで理解しなくてもよさそう? ★Twitterとオープンソース @yusukey http://dev.twitter.com http://bit.ly/tdt-ja id:twj_dev ◎OSSとの関わり 支援してます。 Apache、Eclipse、Open Invention、JCP、OpenJDK パフォーマンス系のためにもOpenJDKに参画してる ◎Twitter API オープンなAPIで無償提供 13言語でAPIライブラリがあるよ ◎Twitter4Jのこれまで ほぼ全てをカバー APIはだいぶ落ち着いてきていて、追加変更は少なくなってる。 ◎立ち位置 Twitterはコミュニティを活発にするためにもライブラリを出さないらしい。 ◎Twitter4Jのこれから キャッシング ストリーミングAPI利用を簡単に モックテスト レートリミットの影響を受けると辛いから。。。 ツイート/ユーザの永続化機能 jClouds対応? ライブラリからフレームワークへ 半公式ライブラリへ github/twitter/twitter4jへ JSR Social API Twitter4Jが参照実装に??? スケーラビリティの話。 Hadoopはユーザのデータ解析とかに使ってる。 メッセージはキューイングしている。デモ。 memcachedプロトコルなんだけど、値を取ると値が消えるよ。(memcachedとは動きが違うよねー。プロトコル的にはクライアントがいっぱいあっていいよねー) RubyのGCがきつかったのでJavaベースに変更 Kestrel(Scalaで記述。) Kestrelのフォーカス外 メッセージの順序保証(してないよ) トランザクション memcachedプロトコルの拡張1 ブロックフェッチ コンシューマから取りに行くというのが特徴 memcachedプロトコルの拡張2 リライアブルフェッチ ということで感想。\nScalaは前から気になっていて、本までかってるのになかなか手を付けられていない始末でした。 そんな時にこのJJUGの話があったので、ちょうどいいと聞きに。 関数型やScalaのぼんやりしたイメージのみを持って聴いていたのですが、思った以上にキーワードが多くてついていくのがやっとというイメージ。 で、いつものごとく、Twitterでつぶやいていた所、色々な反応が。(わからずにつぶやいたのもあり、波紋を呼んだ模様) お陰で、Scala関連の方たちをフォローできたので結果オーライでした。 話の内容自体はサラっとながす感じだったので、再度資料を見る+Scalaをもっと勉強しないと理解出来ないなぁという印象でした。 ちなみに、資料はこちら。\n次は、最近Twitterの中の人になった山本さん(@yusukey)の話しを聞きました。 Twitter4Jの話と、TwitterのOSSへの関わりの話。あとは、実際にTwitterが作成しているOSSのひとつKestrelについて。 TwitterはRubyベースで色々と作ってきていたのだが、Java(JVM上で動く言語(Scalaなど))に徐々にシフトしているというのが一番の印象です。あとは、Lucene、Hadoopなど私の興味のあるOSSも利用しているなど。 Kestrelについてはデモを交えながら、実際の動きを説明されていたのでとてもわかり易かったです。 プレゼン中もTweetを表示しながらという、さすがTwitterの中の人という印象でした。 Twitterでは少し前から知り合いだったのですが、実際にお会いできた(イケメンでしたよ!)のも収穫でした。 次はStormの話も聞きたいかなぁ\nで、2セッション(山本さんの話のあとにLT大会にも参加)だけですが、全体の感想を。 「クロスコミュニティカンファレンス」というだけあり、Java以外の話題(CouchDBとか名前がありました)もちらほらあったようです。 ただ、最近の他の勉強会やカンファレンスに比べると人が少ない印象でした。 私が参加したセッションは比較的大きな部屋だったせいもあり、40~50人くらい入っていたと思うのですが、ガラガラな印象でした。良い意味で、Javaも安定してきているため、参加者が少なかったのかなぁと あとは、年齢層がHadoopなどに比べると高めかなぁという印象(かく言う私も年齢層を上げている一人ですが。。。)。Javaも長いですからねぇ。 午前中から参加していると違った印象だったかもしれないですが。。。 あと、初めて行った会場で、しかも大きめの施設でした。午後の途中から行ったせいもあるかもしれないですが、 案内が出ていなくて若干迷子に。。。 ただ、セッションの部屋自体は各席に机があり、電源も比較的多めにあったので、PC持ち込みでメモを取るには最適でした。\n","date":1318922443,"dir":"post/2011/","id":"5d827a1e8ea70edb11d946b54f076cae","lang":"ja","lastmod":1318922443,"permalink":"https://blog.johtani.info/blog/2011/10/18/jjug-ccc-2011-fall%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%A6%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-10-18T16:20:43+09:00","summary":"JJUG CCC 2011 Fallに参加してきました。 個人的にはかなり久々のJavaのカンファレンスです。(※あくまで「Javaの」という話で。SolrやHad","tags":["備忘録"],"title":"JJUG CCC 2011 Fallに参加してきました。(Jugemより移植)"},{"contents":"昨日、文章から特定の単語(リストあり)を探したいという話を聞き、lucene-gosenでもできるねぇという話になりました。 まぁ、考えてみればごくごく当たり前なのですが。。。(その筋の方たちにしてみれば常識なのかもしれないですが。。。) 一応やってみたので、こんなこともできるなという一例ですということで、記録を残しておきます。\n今回の例文として野田首相の所信表明演説の一部を活用させてもらいます。 単語のリストは次のようにします。\n内閣総理大臣 正心誠意 東日本 日本 今回も結果をわかりやすくするためにSolrのanalysis画面を利用します。 作業手順は以下のとおり。\ndictionary.csvの編集 辞書のコンパイル fieldTypeの定義(Solrのschema.xmlの設定) 文章からキーワード抽出(Solrのanalysis画面) ### **1.dictionary.csvの編集** 今回はnaist-chasenディレクトリで作業します。 なお、今回利用するlucene-gosenは[ここ](http://johtani.jugem.jp/?eid=21)で紹介した辞書分離バージョンです。(はやくtrunkにコミットせねば。。。) dictionary.csvを先ほど上げた単語だけのエントリに変更します。 キーワードだけを抽出したいので、他の単語は必要ないからです。 ``` \u0026ldquo;内閣総理大臣\u0026rdquo;,1,名詞,一般,,,,,\u0026ldquo;内閣総理大臣\u0026rdquo;,\u0026ldquo;ナイカクソウリダイジン\u0026rdquo;,\u0026ldquo;ナイカクソウリダイジン\u0026rdquo; \u0026ldquo;正心誠意\u0026rdquo;,1,名詞,一般,,,,,\u0026ldquo;正心誠意\u0026rdquo;,\u0026ldquo;セイシンセイイ\u0026rdquo;,\u0026ldquo;セイシンセイイ\u0026rdquo; \u0026ldquo;東日本\u0026rdquo;,1,名詞,一般,,,,,\u0026ldquo;東日本\u0026rdquo;,\u0026ldquo;ヒガシニホン\u0026rdquo;,\u0026ldquo;ヒガシニホン\u0026rdquo; \u0026ldquo;日本\u0026rdquo;,1,名詞,一般,,,,,\u0026ldquo;日本\u0026rdquo;,\u0026ldquo;ニホン\u0026rdquo;,\u0026ldquo;ニホン\u0026rdquo;\n\u0026lt;/div\u0026gt; \u0026lt;div\u0026gt; ### **2.辞書のコンパイル** 先ほど作成した辞書をコンパイルし、lucene-gosen用バイナリ辞書を作成します。 $ cd $LUCENE_GOSEN_HOME¥dictionary $ ant -Ddictype=naist-chasen clean-sen compile\n\u0026lt;/div\u0026gt; \u0026lt;div\u0026gt; ### **3.fieldTypeの定義(Solrのschema.xmlの設定)** Solrのschema.xmlにlucene-gosenを利用するフィールドタイプを定義します。 追加するのは次の通り \u0026lt;fieldType name=\u0026quot;text_ja\u0026quot; class=\u0026quot;solr.TextField\u0026quot; positionIncrementGap=\u0026quot;100\u0026quot; autoGeneratePhraseQueries=\u0026quot;false\u0026quot;\u0026amp;gt; \u0026lt;analyzer\u0026amp;gt; \u0026lt;tokenizer class=\u0026quot;solr.JapaneseTokenizerFactory\u0026quot; compositePOS=\u0026quot;compositePOS.txt\u0026quot; dictionaryDir=\u0026quot;keyword-dic\u0026quot;/\u0026amp;gt; \u0026lt;filter class=\u0026quot;solr.JapanesePartOfSpeechKeepFilterFactory\u0026quot; tags=\u0026quot;keeptags_ja.txt\u0026quot; enablePositionIncrements=\u0026quot;true\u0026quot;/\u0026amp;gt; \u0026lt;/analyzer\u0026amp;gt; \u0026lt;/fieldType\u0026amp;gt; また、ここで定義しているcompositePOS.txt、keeptags_ja.txtは次のようになります。 compositePOS.txt 未知語\nkeeptags_ja.txt 名詞-一般\n未知語がバラバラに出現しないようにして見やすくするためと、必要な単語(今回は「名詞-一般」しか利用しないため。)だけを抽出したいための設定です。 \u0026lt;/div\u0026gt; \u0026lt;div\u0026gt; **### 4.文章からキーワード抽出(Solrのanalysis画面)** あとは、analysis画面で解析して見るだけになります。 ということで、辞書に登録された単語だけが抽出されてますね。 この例ではインデックスに登録となりますが。 ただし、「東日本」「日本」のような一部を含む単語の場合、「東日本」が見つかった場合は「日本」は抽出されません。 あくまでも、ベストな解が見つかるのみという形です。 すべての単語を出したい場合はもう少しやり方を考えたほうがいいかもしれません。 (まぁ、このやり方でキーワードを抽出するかも考えたほうがいいかもしれませんが。。。) \u0026lt;/div\u0026gt; 最近、頭が硬くなってきてるなぁと実感してしまいました。まぁ、こんな使い方もあるかなぁと。 もっと頭を柔らかくして問題を解けるけるようになりたいなぁと。 ","date":1318389420,"dir":"post/2011/","id":"b9d4f73fa7ca8ef66891554b66b2cded","lang":"ja","lastmod":1318389420,"permalink":"https://blog.johtani.info/blog/2011/10/12/lucene-gosen%E3%81%A7%E6%96%87%E7%AB%A0%E3%81%8B%E3%82%89%E3%82%AD%E3%83%BC%E3%83%AF%E3%83%BC%E3%83%89%E6%8A%BD%E5%87%BA%E3%82%A4%E3%83%AC%E3%82%AE%E3%83%A5%E3%83%A9%E3%83%BC/","publishdate":"2011-10-12T12:17:00+09:00","summary":"昨日、文章から特定の単語(リストあり)を探したいという話を聞き、lucene-gosenでもできるねぇという話になりました。 まぁ、考えてみれ","tags":["lucene-gosen"],"title":"lucene-gosenで文章からキーワード抽出(イレギュラー?)(Jugemより移植)"},{"contents":"ちょっと間があいてしまったが、ようやくIoの1日目を終了。 なれない感じの言語なので苦労しました。 今回もセルフスタディの私の回答が最後の方に記載されてます。見たくない人は気をつけてください。 ツッコミ大募集です。コメント欄にどしどしコメントください。そこは違うだろ?こっちのほうがいいのでは?という感じで。\n感想: プロトタイプ言語であり、すべての言語はクローンだそうです。\n○手始めに スロット、オブジェクトのクローンについて。 メッセージとその送信について。 あくまでもオブジェクトだけの世界。クローンであり、クラスのインスタンスではない。(まだつかめない。。。) ### ○オブジェクト、プロトタイプ、継承 slotNamesで取れないけど、継承してる。クローンで元をコピーしてるだけか? 頭文字が大文字かどうかがtypeかどうかの違い。大文字=type(クラスもどき=) オブジェクト=スロットの入れ物 オブジェクトのクローン=オブジェクトのチェーン?(Object => Vehicle => Car => ferrari) 疑問点: 存在しないスロット名をgetSlot()で呼び出したら?=>nilが返る 存在しないスロットをメッセージとして送信したら?=>Exceptionが出る ○メソッド method()で定義 メソッドもオブジェクト=スロットに入れることができる(まだつかめない。。。) メソッドをスロットから呼び出すと実行される。 ○リストとマップ リスト、マップは簡単。幾つか(スタックやキュー)のメソッドも用意されてる。 ○true、false、nil、singleton cloneメソッドを最定義することでsingletonの動作にする。(言われてみれば当たり前か) Object cloneをオーバーライドすることもできるが、プロセス停止などしないとダメ。(恐るべし。。。) ○インタビュー SIMD(Single Instruction Multiple Data)http://ja.wikipedia.org/wiki/SIMD やりながら感想: シンタックスが全然違うのでかなり戸惑い。 ただ、考え方はシンプル。slotとか。 まだ、予約語がわかってない(cloneとかprintとかslotNamesとか)ので。 ★セルフスタディ (探してみよう) ○Ioのいくつかの問題点の例 見つけられず。。。英語がダメダメ。。。 ○質問に答えてくれるIoコミュニティ\nML:http://tech.groups.yahoo.com/group/iolanguage/ twitter:http://twitter.com/#!/iolanguage **○Ioのイディオムに関するスタイルガイド** Io Note(英語) [http://iota.flowsnake.org/](http://iota.flowsnake.org/) Ioプログラミングガイド [http://iolanguage.com/scm/io/docs/IoGuide.html](http://iolanguage.com/scm/io/docs/IoGuide.html) [http://xole.net/docs/IoGuide_ja.html](http://xole.net/docs/IoGuide_ja.html)(日本語) Ioスタイルガイド [http://en.wikibooks.org/wiki/Io_Programming/Io_Style_Guide](http://en.wikibooks.org/wiki/Io_Programming/Io_Style_Guide) [http://d.hatena.ne.jp/katzchang/20080819/p1](http://d.hatena.ne.jp/katzchang/20080819/p1)(日本語訳してくれてるブログ) (確認してみよう) ○1 + 1を評価してから、1 + \u0026ldquo;one\u0026quot;を評価する。Ioは強く型付けされた言語か?\n``` Io\u0026gt; 1 + 1 ==\u0026gt; 2 Io\u0026gt; 1 + \u0026ldquo;one\u0026rdquo;\nException: argument 0 to method \u0026lsquo;+\u0026rsquo; must be a Number, not a \u0026lsquo;Sequence\u0026rsquo; message \u0026lsquo;+\u0026rsquo; in \u0026lsquo;Command Line\u0026rsquo; on line 1\nということで、型付けは強いです。 \u0026lt;/div\u0026gt; **○0は真か偽か?空文字列はどうか?nilは真か偽か?** \u0026lt;div\u0026gt; Io\u0026gt; 0 ==\u0026gt; 0 Io\u0026gt; true and 0 ==\u0026gt; true Io\u0026gt; true and \u0026quot;\u0026rdquo; ==\u0026gt; true Io\u0026gt; \u0026quot;\u0026quot; ==\u0026gt; Io\u0026gt; true and nil ==\u0026gt; false Io\u0026gt;\n0、空文字列はtrue、nilはfalseでした。 \u0026lt;/div\u0026gt; **○プロトタイプに存在するスロットを確認するにはどうすればよいか?** \u0026lt;div\u0026gt; Io\u0026gt; Highlander := Object clone ==\u0026gt; Highlander_0x1a233a0: type = \u0026ldquo;Highlander\u0026rdquo;\nIo\u0026gt; hoge := Highlander clone ==\u0026gt; Highlander_0x1a83630:\nIo\u0026gt; hoge proto slotNames ==\u0026gt; list(type) Io\u0026gt; Highlander name := \u0026ldquo;arnold\u0026rdquo; ==\u0026gt; arnold Io\u0026gt; hoge slotNames ==\u0026gt; list() Io\u0026gt; hoge proto slotNames ==\u0026gt; list(type, name) Io\u0026gt; Highlander slotNames ==\u0026gt; list(type, name) Io\u0026gt; hoge name ==\u0026gt; arnold Io\u0026gt; hoge getSlot(\u0026ldquo;name\u0026rdquo;) ==\u0026gt; arnold\nこんな感じ。slotNamesでスロット名を確認し、スロット内部についてはgetSlotで確認できます。 \u0026lt;/div\u0026gt; **○等号(=)、コロン等号(:=)および、コロンコロン等号(::=)の違いはなにか?どのようなときに使うか?** \u0026lt;div\u0026gt; \u0026lt;table class=\u0026#34;list_view\u0026#34;\u0026gt; \u0026lt;thead\u0026gt; \u0026lt;tr\u0026gt; \u0026lt;th\u0026gt;演算子\u0026lt;/th\u0026gt; \u0026lt;th\u0026gt;説明\u0026lt;/th\u0026gt; \u0026lt;/tr\u0026gt; \u0026lt;/thead\u0026gt; \u0026lt;tbody\u0026gt; \u0026lt;tr class=\u0026#34;spec\u0026#34;\u0026gt; \u0026lt;td\u0026gt;:::=\u0026lt;/td\u0026gt; \u0026lt;td\u0026gt;スロットへの代入+setterの追加\u0026lt;/td\u0026gt; \u0026lt;/tr\u0026gt; \u0026lt;tr class=\u0026#34;specalt\u0026#34;\u0026gt; \u0026lt;td class=\u0026#34;alt\u0026#34;\u0026gt;:=\u0026lt;/td\u0026gt; \u0026lt;td class=\u0026#34;alt\u0026#34;\u0026gt;スロットへの代入\u0026lt;/td\u0026gt; \u0026lt;/tr\u0026gt; \u0026lt;tr class=\u0026#34;spec\u0026#34;\u0026gt; \u0026lt;td\u0026gt;=\u0026lt;/td\u0026gt; \u0026lt;td\u0026gt;スロットへの代入(ただし、スロットが存在しない場合は例外が発生)\u0026lt;/td\u0026gt; \u0026lt;/tr\u0026gt; \u0026lt;/tbody\u0026gt; \u0026lt;/table\u0026gt; とまぁ、記載したが、実際に動かして確認しました。 Io\u0026gt; Highlander := Object clone ==\u0026gt; Highlander_0x223b800: type = \u0026ldquo;Highlander\u0026rdquo;\nIo\u0026gt; hoge := Highlander clone ==\u0026gt; Highlander_0x21acd60:\nIo\u0026gt; hoge slotNames ==\u0026gt; list() Io\u0026gt; hoge name ::= \u0026ldquo;arnold\u0026rdquo; ==\u0026gt; arnold Io\u0026gt; hoge slotNames ==\u0026gt; list(setName, name) Io\u0026gt; hoge sword := \u0026ldquo;long sword\u0026rdquo; ==\u0026gt; long sword Io\u0026gt; hoge slotNames ==\u0026gt; list(setName, name, sword) Io\u0026gt; hoge clothes = \u0026ldquo;armor\u0026rdquo;\nException: Slot clothes not found. Must define slot using := operator before updating. message \u0026lsquo;updateSlot\u0026rsquo; in \u0026lsquo;Command Line\u0026rsquo; on line 1\n\u0026lt;/div\u0026gt; ### (試してみよう) **○ファイルからIoプログラムを実行せよ** \u0026lt;div\u0026gt; ファイル「great.io」を作成し、以下を入力。 Highlander := Object clone Highlander giveWarCry := \u0026ldquo;Woooooooo!!\u0026rdquo; println Highlander giveWarCry()\nで、以下のコマンドを実行する。 $ io great.io Woooooooo!!\n\u0026lt;/div\u0026gt; **○スロットの名前を指定して格納されているコードを実行せよ** \u0026lt;div\u0026gt; Io\u0026gt; Masason := Object clone ==\u0026gt; Masason_0x20ae7d0: type = \u0026ldquo;Masason\u0026rdquo;\nIo\u0026gt; Masason recieveNiceTweet := method(\u0026ldquo;やりましょう\u0026rdquo; println) ==\u0026gt; method( \u0026ldquo;やりましょう\u0026rdquo; println ) Io\u0026gt; Masason getSlot(\u0026ldquo;recieveNiceTweet\u0026rdquo;) ==\u0026gt; method( \u0026ldquo;やりましょう\u0026rdquo; println ) Io\u0026gt; Masason getSlot(\u0026ldquo;recieveNiceTweet\u0026rdquo;) call やりましょう ==\u0026gt; やりましょう\ncallとgetSlotが鍵ですね。 \u0026lt;/div\u0026gt; 1日目の途中で間があいてしまったのでシンタックスを忘れてしまう始末。。。 ただ、そんなに込み入った記述もないので、最初に勉強することは少ないかもしれないです。 まだメソッドをあとから追加とか、cloneしたあとにまたプロトタイプを変更して反映可能など、考え方になれないもところがありますが、良い頭の体操になってます。 間を置かずに3日目まで行かないと!! ","date":1317990120,"dir":"post/2011/","id":"dc962e34780f0374b7eb3d583f6d7eb6","lang":"ja","lastmod":1317990120,"permalink":"https://blog.johtani.info/blog/2011/10/07/7%E3%81%A4%E3%81%AE%E8%A8%80%E8%AA%9E-7%E3%81%A4%E3%81%AE%E4%B8%96%E7%95%8C-io-1%E6%97%A5%E7%9B%AE/","publishdate":"2011-10-07T21:22:00+09:00","summary":"ちょっと間があいてしまったが、ようやくIoの1日目を終了。 なれない感じの言語なので苦労しました。 今回もセルフスタディの私の回答が最後の方に記","tags":[],"title":"「7つの言語 7つの世界」 Io 1日目(Jugemより移植)"},{"contents":"久々に、MBAの備忘録です。 あれから色々入れました。 なので、入れたソフトの一覧を追加。\nAIR:TweetDeckをインストールするのに必要だったため TweetDeck(AIR版):TwitterとFacebookを同じ画面で見ることができるため。 TextWrangler:テキストエディタ(まだあんまり使ってない) Skitch:Evernoteに買収されて無料に。先日のSolr管理画面の説明書きにもちょっと使用 ClamXav:フリーのセキュリティソフト。 SourceTree:Twitterで知ったMac用のgit、mercurialのクライアントソフト。AtlassianがSourceTreeを買収したのを機に一時的に無料公開されていたので。 Firefox:基本はSafariを使ってます。WindowsではChromeを使ってます。ただ、Webページを表示されていない部分もまるごとキャプチャするのにChromeのプラグインだとダメだったので入れました。今のところキャプチャ用のブラウザです。 Full Screen enable for Eclipse on Lion:Eclipseをフルスクリーン対応するためのプラグイン MercurialEclipse:bitbucketにアカウントをもっているので。 mercurial:pipを使ってインストール。MercurialEclipseでコマンドが必要だから。「sudo pip install Mercurial」 pip:mercurialをインストールするためにインストール。「sudo easy_install pip」でインストール iStat pro(ウィジェット):CPUなどの情報を表示するウィジェット。ウィジェットがアップルのサイト(AppStoreではない)から検索できるというのを人から聞いた。ウィジェットってあんまり使われないのか? Mac Blu-ray Player:現時点で有料ソフトはこれだけ。こちら。もともとNASのデータのバックアップ用にBlu-rayのドライブ買ったんですが、せっかくだからMacにも使ってみようと思い、MacでBlu-rayを見るために購入しました。所用で長距離移動もあったので、新幹線で映画見てました。 このくらいです。 ほんとはリンクを貼ればいいのですが、そこまでの元気がないので、ご勘弁を。\nSkitchがおすすめです。簡単に画像編集+説明書きが入れられて、矢印などがよくある画像編集の野暮ったさがないので、画面キャプチャに説明書くのに今後活躍する予定です。\nあと、ソフトではなく、サービスなのですが、Cacooというサービスが便利です。 ここ最近、ちょっとした作図にはこのサービスを使うようにしています。オンラインで利用できるので、いろんな場所で編集できます。 また、図の作成もさることながら、図を共有することが可能です。 先日は、lucene-gosenが思ったように動かないという相談を受けて、このCacooでanalysis画面や設定をを貼ってもらったりしながら使いました。結構便利ですね。 ただ、付属のチャットを使ったのですが、このチャットの内容がテキスト形式でコピー出来なかったのが残念でした。今後の改修に期待ということで。\nあと、セットアップとは少し違いますが、ジャケット買ってつけました。 ステッカーを直接貼るのがちょっと気になったので、ジャケットつけてステッカーを貼ってます。 ただ、ステッカーは思ったよりチープな感じが。。。ジャケットの中に貼らないとダメだったかも。まぁ、それが嫌でジャケット買ったんですが。。。 エアージャケットセット for Macbook Air 13inch(クリア)PMC-81 ","date":1317968700,"dir":"post/2011/","id":"de1ab82817c0fb24e591b9a89a82f736","lang":"ja","lastmod":1317968700,"permalink":"https://blog.johtani.info/blog/2011/10/07/mba%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97%E5%82%99%E5%BF%98%E9%8C%B2%E3%81%9D%E3%81%AE%EF%BC%94/","publishdate":"2011-10-07T15:25:00+09:00","summary":"久々に、MBAの備忘録です。 あれから色々入れました。 なので、入れたソフトの一覧を追加。 AIR:TweetDeckをインストールするのに必要だ","tags":["備忘録"],"title":"MBAセットアップ備忘録その4(Jugemより移植)"},{"contents":"Lucene/SolrのMLでSolrの管理画面を新しくするというチケットが流れていたのでちょっと触って見ました。 ほんとにちょっと触っただけですが、いくつかキャプチャ撮ってみたので、アップしときます。 ※以下ではサムネイル画像に元画像(100Kくらいの画像)へのリンクが設定されています。携帯などでは見づらいかもしれませんが、ご容赦を。\nURLは旧管理画面とことなり、http://localhost:8983/solr/になります。\nまずはトップ画面 ダッシュボードと呼ばれるトップ画面。メモリの利用率や起動してからの時間、Luceneなどのバージョンが表示されます。 次は検索画面すっきりしてます。facetが指定できるようになったのは大きいかな。ただし、facet.fieldを複数指定などができないが。結果についてはとくに指定がなければXMLで帰ってきます。ただ、パラメータの追加ができなくなってる気がするなぁ ちなみに、Solrを止めて検索したらこんな感じの画面になりました。クエリの実行ならこのようにエラーがわかったのですが、停止後に左のメニューにあるSchemaなどをクリックしても白い画面が出るだけで、エラーかどうかがわかりにくいです。 Analysis画面。入力画面がシンプルになりました。フィールド名はリストで表示されるので選択するだけです。あとは、これまでどおり。サンプルはlucene-gosenの解析結果です。ハイライトもきちんと表示されます。ただし、長い文章の場合は結果部分だけがスクロールできる形になり、ちょっとわかりにくかったです。 Analysisの入力画面を表示したあとにSolrを停止して解析してみたらこんなエラー画面が出ました。ちなみに、その後、画面を切り替えずにSolrを起動して解析したら、赤い帯のエラーは出たままでした。一度別画面にすれば、元に戻りますが。 Pluginsの画面(旧管理画面のstatisticsに相当)。 キャッシュの状態が確認できます。今まであった画面と情報的には一緒かと。一段カテゴリ(CACHEとかCOREとか)の選択ができるようになり、見やすくなりました。 同じくPluginsの画面。 こちらはupdateHandlerについての情報です。commit数やoptimizeの回数、updateして、commitする前の状態のドキュメント数などが表示されます。前より表示される項目が多くなってるかな? 最後はスキーマブラウザこの画面が一番良くなっています。旧管理画面では、フィールド名がすべて大文字で表示され、しかもソートがされていない状態だったため、ダイナミックフィールドを利用しているとフィールドを探すのが一苦労でした。 今回は、プルダウンでフィールドやフィールドタイプのリストが表示され、辞書順で並んでいます。Filterなどもわかりやすい表示になっているかと。 おまけ Solritasと呼ばれるVelocityを使った、3.x系で入ってきた新しいサンプル画面です。URLはhttp://localhost:8983/solr/browseです。ファセットなどを使った簡単なサンプル画面なので、検索結果画面でこんなことができるというデモにも使えるかと。ただ、これも旧管理画面よりはましですが、デザインが。。。 とまぁ、簡単ですが、4.x系の管理画面をいくつか触ってみて、キャプチャをとって見ました。 デザインは前よりもすっきりしています。ただ、クエリについてはパラメータの追加ができなくなっているので、もう少し改良されるといいかなぁ(自分でやれよと言われそうですが。。。)\n","date":1317811380,"dir":"post/2011/","id":"09677934e13a5d728f00c6ed7c8870a9","lang":"ja","lastmod":1317811380,"permalink":"https://blog.johtani.info/blog/2011/10/05/solr%E3%81%AE%E6%96%B0%E3%81%97%E3%81%84%E7%AE%A1%E7%90%86%E7%94%BB%E9%9D%A2solr4-x-trunk%E7%B3%BB/","publishdate":"2011-10-05T19:43:00+09:00","summary":"Lucene/SolrのMLでSolrの管理画面を新しくするというチケットが流れていたのでちょっと触って見ました。 ほんとにちょっと触っただけ","tags":["solr"],"title":"Solrの新しい管理画面(Solr4.x trunk系)(Jugemより移植)"},{"contents":"遅くなりましたが、続きです。 さらに英語力のなさを痛感して凹んでいるところですが、何かの役に立てばと恥を晒すところです。。。\n一応、訳してみたのですが、訳すのに必死になってしまい、つながりがわかっていない点もちらほら。 このあと一旦見直しつつ、再度理解する「理解編」をアップしようかと思います。 できれば、シーケンス図とかも交えつつ。(そうしないと理解ができない可能性が。。。) 前回同様、原文は最後に付加しておきます。\nBoot Strapping Cluster Startup(クラスタの起動) ノードはZookeeperのホストとポートを指定することから始めます。 クラスタの最初のノードはクラスタのschema/configとクラスタの設定を指定するとこから開始します。 最初のノードはZookeeperに設定をアップロードしてクラスタをブートします。 クラスタは「ブートストラップ」状態です。 この状態ではノード-\u0026gt;パーティションマッピングは計算されず、クラスタはクラスタ管理コマンド以外のどんなread/writeリクエストも受け付けません。\nクラスタの最初のノード集合が起動した後、クラスタ管理コマンド(TBD記述???)が管理者によって発行されます。このコマンドは整数「partitions」パラメータを受け取り、次のステップを実行します。\nCluster Lockを取得 「partitions」をパーティション数として割り当て 各パーティションのためのノードを取得 ZooKeeperのノード-\u0026gt;パーティションマッピングを更新 Cluster Lockをリリース 全ノードに対して最新版のノード-\u0026gt;パーティションマッピングをZooKeeper経由で更新させる Node Startup ノードが起動すると、自分がすでに存在するシャードの一部かどうかZooKeeperでチェックします。 もし、ZooKeeperがノードのレコードを持っていない、またはどのシャードの一部でもないと判断したら、 ノードは後述の「New Node」のステップを実行します。すでに存在するノードの場合は後述の「Node Restart」のステップを実行します。\nNew Node\n新しいノードはクラスタの一部ではなく、クラスタのキャパシティを増強するためのものです。\n「auto_add_new_nodes」クラスタプロパティが「false」の場合、新しいノードはZooKeeperに「idle」として登録され、他のノードが参加してくれと言うまで待機します。 そうでない場合(auto_add_new_nods=true)は次のステップを実行します。\nCluster Lockを取得します。 適切なnode-\u0026gt;partitionエントリを選び出します。 利用可能なパーティションのリストをスキャンして「replication_factor」のノード数以下のパーティションのエントリを探します。複数ある場合はノード数が最小のエントリを選びます。それも一緒ならランダムに選びます。 全パーティションが「replication_factor」以上のノードを持っている場合、ノードはパーティションが最も多いものをスキャンします。複数ある場合はパーティション内のドキュメント数が最大のエントリを選びます。ドキュメント数が同一なら任意のエントリを選びます。 もし、選んだノード-\u0026gt;パーティションエントリを現在のノードに移動させることでがクラスタのパーティション:ノード比率の最大値を小さくするなら、現在のエントリを返します。。それ以外の場合選ばれたエントリがないので、アルゴリズムは終了です。。 ZooKeeper内のノード-\u0026gt;パーティションマッピングを更新します ZooKeeper内のノードステータスを「リカバリ」状態にします Cluster Lockをリリースします 「リカバリ」はパーティションのリーダーから開始します。 リカバリが終了したら、再度、Cluster Lockを取得します。 元のエントリはZooKeeperのノード-\u0026gt;パーティションマッピングから削除されます。 Cluster Lockをリリースします 元のノードはZooKeeperからノード-\u0026gt;パーティションマッピングを更新させられます ステップ1に戻ります。 Node Restart ノードの再起動とは次のいずれかを意味しています。\nJVMがクラッシュし、手動または自動でのリスタート ノードが一時的にネットワークから切り離された。もしくは、ZooKeeperに接続できなかった(死んでいると思われた)。または、ある一定期間、リーダーからの更新を受信できなかった。 このシナリオが表す書き込み処理のライフサイクルの間にネットワークから分断された ハード故障もしくはメンテナンスウインドウによりクラスタからノードが分断され、ノードをクラスタにrejoinさせるために起動した。 ノードが各パーティションに対してメンバーであるパーティションのリストを読み、パーティションのリーダーがリカバリプロセスを実行する。その時、ノードは「auto_add_new_nods」プロパティをチェックして、「New Node」処理のステップを実行する。 これはクラスタが。。。(元の文章が切れてて意味が不明)\nクライアントは標準的なSolrの更新形式を利用して書き込みできます。 書き込み処理はクラスタの任意のノードに送信されます。 ノードはハッシュ関数を利用して、どのパーティションに所属するか決めるためにrange-パーティションマッピングを使います。 ZooKeeperはシャードのリーダーを識別して、書き込み処理をそこに送ります。 SolrJはリーダーに対して書き込みを直接送信するための拡張がされています。\nリーダーはPartitionバージョンの操作を割り当て、そのトランザクションログの操作を書き込み、シャードに属する他のノードにドキュメントバージョンハッシュを転送します。 ノードはインデックスにドキュメントハッシュを書き込み、トランザクションログに操作を記録します。 リーダーは、min_writesの最小数のノード以上のノードが「OK」とレスポンスを返したら「OK」とレスポンスを返します。 クラスタプロパティのmin_writesは書き込みリクエスト時に指定することで、異なる値を指定できます。\nクラウドモードはコミット/ロールバック操作を明示的には行いません。 コミットは特定の間隔で(commit_within)リーダーによりオートコミットにより管理されます。 また、シャードの全メンバーのコミットはトリガーにより管理されます。 ノードが利用可能な最新バージョンはコミットの時点で記録されます。\nTransaction Log トランザクションログは2つのコミットの間にインデックスに対して実行された操作全てを記録したもの コミットはそれ以前に実行された操作の耐久性を保証するために、新しいトランザクションログを開始します。 同期は調整が可能です。例えば、flush vs fsynです。fsyncがデフォルトで、JVMクラッシュに対して保証できるが、電源異常の場合には保証できないが、速度的には早いです。 Recovery 次のトリガーにより復旧が可能です。\nBootstrap パーティション分割 クラスタの再構築 ノードは自身に「recovering」というステータスを設定して復旧を開始します。 このフェーズの間、ノードは読み込みリクエストを受けることができませんが、トランザくkションログに書きこまれるすべての新しい書き込みリクエストを受け取ります。 ノードは自身が持つインデックスのバージョンを調べて、パーティションの最新バージョンのリーダーに問い合わせます。 リーダーはシャード内の残りのノードと同期する前に実行されるべき操作の集合を返します(???)。\n最初にインデックスをコピーし、最新のノードにあるトランザクションログをリプレイします。 もし、インデックスのコピーが必要ならば、インデックスファイルをローカルにまずコピーし、その後トランザクションログをリプレイします。 トランザクションログのリプレイは通常の書き込みリクエストの流れと同じです。 この時、ノードは新しい書き込みを受け付けるかもしれません。その書き込みはインデックスに再生されるべきです。 ある時点でノードは最新のコミットポイントに追いつき、自身のステータスを「ready」にします。 この時点で、このノードは読み込みリクエストを処理できます。\nHandling Node Failures 一時的にネットワークが分断され、幾つかのノードとZooKeeperの間の通信が遮断されるかもしれません。 クラスタはデータの再構築(リバランシング)の前にしばらく待ちが発生します。\nLeader failure\nノードが故障し、もしそれがシャードのリーダだった場合、他のメンバーがリーダー選出のプロセスを開始します。 新しいリーダーが選出されるまで、このパーティションへの書き込みは受け付けられません。 この時、これはリーダー以外の故障ステップを処理します。(???)\nLeader failure\nシャードの一部に新しいノードが割り当てられる前にリーダーはmin_reaction_timeの間待ちます。 リーダーはCluster Lockを取得し、シャードの新規メンバーとしてノードを割り当てるためのノード-シャード割り当てアルゴリズムを使用します。 ZooKeeperのノード-\u0026gt;パーティションマッピングが更新され、Cluster Lockがリリースされます。 新しいノードはZooKeeperからノード-\u0026gt;パーティションマッピングを強制的にリロードされます。\nSplitting partitions 明示的なクラスタ管理コマンドもしくはSolrによる自動的な分割戦略(ストラテジ)はパーティションを分割することができます。 明示的な分割コマンド(split command)は対象となるパーティションを分割するために実行されます。\nパーティションXが100から199のハッシュの範囲を持つものとし、X(100から149)、Y(150~199)に分割するとします。 Xのリーダーは、XとYの新しい値の範囲をZooKeeperに分割アクションを記録します。 ノードはこの分割アクションもしくは新しいパーティションの存在については通知を受けません。(???)\nXのリーダはCluster Lockを取得し、パーティションY(アルゴリズムはto be determined)を割り当てるノードを決定し、新しいパーティションを知らせ、パーティション-\u0026gt;ノードマッピングを更新します。Xのリーダはノードのレスポンスを街、新しいパーティションがコマンドを受付可能な状態になったら次の処理を実行します。 Xのリーダーは分割が完了するまですべてのコミットを停止します。 Xのリーダーは最新のコミットポイント(バージョンVとする)のIndexReaderをオープンし、同じバージョンのIndexReaderもオープンするように命じます XのリーダーはYのリーダーに対してバージョンV以降のトランザクションログのうちハッシュ値の範囲が150から199のものを流します。 Yのリーダーはトランザクションログの#2(#3の間違い?)で送られたリクエストだけを記録します??? Xのリーダーはステップ#2で開いたIndexReaderに対してインデックスの分割を開始します。 #5で作成されたインデックスはYのリーダーに送られ、登録されます。 Yのリーダーは「recovery」プロセスを開始するように(シャードの)他のノード命令し、インデックスのトランザクションログを再生し始めます。 パーティションYのすべてのノードがバージョンVに到達したならば YのリーダーはXのリーダーに#2で作成されたReaderの上に、ハッシュの範囲が100から149だけに属しているドキュメントを抽出するようにするFilteredIndexReaderを準備するように頼みます。 Xのリーダーは#8aのリクエストが完了したのを検知したら、YのリーダーがCluster Lockを取得し、クラスタ全体の検索/登録リクエストの受信を開始するためにレンジ-\u0026gt;パーティションマッピングを変更します。 YのリーダーはXのリーダーに検索リクエストのために#8aで作成されたFilteredIndexReaderの利用開始を頼みます YのリーダーはXのリーダーに、ZooKeeperからレンジ-\u0026gt;パーティションマッピングを矯正リフレッシュするように頼みます。この時点で#3で開始されたトランザクションログの流しこみが停止されるのが保証されます。 Xのリーダーは自身のパーティションに存在するべきでないハッシュ値をもつドキュメントを削除し、最新のコミットポイントのsearcherを再度開きます。 この時点で分割は完全に終了し、Xのリーダーはcommit_withinパラメータによるコミットをレジュームします(???) Notes:\n分割操作が完了するまで、commit_withinパラメータによるパーティションの分割は実行されない #8b開始から#8c終了までの間の分散検索は一貫しない検索結果を帰す場合がある(例えば:検索結果が異なる) Cluster Re-balancing クラスタは明示的なクラスタ管理コマンドにより再構築(リバランシング)できる。\nTBD (to be determined)\nCluster Re-balancing TBD (to be determined)\nConfiguration solr_cluster.properties これはクラスタ内の全ノードにわたって適用される一般的なSolr設定ファイルとは別のプロパティファイルの集合である。\nreplication_factor:クラスタによって管理されるドキュメントのレプリカの数 min_writes:書き込み操作が成功になる前の最小の書き込み????。これは書き込みごとに上書き設定可能 commit_within:検索に現れるまでの書き込み操作の最大回数 hash_function:ドキュメントのハッシュ値を計算するための関数の実装 max_hash_value:ハッシュ関数が出力することができる最大値。理論的には、この値はクラスタが保持できるパーティションの最大数でもある min_reaction_time:起動、停止の後に再配分/分割にかかる時間(??) min_replica_for_reaction:レプリカノード数がこの値以下になったら、min_reaction_timeにならなくても分割が実行される。 auto_add_new_nodes:booleanフラグ。もしtrueなら新しいノードは自動的にパーティションからレプリカを読み込む。そうでない場合は新しいノードはクラスタに「idle」状態で登録される Cluster Admin Commands すべてのクラスタ管理コマンドはすべてのノードでパス(/cluster_admin)を与えることで実行できます。 全ノードは同じコマンドを受け付けることができ、振る舞いも同じものになるでしょう。 以下のコマンドはユーザが利用できるパブリックなコマンドです。\ninit_cluster:(パラメータ:パーティション)このコマンドはノードの集合の初期化後に実施されます。このコマンドが実行されるまで、クラスタは読み込み/書き込みコマンドを受け付けません。 split_partition:(パラメータ:パーティション(任意))パーティションを2つに分割します。もしパーティションパラメータが指定されない場合は、ドキュメント数が最大の add_idle_nodes:このコマンドはauto_add_new_nodes=falseの場合に利用できます。このコマンドはクラスタに対して「idle」状態のすべてのノードを追加するトリガーとなります。 move_partition:(パラメータ:パーティション、from、to)fromのノードからtoの別のノードに引数で指定されたパーティションを移動します。 command_status:(パラメータ:completion_id(任意))上記コマンドはすべて非同期で実行され、completion_idを返します。このコマンドは特定の実行中のコマンドもしくは全ての実行中のコマンドの状態を表示するために利用できます。 status:(パラメータ:パーティション(任意))パーティションのリストを表示し各パーティションの次の情報を表示します。 リーダーノード ノードのリスト ドキュメント数 平均読み込み回数(reads/sec) 平均書き込み回数(writes/sec) 平均読み込み時間(time/read) 平均書き込み時間(time/write) Migrating from Solr to SolrCloud クラウドに移行するときに幾つかの特徴は不要かもしれないし、サポートされないかもしれません。 既存の(クラウドでない)バージョンでのすべての特徴をSolrCloudでサポートし続けなければなりません。\nレプリケーション:これは必要ありません。 CoreAdminコマンド:明示的なコアの操作は許可されません。内部にコアがあるかもしれないが、暗黙的に管理されるでしょう 複数スキーマのサポート?:単純化のため、ver1.0ではサポートしないかもしれない solr.xml:SolrCloudでほんとに必要? Alternative to a Cluster Lock リーダーを選出する常設の調停ノード(masterはインデックスレプリケーションで利用している用語なので、「調停」とする)を持つほうが単純かもしれません。 「truth」状態をZookeeperの状態としてみなすような次のパターンでは、将来の柔軟性(クラスタを制御するためのZookeeperの状態を直接変更するような外部管理ツールのような)を考慮に入れることができます。 (毎回ロックを取得するよりも)調停ノードを持つことにより、よりスケーラブルになるかもしれません。 特定条件下でのみCluster Lockを利用するハイブリッドも意味があるでしょう。\nSingle Node Simplest Use Case 単一ノードでスタートして、ドキュメントをインデックス登録できないといけません。 また、あとで、クラスタに2番目のノードを追加できないと行けません。\n1つのノードから開始し、最初にZookeeperに設定ファイルをアップロードし、shard1にノードを作成+登録します。 他の情報がない状態で設定が作成され、1つのシャードのシステムとなります。 いくつかのドキュメントをインデックスします 他のノードが起動し、「まだ割り当てられていない場合、レプリカの最小の数をもつshardに割り当てられ、「recovery」プロセスを開始します」というパラメータを受け取ります。 * 出来れば、同一ホスト上に同じシャードはコピーしない * この時点の後で、ノードが停止したら、再起動し、同じ役割が再開されるべきです。(Zookeeperでそれ自身であると判別されれば) 原文はこちらからです。\nBoot Strapping Cluster Startup A node is started pointing to a Zookeeper host and port. The first node in the cluster may be started with cluster configuration properties and the schema/config files for the cluster. The first node would upload the configuration into zookeeper and bootstrap the cluster. The cluster is deemed to be in the “bootstrap” state. In this state, the node -\u0026gt; partition mapping is not computed and the cluster does not accept any read/write requests except for clusteradmin commands.\nAfter the initial set of nodes in the cluster have started up, a clusteradmin command (TBD description) is issued by the administrator. This command accepts an integer “partitions” parameter and it performs the following steps:\nAcquire the Cluster Lock Allocate the “partitions” number of partitions Acquires nodes for each partition Updates the node -\u0026gt; partition mapping in ZooKeeper Release the Cluster Lock Informs all nodes to force update their own node -\u0026gt; partition mapping from ZooKeeper The Cluster Lock is acquired A suitable source (node, partition) tuple is chosen: The list of available partitions are scanned to find partitions which has less then “replication_factor” number of nodes. In case of tie, the partition with the least number of nodes is selected. In case of another tie, a random partition is chosen. If all partitions have enough replicas, the nodes are scanned to find one which has most number of partitions. In case of tie, of all the partitions in such nodes, the one which has the most number of documents is chosen. In case of tie, a random partition on a random node is chosen. If moving the chosen (node, partition) tuple to the current node will decrease the maximum number of partition:node ratio of the cluster, the chosen tuple is returned.Otherwise, no (node, partition) is chosen and the algorithm terminates The node -\u0026gt; partition mapping is updated in ZooKeeper The node status in ZooKeeper is updated to “recovery” state The Cluster Lock is released A “recovery” is initiated against the leader of the chosen partition After the recovery is complete, the Cluster Lock is acquired again The source (node, partition) is removed from the node -\u0026gt; partition map in ZooKeeper The Cluster Lock is released The source node is instructed to force refresh the node -\u0026gt; partition map from ZooKeeper Goto step #1 Node Restart A node restart can mean one of the following things:\nThe JVM crashed and was manually or automatically restarted The node was in a temporary network partition and either could not reach ZooKeeper (and was supposed to be dead) or could not receive updates from the leader for a period of time. A node restart ine node failure. Lifecycle of a Write Operation this scenario signifies the removal of the network partition. A hardware failure or maintenance window caused the removal of the node from the cluster and the node has been started again to rejoin the cluster. The node reads the list of partitions for which it is a member and for each partition, starts a recovery process from each partition’s leader respectively. Then, the node follows the steps in the New Node section without checking for the auto_add_new_nodes property. This ensures that the cluster recovers from the imbalance created by th\nWrites are performed by clients using the standard Solr update formats. A write operation can be sent to any node in the cluster. The node uses the hash_function , and the Range-Partition mapping to identify the partition where the doc belongs to. A zookeeper lookup is performed to identify the leader of the shard and the operation is forwarded there. A SolrJ enhancement may enable it to send the write directly to the leader\nThe leader assigns the operation a Partition Version and writes the operation to its transaction log and forwards the document + version + hash to other nodes belonging to the shard. The nodes write the document + hash to the index and record the operation in the transaction log. The leader responds with an ‘OK’ if at least min_writes number of nodes respond with ‘OK’. The min_writes in the cluster properties can be overridden by specifying it in the write request.\nThe cloud mode would not offer any explicit commit/rollback operations. The commits are managed by auto-commits at intervals (commit_within) by the leader and triggers a commit on all members on the shard. The latest version available to a node is recorded with the commit point.\nTransaction Log A transaction log records all operations performed on an Index between two commits Each commit starts a new transaction log because a commit guarantees durability of operations performed before it The sync can be tunable e.g. flush vs fsync by default can protect against JVM crashes but not against power failure and can be much faster Recovery A recovery can be triggered during:\nBootstrap Partition splits Cluster re-balancing The node starts by setting its status as ‘recovering’. During this phase, the node will not receive any read requests but it will receive all new write requests which shall be written to a separate transaction log. The node looks up the version of index it has and queries the ‘leader’ for the latest version of the partition. The leader responds with the set of operations to be performed before the node can be in sync with the rest of the nodes in the shard.\nThis may involve copying the index first and replaying the transaction log depending on where the node is w.r.t the state of the art. If an index copy is required, the index files are replicated first to the local index and then the transaction logs are replayed. The replay of transaction log is nothing but a stream of regular write requests. During this time, the node may have accumulated new writes, which should then be played back on the index. The moment the node catches up with the latest commit point, it marks itself as “ready”. At this point, read requests can be handled by the node.\nHandling Node Failures There may be temporary network partitions between some nodes or between a node and ZooKeeper. The cluster should wait for some time before re-balancing data.\nLeader failure\nIf node fails and if it is a leader of any of the shards, the other members will initiate a leader election process. Writes to this partition are not accepted until the new leader is elected. Then it follows the steps in non-leader failure\nNon-Leader failure\nThe leader would wait for the min_reaction_time before identifying a new node to be a part of the shard. The leader acquires the Cluster Lock and uses the node-shard assignment algorithm to identify a node as the new member of the shard. The node -\u0026gt; partition mapping is updated in ZooKeeper and the cluster lock is released. The new node is then instructed to force reload the node -\u0026gt; partition mapping from ZooKeeper.\nSplitting partitions A partition can be split either by an explicit cluster admin command or automatically by splitting strategies provided by Solr. An explicit split command may give specify target partition(s) for split.\nAssume the partition ‘X’ with hash range 100 - 199 is identified to be split into X (100 - 149) and a new partition Y (150 - 199). The leader of X records the split action in ZooKeeper with the new desired range values of X as well as Y. No nodes are notified of this split action or the existence of the new partition.\nThe leader of X, acquires the Cluster Lock and identifies nodes which can be assigned to partition Y (algorithm TBD) and informs them of the new partition and updates the partition -\u0026gt; node mapping. The leader of X waits for the nodes to respond and once it determines that the new partition is ready to accept commands, it proceeds as follows: The leader of X suspends all commits until the split is complete. The leader of X opens an IndexReader on the latest commit point (say version V) and instructs its peers to do the same. The leader of X starts streaming the transaction log after version V for the hash range 150 - 199 to the leader of Y. The leader of Y records the requests sent in #2 in its transaction log only i.e. it is not played on the index. The leader of X initiates an index split on the IndexReader opened in step #2. The index created in #5 is sent to the leader of Y and is installed. The leader of Y instructs its peers to start recovery process. At the same time, it starts playing its transaction log on the index. Once all peers of partition Y have reached at least version V: The leader of Y asks the leader of X to prepare a FilteredIndexReader on top of the reader created in step #2 which will have documents belonging to hash range 100 - 149 only. Once the leader of X acknowledges the completion of request in #8a, the leader of Y acquires the Cluster Lock and modifies the range -\u0026gt; partition mapping to start receiving regular search/write requests from the whole cluster. The leader of Y asks leader of X to start using the FilteredIndexReader created in #8a for search requests. The leader of Y asks leader of X to force refresh the range -\u0026gt; partition mapping from ZooKeeper. At this point, it is guaranteed that the transaction log streaming which started in #3 will be stopped. The leader of X will delete all documents with hash values not belonging to its partitions, commits and re-opens the searcher on the latest commit point. At this point, the split is considered complete and leader of X resumes commits according to the commit_within parameters. Notes:\nThe partition being split does not honor commit_within parameter until the split operation completes Any distributed search operation performed starting at the time of #8b and till the end of #8c can return inconsistent results i.e. the number of search results may be wrong. Cluster Re-balancing The cluster can be rebalanced by an explicit cluster admin command.\nTBD\nMonitoring TBD\nConfiguration solr_cluster.properties This are the set of properties which are outside of the regular Solr configuration and is applicable across all nodes in the cluster:\nreplication_factor : The number of replicas of a doc maintained by the cluster min_writes : Minimum no:of successful writes before the write operation is signaled as successful . This may me overridden on a per write basis commit_within : This is the max time within which write operation is visible in a search hash_function : The implementation which computes the hash of a given doc max_hash_value : The maximum value that a hash_function can output. Theoretically, this is also the maximum number of partitions the cluster can ever have min_reaction_time : The time before any reallocation/splitting is done after a node comes up or goes down (in secs) min_replica_for_reaction : If the number of replica nodes go below this threshold the splitting is triggered even if the min_reaction_time is not met auto_add_new_nodes : A Boolean flag. If true, new nodes are automatically used as read replicas to existing partitions, otherwise, new nodes sit idle until the cluster needs them. Cluster Admin Commands All cluster admin commands run on all nodes at a given path (say /cluster_admin). All nodes are capable of accepting the same commands and the behavior would be same. These are the public commands which a user can use to manage a cluster:\ninit_cluster : (params : partition) This command is issued after the initial set of nodes are started. Till this command is issued, the cluster would not accept any read/write commands split_partition : (params : partitionoptional). The partition is split into two halves. If the partition parameter is not supplied, the partition with the largest number of documents is identified as the candidate. add_idle_nodes : This can be used if auto_add_new_nodes=false. This command triggers the addition of all ‘idle’ nodes to the cluster. move_partition : (params : partition, from, to). Move the given partition from a given node from to another node command_status :(params : completion_idoptional) . All the above commands are asynchronous and returns with a completion_id . This command can be used to know the status of a particular running command or all the current running commands status : (params : partitionoptional) Shows the list of partitions and for each partition, the following info is provided leader node nodes list doc count average reads/sec average writes/sec average time/read average time/write Migrating from Solr to SolrCloud A few features may be redundant or not supported when we move to cloud such as. We should continue to support the non cloud version which supports all the existing features\nReplication. This feature is not required anymore CoreAdmin commands. Explicit manipulation of cores will not be allowed. Though cores may exist internally and they meay be managed implicitly Multiple schema support ? Should we just remove it from ver 1.0 for simplicity? solr.xml . Is there a need at all for this in the cloud mode? Alternative to a Cluster Lock It may be simpler to have a coordinator node (we avoid the term master since that is associated with traditional index replication) that is established via leader election. Following a pattern of treating the zookeeper state as the \u0026ldquo;truth\u0026rdquo; and having nodes react to changes in that state allow for more future flexibility (such as allowing an external management tool directly change the zookeeper state to control the cluster). Having a coordinator (as opposed to grabbing a lock every time) can be more scalable too. A hybrid model where a cluster lock is used only in certain circumstances can also make sense.\nSingle Node Simplest Use Case We should be able to easily start up a single node and start indexing documents. At a later point in time, we should be able to start up a second node and have it join the cluster.\nstart up a single node, upload it\u0026rsquo;s configuration (the first time) to zookeeper, and create+assign the node to shard1. in the absence of other information when the config is created, a single shard system is assumed index some documents start up another node and pass it a parameter that says \u0026ldquo;if you are not already assigned, assign yourself to any shard that has the lowest number of replicas and start recovery process\u0026rdquo; avoid replicating a shard on the same host if possible after this point, one should be able to kill the node and start it up again and have it resume the same role (since it should see itself in zookeeper)\n","date":1317720720,"dir":"post/2011/","id":"7052598d2355984237d126afea2f6e88","lang":"ja","lastmod":1317720720,"permalink":"https://blog.johtani.info/blog/2011/10/04/new-solrcloud-design%E3%81%AE%E7%BF%BB%E8%A8%B3%E3%81%9D%E3%81%AE2/","publishdate":"2011-10-04T18:32:00+09:00","summary":"遅くなりましたが、続きです。 さらに英語力のなさを痛感して凹んでいるところですが、何かの役に立てばと恥を晒すところです。。。 一応、訳してみたの","tags":["solr"],"title":"New SolrCloud Designの翻訳(その2)(Jugemより移植)"},{"contents":"ちょっと興味があるので、訳してみました。(Wikiのページはこちら) 更新されているようなので、もとの文章も残しておきます。(ページ下部の続きはこちら部分以降) 全部訳そうと思ったのですが、終わらなかったので、まずは前半部分です。まだ、訳しただけで理解できてない。。。 (英語力のなさをさらけ出してしまうのですが、これも修行です。。。おかしいところはツッコミを。)\nWhat is SolrCloud? Solrクラウドはクラウドでの検索サービスとしてのSolrを管理、運用するための既存のSolrを拡張するものです。\n用語集 Cluster:クラスタは1単位として管理されるSolrノードの集合です。クラスタ全体で単一のschema、solrconfigをもたないといけません。 Node:ひとつのJVMインスタンスで起動しているSolrのこと Partition:パーティションはドキュメント集合全体のサブセット(部分集合)のことです。パーティションは部分集合のドキュメントが単一のインデックスに含まれるような形で作られます。 Shard:パーティションはn(=replication factor)個のノードに保存される必要があります。このn個のノードすべてでひとつのshardです。1つのノードはいくつかのshardの一部にで有る場合があります。 Leader:各Shardは1つのリーダとなるノードを持っています。パーティションに登録されたドキュメントリーダーからコピーされます Replication Factor:クラスタによって保持されるレプリカの最小限の数 Transaction Log:各ノードによって保持される書き込み処理の追記ログ Partition version:これは各shardのリーダーが持っているカウンターで、書き込み処理ごとに増加し、レプリカに送られます。 Cluster Lock:これはrange(※後述されているハッシュ値の範囲のことか?)-\u0026gt;パーティションもしくはパーティション-\u0026gt;ノードのマッピングを変更するために取得しなければいけないグローバルなロックのことです。 ※用語だけだと関係がわかりづらかったので、図を書いてみました。\nドキュメントの集合とパーティションについての考え方\nクラスタ、ノード、シャードの考え方。\n処理原則 任意の処理はクラスタにある任意のノードに実行可能です。 リカバリできないSPOFはありません。 クラスタは伸縮自在(elastic)でなければならない 書き込みが失われないこと(耐久性)を保証する 書き込み順序が保証されなければならない 2つのクライアントが2つの「A」というドキュメントを同時に送信してきた場合、すべてのレプリカで一貫してどちらか一方が保存されなければならない。 クラスタの設定は中央管理されなければならない。また、クラスタのどのノードからもクラスタ設定が更新できます。 読み込み(検索)の自動的なフェイルオーバー 書き込み(インデクシング)の自動的なフェイルオーバー ノードの故障が発生しても自動的にrepcation factorの数は守られます。(故障したら動的にレプリカを再配置?) Zookeeper ZooKeeperクラスタは次のために使用されます。\nクラスタ設定の集中管理 分散同期に必要な操作のコーディネータ クラスタ構成を保存するためのシステム Partitioning クラスタは固定されたmax_hash_value=「N」が設定されます。 max_hash_valueは1000のような大きな値が設定されます。\nhash = hash_function(doc.getKey()) % N ハッシュ値の範囲がパーティションに割り当てられ、ZooKeeperに保存されます。 次の例のような形で、パーティションに対して範囲が設定されます。\nrange : partition ------ ---------- 0 - 99 : 1 100-199: 2 200-299: 3 ハッシュはドキュメントにインデックスフィールドとして追加され、変更されない値です。 これは、インデックスを分割するときにも利用します。\nハッシュ関数はプラガブルです。これはドキュメントを受け取り、一貫した正整数ハッシュ値を返します。デフォルトのハッシュ関数として、必須でかつ変更されないフィールド(デフォルトはユニークキーフィールド)からハッシュ値を計算する関数が提供されます。\nUsing full hash range max_hash_valueは必ずしも必要ではありません。各shardはいずれにしろハッシュ値の範囲持っているので、完全な32 bitsハッシュを使うこともできます。 設定可能なmax_hash_valueを利用しないで、クライアントからの値をもとにハッシュ値を作ることができます。 例えば、電子メールの検索アプリでは次のようにハッシュ関数を作ることができます。\n(hash(user_id)\u0026lt;\u0026lt;24) | (hash(message_id)\u0026gt;\u0026gt;\u0026gt;8) ユーザIDから8bitのハッシュコードの先頭8ビットを利用することで、任意のユーザのメールがクラスタの同じ256番目(のノード?)にあるのを保証します。検索時はこの情報をもとにクラスタのその部分への問い合わせだけで情報が得られます。\nおそらく、私たちは最大値から最小値をカバーする範囲を表現するのにハッシュ空間を輪(固定のハッシュではなく)とみなしたいです。(???円状のハッシュ空間とすることで、クラスタ内のノード数の増減に耐えられるようにするよということかな?)\nshard naming シャードからハッシュ値の範囲へのマッピングを別々に管理するよりも、ハッシュコードによりパーティションを構成するときに実際にはハッシュの範囲をシャード名にします。 (シャード「1-1000」は1から1000の間のハッシュコードを持つドキュメントが含まれるという形)\n現時点では(コレクション1つに対してシングルコアの1Solrサーバと仮定して)solrコア名はコレクション名をつけるようになっています。 同一コレクションのためのマルチコアに対してのいい命名規則をつけるという課題が残っています。 (※コレクションに対する説明がここまでないかな?)\nShard Assignment ノード-\u0026gt;パーティションのマッピングはZooKeeperにあるCluster Lockを取得したノードによってのみ変更が可能です。 ノードの追加時に、まず、Cluster Lockを取得し、次にそれがどのパーティションを取得できるかを識別します。\nNode to a shard assignment 新しいノードを探しているノードはまずCluster Lockを取得しないといけません。 第一に、リーダーはシャードを決めます。 シャードが持つ、すべての利用可能なノード数で最小の値を持つノードが選び出されます。 もし、同値ならランダムにノードを選びます。\n原文はこちらからです。\nNew SolrCloud Design (Work in progress)\nWhat is SolrCloud? SolrCloud is an enhancement to the existing Solr to manage and operate Solr as a search service in a cloud.\nGlossary Cluster : Cluster is a set of Solr nodes managed as a single unit. The entire cluster must have a single schema and solrconfig Node : A JVM instance running Solr Partition : A partition is a subset of the entire document collection. A partition is created in such a way that all its documents can be contained in a single index. Shard : A Partition needs to be stored in multiple nodes as specified by the replication factor. All these nodes collectively form a shard. A node may be a part of multiple shards Leader : Each Shard has one node identified as its leader. All the writes for documents belonging to a partition should be routed through the leader. Replication Factor : Minimum number of copies of a document maintained by the cluster Transaction Log : An append-only log of write operations maintained by each node Partition version : This is a counter maintained with the leader of each shard and incremented on each write operation and sent to the peers Cluster Lock : This is a global lock which must be acquired in order to change the range -\u0026gt; partition or the partition -\u0026gt; node mappings. Guiding Principles Any operation can be invoked on any node in the cluster. No non-recoverable single point of failures Cluster should be elastic Writes must never be lost i.e. durability is guaranteed Order of writes should be preserved If two clients send document \u0026ldquo;A\u0026rdquo; to two different replicas at the same time, one should consistently \u0026ldquo;win\u0026rdquo; on all replicas. Cluster configuration should be managed centrally and can be updated through any node in the cluster. No per node configuration other than local values such as the port, index/logs storage locations should be required Automatic failover of reads Automatic failover of writes Automatically honour the replication factor in the event of a node failure Zookeeper A ZooKeeper cluster is used as:\nThe central configuration store for the cluster A co-ordinator for operations requiring distributed synchronization The system-of-record for cluster topology Partitioning The cluster is configured with a fixed max_hash_value (which is set to a fairly large value, say 1000) ‘N’. Each document’s hash is calculated as:\nhash = hash_function(doc.getKey()) % N Ranges of hash values are assigned to partitions and stored in Zookeeper. For example we may have a range to partition mapping as follows\nrange : partition ------ ---------- 0 - 99 : 1 100-199: 2 200-299: 3 The hash is added as an indexed field in the doc and it is immutable. This may also be used during an index split\nThe hash function is pluggable. It can accept a document and return a consistent \u0026amp; positive integer hash value. The system provides a default hash function which uses the content of a configured, required \u0026amp; immutable field (default is unique_key field) to calculate hash values.\nUsing full hash range Alternatively, there need not be any max_hash_value - the full 32 bits of the hash can be used since each shard will have a range of hash values anyway. Avoiding a configurable max_hash_value makes things easier on clients wanting related hash values next to each other. For example, in an email search application, one could construct a hashcode as follows:\n(hash(user_id)\u0026lt;\u0026lt;24) | (hash(message_id)\u0026gt;\u0026gt;\u0026gt;8) By deriving the top 8 bits of the hashcode from the user_id, it guarantees that any users emails are in the same 256th portion of the cluster. At search time, this information can be used to only query that portion of the cluster.\nWe probably also want to view the hash space as a ring (as is done with consistent hashing) in order to express ranges that wrap (cross from the maximum value to the minimum value).\nshard naming When partitioning is by hash code, rather than maintaining a separate mapping from shard to hash range, the shard name could actually be the hash range (i.e. shard \u0026ldquo;1-1000\u0026rdquo; would contain docs with a hashcode between 1 and 1000).\nThe current convention for solr-core naming is that it match the collection name (assuming a single core in a solr server for the collection). We still need a good naming scheme for when there are multiple cores for the same collection.\nShard Assignment The node -\u0026gt; partition mapping can only be changed by a node which has acquired the Cluster Lock in ZooKeeper. So when a node comes up, it first attempts to acquire the cluster lock, waits for it to be acquired and then identifies the partition to which it can subscribe to.\nNode to a shard assignment The node which is trying to find a new node should acquire the cluster lock first. First of all the leader is identified for the shard. Out of the all the available nodes, the node with the least number of shards is selected. If there is a tie, the node which is a leader to the least number of shard is chosen. If there is a tie, a random node is chosen.\n","date":1317210300,"dir":"post/2011/","id":"927612b57ba01ca878b2d7edce52a563","lang":"ja","lastmod":1317210300,"permalink":"https://blog.johtani.info/blog/2011/09/28/new-solrcloud-design%E3%81%AE%E7%BF%BB%E8%A8%B3%E3%81%9D%E3%81%AE%EF%BC%91/","publishdate":"2011-09-28T20:45:00+09:00","summary":"ちょっと興味があるので、訳してみました。(Wikiのページはこちら) 更新されているようなので、もとの文章も残しておきます。(ページ下部の続き","tags":["solr"],"title":"New SolrCloud Designの翻訳(その1)(Jugemより移植)"},{"contents":"Hadoop Conference Japan 2011 Fallに行ってきました。 まずは、ユーザ会の方々、運営の方々、発表された方々お疲れ様でした。こんな機会を用意していただき、ありがとうございます。 Hadoopは昨年触っていたのですが、最近は縁がなくなってしまいました。 ただ、触っていたときに面白かったので参加してきました。 ということで、今回も自分用にメモを取ったので。(今回は英語のヒアリングがあって、メモがひどい事になってます。。。) いつものことながら、おかしいところとかあれば、ツッコミなどフィードバックをもらえると嬉しいです。\n場所:ベルサール汐留 日時:2011/09/26 10:00~18:00+懇親会:18:30~21:00\nオープニングトーク:濱野、太田 参加者:1100名超!(実際は800名弱?) Hadoopの経験:利用経験なしな方が580名 カンファレンスの認知:Twitterよりも知人、その他が多かった。 会場提供:リクルート様 リクルート米谷様より一言。 Question VOTE!!サイトを用意。 http://mit.recruit.co.jpにて情報提供。 ※残念ながら地下だったため、E-mobileにつながらず、あと、電源確保が難しかったのでMBAをスタンドアロンにしてメモをとっていたので、 QAサイトにはアクセスしませんでした。もう少し活用したかったんですが、携帯でTwitterを追っかけるので精一杯。。。\n◎The role of the Distribution in the Apache Hadoop Ecosystem:Todd Lipcon(Cloudera)\n1.Introduction Todd Lipcon:Clouderaエンジニア Hadoop とHBaseのコミッター 2. Hadoop Overview HDFS+MapReduceの説明 Hadoopの生まれてきた経緯 様々な形式のデータが大量に存在し、データのハンドリングが難しくなってきたため。 Flexible, Scalable Solutionが必要に。 Hadoop の2つのユースケース 1.Advanced Analytics SNS(Web)、Content Optimization(Media)、Network Analytics(Telco)、 2.Data Processing Clickstream SessionizationEngagement 3.Cloudera Overview ClouderaCustomers ・Large National Bank ・Web-Based Media click-through dataや広告のログ ・Wireless Telecom 大量のデータ 目標:大量データからビジネスを引き出すこと。 Cloudera Japan:トレーニング。NTTDと協業して開発支援も 4.CDH Overview 100% pure Apache Hadoop SCM Epress(Service \u0026amp;amp; Configuration Manager) Free なぜ、CDHを利用するの? Linuxを利用する場合にLinux.orgからはダウンロードしないように、Hadoopも同じように提供したい。 RedHat系を目指しているみたい。 様々なパッケージの依存関係が混乱を招く。 CDHならテストが終わってるものが提供されてる。 ※SolrはLWEがLucidWorksEnterpriseがこれを目指してるのか。 5.Cloudera Enterprise Activity Monitor:Jobのパフォーマンスをリアルタイムに監視 SCM:設定のvalidateや管理。 Resource Manager:。。。 6.まとめ CDH:簡単にHadopが使えるよ。 SCM Express:簡単にHadoopの設定ができてフリーだよ Cloudera:Hadoopに関していろいろサポートしているよ。(Enterprise用ソフトやトレーニングなど) ◎About Hortonworks:Owen O\u0026rsquo;Malley(Hortonworks)\n1.About Hortonworks 2011/2月に設立 22人のYahooからのアーキテクトとコミッタにより設立 2.Credentials Yahooのクラスタの経験者がいますよ。 OSSに長けた人達によるチームです。 3.What is Apache Hadoop Hadoopの説明(別の側面が幾つかあり。) Commodity Hardwareで動く 簡単にプログラムできる 典型的なアプリケーションのタグクラウド(あとでちゃんと見る) HadoopのほとんどのソースコードはYahooで作られてるよ。 Clouderaとか目じゃないよ 4.Hadoop @ Yahoo! 各種サーバや規模など Science Hadoop Cluster \u0026lt;-\u0026amp;gt; Production Hadoop Cluster \u0026lt;-\u0026amp;gt; Serving Systems という構成で、いろいろやってます。 5.Hadoop Market ビジネス:ビッグデータを扱って色々やろうね 金融系:IT系のコストをOSSとHadoopで削減 技術系: 6.Hortonworks Strategy Hadoopを利用、管理しやすくするためのいろんなことをコミュニティに還元しますよ。 性能などについても同様。 トレーニングやテクニカルサポートやりますよ。 QA: Q:42Kのノードの管理ツールはなに? A:手で管理してます。 Q:社名の由来は? A:童話でHortonという名前の象の話がある。 Q:CDHはおすすめ?それともほかのものがいい? A:※聞き取れず。。。 Q:500万Query/月はアドホックQueryもあるの? A:幾つかのクラスタに分けて使ってる。アドホックは不明 ◎How Hadoop needs to evolve and integrate into the enterprise:Ted Dunning(MapR)\n・Quick History ・英語わからない身には辛い。。。 Zookeeperの人らしい。 Narrow Foundations HDFSとNASの間には大きな壁があり、大きなデータを移動するのはコストが掛かる。 Broad Foundation HDFSの代わりにNAS、RDBMSの下に位置するMapRを用意 ど、どんな仕組み?-\u0026amp;gt;テクニカルセッションで。 QA: Q:MapRはOSSにしないのか? A:MapRで開発したものはApacheに還元はしますが、OSSにはしないよ。フリー版は提供するかも ここで昼食。午前中からいた人にはランチボックスが提供されました。 午後からはコミュニティトラックとテクニカルトラックの2トラックがありましたが、LTが聞きたかった(それよりも英語が辛かった?)のでコミュニティトラックのど真ん中、最前列に入り浸りました。 ★コミュニティトラック ◎Elastic MapReduce Amazonが提供するHadoop:大谷晋平(Amazon)\n・Amazonとは Eコマース 流通 AWS の3つのサービス ・AWS Low-level、High-level、Cross Service、Tools to access services、アプリケーション 色々あるなー ・Bigデータが大変な理由 ケタ違いのデータ量、異なる形式データ、即時性 現状システムはスケールしない ビジネスとして成立する? 成立するならすぐスケールだめならすぐ縮小 ・Hadoopとは? これまでのお話。 スケーラブル、低価格なハード 誰でも入手可能で、実績多数。 ・Amazon EMR AWS上でスケーラブルなインフラ上に構築が可能 オンプレミスからMapReduceアプリを移行可能なため、分析、解析に集中可能 S3からデータIN/OUTするので、データ欠損がない。 Hadoopそのままではチューニングやクラスタサイズ見積もりも難しい =>クラスタサイズを動的に拡張伸縮可能。パフォーマンス最適化もできるよ。 0.18、0.20が利用可能。 EMRはHDFSとジョブ(タスク)トラッカーを別構成にしている。 EC2上にMaster、Core、タスクノードを展開 S3にデータを格納 SimpleDB(KVS)を利用 ・EMR注目機能 ジョブフローの高速化 ジョブの再起動無しにコスト/パフォーマンス比を変更可能。 タスクノードを動的に増やせる 柔軟なデータウェアハウスクラスタ タスクノードをバッチ実行時にのみ増やせる。 ※増減できるのはタスクノード Coreノードは増加のみ EMR+Spotインスタンスの活用 コスト削減効果が非常に高い AWSの余剰リソースをリーズナブルに提供(Amazon的にもウハハだ) ・その他の機能 東海岸だけだけど、スパコンレベルのインスタンスも利用可能 AWS上での最適化設計など ※ちょっと時間足りなくなってきたw ・EMRの事例 1.Razorfish ROAS(広告費用対効果)を500%改善(すげー) 2.So-net ・EMR都市伝説 物理vs仮想 そりゃ、物理が速いよ EMRの柔軟性・拡張性がセールスポイント ビッグデータは成功/失敗が読めないのもあるので、 インフラに投資する部分を少なくできるよ。 オンプレミスが安い? いやいや、HWの購入から設定など時間かかる。 ・Beyond Hadoop HadoopのIn/Out含めてスケーラブル、フレキシビリティが重要 運用管理の仕組みも重要 まだまだやってくよ。 QA Q:EMRは複数サービスから構築してるけど、一部がダウンするとどーなる?(例:SimpleDBが落ちてるとか) A:ジョブはReRunしてもらうか、SimpleDBの状態をみてリカバリをしてもらう。 Q:上記にともない、SLAの計算は? A:SLAはEMRについては定義できてない。S3などはリージョン跨いで Q:S3のセキュリティが心配だが、どう考えてるか? A:いままで脆弱性を晒してデータをロストしてない。 ユーザコントロールなどもできる。基本的には問題ない Q:EMRでS3を使う=Hadoopのローカリティの利点が失われるのでは? A:オーバヘッドはあるが、実際のデータはS3で守られているので、HDFSが飛んでも大丈夫。 Q:S3からのコピーオーバヘッドはどーなるか? A:Single5で少しずつor分割して全部送るも可能 Q:EMRはマルチテナントだけど他のユーザのネットワークの影響を受けないの? A:マルチテナントだと起こる可能性がある。 M1(?)だと内部ネットワークは専有可能らしい。 ◎LT\n・Hadoop and Subsystems in livedoor @tagomoris ピーク時に15Gbps。 10ノード(36コア) CDH3b2を利用 データマイニングではなく、ログからレポーティングをするのに利用している。 hadoop streaming + Hiveで実施 580G/dayが96サーバから来る ScribeにてHadoop Streaming(Perl)でper hourでHiveにload scribelineをWebサーバに入れててログ配送してくれる。 ** ・Lightweight @stanaka(はてなCTO:田中慎司さん)**\nEMR以前 自前20台クラスタ ジョブがあふれてきた ナマMapReduceを利用 PerlでMapper/Reducerを記述(Hadoop Streaming) EMR導入 リソース増やせて便利! 必要な台数に伸縮可能 問題点: S3にアップしないとダメ =>ログデータをS3に展開するlog2s3.plを作成。毎時実行。 起動、ジョブキック、結果改修どーする? =>Net::Amazon::EMR::Wrapperを作成した。 クラスタ起動、ジョブキック、クラスタ停止などできる 作ってみて思ったこと よかったところ: Perlでかける。Cronで実行可能。HiveQL便利。 悪かったところ。 途中で失敗してクラスタ起動しっぱなしとかがある。S3にデータを展開が大変。複雑な計算がきつい。 慣れてないエンジニアにも触れるようにしたい =>Perlで書けるようにした?。 ** ・HBaseでグラフ構造を扱う(開発中):アメーバ鈴木**\n自己紹介@brfrnl69 アメーバのソーシャルグラフ 基本はMySQL マスタ分散が難しい、シャーディング管理が面倒 =>HBaseでやってみるか。 目的 グラフデータに対して高速に更新追加したい。 隣接ノードが取れればいい(これを高速化したい) オンライン処理したい 運用コストの削減したい。 Not目的 マルチホップはどうでもいい。 アーキテクチャ JavaでGatewayつくってみる。 ・Large-Scale Graph Processing:井上さん(@doryokujin)さん Map/Reduceではグラフ計算だめ? Vertex基本だとShuffleに問題ががが。 BSPの紹介 Bulk Synchronous Processing Google Pregel SSSP:MapReduce Model すごい計算時間が掛かりそう。MRの組み合わせが何回回ることやら。 枝が少ないとこっちのほうがいいのか? SSSP:PregelModel シンプルなアルゴリズム Pregel使えるのあるの? Hama GoldenOrb Giraph YERN?YARN? ◎リクルート式Hadoopの使い方:石川(リクルート)\n@ground_beetle ・導入の課題点 バッチ処理時間対策のため。 =>実は入れたかっただけw ・導入の障壁 現行システムへの影響+開発工数 =>これへの対処がこのあとの話 ・課題の克服と活用シーン Azkaban知らなかった。ジョブスケジューリングツール Hadoop単体ではなく、エコシステム(関連ツール)が魅力 ・活用シーン:Hive SQLゆーがざ多く、HiveQLがSQLライクのため導入が簡単に! 既存機能のリプレイス系案件に活躍(低工数+簡単に高速化) とりあえず、Hive実装 =>性能アップのためにMapReduceで書きなおし Hotpepperなどのアトリビューション分析に利用 ・活用シーン:Sqoop+Hive RDBとHadoop連携のツール:Sqoop 現行システムの横にHadoopを配置でき、RDBMSの利点も利用しつつHiveも利用できるようになる。 (※気を付けないといけないけどねぇ。) ゼクシィで活用しようとしてるところ。 ・活用シーン:Mahout マイニング用ツール カーセンサーのレコメンド(同時に閲覧される車種) アソシエーション分析+クラスタリング ・活用シーン:BIツールの導入 何度か導入しようとして失敗してます。。。 BIツールの前処理(クレンジングなど)にHadoopを活用 ・インフラリソースは? 全部で118台。 最小のクラスタ構成はサーバ6台で構成してる ・Hadoopで複数処理を回す方法 ここまで紹介したものを入れてますよ。Hive、Sqoop、Solr。。。 ・Azkaban TomcatにWar配置で利用可能。 LinedInのチームにより作成 ※若干マシントラブルで中断 ・今後のHadoop導入 ログ基盤 分析エンジン・レコメンドエンジンとして バッチ処理短縮=トライアンドエラーが簡単にできるようになる。=色々な気づきが出てくる。 アジャイル的な解析が可能に。 ・開発サイクルの短縮ができるエコシステムでビジネスが回りだす。 ・今後の展開 MapRが気になってる。 マルチテナント対応ができてうはうはできそう。 EMCと共同して検証中 QA: Q:性能監視ツールの選別の理由は? A:Zabbix、Cactiです。今から利用しようと思っている段階。 Q:CDH、GreenPlum、Apacheをそれぞれ利用してるけど、使い分けのシーンは?比較は? A:CDH3u0です。GreenPlumは使ってないです。理由は言うとクビが飛ぶ可能性ががが。 Q:高度なデータ分析ができる技術者はどこからヘッドハントしてるの? A:MITに別途分析チームが存在し、高度な分析をしてくれる。 Q:NameNodeの冗長化はどーやってんの? A:象本と一緒DRBD+HeartBeat Q:EMRの導入を検討してる? A:今後、サーバ数が多くなると導入の検討をしていくと思う。 現時点は、運用ノウハウも入手するために社内で使ってる。 EMRになるかRCloud(リクルート社内クラウド)になるかは不明。 Q:HBaseを利用してる? A:してないです。スペック的にサーバが買ってもらえないと厳しいです。 ◎The history and the future of Hadoop use case at Rakuten:Tarje Marthinussen(楽天)\n・Introduction(self、rakuten) NextGeneration Search Group Norwayから来ましたよ。 ・RakutenのBigDataとは ・Hadoop at rakuten Recommendation(2009) ProductRanking、GenreRanking、Log解析、(2010) Enhance Search。。。(2011) ・PigやHiveのようなものが簡単に利用できるようになってきた ・新しい検索プラットフォームを構築中 index 10k docs/sec search 400qps ・What\u0026#39;s Next Generation Search 20%はインデックスとQuery評価の 50%がデータの前処理(データとQuery) 30%がアナライズ ・Collecting Data? ログの取得はバッチ処理だった。これをStreamingに(Flume) ・Flume Zookeeperを利用してFlumeを管理してる??? ・気になる部分があったので、改善のコーディングしてるよ。 ・セキュリティ マスタで管理できるように ・Pools Agentが送信先がコケてると他のPoolにスイッチ可能に。 ・MasterlessACKs QA Q:パッチ作成は何人でやってるの? A:50人が働いていてOSSコミッターが何人いるかはわからんです。 Q:ログはテキストだけど、パース処理はどこで?(古橋さん) A:Flumeは各ノードでうまい構成になっていて Decorator 性能問題は? HiveはJSONデータをうまく活用できてるよ。 Q:Masterlessとそうじゃないバージョンの性能比は? A:ノード数が増えると Q:HBaseじゃなくてCassandraなの? A:(※英語きつい。。。聞き取れず) ◎マーケティング向け大規模ログ解析事例紹介:原謙治(NTTコミュニケーション)\n・自己紹介 ・BizCITYというクラウドサービスを展開中 まずは、宣伝。 Bizストレージ、Bizマーケティングとして大規模データ、分散処理を実施してる。 ・Hadoop in Bizマーケティング CGMデータを解析して口コミ情報抽出 アクセスログから行動情報抽出 ・Hadoop in BuzzFinder CGM DBからHDFSにインポートして解析開始。DBはPostgreSQL 処理フローは資料参照。 リッチインデクシング技術(NTT研究所が開発した日本語解析技術) ※検索インデックスってどんなものなんだろう? ポジネガ分析気になる。 ・Fast Map-Reduce for PaaS Services アクセス解析やマーケティング解析を行う上でShuffleコストが大きくなるため大量マシンが必要 =>マシン数を減らすことが目的? Map Multi-Reduce、PJoinはNTT研究所が開発した技術!?(子象本にないっけ??) =>Multi-Reduce。同一ノード上のMap出力をReduceすることで、shuffleフェーズに渡るデータを削減している。 =>PJoin QA Q:Map multi-reduce、PJoinはどう実現してるのか?公開するのか? A:Hadoopの0.19に改造をしてる。 公開できるかどうかはわかりません。NTT研究所が研究しているものを試しに実装してみてるから。 なのでパッチにはなりませんかね(研究所に聞いてみないとわからないっす) Q:性能が向上したパターンはあったが、悪化する場合などはあるのか? A:不明 Q:Map-side Joinとの違いは? A:。。。 ※この辺で少し集中力が途切れてしまいました、すみません。(次に集中したかったので。。。) ◎ミクシィにおけるHadoopの利用:伊藤敬彦(mixi)\nLSH-Based Recommendation engine powered by hadoop ・実はmixiの話はすくないよ。 ・利用している環境。5or6台/クラスタ ・Hadoopの活用 ログデータをHDFSに保存 DBコンテンツをHDFSに入れることで、DBに負荷をかけずに解析する。 ・マイニングも検証中 検索クエリログをベースにデータマイニング では、本題。 ・LSHを利用した推薦 ・推薦とは? mixiにはいろいろ推薦(レコメンド)を付加できるサービスがある。 ・推薦するには? 類似インスタンス集合を抽出する。 インスタンスは文書だったりユーザだったり ・類似インスタンスとは? 同じ特徴を持つ集合 例:同一商品購入したユーザとか同一単語を持つ文書とか ・抽出するには? 全ユーザごとに全ユーザとの類似性をチェックすると時間がかかりすぎる! =>LSHを利用しよう! ・LSHについて 特徴: ・速い! ・精度はそれほどではない 事例: ・Google Newsのレコメンド(USロケール) ・LSHの処理ステップ 2つだけ。 1.インスタンスベクトルを計算(似ているデータは同じ値が返りやすい関数) 2.同一値が帰ってきたデータが類似インスタンス ・インスタンスベクトル例(あとでスライド見ようね) ・Likelikeがいち実装。Hadoopでうごくよ ・実験について トップページに表示されていない記事を知ってもらうために推薦してみるぞ! ・実験1 性能を測ってみた ・実験2 精度を調べてみた。 精度はほんとにひどいな。。。 =>同一カテゴリの遷移を元に計算したらそれなりになってきた。 ・今後 データソースを増やしたい。 他のアルゴリズムも実装したい ・CM 以下も作ってますよ。 Oluolu Anuenue QA Q:Mahoutは使わないんですか? A:Likelikeを作った頃にMahoutになかったので作った。 性能比較したいと思ってる。 Q:ログサーバのデータ転送はどーやってる? A:伊藤さんのところにはどういう仕組みかは上がって来てない。 Q:ベクトルの次元数はどのくらいまで耐えられる? A:高次元のデータに対して耐えられるように作られてる。 次元数が低くて良い制度が欲しければ他のアルゴリズムがいいかも。 Q:ユーザのベクトルを作るテクニックは? A:画像などであれば大変だけど、ユーザであれば、単語とかキーワードとかで Q:ニュース以外のデータは? A:まだまだ実験中。まだやってない。 Q:推薦される記事数のばらつきはどういった理由が考えられる? A:後ほど考察してQAサイトに入れます。 Q:LSHをMapReduceに載せたということだけど、関数の計算をさせてる? A:Iterationはしてない。 Map側でLSH関数計算してる。Reduceにて類似インスタンスを導出してる。 Q:今後の予定の空間木とは?R-Treeだと高次元できついのでは? A:低次元にて利用できるように用意したい。 Q:HamaとかGiraphで高速化させてみるのはどう? A:イテレーションがいらないからあまり利用用途がないかなぁ。 ◎懇親会\nAWSを採用しない企業がいくつかあったのでそのあたりを質問してみた。 AWSは通常運用に利用すると結構なコストがかかる場合があるので、ノウハウがある企業や データ量が多い場合は、オンプレミスの場合を選択しているらしい。 やはりスポットで利用する方がお得感があるみたいだった。 Twitter上だけの知り合いだった方々と面識が持てたのが一番の収穫でした。 感想+調べること\n感想\n会場規模とかQAサイトとかオープニングムービーとかすごかったです。しかも無料。さすがリクルートさん。 ランチボックスとか出てきたし。装飾もとても無料のカンファレンスと思えない出来でした。 午前中はHadoopをもとにした各社の戦略とCMという感じが色濃かったです。少しずつ各社の立ち位置が違いそれはそれで面白かったです。 AWSの説明を聞いてやはりAWSを扱える技術は必要だと再認識。 お金かけないで触ってみれるレベルでまずは触ってみるかなぁ。 洗脳されてるのかもしれないけど、自社or自前でHadoop運用するのは厳しそうです。(懇親会ですこし認識が変わった) カフェコーナーでは、リクルートのMITの冊子が配られていたり、映像や案内に使われていたHadoopマスコットのシールが配られていたりと小技も聞いてました。 あと、オライリーの販売コーナーも用意されていて、思わず子象本を買ってしまう罠にはまったりもしましたが。。。 mixiの伊藤さんの話は最後で疲れていたのですが、ストーリーが上手くできていて、実験や事例もあったのでわかりやすかったです。 Hadoopはエコシステムと呼ばれるHadoopを活用するツール群(Hiveの話が多かった?)、Hadoopの今後、Hadoopを活用したログ解析の話など、 話題が豊富でそれぞれの話が面白くて困ってしいまうくらいです。 いくつかのセッションで出てきたのですが、アクセスログなどをHDFS上に集めるための仕組みがまだ乱立(定番がまだない)している感じを受けました。 Flume、Scribe、MapR。。。などなど あとは、テクニカルセッションのビデオがアップされたらまた目を通さないと。。。 残念ながらHadoopから少し縁遠くなっていますが、これからもネタや参考になりそうな話には事欠かなそうなのでかじりついていこうと思います。 ※一番やらないといけないのは英語の勉強かもしれないです。。。 調べること 一応Solrの人なので、Solrに関連しそうな話に興味がいってしまいます。\nNTT研究所のリッチインデクシング技術 やっぱりAWS触ってみる。EMRまでとは言わないが。(herokuもちょっと興味あるが。) Mesos、GreenPlum、Scribe、Storm、Flume、Giraphこれらの概要 関連サイト 公式QAサイト。後日録画していたセッションがアップされるそうです Hadoop Conferene Japan Fall 2011 - 急がば回れ、選ぶなら近道 Hadoopカンファレンスが開催、本格普及を見据えた支援サービスや先進事例が充実 - ニュース:ITpro Hadoop Conference Japan 2011 fallで使用された資料 #hcj11f | インフラエンジニアのつぶやき(スライドをまとめてくれてます。)\n","date":1317113460,"dir":"post/2011/","id":"97402287d8c6c03f0b63848e17e9d944","lang":"ja","lastmod":1317113460,"permalink":"https://blog.johtani.info/blog/2011/09/27/hadoop-conference-japan-2011-fall%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%A6%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-09-27T17:51:00+09:00","summary":"Hadoop Conference Japan 2011 Fallに行ってきました。 まずは、ユーザ会の方々、運営の方々、発表された方々お疲れ様でした。こんな機会を用意していただき、ありがとう","tags":["hadoop"],"title":"Hadoop Conference Japan 2011 Fallに参加してきました。(Jugemより移植)"},{"contents":"台風15号すごかったですね。幸いにも(?)夏休みだったので、通勤などでひどい目に合わずにすみました。 風雨はすごくてちょっと怖かったですが。。。\nさて、夏休みに進める予定が、子供の寝かしつけで一緒に寝てしまう日が続いてしまい、 間が開いてしまいました。\n0日目というタイトルになっているのは、まだ、1日目に入ってないからです。。。 Ioという未知の言語をMBAにそのままインストールするのも抵抗があり、VirtualBox上にLinuxをインストールしてから 進めようとして思いの外手こずってしまったためです。 ということで、0日目として、VirtualBox上にScientific Linux 6.1をインストールしてIoのインストールまでではまった箇所を記録として残しておきます。\n罠その1 罠と言うよりは、私の無知に関する部類なのですが。。。 Scientific Linux 6.1のインストールは特に手こずることなくインストールでき、 起動も出来ました。 次にscpコマンドでダウンロードしてきたIoのソースをLinuxに渡そうとしてはまりました。 問題となったのはネットワーク接続が「NAT」のみだったため。 NATのため、Linux(ゲストOS)から外部への接続は可能だったのですが、Mac(ホストOS)からLinux(ゲストOS)への接続ができませんでした。 で、変更したのは以下の2点。\nVirtualBoxの環境設定-\u0026gt;ネットワーク-\u0026gt;ホストオンリーネットワークの追加 仮想マシン(Linux)の設定-\u0026gt;ネットワーク-\u0026gt;アダプタ2を有効にしてホストオンリーアダプタを割り当て 1番目のホストオンリーネットワークの追加をしておかないと、2番目のアダプタ2でホストオンリーアダプタを選択したときにエラーが出て、設定ができませんでした。割り当てるべきアダプタを先に用意しとかないとダメですよね、そりゃあ。\n罠その2 これも罠というほどではないのですが。。。 Ioのビルドにはcmakeが必要なのですが、Scientific Linux 6.1に入っているcmakeはバージョンが古い(2.6.4)ため、必要なバージョン(2.8以上)をインストールしないとダメでした。 インストール自体はcmakeのサイトにある手順通りのため割愛します。\n罠その3 これもちゃんとドキュメント読めよというレベルですが。。。 Ioのインストールは以下のコマンドを実行するという話です。 私がcmakeについて知らなかったと言われればそれまで。。。\n$ cd io $ mkdir build \u0026amp;amp;\u0026amp;amp; cd build $ ccmake .. $ make $ sudo make install 3つ目の「ccmake」の部分がIoのGetting Startedの下の方にありました。上の方に記載がある「cmake」ではエラーがでてうまく行かなかったので。 IoのGetting Startedにもありますが、ccmakeの場合はCUI上にGUIのようなものが起動するので、「c」(configure)と実行後、「g」(generate)を実行して最後に「e」(exit)でccmakeを離れます。 するとmakeが実行できるようになりました。\nあとは、/etc/ld.so.conf.d/io.confファイルを作成し、「/usr/local/lib」と記述。ldconfigを実行することで、Ioが実行可能になります。 ということで、1日目に入れず終了。。。\n明日は出来るかなぁ。\n","date":1316716440,"dir":"post/2011/","id":"62f31128a21b0e240bdb7b3d5b121c04","lang":"ja","lastmod":1316716440,"permalink":"https://blog.johtani.info/blog/2011/09/23/7%E3%81%A4%E3%81%AE%E8%A8%80%E8%AA%9E-7%E3%81%A4%E3%81%AE%E4%B8%96%E7%95%8C-io-0%E6%97%A5%E7%9B%AE/","publishdate":"2011-09-23T03:34:00+09:00","summary":"台風15号すごかったですね。幸いにも(?)夏休みだったので、通勤などでひどい目に合わずにすみました。 風雨はすごくてちょっと怖かったですが。。","tags":["読書"],"title":"「7つの言語 7つの世界」 Io 0日目(Jugemより移植)"},{"contents":"Solr/Lucene 3.4がリリースされました。(速報)\n以下、各サイトへのリンクです。\nSolrリリースのお知らせ\nLuceneリリースのお知らせ\nちなみに、先日のSolr勉強会で関口さんが話されていたインデックスが壊れるバグですが、 先日のアメリカのハリケーン(Irene)で実際に電源が落ちて見つかったみたいです。\nということで、3.4がリリースされたので、3.1~3.3は利用しないほうがいいようです。\n追記: lucidimagination.jpのサイトに日本語のリリースノートが公開されていたので、リンクを記載しておきます。\n","date":1316046660,"dir":"post/2011/","id":"54da1b916f49ef40c822fab61d37cf66","lang":"ja","lastmod":1316046660,"permalink":"https://blog.johtani.info/blog/2011/09/15/lucene-solr-3-4%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E9%80%9F%E5%A0%B1/","publishdate":"2011-09-15T09:31:00+09:00","summary":"Solr/Lucene 3.4がリリースされました。(速報) 以下、各サイトへのリンクです。 Solrリリースのお知らせ Luceneリリースのお知らせ ちなみに、先日の","tags":["solr"],"title":"Lucene/Solr 3.4リリース(速報)(Jugemより移植)"},{"contents":"ということで、Rubyの最終日の感想。 今回もセルフスタディの私の回答が最後の方に記載されてます。見たくない人は気をつけてください。 ツッコミ大募集です。コメント欄にどしどしコメントください。そこは違うだろ?こっちのほうがいいのでは?という感じで。\n感想: ◎メタプログラミングが特徴 例:ActiveRecordのhas_many、has_oneがいい例\n◎オープンクラス クラス定義をいつでも変更可能。 あらゆるクラスやオブジェクトをいつでも再定義できる 書きやすいコードのために再定義が可能=何でもできるが気を付ける必要あり。 DSLの定義に便利。 確かに便利。ただ、範囲を限定しないと予期せぬ場所で問題が発生しそう。 ※解析するための手段はいいのがあるのかな?=\u0026gt;method_missingみたい\n◎method_missing 対象メソッドが見つからない場合に最後に実行されるメソッド 通常はNoMethodErrorが発行される。\n◎モジュールによるメタプログラミング defやattr_accessorなどその一例。 DSLではモジュール内にメソッドを定義してメソッド+定数を利用 ActsAs\u0026hellip;ってそういう意味合いだったのか。 親クラスバージョン、親クラス+マクロ、モジュールそれぞれの実装の仕方の紹介。 ※マクロもinclude同様、実行順で、メソッドの上書きが発生するのか? ActiveRecordではメタプログラミングを利用してDBのカラム名からアクセサを追加。 シンタックスの美しさ=読みやすさ\n感想&疑問点: メタプログラミングはフレームワークを作成するのが便利そう。 ただし、エラーや問題が起きた時の対処をきちんと準備しておかないとひどい目に合いそう。 クラスやモジュールはわかりやすい単位で1ファイルにまとめるもの? ファイル名の規則とかあったりする? ディレクトリ構成でパッケージ構成が可能? 複数のモジュール(gemとか)を組み合わせて使っている場合にincludeの順序がどのようになるかが気になる。 予期せぬ順序でincludeされて利用しようと思ったメソッドがオーバーライドされてるとかありそう。 追っかけるのがまた大変そうだ。 異なるパフォーマンス(開発者の開発速度)の観点が一番おもしろかった。ただ、なれるまでは大変そう。すんなりinjectとかコードブロックをうまく利用するイメージがわかない。 まぁ、思考については反復練習かな。これは他の言語でも一緒かな\nようやく、Rubyの世界が終わりました。楽しかった。次は未知の言語である「Io」です。\n(試してみよう:) ○eachメソッドがCsvRowオブジェクトを返すようにCSVアプリケーションを変更せよ。そのCsvRowのmethod_mmissingを使って、与えられた見出しの列の値を返すようにせよ。 モジュールにて実装してみた。 ``` module ActsAsCsv\ndef self.included(base) base.extend ClassMethods end module ClassMethods def acts_as_csv include InstanceMethods end end\nmodule InstanceMethods\ndef read @csv_rows = [] file = File.new(self.class.to_s.downcase + '.txt') headers = file.gets.chomp.split(', ') file.each do |row| @csv_rows \u0026lt;\u0026lt; CsvRow.new(headers,row.chomp.split(', ')) end end def each(\u0026amp;block) csv_rows.each(\u0026amp;block) end attr_accessor :csv_rows def initialize read end end\nclass CsvRow def initialize(headers, csv_contents) @headers = headers @csv_contents = csv_contents end\nattr_accessor :headers, :csv_contents def method_missing name, *args csv_contents.fetch(headers.find_index(name.to_s)) end end end\nここまでが実装したモジュール+クラス。 以下は実行例。id,name,sizeというheaderをもつCSVを使ってみた。 require \u0026lsquo;acts_as_csv_module_mod.rb\u0026rsquo; =\u0026gt; true class RubyCsv include ActsAsCsv acts_as_csv end =\u0026gt; RubyCsv csv = RubyCsv.new =\u0026gt; #\u0026lt;RubyCsv:0x103c4c530 @csv_rows=[#\u0026lt;ActsAsCsv::CsvRow:0x103c4c030 @csv_contents=[\u0026ldquo;1\u0026rdquo;, \u0026ldquo;RubyCsv.class\u0026rdquo;, \u0026ldquo;20\u0026rdquo;], @headers=[\u0026ldquo;id\u0026rdquo;, \u0026ldquo;name\u0026rdquo;, \u0026ldquo;size\u0026rdquo;]\u0026gt;, #\u0026lt;ActsAsCsv::CsvRow:0x103c4be78 @csv_contents=[\u0026ldquo;2\u0026rdquo;, \u0026ldquo;JRubyCsv.class\u0026rdquo;, \u0026ldquo;50\u0026rdquo;], @headers=[\u0026ldquo;id\u0026rdquo;, \u0026ldquo;name\u0026rdquo;, \u0026ldquo;size\u0026rdquo;]\u0026gt;]\u0026gt; csv.each {|row| puts row.name} RubyCsv.class JRubyCsv.class =\u0026gt; [#\u0026lt;ActsAsCsv::CsvRow:0x103c4c030 @csv_contents=[\u0026ldquo;1\u0026rdquo;, \u0026ldquo;RubyCsv.class\u0026rdquo;, \u0026ldquo;20\u0026rdquo;], @headers=[\u0026ldquo;id\u0026rdquo;, \u0026ldquo;name\u0026rdquo;, \u0026ldquo;size\u0026rdquo;]\u0026gt;, #\u0026lt;ActsAsCsv::CsvRow:0x103c4be78 @csv_contents=[\u0026ldquo;2\u0026rdquo;, \u0026ldquo;JRubyCsv.class\u0026rdquo;, \u0026ldquo;50\u0026rdquo;], @headers=[\u0026ldquo;id\u0026rdquo;, \u0026ldquo;name\u0026rdquo;, \u0026ldquo;size\u0026rdquo;]\u0026gt;] csv.each {|row| puts row.id} (irb):8: warning: Object#id will be deprecated; use Object#object_id 2179096600 (irb):8: warning: Object#id will be deprecated; use Object#object_id 2179096380 =\u0026gt; [#\u0026lt;ActsAsCsv::CsvRow:0x103c4c030 @csv_contents=[\u0026ldquo;1\u0026rdquo;, \u0026ldquo;RubyCsv.class\u0026rdquo;, \u0026ldquo;20\u0026rdquo;], @headers=[\u0026ldquo;id\u0026rdquo;, \u0026ldquo;name\u0026rdquo;, \u0026ldquo;size\u0026rdquo;]\u0026gt;, #\u0026lt;ActsAsCsv::CsvRow:0x103c4be78 @csv_contents=[\u0026ldquo;2\u0026rdquo;, \u0026ldquo;JRubyCsv.class\u0026rdquo;, \u0026ldquo;50\u0026rdquo;], @headers=[\u0026ldquo;id\u0026rdquo;, \u0026ldquo;name\u0026rdquo;, \u0026ldquo;size\u0026rdquo;]\u0026gt;]\n\u0026lt;span style=\u0026#34;color:#FF0000\u0026#34;\u0026gt;※idというcsvフィールド名にしたら、object_idとかぶっているようでwarningが出てしまった。\u0026lt;/span\u0026gt; CsvRowクラスの定義がモジュールの中に入っているが、この実装でも動くみたい。ただ、パッケージみたいな感じ7日までは調査してない。。。 ","date":1315992060,"dir":"post/2011/","id":"41b811063b9425de1934e77d89118022","lang":"ja","lastmod":1315992060,"permalink":"https://blog.johtani.info/blog/2011/09/14/7%E3%81%A4%E3%81%AE%E8%A8%80%E8%AA%9E-7%E3%81%A4%E3%81%AE%E4%B8%96%E7%95%8C-ruby-3%E6%97%A5%E7%9B%AE%E6%9C%80%E7%B5%82%E6%97%A5/","publishdate":"2011-09-14T18:21:00+09:00","summary":"ということで、Rubyの最終日の感想。 今回もセルフスタディの私の回答が最後の方に記載されてます。見たくない人は気をつけてください。 ツッコミ大","tags":["読書"],"title":"「7つの言語 7つの世界」 Ruby 3日目(最終日)(Jugemより移植)"},{"contents":"「第6回Solr勉強会」に参加しました。 なんだかんだと第6回で、今のところ皆勤賞です。\nということで、主に自分用ですが、メモなどとったので。\n概要\n日時 :2011/09/12 19:00 to 21:00 定員 :110 人 会場 :株式会社 ECナビ 1.「Lucene/Solr 3.2-3.4」 by ロンウイット 関口 宏司さん ※Solr2.9.4、3.1でデグレードし、Solr3.4で修正されたバグがあります。 インデックス中にPCがシャットダウンされた場合にインデックスが壊れてしまうものあり。 Solr3.1-3.3は使用しないようにとのこと。 ○index ・IndexWriter.addDocuments(docs) 複数ドキュメントの更新が可能になった。 ※検索で話をする親子関係のNestedQuery向けの登録にも利用する。 この登録では途中でフラッシュされないため、セグメントが分割されない特徴あり。 複数だけでなく、 ・TieredMergePolicy ※Lucene3.2/Solr3.3からデフォルトになった。 新しいインデックスのマージポリシー。(amebaの開発者ブログに説明があった。) インデックスの登録順が守られていたが、このマージ処理では保証がされなくなったので注意が必要。 ・update.chain update.processorがdeprecatedに。 update.chainというパラメータに変更 ○index(cont\u0026#39;d) ・TwoPhaseCommit ・UniqFieldsUpdateProcessor 重複した値を削除するための機能。 UIMAでの提案から取り込まれた ○search ・group=on 検索グルーピング機能を使えるパラメータ ・{!term} クエリパーサを通さないでTermQueryをかける機能。 ・structured explanation debug=onの算出根拠を XMLタグで構造化されたExplanationが取得可能に ・ReloadCacheRequestHandler 関口さん担当。ExternalFileField インデックス外(外部ファイル)を元にFunctionQueryの情報を利用可能にできるのだが、 このファイルのリロードが可能になる。 ・Carrot2 3.5.0 アップグレード。 デモあり。Carrot2のworkbenchとか ○search(cont\u0026#39;d) ・hl.phraseLimit parameter FastVectorHighlighterの高速化用パラメータ。 ・{!cache=false} キャッシュを利用しないためのローカルパラメータ。fqのローカルパラメータに利用可能。 検索セッション内でキャッシュへの処理(参照・登録)をしなくなる ・BlockJoinQuery NestedDocumentQueryの名前が変更された。 (Luceneで登録されたところまで。) ○schema ・KStemFilter PoterStemmerとは別のstemmer ・ReversePathHierarchyTokenizer パスの構造化インデックスの逆バージョン ・ommitPositions=\u0026#34;true\u0026#34; 指定が可能になった。 ・version 1.4 スキーマのバージョンが新しくなった。 ○admin/tools ・action=MERGEINDEXES\u0026amp;srcCore=coreName コア名指定可能。 ・action=UNLOAD\u0026amp;deleteIndex=true UNLOAD時にインデックス削除 ・action=CREATE\u0026amp;property.name ※ぎゃーーー。打ち込み失敗。 ○ぎゃーーーー失敗。 ○技術者大募集中!! Q\u0026amp;A Q:クラスタリングの日本語は大丈夫?入門には制限があると記載があったが。 A:analyzerが記載が簡単になってるかは不明 前処理をして別フィールドにメタデータ的にある程度単語で区切ったようなものを作成したほうがいい。 Q:グルーピングで、グルーピング後のファセット件数が取得可能か? A:3.4ではグループ数で表示可能。 パラメータ指定で可能。 2.「Solr@cookpad」 by @PENGUINANA_ さん ○COOKPADとは? ・レシピ投稿サイト ・105万のユーザのレシピ ・30代女性の1/2が利用 ○レシピ検索 ・PC:1307万UU、1億回強/月 ・モバイルで利用が多く、スーパの店頭などで利用? ・Androidもあるよ。 ○人気順検索(Solrですよ) ○自己紹介 ・@PNGUINANA_ ・情報可視化+検索が好き!! yats、など ○Solrはどのように利用 ・レシピ検索 ・もしかして ○Tritonnから移行 同じ検索結果になるようにして徐々に移行 ○なぜ? パフォーマンスが良い。 フィールド追加が簡単 レプリケーション-\u0026gt;ファイルベース プロトタイピングが楽 ○Solr4 nightly(on Oracle JVM) ・マルチコア利用 ・Ruby on Railsから ○簡単な構成+説明 ・バッチからSolrへの更新をしている。 ※Analyzerを利用せず、バッチ側で分かち書き、正規化、同義語展開を行っている。 Rubyで全部かけるほうが社内に展開しやすい。 ・バッチ終了後、可能ならoptimize ※検索速度がmax20%高速になる。 ・マスタ-\u0026gt;スレーブレプリケーションはschema.xmlもレプリケート 新規フィールド追加などはレプリケーションだけで実行できて楽。 ・アプリはMySQLとSolrのSlaveにアクセス。 Solrにはidのみ。本文はMySQLから取得 インデックスサイズを小さくできる=レプリケーション時間が短くなる オンメモリにできるため検索速度も向上 ○監視(munin) ・監視項目(コア別): クエリ:QTime/QPS キャッシュ:hit/eviction キャッシュから漏れている数をみてキャッシュサイズを定期的に変更して無駄をなくす インデックス:サイズ/docの数 運用してから重要。開始当初は気にしてるが、そのうち気にならなくなるため。 レプリケーション:所要時間 スレーブ間でのズレを検知するため。 ※コアごとに監視することで、問題点を把握しやすくしている。 ○監視(nagios) ・監視項目(コア別): サーバの基本的なヘルスチェック Solrが動いてるサーバのはなし。 レプリ:インデックスバージョンのチェック ズレが長いとメールが飛ぶ ○便利だった機能 ・DynamicField フィールドをあとから簡単に追加可能。 例:人気順のアルゴリズムの違うフィールド。検索用フィールド ・FacetQuery 絞り込み検索をクエリで記載可能。 現時点では社内向け検索機能で利用。 ※ファセットで簡単な解析もやってる。 例:鍋の季節ごとの登録件数。 ・HTTP経由で色々可能 検索の並列化 通常検索画面:3クエリを同時実行 あるプロトタイプ画面だと8クエリで実行したりしてる。 ・分散検索(Distributed Search) 簡単にsharding可能 思いクエリは4shardで投げる オーバヘッドが大きいので思いクエリにだけ利用しているらしい。 ○開発の流れ ・まずはステージングを更新 ・問題なければマスターも更新 例外: フィールド追加するだけだったら直接マスタへ 例:ファセット追加など。 ○パフォーマンスとか大丈夫? 本番で複数のバージョンを持っており、 バグっていても自動フォールバックするらしい。 価値があったらパフォーマンス向上+テスト追加 例:スニペット変更 ○気になっている機能 ・not to cache(SOLR-2429) ・SurroundQuery(Solr-2703) ・JOIN(SOLR-2272) SQLのJOINなイメージ ・BloomFilter(SOLR-1375) 単語が存在するかどうかのチェック ○Solr入門おすすめ ○おすすめ ・http://blog.sematext.com 月一で新機能が出てくる ・SolrのJIRA ・@otisg ○今後やりたいこと ・わかち書きの精度向上 ・検索セッションの分析 nDCG、クエリ分類、検索意図 ・デバイス対応 ・パーソナライズ Q\u0026amp;A Q:同義語は誰が集めている? A:外部辞書を利用。0件キーワードから解析して取得 単語登録も一緒。 Q:プチトマトとトマトの違いはどうやってる? A:上位、下位の概念で同義語を利用している。 本にあるよ。 Q:もしかしてはSolrの機能? A:Solrではない。訂正候補の単語をSolrに検索してからチェックして表示する。 Q:人気順はどういった計算をしてるんですか?計算してから登録?By 大谷 A:1フィールドに外から入れている。 Q:RubyからSolrの利用方法は?独自?ライブラリ?By 大谷 A:Rsolrを利用しており、コネクション管理にだけ利用している。 あとは、ラッパーを独自で作成。 Q:4.0を利用している理由は?なかなかチャレンジャー。By関口 A:グループクエリを利用したかったため。 実際には重くて使えていない。 今は必要ないかもと思っている。年始のバージョンを利用。いつでも入れ替え可能。 マスタスレーブ構成のsolrのバージョンアップはサービスアウトしてから入れ替える。 3. 「Solrを用いた検索システムの構築」 by データセクション株式会社 高井さん いろいろな試行錯誤について ○データセクションについて 言語処理を元にデータの解析(Twitterとかブログとか)している会社。 ・昔は自社で検索サーバを構築していた ・Luceneを利用して検索サーバを構築するように変更。 ○構成(過去?) ・Lucene+RMI 3.0から縮小で、4.0で廃止に ○SolrにするかLuceneにするか? ・いろいろ機能があるからSolr使ってみるかw ○Solr導入は1.4.1から スペック マスタ: メモリ:16G Disk:2Tx12 スレーブ: 256GのSSDを利用 JavaVMが32bit ○ひと月分を1shardにして登録 ○検証+手探り? メモリが足りない。 Solrのキャッシュを全Offに。 BOBO SolrPluginってのを利用 compressオプションも利用。 各スレーブにキューを用意して1つだけしか処理しない。(なんでだ??) ○結果 キャッシュはフィルタキャッシュのみ利用 ユーザが同じクエリを投げるのはほぼないので。 フィルタキャッシュのエントリのメモリ量の計算式(あとで資料が出てくるかなぁ。) ○問題点 ・レプリケーションでインデックスサイズの2倍の容量が必要になる。 ・レプリケーションの日時フォーマットのバグ(SOLR-1995)を踏んでしまった。 ・レプリケーション後にインデックスが消えない場合がある ○検討(1.4.1-\u0026gt;3.2) うれしい要素 レプリケーションバグがfix 省メモリや範囲検索の高速化など かなしい要素 compressが使えなく(しかも回答してからriindexしてくれる) ○検討 余計なインデックス消す nearinfinityが出しているlucene-compressionを利用 https://github.com/nearinfinity/lucene-compression ○残った問題 facet.rangeが使えないなど。 ○じゃあ集約サーバつくっちゃえ(すごいな。) facet書き換えコンポーネントなど。 ○シャードのインデックスサイズが下がった 130GiB-\u0026gt;90GiB これはlucene-compressionの効果 ○ここまでの変更はプラグインにて対応(この一覧いいかも) ○感想 コンポーネント化されてて、簡単に追加機能が実装可能 用途次第であまりスペック高くなくても使える。 Q\u0026amp;A Q:Twitterのデータのクロール方法は? A:HTMLをスクレイピングしている。publicなTLのみ。 Q:いきなりSolrに入れる?Solrの前処理は? A:SolrJを利用して前処理済みのデータを登録している。 4. 「Anuenueの紹介と最近の進捗」 by @takahi_i さん(mixi) ○自己紹介 ・NAIST出身 ・ファストサーチ ・今はmixi ○mixiとは? ○社内の緊急タスク ・内製検索エンジンをメンテナンスしやすいOSSにしたい! -\u0026gt;Solrを選択 Anuenueも実装 ○Anuenueの作成理由は? インデックス運用が面倒(検索(distributed search)はあるがインデックスは自前) クラスタ用のコマンドが提供されていない。 ○Anuenueが提供する機能 ・検索クラスタの簡単設定 ・クラスタ用コマンド ・もしかして機能 ○機能:Anuenueのクラスタ設定 Merger:クライアントからのクエリをMasterに分散 Master:インデックス作成側 Slave:検索用スレーブ。マスタからコピー ○クラスタの管理コマンド クラスタのコマンドを用意。 起動、コミット、登録など ○SolrCloud向けのAnuenueを検討中 branch-cloudにあります。 今後の予定 インスタンス追加削除を動的に実行できるようにしたい ○Hadoop Conferenceの宣伝w Oluolu:Hadoop上で動くクエリログマイニングツール Likelike:LSHをHadoopで実装(Hadoop Conference 2011 Fallで発表) 5. LT 5.1 「solrとRの連携について」 by @yutakashino さん(BakFoo) Python本、Zope本を書いてます。 ○NHKの実証実験で利用? ○TwitterストリームをSolrにストア facet.date ○Rでキーワード頻度グラフ Node.js、Redis、R、Solrを使ってる。しかもPython ○デモ キーワード+日付でグラフが出てくる。 Rでプロット。 GoogleのチャートAPIを利用すると面白いことができる。 5.2 「 Apache ManifoldCF」 by 阿部さん(ロンウィット) ○Apache Incubator ○Manifold Connector Framework Solr <- MCF <- web+non-web repositories すぐに利用可能。 ○概要 出力はSolr。 接続先はWeb、DB、CMS、などなどいろいろRepositoryConnectorというのがあります。 ○Crawler Agent クロールに関するJobの管理 接続先、スケジュールなど ○Windowsサーバのクロールもできる 社内のナレッジ共有などに使える。権限周りも簡単に対応可能。 JCIFS.jarによりWindowsの権限情報を取得 ○クロール設定画面もある デモ ○導入が簡単なのがおすすめ。 ○ManifoldCFの資料関連 http://www.manning.com/wright 懇親会についてはあとで記載します!! ということで追記です。 懇親会でも色々と面白い話を聞けました。 @PENGUINANA_さんにはCOOKPADのCI関連の話を聞けました。 1日に数度リリースするという話もあるようでした。\nあとは、Rについても@yutakashinoさんから概要が聞けたのが良かったです。\nちょっとだけ追記。まだ成形する予定ですが、とりあえず。\n追記:スライドが公開され始めたので。\n関口さんのスライドはこちら 阿部さんのスライドはこちら @PENGUINANA_さんのスライドはこちら。 @takahi_iさんのスライドはこちらからPDFダウンロード可能。\nその他に関連するブログも見つけましたので。 「Solr@Cookpad」- Solr勉強会で発表してきました Ars longa, vita brevis: 第6回 Solr 勉強会に行ってきた\n勉強会で出てきた各製品などのリンク: 色々とURLが出てきていたので、リンクをまとめておきます。\nlucene-compression Anuenue Apache Solr のラッパー Likelike LSH (Localtiy Sensitive Hashing)の実装 OluOlu 検索ログマイニングツール @takahi_iさんのLuceneRevolution2011のスライド Kuromoji 形態素解析器 lucene-gosen 形態素解析器(Senの後継) Apache ManifoldCF ","date":1315810980,"dir":"post/2011/","id":"37b622eaad1f79e759a722aacebf48ec","lang":"ja","lastmod":1315810980,"permalink":"https://blog.johtani.info/blog/2011/09/12/%E7%AC%AC6%E5%9B%9Esolr%E5%8B%89%E5%BC%B7%E4%BC%9A%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-09-12T16:03:00+09:00","summary":"「第6回Solr勉強会」に参加しました。 なんだかんだと第6回で、今のところ皆勤賞です。 ということで、主に自分用ですが、メモなどとったので。 概","tags":["勉強会"],"title":"第6回Solr勉強会に参加しました。(Jugemより移植)"},{"contents":"ということで、Ruby2日目の感想(2日目だけで2日間かかったのは内緒。。。) 今回もセルフスタディの私の回答が最後の方に記載されてます。見たくない人は気をつけてください。 ツッコミ大募集です。コメント欄にどしどしコメントください。そこは違うだろ?こっちのほうがいいのでは?という感じで。\n感想: ◎関数の定義:ありゃ、利用するのはダメなんだ、これじゃ。\u0026ndash;\u0026gt;単なるタイプミスでした。お恥ずかしい。。。 \u0026gt;\u0026gt; def tell_the_truth \u0026gt;\u0026gt; true \u0026gt;\u0026gt; end =\u0026gt; nil \u0026gt;\u0026gt; tell_the_trueth() NoMethodError: undefined method `tell_the_trueth\u0026#39; for main:Object from (irb):4 ◎配列:そしてシンタックスシュガー puts animalsで内容が出力されるのはうれしい。JavaだとHashCodeが出てくるから。出力メソッド書かないといけなくなる。 animals[-1]で最後の要素とかかなり便利。 animals[0..1]はRangeクラスを利用する形。Rangeはやはり便利。substringなどもできそう。 カラ配列の定義は必要。a = [] 1.9と1.8でinclude?の書き方が異なるので注意! 配列(Array)クラスは中はObjectが入る。 多次元配列もOK。popやpushでキューとしても利用可能。\n◎ハッシュ: Mapのようなもの。任意のキーが利用可能。:付きの文字列はシンボルと呼ばれる定数値を簡単に定義する方法。 object_idという属性?関数によりObjectのハッシュコードが取れるらしい。 ブレース=「{}」のカッコのこと。do~endでも代用可能\n◎コードブロックとyeild コードブロック=名前なし関数。習慣では複数行の場合、do/endで、1行は{}みたい。Javaと混同しそう。 コードブロックは引数も指定可能。 「yield」予約語?を利用してコードブロック自体をメソッド内部などで呼び出し可能。 ということで、コードブロックは引数にも指定できると。コードブロック=関数もObjectとして扱われてる感じか? 実行遅延、分岐、共通関数とか?Javaだとabstractメソッドを利用して処理するようなイメージか?ちょっと違うなぁ。 なれると、yieldはコードを読みやすくできそう。また、シンタックスハイライトしてくれるツールがあれば、更に便利。\n◎ファイルの実行 ruby ファイル名 vi、Emacs、TextMateなどがあるよ。\n◎クラスの定義 ※数字で始まる変数は利用できない!Javaと一緒 Tree.rbとログを参考にすること。 \u0026amp;使うとブロックに名前が付けられる。yieldじゃなくてもいい? クラス名はキャメルケース。 変数とメソッド名は「_」アンダーバーつなぎ インスタンス変数の頭は@ クラス変数は@@ 定数は大文字 ※メソッド名、変数名には違和感が。なんでこんな規則?? 判定用関数とメソッドには「?」(if test?)をつける!!Javaでいう「is」か。\n◎Mixin(多重継承?モジュールと呼ばれるものを利用) 多重継承のような類似の振る舞いを伝搬する仕組み。 Javaではインタフェースでやること。 Rubyではモジュールといい、関数と定数の集まり。 クラスに機能を盛り込む場合はincludeする ※複数includeして、includeしたものの中に同じメソッドとかあったらどーなる? \u0026ndash;\u0026gt;Overrideされた=includeがあとにあるもので上書きされる Abstractにできないものをモジュール化できるの楽。 javaだとstaticメソッドだらけのUtilクラスを別途起こすイメージだけど、内部で呼ばれるメソッド(コードブロック)が同じインタフェースじゃないと行けないから、インタフェースの記述もしないと行けない。 ただし、同一名のメソッドを持ってるとややこしそう。 ※モジュールからモジュールは呼べる?\n◎モジュール、Enumerable、セット EnumerableとComparable(JavaのCollectionまわりかな。) 宇宙船演算子(\u0026lt;=\u0026gt;)Javaのequalsに似てる any?とかCollectionUtils??に似たのあったな。 ※今利用しているクラスが何をincludeしてるかってのは分かる仕組みあるのかな? ※そういえば、メソッドごとに戻り値があるが、全部newされてインスタンス化されてGCの対象になってるのか?irbだけ? injectはすんなり使うイメージが出にくそう。また、ソースをぱっと見て理解出来ない。なれだろうけど。 ※injectしながらinjectとかあるんだろうな。\n(探してみよう:) ○コードブロックを使った場合と使わない場合の両方について、ファイルにアクセスするコードを書く。コードブロックの利点は? ※コードブロックあり。 ``` File.open(\u0026ldquo;tree.rb\u0026rdquo;, \u0026lsquo;r\u0026rsquo;) {|f| f.each {|line| puts \u0026ldquo;#{f.lineno} : #{line}\u0026rdquo;}}\n※コードブロックなし f = File.open(\u0026ldquo;tree.rb\u0026rdquo;, \u0026lsquo;r\u0026rsquo;) while line = f.gets puts \u0026ldquo;#{f.lineno} : #{line}\u0026rdquo; end\nコードブロックの利点: 見通しの良さ。行数が少なくてすむ。繰り返し処理が簡単に記述できる。 ※うーん、まだきちんと理解できてないか? \u0026lt;/dd\u0026gt; \u0026lt;dt\u0026gt;○ハッシュを配列に変換するにはどうすればよいか?また、逆に配列をハッシュに変換する方法は?\u0026lt;/dt\u0026gt; \u0026lt;dd\u0026gt; ※間違えた。。。 h = [:key1 =\u0026gt; \u0026ldquo;hoge\u0026rdquo;, :key2 =\u0026gt; \u0026ldquo;boke\u0026rdquo;, :key3 =\u0026gt; \u0026ldquo;fuga\u0026rdquo;] h.each {|key, value| puts \u0026ldquo;#{key} is #{value}\u0026rdquo;} =\u0026gt;key1hogekey2bokekey3fuga is\nハッシュ-\u0026amp;gt;配列変換 h.to_a\n配列-\u0026amp;gt;ハッシュ変換 a = [\u0026ldquo;value1\u0026rdquo;, \u0026ldquo;valu2\u0026rdquo;, \u0026ldquo;value3\u0026rdquo;] h = {} a.each {|i| h.store(a.index(i),i) }\n※また間違い?なんでそうなる? a.inject(h2) {|hoge, i| hoge[a.index(i).to_s] = i}\nこっちならいいみたい。まだinjectがわかってない。 a.inject(h2) {|hoge, i| hoge[a.index(i).to_s] = i;puts \u0026ldquo;#{i}\u0026rdquo;; hoge}\n\u0026lt;/dd\u0026gt; \u0026lt;dt\u0026gt;○ハッシュの各要素について繰り返すにはどうすればよいか?\u0026lt;/dt\u0026gt; \u0026lt;dd\u0026gt; h.each {|key, value| puts \u0026ldquo;#{key} is #{value}\u0026rdquo;}\n\u0026lt;/dd\u0026gt; \u0026lt;dt\u0026gt;○Rubyの配列はスタックとしても使える。スタック以外に配列で実現可能なよくあるデータ構造体を挙げよ。\u0026lt;/dt\u0026gt; \u0026lt;dd\u0026gt;キュー。 他にある?Treeとか?Treeはハッシュじゃないか?Set?順番が関係ないけど。\u0026lt;/dd\u0026gt; \u0026lt;/dl\u0026gt; ### **(試してみよう:)** \u0026lt;dl\u0026gt; \u0026lt;dt\u0026gt;○最初に、eachだけを用いて、16個の数値と4個の数値の配列の中身を同時に出力せよ。次に、同じ事をEnumerableのeach_sliceを用いて実行せよ。\u0026lt;/dt\u0026gt; \u0026lt;dd\u0026gt; \u0026lt;span style=\u0026#34;color:#FF0000\u0026#34;\u0026gt;\u0026lt;em\u0026gt;※これ日本語がわからないんだが、4個ずつ出せってことか??\u0026lt;/em\u0026gt;\u0026lt;/span\u0026gt;ということで、「16個の数字の配列の中身を4個ずつ同時に出力せよ。」と解釈して実装してみた ※each利用版 a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] s = [] a.each do |b| unless s.length \u0026lt; 4 puts s.inspect s.clear end s \u0026laquo; b end\n※each_slice a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] a.each_slice(4) {|b| puts b.inspect}\nまた、えらい違いだな。 \u0026lt;/dd\u0026gt; \u0026lt;dt\u0026gt;○Treeクラスは面白いクラスだったが、きれいなインタフェースを用いて新しいツリーを指定することは出来なかった。そこで、initializerにハッシュと配列が入れ子になった構造体を指定できるようにせよ。具体的には、次のようなツリーを指定できるようにしたい。{\u0026#39;grandpa\u0026#39; =\u0026amp;gt; { \u0026#39;dad\u0026#39; =\u0026amp;gt; {\u0026#39;child 1\u0026#39; =\u0026amp;gt; [], \u0026#39;child 2\u0026#39; =\u0026amp;gt; [] }, \u0026#39;uncle\u0026#39; =\u0026amp;gt; {\u0026#39;child 3\u0026#39; =\u0026amp;gt; [], \u0026#39;child 4\u0026#39; =\u0026lt; [] } } }\u0026lt;/dt\u0026gt; \u0026lt;dd\u0026gt;\u0026lt;span style=\u0026#34;color:#FF0000\u0026#34;\u0026gt;※root(ここではgrandpaレベル)が複数あると破綻しないのか?\u0026lt;/span\u0026gt; class Tree attr_accessor :children, :node_name\ndef initialize(name, children=[]) @children = children @node_name = name end\ndef initialize(hash) hash.each do |key, value| @node_name = key @children = value.inject([]) do |array, (child_key, child_val)| puts \u0026ldquo;inject! #{key}\u0026rdquo; [Tree.new({child_key =\u0026gt; child_val})] + array end end end\ndef visit_all(\u0026amp;block) visit \u0026amp;block children.each {|c| c.visit_all \u0026amp;block} end\ndef visit(\u0026amp;block) block.call self end end\n残念ながらちょっとカンニングしてしまいました。。。 \u0026lt;/dd\u0026gt; \u0026lt;dt\u0026gt; ○ファイル内で、あるフレーズを含む全ての行を出力する簡単なgrepをかけ。簡単な正規表現でマッチングを行い、ファイルから行を読み出す必要がある(この処理はRubyでは驚くほど簡単にかける)。必要なら行番号も出力してみると良い。\u0026lt;/dt\u0026gt; \u0026lt;dd\u0026gt;※メソッドだけでいいな。\u0026lt;span style=\u0026#34;color:#0000FF\u0026#34;\u0026gt;ファイルクローズはこの記述の場合はコーディングブロックのendのタイミングでクローズされるのか?\u0026lt;/span\u0026gt; class RegGrep def grep(filename, regexp) File.open(filename, \u0026lsquo;r\u0026rsquo;) do |f| f.each do |line| puts \u0026ldquo;#{f.lineno} : #{line}\u0026rdquo; if line.match(regexp) end end end end\n\u0026lt;/dd\u0026gt; \u0026lt;/dl\u0026gt; ということで、2日目終了。 恥ずかしいコードだらけだけど、ぜひツッコミ入れてもらえると助かります。 数年前までは、恥ずかしいからとか見せられるレベルじゃないからと、ほとんどアウトプットしなかったのですが、 最近はそれではものすごく損をしていると思っています。 ホントは発表するとか議論するとかする場もあればいいのですが。 アウトプットすることで、フィードバックが貰えて、いろんなかたの考えが参考になり、糧となり成長していけるのかと。 (これじゃ成長できないレベルだよという話でなければいいのだが。。。) 一度、Rubyのプロフェッショナル各位に見てもらいたいなぁw ","date":1315588260,"dir":"post/2011/","id":"73262345214f9b7794f2cc4a612b15e8","lang":"ja","lastmod":1315588260,"permalink":"https://blog.johtani.info/blog/2011/09/10/7%E3%81%A4%E3%81%AE%E8%A8%80%E8%AA%9E-7%E3%81%A4%E3%81%AE%E4%B8%96%E7%95%8C-ruby-2%E6%97%A5%E7%9B%AE/","publishdate":"2011-09-10T02:11:00+09:00","summary":"ということで、Ruby2日目の感想(2日目だけで2日間かかったのは内緒。。。) 今回もセルフスタディの私の回答が最後の方に記載されてます。見た","tags":["読書"],"title":"「7つの言語 7つの世界」 Ruby 2日目(Jugemより移植)"},{"contents":"実に3年ぶりくらいにゆっくりできる日々が訪れたので、積読状態の本を消化しようと「7つの言語 7つの世界」を読み始めました。\nせっかくブログも始めたので、備忘録も兼ねて感想などを書いていこうかと。\nこの本ですが、以下の7つの言語についてエッセンスがまとめられています。\nRuby Io Prolog Scala Erlang Clojure Haskell まずはRubyからです。 ここ2年ほどRuby(Rails)に関連する仕事をしていたのですが、Ruby周りはプロフェッショナルな方たちがいたので、きちんと勉強していないことがこの本を読み始めてわかりました。\nということで、前置きはそれなりな記述ですが、感想は適当になりますので、あしからず。\n感想: irbが便利。簡単に動作確認ができるのが便利。Javaだとコンパイルが必要。 変数を定義する必要がない気軽さはある。 必ず戻り値が帰ってくる「puts \u0026lsquo;hello, world\u0026rsquo;」でも。=\u0026gt;nil putsは楽かな。まぁ、Eclipse使ってると一緒か。 「4」もオブジェクトとなっている。ここもJavaと異なる。 (x \u0026lt;= 4).classという記述でTrueClassというクラスだとわかる。 unlessが結構便利。ただし、記述方法が多数あるので、可読性は落ちる?場合によってはわかりやすいか? あと、括弧()がないのも慣れない。(まぁ、これは慣れの問題。ただし、カッコありでもOK) {}のかわりがif~endなのはわかりやすいかも。 if not はわかりやすくていい。!はだいたい間違えるから。。。 whileも1行形式で書けるのか。「x = x + 1 while x \u0026lt; 10」慣れないと厳しい。個人的には混在すると読めないなぁ。 nilとfalse以外がすべてtrueに評価されるのは厳しいのでは?型のチェックがないので、booleanが入ってると想定してない場合に挙動を読めないかも。実行時に動作が変だなーと思うことが出てきそう。 and、orの記述が使えるのは読みやすい。ただし、混在するとやっかい。 判定結果が明らかになった時点で実行が中止されるのは普通。\u0026amp;、|の挙動はJava同様。\nやりながら疑問点:\nNetBeansとかIDEでフォーマッタやcheckstyleみたいなのはあるのか? コーディング規約はあるのか?(2日目に「習慣」があるらしいとの記載があった。) 必ず戻り値が戻ってくるのは、必ずGC対象になりうるオブジェクトが生成されるってことか? ここまでが感想と疑問点。で、この本の面白いところは最後に調査、コーディングを行う練習問題的なものがある部分です。 一応、私なりの答えを書いておこうかと。(一覧などで見えないようにはしますが、ネタバレがあるので注意してください。)\nということで、セルフスタディの回答。\n(探してみよう) ○Ruby API http://ruby-doc.org/core/ ○Programming Ruby: The Pragmatic Programmer's Guideのオンライン版 http://www.ruby-doc.org/docs/ProgrammingRuby/参考資料:http://www.swlab.it.okayama-u.ac.jp/man/ruby/uguide/uguide00.html ○文字列の一部を置換するメソッド \"hello\".gsub(/[aeiou]/, '*') ○Rubyの正規表現に関する情報 日本語:http://www.namaraii.com/rubytips/?%A5%D1%A5%BF%A1%BC%A5%F3%A5%DE%A5%C3%A5%C1 英語の試せるサイト(irbが動けば必要ないかもね):http://rubular.com/ ○Rubyの範囲に関する情報 日本語:http://doc.okkez.net/static/192/class/Range.html 英語:RDocのRangeクラスに相当するのかな。 (試してみよう) ○文字列\"Hello, world\"を出力する。 ``` ○文字列\"Hello, Ruby\"の中の\"Ruby\"という単語のインデックスを検索する。 ``` s = \u0026lsquo;Hello, Ruby\u0026rsquo; s.index(\u0026lsquo;Ruby\u0026rsquo;) //indexofで間違えた\n\u0026lt;dt\u0026gt;○自分の名前を10回出力する。\u0026lt;/dt\u0026gt; \u0026lt;dd\u0026gt;``` ※まずは、正統派。 i = 0 while i \u0026lt; 10 puts \u0026#34;johtani\u0026#34; i = i + 1 end ※Rangeを利用 (1..10).each {|n| puts \u0026#34;johtani #{n}\u0026#34;} ※forもあるよね for i in 1..10 puts \u0026#34;johtani\u0026#34; end ※timesってのもある。(0始まり) 10.times {|n| puts \u0026#34;johtani #{n}\u0026#34;} ※uptoなんてのもあるのか。 1.upto(10) {|n| puts \u0026#34;johtani #{n}\u0026#34;} ※downtoも 10.downto(1) {puts \u0026#34;johtani\u0026#34;} ※stepもある。 10.step(1, -1) {puts \u0026#34;johtani\u0026#34;}//step(上限,ステップ) ```\u0026lt;/dd\u0026gt; \u0026lt;dt\u0026gt;○文字列\u0026#34;This is sentence number 1\u0026#34;の1を10までカウントアップしながら10回出力する。\u0026lt;/dt\u0026gt; \u0026lt;dd\u0026gt;``` 1.upto(10) {|n| puts \u0026#34;This is sentence number #{n}\u0026#34;} ※あとは上記と一緒 ```\u0026lt;/dd\u0026gt; \u0026lt;dt\u0026gt;○ファイルに格納されているRubyプログラムを実行する。\u0026lt;/dt\u0026gt; \u0026lt;dd\u0026gt;``` vi hoge.rb ※#上記処理をどれか記述 $ ruby hoge.rb ○ボーナス問題:少し物足りない人は、乱数を選択するプログラムを書いてみてほしい。プレーヤーに数字を選択してもらい、その数字が生成された乱数よりも大きいか小さいかを返す。 ``` -- coding: utf-8 -- range = (1..100) while true puts \u0026ldquo;#{range.min}から#{range.max}の数字を入力してください\u0026rdquo; n = gets n = n.to_i if range.include?(n) break; else puts \u0026ldquo;範囲外の入力値です。もう一度入力してください\u0026rdquo; end end i = rand(range.max) if i \u0026lt; n puts \u0026ldquo;入力「#{n}」は乱数「#{i}」より大きいです\u0026rdquo; elsif i == n puts \u0026ldquo;入力「#{n}」は乱数「#{i}」と等しいです\u0026rdquo; else puts \u0026ldquo;入力「#{n}」は乱数「#{i}」より小さいです\u0026rdquo; end\n\u0026lt;/dl\u0026gt; とまぁ、こんな感じ。こんな方法もあるよ、ここおかしくない?などあれば、コメント欄まで。 リアクション大募集です。 はやく、シンタックスライター導入せねば。 ","date":1315545120,"dir":"post/2011/","id":"9baedcd033169611a42c3cfd58b3ae03","lang":"ja","lastmod":1315545120,"permalink":"https://blog.johtani.info/blog/2011/09/09/7%E3%81%A4%E3%81%AE%E8%A8%80%E8%AA%9E-7%E3%81%A4%E3%81%AE%E4%B8%96%E7%95%8C-ruby-1%E6%97%A5%E7%9B%AE/","publishdate":"2011-09-09T14:12:00+09:00","summary":"実に3年ぶりくらいにゆっくりできる日々が訪れたので、積読状態の本を消化しようと「7つの言語 7つの世界」を読み始めました。 せっかくブログも始め","tags":["読書"],"title":"「7つの言語 7つの世界」 Ruby 1日目(Jugemより移植)"},{"contents":"現在の出先でMBAを使えないので、なかなか進んでいないMBAのセットアップです。。。\nとりあえず、Eclipse、homebrewをインストールしたので、lucene-gosenの開発やビルドには支障がない程度になってきました。(肝心のSolrがまだ動く状況になかった。。。)\nあとは、Windowsで使用頻度の高いソフトを列挙して、対応するMacのアプリを探そうかと。 まずは、Windowsでよく利用するソフトのリストアップ\nEclipse Cygwin TeraTerm WinSCP meadow サクラエディタ WinMerge PDF-XChange Viewer Evernote FreeMind VMWare こんなところかな。 a.~e.についてはMacOS特に問題なし。Eclipseは入れたし、その他は標準で入ってるものでまかなえると。 f.についてもEmacsで当面対応する予定。ただ、OmmWriter やCotEditorがおすすめらしいと聞いてます。 g.についてはFileMergeなるものがあるらしいので、試してみようかと。 h.は現状Adobe Readerです。ほかにいいのあるのかしら。PDF-XChange Viewerはちなみに、Solr入門を書くときに編集の方から教えてもらったPDFのビューワです。コメントとかハイライトできるのが便利でした。 i.はMacOS版をインストールして、すでに活用中。 j.については一時期活用していたのですが、最近利用していないです。なので、保留 k.についてはVirtualBoxをインストールしてみました。フリーだったので。WindowsではVMWareだったのですが。。。\nほんとにこれくらいで大丈夫かどうかはもう少し使ってみてからかなぁと。 その他におすすめ、これがあるとかなり便利などあれば、教えてもらえると助かります。 まだ、MacOSに触り始めたところなので、細かな部分のカスタマイズなどができていないので、その辺りもオイオイ考えていこうかと。\n※余談ですが、現在「7つの言語 7つの世界」を読み始めました。いろいろな言語の特徴について学べる本のようでかなり楽しく感じています。どうしてもJavaで仕事優先だとコーディングする速度優先でJavaばかり使ってしまうので。 いい頭の体操にもなりそうなのでオススメです。(といってもまだ、最初の言語Rubyなのですが。。。)\n","date":1315329480,"dir":"post/2011/","id":"f23ca2aa066b1ee0fa4df1f2f865be4c","lang":"ja","lastmod":1315329480,"permalink":"https://blog.johtani.info/blog/2011/09/07/mba%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97%E5%82%99%E5%BF%98%E9%8C%B2%E3%81%9D%E3%81%AE%EF%BC%93/","publishdate":"2011-09-07T02:18:00+09:00","summary":"現在の出先でMBAを使えないので、なかなか進んでいないMBAのセットアップです。。。 とりあえず、Eclipse、homebrewをインストー","tags":["備忘録"],"title":"MBAセットアップ備忘録その3(Jugemより移植)"},{"contents":"すぐにテストケース追加しますといいつつ、はや一週間。\nようやく仕事が落ち着いたので、テストケースを追記しました。まだパッチの段階です。 一応、異なる辞書の読み込みのテストケースなどを追加し、テストケース追加時点で いくつか気になったところもあったので、ついでに修正を加えました。 一応、辞書の分離+複数辞書対応については現時点ではこんなところかと。\nあと、もう1項目対応してからtrunkに取り込む予定です。 対応する項目とは以下の項目です。\nカスタム辞書ビルドの簡易化 以前の記事にも書いていますが、カスタム辞書のビルドが思いのほか手間がかかります。 辞書の外部化は対応したのですが、せっかく辞書が外部化できたのですから、コマンド(ant?)で一発で カスタム辞書を含んだビルドをしたくなるのが人情です。 辞書なしのjarファイルもあることなので、すぐに対応可能かと。 ということで、今週中には対応する予定です(宣言しないとまた先延ばしになりそう)\n忘れてそうだったらTwitterやコメントでツッコミを入れてもらえると助かります。\n","date":1315328188,"dir":"post/2011/","id":"3c2523e65ff953fd73579aaaf5d7ce36","lang":"ja","lastmod":1315328188,"permalink":"https://blog.johtani.info/blog/2011/09/07/%E8%BE%9E%E6%9B%B8%E5%88%86%E9%9B%A2%E3%81%AE%E3%83%86%E3%82%B9%E3%83%88%E3%82%B1%E3%83%BC%E3%82%B9%E8%BF%BD%E5%8A%A0%E3%81%A8%E6%AE%8B%E3%82%BF%E3%82%B9%E3%82%AF/","publishdate":"2011-09-07T01:56:28+09:00","summary":"すぐにテストケース追加しますといいつつ、はや一週間。 ようやく仕事が落ち着いたので、テストケースを追記しました。まだパッチの段階です。 一応、異","tags":["lucene-gosen"],"title":"辞書分離のテストケース追加と残タスク(Jugemより移植)"},{"contents":"先日、辞書のjarファイルからの分離についてパッチと記事を書きました。\nIssueにあげていたパッチをRobertさんが見ていたらしく、次のようなコメントをもらいました。\nMaybe if we change SenFactory.getInstance to use a ConcurrentHashMap then you can easily use multiple dictionaries at the same time? 「SenFactory.getInstanceメソッドでConcurrentHashMap使ったら複数辞書対応できるんじゃない?」(訳) たしかに。。。なんで思いつかなかったのだろう。。。\nということで、実装してみました。 パッチはこちら。\n使い方ですが、先日の記事と代わりはありません。 ただし、あった制限事項が次のようになります。\nマルチコアの設定でsharedLibにlucene-gosenのjarを含まない 同一コア内で異なるdictinaryDirの指定はできない ソースの変更点ですが、ものすごく単純です。 dictionaryDirに指定された文字列をキー、その辞書ディレクトリを利用したSenFactoryのインスタンスを値に持つmapをSenFactory内に保持します。あとは、SenFactoryのgetInstance(String dictionaryDir)メソッドで取得する際にmapに対応するインスタンスがあれば、そのインスタンスをなければ、dictionaryDirから辞書を読み込んでインスタンス生成してmapにキャッシュしつつ返すという実装に変えただけです。 ということで、次のようなIPADICとNAIST-JDIC for ChaSenを同時に使う設定も可能となります。\n\u0026lt;fieldType name=\u0026#34;text_ja_ipadic\u0026#34; class=\u0026#34;solr.TextField\u0026#34; positionIncrementGap=\u0026#34;100\u0026#34;\u0026amp;gt; \u0026lt;analyzer\u0026amp;gt; \u0026lt;tokenizer class=\u0026#34;solr.JapaneseTokenizerFactory\u0026#34; dictionaryDir=\u0026#34;/tmp/lucene-gosen/dictionary/ipadic\u0026#34;/\u0026amp;gt; \u0026lt;/analyzer\u0026amp;gt; \u0026lt;/fieldType\u0026amp;gt; \u0026lt;fieldType name=\u0026#34;text_ja_naist_chasen\u0026#34; class=\u0026#34;solr.TextField\u0026#34; positionIncrementGap=\u0026#34;100\u0026#34;\u0026amp;gt; \u0026lt;analyzer\u0026amp;gt; \u0026lt;tokenizer class=\u0026#34;solr.JapaneseTokenizerFactory\u0026#34; dictionaryDir=\u0026#34;/tmp/lucene-gosen/dictionary/naist-chasen\u0026#34;/\u0026amp;gt; \u0026lt;/analyzer\u0026amp;gt; \u0026lt;/fieldType\u0026amp;gt; あと、注意事項です。 普通に考えるとわかることですが、辞書を複数読み込めるようになったことで、読み込んだ複数の辞書をメモリに保持することになります。ですので、今までよりも多くのメモリを利用するので、Heapのサイズには注意が必要です。 例のごとく(ほんとよくない。。。)テストコードを書いていない状態のパッチをまずはアップしました。 テスト書かないと。。。次回はテストコードかきましたと言う報告をしたいな\nあと、Robertさんのコメントの前に@shinobu_aokiさんからJapaneseTokenizerFactoryの設定では辞書のディレクトリを$SOLR_HOME/confからの相対パスで記述できるというパッチもいただいています。 この部分については先日と使い方が異なります。 (すみません、まだきちんとソースを見れてないです。。。)\n","date":1314668040,"dir":"post/2011/","id":"88a8e608108be939da9aab5a9a8af7d1","lang":"ja","lastmod":1314668040,"permalink":"https://blog.johtani.info/blog/2011/08/30/%E8%A4%87%E6%95%B0%E8%BE%9E%E6%9B%B8%E3%81%AE%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%81%BF%E6%A9%9F%E8%83%BD%E8%BF%BD%E5%8A%A0%E4%BB%AE/","publishdate":"2011-08-30T10:34:00+09:00","summary":"先日、辞書のjarファイルからの分離についてパッチと記事を書きました。 IssueにあげていたパッチをRobertさんが見ていたらしく、次のよ","tags":["lucene-gosen"],"title":"複数辞書の読み込み機能追加(仮)(Jugemより移植)"},{"contents":"ひさびさに、lucene-gosenの話題です。\nlucene-gosenはjarファイルに辞書も同梱されており、jarファイルをクラスパスに取り込むだけで、 簡単に形態素解析器が利用できるといお手軽さがあり、便利です。\nですが、以前カスタム辞書の登録について記事を書いたように、カスタム辞書の登録は思いのほか手間がかかります。 lucene-gosenのソースをダウンロードし、lucene-gosenを一度コンパイルし、カスタム辞書のcsvファイルを作成し、カスタム辞書を取り込んだ辞書のバイナリを生成し、最後にjarファイルにするという作業です。(書くだけでいやになってきました。。。)さらに作成したjarファイルをSolrや各プログラムに再度配布するという具合です。\nそこで、辞書ファイルの外部化ができないかという話があがっていました。 すこし時間ができたので、山積みになっているissueを横目に軽く実装をしてpatchをissueにアップしました。\n機能としてはごく簡単で、JapaneseTokenizerのコンストラクタに辞書のディレクトリ(*.senファイルのあるディレクトリ)を指定可能にしただけです。 また、JapaneseTokenizerFactoryでもdictionaryDir属性で指定可能になっています。 まずは、コンパイルの方法から。 trunkをSVNでcheckoutし、issueにあるpatchをダウンロードして適用します。(svnのチェックアウトについてはこちらを参考にしてください。)\n$ cd lucene-gosen-trunk $ patch -p0 --dry-run \u0026lt; lucene-gosen-separate-dictionary.patch $ patch -p0 \u0026lt; lucene-gosen-separate-dictionary.patch 次に、antを実行し辞書なし版のjarファイルをビルドします。\n$ ant nodic-jar これで、dictディレクトリに「lucene-gosen-1.2-dev.jar」というjarファイルが出来上がります。 (※ただし、これだけでは動作しないので、別途辞書のコンパイルは必要です。)\n次に、指定の仕方です。JapaneseTokenizerのコンストラクタは第3引数に辞書のディレクトリ(フルパスor実行ディレクトリからの相対パス)を渡すだけです。\nTokenizer tokenizer = new JapaneseTokenizer(reader, compositeTokenFilter, dictionaryDir); 最後に、Solrのtokenizerタグでの指定方法です。\n\u0026lt;fieldType name=\u0026#34;text_ja\u0026#34; class=\u0026#34;solr.TextField\u0026#34; positionIncrementGap=\u0026#34;100\u0026#34;\u0026amp;gt; \u0026lt;analyzer\u0026amp;gt; \u0026lt;tokenizer class=\u0026#34;solr.JapaneseTokenizerFactory\u0026#34; dictionaryDir=\u0026#34;/hoge/dictionarydir\u0026#34;/\u0026amp;gt; \u0026lt;/analyzer\u0026amp;gt; \u0026lt;/fieldType\u0026amp;gt; 以上が、簡単な設定の仕方です。なお、辞書を内包したjarファイルでもdictionaryDirは利用可能です。優先度としては、dictionaryDirが指定されている場合はdictionaryDirを探索しファイルがなければRuntimeExceptionです。指定がnullもしくは空文字の場合はjarファイルの辞書の読み込みを行います。\n次に利用シーン、制限事項についてです。 利用シーンとしてはカスタム辞書を定期的にメンテナンス(追加更新)しながらSolrを運用するというのが想定されます。定期的に辞書の再読み込みをしたい場合です。 利用方法は次のようになります。\nSolrのマルチコア構成を利用する 各コアごとにlib/lucene-gosen-1.2-dev.jarを用意 辞書の更新が終わったらコアのRELOADを実施 コアをリロードすることで、lucene-gosenが辞書を再読み込みようになります。(現状でも再読み込みするが、jarファイルを再配置しないといけない。)あとは、定期的に辞書ファイルを更新、再構築しコアをリロードすれば、 リロード後に新しい辞書が利用できるという具合です。 (もちろん、辞書更新後に入った単語は辞書更新以前に作成したインデックスにはでてこないですが。。。) また、コアごとにdictinaryDirを別々に指定することも可能です。\n制限事項は次のようになります。\nマルチコアの設定でsharedLibにlucene-gosenのjarを含まない 同一コア内で異なるdictinaryDirの指定はできない 以上が、辞書の外部ファイル化のパッチについてでした。 少しテストケースを追加したら、trunkにコミットする予定です。興味があれば、パッチを利用してみてください。\nSyntaxHighlighterの導入をしないとソースコードが見にくいですね。。。導入を検討しないと。。。どこかにWebサーバ用意しないとダメかも\n","date":1314062760,"dir":"post/2011/","id":"2f1ec795216d5bafa33a810af3421942","lang":"ja","lastmod":1314062760,"permalink":"https://blog.johtani.info/blog/2011/08/23/%E8%BE%9E%E6%9B%B8%E3%81%AEjar%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%8B%E3%82%89%E3%81%AE%E5%88%86%E9%9B%A2/","publishdate":"2011-08-23T10:26:00+09:00","summary":"ひさびさに、lucene-gosenの話題です。 lucene-gosenはjarファイルに辞書も同梱されており、jarファイルをクラスパスに","tags":["lucene-gosen"],"title":"辞書のjarファイルからの分離(Jugemより移植)"},{"contents":"すみません、また、MBA関連の記事になってしまいました。 ということで、備忘録その2です。\n前回からいくつかインストールや環境の設定をしたので、リストアップ。\nVirtualBoxとWindowsのインストール homebrewのインストール KeyRemap4MacBookのインストール Growlのインストール Time Machine用HDDの購入と設定 VirtualBoxのインストールとWindowsXPのセットアップ。会社関連でどうしてもWindowsが必要なので、 とりあえず、VirtualBoxとWIndowsを入れました。これまでのWindows環境ではVMWareを利用してたのですが、 Macだと有償ということで、無償版が存在するVirtualBoxを選択。 MBAにはDVDのドライブがなく、また、ケチって購入しなかったので、ちょっと手間取りました。 自宅のデスクトップでXPのイメージをisoにして、MBAにコピーしてからインストールと。。。 ただ、MBAのSSDの効果なのか、XPの起動がすごく速くてびっくりです。\nhomebrewのインストールは、まだインストールしただけの状態。。。 MacPortsってのがあるというのは知っていたのですが、最近はこちらがいいとのこと。 ちなみに、MacPortsにはSolrがあるらしいです。デフォルトのため、lucene-gosenとか入れる必要がありますが。\nKeyRemap4MacBookのインストール。入れた方がいいですよと言われてたのだが、きちんと調査してなく、 キーの入れ替えができる程度だと思ってました。昨日、EmacsModeなるものが存在するというのをKeyRemap4MacBookのドキュメントを読んでいて発見し即インストール。 とりあえず、Ctrl-x,Ctrl-cでEvernoteが終了できて喜んでるところです。\nGrowlのインストール。KeyRemap4MacBookのCtrl-xを通知してくれます。ほかにも使い方があるかは調査が必要。\nあとは、昨日、ビックカメラでWDの2TBのHDDを購入してTimeMachineの設定をしてバックアップをとりました。 まだバックアップをとっただけで、差分を見たりはしていないです。帰ってからやってみようかと。\n最後に、ケースを買いました。封筒とかいろいろ考えたのですが、やはり機能重視ということで、以下のケースです。 できれば、ファスナーが2つついていて、両方からあけられるとよかったのですが。リュックとショルダーバッグを使い分けるので、横でも縦でも取り出しが楽なものがよかったので、このケースを買いました。 一応、がんばれば縦でも出せるので。あとは、PCだけもって移動することもあるため、取っ手があるのが便利かと。\nとまぁ、お盆なので、このエントリーで許してください。次回は技術的なことを書きますので。。。 CaseLogic 機能的なモバイルコンピュータケース(13~14.1インチPC対応)、MacBookやMacBook Proにも対応 ダークグレー UNS-114J-DG ","date":1313369460,"dir":"post/2011/","id":"ce0aea06d44878b4a373efe090a66a62","lang":"ja","lastmod":1313369460,"permalink":"https://blog.johtani.info/blog/2011/08/15/mba%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97%E5%82%99%E5%BF%98%E9%8C%B2%E3%81%9D%E3%81%AE%EF%BC%92/","publishdate":"2011-08-15T09:51:00+09:00","summary":"すみません、また、MBA関連の記事になってしまいました。 ということで、備忘録その2です。 前回からいくつかインストールや環境の設定をしたので、","tags":["備忘録"],"title":"MBAセットアップ備忘録その2(Jugemより移植)"},{"contents":"Mac Book Airのセットアップ関連の備忘録\n(今回は備忘録なので、文体も変かも)\nインストールしたもの(順不同)だいたい、このサイトを参考にした。\nEvernote Dropbox XCode Twitter YoruFukurou GNU Emacs For Mac OS X Java Office for mac 現状はこんなところ。\nまだ、キーボードの配列とショートカット、ウィンドウの切り替えなどがすぐにできないので、かなりおぼつかない状態。\nCtrl+aなどの操作は快適なのだが、ウインドウを閉じたりする場合のcommandキーの扱いがまだなれない。キー配置を切り替えたりした方がいいのか悩み中。 Windowsでは長年XKeymacsを使ってきたため、通常のOfficeなどもCtrl+x Ctrl+sなどで閉じていたので、command+qなどがすんなり出てこない。。。\nあとは、VirtualBoxにWindowsを入れて、Eclipseを入れればなんとか、WindowsPCからMBAへの切り替えができそう。\n残っている課題は以下の通り。\nTime Machine環境の整備USB接続のHDDの導入(ミラーリング対応にするか悩み中)※ちなみにうちで使ってるNASは古い+NFSマウントできない機種だった。。。 対応可能だったらScientific Linux+Netatalk環境などを用意するのも考えたんだが。 homebrewのインストール 日本語入力(GoogleIME?SKK?) ウォークマン、Xperia arcの運用方法まぁ、今まで使ってたPCで対応かな キーの配置Emacsのショートカットに変更できたりするか調査したい データの移行Windowsに入ってるデータのうち移行するものしないものの選別Macでは利用できないデータやファイルもあると思う。 解凍ツールの選別?いるのかな? ブラウザのインストールchrome、Firefoxはいれるかな。 メーラーのインストールWindwosではBecky!を使ってたのだが、どうするか。デフォルトメーラで様子見? ウイルス対策ソフトの導入Macってどんなソフトがあるかがわからない。。。 あと、1週間触っての感想\nまずは、良かった点。\nいろんなUIがよくできてるセットアップなどきれいな画面で説明が進むのが新鮮だった。あと、フォントのきれいさも新鮮。これは、今までのPCが古いからかもしれないが。 トラックパッドがいいまだなれてないけど、スイスイ動くのでストレスなく作業できる。スワイプとかも画面の移動が楽でいい。 静かで速いSSDのため、静かだし起動がすごく速い。会社で支給されてるPCもSSD(3年くらい前のもの)だけど、こんなに起動などがはやくない。 あとは、気になった点。\nAppStoreでページ間のスワイプができない。かなり使いづらい。Safariと同じイメージでいるので。 手首がいたい手前のエッジ部分が手首に当たってちょっといたい。 アプリインストール時にファンがうるさい動画などはまだ見てないが、Office、XCodeのインストール時にファンの排気音がうるさくなり、結構な熱を発していた ファーストインプレッションはこんな感じ。\nただ、前回も書いたようにうらやましかったのもあり、かなり満足している。 もっと触る時間が欲しいのだが、なかなかとれないのが歯がゆい。。。\n持ち歩くようになったらとりあえず、「7つの言語 7つの世界」を読み進め+写経をやる予定。\n","date":1312904760,"dir":"post/2011/","id":"c0e423f9ac41cc5b265c95a3e97e3fcb","lang":"ja","lastmod":1312904760,"permalink":"https://blog.johtani.info/blog/2011/08/10/mba%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97%E5%82%99%E5%BF%98%E9%8C%B2/","publishdate":"2011-08-10T00:46:00+09:00","summary":"Mac Book Airのセットアップ関連の備忘録 (今回は備忘録なので、文体も変かも) インストールしたもの(順不同)だいたい、このサイトを参考にした。 Evernote Dropbox","tags":["備忘録"],"title":"MBAセットアップ備忘録(Jugemより移植)"},{"contents":"個人用のPCを8年ぶりに新調しました。\n前回購入した家のデスクトップPCがもう8年ものになりつつあるということで、\nさすがに今年はPCを買おうと思い、年初からいろいろと調べていました。\n当初は次もデスクトップPCを購入する予定でした。ただ、次のような状況ということもあり\nデスクトップは見送ることにし、代わりにノートPCにすることに。\n通勤時間が1時間を超えること\n基本、客先に出向いての仕事\n家でPCに触る時間が少ない(家族サービスのため。)\nで、ここ数週間悩んでいたのですが、Mac Book Air 13インチを購入しました。(そのMBAから初投稿です。)\n実は、Apple製品はこれが初の購入となります。\n対抗馬としてあがっていたのはSonyのVAIO Type Zでした。\n元々ソニスト(ソニー大好き)であり、携帯(Xperia arc)、ウォークマン(Sony)、PSP go、ハンディカムなど、\nソニー製品に囲まれており、デザインもType Zのほうが好みなのですが、MBAを購入しました。\nこの理由なのですが、私が大学時代にさかのぼります。\n情報系の大学の出身で、はじめてきちんと触ったマシンがSunOS4.1(最後の数年はSolaris2.6)でした。\nその後、大学6年間は基本的にEmacsでメールをみて、Emacsで文章を書いていました。\nそのため、社会人になってからもEmacsのキーバインドから抜け出せない日々を送っていました。\n社会人ではやはりWindowsでしたが、XKeymacsというフリーソフトのおかげ(せい?)でEmacsの\nショートカットからは抜け出せないまま。(家のPCはXPで、XKeymacsがインストールされてます。)\n今までの流れだと、何も考えずにWindows7+XKeymacsの流れだったのですが。。。\n職場でWindows7のPCを使う機会があり、XKeymacsを入れてみたのですが、これまでとことなり、\nうまく機能しないことこの上なし(例:chromeのアドレスバーでCtrl+Kとかできないなど)。\nさらに、64bit版の場合、XKeymacsを32bit、64bitの2つインストールしないといけないことに。(32bit用アプリのために32bitを入れないといけない)\nで、数ヶ月使っているのですが、ちょっとずつストレスがたまっている始末。。。\n今までは、「Mac?今更恥ずかしくてかえない」「Mac?おしゃれすぎて無理」「Apple?MSにかわって独占してるの気に食わん」と公言していたのですが。。。\nやはりUnixベースであり、Ctrl+aやCtrl+kが意識せずに利用できるということでコーディングなどを行う場合のストレスよりも保守的な思考を変える方が今後のためにも良さそうだということで、心機一転MBAを購入しました。\nということで、ついにApple教へ入信です。\nまだ、1時間も触ってないですが、すでに洗脳されつつあります。。。\n新しいものに触れるのって楽しいですよね。当分は何をインストールするかなど楽しい悩みでいっぱいになれそうです。(次回はちゃんとした技術的な記事書きたいと、書けるかな、書くぞ、たぶん。。。)\nとまぁ、いろいろと理由を書いてみましたが、要は(オシャレさに)憧れてて、あまのじゃくになって思ってもないこと言ってたんです!\n理由が欲しかったんです!!\nMacかっこえーわーw\nMac miniとかiMacとかもほしーわー\n","date":1312389240,"dir":"post/2011/","id":"7ed1d2efa3e0f0ed6b77eb4eff3d86b3","lang":"ja","lastmod":1312389240,"permalink":"https://blog.johtani.info/blog/2011/08/04/apple%E6%95%99%E3%81%AB%E5%85%A5%E4%BF%A1%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-08-04T01:34:00+09:00","summary":"個人用のPCを8年ぶりに新調しました。 前回購入した家のデスクトップPCがもう8年ものになりつつあるということで、 さすがに今年はPCを買おうと","tags":["備忘録"],"title":"Apple教に入信しました(Jugemより移植)"},{"contents":"かなり遅くなりましたが、第1回 データ構造と情報検索と言語処理勉強会 #DSIRNLPに参加しました。\n帰ってから2日半ほど寝込んでしまい、更新が遅れました。。。\n初の土曜日開催の勉強会でしたが、家族を説得してなんとか参加しました。\nおかげで色々と面白そうなキーワードが拾えてよかったです。(拾っただけで理解するのはかなり時間がかかりそうですが。。。)\nということで、前回同様、個人的にメモを取ったので。誤記などあるかもしれませんが、その時はコメントいただければと。\n0.DSIRNLPについて\n※ボランティアで受付してたので聞けず。\n1.TRIEにトライ!~今日からはじめるTRIE入門~\n@echizen_tm さん\n資料:http://www.scribd.com/doc/58688141/Try-for-Trie\n1.TRIEの説明\n実装についてはあとでスライドをみればいいか。(※ボランティアで受付してたので前半聞けず)\n・パトリシア木\n・Double Array\n・LOUDS\n・XBW\n2.作ってみた\nその1 ベーシック\nQ.ノードのラベルどーする?\n・固定長(ラベル=1文字)\n定数時間でアクセス可能\n・可変長(ラベル=任意文字列)\nPatricia木に拡張可能\nA.拡張性を考えて可変長に!\n3.LOUDSとは?\n概要\nJacobsonが提案 Level-Order Unary Degree Sequenceの略(いつからLOUDSになったのか不明)\n構築済みTRIEからLOUDSを構築\n作業領域がO(NlogN)からO(N)に\n・ノードに幅優先で順番(Level-Order)をつける\n・子ノードの数を付ける。Unary符号で実装\n作ってみた\n・UnaryよりVerticalCodeのほうがよさそう\nhttp://d.hatena.ne.jp/echizen_tm/20100531/1275323074\n・dag_vectorを使ってもいいかもよ?\n4.QA\nQ.可変長を配列にすればいいんじゃね?\nA.単純にやると効率悪そう?\n※LOUDSをlucene-gosenに適用するとなんか嬉しいことあるかな?\n現状はDouble-Arrayだけど。\n2. ランキング学習ことはじめ(Solr系に利用できそうな予感。。。ごごご。。。むずかしい。。。)\n@sleepy_yoshi さん NTTのSuharaさん「話がうまい」\n数原 良彦\n自己紹介\n情報検索、ランキング学習をやってる。\n三浦半島在住\nねらい\nランキング学習の認知度を高める、ざっくり伝える。 ごめんなさい 「実装」についてをわすれてた。\n・ランキング学習とは?\nLearning to rank\npreference learningとは違う\n教師あり機械学習で検索ランキングに適用\n・歴史\n従来は単一ランキング\nクエリ・文書関連度(TF-IDF、BM25)\n文書の重要度(PageRank、HITS、SALSAなど)\n近代的なランキングの実装方法\n上記データを利用して関数を適用する。\n・何を正解とするのか?\n適合性評価の作成方法\n評価点数を多段階で点数化\nランキング評価方法\nランキングを正解データと比較\nNDCG(Normalized Discounted Cumulative Gain) ※分類問題におけるモデルの生成\nTraining Data+学習アルゴリズム=>モデル\nランキング学習の訓練データ\n素性や評価はクエリごとに変わってくるTraining data(ここが違う)\nここまでのまとめ\n正解データは適合度至上主義!\nランキング学習手法\n3つのアプローチ\n教師あり機械学習(識別学習)≒\nどのような目的関数/損失関数を\nどのように最適化するのか\nアプローチ\n1.Pointwise手法\n単一のデータに対して損失関数を設定\n2.Pairwise手法\n同一クエリのペアに対して損失関数を設定\n3.Listwise手法\n同一クエリのリストに対して損失関数を設定\nPointwise:あまりつかえない。\n例:二値分類(適合+1不適合-1)で学習\n補足:Perceptron\n例:PRank\nしきい値と重み両方修正する。\nPairwise:Pointwiseよりいいらしい\n文書ペアで損失を設定\nMQ2007、MQ2008データセットの結果\nPairwise手法とListwise手法を比較しても\nそんなに悪くないらしい\nIR-SVMってので偏りなどを排除できて、精度向上になるよ\nNLP2011でPARankっての発表したよ(手前味噌)\nQA\nQ.じゃんけんみたいに循環しない?(nokuno)\nA.半順序のデータだと起きるが、検索の場合は全順序なので大丈夫だよ\nListwise:Pairwiseよりいいらしい\nListNetってのあり。\nAdaRank\n検索評価指標を直接最適化するブースティング手法\n性能はいまいち?実装は簡単\nその他の話題\nClick-through logs\nQuery-dependent ranking\nFeature selection\nTransfer learning/Domain adaptation\nDiversity/Novelty\n公開Dataset\nLETOR3.0/4.0 Dataset\nMSLR-WEB Datasetなど\n実装\nRankingSVM\nStoch\u0026hellip;.\nLearning to Rank教科書\n英語の資料が今年複数出たみたい\nまとめ\n近代的な検索エンジンは多数のランキング素性を利用\n評価データを用いてランキング素性の最適な重み付けを求める方法\n。。。\n機械学習手法は論文≒実装\nなので、ソースコード見るほうが重要(論文にないノウハウがあるよ)\n3.snappy調べてみた\n@machy 町永圭吾(赤いポータルサイト)\nTopCoderなどで活躍中?\n・snappyは圧縮/伸張ライブラリ\nzlibよりサイズが大きいけど一桁はやいですぞ。\n・インストールなど\ngoogle-gflagsってのがないと動作しないよ。\n・比較してみた(zlib)\n一桁は言い過ぎだけど、はやかった。\n・比較してみた(lzo)\nHadoopで利用されているlzo\nはやかった。\n・仕組みは?\nzlib 辞書式符号化+ハフマン符号化=出力\nsnappy 辞書式符号化+リテラル=出力\n・辞書式符号化は?\n前に出てきたデータで同じ文字列の部分について端折る\n・ハフマン符号化\nよく出てくる記号を短い符号で置き換えることで圧縮する。\n・snappyの符号化\n基本バイト単位での処理にすることで、高速化してるみたい。\n・snappyの辞書参照元の探し方\nハッシュテーブル利用してマッチする位置を検索\n4byte窓でハッシュ値を計算してハッシュテーブルを更新\n・圧縮しにくいデータ(同じ単語が出てこないパターン)について\n圧縮をあきらめ始める(32回同じのが見つからないと窓の移動幅が1つずつ大きくなる)\n16KB(フラグメント内)での比較回数が1008回に抑えられる。\n・特徴\nハッシュがしょうと移したらあるはずのマッチが見つからないこともある。\nメモリ消費量を抑えるためのハッシュのサイズ?\n最悪ケースのサイズを予め確保してから処理するため、メモリの再確保が起きないのではやいぞ。\n4.類似文字列検索してますか?\n@overlast さん Yな会社\n1.曖昧な情報を処理する能力\n曖昧な情報を解決しようとする能力が高い。\n例:お笑い芸人の芸がサンプルw\n画像検索は曖昧クエリに答える例。。。\nスターバックス、スタバ、SUTABA\nスータバでも画像が出てきた。-\u0026gt;女子高生とかが「スータバ」で画像をアップしてたりするから。\n文字列を使った検索は現代のインフラになってるよね。\n例:iタウンページ\nタイトルとかに「スターバックスコーヒー」って書いてないとだめ。?\n「スタバ」800件くらい -\u0026gt; 正規化で「ー」消してるんじゃないの?\n「スータバックスコーヒー」0件 ちがうな。シノニム辞書登録してるな。\n曖昧なクエリ(キーワード)から検索できないかなぁ?\n曖昧情報の処理は文字列処理にこそ必要\nなんでヒットしたかがわかるのが正解 なんでヒットしたかわからないけど、ちゃんと出てきたから正解!\n2.ゼロ件ヒット問題(ゼロマッチ)\nピクシブ百科事典\n「ピングドラム」だと17件\n「ピンクドラム」だと0件 しかも真っ白!!\n使いにくいよね。けど、一般的な検索システムの問題だよね。\nGoogleだと出てくる「ピンクドラム」の結果の最初にはピングドラムが出てくる。\n-\u0026gt;リンクがはられているから出てきた?みんなの間違いで助けられてる\n食べログ\n「俺のハンバーグ」\n「俺はハンバーグ」で検索したら。。。「俺はハンバーグで連れは。。。」がヒット-\u0026gt;しらねーよw\nまとめ\nゼロ件ヒットは機会損失!!\n3.曖昧な文字列で正しい文字列を探す方法\n正しい文字列って?\n1.表記誤りがない\n2.心の底で求めている\n※異表記同義、同表記異義、異言語表記(日本語の情報を英語で検索)などもある\n正しさはユーザによって変わる。\n正しい文字列をさがす手法\nクエリ表記の正誤という軸\n誤の場合表記をヒントに似た文字列を検索してみる。\n探したい対象が正確か曖昧か\n表記意外がヒントで同じ対象に到達できる?\nどんな情報を手がかりにする?\n編集距離(レーベンシュタイン)\n検索ログ\n4.Apporoの紹介\nチョコ?いや、ロケット?いや、Approximate \u0026hellip;\nhttp://code.google.com/p/apporo/\n中小規模だと使えそう\nSimString\n今後\nよみかな、ローマ字表記に基づく類似文字列検索+高速化の予定\n技術概要\nSuffix Array\nN-gram Searchベースの近似文字列照合\nBit Parallel Matchingによる編集距離計算\n5.検索と言語と文化(仮)\n@mizuno_takaaki さん\n放送禁止のためメモなし。\n7.自然言語処理におけるargmax操作\n@hitoshi_ni さん\n※順番変更\n・近似解法\nその1 全探索\nいや、無理でしょ、計算が。\nその2 貪欲法\n最適解が出るかは不明。\nその3 ビームサーチ\n上位kこの仮説を保持しながら幅優先探索\n・動的計画法\nすでに最大値がわかっていて、ゴールから眺めてみる。\n逆からたどるとルートがわかるんじゃないか。\nマルコフ性につけ込むことで、わかるんじゃないか。\n計算量:品詞数の2乗\n(品詞数の2乗)*形態素数\nDPの実装\nViterbiかなぁ?\n・整数計画法(線形-\u0026gt;整数)\n自然言語処理としては整数計画法でだいたいOK。\nアルゴリズム\n・手元の解空間中から許容解を得る\n・分枝してそこから最大値を求める\n最大値>許容解ならそちらを探索。\nプログラム実装する?\nすごく大変じゃないけど簡単でもないね。\n問題の弱点がわかってるなら実装してもいいよね。\n整数計画法の場合lp_solveなどのフリーのソフトで解くのがいいよ。エクセルでも解けるよ\nILP(整数計画法?)\n問題の切り分けに使える。\nまとめ\nILPで解けたら、いろいろ自分で考えると面白いよ。\nその他のバズワード\n参考資料\n組み合わせ最適化=1万円超\nアリ本\n6.ソーシャルグラフ分析(導入編)\n@kimuras さん mixiの木村さん\n・グラフ探索部分はまた今度。\n・テキストマイニングや検索エンジンまわりやってる。\n・ノードが数1千万、エッジが数億のオーダー\n・分散技術の発展によるアルゴリズムの多様化\nこれまで\nRDBからDumpしたデータをKVSに入れて頑張ってた。\nDump部分でデータ構造を毎回構築\n問題点\n変更による再実装、メンテナンスコスト、\nこれから\ngraphDBに取組中。マイニングに最適な感じ\ngraphDBの実装\nOrientDB、Neo4jとか\nNeo4jって\nACIDトランザクション可能\nEmbeddedGraphDatabaseだとAGPLv3だから気をつけてね。\nluceneで全文検索インデックスつくってるみたい。\nGremlinってのがquery言語を汎化してるらし。\nとあるSNSのデータを使ってみたよ。\nメモリ64G、CPUは1コアしか使えなかったよ。\nノード:15million、枝:600million\nまとめ\nということで、色々と面白い話が聞けました。特にTRIEの話はかなり興味を持ちました。\n検索周りで嫌というほど出てくるので。まだまだきちんと理解できてないので復習しないと。。。\nlucene-gosenにも関係あるので、しっかり資料をみて復習する予定です。\n基本的に検索系の話に関連があることが多くて面白く聞くことができました。\n「類似文字列検索してますか?」や「ランキング学習ことはじめ」などは身近な話(だけど、なかなかきちんと学習できてない話)でした。\nまた、「自然言語処理におけるargmax操作」では大学でやっていた線形計画法などのわかりやすい説明で10年経ってようやく理解ができた次第です。。。(もっとちゃんと勉強しとけば。。。)\n懇親会にも参加し、研究に近い分野の方が多い中でいろいろな話が聞けたのはよかったと思います。\n次回もいろいろなキーワードを拾いたいのでぜひ参加したいです。\n","date":1311737580,"dir":"post/2011/","id":"3811b40721f7ca651887aac4eb17f9f0","lang":"ja","lastmod":1311737580,"permalink":"https://blog.johtani.info/blog/2011/07/27/%E7%AC%AC1%E5%9B%9E-%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0%E3%81%A8%E6%83%85%E5%A0%B1%E6%A4%9C%E7%B4%A2%E3%81%A8%E8%A8%80%E8%AA%9E%E5%87%A6%E7%90%86%E5%8B%89%E5%BC%B7%E4%BC%9A%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-07-27T12:33:00+09:00","summary":"かなり遅くなりましたが、第1回 データ構造と情報検索と言語処理勉強会 #DSIRNLPに参加しました。 帰ってから2日半ほど寝込んでしまい、更新が","tags":["勉強会"],"title":"第1回 データ構造と情報検索と言語処理勉強会に参加しました。(Jugemより移植)"},{"contents":"以前から春山さんのブログ(リンク)や勉強会で耳にはしていたのですがソースは読んでいませんでした。 先日、Luceneにcontributeされた(リンク)ので軽くソースを読んでみました。\n公式サイトはこちら\nまずはMeCabのページにある比較表(リンク)を基準に特徴を調べてみました。せっかくなので、lucene-gosenも隣に。\n\u0026nbsp; Kuromoji lucene-gosen 解析モデル なし(学習機能なし) なし(学習機能なし) コスト推定 なし(学習機能なし) なし(学習機能なし) 学習モデル なし(学習機能なし) なし(学習機能なし) 辞書引きアルゴリズム Double Array Trie Double Array Trie 解探索アルゴリズム Viterbi Viterbi 連接表の実装 2次元 Table 3次元 Table 品詞の階層 無制限多階層品詞?ipadic、unidic形式に対応 無制限多階層品詞 未知語処理 字種 (動作定義を変更可能)(おそらく。) 字種(変更不可能) 制約つき解析 たぶん、不可? たぶん、不可? N-best解 不可能 不可能 こうやって比較してみるとlucene-gosen(Sen)とあまりかわりはありませんが、lucene-gosenが少し古いのがわかりますね。。。\nKuromojiで利用出来る辞書は現時点ではMeCab IPADIC、UNIDICの2種類のようです。\nソースを読んでの感想ですが、やはりMeCabが偉大だということがよくわかりました。 Senよりも新しいMeCabの処理に似ている点が多いです。解探索アルゴリズムや連接コスト表が特に。 MeCab向けの辞書を利用しているためというのもあるかと思います。\nKuromojiが特徴的なのは「searchモード」と呼ばれるモードが用意されていることです。 公式サイトにある例ですと、「関西国際空港」が「関西」「国際」「空港」というTokenで出力されます。 ソースを見たところViterbiアルゴリズムで辞書を探索しているときに特定の条件でコストをカサ増しすることで、結果を変えるという処理を行っているようです。\n全て漢字の単語:3文字以上の場合に「(単語の長さ-3)*10000」をコストに加算 その他の単語:7文字以上の場合に「(単語の長さ-7)*10000」をコストに加算 このようにコストを変化させることで「空港」でも「関西国際空港」という文字を含む文章が検索できる仕組みになっています。 また、「拡張searchモード」と呼ばれるモードも存在し、こちらは、未知語をuni-gramで区切って出力を行うようです。\nソース上で確認しただけで、未確認ですが、GraphvizFormatterというクラスがあるので、Graphvizで読み込める形式で形態素解析の結果が出力されるかもしれません。(すみません、確認してなくて。)\n未知語の処理やsearchモードなど面白い機能があるので、試してみるのもいいかもしれません。lucene-gosenを考えていく上でも参考になりそうです。\n最後に余談ですが、FAQのページ(リンク)が面白いです。。。\n","date":1311132540,"dir":"post/2011/","id":"5a765f9668608a39333fa90cf462657e","lang":"ja","lastmod":1311132540,"permalink":"https://blog.johtani.info/blog/2011/07/20/kuromoji%E3%82%92%E8%AA%BF%E3%81%B9%E3%81%A6%E3%81%BF%E3%81%9F/","publishdate":"2011-07-20T12:29:00+09:00","summary":"以前から春山さんのブログ(リンク)や勉強会で耳にはしていたのですがソースは読んでいませんでした。 先日、Luceneにcontributeされ","tags":["形態素解析"],"title":"Kuromojiを調べてみた(Jugemより移植)"},{"contents":"忘れてしまうので、備忘録を残しておきます。 一応、ソースには少しずつコメントをいれてはいるのですが。 私は残念ながら、自然言語処理は初心者に毛が生えた程度(現在、鋭意勉強中)で、対応方法に問題があるかもしれません。気づいた方はコメントをいただけると助かります。\n辞書ファイルについて NAIST-JDic for MeCabの辞書ファイルは以下の構成になっています。\nファイル名 メモ char.def 文字種の設定 feature.def 辞書学習用の設定? left-id.def左文脈IDのマスタ(左文脈ID、品詞情報) matrix.def 連接コスト表(前件文脈ID,後件文脈ID,連接コスト) pos-id.def 品詞IDのマスタ(品詞情報、ID) rewrite.def rewrite情報(左右文脈に出現した場合のそれぞれの品詞情報のrewriteルール。辞書学習で主に利用) right-id.def 右文脈IDのマスタ(右文脈ID、品詞情報) unk.def 未知語の品詞情報(文字種ごとに未知語のコスト、左右文脈ID、品詞情報が記載されている) naist-jdic.csv 単語辞書(単語、左右文脈ID、単語コスト、品詞情報、読みなど記載) 現時点では、MeCabDicPreprocessorでは以下のファイルを利用しています。\nleft-id.def matrix.def right-id.def naist-jdic.csv 上記以外のファイルは現時点では利用しない実装になっています。 ただし、rewrite.def、unk.def、char.defについては利用したほうがよりMeCabに近い結果が得られるような気がしています。(特に文字種ごとのコストを利用することは有効と思われます。)\nPreprocessorでの処理について lucene-gosenはSenの後継であり、MeCabの昔のバージョンを移植したものがベースとなっています。 lucene-gosenとMeCabの現時点での実装の大きな違いとして、連接コスト表の違いがあります。 ここからは憶測になってしまいますので、注意してください。(論文を探せばどこかにこの実装の変化の過程が記載してあるかもしれないですが、まだ探していません、すみません。) 過去のMeCabではChaSen向けの辞書を利用していました。 ChaSenでは連接コスト表が3つの項(前の前、前、後)から構成されていました。(n項まで定義可能らしい) ですので、lucene-gosenのViterbiアルゴリズムの引数も3つのノードが引数となっています。 lucene-gosen向けの連接コスト辞書も同様の作りになっています。 一方、現在のMeCabは先ほど書いたとおり、matrix.defでは2項の連接コスト表(前、後)となっています。この違いを保管するために、Preprocessorでは、matrix.defを3項にするために一番左(前の前)については任意の品詞を採用できるように「,,,,,,*」のみを設定しています。\n現時点では、Preprocessorの出力である中間ファイルを共通の形式に出力することで、DictinaryBuilder以降の処理に変更を加えることなくNAIST-JDic for MeCabへの対応を行う形を取りました。まずは使えるようにするのが先かと思いまして。 ただ、MeCabの辞書の構成から考えると中間ファイルに落とし込む処理に無駄があると感じています。 matrix.defでせっかく、IDによる連接コスト表を構成しているのに、IDを品詞情報の文字列に戻したconnection.csvを生成していますので。\nということで、備忘録でした。 あとは、テストをどうするか(正解をどう考えるか)なども考える必要があります。現時点での悩みの種です。。。アイデア募集中です。\n","date":1310432760,"dir":"post/2011/","id":"c70b78fd0b5dffcd38322355e9c2471e","lang":"ja","lastmod":1310432760,"permalink":"https://blog.johtani.info/blog/2011/07/12/naist-jdic-for-mecab%E3%81%AEpreprocessor%E3%81%AE%E5%AE%9F%E8%A3%85%E3%81%AB%E9%96%A2%E3%81%99%E3%82%8B%E5%82%99%E5%BF%98%E9%8C%B2/","publishdate":"2011-07-12T10:06:00+09:00","summary":"忘れてしまうので、備忘録を残しておきます。 一応、ソースには少しずつコメントをいれてはいるのですが。 私は残念ながら、自然言語処理は初心者に毛が","tags":["lucene-gosen"],"title":"NAIST-JDic for MeCabのPreprocessorの実装に関する備忘録(Jugemより移植)"},{"contents":"lucene-gosen 1.1.1をリリースしました。\n先日お知らせしたバグ修正を取り込んだjarを用意いしました。\nダウンロードはこちらから\n","date":1309777240,"dir":"post/2011/","id":"229975f1e84b5088e819cd5f2dc43080","lang":"ja","lastmod":1309777240,"permalink":"https://blog.johtani.info/blog/2011/07/04/lucene-gosen-1-1-1%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9/","publishdate":"2011-07-04T20:00:40+09:00","summary":"lucene-gosen 1.1.1をリリースしました。 先日お知らせしたバグ修正を取り込んだjarを用意いしました。 ダウンロードはこちらから","tags":["lucene-gosen"],"title":"lucene-gosen 1.1.1リリース(Jugemより移植)"},{"contents":"Solr/Lucene 3.3がリリースされました。(速報)\n以下、各サイトへのリンクです。\nSolrリリースのお知らせ\nLuceneリリースのお知らせ\nリリースのタイミングがどんどん早くなってる。。。\n","date":1309501779,"dir":"post/2011/","id":"10eb1e7dc64d8ca3dad92641dadb5de7","lang":"ja","lastmod":1309501779,"permalink":"https://blog.johtani.info/blog/2011/07/01/lucene-solr-3-3%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E9%80%9F%E5%A0%B1/","publishdate":"2011-07-01T15:29:39+09:00","summary":"Solr/Lucene 3.3がリリースされました。(速報) 以下、各サイトへのリンクです。 Solrリリースのお知らせ Luceneリリースのお知らせ リリースのタイミ","tags":["solr"],"title":"Lucene/Solr 3.3リリース(速報)(Jugemより移植)"},{"contents":"「Hadoopを中心とした分散環境での開発方法論・モデリング・設計手法等についての座談会(第5回)」に参加しました。300名入るイベントルームでしたが、後ろの方まで人が埋まっていました。\nということで、主に自分用ですが、メモを取ったので。\n※二次会行きたかった。。。\n1.「鉄道システムへの誘い」\n@ayasehiro(本名無理w)\nHadoopの話はありません。\n○鉄道系基幹システムの開発\n実態:\n耐用年数:10年以上\n開発期間:数年~5年程度\n開発規模:~10Mステップ、10k人月~\nほとんどテスト、しかも異常系が主体。\n夜間に実際に鉄道を走らせて試験したり。\n開発サイクルが長い\n人材育成が難しい、ノウハウがたまらない。\n開発自体はほとんど時間がなく、設計・製造・試験など新規技術の採用が難しい。\n開発4年前の調査・検証自体が2年程度。\nHadoopも調査中。\n○鉄道システム3大システム\nマルス(予約オンラインシステム)(1960~)\nコムトラック(運行管理システム)(1972~)\nヤックス(ヤード自動化システム)(1968~1984)\n○鉄道輸送システムとは\n用語:\n運行を計画する=\u0026gt;輸送計画\n列車を運行する=\u0026gt;運行管理\n需要想定+営業施策+その他(お召し列車など)=列車ダイヤ作成\n基本計画(長期)+短期計画(数日~四半期程度)=列車ダイヤ(重ねあわせてできあがり)\nダイヤの計画(発車時刻など)と車両運用(車両自体の走る組み合わせ(仮の車両))の作成\n+乗務員運用(乗務員の運用計画)\n運行管理:\nなにも起きなければすることなし。(車両故障、天候、人身事故などによる整合性を取る作業)\n=事前に計画した輸送計画をすべて見直し\n遅延の検知は?\n昔:人による伝令\n今:システムによる検知(レールに電流流して検知)\n運転整理(実際に遅れた):\n部分運休、折り返し駅の変更などにより対応\n元の計画になるべく近づく形で修正していく。\n新幹線、山手線、京浜東北線などは速度信号という信号が表示される。\n線路上に信号はないらしい。\n○鉄道システムを取り巻く情勢\n少子高齢化・人口減少のため凋落産業となっている。\n社会インフラの責務=動くのが当たり前\n2007年問題(ベテランの引退)=スジ屋さんは最近いないらしい。\n高度な判断支援をするシステムが必要\n連続稼動=分散技術を適用できない?\n関係各所との情報共有\n計画立案のための情報支援=最適化技術を適用できない?\n○分散処理技術の適用\n個人的な感想\n可用性(連続稼動)のための仕組み\nバッチ処理\n○分散技術の適用\n・連続稼動\nactive-active構成がメイン\n主系の出力だけを行う。問題が出れば副系の出力。\n3系統の出力を比較器にて出力もある\nmagiシステム\n問題点:\nハードが高い(H社)\nソフトウェアの作り込みが複雑=テストが前パターンできない\n解決案:\n汎用的なハードが使いたい。\n作り込みも減らしたい\n・バッチ処理:\nAsakusa使えないかなーw\n○最適化技術の採用\nコンピュータ技術の発展\n2007年問題\n職人に言わせれば最適化はいらない、俺の言うことを聞けw\n・車両運用のモデリング\n車両数大=\u0026gt;組み合わせ大\n制約条件が多い\n車両運用の場合、走行累積キロの条件もある\n-\u0026gt;有向グラフにモデル化される。(ただし、グラフ化するまでが大変)\n・乗務員運用のモデリング\n車両と違い、乗務員は1回で2人とか運べる(運転士+移動する人とか)\n・車両割当のモデリング\nやはり、グラフ化が可能\n・乗務員交番のモデリング。。。など\n結構一般的なモデルに落とし込める。ただし、落し込みが大変。\n机上研究だったものが、コンピュータの発展により実証研究になりつつある。\n○まとめ\n鉄道システムはまだまだ未到の領域が残っている。\n開発サイクルが長いため、保守的な開発になる(35年前の設計思想からあまり変わってなかったりする)\nしかし業務要件やシステム利用者の意識は変化している\n興味を持たれた方は、ぜひ、我社に!(社名は2次会でw)\n○Q\u0026amp;A\nQ:鉄道システムのカルチャーってイケイケ?保守的?(@okachimachiorgさん)\nA:最新技術も知らないとだめじゃないかという人が出てきている。\nコア部分(安全第一なところ)+周辺領域(ある程度融通が効きそうな部分)と考えることができるんじゃないかって人も出てきている。\nJR九○=先進的\nJR四○、北○道=お金ない\nJR○海=超保守(企業的に超保守)\nJR東、西=うーむ?\n東京メト○(運行計画)、阪○=先進的\n京○急行=基本人間で進路制御w\n基本的には新しいものには興味をもつ人たちでは。\nQ:Su○caとかで分散処理は利用出来るんでは?\nA:匿名なので外側から見ていると分散処理はいろいろ使えるんでは?\nログデータからいろいろできるんじゃないの?活かすべきでないの?\n使いどころはいっぱいある。\nQ:鉄道システムでどうしようもなくなったことはあるか?\nA:保守体制が一番気になる。\nOSSとかならまだ調べられる。ミドルウェアなどの保守契約が必要。\n保守体制が確立されてればある程度の保守費用は飲み込む。\nどうしようもないことはないが、今すごく困ってることは\nExcelで帳票を出したいとかいわれること。(ちょっと前に作ったシステムでExcel2003。バージョンあげると速度が遅くなったりするw)\nilog社のものを使ってたが、IBMに買収されて保守費用があがってこまってるw\n保守が10年と長いため、サポートなどの折衝が必要。\nQ:最適化の適用範囲は?\nA:走行順序(どこで追い抜くか)の算出に活用。ほぼ完成でユーザ教育中。\n1列車の波及がかなり影響が出る。ダイヤだけ見ると列車だけだが、乗務員も関係しており、大変。\nある時点から終電までを最適化の対象としたりして割り切っている。\nまた、不足分について算出が出来れば、そこで打ち切ったりもする。\n2.「九州電力におけるHadoopの取り組みについて」\n株式会社キューデンインフォコム e-ビジネス部 @hisashi_yano\n概要:2年間関係したOSSをメインにしたシステムの話。\n○九州電力の概要\n現在風当たりが強い業界。\n東電の1/10くらい\n部門ごとに大手ベンダーが関わってる。\n○Hadoop採用の経緯\n部門ごとに個別最適なシステムを導入していてベンダーロックインされてる。\n・ホストのリプレース\n・両現用センター構成への対応\n・スマートグリッドへの対応\n問題点\n・コスト削減\n・技術革新への中の人の対応(内部でも問題を理解できるように)\n・商用パッケージのカスタマイズの限界\n・脱ベンダーロックイン(実は楽なんだけど。。。)\n○過去2年間の研究内容\n・H21年度の結果\nテーマ:クラウドの要素技術の研究\nKVM、Eucalyptus、wakame、hadoop 性能比較:VMWareとKVM-\u0026gt;ベンチマーク比較\n結論:性能的にあまり問題なし。\nMapReduceの耐障害性など\nダミーデータにより台数増加による影響を検証\n結論:台数大-\u0026gt;性能向上\nストリーミングは性能劣化する\nスループットはリニアに向上\n信頼性は?\n実行中にノードを抜いたりして検証。\n結論:問題なし。\nクラウド環境におけるシステム管理手法\n複数ハードで1アプリという構成になる。\n監視対象が膨大になる。\n障害発生時の切り離しや監視対象も膨大。\nデータセンター自体を監視する仕組みが必要では?というところで終了。\n・H22年度の結果\n分散に特化した研究\n前年度の課題\nサーバの仮想化・管理に関する課題\n分散処理に関する課題\n分散処理環境の運用監視に関する課題\n目的:\nHadoopを本番への適用(実際にはダミーデータ+本番の仕組み)\n柔軟なサーバ統合基盤(サーバを起動-\u0026gt;バッチを起動-\u0026gt;回す仕組み)=MonkeyMagic\nlibvirtを使ってる\n50台の仮想サーバの起動が10数分で完了。\n運用監視基盤(monkey magic)\n仮想、実サーバ混在の監視\n監視状況(サーバの状況)から判断して制御する仕組みを構築\nDSLにてルール(判断+制御)を指定\n・ジョブの監視\n・ジョブの実行管理\n・構成管理の省力化\nvolanteと連携が可能=AmazonWebServiceとも連携可能\n・サーバリソース+アプリケーションの一括監視が可能\n分散バッチ処理の概要\nRDBからKV形式にして抽出し、MRで回してRDBに戻すという研究\n対象:\n配電部門(電柱の設備情報の目視検査)のデータの月間バッチ処理\n現状:\n19時間程度かかってる。\nテスト環境:\n実サーバ2台(仮想10台)\nMySQL、Javaで実装\n処理内容\n電柱104万本\n巨大バッチを分割して実装\n結果\nMySQL1台では15日以上かかる処理(現行システムで19時間)\n処理が32分で終了!他でも効果でるよね。\nバッチ短縮の理由は?\n1.データアクセスが分散された\n2.処理の並列化(多重化出来る部分がうまくできた)\n分散処理を書くのに2名死亡。。。\n適用基準の策定、開発ガイドライン、フレームワーク整備などが必要。\n・H23年度は?\nAsakusaの適用など。\n・さらに今後は?\nスマートグリッドへの適用\n-\u0026gt;メーターの交換が必要だが、10年くらいかかる\n-\u0026gt;スパンが長い(10年)ので商用製品だときつい?\nデータ量も半端ない。\nテネシー州とClouderaでOpenPDCってのやってるらしい。\n電力と気温の関係は密接な関係あり。\nエアコンが割合を占めてるから。\n過去実績と予想気温データから分析するのにHadoop使える!\n・2年間やってきて思うこと\n将来目指すべき理想像を掲げるのが重要\n新技術導入は段階を踏むことが必要\nコミュニケーション大切!\n○Q\u0026amp;A\nQ:仮想化環境のオーバヘッドは?(I/O)\nA:台数を増やしたときにどうなるか?というのを検証したかった。\nアプリ配布も考えていたので、物理サーバに縛られたくなかった。\nQ:仮想化に関して気をつけたM/RのPGで気をつけたことありますか?\nA:まったくないです。\nQ:日本でスマートグリッドははやるの?\nA:電力会社的にはやりたくない。費用対効果があまりない。\nQ:今後のスケジュールは?\nA:文書管理システムの組織名変更などの処理時間が540時間とかでてくるらしい。\nこれをHadoopで対応してみようかと思ってる。\nQ:Asakusaをどう評価していくのか?\nA:開発効率性があがるか?は検証する予定。1/3くらい楽になるんじゃないかなぁ?byのぐちさん\nバッチの種類などにもよると思うが、標準化も指標にする予定。\n結果はまたこの場で報告する予定。\nQ:Asakusa+MonkeyMagicの連携はどんなこと考えてる?\nA:MonkeyMagicを運用基盤として行く予定。合意が取れればだけど。\n※MonkeyMagicもOSSにするよー\nまとめ\nHadoopから少しずつ離れつつありますが、やはり興味があるので、非常に楽しく話を聞けました。\nまた、今回はインフラ分野のシステムということで、システムに要求されるレベルや\n運用周りにも気を配っている話が聞けたのが収穫でした。保守期間が長いため、テストが長い=\n運用もしっかりと考慮を入れた設計、実装が必要になるというのは最もだと思います。\nただ、少しずつ修正が入るアジャイルなども同様かと。\nMonkeyMagicが出来上がってきた背景の話を聞いて、さらに興味が湧いてきたところです。\n今後もかかわりが少ないかもしれないですが、ウォッチしていきたいと思いました。\nただ、興味あるモノが多すぎるので、優先度をつけつつこなして行かないと。。。\n少しずつでも身につけていきたいと思う今日このごろです。\n※追記:Twitterでコメントを頂いたので、忘れないように追記。\nコメントを貰えるだけでもうれしい。やはり、アウトプットしたらフィードバック貰いたいし。\nありがとうございます!\nTwitter / @cocoatomo: あの質問をまとめるとこうなるのかぁ…… 最適化そのも \u0026hellip;\nTwitter / @cocoatomo: @johtani すみません, コメントはコメント欄 \u0026hellip;\nTwitter / @cocoatomo: @johtani そこらへんの理論って最後には計算量 \u0026hellip;\nTwitter / @cocoatomo: @johtani あの話し振りだとどうもまだ本格的に \u0026hellip;\nあと、まとめも出来ていたので、ついでに。\nTogetter - 「2011/06/29_Hadoopを中心とした分散環境での開発方法論・モデリング・設計手法等についての座談会(第5回) #hadoopmodeling」\n関連するブログも見つけたので。\n第5回Hadoop座談会の感想 - ひしだまの変更履歴\nHadoopモデリング座談会(第5回)へ行ってきました - 虎塚\n","date":1309356600,"dir":"post/2011/","id":"49ba23148db9effdc3979aa0fe5876ea","lang":"ja","lastmod":1309356600,"permalink":"https://blog.johtani.info/blog/2011/06/29/hadoop%E3%82%92%E4%B8%AD%E5%BF%83%E3%81%A8%E3%81%97%E3%81%9F%E5%88%86%E6%95%A3%E7%92%B0%E5%A2%83%E3%81%A7%E3%81%AE%E9%96%8B%E7%99%BA%E6%96%B9%E6%B3%95%E8%AB%96%E3%83%A2%E3%83%87%E3%83%AA%E3%83%B3%E3%82%B0%E8%A8%AD%E8%A8%88%E6%89%8B%E6%B3%95%E7%AD%89%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E3%81%AE%E5%BA%A7%E8%AB%87%E4%BC%9A-%E7%AC%AC5%E5%9B%9E%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-06-29T23:10:00+09:00","summary":"「Hadoopを中心とした分散環境での開発方法論・モデリング・設計手法等についての座談会(第5回)」に参加しました。300名入るイベントルー","tags":["hadoop"],"title":"Hadoopを中心とした分散環境での開発方法論・モデリング・設計手法等についての座談会(第5回)に参加しました。(Jugemより移植)"},{"contents":"以前、こちらで話題に上がっていた「未知語」に関するcompositePOSのエラーの件を調査しました。(Twitterでも流れてました。) 次のような条件の場合にエラーが発生するようです。\ncompositePOSの設定に構成品詞として「未知語」が指定されたエントリが存在する。 未知語が連続して出現する文字列をanalyzeする。(例:ニンテンドーDSi) ということで、trunkに修正版をコミットしました。 Issueはこちら。\n※お茶をにごす感じの日記になってしまいました。次回はマシな記事を書く予定です。。。\n6/29追記:恥ずかしいバグをいれこんでしましました。。。 ということで、trunkに再度修正版をコミットしました。\n","date":1309232160,"dir":"post/2011/","id":"f6dff70097776e24c2a7c9c0f2514f79","lang":"ja","lastmod":1309232160,"permalink":"https://blog.johtani.info/blog/2011/06/28/compositeposcompositetokenfilter%E3%81%AE%E3%83%90%E3%82%B0%E4%BF%AE%E6%AD%A3/","publishdate":"2011-06-28T12:36:00+09:00","summary":"以前、こちらで話題に上がっていた「未知語」に関するcompositePOSのエラーの件を調査しました。(Twitterでも流れてました。) 次","tags":["lucene-gosen"],"title":"compositePOS(CompositeTokenFilter)のバグ修正(Jugemより移植)"},{"contents":"lucene-gosenのtrunkbranches/impl-mecab-dicにNAIST-JDic for MeCabの辞書を利用出来るPreprocessorをコミットしました。\nビルド方法は次のとおりです。\n$ cd lucene-gosen-trunk $ ant -Ddictype=naist-mecab 現在のstable版で利用できる辞書は「ipadic」「naist-chasen」の2種類でした。\n[以前の記事](http://johtani.jugem.jp/?eid=4)に書きましたが、naist-chasenの辞書でも2008年の更新となっています。\n今回コミットしたPreprocessorでは[NAIST-JDicのサイト](http://sourceforge.jp/projects/naist-jdic/)で公開されているMeCab向けの辞書である「mecab-naist-jdic-0.6.3-20100801」を利用出来るようになります。\nただし、lucene-gosenは昔のMeCabから派生したSenをもとにしていますので、最新のMeCabが持っている機能は\n利用できません。\nMeCab向けの辞書のうち一部のもの(matrix.def、naist-jdic.csvなど)を利用してlucene-gosen向けの辞書の中間ファイルを生成する仕組みになっています。\nまだ、仮実装版ということで、とりあえず動作するバージョンとなっています。\nまだテストが不十分ですが。。。\n利用してみて問題などあれば、lucene-gosenの[issue](http://code.google.com/p/lucene-gosen/issues/list)に登録していただくか、コメントを頂ければと思います。\n※更新が週1回に落ちてきてるので、もう少し頑張らねば。\n※2011/07/04追記 trunkにコミットしていましたが、branchに一旦移動しました。 仮実装として一旦コミットしたので、trunkとは別でテストする必要があるかと思った次第です。 ということで、試してみたい方は、[branches/impl-mecab-dic](http://code.google.com/p/lucene-gosen/source/browse/#svn%2Fbranches%2Fimpl-mecab-dic)にありますので、触ってみてください。 ","date":1308609480,"dir":"post/2011/","id":"991285e3967c3295b4ff2dcd835f7c61","lang":"ja","lastmod":1308609480,"permalink":"https://blog.johtani.info/blog/2011/06/21/naist-jdic-for-mecab%E5%AF%BE%E5%BF%9C%E7%89%88%E4%BB%AE%E5%AE%9F%E8%A3%85/","publishdate":"2011-06-21T07:38:00+09:00","summary":"lucene-gosenのtrunkbranches/impl-mecab-dicにNAIST-JDic for MeCabの辞書を利用出来るPre","tags":["lucene-gosen"],"title":"NAIST-JDic for MeCab対応版(仮実装)(Jugemより移植)"},{"contents":"前回、naist-chasenではアルファベットが別々の単語としてanalyzeされてしまうという話をしました。\nただ、これだと、英単語が含まれた文章を形態素解析すると、英単語がアルファベット単位に区切られてしまい、 単語の意味をなさなくなってしまいます。\nlucene-gosenでは、この問題に対応するための方法が提供されています。 CompositeTokenFilter(compositePOS)という機能です。\n文字通り「トークン」を「合成」するための機能になります。\n利用するためには以下の作業が必要です。(※Solrでのの利用方法を説明します。)\ncompositePOS設定ファイル(composite_pos_ja_naist-chasen.txt)の用意 schema.xmlのtokenizerにcompositePOS設定を追加 まずは、compositePOS設定ファイルの記述方法について説明します。 compositePOS設定ファイルには1行につき1つのcompositeの設定を記述していきます。 記述方法は次のようになります。品詞名を半角スペース区切りで記述します。\n連結品詞名 構成品詞名1 構成品詞名2 ... 構成品詞名n それぞれは次のような意味を持ちます。\n連結品詞名:合成したあとのトークンの品詞として出力する品詞名 構成品詞名:合成したい品詞名(スペース区切りで複数指定可能) TokenizerのcompositePOS機能は、構成品詞に定義されたトークンが連続して出力された場合に、 結合(合成)して1つのトークン(連結品詞名)として出力します。 また、以下のように構成品詞名が1種類で連続品詞名としても利用する場合は次のように省略した記述も可能です。\n以下にcompositePOSファイルの設定例を上げます。 ※なお、現時点では#によるコメント機能はありません。ので、記述した内容がそのまま利用されます。\n名詞-数 未知語 記号-アルファベット 1行目は連続した数字を1つのトークン(名詞-数)として出力する設定です。(連続品詞名=構成品詞名として省略して記述した例になります。) 2行目は連続したアルファベットを1つのトークン(未知語)として出力する設定です。\n次にSolrのschema.xmlにlucene-gosenのtokenizerを利用するフィールドタイプの設定を記述します。 $SOLR_HOME/conf/schema.xmlに以下を追加します。\u0026lt;types\u0026gt;~\u0026lt;/types\u0026gt;タグの間に記載します。\n... \u0026lt;types\u0026amp;gt; ... \u0026lt;fieldType name=\u0026amp;quot;text_ja\u0026amp;quot; class=\u0026amp;quot;solr.TextField\u0026amp;quot; positionIncrementGap=\u0026amp;quot;100\u0026amp;quot;\u0026amp;gt; \u0026lt;analyzer\u0026amp;gt; \u0026lt;tokenizer class=\u0026amp;quot;solr.JapaneseTokenizerFactory\u0026amp;quot; compositePOS=\u0026amp;quot;composite_pos_ja_naist-chasen.txt\u0026amp;quot;/\u0026amp;gt; \u0026lt;/analyzer\u0026amp;gt; \u0026lt;/fieldType\u0026amp;gt; \u0026lt;/types\u0026amp;gt; ... 重要なのはtokenizerタグのcompositePOS属性になります。ここに1.で記載したファイルを指定します。指定したファイルはschema.xmlと同じディレクトリに配置します。 以上が利用するための設定です。\n前回同様、「このComputerは、10回に1回の割合で起動中に青い画面が表示されます。」という文章をanalyze画面で解析した結果を示します。\nとまぁ、記事を書きましたが、すでにこちらで出ている話ですね。。。\nみなさん手が早くて困ってますw\nちなみに、上記の設定の場合、「100,000」や「3.14」といった文字列は「100」「,」「000」という形で出力されてしまいます。これらも数字とみなしたい場合は「名詞-数 名詞-数 記号-句点 記号-読点」という設定で1つのトークンとして出力されます。ただし、「。」も「記号-句点」なので注意が必要です。\n※なお、今回はlucene-gosen-1.1.0、Solr3.2を利用した例になっています。 ","date":1307977200,"dir":"post/2011/","id":"50f43b1726cf61066ef8656477b226be","lang":"ja","lastmod":1307977200,"permalink":"https://blog.johtani.info/blog/2011/06/14/compositepos%E3%81%AE%E5%88%A9%E7%94%A8%E4%BE%8Bnaist-chasen%E3%81%A7%E3%81%AE%E8%8B%B1%E5%8D%98%E8%AA%9E%E3%81%AE%E5%87%BA%E5%8A%9B%E6%96%B9%E6%B3%95%E4%BE%8B/","publishdate":"2011-06-14T00:00:00+09:00","summary":"前回、naist-chasenではアルファベットが別々の単語としてanalyzeされてしまうという話をしました。 ただ、これだと、英単語が含ま","tags":["lucene-gosen"],"title":"compositePOSの利用例(naist-chasenでの英単語の出力方法例)(Jugemより移植)"},{"contents":"lucene-gosenの1.1.0がリリースされました。\n大きな目玉はJapaneseTokenizerが出力する形態素に関するデータを遅延ロードすることで、パフォーマンスの改善を行ったことです。\n詳しくは関口さんのブログで実測されてます。さすが、早い。。。 あと、先日リリースされたLucene/Solr 3.2への対応も行われています。\nlucene-gosen-1.1.0のダウンロードはこちらから。\nうーん、中身がない記事だ。。。\n","date":1307934480,"dir":"post/2011/","id":"eeef60efe889349870426d10edc694be","lang":"ja","lastmod":1307934480,"permalink":"https://blog.johtani.info/blog/2011/06/13/lucene-gosen-1-1-0-%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9/","publishdate":"2011-06-13T12:08:00+09:00","summary":"lucene-gosenの1.1.0がリリースされました。 大きな目玉はJapaneseTokenizerが出力する形態素に関するデータを遅延","tags":["lucene-gosen"],"title":"lucene-gosen 1.1.0 リリース(Jugemより移植)"},{"contents":"lucene-gosenをSolr/Luceneで利用する場合、TokenFilterを利用してTokenizerが出力したToken対してさまざまな処理(Tokenに対する正規化や展開など)を追加することが可能です。\n今回は現在(ver. 1.0.1)用意されているTokenFilterについて説明します。 以下はTokenFilterの一覧です。 「フィルタ名」にはSolrのschema.xmlで記述するクラス名を書いてあります。\nフィルタ名(Factory名) 概要 solr.JapaneseWidthFilterFactory 全角のASCII文字を半角に、半角カタカナを全角にするフィルタ。例:「Computer」-\u0026gt;「Computer」 solr.JapanesePunctuationFilterFactory 区切り文字、記号などを除外するフィルタ。[※1](#token_filter_kome_1) solr.JapanesePartOfSpeechStopFilterFactory 設定ファイルに記載した品詞に該当するTokenを除外するフィルタ。ファイルは「tags=\"ファイル名\"」とfilterに記載。なお、ここで記述する品詞とはanalysis画面に表示される「partOfSpeech」の完全一致となります。 solr.JapanesePartOfSpeechKeepFilterFactory 設定ファイルに記載した品詞に該当するToken\"以外\"を除去フィルタ。ファイルは「tags=\"ファイル名\"」とfilterに記載。なお、ここで記述する品詞とはanalysis画面に表示される「partOfSpeech」の完全一致となります。 solr.JapaneseBasicFormFilterFactory Tokenを基本形に変換するフィルタ。例:「悲しき」-\u0026gt;「悲しい」 solr.JapaneseKatakanaStemFilterFactory カタカナの長音(ー)の正規化フィルタ。4文字以上のカタカナのみの文字列の最後の長音(ー)を除去した文字列に変換します。例:「コンピューター」-\u0026gt;「コンピュータ」、「コピー」-\u0026gt;「コピー」 上記のTokenFilterをJapanizeTokenizerを利用するフィールドタイプに設定することで 各フィルタによる機能が有効になります。 schema.xmlの記載に関する詳細についてはこちらを参考にしてください。\n※1 Characterクラスの以下の定数に相当する文字が。SPACE_SEPARATOR、LINE_SEPARATOR、PARAGRAPH_SEPARATOR、CONTROL、FORMAT、DASH_PUNCTUATION、START_PUNCTUATION、END_PUNCTUATION、CONNECTOR_PUNCTUATION、OTHER_PUNCTUATION、MATH_SYMBOL、CURRENCY_SYMBOL、MODIFIER_SYMBOL、OTHER_SYMBOL、INITIAL_QUOTE_PUNCTUATION、FINAL_QUOTE_PUNCTUATION\n","date":1307344980,"dir":"post/2011/","id":"4b046ac6a4796fb1338f0481dbd4003d","lang":"ja","lastmod":1307344980,"permalink":"https://blog.johtani.info/blog/2011/06/06/lucene-gosen%E3%81%AEtokenfilter%E3%81%9F%E3%81%A1/","publishdate":"2011-06-06T16:23:00+09:00","summary":"lucene-gosenをSolr/Luceneで利用する場合、TokenFilterを利用してTokenizerが出力したToken対して","tags":["lucene-gosen"],"title":"lucene-gosenのTokenFilterたち(Jugemより移植)"},{"contents":"辞書の特性について 現在lucene-gosenでは以下の2つの辞書が利用可能です。 簡単に違いについて説明します。\nIPAdicの辞書について\nバージョン:2.6.0(※IPAdicとして公開されている最新は2.7.0) 最終更新日:2003/06/19 登録単語数:約24万語 NAIST-Jdicができたためか、更新されていない NAIST-Jdic-for-ChaSenの辞書について\nバージョン:0.4.3(※NAISTとして公開されている最新はMeCab用の辞書0.6.3) 最終更新日:2008/07/07 登録単語数:約28万語 IPAdicの後継として整備。品詞の定義など大まかな仕様は共通。 IPAdicと異なり、アルファベットや数字が1文字ずつ単語として登録されている。 IPAdicとNAIST-Jdicで大きな違いはアルファベットと数字の扱いについてです。 次のような文章をそれぞれの辞書で解析した結果は次のようになります。(SolrのField Analysisの画面です。思いの外大きいのでサムネイルのみですが。) 「このComputerは、10回に1回の割合で起動中に青い画面が表示されます。」 ○IPAdicの場合 ○NAIST-Jdicの場合 「Computer」と「10」という単語の区切り方が異なることがわかります。 この違いは、辞書のエントリが異なるために発生します。 NAIST-Jdicでは、数字(例:「1」)やアルファベット(例:「a」)が個々のエントリで登録されているため、分割された単語として認識されます。\n※この問題への対応方法はまた後日。\nカスタム辞書について 実際のデータを形態素解析したい場合、辞書に存在しない単語を登録して、1単語として認識させたい場合があります。(固有名詞など) このような場合にカスタム辞書を利用することで、新しい単語を辞書に登録することが可能になります。 カスタム辞書を利用する手順としては次のようになります。\nカスタム辞書ファイルの作成 作成した辞書ファイルを利用したjarファイルの生成 まずは辞書ファイルの作成についてです。 以下では、naist-chasen(NAIST-Jdic)の辞書を例として説明します。(ディレクトリの違いだけで、IPAdicでも同じ方法でOKです。)\nlucene-gosenでは辞書のコンパイルに2つのフェーズが存在します。\ngosen用辞書を生成する前処理(中間csvファイルの生成) gosen用バイナリ辞書の生成 カスタム辞書は1の出力の形式(=中間csvファイル=dictionary.csv)にあわせたCSVファイルとして作成します。 CSVの各カラムは次のような意味を持っています。\n単語 単語の生起コスト 品詞 品詞細分類1 品詞細分類2 品詞細分類3 活用型 活用形 基本形 読み 発音 3カラム目以降は「素性(そせい?)」と呼ばれる項目です。ipadic、naist-jdicでは「品詞」「品詞細分類1」「品詞細分類2」「品詞細分類3」「活用型」「活用形」「基本形」「読み」「発音」となります。 ※「見出し語」「形態素生起コスト」「素性」と呼ばれる項目を表形式にする。 厳密な品詞の体系に関してはIPAdicやNAIST-Jdicのサイトをご覧ください(説明できるレベルにはまだまだなっていないので。。。) 今回は、固有名詞(人名、地名など)を追加するという例でカスタム辞書について説明します。 固有名詞として「達川」という人名を追加してみましょう。 まずは、次のようなエントリをもつ「custom-dic.csv」ファイルを作成します。ファイルはUTF-8で保存してください。 コストはすでにあるエントリで似たようなエントリのコストを真似します。(今回は固有名詞,人名で似ているものを採用)。ちなみに、コストは小さいほど単語として出てきやすくなります。 ※カスタム辞書にはSenで利用していたものが利用できます。 **\"達川\",2245,名詞,固有名詞,人名,名,*,*,\"達川\",\"タツカワ\",\"タツカワ\"** 上記ファイルを、先日紹介した$LUCENE-GOSEN/dictionary/ディレクトリにコピーします。 では、カスタム辞書を含んだlucene-gosenのjarを作成しましょう。 カスタム辞書のビルドは$LUCENE-GOSEN/dictionary/で行います。 また、カスタム辞書の指定はCSVファイル名をantの引数で指定します。次がコマンドの例になります。\n$ cd lucene-gosen-trunk $ cd dictionary $ ant -Ddictype=naist-chasen clean-sen $ ant -Ddictype=naist-chasen -Dcustom.dics=\u0026#34;../custom-dic.csv\u0026#34; compile $ cd .. $ ant -Ddictype=naist-chasen 上記コマンドの例で\u0026quot;clean-sen\u0026quot;というタスクを実行しています。これは、すでに出来上がっているgosen用のバイナリ辞書を削除するタスクになります。すでにgosen用の辞書が作成されている場合には辞書の再生成が行われないためです。 また、複数のファイルを利用したい場合は-Dcustom.dics=\u0026ldquo;custom-dic.csv custom-dic2.csv\u0026quot;という形でスペース区切りでファイル名を記述すればOKです。\nカスタム辞書を適用する前と適用後の違いは次のとおりです。 適用前 適用後 簡単ですが、以上がカスタマイズ辞書を利用する方法でした。 ちなみに、この記事を書く前にすでにカスタム辞書の件を書いているブログがありました。。。こちらも参考にしてください。 今回の例でいくつかSolrのanalysis画面を利用して説明してきました。Solrでのlucene-gosenの利用方法についてはまた後日記載したいと思います。 ※参考までに。Solrでの利用方法はこちらにも記載してあります。\nまた、IPAdicなどの辞書について記載のある書籍を見つけましたので、参考になれば。\nアプリケーションソフトの基礎 (講座ITと日本語研究) ","date":1307002560,"dir":"post/2011/","id":"b2621497b3313c97855ed951f0d9b291","lang":"ja","lastmod":1307002560,"permalink":"https://blog.johtani.info/blog/2011/06/02/%E8%BE%9E%E6%9B%B8%E3%81%A8%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0%E8%BE%9E%E6%9B%B8%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/","publishdate":"2011-06-02T17:16:00+09:00","summary":"辞書の特性について 現在lucene-gosenでは以下の2つの辞書が利用可能です。 簡単に違いについて説明します。 IPAdicの辞書について バ","tags":["lucene-gosen"],"title":"辞書とカスタム辞書について(Jugemより移植)"},{"contents":"今回はソースのダウンロードとビルドについてです。\n最新版のソースを利用したり、JavaDocを見たい場合はソースをダウンロードしてからビルドすることになります。 ソースのダウンロードからビルドまでの手順について説明します。\nまずはソースのダウンロードです。\n$ mkdir ~/work $ cd work $ svn co http://lucene-gosen.googlecode.com/svn/trunk/ lucene-gosen-trunk $ cd lucene-gosen-trunk ダウンロードしたソースは次のようなディレクトリ構成です。\n.classpathEclipse用ファイル .projectEclipse用ファイル .settingsEclipse用ファイル AUTHORS作者のリスト(Sen、GoSen) CHANGES.txtlucene-gosenにおける更新履歴 COPYING.LGPLライセンス README.txtReadme build.xmlAntのビルドファイル dictionary辞書コンパイル用ディレクトリ docsAPIドキュメント用ディレクトリ libライブラリ prettifyGoogle Code Prettify用ディレクトリ(APIドキュメントでの色づけ用) srcソースコード また、辞書やソースのコンパイルにはAntを利用します。 通常利用するAntのタスクには次のようなものがあります。\ncleanプロジェクトのクリーンアップ build-dic辞書のコンパイル(辞書のダウンロードも行う) jarjarファイル生成 dist配布パッケージの生成(2つのjarファイル生成) javadocJavaDocの生成 jarファイルの生成までの大まかな流れは「javaソースのコンパイル」~「辞書のダウンロード」~「辞書のプレコンパイル」~「辞書のコンパイル」~「jarファイルの生成」となります。 Antのタスク以外にjarファイルを生成する場合に利用するオプションは以下の通りです。\n-Dproxy.hostプロキシのホスト -Dproxy.portプロキシのポート -Ddictype辞書の指定(指定可能なものは次の通り。naist-chasen、ipadic) 以下はNaist-Jdicのjarファイルを生成するコマンドの実行例になります。プロキシサーバを利用する環境の場合は-Dproxy.hostと-Dproxy.portも指定してください。(※認証が必要なプロキシの場合はAntのビルドファイルを修正する必要が出てきます。)\n$ ant -Ddictype=naist-chasen jarファイルはdistディレクトリに生成されます。 これで、jarファイルが利用できるようになります。\n次回は、ipadicとNaist-chasenの辞書の違いとカスタム辞書を利用する方法について書こうと思います。\n","date":1306398840,"dir":"post/2011/","id":"ff1441a42144a7de9a3eaf9f5e7cfea9","lang":"ja","lastmod":1306398840,"permalink":"https://blog.johtani.info/blog/2011/05/26/%E3%82%BD%E3%83%BC%E3%82%B9%E3%81%8B%E3%82%89%E3%81%AE%E3%83%93%E3%83%AB%E3%83%89%E3%81%A8%E6%A7%8B%E6%88%90/","publishdate":"2011-05-26T17:34:00+09:00","summary":"今回はソースのダウンロードとビルドについてです。 最新版のソースを利用したり、JavaDocを見たい場合はソースをダウンロードしてからビルドす","tags":["lucene-gosen"],"title":"ソースからのビルドと構成(Jugemより移植)"},{"contents":"概要: Lucene/SolrのコミッターであるRobert Muirさんが始めたプロジェクト 歴史: MeCabのJava移植版としてスタートしたSenがベースになります。 その後、辞書の構築部分をPerlからJavaに置き換えたGoSenが登場しました。 が、どちらもメンテナンスされなくなってきたので、Robertさんが引き継いでメンテナンスとLucene/Solr対応をはじめました。そして、現在にいたります。 ライセンス: LGPLライセンス(ベースになったMeCabのライセンスにならって) 特徴: 以下のような特徴があります。 ・Lucene/Solrですぐに利用可能(3.1、4.0に対応済み) ・jarファイル1つで利用可能(辞書をjarファイルに内包) ・LuceneのAttributeをベースにしたTokenの解析 ・その他(パフォーマンス改善、テスト改善など) プロジェクトのサイト: http://code.google.com/p/lucene-gosen/ ダウンロード: http://code.google.com/p/lucene-gosen/downloads/list 現時点では2つの辞書を内包したjarファイルが用意されています。 Naist-jdic 0.4.3(for ChaSen) 参考サイト:http://sourceforge.jp/projects/naist-jdic/ IpaDic 2.6.0 参考サイト:http://sourceforge.jp/projects/ipadic/ ","date":1306130400,"dir":"post/2011/","id":"5988b62a0c0785a303b77c74608e8b55","lang":"ja","lastmod":1306130400,"permalink":"https://blog.johtani.info/blog/2011/05/23/lucene-gosen%E3%81%A8%E3%81%AF/","publishdate":"2011-05-23T15:00:00+09:00","summary":"概要: Lucene/SolrのコミッターであるRobert Muirさんが始めたプロジェクト 歴史: MeCabのJava移植版としてスタートした","tags":["lucene-gosen"],"title":"lucene-gosenとは(Jugemより移植)"},{"contents":"今さらですが、ブログをはじめてみようかと。今さらですが…\nはじめてみようと思った一番の理由は、自分で調べたことをメモがわりに残すためです。 あとは、自分を追い込むためもありますが。(こっちが一番の理由かも)最近勉強してないなぁと感じているので。 ということで、まずは、lucene-gosenやsolrについて書いていく予定です。\n","date":1305859440,"dir":"post/2011/","id":"94b85ba716dbb7c20b230e69248b8208","lang":"ja","lastmod":1305859440,"permalink":"https://blog.johtani.info/blog/2011/05/20/%E3%83%96%E3%83%AD%E3%82%B0%E3%81%AF%E3%81%98%E3%82%81%E3%81%BE%E3%81%99/","publishdate":"2011-05-20T11:44:00+09:00","summary":"今さらですが、ブログをはじめてみようかと。今さらですが… はじめてみようと思った一番の理由は、自分で調べたことをメモがわりに残すためです。 あと","tags":["misc"],"title":"ブログはじめます(Jugemより移植)"}]
\ No newline at end of file
diff --git a/index.xml b/index.xml
index 106b558448..1ca337447f 100644
--- a/index.xml
+++ b/index.xml
@@ -63,7 +63,7 @@ Amazonのプロダクトデータを使ってもうちょっとやろうと思
全然終わる気配がないw</p>
<p>ローカルでの開発環境などをDev containerにちょっとずつしています。
Slackのボット、検索の遊び場、このブログ環境など。Dockerが必要にはなりますが、VSCodeとDev containerで環境を隔離できるし、VSCodeの拡張もコンテナごとに入れるのもできたりと便利です。</p>
-<p>最後は、検索技術勉強会を再開したことです。再始動という感じで4年ぶり?に再開しました(<a href="https://search-tech.connpass.com/event/303330/">12月に開催した時のページ</a>)。残念ながら私は裏方をしてただけで、当日は参加できてないのですが、次回(たぶん4月くらい)は参加するつもりです。再開の声を上げてくれた<a href="https://twitter.com/takuya-b">@takuya-a</a>さんありがとう。<a href="http://bit.ly/SpeakerSearchTechTalk">絶賛スピーカーを募集中</a>です。</p>
+<p>最後は、検索技術勉強会を再開したことです。再始動という感じで4年ぶり?に再開しました(<a href="https://search-tech.connpass.com/event/303330/">12月に開催した時のページ</a>)。残念ながら私は裏方をしてただけで、当日は参加できてないのですが、次回(たぶん4月くらい)は参加するつもりです。再開の声を上げてくれた<a href="https://twitter.com/takuya_b">@takuya_a</a>さんありがとう。<a href="http://bit.ly/SpeakerSearchTechTalk">絶賛スピーカーを募集中</a>です。</p>
<h2 id="来年の抱負">来年の抱負</h2>
<p>さて、来年の抱負です。</p>
<ul>
diff --git a/orama.json b/orama.json
index a59c6c5c65..e78792d1a1 100644
--- a/orama.json
+++ b/orama.json
@@ -1 +1 @@
-[{"contents":"今年も振り返りブログをリビングで書いています(ドミノ倒しすごいな)。 FMVのキーボードで書いているのでタイポがつらい。。。\n振り返り(2022年に書いた抱負から) まずは振り返りをと。\nフリーランス継続 今年も個人事業主として乗り越えられました。 ZOZOさんには今年も引き続きお世話になっている感じです。 そのほかにベクトル検索のお手伝いをしたり、OpenSearchを調べたりといった仕事を手伝っています。 今年も完全にリモートで作業していましたが、イベントに出かけたりできました。 来年はもう少し出かける感じになるかな? 今年はすこしのんびり仕事をしていたので、来年はもう少し仕事探さないとかな(営業しないとなあ)\nプログラミング 今年はプログラムを書いたほうかなと。 Goで個人用ですが、Slackのボットを書いてみたり(GoでSlackのボットを作った話 | @johtaniの日記 3rd | @johtani\u0026rsquo;s blog 3rd edition)、公開されているAmazonのプロダクトデータを使って検索アプリを書いてみたり。 プロダクト用のアプリを書いているわけではないですが、ちょっとずつコードを読んだり書いたりしています。\nベクトル検索まわりをさわる がっつりとまではいかないですが、Elasticsearchのベクトル検索の調査をやったりしました。 Amazonのプロダクトデータを使ってもうちょっとやろうと思いつつ、そこまでは手が回せてない感じですが。 速度という面でどうやって折り合いをつけつつ導入するのか? どういうシーンでつかうのがいいのか? どのモデル選ぶのか?とか気になることだらけ。 なんか、みなさんがどうしてるのか気になってしょうがないので、話をしてもいいよという方は連絡をもらえるとうれしいかもなぁ。 ベクトル検索とかLLMの周りの動きがはやすぎてついていけてるのかどうか。。。\n本を読む 今年は比較的読んだかも?\n単体テストの考え方/使い方 ユーザーの問題解決とプロダクトの成功を導く エンジニアのためのドキュメントライティング ザ・ダークパターン ユーザーの心や行動をあざむくデザイン これまでの仕事 これからの仕事 機械学習による検索ランキング改善ガイド ソフトウェア設計のトレードオフと誤り 初めてのGo言語 買って読んでない本ももっとあるんですが。。。\n振り返り(今年あったできごと) ここからは今年の出来事を。 今年もずっと自宅でしごとしてました。 あとは少し仕事が少なめだったのでゲームが多くなってしまったかも?(本読めばいいのに。。。)\nゲーム(ONI、ゼルダ、FactorioのSpace Exploration) Dev container導入 検索技術勉強会の再開 ゼルダの新作面白かったですね。年初はOxigen Not Includedをやっていたのに、ゼルダが出てからはご無沙汰中です。ゼルダが終わった後は、ゼルダロスになってPythonを書いたりしていたのですが、うっかりFactorioのSpace Explorationを始めてしまい大変なことに。。。 全然終わる気配がないw\nローカルでの開発環境などをDev containerにちょっとずつしています。 Slackのボット、検索の遊び場、このブログ環境など。Dockerが必要にはなりますが、VSCodeとDev containerで環境を隔離できるし、VSCodeの拡張もコンテナごとに入れるのもできたりと便利です。\n最後は、検索技術勉強会を再開したことです。再始動という感じで4年ぶり?に再開しました(12月に開催した時のページ)。残念ながら私は裏方をしてただけで、当日は参加できてないのですが、次回(たぶん4月くらい)は参加するつもりです。再開の声を上げてくれた@takuya-aさんありがとう。絶賛スピーカーを募集中です。\n来年の抱負 さて、来年の抱負です。\nフリーランス継続 プログラミング継続 ベクトル検索の使い方をいろいろ試す 本を読んだブログを書く 今年もなんとかフリーランスを継続できましたが、そろそろ営業をしないといけないのかも? ということで、外でしゃべったりもしていかないとなぁと。 あとは、検索ってどうやって導入すればいいのか?検索どうすれば改善できる?みたいなところのお手伝いをもっとしたいと思っています。 昨年出したこの本もあるので(『検索システム ― 実務者のための開発改善ガイドブック』 – 技術書出版と販売のラムダノート)、勉強会をやろうとしているところに顔を出したりしたいなあ。 外部の人を呼んで社内勉強会とかをできるというところがあれば参加したいので、声をかけてもらえればと。\nプログラミングはGo言語を触ったし、今年後半には検索の画面回りのプロダクトを触ってTypeScriptを勉強していこうかなという気になっています(なっているだけかもしれない?)。\nベクトル検索の使い方は、LLMだったりRAGだったりが世の中を席巻しているのもあり、いろんな記事が出てきて全然追いつけていません。だれか、少人数で勉強会とかやると興味ある人とかいるかなぁ? こんなブログ見つけたよ、こんな論文があったよ、こんな使い方したらよかったよとかの共有をやるとみんな楽になったりしないかなぁ?\n今年は時々出かけて移動するタイミングで書籍を読んでいました。 読んだだけになってるのもあるので、少しでもいいからブログか何かに残しとかないとな。\nさて、今年は少しゆっくりできたので、来年はもうちょっといろんなところに顔を出しつつ、新しい仕事もできるといいなぁ。 勉強会もスピーカー集めをがんばるぞと。\nということで、今年もあと少しというところで無事書き終わりました。 来年もよろしくお願いいたします。よいお年をー\n","date":1704008961,"dir":"post/2023/","id":"d869fb48cb9acba03dc639481524ee80","lang":"ja","lastmod":1704008961,"permalink":"https://blog.johtani.info/blog/2023/12/31/review-2023/","publishdate":"2023-12-31T07:49:21Z","summary":"今年も振り返りブログをリビングで書いています(ドミノ倒しすごいな)。 FMVのキーボードで書いているのでタイポがつらい。。。 振り返り(2022","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2023)"},{"contents":"この記事は、情報検索・検索技術 Advent Calendar 2023の15日目の記事です。\n昨年に続き2回目の情報検索のAdvent Calendar参戦です。\n今年は、夏にオンライン参加したBerlin Buzzwordsの「The Debate Returns (with more vectors) Which Search Engine?」というセッションでPhilippさんが話題に出したOrama searchという検索エンジンを紹介してみようと思います(Oramaが正式名称なのかな?)。\nOramaという検索エンジン 公式サイトのトップにも記載がありますが、エッジで動作する全文検索&ベクトル検索エンジンというもののようです。 なにそれ?という感じがしますが、オープンソース版のドキュメントを見るともう少しわかりやすい説明になっています。\nOrama is a fast, batteries-included, full-text and vector search engine entirely written in TypeScript, with zero dependencies.\nOramaはTypeScriptで書かれた、依存なしで利用できる検索エンジンということです(batteries-includedって初めて見たかも。「必要なものがそろってる」とかいう意味みたい(参考:英語のWikipedia))。\n以下は公式サイトにあるサンプルです。\ncreateでスキーマの定義をした検索エンジンのインスタンスを生成します。 insertで先ほど生成した検索エンジンにデータをインデックスします(後で紹介しますが、一括でインデックスするメソッドも用意されています)。 searchで検索し、検索した結果が返ってきます。 以上です。あとは、必要に応じてGUIを用意するだけです。\nimport { create, insert, search } from \u0026#39;@orama/orama\u0026#39; const db = await create({ schema: { title: \u0026#39;string\u0026#39;, director: \u0026#39;string\u0026#39;, isFavorite: \u0026#39;boolean\u0026#39;, year: \u0026#39;number\u0026#39; } }) await insert(db, { title: \u0026#39;The Prestige\u0026#39;, director: \u0026#39;Christopher Nolan\u0026#39;, isFavorite: true, year: 2006 }) const searchResults = await search(db, { term: \u0026#39;prestige\u0026#39;, where: { isFavorite: true, year: { between: [2000, 2008] } } }) サクッと動きそうですよね?依存関係がなくTypeScriptで書かれているということは静的なサイトなどでコンテンツを検索するのに使えるのでは?\nということで、自分のブログに組み込んでみました。 今回は組み込んだ時の流れと気になった点などを紹介します。 Hugoに組み込む際になるべく簡単にしたかったので、unpkg.comで公開されているJavaScriptだけを利用する形で検索ページを作ってみました。 JavaScriptやTypeScriptは不慣れなので効率がよくなかったり、間違っている点があればコメントなどをいただけると嬉しいです。\n構成 私のブログサイトはHugoで生成(参考:Hugo導入時の記事)して、GitHub Pagesとして公開しています。 現在のブログ検索にはAlgoliaを利用しているのですが、テスト目的としてOramaも使えるようにしてみました(右上のメニューでOramaをクリックすると以下で説明するOramaによる検索を試すことができます。\n今回実装してみたのは次のような流れです(日本語検索対応については後で説明します)。\nHugoでJSONのリストを生成(これまでと一緒) 1.で生成したリストをもとにNodeのスクリプトでOramaのインデックスファイルを作成 2.で作成したファイルを公開 画面で3.のファイルをダウンロードして検索 1. HugoでJSONのリストを生成(これまでと一緒) HugoでJSONのリストを生成します。Algoliaに記事を登録するのにも利用している仕組みです。 検索に利用する記事の情報を1記事を1つのオブジェクトとして出力します。1つの配列に記事ごとのオブジェクトが入っているJSONファイルになります。\n少しだけ特殊なことをしています。 ブログ記事にTagsというフィールドのありなしで処理を分岐しています。 Oramaが配列にNullを受け取った場合にうまく動かなかったので出力するJSON側で調整しています(あとで再確認してIssueあげておかないと)\n2. 1.で生成したリストをもとにNodeのスクリプトでOramaのインデックスファイルを作成 最初に紹介した公式のサンプルの場合、毎回Oramaのインスタンスを生成した後にインデックス登録の処理を行わなければいけません。 ただ、Hugoで生成したコンテンツは特に動的に更新があるわけでもないので、検索画面を表示するたびにインデックス登録するのも無駄が多い気がします。 Orama単体で最初に実装した時には、1.で作成した記事一覧のJSONをOramaで実装した検索ページのスクリプトが呼ばれたタイミングでフェッチし、insertMultiple(複数登録用のメソッド)を呼び出す実装にしていました。\nOramaでは、あらかじめ作成したOramaのデータベースを永続化・リストアするためのData Persistenceプラグインが提供されています。 インデックスに登録する処理コストはHugoでコンテンツを生成した直後に行い、検索画面では作成済みのインデックスファイルをフェッチしてリストアする形にすることにしました。インデックスと記事のJSONデータを含んだファイルになるので、元の記事一覧のJSONよりはファイルサイズが大きくなってしまいますが、処理時間も含めて考えると許容できるサイズではないかなと。\n次のスクリプトは1.で生成したJSONファイルを読み込んで、Oramaでインデックスした後にdpackというバイナリ形式でファイルに保存しています。 こののプラグインで選択できる形式は現時点ではjson、binary(デフォルト=msgpack)、dpackの3種類になります。 残念ながら今回試したところ、binaryではエラーが発生したので、dpackを使用しました。\n3. 2.で作成したファイルを公開 単にGitHub Pagesに公開しているだけです。 ブラウザが2.で作成したインデックスファイルをフェッチしてから利用するためです。\n4. 画面で3.のファイルをダウンロードして検索 あとは検索画面です(長すぎるので、styleの部分は省略しています)。\nまず、必要なライブラリなどを読み込みます(下のソースコードの1行目から14行目)。\nOramaだけであれば問題ないのですが、OramaのプラグインがOramaをモジュールとして参照しているため、importmapとして定義しています。 Oramaのプラグインがいくつか利用しているものがあったので、まとめてimportmapに定義してあります。\n次に、検索窓(search-searchbar)や検索結果(search-hits)などのHTMLタグを用意します。 ヒット件数と検索にかかった時間も取れるので、表示する場所としてstatsも用意してあります。\n22行目からが実際の処理になります。\n28行目で、手順2.で作成したインデックスのファイルをフェッチします。 32行目でフェッチしたファイルから取り出した文字列をリストアして、Oramaのインスタンスを生成します。 34行目のtokenizerに関しては日本語対応で説明します。\n48行目のquery関数がクエリの組み立て+検索の処理です。search-inputで入力されたテキストをtermとして渡して検索をしています(56行目)。 検索した結果のリストをもとに検索結果のHTMLタグを組み上げていきます。 検索結果には後述する@orama/highlightのモジュールを利用してスニペットを追加しています。\n日本語対応 残念ながらOramaは公式には日本語をサポートしていません(サポートしているスキーマに設定できるlanguageの一覧(=STEMMERSにあるものだけ指定可能)。一覧と実装分けたほうがいい気がするけど?)。 ただ、tokenize関数を変更できるようにしてくれています。これを利用して、少しトリッキーな形で日本語対応しました。\n先ほどの手順2.でOramaのcreate関数として、componentsに次のtokenizerを渡します。\nlanguageはenglishですが、日本語をtokenizeする処理に次のように書き換えました。 stemmingは今回は行わない(=用意されているstemmerを使えない)のでfalse、normalizationCacheは空のMapを用意しておかないとエラーが出るので、new Map()しています。 この設定を使ってcreateすることで、\ncomponents: { tokenizer: { language: \u0026#34;english\u0026#34;, stemming: false, normalizationCache: new Map(), tokenize: (raw) =\u0026gt; { return tokenize(raw) }, }, }, 少しわかりにくいですが、tokenizerのtokenize関数の中で呼び出しているreturn tokenize(raw)の部分はwakachigakiというライブラリのtokenize関数となっています。\nwakachigakiというライブラリ Elasticsearchなどのサーバー上で動作させる検索エンジンではkuromojiなどの辞書を内包した形態素解析器を利用するのが通常です。 ただ、今回はブラウザだけで完結した簡単な検索を行う仕組みをOramaを使って提供しようと考えました(kuromoji.jsというのもありますが、辞書のサイズがそこそこのサイズです)。 ですので、辞書ファイルのない軽量の形態素解析ライブラリとして、wakachigakiというライブラリ(=6.2Kbの軽量日本語分かち書きライブラリ)を利用してみました。\n最初はTinySegmenterの利用をしていたのですが、wakachigakiのサイトにもあるように、TypeScriptやES Moduleでも利用できる形式となっていたのでこちらに切り替えました。\n辞書もっていないため、品詞でのフィルタリングや読みを利用した処理はできませんが、日本語の文章を分かち書きしてくれます。\ntokenize関数の設定 OramaのTokenizerインタフェースのtokenizeは入力の文字列をstring[]として返すことを期待しています。 wakachigakiのtokenizeも文字列を引数にとり、string[]を返すので、そのまま呼び出すだけにしてあります。\nただ、今回のブログ検索の実装では、検索窓に入力された文字列も特に何も処理せずにtokenizeに渡す形にしています。 クエリパーサーなどを考える場合は、検索窓に入力された文字列を前処理したりする必要がありますが今回はいったんこれで。。。\ndata-persistenceはcomponentsはpersistしない 手順2.で導入した、data-persistenceプラグインですが、現在の実装ではOramaが生成したデータベース(転置インデックス)だけを永続化しています。 独自に設定したtokenizerは残念ながら含まれていませんでした。 手順4.の検索画面のコードの34行目の部分(下記)で、フェッチしたインデックスデータからrestoreした後のOramaのインスタンスのtokenizerに手順2.と同じ設定のtokenizerを設定することで検索時にも同じトークナイズがされるようになります(今の仕組みだと修正した場合には、両方のソースコードを修正しないといけないのがちょっと面倒かも?)。\ndb.tokenizer = { language: \u0026#34;english\u0026#34;, stemming: false, normalizationCache: new Map(), tokenize: (raw) =\u0026gt; { return tokenize(raw) }, } tokenizerはOramaの検索エンジンのインスタンスに紐づく設定となっているので、フィールドごとに切り替えるといったことも現在では想定されていない気がします。\nハイライト ハイライトのために、インデックスデータに単語のポジションを保存するためのプラグインも提供されています。 このポジションは検索の単語がヒットしドキュメントのどの位置に出てくるのか?をあらかじめデータとして保存しておくことで、ハイライトのたびに単語の位置を毎回計算しなくてもよくするためのものと思われます。\nこれを利用してもよかったのですが、今回は@orama/highlightというモジュールを利用することにしました。 検索にヒットしたドキュメントの元の文章と検索のキーワードを入力すると検索キーワードの周りにハイライトのHTMLタグを埋め込んでくれるライブラリを利用しました。これは普通に他でも便利かも?\n余力があればプラグインを利用した時のインデックスのサイズの違いや検索時の速度の違いを調べてみるのもいいかもしれないです。\nそのほかの機能 今回は利用していませんが、Oramaにはそのほかの機能も用意されています(公式ドキュメントの検索の紹介のページ)。詳細は公式ドキュメントをご覧ください。\nTypo tolerance Facet/Filter Vector Search Geo Search Grouping Threshold Preflight Oramaで(まだ?)できないこと 今回触ってみて、現在のOramaの実装ではできなそうなことがいくつかあったので書き出しておきます。 あくまでも現時点のことです。今後実装される可能性もあります。\nデフォルトでは、searchのtermに渡した文字列をtokenizeし、出力されたトークン列(単語の配列)のそれぞれのトークン(単語)にヒットしたドキュメントが全て検索結果に含まれます。 検索結果のドキュメントはBM25でスコアリングされるので、多くのトークンが含まれるものが上位に来る可能性が高いです。\nただ、特定の単語を含まない検索、ANDやOR検索など凝ったクエリは現在は書けないようです(Issueがある)。\nfilterは別途用意されているので、例えばファセットで表示したカテゴリで絞り込んだ状態にするといったことはできそうです。\n残課題 とりあえず日本語をなんとなく検索できるようにすることはできました。 が、気になることもいっぱいありました。 時間を見つけてTypeScriptなどを勉強しながら探っていく感じでしょうか。\nインデックスを小さくする方法 今回はブログ記事のサマリー(Hugoで生成されるSummary)でインデックスを作ったので、インデックスのサイズはまだ小さくなっています(といっても1MB超えてるけど)。ブログ記事全体を検索できるようにする場合は、インデックスファイルが大きくなります。\nこれは、OramaがデフォルトではインデックスしたJSON自体もインデックス(ドキュメントストア)に保存しているためです。 ですので、Oramaに登録したJSONデータ+検索用のインデックスがインデックスファイルとなります。 ただ、検索だけができればよい場合は、出来上がったインデックスがあればドキュメントのIDは取得できます。\n公式ドキュメントでもそのことに触れているページがあります(参考:Remote document storing)。\nまだちゃんと実装を見ていませんが、ブログ記事本体の文字列はドキュメントストアに保存しないようにすれば検索はできるが、容量が大きくならないといった工夫ができそうです。\nただ、検索結果にハイライトを含んだスニペットを表示したい場合は、コンテンツ文字列が必要になってくるので、代わりに何かしらの仕組みを考える必要が出てきます(例えばサマリー部分の文字列だけ保存しておいて、ハイライトはそこだけを対象とするなど)。\nそのほか そのほかに思いつくのはこの辺でしょうか?\nオートコンプリート:Oramaというよりも、JavaScriptやTypeScriptでうまく実装できるのか?という話のような気がしますが。。。 ファセット対応:機能としては存在していますが、今回は実装が間に合いませんでした。 Vector Search:検索キーワードのベクトルをどうやって作るのか?という問題が残りそう。コンテンツのベクトルだけで関連ページの表示みたいなことはできるかも?(動的にやる必要がないので、事前計算して各ページに埋め込むほうがよさそうだけど) Geo Search:緯度経度があるデータを探し出してこないと? relevanceの処理の変更:BM25以外に切り替えることができるかどうか(Oramaのソースとにらめっこしないといけなそう) tokenizeの改良:辞書を利用する形態素解析ライブラリやAPIを利用してみたり、「てにをは」といった1文字のひらがなを削ることで、無駄な検索ヒットを減らしてみたり。大文字小文字の正規化も必要。 検索ログの解析:検索ログを保存する仕組みなどはないので、Google AnalyticsやほかのAPIなどを用意する? まとめ ということで、Oramaという検索エンジン?ライブラリ?を利用して日本語のブログ検索を実装してみました。 まだ、機能が少ない部分もありますが、少数のデータをブラウザだけで簡単に検索できる仕組みをGitHub Pagesだけで提供することができそうです。 今回は静的なファイルだけで完結する形にしましたが、TypeScriptで利用できる簡単な検索エンジンライブラリとして使ってみるとまた別の面白さもあるかもしれないです。 まだ触っていない機能は思いついたこと(=残課題に書いたこと)もあるので、ちょっと試行錯誤してみようかなぁ。\n","date":1702566000,"dir":"post/2023/","id":"476e17b6f854414033d5cec1470774ee","lang":"ja","lastmod":1702566000,"permalink":"https://blog.johtani.info/blog/2023/12/15/introduce-orama-to-blog/","publishdate":"2023-12-15T00:00:00+09:00","summary":"この記事は、情報検索・検索技術 Advent Calendar 2023の15日目の記事です。 昨年に続き2回目の情報検索のAdvent Calendar参戦です。 今年は、夏","tags":["orama","search"],"title":"Oramaという検索エンジンでブログ検索を作ってみた"},{"contents":"PySpaアドベントカレンダーの12/08のエントリーです。昨日は渋川さんのアンラーニングで失敗した話でした。\n私は、今年は昨年の続きっぽい話を。\n音楽の再生とか停止とか 今年もリモートで仕事を継続しています。 昨年、OwnToneという音楽サーバーを導入しましたが、ミーティング開始時や終了後に音楽の停止や再生をするのに、ブラウザで操作するのはちょっと面倒です。 加えて、ミーティングする際には実際には\n音楽を止める 電気をつける といったことをっやります。 音楽再生についても\n音楽を再生する アンプの音は音楽再生用の音量にする といった複数のことを行います。\n基本的にPCの前にいるし、Slackを常に開いているからSlackのBotを作ると便利になるのでは? ということで、自分専用のSlack Botを作ってみました。\nGitHubリポジトリ 全く誰の役にも立たないけど、公開しています。\nhttps://github.com/johtani/smarthome Goで実装 知り合いに勧められたということもあり、Goをあまり触ったことがなかったので、Goでやってみました。時々新しい言語を触ってみたくなるので。。。\nコマンドパターンのような作りで、コマンド(操作)を増やしていく感じで実装してはみたのですが、この書き方がいいのかはまだよくわかっていないです。\nActionという単体の操作(例:OwnToneの一時停止)を、操作したい機器の操作ごとに作成しています。 インターフェースとしてはRunだけを定義しています。\ntype Action interface { Run() (string, error) } それらの操作(Action)をひとまとめにしたものをSubcommandという形で定義して、SlackのBotにはSubcommandの名前を送って処理を実行する形にしています。\ntype Subcommand struct { Definition actions []action.Action ignoreError bool } やりたいことを追加するタイミングで時々リファクタしたりもしていますが、基本はこんな感じです。 細かな実装はさておき、今回ボットを作るときの観点をいくつか。\n宅内ネットワーク 音楽サーバーのOwnToneもですが、YAMAHAのアンプのAPIも見つけたのでこれらの操作をボットから行っています。どちらも自宅のネットワークにあるので、今回作成したボットも同じネットワークで動作します。\n外部に公開されたHTTPのエンドポイントがあればよいのですが、今回は用意していません。 SlackのAPIではこれに対応したアプリを作るときのためにSocket Modeを用意してくれています。\nドキュメントがしっかりしているのもあり、チュートリアルなどを見つつ特に迷うことなく構築できました。\n基本的には「特定のチャンネルでボットがメンションされたら動作する」という挙動だけしか実装していないので、特に今回はこれで困ることもありませんでした(世の中の人たちはもっとすごいSlackの使い方をしていそうだけど。。。)。\n対象となるものたち ボットから操作しているのは今のところ3種類です。\nSwitchBot OwnTone YAMAHAのアンプ SwitchBot SwitchBotについては、go-siwtchbotを利用しています。 電気、エアコン、空気清浄機、サーキュレーターのオンオフをSwitchBot経由でやっています。\n室内灯の明るさのために、SwitchBot側でシーンを設定している(一番暗い明るさで電気をつける)ので、そこが少しと特殊でしょうか?\nあとは、SwitchBotの温湿度計を3つ(室内2つ、室外1つ)おいてあるので、これらの温度を表示するコマンドも用意しました。\nそれぞれの機器の電池残量(電池の絵文字の右側)を表示してます(書斎が2つあるように見えますが、温湿度計の名前なので、同じ部屋においてあります。。。温度が高いほうがデスクトップPCの近くにある)。 防水の温湿度計があるので、外の気温もわかるのは便利です。\nOwnTone JSONのAPIが用意されていますが、特にクライアントライブラリなどは用意されていません。 今回は、用意されているAPIのごく一部だけを利用するので、net/httpのClientでJSONを投げています。 必要になったらowntone/clientにメソッドを追加していく感じです。\nhttps://github.com/johtani/smarthome/blob/master/subcommand/action/owntone/client.go#L45 再生、一時停止、プレイリストの取得、音量指定あたりを実装しています。 音の出力先はAirPlay(次に出てくるYamahaのアンプ)になっています。\nあと、JSON APIのサンプルをChatGPTに渡して、「このJSONをレスポンスに受け取る処理をGoで書いてください」と聞いて処理を書いたりしました(細かいのはどう聞いたか覚えてないけど)。\nYAMAHAのアンプ ググって探してきましたが、利用しているYAMAHAのアンプにYXC(Yamaha Extented Control)と呼ばれるAPIが用意されていました。 PDFでAPIの仕様が公開されていたので、この資料とにらめっこしながら、必要そうなAPIを実行するクライアントを実装しました。 こちらは、OwnToneのAPIの処理をすでに書いた後だったので、それをもとに必要な実装を追加しただけです。\nちなみに、アンプの電源をONにするAPIは実装していません。\nOwnToneで音楽を再生する(AirPlayで信号が送られるみたい) シーン選択(Nintendo SwitchやPS5のシーンを用意している)のAPIを呼び出す という処理をすると自動で電源がONになりました。スタンバイしている状態でもAPIはリクエストを受け付ける状態になっているようです。 また、PS5のシーンを呼び出したら、PS5自体も起動するのが便利だったりします。HDMI経由で信号が飛んでるのかな? 「ミーティング開始」や「音楽停止」コマンドではアンプの電源をオフするAPIを呼び出すようにしています。\nタイポ対応 「入力間違いしちゃうんです、人間だもの。。。」\nということで、10月にタイポ対応の処理を入れてみました。 タイポ対応前の実装では、入力された文字列がコマンドの文字列と完全一致した場合にだけ、コマンドが実行される形になっていました。 結構タイポしちゃうので、完全一致で見つからない場合の処理として、入力された文字列とコマンド名のレーベンシュタイン距離が2以下のものを探し、その中で距離が一番小さな値のコマンドを実行する形にしてみました。 コマンド数はたかが知れているのでコマンドのリストを全部チェックする形にしています。 タイポするとこんな感じ。\nレーベンシュタイン距離の計算にはGo-edlibを利用しています。OSS便利ですね。\nやってよかったこと ミーティング開始時などのいくつかの手順が簡素化できたので満足しています。 SwitchBotの操作もスマホをわざわざ操作しなくてもいいですし(仕事してるとキーボードとSlackは常に使ってるし)。 また、副次的な効果として、部屋の外から電源を切り忘れていたり、エアコンの切り忘れなどの場合に、スマホから遠隔でまとめた処理ができるのが便利です。\n今後やってみたいこと こういうのがあるともうちょっと便利かもなぁ?というのもあるので今後も気が向いたらコマンドなどを追加していく予定です。 今のところこんなことやりたいなというのがいくつかあります。\nキーワードに関連する曲の再生 OwnTone自体に検索の仕組みがついているので、キーワードを受け付けてそれに関する曲を流す Flexispotの操作 ミーティングの時は立ち上がっているので、机をスタンディングの状態にしたい 電子工作しないとだめかも? Webカメラ用ライトの点灯 ミーティング時に明かりが必要なのですが、物理スイッチのOn/Off これも電子工作かな? 定期的に温度をBotに表示させるとと面白いかも? まとめ ということで、新しいプログラミング言語にも触れたし、作業環境も便利になって一石二鳥でした。 新しいプログラミング言語触るのはやっぱたのしいですね。\n","date":1701961200,"dir":"post/2023/","id":"516a7aa07f8faa6b7aa38beb5010cf8c","lang":"ja","lastmod":1701961200,"permalink":"https://blog.johtani.info/blog/2023/12/08/smarthome-bot/","publishdate":"2023-12-08T00:00:00+09:00","summary":"PySpaアドベントカレンダーの12/08のエントリーです。昨日は渋川さんのアンラーニングで失敗した話でした。 私は、今年は昨年の続きっぽい話","tags":["misc","music","bot"],"title":"GoでSlackのボットを作った話"},{"contents":"「機械学習による検索ランキング改善ガイド」を読みました。\n著者の鈴木さんより献本いただいたのを読み終わったのでレビューと、あとおまけです。\n紹介とレビュー どんな本なのか?は打田さんが書かれたブログ、「ブックレビュー:『機械学習による検索ランキング改善ガイド』 - Tomoko Uchida - Medium」に詳しく書かれているので、そちらも参考にしてもらうほうがわかりやすいと思います(丸投げ)。\n読みながらいくつかツイートしていたので、そちらも参考のために貼っておきいます。\nオライリーの検索ランキング本、負荷テストのことも書いてある、すごいhttps://t.co/YPnB6kxFY2\n\u0026mdash; Jun Ohtani (@johtani) August 28, 2023 私のレビュー わかりやすく検索の基本を紹介しつつ、本書のメインであるランキング改善について全体の流れが書かれています。 ランキング改善のやり方といっても、手法の話だけではなく、プロジェクトとしてどの様に進めていくべきなのか?また、関係するものはどんなものがあり(システムだけではなくチームについても書かれていたり)、どういう判断をもちながら運用していくのか?、負荷テストにまで言及されています。\n読んでいて特に私が気に入ったのは以下のような話でした\nランキング改善を進める前にきちんと解ける問題なのか?それ以前にやることはないのかを考えましょう マッチング改善についても少しだけ触れられているが、メインはランキングについてだと明記されている 実際に体験されたのであろう落とし穴の話 負荷テストについて1章設けてある! ハンズオンのパートでもレイテンシの話がされている 付録としてベクトル検索についても触れてある 日本語でまとまって読める本があるのは本当に幸せですよね。\nおまけ 書籍ではハンズオンで、Elasticsearchとランキング学習のプラグインであるelasticsearch-learning-to-rankを利用しています(GitHubにサンプルが公開されています)。 書籍ではElasticsearchが7.13.4、プラグインが1.5.7-es7.13.4というバージョンになっていました。\nブログを書いている時点でのElasticsearchは8.x系になっています。せっかくなので、書籍を読みながら現時点で最新のものに置き換えてみるというのをやってみました。\nElasticsearchは8.10.2が最新なのですが、ランキング学習のプラグインはサードパティ製で、1.5.8-es8.8.2が最新版となっています。 ハンズオンのサンプルコードをフォークして、以下の構成にして動くようにしてみました。\nElasticsearch : 8.8.2 learning-to-rankプラグイン : 1.5.8-es8.8.2 Kibana : 8.8.2 Python : 3.10 Elasticsearch、プラグイン、Kibanaのアップグレード Elastic社が提供しているDockerイメージが利用されているので、バージョン番号を書き換えました。 あとは、learning-to-rankプラグインのバージョンを書き換えるついでに、elasticsearch-pluginコマンドで直接ダウンロードさせる形に書き換えました。\nhttps://github.com/johtani/building-search-app-w-ml/blob/es8/part2/app/search-engine/Dockerfile\nPython3.10にアップグレード 本当は必要なかったのですが、Pythonのイメージもついでに3.10にしました。 ただ、このおかげでインストールされるXGBoostのバージョンも1系から2系に上がってしまい、XGBoostを利用してモデル生成をする処理でエラーが出るようになってしまいました。。。\n2系へのアップグレードは手間がかかりそうだということで、pipコマンドでのインストールでのバージョンを\u0026lt;2として、1系をインストールすることで回避しました。\nhttps://github.com/johtani/building-search-app-w-ml/blob/es8/part2/app/workspace/Dockerfile\nelasticsearch-pyのアップグレード Elasticsearchを8系にしたので、クライアントライブラリ側も8系に書き換えました(元は7.17以下に固定されていた)。 pipで7系に固定されていたものを外して最新のもの(8系)をインストールするようにしました。 これだけでも特に問題なく動いたのですが、「DeprecationWarning」が出ている部分が1か所だけあります(サンプルではDeprecationWarningが出力されない形になっていましたが、出力するように変更しました)。\nElastic公式のドキュメントにMigrate to 8.0というページが公開されています。Pythonクライアントのアップグレードを行う際はこちらを参考にすると指針が記載されています。\n今回のサンプルコードではsearchの時の引数としてbodyを渡していたのですが、8系のクライアントライブラリからこちらが廃止になり、queryやrescoreなど個別の引数を渡す形に変更されています(search APIのリファレンス)。 ですので、bodyを**bodyでアンパックして渡すようにしただけです。サンプルコードがわかりやすく書かれているので変更も少しで済みました。\nhttps://github.com/johtani/building-search-app-w-ml/blob/es8/part2/app/workspace/collect_responses.py#L59\n一応、これでエラーが出ないで動きました。 すべて適用した、フォークして修正したブランチはhttps://github.com/johtani/building-search-app-w-ml/tree/es8で公開しています。\nまとめ すごくわかりやすいうえに、手を動かしながらどんなデータを使ってどんなことをやるのかが体験できる良い本でした。 理論的な話だけでなく、システムとしてどういうものが必要で、どういうことをやらないといけないのか?というのがわかるのがイメージできるのは重要だと思います。\n最後は広告ですが、ランキング改善以外の検索システムについて学べる本を検索システム ― 実務者のための開発改善ガイドブック – 技術書出版と販売のラムダノート出していますので、こちらも参考書として読んでいただけるとうれしいです。\n","date":1695612744,"dir":"post/2023/","id":"7f78b02c531f09602ba4e140132d26a2","lang":"ja","lastmod":1695612744,"permalink":"https://blog.johtani.info/blog/2023/09/25/read-search-raking-guide/","publishdate":"2023-09-25T03:32:24Z","summary":"「機械学習による検索ランキング改善ガイド」を読みました。 著者の鈴木さんより献本いただいたのを読み終わったのでレビューと、あとおまけです。 紹介","tags":["読書","elasticsearch"],"title":"機械学習による検索ランキング改善ガイドを読みました"},{"contents":"趣味?(検索エンジンに関する趣味プロジェクト)でPythonのプログラムを書いています。 ベクトル検索などの確認なども含めて、Jupyter Notebookで簡単なAPIの呼び出しを書いていましたが、検索はやはり画面があるほうがにぎやかでいいですよね。 ということで、画面周りで調べものをしていた時のことを後日の自分のためのメモとして残しておきます。\nSearch UIとSearchkit ということで、それほど手がかからないで検索の画面をサクッと作る方法がないか?ということでちょっとだけ探してみました。 最初にElasticsearchを利用していることもあり、すぐに検索の画面を作れるライブラリ・フレームワーク・コンポーネントがないかな?ということで思いついたのが次の2つでした。\nElastic Search UI Searchkit どちらも直接Elasticsearchに接続して検索をすることができるコンポーネントです。 Elasticsearchだけで完結していればそれでおしまいだったのですが、今回はバックエンド経由でElasticsearchに検索を書ける必要があります(ベクトル検索の仕組みもデモをしたいため、クエリの文字列をLLMなどでベクトルにしてからknn検索をすることになります)。\nSearch UIの構成 もともとSearch UIはElasticのApp SearchのGUI構築向けのコンポーネントとして作られました。 最近になって、直接Elasticsearchに接続できるコネクターを提供しています(ベータだけど)。 このコネクターを利用した場合は、ざっくりですが、このような流れになります。\nまた、Search UIはCustom Connectorの仕組みも用意しており(ConnectorのAPIが宣言されているのでそのAPIで独自実装が可能)、これを利用することで、ブラウザではなくバックエンド(Node)でElasticsearch Connectorを利用するような構成も取れるようになっています。\n改めて要件をまとめると ということで、やりたいことは\n簡単にUIが作れる バックエンドはPythonを経由して検索したい となります。 Searchkitも調べようかと思いましたが、いったんはSearch UIのCustom ConnectorでPythonでFastAPIでバックエンドのAPIを実装して、Search UIの想定しているリクエスト・レスポンスに変換すればいいかな?ということにしました。\nとりあえずSearch UI+Custom Connectorからのリクエスト・レスポンス(フロントからバックエンドへの出入りの部分)を記録し、 Search UI+Elasticsearch Connectorのときのリクエスト・レスポンス(バックエンドからEsへのの出入りの部分)も記録して、 参考にしながらバックエンドを実装しようと試みました。 Search UIのCustom Connectorのサンプルとなっていた、Node上でElasticsearch Connectorを動かしている部分をPythonで簡単に再実装しようという試みです(まったく同じ実装にする必要はなく、必要最低限の機能(検索窓、ファセット、ページング)が動作するところを目指します)。\nElasticsearch API connectorの調査 方針が決まったので、Search UIがElasticsearch API Connectorに渡しているリクエストをブラウザのデバッグ機能を使って追いかけてみると。。。 内部でSearchkitを読んでいる??ことがわかりました。\nElasticsearch API Connectorがリクエストを変換しているのかと思っていたのですが、実は内部にもう一段変換が行われていました。\n方針を決めたつもりが、Searchkitが出てきてしまったので、Searchkitも調べてみることに。。。 なお、Search UIにElasticsearch API Connectorを導入したのがどうやら、Searchkitの作者で、現在はElasticのエンジニアになられているようです。\nSearchkitとは? Search UIが利用しているSearchkitは、3.0ですが、Searchkit本家のリポジトリを見ると4.x.0となっています。\nどうして新しいものをSearch UIで使っていないのかな?と思いつつ調べてみたところ、Searchkit V4のブログを発見しました。\nSearchkit V4 integrates with Algolia’s Instantsearch library, which is a Search UI library built by Algolia. Instantsearch is an amazing library, and it’s been used by many companies and supports many frameworks like React, Vue and Angular. ブログより引用\nどうやら、V4ではコンセプトをガラッと変更されたようで、Algoliaがオープンソースとして開発しているInstantSearchのコネクター(アダプター)としてSearchkit V4を開発しているようです。 これは最近出てきている検索エンジンのTypesenseやMeilisearchの戦略にもなっています。\nなお、SearchkitのGitHubリポジトリやSearch UIのリポジトリを見ていると、Search UIの開発(およびSearchkitの3系)は現在は活発に行われていないように見えました。 Searchkit V4はちょっとずつ開発が進んでいるようです。\nまとめ? 一応Searchkit V4の現状やInstantSearchもすこしだけ見てみたのですが、今回の私のプロジェクトでは検索画面はまだそこまで重要度は高くないので、いったん調べていたSearch UI+Pythonのバックエンドの構成で動作する最小限を実装したところで終わりにしました。 なので、Searchkit V4+InstantSearchの構成はまた今度という感じです。\nなお、Search UIの方は5月からコミットがされていないようです。どうも開発しているチームが別件で忙しそうだなというのを感じました。\n","date":1692768764,"dir":"post/2023/","id":"8f58cbe5f2ce85c22569af765de3f8d3","lang":"ja","lastmod":1692768764,"permalink":"https://blog.johtani.info/blog/2023/08/23/search-ui-and-searchkit/","publishdate":"2023-08-23T05:32:44Z","summary":"趣味?(検索エンジンに関する趣味プロジェクト)でPythonのプログラムを書いています。 ベクトル検索などの確認なども含めて、Jupyter N","tags":["searchkit","search-ui","画面"],"title":"search-UIとSearchkitと検索画面"},{"contents":"いくつかある環境をDev Containerで動くように変えていますが、最初に導入した時に疑問点だった「コンテナ名」について解消したのでメモを残しておきます。\nコンテナ名の指定 最初のDev Container導入の記事で、起動したコンテナの名前が自動で付与されて、ランダムに変わるという疑問点を書いていました。\ndocker-compose.yml対応の記事ではdocker-compose.ymlを利用すると、コンテナ名はファイル内で定義されたサービス名で起動されて見やすくなると気づきました。\nやはり、Dev Containerでイメージを指定している場合もわかりやすいコンテナ名がいいなと思ったところで、「runArgs」を思い出しました。 Dev Containerからコンテナを起動するときに渡す引数が書けるじゃないですか。そういえば、むかしdockerコマンドを使う時に名前を指定した記憶があったなと。ということで、Google検索です。「docker command args container name」で検索しましたw\n--nameというオプションで起動時のコンテナの名前の指定ができます。ということで、このブログを生成するためのdevcontainer.jsonに\u0026quot;runArgs\u0026quot;でコンテナ名を指定してコンテナ起動ができるようになりました(「ブログ記述環境としてのDev Container」という記事のdevcontainer.jsonにrunArgsの行を追加しただけ)。\n{ \u0026#34;name\u0026#34;: \u0026#34;Hugo - blog generator\u0026#34;, \u0026#34;image\u0026#34;: \u0026#34;mcr.microsoft.com/devcontainers/javascript-node:16\u0026#34;, \u0026#34;runArgs\u0026#34;: [\u0026#34;--name\u0026#34;, \u0026#34;blog_generator\u0026#34;], \u0026#34;postCreateCommand\u0026#34;: \u0026#34;/bin/sh ./.devcontainer/postCreateCommand.sh\u0026#34;, ... ","date":1690420969,"dir":"post/2023/","id":"f9e847ee886bdb9ab5583eeb6eabbd51","lang":"ja","lastmod":1690420969,"permalink":"https://blog.johtani.info/blog/2023/07/27/container-name-in-devcontainer/","publishdate":"2023-07-27T01:22:49Z","summary":"いくつかある環境をDev Containerで動くように変えていますが、最初に導入した時に疑問点だった「コンテナ名」について解消したのでメモを","tags":["dev container"],"title":"VS CodeとDev Container(コンテナ名の指定)"},{"contents":"このブログの生成には、Hugoを利用しています。 ブログ移行日記(その1)に書いてありますが、当時はbrewでインストールしていました。 また、Windowsに移行したタイミングで、WSL2のUbuntuにaptでhugoをインストールして利用していました。 WSL2の環境が壊れなければこのままでもいいのですが、最近Dev Containerを触っていたので、このブログを書く環境(おもにHugo)もDev Containerにできるのでは?と気づきました。\nということで、Hugo+αの環境をDev Container化したので、そのメモです。\n必要なもの ブログを書いて、記事を構築して、公開するところまでに利用するのは次のようなものです。\ngit Hugo node atomic-algolia GitHubのプライベートリポジトリでHugoのプロジェクトを管理しています。 また、GitHub Pagesで公開しており、生成したHTMLもgitコマンドを利用してGitHubにpushしています。 このため、gitコマンドが必要です。\nコンテンツの生成はHugoコマンドを利用します(テーマの適用とかいろいろ)。\nあと、Algoliaでブログを検索できるようにしており(ブログ移行日記(その4)参照)、Algoliaへドキュメントのデータをアップロードするために、atomic-algoliaを利用しています。こちらは、nodeのモジュールであるので、nodeの環境も必要です。\nベースにするイメージ Dev Container Templatesというリポジトリが公開されています。 こちらを探すと、元となるdevcontainer.jsonが見つかることがあります。 Hugoのものがあるか探してみましたが、残念ながら見つかったのはJekyllのテンプレートでした。 今回は、nodeの環境が必要なのでjavascript-nodeを元に編集していきます。\n手元のUbuntuのnodeのバージョンが16だったので、バージョン16のイメージを指定します(devcontainer.jsonは後述)。\nHugoの追加 Hugoのテンプレートはなかったのですが、Dev Container FeaturesにHugoのfeatureが用意されていました。 featuresに1行追加するだけでコンテナにHugoをインストールしてくれる便利ものです。\nMarkdownの環境 Dev Container Templatesを探索していて見つけたMarkdownのテンプレートも参考にしてみました。 VS CodeのMarkdown向けの拡張機能がいくつかリストアップされていたので、ついでに追加です。 markdown-all-in-oneやmarkdownlintはこれまでも利用していたので、他のものも便利だろうということで。 他の物はどんなものかを後で調べてみる予定です。\n作った.devcontainerの設定はこちら ということで、出来上がった設定は以下の通りです。\ndevcontainer.json { \u0026#34;name\u0026#34;: \u0026#34;Hugo - blog generator\u0026#34;, \u0026#34;image\u0026#34;: \u0026#34;mcr.microsoft.com/devcontainers/javascript-node:16\u0026#34;, \u0026#34;postCreateCommand\u0026#34;: \u0026#34;/bin/sh ./.devcontainer/postCreateCommand.sh\u0026#34;, \u0026#34;features\u0026#34;: { \u0026#34;ghcr.io/devcontainers/features/hugo:1\u0026#34;: {} }, \u0026#34;customizations\u0026#34;: { \u0026#34;vscode\u0026#34;: { \u0026#34;extensions\u0026#34;: [ \u0026#34;yzhang.markdown-all-in-one\u0026#34;, \u0026#34;streetsidesoftware.code-spell-checker\u0026#34;, \u0026#34;DavidAnson.vscode-markdownlint\u0026#34;, \u0026#34;shd101wyy.markdown-preview-enhanced\u0026#34;, \u0026#34;bierner.github-markdown-preview\u0026#34; ] } } } postCreateCommand.shでは、npm installで、必要なモジュールのインストールをコンテナビルド後に実行できるようにしました。 (apt updateはなくてもいいな)\npostCreateCommand.sh #!/bin/sh # postCreateCommand.sh echo \u0026#34;START Install\u0026#34; sudo apt update sudo chown -R vscode:vscode . npm install echo \u0026#34;FINISH Install\u0026#34; まとめ ということで、ここ最近Dev Containerについて色々調べていたのでサクッとDev Container化ができました。 まぁ、HugoのFeatureが用意されていて、他に大したことをやっていないというのが大きいのですが。 このブログは今回構築したDev Containerで生成して公開した記事になります。\n","date":1690189832,"dir":"post/2023/","id":"7884b62c561b999b9358d52779a18218","lang":"ja","lastmod":1690189832,"permalink":"https://blog.johtani.info/blog/2023/07/24/introduce-dev-container-to-hugo-env/","publishdate":"2023-07-24T09:10:32Z","summary":"このブログの生成には、Hugoを利用しています。 ブログ移行日記(その1)に書いてありますが、当時はbrewでインストールしていました。 また、","tags":["hugo","dev container"],"title":"ブログ記述環境としてのDev Container"},{"contents":"WSL2にUbuntuを入れて、開発とかはこちらを利用しています。 また、Docker DesktopもWSL2のバックエンドエンジンを利用しています。\n知り合いとの話で、Ubuntuの外付けのSSDをマウントしたという話が出てきて、それだと遅くない?Ubuntu自体を移動できるんじゃないかな?という 流れになりました。 知り合いは、特に移動とかは考えてなかったのですが、自分のディスクの容量が今どのくらい使われているのかが気になり、調べてみると、 Cドライブの使用率が90%を超えてるじゃないですか。\nWizTreeというソフトを前回入れていたのを思い出して、再度調べてみたところUbuntuらしきvhdxファイルのサイズが171GB、Docker Desktopのデータ領域のvhdxファイルのサイズが81GBと、結構な割合です。\n前回は、Hyper-V管理ツールで仮想ディスクの圧縮処理を行ったのですが、Dドライブに移行したほうが安心できそうな気がしたので、移動の方法を調べました。\nWSLコマンドのドキュメントが公式で公開されています。こちらのコマンドを元に作業をしました。 また、ググって出てきた記事も参考にさせていただきました。ありがとうございます。\nwsl をDドライブに入れ直してディスク拡張する | blog.ojisan.io WSL2環境をコピー(複製)する方法 - Qiita まずは確認と停止 WSL2で使っているディストリビューションを確認します。コマンドは以下の通り。 実行した結果も含まれています。コマンドの実行にはコマンドプロンプトを使用しました。公式ドキュメントのドキュメントではスニペットはPower Shellと書かれてますが、コマンドプロンプトでも大丈夫そうでした。\nD:\\\u0026gt;wsl -l -v NAME STATE VERSION * Ubuntu Running 2 docker-desktop Running 2 docker-desktop-data Running 2 残念ながら、wslのコマンドでは実体がどこにあるのかを調べることができなかったですが、WizTreeでディレクトリ名などを見ていたのでなんとなう予測ができました。 (これ、他に知る方法あるのかなぁ?)\nディストリビューションの移動は次のような手順になります。\nwslのshutdown エクスポート(ディストリビューションのコピー) 今あるディストリビューションを削除 インポート(今ある名前で2.のファイルをインポート) まずは停止です。これをやらないとエクスポートができないので。\nD:\\\u0026gt;wsl --shutdown エクスポート 次にエクスポートです。 今回は以下の2種類の仮想環境をエクスポートします。\nUbuntu docker-desktop-data エクスポートでは、元のディストリビューションのファイル(Cドライブにあるファイル)が消えることはありません。 また、エクスポートの形式として、tarとvhdxの2種類が指定できます。 エクスポートのコマンドのデフォルトはtar形式ですが、エクスポート元のファイルがvhdxなので、vhdxでエクスポートしたほうがCPUにやさしかったです。 ちなみに、docker-desktop-dataはtar形式でエクスポートしてインポートしました。tar形式の場合は、ディスクのサイズが小さくなる可能性があるみたいです(不要なデータがvhdxの中に残っていたりする影響かと)。\nコマンドは以下の通りです(詳細は公式ドキュメントを参照してください)。出力ディレクトリはあらかじめ作っておきました(作ってない場合の挙動は未確認です。)\nD:\\\u0026gt;wsl --export Ubuntu .\\wsl\\Ubuntu\\ext4.vhdx --vhd docker-desktop-dataはtar形式です。\nD:\\\u0026gt;wsl --export docker-desktop-data .\\Docker\\ docker-desktop-data.tar ディストリビューションの削除(こわい?) 今ついているディストリビューション名を利用したいので、いったん、Cドライブ上にあるディストリビューションを削除する必要があります。 コマンドは公式ドキュメントにある--unregisterオプションを利用します。 以下のコマンドはUbuntuですが、docker-desktop-dataもやりました。\nD:\\\u0026gt;wsl --unregister Ubuntu ちなみに、このコマンドを実行すると、Cドライブの容量がいきなり空きました。 コマンドいっぱつでなくなりました。きちんとエクスポートしてから実行しましょう。 (なんなら、一度、別名でインポートして動作確認するのもいいかもしれないです。私はしましたw)\nインポート インポートするオプションも2種類あります。vhdxファイルの場合は、インプレースでのインポート(vhdxファイルをそのまま利用する形式)が可能です。 Ubuntuについてはこちらを利用しました。この場合、vhdxファイルがそのまま利用されるため、バックアップとしては利用できなくなります。今回は170GBもあるので、これでいいかと。\nD:\\\u0026gt;wsl --import-in-place Ubuntu .\\wsl\\Ubuntu\\ext4.vhdx tarファイル(docker-desktop-data)の場合は、通常のインポートを行いました。\nwsl --import docker-desktop-data D:\\Docker\\docker-desktop-data\\ D:\\Docker\\docker-desktop-data.tar この場合、tarファイルは残ったままで、新たにD:\\Docker\\docker-desktop-data\\ディレクトリにext4.vhdxファイルが作られました。 バックアップも取りつつ移行したい場合は--importがいいかもしれません。 また、WSLはバージョン1とバージョン2があり、インポートの際にこの部分も気にする必要があるようです。 今回はすべてバージョン2で、かつ、wslのデフォルトのバージョンを2にしてあったので特に意識していません。\nUbuntu起動ユーザーの指定と注意点 公式ドキュメントに、既存のユーザーを変更するコマンドの記載があります。 インポートしたディストリビューションは、デフォルトユーザーがrootになっていることがあるようなので、Ubuntuのユーザーを次のようなコマンドで変更しました。\nubuntu config --default-user johtani 公式ドキュメントの警告にもありますが、実行可能ランチャーがない場合があります。 今回のubuntuは、WSL2でUbuntuをインストールした時に作成されたコマンドで、unregisterした後にimportしてもきちんと動いたので問題にはなりませんでした。これは、インポートするときに、既存のディストリビューション名を利用したためと思われます。\nエクスポートやインポートの検証するために、NewUbuntuという名前で別途インポートした時には、NewUbuntuという実行可能ランチャーは作成されず、上記のデフォルトユーザーの設定は別の方法が必要になります(罠だ)\ndocker-desktop-dataのほうは、特に変更してないけど動いてそうだからいいのかな? 前の設定の確認とかやっておくのがいいんだろうな、本当は。。。\nまとめ ということで、Cドライブに300GB近い空きができて、心の余裕もできました。 今回は、同じPC内で別のドライブへの移動でしたが、他のPCにもこれで移行ができそうですね。 たまにはバックアップをとっておくのもいいのかも?と思いました(やるかどうかはまた別の話)\n","date":1690180128,"dir":"post/2023/","id":"ed431877ce11fe403fee77f7d26ce637","lang":"ja","lastmod":1690180128,"permalink":"https://blog.johtani.info/blog/2023/07/24/move-distribution-to-another-disk/","publishdate":"2023-07-24T06:28:48Z","summary":"WSL2にUbuntuを入れて、開発とかはこちらを利用しています。 また、Docker DesktopもWSL2のバックエンドエンジンを利用して","tags":["wsl","windows"],"title":"WSL2のディストリビューションの環境移行"},{"contents":"前回の記事で、VS Code+Dev Containerを導入しました。 残課題として「マルチコンテナ化」があるという話もしました。今回はDev Containerのdocker-compose.yml対応をした話をメモとして残しておきます。 実際、VS Code + Dev Containerに移行した後に、Esを起動してアプリからつなげるというのがうまくいかないというのがあったので対応がんばりました。。。\nDev Containerのdocker compose設定 この記事ではすでにdocker-compose.ymlが存在している状態の話をします。 変更する前は、devcontainer.jsonでベースのコンテナイメージの指定、マウントの設定などを行っていましたが、docker-compose.ymlにいくつかを移動しないといけません。 対応した時の作業の流れは以下のような感じです。\nワークスペース用のDockerfileの作成 docker-compose.ymlにワークスペース用のサービスを追加 devcontainer.jsonをdokcer-compose.ymlを利用する形に書き換え アプリでの接続文字列をlocalhostからdocker-compose.ymlのサービス名に変更 参考:対応した時のコミットです。差分などはこちらをごらんください。\ndevcontainerのリポジトリにPython+PostgreSQLのサンプルが公開されており、こちらを参考にしながら作業をしました。\n1. Dockerfileの作成 docker-compose.ymlだけでも完結するのかもしれないですが、いろいろやりたいことも出てくるかもしれないので別のファイルに切り出しました。 といっても、コンテナのイメージはdevcontainer.jsonに記述していたものを使っています。\nARG VARIANT=3.11-bookworm FROM mcr.microsoft.com/devcontainers/python:${VARIANT} ENV PYTHONUNBUFFERED 1 ENV TZ Asia/Tokyo TZはdevcontainer.jsonで指定していたものを、こちらに移行した形になります。 PYTHONUNBUFFEREDは参考にしたDockerfileの記載です。標準出力・エラーをバッファリングしない指定になっています。\n2. dokcer-compose.ymlにサービス追加 backendという名前のサービスをdevcontainer(VS Code)から接続するコンテナのサービス名にしています。\nservices: backend: build: context: . dockerfile: .devcontainer/Dockerfile init: true environment: - TZ=Asia/Tokyo command: sleep infinity volumes: - .:/workspace/search-research:cached - venv-search-research-backend:/workspace/search-research/.venv ... volumes: venv-search-research-backend: 1.で作成したDockerfileを利用します。docker-compose.ymlファイル自体は、プロジェクトのルートディレクトリに配置していますが、Dockerfileは.devcontainerディレクトリに入れたため、contextとdockerfileはこのような指定になっています。\ninitは、devcontainer.jsonで指定していた\u0026quot;runArgs\u0026quot;: [\u0026quot;--init\u0026quot;],の設定になります。\ncommandの部分は、コンテナが起動したままにしておくための設定です。\nvolumesでは2つのボリュームに関しての指定があります。 1つ目の/workspace...は、VS Codeがコンテナにプロジェクトをマウントする場所の指定です。 devcontainer.jsonだけを利用していた場合は意識していませんでしたが、/workspace/プロジェクト名というディレクトリにプロジェクトがマウントされていました。 docker-compose.ymlを利用する場合は、明示的に指定が必要です。 2つ目のvenv-...は.venvのディレクトリをコンテナの中だけのものにする設定を移植したものになります。 前回の記事ではコンテナIDをボリューム名に含めていましたが、こちらのほうがわかりやすいかと思い、プロジェクトの名前とサービス名をつけるようにしてみました。 Dev Containerで起動した場合はsearch-research_venv-search-research-backendという名前がついています(最初の部分はDev Containerがつけてるのかな?)\n3. dovcontainer.jsonの変更 devcountainer.jsonから呼び出すものの準備ができたので、devcontainer.jsonを書き換えます。 公式のドキュメントとしてDocker Compose向けのプロパティが紹介されています。 変更したものは次のような形です。\n{ \u0026#34;name\u0026#34;: \u0026#34;search-research\u0026#34;, \u0026#34;dockerComposeFile\u0026#34;: \u0026#34;../docker-compose.yml\u0026#34;, \u0026#34;service\u0026#34;: \u0026#34;backend\u0026#34;, \u0026#34;workspaceFolder\u0026#34;: \u0026#34;/workspace/search-research\u0026#34;, \u0026#34;postCreateCommand\u0026#34;: \u0026#34;/bin/sh ./.devcontainer/postCreateCommand.sh\u0026#34;, \u0026#34;customizations\u0026#34;: { ... dockerComposeFile : 利用するdocker-compose.ymlのファイルパス service:VS Codeが利用するワークスペース用のサービス名 workspaceFoldeer:VS Codeがコンテナに接続したときに開くフォルダのパス を指定します。これで、VS Codeでこのプロジェクトを開いた時に、Dev Containerがdocker-compose.ymlを使ってコンテナの起動(ビルドとか)を行ってくれます。\n4. アプリの接続文字列の書き換え こちらはおまけです。 PythonのアプリからElasticsearchに接続するときの文字列として、Dev Container化の前は、http://localhost:9200と指定をしていました。 Elasticsearch用のサービス(es)で、ポートフォワードをしていたためです。\nアプリ側もコンテナ化したので、Docker Composeが名前の解決をしてくれるので、http://es:9200という接続文字列で接続ができるようになりました。\nということで、ここまでで、VS Codeでプロジェクトを開くと、2つのコンテナ(backendとes)が起動してVS Code上でPythonアプリからEsへの接続ができるようになりました。\n追加の変更 参考のプルリクでは、上記まででしたがさらにいくつかの変更をそのあとやっています。\n起動するサービスの指定(開発だけするときはEsを起動したくない) devcontainer.jsonでrunServicesを使って指定できます(公式ドキュメント) GPUをコンテナから利用できるように devcontainer.jsonでfeaturesのnvidia-cudaを指定し、docker-compose.ymlでnvidiaのドライバーなどを設定することで対応しました。 nvidiaが公開しているcuda対応のコンテナイメージでもよかったのですが、こちらのほうが楽そうだったという理由です。featuresとコンテナのビルド、postCreateCommandの順序などはもうちょっと勉強しないといけない気がしています。 これらの対応はこちらのコミットで対応しています。\nGPUの対応は、私個人の環境はこれでいいのですが、複数の人がこのリポジトリを使う場合はどうやって切り替えたりするんだろう?という疑問が残っています。。。 今回はrinna/japanese-clipのモデルを使って、テキストからベクトルを生成する部分の処理のためにGPUを使いたいというモチベーションがあり、コンテナでもGPUを使えるようにしています(CPUだと時間がすごくかかる。。。)。\nサービス起動の新たな問題点 runServicesで起動するサービス名を指定したのはよかったのですが、Elasticsearchのサービスを起動して、データ登録や検索の確認を行おうと思った時に、EsのコンテナをVS Codeだけで起動する方法がまだわかっていません。。。 一度コンテナをビルドした後なら、「Remote Explorer」でOther Containerというくくりで表示され、右クリックで起動や停止ができそうなのだけど、新規サービスをdocker-compose.ymlに追加した場合は、自分でターミナルなどでコンテナのビルドをしないといけないかもしれないです。もうちょっと調べてみないとなぁ。\n副次的な効果 Docker Compose対応をしたことで、前回の記事での疑問点のうち、「コンテナ名」「VolumeのID」については懸念点がなくなりました。\n「コンテナ名」は、docker-compose.ymlのサービス名がコンテナ起動時に名前として利用されるため、Docker Desktopで見た時などの探しにくさはなくなりました。 ただ、「イメージ名」については、いまだに2つできています。「-uid」がつかないものの代わりに、search-research-backendというイメージが作られています。 ただし、実際に利用されるのは前回の記事に書いたようなvsc-search-research-bf04371c017c8d2f1dd5ad2529841b02e9ea1d1aaa4354c19edf53cef3f0c13b-uidという名前のイメージです。\n「VolumeのID」については、docker-compose.ymlのファイルで自分で名前をつけるようにしたので、コンテナのIDが利用されなくなったという次第です。 代わりに、プロジェクト名である「search-research」という名前を直接記述しているので、変数などで置き換えたほうがいいのかも?という気がしています。\nまとめ ということで、複数のコンテナを利用するプロジェクトでVS Code+Dev Container対応ができそうだということがわかりました。 ついでに、GPU対応もできたのでこれで、やっと他の検索エンジン対応などができる気がしています。 (その前にpre-commitを保存時にチェックする形に変更かなぁ) やりたいことからちょっとずつ外れている気もするけれど、新しいことを調べるのは楽しいですね。\n","date":1689902010,"dir":"post/2023/","id":"086b4fd5f77021a0a2aa6b0e90061486","lang":"ja","lastmod":1689902010,"permalink":"https://blog.johtani.info/blog/2023/07/21/multi-containers-with-dev-container/","publishdate":"2023-07-21T10:13:30+09:00","summary":"前回の記事で、VS Code+Dev Containerを導入しました。 残課題として「マルチコンテナ化」があるという話もしました。今回はDev C","tags":["python","dev container"],"title":"VS CodeとDev Container(docker-compose.yml対応)"},{"contents":"前回の記事で、pre-commitとPyCharmとWindowsの組み合わせで困っていることを書きました。 これについて、知り合いとチャットで話をしていて、それほどPyCharmにこだわりもないよなぁということになり、 であれば、ISIDのブログ(Dev Containerを使ってステップバイステップで作るPythonアプリケーション開発環境 - ISID テックブログ)を試してみるとすっきりするかもしれないとなり、Dev Container対応をブログを参考に行ってみました。\n順を追ってブログで説明されているので、どういう仕組みなのか、どの設定が何を意味しているのか?がとてもよくわかりやすくすんなり対応することができました。\nブログの手順をなぞっているところでいくつか固有の手順や疑問点が出てきたのでブログに書き記しておきます。 結果は、コミットしてあるものを見てください。\nブログとは違う手順 まずはISIDのブログとは違う点をいくつか。\n.venvはいったん削除 ブログでは新規のプロジェクトを作成していく過程で、コンテナ化した環境を作った後に.venvをDockerコンテナのボリュームにして、最後に仮想環境のPythonを生成していました。 私の場合は、すでにホストOS(実際にはWSL2のUbuntuだけど)で.venvのディレクトリを作成してある状態だったので、いったん削除する必要がありました。 すでに存在する.venvがbindマウントされてしまっている状態になるため、Dockerのボリュームとの整合性が取れなくなるようです。\nこの作業を行う前か、途中でDev Containerを停止した状態で、.venvを削除することで問題なくDockerのボリュームに仮想環境のPythonが登録されるようになります。\npostCreateCommand.shの呼び出し方 ファイルに実行権限がないと、実行権限エラーが出ました。 実行権限を与えるか、次のような記述で動くようになりました。 今は、ファイルに実行権限をつけるのではなく、次のような記述にしていますが、何か問題あるかな?\n\u0026#34;postCreateCommand\u0026#34;: \u0026#34;/bin/sh ./.devcontainer/postCreateCommand.sh\u0026#34;, 実際に動作しているログを見ると\n/bin/sh -c /bin/sh ./.devcontainer/postCreateCommand.sh\nとなっているので、少し気持ち悪いのだけれども。。。\npostCreateCommand.shの追加処理 今回Dev Containerを適用したプロジェクトでは、sentencepieceを利用します。 この、sentencepieceをpoetryがインストールするタイミングで、cmakeを要求してきました。 今回利用しているDocker Imageにはcmakeは含まれていないため、以下の処理を追加しています。\nsudo apt update sudo apt-get install cmake -y また、rinna/japanese-clipも利用しているのですが、こちらは、poetryで追加してインストールでは依存するパッケージがインストールされないため、pipコマンドを利用するようにしています。\npip install git+https://github.com/rinnakk/japanese-clip.git コンテナイメージを作った後にやりたいことを、自由にスクリプトで書けるのは便利ですね。\npre-commitのスクリプトの再生成 こちらも、既存の環境が残っているとPythonへのパスの違いの問題が出たので、作り直しました。 .git/hooks/pre-commitのファイルを削除し、pre-commit installをやったものをリポジトリにコミットしてあります。\n疑問点 作業をしていて疑問点もいくつか出てきたのでメモを残しておきます。ちなみに、これらの疑問について実際に調べるまでには至っていません。 時間を見て解決できればなぁと(できるのか?)。\nImageが2つ Dev Containerの設定を書いた後に、コンテナをビルドすると、Docker DesktopのImagesにイメージが出来上がります。 この時、イメージが2つできあがっています(なぜ?)。\nREPOSITORY TAG IMAGE ID CREATED SIZE vsc-search-research-bf04371c017c8d2f1dd5ad2529841b02e9ea1d1aaa4354c19edf53cef3f0c13b-features-uid latest 25c7e23416ec 3 days ago 1.69GB vsc-search-research-bf04371c017c8d2f1dd5ad2529841b02e9ea1d1aaa4354c19edf53cef3f0c13b-features latest fcf9eaeb2187 3 days ago 1.69GB こんな感じで、最後に-uidがついているかいないかの違いです。 実際にコンテナ起動時に利用されるのは-uidがついているものになります。 なぜ2つになっているのか、1つにする設定などがあるのか?といったところが気になるところです。\nContainerの名前 devcontainer.jsonの設定を書き換えて、コンテナをリビルドすると起動したコンテナの名前が自動で割り振られているようです。 今は、fervent_hopperとなっています。ランダムにつけられているようなのですが、名前を付ける方法はないのかなぁ?と。\ndevcontainer.jsonにはnameというプロパティもあるのですが、この値がどこで使われているのかはよくわかっていません。 Remote Explorerでコンテナの一覧が見えますが、ここでは、リポジトリ名が利用されているようです。\nVolumeのIDはどこから? devcontainer.jsonで次のような記述で、.venvのディレクトリようにDockerにボリュームを作っています。\n\u0026#34;mounts\u0026#34;: [ \u0026#34;source=venv-${devcontainerId},target=${containerWorkspaceFolder}/.venv,type=volume\u0026#34; ], 実際にコンテナでマウントされている情報を見ると\n/workspaces/search-research/.venv /var/lib/docker/volumes/venv-04emir9hi2caivtjunfe3l17452hkbb3hdut1qflbrn8n924ho5c/_data となっています。 04emir9hi2caivtjunfe3l17452hkbb3hdut1qflbrn8n924ho5cがdevcontainerIdに相当するのだとは思うのですが、誰がつけたものかなどがまだよくわかっていません。 もうちょっとわかりやすいものが使えるほうが嬉しいかも?と思っていたりします。 (複数Dev Containerを使い始めると、Docker Desktopで見ると、どのボリュームがどのDev Containerに紐づいているかがぱっと見ではわからない)\n.vscodeディレクトリどうしよう? たぶん、VS Codeを触っている過程で、何かの設定をしてしまったのだとは思うのですが、 .vscode/settings.jsonというファイルができており、次のような内容になっています。\n{ \u0026#34;git.ignoreLimitWarning\u0026#34;: true } 何か意味があるかも?ということで、コミットしてリポジトリに入れたのですが、いらないのかもしれないなぁと。\n残作業 とりあえず、VS CodeでPython環境ができて、VS CodeのTerminalでPythonのプログラムが実行できるのはわかった段階です。 いくつか、今後調べながらやる必要があるものが残っているのでメモとして残しておきます。\nマルチコンテナ化 今回Dev Containerに対応したプロジェクトでは、検索エンジンもDockerのコンテナとして起動して、Pythonのプログラムから接続したいと思っています。 となると、docker composeでいろいろと起動するほうがネットワークなどの設定も楽になるのでは?と思っているところです。 Dev Containerのテンプレートがいくつか用意されており、その中に「Python 3 \u0026amp; PostgreSQL (postgres)」というのを見つけたので、このあたりが参考になるのでは?と考えているところです。\npre-commitではなく、保存時にフォーマット pre-commit+localのコマンドも動くようにはなったのですが、保存時にフォーマットなどをかける設定もISIDのブログで記載がありました。 コミットしようとして、怒られるよりも、保存時に怒られたりするほうがいいかも?という気分になってきています。 どこまでが切り替え可能なのか?なども見ながら対応してみようかなと。\nもう少し開発してみて改善点を探っていく とりあえず動いたという段階です。 PyCharmとの違いがあるはずで(たとえば、git周りのGUIの違いとか)、そのあたりでどんな違いがあり、どんなものがあると嬉しいのか?といったものを調べる必要もあるかなと考えています。 TerminalでCtrl+rがうまく使えなかったり(Auto Hot Keyで検索のショートカットに割り当ててしまっているから。。。)などもあるので、この辺も調べていきたいなと。 Windows Terminalを使えたりするのかなぁ?\nまとめ さて、とりあえず、VS CodeでPythonのDev Container環境を作って動くところまでは来ました。 PyCharmを使いこなしていなかったのもあり、それほど違和感なく移行できるような気がしています。 調べることはまだまだあるし、プログラム書くつもりが、環境を整える方向に話がずれている気もしますが、まぁ面白いのでよしとするかなぁ。 いろいろまだまだ知らないことだらけです。。。\n","date":1689254123,"dir":"post/2023/","id":"a12474027c91fad5a861aa9919817d72","lang":"ja","lastmod":1689254123,"permalink":"https://blog.johtani.info/blog/2023/07/13/introduce-vs-code-and-dev-container/","publishdate":"2023-07-13T22:15:23+09:00","summary":"前回の記事で、pre-commitとPyCharmとWindowsの組み合わせで困っていることを書きました。 これについて、知り合いとチャット","tags":["python","dev container"],"title":"VS CodeとDev Containerの導入(まだ途中)"},{"contents":"最近、趣味(検索エンジンに関する趣味プロジェクト)でPythonのプログラムを書き始めました。\nきちんとPythonのプログラムをプロジェクトとして書いたことがないので、 Pythonのプロジェクトのディレクトリ構成などを手探りで進めているところです。 コードのフォーマットとかもやらないとなぁ?と知り合いのいるSlackでつぶやいたところ、gitのpre-commitフェーズでblackなどのフォーマットやスタイルを修正してくれるツールを実行する方法を教えてもらいました(PRまで送ってもらえたのでありがたい)。\nで、pre-commit周りの設定などを変えている段階で遭遇した問題点についてログを残しておこうと重いブログを書いています。 残念ながら現時点では解決してないんですけどね。。。\n手元の環境 簡単に環境を書いておくとこんな感じです。\nWindows上のPyCharmを開発で使用 プロジェクトのディレクトリはWSL2のUbuntu上 Python、gitはUbuntuのものを利用 プロジェクトのルートディレクトリにある.venvにvenvでPythonの仮想環境を作成してある 問題点 遭遇したpre-commitの問題点は次の通りです。\npre-commitの設定でrepo:localでローカルのプロジェクトにインストールしたコマンドを利用するように変更 すると、PyCharmでコミットすると、blackなどのコマンドが見つからない ターミナルでコミットするときはきちんと動作する 色々調べて試行錯誤した結果、現在はrepo:localでのローカルコマンドを使用する方法はあきらめました。 移行は、作業記録みたいなものです。どういう流れでpre-commitを取り込み、ローカルに切り替え、切り戻したかという話です。\npre-commitとpre-commit 最初に少し戸惑ったのは、pre-commitというツールとgitのpre-commitフックです。 gitのpre-commitのフックのために作られたPython製のpre-commitというツールがあります。\nこのPython製のツールを利用することで、プロジェクトに.pre-commit-config.yamlという設定ファイルを置けば設定に記述されたツールをgit commitのタイミングで実行してくれます。 実際には、pre-commitというツールの初期設定のタイミングでpre-commit installというコマンドを実行して .git/hooks/pre-commitというスクリプトが生成されます。 gitコマンドはcommitされた時に(commit前のフェーズ)でこのスクリプトを実行し、そこで.pre-commit-config.yamlが参照されています。\n.pre-commit-config.yamlの記述は次のようなものになります(最初にもらったPRより)。\nrepos: - repo: https://github.com/psf/black rev: 23.3.0 hooks: - id: black args: [\u0026#34;--line-length\u0026#34;, \u0026#34;120\u0026#34;, \u0026#34;.\u0026#34;] - repo: https://github.com/pycqa/flake8 rev: 6.0.0 hooks: - id: flake8 - repo: https://github.com/pycqa/isort rev: 5.12.0 hooks: - id: isort args: [\u0026#34;--profile\u0026#34;, \u0026#34;black\u0026#34;, \u0026#34;--filter-files\u0026#34;, \u0026#34;--multi-line\u0026#34;, \u0026#34;3\u0026#34;] - repo: https://github.com/pre-commit/mirrors-mypy rev: v1.4.1 hooks: - id: mypy 実際に、PRを取り込んで動かしてみたところ、blackなどが動いて行末のスーペースの除去や未使用のimportについて指摘をしてくれました。 便利だなと思ったのですが、ここで疑問が。\n今回は対象とするプロジェクトはpoetryで依存パッケージの管理を行っています。 今回、上記を動かすためにpoetryに追加されたものはpre-commitだけでした。 「あれ?blackとかはどこにあって、どうやって動いてるんだ?」という疑問が出てきます。 コンフィグファイルにはパスなどの記載をせず、それぞれのgithubリポジトリの記載とバージョンがあるからです。\npre-commitが使用するツールのインストール先 調べてみたところ、どうやらホームディレクトリにある.cache/pre-commitにblackなどのコマンドが見つかりました。 pre-commitツールが設定ファイルを基に、必要なコマンドをgithubからダウンロードしてきて実行時に利用しているようです。 pre-commitは便利なのだけど、せっかくPythonのプロジェクトだしそれぞれのツールはpoetryでpyproject.tomlでバージョンや設定を管理したほうがすっきりするのではないか?ということで、少し調べてみました。\n同じようなことを考えている方がブログを残していてくれました(Pythonレポジトリ用のpre-commit環境を整える)。 設定をpyproject.tomlに移行し、そのあと、ローカルのpetryでblackなどのコマンド類をインストールして利用する設定に書き換えています。 先人の肩に乗っかって、手元で同じようにpre-commitの設定ファイルのrepoをlocalに書き換えていき(その時のコミット)、ターミナルでpoetry run pre-commit run -aで動作確認できました。\nPyCharmでコミットしたらエラー ですが、実際に変更した状態でPyCharmからコミットしたら、コマンドが見つかりませんというエラーが出ます。。。 WSL2のターミナルでgit commitした場合は問題ありません。 どうして?となりますよね。。。。\n.git/hooks/pre-commitはPyCharm、ターミナルのどちらからも実行されています。 ですが、PyCharmではblackなどが見つからないというエラーが出ました。\n.git/hooks/pre-commitを見てみると、python実行するためのpythonのパスはプロジェクトにある.venv/bin/pythonを指定しています。 デバッグのために、このスクリプトにecho $PATHを差し込んで、git commitをPyCharmとターミナルからそれぞれ実行してみたところ、大きな違いがあります。\nターミナルで実行した場合は、\u0026lt;プロジェクトのディレクトリ\u0026gt;/.venv/binもPATH環境変数に存在していました。このため、.venv/binにあるblackなどを実行できています。\nPyCharmはWindowsから起動しています。プロジェクトのインタプリタとしては、WSL2のUbuntuにある.venv/bin/pythonを指定しているためもあり(?)、出力されたパスは/mnt/c/などのWindowsのパスなども入っていたりしますが、\u0026lt;プロジェクトのディレクトリ\u0026gt;/.venv/binは見つかりません。\nここからはソースコードは読んでいないので憶測ですが、.git/hooks/pre-commitで呼び出されているpre-commitツール(Python製)は、設定ファイルで指定されたコマンド(blackなど)を、コマンドとして今の呼び出されたコンテキストで実行しているのではないかということです。 実際、ターミナル上でもsource .venv/bin/activateを実行していない状態だとコマンドが見つからないというエラーが出ました。\n対処方法は? ということで、今考えられる対処方法としては次の通りです。\n.git/hooks/pre-commitのスクリプトを修正して、\u0026lt;プロジェクトのディレクトリ\u0026gt;/.venv/binのパスを見えるようにする PyCharmで何かしらの設定を探す PyCharmではgit操作しない repo:localはあきらめて、.pre-commit-config.yamlでblackなどは管理して、pyproject.tomlからは除外する 1.ですが、.git/hooks/pre-commitはprecommit intallを実行すると自動で生成されるスクリプトです。自分の環境で書き換えたとしても他の人が同じ環境を作るときにパッチを当てるなどをしないといけなくなります。\n2.はそれらしい設定を見つけることができませんでした。\n3.はめんどくさいですよね。。。ターミナルでgitのコメントを日本語で書くためにいくつか他の設定を考えないといけないです。。。\nということで、今回は4.の対処をとりました。やりたいことは、ツールや環境をそろえるのではなく、プロジェクトでやりたいことをやることなので。。。\nまとめ 最終的には元に戻ってしまいました(pyproject.tomlに設定周りは移動した)。 Windows環境がちょっとややこしくしてるかもな?というのと、個人のプロジェクトなのでそこまで気にしなくてもいいのでは?というのもありそうです。 それにしても、世の中の皆さんはフォーマッターとかどのタイミングで動かしてるんだろう?とかどういう環境構築してるんだろう?とか気になってます。 最近だとこういうディレクトリ構造にする、こういうツールを使うと便利などあれば、コメントいただけると嬉しいです。\n教えてもらったISIDのブログ(Dev Containerを使ってステップバイステップで作るPythonアプリケーション開発環境 - ISID テックブログ)も参考にさせてもらおうと思ってるところです。Pythonの環境をコンテナに移動したいなぁというのもあるので。ただ、PyCharmだからこのブログの通りには行かないけど(VS Codeに移るのも検討したほうがいいのかなぁ)。\n参考サイト Git - Git フック pre-commit Pythonレポジトリ用のpre-commit環境を整える Dev Containerを使ってステップバイステップで作るPythonアプリケーション開発環境 - ISID テックブログ ","date":1688954148,"dir":"post/2023/","id":"698cf3cbd796161d82c9ac438ebab5d2","lang":"ja","lastmod":1688954148,"permalink":"https://blog.johtani.info/blog/2023/07/10/pre-commit-and-python/","publishdate":"2023-07-10T10:55:48+09:00","summary":"最近、趣味(検索エンジンに関する趣味プロジェクト)でPythonのプログラムを書き始めました。 きちんとPythonのプログラムをプロジェクト","tags":["python"],"title":"pre-commitとvenvとPyCharm(困ったな?)"},{"contents":"今年もこの季節がやってきました。 Berlin Buzzwordsにオンラインで出張してました。 今年もハイブリッド開催をしてくれたので、オンラインで参加できました。 現地ではブースが出たり、朝食なども用意されているようでした。今年は昨年と違いマスク必須でもなくなったようです。 MICESも去年同様、現地開催のみのようです(今見たら、昨年のビデオとスライドが公開されてるので、時間見つけてみてみよう)。\n今年はうれしいことに検索に絡むセッションが大多数でした。世の中的にChatGPTの盛り上がりやベクトル検索がいろんな検索エンジンで使えるようになってきたこともあり、 大規模言語モデルと検索エンジン、ベクトルデータベースに関する話がたくさんありました(昨年まではKafkaやストリーム処理の話も多かったんですが)。\nということで、今年もセッションを見ながら残したメモを公開しておきます。\n簡単にメモ What defines the “open” in “open AI”? セッションページ:What defines the “open” in “open AI”? 動画: Jennifer Ding - What defines the \u0026ldquo;open\u0026rdquo; in \u0026ldquo;open AI\u0026rdquo;? - YouTube \u0026ldquo;OpenAI\u0026quot;の話ではなく、オープンなAIとは?という話で、ライセンスの話であったり、コミュニティ(データセットの公開とかベンチマークの共有とか)に関する話であったり。 後半は気を抜いてしまって話をうまく聞き取れてないので、興味がある方はビデオで。。。\nVectorize Your Open Source Search Engine セッションページ:Vectorize Your Open Source Search Engine 動画: Atita Arora - Vectorize Your Open Source Search Engine - YouTube ベクトル検索が流行ってきてるけど、これまでの検索(エンジン)に対して、どうやってベクトル検索を取り入れる?という話です。 ベクトル検索ってどんなもので、どういうことの助けになりそうか?じゃあ、どうやって、これまでの検索が改善したかを見ていくのか? という、これからベクトル検索を取り入れようとしている時にどのようなアーキテクチャにして、 どのような考慮するポイント(モデルの選択とかスケーラビリティとか)にどんなものがあるのか?といった紹介でした。 ざっくりですが、ベクトル検索やるのにどんなことをやっていけばよいのか?という地図になるようなセッションでした。\nSupercharging your transformers with synthetic query generation and lexical search セッションページ: Supercharging your transformers with synthetic query generation and lexical search 動画: Milind Shyani - Supercharging your transformers with synthetic query generation and lexical search - YouTube AWSの人の話でした。こちらもトランスフォーマーが検索に使えると便利だよねという話なのですが。 LLMを使うと高コストでサイズがどんどん大きくなっていて、小さな学習済みのモデルだといまいちな精度でだし、 ファインチューニングしたい場合、ドメインに特化したデータはなかなかないよね。とくにデータ(検索したいもの)はあるけど、クエリがないということがよくあるよね。 そこで、LLMを使って、データからクエリを作って、正解データを作り、それでファインチューニングすればいいのでは? ということで、やってみました、どうでしたという話でした。\nブログなどもあるので参考にすると面白いかも\nThe Debate Returns (with more vectors) Which Search Engine? セッションページ:The Debate Returns (with more vectors) Which Search Engine? 動画:Charlie Hull - The Debate Returns (with more vectors) Which Search Engine? - YouTube 今年も検索エンジンの人を集めてパネルディスカッションです。今年は次の方たちが参加してディスカッションでした。\n参加者 Jo:Vespaの人。ランキングとかがよくできてるからVespa好き Alessandro:Apache Solrの人。SolrのPMCメンバー。なんでSolr?Pure OSSだし。スケーラブルだ Etienne:Weaviateの人。新しいAI nativeなベクトルデータベース Philipp:Elasticの人。 Kacper:Qdrantの人。 質問は次のようなものでした。\n最初の質問:スケールの話。スケールアウトかな? 2つ目の質問:どんなアプリケーションが適していないか? 3つ目の質問:どうやってAIをサポートできるの? 4つ目の質問:どうやってコミュニティにアプローチしてる? 5つ目の質問:自分の検索エンジンが使えない時に何を使う? 6つ目の質問:今後に何が面白そう? 最後の質問:あなたの検索エンジンが使われてるユースケースで一番好きなものは? 2つ目や5つ目の質問が面白いですよね。実際の内容はぜひビデオを見ていただくのがいいかと(メモも取ったけど、聞いてもらうほうが面白そうだし)。\nWhat\u0026rsquo;s coming next with Apache Lucene? セッションページ:What\u0026rsquo;s coming next with Apache Lucene? 動画:Uwe Schindler - What\u0026rsquo;s coming next with Apache Lucene? - YouTube 毎年恒例Uweさん。今年Luceneが25周年という話で、これまでの進化の話を駆け足でしてくれました。 あとは、後半は来週9.7が出るよということで、9.7で入ってくるベクトルの距離計算の最適化に関して説明してくれています。 次のバージョンのElasticsearchでもこの最適化が使えるようになるという話もされていましたので、ベクトル検索を使ってる方は、次のバージョンも楽しみですね。\nBuilding MLOps Infrastructure at Japan\u0026rsquo;s Largest C2C E-Commerce Site セッションページ:Building MLOps Infrastructure at Japan\u0026rsquo;s Largest C2C E-Commerce Site 動画:Berlin Buzzwords 2023: Building MLOps Infrastructure at Japan\u0026rsquo;s Largest C2C E-Commerce Site - YouTube メルカリの検索システムに関係しているMLOps周りがどうやって進化してきたのか?という話でした。 英語にいらすとやの絵があるスライドがドイツで使われているのがとても新鮮ですw\nHighly Available Search at Shopify セッションページ:Highly Available Search at Shopify 動画:Khosrow Ebrahimpour - Highly Available Search at Shopify - YouTube Shopifyの検索プラットフォームチームの人の、Shopifyの検索プラットフォームがどういったものか?(EsとKafka使ってる)どんな工夫をしているか?という話です。 Kubeconでも他の同僚の方が話をされている見たいで、そちらも参考になるとのことでした(動画)。 スキーマ変更時の話とかもあり、実践的でした。最後に将来的な話でやはりベクトル検索というキーワードが出てきていました。あとは、データ量が大きいのでスケーリングの挑戦もあるとのこと。\nUsing Dense Vector search at the EU Publications Office セッションページ:Using Dense Vector search at the EU Publications Office 動画:Martin Bayton - Using Dense Vector search at the EU Publications Office - YouTube EUのPublication Office(日本だと公文書館とかになるのかなぁ?)の検索サービスで、Googleみたいなこと(検索結果の上にスニペットが出たり、そこにハイライトされたり)をやってみたいよね?という話みたいでした。実際公開してるかはわからないですが、途中からはPureinsightsという会社のプラットフォームで似たようなことをやるデモになってました。\nGoogleでも12%のクエリが、質問の自然文になっているという話で、検索結果にナレッジグラフからの情報(スニペットとか、質問に対する答えとか、地図とか)が出るようになってきていますと。 それをPublication Officeのデータで再現したデモを行った後に、どんな感じのアーキテクチャなのか?という概略を説明されています。国会図書館とかの検索サービスやってる方が興味を持ったりするかもなーと思ったり、思わなかったり?\nLearning to hybrid search セッションページ:Learning to hybrid search 動画:Berlin Buzzwords 2023: Learning to hybrid search - YouTube これまたキーワード検索とセマンティック検索のハイブリッドの話です。 よくハイブリッド検索というのを聞きますが、データだったりベンチマークなどの話があまりないですよね?昨年AmazonがECSIというデータセットを公開したりしています(rejasupotaroさんが年末に書かれた記事にも出てきていました)。 これにLearn to Rankとかもテストできるようなデータ(レビューや評価、カテゴリーとか)を拡張したものを作って、それをもとにいろいろとハイブリッド検索で精度を測ってみたというお話でした。 Metarankというリランキングエンジンの会社の方たちで、Metarankを使ってハイブリッドな検索結果のリランキングで精度がどのように上げられるか?という話です。 今年のTRECのProduct Search Trackの話もされていました。 これが元ネタのブログかな?\nCatch the fraud — with observability and analytics セッションページ:Catch the fraud — with observability and analytics 動画:まだ? 最後は元同僚のセッションです。こちらは検索ではなく、ちょっと自虐的なネタをもとにしたオブザバビリティおよび分析のお話です。 コミュニティの人たちの貢献(ブログ書いたりプルリク送ったり、どこかで話をしたり)を計測して、年間の貢献者に対してプレゼントを上げるというのをやっているみたいです。 で、昨年の最も貢献した人にMac Bookをプレゼントするというすばらしい(暴挙)話で、チートしようとした人がいてそれを分析した話でしたw 締め切り直前に信じられない量の貢献したという登録がブラジルからあり、何かおかしいよね?ということで、Elastic Stackのオブザバビリティの機能などを元に分析してチートした人を除外していったよという話でした。 Kibanaが使いやすくなってるのがわかるセッションで面白かったです。\nまとめ 検索がまたすごく盛り上がってきたなーという時間があるカンファレンスでした。みんな似たような話(ベクトル検索、LLM、AIなど)だったりしますが、 知らないプロダクトで興味が出てくるものもあったし、Amazonのデータセットがあるからいろいろ試してみることもできそうだなぁと。\nすでにビデオが公開されはじめているので、気になったセッションのビデオも見てから後日またブログを書こうとおもいます (たぶん、一覧が作成されるので後日リンクを貼っておきます)。\n来年の予定(6月11日から開催)も公開されていましたし。来年も楽しみですね。 来年はプロダクションでベクトル検索やってみた話とかがさらに出てくるのかなぁ?\n","date":1687278645,"dir":"post/2023/","id":"9335522f4c8dbc7256a42a091e6e00bc","lang":"ja","lastmod":1687278645,"permalink":"https://blog.johtani.info/blog/2023/06/21/attend-berlin-buzzwords-2023/","publishdate":"2023-06-21T01:30:45+09:00","summary":"今年もこの季節がやってきました。 Berlin Buzzwordsにオンラインで出張してました。 今年もハイブリッド開催をしてくれたので、オンラインで参加で","tags":["conference","belin buzzwords"],"title":"今年もオンラインでBerlin Buzzwordsに参加した"},{"contents":"今年もなんとか振り返りブログを書いてます(時間大丈夫かな?w)。紅白をリアタイで見ながら。\n振り返り(2021年に書いた抱負から) まずは振り返りをと。\nフリーランス継続 ありがたいことに個人事業主として今年も1年乗り越えられました。 ZOZOさんには引き続きお世話になっている感じです。 10月からは今月末まで別のお客さんを手伝っていたりという感じでした(アップグレードの手伝いとか)。 相変わらず完全リモートで作業をさせていただいてます。\nただ、来年は今の所、余力がある感じになっているので、新しい仕事を見つけたいところだなあという感じです。 検索で何かお手伝いできることあれば、気軽にお声がけいただければと。\nプログラミング Linderaの大須賀さんのおかげで、レビューは定期的にやらせていただいてますw 業務がっつりというほどではないのですが、検証用のコードを書いたりはしています。\n個人用では、BGM環境のためにシェルを書いたり、文字化けしてるデータを解析したりするのにコードを書いてますが、もうちょっと量を増やしたいところです。 コードがっつり書く仕事をやらせてもらうのとかやらせてもらうのがいいかもなぁ。\n書くよりもどうしても読むほうが多くなってる気がします。\nブッチャー本ちゃんと読む 全部ではないですが、ZOZOさんで輪読をしたりしていました。 が、自分で全部読むといったところまではできてないです。\n読んだ本のブログを書く これはできてないですね。 読むのはちょとちゃってるんですが、ブログを書くところまではできてない。 メモとりながら読みたいですね。\n振り返り(今年あったできごと) ここからは今年の出来事を。 今年もずっと自宅で仕事した。来年は出張とかできるのかなあ?\n自宅環境 今年もDIY 検索ペンギン本が出版された 仕事場を模様替えしました。 今年もずっとWindows環境をメインで仕事をしていました。 年末まではM1 Macを借りて作業するという経験もできたのでよかったです。 今年仕事の環境は少し変わって、AVアンプ(譲り受けたもの)+Polk Audioのスピーカーで音が良くなりましたw あと、机の天板を大きくして、作業がやりやすくなりました。写真はそのうち。\n仕事場の模様替えにもなるのですが、今年のDIYはラブリコ+有孔ボードでケーブルやキーボードをすっきり片付けられる環境を作ってみました。 壁を有効活用できるのはよかったです。こちらについては、別途ブログを書こうと思います。\n今年最大のニュースは検索ペンギン本を出版したことです。 声をかけていただいた打田さんには感謝です。著者の皆さん検索システムを色々と手掛けられているので良い本になったと思います。\n『検索システム ― 実務者のための開発改善ガイドブック』 – 技術書出版と販売のラムダノート おー、届いたー pic.twitter.com/RbY5tOe9GB\n\u0026mdash; Jun Ohtani (@johtani) May 17, 2022 いろんなところで輪読も開催されているようで、顔を出してみたいなぁ。 輪読やってます!外部の人を呼んでもOKという方がいたら、参加してみたいのでTwitterでメンションしてもらえると嬉しいです。\n来年の抱負 ということで、来年の抱負です。\nフリーランス継続 プログラミング ベクトル検索まわりをさわる 本を読む 今年もありがたいことに仕事を継続していただけて、乗り越えられました。 来年も価値を提供できるように頑張っていきます。 もっといろんな会社の検索システムを見てみたいですし、検索エンジン入れてみたけどここからどうすればいい?という方も増えて来ているような気がするので、気軽に声をかけていただければと。\nプログラミングは、家の音楽ファイルの文字化けを直すプログラムをもう少しちゃんと書いてからブログを書きたいなと。まぁ、個人的なプログラムなので誰も嬉しくないかもですが(色々検討した結果Javaで書いてる)。 あとは、オライリーさんの初めてのGo言語を買ったのもあるので、前にRustで書いたElasticsearchへのBulk登録のツールをGoで書いてみようかなと考えているところです。みんなはデータ登録するときはどうしてるんだろう?\nNLPでBERTなどによる目まぐるしい進歩の影響もあり、ベクトル検索やセマンティック検索といった検索技術が各社から出て来ています。 ElasticsearchでもGAされたのもあり、今後ますます注目を浴びる技術になるのだろうなと。 ただ、これまでの検索とどう組み合わせるのがいいのか?どう言ったメリットデメリットがあるのか?向き不向きは?といったものもあるので、仕組みを調べながら色々と試行錯誤してみたいと思っています。\nさいごは、毎年書いてる気もしますが、本を読むのもやらんとなぁ。 あたらしいネタを仕入れては実践できる時間もとりつつ、他のことにも目を向けたいと思っています。\n今年は仕事の変化も少し出て来ているので、来年は新しいことをいくつかやってみたいところです。 あとは、外に出る機会が増やせるといいなぁ、少しずつ人から刺激をもらいたいと思っています。\nさて、今年は年内に無事描き終わりました。 来年もよろしくお願いいたします、良い年にしたいなー。\n","date":1672486684,"dir":"post/2022/","id":"df30d810068e4656498e5972c6de7e3d","lang":"ja","lastmod":1672486684,"permalink":"https://blog.johtani.info/blog/2022/12/31/review-2022/","publishdate":"2022-12-31T20:38:04+09:00","summary":"今年もなんとか振り返りブログを書いてます(時間大丈夫かな?w)。紅白をリアタイで見ながら。 振り返り(2021年に書いた抱負から) まずは振り返","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2022)"},{"contents":"PySpaアドベントカレンダーの12/15のエントリーです。昨日はtaichiさんでした。 今年はDIYではなく、PCにまつわる話を。\n仕事中はBGMが基本 フリーランスを始めて(2020年初頭)からすぐに、自宅で仕事をする情勢になりました。 打合せをしていないとき、カンファレンスの発表などの動画を見ていないときは基本的にBGMをかけて作業をしています。 音源としては、CDなどから音楽ファイルにしたり、AmazonやSonyのサイトで購入した音楽ファイルなどがNASにあります。\n今年10月までの環境 2020年の後半に次のような環境を構築して今年の10月まで使っていました。\nLibreELECをラズパイ4に入れて、Kodiのリモコンをスマホに入れたら快適になった\n\u0026mdash; Jun Ohtani (@johtani) October 20, 2020 KODIと呼ばれるマルチメディアセンター?のようなソフトで、それを動かす最小限のOSとして、LibreELECが公開されています。 これをラズパイ4に入れて、NASからファイルをSSDにコピーしてそれをラズパイに接続して音楽を聞いていました。 毎回ラズパイの画面を見に行くのも面倒なので、再生などの操作にはAndroid用のKodiのリモコンアプリを使っていました。\n場所も取らないのでよかったのですが、使っているといくつか問題点が。\n時々調子悪(音が出ない、リモコンからつながらない、無反応など)くなって、ラズパイ再起動 音楽ファイルを購入して増えた時に、外付けSSDを取り外してPCでコピーしたり スマホじゃないと再生できない(PCのクライアントもあったのかもだけど調べてなかった) Ubuntu on Mac mini 10月に模様替えをして、2012年製のMac Miniが宙ぶらりんになりました。 さすがに古いしメインマシンがWindowsになっているのもあり、macOSである必要も特にないので、Ubuntu 22.04を入れて何かに使えるのでは?と。 また、1TBのSSDに内臓ディスクを乗せ換えていたのもあり、音楽再生に使ってみようということに。 なので、Kodiの環境で困っていた点も考慮して、ほしい機能を元にちょっと探してみました。\n音楽再生 on Ubuntu 音楽再生でほしい要件としては次のようなものです。\nUbuntuで音楽再生できるソフト(あたりまえ) PCから操作したい(できればブラウザ) 音楽ファイルの更新(ローカルでもいいけどNASからもってきたり) 日本語の曲情報も表示 対象音楽ファイルが豊富(そんなに制限があるものはないだろうなぁ) 上記の要件をもとに適当にググって見つけてきたのがOwnToneというソフトでした。\nOwnTone OwnToneの説明は公式サイトを見ていただくとして、OwnToneにしてよかったなというのが以下の点です。\nインストールが簡単(apt-getでインストールできる) サポートフォーマットが豊富 Web UIがついてる(ブラウザで見えるし、スマホでもOK。どのブラウザから見ても今の状況も分かる) 簡単だけど検索できる プレイリスト対応(ファイルパスを入れるだけ) サムネイルとかも出てくる(どうやってんだろう?w) AirPlayで再生できる(AVアンプを利用しており、そこにAirPlayで再生できてる) OSS(まだソースは見たことないですがw) 再生画面例\nやっぱ検索も気になるよね?\n日本語も検索できるな。 pic.twitter.com/EF6WHkJKli\n\u0026mdash; Jun Ohtani (@johtani) October 19, 2022 とりあえず、インストールして画面もすぐに出て操作も簡単で、便利な世の中になったなーと感動しましたw\nただ、音がヘッドフォン端子に刺したアナログ出力先のスピーカーではなく、本体のスピーカーで最初はなってしまいましたww Linuxの音周りが全然わかってない問題が発覚。\n幸い、先週のPyspa Advent Calendarのエントリーを書いていたaodag先生に助言をいただき、alsamixerで音の設定を見たところ、ヘッドフォン端子がミュートされていたので、ミュートを外して無事再生できました。 インストール当初はYAMAHAのアクティブスピーカーにJust Mixer経由でヘッドフォン端子(アナログ)で出力して音楽再生をしていました。 今は(この記事を書いてる現時点で)、AVアンプのAirPlayにOwnToneから音を流している形で聞いています(便利なんだけど、当初の想定とは異なる、理由は後述)。\nファイルのコピーとか さて、上にも書きましたが、NASにバックアップもかねて音楽ファイルを保存してあります。 新しく買ったファイルもここに置くようになっています。 OwnToneのMac MiniからNASをネットワーク経由で見に行くのもいいのですが、できればローカルにあったほうがネットに影響も出ないなと。\nということで、定期的にNASをウォッチしてMac Miniにファイルをコピーするようなプログラム(Bashスクリプト)を書いてみました。 毎回購入後に手で実行もめんどくさいので毎日夜中にcron実行するような設定になっています。\nスクリプトの中身は次のような感じです。\nfindコマンドで特定の日時(最近コピーしたファイルの日付)以降(-newermtオプション)のファイルのリスト(音楽ファイルの拡張子に限定)を取得 取得したリストをもとに以下の操作 ファイルをコピー コピーしたファイルをコピーした日付のプレイリストを作って入れる(プレイリストはパスだけ書けばOK) mp4形式だと聞けない端末もあるので、soundconverterコマンドでmp3に変換してNASに戻す 最新のファイルの日付を保存(次回のfindコマンド) ファイルがあったら、OwnToneの再読み込みのエンドポイントをcurlでキック NASはSambaでマウントして、見えるようにしてあります。 やっぱり、自動化便利ですねぇ。 気に入った曲を買ってNASに入れとけば聞けるようになるのは本当に便利。\n他にもスマートプレイリストとかもあるので、活用しないとな。\n今後の課題 さて、すごく便利になったのですが、課題も残っています。\n音声出力問題 アナログ出力はaodag先生の助言ですぐに解決したのですが、takabowから譲り受けたAVアンプを導入してから実は音の出力がうまくいっていません。\nHDMI、光端子出力でAVアンプにつなごうとしたのですが、私のUbuntu力(Linux力?)が全然不足しているのでうまくいっていません。ググりつつ、HDMI、光出力でamixerというコマンドで音声ファイルを鳴らすところまでは行ったのですが、OwnToneに設定するとうまくいかない状況です。 結局、解決してないのですが、AVアンプのAirPlayのレシーバー経由で音楽再生ができてしまったので、とりあえずAirPlayで運用することにしました。時間を見つけてaodag先生の記事を読み直して再チャレンジしないとな(けど、鳴ってるしなぁ、音w)。\n文字化け問題 これは、OwnToneというよりはもともとあった問題です。 古い音楽ファイルだったり、Wav形式のファイルなど、様々な形式のファイルを持っています。 音楽サーバーとは別に、音楽ファイルの検索をできるようにしつつ、付加的な情報(Wikimediaなどのデータとか)を付与して、検索できるようにしてみようと思い、音楽ファイルからメタデータを抜き出して、ElasticのApp Searchにいれるデータを作るツールを書いたりしています。 この時にも文字化けに遭遇しました。\n様々な音楽ファイルにはメタデータを付与することができる仕様が決まっています(ID3タグ - Wikipediaなど)。 ただ、文字コードの情報が入っていなかったり、デフォルトとは違う文字コードでデータを付与したファイルがあったり、いろいろな原因で文字化けしているものがあります。 昨年Amazonで購入したmp3の中にも文字化けしているものもあったりします。Wavファイルに付与されたタグなどは、容赦なくShift-JISだったりしますが、読み込むソフトはUTF-8で読もうとしたり。。。\n検索サーバーにデータを抜き出して入れるツールを書いているときは、元のファイルを変更することなく、抜き出す時点でいくつかの文字化けに対応した処理を書いたのですが、今回のOwnToneで曲を流すと結局、元のファイルをきれいにしないとダメだということに気づきました(すぐわかるだろ。。。)\nということで、書いている途中のツールをもとに、根本的な文字化けのファイルのメタデータをきれいにするプログラムを書かないといけないなぁと。\nちなみに、メタデータの抜き出しにはJavaでプログラムを書いており、JAudiotaggerというライブラリを利用しています。 Pythonや他のJavaのライブラリを試そうとしたのですが、文字コードが決め打ちで抜かれているものが多く、ライブラリから読みだした時点ですでにどうしようもない状態のものが多いといった問題からこのライブラリにたどり着きました(まぁ、まだちゃんとしたものができていないんですけどね)。\n検索サーバー OwnToneのUIはブラウザでうごきます。 検索窓もついています。 が、先ほども書いたように、他にもデータを追加して、いろんな検索をしてみたいなぁと(ドラマに使われてたとか、CMにつかわれてたとかとか)。 検索が好きでいろいろとやってるので、その辺も遊んでみたいなぁと思っているところです(実際、ElasticのApp SearchにWikidataから生成した類義語を入れてみたりしている)。\nこうやってブログにしてしまったので、課題をつぶしていなかったら、Twitterなどでつついてくださいw\nまとめ 構成図とかは書かなかったですが、OwnToneを使うと簡単にWeb UIが入った音楽サーバーが使えるようになって、仕事がはかどりますよという記事でした。 他にもこれに関するネタを募集してますので、コメントもらえるとうれしいです(Twitterでメンションも大歓迎)。\n","date":1671030358,"dir":"post/2022/","id":"67c2ae6761e89be0fa66db9623b40d30","lang":"ja","lastmod":1671030358,"permalink":"https://blog.johtani.info/blog/2022/12/15/music-server-on-mac-mini/","publishdate":"2022-12-15T00:05:58+09:00","summary":"PySpaアドベントカレンダーの12/15のエントリーです。昨日はtaichiさんでした。 今年はDIYではなく、PCにまつわる話を。 仕事中は","tags":["misc","music"],"title":"仕事中のBGM環境"},{"contents":"本記事は情報検索・検索技術 Advent Calendar 2022の9日目の記事です。\nだいぶ間が空いてしまいましたが、日本語のオートコンプリートに関する記事の続きです。 という感じで、Suggesterのデータ構造とか仕組みを書こうと思っていたのですが、思ったよりも調べないといけないことが多くて挫折しました。。。 (これの続きは年末年始で調べて書くはず?)\nということで、代わりにElasticsearch/OpenSearchのアーキテクチャの変更に関してさらっとまとめてお茶を濁してみようと思います。\n発端はElasticON Tokyo? 先週の11月30日に、ElasticのオフラインイベントであるElasticON Tokyoが開催され参加しました。 参加しようと思ったのは、10月の頭にElasticのブログで公開された「Stateless — your new state of find with Elasticsearch」というアーキテクチャの変更がきっかけです。\n(図はElasticのブログから引用)\nElasticsearchはLuceneのインデックスを分散したシステムとしてスケールアウトできるようにするという目的でリリースされました。 インデックスをシャードという単位で複数のElasticsearchのノードにデータを保存し、レプリカを作ることで分散する仕組みを実装していました。 Elasticsearchでは、インデックスのレプリカは、作成したインデックスを定期的にコピーするのではなく、登録するデータがElasticsearchのクラスターにやってきた時に、 データ自体をコピー先にも配り、プライマリーやレプリカとなるシャードがあるノード上でそれぞれインデックスに登録する処理を行うという処理の流れです(古いけど、わかりやすい説明はこちら)。 この場合、インデックスにデータを登録する処理(転置インデックスのデータ構造に変換する処理など)は、レプリカの数だけ同じ処理がクラスター上で発生します。\nこの基本的なアーキテクチャをもとに、保持するデータの鮮度(新しいデータのほうが検索頻度が高い、インデックス登録する時はマシンは多く、古くなったデータが入ったインデックスはコストが低いマシンになど)などを元に、クラスター内のノードの特性を異なるものが混在するような複雑な仕組みを作ってきました。 いろいろなデータの持ち方などで多くのデータなどを保持できるようにしてきたのですが、クラスター全体としては、検索の負荷のピークをさばけるような構成を基本的に保持しておくというかんがえです。\nただ、昨今は必要に応じてスケールアウト(リクエストが増えたりデータ量が増えた時)、スケールイン(夜中は利用者が少ないからクラスターを小さくしたい時)できるような仕組みのほうが求められています。 そこで、発表されたのが上記のブログであり、上図の新しいアーキテクチャです。 計算処理(データを登録、検索する処理)とストレージを分離し、さらに登録する処理と検索する処理も分離した構成です。 このようなアーキテクチャにすることで、登録処理の演算コストがレプリカごとに必要ではなくなり、検索の部分だけだったり、登録の部分だけをスケールアウト・インできるような自由度が手に入ります。 また、ストレージ部分でレプリカを担保(S3とかのオブジェクトストレージで冗長性を担保)できれば、レプリカのストレージコストも必要なくなります。\nというブログが発表されたのですが、詳細などはまだよくわからなかったのでElasticON Tokyoに参加して詳しい話が聞けるのかなぁと期待していました。\n参加当日の朝のびっくりするニュース 11月30日の朝に起きて、出かけようかと思っていたところに、AWSのre:Inventで発表されたニュースが舞い込んできました。\nほー(まだタイトルしか読んでない)https://t.co/KK22duaBNH\n\u0026mdash; Jun Ohtani (@johtani) November 29, 2022 Amazon OpenSearchがServerlessオプションを発表というニュースです。 (Amazon OpenSearchとは、AWSがElasticsearchをフォークして始めた検索エンジンで、Amazon OpenSearch Serviceというのは、AWSがそれをSaaSとして提供しているものです)\nまぁ、気になりますよね、「Serverless」ってキーワードに。 ElasticON Tokyoに向かう電車でブログを読んだり、どんな仕組みかを調べたので、それを簡単にまとめておきます。\nプレビュー段階(Tokyoリージョンではもう試せる) これまでのAmazon OpenSearch Serviceとは別(オンザフライで移行はできない?) 「コレクション」という単位でクラスターを管理(スケールインとかアウトとか) コレクションにはタイプがあり、タイムシリーズ(ログとか)か検索のユースケースなのかで使い分ける(公式ドキュメント) インデックス処理と検索処理で計算ユニット(OCU)が別々にスケールできる(下図) 作成されたインデックスはAmazon S3に保存され、そこで冗長性は担保される。(下図) 検索処理のユニットはS3のデータをローカルに持ってきて処理をできる データ登録とかのAPIは基本的にServerlessかどうかで違いはなさそう(これまで通りのクライアントでアクセスとかで競う) 設定した範囲でいいかんじにスケールアウトインしてくれそう(ほんとかな?) もちろん、いくつか制限がある(サポートしてないプラグインとか操作もある) (図はAWSのドキュメントより引用)\n発表時のブログでは詳しくはわからないのですが、公式ドキュメントではさらに詳しく説明がありました。 こちらを読むほうが仕組みがわかると思います。 今後もどんどんドキュメントは充実していくんだろうなと。今ならまだサクッと読める量ですw\nただ、「サーバーレス」という定義が私はよくわかりませんでした。 公式ドキュメントを読むとコレクションを作ると少なくとも4つのOCUが起動しているみたいで課金されると記載があります。\nまぁ、Elasticの発表と同様に、これまでは最大負荷の時を元にクラスターを維持せずとも、より柔軟に検索だけ、登録処理だけを一時的にスケールできるとコストを下げられそうですね。 すぐに誰かが使ってみたブログなどを出してくれると思うので、細かな使用感などはそのうちわかってくるかと。\n今後は? ElasticもAWSも考え方の基本となっているのは、Berlin BuzzwordsでAmazonのMikeさん(Luceneのコミッター)が2019年に発表されたものだと思っています。 アーキテクチャの変更がどんな影響が出るかはわからないですが、少なくとも検索のユースケースでよりスケールアウトしやすくなるだろうなと。 どちらもSaaSとしての仕組みとして提供するので、検索エンジンそのものの機能として公開されるかはわからないです。 ですが、そのほかの検索エンジンも出てきていますし、今後も検索エンジンから目をはなせないです。 今回は残念ながら触っていませんが、時間を見つけて使ってみたいです(Elasticも早く出してくれないかなー)\nということで、当初の予定とは違うブログになってしまいました。。。 技術的な深い話はまたどこかで。。。\n参考文献 Stateless — your new state of find with Elasticsearch | Elastic Blog Preview: Amazon OpenSearch Serverless – Run Search and Analytics Workloads without Managing Clusters | AWS News Blog Berlin Buzzwords 2019: Michael Sokolov \u0026amp; Mike McCandless–E-Commerce search at scale on Apache Lucene - YouTube ","date":1670516125,"dir":"post/2022/","id":"9693a1e77dee5785b1dc61ccffd2e906","lang":"ja","lastmod":1670516125,"permalink":"https://blog.johtani.info/blog/2022/12/09/open-search-serverless/","publishdate":"2022-12-09T01:15:25+09:00","summary":"本記事は情報検索・検索技術 Advent Calendar 2022の9日目の記事です。 だいぶ間が空いてしまいましたが、日本語のオートコンプリートに関する記事の続きです。","tags":["elasticsearch","opensearch"],"title":"ElasticsearchのアーキテクチャとStateless / Serverless"},{"contents":"前回は日本語用オートコンプリートのためのAnalyzerとして、どうやって使うのかを簡単に紹介しました。\n今回はもう少し、いろんなパターンを試してみたいと思います。\nローマ字入力のゆれ 前回のサンプルでも「吾輩\u0026hellip;」のデータをサジェストするためのサンプルとして、「wagah」という「わがはい」をローマ字にしたものを利用しました。\nちなみにローマ字というとどんなものを思い起こしますか? 普通は学校で習ったヘボン式あたりだと思います。 Kuromojiの読みでローマ字出力するには通常、kuromoji_readingformでuse_romajiをtrueにします。 以下、「吾輩」のサンプルです。\nGET _analyze { \u0026#34;text\u0026#34;: [\u0026#34;吾輩\u0026#34;], \u0026#34;tokenizer\u0026#34;: \u0026#34;kuromoji_tokenizer\u0026#34;, \u0026#34;filter\u0026#34;: [ { \u0026#34;type\u0026#34;: \u0026#34;kuromoji_readingform\u0026#34;, \u0026#34;use_romaji\u0026#34;: true } ] } レスポンス { \u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;wagahai\u0026#34;, \u0026#34;start_offset\u0026#34;: 0, \u0026#34;end_offset\u0026#34;: 2, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 0 } ] } 「吾輩」の場合は特に問題ないのですが、ローマ字による日本語入力の場合、次のような単語を入力するときに、ゆれが生じます。\nシャボン=「shabon」 新橋=「shimbashi」 括弧内はkuromoji_readingformで出力したもの(=ヘボン式のローマ字)です。 ですが、ローマ字入力の場合は「syabon」や「shabon」と入力したり、「sinbasi」や「sinnbasi」と入力すると思います。 JapaneseCompletionAnalyzerを利用したCompletion Suggesterの場合、これらのゆれも考慮してサジェストしてくれるようになっています。 前回のサンプルデータを用いると次のような感じです。\nGET aozora_index/_search { \u0026#34;explain\u0026#34;: true, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: { \u0026#34;prefix\u0026#34;: \u0026#34;sha\u0026#34;, \u0026#34;completion\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;suggest_ja\u0026#34; } } } } GET aozora_index/_search { \u0026#34;explain\u0026#34;: true, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: { \u0026#34;prefix\u0026#34;: \u0026#34;sya\u0026#34;, \u0026#34;completion\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;suggest_ja\u0026#34; } } } } これらのリクエストは、「しゃ」について2パターンになっていますが、結果はどちらも次のものが返ってきます(このレスはsyaのレスになります)。\n{ \u0026#34;took\u0026#34;: 1, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;sya\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 3, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;シャドウ・ワーク\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;000739\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;シャドウ・ワーク\u0026#34;, \u0026#34;朝倉 克彦\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;シャボン玉\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;045054\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;シャボン玉\u0026#34;, \u0026#34;豊島 与志雄\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;上海\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;050899\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;上海\u0026#34;, \u0026#34;横光 利一\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;斜坑\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;002095\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;斜坑\u0026#34;, \u0026#34;夢野 久作\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;社会事情と科学的精神\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;053864\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;社会事情と科学的精神\u0026#34;, \u0026#34;石原 純\u0026#34; ] } } ] } ] } } 「sinnba」や「shinba」も試してみました。\nGET aozora_index/_search { \u0026#34;explain\u0026#34;: true, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: { \u0026#34;prefix\u0026#34;: \u0026#34;sinnba\u0026#34;, \u0026#34;completion\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;suggest_ja\u0026#34; } } }, \u0026#34;_source\u0026#34;: [\u0026#34;suggest_ja\u0026#34;] } GET aozora_index/_search { \u0026#34;explain\u0026#34;: true, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: { \u0026#34;prefix\u0026#34;: \u0026#34;shinba\u0026#34;, \u0026#34;completion\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;suggest_ja\u0026#34; } } }, \u0026#34;_source\u0026#34;: [\u0026#34;suggest_ja\u0026#34;] } これらも同じ結果です。\n{ \u0026#34;took\u0026#34;: 0, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;shinba\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 6, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;しんばい\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;044942\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;しんばい\u0026#34;, \u0026#34;村山 籌子\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;新橋\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;002409\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;新橋\u0026#34;, \u0026#34;北原 白秋\u0026#34; ] } } ] } ] } } 入力されるパターンを想定した実装がされているので対応できている形です。 使い方が楽なだけでなく、より使いやすくなってるのは便利ですね。\nうまくいかないパターン 万事OKかというと残念ながらそうでもありません。 うまくいかないパターンもあります(これが本当にうまくいかないかは難しい話な気がしますが)。 「日本」という漢字ですが、「にほん」「にっぽん」どちらとも読めますよね? これらを試してみると次のようになります(リクエストは省略します)。\nまず「にほん」\n{ \u0026#34;took\u0026#34;: 0, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;にほん\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 3, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;日本橋\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;004565\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本橋\u0026#34;, \u0026#34;泉 鏡花\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本橋\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;045357\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本橋\u0026#34;, \u0026#34;牧野 信一\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本橋あたり\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;047648\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本橋あたり\u0026#34;, \u0026#34;長谷川 時雨\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本橋附近\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;055666\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本橋附近\u0026#34;, \u0026#34;田山 花袋\u0026#34; ] } } ] } ] } } 次に「にっぽん」\n{ \u0026#34;took\u0026#34;: 1, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;にっぽん\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 4, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;日本アルプスの五仙境\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;056269\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本アルプスの五仙境\u0026#34;, \u0026#34;木暮 理太郎\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本出版協会論\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;049436\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本出版協会論\u0026#34;, \u0026#34;嶋中 雄作\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本文化と科学的思想\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;055750\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本文化と科学的思想\u0026#34;, \u0026#34;石原 純\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本文化のために\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;003183\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本文化のために\u0026#34;, \u0026#34;宮本 百合子\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本文化の特殊性\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;055290\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本文化の特殊性\u0026#34;, \u0026#34;戸坂 潤\u0026#34; ] } } ] } ] } } 最後に「日本」\n{ \u0026#34;took\u0026#34;: 1, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;日本\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 2, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;日本アルプスの五仙境\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;056269\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本アルプスの五仙境\u0026#34;, \u0026#34;木暮 理太郎\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本出版協会論\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;049436\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本出版協会論\u0026#34;, \u0026#34;嶋中 雄作\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本文化とは何ぞや(其二)\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;002940\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本文化とは何ぞや(其二)\u0026#34;, \u0026#34;内藤 湖南\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本文化と科学的思想\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;055750\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本文化と科学的思想\u0026#34;, \u0026#34;石原 純\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本文化のために\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;003183\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本文化のために\u0026#34;, \u0026#34;宮本 百合子\u0026#34; ] } } ] } ] } } 最初の「にほん」は「日本橋」がヒットしているようです。返ってきたoptionsの数は4件しかなく、どうやらこれがすべてのようです(取得件数はデフォルト5件)。 2番目の「にっぽん」は「日本」という単語から始まるものがヒットしていますが、「日本橋」はなさそうでした。 最後に「日本」という漢字を入力にした場合は2つの合計が帰ってきているようです(今回のレスポンス例にはありませんが、サイズを大きくすると「日本橋」が帰ってきていました)。\nどうしてそうなるの? JapaneseCompletionAnalyzerの基本的な動作としては、\nKuromojiが単語に区切る 区切られた単語ごとに読みを持っている 元の単語と読みをローマ字にしたものが最終的に出てくる というような動きです。 この時、単語には「1つ」の読みが対応しています。 読みから単語を探そうとすると、読みの違い(ゆれ)を吸収することはできないためです。 JapaneseCompletionAanlyzerは3点目のローマ字のゆれに対応していますが、入力となる読みのゆれまでは対応できないです。 対応しているといいかどうかというのも難しい判断になる気もします。。。\nそのほかの例としては次のようなものもあります。 これは、今回のオートコンプリートの話とは少しずれてるかもしれませんが、1番目の処理の結果が変わってくる例です。 「南方熊楠」という名前の間にスペースがあるかないかで、出力される読みが変わってくる例です。\nGET _analyze { \u0026#34;text\u0026#34;: [\u0026#34;南方 熊楠\u0026#34;], \u0026#34;tokenizer\u0026#34;: \u0026#34;kuromoji_tokenizer\u0026#34;, \u0026#34;filter\u0026#34;: [\u0026#34;kuromoji_readingform\u0026#34;] } GET _analyze { \u0026#34;text\u0026#34;: [\u0026#34;南方熊楠\u0026#34;], \u0026#34;tokenizer\u0026#34;: \u0026#34;kuromoji_tokenizer\u0026#34;, \u0026#34;filter\u0026#34;: [\u0026#34;kuromoji_readingform\u0026#34;] } # GET _analyze { \u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;ナンポウ\u0026#34;, \u0026#34;start_offset\u0026#34;: 0, \u0026#34;end_offset\u0026#34;: 2, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 0 }, { \u0026#34;token\u0026#34;: \u0026#34;クマグス\u0026#34;, \u0026#34;start_offset\u0026#34;: 3, \u0026#34;end_offset\u0026#34;: 5, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 1 } ] } # GET _analyze { \u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;ミナカタ\u0026#34;, \u0026#34;start_offset\u0026#34;: 0, \u0026#34;end_offset\u0026#34;: 2, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 0 }, { \u0026#34;token\u0026#34;: \u0026#34;クマグス\u0026#34;, \u0026#34;start_offset\u0026#34;: 2, \u0026#34;end_offset\u0026#34;: 4, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 1 } ] } 人名や地名は1つの漢字に対して多くの読みが存在しているので大変です。。。 どうしてこれは出てこないんだろう?と不思議に思った場合は、_analyze APIを使ってどういう動きなのかを見てみるのがいいかと。\nまとめ ということで、少しだけですが、こんなことができるよ、できないよというのを書いてみました。 挙動をしっていれば、なんでこうなってるんだっけ?といったことを調べる役に立つかと思います。 入力された文字をもとにどれをサジェストするかなどについてはもう少し違う動きなので、中の仕組みをそろそろ書かないとなぁ。\n参考 同形異音語 - Wikipedia ","date":1660099802,"dir":"post/2022/","id":"73279888a8fe482c836fb19ca23318dc","lang":"ja","lastmod":1660099802,"permalink":"https://blog.johtani.info/blog/2022/08/10/jp-auto-completion-2/","publishdate":"2022-08-10T11:50:02+09:00","summary":"前回は日本語用オートコンプリートのためのAnalyzerとして、どうやって使うのかを簡単に紹介しました。 今回はもう少し、いろんなパターンを試","tags":["elasticsearch","lucene"],"title":"ローマ字入力のゆれと読み(JapaneseCompletionAnalyzerその2)"},{"contents":"風のうわさで、日本語用のオートコンプリートのためのTokenFilterとAnalyzerがLuceneに取り込まれたと聞きました(LUCENE-10102)。 Elasticsearchでも使えるかなぁ?ということで調べたところ(調べた?聞いた?)、どうやら8.1から利用できるようになっている(GitHub Issue #81858)みたいです(まだ、公式ドキュメントには記載がないのですが)。\n8/17追記\n作者の打田さんがブログ書いてたの見落としてた(もしくは見たけど忘れてた)ので貼っておきます。マルチテナンシー下での Query Auto Completion 設計・運用戦略 - LegalForce Engineering Blog\nということで、こんな感じで使えるよというのを試してみました。\nどういうもの? 日本語入力方法を考慮したオートコンプリート用のトークンを生成してくれるTokenFilterと、 それをLuceneのSuggesterで動くようにしたAnalyzerが用意されています。 Elasticsearchでは、Kuromojiプラグインにそれらを使えるようになっています(バージョン8.1.0以降)。 KuromojiTokenizerと一緒に利用する前提の仕組みとなります。\nオートコンプリートとは? 検索窓などでキー入力をしていると、入力した文字で始まる単語の一覧が現れることがあると思います。 あの機能がオートコンプリートと呼ばれるものです。search-as-you-typeとも呼ばれることもあります。 (検索ペンギン本にも書いてあるので興味のある方はぜひ!(ステマ)) 入力された文字列を含むパターンもありますが、今回紹介するものは入力された文字で始まる単語を見つけてくる機能になります。\n何がなんで追加されたの? 日本語の入力方法は、かな入力の人もいればローマ字入力の人もいます。 ですので、オートコンプリートでの入力として、「しゃ」という入力が来る場合もあれば、「sha」というローマ字入力途中のものが来る場合もあります。 これらを考慮したトークンの扱いができるように、 JapaneseCompletionFilterというクラスが追加されています。 内部的にはKuromojiTokenizerでトークンに分割された後に、もともとのトークンと同じポジションで読みをローマ字にしたものを出力します。 JapaneseCompletionAnalyzerは上記Filterをすぐに使えるようにしたAnalyzerです。\n動かし方 百聞は一見に如かずということで、Elasticsearchでの使い方を見たほうが分かりやすいので、簡単に動かしてみることにします。\nインストールとインデックスの用意 Elasticsearch(8.1以上)とKuromojiのプラグインをインストールします(今回試したのは8.3.1)。\nサンプルデータ なにかいいデータはないものか?と思っていたところ夏休みだというのを思い出しました。 夏休みといえば読書感想文だ、ということで、書籍のタイトルがいいかもなと。 青空文庫の著者名と書籍のタイトルの一覧を見つけたのでそちらのデータを使って試してみました。\nCSV to JSON CSVファイルは最後の参考にある青空文庫のページから、「公開中 作家別作品一覧:全て(CSV形式、zip圧縮)」をダウンロードしたものを利用しました。 CSVファイルだったので、jqコマンドで必要な部分だけをNDJSONの形でとりあえずファイルに出力します。\ncat list_person_all_utf8.csv | tr -d \u0026#39;\u0026#34;\u0026#39; | jq -c -R \u0026#39;split(\u0026#34;,\u0026#34;) | {\u0026#34;auth_id\u0026#34;: .[0] | tonumber, \u0026#34;author\u0026#34;: .[1], \u0026#34;id\u0026#34;: .[2] , \u0026#34;title\u0026#34;: .[3], \u0026#34;suggest_ja\u0026#34;: [.[3], .[1]]}\u0026#39; 次のようなJSONが1行ずつ出力されます。\n{\u0026#34;auth_id\u0026#34;:1257,\u0026#34;author\u0026#34;:\u0026#34;アーヴィング ワシントン\u0026#34;,\u0026#34;id\u0026#34;:\u0026#34;056078\u0026#34;,\u0026#34;title\u0026#34;:\u0026#34;駅伝馬車\u0026#34;,\u0026#34;suggest_ja\u0026#34;:[\u0026#34;駅伝馬車\u0026#34;,\u0026#34;アーヴィング ワシントン\u0026#34;]} suggest_jaがオートコンプリートの対象となるデータになります。今回は著作と著者にしてみました。 あとは次に紹介するスキーマでインデックスを作成して、適当なプログラムを使ってBulkでElasticsearchに登録しましょう(私は個人作のツールで入れました)。\nインデックス オートコンプリート用のSuggesterを利用するための特殊なフィールド(completion)を利用したフィールドを用意します。 ちなみに、今回はLUCENE-10102に記載があった設定をそのまま使わせていただきました。 そのほかのフィールドは今回は特に必要はないのでおまけです。\nPUT aozora_index { \u0026#34;mappings\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;completion\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;japanese_completion_index\u0026#34;, \u0026#34;search_analyzer\u0026#34;: \u0026#34;japanese_completion_query\u0026#34;, \u0026#34;preserve_separators\u0026#34;: false, \u0026#34;preserve_position_increments\u0026#34;: true, \u0026#34;max_input_length\u0026#34;: 50 }, \u0026#34;auth_id\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;author\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;fields\u0026#34;: { \u0026#34;keyword\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;keyword\u0026#34;, \u0026#34;ignore_above\u0026#34;: 256 } }, \u0026#34;analyzer\u0026#34;: \u0026#34;kuromoji\u0026#34; }, \u0026#34;author_id\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34; }, \u0026#34;id\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34; }, \u0026#34;title\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;fields\u0026#34;: { \u0026#34;keyword\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;keyword\u0026#34;, \u0026#34;ignore_above\u0026#34;: 256 } }, \u0026#34;analyzer\u0026#34;: \u0026#34;kuromoji\u0026#34; } } }, \u0026#34;settings\u0026#34;: { \u0026#34;index\u0026#34;: { \u0026#34;number_of_shards\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;analysis\u0026#34;: { \u0026#34;analyzer\u0026#34;: { \u0026#34;japanese_completion_index\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;index\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;kuromoji_completion\u0026#34; }, \u0026#34;japanese_completion_query\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;query\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;kuromoji_completion\u0026#34; } } } } } } 動作確認 ここまでで、インデックスとデータの用意ができました。 オートコンプリートを実現するためにはElasticsearchのSuggesterという機能の、Completion Suggesterを利用します。検索の仕方が通常のものとは少し異なります。 ちなみに、速度重視のためにインメモリで動いているとの記載がドキュメントにあります。\nCompletion Suggesterのクエリ Suggester用のクエリがあるのでこちらを使います。 例えば、「wagah」という入力がある時に、サジェストする内容を取得するには次のようなリクエストになります。\nGET aozora_index/_search { \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: { \u0026#34;prefix\u0026#34;: \u0026#34;wagah\u0026#34;, \u0026#34;completion\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;suggest_ja\u0026#34; } } }, \u0026#34;_source\u0026#34;: [\u0026#34;title\u0026#34;, \u0026#34;author\u0026#34;] } 最初の「suggest」がsuggest用のパラメータを意味しています。 次の「title-suggest」は好きな名前をつけられます。レスポンスにこの名前がついた配列がサジェストの結果になります(同時に3. 複数suggestを呼び出せるので、対応した結果が分かるように名前が付けられます)。 「prefix」に入力の文字列を渡します。 「completion」がsuggesterのタイプの指定です。今回はCompletion Suggesterなので「completion」を指定します。その中に「field」でcompletionに利用するフィールド名を指定します。先ほどのスキーマでcompletionタイプを指定したフィールドです。今回は「suggest_ja」になります。 「_source」は結果を見やすくするために、ヒットしたデータの一部だけ取得するオプションです。 すると、次のような結果が返ってきます。\n{ \u0026#34;took\u0026#34;: 1, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;wagah\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 5, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;『吾輩は猫である』中篇自序\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;002671\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;『吾輩は猫である』中篇自序\u0026#34;, \u0026#34;夏目 漱石\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;わが俳諧修業\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;003771\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;わが俳諧修業\u0026#34;, \u0026#34;芥川 竜之介\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;わが母をおもう\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;003997\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;わが母をおもう\u0026#34;, \u0026#34;宮本 百合子\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;わが母を語る\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;049723\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;わが母を語る\u0026#34;, \u0026#34;上村 松園\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;吾輩は猫である\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;000789\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;吾輩は猫である\u0026#34;, \u0026#34;夏目 漱石\u0026#34; ] } } ] } ] } } 「suggest」の「title-suggest」がCompletion Suggesterのレスポンスになります。 最初の「text」は入力の「prefix」の値です。「offset」、「length」もこの文字に関する情報なので特に気にしなくてもいいかと。 「options」がサジェストされた内容になります。それぞれの「text」がサジェストされた文字列になります。「suggest_ja」には著作と著者名を入れましたが、今回は著作が「text」に帰ってきていることがわかります。 次に著者名でもやってみましょう。 「太宰」という入力が来たものとしてリクエストを投げます。\nGET aozora_index/_search { \u0026#34;explain\u0026#34;: true, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: { \u0026#34;prefix\u0026#34;: \u0026#34;太宰\u0026#34;, \u0026#34;completion\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;suggest_ja\u0026#34; } } } } レスポンスは次のようになります。\n{ \u0026#34;took\u0026#34;: 1, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;太宰\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 2, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;太宰 治\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;000236\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;ア、秋\u0026#34;, \u0026#34;太宰 治\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;太宰 治\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;001572\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;I can speak\u0026#34;, \u0026#34;太宰 治\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;太宰 治\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;001578\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;愛と美について\u0026#34;, \u0026#34;太宰 治\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;太宰 治\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;046597\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;青森\u0026#34;, \u0026#34;太宰 治\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;太宰 治\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;004357\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;青森\u0026#34;, \u0026#34;太宰 治\u0026#34; ] } } ] } ] } } 先ほどとは異なり、「options」の中の個々の「text」はすべて「太宰 治」になってしまいました。 登録したデータは著作の一覧ですが、「suggest_ja」には著作と著者名を入れたためです。 これでは、実際に検索窓に実装したときに同じものが並んでしまいます。 こんな時のためのオプション「skip_duplicates」が用意されています。 先ほどのリクエストに「\u0026ldquo;skip_duplicates\u0026rdquo;: true」を追加します。\nGET aozora_index/_search { \u0026#34;explain\u0026#34;: true, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: { \u0026#34;prefix\u0026#34;: \u0026#34;太宰\u0026#34;, \u0026#34;completion\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;suggest_ja\u0026#34;, \u0026#34;skip_duplicates\u0026#34;: true } } }, \u0026#34;_source\u0026#34;: [\u0026#34;suggest_ja\u0026#34;] } するとレスポンスは次のように変化します。\n{ \u0026#34;took\u0026#34;: 1, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;太宰\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 2, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;太宰 治\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;000236\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;ア、秋\u0026#34;, \u0026#34;太宰 治\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;太宰治との一日\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;042582\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;太宰治との一日\u0026#34;, \u0026#34;豊島 与志雄\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;太宰治情死考\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;043137\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;太宰治情死考\u0026#34;, \u0026#34;坂口 安吾\u0026#34; ] } } ] } ] } } 「options」は3つに減り、重複していないことがわかります。 「text」が同じ場合は最初に出てきたものを返すようです(注意:結果から観測しているだけで、実装はまだ見ていません)。 (なお、今回は説明を省きますが、入力データでスコアを指定することも可能になっています)。 そのほかにもCompletion Suggesterにはいくつか仕組みが用意されているのですが、それはまた今度にでも。\nまとめ ということで、Luceneコミッターの打田さんに感謝です。 便利な仕組みが簡単に使えるようになるのはとてもありがたいですね。\nまずは簡単にどういうものかとどうやって使うのかを記事にしてみました。 中の動きや、注意点、これまでとの違いなどは次の記事にしようと思います。 そういえば、公式ドキュメントにはまだ出てきてないな、それを書こうと思ってついでに動かしてみたんだけど、追加するのはまた後日かな。。。\n参考資料 青空文庫 - 公開中 作家リスト:全て [LUCENE-10102] Add JapaneseCompletionFilter for Input Method-aware auto-completion - ASF JIRA Expose Japanese completion filter to kuromoji analysis plugin by mocobeta · Pull Request #81858 · elastic/elasticsearch Suggesters | Elasticsearch Guide [8.3] | Elastic ","date":1660028402,"dir":"post/2022/","id":"6639ec6f88c4976f8ca20fa840f169e3","lang":"ja","lastmod":1660028402,"permalink":"https://blog.johtani.info/blog/2022/08/09/japanese-auto-completion/","publishdate":"2022-08-09T16:00:02+09:00","summary":"風のうわさで、日本語用のオートコンプリートのためのTokenFilterとAnalyzerがLuceneに取り込まれたと聞きました(LUCE","tags":["lucene","elasticsearch"],"title":"日本語用オートコンプリートのためのAnalyzer"},{"contents":"Hugoを0.84から0.92にアップデートをする際に、これまでのブログ記事やレイアウトファイルを修正したので個人的にメモを残しておきます。\nなんでアップデート? うっかり魔がさして、メインのWSL2のUbuntuを20.04から22.04にアップグレードしました。。。 新規に22.04を落としてきて移行ではなく。 皆さんはまねしないほうがいいですよ! アップデートした後にGitの環境がおかしくなったりと大変でした。 WSL2のUbuntuではHugoでブログのビルド、いろんな確認のためのElasticsearchの起動、個人的なプログラムとかを書く環境として利用しています。\nで、Ubuntuを上げたところ無事(?)Hugoもアップデートされたわけです。 最初はGitでfetchが出来なくなって修正していましたが、そのほかの動作確認を行なう段階でHugoでブログがビルドできなくなっていることが判明しました。\nバージョンアップに伴う修正 hugoコマンドを実行すると、いくつかのERRORとWARNが出力されました。 次のようなものです。\nhugo v0.92.2+extended linux/amd64 BuildDate=2022-02-23T16:47:50Z VendorInfo=ubuntu:0.92.2-1 ERROR 2022/08/05 13:22:32 Page.URL is deprecated and will be removed in Hugo 0.93.0. Use .Permalink or .RelPermalink. If what you want is the front matter URL value, use .Params.url WARN 2022/08/05 13:22:32 The \u0026#34;tweet\u0026#34; shortcode will soon require two named parameters: user and id. See \u0026#34;/home/johtani/blog_generator/content/post/2020/2020-12-04-build_corne_choc.md:46:1\u0026#34; ... ERROR 2022/08/05 13:22:33 Failed to get JSON resource \u0026#34;https://publish.twitter.com/oembed?dnt=fa... If you feel that this should not be logged as an ERROR, you can ignore it by adding this to your site config: ignoreErrors = [\u0026#34;error-remote-getjson\u0026#34;] ERROR 2022/08/05 18:44:11 Page.UniqueID is deprecated and will be removed in Hugo 0.93.0. Use .File.UniqueID ERROR 2022/08/05 18:44:11 Page.Dir is deprecated and will be removed in Hugo 0.93.0. Use .File.Dir Page.URLなどがdeprecatedに 最初と最後2行のERRORがこちらになります。 どうやら、Pageオブジェクトの変数に変更があったようです(まだdeprecatedであり、存在はしていそう?)。 レイアウト(テンプレート)ファイルで「Previous Post」や「Next Post」といったリンクを作ったり、 Algoliaに登録するためのJSONファイルを生成するところでURL文字列を取得するために参照していました。\nログ出力でどのように変更すればよいのか?という記載があるので便利ですね。 ただ、どのファイルにこの記述があるのかはログに出てなかったので少しだけ苦労しました。\n実際には「UniqueID」という文字列でディレクトリ内を検索してあたりを付けた感じです。 利用させていただいているテーマ(Clean White)がすでにアップデートに対応されていたのでそちらが参考になりました。\nいくつか、テーマをもとに修正したテンプレートがlayoutsディレクトリにあったので、それらを修正した形です(参考のリンクはテーマのファイルになります)。\n.URLを.Permalinkに変更(参考:single.html) .UniqueIDを.File.UniqueIDに変更(参考:list.algolia.json) tweetのshortcodeの引数が増えた これまでは以下のようにIDだけで良かったのですが、userとidという2つの引数が必須になるという変更が入ったようです。\n変更前:\n{{ \u0026lt;tweet 1449214872143609860\u0026gt; }} 変更後:\n{{ \u0026lt;tweet user=\u0026#34;johtani\u0026#34; id=\u0026#34;1449214872143609860\u0026#34;\u0026gt; }} WARNにはファイル名、行番号が出力されていたので、1つずつ修正していきました。 結構な量があったので、地味に大変でした、 公開しているブログを見ながら、該当するツイートを見つけてはuserを指定していく部分が特に。 自分のツイート以外もブログに貼っていたので画一的には対処できなくて。。。\nなにかプログラムで機械的に対応ができたかもなぁ。\n鍵付きツイートによるエラー tweetのshortcode対応を行なった後でもビルドがエラーになっており、次のようなエラーが消えないままでした(エラーの一部は省略しています)。 (幸いにも)1つのツイートだけ、ブログ記事を書いた後で鍵付きになってしまった方のツイートがあったようで、ツイート用のJSONが取得できなくてエラーになっていました。\nERROR 2022/08/05 13:22:33 Failed to get JSON resource \u0026#34;https://publish.twitter.com/oembed?dnt=fa... If you feel that this should not be logged as an ERROR, you can ignore it by adding this to your site config: ignoreErrors = [\u0026#34;error-remote-getjson\u0026#34;] こちらもログに対処方法が出ています。 config.tomlにignoreErrors = [\u0026quot;error-remote-getjson\u0026quot;]を追加すれば、エラーが出力されなくなりビルドも成功するようになります。 ただ、tweet以外でもエラーが出る可能性がありそうで、その場合に、ブログに書いたつもりが一部が出力されないまま公開されそうな気がします。 なので、今回はconfig.tomlに該当の設定を追加するのではなく、ブログ記事から該当のツイートを消す対応をしました。 幸いにも、ツイートを消してもブログ記事自体には影響がありませんでした。\n.hugo_build.lockファイルが生成される これは、エラーではないのですがgit addしようとした際に、ファイルが増えていたのでどういったファイルなのかを調べました。 0.89.0から追加されたロックファイルのようです(参考:0.89.0のリリースノート)。 こちらは特に保管する必要もなさそうなので.gitignoreに追加して対処しました。\nまとめ ということで、気軽にUbuntuをアップグレードしないほうがいいですね。。。 期せずしてHugoのアップグレードができたのは良かったかもなw\n参考 【WSL2】Ubuntu 20.04.4 LTS を 22.04 LTS へアップグレードした ","date":1659689954,"dir":"post/2022/","id":"167a7c9d579ce6f2cebf64a6f6329ecb","lang":"ja","lastmod":1659689954,"permalink":"https://blog.johtani.info/blog/2022/08/05/upgrade-hugo-accidentally/","publishdate":"2022-08-05T17:59:14+09:00","summary":"Hugoを0.84から0.92にアップデートをする際に、これまでのブログ記事やレイアウトファイルを修正したので個人的にメモを残しておきます。","tags":["hugo"],"title":"Hugoをアップデートした"},{"contents":"今回はQuerqyのElasticsearchのプラグインがどんなつくりになっているか?をちょっとだけ調べてみました。 SolrでもElasticsearchでも使えるという形なので、どんなつくりになっているのかな?と思ったのが発端です。\nGitHubのリポジトリ GitHubにリポジトリが公開されています。 2つのリポジトリに分かれています。\nEs向けのプラグイン コアのライブラリ どちらもJavaのライブラリで、ビルドシステムとしてはMavenを利用しています。 コアのライブラリのリポジトリにはさらに、以下の2つが存在しています。\nlucene向けライブラリ(Solr向けのモジュールもこちらに含まれる) コアライブラリ pom.xmlを読んだところ、次のような依存関係になっています(それ以外にも使ってるライブラリはあるけど)。\nEsプラグイン -\u0026gt; Lucene向けライブラリ -\u0026gt; コアライブラリ Esプラグイン Es向けのエンドポイントの実装、Esのクエリの組み立てを行なっています。 Rewriterの実装については、Lucene向けライブラリ、コアライブラリを利用する形になります。\nquerqy用のQueryBuilderを実装しており、EsがクエリをパースするタイミングでRewriterなどを呼び出してクエリの書き換えを行う仕組みです。 なお、Es向けのクエリの組み立てと書きましたが、ほとんどLuceneのクエリの組み立てになっています(そりゃそうだ)。 実際にquerqyのクエリ組み立て処理を行っているのは、Lucene向けライブラリのQueryParsingControllerになります。 いくつかのRewriterは、生のEsクエリをルールなどとして登録することができるようになっています。 これらのクエリのパースをEs側にやらせる処理の部分もこちらで定義されている感じです。\nそのほかに、ドキュメントには記載がないエンドポイントが2つ用意されていました。 インデックスに登録してあるRewriterの設定を各ノードでキャッシュする仕組みがあって、そのキャッシュの操作(クリア、リロード)用みたいです。 これらは、Rewriterの追加、削除のアクションの内部で呼び出されているので、ユーザー側で呼び出す必要はなさそうです。\nLucene向けライブラリ Luceneに関連する処理がまとめられています。 Es内部ではLuceneを使って検索処理が行なわれるため、Luceneのクエリを組み立てる必要があります。 querqyとしてLuceneのクエリを組み立てるときに必要なクラスがこのライブラリに含まれています。\nまた、Word Break Rewriterの実装はコアライブラリではなくこちらのライブラリに実装されています。 これは、Luceneのタームディクショナリを活用したRewriterになっているため、Lucene必須となっているからのようです。 (まだちゃんと実装を見ていないので、どんな活用の仕方をしているのかまではわかっていませんが。。。)\nコアライブラリ Rewriterの設定のパース処理、クエリのリライト処理の実装がまとめられています。 querqyのクエリが、Rewriterの処理に基づいて、querqyとして定義されたクエリのモデルに一旦変換される作りになっています。 Lucene向けライブラリやEs向けプラグインはこの内部のクエリモデルになったものをもとに、Lucene向けのクエリに書き換えていくというながれになっています。\nまとめ ざっくりですが、どんな構成なのかを見てみました。 Esのプラグインとなっているのですが、プラグインではなく、外部に出すことってできるのかな?と思いつつ、なんとなくソースを読んでみました。 パターンとしては、Lucene向けのクエリからEs向けのクエリを組み立てるとかの無駄な努力が必要になる気もするけど。。。 Luceneを使っていない検索エンジンに対しては、コアライブラリをもとに、それぞれの検索エンジンむけのクエリを組み立てる仕組みを作る形になると思います。 その際、Rewriterの設定を保持する仕組み、querqyが置き換えたクエリのマッピングができるか?といった点を考える必要がありそうです。 デバッグとかするときに、EsのクエリDSLのJSONとして見れるといいなぁと思ってたけど、そんなことできるかなぁ?\n","date":1658300650,"dir":"post/2022/","id":"3384ea6bb47d70f8ca94b4510813f36a","lang":"ja","lastmod":1658300650,"permalink":"https://blog.johtani.info/blog/2022/07/20/querqy-architecture/","publishdate":"2022-07-20T16:04:10+09:00","summary":"今回はQuerqyのElasticsearchのプラグインがどんなつくりになっているか?をちょっとだけ調べてみました。 SolrでもElast","tags":["elasticsearch"],"title":"Querqyの調査(その2:アーキテクチャ)"},{"contents":"Querqyというクエリのリライト用のプラグインがあるのでどんなものかを調べてみました。とりあえずは概要をドキュメントから追いかけてみた感じです。対応しているのはSolrとElasticsearch(以降、Es)になります。手元にはEsの環境があるのでそちらで試してみました。\nなにもの? EsやSolrのプラグインで、ルールやパラメータを利用して、クエリの書き換えをEsやSolr側で行えるプラグインです。 なお、本記事ではEsのプラグインを説明します。 今回はドキュメントを読みながらメモを取った感じなので、詳細については公式ドキュメントを見ていただくのが良いかと。 手元では動作させてみましたが、今回の記事ではざっとメモを取っただけになります。\nインストール Esのpluginコマンドでインストール可能ですが、Mavenにアップロードされているバージョンは限定的なので、必要に応じて自分でビルドする必要があります。 対応しているかは、公式ドキュメントのInstallationのプルダウンが参考になります。\nどうやって使うの? Query DSLにquerqyというクエリが追加されるので、あとはドキュメントをもとにクエリを組み立てるクエリを書いていきます。 すると、プラグインが指定されたルールに従い、EsのQueryに書き換え、実際の検索が実行して結果が返ってきます。 普通にmatchなどの既存のQueryと同レベルのものになるので、既存のEsのクエリと組み合わせた使い方もできるようです。\nサンプルとして紹介されている短めのクエリ(このクエリではルールによるクエリの書き換えはない)。\nGET ecommerce/_search { \u0026#34;query\u0026#34;: { \u0026#34;querqy\u0026#34;: { \u0026#34;matching_query\u0026#34;: { \u0026#34;query\u0026#34;: \u0026#34;notebook\u0026#34; }, \u0026#34;query_fields\u0026#34;: [ \u0026#34;title^3.0\u0026#34;, \u0026#34;brand^2.1\u0026#34;, \u0026#34;short_description\u0026#34;] } } } また、書き換え(Rewriter)の設定をElasticsearchに対して保存できるエンドポイント_querqy/rewriterが用意されています。\nSynonymの書き換えを行なうサンプル(後述するCommon Rules Rewriterの設定)。\nPUT /_querqy/rewriter/common_rules { \u0026#34;class\u0026#34;: \u0026#34;querqy.elasticsearch.rewriter.SimpleCommonRulesRewriterFactory\u0026#34;, \u0026#34;config\u0026#34;: { \u0026#34;rules\u0026#34; : \u0026#34;notebook =\u0026gt;\\nSYNONYM: laptop\u0026#34; } } どんな書き換えができるの? 用意されているRewriterは2022年7月時点では次のようなものになります(がんばれば、Javaで実装すれば自作もできそう)。\nCommon Rules Rewriter Replace Rewriter Number Unit Rewriter Word Break Rewriter また、複数のRewriterをチェインして使うこともできる。記述した順番で適用されます。 それぞれのRewriterについて簡単にメモを。\nCommon Rules Rewriter シノニム、結果のブースト、フィルター、結果に対して追加情報を付与したりできます。\nrulesにルールを記載していきます。 以下のようなフォーマットになっています。 クエリが入力に合致したら、ルールが適用される形です。プロパティは後述しますが、ルールの適用する順序などをハンドリングするために使用します。\n入力 =\u0026gt; ルール ルール @プロパティ @プロパティ 入力部分に関する書式 ルールの左辺に該当する部分で、クエリに入力された文字列がマッチするかどうかで、右辺のルールを適用するかがきまります。\n入力の一致の条件は次のような感じです。 完全一致、前方一致、後方一致の使い分けが可能。ダブルクォート\u0026quot;で制御 デフォルトでは、大文字小文字の区別なし(後述するオプションで変更可能) 単語の末尾にワイルドカード*で1文字以上にマッチ。入力の最後にだけ利用可能 書き換えの命令(ルール) 右辺に利用できる命令で、次のようなものがあります。\nSYNONYM 同義語展開するための命令です。Synonym Token Filterとの違いは、複数のルールを同時に適用できます。 フィールドに依存しない設定なのでメンテナンスが楽になるとのこと。 ただし、双方向の設定はないため、例えば\u0026quot;personal computer\u0026quot;と\u0026quot;pc\u0026quot;の場合、2つの設定を個別に定義する必要があります。 また、ステミングなどには未対応なので、\u0026ldquo;personal computers\u0026quot;も対応する場合はこれも追加する必要があります。 類義語ごとに重みを変えることが可能になっています。同列ではなく、同義語のスコアを下げるなどで、リコールを増加させつつ、入力語のスコアを上位にすると行ったことが可能です。\nUP/DOWN 入力文字列がマッチした場合に、追加のクエリを正か負のブーストをしつつ追加できます。 例えば、「iphone」と検索された場合に、「apple」もクエリとして追加しつつスコアをブーストし、「case」のクエリをスコアを下げるように追加できます。 これにより、アクセサリーではなく本体が検索結果の上位に出てくるような仕組みを提供できます。\nFILTER UP/DOWNではクエリとして追加されていたが、こちらはフィルターとして追加されます(=スコアで調整ではなく、結果から除外される)。\nDELETE クエリからキーワードを削除できます。 単語自体をそのまま削除することも、入力された単語に合わせて他の単語を削除することもできます。\nDECORATE 2022年7月時点でEsでは利用不可で、Solrのみで利用可能です(なので読み飛ばしました)。\nプロパティ 各ルールの設定にタグをつけられるような機能です。 このプロパティを利用して、ルールのソートやフィルタリングなどが可能になります。 複数のルールにクエリがマッチした場合に、優先度が最高のものだけを適用したり、プロパティに特定の値を持っているものだけを採用したりできます。 なお、プロパティは命令のあとに記述する必要があります(パーサーの関係かな?)。\nReplace Rewriter クエリタームの置き換え用のRewriterです。クエリの正規化処理として、他のRewriterの前処理に利用したりできます。 サンプルではタイポの修正などに利用したり、不要な語の除去などがあげてありました。\nWord Break Rewriter クエリトークンを分解・結合します。 たとえばドイツ語は、複合語と呼ばれる個別の意味の単語を結合した1つの単語を持っているため、個別の意味に分解して検索すると便利なことがあります。 そういった単語を辞書を基にして分割できるようにする機能です。 辞書とは実際のインデックスのタームディクショナリのことと思われます(要調査。どのインデックスのフィールドを指し示すのかなど、設定とドキュメントではよくわからない)。 なお、利用可能な形態素解析を基にした実装はドイツ語のみとなっており、また、分解の時には形態素解析を考慮しますが結合時には考慮しません。\nNumber-Unit Rewriter クエリの数値と単位を判別し、対象となるフィールドにマッチさせます。範囲での一致や完全一致やブーストが可能です。 単位をもとにして、特定のフィールドに対する数値のクエリに書き換えることができます。\nShingle Rewriter Solrのみで利用可能なので読み飛ばしました。\nルールはどこに保存されるの? .querqyというインデックスが内部で作成され、そこに保存されます(公式ドキュメントより)。 (ちなみに、Mappingはこんな感じみたいです)。 現状、プラグインでは設定したRewriterの取得ができないようなので、自分で登録した設定がどんなものかは、このインデックスを検索する必要がありそうです。\n気になった点・改善点? 気になった点があったので。\nRewriterのエンドポイントは、登録・更新・削除のみ対応しており、登録したものの確認は直接インデックスを見に行くしかなさそうです(Issueは作られてた)。 [要検証]書き換えられたクエリがどんなものか?は残念ながら確認できなそうで、_validate/queryで最終的なLuceneレベルのクエリで確認するしかなさそう? スキーマ側で定義したものと、Querqyで定義したものの兼ね合いがどういう形になるのか?などを気にする必要があるのが注意点かも。組み合わせたときの副作用などがどんなことになりそうか?が予測がつきにくそう。 Rewriterの定義自体のテストはどうしたものか? まとめ とりあえず、ざっとドキュメントを見ながらメモを取った感じです。 設定などの記述が独自のものなので、そこに慣れていく必要がありそうです(特にルールの改行の部分とか)。 次は実際にどんな感じで使えそうか、既存の仕組みとの違いは?みたいなところをもう少し見ていきたいとおもいます。\n参考文献 querqy/querqy: Query preprocessor for Java-based search engines (Querqy Core and Solr implementation) Getting started with Querqy — querqy.org documentation ","date":1658285563,"dir":"post/2022/","id":"779e444b4bc720a9eed97f19c41e8773","lang":"ja","lastmod":1658285563,"permalink":"https://blog.johtani.info/blog/2022/07/20/intro-querqy/","publishdate":"2022-07-20T11:52:43+09:00","summary":"Querqyというクエリのリライト用のプラグインがあるのでどんなものかを調べてみました。とりあえずは概要をドキュメントから追いかけてみた感じ","tags":["elasticsearch"],"title":"Querqyの調査(その1)"},{"contents":"今年もBerlin Buzzwordsにオンライン出張してました。 今年はハイブリッドな開催だったようで、現地で再開している人もいるようでした。 ブースもあったみたいです。ちなみに、現地で参加する人はマスク必須のようでした(Health \u0026amp; Safetyというページが用意されていました)。 昨年オンラインだったMICESは現地のみでの開催みたいで見ることはできなかったです(録画公開されないかなぁ)。\nさて、いくつか見たセッションで面白かったものがあったので簡単にメモを。 すでにセッションのビデオがYouTubeで公開されているので、興味のある方は見てみてください。\n面白かったセッション The future of Lucene\u0026rsquo;s MMapDirectory: Why use it and what\u0026rsquo;s coming with Java 19 and later? セッションページ: The future of Lucene\u0026rsquo;s MMapDirectory: Why use it and what\u0026rsquo;s coming with Java 19 and later? :: Berlin Buzzwords 2022 動画:Uwe Schindler – The future of Lucene\u0026rsquo;s MMapDirectory: Why use it \u0026amp; what\u0026rsquo;s coming with Java19 \u0026amp; later - YouTube 毎年恒例になってる気も? 前半は昨年も話をした内容で、後半はJava 19がリリースされたら、Previewという形でフラグを立てて使えるようになるようです。 使えるようにするから、テストしてみて!という感じで終わっていますw\nScaling an online search engine to thousands of physical stores セッションページ:Scaling an online search engine to thousands of physical stores :: Berlin Buzzwords 2022 :: pretalx 動画:Aline Paponaud – Scaling an online search engine to thousands of physical stores - YouTube 数千の実店舗の商品をオンラインで検索できるようにしつつ、オンラインのマーケットプレイスのような検索も一緒にできるようにしたというお話でした。 インデックスの構成をどう工夫したのか?とかどういうクラスター構成にして、どんなことをモニタリングしてるよ?というお話です。 実際の店舗がどんなものかなどは出てこなかったので、少しイメージは沸きにくかったのですが、どんなことを考えながらインデックスの構成とか考慮したよという話はおもしろかったです。 実際に検索したときに、実店舗のデータがどんな感じで結果として表示されたりするのか?といった点はわからなかったので、そのあたりの話をもうちょっと聞いてみたかったなぁ。\nOffline Ranking Validation - Predicting A/B Test Results セッションページ:Offline Ranking Validation - Predicting A/B Test Results :: Berlin Buzzwords 2022 :: pretalx 動画:Andrea Schütt \u0026amp; Yunus Lutz – Offline Ranking Validation - Predicting A/B Test Results - YouTube otto.deというECサイトでのランキングをどうやって改善していくか?という話。 現在はマニュアルなチューニングをコンテキストごとにやっているけど、リクエスト量とかデータとかが増えてきてて、このままマニュアルで改善していくのも大変なので、 モデルベースのランキングを開発できないか?というのをはじめていますよと。 そのために、これまでのデータから、A/Bテストの結果を予測できるモデルが作れないか?というのをやっていますという話。 いくつかわからない単語も出てきたので、誰か詳しい人教えて!\nAI-powered Semantic Search; A story of broken promises? セッションページ:AI-powered Semantic Search; A story of broken promises? :: Berlin Buzzwords 2022 :: pretalx 動画:Jo Kristian Bergum – AI-powered Semantic Search; A story of broken promises? - YouTube Vespaの開発にかかわってる方の、Semantic Searchに関する話。 Semantic Searchが流行り始めていて、どうやればできるのか?という話が出てきています。 けど、どういうものでどういう点に気を付けたほうがいい?という話でした。 LtRってこんなもの、そのあとに出てきたLLM(Large Language Model)でどうやって検索の改善に使えるの?というのが分かりやすく説明されていました。 それらの説明の後、BEIRという論文を紹介しつつ、LLMを使うときの注意点の話がありました。\nBERTとかをちょっと勉強してたのもあり、なんとなくそうだよなぁと思っていた結論と同じ結論が出てきたので面白いと感じました。 BEIRの論文は時間を見つけて読んでみないとな。\nHybrid search \u0026gt; sum of its parts? セッションページ: Hybrid search \u0026gt; sum of its parts? :: Berlin Buzzwords 2022 :: pretalx 動画:Lester Solbakken – Hybrid search: Greater than the sum of its parts? - YouTube こちらもVespaの人の話。 先ほどのSemantic Searchの話では、Semantic Searchがどんなものか?という話でした。 が、それだけで検索ができるわけでもないので、キーワードサーチとSemantic Searchの両方をうまく活用するには?というのがこのセッションでした。 最終的にはVespaを使うとうまくハイブリッドできるよという話ですが、考え方は参考になるかなと。 Vespaも触ってみたいなぁ。\nThe life of a search engine administrator セッションページ:The life of a search engine administrator :: Berlin Buzzwords 2022 :: pretalx 動画:Lucian Precup \u0026amp; Vincent Bréhin – The life of a search engine administrator - YouTube 検索システムの管理者ってどんなことやるの?それにはどんなことができるツールがあるといいの?という話です。 まぁ、ツールについてはこの会社の人たちのツールの宣伝なのですが、検索システムを作って育てていくのにどんなことを考えたりするのか?という参考になるかなぁと。\nShould we stop using distance in our location-based data recommendation models? セッションページ:Should we stop using distance in our location-based data recommendation models? :: Berlin Buzzwords 2022 :: pretalx 動画:Charlie Davies – Should we stop using distance in our location-based data recommendation models? - YouTube TravelTimeという会社を立ち上げた人の話。 位置に関する情報って重要だし、検索するときに利用しますよね?例えば、ホテル決めたりとか、仕事探したりするときに。 ということで、位置情報を検索エンジンで利用する方法(Bounding Box、ポリゴン、距離)をまず紹介して、どんなユースケースで使えるかという話があります。 また、それとは別に検索速度(いかに検索を速く返すか)も重要だという話があります(ウォルマートはページロード時間を1秒早くしてコンバージョンが2%あがったとか)。 で、実際に検索結果に距離とかでるけど、実際に知りたいのはどのくらいの時間で行けるのか?という話だったりしませんか?と。 公共交通機関を使ったりする場合に、実際に45分で移動できる距離というのは半径5マイルとかできまるものではないのに、単純に位置情報を利用した距離だけでソートしていいの?という問いかけから、 その辺を考慮した検索ができるAPIを開発しているよ、検索速度もはやいよというお話でした。 残念ながら具体的にどうやって作っているのか?というのはなかったですが、観点がおもしろかったです。\nWord2Vec model to generate synonyms on the fly in Apache Lucene セッションページ:Word2Vec model to generate synonyms on the fly in Apache Lucene :: Berlin Buzzwords 2022 :: pretalx 動画:Daniele Antuzi \u0026amp; Ilaria Petreti – Word2Vec model to generate synonyms on the fly in Apache Lucene - YouTube Word2Vecのモデルを使った、Apache LuceneのSynonym Filterを開発中だよという話 DeepLearning4Jを使ってみたが、遅くて使えなかったんだけど、最近Luceneに入ったkNNを使うことでそれなりの速度で使えそうなものができるかもよ?って感じでした。 モデル学習用のツールも作ってて、イタリア語のWikipediaで学習したものでちょっと動かしたらそれっぽい感じになってるという話でした。 まだ途中でいくつかやりたいことがあるという話で、実用はまだ先のようでした。例えば、1単語のSynonymにしか対応してないとか、モデルをインメモリでしか動かせないとか。\nQAでも出たのですが、Word2Vecだと対義語も類似していると判定されてしまうと思うので、その辺がどうなっているのかなぁ?という疑問があります。 ルールベースの類義語ではないので、調整するのはどうやるのかなぁ、学習用のコーパスをいい感じにするとかなのかな?とか、気になるところです。\nNrtSearch: Yelp’s fast, scalable, and cost-effective open source search engine セッションページ:NrtSearch: Yelp’s fast, scalable, and cost-effective open source search engine :: Berlin Buzzwords 2022 :: pretalx 動画:Umesh Dangat – NrtSearch: Yelp’s fast, scalable, and cost-effective open source search engine - YouTube YelpがLuceneベースで開発をしているNrtSearchというOSSの話です。 Elasticsearchを使っていたんだけど、どういった点が問題点になってどういうモチベーションでNrtSearchを開発したのか?を説明しています。 アーキテクチャがどんなもので、実際に動かしてみてどんな利点があって、どんな点が問題として出てきているか、将来どんなことをやろうとしているかがわかります。 QAでもいろんな質問が出ていて面白いです。\nまとめ ということで、簡単でしたがセッションの感想でした。 Neural/Semantic Searchというのがセッションのタイトルなどに入っているのが多くなってるなぁという感想です(ちょっとやってみたい気はしてるんだよなぁ)。 すでにYouTubeに動画が公開されているので興味があるセッションを見つけてみてください。 Berlin Buzzwordsの次の日に開催されたMICESも観てみたかったですが、オンラインでも参加できる形式で海外のカンファレンスが開催されるのはとても助かりますね(ヨーロッパだと時差もそれほど大変じゃないし)。 けど、落ち着いたらまたオフラインで参加してみたいなぁ。\n","date":1655283615,"dir":"post/2022/","id":"f56c19442484b3e4f47875b58b3f72b2","lang":"ja","lastmod":1655283615,"permalink":"https://blog.johtani.info/blog/2022/06/15/ttend-berlin-buzzwords-online/","publishdate":"2022-06-15T18:00:15+09:00","summary":"今年もBerlin Buzzwordsにオンライン出張してました。 今年はハイブリッドな開催だったようで、現地で再開している人もいるようでした。","tags":["conference","berlin buzzwords"],"title":"今年もオンラインでBerlin Buzzwordsに参加した"},{"contents":"7.16で正式リリースされましたが、Elasticsearchの新しいJavaのクライアントが出ています。 使ってみたので、ちょっとだけ紹介でもしてみようかな。\nこのクライアントが出るまでは、ElasticsearchのJavaクライアント(REST版)はElasticsearch本体の一部として実装・管理されていました(Elasticsearchのリポジトリにあるclientディレクトリ)。\nHTTP経由でElasticsearchにアクセスするクライアントだったのですが、Elasticsearch本体のリポジトリで管理されていることもあり、Elasticsearch本体で利用されているクラスを使用していました。 このため、クライアントライブラリなのですが、Elasticsearch本体のJarが必要になりサイズが大きくなっていました。 また、JavaのObjectへの詰め替えなどの機能も備えておらず、すこし古臭い感じでもあります。 この辺りを刷新する目的もあり新しいクライアントが公開されたようです。 3月くらいに触った時はまだ、ドキュメントが揃ってなかったのですが利用方法などが増えているので移行も楽になってきているようです。 根本的に作り直されたため、これまでのREST Clientとは使い方が違います。ですので、jarだけの差し替えでこれまで動いていたプログラムを移行ができるわけではないので注意が必要です。\nどの辺が便利? 順次移行が可能 これまでのRESTクライアントとはパッケージ名もjarも別モノになっています。 ですので、少しずつ新しいJava Clientに切り替えていくことが可能になっています。 根本的に使い方が変わっているので、大きなシステムのクライアントを全部切り替えるのは結構大変かと思います。 ですので、Indexをしている部分だけとか、検索部分だけなどといった部分的な置き換えをしつつ新しいクライアントに慣れていくことができます。\nラムダっぽく書ける 検索のクエリのサンプルを見るとわかりますが、こんな感じでクエリが書けます(公式ドキュメントより抜粋)。\nSearchResponse\u0026lt;Product\u0026gt; response = esClient.search(s -\u0026gt; s .index(\u0026#34;products\u0026#34;) .query(q -\u0026gt; q .match(t -\u0026gt; t .field(\u0026#34;name\u0026#34;) .query(searchText) ) ), Product.class ); また、最後で渡しているProduct.classは、検索結果をどのクラスのインスタンスにして返すかの指定です。 Elasticsearchのレスポンス(JSON)から値をコピーして返してくれるようになっています。 ですので、値を入れ替える処理を書く必要がなくなっています。\nJSON文字列をそのまま使える 触り始めてからリリース(7.17.2より後なら使える)された、JSON文字列からリクエストを作る機能もあります。\nこれまでのREST Clientだと、Elasticsearchへのリクエストを必ずJavaのメソッドで構築する必要がありました。 今回のこの機能を利用すると、JSON文字列(やファイル)からリクエストオブジェクトを作るためのメソッド.withJson()が提供されています。 例えば、スキーマや設定変更用のリクエストのJSONなどは、Kibanaやcurlから試験的に投げたリクエスト(JSON)と同じものを使いたいことが多いです。また、ElasticsearchのAPIは数が多く、ドキュメントを見ながら利用方法を調べてJSONでまず試行錯誤することが多いです。 このwithJsonメソッドを利用することで、動作確認などをしたJSONがそのままソースにも利用できるので、リクエスト変更時の確認なども容易になると思います。\n使ってみて困ったのは? 便利な面も多いのですが、使っていて少し困ったこともあったのでそれもメモを残しておきます。\nどんなリクエストを投げているかが不明 先ほども書きましたが、Elasticsearchのリクエストを試行錯誤するときは公式ドキュメントを見ながら、Kibanaなどを利用して試すことが多いです。 ですので、自分がやりたいことのJSONは手元にあることが多いです。 ただ、プログラムでクエリを組み立てる必要も出てきます。この時、実際にRESTリクエストとしてどんなJSONを投げているのかを知りたいことがあります(実際、検索クエリ作っててメソッドの使い方がうまくいかなくて四苦八苦してました)。 4月時点では簡単にリクエストで投げているJSONを文字列としてログに出すメソッドなどは用意されていないようでした。 デバッグ用に次のようなメソッドを書いてみました。 Elasticsearchへ投げるRequestのクラス(例:CreateTemplateRequestとか)を引数に渡すことで、JSON文字列に変換できるようになっています(StringWriterに書き出されてる)。 ここのLoggerはサンプルです。writer.toString()で取り出せる文字列がJSON文字列になっているので、ログに出してみるなり、ファイルに落とすなりしてデバッグのお供にしてください。\nimport java.io.StringWriter; import co.elastic.clients.elasticsearch._types.RequestBase; import co.elastic.clients.json.SimpleJsonpMapper; import jakarta.json.stream.JsonGenerator; ... private void printRequestBodyJsonForDebug(RequestBase request) { //for debug Logger.log(\u0026#34;** Debug print start **\u0026#34;); StringWriter writer = new StringWriter(); SimpleJsonpMapper mapper = new SimpleJsonpMapper(); JsonGenerator generator = mapper.jsonProvider().createGenerator(writer); mapper.serialize(request, generator); generator.close(); Logger.log(writer.toString()); Logger.log(\u0026#34;** Debug print finish **\u0026#34;); } プラグインなどで提供されるクエリが書けない LtRプラグインなどは、Elasticsearchの検索クエリを拡張しています。 残念ながら、現時点(2022/06/13)ではカスタムクエリを新しいJavaクライアントで利用しようとした場合、エラーが発生してしまいます(知らないJSONだと判断されてしまいます)。\nGitHubのIssueとして「[roadmap] Add support for plugin-defined custom components · Issue #252 · elastic/elasticsearch-java」があります。 これに対応されたら、拡張されたクエリも利用できるようになるでしょう。 プラグインなどで拡張されているものを使いたい場合は、残念ながら既存のRESTクライアントを当面は使うことになりそうです。\nまとめ 新しいElasticsearchのJavaクライアントを簡単ですが触ってみて、気になった点を記事にしました。 JavaのObjectに詰め替えてくれる機能など便利になっているので使ってみてください。 ドキュメントもちょっとずつ増えているようで、使い方も分かりやすくなっていました(触った時はレスポンスの扱い方などがJavaDocしか用意されてなかったんです)。 説明が欲しいなぁと思うことがあれば、GitHubにIssueを上げてみるといいかもです。\n参考 公式ドキュメント Java Clientチームの人がカンファレンスで利用したスライド ","date":1655119446,"dir":"post/2022/","id":"5eebdf85fd1726db301194bfeeee4377","lang":"ja","lastmod":1655119446,"permalink":"https://blog.johtani.info/blog/2022/06/13/new-elasticsearch-java-client/","publishdate":"2022-06-13T20:24:06+09:00","summary":"7.16で正式リリースされましたが、Elasticsearchの新しいJavaのクライアントが出ています。 使ってみたので、ちょっとだけ紹介で","tags":["elasticsearch","java"],"title":"Elasticsearchの新しいJavaクライアント"},{"contents":"Azure Cognitive Searchで2月に新しい機能が公開されました。 「Index Alias」(インデックスの別名)です。まだ、パブリックプレビューの段階ですが、ドキュメントなどが公開されていたのでどんな機能かを調べてみました。なお、本ブログの内容は2022/05/18時点での内容となります、ご注意ください。\n公式ドキュメント まずは公式ドキュメントです。1つ目の「インデックスの別名を作成する」の冒頭で別名(エイリアス)がどんなものかを説明しています。\nインデックスの別名を作成する - Azure Cognitive Search | Microsoft Docs エイリアスの作成または更新 (2021-04-30-Preview) - Azure Cognitive Search | Microsoft Docs Alias Operations (2021-04-30-Preview) - Azure Cognitive Search | Microsoft Docs REST APIのドキュメント(2022/05/18現在、日本語のページだと左のメニューが壊れているため、どんなAPIがあるかがわかりにくいため、Alias Operationsのページは英語のリンクになっています)\nインデックスエイリアスってどんなもの? 文字通り、インデックスにエイリアス(別名)をつけることができるようになります。 Azure Cognitive Searchでは残念ながらインデックスを作成するタイミング以外ではインデックスの名前を変更できません。 このため、インデックスのスキーマ(Analyzerの設定変更など)を変更したい場合、新しいインデックスを作成します。 新しいインデックスの名前はこれまでのものとは別の名前になってしまうため、アプリケーションで指定しているインデックス名も書き換える必要が出てきます。 利用しているアプリが複数ある場合は、すべて変更が必要です。\n今回出てきたエイリアスを利用することで、アプリケーションではエイリアスを指定することで、アプリケーション側の変更なくインデックスを入れ替えることができるようになります。\nエイリアスの操作方法 公式ドキュメントにAPIの一覧や利用方法の記載があるので詳細はそちらをご覧ください。 本ブログでは、いくつか利用するときに気になった点を書き残しておきます。\n作成 aliasesというエンドポイントにエイリアスの名前とインデックス名をPOSTすることで作成できます。 以下のサンプルは公式ドキュメントの例です。\nPOST /aliases?api-version=2021-04-30-preview { \u0026#34;name\u0026#34;: \u0026#34;my-alias\u0026#34;, \u0026#34;indexes\u0026#34;: [\u0026#34;hotel-samples-index\u0026#34;] } ちなみに、インデックスの指定がindexesで配列になっていますが、公式ドキュメントに以下の記述があり、複数の指定はできないです(エラーが返ってきます)。\nindexes 配列に指定できるインデックスの名前は 1 つだけです。\nまた、1つのインデックスに対して複数のエイリアスをつけることは問題ありません。\n確認 エイリアスのリストも取得できます。\nGET /aliases?api-version=2021-04-30-preview 現在どんなエイリアスが、どのインデックスに対して付与されているかがリストで取得できます。 きちんと作成されたかどうかなどの確認にも使えるかと思います(もちろんエイリアス名を指定したGETも可能です)\n検索での利用 検索のREST APIでインデックス名を指定していた部分をエイリアス名に置き換えるだけです。\nPOST /indexes/my-alias/docs/search?api-version=2021-04-30-preview { \u0026#34;search\u0026#34;: \u0026#34;pool spa +airport\u0026#34;, \u0026#34;searchMode\u0026#34;: any, \u0026#34;queryType\u0026#34;: \u0026#34;simple\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;HotelId, HotelName, Category, Description\u0026#34;, \u0026#34;count\u0026#34;: true } 更新 エイリアスの更新(インデックスの入れ替え)は作成と同じリクエストです。 更新が成功すれば204のステータスコードが返ってきます(エイリアス初回作成時は201) なお、ドキュメントには以下のような記述があります。入れ替え時の注意点になるかと(入れ替えのタイミングをきちんと制御したい場合は、少しだけアプリケーションを停止するなどが必要かと思います)。\n別名に対する更新がシステムに反映されるまでに最大 10 秒かかります。以前その別名が対応付けられていたインデックスを削除するのは、10 秒以上待ってからにしてください。\n削除 もちろん削除もできます。\nDELETE /aliases/my-alias エイリアスを利用する場合の注意点 便利なエイリアスですが、エイリアスが使用できない場合もあるので注意が必要です。\nデータ登録のAPIと検索のAPIでのみエイリアス名を利用可能 インデックスの設定変更やAnalyze Text APIではこれまで通りインデックス名を指定します。 また、エイリアス名はインデクサー機能でtargetIndexNameにも指定できません。 エイリアス名がついているインデックスは削除不可 エイリアスがついているインデックスを削除しようとした場合はエラーが出るようになっています。 まずはエイリアスを削除してからインデックスを削除するという手順になります。 まとめ 簡単ですが、インデックスのエイリアスに関しての紹介でした。まだパブリックプレビューなので正式リリース時点では利用方法が変わっている可能性もあります。こちらは注意してください。\n正式公開されればですが、今後Azure Cognitive Searchを使ったアプリを開発する場合はインデックスエイリアスを利用することを基本にするのがいいかもなと思います (ちなみに、Elasticsearchにもインデックスエイリアスの機能がありますが、異なる点が多いので同じものとは思わないほうがよさそうです)。\n","date":1652856857,"dir":"post/2022/","id":"7cc21814165879f72529e91682ece5c6","lang":"ja","lastmod":1652856857,"permalink":"https://blog.johtani.info/blog/2022/05/18/index-alias-in-azure-cognitive-search/","publishdate":"2022-05-18T15:54:17+09:00","summary":"Azure Cognitive Searchで2月に新しい機能が公開されました。 「Index Alias」(インデックスの別名)です。まだ、パブリックプレビューの段階です","tags":["azure search"],"title":"インデックスエイリアス - Azure Cognitive Searchの新機能"},{"contents":"年末までに知り合いと次の論文を読んだので軽くまとめておきます。\nExtreme Multi-label Learning for Semantic Matching in Product Search なんで読んだの? 前回読んだ理由と一緒ですが、Semantic Searchに絡んだ検索の論文であり、Amazonの製品検索での話も関係していたので読みました。\nどんな論文? Amazonの製品検索でセマンティックマッチングを利用する方法、レイテンシを低くしつつ再現率を改善できるような仕組みを検討して評価した論文です。 実際には商品検索のマッチングを大規模なマルチラベル問題(Extreme Multi-label Classification:以下ではXMC問題とする)として定義して、その問題を効率よく解く方法について検討評価しています。\n検索には大きく2つのフェーズがあります。マッチング(クエリにヒットした文書の集合を求める)とランキング(マッチングのデータを関連性の高い順序で並べる)です。 前回のMSの論文では、マッチング後のランキングのフェーズで言語モデルを利用した並び替えを行う話でした。 今回の論文ではマッチングに関してセマンティックサーチを有効活用できないか?という論文になります。 転置インデックスベースの(語彙による)検索では、スペルミスや類義語などを検索することが難しいです。 語彙以外のデータ(クリックや購入といったユーザーの行動や製品の意味的表現など)を学習できる埋め込みベースのニューラルモデルを活用して、マッチングを補完する方法を検討しています。 下図のようにあくまで転置インデックスベースの検索の補完として利用するみたいです(論文に掲載されていたアーキテクチャ)。\nXMC問題とは? セマンティックサーチを行なう場合、埋め込みベースのニューラルモデル(例えばBERTとか)を利用することが多いですが、 クエリトークンを埋め込み空間にベクトル化する部分が推論のボトルネック(レイテンシが高くなる)になることが多いです。 これは、ニューラルネットワークの複雑さに依存します。 低レイテンシになるように、複雑ではないエンコーダーを用いることもありますが今度は性能(精度)が良くなくなります。\nそこで、この論文ではセマンティックマッチングをXMC問題として定義し、これを効率よく解くための手法を提案しています。 ここで、XMCの問題とは、入力(今回はクエリ)に対して、最も関連性の高い複数のラベル(今回は製品)を出力することとなります。 Amazonでの製品なのでほんとに大規模(ラベル=製品=1億件)です。\n従来のXMC問題を解くための手法として、疎な線形モデルの手法、パーティションベースの手法、グラフベースの手法などが列挙されています。 疎な線形モデルの手法では、ナイーブなOVR(one-versus-rest)だと出力となるラベルの数に対して線形に推論時間も大きくなるため、今回の用途には適しません。 この論文ではパーティションベースの手法として、推論時間を短くできるツリーベースで疎な線形モデルの手法を評価しています。\nどういう仕組み? ツリーベースのモデルは次のような感じです。 PECOSのXR-Linearモデルを利用しています。 モデルに関する詳細についてはこちらの論文に詳しく載っているようです(まだ読んでいないです、、、)。\n一番上に入力として与えられるxがクエリ(ベクトル)で一番下の四角が製品にあたるラベル(Y={1,...,l,...L})です。 これらが与えられたときに最も関連性の高い上位k件のラベル(製品)を出力するモデルを生成します。 モデルのパラメータは、学習データとして(x, y)(ここで、y∈{0, 1}^𝐿、すなわちクエリに製品がマッチするかしないかの二値)を使って調整します。\nこれは、ツリーのそれぞれの階層のノードで、その下の層に関連するデータがあるかどうか?という分類を学習すればよいことになります。 学習データとしては、入力と最下層のラベルにマッチするかどうかというデータです。 これをもとに、ツリーの最下層のデータをもとにひとつ上の層の分類器の学習をすればよいことになります。\n推論は出来上がったツリーベースのモデルに対して、ビームサーチで行ないます。 この時、それぞれの層のノードの分類器では推論の効率化のために枝刈りの閾値を設定しています。 本論文で閾値の違いによる精度とレイテンシの比較も行われています。 また、ビームサーチのビームサイズを変化させた場合の性能についても実験しています。\nどうやって検証した? 次のようなデータを用いてAWS上にモデル構築、推論のシステムを用意し実験しています。\n10億件以上のポジティブなクエリ-商品ペアのデータセット クエリ:2億4千万、商品:1億 ポジティブなペアとは、クリック数や購入数の集計値が閾値以上。ただし、データセットとしては集計値は利用していない。 トレーニングセット:12か月分の検索ログ 評価用テストセット:1か月分の検索ログ(12%の製品はトレーニングセットには出てこない) というデーセットをもとに上記のモデルを学習しています。 特徴量はクエリテキストと製品のタイトルをもとにTF-IDFをいくつかのパターンで導出したものが使われています。 詳しくは論文の結果に関する表などを見ていただくとして。。。\n結果として、1億件の商品カタログで60.9%のRecall@100を1.25ミリ秒/リクエストという低レイテンシで達成したとなっています。\n気になる点は? 知り合いと3人で読んでいて次のような気になる点が出てきました。\nツリーの構築をするときに、製品のラベルの並び順(製品のクラスタリング?に他製品が似た場所に来る感じ)が推論の効率の良し悪しに影響するんじゃないの?=Amazonではないところではうまくいかない? PECOSの論文読まないといけない? 製品が増えたときにモデルの組み換えとかどうするの? コールドスタート問題という形で今後の課題として書かれていたので、今後に期待 転置インデックスでのマッチングの補完として利用しているということだったけど、ランキングはどうしてるんだろう? 別のランキング用の指標があるのかな?上位k件とした場合にどうやって、決めているのか? モデル更新のタイミングはどのくらいのスパンなんだろう? まとめ&感想 セマンティック検索の処理を分類問題に置き換えてその手法を用いて行い、実際のシステムに適用できそうな速度と精度を出しているのが面白かったです。 セマンティック検索にもいろんな手法があるのだなと(そして、いろいろ勉強しないといけないんだなと。。。)。\n気になる点にも書きましたが、ツリーの作り方になにかコツがあるのか?他の検索結果と組み合わせるときに、どのような基準で上位を選択しているのか?など疑問点も残っています。 個人的には特にどのように既存のシステムにくっつけていくのかというところが気になっています。 論文の続編でその辺の話が出てくるのかなぁ?\nツリーの作り方に関するPECOSの論文を誰か解説してくれると嬉しいかもなぁと思いつつ、とりあえずブログに書き残してみました。参考になるかなぁ。。。\n参考文献 Extreme Multi-label Learning for Semantic Matching in Product Search - ACM Extreme multi-label learning for semantic matching in product search - Amazon Science PECOS: Prediction for Enormous and Correlated Output Spaces 数えきれないほどの分類を行うExtreme Classification - Technical Hedgehog ","date":1641980462,"dir":"post/2022/","id":"0645bdb1cdf88ec74288d503eb71839c","lang":"ja","lastmod":1641980462,"permalink":"https://blog.johtani.info/blog/2022/01/12/reading-xmc-for-semantic-search-in-prod/","publishdate":"2022-01-12T18:41:02+09:00","summary":"年末までに知り合いと次の論文を読んだので軽くまとめておきます。 Extreme Multi-label Learning for Semantic Matching in Product Search なんで読んだの? 前回読んだ理由と一緒ですが、Semantic","tags":["search","paper"],"title":"Extreme Multi-label Learning for Semantic Matching in Product Searchという論文を読んだ"},{"contents":"今年も振り返りブログです。録画した紅白をオッかけ再生して気になるアーティストだけ見ながら書ています。\n振り返り(2020年に書いた抱負から) まずは去年の抱負を元に書きます。今年もコロナウィルスの影響が年末まで続き、ほとんどで書けなかったです。\nフリーランス継続? ありがたいことに個人事業主として無事1年を終えられました。 夏頃は5社ほどお手伝いをさせていただき、年末時点では3社をお手伝いさせていただいています。\n昨年の振り返りで書いた2社はありがたいことに継続していただいています。\n今年も完全リモートで仕事が終わりました。オミクロン株が来ているし、来年春くらいにはミーティングに出かけられるかなぁ。 相変わらず検索のお手伝いをしています。手伝いをしつつ勉強させていただいている感じです。 ありがたし。\nプログラミング ちょっとペースダウンしています。。。\nextract-kana-java 新しく書いたのはこれくらいかな。 SudachiやNeologdのkuromojiでフリガナを出力して違いを見るというコマンドツールです。 ちょっと比較してみたくなったので書いて公開しました。\nあとは、Sudachiをいろいろと触り始めています。 来年はそのへんをもうちょっと何かできるかなぁ。 コーディングしないとよくないなぁと思っているので、強制的になんかやらないとだ。\n検索の勉強 仕事でやってます。ブッチャー本は昨年買って手を付けてませんが。。。 来年は少しずつやる予定です。 あとは、Azure Cognitive SearchのSemantic Searchを触った関係でSemantic Searchに関する論文を探してちょっとずつ読んでいます。 知り合いと読んでいたAmazonの論文をブログにまとめるのは来年早々に。。。\n検索のポッドキャスト? これはできませんでした。重い腰が上がらない。 公開しないまでも雑談したいなぁ。\n振り返り(今年あったできごと) ここからは今年の出来事を。\n自宅環境 キーボード以外もDIY 検索Slack爆誕 車買い替えた WindowsノートPC買った 今年もずっと自宅で仕事でした。 昨年だいぶそろえていたのでそれほど変更はないですが。\n2月バージョン 切り替えてからずっとWindowsです。Macもブラウズ用に使ってはいますが。 ただ、Windowsといっても、プログラムなどに関する環境はほぼWSL2になっています。コマンドプロンプトは触ってないなぁ。 今年最後に更新された自宅環境は椅子になります。 詳しくは昨日のブログをご覧ください。\nキーボードもDIYしましたが、今年はほかにも少しDIYしました。\n今年のDIYキーボードとコントローラーラック このブログにも書きましたが、来年はキーマップやファーム関連を触っていきたいなと。あとロータリーエンコーダー。。。 BLE化は快適で、3台のPCの切り替えがとっても便利です。\ntakuya_aさんの鶴の一声で検索のSlackが爆誕しました。 検索に関連する情報交換ができる場として楽しませてもらってます。 年末には検索100本ノックの話が立ち上がってきています。 来年も面白い話が聞けそうでワクワクしています。\nあとは、車を買い替えました。初のハイブリッドです。 まだまだ慣れないですが、燃費とかがとても楽しみです。\n結局まだ出かけていませんが、出かけられるようにFMV Zeroを購入しました。 このブログもリビングでFMV Zeroで書いています(まだちゃんとセットアップしていないので、実際にはリモートデスクトップでデスクトップにつないでそこのVSCodeで書いちゃってますが。。。)。 ブログ書いたりコード書ける程度の環境は作らないとな。\n来年の抱負 ということで、来年の抱負です。\nフリーランス継続 プログラミング ブッチャー本ちゃんと読む 読んだ本のブログを書く 今年もありがたいことに仕事を継続していただけて、乗り越えられました。 来年も価値を提供できるように頑張っていきます。\nプログラミングは失速気味のでなにかテーマを見つけないとなあ。\nブッチャー本は読み始めます。必ずw\nブログのペースが落ちていたり、本を読むペースが落ちているので、 本を読んで自分のためにもブログを書こうと思います。 書いてないって思ったら叱咤してください。。。\n今年も出かけられませんでしたが、仕事も安定してあり、無事乗り切れました。 人と話をする機会は減っているので雑談したいな、オンラインなどで。 相手をしてやってもいいぞという方はぜひ連絡ください。\nさて、来年(もう年あけちゃったけど)は出かけられるかなぁ。 何はともあれ、今年もよろしくお願いします!\n","date":1640957359,"dir":"post/2021/","id":"104b8ee17a8bf1f7043d236659680493","lang":"ja","lastmod":1640957359,"permalink":"https://blog.johtani.info/blog/2021/12/31/looking-back-2021/","publishdate":"2021-12-31T22:29:19+09:00","summary":"今年も振り返りブログです。録画した紅白をオッかけ再生して気になるアーティストだけ見ながら書ています。 振り返り(2020年に書いた抱負から) ま","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2021)"},{"contents":"2021年もあと少しですが、今年買って良かったものをリストアップしておこうかと思います。 今年買ったといいながら、昨年このネタを書くといいつつ書いてないので、昨年の分も入っているかも? Amazonのアフィリンクを貼っていますが、急いでないものはAliExpressで購入したりもしています。\n象印のポット Amazon | 象印 電気ケトル 1.0L コーヒードリップ用機能付き ホワイト CK-AX10-WA | 象印マホービン(ZOJIRUSHI) いわゆる電気ケトルというやつです。これが来るまでは鍋で湯を沸かしていました。 水を入れてボタンを押し、湯を沸かしている間に他のことができるのはやはり便利です。 また、コーヒーを入れるためのコーヒードリップモードがあるので、ドリップするためにわざわざ湯を他のものに入れたり、 専用のヤカンを使わなくても簡単にドリップができるのがさらに便利で重宝しています。\nウォータードリップコーヒーサーバー Amazon | iwaki(イワキ) コーヒーサーバー SNOWTOP ウォータードリップ ここ数年、冬以外は水出しコーヒーを飲んでいます。 麦茶のポットのような水出しコーヒー用ポットを使っていたのですが、滴下式のほうがえぐみが少ないというのを見かけてウォータードリップのサーバーに変えてみました。 このひとつ前に水のタンクの部分がプラスチックのものを利用していたのですが、ドリップする部分を壊してしまったので、部品を購入することができるこちらに切り替えました。 朝、仕事をする前に豆を挽いて仕込んでおくと、昼にはコーヒーが落ちています。 夏は入れ終わったポットごと冷蔵庫に入れておくと氷を入れなくてもアイスコーヒーが飲めるので気に入っています。\neufyの掃除機 Amazon | Anker Eufy HomeVac H11(ハンディクリーナー) USB充電 仕事に使っている机でプラモデルを作ったり、DIYキーボードの工作をしたりと細かなごみが出る作業を行ないます。 ちょっとごみを吸いたいだけなのに、掃除機を毎回取りに行くのも面倒なので充電式のクリーナーを買ってみました。 仕組みも簡単だし、USBで充電できるのでおすすめです。アタッチメントを利用してキーボードの掃除なんかもしています。\n電動精密ドライバー Amazon | Wowstick 1F\u0026#43; 69in1 電動精密ドライバー ビット56種セット ケース USB充電式 LEDライト付き [並行輸入品] キースイッチを付け替えたり、工作したりでねじの開け閉めを頻繁に行います。 思ったよりも頻度が高くなってきたので、電動の精密ドライバーを試しに使ってみたらすごく楽ができました。 電池の入れ替えなどでもねじの開け閉めは行なうので、すごく役に立っています。 ビットが56種類もついていますが、プラスとマイナス以外はまだ使ってないかも。。。\n磁石のUSBケーブル Amazon | SUNTAIHO マグネット充電ケーブル DIYキーボード、エネループの充電器、上記のドライバーや掃除機など、USBで充電したり、接続するものが結構あります。 毎回ケーブルを差し替えるのも大変なのですが、@ymotongpooに教えてもらった磁石のUSBケーブルがお気に入りです。 先端部分(USB-C、micro)とケーブル部分が別々になっており、また、ケーブルと先端は磁石でくっつく構造なので、充電したい機器に先端部分を刺しておきます。 充電や接続したいときにケーブルを近づけると磁石でくっついてくれるのでケーブルの抜き差しが必要なくなります。 先端部分だけを個別に購入できたので、色々な機器にあらかじめつけてあります。\nMaker hart Just Mixer 5 Amazon | Maker hart Just Mixer 5 ステレオ5入力音声ミキサー/Bluetoothオーディオ入力対応 3台のPC+音楽サーバーとしてラズパイを主に利用しており、通知音などを1つのスピーカーから聞きたいので、ミキサーを導入しました。 5つの入力個別に音量調節できるので打ち合わせの時だけ他の音源を小さくしたりなど重宝しています。 ただ、入力が増えるとノイズが乗っている気もしますが。。。\nリストレスト(アームレスト) Amazon | エレコム リストレスト アームレスト 肘起き 扇形 左右で使える2個セット ブラック MOH-EL01BK 扇形のものを分割キーボードの手間においてリストレストとして使っています。 使用例の写真を見ると肘を置いていますが、手のひらをおくのにちょうどいいです。 これまでいくつかパームレストを試してみましたが、凹凸もなく適度な硬さで気に入っています。\nコンテッサセコンダ Amazon | オカムラ オフィスチェア コンテッサ セコンダ 10月に注文してクリスマスに届きました。部品が不足しているようで年内に届かないかもといわれていたのですが。 2003年くらいからアーロンチェアを使っていたのですが、さすがに買い替えるかということで奮発しました。 アーロンチェアは座面がメッシュなのですが、ももが疲れるのもあり、クッション座面のものにしてみました。 冬寒くないのがいいですねwまだ届いたばかりなので調整しないと。\nKindle paperwhite Amazon | Kindle Paperwhite - 大きくなった6.8インチディスプレイ 防水機能搭載 wifi 8GB 電子書籍リーダー 車の点検などでちょっとした待ち時間があるようなときに新書や小説が読めるようにセールで安くなったタイミングで購入しました。 健康診断で読書がはかどりました。もっと本を読まないとなぁ。\nということで、ここ数年で買って便利なものをまとめてみました。 他にもある気がするけど、とりあえずこの辺で。\n","date":1640784504,"dir":"post/2021/","id":"218e2c36d5945ece02fdc55d6cbcbc38","lang":"ja","lastmod":1640784504,"permalink":"https://blog.johtani.info/blog/2021/12/29/best-buy-2021/","publishdate":"2021-12-29T22:28:24+09:00","summary":"2021年もあと少しですが、今年買って良かったものをリストアップしておこうかと思います。 今年買ったといいながら、昨年このネタを書くといいつつ","tags":["misc"],"title":"2021年かって良かったもの"},{"contents":"Azure Cognitive Searchのスキーマの確認をするときに、Azureのポータルでは次のようにフィールドの一覧として見ることができます。\nただ、実際のインデックス定義はJSON形式でやり取りする形になっています(JSONの例:Create Index | Microsoft Docs)。 上記のスクリーンショットのようにフィールド数が少ない場合はそれほど気にならないのですが、フィールド数が大きくなると一覧で見たくなることがあります。 また、ポータルを自分で確認できない場合にJSONファイルを受け取って確認することもあります。 こういう時は、Excel(CSV)って便利ですよね?\nということで、サクッと確認するときには、次のようなjqコマンドをWSL2上で利用して、CSVに変換して確認しています。\necho \u0026#34;Name\u0026#34;, \u0026#34;Type\u0026#34;, \u0026#34;Searchable\u0026#34;, \u0026#34;Facetable\u0026#34;, \u0026#34;Filterable\u0026#34;, \u0026#34;Retrievable\u0026#34;, \u0026#34;Sortable\u0026#34;, \u0026#34;Analyzer\u0026#34;, \u0026#34;IndexAnalyzer\u0026#34;, \u0026#34;SearchAnalyzer\u0026#34; \u0026gt; index_schema.csv cat index_schema.json | jq -r \u0026#39;.fields[]|[.name, .type, .searchable, .facetable, .filterable, .retrievable, .sortable, .analyzer, .indexAnalyzer, .searchAnalyzer]|@csv\u0026#39; \u0026gt;\u0026gt; index_schema.csv 例えばこんな感じになります(上記のポータルのスクショとは別のスキーマですが。。。)。\nどんなフィールドオプションが利用されているか?などをExcelで開いてフィルターなどを活用してチェックするのには便利かなと。 jqコマンドをもっとうまく使うと、ヘッダ行ももっとスマートに出せるかもしれないんですが。。。\nちなみに、上記のコマンドでは残念ながらEdm.ComplexType(参考: 複合データ型をモデル化する方法 - Azure Cognitive Search | Microsoft Docs)には対応していません。 必要になった時に考えるかな。。。\n","date":1640141671,"dir":"post/2021/","id":"f0fdc140e18514362a4e52376a6fecba","lang":"ja","lastmod":1640141671,"permalink":"https://blog.johtani.info/blog/2021/12/22/azure-search-schema-json2csv/","publishdate":"2021-12-22T11:54:31+09:00","summary":"Azure Cognitive Searchのスキーマの確認をするときに、Azureのポータルでは次のようにフィールドの一覧として見ることができます。 ただ、実際のインデ","tags":["azure search","misc"],"title":"Azure Cognitive SearchのIndex Schema JSONをCSVで見たくなる"},{"contents":"今年もアドベントカレンダーの季節になってしまいました。 今年で2回目となる、pyspa Advent Calendar 2021の投稿です。 昨年に引き続きDIYがらみの投稿です。\nコントローラーラック 3つのコントローラーがあるのですが、結構場所を取ります。 また、それぞれ充電しないといけません。\n充電しつつ、邪魔にならない置き方はできないものか?と思っていたところ次のようなコントローラーラックを見つけました。\nAmazon | 山崎実業(Yamazaki) ゲームコントローラー収納ラック これそのものは場所を取るので購入は見送りましたが、エレクターの棚にワイヤーネットをつけると似たようなものができるのでは?ということで、DIYしてみることにしました。\n材料 材料は以下の通りです。 書いていない材料としてあとは、結束バンドがあります。\nワイヤーネット44×29.5cm オフホワイトB28 | 【公式】DAISO(ダイソー)ネットストア スリム型ネットフック50mm 2本入り | 【公式】DAISO(ダイソー)ネットストア クロームメッキワイヤーフック(2連、U字、2個) | 【公式】DAISO(ダイソー)ネットストア Amazon | マグネット 充電ケーブル SUNTAIHO USBケーブル LEDインジケーター付き Amazon | Anker PowerPort Atom III Slim (PD 充電器 65W 4ポート USB-C) 設置 まずは、2連のワイヤーフックでワイヤーネットをエレクターの棚にぶら下げました。\nそのままでは固定されないので、下のエレクターの棚とワイヤーネットを結束バンドで固定。 これで、コントローラーを置いたり取ったりしてもぐらぐらしません。\n固定したワイヤーネットの表(コントローラーを配置する側)に、ネットフック50mmをコントローラーの数だけ配置しました(上の写真でフックとコントローラーの関係がわかります)。\n前から見るとこのような形です。 裏側に、2連フックを使って、Ankerの充電器を固定し、USBのケーブルをコントローラーの上に来るように配置します(写真ではPS4とPS5のコントローラーの上の部分にぶら下がる形です)。\nコントローラーには磁石の端子をコントローラーに差し込んでおきます。\n磁石のUSBケーブルを利用していることで、コントローラーを取り出すときは少し力を入れて引っ張るだけ、収めるときは、ケーブルに近づけて充電できる状態にした後にフックに載せるだけとなりました。 ケーブルの抜き差しをしなくてもよいのでとても便利。 全体像は次の写真のようになっています。一番上のコントローラーはエネループを利用しているのでケーブルは不要になっています。\n磁石のUSBケーブルをpyspaでとんぷーに教えてもらって思いついたアイデアです。 磁石の端子は色々と使い勝手が良いので、DIYキーボードやテンキー、MX Ergo、Kindleなど色々なところに使っています。\n今年のDIYキーボード キーボードを作ったのは2つですが、改造を色々やってました。 ブログに記載したものはリンクだけにしておきます。\nケーブル自作 自作ケーブルキット – 遊舎工房 ケーブルも自作できるみたいなので作ってみました。 現在はテンキーの配置の問題もあって、メインでは利用はしていませんが工作としては面白かったです。 熱収縮チューブを処理するための道具を持っていなかったので、チューブの固定が甘いのが失敗でした。ドライヤーくらいの熱では足りないので作ろうと思っている方は要注意かと。\nCorne Light v2のBLE+LPME-IO対応 詳細はブログ記事を。Corneはこれ以外に、キースイッチの付け替えも行ないました。ルブしたGateronクリアをハンダでつけなおしました。\nCorne Light v2のBLE+LPME-IO対応 #DIYキーボード Sofle keyboard v2のBLE+LPME-IO対応 詳細はブログ記事を。このブログはSofleで書いています。現在メインに利用しているキーボードです。\nSofle v2を組み立てて、BLE+LPME-IO化してみた #DIYキーボード 10月には電池モジュールを次のものに付け替えました。家で主に使用するのもあり、充電池のほうが使い勝手がよさそうだという判断です。スイッチのON/OFFもしやすくなって満足しています。\n単4電池昇圧モジュール - のぎけす屋 - BOOTH Sofleの電池モジュールをボタン電池から単4電池用に差し替えた。 pic.twitter.com/TUizwr2qmw\n\u0026mdash; Jun Ohtani (@johtani) October 16, 2021 Lunakey Miniの組み立てとBLE+LPME-IO対応 詳細はブログ記事を。Sofleと時々入れ替えて使っています。小指のあたりのずれの大きさ、親指のキーの多さが使い勝手のよいキーボードです。コンパクトなのもあり、こちらは持ち運びにも利用できるかなと考えています。\nLunakey Miniを組み立てて、BLE+LPME-IO化してみた #DIYキーボード Soyuzの組み立て(Numpadキット) Soyuz (黒基板) – 遊舎工房 自宅の作業環境(2021/02)の写真にもありますが、分割したキーボードとは別にテンキーを利用しています。 WindowsのログインでPinコードを入力したり、色々な場面で数字の入力をすることがあるためです。 Soyuzを組み立てる前は素 - Shiro – 遊舎工房を利用していたのですが、これでは「⁺」や「Enter」など、電卓のような利用方法の場合にはキーが足りません。 かゆいところに手が届かないので、きちんとしたNumpadをということでSoyuzを組み立てました。\nShiroよりもだいぶ存在感があります。\nGK21S(Numpad) USB Type C充電器付きの滑らかな交換用キーボードキット (Gk21s/k21),スイッチ,デュアルモードPCB|Keyboards| - AliExpress 最後は独身の日のセールで見つけたNumpadキットです。キットといってもこちらは、基盤からケースまで組み立てが終わっているキットで、キースイッチを差し込んで、キーキャップを付けるだけというものになります。 現在はこれをメインに利用しています。通常のNumpadの上に1列キーが多く、Backspaceなどを割り当てられるのが便利です。 ドライバーソフトも用意されており、キーマップのカスタマイズも可能です(まだそこまでやってないけど)。\nお気に入りキースイッチ Kailh Box Silent ピンク軸 5個 | Kochi Keyboard Input Club Hako スイッチ(10個入り) – 遊舎工房 最後はキースイッチの紹介です。 現時点ではこの2種類を組み合わせるのが私の好みに合っているようです(今のところ)。 Box Silentのピンクをアルファベットのキーに、Input Club HakoのVioletをCtrlやShift、Enterなどのキーに割り当てて使っています(下の写真の左側で、キーキャップをつけている部分がHako Violetになっています)。\nまとめ ということで、pyspa Advent Calendar 2021の8日目の記事でした。 それほど作ったりしてないなと思っていたのですが、記事にしてみると今年も色々とDIYしてたみたいです。 キースイッチやキーキャップも自分の好みが固まってきたので、来年はファームウェアやキーマップ周りをいじっていきたいと思っています。\n","date":1638889200,"dir":"post/2021/","id":"26e44dfd16a2963d4c18e99806c26fd7","lang":"ja","lastmod":1638889200,"permalink":"https://blog.johtani.info/blog/2021/12/08/controller-rack/","publishdate":"2021-12-08T00:00:00+09:00","summary":"今年もアドベントカレンダーの季節になってしまいました。 今年で2回目となる、pyspa Advent Calendar 2021の投稿です。 昨年に引き続きDIYがらみの投稿","tags":["DIYキーボード","misc"],"title":"今年のDIYキーボードとコントローラーラック"},{"contents":"Domain-Specific Pretraining for Vertical Search: Case Study on Biomedical Literatureという論文を読んだので軽くメモを残しておきます。論文自体はリンクから参照してください。\n読んだ理由 Azure Cognitive SearchでSemantic Searchが利用可能になったこともあり、「Semantic Search」に関するMSのリサーチチームが発表している論文をたまたま見つけたためです。 Elasticsearchとニューラルモデルを利用したランカーでのリランクする仕組みがSemantic Searchと似ていたので読んでみました。\nざっくりメモ どんなもの? クリックログなどで関連度を改善できないような場合に、ドメイン固有の言語モデルを利用して検索結果の改善をする方法が提案されているので、バイオメディカル検索で実際に評価してみたという論文です。 特定分野の大量の文書から検索をするときに、ドメイン固有の事前学習した言語モデルを用意して、さらにファインチューニングする方法を評価しています。 言語モデルの生成に利用されたのはBERTになります。\n技術や手法のキモはどこ? 医療分野のデータを利用して評価していますが、ほかのドメインにも一般化できる可能性があることや、実際のシステムを提示している部分が肝になりそうです。\n論文から引用した言語モデルを用いてランキングを行う仕組みを構築する部分の構成です。\n左半分が、ドメイン固有の事前学習についてです。Wikipediaなどを利用したBERTのモデルが公開されたりしていますが、大量のドメイン固有データが用意できるのであれば、ドメイン固有のデータで事前学習することが有効であるという主張です(参考文献。これもMS Researchでした。同じチームなのかな?)。 この論文ではBERTの学習データとして、ドメイン固有のテキストを用いています。 実際にはPubMedBERTを利用しています。\n右半分がドメイン固有のデータで生成された言語モデルを利用して、ドメイン固有のニューラルランカー(検索結果のランキングを行なう仕組み)をファインチューニングする処理です。 MS MARCOと呼ばれるMSが公開している機械学習向けのデータセットのうち、ドメイン固有のサブセットを取り出して利用しているようです。\nこの論文では、L1検索(第1段階の検索)にBM25を利用して、L2検索にここで作成したニューラルランカーを利用し、検索結果を返す仕組みとなっています。 これは、Azure Cognitive SearchのSemantic Searchのシステムに似ています。\nこの論文では、BM25で検索した結果の上位60件の結果がL2のランカーの入力となっています。\n以下の2つが主な論文の成果となっています。\nドメイン固有の事前学習を利用することで、高度な学習コンポーネントなどの追加することなく高い精度が出た。 既存のBM25の検索エンジンと組み合わせてニューラルランカーを使うことで、計算コストを下げつつより良い上位の検索結果を返す仕組みを構築した。 どうやって有効だと検証した? TREC-COVIDデータセットを用いて評価して、TREC-COVIDに参加しているシステムと論文で提案している構成のシステムとの比較をしています。 また、ドメイン固有の事前学習が、一般ドメインなどの事前学習と比較して影響があるかどうかの評価もしています。\n実際にAzure上で構築した仕組みをMicrosoft Biomedical Searchとして公開しているようです。 上記のシステム構成のように、Elasticsearchで検索して、ニューラルランカーはKubernetes上に展開されたGPUで計算をしています。 論文には使用しているマシンの構成や台数なども記載があります。\n実際に構築したシステムをユーザーに利用して体験したもらった結果としては、 複雑な意図を持った長いクエリに対してはPubMedなどの他の検索ツールとしても良い結果が返ってきたことが確認されたとなっています。 ただし、一般的な短いクエリの場合は十分な結果にならない場合があったとのことです。\n議論はある? 実際にほかのドメイン(金融、法律、小売りなど)で適用してもうまくいくかは今後の研究に期待だと思います。 また、ファインチューニングするときに利用できるデータが今回の論文にあるようにMS MARCOのサブセットとして抽出できればよさそうです。\n他に読むべき論文は? TREC-COVIDに参加しているほかのシステムがどのような学習や仕組みが必要なのかを見ることで、どのくらいの手間・コストが軽減しているのかがわかるはずです。\n感想 ということで、読んでみました。 細かなほかの手法については調べていませんが、システム構成としてはAzure Cognitive SearchのSemantic Searchの仕組みと同じだと思われます。 違いは、ドメイン固有の事前学習のモデルではないことでしょうか。 ある程度のドメイン固有のモデルを利用できる仕組みができると、さらにSemantic Searchがうまく使えるようになるのかもしれません(前回書いたブログではWikipediaのデータを利用してみましたが、思ったほど良い感じはしなかったです。。。ファインチューニングの仕組みもないしなぁ)。 また、短いクエリでは芳しくない結果もあったというのは、おそらくニューラルランカーで評価するための情報が少なくなってしまうのだと思います。Semantic Searchに向いているクエリの作り方とかが出てくるのかな?\n","date":1636522396,"dir":"post/2021/","id":"35200cbf0b5b45d7f5f0b343cb18868b","lang":"ja","lastmod":1636522396,"permalink":"https://blog.johtani.info/blog/2021/11/10/reading-ms-biomedical-search-paper/","publishdate":"2021-11-10T14:33:16+09:00","summary":"Domain-Specific Pretraining for Vertical Search: Case Study on Biomedical Literatureという論文を読んだので軽くメモを残しておきます。論文自体はリンクから参照してください。 読んだ理由 Azure Cognitive S","tags":["search","paper"],"title":"Domain-Specific Pretraining for Vertical Search: Case Study on Biomedical Literatureという論文を読んだ"},{"contents":"今年もMICESにも参加してました。 昨年はBerlin Buzzwordsと共同開催でしたが、今年は別開催(別日程)でした。\nMICESは2017年から始まったe-commerceの検索にフォーカスしたカンファレンスです。 ECに関連する話に特化されていますが、話題は多岐にわたっています。色々やることありますねぇ、ECも。\n参加したセッション 参加したセッションの個人メモを今回も残しておきます。 セッション個別のリンクは用意されていないみたいですが、公式サイトにタイムテーブルがあり、セッションのタイトル、概要に加えて、スライドのPDFもリンクがあります。動画が公開されているものもあります。\nDreaming Search ビデオが公開されています。スライドがざっくりしたものなので最初に聞いた時にはしっくりこなかったので、聞き直してのメモです。 GDPRのような話で、個人の情報を自分たちで管理しようと流れがあります。 それぞれのECサイトなどでのユーザーのイベント(何を検索して、何をクリックした)情報はそれぞれのサイトで閉じた情報になっています。このため、自分の興味のある情報が断片化された情報でそれぞれのサイトで管理されてしまい、パーソナライゼーションされるもの(ランキングだったりレコメンドだったり)がいまいちな場合があります。 この個人の情報(ユーザーのイベント)をユーザー自身がハンドリングして、どの情報までをどこまで公開できるようにするというように管理できる仕組みができないか?という話のようでした。実際にそのための仕組み(もっと大きな話の仕様)を検討しているプロジェクトがあり、それに関連して検索という観点で夢を語っているセッションです。\nざっくり私が理解したのをまとめましたが、empathy.coという会社としてはいくつかPoCなども実施されているようでした。 個人の情報の扱い方に関する話は新鮮で面白かったです。 仕組みが出来上がり、各サイトが対応するとより個人が欲しい情報が集まりやすくなるのかなぁ?\nForget Facets, welcome Refinements (TM) Berlin BuzzwordsでいくつかLTをやられていた方によるファセットとその応用(彼らはRefinementsと名前をつけたみたい)についての話でした(ビデオとスライドが公開済み。)。 検索エンジンとファセットの関係の歴史から始まって、Kibanaでの使い方、モバイルや音声検索・チャットボットでのファセットは難しいよね?という話につながります。 ということで、Refinementsとして、ファセットを提示してユーザーに選んでもらうだけでなく状況に応じて、提案するための情報としてファセットを使うといいのでは?という話でした。例えば、チャットボットや音声検索での結果の場合、検索結果数が多くなるとユーザーが望んだものが返せるとは限らないです。その時に、ファセットの情報をもとに絞り込み条件を聞き返すネタに使うのはどうか?というような話でした。オートサジェスト(検索があいまいな時に、追加のキーワードを提案するもの)のような形でブランド名だったり、カテゴリーなどを表示する仕組みです。 実際の実装の話は、彼らが過去にBerlin Buzzwordsなどで話をしているのでそちらが参考になるとのことでした(参考:berlin buzzwords 2019 / Heystack 2019)\nReinforcement learning in search 検索における強化学習の話みたいです。ビデオとスライドが公開されています。ビジネス的に検索のランキングが重要だが、そのランキングをどうやって良くしていくのか?という話です。 ランキングでデフォルトのBM25から始まり、LtRを導入し、A/Bテストなどをしつつ、モデルの変化がどのようにビジネスに影響するかをはかるのが難しくなります。 LtRに対するオンライン機械学習のアプローチについて実際に直面した課題の話などがされている(はず?)です(どうも、実際にCTRなどを用いたところまでは行ってなさそう)。\n多腕バンディットなどの強化学習の話が続いたあたりでギブアップしてしまいました。。。\nBetter Search through Query Understanding - Panel Query Understandingに関するパネルとして3社の人がそれぞれどういった取り組みをしてるか?という話をしたあと質問などに答えていく形式でした。残念ながらビデオはまだ公開されていませんが、スライドが公開されています。QA部分も結構な時間だったのでビデオの公開がされるといいなぁ。\nUnderstanding queries by analysing user interaction / Andrea Schütt (OTTO) OTTOというECサイトでのQuery Understandingの紹介と、LtR導入にまつわる話。 データサイエンスとして最初はQuery Understandingやってたけど、スケールしないのでLtR導入して色々と試行錯誤しているところのようだった。\nQuery Understanding AI search eBayの方の発表。Query Understanding = ユーザーの興味をクエリから類推するという定義から、クエリを分類する、同定するためにどうしているか?という話でっした。 単語の表面的な文字としての近さだけでは、語順が変わると意味が変わるものや、ステミングのせいで同じになってしまうものといった例を紹介しつつ、クエリをベクトルにして表現(コンバージョン、クリックなどの情報を元にプロダクトのベクトルにしてみたり)し似ているかどうか?を判断している話です。\nCase study : Autocomplete Search Suggestions Digitec Galaxusというサイトでのオートコンプリートをもっと使いやすくするためにどんなデータを集めて、どうやって表示しているか?という話でした。 とりあえず入力されたものにヒットしたものを出すような実装だった場合に、サジェストされる量が多く、ノイズも多いので使いにくかったものをどうやって改善して行ったかという処理の流れなどの説明もありました。\nThe need for an open web search in Europe - The approach of the Open Search Foundation and its implications for E-Commerce-Companies Speaker: Alexander Decker / OPEN SEARCH FOUNDATION\nもっとオープンな検索システムを作っていこうという団体の話でした。 AWSが最近1.0をリリースしたやつとは別物です。 Googleでみんな検索しているけど、ブラックボックスなのでバイアスがかかっている。 もっとバイアスフリーなインデックスを提供できると、使いやすくなるよね?みんなでそういうインデックスを作っていかないか?という話でした。 ECとの直接の関係はセッションからは読み取れませんでした。 どうやって、集めるデータの基準(入れるべき、入れるべきではないなど)を作るんだろう?という疑問が残っています。公共的なものやオープンデータについてはあるとよさそうかもなぁ。\n101 hints to improving the customer satisfaction on search engines in the retail industry Speaker: Marion Hemery (Carrefour France) \u0026amp; Lucian Precup (a// \u0026amp; Adelean)\nカルフールのECサイトでの検索に関する顧客満足度の改善についての話です。 どんなものをどうやって図るのか、フィードバックを取るための仕組みは? そこからわかったものをどうやってシステムに優先度をつけながら取り込んでいくのか? というのをどんなものを使っているかという説明を交えながらのセッションです。 スライドが結構細かく書かれているのでスライドを見るだけでもわかりやすいかな。\n“An ounce of prevention is worth a pound of cure”: establishing a gold standard-based evaluation in customer projects Speaker: Bertram Sändig \u0026amp; Cornelia Werk / NEOFONIE\n検索の性能指標(速度ではないほうの性能)をきちんと評価する仕組みが重要だよというセッションです。 検索の仕組みを変更(例ではステミングを導入するはなしをしてました)した場合に、現行システムにどういう影響が出るのか?それをどうやって図るのか、どうやってテストしていくのか?という話です。 ステミングを導入したら、検索にヒットしやすくなったものも出てきたけどその弊害として今までよかった検索の結果にノイズが増え多という話をもとに、検索結果としてこうあってほしいというゴールデンスタンダードをきちんと作って育てていくべきですよという話でした。完ぺきなものなどないので少しずつやっていきましょうと。\nということで、見ていないもの(LTや最後のワークショップ)もありますが、見たものに関してメモを残してみました。\n","date":1626160103,"dir":"post/2021/","id":"10a7f69bd03d2632722300194f01e93d","lang":"ja","lastmod":1626160103,"permalink":"https://blog.johtani.info/blog/2021/07/13/attend-mices-2021/","publishdate":"2021-07-13T16:08:23+09:00","summary":"今年もMICESにも参加してました。 昨年はBerlin Buzzwordsと共同開催でしたが、今年は別開催(別日程)でした。 MICESは201","tags":["conference","berlin buzzwords","MICES"],"title":"今年もMICESにオンライン出張してた"},{"contents":"今年もBerlin Buzzwordsにオンライン出張してました。 今年の開催は6月14日から17日まででした。 どんなカンファレンスなのかは昨年のブログ記事をごらんください。\n今年はHAYSTACKは共同開催で、MICESは別開催でした。 MICESにも参加していたので、また後日にブログ記事を公開する予定です。\n参加したセッション 参加したセッションの個人用のメモを取ってあるので、簡単にまとめておきます。 セッションページに動画やスライドも追加されつつあります。興味のある方はそちらをご覧いただければと。 (今のところYouTubeに上がっているビデオは69本あります。再生リストはこちら) 気になっていたセッションもあるので、ビデオを見てまたメモを公開すると思いますが、まずは第1弾を。 ちなみに、検索をメインに見ています。Berlin Buzzwords自体はオブザバビリティやOSSコミュニティ、データのストリーミングの話などの話題もあるので、この辺りも興味があれば探してみても面白いかもです。\nHow to measure Diversity of Search Results セッションページ: How to measure Diversity of Search Results | Berlin Buzzwords 2021 従来の検索では、クエリに対して精度の高い検索結果を1件または数件返すのはどうするか?というものだったが、最近、あるユースケース(ほかの物の発見を促したいケース)では 検索結果の多様性を高めつつ、精度もある程度確保したいという場合があります。\nざっくりした検索クエリ(例えば自転車)の場合に、自転車だけが1ページ目にある場合よりも自転車とは別に自転車グッズも表示された場合のほうがクリック率やGMV(Gross Merchandice Value?)が上がったという話が紹介されていました。 この時どのくらい混ぜればいいのか?というのを、シャノンのエントロピーを使って、検索結果の多様性を保つための具体的なヒントについて話をされています。 実際にこういう計算をしてやれますねという紹介がされています。\nFrom text search and recommendation to ads and online dating; approximate nearest neighbors in real world applications セッションページ: From text search and recommendation to ads and online dating; approximate nearest neighbors in real world applications | Berlin Buzzwords 2021 Vespa.ai(OSS)の紹介でANNの話でした。通常、ANNを用いた検索の場合に他の検索条件(地理情報、日付など)をANNの結果に対して適用すると、望んでいる数がとれないです。その場合に、Vespaは内部でいい感じの動きをしますよという紹介でした。\n\u0026ldquo;Are You Sure?\u0026quot;: blending product comparisons and recommendations with A.I. セッションページ: \u0026ldquo;Are You Sure?\u0026quot;: blending product comparisons and recommendations with A.I. | Berlin Buzzwords 2021 Amazonの製品ページにある、類似商品との比較一覧のような一覧をどうやって実現するか?という話でした。比較一覧に掲載する商品を選出するパイプラインをこうやれますよね?という話でした。ログ(クリックやカートに入れたかどうかなど)を元にkNNで似ているデータを洗い出し、どの商品、どの項目を比較一覧として選ぶかという流れでした(セッションではもっと詳しい話がされています)。オフライン実験の話までがセッションでされています。\nThe future of Lucene\u0026rsquo;s MMapDirectory: Why use it and what\u0026rsquo;s coming with Java 16 and later? セッションページ: The future of Lucene\u0026rsquo;s MMapDirectory: Why use it and what\u0026rsquo;s coming with Java 16 and later? | Berlin Buzzwords 2021 Apache Lucene PMCのUweさんによるLuceneのMMapDirectoryの話です。 ファイルシステムとJavaに関する歴史と、なぜMMapなのか、現在のMMapの実装の問題点とJDK 16でどうなっているか(どんな感触か)、さらにその先(JDK17)は?という話です。 Luceneでの利用方法からJDKへのフィードバックが行われている話や、そのフィードバックをもとに今後どのようにしていくのか?という話がされています。\nSearch and Sushi; Freshness Counts セッションページ: Search and Sushi; Freshness Counts | Berlin Buzzwords 2021 こちらもVespa.aiの紹介です(今年はスポンサーしてるから多いのかも?)。Yahoo!とVerizon Mediaで利用している話をしたあと、Vespaでのリアルタイムインデキシングに関するアーキテクチャの紹介でした。内部で転置インデックスやそれ以外のデータをどのように保持しているのか?どういったことができるのか?というのをアーキテクチャ、ストレージの観点から紹介しています。\nEncores? - Going beyond matching and ranking of search results セッションページ(動画がまだない): Encores? - Going beyond matching and ranking of search results | Berlin Buzzwords 2021 検索のマッチングやランキング以外のいくつかの機能についての紹介をワークショップ形式で行うセッションです。ファセット、クエリオートコンプリート、スペル訂正、クエリリラクゼーションについて、データとSolrのクエリを基準に説明をしてくれます。\nThe Invasion of Transformers - Boosting Search with Latest NLP セッションページ: The Invasion of Transformers - Boosting Search with Latest NLP | Berlin Buzzwords 2021 deepsetという会社のCTOの方で、自社で作っているOSSのhaystackという製品の紹介です。 最近のGoogleの検索結果にはいろんなもの(問いかけに関する答えそのもの、またそのプレビューやサマリー)が出てきているという話から、Transformersを使って検索ができないかということで自社のOSSの仕組みを紹介しています。\n参考 Google: BERT now used on almost every English query deepset-ai/haystack: End-to-end Python framework for building natural language search interfaces to data. Leverages Transformers and the State-of-the-Art of NLP. Supports DPR, Elasticsearch, Hugging Face’s Hub, and much more! Learning to Judge セッションページ: Learning to Judge | Berlin Buzzwords 2021 otto.deというECサイトでLtRを導入し、そのLtRにどんな特徴を利用しどうやって実験したかというセッションでした。Apache Solrで検索ができていて、これまでは検索の管理を人手で行っていたがスケールしない(扱う商品などは増えているのに)のでLtRを導入し始めたという感じでした。LtRの導入の過程でどういう仮定を置いて、どうモデルを決め、それをどうやってテストしてどう分析したか?という流れでした。\nText categorization with Apache Lucene セッションページ: Text categorization with Apache Lucene | Berlin Buzzwords 2021 LTなので短めです。BBCのデータセットをインデックスに登録し、そのデータをもとにLucene(デモではKibana+Esを利用していた)でテキスト分類を行なう方法について紹介しています。BBCのデータセットは記事(テキスト)とカテゴリ(タグ)というデータです。 このデータが登録されているインデックスに対して、More Like Thisクエリに分類したい文章を与え、ヒットしたデータをもとにAggregationでカテゴリを取得し、上位のカテゴリが分類された結果になるというデモでした。 テキストフィールドにはEdge N-Gramを利用していること、Aggregationのソートの条件はMore Like Thisクエリでのスコアの平均を利用していることというのがこの方法がうまくいくことのようでした(なるほど!)。ただ、日本語でもこれが使えるかな?というのはやってみないとわからないかなぁと(やってないです)。\nとりあえず、メモしておいたのはこの辺でした。 他にもセッション一覧を眺めながら面白そうな話をピックアップしてメモを取っていこうかなぁ?気になるセッション、メモがおかしいなどあればコメントいただければと。\n","date":1625815493,"dir":"post/2021/","id":"59b7b60e6bbf4858d72643d22ad90451","lang":"ja","lastmod":1625815493,"permalink":"https://blog.johtani.info/blog/2021/07/09/berlin-buzzwords-2021-1/","publishdate":"2021-07-09T16:24:53+09:00","summary":"今年もBerlin Buzzwordsにオンライン出張してました。 今年の開催は6月14日から17日まででした。 どんなカンファレンスなのかは昨年","tags":["conference","berlin buzzwords"],"title":"今年もBerlin Buzzwordsにオンライン出張してた"},{"contents":"Azure Cognitive Searchで新機能「Semantic Search(セマンティック検索)」という機能の日本語対応が発表されました。 実際にはPublic Previewという状態ではありますが、どんな機能か気になったので調べてみました。 なお、本ブログは2021年6月時点での内容となります。\n公式ドキュメント 公式ドキュメントでいろいろと説明されています。まずは公式ドキュメントを見ていただくのが良いかなと。最初のドキュメントには10分ちょっとの紹介ビデオもあります。ピックアップしたのは概要、クエリ、レスポンスの構造、紹介ブログになります。ブログ以外は日本語(たぶん機械翻訳?)になっています(新機能の紹介の日本語ページにはまだ記載がありません)。\nSemantic search - Azure Cognitive Search | Microsoft Docs Create a semantic query - Azure Cognitive Search | Microsoft Docs Structure a semantic response - Azure Cognitive Search | Microsoft Docs The science behind semantic search: How AI from Bing is powering Azure Cognitive Search - Microsoft Research 簡単にですがデータを入れて試してみたので、どんな仕組みなのかどういう挙動なのかを紹介します。\nSemantic Searchとは? 言語理解、セマンティック関連性などを提供する機能です。BingとMSリサーチにより開発されて、Azure Cognitive Searchに導入されました。 クエリの書き方を少し変更する必要がありますが、再インデックスや設定変更などは必要ないという仕組みになっています。\n検索クエリからコンテキストを読み取って、検索し、リランクするアルゴリズム(Semantic Ranker) 関連する一節を強調表示(Semantic Caption) クエリに対するセマンティック回答(Semantic Answer) スペルチェック機能 言語によって利用できる機能が異なります。\nSemantic Searchの利点は先ほどの紹介にも書きましたが、インデキシング時に特殊処理をする必要がないことかなと。 すでに登録してあるデータ(制限がありますが)でもすぐに試すことができます。\n仕組み https://docs.microsoft.com/ja-jp/azure/search/media/semantic-search-overview/semantic-query-architecture.png\nスペル修正機能 クエリパース スコアリング 上位50件に対してSemantic Rankerにより再評価(検索ヒットが50件以上の場合でも上位50件のみがリランクの対象) 言語表現モデルを利用 結果の要約として最適な部分をキャプションとして抽出。 クエリが質問形式の場合は一番よさそうな場所を回答として選択 1および4番目の処理が今回新しく使えるSemantic Searchの機能になります。スペルチェックは日本語がまだ対象外なので、4番目の機能について紹介します。\n利用できる環境と制限 冒頭でも書きましたが、Public Previewの段階です。実際に利用するにはリクエストページから申し込みが必要になっています。\n利用リクエスト時に利用するAzure Cognitive Searchのサービス名が必要になるので、あらかじめ起動しておかなければいけません。 また、利用できるリージョンが限定されているのでサービス起動時のリージョンには気を付けてください。\n利用できるリージョン 米国中北部、米国西部、米国西部 2、米国東部 2、北ヨーロッパ、西ヨーロッパ 利用できるTier セマンティック検索はStandardレベル スペルチェックはレベル制限なし 価格(セマンティック検索のみ) 7月初旬までは25万クエリで500ドル Analyzerの制限 Azure Cognitive Searchが提供する言語アナライザーが対象(Custom Analyzerでは利用不可) サービス起動後にプレビュープログラムを申請すると、利用できるようになるとメールが届きます。そこから利用ができるようになります。\n今回は日本語のWikipediaのデータをいれてどんな機能なのかを確認してみました。\nWikipediaのデータを入れて試してみた 日本語のWikipedia(あとで英語も入れました)を一部(10万件程度)登録してSemantic Search(主にRanker)の動きを確認してみました。\nデータの登録には自作ツールを利用。\nJSONデータ生成ツール:https://github.com/johtani/wiki-extractor-rs JSONデータ登録ツール:https://github.com/johtani/wiki-json-loader 日本語Wikipediaの2020年6月のデータ、英語Wikipediaの2021年6月のデータを利用。上記ツールで生成したもののうち約10万件をAzure Cognitive Searchに登録して動作確認をしました(英語のデータでJSONデータ生成ツールでバグがあるのですが修正していません。。。)。 また、クエリの実行にはVisual Studio CodeのREST Client拡張(どんなものかは以前のブログをご覧ください)を使いました。簡単にREST APIを呼び出せるのはすばらしい。\n日本語のWikipedia 日本語のWikipediaのデータを「96,344件」登録し実験しました。 スキーマは次のような形です(説明に必要なものだけ抽出してあります)。自然分が入っているtitle、contents、headingsの3つのフィールドを今回はSemantic Searchの対象にしてみるので、AnalyzerをLuceneベースの日本語Analyzerであるja.luceneを設定しました。\nフィールド名 : タイプ / Analyzer id : Edm.String / keyword categories : Collection(Edm.String) / keyword title : Edm.String / ja.lucene contents : Edm.String / ja.lucene headings : Edm.String / ja.lucene Analyzerに言語Analyzerを設定するくらいで、他の設定は特に必要ありません。\nクエリとデータの確認 デモの動画や説明のサンプルを見たところ英語で「Where was Alan Turing born?」や「What\u0026rsquo;s the capital of France?」のような自然文のクエリが出てきたので、次のようなクエリで試してみました。\nフランスの首都はどこですか? 実際にパリのページがインデックスに存在していることは以下のクエリで確認しました。\nパリ:3047件 POST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;パリ\u0026#34;, \u0026#34;top\u0026#34;: 10, \u0026#34;searchFields\u0026#34;: \u0026#34;title, categories, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id, contents\u0026#34; } ※ここで{{host}}などはREST Client拡張で変数として定義したものです。\nhost : Azure Cognitive Searchのサービス名 index-name : インデックス名 api-key : 接続のためのAPIキー URLパラメータのapi-version=2020-06-30-PreviewがPreview機能を呼び出すための指定になっています。\n3047件の1件目が「パリ」のページで以下のようなWikipediaの文章をセクションごとに文字列としてページ全体を配列に入れてcontentsに登録してあります。\n\u0026#34;パリ(、巴里)は、フランス北部、イル=ド=フランス地域圏にある都市。フランスの首都であり、イル=ド=フランス地域圏の首府である。\\nフランス最大の都市であり、同国の政治、経済、文化などの中心である。ロンドンと共に欧州を代表する世界都市。行政上では、1コミューン単独で県を構成する特別市であり、ルーヴル美術館を含む1区を中心に、時計回りに20の行政区が並ぶ(エスカルゴと形容される)。\u0026#34;, このインデックスに対して「フランスの首都はどこですか?」というクエリを、セマンティック検索のクエリと通常のクエリの2パターンで検索をしてみました。\nこれまでのクエリ(セマンティックではない検索) まずは通常のクエリです。 searchがクエリ文字列、searchFieldsが検索対象フィールドになります。\nPOST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;top\u0026#34;: 100, \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;フランスの首都はどこですか?\u0026#34;, \u0026#34;searchFields\u0026#34;: \u0026#34;title, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id\u0026#34; } クエリを実行するとヒット件数が'13996\u0026rsquo;件で、トップ5件のデータは次のようになりました。\n\u0026#34;@odata.count\u0026#34;: 13996, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 17.059355, \u0026#34;id\u0026#34;: \u0026#34;462\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;首都\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 16.086372, \u0026#34;id\u0026#34;: \u0026#34;21053\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;首都圏\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 15.059893, \u0026#34;id\u0026#34;: \u0026#34;71414\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;どこでもドア\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 14.086605, \u0026#34;id\u0026#34;: \u0026#34;51972\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;首都機能移転\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.996841, \u0026#34;id\u0026#34;: \u0026#34;3877\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;首都の一覧\u0026#34; }, 見るとわかりますが、「首都」「どこ」といった単語を含むデータが上位に入っています。「フランス」を含むデータは8件目と10件目に「フランス植民地帝国」、「ラ・フランス」といったデータが出てきます。\n{ \u0026#34;@search.score\u0026#34;: 12.705561, \u0026#34;id\u0026#34;: \u0026#34;129279\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;フランス植民地帝国\u0026#34; }, ... { \u0026#34;@search.score\u0026#34;: 12.036648, \u0026#34;id\u0026#34;: \u0026#34;3173\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ラ・フランス\u0026#34; }, 残念ながら望んでいる結果にはほど遠いかと。\nどんな検索になっているのでしょうか?まずは、クエリの解釈から。 デフォルトで、Azure Cognitive Searchはデフォルトでは、入力された文字列をtype=simple、mode=anyで検索します(クエリパラメータ参照)。 対象となるフィールドはsearchFieldsで今回は指定してあるので、これらのフィールドに対して、入力された文字列を渡してAnalyzerで単語分割し(今回はsimpleクエリ用の特殊文字が入っていないため文字列として扱われる)、 出てきた単語で(mode=anyだから)OR検索します。 ja.luceneのAnalyzerが出力する単語列がどんなものかは以下のリクエストを実行するとわかります。\nPOST https://{{host}}/indexes/{{index-name}}/analyze?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;analyzer\u0026#34;:\u0026#34;ja.lucene\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;フランスの首都はどこですか?\u0026#34; } 結果は以下の通りです。\n\u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;フランス\u0026#34;, \u0026#34;startOffset\u0026#34;: 0, \u0026#34;endOffset\u0026#34;: 4, \u0026#34;position\u0026#34;: 0 }, { \u0026#34;token\u0026#34;: \u0026#34;首都\u0026#34;, \u0026#34;startOffset\u0026#34;: 5, \u0026#34;endOffset\u0026#34;: 7, \u0026#34;position\u0026#34;: 2 }, { \u0026#34;token\u0026#34;: \u0026#34;どこ\u0026#34;, \u0026#34;startOffset\u0026#34;: 8, \u0026#34;endOffset\u0026#34;: 10, \u0026#34;position\u0026#34;: 4 } ] これで、どのような単語が出てきているかがわかりました。 それぞれのフィールドでどのようなスコアになっているかまではわからないですが、検索結果には上記3つの単語のいずれかがsearchFieldsにヒットすれば出てきます。おそらく、ヒットした単語数が多い、短い文字列のフィールドがより高いスコアになるというような動きになっていると思われます(BM25になってるはず)。\nセマンティック検索 では、セマンティック検索のクエリに変更してみましょう。\nPOST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;top\u0026#34;: 100, \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;フランスの首都はどこですか?\u0026#34;, \u0026#34;searchFields\u0026#34;: \u0026#34;title, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id\u0026#34;, \u0026#34;queryType\u0026#34;: \u0026#34;semantic\u0026#34;, \u0026#34;queryLanguage\u0026#34;: \u0026#34;ja-jp\u0026#34; } queryType、queryLanguageがセマンティック検索のクエリを実行するためのパラメータになります(公式ガイド参照)。 今回は日本語のデータであるため、日本語のモデルを利用するようにqueryLanguageを指定します(許可されていない文字列を渡すとエラーになる)。 この2つを追加するだけです。簡単ですね。\n結果は次のようになります(上位5件抜粋)。\n\u0026#34;@odata.count\u0026#34;: 13996, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 12.036648, \u0026#34;@search.rerankerScore\u0026#34;: 2.3456064984202385, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;ラ・フランス\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;ラ・フランス\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;3173\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ラ・フランス\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 11.144733, \u0026#34;@search.rerankerScore\u0026#34;: 2.3173404783010483, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;ラン (フランス)\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;ラン\u0026lt;/em\u0026gt; (\u0026lt;em\u0026gt;フランス)\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;108094\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ラン (フランス)\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 11.144793, \u0026#34;@search.rerankerScore\u0026#34;: 2.1937477812170982, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;ブレスト (フランス)\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;ブレスト\u0026lt;/em\u0026gt; (\u0026lt;em\u0026gt;フランス)\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;116154\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ブレスト (フランス)\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 10.199907, \u0026#34;@search.rerankerScore\u0026#34;: 2.1590753793716431, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;フランス・ハルス\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;フランス・ハルス\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;81566\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;フランス・ハルス\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 11.273148, \u0026#34;@search.rerankerScore\u0026#34;: 2.1434053033590317, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;バカロレア (フランス)\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;バカロレア\u0026lt;/em\u0026gt; (\u0026lt;em\u0026gt;フランス\u0026lt;/em\u0026gt;)\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;54514\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;バカロレア (フランス)\u0026#34; }, 検索結果数を見ると、通常のクエリと同じ値です。 これは、公式ドキュメントのセマンティック検索に説明があるように、 セマンティック検索が通常のクエリで実行した後の検索結果に対して、上位50件のデータだけに対してsemantic rankerによってスコアを再計算するという仕様のためです(ドキュメントからの推測)。\n実際に検索結果の50件目、51件目は次のようになっていました。50件目までのデータには@search.rerankerScoreというスコア(と@search.captions)が追加されています。 51件目のデータについては、前の通常のクエリの51件目のデータと同じデータでした。\n{ \u0026#34;@search.score\u0026#34;: 10.909212, \u0026#34;@search.rerankerScore\u0026#34;: 0.07321979058906436, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;首都高速埼玉大宮線\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;67667\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;首都高速埼玉大宮線\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 10.049902, \u0026#34;id\u0026#34;: \u0026#34;68569\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;スタッド・ド・フランス\u0026#34; }, 上位5件のデータに戻ります。 これらは、通常のクエリとは異なる結果となりました。 見ると@search.captionsというところにハイライトされた項目が表示されています。 検索クエリをもとにそれっぽい部分がキャプションという形で返ってくる仕組みです。\n結果を見るとわかりますが、残念ながら「パリ」のページは返ってきませんでした。 もともと通常のクエリを実行したときの「326」番目の結果として返ってきているため、セマンティック検索の対象とはならなかったためです。 ただ、「首都」「どこ」といった単語よりも「フランス」に関するドキュメントが通常の検索よりも上位に来ています。 クエリに存在する単語で「フランス」がより重要であると判断されているようです。\nSemantic Rankerに処理させてみる ちなみに、今回登録したデータにはWikipediaのカテゴリも登録してあります。 「ヨーロッパの首都」というカテゴリで絞り込んでから検索してみるとどうなるかもやってみました。 filterのパラメータが絞り込み条件です。\nPOST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;top\u0026#34;: 100, \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;フランスの首都はどこですか?\u0026#34;, \u0026#34;searchFields\u0026#34;: \u0026#34;title, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id\u0026#34;, \u0026#34;queryType\u0026#34;: \u0026#34;semantic\u0026#34;, \u0026#34;queryLanguage\u0026#34;: \u0026#34;ja-jp\u0026#34;, \u0026#34;filter\u0026#34;: \u0026#34;search.ismatch(\u0026#39;ヨーロッパの首都\u0026#39;, \u0026#39;categories\u0026#39;)\u0026#34; } 結果は次の通りです。カテゴリで絞り込みをしているので検索結果数は39件となります。このため、すべてのデータがSemantic Rankerの対象です。 ですが、「パリ」のページは11件目に出てきました。\n\u0026#34;@odata.count\u0026#34;: 39, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 3.8405614, \u0026#34;@search.rerankerScore\u0026#34;: 2.0472740978002548, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;ウィーン\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;9465\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ウィーン\u0026#34; }, ... { \u0026#34;@search.score\u0026#34;: 4.8915977, \u0026#34;@search.rerankerScore\u0026#34;: 1.8480307757854462, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;レイキャヴィーク\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;レイキャヴィーク\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;112253\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;レイキャヴィーク\u0026#34; }, ... { \u0026#34;@search.score\u0026#34;: 7.277628, \u0026#34;@search.rerankerScore\u0026#34;: 1.7982495501637459, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;パリ\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;パリ\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;31\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;パリ\u0026#34; }, キャプションは入力された単語だけではなく、クエリが持っている単語をもとにした何かしらの基準(おそらく言語モデルで近い単語?)で選択されていると思われます。首都というカテゴリーで絞り込んでしまったので、ヒットした文章が似たようなものが多くなったせいか、残念ながらそこまでSemantic Rankerが意図を汲み取るところまでは行きませんでした。\nフランスの歴史 視点を変えてみましょう。質問そのものの答えではなく、クエリの意図に近いものが出てくるかを見てみましょう。 ここまでのクエリでフランスに関するクエリを投げていました。今回のインデックスに「フランスの歴史」で検索すると「30820」件のドキュメントがヒットし、上位にはフランスには関係ない「歴史」のページや「フランス」の文学、都市など「フランスの歴史」とは少し離れた意味のものが上位に来ています。\n\u0026#34;@odata.count\u0026#34;: 30820, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 12.888079, \u0026#34;id\u0026#34;: \u0026#34;17875\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;スコットランドの歴史\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.718105, \u0026#34;id\u0026#34;: \u0026#34;10665\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;世界の歴史\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.701981, \u0026#34;id\u0026#34;: \u0026#34;31397\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ベトナムの歴史\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.579847, \u0026#34;id\u0026#34;: \u0026#34;22433\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;フランス文学\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.524254, \u0026#34;id\u0026#34;: \u0026#34;34667\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;フランスの国旗\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.52136, \u0026#34;id\u0026#34;: \u0026#34;108094\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ラン (フランス)\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.41088, \u0026#34;id\u0026#34;: \u0026#34;20717\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;歴史小説\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.388911, \u0026#34;id\u0026#34;: \u0026#34;56229\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;演劇の歴史\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.343941, \u0026#34;id\u0026#34;: \u0026#34;39669\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;イギリスの歴史\u0026#34; }, このクエリをセマンティッククエリで検索すると次のようになりました。\n\u0026#34;@odata.count\u0026#34;: 30820, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 12.274498, \u0026#34;@search.rerankerScore\u0026#34;: 1.482184374704957, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;自由フランス\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;自由フランス\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;96475\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;自由フランス\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 11.446766, \u0026#34;@search.rerankerScore\u0026#34;: 1.3535655084997416, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;フランスの地域圏\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;フランスの地域圏\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;51845\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;フランスの地域圏\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 10.926437, \u0026#34;@search.rerankerScore\u0026#34;: 1.3261859538033605, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;フランス第一帝政\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;フランス第一帝政\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;57573\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;フランス第一帝政\u0026#34; }, 上位には「フランスの歴史」に関連しそうなタイトルが上がってきています。 また、先ほど「歴史」という単語でヒットして上位に来ていた「スコットランドの歴史」は@search.rerankerScoreの値が低くなっていました(31件目に出現)。\n{ \u0026#34;@search.score\u0026#34;: 12.888079, \u0026#34;@search.rerankerScore\u0026#34;: 0.42768346797674894, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;スコットランドの歴史\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;17875\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;スコットランドの歴史\u0026#34; }, 考察 日本語のWikipediaを約10万件入れたインデックスでセマンティック検索を試してみました。 デモや説明などでクエリが自然文の質問だったこともあり、質問の回答になりそうなページが上に来るかと期待しましたが、期待しすぎました。\nこれは、Azure Cognitive Searchのセマンティック検索の仕組みを考えると納得のいくものです。 説明を読んだ時にも感じたのですが、入力された文字列でまず検索をし、上位50件をセマンティック検索の対象としています。\nですので、そもそもクエリの文章に出てくる単語が含まれたデータだけが対象となります。 このため、クエリに出てこない単語のみで構成されているものは残念ながら対象とできません。 また、上位50件だけがSemantic Rankerの対象となっているため、検索にヒットしたとしても上位に食い込まなければ言語モデルによるランキングの対象にもなりません。 セマンティック検索といっても、残念ながらドキュメントに出てこない単語(似た単語、質問に対するそのものの回答)まで読み取る機能はありません。\nただ、「フランスの歴史」の検索で見たようにそれぞれの単語だけで検索をしていた場合とは異なり、 クエリの意味に沿ったスコアづけにより、通常の検索よりも意図したものに近いデータが出ていることが確認できました。 複数の単語で構成されるクエリの場合に、単語だけでスコアを計算した場合よりもよさそうな結果が上位に出てくることがわかりました。\nただし、重要なのは「上位50件」までしかSemantic Rankerの対象にはならない点です。\n英語のWikipedia セマンティックは英語対応が一番最初にリリースされているので、英語のWikipediaについてもデータを登録してみました。\n英語のWikipediaのデータを「111,649件」登録しました。 スキーマは以下の通り(今回の調査に利用していないものは省略)です。日本語と異なる点はAnalyzerがen.luceneになっていることぐらいです。\nフィールド名 : タイプ / Analyzer id : Edm.String / keyword categories : Collection(Edm.String) / keyword title : Edm.String / en.lucene contents : Edm.String / en.lucene headings : Edm.String / en.lucene クエリとデータの確認 日本語同様に首都に関する質問形式にしてみました。\nWhat\u0026rsquo;s the capital of Italy? 実際にRomeのページがインデックスに存在していることは以下のクエリで確認済みです。\nRome:2302件\nPOST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;Rome\u0026#34;, \u0026#34;top\u0026#34;: 10, \u0026#34;searchFields\u0026#34;: \u0026#34;title, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id, contents\u0026#34; } 以下のようなWikipediaの文章をセクションごとに文字列としてページ全体を配列に入れてcontentsに登録してあります(これも日本語と同じです)。\n\u0026#34;\u0026#34;\\n\\nRome (Italian and Latin: Roma ) is the capital city and a special comune of Italy (named Comune di Roma Capitale), as well as the capital of the Lazio region. The city has been a major human settlement for almost three millennia. With 2,860,009 residents in , it is also the country\u0026#39;s most populated comune...\u0026#34;, このデータ群に対して「What\u0026rsquo;s the capital of Italy?」というクエリを、Semantic Searchのクエリと通常のクエリの2パターンで検索をしてみる。\nこれまでのクエリ(セマンティックではない検索) まずは、Semantic Searchではないクエリです。\nPOST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;top\u0026#34;: 100, \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;What\u0026#39;s the capital of Italy?\u0026#34;, \u0026#34;searchFields\u0026#34;: \u0026#34;title, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id\u0026#34; } ヒット件数は18049件で、トップ5件は次のような形です。\n\u0026#34;@odata.count\u0026#34;: 18049, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 17.870815, \u0026#34;id\u0026#34;: \u0026#34;14532\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Italy\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 16.596167, \u0026#34;id\u0026#34;: \u0026#34;14702\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Economy of Italy\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 16.180624, \u0026#34;id\u0026#34;: \u0026#34;183878\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Louis II of Italy\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 15.917025, \u0026#34;id\u0026#34;: \u0026#34;29665\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;State capitalism\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 15.88901, \u0026#34;id\u0026#34;: \u0026#34;215741\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Capitalization\u0026#34; }, 日本語の場合よりもItalyに関連するものが上位に多く含まれます。 ただ、Rome自体のページは上位50件には出てきていませんでした。 また、capitalとは意味の異なるcapitalizationやcapitalismが上位に来ています。 日本語の場合と同様にクエリがどのように解釈されているのか?も見てみます。\nPOST https://{{host}}/indexes/{{index-name}}/analyze?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;analyzer\u0026#34;:\u0026#34;en.lucene\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;What\u0026#39;s the capital of Italy?\u0026#34; } 結果は以下の通りです。\n\u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;what\u0026#34;, \u0026#34;startOffset\u0026#34;: 0, \u0026#34;endOffset\u0026#34;: 6, \u0026#34;position\u0026#34;: 0 }, { \u0026#34;token\u0026#34;: \u0026#34;capit\u0026#34;, \u0026#34;startOffset\u0026#34;: 11, \u0026#34;endOffset\u0026#34;: 18, \u0026#34;position\u0026#34;: 2 }, { \u0026#34;token\u0026#34;: \u0026#34;itali\u0026#34;, \u0026#34;startOffset\u0026#34;: 22, \u0026#34;endOffset\u0026#34;: 27, \u0026#34;position\u0026#34;: 4 } ] 日本語とあまり変わってはいません。ただ、単語が入力されたものとは少し変わっています。 これは、en.luceneの処理で、stemmingが行われているためだと思われます。たとえば、「capital」の場合、Stemmingにより「capital」「capitalize」などの単語が元になりますが、動詞、名詞などの違いなく検索できるようにするためにこのようなStemmingの処理が行われます。 ということで、これらの単語を含むドキュメントがヒットしています。Italyが一番上に来ているのはItalyという単語が多く含まれるからのようです。\nSemantic Searchクエリ では、Semantic Searchのクエリに変更してみましょう。\nPOST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;top\u0026#34;: 100, \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;What\u0026#39;s the capital of Italy?\u0026#34;, \u0026#34;searchFields\u0026#34;: \u0026#34;title, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id\u0026#34;, \u0026#34;queryType\u0026#34;: \u0026#34;semantic\u0026#34;, \u0026#34;queryLanguage\u0026#34;: \u0026#34;en_us\u0026#34; } queryType、queryLanguageがsemantic searchのクエリを実行するためのパラメータになります(公式ガイド参照)。 今回は英語のデータであるため、英語のモデルを利用するようにqueryLanguageを指定します(許可されていない文字列を渡すとエラーになる)。\n結果は次のようになります(上位5件抜粋)。\n\u0026#34;@odata.count\u0026#34;: 18049, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 17.870815, \u0026#34;@search.rerankerScore\u0026#34;: 1.9688458815217018, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Italy\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;14532\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Italy\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 14.239678, \u0026#34;@search.rerankerScore\u0026#34;: 1.9419755563139915, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Capital city\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;181337\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Capital city\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 10.181764, \u0026#34;@search.rerankerScore\u0026#34;: 1.8902588561177254, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Lepontii\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;325133\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Lepontii\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 10.865718, \u0026#34;@search.rerankerScore\u0026#34;: 1.875102698802948, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;ItalY\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;14482\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ItalY\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 11.689348, \u0026#34;@search.rerankerScore\u0026#34;: 1.8201303631067276, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Savoy\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;27885\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Savoy\u0026#34; }, 日本語で見てきたように、検索結果数を見ると、通常のクエリと同じ値で、残念ながら50件までにRomeは入っていないため、Semantic Rankerによるブーストもかかりませんでした。 ただし、「Capitalization」や「State capitalism」といった別の意味(地理に関するものではない単語)のものが上位に出てこなくなっています。 これは、capitalという単語が地理に関する意味を持っていると判断された結果のように見えます。 Capitalizationの@search.rerankerScoreは上位のスコアに比べて小さいものとなっています。\n{ \u0026#34;@search.score\u0026#34;: 15.88901, \u0026#34;@search.rerankerScore\u0026#34;: 0.93921028636395931, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Capitalization\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;215741\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Capitalization\u0026#34; }, What\u0026rsquo;s the capital of Finland? 上位50件以内(20件目)に「Helsinki」のページが出てくるクエリでセマンティック検索をしてみました。\nPOST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;top\u0026#34;: 100, \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;What\u0026#39;s the captial of Finland?\u0026#34;, \u0026#34;searchFields\u0026#34;: \u0026#34;title, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id\u0026#34;, \u0026#34;queryType\u0026#34;: \u0026#34;semantic\u0026#34;, \u0026#34;queryLanguage\u0026#34;: \u0026#34;en-us\u0026#34; } 結果としては、2件目にHelsinkiが返ってきていたので、Semantic Rankerがによる並び替えがうまくいきました。 (下記の結果は上位3件を抜粋したものです)。\n\u0026#34;@odata.count\u0026#34;: 16673, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 14.026371, \u0026#34;@search.rerankerScore\u0026#34;: 2.42378556355834, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Vanaja (Finland)\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;7132102\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Vanaja (Finland)\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.434971, \u0026#34;@search.rerankerScore\u0026#34;: 2.383675143122673, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Helsinki\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;13696\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Helsinki\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 13.380153, \u0026#34;@search.rerankerScore\u0026#34;: 2.2026549801230431, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Rauma, Finland\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;178635\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Rauma, Finland\u0026#34; }, 考察 今回の英語のクエリではSemantic Rankerがある程度の役割をはたしていそうだということはわかりました。 Capitalがいくつもの意味を持っていることもあり、文章をもとにより意味の近いドキュメントが上位に来たということです。 ただ、英語の場合も基本的には上位50件以内のデータに対して処理が行われるので上位50件以内にデータが入らなければうまくいかないようです。\nまとめ Azure Cognitive Searchの新機能であるセマンティック検索について調べてみました。 まだPublic Previewですが、簡単に使えるような仕組み(データの再登録なし、クエリでパラメータを追加するだけ)が用意されているのは便利でした。 ただ、最初に想像していたもの(私の早とちりもありますが)ほどのセマンティック検索とは行きませんでした。 似たような言葉の意味を持ったものを探してくれたり、答えそのもののページのスコアがすごく高くなるといったものではありませんでした。\n仕組み上、クエリに含まれる単語で検索し、上位50件以内のデータだけが対象になる(残念ながら現時点ではこの件数の変更はできません。)ため、これまでの検索とは劇的に変化するものではないことはわかりました(銀の弾丸はないんですけどね)。\nある程度の挙動をわかっていれば、Wikipediaのようなデータでもそれなりの結果は取得できそうだということはわかりました。\n「言語モデル」でクエリとヒットしたデータをもとにスコア計算をし直しているようですが、この部分がどのようなデータ・クエリだと有効活用できるのか?というのをもう少しいろいろな角度で試してみる必要がある気がします(適材適所が何なのか?)。 あとは、上位50件までが対象なので、それ以上の件数のデータの並びに関してはこれまでと同様の結果となる点は注意しないといけません。 また、今回試していないほかの機能(スペルチェック、Semantic Answerなど)にメリットがあるのかもしれません。\nざっくりですがセマンティック検索について調べてみました。 こんなデータだとどうなの?ここの考え方が間違ってるのでは?などの指摘がありましたら、コメント欄またはTwitter(@johtani)でコメントを頂けたらと。\n","date":1625130583,"dir":"post/2021/","id":"43caef5d41c4e74826e4a8d82088739d","lang":"ja","lastmod":1625130583,"permalink":"https://blog.johtani.info/blog/2021/07/01/semantic-search-in-azure-cognitive-search/","publishdate":"2021-07-01T18:09:43+09:00","summary":"Azure Cognitive Searchで新機能「Semantic Search(セマンティック検索)」という機能の日本語対応が発表されました。 実際にはPublic P","tags":["azure search"],"title":"Azure Cognitive Searchの新機能、Semantic Searchを試してみた"},{"contents":"Sofle v2を長らく使っていましたが、コンパクトなのもやっぱりいいよなぁというときにKochi KeyboardからLunakey Miniが発売していました。 小指のあたりの傾斜が使いやすいかも?ということで、組み立ててみました。\nもちろん購入はKochi Keyboardさんからです(購入はこちらから)。\nLunakey Miniビルドガイド 作者のYoichiroさんが公開しているビルドガイドが詳細まで書かれています。 こちらをまずは参照してください。\nLunakey Mini ビルドガイド (Rev.4以降) ビルドログ(主にツイート) 私の組み立てについては、Twitterでツイートしていたものがありますので、そちらを貼っておきます。 ちなみに、ツイートしていて躓いているときに、作者のYoichiroさんからたびたびコメントをいただきました。 ありがとうございました!!\n間にいくつかコメントを差し込んでいます。\n結局両方のダイオードつけてしまいました。今日はここまで pic.twitter.com/3qLI6EpfXB\n\u0026mdash; Jun Ohtani (@johtani) April 12, 2021 ハンダはつけた pic.twitter.com/ySE9SA3gZn\n\u0026mdash; Jun Ohtani (@johtani) April 13, 2021 コンスルー問題 左手じゃん、T。Tのダイオード浮いてた。右手も一回全部見直すか\n\u0026mdash; Jun Ohtani (@johtani) April 13, 2021 ここで問題が発覚。右手(ツイートではぼけていて、左手と書いています)についてはダイオードが1か所浮いていただけなので、はんだ付けですぐ直りました。 左手側が大問題です。そもそも右手につけたProMicroへの書き込みができませんでした。 キーボードによっては、ダイオードなどを付ける前からまず、リセットボタンを付けて、ProMicroを指して書き込みをする場合もあります。 ただ、その書き込みができない。 (ちなみにこのタイミングでテスターをつけっぱなしにしていたのが発覚し、9V電池切れのため翌日に持ち越した。。。)\nさて、デバッグのお時間です pic.twitter.com/CaEOv4E5Bg\n\u0026mdash; Jun Ohtani (@johtani) April 14, 2021 ただ、ProMicro刺した状態で、リセットボタン、リセットボタンの足をショートさせても書き込みはできず、ProMicroのGndとResetの足のショートでは書き込みができる。\n\u0026mdash; Jun Ohtani (@johtani) April 14, 2021 テスターで調べてみたところ、リセットボタンとProMicroがうまく通電していません。\nだいぶ進んだけど、Eの列がおかしいなぁ。さて、どこの接触だ? pic.twitter.com/5tci12Vk05\n\u0026mdash; Jun Ohtani (@johtani) April 14, 2021 どうも、左手の基盤のProMicroの足の穴がコンスルーとの接触が悪いみたいでした。 コンスルーの足を無理やりまげて(3個のコンスルーの足を折りました。。。)、通電できるようにして解決(結局あとでいくつかの足についてははんだ付けしました)。\n終わった。LEDの予備はんだまでやってからおしまいにしよ\n\u0026mdash; Jun Ohtani (@johtani) April 16, 2021 LED実装 鬼門の表面実装ですが、LEDを1個破損するだけで乗り切りました。ちょっと色はおかしかったですが、これはおそらくProMicroの足のせい。\n一個逆につけてしまい、お亡くなりになりましたが、まぁ、良いかな。まずは右手 pic.twitter.com/zldu6fRsXR\n\u0026mdash; Jun Ohtani (@johtani) April 18, 2021 ソケットの実装x2 ロープロファイル(Kailh choc v1)のキースイッチも試してみたいので、MXと両方のソケットをはんだ付けしました。 両方利用できるのは便利ですね。はんだ付けも楽しいし。\nソケットを片手だけ(両方のソケットつけるのでまだ、1/4) pic.twitter.com/7XFRDx0D0I\n\u0026mdash; Jun Ohtani (@johtani) April 18, 2021 キースイッチ設置 親指以外にはKailh Box Silentのピンク軸(Kochi Keyboardから)、親指にはKailh Input Club Hako Violet(AliExpressで購入したもの。リンクは遊舎工房のもの)をつけました。 どちらもそれほどぶれもないものです。Silent ピンクはリニアで静かでそれほど力がいらないスイッチになっています。 親指はタクタイルで小気味のいい音が気に入っています。Sofleもこのキースイッチになってます。\n残りのソケットつけて、キースイッチも設置して、動確してボトムプレートも装着。残りはキーキャップ。 pic.twitter.com/hGc1TtI6fu\n\u0026mdash; Jun Ohtani (@johtani) April 25, 2021 キーキャップ+キーマップ お試しにXDAのキーキャップをはめてみたのですが、キーの境目がわかりにくく、タイプミスが多かったです。 その後のツイートにあるようにOEMに切り替えています。\nキーマップについては、Lunakey Miniの作者のYoichiroさんが作ったRemapというブラウザベースでキーマップの書き換えができるツールで楽々変更ができました。JISキーまで対応しているのでJISベースでキーマップを作成している私にはうってつけでした。 Remapの利用方法についてはサリチル酸さんのブログが詳しく書いてあります(本当に頭が下がります)。\nRemap使ってキーマップいじったら、すごく楽だった。\n\u0026mdash; Jun Ohtani (@johtani) April 26, 2021 BLE + LPME-IO化 ここまでで、USB接続で動作はしていたのですが、Sofle同様に3台をBluetoothで切り替えながら使いたかったので、 Corne Light v2につけていたBLE+LPME-IO(Corneの実装などは前のブログを参照)を抜き取って、Lunakey Miniに移植してみました。\nBLE ProMicro化は作者の方のブログで行われていたので、LPME-IO対応も何とかなるだろうと。\nBLE+LPMEに変えた。後でブログ書こう pic.twitter.com/mGePN52v6k\n\u0026mdash; Jun Ohtani (@johtani) April 29, 2021 LPME-IOへの対応はCorneとSofleの時に行なったこともあり、なんとなくあたりがついていました。 流れとしては、以下の通りです。\nBLE Micro Pro用の設定ファイルを作成 BLE Micro Proのサイトの「キーボードの設定ファイルを編集する」のコマンドでコンフィグファイルを生成 LPME-IOのジャンパをはんだでブリッジ 1.で生成したコンフィグから、Corne Lightと同じ個所のジャンプをすれば良いとわかったので今回はスキップ TRRSのI2C対応 Corne LightのLPME-IO対応の時と同様にSDAとSCLをTRRSの足にショートカット ただ、今回右手側は、下記ツイートのようにOLEDの足からTRRSの足にショートカットしました。Corneの基盤を見ていた時にこれでも行けそうだな?と思っていたので、試してみた次第です。ちなみに、左手はCorneの時と同じPro Microから長い銅線を引っ張っています(電池基盤があったので、外すのがめんどくさかったため)。 BLE Micro Proにファームウェア書き込み BLE Micro Proのサイトの手順に従います。 設定ファイルには1.で出力されているLPME用のファイルを使用。 といった感じです。キーマップが設定されていないので、Remapで設定しなおしました。 Remapは、キーマップをPDFで出力する機能までついていて、すごくいいですね。サイコー\nあと、足。 pic.twitter.com/W0Wpf5k5SE\n\u0026mdash; Jun Ohtani (@johtani) April 29, 2021 傾斜がつくように奥側に高さを出すためのゴム足を貼り付けました。 あとは、3台のPCにBluetoothで接続すれば終了です。 (AD_WO_Lのキーを利用して追加していくのを毎回忘れる。。。)\n疑問点 ちょっとだけ疑問点がありますが、時間があればそのうち調べるかな。\nRemapはクラウドに設定ファイルをセーブできるけど、json形式で手元にダウンロードしたりはできないのかなぁ? LEDは有線じゃないと点かないみたいだけど、音はどうなんだろう? 音が出せそうなら、Bluetoothの接続切り替えするときに音の出方を変えるとかをやってみたいなぁ。 まとめ ということで、Lunakey Miniを組み立てて、BLE+LPME-IO対応してみました。 はんだ付けはだいぶ慣れてきましたし、今回もトラブルがあったおかげでテスターを利用して、どのあたりがおかしいかという調査をするのも慣れてきました。 あとは、キーの配置の違いを体感して、どれが自分に合ってるかなぁ?というのを試したり仕様と思います。 ロープロファイルも試してみようかな。\nあ。もちろん、このブログは組み立ててBluetoothで接続したLunakey Mini Rev5、Kailh Box Silentピンク軸+Input Club Hako Violetで書きました!!久々に数字列がないので記号入力とかがちょっとバタバタしましたw\n","date":1619709972,"dir":"post/2021/","id":"f4baa43cc7ca712d83b99a794c4e2dbd","lang":"ja","lastmod":1619709972,"permalink":"https://blog.johtani.info/blog/2021/04/30/build-lunakey-mini-ble/","publishdate":"2021-04-30T00:26:12+09:00","summary":"Sofle v2を長らく使っていましたが、コンパクトなのもやっぱりいいよなぁというときにKochi KeyboardからLunakey Miniが発売して","tags":["DIYキーボード","misc"],"title":"Lunakey Miniを組み立てて、BLE+LPME-IO化してみた #DIYキーボード"},{"contents":"みなさんは、スライドの作成には何を使っていますか? Keynote?Powerpoint?Google Slides?\n私は、Macでスライドを作るときは前職ではテンプレートもあったのでKeynoteでしたが、ちょっとしたものはMarkdownベースのDecksetを利用していました(買い切りタイプの有料ソフト)。\nフリーランスになってもこちらを利用していたのですが、Windows環境に切り替えたので使えなくなってしまいました。 一度はGoogle Slidesで作ったのですが(第39回Es勉強会スライド)、既存の資産を流用したくなりどうしたものかと悩んでい(ツイートし)たら。\nMacの頃はDecksetってアプリでMarkdownで書いてたんだけど、Winに移動したのでこのタイミングでGoogle Slidesにでもしようかなと考えてるところ。Markdownでスライド作るのほかになんかあるか探すほうがいいかなぁ?\n\u0026mdash; Jun Ohtani (@johtani) March 18, 2021 僕はこれ使ってますhttps://t.co/sFaAmKZY6V\n\u0026mdash; miyake | ZEN (@kazuyukimiyake) March 18, 2021 ということで、利用してみようかなとなりました。\nMarpとは? Markdownでプレゼンテーションのスライドを作ることができるOSS?になります。\nMarp公式サイト といっても、これ自体を使わなくても、VS Code上でプレビューしたりHTML形式で動作するスライドを吐き出すことが可能です。 なので、VS Code用のプラグインを利用しています。\nサンプル この間利用したスライドはこんな感じのMarkdownになってます。 ---でページを区切りつつ、記述していく形です。\n--- marp: true theme: poster --- \u0026lt;!-- _class: big-center --\u0026gt; # 本当にその検索は\u0026lt;br/\u0026gt;自分が想像している検索に\u0026lt;br/\u0026gt;なってますか? \u0026lt;br/\u0026gt; \u0026lt;br/\u0026gt; \u0026gt; 2021/03 \u0026gt; Jun Ohtani / @johtani --- ![bg right:40% 40%](johtani_face.jpg) # 自己紹介 - フリーランスエンジニア - 検索技術勉強会主催者 - Apache Solr入門(第2版まで)や データ分析基盤構築入門の著者の一人 --- プレビューで見るとこんな感じです。\nプラグイン Marp for VS Code プラグインをインストールするのも簡単ですよね。 マーケットプレイスからインストールすれば完了です。\n機能については上記のページにあるように、プレビューとスライドの出力です。 プレビューでは、Markdownのプレビューみたいな形で、スライドが表示できます。\n先日この機能を利用して作成して、HTMLで出力して利用しました。 PDFとかPPTX出も出せるようなので、今後試してみようかなと。\nDecksetのスライドとの違い ページの区切りなども同じだったので、大筋ではそれほど違いはありませんでした。 ただ、画像周りとスタイルの設定は細かく修正をしました。\n変更した点としては、以下のようなものがあります。\nヘッダ部分の変更 上のサンプルにありますが、marp: trueを含む部分がMarp独自の記述です。 ページごとのちょっとした変更 ページごとにスタイルの変更ができるみたいで(Decksetではできなかったはず?)、タイトルページのスタイルを変えてあります。 画像の指定 画像の読み込み自体は違いはないのですが、画像の配置についての指定方法は カスタムテーマ用CSSの作成 デフォルトではなく、Decksetで用意されているような感じのスタイルに変更してみてます。 カスタムテーマはCSSで設定できるので、CSSファイルを用意して、VS Codeの拡張機能の設定からファイルパスを指定する形です。\nということで、当面はMarpでスライドを作っていくことになるかと思います。 まぁ、ただ、スライドを作るいこと自体が減ってきてはいるのですが。 ほかの配色を試したり、ヘッダフッタとかも試してみるのもいいかもな。\n気が向いたら、CSSをどこかにアップロードするかもです。\n※今回のブログはGateronサイレントクリア軸をルブしてみた、Corne Light v2で最後の数行を書いてみました。 キースイッチだけだとこすれる音が減った気がしてましたが、キーキャップを付けたら少しこすれる音が気になる感じです。\n","date":1617615911,"dir":"post/2021/","id":"f41d4fde94cbd7bbd28808dc080a2019","lang":"ja","lastmod":1617615911,"permalink":"https://blog.johtani.info/blog/2021/04/05/intro-marp/","publishdate":"2021-04-05T18:45:11+09:00","summary":"みなさんは、スライドの作成には何を使っていますか? Keynote?Powerpoint?Google Slides? 私は、Macでスライドを作","tags":["勉強会"],"title":"スライド作成の環境をMarpにしてみた"},{"contents":"新型コロナウィルスの影響もあり、オフラインで集まって勉強会も開催できなくなっています。 検索技術勉強会も、もう1年以上開催できていないです。\nスピーカーの人にオンラインでしゃべってもらうのもありだとは思うのですが、 懇親会とセットでその価値があったかもなぁと思うところもあり、オンラインでの開催に乗り気になれないまま時間がたってしまいました。 (配信周りを調べるのがめんどくさいなぁというのもあったかも(反省))\nそんな中、takuya-aさんと話をしていて、エンジニア同士のゆるいつながりができる場所が欲しいですねぇということに。\nはー、検索技術勉強会、オフラインでできないまま1年以上たってしまったのか。オンライン勉強会とかはスピーカーの人の負担とかもあるし、Discordみたいなオープンな場だけ用意してみるのありかなぁ?ただ、活発に話がされるのかどうかわからんし、ROMな人ばかりだとアレなんだけどなぁ。\n\u0026mdash; Jun Ohtani (@johtani) March 30, 2021 そこからの、このツイートです。 ちらほらと興味のありそうな人が出てきたねという話をしていたら、Slackのワークスペースが出来上がってましたw\n検索技術に関する情報交換を目的とした Slack を立ち上げました!こちらの招待リンクからご参加ください。 https://t.co/Tca70vuMff\n\u0026mdash; takuya-a (@takuya_b) March 31, 2021 ありがとう、takuya-aさん!\nということで、検索周りでわいわいできる場になればいいなぁと。 盛り上がってくれば、オンラインでの勉強会とかもありかもしれないですね! 興味のある方は、上記ツイート内のリンクからご参加下さい!!\n","date":1617200894,"dir":"post/2021/","id":"ce426b7f3190c8a4a47d45ac799e91a4","lang":"ja","lastmod":1617200894,"permalink":"https://blog.johtani.info/blog/2021/03/31/search-tech-jp-slack/","publishdate":"2021-03-31T23:28:14+09:00","summary":"新型コロナウィルスの影響もあり、オフラインで集まって勉強会も開催できなくなっています。 検索技術勉強会も、もう1年以上開催できていないです。 ス","tags":["勉強会"],"title":"検索技術に関する情報交換を目的としたSlackができました!"},{"contents":"Azure Cognitive SearchにはOData式という書式で条件が書ける仕組みがあります。 ODataは検索条件($filter)やソート条件($orderby)、取得する項目名の指定($select)です。\n私は、Luceneの構文に慣れているので、普通のsearchパラメータを利用しようとします。 が、OData式として特殊な書き方がいくつかあるようなのでこちらの利用方法も調べてみました。 その時、N-Gram(よくやるのはN=2)で陥る問題の話もあるのでこちらについても言及します。\nOData式で検索 次のような3件のドキュメント(フィールド名はbodyとします)をN-Gramで登録していたとします。\nミルクティを飲みたいです。 マティーニはカクテルですが、ミルクセーキは? 風呂上がりのミルクは最高です。 この時、OData式でミルクティという単語で検索してみましょう。\n検索条件は$filterで指定します。 フルテキスト検索用に関数が用意されており、こちらに単語を指定します。\n$filter=search.ismatchscoring(\u0026#39;ミルクティ\u0026#39;) こんな感じ。フィールドの指定がない場合、対象のフィールドは検索可能なフィールドすべてが検索対象になります(公式ガイドのクエリパラメータのqueryTypeに説明あり)。\nでは、実行してみましょう。で返ってくるのは?1だけかな?と思う人が多いかもしれません。 が、結果は3件とも帰ってきます。\n問題点は? では問題点はどこでしょう? ismatchscoringのオプションなどを見る前に、転置インデックスを用いた検索エンジンの挙動をおさらいしましょう。 転置インデックスの仕組みを理解することで、なぜそんな挙動になるのか?というのがわかりやすくなります。 おさらいにはElasticsearchをベースに話をしますが、Azure Cognitive Searchでも同じような挙動になります。\n転置インデックスとトークナイザー(アナライザー)の関係(おさらい) 昨年、オンラインで開催されたOSC広島で発表した資料(録画あり)でもざっくりと説明しています。\nView 本当にその検索は自分が想像している検索になってますか? on Notist.\nざっくりですが、おさらいです。\n検索エンジンでは、入力された文章を、ある規則(アナライザー)で単語に分割し、その単語ごとにどのドキュメントに出現したのか?というリストが作られます。 このリストが転置インデックスです。書籍の後ろにある索引を想像するとどんなものかがわかりやすいです。 単語に対してその単語が出てくるページ番号がわかるという仕組みです(下図は本の索引の一例)。\n書籍の索引は著者や編集の方により厳選された単語のみが採用されています。 が、検索エンジンでは文章を単語に区切る機能が存在します。 この「ある規則」で単語を区切る仕組みが「アナライザー(トークナイザー)」と呼ばれる機能です。 例えば英語用のアナライザーに英語の文章が入力されたとき、文章はこのように単語に区切られたもの(単語列)を出力します(下図)。\n今回はNGramの話なので、NGramのAnalyzerを利用してみるとこんな感じになります。\n実際に出来上がる転置インデックスは次のような形になります。 検索の仕組み(おさらい) 出来上がっている転置インデックスに対して検索をする場合、入力文字列(検索条件)に対して、転置インデックス作成時と同様にAnalyzerが動作します。 処理としては、\nクエリのパース フィールドのAnalyzerで処理 転置インデックスを検索 という形です。 例えばこんな感じ。\n同じAnalyzerの処理が入ることで、転置インデックスに採用されているのと同じ単語が出てくるため、検索がきちんとできるということになります。\n英語と日本語(NGram)の違い 英語と日本語の違いは、スペースの意味になります。 英語の場合は、スペースが単語の区切りになりますが、日本語の場合スペースでは区切られていません。\nですので、検索窓に入力された文字列は、英語の場合、クエリのパースの時点で単語に区切られます。そのあとにAnalyzerになるので、基本的には単語単位でAnalyzerの処理が動きます。そのあと、転置インデックスへの検索となります。なので、多くの場合はAnalyzerの出力は1単語です(類義語などを利用していたりする場合は異なりますが)。\n日本語の場合、スペースでは区切られていないので、クエリのパースの時点で入力された文字列がそのままAnalyzerにわたります。 今回はAnalyzer(NGram)が単語に分割し、それをもとに検索処理が実行されます。\nismatchscoringの問題点は?(やっと帰ってきました) さて、回り道をし、簡単ですが転置インデックスやAnalyzerについて説明しました。 では本題です。\n$filter=search.ismatchscoring(\u0026#39;ミルクティ\u0026#39;) このismatchscoring関数ですが、そのほかにも引数の指定が可能で、省略した場合にデフォルトで採用される値がいくつかあります。 公式のドキュメントにパラメータの意味が掲載されています。\n今回は、第4引数のsearchModeの値が問題点です。デフォルトでは、anyが指定されます。 この、anyは検索語(今回はミルクティ)の任意の検索語句が一致する必要があることになります。 「検索語句」?なんでしょう?これが、ここまで回り道をして説明してきた、Analyzerの出力した単語になります。 「ミルクティ」はNGram(N=2)のAnalyzerを通すと、\n「ミル」「ルク」「クテ」「ティ」\nという4つの単語が出力されます。 これが、「検索語句」です。「任意の」とあるので、上記4つの2文字のどれか?が出現すれば検索条件にヒットしたこととなります。\nですので、以下のように(一部のみ色を変えてます)3つの文章にはそれぞれの文字が含まれているため、先ほどの条件では3件の結果が返ってくることになります。\nミルクティを飲みたいです。 マティーニはカクテルですが、ミルクセーキは? 風呂上がりのミルクは最高です。 NGramで一部分の単語だけで一致したものがヒットしてしまうと違和感があるので、allに変更します。\n$filter=search.ismatchscoring(\u0026#39;ミルクティ\u0026#39;, \u0026#39;body\u0026#39;, \u0026#39;simple\u0026#39;, \u0026#39;all\u0026#39;) 今度はどうなるでしょう?\nミルクティを飲みたいです。 マティーニはカクテルですが、ミルクセーキは? 先ほどよりもマシになりました。 3がヒットしなくなっています。3の文章には「ティ」などが出てこないためです。 ただ、感覚的に2番目がヒットするのは少し違和感がありますよね? 確かに4つの単語がすべて出てきていますが、「ミルクティ」とは少し遠いです。\nさらに「ミルクティ」にヒットさせるにはフレーズ検索にする必要があります。 Elastic社のブログの日本語の検索に関する記事でも出てきますが、フレーズで検索することで「ミルクティ」だけにヒットさせることができます。\n「フレーズ検索=語順を保証する検索」となります。 ですので、\n「ミル」「ルク」「クテ」「ティ」\nこの順序で出てきた場合のみ、検索にヒットしたことになります。 OData式でフレーズ検索する場合は、単語をダブルクォート\u0026quot;でくくる必要があります(公式ドキュメントの例に記載あり)。\n$filter=search.ismatchscoring(\u0026#39;\u0026#34;ミルクティ\u0026#34;\u0026#39;, \u0026#39;body\u0026#39;, \u0026#39;simple\u0026#39;, \u0026#39;all\u0026#39;) これで結果は以下の1件だけとなります。\nミルクティを飲みたいです。 これでNGramで部分一致のような挙動で日本語の検索ができるようになりました。\nちなみに、フレーズにした場合は第4引数はanyに変更しても1件だけの検索結果となります。 フレーズ検索には「すべての語が含まれる」、「すべての語が順番に現れる」という2つの条件が含まれるためです。\n$filter=search.ismatchscoring(\u0026#39;\u0026#34;ミルクティ\u0026#34;\u0026#39;, \u0026#39;body\u0026#39;, \u0026#39;simple\u0026#39;, \u0026#39;any\u0026#39;) この例の引数をミルクティを\u0026quot;ミルク\u0026quot; \u0026quot;最高\u0026quot;のような検索条件に変えた場合、「\u0026ldquo;ミルク\u0026rdquo;」「\u0026ldquo;最高\u0026rdquo;」の2つの条件をanyで扱うため、 「\u0026ldquo;ミルク\u0026rdquo;」「\u0026ldquo;最高\u0026rdquo;」のどちらかが出てくれば良い結果となり、3件の結果が返ってきます。 第4引数をallに変更すると、「\u0026ldquo;ミルク\u0026rdquo;」「\u0026ldquo;最高\u0026rdquo;」の両方が出てこなければならないため、3件目のデータのみが返ってきます。\n$filter=search.ismatchscoring(\u0026#39;\u0026#34;ミルクティ\u0026#34; \u0026#34;最高\u0026#34;\u0026#39;, \u0026#39;body\u0026#39;, \u0026#39;simple\u0026#39;, \u0026#39;all\u0026#39;) これは、\n$filter=search.ismatchscoring(\u0026#39;\u0026#34;ミルクティ\u0026#34;\u0026#39;, \u0026#39;body\u0026#39;, \u0026#39;simple\u0026#39;, \u0026#39;any\u0026#39;) and search.ismatchscoring(\u0026#39;\u0026#34;最高\u0026#34;\u0026#39;, \u0026#39;body\u0026#39;, \u0026#39;simple\u0026#39;, \u0026#39;any\u0026#39;) と同じ意味となります。 少し長くはなりますが、後者の書き方をプログラムで書くと思います、私の場合は。 検索窓に入力された単語に必ず\u0026quot;を追加する処理を書くために、画面入力の文字列を一旦パースをすることになるからです。\nまとめ 簡単?にですが、OData式でのフルテキスト検索と、NGramでのフレーズ検索について説明しました。 英語の場合、もともとスペースで区切られているので、フレーズといわれてピンときますが、日本語の場合はAnalyzerの挙動をわかっていないと「?」となるかと思います。 なぜフレーズ検索が必要なのか?というのが少しでもわかっていただければと。 ちなみに、NGramのTokenizerには別の落とし穴もありますが、その話はまた後日にでも。\n参考として日本語関連の検索に関する記事のリンクを残しておきます。\n参考 Elasticsearch日本語でフレーズ検索が必要なわけ NGramも含め、Elasticsearchでの日本語の検索の設定やクエリについては、Elastic社のブログで日本語で書かれた記事が詳しいのでこちらをご覧いただくのがいいです。 ","date":1614756213,"dir":"post/2021/","id":"eced95e5f301a8340e83d81d3c0d5c0d","lang":"ja","lastmod":1614756213,"permalink":"https://blog.johtani.info/blog/2021/03/03/phrase-query-in-japanese/","publishdate":"2021-03-03T16:23:33+09:00","summary":"Azure Cognitive SearchにはOData式という書式で条件が書ける仕組みがあります。 ODataは検索条件($filter)やソート条件($orderb","tags":["azure search","elasticsearch"],"title":"OData式と日本語の検索(NGram)とフレーズ検索"},{"contents":"自宅の環境がいろいろと変わったのですが、書いていなかったので更新版です。 前回のブログ(2020/09)、前々回のブログ(2020/03)はそれぞれリンクをたどってください。\n現状のデスクトップはこんな感じ\nPC 別のブログにまとめましたが、Windowsメインに切り替えました。 ハードの話以外に、Windows OSに切り替えたときにいくつか入れたものもあります。 それは、移行のブログに少しだけ書いてあります。\nひさびさにWindowsに戻ってきていますが、だいぶ慣れました。 まぁ、それほど大したことをやってないというのもあるかもですが。。。\nメインPC以外にこれまでのmacをブラウジング用にサブディスプレイにつなぎ、マウスをLogicool Flowで行き来できるようにし、 キーボードはKVMスイッチで切り替えてやりくりしていました(最新環境はキーボードのところを参照してください)。\nAmazon | サンワダイレクト USB切替器 キーボード・マウス用 KVMスイッチ キーボード いくつかDIYしましたが、今はメインでSofle Keyboard v2を利用しています(Kochi Keyboardさんで購入できます)\nSofle keyboard v2を有線で使っていましたが、最近Bluetooth対応して無線化しました(その時のブログはこちら)。 ですので、PCとの接続の切り替えはキーボード上で特定のキーの組み合わせを押すことで、切り替えられるようになっています。 KVMとは異なり、Bluetoothの接続が切り替わるのにタイムラグがある+どこにつながっているのか?というのがわからないので、想定していないところでキーが入力されていることがあります。 これは、何とかしたいかもなぁと考えてはいるところ。\nマイク&オーディオインターフェース 基本的に自宅でリモート作業をしています(ありがとうございます)。 なので、ミーティングもオンラインです。 となるとやはり、音がいいほうがお客さんにも喜ばれるかなぁと。 2020年3月時点ではSAMSONのGoMicを利用していました。 これもいい音なのですが、大きいマイクでもいいかなと。 あとは、ほかの使い道もあるかも?ということで、オーディオテクニカのマイク(+ポップガード)とフォーカスライトのオーディオインターフェースに変えてみました。 自分は実感ないですが、きっと役に立っていると思いますw\nAmazon | audio-technica サイドアドレス コンデンサーマイクロホン AT2050 | コンデンサ | 楽器 Amazon | AUDIO-TECHNICA AT-PF2 ポップフィルター | マイクアクセサリ | 楽器 Amazon | Focusrite フォーカスライト オーディオインターフェイス 2イン/2アウト 24bit/192kHz Scarlett Solo (3rd Gen) ステッカー付きセット 【国内正規品】 | 楽器・音響機器 | 楽器 ディスプレイ 以前は、MacBookProの16インチで、メインディスプレイの下に2枚目のディスプレイも兼ねて開いて利用していました(前回のブログ参照)。 自作PCに切り替えたので、ディスプレイがなくなってしまうので、同じような大きさのモバイルモニターを利用しています。 今のところは据え置きになっていますが、持ち運べるので、ほかの部屋や外出時にも使えるんではないかなと。 ディスプレイの足などはないので、邪魔にもならず便利ですね。\nAmazon | モバイルモニター モバイルディスプレイ 4K 15.6インチ cocoparスイッチ用モニター 非光沢IPSパネル 薄い 軽量HDRモード/FreeSync対応/ブルーライト機能 3840x2160 UHD/USB Type-C/標準HDMI/mini DP/カバー付3年保証付 | cocopar | ディスプレイ 通販 音楽再生環境 サブディスプレイにサンダーボルトディスプレイを使用していたので、Mac Miniを接続していましたがサンダーボルトディスプレイには退役してもらいました。 それに伴って、Mac Miniも別の場所に移動しました。音楽再生環境にラズパイ4を復活させました。 以前購入したセットについていたケースではファンの音が気になっていたので、ヒートシンク型に変えました。 結構重いですが、冷えてそうです。\nAmazon | Geekworm Raspberry Pi(ラズベリーパイ) 4 B 用アーマー金属ケース パッシブ冷却/シェル熱放散 ラズベリーパイ4 コンピュ ータモデルB適用 (アーマーケース(ファン無し)) | Geekworm | 冷却パーツ・ファン 通販 Webカメラ カメラ自体に変更はないですが、付属品をいくつか。 Webカメラではないカメラもつけてみたいなと思い、モニターアームにカメラを付けられるものを付けてみました。 ただ、おっさんの顔をきれいに映してもなぁという結論に至ったので、Webカメラが乗っかっています。。。 あとは、デスクトップPCになり、カメラのケーブルだけではPCまで届かなくなってしまったのでUSB Type-Cの延長コードを買ってみました。実はこれ2本目ですが。。。 スタンディングデスクの昇降でケーブルに負荷がかかってしまったことがなんどかあり、1本目の延長コードは接触が悪くなってしまいました。。。時々外したりしていて、ケーブルの配置がおかしいときがあるので、気を付けるようにしています。\nAmazon | 長尾製作所 モニターアーム用 VESA カメラ&マイクマウント NB-MV001MH | 長尾製作所 | モニタアーム\u0026amp;スタンド 通販 Amazon | iVANKY USB Type C 延長ケーブル USB 3.1 Gen 2(4K@60Hz/1.0m/オス-メス)10Gbps高速データ転送 3A急速充電 usb-c 変換 Huawei MateBook13, iPad Pro11, Nintendo Switch, MacBook等対応 | IVANKY | USBケーブル 通販 照明 裸の蛍光管だったのですが、リモコンで点灯したり、照度を変えられるようにしたかったので、 パナソニックの照明に変えました。\nAmazon | パナソニック LEDシーリングライト 調光・調色タイプ リモコン付 6畳 3, 699lm HH-CD0620AZ 【Amazon.co.jp限定】 | パナソニック(Panasonic) | ホーム&キッチン 変えたのはよかったのですが、部屋が長細い+Webカメラの位置(自分から見て左にカメラを置いて、部屋の奥への画角?になっている)のせいで、右半分の顔が暗くなる場合がありました。 幸い、右にはスチールラックが組んであるので、そこにつけられる照明を購入して女優ライトみたいな感じで使っています(頻繁ではないですが)\nAmazon|ルミナス メタルラック用 LEDライト 磁石で簡単設置 連結可能 幅60cm 昼白色 LED60R-N|メタルラックパーツ オンライン通販 フットレスト 昨年3月くらいに配置して、座っているときに足を置くのに便利に使っていました。 が、1台だと幅が足りないので最近2つ目を購入して並べて使っています。 片足ずつ載せられるのは便利ですね(基本ガニ股なので。。。)。\nAmazon | サンワダイレクト フットレスト スチール製 角度10° 幅40×奥行30cm 足置き台 100-FR011 | フットレスト | 文房具・オフィス用品 ということで、最近はこんな環境で仕事をしています。 当分これで更新しないんじゃないかなぁ。 (サブディスプレイが左に寄っているので、局面ディスプレイが気になっているところですが。。。)\n","date":1614246182,"dir":"post/2021/","id":"fcb0105fa6b5777a133f247784b9d930","lang":"ja","lastmod":1614246182,"permalink":"https://blog.johtani.info/blog/2021/02/25/update-working-facility/","publishdate":"2021-02-25T18:43:02+09:00","summary":"自宅の環境がいろいろと変わったのですが、書いていなかったので更新版です。 前回のブログ(2020/09)、前々回のブログ(2020/03)はそ","tags":["misc"],"title":"自宅の作業環境(2021/02)"},{"contents":"Azure Cognitive SearchにSuggestやAutocompleteの機能があるのを見つけたので、どんな挙動なのかを調べてログとして残しておきます。\n公式ドキュメント 日本語で公式ドキュメントが公開されています。使い方や流れについてはこちらをまずは見れば使えると思います。\n本ブログでは、ざっくりとした機能の紹介と内部がどんな挙動をしていそうか?、日本語だとどういう感じになるのか?という点を紹介しようと思います。\nどんな機能? 検索窓でよく、キーワードを入力しているときに検索キーワードの候補が表示されることがあります。 このキーワードの候補を表示するための機能が今回紹介するSuggesterと呼ばれる機能です(日本語の公式ドキュメントでは「先行入力エクスペリエンス」)。 Suggesterには、以下の2つの機能が用意されています。\nAutocomplete:キー入力しているときに、入力されている文字列で始まる単語で、検索できるもの(転置インデックスに登録されている単語)をリストで返す機能 Suggestion:入力した文字列で始まるキーワードを含む、元のデータを返す機能 利用方法 Suggesterの機能を利用するにはインデックスに設定を追加する必要があります(新規、既存どちらでも可)。 ただ、既存のインデックスに設定を追加した場合、内部にすでに存在するドキュメント(データ)については、このSuggesterのデータは作られません。 ですので、既存データを再度登録しなおすといった作業が必要となるので注意が必要です。\n本ブログでは、いくつかAzure Cognitive Searchのサンプルのリクエストが出てきます。Visual Studio CodeのREST Client Extensionの書式となります。拡張機能の簡単な紹介は昨年のブログをご覧ください。\n設定編 Suggesterの設定では、主に以下の2つを設定する必要があります。\nname: suggesterの名称。クエリ時に指定します。 sourceFields: 入力データのもととなるフィールド名。 String型のみ指定可能。また、Azureで用意されたアナライザーだけが利用可能です。自分で用意するカスタムアナライザーは利用できないので注意が必要です(制限についてはこちら)。 今回使用するサンプルのインデックス設定は次の通りです。\nインデックス作成のリクエスト(@host、@api-keyはご自身のものに置き換えてください。)\n## 設定 @host = 名前.search.windows.netと記載 @api-key = APIキーを入力 ### Create index with suggester POST https://{{host}}/indexes/?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;name\u0026#34;:\u0026#34;suggester-test\u0026#34;, \u0026#34;fields\u0026#34;:[ { \u0026#34;name\u0026#34;:\u0026#34;id\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;Edm.String\u0026#34;, \u0026#34;key\u0026#34;:true, \u0026#34;searchable\u0026#34;:false }, { \u0026#34;name\u0026#34;:\u0026#34;name\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;Edm.String\u0026#34;, \u0026#34;searchable\u0026#34;:true, \u0026#34;analyzer\u0026#34;:\u0026#34;ngram_analyzer\u0026#34; }, { \u0026#34;name\u0026#34;:\u0026#34;category\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;Edm.String\u0026#34;, \u0026#34;filterable\u0026#34;:true, \u0026#34;facetable\u0026#34;: true } ], \u0026#34;suggesters\u0026#34;: [ { \u0026#34;name\u0026#34;: \u0026#34;name_suggester\u0026#34;, \u0026#34;searchMode\u0026#34;: \u0026#34;analyzingInfixMatching\u0026#34;, \u0026#34;sourceFields\u0026#34;: [ \u0026#34;name\u0026#34; ] } ] } 公式ドキュメントのサンプルでは日本語がないので、日本語のデータも入力しています。\nデータ登録リクエスト\n### Index data POST https://{{host}}/indexes/suggester-test/docs/index?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;value\u0026#34;: [ { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Microsoft Office\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;microsoft\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;2\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Microsoft Azure\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;microsoft\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;3\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;GitHub Enterprise\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;github\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;4\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;GitHub dot com\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;github\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;5\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Bluetooth Mic\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;hardware\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;6\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;東京スカイツリー\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;japanese\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;7\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;東京タワー\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;japanese\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;8\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;東京特許許可局\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;japanese\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;9\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;グランメゾン東京\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;japanese\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;10\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;東京都庁\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;japanese\u0026#34; } ] } 以上が事前準備です。データ登録時に内部でSuggester用のデータを内部で生成しているようです(公式ドキュメント)。\nクエリ編 最初に説明しましたが、Suggesterの中ではAutocompleteとSuggestionという2種類の機能が用意されています。それぞれについて例をもとに説明していきます。\nAutocomplete API 検索窓に入力された文字を元に、前方一致でどのような単語で検索できるか?という候補を表示するための機能です(2単語も対応していますが今回は省略。APIの仕様はこちら)。\nたとえば、micという文字が入力されているところでAutocomplete APIを呼び出す時は、次のようなリクエストです。searchというパラメータに入力値を与えます。suggesterNameはインデックス作成時につけた名前になります。\nPOST https://{{host}}/indexes/suggester-test/docs/autocomplete?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#34;mic\u0026#34;, \u0026#34;suggesterName\u0026#34;: \u0026#34;name_suggester\u0026#34; } レスポンスとして、次のようなJSONが返ってきます。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;value\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;microsoft\u0026#34;, \u0026#34;queryPlusText\u0026#34;: \u0026#34;microsoft\u0026#34; }, { \u0026#34;text\u0026#34;: \u0026#34;mic\u0026#34;, \u0026#34;queryPlusText\u0026#34;: \u0026#34;mic\u0026#34; } ] } サンプルデータとして登録したデータにcategoryというフィールドを入れていました。 Autocompleteは条件を絞り込んで結果を返すこともできます。 filterにODataの書式で条件を書けます。 categoryフィールドにmicrosoftが設定されているデータだけを取得するということができます。\n### Autocomplete with filter POST https://{{host}}/indexes/suggester-test/docs/autocomplete?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#34;mic\u0026#34;, \u0026#34;suggesterName\u0026#34;: \u0026#34;name_suggester\u0026#34;, \u0026#34;filter\u0026#34;: \u0026#34;category eq \u0026#39;microsoft\u0026#39;\u0026#34; } レスポンスはこちら。先ほどとは違い、micというデータは返ってきていません。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;value\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;microsoft\u0026#34;, \u0026#34;queryPlusText\u0026#34;: \u0026#34;microsoft\u0026#34; } ] } 英語の場合、「単語」の単位は字面の通りです。スペースで単語が区切られているのでわかりやすいです。 日本語の場合は普通の人には少し想像しにくいです。 東京という文字を入力してみます。\n### Autocomplete in Japanese POST https://{{host}}/indexes/suggester-test/docs/autocomplete?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#34;東京\u0026#34;, \u0026#34;suggesterName\u0026#34;: \u0026#34;name_suggester\u0026#34; } すると返ってくるのは以下の通り「東京」だけになります。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;value\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;東京\u0026#34;, \u0026#34;queryPlusText\u0026#34;: \u0026#34;東京\u0026#34; } ] } 入っているデータは「東京スカイツリー」、「東京タワー」などです。 普通に考えると、これらがそのまま返ってくると思うかもしれませんが、違います。\nこれは、Suggesterの元となるフィールドのAnalyzerの挙動によります。 今回のインデックスのnameフィールドのanalyzerにはja.luceneです。これは、日本語用のアナライザー(Kuromoji)になります。いわゆる形態素解析器で日本語の文字列を「単語」に分割します。 英語についてはスペース区切りで分割しますが、日本語についてはKuromojiが内部の辞書とアルゴリズムに基づいて単語に分割してくれます。 Azure Cognitive Searchでは、Analyzerの挙動を確認するためのAPIも用意してあるので実行しみると、\n### Autocomplete in Japanese POST https://{{host}}/indexes/suggester-test/analyze?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;text\u0026#34;: \u0026#34;東京スカイツリー\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;ja.lucene\u0026#34; } このような結果が返ってきます。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;東京\u0026#34;, \u0026#34;startOffset\u0026#34;: 0, \u0026#34;endOffset\u0026#34;: 2, \u0026#34;position\u0026#34;: 0 }, { \u0026#34;token\u0026#34;: \u0026#34;スカイ\u0026#34;, \u0026#34;startOffset\u0026#34;: 2, \u0026#34;endOffset\u0026#34;: 5, \u0026#34;position\u0026#34;: 1 }, { \u0026#34;token\u0026#34;: \u0026#34;ツリー\u0026#34;, \u0026#34;startOffset\u0026#34;: 5, \u0026#34;endOffset\u0026#34;: 8, \u0026#34;position\u0026#34;: 2 } ] } ja.luceneのAnalyzerによって、3つの単語に分割されているのがわかります。 Autocomplete APIの実行結果も、このAnalyzerによって分割された単語をもとに、候補となる単語を前方一致で検索して結果を返しているのです。 ですので、「東」と入れても「東京」が返ってくるのがわかります。 一方で、「東京ス」と入力した場合は次のような結果となります。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;value\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;スカイ\u0026#34;, \u0026#34;queryPlusText\u0026#34;: \u0026#34;東京スカイ\u0026#34; } ] } これは、autocompleteModeと呼ばれるパラメータの挙動となります。 デフォルトでは、oneTermという設定で、最後の単語(例の「東京ス」の場合は「東京」「ス」と区切られるので「ス」という文字を単語とみなす)にマッチする単語(例では「スカイ」)が返ってきます。 queryPlusTextについては、入力された文字にtextで返ってきた単語をくっつけたものが取得できます。\n英語であれば、スペースで区切られており、単語が切れているのが簡単にイメージできますが、日本語の場合は少し違和感が出るかと。\nこのように、入力された文字が含まれる「単語」を基本的に返す動作をするのがAutocomplete APIです。\nSuggest API では、もうひとつのSuggest APIはどういったものでしょうか? autocomplete APIに似ていますが、返ってくるデータが登録されたデータそのものになります。\nたとえば、micという文字列を入力とした場合、\nPOST https://{{host}}/indexes/suggester-test/docs/suggest?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#34;mic\u0026#34;, \u0026#34;suggesterName\u0026#34;: \u0026#34;name_suggester\u0026#34; } 次のような結果が返ってきます。Autocompleteの時は単語でしたが、こちらは入力データがそのまま返ってきています。 入力データの中にmicで始まる単語が含まれたものが候補となっています。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.text\u0026#34;: \u0026#34;Bluetooth Mic\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;5\u0026#34; }, { \u0026#34;@search.text\u0026#34;: \u0026#34;Microsoft Office\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;1\u0026#34; }, { \u0026#34;@search.text\u0026#34;: \u0026#34;Microsoft Azure\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;2\u0026#34; } ] } 日本語の場合、Autocompleteとは異なり、その単語を含むものがサジェストされるので、「東京」をsearchに指定すると「東京」を含むデータが出てきます。\n### Suggest in Japanese POST https://{{host}}/indexes/suggester-test/docs/suggest?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#34;東京\u0026#34;, \u0026#34;suggesterName\u0026#34;: \u0026#34;name_suggester\u0026#34; } レスポンスはこちら。単語を含む元の文字列が返ってきます。ここまでは違和感はありません。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.text\u0026#34;: \u0026#34;東京タワー\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;7\u0026#34; }, { \u0026#34;@search.text\u0026#34;: \u0026#34;グランメゾン東京\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;9\u0026#34; }, { \u0026#34;@search.text\u0026#34;: \u0026#34;東京都庁\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;10\u0026#34; }, { \u0026#34;@search.text\u0026#34;: \u0026#34;東京スカイツリー\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;6\u0026#34; }, { \u0026#34;@search.text\u0026#34;: \u0026#34;東京特許許可局\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;8\u0026#34; } ] } では、「東京」「特許」という2つの単語をスペースで区切ったものが入力されたとするとどうでしょう?\n### Suggest in Japanese POST https://{{host}}/indexes/suggester-test/docs/suggest?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#34;東京 特許\u0026#34;, \u0026#34;suggesterName\u0026#34;: \u0026#34;name_suggester\u0026#34; } スペースがありますが、内部処理では形態素解析器が分割した後でこの単語の順番で出てくるものを探しているので、出てくることになります。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.text\u0026#34;: \u0026#34;東京特許許可局\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;8\u0026#34; } ] } なお、このSuggestのAPIは、単語の語順を気を付ける必要があります。 「特許」「東京」と順序を入れ替えたスペース区切りの場合は、\n### Suggest in Japanese POST https://{{host}}/indexes/suggester-test/docs/suggest?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#34;特許 東京\u0026#34;, \u0026#34;suggesterName\u0026#34;: \u0026#34;name_suggester\u0026#34; } 結果は返ってこないです。おそらく内部では、フレーズクエリで、最後の単語だけを前方一致で検索するような仕組みが動いているのだと思われます。 スペースで区切られてはいるが、順序があるので少し違和感を感じるかもしれません。英語だとフレーズの部分のイメージは沸きやすいのですが。\n短い文章のデータ(例:本のタイトルやランドマーク名など)では、このSuggestAPIを利用するとデータそのものが返却されるので、便利かもしれません。\nまとめ ということで、Azure Cognitive SearchのSuggesterの簡単な紹介でした。APIのページにはそのほかのパラメータについても説明があるので、使ってみようと思う方は目を通していただくのがよいかと。\n今回のブログは裏の仕組みがどんな感じなのか?を想像しながらAPIについて調べた形になります。日本語の場合に、少し違和感を覚える人もいそうだろうなということでブログを書いてみました。 今回は書いていませんが日本語でAutocompleteをやりたい場合は、読み仮名でも漢字が表示されるほうがよいという場合もあると思います。 その場合は、用意されている機能では難しいので、独自実装するといった方法になりそうです。 英語や、読みを利用しない場合は、挙動を理解していれば役に立つ場面もありそうです。\n","date":1612515120,"dir":"post/2021/","id":"931b2ebd9bfaeb5dcf1973e724a1f8d0","lang":"ja","lastmod":1612515120,"permalink":"https://blog.johtani.info/blog/2021/02/05/autocomplete-and-suggest-on-azure-search/","publishdate":"2021-02-05T17:52:00+09:00","summary":"Azure Cognitive SearchにSuggestやAutocompleteの機能があるのを見つけたので、どんな挙動なのかを調べてログとして残しておきます。 公","tags":["azure search"],"title":"Azure Cognitive Searchでオートコンプリートやサジェストをしてみる"},{"contents":"オライリー・ジャパンから出ている「コンピュータシステムの理論と実装」を読み始めたのでメモを取ることに。\n原著はオライリーじゃないのかというのが、まず最初の気づきでした。\nNANDからテトリス コンピュータのハードウェアからOS、さらにその上で動くアプリケーションまでを動作させるというのを少しずつやっていくという書籍みたいです。 イントロと1章を読みましたが、1章では論理回路の話でした。\n実際に物理的に作るわけではなく、シミュレーターなどのソフトウェアが用意されており、 そのソフトウェア上で動くものを作っていくことになります。 ソフトウェアのために専用のサイトが用意されて、ダウンロードもできるようになっているので、実際に手を動かしながら理解を進める感じになるのかと。\n目次を見ていただくとわかりますが、すごく幅が広いです。 1年で読み終われるかなぁ?まぁ、のんびりやっていこうかなと。\n用意されているソフトウェアなどで便利だなと思ったのは、どの章からでも興味のある部分から始められるようになっているようです(まだ始めてなくて。。。) 内部ではすべてのパーツがそろえてあるけど、章ごとのプロジェクトでは、個別に自分で実装したものがあればそちらが動くという挙動のようです。\nということで、ちょっとずつやっていこうかなと。 ほんとにテトリス動くのかなぁ?\n","date":1612424444,"dir":"post/2021/","id":"aa61b4543e8a7c67fccabee27a6e99cd","lang":"ja","lastmod":1612424444,"permalink":"https://blog.johtani.info/blog/2021/02/04/reading-elements-of-computing-systems/","publishdate":"2021-02-04T16:40:44+09:00","summary":"オライリー・ジャパンから出ている「コンピュータシステムの理論と実装」を読み始めたのでメモを取ることに。 原著はオライリーじゃないのかというのが","tags":["輪読","Nand2Tetris"],"title":"「コンピュータシステムの理論と実装」を読み始めた #Nand2Tetris"},{"contents":"Corne使ってましたが、数字キーがあるとどうなのかな?というのがやはり気になって。 そこに、Kochi KeyboardさんからSofle Keyboard v2というのが発売されたので組み立ててみました(去年末に)。また、先日Corne Light v2のBLE化に成功したので、Sofle keyboard v2のBLE Pro Micro + LPME-IO化にもチャレンジしてみました。\nSofle keyboard v2 ビルドログ 自分で書くよりもすごくよくできたビルドログがKochi Keyboardさんで公開されているので、そちらを参考にしてください。\nSofle Keyboard v2ビルドガイド すごく詳しく書いてあります。なので、こちらを見ていただければ問題ないかなと。 ただ、自分ではいくつか失敗したので自戒を込めてログを残しておきます。\nOLED用のジャンパをはんだ付けし忘れ 単にビルドログを流し読みしたツケが。。。 Sofleは同じ基盤を左右で利用します。なので、右手と左手で、同じ基盤の表と裏を利用します。 OLED用のジャンパする部分は両面に用意されていますが、はんだでジャンプするのはPro Microが実装される面となります。\n両面にジャンプ用のランドがあるとは気づかないで、左手の裏面をジャンプしてすべて実装し終わってから、OLEDが表示されないことに気づいてしまいました(ビルドログ用にと思って撮った写真に証拠が残ってますねw)。。。\nということで、またはんダッシュ太郎くんのお世話になりました(Pro Microを外してジャンプしました)。本当に有能ですよ彼は。。。\nAmazon | サンハヤト はんだシュッ太郎NEO 45Wタイプ HSK-300 | ハンダゴテパーツ ソケットのはんだ付け甘すぎ あとは、慣れてきたなぁと思っていたところに天罰が。 キースイッチのソケットを付けるの慣れてきたなーと思って、サクサクとつけていたのですが、 いざキースイッチをはめるときにボロボロとはがれていきましたw 半分くらいは外れたんじゃないかな?ちゃんとはんだ付けした後にピンセットなどで軽くいじってみるべきですね。。。\n滑り止め 利用しているキーキャップがOEMプロファイルということもあり、数字キー側を少し高くしたほうが入力しやすいです。そのために、少し大きめのソフトクッションを購入しました。\nAmazon | WAKI ソフトクッションCN-020 クリアータイプ: 産業・研究開発用品 上の左右の角に貼り付けると、がたつきがあったので少しずらして貼り付けて安定させています。 OLEDのプレートの部分を押すと手前が浮き上がってしまいますが、そこにはキーはないので問題ないかと。\nということで、毎回気づきがあって面白いですね。。。\nSofle keyboardのBLE化 Corne LightのBLE化がうまくいったので、もうひとセットのぎけす屋さんから購入しました。 BLE Micro ProやLPME-IO、電池基盤などについては前回のCorneのBLE化の記事を参照してください。\nハードウェア編 Sofle keyboard v2は残念ながらせきごんさんの公式ページの対応キーボード一覧には掲載されていません。 が、Sofle KeyboardのGitHubのページには次のような記載があります。\nSofle is 6×4+5 keys column-staggered split keyboard with encoder support. Based on Lily58, Corne and Helix keyboards.\n基盤の写真のPro Micro周りもCorneに似ています。 ということで、おそらくBLE + LPME-IO化が行けるのでは?と予測して作業に取り掛かりました。\nPCBの確認 Sofle Keyboardの基盤の設計図はGitHub上に公開されています。 この設計図を見る方法をまずは探しました。\n自作キーボードについて探すにはまずはサリチル酸さんのブログ「自作キーボード温泉街の歩き方」です。 回路図なので、設計ノウハウあたりのカテゴリーにあるだろうと探したところ見つかりました。\n(設計者向け)オートルーターを使って睡眠時間を確保しよう 配線のテクニックというブログですが、回路図を書くためのツールKiCadについて記載があります。 このブログにある以下の記事をもとに、KiCadのインストールや使い方をちょっとだけ勉強しました。\nfoostanさんのMeishi Keyboardの開発者向けガイド(JP) KiCadことはじめ KiCadの中の回路図エディタ「Eeschema」でSofle keyboardのPCBのフォルダを開くと回路図が開きます。 実際の基盤になる前に、Pro Microのどの足と何がつながっているのか?などが見て取れます。 前回のCorneのBLE化でLPME-IO対応したときに、学習しましたが、 TRRSの足とPro MicroのSDAとSCLをつなぐことで、LPME-IOを使うことができるようになるというのがわかっています。 それをもとに回路図を見たところ、以下のような記述がありました。\nどうも、JP9とJP10というはんだでジャンプする場所を用意してくれていそうです。 先を見越した設計本当にありがたいですね。\nJP9とJP10のはんだ付け 今ついているPro Microを外し(またはんダッシュ太郎が活躍)、基板を確認したところ対象の個所がありました。下の写真は左手の裏側です。\nこれらをはんだでジャンプします。\n右手は表側にあるので、Pro Microを外した後にジャンプしました。 左手は裏側です。 Corne Lightでは、Pro Microの足から導線を使ってTRRSの足につなぎましたが、今回はすっきり実装できました。 ジャンプした後はBLE Micro Proをはんだ付けします(はんだ付けせずに動作確認しようとしましたが、うまく通電しなくてちゃんと動かなかったです)。\nLPME-IOのジャンパ LPME-IOのGitHubページにあるように、利用するキーボードによって、いくつかはんだでジャンプする必要があります。 これは、BLE Micro Pro用のConfigファイルを見て、対象を決める必要があります。 が、Sofleは事前に用意されたものがありません。\nConfigファイルの生成 用意されていないConfigファイルが、QMKの設定ファイルから生成することができるようななっています(本当に感謝しかないですね)。 手順はBLE Micro Proのドキュメントにありました。\n新しいキーボード用の設定を作成する - QMK用の設定から変換する この変換スクリプトで3種類のconfig(右手用、左手用、LPME-IO用)が生成されます。 私の場合はLPMEを利用するので、lpmeという名前の入ったconfigを利用します。 中を見るとcol以下の記載が以下の通りだったので、8からDをジャンプします。\n\u0026#34;col_pins\u0026#34;:[18, 17, 16, 15, 14, 13, 18, 17, 16, 15, 14, 13], ここまででハードウェア側が終了です。\nファームウェア・設定編 ハードウェアの実装が終わったので、ファームウェアおよびアプリの設定です。\nファームウェアのセットアップ キーボードをUSBで接続し、BLE Micro Pro Web Configuratorのページにアクセスすると、 セットアップ初期画面が出てきます。\n公式ページの「キーボードを選ぶ」を参考にファームウェア、アプリのアップデートを行います。 「設定ファイルの書き込み」のタイミングでupload your ownを選択すると、ファイル選択画面が出てくるので、変換スクリプトで生成したJSONファイルを選択します。 このとき、Mas Storage Classとしてキーボードが認識されている状態だとうまく書き込めなかったので、キーボードのドライブを「取り出し」してからファイルをアップロードしました。\nキーマップの設定 BLE Micro Proのアプリが設定をきちんと認識すれば、あとはWeb Configuratorでキーマップの設定が可能になります。 これまた、残念なことに、BLE化する前のキーマップをJSONファイルで保存してなかったので(泣きそうw)、QMKのkeymap.cのファイルをもとに、ブラウザ上でがんばって設定しましたw また、新しい設定ではBLE関連のキーをマッピングとして追加しています。\nBluetooth接続 あとは、接続確認です。 MacとWin2台と接続するのですが、Win→Mac→Winの順番でBluetoothの接続をやっていたら、なぜか3つ目のWindowsで接続候補に出てくるけど、接続しようとするとタイムアウトをするという現象に遭遇しました。 MacのBluetoothの設定を一旦削除してから、Win→Win→Macの順番でペアリングしたところ問題なく接続できました。ただ、これが本当の対処なのかどうかは不明です。3番目だと接続できなかったWindowsマシンは再起動もしてみたのですがダメでした。この辺よくわかってないなぁ。\nまとめ ということで、Corne Lightに引き続き、Sofle Keyboard v2もBLE+LPME化に成功しました。 導線なども使わずにLPME対応ができたので見た目もすっきりしています。 これで、KVMスイッチだと2台までしか切り替えできなかったのが、3台をひとつのキーボードで操ることができるようになりました。 だいぶ楽になりそうな予感がしています。\nまだ、完ぺきではないので、次のような対応をやっていく予定です。\nロータリーエンコーダー対応:BLE以前はQMKのkeymap.cの中でロータリーエンコーダーの動作を記述していたので、BLE Micro Proでどうやるのかを調べたい。encorder.jsonというファイルがあったのでその辺ではないかな? OLED対応:Corne Lightの時と同様に、OLEDが点かなくなったのでこの辺りを調べたい。 ということで、とりあえずキー入力するのには困らない程度にはできたので、より便利にする方法を時間を見つけて模索する感じになりそうです。 あと、KiCadも面白そうなのでこっちもちょっと触ってみたくなってきたかも?\n","date":1612106122,"dir":"post/2021/","id":"d95522c691013bfe66dd46ded85a98ed","lang":"ja","lastmod":1612106122,"permalink":"https://blog.johtani.info/blog/2021/02/01/apply-ble-to-sofle/","publishdate":"2021-02-01T00:15:22+09:00","summary":"Corne使ってましたが、数字キーがあるとどうなのかな?というのがやはり気になって。 そこに、Kochi KeyboardさんからSofle Keyboard v","tags":["DIYキーボード","misc"],"title":"Sofle v2を組み立てて、BLE+LPME-IO化してみた #DIYキーボード"},{"contents":"メインマシンとMacは下記のサンワサプライのUSB接続のKVMスイッチを使っていますが、もう一台ノートPCがありここに接続しているCorne(初めてのDIYキーボード)が長いUSBケーブルでつながっています。\nAmazon | サンワダイレクト USB切替器 キーボード・マウス用 KVMスイッチ 時々必要になって、デスクにキーボードだけ引っ張ってきて利用するのですが、ケーブルの取り回しがまぁ邪魔で。。。 BLE対応(BLE Micro Pro)をしてみようかなということに。\nBLE + LPME-IO対応 分割キーボードをBLE対応(それぞれにBLE Micro Proを実装)すると、キーボード間のつながりがいまいちになることもあるというのをちらほら見ていたので、BLE Micro Pro + LPME-IOという構成で、 Corneのキーボード同士はTRRSケーブルで接続し、PCとCorne間をBluetoothで接続する構成にしてみました。\nBLE Micro Proについては、公式ドキュメントにいろいろと記載があります。\n材料 ということで、材料は以下の通り。セット販売は売り切れていたので、個別に購入しました。 コンスルーと電池以外は1つずつです。\nBLE Micro Pro(のぎけす屋) x 1 LPME-IO(のぎけす屋) x 1 BLE Micro Pro用電池基盤(遊舎工房) x 1 コンスルー(Kochi Keyboard) x 4 CR1632ボタン電池(近所のスーパー) x 2 実装 まずは、それぞれ組み立てです。\n電池基盤 以下の記事を参考にはんだ付けしました。\nQiita: 自作キーボードビルドログ:その2「ErgoDash」無線化対応 ハードウェア編 - 電池基盤の組み立て・半田付け yfuku docs - Claw44 / 無線接続について 注意点は以下の通りです。\n基盤が軽いので固定が必要(マスキングテープでマットに貼り付けたらましになった) 電池ホルダーが変形しやすい(設置して、足を折るために上から押さえつけたら、本体が曲がってしまった。。。) 部品が細かいので大変(老眼だから?) BLE Micro Proとの接続は参考にしたyfuku docsにある方法(余っていたピンヘッダを1本ずつ使ってはんだ付け)を採用しました。 (パッと見大丈夫そうだったので電池基盤の裏に絶縁テープは貼ってないです貼ってないです)\nBLE Micro Pro(もげ対策) BLE Micro Pro自体はコンスルーをはんだ付けするだけですが、今回はもげ対策として、ダイソーで買ってきたグルーガンで ちょっとだけ補強してみました。 初グルーガンだったので不細工だけど。これ難しいな。\n効き目あればいいけど?\nLPME-IO対応 いくつかのジャンパをはんだでブリッジ まずは、LPME-IOのREADMEのページの導入手順を読み、いくつかのピンをジャンプしました。 せきごんさんのBLE-Micro-Proのリポジトリに、CorneのLPME用コンフィグファイルを見ると、ジャンプするのは20, 19, 18, 17, 16, 15に対応している、F,E,D,C,B,Aの6つです(写真撮り忘れた。。。)。\nTRRSのI2C対応(って言い方であってるのかなぁ?) ジャンプだけでいけないかなぁ?と思いましたがダメでした(USBでつないでみたけど、左手(BLE-Micro-Proがついている側)だけ入力可能です。\nBLE Micro Proの公式サイトにLPME-IOについても記載があります。 実績のあるキーボード一覧にCorne Lightの記載もあったので、試してみようと思ったのが発端です。\nただ、LPME-IOの欄に注意書きが。\n*LPME-IOを使うには改造が必要\nまた、一覧の最初にも記載があります。\nLPME-IOを使うにはキーボードの左右の有線通信がI2Cである必要があります。とくにOLEDに対応しているキーボード等の場合は、I2C用のピンをTRRSジャックに接続する改造を施すことでI2C化できる場合があります。\nまだ、自作キーボードの仕組みをがっつり理解しているわけではない初心者なので、まぁ、ちょっとわからないかなと。。。 BLE Micro Proのはじめにのページを見ると、 Self Made keyboard in JapanのDiscordに専用チャネルがあるようで、過去ログを検索してみました。 検索したところ、Corneの場合Micro ProのSDA(写真の青い線)とSCL(写真の黄色い線)(参考:Corneの基盤の図)をそれぞれ、TRRSの2つのピンに接続する必要がありそうだというコメントがありました。\nCorne Cherry v2の場合は、接続するためのショートカットが用意されていましたが、Corne Light v2だと見当たりませんでした。 ということで、線を使って物理ショートカットしました。ちなみに、ショートカットは両手ともに必要なようです。\nUSB-Cで接続テスト 上記対応が終わって、基板に設置してUSB-Cケーブルで接続したところ、外部ドライブとして見えるようになりました。\nキーマップの書き換えとか 公式ドキュメントのBLE Micro Pro Web Configuratorを使うの手順通りに書き込みを行っていくと、特に問題なく接続できました。 便利すぎですね。キーマップの変更は、これまでのCorneのキーマップJSONファイルからコピペして書き込んだだけです。 (この後、BLE用のキーマップを書き足すためにもう一度変更しますが)\nLPME-IO対応なので、Micro Proは片側しかないので、書き換えも楽々でした。\nBLEで接続テスト 今回の目的だったWindowsにBluetoothで接続できるようにしてみました。 最初はサリチル酸さんの記事を見ていたのですが、キーコードがちょっと変わっているようでした。\nで、よくよく見ると、BLE Micro Pro Web ConfiguratorにBLE関連のキーも用意されているじゃないですか。。。\nBLE関連のキーを割り当てた後は、USBをオフにして、Bluetoothをオン、BTNEWで新しくペアリングするようにすれば接続完了でした。\n課題 これまでと違い、すんなり実装ができましたがまだいくつか気になる点が。\n複数の機器とペアリングして切り替え Macともペアリングしてみようとしたのですが、切り替えがうまくいかないようで。。。 OLEDつけるにはどうするんだろう? 左手側は電池が乗っているのですが、右手側はLPME-IOだけなので、上にOLEDを載せる余裕があります。 なので載せてみましたが点かないですね。ファームウェアを何かしないといけないんじゃないかな?調べないとなぁ。 という感じです。 まだちゃんと長時間使っていないので、他の問題点も出てくるかもしれませんが、まぁとりあえず使ってみてからかな。 うまくいくようなら、メインマシンにBluetoothモジュール追加してみるのもありかと考えているところです。\n調べながら、自分なりに対応してみましたが他にもいい方法とかあれば教えてもらえると助かります。\n","date":1610332951,"dir":"post/2021/","id":"4ad8239a37f641bcd17abeb96106314e","lang":"ja","lastmod":1610332951,"permalink":"https://blog.johtani.info/blog/2021/01/11/apply-ble-and-lpme-to-corne/","publishdate":"2021-01-11T11:42:31+09:00","summary":"メインマシンとMacは下記のサンワサプライのUSB接続のKVMスイッチを使っていますが、もう一台ノートPCがありここに接続しているCorne","tags":["DIYキーボード","misc"],"title":"Corne Light v2のBLE+LPME-IO対応 #DIYキーボード"},{"contents":"振り返りブログにも書きましたが、デスクトップPCを自作(DIY)しました。 組み立てたに使ったパーツのアフィリンクを貼っておきます。\n10月くらいにPC組もうと思って、組み上がったのは11月半ばでした。 最初はもうちょっと小さいPCにしようと思ってたのに気づいたらATXになってました。 パーツの選定の基準は以下のツイートです。影響されやすいなぁ。\nタワーってほど大きくなくていいと思いますが、NZXT H510 ぐらいの大きさは欲しいですね。https://t.co/s1c1fOnPyI\n単純に、スペースがないと組みにくいのと冷えにくい、買ってきたものがやっぱりこれだと入らない、というリスクがかなり減るので。\n\u0026mdash; さぼてん(さぼ福)🌵 (@cactusman) October 9, 2020 今年3台作りました。ノートPC使えない体になります。 pic.twitter.com/8zDmeRwNkS\n\u0026mdash; miyake | ZEN (@kazuyukimiyake) October 9, 2020 白いケースいいなぁという感じで、ケースとCPUクーラーが決まったんで、ググってこちらのHAKKAさんのYouTube見ながら妄想してました。 パーツがなかなか揃わなくて。 そして、PCが光るのどうなの?と思ってたのに、気づいたら光ってました(なぜ?)。\nグラボがない状態(CPU内蔵GPU)で12月頭までは動作してました。\n購入自体はTSUKUMO、ビックカメラオンライン、パソコンSHOPアーク、イートレンドオンラインショップでオンラインで購入しました。\nPCケース Amazon | NZXT H510i White CA-H510I-W1 CS7946 | NZXT | PCバッグ・ケース・スリーブ 電源 Amazon | NZXT E850 デジタル電源ユニット 80 Plus Gold 認証 [ 定格 850W 出力 ] NP-1PM-E850A-JP NP-1PM-E850A-JP SP947 | NZXT | パソコン・周辺機器 通販 マザーボード Amazon | ASRock AMD Ryzen 3000シリーズ CPU(Soket AM4)対応 X570チップセット搭載 ATX マザーボード X570 Steel Legend | ASROCK CPU AMD Ryzen 4750G\nCPUクーラー Amazon | NZXT KRAKEN Z63 簡易水冷CPUクーラー 液晶モニタ搭載 RGB対応 280mm RL-KRZ63-01 FN1441 | NZXT | CPUファン 通販 メモリ Amazon | G.SKILL 128GB(4 x 32GB)Trident Z NeoシリーズDDR4 SDRAM 3200MHz PC4-25600デスクトップメモリモデルF4-3200C16Q-128GTZN | G.Skill | メモリ 通販 SSD Amazon | Seagate FireCuda 520 M.2 1TB PCIe Gen4x4 内蔵SSD M.2 2280 3D TLC ZP1000GM3A002 | SEAGATE グラボ Amazon | GIGABYTE NVIDIA GeForce RTX3080搭載 グラフィックボード GDDR6X 10GB ホワイトモデル【国内正規代理店品】GV-N3080VISION OC-10GD | 日本ギガバイト 拡張カード Amazon | ASRock 拡張インターフェースボード Thunderbolt 3 AIC R2.0 | ASROCK | インターフェースカード 通販 拡張カードは実は差し込んだら最初うまく動かなくてサポートに連絡しました。同じ構成の検証機を用意して解決方法を見つけてもらいました。しかも数日で。サイコーのエクスペリエンスでした!\n日本語でサポートしてもらえてしかも数日で解決してもらった。ASRockのサポートすばらしかったです! https://t.co/8FasCInIqt\n\u0026mdash; Jun Ohtani (@johtani) December 8, 2020 その他 ケースのフロントパネルのUSB-Cポートを使えるようにするために。\nAmazon | Cablecc USB 3.1フロントパネルソケットType-E-マザーボード用USB 3.0 20ピンヘッダーオス拡張アダプター | cablecc | PCアクセサリ・サプライ 通販 最近のPCパーツはUSBでモニタリングできるみたいで、マザボのUSBポートが足りなかったので拡張しました。\nAmazon | マザーボードのUSB 9ピン 増設 内部用4ポートUSB2.0 HUB | ノーブランド品 | USBハブ 通販 白いケースだし、「映え」のために白いケーブルを。\nAmazon | Novonest 電源専用延長スリーブ 補助電源モジュラーケーブル 長さ300mm 6本1セット スリーブガイド24点セット付き 【SC304】 | novonest | 電源ユニット 通販 組み立て中 手元にあったCPUでBiosアップデート(Ryzen 5000シリーズにしたかったから。まだできてないけど)。\n応急処置でBiosアップデートしてる pic.twitter.com/mXf2B5kwqB\n\u0026mdash; Jun Ohtani (@johtani) November 8, 2020 さーて、頑張るぞー pic.twitter.com/HmlGqREjmP\n\u0026mdash; Jun Ohtani (@johtani) November 13, 2020 さて、仮起動実験ですよと pic.twitter.com/5HP3cbs6SH\n\u0026mdash; Jun Ohtani (@johtani) November 13, 2020 きたきたー pic.twitter.com/4sL3ymecEo\n\u0026mdash; Jun Ohtani (@johtani) November 13, 2020 コネクター刺しまくらないと pic.twitter.com/Soye3lS4M9\n\u0026mdash; Jun Ohtani (@johtani) November 13, 2020 完成はこんなかんじ 初期構成\n組み上がったよー pic.twitter.com/sBwpvLsZh3\n\u0026mdash; Jun Ohtani (@johtani) November 14, 2020 グラボデプロイ\n設置完了してこんな感じ。なんかベンチマーク走らせるかなぁ。何がいいだろ pic.twitter.com/aZufAE9fJA\n\u0026mdash; Jun Ohtani (@johtani) December 4, 2020 グラボのおまけも付けてみた。\nまぁ、せっかくついてきたので取り付けてみました(グラボ下の光ってるパネル)。 pic.twitter.com/068IxaV1ps\n\u0026mdash; Jun Ohtani (@johtani) December 4, 2020 とまぁ、こんな感じでした。 メモリは多分使い切れないだろうなぁと思いながら、やってみたかったという感じです。。。\n","date":1609422526,"dir":"post/2020/","id":"64a421c2367372c3199c66a6420faf89","lang":"ja","lastmod":1609422526,"permalink":"https://blog.johtani.info/blog/2020/12/31/diy-pc/","publishdate":"2020-12-31T22:48:46+09:00","summary":"振り返りブログにも書きましたが、デスクトップPCを自作(DIY)しました。 組み立てたに使ったパーツのアフィリンクを貼っておきます。 10月くら","tags":["misc"],"title":"PCもDIYしました"},{"contents":"今年も振り返りブログ書いてます。カタンの航海者版を購入して家族とやってましたが、負けてしまいました。\n振り返り(2019年に書いた抱負から) まずは去年の抱負を元に書きますが、3月以降はコロナウィルスの影響でいろいろと生活が変わってしまいましたね。\n職につく 厳密には達成してないことになるのかな?\n1月末にフリーランスはじめました(仮)という記事を書きましたが、 そのまま、現時点では個人事業主でフリーランスとして4社ほどお手伝いさせていただいています。\nお手伝いしてるお客さんの事例が出てた。直接的に類似画像検索の部分を手伝ってるわけではないんですが、Azure Cognitive Searchの調査とかやってます。 / 「ハッカソン」で社外の知見を積極的に活用! 富士フイルムソフトウエアが実践するサービス開発の理想形 - https://t.co/yDIwYmYDBM\n\u0026mdash; Jun Ohtani (@johtani) June 19, 2020 名前出てた。ZOZOさんの手伝いさせていただいております。 / ZOZOTOWNにおける検索速度改善までの道のり - ZOZO Technologies TECH BLOG - https://t.co/OqaFMYe0TY\n\u0026mdash; Jun Ohtani (@johtani) August 20, 2020 こんな感じです。 コロナウィルスの影響もあり、完全リモートで仕事をさせていただいています。 感謝しかないです。\nブログプラットフォームの移行 昨年の振り返りの時点で目を付けていたHugoへの乗り換えを行いました。 乗り換えについてもまとめてあります。\nOctopressからHugoへ移行中(まだ途中) ブログ移行日記(その1) - Hugoとテーマ ブログ移行日記(その2) - Markdownファイルの変換 ブログ移行日記(その3) - Hugoの設定と微調整(テーマに合わせた) ブログ移行日記(その4) - 検索機能(Algolia)の導入 ブログ移行日記(その5) - Jugemのブログを移行 無事移行できて、特に困ってない感じです。\nプログラミング 昨年よりは書いた気がしています。 まぁ、書きなぐって放置してるのもありますが。。。\n細々としたツールがいくつか。\nfrom-octopress-to-hugo bulk2es-rs azure-search-analyze-client wiki-extractor-rs kuromoji-graphviz-output kuromoji-cli あとは、Linderaという形態素解析も手伝ってみました。 ちょっと後半は忙しくなり、コーディングが減ってるんで、また復活させないと。\nRust再入門 Tantivyは結局触れてないけど、Linderaを手伝えました。あとは、ちょっとしたツール(bulk2es-rs)なども作りました。 知り合いとやっていたRust the bookを読むのも一通り終わりました。 Linderaまわりのリファクタとかを年明けにやろうかな?\n検索の勉強 仕事になりました。というか、しました。 ブッチャー本も買ったんですが、手を付けられてないので、年明けから心機一転、よみ始めようと思います。\n検索技術勉強会の継続 残念ながらだめでした。 年初にスピーカーの方に連絡は入れて履いたのですが、コロナウイルスの影響で 今年はオフラインの勉強会は無理だろうとい事で延期したままです。 オンラインの勉強会もいくつか開催されていましたが、検索技術勉強会は残念ながらモチベーションもわかずのまま今年も終わってしまいました。 単に話を聴くセミナーのようなものよりは、Podcastのような形を取るのがいいのかもなぁとは思っているのですが。。。 だれか、サクッと話したい人いたらやってみませんか?\n振り返り(今年あったできごと) さて、ここからは今年の出来事を。\n自宅環境の改善 Windowsへの移行 キーボードDIY フリーランス ブログ書いたなぁ 3月以降はずーっと自宅で仕事してました。 ということで、自宅の環境がどんどんアップデートされていった1年でした。 最終バージョンは年内に間に合わなくて、年明けに書きますが。。。 途中経過はこんな感じでした。今は更に変わっていますが。\n3月バージョン 9月バージョン 12月バージョンでも書きますが、ずっと自宅で作業だったのもあり、自作PCをやりたくなったので、久々にWindowsに帰ってきました。Ubuntuもチョット検討しましたが、Windowsに今は落ち着いています。自作PCはこんな感じ。 自作PCブログも後で書きますね。\n設置完了してこんな感じ。なんかベンチマーク走らせるかなぁ。何がいいだろ pic.twitter.com/aZufAE9fJA\n\u0026mdash; Jun Ohtani (@johtani) December 4, 2020 Windowsをお試し中 Windowsへの移行(その1) AutoHotKeyで色々と弄っているので、素のWindowsは触れる気がしないけど。。。\n自作つながりで、キーボードもDIYしました。\nDozen0を作成した Corne Light v2を作成した Corne Chocolateを組み立てた Sofle Keyboardも組み立てた(けど、ビルドブログはまだ) 分離キーボードには昨年から興味があったのですが、手を付けていませんでした。 今年は自宅でずっと作業でしたから、これを機会に作ってみました。 既製品(Moonlander)も気になってはいたのですが、DIYキーボードはプラモデル感覚で作れそうだし面白そうだなと。 今年一番ハマったものかもしれないです。 知り合いが始めたKochi Keyboardで最初に発売されたのがCorne Light v2だったので、これが初めての分割キーボードです。 40%キーボードからいきなり入ったので最初はかなり大変でしたが、なれると入力が早くなる気がします。ホームポジションからほぼ動かないのはいいですね。最初は数字列がないのでアホか???と思っていましたが。 今は、Sofle(60%キーボード)がメインになっています。40%から60%に移行すると 数字のキーが遠いなと思ってしまいますねw\nどうなるものかと思いつつ、フリーランスを続けています。 最初に仕事をいただいた富士フイルムソフトウェアさんには非常にお世話になっています(今もお手伝いさせてもらっています、ありがたい)。来年も精進していきます!\n今年はブログを書きました、最後はちょっと息切れしてる感じになってるけど。。。 もっとカジュアルに書くようにしないとなぁ。 年明けにまだ書いてないブログを書いていかないと。「自作PCブログ」「Sofleのビルドブログ」「2020年買ってよかったブログ」とか。\n来年の抱負 ということで、来年の抱負です。\nフリーランス継続? プログラミング 検索の勉強 検索のポッドキャスト? とりあえず今年は乗り切れました。来年も食べていくためにもフリーランスを継続できるように、お手伝いさせて頂いてる各社に 継続してもらえるように精進していきます。色々と勉強させて頂いてるのでほんとうにありがたいです。\nプログラミングは今年の後半はスローダウンしてしまったのでがんばらないと。 検証用のコードやちょっとしたツールを書くほうが多いので、もう少し継続してメンテナンスするようなものも書きたいなぁと。\n検索の勉強はまずはブッチャー本を買ってしまったので、ここからでしょうか。 値段も厚みもすごいので、コツコツ元を取れるようにがんばります。。。\n来年もまだまだ自宅で仕事が続きそうなので、勉強会というよりもポッドキャストみたいなものをやるのがいいのかもなと。 2020年初にやらせていただいた、「検索システム探訪」をポッドキャスト風にやるのもありなのかもなぁ。 興味ある人いたら連絡ください。公開しない雑談とかもありだと思ってるので。\n今年は色々ありましたが、無事に乗り切れました。 気軽にランチなどで遊びに行けない状況ですが、雑談相手になっていいなと思う方、連絡お待ちしています。\nさて、来年はどんなキーボード作るのかなぁ(え?また作るの??)。 今後もよろしくおねがいしまーす!\n","date":1609406004,"dir":"post/2020/","id":"a5b2ee641e10d3e4db8f888217ab9ecc","lang":"ja","lastmod":1609406004,"permalink":"https://blog.johtani.info/blog/2020/12/31/looking-back-2020/","publishdate":"2020-12-31T18:13:24+09:00","summary":"今年も振り返りブログ書いてます。カタンの航海者版を購入して家族とやってましたが、負けてしまいました。 振り返り(2019年に書いた抱負から) ま","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2020)"},{"contents":"Elastic stack (Elasticsearch) Advent Calendar 2020の18日目の記事になります。\n本日の勉強会でLTをしましたが、しゃべり足りなかったんで。 Elasticsearch 7.8でこっそりとリリースされたIndex Template V2について調べたのでどんなものかをまとめてみます。 リリースブログには出てきてない(7.8のEsのページのWhat\u0026rsquo;s newには出てた)ので気づいてない人も多いのではないでしょうか?\nIndex Templateとは? まずはIndex Templateがどんなものかを説明しましょう。\nIndexの設定やマッピングはデフォルト値以外を設定したい場合に、毎回\u0026quot;mappings\u0026quot;や\u0026quot;settings\u0026quot;の設定を指定してIndexを作成するのは手間がかかります。 そこで便利な機能として提供されているのがIndex Templateです。このIndex TemplateはCluster Stateに保管されます。\nIndex Templateを利用するときの流れは以下の通りです。\nIndex Templateの作成 Indexの作成 例えば、3ノード構成のクラスターでインデックスを作成するときに常に\u0026quot;number_of_shards: 3\u0026quot;を設定したいとします。 Index Templateは次のような感じになります。\nPUT _template/blog_num_shards { \u0026#34;index_patterns\u0026#34;: \u0026#34;blog_*\u0026#34;, \u0026#34;settings\u0026#34;: { \u0026#34;index\u0026#34;: { \u0026#34;number_of_shards\u0026#34;: 3 } } } または日本語のシンプルな形態素解析のアナライザーの設定を\u0026quot;jp_\u0026ldquo;という名前でるようできるようにしたい場合には次のような感じになります。\nPUT _template/jp_simple_kuromoji { \u0026#34;index_patterns\u0026#34;: \u0026#34;jp_\u0026#34;, \u0026#34;settings\u0026#34;: { \u0026#34;index\u0026#34;: { \u0026#34;analysis\u0026#34;: { \u0026#34;simple_jp\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;custom\u0026#34;, \u0026#34;tokenizer\u0026#34;: \u0026#34;kuromoji\u0026#34; } } } } } インデックステンプレートの登録が終われば、インデックスを作成するタイミングでIndex Templateが適用されます。 例えば、blog_2020というインデックスを作成すると、number_of_shards: 3のインデックスが作成されます(デフォルトは1)。 jp_blog_2020というインデックスを作成すると、simple_jpというAnalyzerが設定されています。 このように、インデックス名を意識するだけで設定が適用されていくのが利点です。\nちなみに、Index TemplateはIndex作成時に適用されるだけなので、Index Templateを変更してもこれまでのインデックスへは影響はありません。\nこれまでのIndex Templateの問題点 と、Index Templateが便利なのはわかりましたが、ではなぜ今回V2がリリースされたのでしょうか? 先ほどの例を見るとわかりますが、これまでのIndex Templateは部品化が難しいのが問題でした。 Index Templateはそれぞれがインデックスの作成時に適用されます。 が、Index TemplateにIndex Templateを組み込むことはできません。 例えば、先ほどサンプルとして作成したjp_simple_kuromojiのIndex Templateはjp_で始まるインデックスにしか適用できません。\nでは、blog_で始まるインデックスにもkuromojiのシンプルなアナライザーを使いたくなった場合はどうなるでしょう? 残念ながら、jp_simple_kuromojiと同じ設定をblog_num_shardsのテンプレートに追加するか、jp_simple_kuromojiのindex_patternsの部分だけを書き換えた新しいテンプレートを用意するか、jp_simple_kuromojiのindex_patternsにjp_を追加する方法です。 いずれにしてもIndex Templateの継承(複数のテンプレートを1つのインデックスに紐づける)が必要となります。 この時、複数のIndex Templateが適用されるため、適用する順番が出てきます。 この順番をIndex Templateのorderパラメータで指定できます。\nただ、これも問題のもととなっていました。 複数あるIndex Templateのどれがどの順番で適用されるのか?それはインデックスを作成時にようやくわかります。 使いたい側(インデックス)が、使いたいもの(テンプレート)を指定するのではなく、その逆(使いたいものに使いたい側の情報を設定しなくてはならない(index_patternsやorder))になっているのでわかりにくくなっていました。\nということで解決策としてリリースされたのがIndex Template V2です(ちなみに名前にV2とは言ってるわけではなく、現在のIndex Templateの機能がlegacy index templateという名前になり、Deprecatedになっています(まだログには出ない))。\nIndex Template V2 7.8のWhat\u0026rsquo;s newドキュメントではComposable Index Templateと紹介されています。 大きく3つのエンドポイントが提供されます。\nComponent Template 用API テンプレートのコンポーネントという単位で管理するためのAPI。 登録更新、削除、取得が可能 Index Template 用API Index Templateを管理するためのAPI 登録更新、削除、取得が可能 Simulate index template API(Experimental) Index Template Legacy Index Templateとの大きな違いは、\nテンプレートをコンポーネントにできる 1つのインデックスに適用されれるテンプレートは1つだけ という点です。これまでとは挙動が異なるので注意が必要です。\n新しいIndex Templateを利用する際の流れは次のようになります。\nComponent Templateの作成 Index Templateの作成 作成したIndex Templateの挙動を確認 実際にIndex名を指定してIndex Templateの挙動を確認 という形です。では、それぞれの機能を見ていきましょう。\nCoponent Template API テンプレートコンポーネントを管理するためのAPIです。 具体的なAPIごとに説明していきます。\nPUT _component_template コンポーネントを登録、変更するためのAPIです。公式ドキュメントはこちらです。 先ほどのkuromojiのAnalzyerをコンポーネントとして登録してみましょう。\nPUT _component_template/jp_simple_kuromoji { \u0026#34;template\u0026#34;: { \u0026#34;settings\u0026#34;: { \u0026#34;index\u0026#34;: { \u0026#34;analysis\u0026#34;: { \u0026#34;analyzer\u0026#34;: { \u0026#34;simple_jp\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;custom\u0026#34;, \u0026#34;tokenizer\u0026#34;: \u0026#34;kuromoji_tokenizer\u0026#34; } } } } } }, \u0026#34;version\u0026#34;: 1, \u0026#34;_meta\u0026#34;: { \u0026#34;description\u0026#34;: \u0026#34;simpleなKuromoji analyzer\u0026#34; } } 先ほどと特に違いはありません。templateという階層が1段増え、index_patternsがなくなりました。 template部分はIndexに設定するsettings、mappings、aliasesが指定可能です。 ちなみに、\u0026ldquo;template\u0026quot;の中身をそのままIndex作成時に使用した場合にエラーにならない設定である必要があります。 ここは注意が必要です。例えば、component Aでkuromojiのアナライザーの設定をし、component Bでそのアナライザーを使用するフィールドのmappingだけを記述した場合、component Bでエラーが発生します。上記のようなシチュエーションでは、Index Templateで利用するフィールドを定義し、component Aを利用する宣言をすれば問題ありません。\nそのほかに使えるパラメータで便利なものを紹介しておきます。\nクエリパラメータ\ncreate: URLに指定するパラメータ。trueを指定することで、既に存在する場合にエラーを返してくれる。更新も同じAPIなので間違わないようにするために利用すると便利。デフォルトはfalse リクエストボディ\n_meta: テンプレートにメタ情報を付与できる。_metaの中は自由に記述可能。コメントなどを書いておくとあとでわかりやすい GET _component_template コンポーネントを取得するためのAPIです。公式ドキュメントはこちらです。 一覧での取得とリストでの取得が可能です。\n一覧取得サンプル\nGET /_component_template GET /_component_template/* これ以外に、IDを指定して取得することも可能です。\nGET _component_template/jp_simple_kuromoji *を利用して複数取得も可能です。\nGET _component_template/jp* GET _component_template/j*_* DELETE _component_template コンポーネントを削除するためのAPIです。公式ドキュメントはこちらです。 IDを指定してコンポーネントを削除できます。\nDELETE /_component_template/jp_simple_kuromoji ID指定以外に*を利用することも可能ですが気を付けて使用しましょう。\nDELETE /_component_template/jp_* DELETE /_component_template/* ちなみにIndex Templateで利用されているコンポーネントを削除しようとした場合はエラー(ステータスコード400)が返ってきます。 *などを使用して削除しようとした場合は、ひとつでも利用されているものが含まれている場合は削除は実行されずにエラーだけが返ってくるようになっています。\nIndex Template API Index Templateを管理するためのAPIです。 Component Template APIで定義したコンポーネントを利用してテンプレートを作成できます。コンポーネントを利用しないで単体で完結したテンプレートも作成可能です。 具体的なAPIごとに説明していきます。\nPUT _index_template Index Templateを登録・更新するためのAPIです。公式ドキュメントはこちらです。\nこれまでのLegacy Index TemplateのAPIのエンドポイント(_template)ではなく、(_index_template)というエンドポイントになっていることにまず注意してください。 先ほど作成したjp_simple_kuromojiコンポーネントと、追加で作成した3_shardsというコンポーネントを利用して blog_で始まるインデックスに適用できるIndex Templateを作成してみましょう。\nPUT _index_template/blog_template { \u0026#34;index_patterns\u0026#34;: [\u0026#34;blog_*\u0026#34;], \u0026#34;template\u0026#34;: { \u0026#34;mappings\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;hoge\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;simple_jp\u0026#34; } } } }, \u0026#34;priority\u0026#34;: 100, \u0026#34;composed_of\u0026#34;: [\u0026#34;jp_simple_kuromoji\u0026#34;, \u0026#34;3_shards\u0026#34;] } composed_ofというパラメータに利用したいコンポーネントを配列で記述していきます。 Index Templateが適用される時に、ここに記述されている順番でコンポーネントが適用されていきます。 ですので、最後に書いてあるテンプレートが一番強いことになります。 これは例えば、同じ設定値number_of_shardsを2つのコンポーネントが設定している場合に、最後に設定した値がインデックスに採用されるという意味です (公式ドキュメントにサンプルが掲載されています)。 なお、存在しないコンポーネントをcomposed_ofに指定した場合は400エラーが返ってきます。同じコンポーネントを複数重複して指定した場合は特にエラーにはなりませんでした。 composed_ofを指定しなければ、単体で完結したテンプレートを定義可能です。\n次に重要な設定はpriorityです。これまでのテンプレート機能と異なる点で説明しましたが、\n1つのインデックスに適用されれるテンプレートは1つだけ となっています。 この1つを決めるための値がpriorityになります。 インデックス名によってはindex_patternの定義によって、複数のIndex Templateにマッチします。例えばblog_*と*_2020のIndex Templateがあった場合にblog_2020というインデックスを作った場合です。 この時、Elasticsearchはpriorityの大きい値を持ったIndex Templateだけを適用します。 blog_*のIndex Templateのpropertyが10、*_2020のIndex Templateのpropertyが100だった場合、*_2020のテンプレートが適用されます。Legacy Index Templateではorderという似たパラメータがありましたが、こちらは適用する順序を決定するためのものでした。挙動が違うので注意しましょう。\nちなみに、blog_*と*_2020のpropertyがどちらも10というIndex TemplateをPUTしようとした場合、2番目にIndex TemplateをPUTするタイミングでエラーが返ってきます。\nそのほかに使えるパラメータで便利なものはPUT _component_templateと同様にcreateと_metaです。\nGET _index_template Index Templateを取得するためのAPIです。公式ドキュメントはこちらです。 一覧での取得とリストでの取得が可能です。\n一覧取得サンプル\nGET /_index_template GET /_index_template/* これ以外に、IDを指定して取得することも可能です。\nGET _index_template/blog_template *を利用して複数取得も可能です。\nGET _index_template/blog_* GET _index_template/b*_* DELETE _index_template Index Templateを削除するためのAPIです。公式ドキュメントはこちらです。\nIDを指定してコンポーネントを削除できます。\nDELETE /_component_template/jp_simple_kuromoji ID指定以外に*を利用することも可能ですが気を付けて使用しましょう。\nDELETE /_component_template/jp_* DELETE /_component_template/* 最後のサンプルを実行すると、Elasticのツールなどが登録したIndex Template以外はすべて削除されてしまうので本当に気を付けましょう。\nSimulalte API さて、コンポーネントとテンプレートを作成したので確認をしましょう。 Legacy Index Templateでは確認するためには実際にインデックスを作成するしかありませんでしたが、V2ではSimulate APIが用意されています。 このSimulate APIには2つのAPIがあります。\nPOST /_index_template/_simulate/\u0026lt;テンプレート名\u0026gt; POST /_index_template/_simulate_index/\u0026lt;インデックス名\u0026gt; Index Templateの確認のためのAPIとインデックス名を指定したときに出来上がるIndexの設定を確認するためのAPIです。 Indexを実際に作成しなくても確認できるのは便利ですね。\n例えば先ほど作成したblog_templateを試してみましょう。\n_index_template/_simulate API POST _index_template/_simulate/blog_template レスポンスはこんな感じです。\n{ \u0026#34;template\u0026#34; : { \u0026#34;settings\u0026#34; : { \u0026#34;index\u0026#34; : { \u0026#34;analysis\u0026#34; : { \u0026#34;analyzer\u0026#34; : { \u0026#34;simple_jp\u0026#34; : { \u0026#34;filter\u0026#34; : [ \u0026#34;kuromoji_readingform\u0026#34; ], \u0026#34;type\u0026#34; : \u0026#34;custom\u0026#34;, \u0026#34;tokenizer\u0026#34; : \u0026#34;kuromoji_tokenizer\u0026#34; } } }, \u0026#34;number_of_shards\u0026#34; : \u0026#34;3\u0026#34; } }, \u0026#34;mappings\u0026#34; : { \u0026#34;properties\u0026#34; : { \u0026#34;hoge\u0026#34; : { \u0026#34;type\u0026#34; : \u0026#34;text\u0026#34;, \u0026#34;analyzer\u0026#34; : \u0026#34;simple_jp\u0026#34; } } }, \u0026#34;aliases\u0026#34; : { } }, \u0026#34;overlapping\u0026#34; : [ { \u0026#34;name\u0026#34; : \u0026#34;blog_template2\u0026#34;, \u0026#34;index_patterns\u0026#34; : [ \u0026#34;blog_*\u0026#34; ] } ] } templateにコンポーネントがマージされた結果が出力されます。 overlappingはindex_patternsがかぶる可能性があるIndex Templateの情報が出力されます。 サンプル用にblog_template2という、同じindex_patternsでpriorityが低いものを登録してあるためです。 index_patternsが完全に同じではなくとも、重複する可能性があるものはここに出力されます。 例えば、index_patternsがb*という別のIndex Templateを作成してからSimulate APIを実行すると、overlappingにそのIndex Templateも出力されます。\nSimulate Index Template APIのもう一つの機能は登録前のIndex Templateの確認です。 リクエストのURLのテンプレート名をなくし、PUT _index_templateと同じJSONをリクエストボディとして送信した場合、コンポーネントをマージしたテンプレートがどんなものかを確認できます。\nPOST _index_template/_simulate { \u0026#34;index_patterns\u0026#34;: [\u0026#34;blog_*\u0026#34;], \u0026#34;template\u0026#34;: { \u0026#34;mappings\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;hoge\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;simple_jp\u0026#34; } } } }, \u0026#34;priority\u0026#34;: 10, \u0026#34;composed_of\u0026#34;: [\u0026#34;jp_simple_kuromoji\u0026#34;] } このリクエストを送信すると、コンポーネントがマージされた結果が返ってきます。index_patternsがかぶるものがある場合はoverlappingも一緒に返却されます。\n_index_template/_simulate_index API 今度はインデックス名を指定するSimulate APIを試してみましょう。\nPOST _index_template/_simulate_index/blog_2021 これだけです。\n{ \u0026#34;template\u0026#34; : { \u0026#34;settings\u0026#34; : { \u0026#34;index\u0026#34; : { \u0026#34;analysis\u0026#34; : { \u0026#34;analyzer\u0026#34; : { \u0026#34;simple_jp\u0026#34; : { \u0026#34;filter\u0026#34; : [ \u0026#34;kuromoji_readingform\u0026#34; ], \u0026#34;type\u0026#34; : \u0026#34;custom\u0026#34;, \u0026#34;tokenizer\u0026#34; : \u0026#34;kuromoji_tokenizer\u0026#34; } } }, \u0026#34;number_of_shards\u0026#34; : \u0026#34;3\u0026#34; } }, \u0026#34;mappings\u0026#34; : { \u0026#34;properties\u0026#34; : { \u0026#34;hoge\u0026#34; : { \u0026#34;type\u0026#34; : \u0026#34;text\u0026#34;, \u0026#34;analyzer\u0026#34; : \u0026#34;simple_jp\u0026#34; } } }, \u0026#34;aliases\u0026#34; : { } }, \u0026#34;overlapping\u0026#34; : [ { \u0026#34;name\u0026#34; : \u0026#34;fuga\u0026#34;, \u0026#34;index_patterns\u0026#34; : [ \u0026#34;b*\u0026#34; ] }, { \u0026#34;name\u0026#34; : \u0026#34;2021\u0026#34;, \u0026#34;index_patterns\u0026#34; : [ \u0026#34;*_2021\u0026#34; ] } ] } 例で作成したblog_templateが適用されていますが、それ以外にindex_patternsに合致したがpriorityが低くて適用されなかったものがoverlappingに出力されています。 実際に適用されたテンプレートの名前も別途出力してくれるとわかりやすいかもしれないですね。 (*_2021というインデックスパターンのテンプレートを試しに作ってみたのですが、これはバグがありそうです。2021に合致するインデックス名をSimulateしたらoverlappingに合致しないものがたくさん出てきました。バグ報告しとくか)。\nKibana対応 ここまで、Index Template V2のAPIの説明でしたが、Kibanaでの対応についても調べてみました。\nIndex Management(Stack Management機能。Elasticライセンスが必要だが無償の機能) 7.9からKibanaのIndex管理画面でComposable Templateが利用できるようになっています(GitHub Issue)。 画面のスクショを一通り貼っておきます。残念ながら、それぞれのJSONの編集部分では補完などはサポートされていないようでした。 頑張って自分でsettingsやmappingsのJSONを記述していく感じになります。JSONとして正しいかどうかはチェックしてくれます。 Index Templateのウィザードでは、ボタンでコンポーネントを追加したり削除したり、順序を入れ替えたりといった作業が可能になっています。 また、プレビュー表示が可能なので、composed_ofで選択したものが今どのように適用されているか?といったのも確認できるようになっていました。 結構便利に管理できそうです。ちなみにスクショは7.10の画面になります。\nComponent Template周り 一覧表示とウィザード Index Template周り 一覧表示とウィザード Console(Dev Tools。OSSで利用可能) リクエストを実行は可能ですが、自動補完機能は一部のみ対応しているようです(GitHub Issue)。\n対応済みの機能\nDELETE _component_template (ただし、ここまで。存在するコンポーネント名は補完されない) 上記以外はまだ未対応のようです。 プルリクエストチャンスかも?\n参考 Composable Templates · Issue #53101 · elastic/elasticsearch What’s new in 7.8 | Elasticsearch Reference [7.8] | Elastic Index management | Elasticsearch Reference [7.10] | Elastic [Composable template] Create / Edit wizard by sebelga · Pull Request #70220 · elastic/kibana [Console] Support suggesting index templates v2 · Issue #75967 · elastic/kibana まとめ ちょっと長くなってしまいましたが、新しいIndex Templateについての紹介でした。 これまでと違い、複数のテンプレートが適用されない点があるのでそこは注意が必要そうです。 コンポーネントをうまく使えば、管理が簡易化はされそうですね。\n","date":1608216955,"dir":"post/2020/","id":"c6fc88bd57a0e57ddf22e2eb1bef892c","lang":"ja","lastmod":1608216955,"permalink":"https://blog.johtani.info/blog/2020/12/17/index_template_v2/","publishdate":"2020-12-17T23:55:55+09:00","summary":"Elastic stack (Elasticsearch) Advent Calendar 2020の18日目の記事になります。 本日の勉強会でLTをしましたが、しゃべり足りなかったんで。 Elasticsearch 7.8でこっそりとリリースされたI","tags":["elasticsearch"],"title":"Index Template V2"},{"contents":"はじめまして、pyspa。 ということで、pyspa Advent Calendar 2020の4日目(大谷コンビの2号)の投稿になります。 コンビそろってキーボード記事ですね。\n今年はDIYキーボードにはまった(はめられた?)年でした。 もともと分割キーボードには興味があり、自宅で作業するのが基本となったのもあり手を出した次第です。 まだまだ使いこなすところまでは来てないかもしれないですが、組み立てたり、問題点のキリ分けしたり、試行錯誤するのは楽しいなと。\n今回はCorne Chocolateというキーボードを組み立てたのでそちらのビルドログ(かつ今後のための教訓)になります。 LEDを使ったキーボードがどんなものなのか+薄いキーボードも気になるなということで取り組んでみました。 今回もいくつか失敗をしつつ、リカバリーして動くものができました。\nパーツ(材料) 基本のパーツは今回もKochi Keyboardさんから購入しました。\nキット : Corne Chocolate(ベースキット) キースイッチ : Kailh Choc v1 Blue (25gf リニア) 5個 キーキャップ : Kailhロープロ刻印キーキャップ ケーブル類は家に転がっていたケーブルを利用しました。 キースイッチセットもあるのですが、軽いキータッチが好みなので、一番軽いKailh ChocのBlueを試してみたくキースイッチを個別に選択しました。 キーキャップはShiroを作るときに調達していたものを利用した形です。\n今回も公式のビルドガイドにざっと目を通してから着手しました。\n準備 ビルドログにもあるようにPCBがリバーシルブなので、作業中に迷子にならないようにこんな感じで表にマスキングテープで目印をつけておきました。\n今回から耐熱ワーキングマットで作業をすることにしました。机の天板に傷つくの嫌だし。 気兼ねなくはんだできるのでおすすめです。\nhttps://t.co/0qntPD8qIa\n2ヶ月ぐらいにここで買いました!\n\u0026mdash; 西田和史(k.bigwheel) 開発基盤EM (@k_bigwheel) November 11, 2020 ダイオード、OLEDソケット、コンスルー、TRRSソケット、 こちらは前回のCorneとほぼ同様だったのでビルドガイド通りに進めます(写真撮り損ねました。。。) 前回との違いはダイオードの形です。 表面実装するタイプのダイオードなので向きに気を付けつつ、つけていきます。\nビルドガイドに向きやダイオードのつけ方が紹介されています。 拡大鏡とピンセット必須ですね。 前回同様に、ここまででいったんqmk_toolsでファームウェアをインストールして、ピンセットを使いながらキーの認識とOLEDの動作確認を行いました。 今使っているファームウェアがあるのでそれを入れて問題ないかを確認しました。\nLED実装 今回のメインイベントです(そして苦杯をなめたイベントでもあります)。 ビルドガイドにも記載がありますが、信号が流れる順番があるようなので1番から取り付けていきます。 また、ビルドガイドにLEDに関する注意事項もいくつか掲載されています。必ず読みましょう。\nこの1~6までのLEDがすごく大変でした。。。\n表面実装のLED(Underglow LED)で四苦八苦 いくつかのブログを参考にしながら作業を進めました。\nコルネキーボードを作りました ~LED取り付けに四苦八苦記~ | キオクノロンダリング SK6812miniの仕様などについて書いてあります。デバッグするのにすごく役に立ちました。 Corne Chocolateビルドログ - nokの雑記 手書きでどんな感じでやればいいのかを解説してくれています。最終的にはこの方法が一番だったのかも? 自作キーボードキット「Corne Cherry」のレビュー - 自作キーボード温泉街の歩き方 あとで出てきますが、リカバリ方法の参考になりました。 皆さん苦労されてますね、そして私も苦労しました。。。\n試してみた方法、考察は次の通りです。\nLEDチェック用のファームウェアをインストールして1つつけては動作確認 HelixのLEDテスト用ファームウェアをインストールしました。 白光 1C型こて先 失敗した後にリカバリするために購入しました。 LEDのランドなどが2Cよりも面積が小さいので、そのサイズに合わせたこて先のほうがよかったようです。 はんだの温度(温調できるはんだごて必須) 最初は250℃でやっていましたが、なかなかはんだが溶けません。そのせいで焦りも出てきます。 最終的には270度で作業しましたが、温度のせいでLEDが壊れたのはなかった気がします。1Cのこて先だったので無事だったのかもしれません。 フラックスなし あると楽だったのかも?残念ながら試してないです。 予備はんだ手法(だめっぽかった) 基盤のランド4か所に予備はんだをし、はんだを温めつつLEDを乗せる方法 LEDの裏にも予備はんだ どちらも試してみましたが、温めている個所以外のはんだと高さの違いが出てしまい、LEDが浮いてしまいます。4か所を同時に温めることはできないので、すこしずつ調整しているうちにLEDを物理的に壊してしまうことがありました。。。 ちょっとコツが分かったかも? pic.twitter.com/ruwrmEWCAe\n\u0026mdash; Jun Ohtani (@johtani) November 19, 2020 わかった気になっていますが結局失敗しました。。。\n結局最後までこれというコツはわかってない気がします。結局3つか4つのLEDがお亡くなりになりました。 うまくいかなかった原因は、予備はんだで傾きなどができ、それを修正していくうちに基盤やLEDにダメージを与えてしまったのだと思います。\nよく見ると基盤が一部剥がれかけてるのがわかるかなぁと。\nリカバリー 右手側の表面実装の4番と5番が失敗しました。\n4番目(以下のツイート右側画像の上) こちらは、1度付けたLEDをはがすときにはんだを取り除くのが不十分な状態でLEDをはがしたために、基板のランドごとはがれてしまいました。 なのでここはLEDはつかないです。。。 5番目(以下のツイート右側画像の真ん中あたりの黄色い線がつながっているLED) LED自体はつけてありますが、青色しか発光しなくなっています。 4番目が完全に死んでしまったので、無事な3番目のLEDのDINに流れている信号を 5番目のLEDのDINにも流れるようにするために10芯コードでショートカットさせました。 (リカバリ方法は先ほど紹介したブログが非常に参考になりました、先人の知恵ありがたし)。 黒い線も売っていたのですが、自戒も込めて目立つ色にしてみました。\n勉強させていただきました、、、 pic.twitter.com/Zp16fJKziM\n\u0026mdash; Jun Ohtani (@johtani) November 22, 2020 ちなみに、左側のショートカットのコードはつけた後に1か所LEDの向きが違うことに気づき必要なくなっています (上記の基盤が傷ついている画像をよく見ると上下が逆になってるのがわかる人にはわかるかも)。\n片方は導線なくて良くなった。表から見たら向きが違うのに気がついたわ、、、 pic.twitter.com/7TSDMPPxlX\n\u0026mdash; Jun Ohtani (@johtani) November 22, 2020 最終的に2か所おかしいLEDにはなりましたが、幸いにもアンダーグローです。 Kochi Keyboardさんで購入したキットのボトムプレートはFR4なのでほぼ見えません!(負け惜しみ)\nソケット さて、気を取り直してソケットをつけていきます。 Dozen0にて経験済みなのでそれほど手間はかかりませんでした。 LEDの失敗の時に1Cのこて先を購入していたため、ソケットの横の隙間からこて先が差し込めたのが便利でした(LEDでダメージを受けていたのもあり写真撮り忘れ)。\n完成 ということで完成です。デフォルトで赤く光ってます。キーキャップがLEDを透過してくれるタイプだったのがこれまたよかったですね。 作る前は光らなくてもなんて思ってたのに。\nキーマップ(v2) Corne Lightで作業を数週間ほどして、いくつか入力しにくい部分があったのでマッピングを少しだけ変えました。 相変わらず日本語キーボードベースですが、数字のレイヤーにいくつかの記号を使えるように割り当てました。 コーディングをするときに、ライブラリのバージョン(例:7.10.0とか)やIPアドレスを入力していてレイヤー切り替えのためのキーを押したり話したりするのは効率が悪すぎたためです。 数字との組み合わせでよく使いそうな以下のキーを数字のレイヤーに移動しました。\nセミコロン(JP_SCLN) コロン(KC_QUOT) アンダースコア(JP_UNDS) コンマ(KC_COMM) ピリオド(KC_DOT) スラッシュ(KC_SLSH) #include \u0026#34;keymap_jp.h\u0026#34; const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [0] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, JP_MINS, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, JP_SCLN, KC_QUOT, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, MO(1), KC_SPC, KC_ENT, MO(2), KC_RALT //`--------------------------\u0026#39; `--------------------------\u0026#39; ), [1] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LCTL, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_LEFT, KC_DOWN, KC_UP,KC_RIGHT, JP_SCLN, KC_QUOT, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LSFT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, JP_UNDS, XXXXXXX, KC_COMM, KC_DOT, KC_SLSH, XXXXXXX, //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, _______, KC_SPC, KC_ENT, MO(3), KC_RALT\\ //`--------------------------\u0026#39; `--------------------------\u0026#39; ), [2] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. KC_TAB, JP_EXLM, JP_DQUO, JP_HASH, JP_DLR, JP_PERC, JP_AMPR, JP_QUOT, JP_LPRN, JP_RPRN, JP_CIRC, KC_BSPC, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LCTL, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, JP_MINS, JP_EQL, JP_LBRC, JP_RBRC, JP_YEN, JP_AT, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LSFT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, JP_UNDS, JP_PLUS, JP_LCBR, JP_RCBR, JP_PIPE, JP_TILD, //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, MO(3), KC_SPC, KC_ENT, _______, KC_RALT //`--------------------------\u0026#39; `--------------------------\u0026#39; ), [3] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. RESET, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,\\ //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| RGB_TOG, RGB_HUI, RGB_SAI, RGB_VAI, RGB_SPI, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,\\ //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| RGB_MOD, RGB_HUD, RGB_SAD, RGB_VAD, RGB_SPD, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,\\ //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, _______, KC_SPC, KC_ENT, _______, KC_RALT\\ //`--------------------------\u0026#39; `--------------------------\u0026#39; ) }; LEDの色が変えられる!(気づくの遅い) あと、キーマップを変更しているときに4つ目のレイヤーにRGBなどのボタンがあるのに気付いて押してみたら、LEDのパターンや色を変えることができるのに気付きました。 (遅すぎでは。。。)\nキーキャップが白いのもありこんな感じの色にしてみています。\nユニコーンガンダムっぽくなった pic.twitter.com/vHxZkMrYyP\n\u0026mdash; Jun Ohtani (@johtani) November 28, 2020 まとめ ということで、失敗も多々ありましたがキーボードとしてはちゃんと動くできたものができたので安心しました。 今後、状況が落ち着いてきて自宅以外で仕事をするときにはCorne ChocolateをPCと一緒に持ち歩くと思います。 薄くて邪魔にならなくてよさそうです。\n今回もはんだっしゅ太郎大活躍でした。本当に買ってよかった。 LEDがつかないときはちょっと落ち込みましたが、これのおかげで立ち直れたのもありますし。 あとは、試行錯誤しつつLEDとかの理解ができたのも楽しかったです。 キーマップの変更時にLEDの変更などができるのに気づいたのはちょっと遅すぎたので、qmkの仕組みや割り当てられるキーにどんなものがあるのかをもう少し研究したいなと思います。\nさて、次はどんなことを試すかなぁ。\n","date":1607004824,"dir":"post/2020/","id":"a46c601d03a3a26bc418d0096fe83a42","lang":"ja","lastmod":1607004824,"permalink":"https://blog.johtani.info/blog/2020/12/03/build_corne_choc/","publishdate":"2020-12-03T23:13:44+09:00","summary":"はじめまして、pyspa。 ということで、pyspa Advent Calendar 2020の4日目(大谷コンビの2号)の投稿になります。 コンビそろってキーボード記事です","tags":["DIYキーボード","misc"],"title":"Corne Chocolateを組み立てた #DIYキーボード"},{"contents":"前回のブログのまとめに書いたように、セパレートタイプのキーボードであるCorne Light v2を作成したのでそのビルドログです。DIYキーボードとしては2つ目になります。\nまとめで書いていたお店が開店したので、購入してみました。 購入したのはこちらのKOCHI KEYBOARDさんです。 ついこの間オープンしたばっかりのお店です!\nなんで作ったの? スプリット型(セパレートタイプ?どっちが正しいんだろう?)のキーボードに興味があって、KOCHI KEYBOARDさんで買えたのがこれだったというのが大きな理由です。こういうのってタイミングだと思うので。 あとは、組み立てていくのがプラモデルみたいで面白いというのもあります。 基本的にここのところ自宅で仕事をしているので、ノートPCのキーボードにこだわる必要もないなというのも理由ですね。今後も当面は自宅で仕事になると思いますので。\nCorne Light v2 foostanさんが設計された(って言い方であってるのかな?)、3x6のサイズに親指の3キーが配置された分離型のキーボードの一種です。 シリーズ?の名前としてはCorne Keyboardと呼ばれています。 (そういえば、由来は何だろう?自作キーボードがどうやって設計されていくのかという流れがまとめられた作者の方のブログがおもしろいです。) また、基板の設計などがGitHub上でMITライセンスで公開されています。 オープンソースなハードウェアというのも面白いです。\nビルドログ 作者の方がビルドガイドを公開してくれています。ですので、こちらに沿って作業をしていきます。 ちなみに、私は今回Gateronのクリア軸を選択してみました。さらさらと入力できるのが好きなので。 サイレント軸にも興味はあるのですが、今回は実際にスプリット型のキーボードを早く触ってみたいというのが勝ちました。キーキャップについては後述します。 ツイートに都度、写真をアップしていたので組み立ては画像でお楽しみください(時々取り忘れてるけどw)。\nうむ pic.twitter.com/svW9WdzaZv\n\u0026mdash; Jun Ohtani (@johtani) October 21, 2020 刺して曲げる pic.twitter.com/M0jfQJg2k8\n\u0026mdash; Jun Ohtani (@johtani) October 22, 2020 両方できたと。ハンダまでやって今日はおしまいにすっか pic.twitter.com/HgsSrxqpcg\n\u0026mdash; Jun Ohtani (@johtani) October 22, 2020 写真取り忘れたけど、ProMicroつけた pic.twitter.com/RS4z0lqsUZ\n\u0026mdash; Jun Ohtani (@johtani) October 22, 2020 OLEDもついたと。今日はここまで pic.twitter.com/p6Z8MMP0Xz\n\u0026mdash; Jun Ohtani (@johtani) October 22, 2020 ここまでは順調です。\nOLEDがつかない? ビルドガイドに従って、この後キースイッチをつけちゃうと問題の切り分けが難しくなるということで、 ここまでの段階でQMK Toolboxを使ってProMicroにファームウェアを書き込んで、それぞれのキーのソケットの取り付け部をピンセットでショートさせつつ、キーが入力されるかどうかを見ていきます。 QMK Toolboxについてはサリチル酸さんのブログがわかりやすいので参考にさせていただきました(わかりやすい記事をありがとうございます)。 で、ビルドガイドにあるように動いてるかを確認しようとしたのですが。。。\nさて、ファームウェア書き込んだけど、OLEDがつかないな。どっかつながってないのか?\n\u0026mdash; Jun Ohtani (@johtani) October 24, 2020 ビルドガイドのようにはいかず。。。 USBでPCとつないだ状態で、QMK Configuratorをサイトで開いて、キーボード入力テストを開くと、ショートさせたキーがPC側で認識されているかのテストができます。 これで、一通りキーは認識できていそうだというのはピンセットでショートさせながら確認しました。 ただ、OLEDには何も表示されないんです。。。\n前回Dozen0を組み立てた時に、ソケットのはんだ付けが甘かったというのもあったので、 OLEDやソケットのはんだを温めなおしたりしてみて、何度か確認してみたものの特に進展がなしです。 (ちなみにうまくいかないのもあって、ぼけたツイートしたりもしてます。)\nまぁ、OLEDはビルドガイドを見てもオプション扱いなので、それよりも触ってみたい衝動に駆られて、 キースイッチをはんだ付けしていきます。\nちなみに昨晩、OLEDはとりあえず置いといてって感じでキースイッチつけてた。キーキャップはまだない pic.twitter.com/SzLmzNg60Y\n\u0026mdash; Jun Ohtani (@johtani) October 26, 2020 それも終わって、問題点の切り分けに何かできないかな?と思ってやったのがOLED単体でArduinoと接続してみて動くかどうかです。 Qiitaにちょうどいい感じの記事を見つけたのでこれまた参考にさせていただきました(4本のジャンパー線を一人で持ちながら確認するの大変だったw)。\nはんだでの修正にしっぱい で、自分の中での結論として、「OLEDソケットのはんだ付けが怪しい」となりました。 そこで、まずは外してみようかと思ったのが間違いでした。 はんだごてとはんだ吸い取り線で何とか外せるだろうと思っちゃったんですよ。 OLEDピンソケットは足が4本あって、とりあえずとれるところまではんだ吸い取り線で吸い取ってみましたが、 さすがに基盤の穴に流れ込んだはんだまでは吸い取れず、頑張って温めながらソケットを抜こうとがんばって、 ラジオペンチでピンソケットを引っ張りながら引き抜きました。かろうじて引き抜きはできたのですが、ソケットは足が折れてしまいました。\n作者登場(OLED問題の解決) そんなところにCorneの作者の方がツイートを拾ってくれたみたいで以下のような返信を頂きました。\nOLEDが点かないのはファームのせいかもしれません(最近以前のファームで動かない新しいタイプのOLEDモジュールが出回るようになりました)。お手数ですが、https://t.co/vfSBfIeeJX のブランチのものを試して頂けますか?(ただいまPRレビュー中でまだマージされていない状態です)\n\u0026mdash; c7s (@foostan) October 25, 2020 暗闇に光明とはこのことです。 教えていただいたブランチを手元でビルドしてファームウェアを書き込むと、\nすごい、出ました!右側のディスプレイにロゴが。ありがとうございます(左側のOLEDはソケットのはんだ付け直し失敗したのでもうちょっと先になりますが)!\n\u0026mdash; Jun Ohtani (@johtani) October 26, 2020 なんと、ファームウェア書き込んだ瞬間にOLEDが点くじゃないですか。 感謝感激ってやつです。お礼を言うのに便乗してOLEDの問題の切り分けの方法についても聞いてしまいました。\nOLEDリベンジ 片側は無事だったのですが、もう一方は修復が困難になったので救世主を発注します。 自作キーボードの作成に便利なものリストとして、いくつかのブログに上がっていたのですが、必要ないだろうと見送っていたツールです。\nAmazon | サンハヤト はんだシュッ太郎NEO 45Wタイプ HSK-300 | ハンダゴテパーツ 本当にすごく使いやすかったです。 OLEDのピンソケットが修復不可能だったのですが、ProMicro用に付属して余っているピンヘッダがちょうどいい長さでした。 なので、これを4本分切り取り、OLEDモジュールにつけてしまったOLEDヘッダピンを抜き取って、代わりに切り取ったピンヘッダをつかって、OLEDと基盤を直接はんだ付けすれば修復できそうだと判断しました。\nはんだシュッ太郎君を使ってOLEDについてるヘッダピンをまずは除去。 そのあとはこんな感じで繋げました。\n見にくいかもだけど pic.twitter.com/YAHoxjgppN\n\u0026mdash; Jun Ohtani (@johtani) November 5, 2020 取り外しにくくはなったけど、無事両方のOLEDが点くのも確認できました。やったー。\nヤッター、両方のOLEDがついたよー pic.twitter.com/6KLDWvnaEC\n\u0026mdash; Jun Ohtani (@johtani) October 28, 2020 キースイッチがご機嫌斜め キーキャップは別途、AliExpressで発注をかけたのですが、ここまで来たら待ちきれないですよね? ということで、手元にあった上海問屋のキーボードのキーキャップが同じMXキースイッチ用のものだったので移植しました。キーキャップ付けてみないとわかならいものですね、1つだけキースイッチがうまくはまっておらず、斜めについているのがこの時点で判明しました(ボトムプレート付けた後だったので、プレート外してから、はんだで修正)。\nちなみにキーキャップはめてる途中で、一箇所キースイッチが斜めにはんだ付けされちゃってるのを発見して慌てて直しました。 pic.twitter.com/qofHp3o4Pc\n\u0026mdash; Jun Ohtani (@johtani) October 30, 2020 無事使えるようになりました。\nアンスコが打てない&Escどこ? キーキャップ付けたので仮運用ということで、まずはデフォルトのキーマップをもとにどんな感じで入力できるのかを試してみました。 ここにも罠がw ブラウザでQMK Configuratorを開いてデフォルトのキーマップを確認しながら試し打ちをしていたのですが、どうも思ったのと違う動きをしているキーが。\nまずBASEレイヤー(レイヤー0)の右側のシフトと、LOWERレイヤーやRAISEレイヤーのEscです。 入力しているとどうも、右のシフトがEscで、レイヤーを切り替えてもTabのままだなと。 しょうがないので、OLEDが出なくてもいいのでQMK Toolboxでダウンロードしてきたものを利用したら想定通りなのにと。 きちんとqmk_firmwareの構成を理解しないままやってたつけでしたね。 結論としては、OLED用に教えてもらったブランチではキーマップが書き換わっていたようでした。 make crkbd:defautでビルドした時に利用されるkeymap.cがキーマップの定義が書いてあるファイルです。 qmk/qmk_firmwareのリポジトリにあるkeymap.cとfoostanさんにもらったブランチでは差分があったみたいでした。\nおかげで、qmk_firmwareのkeymap.cの仕組みがわかったし結果オーライです。 問題があって調べるとどんな作りになってるかとかちゃんと確認できますしね。 手順通りにやってるだけで問題が起きないと、どんな仕組みになってるのかがわからないので人に聞きまくるしかできなくなっちゃいますしね。\nこれでEsc問題は解決したのですが、アンスコがどうしても入力できません。 自作キーボード以外はすべて日本語配列のキーボードを使用しているのもあり、 日本語配列のキーボードだとどうもキーのマッピングが異なるようだと。\nググって参考にしたのはこの辺でした。\n【QMK】JPキーコードでキーマップを定義する - 天高工房 自作キーボードキット「Corne Cherry」のレビュー - 自作キーボード温泉街の歩き方 そのほかにもVIAのファームなども試したのですが、どれもうまくいかず。 色々ググってみて最終的な解決策はkeymap.cでkeymap_jp.hというファイルが読み込まれていないので、日本語用の設定とかを読み込んでみたつもりがうまく反映されていないという感じでした。\nJISにする場合、keymap_jp.hっていうヘッダファイル読み込んだほうがいいです\n\u0026mdash; Yoshi Yamaguchi (@ymotongpoo) November 3, 2020 今の時点ではこんなキーマップにしてあります。 今後も日本語配列のキーボードをベースに考えていくつもりです。\n#include QMK_KEYBOARD_H #include \u0026#34;keymap_jp.h\u0026#34; const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [0] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, JP_MINS, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, JP_SCLN, KC_QUOT, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, MO(1), KC_SPC, KC_ENT, MO(2), KC_RALT //`--------------------------\u0026#39; `--------------------------\u0026#39; ), [1] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LCTL, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_LEFT, KC_DOWN, KC_UP,KC_RIGHT, XXXXXXX, XXXXXXX, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LSFT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, _______, KC_SPC, KC_ENT, MO(3), KC_RALT\\ //`--------------------------\u0026#39; `--------------------------\u0026#39; ), [2] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. KC_TAB, JP_EXLM, JP_DQUO, JP_HASH, JP_DLR, JP_PERC, JP_AMPR, JP_QUOT, JP_LPRN, JP_RPRN, JP_CIRC, KC_BSPC, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LCTL, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, JP_MINS, JP_EQL, JP_LBRC, JP_RBRC, JP_YEN, JP_AT, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LSFT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, JP_UNDS, JP_PLUS, JP_LCBR, JP_RCBR, JP_PIPE, JP_TILD, //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, MO(3), KC_SPC, KC_ENT, _______, KC_RALT //`--------------------------\u0026#39; `--------------------------\u0026#39; ), [3] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. RESET, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,\\ //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| RGB_TOG, RGB_HUI, RGB_SAI, RGB_VAI, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,\\ //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| RGB_MOD, RGB_HUD, RGB_SAD, RGB_VAD, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,\\ //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, _______, KC_SPC, KC_ENT, _______, KC_RALT\\ //`--------------------------\u0026#39; `--------------------------\u0026#39; ) }; キーキャップが待ちきれなくて この右下のトンガリがちょっと気になる pic.twitter.com/W0A0z67cns\n\u0026mdash; Jun Ohtani (@johtani) October 30, 2020 キーキャップが待ちきれなくて上海問屋のキーキャップを付けてみて、いろいろ試行錯誤してみました。\nあー。上下関係ないのか。だからみんなこんな感じにしてるのか? pic.twitter.com/KTBlPLespr\n\u0026mdash; Jun Ohtani (@johtani) October 30, 2020 どのくらい離すのが良いか実験中 pic.twitter.com/ozK4WyBXY8\n\u0026mdash; Jun Ohtani (@johtani) November 2, 2020 キーキャップもいろいろあるのね 届いた。 pic.twitter.com/jccNW1ZcEM\n\u0026mdash; Jun Ohtani (@johtani) November 2, 2020 もう一個 pic.twitter.com/9y6qat4JiN\n\u0026mdash; Jun Ohtani (@johtani) November 2, 2020 とりあえずセミコロンの位置につけてみた。 pic.twitter.com/TDk5213IHi\n\u0026mdash; Jun Ohtani (@johtani) November 3, 2020 今はこのDSAプロファイルの青いグラデーションのキーキャップを使っています(Dukeはここにはいないですw)。 キーキャップのプロファイルはこれまた、サリチル酸さんのブログがわかりやすく書かれています(ほんとすごいなぁ。)。\n高さ調節 そのまま使っていたのですが、やはりもうちょっと奥側に高さがほしいなと。 ダイソーなどで打っているケーブルクリップがお試しには良さそうだったのでこんな感じで内側がちょっとだけ高くなるような感じにして使っています。\nこうなった。とりあえず仮運用 pic.twitter.com/VkhjawdhLM\n\u0026mdash; Jun Ohtani (@johtani) November 4, 2020 まとめ ということで、駆け足ですがCorne Light v2のビルドログでした。 いきなりフルキーボードから40%キーボードかつ異なる並びにしたので、 混乱しっぱなしですが、いい頭の運動になっているし、なにより作って動かすまでの間に いろいろと調べたり試行錯誤できたのがすごく楽しかったです。\nあとは、スプリット型+Column Staggeredになったので「c」や「b」を間違えまくっていますが、 いい気付きでした。まだまだ記号とかの入力に慣れていないですが、ちょっとずつ身に着けていけたらなと。\nただ、もう次のキーボードをDIYしたい気持ちも出てきているので困っているところです。\n書ききれてないこともあるかと思うので、ここはどうしてるの?これはどうやったの?などあれば、Tweetなりコメントなりを頂けたらなと思います。いやぁ、DIYキーボード楽しいわ。\n","date":1604503527,"dir":"post/2020/","id":"b16bddd1a6d3e5f4136446bebe7ffbc7","lang":"ja","lastmod":1604503527,"permalink":"https://blog.johtani.info/blog/2020/11/05/build-corne-light-v2/","publishdate":"2020-11-05T00:25:27+09:00","summary":"前回のブログのまとめに書いたように、セパレートタイプのキーボードであるCorne Light v2を作成したのでそのビルドログです。DIYキーボードとし","tags":["DIYキーボード","misc"],"title":"Corne Light v2を作成した #DIYキーボード"},{"contents":"ヒゲが不評だったのでいつも通りの長さに切りました。\n前回「Windowsをお試し中」と書きましたが、いくつかソフトをインストールしたりしたので現状を忘れないようにブログに残しておきます(また同じ作業する予定なので)\nインストールしたものたち 今のところインストールしたのはこの辺。 特にコメントしたいものについてこのあと明記します。\nドライバインストール from CD MX Ergoのソフトインストール。接続はコネクター Windowsアップデート Chrome Visual Studio ビルドツール(Lindera用) JetBrains Toolbox IntelliJ CLion Rider Visual Studio Code Slack Teams Google Drive共有 Gitter Divvy for Windows Zoom DeepL Sophos Twitter for Windows Office 365 AutoHotKey WSL2 - Ubuntu Windows Terminal Rustup Git for Windows wsl-ssh-agent PeaZip Speccy Hugo (WSL2のUbuntuにapt-get install hugoした) PowerToys AutoHotKey 前回のブログに書いたように、カーソル系のEmacsショートカットが体に染みついて離れないのです。 そこで、ググって見つけた記事はこちら。 AutoHotKeyというツールが Windowsに常駐して、特定のキー入力の時に、別の操作を実行してくれるツールです。\n見つけた記事にあった、https://github.com/lintaro-jp/gtk-emacs-theme-like.ahkのキーマップをもとに、いくつか変更したものを使用させていただいています。\n書き換えたのは、以下の通りです。\nCtrl+\\でIMEの切り替え(Wnn風) Ctrl+kをEmacsと同じ挙動に(もとにしたキーマップでは、カーソルから行末までが削除されてしまう) Win+sでもファイル保存(Ctrl+sと同じ挙動に。デフォルトではCortanaが起動して邪魔くさいので) すごく快適です。そのうち、もう少し自分が使いやすいようにキーマップを追加していったりするかもしれません。 特に、Macのショートカットがしみついているものについてなどです(仮想デスクトップ切り替えとか?)\nPowerToys Divvyをインストールしたのですが、グローバルショートカットがうまく動かなくていまいちでした(なんでだろ?) そこでググって見つけたのが@ITのPowerToysの記事でした。 PowerToysはMS製のOSSツールで、GitHub上で公開されています。 中には「ColorPicker」、「FancyZones」、「File Explowrer Add-ons」など、複数のツールが入っています。 「FancyZones」です。\nWindowsでは、デフォルトで、アプリにフォーカスしているときにWin+カーソルでウィンドウの配置場所をいくつか(左右どちらかに半分、4分の1(右上、左上など))に配置してくれるAero Snapというものが動いています。が、上半分などデフォルトにない柔軟な配置を設定することができません。 MacではDivvyというツールをいれて、それを実施していたのですが、先ほど書いたようにWindows版はあるものの、なぜかグローバルショートカットが動かず、システムタスクトレイのアイコンをクリックしなければいけませんでした。\nそれを解消してくれるのがFancyZonesです。 FancyZonesの設定項目で、自分で画面上にどのような割り当て領域を作るかを設定できます。さらに、マルチディスプレイ、仮想デスクトップを使っている場合、それぞれのディスプレイかつ仮想デスクトップで個別にレイアウトが設定できるようになります。 レイアウトを設定した後は、Shiftキーを押しながらウィンドウを移動すると、設定した領域が出てきて、あとは、割り当てたい領域にウィンドウを移動するだけでその領域いっぱいにウィンドウをリサイズしてくれます。 また、設定を変えることで、Shiftキーを押さなくてもウィンドウ移動するだけで領域にリサイズすることも可能です。また、Aero Snapの機能をオーバーライドしてWin+カーソルで動作させることも可能になります。\nWSL2 + Windows Terminal 三宅さんからコメントを頂いたので。\nもう少し幅広い感じですかね。あわせて Windows Terminal 使うとわりと快適です。\n\u0026mdash; miyake | ZEN (@kazuyukimiyake) October 15, 2020 なんとなく噂は聞いていましたがということで、MSのドキュメントを見ながらインストールしました。クイックスタートに則って作業するだけで特に問題なくUbuntuまで無事インストールできました。 Windows Terminalも同様です(クイックスタートで入れることになる)。\nGit for Windows + wsl-ssh-agent 少してこずったのがこちらです。 チュートリアルに記述はあったのですが、どちらで作業するのか?などが少しわかりにくかったので。ググって出てきた記事をもとに作用しました。\nRustのプロジェクトファイルをMacから丸ごとコピーしていたのですが、Git for Windowsを入れるまでは、CLion+Rust pluginの環境では、.gitファイルをきちんと認識してくれませんでした(この時WSL2と少し混同してた)。\n無事環境は用意できました。 作業の手順は以下のような感じです。 Macで使用していた.sshのディレクトリを持ってきて作業しました。\nWindows側での作業 Macから.sshディレクトリをc:\\\\Users\\johta\\にコピー Git for Windowsのインストール OpenSSHクライアントの設定 管理者権限でコマンドプロンプトを起動して sc config ssh-agent start=auto sc start ssh-agent [wsl-ssh-agent(https://github.com/rupor-github/wsl-ssh-agent)のインストール ダウンロードして.7zファイルを展開 wsl-ssh-agent-gui.exeとnpiperelay.exeをc:\\\\Users\\johta\\binに移動 c:\\\\Users\\johta\\bin\\wsl-ssh-agent-gui.exeのショートカットをスタートアップに作成 作成したスタートアップのリンク先に -setenv -envname=WSL_AUTH_SOCKを追加 Git BashでOpenSSHを利用するように設定 setx GIT_SSH C:\\\\Windows\\system32\\OpenSSH\\ssh.exe ssh-addで秘密鍵を登録 ssh-add .ssh/id_rsa WSL2のUbuntuでの作業 Ubuntuはgitがすでに入っていたのでインストールはスキップ git config --global user.name \u0026quot;Jun Ohtani\u0026quot; git config --global user.email \u0026quot;メールアドレス\u0026quot; mkdir .ssh .bashrcの最後行にwsl-ssh-agentのWSL2 compatibilityにあるexportからfiまでをコピー。この時、パスを自分のパスに変更すること(私の場合$HOME/winhome/.wslの部分を/mnt/c/Users/johta/binに書き換えました) これで、WSL2側では.sshのファイルを管理しなくても、Windows側のOpenSSHに接続してssh周りの処理をしてくれるようになりました。\nPeaZip wsl-ssh-agentが.7z形式で圧縮されていたので、ダウンロードしました。 とりあえずこれを入れてみたのですが、ほかにお勧めがあれば教えてほしいです。\nSpeccy CPUの温度やスレッドごとのCPU使用率などを見てみたいので入れてみました。 これもとりあえず入れてみた感じなので、ほかにお勧めのソフトがあれば教えてもらえればと。 リソースマネージャーでもスレッドごとのCPU使用率は見れたのですが、温度が見れなかったので。\nHugo + WSL2にあるUbuntuにsudo apt-get install hugoしてインストールしました。\nそこで、VS Code の Remote Extension です。WSL2 から ‘code’ で起動できます😎\n\u0026mdash; Daiyu Hatakeyama@Microsoft, Hack in ChatGPT (@dahatake) October 17, 2020 あとは、畠山さんに教えてもらったVSCodeのRemote - WSLを入れて、 WLSに接続した状態でVSCodeを起動して記事のMarkdownを書くと、VSCodeのターミナルを開くとWSL2に接続してくれて、hugoコマンドが実行できます。\nまとめ とりあえず、ブログが書ける環境ができました。 Mac上にあった各種プロジェクトのディレクトリをコピーして、Rustの開発もできるようになりました。\n今後も環境構築は続いていきます。Javaとか入ってないし。 SDKMan使ってたけど、切り替えどうしよう?とか。\nそういえばSDKMAN!をJDK切替に使ってたけど、結局windows側のパスは通らんので自力インストールになった。scoopがよさげ\n\u0026mdash; きしだൠ(K1S) (@kis) October 17, 2020 IDE系から呼び出すターミナルはWSL2がいいなぁとか。\nhttps://t.co/X4Jj4tih1I\n\u0026mdash; そーだい@初代ALF (@soudai1025) October 17, 2020 ほかにもおすすめなどがあれば教えてください!\n","date":1603029710,"dir":"post/2020/","id":"188c1ee5132a6752dfce5a0235354070","lang":"ja","lastmod":1603029710,"permalink":"https://blog.johtani.info/blog/2020/10/18/restart-windows-no1/","publishdate":"2020-10-18T23:01:50+09:00","summary":"ヒゲが不評だったのでいつも通りの長さに切りました。 前回「Windowsをお試し中」と書きましたが、いくつかソフトをインストールしたりしたので","tags":["misc","windows"],"title":"Windowsへの移行(その1)"},{"contents":"ヒゲが伸びてきて(試しに伸ばしてる)不評を買っている今日このごろです。\n自宅で作業することが多くなってきたので、自作PCでもと思っていますが、OSをどうしようか悩み中。 とりあえず、試しにWindowsにしてみるかということで、10年ぶりくらいにWindowsに帰ってきました (この文章はMacで入力してますが)。\nむかしむかし もともとはWindowsを使っていたのですが、Win7くらいに32bitと64bit混在の時期に、 Xkeymacsを利用するときに少し手間がかかるなぁと思ったのもあり、Macに移行しました。 Macだと自分がよく使うEmacsっぽいショートカットがデフォルトいろんなアプリで使用できる利点があったからです。\nただ、最近、TL上で光るPCとかを見てしまったのもあり、 自作PC(どちらかというとDIYかな?)熱が復活しました。 まだ、OSをWindows、Ubuntuのどちらをメインにしようかな?と悩んでいるところではありますが、まずはWndowsをちょっと試してみるかなと。\nまずは、やりたいことをちょっとリストアップしておこうかなと思います(きっと、先人の知見が集まってくるはず!)。\nどうしてもほしい機能 大学の頃にSunOSやSolarisを使用し、Emacsでメールを読んだしていたせいで、Emacsのショートカット操作が体から抜けない状態です(抜こうとしてないという話もあるが)。 ですので、社会人になってからWindowsを利用していたときはXkeymacsというソフトのお世話になっていました(神アプリでした。まだあるのかな?)。\nショートカット操作とか カーソル移動(必須) 上下左右:Ctrl+n、p、f、b 行頭、行末:Ctrl+a、e 編集 デリートキー:Ctrl+d Ctrl+hがバックスペースだけど使わないな、そういえば カーソルから行末までをカット:Ctrl+k 必須! カーソル移動がホームポジションから移動しなくてもいいのもあって、多用してしまっています。 これ、WindowsとかUbuntuでいい感じにできるのあるのかな? できれば、IMEやブラウザのURLのサジェストなどもこのカーソル移動で移動できると嬉しいです。 (昔はM-%とかで置換などもやってたけど最近はやらないな。)\nデスクトップ操作系 仮想デスクトップ やることごとにデスクトップを切り替えて使うので ウィンドウのリサイズ? DivvyというアプリをmacOSで利用中 自分で登録したサイズ(例:画面右半分)にウィンドウサイズを変更などがショートカットで可能 仮想デスクトップはあると思うけど、ウィンドウのリサイズの便利なツールあるかなぁ?\n利用するアプリ SNS、オンラインミーティング Twitter macOSではTweetDeckと夜フクロウを使用 Slack ネイティブアプリ Gitter ネイティブアプリ Chatwork ブラウザ Teams ネイティブアプリ Zoom ネイティブアプリ Google Meet ブラウザ Discord ネイティブアプリ(最近使ってないな) 色々使ってますが、最悪ブラウザで使う感じかな?\nオンラインストレージ Google Drive 同期アプリ使ってる Dropbox あんまり使ってない 開発系 JetBrainsのIDE Toolbox App IntelliJ CLion + Rust plugin Rider zsh macOSで標準になったから コマンド系 git SDKman ant gradle JDK Rust Hugo Jasper GitHubのIssueとかを見るネイティブアプリ 自分が関連しているIssueとかが楽に見える(メールだと埋もれてしまう) エディタ Visual Studio Code 開発系では?と思われるかもだけど、Markdownエディタとして使ってる Emacs by Homebrew 最近は起動してない その他 カレンダー macOSのカレンダーで複数のGoogleカレンダーを取り込んでる ScanSnap Ubuntuで使えるやつあるのかな? Mac miniにつないであるので、画面共有とかで入れればそれでOK 画面共有 winやubuntuからMac miniとか見えるかな? キーボード共有 macも使うので、KVMスイッチとかかな? マウス共有 MX ErgoのFlowを使うと行き来が簡単にできたので良さそう。 ただし、Ubuntuだとどうなるのか? システム監視系 CPUの温度とかCPU、メモリの使用率とか まとめ とりあえずこんなところです。カーソル移動系が一番重要なので、そのへんから色々とちょっとずつ試していく予定。 ぜひオススメアプリとかあれば教えていただければと。\n","date":1602727442,"dir":"post/2020/","id":"de37d9fae011687eb1eb5a127fcb89e3","lang":"ja","lastmod":1602727442,"permalink":"https://blog.johtani.info/blog/2020/10/15/restart-windows/","publishdate":"2020-10-15T11:04:02+09:00","summary":"ヒゲが伸びてきて(試しに伸ばしてる)不評を買っている今日このごろです。 自宅で作業することが多くなってきたので、自作PCでもと思っていますが、","tags":["misc","windows"],"title":"Windowsをお試し中"},{"contents":"今年の春くらいから、セパレートタイプのキーボードが気になっています。 また、なんか知らないですが、Twitterのタイムラインが自作キーボード(DIYキーボード)で盛り上がってる気がします。 (たぶん、気になってるから余計目についてる)。 これとか。このスライドから、自分がやってるのは「まだ」DIYキーボードだなということで、タイトルに使ってみました。\n#toruby \u0026quot;DIYキーボードは実質Ruby\u0026quot; 本日のスライドです! とちぎでこの話をできてよかった!!!q: https://t.co/RJot71Ngu9\n\u0026mdash; Kakutani Shintaro (@kakutani) September 12, 2020 セパレートタイプのキーボード 今年の夏まではMac Book Pro 16インチのキーボードを利用していました(参考:自宅の作業環境(2020))。 これまで、自宅で作業することよりも、外で仕事をすることが多く、また、外といっても様々な場所(サムライズムだったり、オフィスだったり、カフェだったり)で作業をすることが多かったので、ノートPCのキーボードにしていました。流石にキーボードを持って歩くほどは気にしていなかったので。\nただ、コロナウイルスの影響もあり、ほぼ自宅で作業することとなりました。 となると、前から気になっていたセパレートタイプのキーボードが俄然気になり始めます。 (といいつつ、寄り道してたりしますが)\n気になっていたのはこのあたりなのですが、\nErgodox EZ Moonlander Mark I 流石にいきなり行くにはちょっと気が引けるなぁと(なかなかいいお値段)。 また、自分が日本語キーボードを利用しているというのもちょっとあります。\nキースイッチの感触を知りたくて ただ、日々、楽しそうな自作キーボードの記事や画像が流れてきます。 で、思い出したのが自分の趣味。プラモデルです。色を塗ったりはしないですが、組み立てるのは楽しいなと。 じゃあ、趣味と実益を兼ねればいいのでは?(ほんとか?)となり、作る気になってきました。\nただ、全く知らない世界だし、どんなものなんだろう?と。 市販のキーボードでも、キーの押し具合が色々合ったり、形もまちまちです。 また、このご時世ですので、自宅からあまり出ていないので遊舎工房さんなどに遊びにも行けず。\nそんなところに流れてきたのがキースイッチのテスターでした(世の中誘惑だらけ)。\nスイッチテスター人気スイッチ詰め合わせ 18個セット 「なるほど、これでどんな感触かわかるじゃないか!」と、気づけばポチッと押していました。。。 届いて、「ふむふむ、これがこういう感触なのか。なるほど」ポチポチ押しながら、さらに自作キーボードについて調べていきます。\nいろんな感触なんだなぁ pic.twitter.com/PaGDMIRJiv\n\u0026mdash; Jun Ohtani (@johtani) September 22, 2020 キースイッチのストロークの深さを知りたくて まぁ、当たり前なのですが、先程のキースイッチテスターどこにもつながっていません。 キーボード触ってるとわかりますが、ストロークが違いがあるんですよ。 ただ、これだとわからない。けど知りたい。\nで、ググっているとArduinoを使ってLチカやってる人とか、キー入力させている人がいるじゃないですか。 これでは?そういえば、Arduinoもどきうちにもあるぞ?と。 で、準備をしていたときに見かけてしまったのがこのツイートでした。。。\nhttps://t.co/ALl7OcRVRa 高機能テスターとしてもおすすめ\n\u0026mdash; Kakutani Shintaro (@kakutani) October 4, 2020 やられてしまいました。。。\ndozen0作りました ということで、前置き長かったですが、Dozen0というキーボード(マクロパッド?)を遊舎工房さんから購入して作ってみました。 手順はビルドガイドという形でまとまっています。\n基本的にはこれに沿って作成しました。\nパーツと手順の確認 さてと。 pic.twitter.com/GTBJ7zDleN\n\u0026mdash; Jun Ohtani (@johtani) October 10, 2020 まずは入っているパーツがきちんとあるか確認します。 また、ビルドガイドでどんな作業があるのかをざっと眺めておきます。 まぁ、プラモデルといっしょですよね。\nキットにはキースイッチとキーキャップは含まれていません。これはご注意ください。 私は、キースイッチテスターとして入手していたキースイッチとキーキャップがどんな押し具合なのかを確認したかったので特に問題ありません。\nハンダづけ Amazon | 白光 ダイヤル式温度制御はんだこて FX600 | ハンダゴテ Amazon | 白光 こて先 2C型 T18-C2 | ハンダゴテパーツ Amazon | 白光(HAKKO) セラミックヒーターはんだこて専用こて台 クリーニングスポンジ付き FH300-81 | ハンダゴテパーツ Amazon | goot(グット) 高密度集積基板用 鉛入りはんだ Φ0.6mm スズ60%/鉛40% ヤニ入り SD-60 | ハンダゴテ はんだ付け用に揃えた道具です。「自作キーボード ハンダゴテ」とかでググると出てきたものがこれだったので。 デフォルトのコテ先ではなく、2Cのコテ先に付け替えてから作業を開始しました。\n私の持っていたソケットはCherry MX系なのですが、気が向いたらKailh Chocも試したくなるかも?ということで、 すべてはんだ付けしました。本格的にはんだ付けしたのは大学以来だからもう20年近く経ってますね。 ソケットの足をプリント基板にはんだ付けするのですが、2Cのコテ先が大きくなかなか手こずりました(これがこのあと問題を引き起こしました)。\nソケット、リセットスイッチ、ProMicroをはんだ付けすればはんだの作業は終了です。\npic.twitter.com/jjUo162n54\n\u0026mdash; Jun Ohtani (@johtani) October 10, 2020 pic.twitter.com/p5atvtHfFN\n\u0026mdash; Jun Ohtani (@johtani) October 10, 2020 スイッチの取付と組みたて 試したいキースイッチを選んでトッププレートにつけていきます。\nキーテスターからスイッチとキーキャップ持ってきて完成。動作確認はまだなのでまた、最初に戻るかもだけど、、、 pic.twitter.com/ZmBd3bgOKI\n\u0026mdash; Jun Ohtani (@johtani) October 10, 2020 組み立ても終わり次は実際の動作確認です(ツイートしていますが、予想通りの展開でした)。\nファームウェアの書き込み USBで接続して、ファームウェアの書き込みです。 書き込み手順はビルドガイドにありますが、QMK Toolboxの使い方やQMK Configuratorの使い方は以下のサリチル酸さんのブログがわかりやすかったです。\n(初心者編)自作キーボードにファームウェアを書き込む (初心者編)QMK Configuratorを使ってキーマップを書き換えよう 実際に書き込んで動かしてみると。。。。\nうーん、上半分が死んでる気がするなぁ。\nデフォルトキーマップの書き込みはできたけど、カーソルの上とかバックスペースが入らないw\n\u0026mdash; Jun Ohtani (@johtani) October 10, 2020 とりあえず、もう一回確認してみた。デフォルトのキーマップで、「Cut」「Paste」が強く押さないと入力されない。UpとDeleteは動くようになってた。CopyとBkSpがうんともすんとも言わない。下段のキーは全部動く。https://t.co/zEyINdAK6t\n\u0026mdash; Jun Ohtani (@johtani) October 10, 2020 といった具合に上半分が動作があやしいです。\n再度、はんだ付け ということで、ネジを外して上の段のソケットをはんだで温めてみると、片側だけ温めるとはずれるじゃないですか。 どうやら、うまくソケットの足が基盤にはんだ付けできていなかったようです。 この時、最初に作業したときに2C型のコテ先が大きくて、ソケットの足に入らなかったのを思い出したので、 最初にはんだごてについていたコテ先に戻してから作業をしました。 これだとソケットの足の隙間に入るんです。ということで、挙動のおかしい上段のソケットをすべてつけ直したところ無事動作しました。\n上の段、全体的にソケットがうまくはんだ付けできてなかったみたいだった。今回はMX系のスイッチしかないので、Kailh Chocのソケットの導通は未確認。ざっとブログにまとめるか。\n\u0026mdash; Jun Ohtani (@johtani) October 10, 2020 現在のキーマップ これが今のキーマップです。仕事中のBGMをラズパイ4の音楽プレーヤーで流していますが、 部屋から出るときや、打ち合わせがあるときに音楽の停止、開始などを画面共有経由でやっています。 が、わざわざマウス移動するのもめんどくさいなと。これに使えそうだというのもあったので、Dozen0を購入したというのがあります。 残念ながら、Prev Trackとかがうまく動かないので、ショートカットを調べてキーマップ書き換える予定ですが、非常に便利になりました。\nまとめ ということで、Dozen0を作ってみましたが、楽しかったです。すんなりと行かなかったのがまた良かったです。 試行錯誤して動いたときの喜びが何倍もありました。また、キースイッチの感触も知ることができました。 たぶんGateron Silentクリア軸もしくは赤軸くらいが良さそうだなぁと(こうやって沼へ。。。)。 キーマップの仕組みを調べたり、もっと面白い使い方できないかな?と探りつつ、次のステップに進もうかなと。\n次は本格的なセパレートタイプのキーボードを作る予定です。が、お店のオープンを待ってからということになってます。はやくオープンしないかなぁ!!\nがんばって!!\n\u0026mdash; Jun Ohtani (@johtani) September 29, 2020 ","date":1602428006,"dir":"post/2020/","id":"c377351433a941a927aab543931f6026","lang":"ja","lastmod":1602428006,"permalink":"https://blog.johtani.info/blog/2020/10/11/build-dozen0/","publishdate":"2020-10-11T23:53:26+09:00","summary":"今年の春くらいから、セパレートタイプのキーボードが気になっています。 また、なんか知らないですが、Twitterのタイムラインが自作キーボード","tags":["DIYキーボード","misc"],"title":"Dozen0を作成した #DIYキーボード"},{"contents":" 2020/10/06 11:00くらいにマージされました。\n@minoru_osuka さんが開発を引き継いだLinderaというKuromojiのRustクローンがあります(リポジトリ) 。 最近趣味でRustを勉強しているので、こちらを少し手伝っています。\nRustの勉強仲間である@takuya_bさんや@ikawahaさんと話をしているときに、FST部分をDouble Array Trieに置き換えると速度が向上するのでは?という話が出まして、@takuya_bさんがDouble Array Trieを作るらしいという話になったので、下準備などをしつつ、作ってもらったライブラリyadaを組み込んでみたという話です。\nベンチマークの追加 下準備として、今のLindera(FST実装)がどのくらいの性能なのか?というのを計っておく必要があります。 幸いにも、Linderaのオリジナルの開発者の方が、criterion.rsというライブラリを使ったベンチマークプログラムを作成してくれていました。\nただ、1種類だけだと少し心もとないなというのと、長い文章やパターンを増やしたほうが良さそうだなということで、 ベンチマーク自体をいくつか追加しました(追加したときのPR)。\n種類としては、5種類のベンチマークです。\nシステム辞書のみのTokenizerのコンストラクタ呼び出し カスタム辞書ありのTokenizerのコンストラクタ呼び出し システム辞書のみのTokenizerのtokenize処理の呼び出し カスタム辞書ありのTokenizerのtokenize処理の呼び出し 青空文庫の坊っちゃんのテキストをシステム辞書のみのTokenizerでtokenize 1,2はコンストラクタ部分だけの処理をベンチマークテストする目的で作成しました。 LinderaはTokenizerがtokenize処理するのに利用するデータをいくつか内部で保持しています。 これらはファイルにシリアライズされており、Tokenizerのオブジェクト生成時に読み込みやデシリアライズ処理が発生します。 この部分だけも速度を計測したい目的でコンストラクタだけを切り出しました。\n3,4はTokenizerのメインの処理です。コンストラクタはベンチマークの対象外にしました。 純粋にtokenizeの処理だけを切り出して計測するためです。 カスタム辞書がある場合、ない場合は念の為切り出した形になっています。\n5は長い文章(文章が多いのでバリエーションも増える)を扱いたいために別にしました。\nこれで、一応下準備が完了です。 ちなみに、Criterionは賢くて、前のベンチマークの結果と最新の結果を比較してくれる機能があります。 どんな感じで出てくるかはベンチマーク結果をご覧ください。\nyadaの組み込み ベンチマークの準備をしていたところyadaがリリースされたので、Linderaへの組み込みを検討し始めました。\nというわけで、またダブル配列を書いてしまったので crate として公開しました。フィードバックお待ちしております! https://t.co/As7h0tfmjf\n\u0026mdash; takuya-a (@takuya_b) September 20, 2020 中身の理解 lindera-fstを利用して、prefix searchしている処理があるので、そこで利用しているFSTをyadaに置き換えれば良さそうだと判断して、 処理を読んでいきます。\nTokenizerは、PrefixDictという構造体でlindera-fstを利用している prefixメソッドが入力文字列を元に、FSTを前方一致検索して、ヒットした単語の情報をIteratorとして取り出せる(単語の情報は「入力文字列の先頭からの文字数」と「ヒットした単語のWordEntry構造体」) PrefixDictのfstは辞書(例:ipadic)ごとにlindera-\u0026lt;辞書名\u0026gt;-builderで生成される システム辞書としては、デフォルトではlindera-ipadic-builderでfstを構築している 構築処理はこの辺 という感じです。 また、辞書周りのファイルがそれぞれどんな役割なのか、どんなデータの持ち方をしているのか?といった点を、変更点の調査のついでに書き出してみました。lindera-dictionary/FILES.md。TODOになっている部分も追記が終わっています(PR)\n変更点 実際に変更したプログラムの詳細についてはのPRを見ていただくとして、簡単には以下の点になります。\nRustのバージョンを1.46.0に(おもにREADME.md) yadaが利用している機能に1.46.0で導入された機能があるため lindera-fstをyadaに変更(lindera-core/Cargo.toml, lindera-ipadic-builder/Cargo.toml) 合わせて、dict.fstというファイル名をdict.daに変更 dict.daに関して構築部分と検索部分を変更 FSTではFSTから返ってくる値(入力文字列に出てきた単語に関連する値)はu64だったが、yadaのDoubleArrayがu32しか扱えないため、u32に変更。テストの記述はしていないが、扱うデータ的にu32で問題なさそうだったので。 検索部分:PrefixDict構造体のprefixメソッドでDoubleArrayのprefix_common_searchを使用 DoubleArray自体がprefix_common_searchのメソッドを持っていたので、処理が簡単に置き換え可能だった。FSTはprefixメソッド内で独自で前方一致検索を実装していた。 構築部分:lindera-ipadic-builder/src/lib.rsのbuild_dictとbuild_user_dictのdict.da構築処理 ipadicのCSVファイルを読み込んで、見出し語をキーに、辞書にある単語情報のベクタを値とするBTreeMapを生成し、このBTreeMapに基づいてFSTを構築していた部分をDoubleArray構築処理に置き換えた。 シフト演算などで、実際の値(dict.vals)へのポインタを作っていたのだが、ここの処理を読み解くためにFILES.mdを書き出した。 という感じです。そもそもデータ構造がどうなっているのか?から読み解いて、変更部分を洗い出して変更していった形になります。 取り込み作業中にいくつかyadaに要望(このへん)を上げて、変更を取り込んでもらい、最終的にyadaのバージョン0.3.2で問題なく動きそうだという形になりました。@takuya_bさん、対応ありがとうございました。\nエッジケースバグの発見 作っててよかった、テストケースでした(実際にはベンチマークテストですが)。 取り込み作業中に、Lindera本体のcargo testはすべてOKになるが、ベンチマークを取ろうとしたときに、坊っちゃんの文字列を入力にしたベンチマークが失敗するという事象が発生しました(PRのコメント参照)。 切り分けのために、入力の文章のどこでおかしくなるのか?DoubleArrayのbuildメソッドに渡している値がおかしくないか?などをすこしずつ調べていくと次のバグが判明したという感じです。\n特定のデータ(ipadicの見出し語一覧)をDoubleArrayに入れて、特定の文字列(「は相」)をcommon_prefix_searchにいれたら、 返ってくる情報(0から何バイト目の文字が一覧に存在した)が、不正な値が返ってくるというバグでした。 @takuya_bさんに見てもらいつつ(DoubleArrayの中身わからん。。。)、修正してもらいました。素早い対応ありがとうございます。\nyada 0.3.1 をリリースしています。特定の条件で不正な遷移を許すダブル配列が構築されてしまうバグを修正しています。このエッジケースは @johtani さんが見つけてくださいました。ありがとうございました! https://t.co/CiftZi5GDn\n\u0026mdash; takuya-a (@takuya_b) September 30, 2020 やはり、いろんな文字列入れてテストしてみるの重要ですね。 ということで、ベンチマークだけでなく、テストケースとしても坊っちゃんのファイルを読み込んでトークナイズするようにPRでテストケースを追加しています。\nベンチマーク結果 yadaを利用した変更が終わったので、再度cargo benchを実行して計測です。 計測としては、masterブランチでまずcargo benchを実行し、yadaの実装をしたブランチに切り替えてからcargo benchを実行します。 すると、Criterion? cargo benchが、最終的な結果に前回との差分でどのくらい性能が改善、改悪したかも合わせて出力してくれます。 実行環境と結果は以下のとおりです。\nMacBook Pro 16インチ CPU:Core i7 6コア 2.6GHz メモリ:32GB コンストラクタのベンチマークについては10%ほど性能が悪くなっています。 これは、FSTよりもDoubleArrayTrieのほうがデータが大きくなってしまうためだと思われます。 実際にファイルのサイズは次のようになりました。yada(DoubleArrayTrie)のほうが2倍以上大きいことがわかります。 また、このファイル以外にもLinderaが利用しているデータはありますが、それらは今回変更の対象にはなっていません。 なので、単純にこのファイルの読み込みの処理に時間がかかっているのだと想像できます。\n2147765 / FST / dict.fst 5425152 / yada / dict.da tokenizeのベンチマークについては、11%〜28%の改善が見られました。 文章から、内部に保持している辞書に存在する単語を見つけ出す処理に利用されるのがFST、DoubleArrayTrieです。 今回の変更では、この処理に利用しているデータ構造だけを変更しました。 実際には\nDoubleArrayTrieを用いた単語の検索処理 見つかった単語の持つ値(data.valsのオフセット情報)を元にシフト演算 といった処理が実行されます。シフト演算はu64だったものがu32に変更されたくらいなので、大した処理量ではないかと。 大部分はDoubleArrayTrieを利用したルックアップ処理が速度向上に寄与していると思います。\nまとめ 最近Linderaに加えた変更、作ったPRについて少しブログにまとめてみました。 ちなみに、まだPRの段階でレビュー\u0026amp;リリース待ちという感じです。\n実際には作ってもらったライブラリを組み込んでみたというだけなのですが、速度が向上した結果が見れたのは面白いです。 また、基本的なデータ構造とかアルゴリズムの勉強にもなりました(2次元配列を1次元配列に押し込むとか)。このへんも今後も勉強していきたいです。\n組み込む際に色々と協力していただいた@takuya_bさん、@ikawahaさん、巻き込んでくれた@minoru_osukaさんに改めて感謝いたします。\nRustや形態素解析のプログラムの勉強を兼ねて、今後もなにか改善できる部分がないかなどを見ていこうと思っています。 Rustで形態素解析をしたいという人がどのくらいいるかはわかりませんが、おかしなところや疑問点などあればコメントください。\n","date":1601865378,"dir":"post/2020/","id":"15932a656f7acfac897d27766eadc9e2","lang":"ja","lastmod":1601865378,"permalink":"https://blog.johtani.info/blog/2020/10/05/switch-fst-2-da/","publishdate":"2020-10-05T11:36:18+09:00","summary":"2020/10/06 11:00くらいにマージされました。 @minoru_osuka さんが開発を引き継いだLinderaというKuromojiのRustクローンがあります(リポジトリ)","tags":["Rust","Lindera"],"title":"LinderaのFSTをDoubleArrayTrieに変更した話"},{"contents":"先日は「検索システムを構成するパーツ」ということで検索システムを構成しているパーツについて書いてみました。\n大体、検索がうまくヒットしないといった場合に、問題になるのがコンテンツ自体のデータもしくは、転置インデックスのキーワードだったりします。 そこで今回は、前回のパーツの「データソース・コンテンツ」周りについて少し書いてみようと思います。言葉の定義、それぞれがどんなことをやるのか、とりあえず導入したあとにコンテンツ周りでどんな改善ができるかなどを書いてみます。\n言葉の定義 コンテンツ 実際に検索させたいデータになります。 コンテンツにはWebページ、データベースのレコード(CMSで登録されたデータなど)、ファイルサーバーにある文書(PDF、Word、Excelなど)などになります。\nデータソース コンテンツのマスタデータが保存されている先です。 よくあるデータソースとしては以下のものが考えられます。\nWebサイト - 自社もしくはインターネットに存在しているWebサイトです。 ファイルサーバー - ローカルネットワーク上のファイルサーバーもありますが、最近ではGoogle DriveやDropboxといった外部のWebサービスもあります。 RDB - CMSや自社システムでのデータの保存先です。 クローラー コンテンツをデータソースから収集してくるプログラムのことです。 Webサイトやファイルサーバーからコンテンツを収集して検索エンジンに登録するところまでを担当します。 RDBにあるデータを検索エンジンに登録する場合はクローラーがデータを登録するというよりは、RDBにデータを登録するシステムが検索エンジンに登録する機能を持っていることが多いです。\nデータの収集と登録 収集 クローラーを使用した収集の場合は、サービスの特性とデータソースによって、どの程度の頻度でクロールするのか、クロール対象はどこまでか?といったものを決める必要が出てきます。 これらが決まれば収集ができるかと(他に権限とかもありますが。)。 収集コンテンツは、そのままでは利用しにくかったり、利用できないことがあるので、次はデータの変換を行います。\nデータ変換 コンテンツはそのままの形では検索エンジンには扱いにくいデータ形式である場合があります。\nWebページの場合 Webページの場合、コンテンツにはHTMLタグが入っていたり、JavaScriptなど検索対象にはしたくないデータなどが入っています。これらを除去して、検索させたいものを取り出す必要があります。 また、Titleタグなど、いくつかメタデータとして扱えるものがHTMLで規定されているので、これらを別の項目として取り出して個別に検索できるようにすると便利です。 HTMLをパースしてデータを抜き出す処理ができるライブラリなどがあるので活用します。\nファイル PDFファイルなど、ファイルの場合もメタデータと呼ばれるファイル自体が持っている情報が存在します。作成者、更新日時、ファイル名、パスなどです。 これらも検索時に有効な情報になります。 また、ファイルから文字列を抜き出す処理も必要になります。 それぞれデータフォーマットが異なりますので、そのフォーマットに合わせて文章データを抜き出す処理が必要です。OSSや製品がありますので、それらを利用して、ファイルから文章を抜き出します。\nRDB RDBのデータの場合、データが正規化されています。 検索エンジンでは、非正規化のデータを登録して検索することが基本となるため、まずは非正規化して取り出す必要が出てきます。\n例えば、ジャンルやカテゴリ、各種IDなどが実際のコンテンツのレコードに入っていると思いますが、これらをユーザーが入力したキーワードで検索したい場合などは、IDではなく表示名を取り出して、検索エンジンに登録する必要が出てきます。\nその他 データごとの変換処理について説明しました。 その他に、データのクリーニング処理などと言ったことも必要になってきます。例えば、HTMLのタイトルに必ずサイト名が入っているが、除去したいといった場合や、検索エンジン固有のデータの前処理などもあります。\n登録 最後は検索エンジンへの登録です。 最近の検索エンジンはJSON形式でデータを受け取る場合が多いので、JSONに変換することが多いです。 基本的には各種プログラミング言語のライブラリが用意されているのでこれらを利用するのが基本となります。\n検索したい項目、検索させたい方法などを洗い出し、必要なデータを作成して検索エンジンに登録します。 登録と書いていますが、更新、削除などもここでの対象となります。\nここまでの流れで、データソースからコンテンツを取得し、変換して、検索エンジンへの登録が終わりました。\n検索の改善 検索のログから分析して改善していくのが良いですが、ユーザーからの質問や意見などからも改善すべき点が見えてくると思います。 検索ログでは、次のようなものを元に、検索がうまく行かないものを見つけ出します。\n0件ヒット 0件クリック ヒットしていない検索ワードがある場合、コンテンツに問題がある場合があります。まずはこのあたりをとってみるのが良いかと。 そもそも、入力されたキーワードにマッチするコンテンツを扱っていないこともわかりますし、入力されたキーワードに似た単語を持ったコンテンツなども存在するはずです。 類義語の辞書を用意して、検索にヒットできるようにするといった分析と改善にも利用できます。\nあとは、検索エンジン側の話ですが、形態素解析器などを利用している場合に、意図した区切りになっていないために、うまくキーワードがヒットしないと言ったこともあります。\nコンテンツの理解 実はこれが一番だったりします。 どんなコンテンツを自分たちが扱っているのか?どんなデータがどういった項目でコンテンツに入っているのか?といったところから、 コンテンツのデータを元に検索にヒットさせる方法が改善できます。\nCMSなど人が入力したデータをコンテンツとして扱う場合、入力画面を改良することで、望んでいるデータを入れてもらえたり、不要なデータが入らなくなる可能性があります。 例えば、ECサイトなどで商品の説明文やタイトルにいろいろなキーワードが入っている場合などがあります。むりやりどんなキーワードでもヒットさせたいという入力者の意図もあるのですが、検索しているユーザーにはノイズになることも多いです。適切にカテゴリやジャンル、属性といった項目に分けることでおかしな入力データを減らすことも可能です。\nWebサイトなどをクローリングしたものの場合は、サイトごとに文章の特徴があったり、重複している部分などが合ったりする場合があります。 これらもコンテンツをよく調べることで、不要な情報を除去したりといったことが可能になります。\nまとめ 簡単ですが、検索のデータソースやコンテンツにまつわる話を紹介しました。 もちろんここでは紹介しきれていない項目がいっぱいあります。 また、具体例ではなく概略をざっくりと書いているのでわかりにくい場合もあるかもしれません。 すこしユースケースを絞り込んで書いたほうがわかりやすくなるのかも?\n次はUIとか書くかも?\n不明点とか疑問点、指摘事項などあればコメントしていただければと。 要望などもお待ちしております。\n","date":1600136614,"dir":"post/2020/","id":"b2c4cf0fb96d02d37f03668caaecbc57","lang":"ja","lastmod":1600136614,"permalink":"https://blog.johtani.info/blog/2020/09/15/improve-search-no3/","publishdate":"2020-09-15T11:23:34+09:00","summary":"先日は「検索システムを構成するパーツ」ということで検索システムを構成しているパーツについて書いてみました。 大体、検索がうまくヒットしないとい","tags":["検索"],"title":"検索対象のデータとデータソース(検索システムに関する妄想その3)"},{"contents":"自宅環境に少しアップデートがあったので更新版です。 お客さんのおかげで相変わらず自宅で作業させてもらってるのもあり、昨今のコロナウイルスの影響で出かけることもないので、自室の作業環境が更新されている感じです。 前回のブログはこちらです。 前回のまとめで触れていた2点について更新されています。\nまずは、現状のデスクの上の写真です。\n基本的には前回紹介したものと大きくは変わっていません(?)。 変わったものについて紹介していきます。\nデスク 先程の写真ではちょっとわかりにくいですが、スタンディングデスクになりました。\nタイマーついてるの便利 pic.twitter.com/E9engTIMnM\n\u0026mdash; Jun Ohtani (@johtani) April 30, 2020 Flexispotの天板と足の組み合わせにしました。 前のElectaの天板が明るめの色だったのもあって、メープルの天板です。 組み立てはちょっと大変でした。 足が重たいのと、天板にはネジ穴がなく電動ドライバーもないので、ネジ締めと机を起こすのがちょっと大変です。子供に手伝ってもらいながら組み立て設置をしました。 オンラインミーティングなどのときには基本、立って作業しています。 あとは、デフォルトのタイマー設定のままですが、45分ごとに立ったり座ったりを数回繰り返す感じです。\nAmazon | FLEXISPOT オフィスデスク用天板 スタンディングデスク120×60cm Amazon | FLEXISPOT スタンディングデスク 電動式 昇降デスク メモリー機能付き ブラック EN1B(天板別売り) スタンディングデスクマット フローリングに45分立ちっぱなしだと結構、足の裏がつかれるんですよ。なので、クッション性が高いフロアマットを立ってるときは利用しています。ちょっとめんどくさいのですが、椅子のときは壁に立て掛けて、立つときにマットを敷くようにして使っています。\nちなみに、ウレタン素材なので開封直後はすごい匂いでした。。。 数日は陰干しみたいなのが必要です、ご注意を。 ただ、これを利用してから膝やかかとが痛いことはなくなっています。\nAmazon | 疲労軽減マット スタンディングデスクマット 滑り止め加工 立ち仕事 耐水 耐油 耐菌 (ブラック, 75cm*50cm*2cm) ケーブルトレー スタンディングデスクだとケーブルをぶら下げた状態だと危なそうだなということで、ケーブルトレーも机の下に追加してあります。電源タップを配置して、ディスプレイなどの電源はこちらから取るようにして、ケーブルトレーからは電源タップとスタンディングデスクの電源コードを垂らすという感じです。実際にはLANケーブルも伸びてたりはしますが。。。 また、後で出てくるラズパイ+SSDも最近こちらに移設しました。 最初にチャコールグレーを発注したのですが、配送日が未定になったので、Lサイズのシルバーを発注するという慌てようでした。 結局、今は両方使っています。テーブルタップにラズパイと、結構乗せるものがあるんですよね。見えない場所だし、色が揃ってないのは気にならないかなと。\nAmazon | プラス Garage ワイヤーケーブルトレー Lサイズ 幅63.7cm シルバー Amazon | プラス Garage 配線ケーブルトレー 幅40cm チャコールグレー キーボード+パームレスト 10数年ぶりに外付けキーボードじゃないかな? 少なくともMacに移行してからは、ずっとMac bookのキーボードを使ってました(極稀にMac mini起動後とかにMagic Keyboard使うくらい)。 外出して仕事をすることが多かったのもあり、体をキーボードに合わせる感じでした。\nが、ずっと在宅で仕事をしていますし、ふるさと納税でRealforce(リンクは楽天)がということで、申し込んでみました。2週間ちょっとで到着。 箱が厳重でびっくりしました。\nAmazon | 東プレ REALFORCE SA for Mac ホワイト R2SA-JP3M-WH | Realforce まだ深いキーに慣れつつあると言った感じです。 付属の2mmのキースペーサーでAPCを2.2mmの設定で使用しています。最初は3mm+APC 1.5mmでやっていたのですが、流石にキーが敏感すぎてちょっとキーボードに手をおいたまま考え事をしているだけで「lllllllllll」のようになってしまったので現在の組み合わせに落ち着いています。\nあと、特殊な設定としてはスペースの横のeng/kanaキーを設定でキーロックして使えなくしました。どうも、ご入力の原因になっているようだったので。 日本語の入力切替は、昨日まではCtrl+Spaceを使用していましたが、このブログを書き始めてからCtrl+\\に変更しています。 むかーし、使っていたIME切り替えのショートカットです(知っている人は知っているやつ)。\nマウスは使用しておらず、キーボードの手前にトラックパッドをおいて使っています。パームレストの部分は、サムライズムさんのトラックパッドがきれいに入るmagicTrayPalmです。 Mac book Proと同じような感じでトラックパッドが使えるのがいいですね。 興味がある方は、侍割のリンクをたどってもらうと、初めてサムライズムさんで買い物をする方に限り割引がつくようになってるみたいです(なんと、私もなんか割引になる!)。\nディスプレイアーム 外付けキーボードになったのですが、Mac Book Proの画面も活用したく、さらに上下での配置がやはり目線の移動距離が少ないので気に入っていました。ただ、前回のブログで紹介したアームでは少し高さが足りず。。。 思案しながらAmazonを回遊していたら、同じ会社の新しいアームがあり、調べると高さが取れそうだということで付け替えました。 アーム2本ありますが、今のところ1本だけを使っています。 2本目のアームにカメラを乗せるのもあり?と思いながらまだ試していませんが。玉突き式に前に使っていたアームがサンダーボルトディスプレイ(縦置き)のアームになっています。前にサンダーボルトにつけていたアームは重量オーバーで悲鳴を上げていたので。。。\nAmazon | HUANUO 2画面 アーム デュアル ガススプリング式 スマホ充電器 寝室で利用していた斜めに立てかけるタイプのワイヤレス充電器を作業デスクに持ってきました。 実は部屋に時計がなく、Pixel 3 XLを使っているので、スマホの画面に常に表示されている時計を置き時計の代わりに使えそうだなと (スマホで写真を撮っているので上の画像ではスマホがありませんが)。 結構便利です。ちょっと時間を確認したいときに、メニューバーの時計では流石に小さすぎるのでw\nAmazon | Anker PowerWave 7.5 Stand, Qi ワイヤレス充電器 ミキサー 音声のミキサーです。Yamahaのスピーカーは入力が2系統あるのですが、入力したい音声は3系統あります(ラズパイ4、Mac mini、メインディスプレイ)。2入力を1系統にまとめるプラグを試しに買ってみて、Mac miniとラズパイをまとめてみたのですが、残念ながら切り替わるときに数分無音状態が続くという問題が発生しました。 USB給電できるタイプを購入しました。スライダーとかいらないなと思っていたのですが、電話やミーティング時にBGMの音を下げたりするのに地味に便利だったりします。 ただ、スライダーを動かそうとすると本体も動いてしまっていたので、本体裏に滑り止めを貼ってあります。\nAmazon | Maker hart Just Mixer ステレオ3入力音声ミキサー/電池とUSB電源可能 Webカメラ おっさんの顔がきれいに写っても仕方ないんですが、下からのアングルよりはいいかなぁということと、今後の勉強会で使えそうかな?ということで、購入してみました。 縦でも横でも使える便利なカメラです。また、あんまりないのですが、部屋の中などを写すときにカメラを持ち回せるの便利ですね。 ディスプレイの上に置いてしまうと高さがありすぎるということで、スピーカーの上に乗っけています。仮置きなのですが、このままになるんじゃないかな? 打ち合わせ中は画面共有してることが多いのでオンライン飲み会などで主に活躍してる気も。。。\nAmazon | ロジクール ウェブカメラ フルHD 1080P 60FPS StreamCam C980OW オフホワイト USB-C接続 Mac miniのSSD化 見えないところですが、Mac miniのHDDをSSDに差し替えました。 性能検証用のマシンとしてMac miniを利用し始めたのですが、 計測するたびに速度の差がありすぎるのでおかしいな?と。 よくよく考えてみると、このMac miniはFusion Driveだったんです。。。 開発などで使う分には大容量だし便利だったのですが、負荷計測に利用する場合は挙動をハンドリングできないので、弊害でしかないです。。。 ということで、頑張って差し替えました。想像以上の大手術でした。 「Mac mini HDD 交換」などでググると換装している方たちがいらっしゃいます。興味ある方はググってみてください。\nさて、復路 pic.twitter.com/SwndXPoKqn\n\u0026mdash; Jun Ohtani (@johtani) July 25, 2020 Amazon | シリコンパワー SSD 1TB SATA3 6Gb/s 2.5インチ ラズパイ4 Mac miniの負荷検証マシン化のため+Linuxを触りたかったというのもあり、ラズパイ4を追加しました。 Mac miniは主な使用用途が音楽再生だったのでラズパイ4で肩代わりできるだろう+その他の検証にもラズパイ4が使えそうだと。 現在はUbuntuをインストールして、画面共有で操作しています。\nAmazon | LABISTS Raspberry Pi 4 4B MicroSDHCカード64G まとめ かなり快適になりました。キーボードもうるさくないですし、熱くもありません。マイクのポップガードは意味がなさそうなので外しました。\nまだいくつか気になってるものもあるので、また更新するかもしれません。\n分離式キーボード - 胸を広げた状態でキーを打ったほうがいいのでは?という気がしています。ただ、最近はずっと日本語キーボードを使っているので選択肢が少ないんですよね。。。\nサンダーボルト?USB-C?ドック - MacBook Proのポートがすべて埋まっているし、もう少しケーブルを減らせると幸せになれそうなきが。。。\nモバイルディスプレイ - MacBook Proのディスプレイを使っているのですが、キーボードの上にかぶってるんですよね、結構。。。クラムシェルにしてiPadもしくはモバイルディスプレイに置き換えたほうがスッキリはしそうかなと。ただ、Touch IDが使えなくなったり、クラムシェル状態でMacBook Proの電源を入れられないというはなしなので、あまり意味がなさそうだなというのもあります。\n","date":1599531445,"dir":"post/2020/","id":"d08a3fdc040bbbdd81c9927ce296318c","lang":"ja","lastmod":1599531445,"permalink":"https://blog.johtani.info/blog/2020/09/08/update-working-facility/","publishdate":"2020-09-08T11:17:25+09:00","summary":"自宅環境に少しアップデートがあったので更新版です。 お客さんのおかげで相変わらず自宅で作業させてもらってるのもあり、昨今のコロナウイルスの影響","tags":["misc"],"title":"自宅の作業環境(2020/09)"},{"contents":"Rustで便利なクレートを見つけたので、紹介がてら、自分のメモのためにブログに残しておきます。\nそもそもの問題 Rustで処理を書いていて、なんかちょっと遅いな?どこの処理で時間がかかってるんだろう? ということがありませんか?ありますよね?\nというのを調べるために、最初に思いつくのは自分で計測する方法です。 流石にそれはなぁ、と思ったのでググって出てきた方法を最初は使っていました。\nRustで実行時間計測 3年前の記事ですが、とりあえず計測する分には問題なかったのでこちらの方が書いていたマクロを拝借していました。 が、ちょっと面倒なのが戻り値がある処理などのときに、このマクロを挟むのが結構めんどくさいなと。 また、処理の時間を測りたいのは基本的にはメソッドや関数単位であることが多いです。\nで、さらにググっていて見つけたのが、meteredでした。\nどんなもの? 計測したい部分に#[metric]のようなアノテーションを追加することで計測対象としてくれます。 あとは、計測したものを保存するレジストリという場所を指定するだけです。 処理が終わったタイミングなどで、そのレジストリの内容を出力することで、次の情報を計測することができます。\nHitCount : 実行された回数 ErrorCount : エラーを返した数(Resultを戻り値にしているメソッドが対象) InFlight : 処理中の回数かな? ResponseTime : レスポンスタイム(処理に何秒かかったか) Throughput : スループット(1秒あたり何回呼ばれたか) とりあえず試してみたのは、ResponseTimeとThroughputです。他のメトリクスはまた後日(機会があれば)。 また、metered::metric::Metricトレイトというものが用意されているようで、これを実装した独自のメトリクスも扱うことができるようです。\n使い方 使い方としては次のようになります。\n計測対象となるメソッドがある構造体に、メトリクスを保持するためのレジストリを用意 計測対象にしたい構造体のメソッドに#[measure]を追加(このとき、計測したいものも指定する。) あとは、実行したあとに構造体をダンプするとメトリクスが出力されます。\nレジストリの用意 #[derive(Default, Debug, Serialize)] pub struct NekoParser { metric_reg: NekoParserMetricRegistry, } NekoParserMetricRegistryという型はこのあとのimplのアノテーションで指定する名前になります。 実際にはこの型の構造体を自分で定義する必要はありません。 構造体のderiveでDefaultを指定します。構造体のインスタンス化のときにdefault()メソッドを呼び出して初期化したいためです(おそらくレジストリの初期化をやってくれるのだと思う(要確認))。 レジストリの用意はこれだけです。\nレジストリの指定と計測対象の指定 計測対象側です。少し長いですが、NekoParserのメソッドすべてを掲載しました。 まずは、1行目でレジストリの名前の指定(registry = NekoParserMetricRegistry)、レジストリのフィールド名(registry_expr = self.metric_reg)、レジストリの可視性(visibility = pub(self))を定義します。 2行目では、implブロック全体で計測したいメトリクスを指定しています。今回は、スループットとレスポンスタイムを計測したかったので #measure([ResponseTime, Throughput])]と2種類を指定しています。 メトリクスが2種類のため配列で指定していますが、1種類だけの場合は[]の記号は必要ありません。\nあとは、計測したい各メソッドに#[measure]をつけるだけです。 なお、メソッドごとに#[measure(ErrorCount)]といったかたちで個別にメトリクスを指定することも可能です。 今回はお試しということもあり、すべて#[measure]だけになっています。 アノテーションを付けただけで、メソッド自体を変更はしていません。\n#[metered(registry = NekoParserMetricRegistry, registry_expr = self.metric_reg, visibility = pub(self))] #[measure([ResponseTime, Throughput])] impl NekoParser { #[measure] pub fn load_and_parse_neko(\u0026amp;self) { let file_path = \u0026#34;./data/chap04/neko.txt\u0026#34;; let file = File::open(file_path).unwrap(); let buf = BufReader::new(file); let mut out = File::create(\u0026#34;./data/chap04/neko.txt.lindera.json\u0026#34;).unwrap(); buf.lines().filter_map(|item| item.ok()).for_each(|line| { let tokens = self.tokenize(line.as_str()); self.output_tokens(\u0026amp;tokens, \u0026amp;mut out); }); } #[measure] pub fn output_tokens(\u0026amp;self, tokens: \u0026amp;Vec\u0026lt;Token\u0026gt;, buf: \u0026amp;mut File) { writeln!(buf, \u0026#34;{}\u0026#34;, serde_json::to_string(tokens).unwrap()) .expect(\u0026#34;Error during output json\u0026#34;); } #[measure] pub fn tokenize(\u0026amp;self, line: \u0026amp;str) -\u0026gt; Vec\u0026lt;Token\u0026gt; { let mut tokenizer = lindera::tokenizer::Tokenizer::new(\u0026#34;normal\u0026#34;, \u0026#34;\u0026#34;); let lindera_tokens = tokenizer.tokenize(line); let tokens = lindera_tokens .iter() .map(|lindera_token| { let surface = lindera_token.text.to_string(); let pos = lindera_token.detail[0].to_string(); let pos1 = if pos != \u0026#34;UNK\u0026#34; { lindera_token.detail[1].to_string() } else { String::new() }; let base = if pos != \u0026#34;UNK\u0026#34; { lindera_token.detail[6].to_string() } else { String::new() }; Token { surface, base, pos, pos1, } }) .collect(); return tokens; } } 計測結果の出力 最後は計測結果の出力です。 今回はテストメソッドで実行して結果を出力する処理を書きました。\nlet parser = NekoParser::default();で構造体をインスタンス化します。 あとは、処理をそのまま実行します。\n最後に出力結果をJSON形式の文字列にしてから出力しました。 let serialized ... println!(\u0026quot;{}\u0026quot;, serialized);という形です。 簡単ですね!\n#[cfg(test)] mod tests { use crate::chapter04::answer::NekoParser; use std::path::Path; #[test] fn success_output_tokenlists() { let parser = NekoParser::default(); parser.load_and_parse_neko(); let serialized = serde_json::to_string(\u0026amp;parser).unwrap(); println!(\u0026#34;{}\u0026#34;, serialized); assert!(Path::new(\u0026#34;./data/chap04/neko.txt.lindera.json\u0026#34;).exists()); } } 出力結果 ここまで紹介したものの実行結果は次のような形でした。 レスポンスタイム、スループットともに、最小、最大、99パーセンタイルなどを出力してくれます。 出力はメソッド名ごとにくくられているのでとても便利です。\n{ \u0026#34;metric_reg\u0026#34;: { \u0026#34;load_and_parse_neko\u0026#34;: { \u0026#34;response_time\u0026#34;: { \u0026#34;samples\u0026#34;: 1, \u0026#34;min\u0026#34;: 176128, \u0026#34;max\u0026#34;: 177151, \u0026#34;mean\u0026#34;: 176640.0, \u0026#34;stdev\u0026#34;: 0.0, \u0026#34;90%ile\u0026#34;: 177151, \u0026#34;95%ile\u0026#34;: 177151, \u0026#34;99%ile\u0026#34;: 177151, \u0026#34;99.9%ile\u0026#34;: 177151, \u0026#34;99.99%ile\u0026#34;: 177151 }, \u0026#34;throughput\u0026#34;: { \u0026#34;samples\u0026#34;: 0, \u0026#34;min\u0026#34;: 0, \u0026#34;max\u0026#34;: 0, \u0026#34;mean\u0026#34;: 0.0, \u0026#34;stdev\u0026#34;: 0.0, \u0026#34;90%ile\u0026#34;: 0, \u0026#34;95%ile\u0026#34;: 0, \u0026#34;99%ile\u0026#34;: 0, \u0026#34;99.9%ile\u0026#34;: 0, \u0026#34;99.99%ile\u0026#34;: 0 } }, \u0026#34;output_tokens\u0026#34;: { \u0026#34;response_time\u0026#34;: { \u0026#34;samples\u0026#34;: 9964, \u0026#34;min\u0026#34;: 0, \u0026#34;max\u0026#34;: 143, \u0026#34;mean\u0026#34;: 0.03592934564431955, \u0026#34;stdev\u0026#34;: 1.5152489085107463, \u0026#34;90%ile\u0026#34;: 0, \u0026#34;95%ile\u0026#34;: 0, \u0026#34;99%ile\u0026#34;: 0, \u0026#34;99.9%ile\u0026#34;: 6, \u0026#34;99.99%ile\u0026#34;: 143 }, \u0026#34;throughput\u0026#34;: { \u0026#34;samples\u0026#34;: 174, \u0026#34;min\u0026#34;: 39, \u0026#34;max\u0026#34;: 71, \u0026#34;mean\u0026#34;: 57.103448275862064, \u0026#34;stdev\u0026#34;: 3.8417981983375835, \u0026#34;90%ile\u0026#34;: 60, \u0026#34;95%ile\u0026#34;: 61, \u0026#34;99%ile\u0026#34;: 64, \u0026#34;99.9%ile\u0026#34;: 71, \u0026#34;99.99%ile\u0026#34;: 71 } }, \u0026#34;tokenize\u0026#34;: { \u0026#34;response_time\u0026#34;: { \u0026#34;samples\u0026#34;: 9964, \u0026#34;min\u0026#34;: 12, \u0026#34;max\u0026#34;: 79, \u0026#34;mean\u0026#34;: 16.897230028101177, \u0026#34;stdev\u0026#34;: 2.331145559054724, \u0026#34;90%ile\u0026#34;: 19, \u0026#34;95%ile\u0026#34;: 20, \u0026#34;99%ile\u0026#34;: 24, \u0026#34;99.9%ile\u0026#34;: 46, \u0026#34;99.99%ile\u0026#34;: 79 }, \u0026#34;throughput\u0026#34;: { \u0026#34;samples\u0026#34;: 174, \u0026#34;min\u0026#34;: 39, \u0026#34;max\u0026#34;: 71, \u0026#34;mean\u0026#34;: 57.103448275862064, \u0026#34;stdev\u0026#34;: 3.819293076427424, \u0026#34;90%ile\u0026#34;: 60, \u0026#34;95%ile\u0026#34;: 61, \u0026#34;99%ile\u0026#34;: 64, \u0026#34;99.9%ile\u0026#34;: 71, \u0026#34;99.99%ile\u0026#34;: 71 } } } } 出力内容で気になったのはoutput_tokensとtokenizeのthroughputが全く同じ結果が出ていることです。 なにかバグを踏んでいる気がします。。。(時間を見つけてソースコード読んでみるか。)\n気をつけること meteredの導入時にわかりにくいコンパイルエラーが出たので備忘録として残しておきます。 (下からコンパイルエラーを読んでしまうくせがあったのが問題なのですが。。。) エラーメッセージは次のとおりです。\nerror[E0412]: cannot find type `ResponseTime` in this scope --\u0026gt; src/chapter04/answer.rs:13:12 | 13 | #[measure([ResponseTime, Throughput])] | ^^^^^^^^^^^^ not found in this scope | help: consider importing one of these items | 1 | use metered::ResponseTime; | 1 | use metered::common::ResponseTime; | error[E0283]: type annotations needed --\u0026gt; src/chapter04/answer.rs:12:1 | 12 | #[metered(registry = NekoParserMetricRegistry, /* default = self.metrics */ registry_expr = self.metric_reg)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type | = note: cannot satisfy `_: std::default::Default` = note: required by `std::default::Default::default` = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) 最初のメッセージにはわかりやすく出ていますが、ResponseTimeをuseせずに利用しようとした場合に以下のようなエラーが出ていました。 ターミナル画面が狭かったのでE0283のエラーが目に入り、何を言ってるんだろう?という状態になってしまいました。 スクロールアップしたら、答えが載っているのに。。。\nコード全体 元ネタはNLP100本ノックの第4章です。 コードの全体はGitHubのソースをご覧ください。\nまとめ meteredを簡単ですが紹介してみました。 導入自体も簡単で、想像していたような使い方ができたので満足しています。 ほかにもプロファイラなどはあるのかもしれませんが、まずはこれを使っていこうかと思っています。\nバグらしきものがありそうだったりするので、そのへんは今後調査してみようかと。 まだ、ちょっと試してみただけなので、metered自体のオーバーヘッドや、独自のメトリクスの実装方法、メソッドではなく関数に対して利用する場合にはどうするのか?などいくつか疑問点があるので、今後試してみてまたブログに残しておこうと思います。\n","date":1599487900,"dir":"post/2020/","id":"827de2d7a9d231f6bcb44caf35896c1f","lang":"ja","lastmod":1599487900,"permalink":"https://blog.johtani.info/blog/2020/09/07/intro-metered-rs/","publishdate":"2020-09-07T23:11:40+09:00","summary":"Rustで便利なクレートを見つけたので、紹介がてら、自分のメモのためにブログに残しておきます。 そもそもの問題 Rustで処理を書いていて、なん","tags":["Rust"],"title":"meteredクレートの紹介"},{"contents":"Rustで言語処理100本ノックの第4章です。\n前回はこちら。\n今回は早めに続きをやりました。 「形態素解析」ですしね。\n第4章の概要 吾輩は猫であるの文章が用意されていて、MaCabで形態素解析した結果をファイルに保存したところからが開始となります。\nが、せっかくRustでやっているのでKuromojiのRust版であるLinderaを利用して形態素解析した結果を保存する部分から作成しました。 3章に引き続き、大きな流れのところの説明だけにしておきます。\n形態素解析 もとのneko.txtが文章が1行ごとになっているので、そのまま1行ずつ読みならが、形態素解析していきます。読み込みの部分は3章とあまり変わらないので割愛します。 以下は、形態素解析の処理と形態素解析結果用の構造体です。\n#[derive(Clone, Debug, Serialize, Deserialize)] struct Token { surface: String, base: String, pos: String, pos1: String, } まずは構造体です。今回の問題では、必要な情報は4種類だったのでそれを構造体にしました。\n表層形(surface) 基本形(base) 品詞(pos) 品詞細分類1(pos1) deriveでSerialize、Deserializeを付与しているのは、形態素解析の結果をJSON文字列として保存し、あとのそれぞれの課題で読み出すためにserde_jsonを利用するためです。\nfn tokenize(line: \u0026amp;str) -\u0026gt; Vec\u0026lt;Token\u0026gt; { let mut tokenizer = lindera::tokenizer::Tokenizer::new(\u0026#34;normal\u0026#34;, \u0026#34;\u0026#34;); let lindera_tokens = tokenizer.tokenize(line); let tokens = lindera_tokens .iter() .map(|lindera_token| { let surface = lindera_token.text.to_string(); let pos = lindera_token.detail[0].to_string(); let pos1 = if pos != \u0026#34;UNK\u0026#34; { lindera_token.detail[1].to_string() } else { String::new() }; let base = if pos != \u0026#34;UNK\u0026#34; { lindera_token.detail[6].to_string() } else { String::new() }; Token { surface, base, pos, pos1, } }) .collect(); return tokens; } 次が形態素解析の処理です。 入力に1行分の文章を受け取り、出力として、さきほどの構造体をベクタに入れたものVec\u0026lt;Token\u0026gt;を返します。 内部ではLinderaのTokenizerをnormalモードでインスタンス化してそのtokenizer()メソッドを叩いているだけです。 インスタンス化のときの第2引数は辞書のディレクトリですが、今回はデフォルト辞書(IPADIC)を利用しています。 戻り値はLinderaが用意したToken構造体なので、これを今回作成したToken構造体に詰め替えているだけです。\n注意点としてLinderaはMeCabとは異なり、未知語(辞書に出てこない単語)の処理が実装されていないので、品詞が\u0026quot;UNK\u0026quot;の場合にはその他の情報が取得できないので、空文字を構造体に設定するようにしました。\n結果の保存 形態素解析の結果はJSONで保存しました。 もとのファイルが1文が1行になっていたので、 1行を読み込み、形態素解析し、それをVecで取り出して、1行1配列JSONの形で保存するようにしてあります。\nfn output_tokens(tokens: \u0026amp;Vec\u0026lt;Token\u0026gt;, buf: \u0026amp;mut File) { writeln!(buf, \u0026#34;{}\u0026#34;, serde_json::to_string(tokens).unwrap()).expect(\u0026#34;Error during output json\u0026#34;); } serde_json::to_stringにVec\u0026lt;Token\u0026gt;を渡しているだけですが、構造体にderiveをつけているのでよしなにやってくれます(便利ー)。\nJSONの読み込み処理 1行1JSONの読み込み処理です。 今回も3章のように読み込みながら、各文章ごとの形態素解析結果に対して処理を実施するために、処理を実行するためのtraitをCommandとして用意し、それぞれの問題で形態素解析結果に対して処理を書くような実装にしました。また、設問37で「猫」と共起している単語を処理するという課題があるので、文章に「猫」が入っているものだけを処理できるようにするためのFilterも用意し、これをJSONの読み込み処理のイテレータのfilterにわたすようにしています。 特にフィルタリングが必要ない場合ように、NonFilterを予め実装済みです。\ntrait Command { fn execute(\u0026amp;mut self, tokens: \u0026amp;Vec\u0026lt;Token\u0026gt;); } trait Filter { fn is_target(\u0026amp;self, line: \u0026amp;str) -\u0026gt; bool; } struct NonFilter {} impl Filter for NonFilter { fn is_target(\u0026amp;self, line: \u0026amp;str) -\u0026gt; bool { true } } // ch04-30. 形態素解析結果の読み込み fn load_json\u0026lt;T: Command\u0026gt;(cmd: \u0026amp;mut T) { load_json_with_filter(cmd, \u0026amp;NonFilter {}); } fn load_json_with_filter\u0026lt;T: Command, U: Filter\u0026gt;(cmd: \u0026amp;mut T, filter: \u0026amp;U) { let file = File::open(\u0026#34;./data/chap04/neko.txt.lindera.json\u0026#34;).unwrap(); let buf = BufReader::new(file); buf.lines() .filter_map(|item| item.ok()) .filter(|line| filter.is_target(line)) .for_each(|line| { let tokens = parse_line_json(line.as_str()); cmd.execute(\u0026amp;tokens); }); } output_tokensではserde_json::to_stringを呼び出してましたが、読み込みでは、serde_json::from_strを使うと構造体にしてくれます。\nfn parse_line_json(line: \u0026amp;str) -\u0026gt; Vec\u0026lt;Token\u0026gt; { return serde_json::from_str(line).unwrap(); } あとは、設問ごとにCommandトレイトを実装していく形です。 たとえば、32.の動詞の原形を出力する場合は次のようになります。\nstruct ExtractVerbBase { out: File, } impl Command for ExtractVerbBase { fn execute(\u0026amp;mut self, tokens: \u0026amp;Vec\u0026lt;Token\u0026gt;) { tokens .iter() .filter(|token| token.pos == \u0026#34;動詞\u0026#34;) .for_each(|token| { writeln!(self.out, \u0026#34;{}\u0026#34;, token.base).expect(\u0026#34;Error during writeln\u0026#34;); println!(\u0026#34;{}\u0026#34;, token.base); }) } } 標準出力とは別にファイルにも出力できるようにExtractVerbBaseにoutでファイルを保持しています。\n34. 名詞の連接 「名詞の連接(連続して出現する名詞)を最長一致で抽出せよ.」という課題だったのですが、最初は読み間違えて、名詞の連接の最も長いものだけを出力するようにしてました。。。 やっぱり、出力結果とかのサンプルは用意しといてほしいなぁ。。。\nimpl Command for ExtractMaxConjunctionNoun { fn execute(\u0026amp;mut self, tokens: \u0026amp;Vec\u0026lt;Token\u0026gt;) { let mut nouns = vec![]; // TODO 参照保持でどうにかしたいけどなぁ。 tokens.iter().map(|token| token.clone()).for_each(|token| { if token.pos == \u0026#34;名詞\u0026#34; { nouns.push(token); } else { if nouns.len() \u0026gt; 1 { self.buffer.push(nouns.clone()); } nouns = vec![] } }); } } 名詞の場合に、nounsにバッファリングしつつ、違う品詞が来たら出力するという処理になっています。 cloneを呼び出していますが、これを参照を引き回す感じにできるといいのかもなぁ(結構めんどくさい)。\n36. 頻度上位10語 頻度を数えるのにはBTreeMapを利用しています。 数えながら、Top10を保持する方法がいい気がしたのですが、いい入れ物を見つけられなかったので、数え上げたあとにBTreeMapのIteratorを回しながら、キーバリューのVecをまず生成します。 その生成したVecに値でソートし、その後Iteratorから最初の10件を取得して表示する方法にしました。\nソートして取り出すという処理がついでにかかっています。。。 BinaryHeapがなにか使えそうな気もしたのですが、いい方法が思いつきませんでした。\nfn print_top10(\u0026amp;mut self) { let mut key_values: Vec\u0026lt;(\u0026amp;String, \u0026amp;u32)\u0026gt; = self.terms_count.iter().collect::\u0026lt;Vec\u0026lt;(\u0026amp;String, \u0026amp;u32)\u0026gt;\u0026gt;(); key_values.sort_by(|x, y| y.1.cmp(\u0026amp;x.1)); key_values.iter().take(10).for_each(|(key, value)| { writeln!(\u0026amp;self.out, \u0026#34;{}, {}\u0026#34;, key, value).expect(\u0026#34;Error during writeln\u0026#34;); println!(\u0026#34;{}, {}\u0026#34;, key, value); }); } まとめ 形態素解析結果をちゃんと眺めてはいないですが、処理としてはこんなところかなと。 グラフはめんどくさいのでスキップしてしまいました。。。 Kibana/Esに食わせて見てみるのもありかなぁ?\n次は係り受け解析です。Rustで使えるライブラリとかあるかなぁ?\n","date":1599445027,"dir":"post/2020/","id":"3c5d4d351e0fb9e33e0e8b6d1d43c0f2","lang":"ja","lastmod":1599445027,"permalink":"https://blog.johtani.info/blog/2020/09/07/reboot-nlp100-ch04/","publishdate":"2020-09-07T11:17:07+09:00","summary":"Rustで言語処理100本ノックの第4章です。 前回はこちら。 今回は早めに続きをやりました。 「形態素解析」ですしね。 第4章の概要 吾輩は猫である","tags":["Rust","nlp100"],"title":"第4章終了(言語処理100本ノック2020)"},{"contents":"Rustで言語処理100本ノックの第3章です。\n前回はこちら。\n少し間が空きましたが、再開しました。 間が空いた理由は。。。「正規表現」ですかね。。。 苦手なんです、正規表現。 なので、28はちょっとギブアップしてしまいました。\n第3章の概要 個別に説明はせずに大きな流れのところだけ。 それぞれの問題の解についてはリポジトリを御覧ください(興味ある人いるのかなぁ?)\n第3章はNDJSON(new line delimited JSON)という、 1行に1JSONという形式のデータを格納したファイルがgzipで圧縮された状態で提供されます。 まずは、このJSONファイルからJSONを読み込むのが主な処理になります。\n読み込んだデータに「イギリス」のWikipediaの記事が入っているので、そこから正規表現で必要なデータを抽出します。\n最後の問題が少し特殊で、抜き出した情報の「国旗」のファイル名を元に、MediaWikiのREST APIを叩いて、結果を取得し、その一部の情報を抜き出すというものです。\nJSONの読み込み処理 gzipファイルを読み込んでから、1行ずつ抜き出してVecに入れる処理が次のようになります。 今回のgzipファイルは大した量が入っていないので、全部先に抜き出す処理としてまとめました。 もっと巨大なファイルの場合は個別のJSONに対する処理を buf.lines().map()のmapのなかで実行する形にすると思います。 gzipのファイルを開くのにflate2というクレート(ライブラリ)を利用しました。便利なのは、BufReaderにlines()というメソッドがあるところですかね。\n// https://docs.rs/flate2/1.0.14/flate2/read/struct.GzDecoder.html pub fn extract_ndjson_from_gzip(input_file_name: \u0026amp;str) -\u0026gt; Vec\u0026lt;String\u0026gt; { let f = File::open(input_file_name).expect(\u0026#34;file not found?\u0026#34;); let gz = GzDecoder::new(f); let buf = BufReader::new(gz); let lines: Vec\u0026lt;String\u0026gt; = buf.lines().map(|l| l.unwrap()).collect(); return lines; } こちらは、上記のメソッドで抜き出したVecを元に、記事の情報を抜き出す処理をしています。 JSONをパースして構造体Articleにデシリアライズするために、serdeというライブラリを使用しています。 serde自体は様々なデータ形式(JSON、YAMLなど)をパースするためのフレームワークです。今回はJSONなので、serde_jsonの実装を利用しています。 また、JSON文字列から構造体にデシリアライズするのを簡単にできるように構造体に#[derive(Deserialize)]をつけています。 あとは、let article: Article = serde_json::from_str(json.as_str())という処理を実行すればserde_jsonがJSONをパースして構造体に変換してくれます。形式がわかっているJSONの扱いはこれが楽ですね。変数に型を明記してあるので、型の推論もしてくれてるようです。\n#[derive(Deserialize)] pub struct Article { title: String, text: String, } // ch03-20. JSONデータの読み込み // https://serde.rs/ pub fn load_json(input_file_name: \u0026amp;str, target_title: \u0026amp;str) -\u0026gt; Vec\u0026lt;Article\u0026gt; { let mut results = vec![]; let ndjson = extract_ndjson_from_gzip(input_file_name); for json in ndjson { let article: Article = serde_json::from_str(json.as_str()).expect(\u0026#34;json parse error\u0026#34;); if article.title == target_title { results.push(article); } } return results; } 後続の処理ではパースしたArticleから記事情報を取得して色々と処理をしています。\n正規表現 正規表現用のクレートregexがRustに用意されています。Regex::new(正規表現)で、正規表現をコンパイルし、あとは、この構造体のメソッドを利用して文字列を処理していきます。 問題では、マッチするかどうか、マッチした一部の文字列を抜き出す、不要なタグを削除するといった処理を正規表現で行いました(Rust書くよりも正規表現の書き方とかを調べるのに大半の時間をもっていかれてます。。。)。\npub fn extract_category_lines(article: \u0026amp;Article) -\u0026gt; Vec\u0026lt;String\u0026gt; { let re = Regex::new(r\u0026#34;\\[\\[Category:(.*)\\]\\]\u0026#34;).expect(\u0026#34;syntax error in regex\u0026#34;); let mut lines = vec![]; article.lines_from_text().iter().for_each(|line| { if re.is_match(line) { lines.push(line.to_string()); } }); return lines; } MediaWiki APIリクエスト処理 最後の問題で国旗のファイル名を元にMediaWiki APIを叩いて、URLの文字列を取得しましょうという問題がありました。 ファイル名をREST APIの引数に渡してHTTP経由でリクエストを送信し、返ってくるJSONレスポンスからURLを抜き出すという処理です。\nHTTPのリクエストの送受信にreqwestというクレートを利用しました。 ちょっと長いけど、APIコールしている箇所はこんな形です。\nこの関数にはasyncとついています。非同期処理の関数です。内部で2回ほど(リクエスト送信の結果待ちとレスポンスのパース待ち).awaitがあります。\nclientに.get(URL)やquery(\u0026amp;[])といったメソッドが用意されているので、URLやクエリパラメータを用意してsend()でリクエスト送信します。\nasync fn call_api(file_name: \u0026amp;str) -\u0026gt; Result\u0026lt;String, String\u0026gt; { let client = reqwest::Client::new(); let file_name2 = format!(\u0026#34;File:{}\u0026#34;, file_name); //let mut file_name2 = file_name.to_string().replace(\u0026#34; \u0026#34;, \u0026#34;_\u0026#34;); let query = [ (\u0026#34;action\u0026#34;, \u0026#34;query\u0026#34;), (\u0026#34;format\u0026#34;, \u0026#34;json\u0026#34;), (\u0026#34;prop\u0026#34;, \u0026#34;imageinfo\u0026#34;), (\u0026#34;iiprop\u0026#34;, \u0026#34;url\u0026#34;), (\u0026#34;titles\u0026#34;, file_name2.as_str()), ]; let result = client .get(\u0026#34;https://en.wikipedia.org/w/api.php\u0026#34;) .query(\u0026amp;query) .send() .await; match result { Ok(response) =\u0026gt; match response.status() { StatusCode::OK =\u0026gt; { let body = response.json::\u0026lt;MediaWikiResponse\u0026gt;().await; match body { Ok(obj) =\u0026gt; match obj.get_url() { Some(url) =\u0026gt; Ok(url), None =\u0026gt; Err(String::from(\u0026#34;Cannot get url...\u0026#34;)), }, Err(error) =\u0026gt; Err(error.to_string()), } } _ =\u0026gt; Err(String::from(format!( \u0026#34;Status code is {}.\u0026#34;, response.status() ))), }, Err(error) =\u0026gt; { let error_msg = format!(\u0026#34;Error occurred... {:?}\u0026#34;, error); println!(\u0026#34;{}\u0026#34;, error_msg.as_str()); Err(error_msg) } } } あとは、呼び出し元で非同期の処理を実行するために、tokioというクレートを利用しています。 block_on()でcall_api()の実行をして、結果が返ってくるのを待ち受けています。結果が返ってきて、問題なければ、call_apiの戻り値Result\u0026lt;String, String\u0026gt;の左側のStringの値が取り出され、get_image_urlの戻り値となります。\nfn get_image_url(file_name: \u0026amp;str) -\u0026gt; String { let mut _rt = tokio::runtime::Runtime::new().expect(\u0026#34;Fail initializing runtime\u0026#34;); let task = call_api(file_name); _rt.block_on(task).expect(\u0026#34;Something wrong...\u0026#34;) } 一応、非同期に関して説明してみましたが、合っているのかどうか。。。 クレートの関係などはまだちょっと自身がないです。。。 あとは、エラーの処理の仕方とかももうちょっと勉強したいかな。\nまとめ 一応、3章を終わらせました。だいぶ強引かつ1つスキップしましたが。。。 次は第4章の形態素解析です。\n","date":1599230785,"dir":"post/2020/","id":"eb2a5824e03996c1966bee38866ce349","lang":"ja","lastmod":1599230785,"permalink":"https://blog.johtani.info/blog/2020/09/04/reboot-nlp100-ch03/","publishdate":"2020-09-04T23:46:25+09:00","summary":"Rustで言語処理100本ノックの第3章です。 前回はこちら。 少し間が空きましたが、再開しました。 間が空いた理由は。。。「正規表現」ですかね。","tags":["Rust","nlp100"],"title":"第3章終了(言語処理100本ノック2020)"},{"contents":"負荷を計測するために、数回、Azure Cognitive Searchのクラスターを起動したり、停止したりしてました。 これは、Terraformでやると楽できるのでは?と思ったので、やってみました。 1パーティションのクラスターなので、全然大したことはないのですが、メモを残しておくためにブログに書いておきます。\n基本的にはTerraformの公式ドキュメントにあったものを自分用に変数を抽出しただけです。\nファイルたち 単にクラスターを起動するためだけなので、2種類のファイルだけ作成しました(1個でもいいかも)。\nvariables.tf - 変数用のファイル。いくつかの設定を変数として定義しました。 terraform.tf - Terraform本体のファイル。 variables.tf まずはvariables.tfです(ファイル内の並びは異なりますが。。。)。terraform.tfで利用する5つの変数です。\nresource_group - リソースグループ名。既存とは異なるリソースグループ名にしました(変に壊してもいいので)。 machine_type - 価格レベル(SKU)。公式ドキュメントに設定できる値の一覧があります。今回はWikipediaのデータを登録していたのでそれが入るサイズにしています。 region - 場所(リージョン)。リージョンの一覧はどこにあるんだろう?これを参考にしましたが。 partition_size - パーティションのサイズ(=Elasticsearchでのシャードかな?)です。今回は1つでの性能を計測したかったので1にしてあります。 search_cluster_name - Azure Cognitive Searchのサービス名。search.windows.net名前空間で一意である必要があったので、他の人が使わなそうな名前をつけています。 variable \u0026#34;machine_type\u0026#34; { default = \u0026#34;standard\u0026#34; } variable \u0026#34;region\u0026#34; { default = \u0026#34;East Asia\u0026#34; } variable \u0026#34;resource_group\u0026#34; { default = \u0026#34;johtani-wiki-test\u0026#34; } variable \u0026#34;search_cluster_name\u0026#34; { default = \u0026#34;johtani-wikipedia\u0026#34; } variable \u0026#34;partition_size\u0026#34; { default = 1 } terraform.tf terraform.tfは以下の通り。Terraformの公式ドキュメントにある例にproviderを追加しただけのものになります。\nprovider - プロバイダーの設定。Azureを利用するという宣言です。features {}がないとエラーになります。空でも必ず指定が必要です。認証周りについては、azure-cli経由で認証する方式を採用しました。azure-cliはHomebrewでインストールしています。 azurerm_resource_group - リソースグループの設定。variables.tfのresource_groupとregionを利用しています。必須項目はこの2種類だけです。 azurerm_search_service - Azure Cognitive Searchの設定。partition_count以外は必須項目です。variables.tfとazurerm_resource_groupの設定を利用しています。今回は利用していませんが、レプリカ数なども指定できるようになっています。 # Azureのproviderを指定。 provider \u0026#34;azurerm\u0026#34; { features {} } # リソースグループの設定 resource \u0026#34;azurerm_resource_group\u0026#34; \u0026#34;wiki-test\u0026#34; { name = var.resource_group location = var.region } # Azure Cognitive Searchの設定 resource \u0026#34;azurerm_search_service\u0026#34; \u0026#34;search_service\u0026#34; { name = var.search_cluster_name resource_group_name = azurerm_resource_group.wiki-test.name location = azurerm_resource_group.wiki-test.location sku = var.machine_type partition_count = var.partition_size } 以上がファイルです。ほぼ公式ドキュメントのサンプル通りですねw\nデプロイとか ファイルの準備ができたら実際にデプロイします。 Azureの環境への認証にはAzure CLIを利用して、事前にログインした状態にします。 実際にデプロイするまでの手順は次のようになります。\naz login - Azureの認証。ブラウザが起動してログイン画面が表示されます。無事認証がOKなら、azコマンドでAzure Cloudの情報が取得できます。 terraform init - 初回だけです。Terraformのワーキングディレクトリの初期化処理を実行します。 terraform plan - Terraform \u0026lt; 0.12の場合は実行。最新版だともういらないみたいだ。 terraform apply - 実際にAzure上にクラスターを起動します。Terraformが隠蔽してくれているので、実際にどんなことをやっているかはわかってないですが。 以上で、Azure Cognitive Searchのクラスターが起動します。 すごく簡単です。Webコンソールでチェックすれば、起動していることも確認できます。\nこの状態では、クラスターが起動しただけなので、あとは必要に応じてデータをロードしたり、アプリから検索したりと行ったことが可能になります。 そのへんの話はまた機会があれば。\nDestroy 今回は負荷テスト用にクラスターを起動していましたので、必要なくなれば、クラスターを削除します。Terraformを導入したもう一つの理由がこの簡略化です。 terraform destroyを実行するだけで、Azure Cognitive Searchのクラスターおよび、リソースグループが削除されます。\nまとめ ということで、ほぼ公式ドキュメントのままですが、TerraformでAzure Cognitive Searchのクラスターを起動する方法の紹介でした。 ブログを書いていて、1点気になったのは、ロケーション(リージョン)の一覧はどこにあるんだろう?という点です。azコマンドとかで出てくるのかなぁ?\n","date":1597742807,"dir":"post/2020/","id":"f5effd616a3f8db6193b482caec37912","lang":"ja","lastmod":1597742807,"permalink":"https://blog.johtani.info/blog/2020/08/18/azure-search-with-terraform/","publishdate":"2020-08-18T18:26:47+09:00","summary":"負荷を計測するために、数回、Azure Cognitive Searchのクラスターを起動したり、停止したりしてました。 これは、Terraformでやると楽でき","tags":["azure search"],"title":"TerraformでAzure Cognitive Searchのクラスターを起動"},{"contents":"先日は「システムの特徴と検索機能について」という感じでふんわり書きました。 まぁ、頭の中でぼんやり考えてることを文章にしてみた感じです。 他にもぼんやりしてるものはいくつかあるので今日も書いてみることに。 検索システム?みたいなツイートも見かけたので、検索システムってこんなイメージですというブログを書いてみました。\n検索システム(機能)を構成するパーツ 今回はシステムに組み込まれる検索機能を構成するパーツについて書き出してみようかなと思います。 パーツといってもユーザー、UI、コンテンツなども入れています。\nユーザー 検索UI 検索窓 オートコンプリート 検索結果画面 ファセット ソート ハイライト 詳細画面 レコメンド 検索エンジン コンテンツ 検索ログ クリックログとかも サービス提供者 ざっくり書くとこんな感じです。 システム構成だったり、機能だったり、アクターだったりといろいろなものが混ざってしまっていますが、登場するものはこんなものです。\nざっくりした繋がりの図はこんな感じです。\nそれぞれの役割について見ていきましょう。\nユーザー サイト、システムのユーザーです。 検索UIを経由して望んだコンテンツを探します。 探す目的は、サイトによって異なります。 「何かを購入(ECサイトやオークション)する」だったり、「情報(レシピや社内文書)を見つける」だったりします。 図では「キーワード」と記載しましたが、最近では自然文(文章)を受け付ける検索もあります。\n検索UI サイト、システムが提供するUIです。ユーザーはこのUIにキーワード(質問)を入力し、検索結果を取得します。 UIにはいくつものパーツがさらに存在します。簡単に例を上げると以下のようなものです。\n検索窓 - キーワードを入れるための入力ボックスです。 オートコンプリート(自動補完) - サイトによっては、検索窓に何かを入力すると、キーワードを保管したりサジェストしたりしてくれます。 検索結果画面 - 質問にマッチしたコンテンツの一覧を表示する画面です。一覧以外にもいくつか情報が表示されます。 検索結果一覧 - コンテンツの一覧です。何かしらの基準(日付順や人気順など)によってソートされたものが表示されます。 ファセット - 検索結果が持っている属性(価格帯、カテゴリ、メーカー名など)の一覧で、絞り込み検索のヒントです。 ハイライト - 入力したキーワードがどこにマッチしたかがわかるように、強調表示されたスニペット(情報の一部)が出ます。 検索APIとUIに分かれている場合が多いでしょうか? 処理の流れとしては、検索窓に入力されたキーワードを検索エンジンに問い合わせができるクエリに書き換えてからリクエストを投げます。 あとは、検索エンジンからのレスポンスにある検索結果を表示できる形に変換して表示するのが役割です。 また、検索ログの出力もこの部分で担当することが多いです(もしくは、検索エンジン自体がログ出力の機能を持っている場合もあります)。\n検索エンジン 検索に特化したデータ構造を内部に持っているサーバーもしくはサービスです。 ElasticsearchやApache Solr、Azure Cognitive Searchなどは転置インデックスと呼ばれるデータ構造になっています。 検索エンジンの検索処理に対しての主な役割は次の2つです。\nクエリにマッチするコンテンツの集合を決定する マッチしたコンテンツを特定の条件で並び替える(ランキング) クエリを受け取り、検索結果のリストを返すのが処理の大きな流れです。 その他に、ファセット、ハイライトといった付加的な処理を実行することがあります。\nまた、データ登録(インデキシング/インデクシング)の処理もあります。\n登録するコンテンツを検索に特化したデータ構造にして格納する 転置インデックスの場合は、入力されたデータ(文章)から単語列を作り出して、単語からコンテンツのIDが判別できる形にする処理になります。\nAlgoliaやElastic App SearchのようなSaaSであったり、RDBの機能を利用するといった選択肢もあります。\nデータソース・コンテンツ 実際に提供したいコンテンツになります。 コンテンツが保存されている場所は、サイトによって異なります。\nWebの検索サイト - インターネット上のホームページ ECサイト - データベースに格納されているアイテムのデータ 社内文書検索 - ファイルサーバーやWikiなどのファイル、文書 といった感じです。 実際には、データソースからコンテンツを検索エンジンに登録する場合は、いくつかの処理(いわゆる前処理)が必要になります。 社内文書検索やWebの検索サイトの場合は、データを収集するためのクローラーが必要ですし、 収集したデータから、検索エンジンに登録するデータを加工したり(HTMLタグを除去したり、メタデータ(URL、収集日、タイトル)を付与したり)もします(ETL処理とか言われる)。\n検索ログ 検索を提供するだけであれば、必要ありません。 が、実際に検索がどのような使われ方をしているか?を知るために必要な機能になります。 この検索ログがユーザーのニーズを読み解くための情報になります。 検索ログには次のような情報が入ります。\n検索窓に入力された文字列 入力された文字列でヒットした件数 検索結果を出したタイミングでのログです。他にも実際にヒットしたコンテンツのIDなどをログに残したり、他のユーザーと区別をつけるために、ユーザーのセッションごとにIDを発行してログに残したりもします。\nまた、検索に満足してもらえているかを見るために、実際に検索結果のどのコンテンツに興味をもったのか?という情報も検索ログとして残すことがあります。クリックログなどとも呼ばれます。検索結果のどのドキュメントが実際にクリックされたか(詳細画面に遷移したか)という情報です。1回の検索結果に対してクリックされるごとにログが残ります。 もちろん、結果に満足しない場合は、クリックされずに、キーワードを変えたり、絞り込み条件がクリックされたりします。\nECサイトなどの場合は更に、実際に購入されたかどうかといった情報もユーザーのニーズを読み解くための情報となります。 詳細画面へのクリックログや購入ログについては、検索以外からの流れ(広告やDMだったり、レコメンドだったり)なども考えられます。 これらのログを元に、検索を改善していくことになります。\nサービス提供者 サイト・システムの提供者です。 コンテンツの準備、検索UIにはどんな物が必要なのか、サイト・システムにとって良い検索とはなにか?、検索ログからユーザーのニーズを分析して何を改善していくのか?といったことを考えます。 例としては次のようなことです。\n検索結果に表示するコンテンツとはなにか? コンテンツの持っている項目・属性の何を検索対象とするか? 検索結果の並び順(ランキング)がどんなものがよいのか? 検索UIにはどんなものを表示するのか? 検索機能を作るときの流れ 検索機能を構成するパーツにどんなものがあるかを紹介しました。 実際にシステムに検索機能を追加する場合は、最低限、次のものが必要になります。\n検索UI 検索エンジン(RDB?SaaS?ミドルウェア?) データソース・コンテンツ とりあえずこれらがあれば、検索機能を作ることはできるかと。 ただ、作っただけでは、いいか悪いかの判断がつかないので、どういった使われ方をしているかを知るために検索ログをとったりして、 改善をしていく必要が出てきます。\nまとめ わかってるよそんなことはと言われそうな感じになったかもしれないですが、 検索の機能を構成するパーツについて紹介してみました。 細かなはなしは色々とありますが、大まかにはこのような役割のパーツがあります。\n実際にはこれらのパーツを用意すればよいわけではなく、それぞれで検索を良くしていくためにどんなことを考えていくのか?などが出てきます。そのあたりの話はまた、別のブログで書いていく感じでしょうか。こんな感じで書いてくと、終わらない気がしてきたけど。。。 次はどんなはなしを書くかなぁ。\n","date":1595907282,"dir":"post/2020/","id":"11a61827e80739a6065960eb188d5758","lang":"ja","lastmod":1595907282,"permalink":"https://blog.johtani.info/blog/2020/07/28/improve-search-no2/","publishdate":"2020-07-28T12:34:42+09:00","summary":"先日は「システムの特徴と検索機能について」という感じでふんわり書きました。 まぁ、頭の中でぼんやり考えてることを文章にしてみた感じです。 他にも","tags":["検索"],"title":"検索システムを構成するパーツ(検索システムに関する妄想その2)"},{"contents":"今年の頭からシステムの検索周りを手伝う仕事をフリーランスとしてやっています。 検索の仕組みを知れば知るほど面白くなってきたからという理由になるのかな? LuceneやSolr、Elasticsearchなどを長く触っているというのもあるかと思います。\nということで、検索についていつも考えています。 頭の中でまとまっていない状況ですが、システムにおける検索機能についていくつか頭の中にあることを書き出して、 いろんな方にダメ出しやコメントをもらいたいなと思ったので、色々と書いてみようかと。 思いつきのままに書いているので、はなしがあちこち飛ぶ可能性もありますが、あしからず。\n検索って難しい 「「検索」とは、データの集合から目的のデータを探し出すこと」By Wikipedia\n一言で「検索」といっても、使う人、ユースケースによっていろいろな「検索」があります。 例えば、新しいスマホを買ったときに、スクリーンロックの時間を設定する機能を「検索」したりします。 また、PCで仕事をしているときに、ファイルの中身をある文字列で「検索」したりもします。 TSUTAYAに行って、欲しかった本がおいてあるかどうか店内の端末で「検索」もします。 Rustを書いていて、こんなことをやるライブラリありそうだよな?と思ってGoogleでウェブの検索をしたりもします。\n私が特にそうだと思いますが、なにかあったらまず検索をするという生活をしています。 ただ、このとき、「検索」といっても望んでいる挙動が違ったりするものです。 以下は自分が「検索」しているときに想定していることになります。\nファイル内の検索をしているときはgrep的な検索を想定していることが多い。 書籍の検索をしているときは、特定の項目(著者など)に対してgrep的な検索を想定しているが、名前の読みなどでも検索されることを想定している(漢字覚えてなかったりする。。。)。 Rustを書いているときに機能をGoogleで検索するときは、いい感じに検索してくれることを望んでいる(入力するキーワードが曖昧なことが多々ある。例えば、そのものズバリの名前をしらないときとか) あくまでも私が想像している挙動です。他の人とは違う可能性もあります。 なので、「検索」といってもさまざまな要素があるし、想定しているシーンも異なるので「難しい」なと思っています。 また、そんな「検索」ですが、世の中的にはあって当たり前だと思われていたり、お金や時間がかかるものと思われてなかったりもします。ま、けどそういったことも含めてやればやるほど面白いなと感じている今日このごろです。\n前置きはこのくらいにして、今回はシステムの特徴と検索機能について感じていることを書いてみようと思います。\nシステムの特徴と検索機能 先ほども書きましたが、検索は今やシステムに欠かせない機能となっています。 が、あればいいというものでもないのではないかなと。とりあえず検索できるべきだということで 検索機能を追加しても使いにくいものや、想定している動きをしない場合は使われないものになってしまいます。\nシステムでの検索機能は特に、「情報検索」(Wikipediaはこちら)と呼ばれたりもします。Wikipediaによるとこんな説明です。\n情報検索(じょうほうけんさく)とは、コンピュータを用いて大量のデータ群から目的に合致したものを取り出すこと。検索の対象となるデータには文書や画像、音声、映像、その他さまざまなメディアやその組み合わせとして記録されたデータなどが含まれる。\n「目的」と呼ばれるものは「ユーザーのニーズ」と呼ばれたりもします。 「合致したもの」というのがシステムが返す「検索結果」になります。検索結果は大体の場合、何かしらの順序でソートされていることが多いです。 ざっくり話をすると、「ユーザーのニーズ」を元に「(何かしらの順序でソートされている)検索結果」を返すという処理です。\nただ、この「ユーザーのニーズ」や「何かしらの順序でソートされている検索結果」はシステムの特性、特徴によってぜんぜん違うものになります。検索エンジンを入れただけで解決するものではありません。\nまた、システムは提供する側のニーズもあります。 ECサイトであればより多くのユーザーに購買してもらったり、 コミュニティサイトの場合は利用ユーザーを増やしてコンテンツや広告の収入を増やしたりといったニーズがあります。\nこれらの両方のニーズが検索機能に影響を与えたりもします。\nいくつか例を上げてみましょう。\n書籍の検索の場合 ユーザーのニーズは、「ある本を探す」ことです。そのためにユーザーがクエリを入力します。 クエリは、例にも出しましたがタイトルや著者名の読みだったりします。 検索窓が1つしかないというよりは、著者やタイトル、出版社などそれぞれの項目ごとに検索できるほうが便利だったりしますよね。 検索結果については、完全一致したものが一番最初に出てきてほしいこともあれば、出版年月日の降順で並べたいことなど、 その時々でやりたいことが変わったりもします。\n場合によっては、説明文などでも検索できると嬉しいこともあります。また、システムからは離れますが、図書館や書店で時々、「〇〇について書かれている本ありますか?」といった聞き方をしたりもします。\nまた、書店としては、探している本を見つけてもらうために検索端末などを用意しますが、そ れ以外の本も買ってもらえるといいですよね。 オンラインの書店などでは、検索結果や書籍詳細の画面に関連書籍が出ていることもあります。\n検索とは少し異なり、探索(なにか面白い本とかないかな?というようなニーズ)をしに、書店に行くこともあります。 書店で平積みされた本やポップなどを見て新しい本に興味を持つこともあります。\nオークションサイトやECサイトでの検索の場合 ユーザーのニーズは、「欲しい物を探す」ことです。 ユーザーが入力するクエリは、幅広いものになると思います。製品の型番を入力する人もいれば、 メーカー名や製品名だったり、ジャンルで絞り込んで検索することもあります。\n探されるもの(コンテンツ、アイテム)も多数に渡ります。 検索窓は1つかもしれませんが、検索結果には、絞り込み条件(ファセット)がいくつか並んで、絞り込んでいける仕組みが用意されていることが多いです。\n検索結果のソートは、価格順だったり人気順だったりします。 ただ、オークションサイトの場合は新しいもの順や、終了日時の早い物順だったりします。\nサイト提供者のニーズとしては、より多くのアイテムを購入してもらうこと(売上)です。 また、オークションサイトの場合は、アイテムを提供している人のニーズも影響してくるでしょう。 売りたい人はより多くの人の目に止まってほしいと思うはずなので、 様々な情報を付与していかに目にとまるか?といったことを考えてくると思います。\nまた、様々な商品を扱うECサイトの場合は、さらに色々と大変になってきます。たとえば、「iPhone」で検索されたときに、 iPhoneそのものが上位に来るべきなのか、ケースなどの周辺商品なのかだったりといった問題が出てきます。 商品の提供者が多数に渡る場合は、同一商品でもさまざまなお店から提供されてしまうために、検索結果一覧に多数同じ商品が並んだりもしますよね。\nレシピサイトでの検索の場合 ユーザーのニーズは「レシピを探す」です。が、探し方はユーザーによって様々です。 冷蔵庫にある材料を入力して検索することもあれば、食べたいものが決まっていてそのレシピを検索することもあります。 このとき、重要なのは類義語だったりするでしょう。食材やレシピは同じものでも様々な名前(例:パクチー、コリアンダー、シャンツァイ(香菜)など)を持っていたりします。また、部位や形によっても名前が変わったりもします。\n検索結果は人気順で並ぶことが多いでしょうか? ただ、レシピの提供がユーザーによるものなのか、サイト運営者が提供しているものかによっても変わってくるでしょう。\nサイト提供者のニーズとしては、レシピコミュニティサイトの場合は、ユーザー数の増加や広告の売上などがあるでしょう。 調味料などのメーカーがレシピサイトをやっている場合は、調味料の売上だったりします。この場合は、検索がどの程度売上に寄与しているのか?などを測ることが難しかったりしそうです。\n社内文書検索の場合 ユーザーのニーズは「文書を探す」です。探し方はファイル名であったり、ファイルのなかに出てくる単語だったりします。 社内用語・略語のような特殊な単語で検索されることもあるでしょう。ユーザーによっては、ぼんやりとした「こんな資料を探している」といったふんわりとした検索をしたくなることもあります。\n検索結果の表示順は「それっぽいもの」が上位に出てくることが望まれそうです。 ただ、古い文書が出てきても役に立たないこともあります。新しい文書のほうが役に立つことが多いので、最近作られたものというのも重要な情報になります。ただし、権限によっては見ることができなかったり、そもそも探すこともNGだったりもします。\n社内文書検索の提供者は、素早く検索できるものを提供することで仕事の効率を上げてもらったり、無駄を省くことができることを期待しているでしょう。\n昔からですが、社内の文書は様々な場所に散らばっていることが多いです。顧客管理システム、ファイルサーバー、Wiki、ウェブサイトなどこれらをまとめて検索できるシステムなどが望まれていることも多いです(使われるかはまた別ですが。。。)。\nスマートスピーカーの場合 ちょっと特殊な面白い例かなと思ってます。 音声で検索(というかお願い?)します。 システムとしては、ユーザーのニーズを理解するのに2段階あるのかなと。\n音声認識 認識した文章・キーワードで検索(場合によってはコマンド発行) これだけでも難易度が増します。\nさらに、画面のないスピーカーの場合は、結果は1件だけになります。これって結構難しいことだと思うんです。 画面があれば、検索結果を上位10件などのリストで表示して、あとはユーザーに選んでもらうことができますが、 音声の場合は1件だけしか返せません。 また、レスポンスタイムもシビアなものだと想定されます。ずっとスピーカーに黙っていられると困りますよね? きっと大変なんだろうなぁ(妄想)。\nこのように、検索と言っても、システムごとに要求・想定されるものは変わってきます。\nまとめ 例をいくつか上げましたが、ざっくりしすぎて発散してますかね。。。 想像している部分もあるので、この通りではないと思います。 ただ、システムによって、「検索」といってもシステムの特性上、 さまざまな物事、思惑が絡んでくるというのは想像してもらえたと思います?(思いたい)。\nシステムに検索機能を追加すると言っても、探したいものが何なのか?、探してもらうものはどういったものなのか?、 検索機能を追加することで何を達成したいのか?など考えることは色々あります。 どうやって、検索機能を実装するのか、その検索機能を実装するためにはどんな情報が必要なのか?などの検索機能のコアな部分を考えるだけでなく、提供しているシステム、コンテンツがどんなものかなど、システム全体を考えながら検索機能を考えていく事が検索をより良いものとして行くことだと思います。\nまた、検索されるものも検索する人もシステムが成長するのに合わせて変化していきいます。システム同様、一度作ればおしまいというものではないので、やることはいっぱいあるのかなと。\n次は、検索のパーツについてなにか書こうかなぁ。\nボヤキ もう少しまとめてから書いたほうがいいのかもなぁ。 もしくは、出てくる要素を整理するとか。 ユーザー、コンテンツ、コンテンツ提供者とかで。 ふんわりとしたブログになってしまった。 個別のシステムごとにもっと書けることもありそう。\n","date":1595842134,"dir":"post/2020/","id":"9da845cd31310b8952efd1be1881e651","lang":"ja","lastmod":1595842134,"permalink":"https://blog.johtani.info/blog/2020/07/27/improve-search-no1/","publishdate":"2020-07-27T18:28:54+09:00","summary":"今年の頭からシステムの検索周りを手伝う仕事をフリーランスとしてやっています。 検索の仕組みを知れば知るほど面白くなってきたからという理由になる","tags":["検索"],"title":"システムの特徴と検索機能について(検索システムに関する妄想その1)"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章 Rust the book - 第9章 Rust the book - 第10章 Rust the book - 第13章 14章は飛ばして、15章です(Cargoはまた別途調べればいいかな?と思って)。\n第15章 スマートポインタ たぶん、これを理解すれば、参照とベクタや構造体とかの組み合わせがもう少し効率よく使えるようになるのかなぁ?\nポインタの強い版? 参照カウント方式のスマートポインタ型 - Luceneとかで実装されてた気がするなぁ 複数の所有者!? DerefとDropトレイトを実装している構造体 ヒープのデータを指すBoxを使用する これはコンパイルエラー。let yのタイミングで借用してるので、書き換えでエラーになる。\nfn main() { let mut x = 5; let y = \u0026amp;x; assert_eq!(5, x); assert_eq!(5, *y); x = 6; assert_eq!(6, x); assert_eq!(6, *y); } こっちはOK。\nfn main() { let mut x = 5; // in stack let y = Box::new(x); // in heap assert_eq!(5, x); assert_eq!(5, *y); x = 6; assert_eq!(6, x); assert_eq!(6, *y); } 余談:コンパイラが変なワーニングを出してくれた。\nuse std::ops::Deref; impl\u0026lt;T, Z\u0026gt; Deref for MyBox\u0026lt;T, Z\u0026gt; { type Target = T; fn deref(\u0026amp;self) -\u0026gt; \u0026amp;T { \u0026amp;self.0 } } struct MyBox\u0026lt;T, Z\u0026gt;(T, Z); impl\u0026lt;T, Z\u0026gt; MyBox\u0026lt;T, Z\u0026gt; { fn new(x: T, y: Z) -\u0026gt; MyBox\u0026lt;T, Z\u0026gt; { MyBox(x, y) } } fn main() { let x = 5; let z = \u0026#34;10\u0026#34;; let y = MyBox::new(x, z); assert_eq!(5, x); assert_eq!(5, *y); } Derefトレイトでスマートポインタを普通の参照のように扱う 参照外し型強制 : 日本語ムズカシイネ Derefを自分で実装しないといけない場面がちょっと想像できてない。たぶん、Boxとかの説明に必要なので出てきたって感じなんだろうけど。 Dropトレイトで片付け時にコードを走らせる こっちは、リソース開放とかでいい感じにできそうだってのはわかった。 Dropはどんなときに実装するんだろう?Tantivyだとオブジェクトプールとかで使ってた。 Rcは、参照カウント方式のスマートポインタ これ、ここで作ったConsのリストを追っかけるためのサンプルも書いてほしい。 #[derive(Debug)] enum List { Cons(i32, Rc\u0026lt;List\u0026gt;), Nil, } fn print_typename\u0026lt;T\u0026gt;(_: T) { println!(\u0026#34;{}\u0026#34;, std::any::type_name::\u0026lt;T\u0026gt;()); } use List::{Cons, Nil}; use std::rc::Rc; use std::borrow::Borrow; fn main() { let z = Cons(5, Rc::new(Cons(10, Rc::new(Nil)))); let a = Rc::new(z); let _b = Cons(3, Rc::clone(\u0026amp;a)); let _c = Cons(4, Rc::clone(\u0026amp;a)); match \u0026amp;(*a) { Cons(v1, v2) =\u0026gt; { print_typename(v2); println!(\u0026#34;{}, {:?}\u0026#34;, v1, v2); }, Nil =\u0026gt; println!(\u0026#34;Nil!!\u0026#34;) }; } RefCellと内部可変性パターン 循環参照は、メモリをリークすることもある ","date":1594288778,"dir":"post/2020/","id":"208a8c072ea521c813b86ca7730eb880","lang":"ja","lastmod":1594288778,"permalink":"https://blog.johtani.info/blog/2020/07/09/hap15-rust-the-book/","publishdate":"2020-07-09T18:59:38+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第15章"},{"contents":"6月7日の週に開催されたBerlin Buzzwordsにオンライン出張してました。\nBerlin Buzzwordsとは? ベルリンで開催されている、Big Data、Scarability、Storage and Searchabilityに関するカンファレンスです。 今年はコロナウイルスの影響で、オンラインで開催されました。 また、同時期に検索に関する他のカンファレンス(以下の2つ)もベルリンで毎年開催されているのですが、今年はこれら3つのカンファレンスが1つのチケットで参加できる形で開催されました。\nMICES - MIX-CAMP E-COMMERCE SEARCH HAYSTACK - The Search Relevance Conference! sponsored by OpenSource Connections MICES、HAYSTACKは初参加ですが、検索に関するいくつかのトピックが聞けたので楽しかったです。\n6/7から6/12まで(がんばって)参加したので、その感想などをブログにとどめておきます。\nオンラインってどんな感じで開催されてた? まずは、オンライン開催がどのような感じだったのかをメモしておきます。\n有料のオンラインカンファレンス(事前にチケット購入が必要) 参加者用Slack カンファレンス数日前まではここで連絡とか質問が可能だった(もちろん、メールも来ましたけど)。 基本的なプラットフォームはBrellaのバーチャルイベントプラットフォーム 参加者同士のSNS機能 - 参加者同士の興味によって参加登録時に似たような人ですよとマッチングしたり。ビデオチャット機能もあり。 カンファレンスのスケジュール確認 - セッションのスケジュールの他に、参加者同士でのチャットのスケジュールも可能。一番便利だったのは自分のタイムゾーンも表示してくれること。 ストリームチャネル - セッションが行われている場所への誘導 スピーカー・スポンサーのリスト - スピーカーやスポンサーを探せる機能。スポンサー企業からは参加者も見ることができる セッションはYouTubeライブ ストリーム中だったらちょっと戻ったり、ポーズもできるので、便利だった セッション後の質疑応答にはJitsiというオープンソース!?のビデオカンファレンスの部屋が用意されてた(GitHubで公開されてるのか。https://github.com/jitsi)。 2日目、3日目はLTとかが終わったあとに、オンライン飲み会やってたっぽい(不参加) 主催者側も初めてだとは思うのですが、目立ったトラブルはなかったです。 ちょっとだけ遅れたりしてましたが、それほど影響はなかったです。 オンラインでの開催の一番のネックは、日本だと時差が辛いということです。 ベルリンが開催地なのですが、スピーカーや参加者はアメリカからの方が結構います。 そのため、開始時間が日本の23時といった具合になりました。\n面白かった\u0026amp;気になったセッション いくつか面白かった\u0026amp;もう一度見ないとなと思ったセッションと感想を。\nNatural Language queries at Salesforce scale セッションのページはこちら(2020年7月現在) Salesforceでどのような自然言語のようなクエリに対して書き換え、サジェストのようなことをやっているか?という話です。 Salesforceはテナント(企業)ごとに、データ構造などがカスタマイズ可能なため、 それぞれ個別に入力クエリ(例: new leads in sf)に対して、どういったパーツ(時間?場所?状態?)なのか?、どのフィールドへの条件なのか?といったものをNERのディープラーニングモデルとして捉えて解析しているという話でした。 企業毎にパーソナライズもされていると。実際にはパイプラインの一部でこの処理をやっており、それ以外にも処理はされているという話もありました。評価の話もされています。\nAMA - AI-Powered Search セッションのページはこちら(2020年7月現在) ManningでMEAP(絶賛書いているところ)のAI-Powered Searchの著者2名がAMA形式でいろんな質問に答えていく感じのやつです。 最初は近況報告(Treyさんがカンファレンス直前に転職してた)と、書籍がどんなものかを簡単に紹介したあと、質問に答えていく形式で2時間あります。ディープラーニングのモデルに関する話なども出てきています。 もう一度見たいと思ってたやつなので見ないとな。。。 (パネルっぽいセッションは、ヒントがなにもないので結構辛い)\nAsk Me Anything: Lucene 9 セッションのページはこちら(2020年7月現在) LuceneのPMCメンバーのUweさんが今後のLucene/Solrのいくつかの質問に答える感じのAMAです。 出てきた話(質問の前の)としては、Lucene 8の現状(Bloc-Max WANDとか)や、Java 11対応になるよとかです。 QAでは、SIMDの話、Approximate Nearest Neighborがどんな感じか?などの話でした。\nFrom commercial search to owned search セッションのページはこちら(2020年7月現在) カルフールスペインがECの検索をどのように導入したかという概要レベルの話でした。 モノリシックなものをマイクロサービスでk8s上に載せ替えたという大きなアーキテクチャ以降の話です。 Empathy.coが提供しているものを最終的には使用したみたいだけど、 どんな検索がされているのかといったニーズの調査ができるようになり、検索に絡んだKPIが改善した話でした。 COVID-19に絡んだクエリの変化についてもちょっと話が出てました。\nNeural Search in Practice セッションのページはこちら(2020年7月現在) Zalandoの検索の一部でNIR(Neural IRモデル)を利用してクエリの改善をやって、それをどうやってトレーニングして、テストしたかなどの話。 NIRを利用することで、複数の言語に対して改善が見られたという話だった。 今までは、クエリをいくつかの処理を元に翻訳して、入力された単語がカテゴリーに対するものなのか、スタイルに関するものなのか?などを判別して、クエリの補強?を行っている手法だった。 これに対して、ディープラーニングでクエリに対するクリックデータを元にトレーニングして、どういうクエリに対してどんなアイテムを出すのか?というモデルで検索を改善していた。 ヒット件数が0件だったり少ないものを対象にして上記の処理を入れているらしい。 (ということで、ディープラーニングをしっかり勉強しないといけないみたいなので、どうにかしたい。。。)\nTop 10 Lessons learned in search projects the past 10 years セッションのページはこちら(2020年7月現在) 10年検索プロジェクトをやってきた10個の気づきという感じのセッション。 ごく当たり前のことなんだけど、検索の導入・改善に関して、こういう事あって、何も考えないとこうなっちゃうよね。 だから、こんなことをやるべきだよね?という話です。 たとえば、検索窓はあるけど分析すらしていない状況(レッスン1)だとまずはこういうのやらないとね。とか、 検索クエリの分析・改善ばかりして、コンテンツの分析・改善を怠っていないか?という当たり前の話です。 当たり前なんだけどまとめてくれてるのは、やはりいいなぁと。\nClick logs and insights: Putting the search experts in your audience to work セッションのページはこちら(2020年7月現在) 検索ログとクリックログがあったときに、どういったことに使えるのかを料理のレシピに見立ててデモをするセッションで説明が面白かったです。 「こんなログがあったときに、ログのこの項目とこの項目を材料にすると、こんなのができますね」というのを、Elasticsearchにログを取り込んで、JupyterNotebookでデモをしていました。やはり動くものがあるとわかりやすいですねぇ。\nMixing and Matching: Diversifying Search Results セッションのページはこちら(2020年7月現在) これまたパネルセッションです。 検索結果の多様性に関するディスカッションでした。 これは、ECだからこその課題でもあるのかなと。検索自体は「何かを見つける」ための手段です。 普通に考えた場合は、ピンポイントで探していたものが見つかるのが嬉しいです。 が、例えば、ユーザーが検索した単語そのものが入っているだけのものが見つかるよりも、似たような商品も一緒に出てきてほしいことありますよね?また、ECサイトだと、回遊してほしいというのもあります。ということで、それぞれの方がどんな観点で多様性を考えているのかという話をするディスカッションになっていました。\nThought Vectors, Knowledge Graphs, and Curious Death(?) of Keyword Search セッションのページはこちら(2020年7月現在) AI-Powered Searchの著者の一人、Treyさんのセッション。ベクトルを検索にどうやって使うのか、 ベクトルで表現できるものはどんなものがあるのか?どんな検索エンジンで使えるのか?という話でした。 歴史的な話も交えつつ、検索だとこのへんで使えるんじゃないか?というような話でした。\n録画は? 気になったセッションをいくつか書き出してみました。 ちなみに、全セッションのビデオが公開されています。興味がある方は、ご覧いただければと。\nThe recordings from this year\u0026#39;s Berlin Buzzwords / MICES / Haystack joint event are now online. You can watch them all on our YouTube channel. Thank you once again to all of our wonderful speakers. https://t.co/hTRDmKNdpd\n\u0026mdash; @berlinbuzzwords@floss.social (@berlinbuzzwords) July 6, 2020 感想そして来年は? 楽しかったです。検索に関する話が色々聞けるのはやっぱ楽しいですね。サイトの特性(ECなのか、Wikipediaなのかなど)によっても「良い検索」の定義も変わるので、サービスなどがどんなものか、そしてそれを良くするためには検索はどんなことができるのか?といった話や、技術的な濃い話までいろいろな話を聞けました。 ただ、パネルは英語の聞き取りが辛いですね。。。あと、時差が。日本にいながらにして時差ボケは辛い。。。 オンライン飲み会には流石に参加できませんでした(4時とか5時から始まるし)。\n来年もオンラインで開催されたら間違いなく参加します。 オフラインのみだった場合はどうなるかなぁ。。。\n","date":1594005164,"dir":"post/2020/","id":"e5cb2e5d501d3db2db5d8f14984a66d4","lang":"ja","lastmod":1594005164,"permalink":"https://blog.johtani.info/blog/2020/07/06/attend-berlin-buzzwords/","publishdate":"2020-07-06T12:12:44+09:00","summary":"6月7日の週に開催されたBerlin Buzzwordsにオンライン出張してました。 Berlin Buzzwordsとは? ベルリンで開催されている、Big","tags":["conference","berlin buzzwords"],"title":"Berlin Buzzwordsにオンライン出張してた"},{"contents":"luceneutil - マニアックなツールのセットアップの続きです。 今回も誰得?なブログなので興味ない場合は飛ばしましょう。\n一応、luceneutilのREADMEにあるlocalrun.pyを動かせるところまでいったんですが、そこで一旦本題を思い返してみました。\nKuromojiの性能が落ちてるらしいし、Analyzer系のベンチマーク測ってるグラフに載せたほうがいいよね。\nこれが、そもそも動かしてみようと思った本題です。 READMEに書いてある手順で動いたんですが、よくよく調べてみると、Analyzer系の性能テストをやってるのは、別物っぽいぞと。 なんとなく、「ソフトウェア考古学」っぽくなってきましたね。\nAnalyzerの性能テストやってるのは? Analyzerのパフォーマンステストのグラフに出てきたTokenizerの名前を元にluceneutilのリポジトリを検索してみました。 EgdeNGrams当たりで検索するとヒットしたのが以下のファイルです。\nsrc/main/perf/TestAnalyzerPerf.java src/main/perf/TestAnalyzerPerf4x.java src/python/sumAnalyzerPerf.py 本命はsrc/main/perf/TestAnalyzerPerf.javaっぽいですね。 これを動かしている人はどれかな?ということで、今度はこのファイル名で検索します。\nsrc/python/runAnalyzerPerf.py どうやら、このPythonのファイルが先程のJavaファイルを実行して、性能を計測しているみたいです。 最初に出てきた、sumAnalyzerPerf.pyはrunAnalyzerPerf.pyの実行結果をAnalyzerの計測結果のグラフに追加する処理をしているようだということまでがわかりました。\nKuromojiをTestAnalyzerPerfに追加してみる 動かす対象がわかったので、あとは、やることを追加しましょうと。\nKuromojiの実行をTestAnalyzerPerfに追加 引数を追加して日本語版のWikipediaのファイルも読み込むようにする runAnalyzerPerf.pyに引数の追加とクラスパスの追加 JapaneseAnalyzerはlucene/analysis/kuromojiにビルドされるのでクラスパスを追加 引数に日本語版のWikipediaのファイルを追加 日本語版のWikipediaのデータの用意 こんなものかな?と。\n1と2はそれほど大変ではないので、3をまずはというところから始めてみました。\nWikipediaのXMLから1行1データのTSVファイルに まずは、どんなファイルを想定して動いているのかな?ということで、英語版のファイルがどんなものかを探してみることに。\nTestAnalyzerPerf.javaでは入力ファイルから1行ずつ文字列を読み込んでAnalyzerに処理させているだけというのがわかっています。なので、とりあえず、1行ずつ読めるような形式だと。 次に、runAnalyzerPerf.pyの55行目でenwiki-20130102-lines.txtというものを読み込んでいます。 が、これがよくわからないw\n前回とりあえず動いたときに、src/python/constants.pyにいろんなファイルへのパスとかが記載されていたのを覚えていたので、その当たりから調べてみます。 52行目に約665万件のドキュメントだというような記載があります。 前回のlocalrun.pyのファイルと似たような構造(1行に1記事が埋め込まれたTSVファイル)だろうと判断して、それを作りそうなプログラムを探してみました。 Wikiとかで検索して見つけたのがこのソースたちでした。\nsrc/python/wikiXMLToText.py - それっぽい名前ですよね? 中身を見ると、第1引数のファイル(XML)からpageタグごとにデータを抜き出し、処理をしてからタブ区切りで第2引数のファイルに書き出してます。 src/python/WikipediaExtractor.py - これもそれっぽいですね。 WikipediaExtractory.pyは界隈では有名なhttps://github.com/attardi/wikiextractorみたいです。こっちはなんとなく使い方はわかっています。 src/python/combineWikiFiles.py - これまたそれっぽい。 中身を見ると、1番目のコードで出力したデータに、2番めのコードで出力されたデータを元になにかしら処理をして、引数で与えられたファイルに出力する感じになってます。 ということで、完全に憶測ですが、日本語のWikipediaのXMLファイルを元に次のような流れでファイル作ってみればいいのかな?と。\njawiki-20200620-pages-articles.xml.bz2をwikimediaからダウンロードして、unbzip2で展開 python src/python/wikiXMLToText.py jawiki-20200620-pages-articles.xml jawiki-lines.txtで、1行ごとのデータを作る ちなみに、このプログラムは2箇所ほど修正しました。usernameタグが存在しないpageが出力されなさそうなので、デフォルトでusername: \u0026quot;\u0026quot;みたいなデータをattrってディクショナリに設定しました。 cat jawiki-20200620-pages-articles.xml | python -u src/python/WikipediaExtractor.py -b102400m -o extractedで別途XMLからデータを抽出 python src/python/combineWikiFiles.py jawiki-lines.txt extracted/AA/wiki_00 jawiki-20200620-lines.txtで2と3の出力をかけ合わせる で、まぁ、一応ファイルはできたんですが。。。 前回のブログ記事でセットアップしたときにダウンロードされたファイルはtitle、日付、本文の3つのカラムしかないんですが、上記の手順で作り出したファイルにはいろんなカラムが存在するんですよね(2が出力する項目が結構ある)。。。\n性能テスト用プログラムの書き換え 入力ファイルは出来上がったので、あとは、性能テストを走らせる部分の修正です。 修正部分はプルリク見たほうが明確なので省略で。\n実行してみた で、実行してみました。 せっかくなので、ブランチをbranch_8_5とmasterを対象にしてやってみました。 実際にはsrc/python/runAnalyzerPerf.pyにディレクトリ名やブランチ名が直書きされてたので書き換えつつ実施した結果はこちら。\n他の英語系のAnalyzerと同じグラフに載せてみたのですが、遅いので、下の方に表示されてます。 で、下に凹んだ部分(23 Juneのところ)がbranch_8_5で実行したときの性能値でした。 実際に遅くなってますね。ただ、他のAnalyzerの振れ幅も大きいので、別のグラフにしたほうがわかりやすくなるのかもなぁと思った次第です。\nということで、一応動いたんでプルリク出してみました。 採用されるかなぁ?\n一応誰得ブログはこれでおしまい。 Noriとかもこの感じで対応できるんじゃないかな?\n","date":1593050518,"dir":"post/2020/","id":"bbd2824ff0d5b801bb6f5da3a2a1a888","lang":"ja","lastmod":1593050518,"permalink":"https://blog.johtani.info/blog/2020/06/25/analyzer-perf-test-with-luceneutil/","publishdate":"2020-06-25T11:01:58+09:00","summary":"luceneutil - マニアックなツールのセットアップの続きです。 今回も誰得?なブログなので興味ない場合は飛ばしましょう。 一応、luceneutilのREAD","tags":["lucene"],"title":"luceneutil - Analyzer性能テストへのkuromojiの追加"},{"contents":"LuceneのFSTの修正に関連して、Kuromojiのパフォーマンス問題が出ているようです。 この問題自体はLucene 8.6.0以降で直る予定のようなのです(Elasticsearchへの影響範囲についてはこれが参考になるかな?)。 で、これに関連して、ベンチマーク計らないとねという話が出ていて、 昔から、LuceneのMikeさんがやっているベンチマークのグラフに載せるのがいいよねという話になっていました。 どうも、これについては、Luceneの中にあるbenchmarkというプロジェクトではなく、MikeさんのGitHubリポジトリにあるプログラムで計測しているようです。\nじゃあ、手元でこれどうやって動かすんだろう?ということでやってみたブログになります。 おそらく、99.99%の人は興味ないと思うのでスルーしていただくのがいいと思います。備忘録のために書いてます。\nとりあえずgit clone 公開されているリポジトリはこちらです。\n手順通りに? とりあえず、READMEにセットアップなどのやり方があったんで追っていくことに。 とりあえず動くまでの手順は以下のとおりです。\nディレクトリを決める $LUCENE_BENCH_HOMEが起点になります。名前は何でもいいみたいです。 cd $LUCENE_BENCH_HOME リポジトリをクローン - git clone https://github.com/mikemccand/luceneutil.git utilです。 コレ自体は問題なし。 cd util セットアップスクリプトを実行 - python src/python/setup.py -download ここがすごく時間かかります。6GBのファイルをゆっくりダウンロードしてきますので、一晩置いておきましょう(起きたら終わってた) $LUCENE_BENCH_HOME/dataにenwiki-20120502-lines-1k.txt.lzmaとwikimedium500.tasksいうファイルがダウンロードされている。 ダウンロードした圧縮ファイルを展開 - unlzma enwiki-20120502-lines-1k.txt.lzma macOSにlzmaのコマンド入ってるんですね。知らなかった。 終わったらcd ../で$LUCENE_BENCH_HOMEに戻っておく ベンチマーク対象となるLuceneを用意 - git clone https://github.com/apache/lucene-solr.git READMEにはlucene_candidateとlucene_baselineって名前でって書いてあったのですが、これだと、この後の実行フェーズでエラーになりました。 trunkとpatchというディレクトリにそれぞれ変更しました。localrun.pyを実行したらこのディレクトリ名だったので(相変わらず、自分、行きあたりばったりな対応してるなぁ。。。) とりあえず動くかどうかを確認したかったので、trunkとpatchはどちらもリポジトリをcloneしたものになってます。動いたのを確認したら、タグを指定して比較したいブランチをチェックアウトする予定。 trunkとpatchをビルド - ant jar * localrun.pyを実行 - cd utilそして。。。 5.で記述したディレクトリ以外に1箇所Pythonのコードを書き換えた。 src/python/benchUtil.py内部にhppc-0.8.1.jarのファイルの存在チェックをしているのだが、2020/06/23時点でのLuceneのリポジトリの依存関係だとhppc-0.8.2.jarになっており、ファイルが見つからないエラーが出たため、0.8.2に書き換えた。970行目付近。 改めて実行したら成功した。 まだ途中 とりあえず、実行するところまではできましたが、結果の見方とかちゃんと調べないとなぁ。 いくつかローカルで対応したものについてはあとでGitHubにIssue立てとくべきだな。\nと、動くのを確認したので、日本語周りの準備をしてみてるところです。\n終わったこと\n日本語のWikipediaのデータjawiki-20200620-pages-articles.xml.bz2をダウンロードして展開 試している途中\nWikipediaExtractorでXMLからデータを抽出 - cat ~/tmp/wiki/jawiki-20200620-pages-articles.xml | python -u src/python/WikipediaExtractor.py -b102400m -o extracted これは手順が違うかも???? python src/python/wikiXMLToText.py ~/tmp/wiki/20200620-pages-articles.xml ./hoge.txt これで、title、日付、本文が抜き出せそう? この後にcombineWikiFiles.pyの実行かな? って感じです。 誰得だろうこれ???\n","date":1592917109,"dir":"post/2020/","id":"8a1ea5d5cf843bc5955a94cfcc321e92","lang":"ja","lastmod":1592917109,"permalink":"https://blog.johtani.info/blog/2020/06/23/how-to-use-luceneutil/","publishdate":"2020-06-23T21:58:29+09:00","summary":"LuceneのFSTの修正に関連して、Kuromojiのパフォーマンス問題が出ているようです。 この問題自体はLucene 8.6.0以降で直る","tags":["lucene"],"title":"luceneutil - マニアックなツールのセットアップ"},{"contents":"Azure Cognitive Searchで日本語を扱うときに、形態素解析器を使いたい場合、2種類のAnalyzerが用意されています。今回はこれらの違いがどんなものかを見ていくことにします。\nAnalyzerとは? まずは、その前にAnalyzerとは何者か?というのを少しだけ。 Azure Cognitive Searchは転置インデックスを内部で作成して、検索を行っています。 この、転置インデックスは、「単語」がどのドキュメントに入っているか?を素早く見つけることができるデータ構造となっています。\nAzure Cognitive Searchは、この「単語」を入力された文章から生成するときに、Analyzerというものを利用します。 Analyzerは入力された文章をある規則に則って単語に分割する機能です。 この「ある規則」が、各種言語や用途によって様々に用意されています。 今回はこの中のja.luceneとja.microsoftという2種類のAnalyzerについて違いを見ていきます。\n2種類のAnalyzerの違いはどんなもの? このAnalyzerの挙動を見るためのエンドポイントとしてanalyzeというAPIがあります(詳細は昔のブログを参照)。\nこのAPIを利用して、Wikipediaのいくつかの文章を単語に区切って見て、 ja.microsoftがどんな動きをしているのか想像してみます(残念ながらja.microsoftの仕様?や挙動についてはページが見つからないため)。\nもとの文章と解析結果(一部抜粋) 文章は、手元のElasticsearchに登録したjawikiのデータからランダムに抽出しています。また、自前のツールで生成したWikipediaのデータなので、まだ一部、見苦しい文字列になっています(そっちもなおさないと)。\n1. 砂川(熊本県) thumb|250px|right|上砂川橋より上流方砂川(すながわ)は、熊本県宇城市・八代郡氷川町を流れる二級河川。\nこの文字列から抽出された単語で特徴的なものを一部抜粋しました。\nja.microsoft ja.lucene 250px 250 px 上砂 上, 上砂川 川橋 砂川 橋 宇城 宇 市 城市 二級 二 ^ 級 まず、最初の250pxですが、ja.microsoftでは、pxが単位であると判定しているのか、数値と合わせた単語として抽出されています。この場合、250で検索しても、この文字列はヒットしない形になるので、ノイズが減ることが考えられるかと。\n上砂川橋という文字は、分割の仕方が別れました。 ja.luceneでは、上砂川という単語が地名として辞書に存在するために、このような分割になっています。ja.microsoftのデータは品詞の情報が取れないのですが、上砂、川橋ともに、名詞として辞書に存在しているのではないかなと。ja.luceneには川橋という単語は存在していないようでした。\n宇城市(うきし)については、2005年に合併でできた市のようで、ja.luceneが利用している辞書には存在しない可能性があり、宇城という文字が抽出できてないと思われます。\n最後は二級です。ja.luceneでは、数字と助数詞として分割されています。こちらも何かしらのロジックにより、二級という1単語でヒットできるように数字と単位?が合わせた単語で出てくる仕組みがja.microsoftなのかなと。\n2. UEFA U-18女子選手権2000 UEFA U-18女子選手権2000は第3回目のUEFA U-18女子選手権である。決勝トーナメントは2000年7月27日から8月4日までフランスで行われ、ドイツが初優勝を果たした。\nこの文字列から抽出された単語で特徴的なものを一部抜粋しました。\nja.microsoft ja.lucene u-18, u u 18, nn18 18 第3回目 第 3 回 目 トーナメント, トナメント トーナメント 2000年 2000 年 7月 7 月 27日 27 日 数字を含む単語第3回目や2000年、7月などは、ja.microsoftは先程と同様、数字と単位の組み合わせを1単語として出力しています。\nまた、トーナメントという単語をトナメントという形で、長音を除去した形で出力しています。 今回の文字列ではないですが、この他に、センターをセンターとセンタの2パターンの単語で出力するといったことを行っています。 ja.luceneの場合、単語の最後に長音がある場合だけセンタとして、長音を除去した単語が出力されます。 これは、長音の表記ゆれに対応するためではないかなと。たとえば、インターフェースとインタフェース、インターフェイスのように、人や文章によって、間にでてくる長音を使ったり使わなかったりという表記ゆれに対応するためだと思われます。 その他にも、イプロゥヴェトをイプロゥベトに、ネクストをネキストに、バラエティをバラエチにも変換するなどといった処理をしてくれるようです。カタカナの表記ゆれには強そうですね(これどうやってるんだろう?)。\nja.microsoftでは、nn18というちょっと変わった単語も出てきていました。純粋な数字の場合はnnと入力してくれるようで、数字だけで検索したい場合に利用できるのかな?これはドキュメントに書いておいてほしいかも?\n共通点 ja.lucene、ja.microsoftともに、共通している動作として、「てにをは」といった単語は除去されていました。違いがあるものとしては、「より」(助詞-格助詞-一般)、「されている」(動詞-自立、動詞-接尾、助詞-接続助詞、動詞-非自立)、「ある」(助動詞)といったものはja.microsoftでは除去されずに出てきていました。 ストップワード的に「てにをは」あたりを除去をしている感じでしょうか?\nアルファベットで構成されている単語についても、基本はそのまま出力される挙動のようでした。\nじゃあどっちがいいの? 残念ながらどちらがいいかは、一長一短かなぁと。 ja.luceneに関しては、Luceneの仕組みを利用しているので、Elasticsearchなどを使えば、個別の単語についてより詳細の情報を取得することが可能です(品詞、読みなど)。ja.microsoftについては、残念ながら手の入れようがないので、そういう動きのものだという割り切った使い方になるでしょうか? ただ、長音の除去による表記ゆれなどについては、便利な機能なので、そのあたりの問題に対応したい場合は、ja.microsoftを活用するのも良いかと思います。\n個人的には、より細かい単語としてインデックスに登録できるもののほうが、柔軟な検索には対応できるのではないかなぁと考えています(Kuromojiの辞書をUniDicにするとか?も考えますが、これはAzure Searchではできないですが)。\nまとめ Wikipediaのデータをいくつか使って、ja.microsoftとja.luceneの違いについて、考察してみました。何かの役に立てばと。 他に、これはどんな感じになるの?などありましたら、コメントいただければと。\n","date":1591692240,"dir":"post/2020/","id":"82a115ab8d617e4e96813587fe3a6049","lang":"ja","lastmod":1591692240,"permalink":"https://blog.johtani.info/blog/2020/06/09/difference-analyzers-in-azure-search/","publishdate":"2020-06-09T17:44:00+09:00","summary":"Azure Cognitive Searchで日本語を扱うときに、形態素解析器を使いたい場合、2種類のAnalyzerが用意されています。今回はこれらの違いがどんなもの","tags":["azure search","kuromoji"],"title":"Azure Cognitive Searchでの日本語向けAnalyzerの違い"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章 Rust the book - 第9章 Rust the book - 第10章 11章、12章はちょっと飛ばして、13章です。\n第13章 イテレータ、クロージャです。 12章の話もちょっと出てくるのか。\nクロージャ 基本的に、「変数には値が束縛されている」という固定観念がずっと頭にこびりついたままなので、クロージャに慣れないんだろうなぁ。そろそろこの固定概念をどうにかしないと。\n匿名関数で、変数に保存したり引数に渡せる ちょっと面白い話(ワークアウト)で実際に考えられる手法の説明がいくつか行われる 関数でリファクタリング これが自分がよくやるパターンかなぁ。クロージャになれてないので。。。 クロージャーを変数に束縛 呼び出しは関数みたいな感じ(ここで少し混乱) これだと、結局呼び出されたタイミングが複数回あるよね? -\u0026gt; あはりそうだった ここで、閑話休題で、クロージャの型推論とか注釈の話。 クロージャは狭い文脈だし、外に公開しているものでもないので、戻り値なども定義してなくてもいいよねとのこと。書くことも可能?なので、書いてわかりやすくするのもありなんだろうな。\n推論についてはこれまで通りで、2回異なる型の変数で呼び出すと、2回目で怒られていた。\n遅延評価(クロージャを保持する構造体!?) Fnトレイト トレイトとMatchの組み合わせだからこのへんで説明する形になるのか。 これを真似すれば、いくつか処理を簡素化できるかもしれないなぁ、たしかに。 なければ実行するみたいな処理を書きたいことがよくあるし。Javaだとnullで定義しといて、nullだったらみたいなのがあるから。 Cacherはサンプルだからこの名前でいいけど、自分だと、どんな名前にするかなぁ?\n振る舞いは難しくなるのか。Cacher実装の限界を読むと。\n関数にするとスコープが変わるのでアクセスできなくなると。。。コンパイラが教えてくれるのは便利だな。\n環境から値をキャプチャする3つの方法\n多分この話が一番クロージャに意味がある話なんだと思う。 イテレータ 回しましょう。\n便利。ただ、こういう書き方に自分が慣れてないので、そっちを補正しないとなぁ。 どれがイテレータ?っていうのを判別するのがちょっとむずかしい(慣れの問題かなぁ) イテレータアダプタ便利。どんなのがあるのか?とかがやっとわかってきた。 パフォーマンスに関しては、うーん、どうなんだろう?という感想だった。 ","date":1591259849,"dir":"post/2020/","id":"e74d071363645a588f858b35231128c4","lang":"ja","lastmod":1591259849,"permalink":"https://blog.johtani.info/blog/2020/06/04/chap13-rust-the-book/","publishdate":"2020-06-04T17:37:29+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第13章"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章 Rust the book - 第9章 第10章 ジェネリック、トレイト、ライフタイムです。 手強そう。\nいきなり関数の切り出し方みたいな話が始まって面食らいました。\nジェネリックなデータ型 ジェネリックはJavaにもあるので、それほど理解に苦しむことはなかったです。 また、OptionやResultですでに経験済みでしたし。\nただ、impl\u0026lt;T\u0026gt; Point\u0026lt;T\u0026gt;{、このメソッド定義は少し最初は戸惑いました。 言われてみれば、なるほどなんですけど。\nコンパイル時にコンパイラが単相化を行うことにより、必要最低限なコードを生成してくるというのは理にかなっているなぁと。\nトレイト: 共通の振る舞いを定義する 出だしにもありますが、「インターフェイス」という機能に類似していると考えると割とすんなりと理解が進みました。 ただ、Javaだと、インターフェースはクラスとセットなため、トレイとの実装に関する記述方法は少し戸惑いが。\nデフォルト実装との組み合わせはAbstractに似た処理になるなと考えながら読みすすめました。\n「トレイト境界」という日本語には少し違和感を覚えましたが、線引をして、制限をかけるという理解でいいのかな?\n実際には#[derive()]などで、トレイトを自分で実装する必要がないなどの、便利機能も用意されており、このあたりのコードの追い方がまだ少し慣れていないかもなぁと。便利なんですけど。。。\n少しだけ気になったので、動作確認したのは次の実装です。\nトレイトで宣言されている関数と構造体が独自に実装する関数の名前がかぶるとどうなるのかという実験です。 構造体独自のメソッドが優先される感じになりそう。\npub struct Tweet { pub username: String, pub content: String, pub reply: bool, pub retweet: bool, } pub trait Summary { fn summarize_author(\u0026amp;self) -\u0026gt; String; fn summarize(\u0026amp;self) -\u0026gt; String { // {}さんからもっと読む format!(\u0026#34;(Read more from {}...)\u0026#34;, self.summarize_author()) } } impl Tweet { fn summarize_author(\u0026amp;self) -\u0026gt; String { format!(\u0026#34;hoge {}\u0026#34;, self.username) } fn to_string(\u0026amp;self) -\u0026gt; String { format!(\u0026#34;fuga\u0026#34;) } } impl Summary for Tweet { fn summarize_author(\u0026amp;self) -\u0026gt; String { format!(\u0026#34;@{}\u0026#34;, self.username) } } pub fn summary\u0026lt;T: Summary\u0026gt;(hoge: \u0026amp;T) { println!(\u0026#34;{}\u0026#34;, hoge.summarize_author()); } pub fn main() { let tweet = Tweet { username: String::from(\u0026#34;horse_ebooks\u0026#34;), content: String::from(\u0026#34;of course, as you probably already know, people\u0026#34;), reply: false, retweet: false, }; println!(\u0026#34;{}\u0026#34;, tweet.summarize_author()); summary(\u0026amp;tweet); println!(\u0026#34;{}\u0026#34;, Summary::summarize_author(\u0026amp;tweet)); } ライフタイムで参照を有効化する 言われてみればそうですが、プログラマが色々考えないとまぁ、行けないんですねという感想。\nただ、借用チェッカーが賢くやってくれるおかげで、全てにライフタイム注釈をつけなくて良くなっているというのがわかりました。 逆に言うと、なんとなくRustを書き始めてしまったので、それを知らずに書いたせいで、コンパイラに怒られてても「?」となっていたのかと。。。\n疑問点がいくつかあって、\n通常はどんなライフタイム注釈をみんな書いてるんだろう?'aとかざっくりしすぎてる? 1つのメソッド、関数にライフタイム注釈が大量に出てくるような書き方をした場合は設計がおかしいのでは?って考えたほうがいいのかも? ジェネリックな型とライフタイム引数の順序を入れ替えてみても動くだろ?とおもって入れ替えてみたら怒られた。 あとは、構造体+ジェネリックが絡んできたら少しこんがらがってきそうっという感じです。 まぁ、これから先は実際に書いてみないことにはわからないんだろうなと。\nまとめ 読みました。 実際にはプログラムを書きながら慣れていく感じだろうなぁと。 まだまだ、あれ?ジェネリックってどう書くんだっけ?とか、ライフタイム注釈どうやって付けて、使うときはどうすんだ?みたいになりながら、 出てくるサンプルを少し変えてみてはどうやって動くんだろうこの場合?みたいなことをやってました。 次は、11章、12章を少しだけ自習しつつ、13章に入る予定です(知り合いと一緒に読みすすめてる)。\n","date":1590656815,"dir":"post/2020/","id":"163beeae9620c1a6a46a38aa7ebd9663","lang":"ja","lastmod":1590656815,"permalink":"https://blog.johtani.info/blog/2020/05/28/chap10-rust-the-book/","publishdate":"2020-05-28T18:06:55+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第10章"},{"contents":"今回はAzure Cognitive SearchのSDKを利用したアプリケーションが、実際にAzure Cognitive Searchに対して送信しているリクエストのパラメータとボディをログに保存する方法について紹介します。\n動機 アプリケーションでリクエストを組み立てて、SDK経由で送信していると、最終的にAzure Cognitive Searchに対して送信されているリクエストのパラメータや検索条件などをひと目で見たいことがあります。 アプリケーションでは、ソート条件や、クエリ文字列の組み立てなどの処理は異なる場所で行われたりしますので。\nまた、公式リファレンスでは、機能の説明はRest APIの使い方と組み合わせで説明されることが多いです。\nということで、SDKを利用しているアプリからAzure Searchへ送信されているリクエストをログに保存する方法を調べてみました。\n方法 調べてみるといくつかの手段を取ることができそうだとわかりました。実際に調べて実装する方法を4種類ほど試してみたのでブログに残しておきます。なお、2020年4月時点でのSDKとAzureの仕組みに基づいたブログになります。最新版ではお手軽な方法があるかもしれません。\nDelegatingHandlerを利用する ServiceClientTracingの機能を利用する Azure Application Insightsを活用する Azure Cognitive Searchのコンソールにある診断情報の機能を利用する 1、2はAzure Cognitive SearchのSDKのリファレンスから当たりを付けて見つけた方法です。 3はApplication Insights、4はAzure Cognitive Searchの機能になります。 これらの方法について個別に説明していきます。\n1. DelegatingHandleを利用する まずは、SDKでロギングの機能がないかを調べて見つけた機能がこちらです。 SDKのSearchServiceClientのコンストラクタの引数にDelegatingHandlerというものが渡せることを発見しました。\nこれは、.NET FrameworkのHttpのAPIに存在するクラスで、HTTPのクライアントがHTTPの送受信時に、処理を挟むことができる機能です。フレームワーク側で、LoggingHttpMessaggeHandlerというクラスを用意してくれていましたが、残念ながらこちらは、リクエストとレスポンスのヘッダのみをロギングするクラスでした。 ということで、リクエストボディをログに出力したい場合は独自に拡張してやる必要があります。なお、ロギングにはMicrosoft.Extensions.LoggingのILoggerを使用します。\nまた、Azure Cognitive SearchのSDK側に違う問題点もありました。チュートリアルにあるように、検索するときには、SDKは次のような使い方を想定しています。\n// Create a service and index client. _serviceClient = new SearchServiceClient(searchServiceName, new SearchCredentials(queryApiKey)); _indexClient = _serviceClient.Indexes.GetClient(\u0026#34;hotels\u0026#34;); インデックス用のクライアントを取得するために、GetClient(インデックス名)というメソッドを使用します。このGetClientメソッドのバリエーションとして、DelegatingHandlerを受け取るメソッドがないのです。。。\nということで、DelegationHandlerを活用する方法としては、以下の2つを実装する必要があります。\nCustomなLoggingHttpMessageHandlerクラスを実装 GetClientと同等の処理をDelegatingHandlerを引数にしたものを実装する 以上の2つを実装し、アプリケーション側から2で作成したGetClientを呼び出すことで、リクエストをボディも含めてログ出力することが可能になります。以下は実装例です。\nCustomHttpMessageHandlerクラス。\nusing System; using System.Collections.Generic; using System.Diagnostics; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; namespace AzureSearchSample { public class CustomLoggingHttpMessageHandler : DelegatingHandler { private readonly ILogger _logger; private readonly bool _logContent = false; public CustomLoggingHttpMessageHandler(ILogger logger, bool logContent) { if (logger == null) { throw new ArgumentNullException(nameof(logger)); } this._logger = logger; this._logContent = logContent; } protected override async Task\u0026lt;HttpResponseMessage\u0026gt; SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { if (request == null) { throw new ArgumentNullException(nameof(request)); } await Log.RequestStart(this._logger, request, this._logContent); var stopwatch = new Stopwatch(); HttpResponseMessage response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false); stopwatch.Stop(); await Log.RequestEnd(this._logger, response, stopwatch.Elapsed); return response; } private static class Log { private static class EventIds { public static readonly EventId RequestStart = new EventId(100, \u0026#34;RequestStart\u0026#34;); public static readonly EventId RequestEnd = new EventId(101, \u0026#34;RequestEnd\u0026#34;); } public static async Task RequestStart(ILogger logger, HttpRequestMessage request, bool logContent) { StringBuilder message = new StringBuilder(); message.AppendLine($\u0026#34;Sending HTTP request {request.Method} {request.RequestUri}\u0026#34;); if (logger.IsEnabled(LogLevel.Trace)) { LogHttpHeaders(message, request.Headers); await LogHttpContent(message, request.Content, logContent); logger.Log( LogLevel.Trace, EventIds.RequestStart, message, null, (state, ex) =\u0026gt; state.ToString()); } } public static async Task RequestEnd(ILogger logger, HttpResponseMessage response, TimeSpan duration) { StringBuilder message = new StringBuilder(); message.AppendLine( $\u0026#34;Recieving HTTP response after {duration.TotalMilliseconds}ms - {response.StatusCode}\u0026#34;); if (logger.IsEnabled(LogLevel.Trace)) { LogHttpHeaders(message, response.Headers); await LogHttpContent(message, response.Content, false); logger.Log( LogLevel.Trace, EventIds.RequestEnd, message, null, (state, ex) =\u0026gt; state.ToString() ); } } private static void LogHttpHeaders(StringBuilder message, HttpHeaders headers) { if (headers == null) throw new ArgumentNullException(nameof(headers)); foreach (KeyValuePair\u0026lt;string, IEnumerable\u0026lt;string\u0026gt;\u0026gt; header in headers) { foreach (string value in header.Value) { message.AppendLine($\u0026#34;{header.Key}: {value}\u0026#34;); } } } private static async Task LogHttpContent(StringBuilder message, HttpContent content, bool logContent) { if (content != null) { foreach (KeyValuePair\u0026lt;string,IEnumerable\u0026lt;string\u0026gt;\u0026gt; header in content.Headers) { foreach (string value in header.Value) { message.AppendLine($\u0026#34;{header.Key}: {value}\u0026#34;); } } if (logContent) { string contentBody = await content.ReadAsStringAsync(); message.AppendLine(contentBody); } } } } } } GetClientの実装\nprivate ISearchIndexClient GetClient(string indexName, params DelegatingHandler[] handlers) { var rootHandler = _searchServiceClient.HttpMessageHandlers.OfType\u0026lt;HttpClientHandler\u0026gt;().SingleOrDefault(); var indexClient = new SearchIndexClient(_searchServiceClient.SearchServiceName, indexName, _searchServiceClient.SearchCredentials, rootHandler, handlers) { SearchDnsSuffix = _searchServiceClient.SearchDnsSuffix }; indexClient.HttpClient.Timeout = _searchServiceClient.HttpClient.Timeout; return indexClient; } 出力されるログ例\n2020/04/14 19:17:53.591|TRACE|Sending HTTP request POST https://サービス名.search.windows.net/indexes(\u0026#39;インデックス名\u0026#39;)/docs/search.post.search?api-version=2019-05-06 client-request-id: be02140f-3a07-48cc-b018-d8aa5e819bc3 Accept-Language: en-US Accept: application/json; odata.metadata=none api-key: APIキー User-Agent: FxVersion/4.700.20.11803 User-Agent: OSName/MacOs User-Agent: OSVersion/Darwin.19.4.0.Darwin.Kernel.Version.19.4.0.Wed.Mar.4.22.28.40.PST.2020.root.xnu.6153.101.6.15RELEASE.X86.64 User-Agent: Microsoft.Azure.Search.SearchIndexClient/10.100.19.52907 Content-Type: application/json; charset=utf-8 { \u0026#34;count\u0026#34;: false, \u0026#34;facets\u0026#34;: [], \u0026#34;queryType\u0026#34;: \u0026#34;simple\u0026#34;, \u0026#34;scoringParameters\u0026#34;: [], \u0026#34;search\u0026#34;: \u0026#34;azure\u0026#34;, \u0026#34;searchMode\u0026#34;: \u0026#34;any\u0026#34; } |AzureSearchSample.SearchService|EventId_Id=100, EventId_Name=RequestStart, EventId=RequestStart メリット、デメリット Azure Cognitive Searchの検索の処理だけを対象にリクエストのログを出力することが可能です。また、影響範囲はアプリケーションだけに閉じていますので、デバッグ目的などでログ出力したい場合に、自分だけの手元でログの確認が可能になります。\nデメリットとしては、独自に実装しなければいけない範囲が広いことです。\n2. ServiceClientTracingの機能を利用する Microsoft.Rest.ClientRuntimeというライブラリをAzure Cognitive Searchは利用しています。 このライブラリにServiceClientTracingというクラスが存在します。 なにやら、クライアントの処理のトレースができそうです。\nAzure Cognitive SearchのSDKの実装がGitHubに公開されており、検索リクエストの処理を投げる直前に、このトレースの仕組がONになっていると、ServiceClientTracing.SendRequestメソッドを呼び出していました。\n実際にSendRequestメソッドに送られたものに対して何かしらの処理を行うのは、IServiceClientTracingIntercepterインターフェースを実装したクラスになります。 このインターフェースの実装がLog4Netに存在します。Log4Netを利用している場合は、これを活用すれば楽ができます。\n実際にServiceClientTracingを有効にするには、以下の2行を呼び出すだけです。\nServiceClientTracing.IsEnabled = true; ServiceClientTracing.AddTracingInterceptor(new Log4NetTracingInterceptor()); あとは、Rest.ClientRuntimeがよしなにやってくれます。 1とは異なり、トレースログなので、リクエストのボディについても出力してくれます。\n2020-05-26 19:09:04,058 [1] DEBUG Microsoft.Rest.Tracing.Log4Net.Log4NetTracingInterceptor [(null)] - invocationId: 1 instance: Microsoft.Azure.Search.DocumentsProxyOperations method: SearchPost parameters: {searchRequest=Microsoft.Azure.Search.Models.SearchRequest,clientRequestId=,cancellationToken=System.Threading.CancellationToken} 2020-05-26 19:09:04,164 [1] DEBUG Microsoft.Rest.Tracing.Log4Net.Log4NetTracingInterceptor [(null)] - invocationId: 1 request: Method: POST, RequestUri: \u0026#39;https://サービス名.search.windows.net/indexes(\u0026#39;インデックス名\u0026#39;)/docs/search.post.search?api-version=2019-05-06\u0026#39;, Version: 2.0, Content: System.Net.Http.StringContent, Headers: { client-request-id: 591cb14f-e5c2-4a85-977d-01d1f6431ddc Accept-Language: en-US Accept: application/json; odata.metadata=none api-key: APIキー Content-Type: application/json; charset=utf-8 } Body: { { \u0026#34;count\u0026#34;: false, \u0026#34;facets\u0026#34;: [], \u0026#34;queryType\u0026#34;: \u0026#34;simple\u0026#34;, \u0026#34;scoringParameters\u0026#34;: [], \u0026#34;search\u0026#34;: \u0026#34;azure\u0026#34;, \u0026#34;searchMode\u0026#34;: \u0026#34;any\u0026#34; } } 2020-05-26 19:09:04,459 [Thread Pool Worker] DEBUG Microsoft.Rest.Tracing.Log4Net.Log4NetTracingInterceptor [(null)] - invocationId: 1 response: StatusCode: 200, ReasonPhrase: \u0026#39;OK\u0026#39;, Version: 1.1, Content: System.Net.Http.StreamContent, Headers: { Cache-Control: no-cache Pragma: no-cache request-id: 591cb14f-e5c2-4a85-977d-01d1f6431ddc elapsed-time: 72 OData-Version: 4.0 Preference-Applied: odata.include-annotations=\u0026#34;*\u0026#34; Strict-Transport-Security: max-age=15724800; includeSubDomains Date: Tue, 26 May 2020 10:09:04 GMT Content-Type: application/json; odata.metadata=none Expires: -1 Content-Length: 376 } メリット、デメリット Log4Netを利用しているアプリの場合、2行だけを追加することで実装が完了するのがお手軽な点です。\n難点としては、Rest Client全てにたいしてトレース処理が入ってしまうので、Azure Cognitive Search以外にもRestクライアントを利用しているものが存在した場合、ログの量が増えてしまいます。また、検索以外の処理でもトレースされてしまうのもデメリットになります。\nLog4Net以外のログ機構を使用している場合は、自分でIServiceClientTracingInterceptorを実装する必要も出てきます(参考:StackOverflow)。\n3. Azure Application Insightsを活用する ここから紹介する3と4については、ログの出力先がAzure上になります。\nAzureのApplication Insightsを利用する方法です。 Azure?.NET?のアプリケーションパフォーマンスモニタリングのサービスです。\nApplication Insightsを自分のアプリケーションに設定することで、アプリケーションのパフォーマンス監視に関する情報がAzure上のApplication Insightsリソースに送信されるようになります。\nただ、Application Insightsのデフォルトの機能では、URL程度の情報だけが送信されます(参考:しばやんさんのブログ)\nこちらも拡張機能が用意されており、ITelemetryInitializerのインターフェースを実装したクラスを用意することで、独自の情報をApplication Insightsに出力することが可能となります。詳細についてはしばやんさんのブログを参考にしてもらうのが良いかと。\nHttpリクエストを出力する実装例は次のとおりです。ただ、ちょっとうまく行かないパターンがあったので、コメントアウトとして残してあったりします(なんでだろう?)\nusing System.Collections.Generic; using System.Net.Http; using System.Net.Http.Headers; using Microsoft.ApplicationInsights.Channel; using Microsoft.ApplicationInsights.DataContracts; using Microsoft.ApplicationInsights.Extensibility; namespace AzureSearchWebSample.ApplicationInsights { public class HttpRequestInitializer : ITelemetryInitializer { public void Initialize(ITelemetry telemetry) { if (!(telemetry is DependencyTelemetry dependency)) { return; } HttpRequestMessage requestMessage = null; HttpRequestHeaders requestHeaders; if (dependency.TryGetOperationDetail(\u0026#34;HttpRequest\u0026#34;, out var details) \u0026amp;\u0026amp; details is HttpRequestMessage request) { requestMessage = request; requestHeaders = request.Headers; if (requestMessage.Method == HttpMethod.Post) { string contentBody = requestMessage.Content.ReadAsStringAsync().GetAwaiter().GetResult(); dependency.Properties.Add(\u0026#34;RequestBody\u0026#34;,contentBody); } } else if (dependency.TryGetOperationDetail(\u0026#34;HttpRequestHeaders\u0026#34;, out details) \u0026amp;\u0026amp; details is HttpRequestHeaders headers) { requestHeaders = headers; } else { return; } foreach (KeyValuePair\u0026lt;string,IEnumerable\u0026lt;string\u0026gt;\u0026gt; header in requestHeaders) { foreach (string value in header.Value) { dependency.Properties.Add(header.Key, value); } } //この実装の場合は出力されなかった。なぜ? // if (requestMessage != null \u0026amp;\u0026amp; requestMessage.Method == HttpMethod.Post) // { // string contentBody = requestMessage.Content.ReadAsStringAsync().GetAwaiter().GetResult(); // dependency.Properties.Add(\u0026#34;RequestBody\u0026#34;,contentBody); // } } } } メリット、デメリット すでにApplication Insightsを利用している場合はついでに情報が出力されるので便利です。かつ、常にリクエストログを見れるようにしておく場合はとても便利だと思います。\nApplication Insightsを利用していない場合は、そこから導入しなければならなくなるので、手間が増えるかもしれないです。\n4. Azure Cognitive Searchのコンソールにある診断情報の機能を利用する。 最後はAzure Cognitive Searchの診断ログを有効にする方法です。 ここまで説明してきた方法の中で、一番お手軽な方法です。。。\nこれまでは、リクエストボディを出力する方法を考えていましたが、Azure Cognitive Search側の診断ログを有効にすると、リクエストボディで送信したものが、Azure Cognitive Search側で、クエリパラーメータとして、診断ログに出力されます(診断ログのQuery_s)。\nあとは、Azureのコンソールで当該時間のログを見ればよいだけです。以下は出力されたログの一部です。Description_sにはURLのパスが記載されています。\n診断ログ例(一部)\nDescription_s POST /indexes(\u0026#39;multi-field-test\u0026#39;)/docs/search.post.search Query_s ?api-version=2019-05-06\u0026amp;searchMode=Any\u0026amp;search=azure\u0026amp;queryType=Simple\u0026amp;$count=false メリット、デメリット アプリケーション側に手を入れる必要がなのでお手軽です。 一度設定しておけばコンソール側でログをいつでも見れるので便利です。\nリクエスト量が多くなってしまうと、ログの量も多くなり、費用がかさむ恐れがあります。また、複数の人が触る環境の場合は自分で送信したリクエストがどれだったのか?といった状況に陥る可能性はあります。\nその他は? Azureに対してではないですが、昔似たようなことをやるときにやっていた方法として、ローカルにプロキシサーバーを起動し、そのプロキシサーバー経由でアプリケーションから、Azureに接続することで、リクエストを保存する方法もあります。 ざんねんながら、未調査ですがアプリなどにはそれほど手を入れる必要はないかと思います。\nまとめ ちょっと送信リクエストの内容が見てみたいという話でしたが、いろいろな手段が存在しました。 自分の状況、環境に合わせて手段を選択肢てみるのがいいかと思います。 まずは、簡単な診断ログあたりからでしょうか?\n","date":1590481367,"dir":"post/2020/","id":"36dd94159e3e60076c0c6098086e255f","lang":"ja","lastmod":1590481367,"permalink":"https://blog.johtani.info/blog/2020/05/26/logging-azure-search-request/","publishdate":"2020-05-26T17:22:47+09:00","summary":"今回はAzure Cognitive SearchのSDKを利用したアプリケーションが、実際にAzure Cognitive Searchに対して送信しているリクエストのパラメータ","tags":["azure search",".net"],"title":"Azure Cognitive Searchのリクエストのロギング"},{"contents":"Mircosoft Buildというイベントが今週ありました(MSの方やお客さんに教えてもらった)。\nそこで、Azure Cognitive Searchのセッション(MyBuild - Cognitive Search: The pocket-knife for knowledge mining)があったので、見てみました。 内容がどんなものかをメモっておきます。 最初はCognitive Searchがどんなものよという説明でした。\nビルトインスキルの拡充の話 データソースからデータを取り出し、エンリッチし、検索エンジンに保存するという、パイプラインが組めるようになっています。\nこのパイプラインで利用できる処理のことがスキルと呼ばれています。ここで利用できるビルトインスキルが拡充されますよという話でした。ちょっとだけ抜き出すと以下のとおりです。\nAzure Machine Learning Text translation Brand detection Object detection スキルのリファレンスには載ってるものと載ってないものがあるので、今後追加されてくのかな? Brand detectionがどんなものなんだろう?ってのがちょっと気になりました。どっかにデモとかあるかなぁ?\nスキルセットのための新機能 : Debug Sessionのデモ 上記のスキルを組み合わせてパイプラインを組んで、データソースから取り出したデータをエンリッチしてから、検索エンジンに入れる処理をかけるのですが、その処理のデバッグ用に新しいGUIの機能が追加されてますよという紹介とデモでした。\nTutorial: Use Debug sessions to diagnose, fix, and commit changes to your skillset - Azure Cognitive Search | Microsoft Docs Manage Identityの話 Azure Cognitive Searchにデータを登録するパイプランの最初の段階で、各種データソースにアクセスが必要です。 このアクセス時にコネクションの設定にアカウントキーなども含めてましたが、これをコネクション設定ではなく、専用の管理機能が用意されましたよという話でした。\nSet up a connection to a data source using a managed identity (preview) - Azure Cognitive Search | Microsoft Docs QA Similarityとかの話 BM25になってるよとか SDKの話とか ほかにRelevancyの話 Analyzerをデフォルトのままじゃなくてちゃんと考えて使いましょう(例:各言語用のAnalyzerがいっぱいあるよとか) こんな感じでした。\n","date":1590117041,"dir":"post/2020/","id":"21982f43bc435f22efef22b309a48c66","lang":"ja","lastmod":1590117041,"permalink":"https://blog.johtani.info/blog/2020/05/22/watching-azure-cognirive-search-session-at-ms-build/","publishdate":"2020-05-22T12:10:41+09:00","summary":"Mircosoft Buildというイベントが今週ありました(MSの方やお客さんに教えてもらった)。 そこで、Azure Cognitive Searchのセッション(MyBuil","tags":["azure search"],"title":"Microsoft Build(2020)のAzure Cognirive Searchのセッションを見たのでメモ"},{"contents":"ElasticのWorkplace Searchを触ってみています(その1、その2)が、Elastic Stackの7.7.0がリリースされてしまいました。\n簡単ですが、リリースブログを見ながら気になった点をメモしとこうかと。\n本家のリリースブログ いっぱいあるんですよ、これが。まぁ、内容かぶってるのもあるんですが。\nElastic Stack Elastic Stack 7.7.0をリリース Elasticsearch 7.7.0 released Kibana 7.7.0 released Logstash 7.7.0 released Enterprise Search系 Elastic Enterprise Search 7.7 released, featuring Workplace Search GA | Elastic Blog Elastic App Search updates: Scale your way with new configuration options | Elastic Blog Elastic Workplace Search: 新しい、統合された働き方へ Observability系 Elastic Observability 7.7 released | Elastic Blog\nElastic APM 7.7.0 released with service maps, async profiler, and more | Elastic Blog\nElastic Logs 7.7.0 released with PCF support, MQTT support, and more | Elastic Blog\nElastic Metrics 7.7.0 released with enhanced Prometheus integration and PCF support, | Elastic Blog\nElastic Uptime Monitoring 7.7.0 released with alerting, anomaly detection and more | Elastic Blog\nNew alerting framework released for Observability, Security and the Elastic Stack | Elastic Blog\nIntroducing Elastic Security 7.7.0 | Elastic Blog\n個人的に気になったもの で、全部読んだわけではないのですが、個人的に気になった機能についてメモを残しておきます。 多分に検索によっている可能性がありますが、お気になさらず。 また、ブログとドキュメントを元に気になるところをピックアップしてます。 実際の実装とか動作に関してはまだ未調査の段階です。\nAsync Search - Elasticsearch ElasticsearchのAPIとして非同期に検索できるAPIが実装されました (公式リファレンス)。 大量データを検索が終了してから検索結果を返すのではなく、クエリは実行しつつわかったところまでは都度取得したいという要望だったり、Coldインデックスのように遅いストレージ上にあるデータへの検索でも少しずつ取得できるようにという具合だと思います。ログとか大量に扱う場合にまぁ、ほしいですよね。今回はEsのリリースがメインで、今後はKibanaなどとの連携だったり色々改善していくよという話みたいです(Kibanaの一部の機能は利用しているみたい)。\nライセンスとサブスクリプションのレベル Elastic License Basic 気になるところ(と、予想とか) 仕組みがどうなっているか? Search APIと同等のリクエストパラメータが使える。が、いくつか制約はありそう おそらくTask Manageerで検索してる処理が管理され、レスポンスにはIDが発行されて、そのIDで処理の進み具合を取得する感じ。 Shard単位?Segment単位? 内部的にはShard単位で検索処理を扱ってるので、Shard単位がとりあえず楽そう? Aggsとかも? 対象の模様 Sortは? 有効。ソートのフィールドがインデックス対象だった場合は、そのデータの統計値を使ってShardをソートするっぽい(公式リファレンスのNOTE参照) 関連しそうなGitHubのIssuesとか まだ読んでない\nAsync search · Issue #49091 · elastic/elasticsearch Add a listener to track the progress of a search request locally by jimczi · Pull Request #49471 · elastic/elasticsearch Pre-sort shards based on the max/min value of the primary sort field by jimczi · Pull Request #49092 · elastic/elasticsearch Async search: store intermediate results · Issue #55464 · elastic/elasticsearch Reduced consumption of heap - Elasticsearch ヒープの使用量が7.7で減ってるよというブログも別途ありました。\n元になっているLuceneの実装に関するIssueが「[LUCENE-8635] Lazy loading Lucene FST offheap using mmap - ASF JIRA」です。ヒープ上に展開していたデータをmmapで扱えるようにすることで、ヒープのメモリを削減してる。\nで関連して、これがLuceneで操作できるようになって(「Use reader attributes to control term dict memory useage by s1monw · Pull Request #42838 · elastic/elasticsearch」)、そこからEsに取り込まれたと。\n_idをoff-heapにする話は[ここ](Move the terms index of _id off-heap. by jpountz · Pull Request #52405 · elastic/elasticsearch)にあった。\nこれに関連して、ヒープサイズの推奨について再考が必要かも?というIssue(Reconsider our recommendations for heap size? · Issue #52561 · elastic/elasticsearch)も上がってる。\nPainless Lab - Kibana ほんとにPainless?と言う話はさておき、_script APIでexecuteはできていましたが、やはりもう少し楽に実行したいですよね?ということで画面ができたみたいです。\nシンタックスハイライトとかもできるので、より簡単に使えるようになってますね。 まだ、ベータなので足りないContextとかもあるっぽいけど。\nライセンスとサブスクリプションのレベル Elastic License Basic? まだベータだからか、サブスクリプションのページにはなかった。 公式ドキュメントとGitHubのリポジトリから、Elastic Licenseであることは判明。\n気になるところ(と、予想とか?) 制限事項がどんなものか? 使えるContextがまだ少ない?まだGAではない サジェストがどのくらい効くのか? シンタックスハイライトはあるけど。まだかなぁ? その他Elasticsearch関連 7.7リリースのハイライトが別途用意されています。\n7.7.0 release highlights | Elasticsearch Reference [7.7] | Elastic こっちで気になるのは、ClassificationとかTransformsあたりかなぁ。ML関連の機能で。\nWorkplace Search GA これは別のブログに書くかな。\n気になるところ Betaと何が変わったのか? APIとかどういう形で提供されるのか?そもそも提供されるのか? どんな機能?みたいなのも書く予定です。\nData VisualizerでFilebeatのConfigをサジェスト - Kibana and Filebeat Kibanaの画面からデータをちょっと?(100MB)だけアップロードして、Elasticsearchにサクッとデータ登録できる機能が実はあります。この機能の拡張として、Filebeatの設定だとこんな感じに作れるよ?というのを提示してくれるようになったみたいです。 手元にあるファイルを定期的に読み込むときに、設定を書く下地ができるのは便利じゃないかな?\nライセンスとサブスクリプションのレベル Elastic License Basic Data Visualizerってどんなもの?というのはここにブログがあります。残念ながらKibanaとかの公式リファレンスには使い方のページがないんだよなぁ。\nAPMのサービスマップ - APM and Kibana アプリケーションアーキテクチャのどこでAPMが動作しているか、どこと通信しているかという、APMのエージェントが入っているアプリ間のつながりをKibana上で可視化できる機能っぽいです。まだ、ベータみたいですが、面白そう。Azure Application Insightのアプリケーションマップに似てる気がします。\nライセンスとサブスクリプションのレベル Elastic License Platinum 気になるところ どうやって作ってる(つながりをどうやて判断してる)のか? 分散トレーシングのデータを元に誰がどこと通信してるってのは取れるんじゃなかろうか? Log categorization and contextual examples - Kibana and Elasticsearch 7.6から入ってたっぽいですが、ログの分類をMLの機能を使ってできるものが、LogsのUIとかでさらに使いやすくなった模様。\nライセンスとサブスクリプションのレベル Elastic License Platinum 気になるところ 7.6の機能から追いかけないとなぁ。。。 似たようなログをカテゴリーごとに分析できるようになるので、プラスMLの仕組みでこれまでとは異なる種類のログが出始めたみたいなことが分析できそう。 まとめ 眺めるだけで時間かかりましたが、まぁ、相変わらずいっぱいありますね。 興味のあるところの濃淡が出た感じになりましたが、気になる点をピックアップしてみました。 おかしなところとか、ここはどういう意味?などあればツッコミお願いします。\n","date":1589509037,"dir":"post/2020/","id":"306cecb32320ead508346ad8fed3394d","lang":"ja","lastmod":1589509037,"permalink":"https://blog.johtani.info/blog/2020/05/15/elastic-stack-7_7/","publishdate":"2020-05-15T11:17:17+09:00","summary":"ElasticのWorkplace Searchを触ってみています(その1、その2)が、Elastic Stackの7.7.0がリリースされてし","tags":["elastic stack"],"title":"Elastic Stack 7.7がリリースされた"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章 第9章 エラー処理です。 NLP100とか、いくつかのプログラムを書いていて、なんとなくは扱っていますが、きちんと勉強しないと。\nとりあえず、「Rustには例外は存在しません。」が一番知っておくことかな。\npanic!で回復不能なエラー panic!マクロでスタックを巻き戻して掃除をして終了。 異常終了(panic = 'abort')にもできる。 「RUST_BACKTRACEを0以外の変数にセットして実行」 * Resultで回復可能なエラー expect()は気持ち悪い名前じゃないかなぁ? ここでio::Errorではないものもエラーが発生する場合には panic!すべきかするまいか まとめ 「Rustには例外は存在しない」ので、回復不能か可能かを考えつつ処理を書こうと。\n","date":1589449406,"dir":"post/2020/","id":"1e220a934e16fd941bd804ca03865b60","lang":"ja","lastmod":1589449406,"permalink":"https://blog.johtani.info/blog/2020/05/14/chap9-rust-the-book/","publishdate":"2020-05-14T18:43:26+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第9章"},{"contents":"Rustで言語処理100本ノックの第2章の残りです。\n前回はこちら。\nちなみに、標準入力から受け取る処理は書いてないです。 出力に関してはファイル分割、保存と支持があるもの以外は文字列として取り出すところで終わっています。\n12. 1列目をcol1.txtに,2列目をcol2.txtに保存 pub fn extract_column(input_file_name: \u0026amp;str, num: usize, output_file_name: \u0026amp;str) { let input_f = File::open(input_file_name).expect(\u0026#34;file not found\u0026#34;); let read_buf = BufReader::new(input_f); let mut output_f = OpenOptions::new() .write(true) .create(true) .open(output_file_name) .expect(format!(\u0026#34;can\u0026#39;t open file[{}] with write option\u0026#34;, output_file_name).as_str()); read_buf.lines().for_each(|line| match line { Ok(line) =\u0026gt; { let columns: Vec\u0026lt;_\u0026gt; = line.split(\u0026#39;\\t\u0026#39;).collect(); writeln!(output_f, \u0026#34;{}\u0026#34;, columns[num]); output_f.flush().expect(\u0026#34;Error during flush\u0026#34;); } Err(_) =\u0026gt; panic!(\u0026#34;parse error \u0026#34;), }); } 13で出力結果を利用するので入力として出力ファイル名も受け取るようにしました。 問題としては、1列目と2列目を別々に出力すればいいので、1回の処理で書いても良かったのですが、1回1ファイルの出力という形で実装しました(効率は悪い)。\n改行コードあたりを考えるのがめんどくさかったのでwriteln!マクロでファイルに書き出しています。が、普通にwriteメソッドで改行コードを追加しても良かったのかなと。\nあとは、出力先ファイルが存在しない場合だけopenするようにOpenOptionsを利用してみています。\nflushを呼び出すべきなのかどうか?を調べないとな。。。\n13. col1.txtとcol2.txtをマージ pub fn merge_files(col1_file: \u0026amp;str, col2_file: \u0026amp;str, output_file_name: \u0026amp;str) { let col1_buf = BufReader::new(File::open(col1_file).expect(\u0026#34;file not found\u0026#34;)); let col2_buf = BufReader::new(File::open(col2_file).expect(\u0026#34;file not found\u0026#34;)); let mut output_f = OpenOptions::new() .write(true) .create(true) .open(output_file_name) .expect(format!(\u0026#34;can\u0026#39;t open file[{}] with write option\u0026#34;, output_file_name).as_str()); col1_buf .lines() .zip(col2_buf.lines()) .for_each(|(col1, col2)| { let col1 = col1.expect(\u0026#34;parse error col1\u0026#34;); let col2 = col2.expect(\u0026#34;parse error col2\u0026#34;); writeln!(output_f, \u0026#34;{}\\t{}\u0026#34;, col1, col2); output_f.flush().expect(\u0026#34;Error during flush\u0026#34;); }); } 2つのファイル名を入力として受け取り、タブでくっつけて出力します。 zipを利用することで、2つのイテレーターを同時に回しています。\n14. 先頭からN行を出力 pub fn head(input_file_name: \u0026amp;str, lines: usize) -\u0026gt; String { let buf = BufReader::new(File::open(input_file_name).expect(\u0026#34;file not found\u0026#34;)); let mut head = String::new(); buf.lines().take(lines).for_each(|line| { head.push_str(format!(\u0026#34;{}\\n\u0026#34;, line.expect(\u0026#34;parse error\u0026#34;)).as_str()); }); return head; } イテレーターのメソッドにtakeがあります。 これを利用することで、引数に指定した数のエレメントが取得できるので、これでheadが実現できます。\n15. 末尾のN行を出力 pub fn tail(input_file_name: \u0026amp;str, lines: usize) -\u0026gt; String { let buf = BufReader::new(File::open(input_file_name).expect(\u0026#34;file not found\u0026#34;)); let mut tail = String::new(); let line_count = word_count(input_file_name); buf.lines().skip(line_count - lines).for_each(|line| { tail.push_str(format!(\u0026#34;{}\\n\u0026#34;, line.expect(\u0026#34;parse error\u0026#34;)).as_str()); }); return tail; } tailの場合は少し複雑で、11で作成した行数をカウントするメソッドで総行数を取り出し、そこから引数で指定された行数を引き算した数(=出力しない行数)を、イテレーターのskipメソッドの引数に渡しています。これにより、指定された数のエレメントをスキップしたあとの処理がかけます。\n16. ファイルをN分割する pub fn split_files( input_file_name: \u0026amp;str, num: usize, output_file_prefix: \u0026amp;str, output_file_suffix: \u0026amp;str, ) { let total = word_count(input_file_name) as f64; let lines_in_file = total / num as f64; let lines_in_file = lines_in_file.ceil() as usize; // let buf = BufReader::new(File::open(input_file_name).expect(\u0026#34;file not found\u0026#34;)); let output_files: Vec\u0026lt;File\u0026gt; = create_file_vec(output_file_prefix, num, output_file_suffix); println!(\u0026#34;split file each {} lines.\u0026#34;, lines_in_file); let mut lines = buf.lines(); for mut output_f in output_files { let mut current = 1; while current \u0026lt; lines_in_file + 1 { let line = lines.next(); if let Some(line_rs) = line { if let Ok(line_str) = line_rs { writeln!(output_f, \u0026#34;{}\u0026#34;, line_str); } } current = current + 1; } output_f.flush().expect(\u0026#34;error during flush\u0026#34;); } } fn create_file_vec(output_file_prefix: \u0026amp;str, num: usize, output_file_suffix: \u0026amp;str) -\u0026gt; Vec\u0026lt;File\u0026gt; { let mut files = Vec::with_capacity(num); for i in 0..num { let output_file_name = format!(\u0026#34;{}{}{}\u0026#34;, output_file_prefix, i + 1, output_file_suffix); let output_f = OpenOptions::new() .write(true) .create(true) .open(output_file_name.as_str()) .expect(format!(\u0026#34;can\u0026#39;t open file[{}] with write option\u0026#34;, output_file_name).as_str()); files.push(output_f); } return files; } ちょっと長いですね。\n入力としては、分割するファイル数Nが指定されます。まずは、総行数/Nで各ファイルに保存されるべき行数を計算します。 次に、2つ目の関数をつかって、必要な数のファイルオブジェクトをベクトルとして生成します。\nファイルオブジェクトのベクトルの要素を元にしたfor文を回しつつ、それぞれのファイルに必要な行数を出力している処理になっています。\n総行数がNで割り切れない場合にceilで切り上げした行数にするというちょっとした処理を入れてあります。\n17. 1列目の文字列の異なり pub fn count_uniq_words(input_file_name: \u0026amp;str, col: usize) -\u0026gt; usize { let mut words = HashSet::new(); let buf = BufReader::new(File::open(input_file_name).expect(\u0026#34;file not found\u0026#34;)); buf.lines().for_each(|line| match line { Ok(line_str) =\u0026gt; { let columns: Vec\u0026lt;_\u0026gt; = line_str.split(\u0026#39;\\t\u0026#39;).collect(); words.insert(columns[col].to_string()); } Err(_) =\u0026gt; panic!(\u0026#34;parse error \u0026#34;), }); return words.len(); } HashSetを利用することでユニーク性を担保して、最後はHashSetの数を数え上げれば終了です。\n18. 各行を3コラム目の数値の降順にソート pub fn sort_on_col3(input_file_name: \u0026amp;str) -\u0026gt; String { let mut lines: BTreeSet\u0026lt;Line\u0026gt; = BTreeSet::new(); let buf = BufReader::new(File::open(input_file_name).expect(\u0026#34;file not found\u0026#34;)); buf.lines().for_each(|line| match line { Ok(line_str) =\u0026gt; { let columns: Vec\u0026lt;_\u0026gt; = line_str.split(\u0026#39;\\t\u0026#39;).collect(); let num: u32 = columns[2].parse().expect(\u0026#34;parse error\u0026#34;); let line = Line { line: line_str, num, }; lines.insert(line); } Err(_) =\u0026gt; panic!(\u0026#34;parse error\u0026#34;), }); let mut sorted = String::new(); lines.iter().for_each(|line| { sorted.push_str(format!(\u0026#34;{}\\n\u0026#34;, line.line).as_str()); }); return sorted; } #[derive(Eq)] struct Line { line: String, num: u32, } impl Ord for Line { fn cmp(\u0026amp;self, other: \u0026amp;Self) -\u0026gt; Ordering { let ord = other.num.cmp(\u0026amp;self.num); if let Ordering::Equal = ord { other.line.cmp(\u0026amp;self.line) } else { ord } } } impl PartialOrd for Line { fn partial_cmp(\u0026amp;self, other: \u0026amp;Self) -\u0026gt; Option\u0026lt;Ordering\u0026gt; { Some(self.cmp(other)) } } impl PartialEq for Line { fn eq(\u0026amp;self, other: \u0026amp;Self) -\u0026gt; bool { self.eq(other) } } Lineという、行の文章と第3カラム目の値をもった構造体を作成しました。そこにEq、Ord、PartialOrd、PartialEqを実装し、3カラム目での大小比較できるようにしました。 この構造体をBTeeSetに格納していき、イテレーターで回すことで、ソートされた状態にしてあります。 同一数値の場合は行の降順でソートできるようにOrdを実装してあります。\n19. 各行の1コラム目の文字列の出現頻度を求め,出現頻度の高い順に並べる pub fn sort_on_frequency(input_file_name: \u0026amp;str) -\u0026gt; String { let mut names: HashMap\u0026lt;String, u32\u0026gt; = HashMap::new(); let buf = BufReader::new(File::open(input_file_name).expect(\u0026#34;file not found\u0026#34;)); buf.lines().for_each(|line| match line { Ok(line_str) =\u0026gt; { let columns: Vec\u0026lt;_\u0026gt; = line_str.split(\u0026#39;\\t\u0026#39;).collect(); let name_str = columns[0].to_string(); let count = names.entry(name_str).or_insert(0); *count += 1; } Err(_) =\u0026gt; panic!(\u0026#34;parse error\u0026#34;), }); let mut sorted = String::new(); let mut sorted_names: Vec\u0026lt;(\u0026amp;String, \u0026amp;u32)\u0026gt; = names.iter().collect(); sorted_names.sort_by(|(aname, acount), (bname, bcount)| { let ord = bcount.cmp(acount); if let Ordering::Equal = ord { bname.cmp(aname) } else { ord } }); sorted_names.iter().for_each(|(name, count)| { sorted.push_str(format!(\u0026#34;{} {}\\n\u0026#34;, count, name).as_str()); }); return sorted; } もうすこしうまくできる気がしますが、いったんこれで。 数え上げのためにまずはHashMapに第1カラムの文字列, 個数という組み合わせでデータを入れていきます。 出来上がったHashMapをタプルのベクターに変換し、変換したベクターのsort_byメソッドに比較用の関数を渡すことで個数の降順に並べています。同一個数の場合は文字列の降順になっています。 で、最後に並びかわったベクターのイテレーターを使って出力しておしまいです。 内部的には最悪3回回る感じでしょうか? 最初からベクトルに入れつつソートできる仕組みにするようなのがいいのかなぁ?\nまとめ Unixコマンドの勉強になりましたw あとは、HashMapなどの勉強にもなりました。 最後の方は効率がいまいち良くない気もしてはいますが、とりあえず第3章に進もうかと思います。\n","date":1589253809,"dir":"post/2020/","id":"09155bf417a93847b538ad607f78cca2","lang":"ja","lastmod":1589253809,"permalink":"https://blog.johtani.info/blog/2020/05/12/reboot-nlp100-ch02-12to19/","publishdate":"2020-05-12T12:23:29+09:00","summary":"Rustで言語処理100本ノックの第2章の残りです。 前回はこちら。 ちなみに、標準入力から受け取る処理は書いてないです。 出力に関してはファイル","tags":["Rust","nlp100"],"title":"第2章の12から19まで(言語処理100本ノック2020)"},{"contents":"気づいたら1ヶ月サボってました、ごめんなさい。。。\nRustで言語処理100本ノックの第2章をはじめました。\n前回はこちら。\n確認用のUnixコマンド 確認用のファイルを先に生成して置きました。 これで、Rustでコードを書いて、作成済みの確認ファイルを元にassert_eq!でチェックするという方式を取ろうかと。\nで、コマンド群はこちらです。\nUnix/Linuxコマンド、昔から使っています。が、なにかちょっとした文字列処理やファイル処理をやるときは、Javaのプログラム(最近だとPython)を書くというのが基本になってるので、結構、使ったことの無いコマンドが今回ありました。使ったことがなかったのはこちらです。\nsed tr expand paste cut split sedとかは普通さわってるだろ?って思われそうですね。。。\nで、コマンドをmanで調べつつやりました、macOS上で。 これがまたいくつか罠があったので書き残しておきます(自分が知らないだけかもしれないので、おかしいところがあったらツッコミお願いします。)。\nsedコマンドでのタブの扱い ## sed command for macOS. If using Linux, use \u0026#34;\\t\u0026#34; for tab character cat $INPUT_FILE_NAME | sed -e \u0026#39;s/\t/ /g\u0026#39; \u0026gt; $OUTPUT_DIR/11_sed.txt \\tで行けると思ったのですが、うまく動きませんでした。\u0026lt;tab\u0026gt;みたいな書き方もあると思うのですが、これも駄目で、結局タブ文字をそのまま打ち込みました。。。 これ、めんどくさくないですか??? ちなみに、ターミナルで動作確認して、GitHubにあげてあるシェルファイルにコピペしてたのですが、CLionに貼り付けたらタブ文字がスペースに変換されてしまってて20分くらい悩みました。。。\nsplitコマンドに-nオプションがない LINES=`cat $OUTPUT_DIR/10.txt` SPLIT_LINES=`echo $LINES/$N | bc` split -a 1 -l $SPLIT_LINES $INPUT_FILE_NAME $OUTPUT_DIR/16_ splitコマンドについてググると、-nで指定した数のファイルに分割できるという記事がいくつも出てくるのですが、man splitをターミナル上でやるとそんなオプションがないと。。。 macOSがBSD系だからっぽいです。 ということで、行数を元に、指定した数(N)で行数を割ってから、指定行数ごとにファイルを分割する方式にしました。\nこれらのコマンドの違いはHomebrewとかでインストールするとなくなるのかなぁ?(めんどくさいので確認してないですが。。。)\nってことで、2章のそれぞれの課題の正解ファイルの生成はこれでできたはずです。\n10. 行数のカウント wc -lですね。\n// ch02-10 行数のカウント pub fn word_count(file_name: \u0026amp;str) -\u0026gt; usize { let f = File::open(file_name).expect(\u0026#34;file not found\u0026#34;); let buf = BufReader::new(f); return buf.lines().count(); } ファイルを読み込んで行数を数えます。 文字列として読み込んで改行コードの数を数えるというのもありかな?と思いましたが、RustのBufReaderにlines()という行のイテレータ?が取れることがわかったので、それでカウントを取りました。\n11. タブをスペースに置換 // ch02-11 タブをスペースに置換 pub fn tab_2_space(file_name: \u0026amp;str) -\u0026gt; String { let mut f = File::open(file_name).expect(\u0026#34;file not found\u0026#34;); let mut contents= String::new(); f.read_to_string(\u0026amp;mut contents).expect(\u0026#34;read error\u0026#34;); return contents.replace(\u0026#34;\\t\u0026#34;, \u0026#34; \u0026#34;); } こっちはファイル全体を文字列に読み込んでしまってから、文字列のreplaceで置換するという方式です。 ファイルが大きい場合にこれでいいのか?という問題がある気がしますが、まずはこの実装にしました。 やるとしたら、readメソッドとbufferを用意して、少しずつ読みながら、置換して吐き出す感じでしょうか? ちゃんとした文字コードの区切りで取れるかどうかを気にしないと行けないと思うので、思ったよりはめんどくさくなりそう。\nBufReaderをつかってread_lineのほうがましかも?\nまとめ ということで、サボっていたのを再開しました。 Rustのコードを書く前に、Unixコマンドの処理に結構悩みましたw\nRustのコードとしてはファイル処理なので、今後も役立つ気がしてます。 ということで、頑張っていくぞと。\n","date":1588948640,"dir":"post/2020/","id":"c098c6f0901979bd914ed7a345200f90","lang":"ja","lastmod":1588948640,"permalink":"https://blog.johtani.info/blog/2020/05/08/rebootnlp100-ch02-10to11/","publishdate":"2020-05-08T23:37:20+09:00","summary":"気づいたら1ヶ月サボってました、ごめんなさい。。。 Rustで言語処理100本ノックの第2章をはじめました。 前回はこちら。 確認用のUnixコマ","tags":["Rust","nlp100"],"title":"第2章の10から11まで(言語処理100本ノック2020)"},{"contents":"Rustで言語処理100本ノックのリファクタリングの続き。\n前回はこちら。\nとっくに終わってたのに、ブログ書いてなかった。。。\n08. 暗号文 pub fn cipher(text: \u0026amp;str) -\u0026gt; String { return String::from_iter(text.chars().map(|x| { if x.is_ascii_alphanumeric() \u0026amp;\u0026amp; x.is_lowercase() { let mut b = [0; 4]; x.encode_utf8(\u0026amp;mut b); b[0] = 219 - b[0]; char::from(b[0]) } else { x } })); } Rustの文字列はUTF-8でエンコードされたテキストを保持しているので、文字コード自体は意識していないです。 chars()でUnicodeスカラー値のイテレータが返ってくるので、1文字ずつ扱えるようになります。\nただ、1文字をバイトとして扱うのに手こずりました。 encode_utf8というメソッドを利用して1バイトだけ取り出して、計算するというのをやっています。 文字種の判別のメソッドが用意されているのは便利ですね。\nなんかもうちょっとスマートにできないのかな?と思いつつ動いたのでこれになってます。\n09. Typoglycemia pub fn typoglycemia(text: \u0026amp;str) -\u0026gt; String { return text .split_whitespace() .map(|word| { if word.len() \u0026lt;= 4 { word.to_string() } else { let original = word.chars().collect::\u0026lt;Vec\u0026lt;char\u0026gt;\u0026gt;(); let first = original.get(0).unwrap(); let last = original.last().unwrap(); let mut typo = original[1..original.len() - 1] .iter() .map(|x| x.clone()) .collect::\u0026lt;Vec\u0026lt;char\u0026gt;\u0026gt;(); let mut rng = thread_rng(); typo.shuffle(\u0026amp;mut rng); let mut typo = String::from_iter(typo.iter()); typo.insert(0, first.clone()); typo.push(last.clone()); typo } }) .collect::\u0026lt;Vec\u0026lt;String\u0026gt;\u0026gt;() .join(\u0026#34; \u0026#34;); } 一応、1行で記述できたかな? まずは、スペースで単語ごとに区切った後に、word(単語)の長さによって、処理を分岐し、単語が5文字以上の場合にランダムに並び替えを行うというのをやっています。 文字単位で処理を行うために、chars()で1文字ずつ取り出しています。 最初と最後の文字だけはそのままに、間の文字をランダムにシャッフルするというのをやるのに、もとのwordのスライスからコピーした文字列を作り出してから組み立て直すということをやっています。\nコピーしないでゴニョゴニョする方法ってあるのかなぁ? 思いつかなかったので、結構泥臭い感じの実装になってしまいました。\nまとめ めんどくさいので、コードをGitHubのソースコードからではなく、ブログにコードスニペットとしてコピペしました。Hugoでいい感じにGitHubのコードスニペット表示するのないかなぁ?\nということで、2年越しで1章が終了しました。 2章もやらないとなぁ。\n","date":1588923657,"dir":"post/2020/","id":"2c3270f8797ace2fb37402ea6a09d126","lang":"ja","lastmod":1588923657,"permalink":"https://blog.johtani.info/blog/2020/05/08/reboot-nlp100-finish-ch01/","publishdate":"2020-05-08T16:40:57+09:00","summary":"Rustで言語処理100本ノックのリファクタリングの続き。 前回はこちら。 とっくに終わってたのに、ブログ書いてなかった。。。 08. 暗号文 pub fn cipher(text: \u0026amp;str) -\u0026gt;","tags":["Rust","nlp100"],"title":"第1章の08から09まで(言語処理100本ノック2020)"},{"contents":"前回はWorkplace Searchの概要について書きましたが、今回はインストールと構成要素について説明します。なお、2020/5/7時点での情報を元に本記事は書いていますのでご注意ください。基本的にはインストールと起動方法についての手順を元に書いています。所々に考察を挟んだ形の記事になっていますので、気になるところだけ呼んでいただければと。\n記事一覧 ElasticのWorkplace Searchを触ってみる - その1 インストール インストール方法は公式リファレンスもしくはダウンロードページに記載があります。 現時点ではMacもしくはLinuxが対象でWindowsはまだサポート対象外となっています。\n必要なもの インストールに必要なものは以下になります。\nElasticsearch 7.6.x + Platinum license Elastic CloudのElasticsearch Service もしくは ダウンロードしてローカルで起動 enterprise-search-7.6.0.tar.gz ダウンロードページはこちら Java 8もしくは11 Long Term Supportの対象であるJavaです。2020/5/7時点では8か11 今回はローカルにElasticsearchの7.6.2をインストールしてから試してみます。30日間のトライアルライセンスが有効になっているので、Platinumの機能を試すことができます。\nJavaの8か11が必要になります。Elasticsearchには7.xからJDKが同梱されるようになりましたが、Workplace SearchがJettyを元に動作しているからです(enterprise-search-7.6.0.tar.gzにjettyというフォルダあり)。\nインストール手順 大まかには以下の3つです。\nJava 8もしくは11のインストール 14でも大丈夫でした(ローカルにはSDKMANでインストールした14.0.1が利用された)。 Elasticsearchのインストール(Elastic Cloudの場合はクラスタの起動) 今回はローカルにインストール Workplace Searchのインストール Javaはもともとインストールされていたので、今回は2と3をインストールしました。どちらもローカルで起動するので、2つをダウンロードしてtar.gzファイルを展開するだけになります。\n起動方法と設定 起動方法に起動前の設定の手順も記載があります。 設定しながら起動していきます。\nElasticsearchの起動 既存のElasticsearchのクラスターがあり、Platinumのライセンスが有効になっている場合はこの手順は必要ありません。\nElasticsearchの設定ファイルでSecurity機能をオンに 7.1から基本的なセキュリティ機能はベーシックの機能に含まれています。 Elasticsearchを起動 まずは起動(パスワードなどを設定するために必要) Elasticsearchのパスワードの設定 Elasticsearchでデフォルトで用意されているユーザーのパスワードを設定してします。手順では自動で生成させる方法ですが、独自に設定することも可能です。 Workplace Searchの起動 Elasticsearchが起動したらWorkplace Searchの設定をして起動します。\nEsへの接続設定をconfig/enterprise-search.ymlに指定 Esのパスワード設定時に生成されたelasticというユーザーのパスワードをここで指定。 yamlファイルに記載があるが、${ELASTICSEARCH_PASSWORD:changeme}という記述をした場合に環境変数を読み込める allow_es_settings_modification: trueをconfig/enterprise-search.yml ここに記載があるような変更をWorkplace SearchがEsのクラスターに対して実行する模様。Workplace Search以外でも使用しているElasticsearchクラスターの場合はallow_es_settings_modificationを有効にする代わりに、リンク先にあるような設定を自分で追加する。 secret_management.encryption_keysを複数設定 Encryption Keysのガイドに少し詳しい説明がある。 opensslコマンドとかで作ればいいかな?? 1.と同じような設定をしようとしたがうまくいかなかったので、ファイルにキーを設定する方式にしました(バグ?) 起動するときにデフォルトユーザーパスワードを指定 指定しなければ勝手に生成してコンソールに出力してくれるので、そちらの方がいいかと。 今回は手順通りに指定した。 起動確認のためhttp://localhost:3002にアクセス 起動するとログが流れ、問題がなければ次のようにデフォルトユーザーの情報が出力されます。\n######################################################### *** Default user credentials have been setup. These are only printed once, so please ensure they are recorded. *** username: enterprise_search password: pas...ple ######################################################### そして無事起動に成功したことも出力されます。\n######################################################### Success! Elastic Workplace Search is starting successfully. In a few moments, you\u0026#39;ll be able to login at the following address: * URL: http://localhost:3002 * If this is your first time starting Workplace Search, check the console output above for your user authentication credentials. * Visit the documentation: https://swiftype.com/documentation/enterprise-search Secret session key has been generated. Set the key in your config file to persist user sessions through process restarts: secret_session_key: c23...3 ######################################################### ブラウザで画面にアクセスすると、次のような画面が表示されました。\n起動時のエラー いくつかのパターンも試してどんなエラーが出るのかを見てみました。 おまけですね。\nElasticsearchが見つからないエラー Esを起動しないでWorkplace Searchを起動してみました。\n200秒間アクセスしようと試みて駄目だったらエラーで終了みたいです。\n[2020-05-07T03:48:33.645+00:00][13709][2002][app-server][INFO]: Failed to connect to Elasticsearch backend. Make sure it is running. ... [2020-05-07T03:51:54.038+00:00][13709][2002][app-server][INFO]: Could not connect to Elasticsearch backend after 200s. Terminating... [2020-05-07T03:51:54.039+00:00][13709][2002][app-server][ERROR]: -------------------------------------------------------------------------------- Error: Workplace Search is unable to connect to Elasticsearch. Ensure a healthy Elasticsearch cluster is running at http://127.0.0.1:9200 for user elastic. -------------------------------------------------------------------------------- ElasticsearchのSecurityがオフのときのエラー ちなみにSecurityをオフにしたままWorkplace Searchを起動した場合は以下のようなエラーが出ました。\n[2020-05-07T03:46:53.474+00:00][13567][2002][app-server][ERROR]: -------------------------------------------------------------------------------- Elastic Workplace Search requires Elasticsearch security features to be enabled. Please enable Elasticsearch security features as outlined here: https://www.elastic.co/guide/en/workplace-search/current/workplace-search-install.html -------------------------------------------------------------------------------- 構成要素 ここまでインストールして起動してきました。 では、Workplace Searchがどういったコンポーネントから構成されているかを予測してみましょう(あくまで外から見た予想となります。そのうちElastic社のウェビナーとかイベントで内部の発表とかあるかも?)。\nインストールページの記載から インストールページに最小ハードウェアという記載があり、そこで何が動く可能性があるかというのがわかります。\n起動するものはこんな感じみたいです。\nElasticsearch - 外部でもOK App Server - Workplace SearchのWeb機能 Worker - クローラーとかかな? Filebeat - Workplace Searchのログ収集用 その他プロセス - なんだろ? という具合です。\n設定などからの予想 次は設定項目や起動時のログなどからの予想です。\nWorklpace Search配下のセキュアなデータストア - アクセストークンなどの管理のため JRubyアプリケーション - App ServerはJRuby上で動いているRailsアプリ Filebeatも起動している - Workplace Searchのログ収集のため? Filebeatの接続設定はWorkplace Searchの設定値を利用 では構成要素は? ということで、現時点でわかった構成要素は以下のとおりです。\nElasticsearch Workplace Search App Server - Railsアプリ on JRuby Webアプリとは別に(内部?で)、いくつかのワーカーが存在する 管理画面と検索画面の2種類が存在 Filebeat - ログ収集 といった感じです。 まだ起動したばかりなのでこのくらいでしょうか。ログを見るともう少しわかりそうな気がします。\n基本的には、EsをバックエンドにしたRailsのミドルウェアになります。コネクターや検索画面はすべてWorkplace Searchのミドルウェア経由でアクセスする形になりますので、普通に検索で利用するユーザーにはElasticsearchの存在は見えない作りになっています。\n次は? Getting Startedを元に、どんなアクターがいて、どんな機能が提供されているのか、どんな利用方法なのか?というのを見ていこうと思います。\n","date":1588818770,"dir":"post/2020/","id":"44db1f1fefc97cd28d55d443f2bd2b63","lang":"ja","lastmod":1588818770,"permalink":"https://blog.johtani.info/blog/2020/05/07/install-workplace-search/","publishdate":"2020-05-07T11:32:50+09:00","summary":"前回はWorkplace Searchの概要について書きましたが、今回はインストールと構成要素について説明します。なお、2020/5/7時点で","tags":["elasticsearch","workplace search"],"title":"ElasticのWorkplace Searchを触ってみる - その2 - インストールと起動"},{"contents":"2月のElastic社のブログですが、Enterprise Searchとこれまで呼んでいた製品をWorkplace Searchという製品名に変更し、App Searchなどを含む製品群をEnterprise Searchという名前に変更しました(ちょっとややこしい)。 Workplace Search自体はまだβ版という位置づけですが、ダウンロードして試すことが可能です。\nきちんと触ったことがないので、ちょっと触って見ようかなと思い、何回かに分けてブログを書いてみます。まずは概要とかから。\nWorkplace Searchとは? Elasticsearchをバックエンドに利用するElastic社が提供するアプリケーション(ミドルウェア?)の1つです。\nもともとはSwiftypeという会社が作っていた、Site Search、App Searchと同じような系列で開発されている統合検索の検索エンジンミドルウェアという感じです。 製品ページを見るとわかりますが、様々なデータソースから、データをクロールしてElasticsearchに保存することで、統合された検索を提供することができるようになる製品です。 最近は会社のドキュメントがさまざまな場所(Google Drive、Saleseforce、GitHub、Dropboxなど)に保存されています。 それぞれで検索窓などはありますが、1箇所で検索することで横断的に検索でき、仕事の効率があがりますよね?ということで作られている製品です。\n提供(利用)方法は? 今後の提供方法としては、Elastic Cloudで利用できるSaaS形式のものと、独自に(クラウドのコンピューティングエンジンやオンプレのサーバーなどで)Workplace Searchのアプリを起動する方法(オンプレ版)があります。後者の場合は、Elasticsearchのクラスターを用意する必要があります。なお、後者の場合、Elasticsearchのサブスクリプションのプラチナライセンスが必要になるようです(ダウンロードページに記載あり)\nまだ、β版という位置づけなので、今後どのように変更されるかはわかりませんが、今回は2020年5月1日時点でのベータ版(7.6.0)を元にどんなものかを紹介します。現時点で利用できるのはβ版のオンプレ版で、MacやLinuxで利用可能です。\nダウンロードとインストール ダウンロードページにインストール方法などの記載があります。\nインストールして触って見るところはまた後日。\nライセンス、価格は? まだ不明です。SaaS版の提供はまだです。 オンプレ版については少なくとも、Elasticのサブスクリプションのプラチナが必要になります。こちらは、価格は公開されていません。Elastich社もしくはパートナー企業での問い合わせが必要になります。 (たぶん、ドキュメントレベルのセキュリティとかSSOとかの仕組みがプラチナで提供されているのでそのあたりを使っているのでは?と想像してます。)\n想定できそうな用途は? 社内の文書検索でしょうか。ただ、いわゆる昔ながらのエンタープライズサーチと呼ばれている、社内のファイルサーバーなどの文書検索ではなく、クラウドサービスを複数利用している会社が利用する想定になっています。\n例えば、開発者は社内Wiki(Confluence)で社内文書を書き、Issue管理にはJIRAやGitHubを活用しており、ただ、社内での説明にはGoogle Driveを利用しているといった場合です。こういう場合、あの機能についての説明や資料ってどこだっけ?というので、あちこち探し回ったりしないといけないです。また、営業部門やサポート、マーケティングなどが絡んでくると更に、SalesforceやZendeskといったデータソースも出てきます。 情報が散らばっていて、それらを探し出したりまとめるだけで時間を取られている場合などに便利かもしれません。\n次は? 実際にインストールしてから起動して、どんな感じで使えるのかといったところを見て、どんな機能が提供されているのかを見ていこうと思います。\n","date":1588318144,"dir":"post/2020/","id":"4d71d2a23c85fb7af20e8d1e8b3e0de8","lang":"ja","lastmod":1588318144,"permalink":"https://blog.johtani.info/blog/2020/05/01/intro-workplace-search/","publishdate":"2020-05-01T16:29:04+09:00","summary":"2月のElastic社のブログですが、Enterprise Searchとこれまで呼んでいた製品をWorkplace Searchという製品名に","tags":["elasticsearch","workplace search"],"title":"ElasticのWorkplace Searchを触ってみる - その1"},{"contents":"先日、Elasticsearchでのカスタム辞書の利用方法についてブログを書きました。\n辞書の設定方法について記載しましたが、今回は辞書の更新について書いていなかったので、書いてみようと思います。 ここで「辞書」としているのは、Kuromojiのユーザー辞書、Synonym Graph Token FilterのSynonym辞書(いわゆる類義語辞書)のことになります。サードパーティのAnalyzer等に関する話ではありません。\n辞書更新に関する制限事項 辞書の更新について、大原則と制限事項が存在します。\n大原則(辞書の更新=データも更新) ElasticsearchはAnalyzerが切り出した単語を元に転置インデックスを作成して、検索を行っています(この仕組みに関するスライドはこちらを参照のこと)。 Analyzerが辞書を持っている場合、その辞書を元に単語を切り出して転置インデックスに利用します。 また、検索クエリの単語に対してもこのAnalyzerの辞書が利用されます。\n辞書に新しい単語を追加するということは、その単語に関連するドキュメントも更新しないと行けないということになります。\n例えば、Kuromojiを利用していて、「グランベリーパーク」という単語「グランベリー」「パーク」という単語に分割できるような新しい単語として辞書に追加する場合を考えてみましょう。ユーザーが「グランベリー」で検索しても検索結果として出てきてほしいという場合です。\n辞書に「グランベリーパーク」を登録していない頃に登録されたドキュメントは「グランベリーパーク」という1単語として転置インデックスの見出し語を切り出します(Kuromojiはカタカナの連続している文字列については未知語として1単語にし、「名詞-一般」の品詞を付与)。\n更新前でのドキュメントのAnalyze結果\n「グランベリーパーク」「で」「ショッピング」 もし、辞書に「グランベリーパーク」を「グランベリー」「パーク」から構成される新規の単語として登録しそれを使用した場合、辞書を更新したあとから、「グランベリーパーク」という単語がAnalyzerからは出てこなくなります。\n更新後でのドキュメントのAnalyze結果\n「グランベリー」「パーク」「で」「ショッピング」 ということは、辞書更新以前のドキュメントは「グランベリーパーク」という見出し語に対して登録されているので、辞書更新以前に登録されているドキュメントは検索にヒットしなくなります。\nこのように転置インデックスを利用している検索エンジンでは、単語の区切りが変更されるような辞書の更新があった場合、最低でも影響があるドキュメントについては再登録が必要となるわけです。\nこれが大原則(辞書更新=データも更新)となります。 基本的には辞書の更新を行った場合は、ドキュメントの再インデックス(再登録)が必要となります。\nElasticsearchでの制限事項 Elasticsearchでは、辞書の更新に関して実装上の制限事項が存在しています。 内部的な実装として、ElasticsearchではAnalyzerのインスタンス(正確にはAnalyzerのFactoryのインスタンス)の生成がインデックスに関する内部のインスタンスが生成されたタイミングの1回のみとなっています。\nこのインスタンスの生成時に設定ファイル(辞書を含む)を読み込んでいます。\n言い換えると、辞書(ファイル、インデックス設定に関わらず)の読み込みは、インデックスが作られたタイミングのみということになります。 なおここで言う「インデックスが作られたタイミング」というのは、以下の2パターンです。\nインデックス新規作成時 インデックスオープン時 では、ここから辞書を更新してそれを既存のインデックスに適用する方法について説明しましょう。\n辞書の更新方法(ファイル編) 前回のブログで説明しましたが、Elasticsearch 7.4よりも古いバージョンでは、ファイルでKuromojiのユーザー辞書を設定していました。まずはこちらの方法について説明します。前提として、すでにユーザー辞書を設定したKuromoji Tokenizerがインデックスに設定されているものとします(ユーザー辞書の設定方法については公式リファレンスを御覧ください)。\n辞書ファイルに新規にエントリーを追加しただけでは、設定は読み込まれていません。新規辞書を反映させるためには以下の手順が必要となります。\n更新した辞書ファイルの配布 複数ノードでElasticsearchのクラスターを構成している場合はすべてのノードに更新した辞書ファイルを配布する必要があります。 インデックスのクローズ(公式リファレンス) 設定ファイルを再読込させるために一度インデックスをクローズします。 クローズするので、書き込み、検索などの処理を停止する必要があります。もし停止していない場合はクライアント側ではインデックスがクローズされているという旨のエラーを受け取ります(400で、index_closed_exception)。 インデックスのオープン(公式リファレンス) 設定ファイルを読み込みます。これで、新規追加された単語が読み込まれます。 再インデックス _update_by_queryを利用することで、対象のインデックスのデータを再インデックスすることができます。条件無しでAPIを呼び出すとすべてのデータが再度登録されます。 _sourceがfalseの場合は_update_by_queryは利用できません。元データをもう一度外部からElasticsearchに対して登録する必要があります。 Kibanaでの手順をGistにしてあります。手順はこちらをご覧ください。\n辞書の更新方法(インデックス設定編) ファイルの場合とは少し手順が異なります。 インデックスの設定としてユーザー辞書を登録しているため、ファイルをElasticsearchのクラスターにあるノードに配布する必要がありません。 また、辞書の設定はインデックスの設定に指定してありますが、こちらは動的に設定変更できる項目ではないため、インデックスを先にクローズする必要があります。\nインデックスのクローズ(公式リファレンス) 辞書の設定を更新するにはインデックスをクローズする必要があります。辞書の設定は動的に更新できる項目にはなっていないためです。 オープンしているインデックスで更新しようとした場合はillegal_argument_exceptionでCan't update non dynamic settings...というメッセージが返ってきます。 辞書の更新(公式リファレンス:インデックス設定の更新) user_dictionary_rulesに単語と追加します。 インデックスのオープン(公式リファレンス) 設定ファイルを読み込みます。これで、新規追加された単語が読み込まれます。 再インデックス _update_by_queryを利用することで、対象のインデックスのデータを再インデックスすることができます。条件無しでAPIを呼び出すとすべてのデータが再度登録されます。 _sourceがfalseの場合は_update_by_queryは利用できません。元データをもう一度外部からElasticsearchに対して登録する必要があります。 Kibanaでの手順をGistにしてあります。手順はこちらをご覧ください。\n第3の方法(新規インデックス作成) ここまで、インデックスのクローズ、オープンで既存のインデックスに対して辞書を更新する方法について説明しました。 ただ、残念なことにAmazon Elasticsearch ServiceではElasticsearchが提供しているすべてのAPIが利用できるわけではありません(Amazon ESの利用可能なAPIの一覧はこちら)。 (_closeは駄目だけど_openは呼べるのかな???)\nということで、新規にインデックスを作成して、新しい辞書の設定を反映したインデックスを用意し、そこにデータをコピーもしくは登録するという方法になります(Amazon ESのカスタム辞書のドキュメントに手順がありますね)。\n手順としては以下のとおりです。\n辞書の更新(用意) 新しい単語などを登録した辞書を用意します。 ファイル、インデックス設定どちらでもOKです。 ファイルの場合は、既存のファイル名とは異なるファイル名にしたほうが混乱がなくなります。 新規インデックス作成 1.で作成した辞書を元に新規インデックスを作成します。 新規インデックスにデータコピー _reindex APIを利用するとデータコピーが簡単です。sourceとdestを指定するだけです。 _sourceがfalseの場合は_update_by_queryは利用できません。元データをもう一度外部からElasticsearchに対して登録する必要があります。 アプリケーション側で新規インデックスを利用するように変更 _aliasを使用しておくと切り替えが簡単です(公式リファレンスはこのあたり)。 考慮すべき点としては、サービスを提供しながら行う場合は、3.の_reindexを実行し始めたタイミング以降の登録・更新データの扱いについてでしょうか。\nまとめ 辞書の更新に関する大原則、制限事項、手順などについて説明しました。 辞書の変更は検索に大きく影響がでます。そのあたりをきちんと考慮しながら更新しましょう。 ユーザー辞書、カスタム辞書を扱う際の参考にしていただければと。 他にもユーザー辞書で気をつけないといけないこともありますが、今日はこのあたりで。\n","date":1587951855,"dir":"post/2020/","id":"be2c49ea5816e7daa6d3b3ff45353291","lang":"ja","lastmod":1587951855,"permalink":"https://blog.johtani.info/blog/2020/04/27/note-updating-dictionary/","publishdate":"2020-04-27T10:44:15+09:00","summary":"先日、Elasticsearchでのカスタム辞書の利用方法についてブログを書きました。 辞書の設定方法について記載しましたが、今回は辞書の更新","tags":["elasticsearch"],"title":"辞書の更新についての注意点"},{"contents":"Elasticsearchで日本語を扱うときに、カスタム辞書を使いたいという要望がよくあります。 AWSのElasticsearch Serviceでカスタム辞書ファイルを読み込める機能が発表されたようです。\n実は、Elasticsearchの7.4からファイルを使用しなくても日本語のTokenizerでカスタム辞書を利用することができるようになっています。\nカスタム辞書をインデックスの設定で指定 やり方はドキュメントに記載があります。\nトークナイザーの設定をインデックスの設定に記述しますが、このときに user_dictionary_rulesという設定を利用することでカスタム辞書を指定できます。\nPUT custom_dic_sample { \u0026#34;settings\u0026#34;: { \u0026#34;index\u0026#34;: { \u0026#34;analysis\u0026#34;: { \u0026#34;tokenizer\u0026#34;: { \u0026#34;kuromoji_user_dict\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;kuromoji_tokenizer\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;extended\u0026#34;, \u0026#34;user_dictionary_rules\u0026#34;: [ \u0026#34;グランベリーパーク,グランベリー パーク,グランベリー パーク,カスタム名詞\u0026#34;, \u0026#34;高輪ゲートウェイ,高輪 ゲートウェイ,タカナワ ゲートウェイ,カスタム名詞\u0026#34;] } }, \u0026#34;analyzer\u0026#34;: { \u0026#34;my_analyzer\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;custom\u0026#34;, \u0026#34;tokenizer\u0026#34;: \u0026#34;kuromoji_user_dict\u0026#34; } } } } } } 辞書の内部は\u0026quot;単語,出てきてほしい単語列(スペース区切り),読みの単語列(スペース区切り),品詞名\u0026quot;になります。配列で設定可能で、複数の単語を登録したい場合は、カンマ区切りで登録していきます(上記例では2つの単語を登録しています)。\n_analyzeを利用して設定の確認 実際に上記の設定がうまく動作するかは_analyzeのエンドポイントを利用します。\nGET custom_dic_sample/_analyze { \u0026#34;text\u0026#34;: \u0026#34;グランベリーパークがオープンしました。\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;my_analyzer\u0026#34; } 出力は以下のようになります。\n{ \u0026#34;tokens\u0026#34; : [ { \u0026#34;token\u0026#34; : \u0026#34;グランベリー\u0026#34;, \u0026#34;start_offset\u0026#34; : 0, \u0026#34;end_offset\u0026#34; : 6, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 0 }, { \u0026#34;token\u0026#34; : \u0026#34;パーク\u0026#34;, \u0026#34;start_offset\u0026#34; : 6, \u0026#34;end_offset\u0026#34; : 9, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 1 }, { \u0026#34;token\u0026#34; : \u0026#34;が\u0026#34;, \u0026#34;start_offset\u0026#34; : 9, \u0026#34;end_offset\u0026#34; : 10, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 2 }, { \u0026#34;token\u0026#34; : \u0026#34;オープン\u0026#34;, \u0026#34;start_offset\u0026#34; : 10, \u0026#34;end_offset\u0026#34; : 14, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 3 }, ...(省略) ] } ちなみに、デフォルトのkuromojiを利用した場合は、グランベリーパークが1単語として出力されます。\nGET _analyze { \u0026#34;text\u0026#34;: \u0026#34;グランベリーパークがオープンしました。\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;kuromoji\u0026#34; } ## レスポンス { \u0026#34;tokens\u0026#34; : [ { \u0026#34;token\u0026#34; : \u0026#34;グランベリーパーク\u0026#34;, \u0026#34;start_offset\u0026#34; : 0, \u0026#34;end_offset\u0026#34; : 9, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 0 }, { \u0026#34;token\u0026#34; : \u0026#34;オープン\u0026#34;, \u0026#34;start_offset\u0026#34; : 10, \u0026#34;end_offset\u0026#34; : 14, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 2 } ] } これで、カスタム辞書を使用することでグランベリーで検索された場合に、グランベリーパークもヒットするという仕組みです。\n_analyzeはexplainというパラメータも持っており、こちらを利用することで、単語の品詞情報なども取得できます。これを使うことで、実際に設定がきちんと動作しているかの確認に利用できます。\nGET custom_dic_sample/_analyze { \u0026#34;text\u0026#34;: \u0026#34;グランベリーパークがオープンしました。\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;my_analyzer\u0026#34;, \u0026#34;explain\u0026#34;: true } ## レスポンス(一部のみ) { \u0026#34;detail\u0026#34; : { \u0026#34;custom_analyzer\u0026#34; : true, \u0026#34;charfilters\u0026#34; : [ ], \u0026#34;tokenizer\u0026#34; : { \u0026#34;name\u0026#34; : \u0026#34;kuromoji_user_dict\u0026#34;, \u0026#34;tokens\u0026#34; : [ { \u0026#34;token\u0026#34; : \u0026#34;グランベリー\u0026#34;, \u0026#34;start_offset\u0026#34; : 0, \u0026#34;end_offset\u0026#34; : 6, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 0, \u0026#34;baseForm\u0026#34; : null, \u0026#34;bytes\u0026#34; : \u0026#34;[e3 82 b0 e3 83 a9 e3 83 b3 e3 83 99 e3 83 aa e3 83 bc]\u0026#34;, \u0026#34;inflectionForm\u0026#34; : null, \u0026#34;inflectionForm (en)\u0026#34; : null, \u0026#34;inflectionType\u0026#34; : null, \u0026#34;inflectionType (en)\u0026#34; : null, \u0026#34;partOfSpeech\u0026#34; : \u0026#34;カスタム名詞\u0026#34;, \u0026#34;partOfSpeech (en)\u0026#34; : null, \u0026#34;positionLength\u0026#34; : 1, \u0026#34;pronunciation\u0026#34; : null, \u0026#34;pronunciation (en)\u0026#34; : null, \u0026#34;reading\u0026#34; : \u0026#34;グランベリー\u0026#34;, \u0026#34;reading (en)\u0026#34; : \u0026#34;guramberi\u0026#34;, \u0026#34;termFrequency\u0026#34; : 1 }, { partOfSpeechにカスタム辞書で設定したカスタム名詞が出力されていますね。 _analyzeのAPIはこのように、アナライザーの挙動の確認に非常に便利なので是非活用してみてください。\nKibanaでこのAPIを使うためのプラグインも開発していますので、こちらも合わせて利用してみてください。\n注意点 ちなみに、user_dictionaryとuser_dictionary_rulesを両方指定した場合はエラーとなります。 ファイルをベースにしつつ、追加の設定をするという使い方はできないので、注意しましょう。\nインデックスの設定で書くことにより、バックアップ・リストアは楽になるかな。ただ、クラスターステートに取り込まれるから、あまりにも巨大なカスタム辞書だと心配かなぁ。ファイルの場合はクラスターステートには取り込まれないので、そこは圧迫しない。\n\u0026mdash; Jun Ohtani (@johtani) April 22, 2020 それ以外の注意点については、別途ブログを書きました。 「辞書の更新についての注意点」、こちらも合わせてご覧ください。\nまとめ カスタム辞書をファイルではなくインデックスの設定値として設定する方法を紹介しました。こちらは、Elasticsearch 7.4で導入された機能になります。7.4以降を利用している場合はこちらを利用することも検討してはいかがでしょうか? また、_analyze APIも便利なので合わせて活用してみてください。\n","date":1587519056,"dir":"post/2020/","id":"15357b6978e83daa2d97692c861dc177","lang":"ja","lastmod":1587519056,"permalink":"https://blog.johtani.info/blog/2020/04/22/custom-dictionary-after-7-4/","publishdate":"2020-04-22T10:30:56+09:00","summary":"Elasticsearchで日本語を扱うときに、カスタム辞書を使いたいという要望がよくあります。 AWSのElasticsearch Servi","tags":["elasticsearch"],"title":"Kuromojiのカスタム辞書をインデックスの設定で指定"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 第8章 7章はパッケージなので後回しにして、8章に入ります。 8章はコレクションです。\nベクタ型 ベクタは同じ型の値だけ保持可能。 ジェネリクスで型を指定可能 - Vec\u0026lt;i32\u0026gt;とか。 vec!マクロで初期値とか設定すると便利。 ベクタに値を追加するのはpush。もちろん値が変わるので元のベクタにはmutが必要 ベクタのスコープ(ライフサイクル)は要素に対する参照があるのとないので話が変わってくる メモリの確保などの影響で、ベクタ全体に対して借用の規則が矯正されると。 ベクタの値を読むのはいくつか方法あり getメソッドはOptionを返す \u0026amp;v[2]の添字記法の場合はパニックの可能性あり 走査(唐突に参照外しが出てきた) 単純に値を取り出す場合はfor - in \u0026amp;v Enumをベクタにいれることで、異なる型も保持可能(まぁ、Enumの型では固定されるけど)。 これだけのためにEnumを使うことってあるのかな? トレイとオブジェクトに関する文章はちょっとわかりにくい。。。 説明以外のメソッドなどについてはAPIドキュメント見ましょうと(リンクも張ってくれてると嬉しいなぁと思ったり。まぁ、バージョンとかの絡みがあるから難しいか)。\n文字列型 文字列はUTF-8でエンコードされた文字を扱うための型。\nstrは文字列データへの参照。\nString型は言語のコアではなく、標準ライブラリに入っている文字列型。\n他にもあるのか。。。OsStringとか。。。 文字リテラルはDisplayトレイトを実装していると。\n.to_string() = String::from\nStringはコレクションだから追加とかが可能なのか、なるほど。\npush_strとpush\n+演算子での参照。\n\u0026amp;Stringは\u0026amp;strに型強制(キャスト?)してくれる。してくれる場合としてくれない場合もあるのかな?s2の所有権は奪わない形で扱うのでs2はこのあとも使えていると。 ここでは、s1を変更したあとに所有権がs3に持っていかれてる? format!を使うとどの所有権も奪わないので、これを使うほうが考え方は簡単そう。ただし、効率がいいかはわからん。 添字記法でのアクセスをStringは許容していない\n文字の境界が必ずしも1バイトとは限らないから。 スライスも同様。 基本的には.chars()で文字としてアクセスするのが良い。\n逆にバイト表現を得る方法はどうするんだろう?\nNLP100本ノックではencode_utf8メソッド使ったけど。 ハッシュマップ いろんな呼び方あるよね。Rustではハッシュマップだよ。 ハッシュマップはuseしないと使えない キーは1つの型、値も1つの型 タプルのベクタからcollectで生成。なるほど。 タプルのベクタだと、タプルの中身は同じものであることが言える? -\u0026gt; 言える。エレメント数が異なるとコンパイルエラーになった 所有権周りの話。 これ、ベクタのときに話してほしい感じがした。 値を渡すか参照を渡すかによって話が変わってくる。詳しくは10章 このあたりが自分が混乱していた元だ。 entryとinsertの違い entryの戻り値はEntryというenumでor_insertというメソッドがありそれを使うと存在しない場合だけinsertが呼ばれる。 これ便利だ。毎回existあたりで存在チェックしてた気がする。 or_insertは可変参照\u0026amp;mut Vを返す。 これをlet countで束縛するときに、中身が可変かどうかをcountには指定しないのか。。。 まとめ 一応、大学などで習ってた(はず)ですが、 スタックとヒープを意識して考えないといけないなぁというのを何度か意識させられた感じです。\nあと、これはRustに限らずですが、それぞれがどんな関数を持っているか、どんなメソッドを持っているか、どんなマクロが存在するかなどを探すときにみんなどうしてるんだろう? 人に教えてもらっているのか、APIリファレンスを探すのか、そういったところをみんながどういう感じにプログラミング言語を勉強しているか、業務で書いているのかと言うのが気になりました。\n","date":1587028650,"dir":"post/2020/","id":"f488aa62d39194824861a134567cadb8","lang":"ja","lastmod":1587028650,"permalink":"https://blog.johtani.info/blog/2020/04/16/chap8-rust-the-book/","publishdate":"2020-04-16T18:17:30+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 第8章 7章はパ","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第8章"},{"contents":"Rustで言語処理100本ノックのリファクタリングの続き。\n前回はこちら。\nコードも載せたほうが見やすいかなぁ?\n03. 円周率 2年前はこちら。 どちらかというとJavaっぽい書き方かな? 入れ物を用意して、入力を整形して、それからループを回す感じで書いてました。\n今回は1行で収めてみました。 Rustっぽく、returnを省略してみました。 あとは、Iteratorを組み合わせる感じでやってます。 アルファベットの文字数ということで、is_alphabetic()メソッドでfilterしてます。\n04. 元素記号 2年前はこちら。 エラー処理が多いのと、文字の扱いがちょっと\nここまで同様に極力イテレータを利用するという方針でリファクタリングしました。 あとは、エラー処理を除去してます。 正常系だけのテストなのでスッキリさせました。\nこういった、ストリーム系?の書き方の場合にエラー処理をどう入れるかってところはちょっと悩みどころになるんじゃないかなぁ?と思いつつ、イレギュラーなものは後回しで(あとにやるのかなぁ?)\n05. n-gram 2年前はこちら。 これまでと同じく、入れ物を作ってから処理をしてます。\n同じく、極力イテレータを利用する形で実装しました。 いくつか型の変換が必要なので、.map()を呼び出して詰め替えたりしています。\n06. 集合 2年前はこちら。 独自に実装しています。\nせっかく05で文字n-gramの配列を返す処理を実装しているので、 そちらを呼び出して、Setに入れるという処理に書き換えました。 その後の集合に対する処理については特にリファクタリングしてないです。\nまとめ 2年前にやってたところまでは追いつきました。 07は特にリファクタリングする必要がないので、次は08からの予定です。\nリファクタリングしているときになるのは、速度とかでしょうか。 実装の違いでなにか差が出るのかどうかはちょっと気になるところですが、 今回の目的ではないので、目をつぶって進める予定です。\n","date":1586423695,"dir":"post/2020/","id":"9a687babb0f44db51dc389b75bdaa19d","lang":"ja","lastmod":1586423695,"permalink":"https://blog.johtani.info/blog/2020/04/09/reboot-nlp100-ch01-03to05/","publishdate":"2020-04-09T18:14:55+09:00","summary":"Rustで言語処理100本ノックのリファクタリングの続き。 前回はこちら。 コードも載せたほうが見やすいかなぁ? 03. 円周率 2年前はこちら。 どちらか","tags":["Rust","nlp100"],"title":"第1章の03から06まで(言語処理100本ノック2020)"},{"contents":"今回もツイートから。\n言語処理100本ノックの2020年版を公開しました。最近の自然言語処理の研究動向を反映し、深層ニューラルネットワークに関する問題を追加しました。留学生も一緒に取り組めるように多言語化を進め、その第1弾として英訳を部分公開しています(40番以降は順次公開予定)。 https://t.co/52h362PIQQ\n\u0026mdash; Naoaki Okazaki (@chokkanorg) April 6, 2020 言語処理100本ノックが2020年版になったそうです。 そうです、2年前に初めて、準備運動で止まっていたんです!(衝撃的な続かなさ。。。)\nということで、Rust the bookも読んでいることだし、過去のプログラムをチェックしつつ再開しようかなと。 ということで、いくつかリファクタリングしてみました。\nソースはリポジトリを御覧ください。\n00. 文字列の逆順 2年前の実装では、chars()メソッドで取り出したあとに、collect()でVecにしていたのですが、RustのIteratorトレイトにrev()という便利なメソッドが存在していました。\nということで、これを取り出すと、最初の文字列の逆順で文字を取り出すIteratorが取得できます。 あとは、Stringが実装してくれているfrom_iterに渡せば文字列が出来上がります。\n01. 「パタトクカシーー」 ストリーム処理っぽい書き方に変更しました。 2年前はIteratorを取り出して、詰替していましたが、 enumerate()で添字と文字のタプルのイテレータに変換し、 filterで添字が偶数のときだけフィルタリングして、 mapで対象の文字をまとめたイテレータにします。 で、最後はそれを元に文字列を生成することにしました。 iterを使わないでそのままString::from_iterの引数に渡すことも可能ですね。\n02. 「パトカー」+「タクシー」=「パタトクカシーー」 2年前は2つのIteratorをloopで回して頑張って結合してました。 ではなく、zip()を使って、2つのイテレータを組み合わせる方法に替えてみました。 このとき、2つの文字列が違う文字数の場合の処理として、長い方から取り出した文字をあとに結合する処理を追加で記述しました。 ちょっとスマートな感じになりましたかね?\nzipしたあとに出てきたタプルの文字列を結合するのにformat!マクロを使いましたが、他にいい方法有るかなぁ?\nまとめ とりあえず最初の3つをリファクタリングしてみました。 残りもやりつつ、準備運動以降もがんばるぞと。\n","date":1586338425,"dir":"post/2020/","id":"dc9580308938069159c5afc55b2f3b96","lang":"ja","lastmod":1586338425,"permalink":"https://blog.johtani.info/blog/2020/04/08/reboot-nlp10-with-rust/","publishdate":"2020-04-08T18:33:45+09:00","summary":"今回もツイートから。 言語処理100本ノックの2020年版を公開しました。最近の自然言語処理の研究動向を反映し、深層ニューラルネットワークに関","tags":["Rust","nlp100"],"title":"言語処理100本ノック、再び"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 第6章 Enumです。match式に大活躍\nEnumを定義する 列挙型は取りうる値をすべて列挙できる。これが名前の由来 列挙型と列挙子 2連コロン(::)で列挙子を指定可能 列挙子にデータ(構造体も)が格納可能。 標準ライブラリに実装例あり。 疑問:Write(String)とかはタプルの表現になるのかな? と思ったが、タプルでは1つだけの変数を持つものは定義(正確には定義できるが、内部で普通の変数にもどされてるっぽい)できなかった。 メソッド定義も可能 関連関数もできる? -\u0026gt; できる Optionの紹介 Rustにnullはない。代わりにOptionがある Noneを指定する場合に型が必要。Someの場合はすでに値が入るから推測可能なため。 match制御フロー演算子 アーム -\u0026gt; matchしたときの処理のこと 短い場合は波括弧は不要 returnなしでmatchが書いてあるだけだと、慣れない場合に値を返していることに気づかないかも(実際気づけてないかも) Enumが値を持っているときに、値の束縛がmatch式で可能 すべての列挙子を網羅していないことをコンパイラが検知してくれるのはすごく助かる。 ただし、_を利用していなければだけど if letで簡潔な制御フロー enumで1つのパターンのときに処理をしたい場合に使えるmatchの糖衣構文 elseもかけるよ。 まとめ enumに慣れていないので、値や構造体を持つenumを利用するという想像ができないことがありそうだなぁと読みながら思いました。 それになれると、色々とプログラムがシンプルに書ける部分が多くなりそうかな。\n","date":1586255231,"dir":"post/2020/","id":"4fbdc9c57a37781dc5dd86f470c61d04","lang":"ja","lastmod":1586255231,"permalink":"https://blog.johtani.info/blog/2020/04/07/chap6-rust-the-book/","publishdate":"2020-04-07T19:27:11+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 第6章 Enumです。matc","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第6章"},{"contents":"Kuromoji-CLIの使い方などについては過去のブログを御覧ください。\nKuromojiのCLIコマンドとpicocliとGraalVM GitHubリポジトリ Issueだけ上げていたJSON出力対応をしました。 また、ラティス(後述)の出力対応もしました。\nJSON出力 LinderaがJSON出力に対応してるのでそれを真似しました。 -o jsonで指定していただくと、次のようなJSONが出力されます。\n% echo \u0026#34;春眠暁を覚えず\u0026#34; | build/graal/kuromoji -o json [ { \u0026#34;text\u0026#34;: \u0026#34;春眠\u0026#34;, \u0026#34;detail\u0026#34;: [ \u0026#34;名詞\u0026#34;, \u0026#34;一般\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;春眠\u0026#34;, \u0026#34;シュンミン\u0026#34;, \u0026#34;シュンミン\u0026#34; ] }, { \u0026#34;text\u0026#34;: \u0026#34;暁\u0026#34;, \u0026#34;detail\u0026#34;: [ \u0026#34;名詞\u0026#34;, \u0026#34;一般\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;暁\u0026#34;, \u0026#34;アカツキ\u0026#34;, \u0026#34;アカツキ\u0026#34; ] }, { \u0026#34;text\u0026#34;: \u0026#34;を\u0026#34;, \u0026#34;detail\u0026#34;: [ \u0026#34;助詞\u0026#34;, \u0026#34;格助詞\u0026#34;, \u0026#34;一般\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;を\u0026#34;, \u0026#34;ヲ\u0026#34;, \u0026#34;ヲ\u0026#34; ] }, { \u0026#34;text\u0026#34;: \u0026#34;覚え\u0026#34;, \u0026#34;detail\u0026#34;: [ \u0026#34;動詞\u0026#34;, \u0026#34;自立\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;一段\u0026#34;, \u0026#34;未然形\u0026#34;, \u0026#34;覚える\u0026#34;, \u0026#34;オボエ\u0026#34;, \u0026#34;オボエ\u0026#34; ] }, { \u0026#34;text\u0026#34;: \u0026#34;ず\u0026#34;, \u0026#34;detail\u0026#34;: [ \u0026#34;助動詞\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;特殊・ヌ\u0026#34;, \u0026#34;連用ニ接続\u0026#34;, \u0026#34;ぬ\u0026#34;, \u0026#34;ズ\u0026#34;, \u0026#34;ズ\u0026#34; ] } ] Viterbiラティス出力 Kuromojiが内部でトークンをどのように切り出すかを計算するためのViterbiのラティスです。これをGraphvizというツールのDOTフォーマットのファイルとして出力できるメソッドがデバッグ用ですが、Kuromojiに用意されています。 こちらを呼び出して出力するオプション-v(もしくは--viterbi)を追加しました。 注意点として、このオプションを指定すると、DOTファイルが標準出力に出力され、トークンの結果は標準エラーに出力されます。\necho \u0026#34;春眠暁を覚えず\u0026#34; | build/graal/kuromoji -v \u0026gt; viterbi.dot .dotファイル自体は画像ではないので、Graphvizのdotコマンドにて画像ファイルに変換する必要があります。\ndot -Tpng viterbi.dot -oviterbi.png これで、PNGファイルが出来上がります。出来上がったファイルはこんな感じです。\n画像を見ていただくと、緑色のパスがあるのがわかります。 こちらが、Kuromojiが実際に採用した形態素のリストです。それ以外のパスは不採用だったパスとなります。\nちなみに、macOSで1行で画像表示まで行うにはこんな感じで実行します。 openコマンドでpreviewアプリを指定することで画像が表示できます。 Windowsは。。。わかりません、すみません。\n% echo \u0026#34;春眠暁を覚えず\u0026#34; | build/graal/kuromoji -v -o json | dot -Tpng | open -f -a preview.app まとめ これ以前に複数辞書対応などもしていました。 今回は2つの出力形式を追加してみました。 特にViterbiラティス出力については、内部的にどのようなコスト計算で最終的な結果が出てきているかという理解に役立ちます。想定していない切れ方の場合は、そもそも想定している形態素になっていないか、コスト計算で不採用だったかなどを確認できますので、使ってみると面白いかもです。\n","date":1586143600,"dir":"post/2020/","id":"6fbf7c3d0f4f89e415e89cec28811a94","lang":"ja","lastmod":1586143600,"permalink":"https://blog.johtani.info/blog/2020/04/06/update-kuromoji-cli/","publishdate":"2020-04-06T12:26:40+09:00","summary":"Kuromoji-CLIの使い方などについては過去のブログを御覧ください。 KuromojiのCLIコマンドとpicocliとGraalVM G","tags":["misc"],"title":"KuromojiのCLIコマンドにJSON出力とラティス出力を追加"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた Rust the book - 第4章 第5章 構造体です。勝手知ったるなんとやら?オブジェクト指向的な部分は問題ないかなぁと。\n定義とインスタンス化 structで定義 インスタンスの生成は引数は順不同でOK 構造体のインスタンスを可変にするとフィールドの値も変更可能 特定のフィールドのみ可変にすることは不可能 インスタンス化する関数の最後でreturnなしでインスタンスの返却を暗黙にできる(return書いてほしいな。。。) インスタンス化時にフィールド初期化省略記法が可能(これはちょっと便利?) 構造体更新記法..user1のように、明示的に設定されていない他のフィールドをコピーしてくれる機能あり タプル構造体 タプル構造体!? struct Color(i32, i32, i32); いつ使うんだろう? ユニット様構造体 ユニット様構造体 = フィールドのない構造体。トレイトを実装したいけどインスタンスで持つ値はない場合に利用 ライフタイム 構造体が参照を持つときにライフタイムという話が出てくる。なるほど。 ライフタイム指定子が必要になる -\u0026gt; 10章での話 プログラム例 タプルを引数かぁ。タプルは慣れないので構造体作りそう Debugトレイトと{:?}という書き方 derive(Debug)でデバッグ用のトレイトを自動で実装=継承してくれる {:#?}だとpretty printになる(改行とか入る) この辺の便利なトレイとは付録Cにあるらしい。この辺はやりながら覚えるしかないか。\nメソッド記法 最初の引数は必ずself implは構造体とは別の場所に書く = Javaのクラスとは違う struct Rectangle { width: u32, height: u32, } impl Rectangle { fn area(\u0026amp;self) -\u0026gt; u32 { self.width * self.height } } 参照じゃないselfも使えるらしい。どういうときに使うんだろう? 関連関数 selfなしの関数をimplにかける。Javaのスタティックメソッドみたいな感じ その他 implブロックがあちこちにかける。これはつらいな。。。 2つにわかれたimplブロックに同じメソッドを書いてみたら、CLionのプラグインではエラーを検知してもらえなかった。 cargo buildではきちんとエラーが表示された。 複数のimplブロックが有用になるケースは第10章で見ますが、そこではジェネリック型と、トレイトについて議論します。\n人の構造体に自分のトレイトを適用したりもできる。 実験 スコープとかどうなりそう?って実験もしてみた。\nfn main() { trait Hoge { fn trim(\u0026amp;self); } impl Hoge for String { fn trim(\u0026amp;self) { println!(\u0026#34;hogehoge {}\u0026#34;, \u0026amp;self); } } let c = String::from(\u0026#34;hoge\u0026#34;); c.trim(); println!(\u0026#34;{}\u0026#34;, fuga(\u0026amp;c)); } fn fuga(d: \u0026amp;String) -\u0026gt; \u0026amp;str { d.trim() } 出力はこんな感じ\nhogehoge hoge hoge まとめ 気になったのは以下の点。そのうち分かるようになってくるのかな。\n構造体更新記法はどういったときに使うのを想定して作ったんだろう?とか 可変長引数はマクロじゃないとだめ ","date":1585807758,"dir":"post/2020/","id":"8d9c3760395e8e0eb40e335b22750b68","lang":"ja","lastmod":1585807758,"permalink":"https://blog.johtani.info/blog/2020/04/02/chap5-rust-the-book/","publishdate":"2020-04-02T15:09:18+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた Rust the book - 第4章 第5章 構造体です。勝手知ったるなんとやら?","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第5章"},{"contents":"すもけさんが在宅勤務環境をブログに書いてておもしろそうだな(あと、アフィリンク貼れるな)と思ったので自分の環境も書いてみようかなと。\n私自身は昨今の新型コロナウイルスの影響というのではなく、もう10年以上自宅でも作業ができる環境を整えています。 前前職の頃から家でも仕事をすることがよくあったので。今は、お客さんに恵まれていてリモートができる形で働かせていただいてます。\n机周りはこんな感じです。机はこれも15年以上前から使用しているエレクターの机です。椅子も15年以上前から使っているアーロンチェア(購入時は高いと思ったけど、これだけ使えているので大満足)です。\nメインのPCはMac Book Pro16インチを使っています。それとは別にMac miniがMac bookの後ろに隠れています。こっちはブラウジングや音楽を聞いたりするために使っています。\nまずはディスプレイ周りから。\nディスプレイ周り ディスプレイ Acerの31インチディスプレイです。昨年の夏に購入しました。28インチの4Kディスプレイを探していたのですが、セールか何かで2-3000円の違いでこのサイズが買えたので、このサイズになっちゃいました。Mac Book ProはDisplay port-USB-Cケーブルで接続し、PS4をHDMIで接続しています。 【Amazon.co.jp 限定】Acer モニター ディスプレイ ET322QKwmiipx 31.5インチ マイクの左側に写っているのはAppleのサンダーボルトディスプレイです。縦にしてブラウザやミュージックプレイヤーなどで音楽かけながら仕事をしています。 サブディスプレイって感じです。 Mac Book ProとMac miniの両方を操作するのですが、できれば同じキーボード+トラックパッドがいいなということで、Synergyというソフトを使って、Mac Book Proのキーボードとマウスでネットワーク越しにMac miniを操作しています。ただ、マシンの再起動後などにこのソフトが起動していない場合もあるので、Mac Book Proの右側にMac miniのためのトラックパッドがおいてあります。\nディスプレイアーム ディスプレイはそれぞれディスプレイアームを使っています。写真のようにMac Book Proを下に、外部ディスプレイを上にという上下で作業をしています。 16インチの画面だと普通のディスプレイの足だとメインディスプレイにかぶってしまうので、アームに切り替えました。 最初はグリーンハウスの激安を使っていたのですが、31インチのディスプレイだとアームの高さが足りなかったので、2つ目のガススプリング式のアームを追加で購入しました。ガススプリング式なのに5千円しないので、かなりお得感があります。ただ、ディスプレイは基本的に動かさないので、どちらかというとディスプレイの足の部分を効率良く使うことが目的です。\nAmazon | グリーンハウス 液晶ディスプレイアーム 4軸 クランプ式 Amazon | HUANUO PC モニター アーム 液晶ディスプレイ アーム ガススプリング式 サウンド関連 スピーカー 基本、音楽を聞きながら作業をするので、小型だけどしっかりと音がでるスピーカーを買いました。スタイルもいいし気に入ってます。 入力が2系統あるので、31インチディスプレイのヘッドフォン出力とMac miniのからの出力の2つをつないでいます。 仕事中はMac miniで音楽流しつつ、テレカンやゲームのときはメインディスプレイからの音が出る形です。 Amazon | ヤマハ パワードスピーカー NX-50 マイク 前職がDeveloper Advocateということで、インタビューなどに行くこともあるかも?ということで小さめのも運びができるコンデンサマイクを購入してました。結局それほど持ち運びはしてないのですが、値段の割には音がいいんじゃないかな?一応、無指向と単一指向の2種類を切り替えることが可能です。\nAmazon | SAMSON マイク ポータブル USB コンデンサ Go Mic | コンデンサ | 楽器 マイクスタンド マイクはあったのですが、クリップ式でした。PCのディスプレイにクリップしていると、打鍵音を拾ってしまうので、マイクスタンドを最近導入しました。やすかったです。 前まではヘッドフォンのケーブルに付いているマイクで喋っていたのですが、服によってはマイクに擦れてしまい、ノイズが載っていました。 マイクスタンド+スピーカーでもスピーカーの音をマイクが拾わないので、最近はヘッドフォンを使用しないで気楽に話ができるようになっています。 Amazon | Luling Arts マイクスタンド アーム その他 モニタスタンド Mac Book Proの後ろで見えにくいですが、Mac miniが下に入っていて、上にMac mini用のキーボード、スピーカー、Qiの充電パッドが載せてあります。 Mac miniのキーボードをじゃまにならないように置きたいという目的で購入しました。3次元で空間が利用できるので結構重宝してます。 Amazon | サンワサプライ 机上液晶モニタスタンド(D200・黒) MR-LC303BK 充電関連 スマホ充電用にスピーカーの横においてあります。ただ、スイートスポットを探すのがちょっと大変で、時々充電できてないことがあったりします。。。 Amazon | DesertWest Qi 急速充電ワイヤレス充電器 【Qi認証済み/PSEマーク付き】15W USBでの様々な充電用にはMercariさんのカンファレンスでいただいたAnkerの充電器をおいてあります。Mi Band 4、キーボードなどの充電向けです。 Amazon | Anker PowerPort 6(60W 6ポート USB急速充電器) まとめ 簡単ですが作業環境でした。だいたい満足しています。もうちょっと改善したいなと思っているのは次の点です。\nUSB-Cドック?ハブ?みたいなものがほしい 充電ケーブル、マイク、ディスプレイケーブル、有線LANの4つのケーブルがMac Book Proに刺さっており、ポートが全滅です。出先から帰ったときにつなぐのも少し面倒なので、1つか2つのポートでまとめられるといいなぁと思っています。が、ドック系はいい値段するのでまだ置き換わっていない感じです。 スタンディングデスクが気になる 自宅でずっと座っているのはやはり気になるもので。スタンディングデスクにして時々たって作業したいなぁと思うことがあります。ただ、使ったことがないので、どれがいいのかわからず手を出せない状況です。 ウェブカメラいる? Mac Book Proのカメラでオンラインミーティングなどしています。気にするほどのことではないとは思いますが、メインディスプレイを見ながらしゃべると下からカメラで撮影されている形になります。。。 今のところはこんな形です。なにかの参考になればと。 あと、なにかおすすめのもの(特にスタンディングデスク)があれば教えて下さい!\n","date":1585217511,"dir":"post/2020/","id":"3f431bf71ee866f626daf42bc915fa3f","lang":"ja","lastmod":1585217511,"permalink":"https://blog.johtani.info/blog/2020/03/26/working-facility/","publishdate":"2020-03-26T19:11:51+09:00","summary":"すもけさんが在宅勤務環境をブログに書いてておもしろそうだな(あと、アフィリンク貼れるな)と思ったので自分の環境も書いてみようかなと。 私自身は","tags":["misc"],"title":"自宅の作業環境(2020)"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた 第4章 第4章です。たぶん、これがいちばん大事な概念だと思います、Rustの。 そして、つまみ食いしながらRust書いてましたが、ここがきちんと理解できないまま書いてたってのもあります。。。\n所有権とは? drop関数ってのがあって、明示的に呼ぶことも可能。次のような感じで。2つ目のprintln!はエラーになる。sがもう無いのに借用しようとしてるから。 fn main() { let mut s = String::from(\u0026#34;hello\u0026#34;); s.push_str(\u0026#34;, world!\u0026#34;); println!(\u0026#34;{}\u0026#34;, s); drop(s); println!(\u0026#34;{}\u0026#34;, s); } ムーブ - shallow copyではない。以下の2行目がムーブ。 let s1 = String::from(\u0026#34;hello\u0026#34;); let s2 = s1; println!(\u0026#34;{}, world!\u0026#34;, s1); スタックとヒープの話が絡んでくる。あんまり意識すること無いよなぁ。 スタック = 固定長のデータを入れる場所。ポインタ、数値など ヒープ = 可変長のデータが入る場所。可変の文字列とか。\nクローン - ヒープのデータをコピーすること。 コピー - スタックに収まるデータの場合はクローンが必要なくコピーで事足りる。 CopyトレイととDropトレイとは同居できない。 タプルのコピーはややこしそう 所有権と関数でまた、スタックに入れられるような変数と可変のオブジェクトの違いが出てくる。 takes_ownership(s: String)が参照を受け取れば問題なく、このあとも使える。 戻り値でもムーブが発生 参照と借用 借用 - 関数の引数に参照を取ること 可変な参照\u0026amp;mutは1つ(不変な参照も含めて1つ)しか許さない データの競合を防ぐため。 不変な参照を複数用いるのはOK 実際に変更が実行されるタイミングでエラーと判定される場合もある。 let mut s = String::from(\u0026#34;hello\u0026#34;); { let r1 = \u0026amp;mut s; } // r1はここでスコープを抜けるので、問題なく新しい参照を作ることができる let r2 = \u0026amp;mut s; ダングリング参照はテスト書くときとかにやってるかも。。。 fn dangle() -\u0026gt; \u0026amp;String { // dangleはStringへの参照を返す let s = String::from(\u0026#34;hello\u0026#34;); // sは新しいString \u0026amp;s // String sへの参照を返す } // ここで、sはスコープを抜け、ドロップされる。そのメモリは消される。 // 危険だ スライス型 部分的な参照。開始位置+長さで構成されているっぽい \u0026amp;strの説明がよくわからなかった。 引数としての文字列スライスのテクニックは色々と使いまわせそう。\nまとめ 所有権、これまで特に難しいと思ってたのは、固定長の変数と、可変長の変数の違いを意識してなかったのが原因っぽい。 まぁ、Vecとかがどうなるのかとか、他にもいくつか気になるところはあるので、もうちょっとやらないといけないなと思いました。\n","date":1585210331,"dir":"post/2020/","id":"7fded0345c258eea966c0b5ee1b7c7aa","lang":"ja","lastmod":1585210331,"permalink":"https://blog.johtani.info/blog/2020/03/26/chap4-rust-the-book/","publishdate":"2020-03-26T17:12:11+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた 第4章 第4章です。たぶん、これがいちばん大事な概念だと思","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第4章"},{"contents":"先日、Visual Studio Codeのプラグインを作ってみた(Azure Search Analyze Client)というブログを書きました。 このプラグインを作ってたタイミングで、Elasticの河村さん経由で、Microsoft Open Tech Night #9 w/ ElasticでなにかLTしませんか?という打診がありました。\n仕組み的には似たようなものだし、Elasticsearch用の拡張機能も作れるし、発表のネタにもなるし一石二鳥では?ということで、LTを快諾し、昨日発表してきました。\n資料とか 発表資料やGitHubのリポジトリなどは、以下のとおりです。\n発表資料 : Analyze APIのVS Codeプラグインを作ってみた GitHub Repository : https://github.com/johtani/vs-code-es-analyze-client Visual Studio Code Marketplaceページ 機能 まだ、必要最低限の機能を実装した感じです。\nAnalyze APIのパラメータ入力用のエディタ起動(Elasticsearch Analyze Client: Create Elasticsearch Analyze Request) Esにリクエストを送信して結果の表示 インストールからリクエスト送信して結果が出てくるまでのデモです。\n1点LTのデモのときに話すのを忘れていましたが、.esanalyzeという拡張子のファイルであれば、このプラグインが入力値を見つけ出して、「Analyze text with analyzers」というコマンド送信用のリンクをエディタ画面に表示する機能があります。 ですので、パラメータ入力用のエディタを起動し、値を設定したあとにファイルをhoge.esanalyzeというような名前で保存してもらえれば、後日そのファイルを開くことでリクエストが再送できます。\nAzure Search版との機能の違い 先日のAzure Search向けのクライアントとの違いがいくつかあります。 ElasticsearchのAnalyze APIの方が多機能であるため、プラグインとしても違いがあったほうがいいかなと。\n入力がJSON形式 結果画面に詳細表示切り替えボタンを追加 現時点では対応していませんが、Analyze APIはカスタムのtokenizer、filter、char_filterの設定を入力として受け付けることが可能です。そのときに指定するのはJSON形式でtokenizerなどの設定を記述します。 今後、これらの対応をすることを考えると、入力全体をJSON形式で読み込めるほうがわかりやすいかなということで、入力はJSON形式で入力してもらうことを想定しました。\n結果画面に詳細表示切り替えボタンを追加したのは、2つの理由があります。1つはAzure SearchのAnalyze APIよりもTokenの情報としていくつか他の情報も存在するためです。複数のAnalyzerとの比較をする場合は、単語列だけを比較したいですが、Analyzer個別の詳細情報を見たい場合もあるので、切り替えができたほうがよいかなと。 2つ目の理由はまだ実装していませんが、explainパラメータの出力への対応のためです。 explainパラメータを指定すると、カスタムAnalyzerの場合に、Analyzerの設定にあるchar_filter、tokenizer、token_filterのそれぞれのステップでの単語列の出力が結果として返ってきます。この結果には標準の出力よりもさらに多くのtokenの情報(例えば、kuromojiだと品詞情報、読み、原型など)が追加されてきます。これらの表示を切り替えることができたほうがよいかと。\nこれらは、実はKibanaのプラグインとしてすでに実装済みになっています。 同等の機能は実装できるかなという目論見もあり、そちらに合わせた感じにしてあります。\n今後の対応 現時点では、Analyzer名の指定のみが可能となっています。Kibanaのプラグインと同程度の機能はGitHubのIssueとして登録してみました。\nexplainパラメータ対応 fieldパラメータ対応 custom analyzer対応 その他に、インデックス名やアナライザ名の自動補完みたいな機能があると便利かも?と妄想していたりします(実装が大変かもですが。。。)。Kibanaのプラグインの場合は、Mappingやインデックス名を調べるときに、KibanaのConsoleからチェックすればよかったのですが、このプラグイン単体だとそのあたりの情報の取得に他のツール(Kibanaだったり、REST API Clientだったり)を使わないといけないという問題点はあるかなぁと。\nあとは、結果画面がこのままで本当に見やすいかどうか?なども気になってはいます。\nまとめ まだまだ、作ってみたというレベルのプラグインです。 どのくらいの人に使ってもらえるかもわかりませんが、こんな機能あるといい?など要望があればリクエストいただければと。 Twitterで聞いていただいてもいいですし、GitHubのIssueとして登録していただいても構いません。 そもそもいらないなぁなんて意見でももちろん大歓迎です。フィードバックお待ちしてます!\n","date":1585102205,"dir":"post/2020/","id":"a7f0e85fcad4f5bc5ae5c18c10de4f9e","lang":"ja","lastmod":1585102205,"permalink":"https://blog.johtani.info/blog/2020/03/25/vsc-es-analzye-plugin/","publishdate":"2020-03-25T11:10:05+09:00","summary":"先日、Visual Studio Codeのプラグインを作ってみた(Azure Search Analyze Client)というブログを書きました。 このプラグインを作ってたタイミン","tags":["elasticsearch","visual studio code"],"title":"ElasticsearchのAnalyze APIのVisual Studio Codeのクライアントプラグイン"},{"contents":"自転車本を読み始めましたが、その前にRust the bookを読んだほうが良いかも?と知り合いと話をしていてなったので、先にRust the bookを読み始めてます。 コツコツ読むってのが苦手なので、知り合いと小規模オンライン読書会しながら読むことになりました(基本的になにか書きながら、使い方を調べるので、存在そのものを知らない記述や使用法などがあったりする)。\n日本語版Rust the book Rust the book 基本は日本語版を読んでいます。まずは1章から3章あたり。\n気になった点などを。自分用のメモなので、読みやすさとかは考えてないです(あとで自分が死ぬパターン?)。\n1章 rustfmt便利。\nCLionのRustプラグインでは、保存時にrustfmtするというオプションがある。デフォルトはオフ。\u0026ldquo;Run rustfmt on Save\u0026rdquo; cargoの--binオプション。意識してつけたことなかった=デフォルトだった。\nライブラリにするときは--lib 2章 「変数を値に束縛」という言い回しにまだ慣れない。 「代入」という言い方に慣れているから? ただ、エラーにはassignってあるな。\u0026ldquo;error[E0384]: cannot assign twice to immutable variable x\u0026rdquo; preludeというのがデフォルトで読み込まれる型が存在する場所。 .expect()により、Resultが評価済みになる マクロがまだ慣れない extern crate rand;が最新版だと要らなくなっている。 rand::Rngはgen_rangeのためにuseしている。CLionだとかってにuseを推測して追加してくれた。 matchはswitch文みたいな感じ。けど、defaultが必ず実行されるって感じではないな。 ただし、全て網羅しないと怒られるのが便利。 アームという呼び方が新鮮 単一の式のときは{}が省略できる ブロック{}のときは、終わりにカンマを入力するとrustfmtが除去する(最後の条件かどうかは関係ない)。 シャドーイングは面白い。 よく、hoge_strやhoge_intのような変数を書くので、ありがたい。 ただし、コードを読むときに少し混乱しそう? let ... matchで変数への束縛でmatchが使えるのは便利(これまで知らなかったので、変数宣言して条件つけて束縛する処理書いてた)。 シャドーイング? fn main() { let x = 5; let x = x + 1; let x = x * 2; println!(\u0026#34;The value of x is: {}\u0026#34;, x); } とか\nlet spaces = \u0026#34; \u0026#34;; let spaces = spaces.len(); みたいに、同一変数名を使い回せること。再代入ではない\n3章 constは型注釈が必須 100_000のような記述が便利(Javaもできるって言われてびっくりしたw) タプルの中身を一部だけ書き換え可能。(mutを指定すれば) tup.0 = 20;のような感じで。 配列は固定長でかつ、同一の型のものだけが入る 文末にセミコロンがない場合に四季になるというのはちょっと射にくいので辛いのでは。。。 自分は明示的にreturnを書きたくなる。が、returnだと動かない場合もある。。。 let ... ifのような記述もできる。 (1..4)はRange型 おまけ フィボナッチ数列計算してみろというのがまとめにあったので。こんな感じでいいのかな?\nfn calc_fibonacci(n: usize) -\u0026gt; usize { if n == 0 { return 0; } else if n==1 { return 1; } else { return calc_fibonacci(n-1) + calc_fibonacci(n-2); } } その他 知り合いと読みすすめると、人が不思議に思ったところが、自分が理解が曖昧だったことなどに気づけて便利です。\n","date":1584928642,"dir":"post/2020/","id":"48b5ab9805919736382ffea5a9554c02","lang":"ja","lastmod":1584928642,"permalink":"https://blog.johtani.info/blog/2020/03/23/start-reading-rust-the-book/","publishdate":"2020-03-23T10:57:22+09:00","summary":"自転車本を読み始めましたが、その前にRust the bookを読んだほうが良いかも?と知り合いと話をしていてなったので、先にRust the bookを読","tags":["rust","読書","rust-the-book"],"title":"Rust the Bookを読み始めた"},{"contents":"動機 Azure Cognitive Searchを検索エンジンに使っているお客さんを手伝っています。 そこで、検索の基本的な話をさせていただきました(もともとJJUGナイトセミナーでしゃべる予定だったスライドがベース)。\nで、Elasticsearchなどの転置インデックスを利用している検索エンジンで検索の基本的な動作がどうなっているかを理解するのに、 個人的には一番重要だと思っているのがAnalysis(Analyze)の機能です。 転置インデックスの単語の切り出し方がどうなっているかによって、望んだ単語でうまく検索できているかいないかなどがわかります。\nAzure Cognitive SearchもAnalyze TextというAPIを提供してくれています(内部的にはElasticsearchだし)。 APIはあるのですが、返ってくる結果はJSONです。また、他のAnalyzerの設定との違いなどをみたくなったりもします。 やはり、普段使っているツールなどで簡単にどういう単語が出てくるかがわかるとうれしんじゃないかなぁ?と。\nということで、最初はPythonでちょっとAPI呼び出して、カンマ区切りで出力するものを作ってみたのですが、GUIとかあると便利かなぁという話になりました。 最近、ブログ書いたりするのにVisual Studio Codeを使い始めているので、これなら使いやすいかなと。 ということで、Visual Studio Codeの拡張機能(プラグイン?)としてインストールできるツールを作ってみました。 Azure Cognitive Searchを使っている人向けなので、ニッチなツールですが。。。\n余談 Elastic Stack(Elasticsearch)向けにはKibanaのプラグインでAnalyze APIを可視化するツールを作ってます。 analyze-api-ui-pluginです。Elastic Stack、特にKibanaを必ず利用する方はこちらを使うと便利かもです。\n概要と機能 GitHub リポジトリ Visual Studio Marketplaceのページ Marketplaceに公開しているので、johtaniやAzure Search Analyze Clientなどで検索してもらえれば出てきてインストールができます。\n機能としては、以下の2つです。\nテンプレートから入力値設定用のドキュメントを作成(Untitled-1というドキュメントをエディタに新しく開く) Azure Cognitive SearchのAnalyze Text APIを呼び出して、結果をHTMLのテーブル形式で表示 入力値設定用のドキュメント作成 APIの呼び出しに必要な情報を記入してもらうのに、いくつか案を考えました。\nプラグインの設定に記入してもらう 環境変数とかを読み出す テキストとして保存したファイルを使う 設定や環境変数だと、異なる環境に接続したりするときに、わざわざ設定し直すのがめんどくさいかもと。 で、愛用していたREST API Clientを真似するのが良いかもという結論になり、.analyzeという拡張子のファイルから必要な項目を読み出して、APIを呼び出す形にしてあります。\nCommand Palette(左下の歯車マークもしくは、メニューのViewから開ける)からAzure Search Analyze Client: Create Azure Search Analyze Requestというコマンドを選びます。\nすると、以下のようなファイルがエディタに開きます。\nこれらの項目をまずは埋めていきます。 それぞれの値がどういったものかはGitHubのREADMEを御覧ください。\n入力値エラー(存在チェックしかしていない)がある場合は、ダイアログが表示されます。\n結果表示 値を入力したら、設定値と###の間に表示されているAnalyze text with analyzersというグレーの文字をクリックします。すると、APIにリクエストを送信し、結果が返ってきて、別のパネルとして表示されます。\n複数のAnalyzerを入力値に設定すると、それぞれがどのような区切り方をするかがわかります。 文字の下にある[0:2]は、その単語がもとの文章の何文字目から何文字目までに出現しているかというオフセットの表示になります。\nもし、Analyzer名の設定ミスなどで指定されたAnalyzerがない場合は、結果画面にエラーが表示されるようにしています。\n以上が簡単な機能の説明です。 簡単なと言いつつ、これだけしか機能がありませんが。\nVisual Studio Codeのプラグインの作り方 プラグイン自体の作り方に関してはVisual Studio CodeのGetting Startedがわかりやすかったです。 APIや機能が豊富なので、最初はちょっと戸惑いましたが、サンプルもGitHubで多数公開されています。\nあとは、REST API Clientを参考にさせていただきました。\nGetting Startedを一通り読むことで、なんとなくプラグインの作成からMarketplaceへのリリースまでが完了できました。 (TypeScriptに慣れていないのがあるので、プログラミング自体は手間取りましたが。。。)\n今後の対応? いまのところ、こんなところを考えていますが、こんな機能がほしい、バグが有るなどあれば、GitHubにIssueを上げていただければと(使う人すくないだろうけど)。\nいろいろなエラーに関する対応 Readmeに画像をアップ アイコン作成? 自動補完機能? まとめ Visual Studio Codeの拡張機能を作ってみました。 Yeomanによるプロジェクトテンプレートが用意されているので、とりあえず、Hello worldを作るのは簡単でした。 試行錯誤しつつTypeScriptを書いたので、TypeScriptっぽくないところなどもあるかもですが、誰かの役に立つツールになってくれれば良いなぁと。\n","date":1584582615,"dir":"post/2020/","id":"c9d257aba54475c20b3737ce7c779e55","lang":"ja","lastmod":1584582615,"permalink":"https://blog.johtani.info/blog/2020/03/19/azure-search-analyze-plugin/","publishdate":"2020-03-19T10:50:15+09:00","summary":"動機 Azure Cognitive Searchを検索エンジンに使っているお客さんを手伝っています。 そこで、検索の基本的な話をさせていただきました(もともとJJUGナイ","tags":["azure search","visual studio code"],"title":"Visual Studio Codeのプラグインを作ってみた(Azure Search Analyze Client)"},{"contents":"これまで\n実践Rust入門はじめました 実践Rust入門の3章を読んでるところ 3章終了 3章の終わりまで読み終えた。\nいきなり実践的なプログラムで少し面食らっていたが、ステップを追って所有権周りの話まで来たので、 なんとなくRustのいいところが理解できたような気がする。\nただ、最後のsplit_at_mutが実際には内部でどういう形に変換することによって、コンパイルエラーにならずに、 借用がうまく行っているのかあたりは、まだきちんと理解できていない。\nこれは、どの言語にも言えるんだけど、リファレンスをうまく読み解きながら、 自分がやりたい処理ができるかどうかを考えるのって結構むずかしいなぁと思う。\nbenchmark.rsはコピペして実行しただけなので、またあとで読み返してみるかな。\nということで、ここから先は、基本を勉強する感じで4章から読みつつ、なんかプログラムをまた書いてみるか。\n","date":1583140813,"dir":"post/2020/","id":"6f47cb314fd780c122adb8cc1f44f785","lang":"ja","lastmod":1583140813,"permalink":"https://blog.johtani.info/blog/2020/03/02/finish-bicycle-book-chap3/","publishdate":"2020-03-02T18:20:13+09:00","summary":"これまで 実践Rust入門はじめました 実践Rust入門の3章を読んでるところ 3章終了 3章の終わりまで読み終えた。 いきなり実践的なプログラムで少","tags":["rust","読書"],"title":"実践Rust入門の3章を読み終わった"},{"contents":"Kuromoji-CLI Rust初心者がRust製の日本語形態素解析器の開発を引き継いでみたという記事にありますが、LinderaというRust製の日本語形態素解析が出てきました。KuromojiのRustクローンみたいなものです。 で、作者の人とのチャットの中で、「MeCabみたいなKuromojiのCLIないですかね?誰か知りませんか?」という話になりました。\n自分は普段はKuromojiの確認をするのは、Elasticsearch関連もしくは、Azure Searchなどだったりするので、 当たり前のようにKibanaを立ち上げたり、REST APIを叩いてましたが、たしかにコマンドラインインタフェースあると便利かも? と思い、作ってみるかということに。\npicocli いま、JavaでかんたんなCLI作るとなったら何がおすすめ?\n\u0026mdash; Jun Ohtani (@johtani) February 26, 2020 で、いつものツイートです。で、picocliという返信がありました。 JavaでCLIのプログラムを書くのが簡単になりそうだと。 ドキュメントもしっかりしてます。サンプルも載ってるし。\nAnnotationで、コマンドの説明などパラメータ、オプションなどが記述でき、必須チェックなども可能です。\nまた、オプションの説明文に関しては、テンプレートを用いることで、取りうる値をEnumの値で出力してくれたりといった便利機能まで備わっていました。\nGraalVM また、GRAALVMとPICOCLIでJAVAのネイティブコマンドラインアプリを作ろうというスライドも教えてもらい、ネイティブコマンドまで作れるらしいと。 なんて便利なんでしょう!ってことで、こちらもチャレンジしてみました。 GraalVMがどんなものかはなんとなくは知ってたのですが、何者だろう?とツイートしたところ、これまた返信が。\nっ 資料はかなり古いので現行版と乖離はあるけど概念は変わってないので..https://t.co/KRQjhNdD9f\n\u0026mdash; たむたむ🏫 (@tamtam180) February 26, 2020 本当に、Twitter便利ですね。\nGraalVMがどんなものかもいただいた資料でサクッと理解できました。 ただ、picocliが実はものすごく良くできており、自分でインストールする必要も実はありませんでした。\ngradle-graalというGradleのプラグインと、 Picocli Code Generationを利用することで、 以下のコマンドを実行することで、ネイティブコマンドアプリが作成できました。\ngradle nativeImage build.gradleファイルに記述したのは、以下のような項目です。\npluginの利用 picocli-codegenをannotationProcessorとして呼び出し jarに関する記述(メインクラスと依存するJarを含める設定) ネイティブコマンドの名前とか(gradle-graalの設定) 辞書が読み込めなかった で、native imageを作って実行しましたが、Kuromojiが内包している辞書ファイルが読み込めませんでした。 どうやら、picocli-codegenの自動生成では対応できない、リソース関連設定が必要らしいと。\npicocli-godegenの設定を見ていて見つけたのが、other.resource.patternsというオプションでした。\nkuromoji-cliのbuild.gradleに、その設定を加えたら辞書が読み込めるようになりました。\nこの設定をどうやって書くのか?というのを探すのにちょっと時間がかかりました。Picocli作者のRemko Popmaさんのサンプルリポジトリに設定を利用したbuild.gradleがありました。サンプル本当にありがたいですね。\n完成 出来上がったのは、kuromoji-cliというリポジトリになります。 内部で利用しているのはAtilikaのKuromojiです。LuceneのKuromojiではないのでご注意を(LuceneのKuromojiで最初やってみたのですが、リフレクションなどが多用されてて、Single Imageにするのが手間がかかりそうだった)。 コマンドのポータビリティはそれほど無いと理解してる(あってる?)ので、利用してみたい方は、リポジトリをクローンしてからビルドしてみてください。\n参考資料 kuromoji Picocliドキュメント Getting Started GraalVM / GraalVM超入門 一体何モノなの? GraalVM入門編 / GraalVM for beginners まだ途中? ほかにもあると便利かも?という機能があればIssueやPRを上げてください。 とりあえず、頭にあるのは以下のとおりです。\nJSONの出力はまだ未対応 いろんな辞書をAtilikaのKuromojiはサポートしてるのでそのへんも対応してみる? ","date":1582858179,"dir":"post/2020/","id":"d710a073be2da219a388a150eb7b6b6a","lang":"ja","lastmod":1582858179,"permalink":"https://blog.johtani.info/blog/2020/02/28/kuromoji-cli/","publishdate":"2020-02-28T11:49:39+09:00","summary":"Kuromoji-CLI Rust初心者がRust製の日本語形態素解析器の開発を引き継いでみたという記事にありますが、LinderaというRust製の日本語形態素解","tags":["misc"],"title":"KuromojiのCLIコマンドとpicocliとGraalVM"},{"contents":"これまでのはこちら。読書メモなので、本と合わせて読んでいただくのが良いです。\n実践Rust入門はじめました 3章のクイックツアーを読んでます。 バイトニックソート自体の理解はちょっとおいておいて、読み進めています。 いくつか疑問に思ったことがあったので、またメモを。 まだ、3.5.7の手前ですが。\n疑問点 3.4.1のジェネリクス対応のテストケースの部分で、既存のu32用のテストケースの入力のデータ列にVec\u0026lt;u32\u0026gt;という型注釈をつけるのですが、 追加した文字列の入力データには注釈をここではつけないのはなんでなんだろう?ちなみに、なくても動いた。バージョンの違いとかあるのかしら?\n3.4.6のmatch文\nmatch文の引数?が*orderになっていたが、orderでも実行できた。引数にくるのが参照だから*が付いてるんだとも運だが、なくても動くのはコンパイラがよしなに解釈してくれてるからかな? 便利なツール Rust標準のツールの説明がいくつか3章で紹介されてて便利だったのでメモ。\nrustfmt フォーマッター。デフォルトでフォーマット機能が付いてるの便利ですね。言語として決まってると、プロジェクトごとに悩まなくていいってのがありますし。\nrustfmt ファイル名 という形で使えるみたい。 プロジェクトごとだとcargo fmtのほうが楽そうかな。\n標準ライブラリAPIドキュメントをブラウザで閲覧 rustup doc --std これでデフォルトブラウザでRustの公式ドキュメントが開きます。 しかもローカルファイルだからサクサク。検索バーもついてて便利です。\nエラーのドキュメントを閲覧 rustc --explain 308 コンパイル時にエラーが出たときに、error[E0308]のようにコンソールに出てきます。 ヒントも出てくるのですが、詳細が上記のコマンドで読めるみたいです。\n","date":1582443437,"dir":"post/2020/","id":"71cf83ae0f45e9ede3a3f979b9c74933","lang":"ja","lastmod":1582443437,"permalink":"https://blog.johtani.info/blog/2020/02/23/bicycle-book-chap3/","publishdate":"2020-02-23T16:37:17+09:00","summary":"これまでのはこちら。読書メモなので、本と合わせて読んでいただくのが良いです。 実践Rust入門はじめました 3章のクイックツアーを読んでます。 バ","tags":["rust","読書"],"title":"実践Rust入門の3章を読んでるところ"},{"contents":"もう2020年2月になってしまってますが、2019年に買って便利だったもの良かったものをいくつか記録に残しとこうかなと。\nBRAVIA KJ-55X9500G Amazon | ソニー SONY 49V型 液晶 テレビ ブラビア 4Kチューナー内蔵 テレビをやっと買い替えました。 前に使っていたのはプラズマディスプレイで、10年以上たったもので、パネルの一部が赤い残像が残ってたりしました。 もう流石にいいでしょうということで、買い替えたのがSonyのテレビです。 4Kのチューナーもついているし、アップコンバーターもついているので普通の地上波でもきれいです。 まぁ、10年前のテレビに比べればたくさんいいことがありますよねw\n新しいTV買って一番活躍してるのはYouTubeボタンだったりします。 最近はミュージックビデオがYouTubeにたくさんあるので、King Gnuなどの音楽流したりするのに便利です(テレビなのに)。 今は、プライムビデオボタンがより活用される感じになってきてます(テレビなのにw)。\nSodastream Amazon|スピリット ワンタッチ ホワイト スターターキット ここ数年、炭酸を普段飲んでます。甘いもの飲まないようにって意味でも。。。 で、これを買うまでは、サントリーの天然水スパークリングレモンとかを、箱買いしてました。 が、まぁ、ペットボトルのゴミが半端ないんですよ。場所も取るし。\nソーダストリームのことは知ってたのですが、自分で炭酸の量を考えながら、入れないといけないので避けていました。\nが、今回購入したものは、水の入ったボトルを指して、ボタン一つで3段階の炭酸を入れることができるんです!買って本当に重宝してます。うちでは1Lのボトルを1本追加して、2本で運用してます。 家族はなっちゃんのオレンジとかを炭酸割りしたり、カルピスソーダ作ったりして楽しんでます。 ワンタッチということで、簡単に入れられるので家族も重宝してます。\nNature Remo + Chromecast Amazon | Nature スマートリモコン Nature Remo mini Remo-2W1 Google Home miniがキャンペーンで手に入ったので、ベッドルームの照明やクーラーの操作もできそうなのでNature Remoを導入しました。 Chromecastは余っている液晶モニターにつないで、スマホからキャストできるようにしたり、音楽聞けるようにしてあります。\nNature Remoは温度計などもついているので、部屋の温度に合わせてエアコンのオンオフなども可能で、 暑い夏にとても便利でした。寝る時間にはクーラーが入っているのですんなり寝れたりと。 スマホから電源オンオフできるのも便利ですね。 Chromecastはモニターにつなぎましたが、今は、Google Music Playのプレーヤーになってます。 (最近、家にあるCDを読み込んでGoogle Play Musicにアップしてる)。\nただ、それ以上のことには使えてないので、もうちょっと面白いことしてみないとなぁ。\nモニターアーム Amazon | HUANUO PC モニター アーム 液晶ディスプレイ アーム ガススプリング式 Amazon | グリーンハウス 液晶ディスプレイアーム 4軸 クランプ式 ディスプレイがふるくなってたので、4Kディスプレイに買い替えた(27インチで4万切るとかで安い。。。)んですが、Mac Book Pro 15インチ(今は16インチ)を使っていて、Macの画面がディスプレイにかぶるので モニターアームを買いました。 1つ目がガススプリング式のアームです。なのに、5000円を切ってるんですよ。おそるべし。 2つ目はクランプ式です。アームにしたものの特に動かすことはなく、高さを出したいだけってことがあるので、クランプ式のも使ってます(家ではディスプレイ2枚使ってる)。 コスパ最高です。\nAnker PowerCore 10000 PD Amazon | Anker PowerCore 10000 PD(10000mAh PD対応最小最軽量 大容量 モバイルバッテリー) Pixel 3にしてから、電池の持ちはよくはなってるんですが、もしもの時のためにモバイルバッテリーは話せないですよね。 PD対応なので、Pixel 3に急速充電ができるし、サイズもそれほどじゃまにならないサイズなので便利です。USB-Aもついているので、このあと紹介するイヤホンの充電ケーブルなんかも差し込めて大活躍です。\nサウンドピーツのイヤホン Amazon | SOUNDPEATS(サウンドピーツ) Q35HD ワイヤレス イヤホン 高音質・低遅延 IPX8防水 私が持ってるのはこの前のバージョンで、micro-USBで充電充電するタイプですが、こちらもコスパ最高です。 冬は防寒も兼ねてヘッドフォンをしているのですが、春から秋にかけてはこれまで、優先のイヤホンを使ってました。もしくは、Bluetoothのレシーバーに優先のイヤホンつけてました。電池切れたら、イヤホンさして使う感じで。 が、Pixel 3はイヤホンジャックがありません。ということで、ワイヤレスイヤホンに移行するかということで選んだのがこちらです。 世の中的には、完全ワイヤレスイヤホンが流行っていますが、片方無くなってしまうイメージしかわかなくて。。。 これが壊れても、完全ワイヤレスではなくつながったワイヤレスイヤホンを使うと思います。\nヘッドルーペ Amazon | Tumao ヘッドルーペ ルーペ メガネ LED付拡大鏡 眼鏡の上装着 メガネゴムバンド両用 5レンズ交換調節 プラモデルをちょいちょい作るんですが、もう年ですね。。。細かいところが見にくくて。 ガンダムのRG系のプラモデルだと、1/144なんですよ。小さいんですよ。見えないんですよ。。。\n完成しましたー! pic.twitter.com/S9QTS4kJDI\n\u0026mdash; Jun Ohtani (@johtani) February 16, 2020 ということで、ヘッドルーペ導入してみました。 最初は、卓上に置けるルーペにしてみたんですが、自分がルーペがあるところに動かないといけないの結構つらくて。 これのおかげで、プラモデル作成に問題はなくなりました。老眼とは関係なく、ちょっと猫背になっちゃうのが今は悩みの種ですが。。。こたつで作ってるからなぁ。\nまとめ ということで、いくつかよかったものを紹介してみました。 今年はちゃんと年末に書こう。。。\n","date":1582272302,"dir":"post/2020/","id":"daa3fe935b0be9f31b6b362ad9e0d2d6","lang":"ja","lastmod":1582272302,"permalink":"https://blog.johtani.info/blog/2020/02/21/best-buy-2019/","publishdate":"2020-02-21T17:05:02+09:00","summary":"もう2020年2月になってしまってますが、2019年に買って便利だったもの良かったものをいくつか記録に残しとこうかなと。 BRAVIA KJ-55X9500G Amazon | ソニー SONY 49","tags":["買い物"],"title":"2019年に買ってよかったもの"},{"contents":"ブログ移行日記(その5)です。前回まではこちら\nブログ移行日記(その1) ブログ移行日記(その2) ブログ移行日記(その3) ブログ移行日記(その4) 今回はこれまでとは異なる特殊な話です。\n最初にブログを書き始めたときに利用していたのがJugemのブログでした。 その後、Octopressに移行して、今年、Hugoに移行したという流れです。\nで、よくよく考えると、Jugemのブログも移行できるんじゃないか?となりました。 じゃあ、やってみるかと。なので、今回のブログは自分の備忘録です(興味のない人が大多数じゃないかな)。 一応、Pythonで書いたプログラムはGitHubに上がっています。文字列置換と正規表現のオンパレードです。\nJugemからExport まずは、移行元のデータが取り出せるかどうかを調べたところ、text形式もしくはXML形式でエクスポートが可能でした。\n変換処理が必要なはずなので、XMLでダウンロードします。 独自のXMLですが、記事ごとにXMLのタグ(\u0026lt;entry\u0026gt;)でまとめられているので、処理が楽です。\nXMLをMarkdownに \u0026lt;entry\u0026gt;タグの下に次のような項目が入っているので、抜き出します。\nヘッダ部 title - 記事タイトル author - 著者 category - タグ date - 投稿日付 description : 本文(先頭部分) sequel : 本文(つづき) titleからdateまでをHugoのMarkdownのヘッダ部分として出力します。 日付は形式が違うので合わせるように変換し、 titleは(Jugemより移植)という文字列を追加しました。\nまた、Hugoの個別のコンテンツにするためにそれぞれをMarkdownのファイルに変換しています。 ファイル名は変換後のdateの先頭10文字(yyyy-MM-dd)に-を付け加えて、 タイトルを追加しました。ホントは英語のファイル名にしたかったんですが、ちょっと手抜き。ファイル名に使用できないような文字は-に置換しています。\n本文 本文部分はもう少し複雑です。 まずは、descriptionとsequelから抜き出した文字列を結合します。\nで、内部の文字列に次のようなものがあるので、それぞれMarkdownに変換したりという処理を書いてます。\nHTMLのheadingタグをMarkdown形式に br、hr、del、strongなどのタグもMarkdown形式に aタグの処理 Amazonのアフィリエイトタグの処理 ul、olタグの処理 などです。 アフィリエイトタグは、数行に渡るの複数のHTMLタグで記述されているので、 ASINと商品タイトルだけを抜き出しています。 Hugoでアフィリエイトのリンクを作るために、hugo-amazon-jpという公開されているshortcodeを元に、カスタマイズしたものを使っています。 これ用に、必要なASINとタイトルを別ファイルに出力したりしています。\nまた、いくつか画像を使っている記事があったのですが、これが曲者でした。 XMLに入っているimgタグに画像へのURLがあるのですが、アクセスしても存在しないURL担っています。。。 ブログで公開している画像のファイル名に似たものがXMLに入っていたので、URLを組み直して、ダウンロードするという処理も書いています。\nあとは、昔ちょっと凝った書き方(spanタグで章みたいなことやってた)をしていた部分の処理を加えて完成です。\nまとめ 元のXMLを見たり、抜き出したファイルを見ながら、トライアンドエラーでプログラムを書きました。 なんとなく変換できたなかっていうところで、取り込んで公開しました。 まだ、全部の記事をチェックしてないですが、なんとなく移植できたので一旦これでいいかなと。 昔の記事を見たときにおかしい場所があったら手で治すつもりでいます。\nなんか、もうちょっとうまくプログラムかけた気もしますが、書き捨てのプログラムだと思うのでこんなもんかな。\n1点気になっているところは、コメントの部分です。 ブログにコメントをいただいていたのですが、その部分は移植できてないです。\nOctopresに移植していこうは、Disqusのサービスでコメント部分を提供しています。ここに移植するのも変な話だなぁと思っているので、本文にコメントを取り込む感じかなぁ?\nもともとのJugemのサイトもそのまままだ残してあるので、そのうち気が向いたらで。\n","date":1582254240,"dir":"post/2020/","id":"ef8a399c9679ce4e9710c7c6ecf8bcc7","lang":"ja","lastmod":1582254240,"permalink":"https://blog.johtani.info/blog/2020/02/21/import-jugem-posts/","publishdate":"2020-02-21T12:04:00+09:00","summary":"ブログ移行日記(その5)です。前回まではこちら ブログ移行日記(その1) ブログ移行日記(その2) ブログ移行日記(その3) ブログ移行日記(その4","tags":["hugo","ブログ"],"title":"ブログ移行日記(その5) - Jugemのブログを移行"},{"contents":"お手伝いしているお客さんがAzure Cognitive Searchを利用してます。 検索周り=Azure Cognitive Searchに関する手伝いをする形で入っており、 いくつか触った感触をブログにまとめてみようかと(お客さんからはOKいただいてます)。\nAzure Cognitive Searchとは? 公式サイト 「AIを活用した」クラウド検索サービスと紹介されています。\n昔はAzure Searchと呼ばれていましたが、ここ最近はAzure Cognitive Searchと呼ばれているみたいです(Microsoft Igniteで発表された話がまとまっているページもあります)。 もともと、検索エンジンのSaaSサービス(キーワード検索、あいまい検索、オートサジェスト、スコアリングなどの機能)として作られていた部分に、データの登録パイプラインにCognitive Serviceの便利な機能を簡単に使えるようにしたものというイメージでしょうか。\nバックエンドはElasticsearchのはずです。変わってなければ。 昔、Elastic社主催のユーザーカンファレンスでMSの方が公演された資料が公開されていたりします。 ちなみに質問が多いのでしょうか、Azure Cognitive SearchとElasticsearchの違いはなんですか?というページがよくある質問のページに用意されていました。参考までに。\n今回はちょっとしたインデックスをつくって検索する部分を紹介してみようかと思います (Cognitiveなところは機会があればまた)。\n普通の使い方については、Azureのドキュメントなどを読んで頂く形にします。 ポータルと呼ばれるブラウザ上でAzureのサービスを触ることができる画面が用意されています。 ここで、簡単な操作(インデックス作成、フィールドの追加)\nAPIを使ってインデックス(特にAnalyzer)の設定をしたり、データをいれて、クエリしてみるというところをサクッと紹介しようと思います。\nインデックスの作り方 インデックス作成に関するドキュメントも用意されています。最初はポータル(GUI)でインデックスを作成する方法が紹介されています。 ですが、今回はn-gram(n=2)のAnalyzerを利用したかったので、GUIではなくAPIでインデックスを作成しました。 カスタムアナライザーを利用する場合、REST APIを利用しなければ行けないということになっています。 n-gramのAnalyzerを含むインデックス生成のREST APIは以下のとおりです。こちらを実行することで、インデックスが作成されます(JSONの記述ミスなどがある場合はエラーが返ってきます)。\n@host = \u0026lt;サーチのサービス名\u0026gt;.search.windows.net @api-key = \u0026lt;APIキー\u0026gt; ### POST https://{{host}}/indexes/?api-version=2019-05-06 Content-Type: application/json api-key: {{api-key}} { \u0026#34;name\u0026#34;:\u0026#34;ngram-test\u0026#34;, \u0026#34;fields\u0026#34;:[ { \u0026#34;name\u0026#34;:\u0026#34;id\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;Edm.String\u0026#34;, \u0026#34;key\u0026#34;:true, \u0026#34;searchable\u0026#34;:false }, { \u0026#34;name\u0026#34;:\u0026#34;ngram\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;Edm.String\u0026#34;, \u0026#34;searchable\u0026#34;:true, \u0026#34;analyzer\u0026#34;:\u0026#34;bi_gram_analyzer\u0026#34; } ], \u0026#34;analyzers\u0026#34;:[ { \u0026#34;name\u0026#34;:\u0026#34;bi_gram_analyzer\u0026#34;, \u0026#34;@odata.type\u0026#34;:\u0026#34;#Microsoft.Azure.Search.CustomAnalyzer\u0026#34;, \u0026#34;tokenizer\u0026#34;:\u0026#34;bi_gram_tokenizer\u0026#34;, \u0026#34;tokenFilters\u0026#34;:[ \u0026#34;lowercase\u0026#34; ] } ], \u0026#34;tokenizers\u0026#34;:[ { \u0026#34;name\u0026#34;:\u0026#34;bi_gram_tokenizer\u0026#34;, \u0026#34;@odata.type\u0026#34;:\u0026#34;#Microsoft.Azure.Search.NGramTokenizer\u0026#34;, \u0026#34;minGram\u0026#34;:2, \u0026#34;maxGram\u0026#34;:2 } ] } なんだかどこかで見たことのある記述のようなそうでないような。。。 Analyzerは、charFilters(0以上複数可)、tokenizer(1つ必須)、tokenFilters(0以上複数可)から構成されます。 フィールドで指定するのはAnalyzerなので、まずanalyzersにCustomAnalyzerの設定を行います。 名前はbi_gram_analyzerにしました(好きに付けてください)。 tokenizerにはこのあと設定するtokenizerの名前を設定します。ここでは、bi_gram_tokenizerという名前にしています。 また、大文字小文字を気にせずに検索したいため、tokenFiltersにlowercaseを指定しています。こちらはすでに定義済みのため、定義済みの名前で呼び出すだけで使用できます。\n次が、bi_gram_tokenizerの設定です。 n=2としたいので、tokenizers配下にTokenizerの設定をします。 @odata.type\u0026quot;:\u0026quot;#Microsoft.Azure.Search.NGramTokenizerがTokenizerの名前です(ちょっと独特な名前ですね)。 Tokenizerごとにオプションがあり、NGramTokenizerの場合は、minGram、maxGramがオプションに相当します。 今回は2文字ごとにトークンを出力したいので、minとmaxをそれぞれ2としています。\nこれで、あとは、フィールドでanalyzerという設定にbi_gram_analyzerを指定すればそのフィールドはbi_gram_analyzerを使用してアナライズされるようになります(このへんはElasticsearchといっしょですね)。 フィールドは文字列を扱うので、Edm.Stringというタイプにしてあります。データ型については、フィールドコレクションとフィールド属性というドキュメントを参考に設定しましょう。\n閑話休題 - REST Client Exstension for Visual Studio Code なお、今回のサンプルはREST Clinet Extention for Visual Studio Codeを利用する想定の記述になっています。\nVisual Studio Codeで.restもしくは.httpというファイルに以下のAPIを記述すると、Send RequestというリンクがURLの上部に出てくるような拡張機能です。REST APIにリクエストするときに便利なツールになっています。 変数も使えるので、APIのキーやURLの一部をこのように共通化して、他の環境でも使いやすくできるのは素晴らしいなと。\nアナライザーの挙動の確認 設定したAnalyzerがきちんと機能しているかというのを確認する必要があります。 入力した文字列がきちんと想定している単語として切り出されて、転置インデックスの見出し語に使われるかというのが重要になるからです。\nAzure Cognitive Searchでもアナライザーのテスト用APIが用意されています。 使い方はこちら。 APIの仕様のページもありました。 「アナライザーの挙動はどんな感じ?」という文字列が、作成したインデックスの定義したアナライザーbi_gram_analyzerにより、 どのように分割されるかを確認するAPIの呼び出しは以下のとおりです。\n### POST https://{{host}}/indexes/ngram-test/analyze?api-version=2019-05-06 Content-Type: application/json api-key: {{api-key}} { \u0026#34;analyzer\u0026#34;:\u0026#34;bi_gram_analyzer\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;アナライザーの挙動はどんな感じ?\u0026#34; } レスポンスはこんな形です。ヘッダ部分は省略してあります。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;https://{{host}}.search.windows.net/$metadata#Microsoft.Azure.Search.V2019_05_06.AnalyzeResult\u0026#34;, \u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;アナ\u0026#34;, \u0026#34;startOffset\u0026#34;: 0, \u0026#34;endOffset\u0026#34;: 2, \u0026#34;position\u0026#34;: 0 }, { \u0026#34;token\u0026#34;: \u0026#34;ナラ\u0026#34;, \u0026#34;startOffset\u0026#34;: 1, \u0026#34;endOffset\u0026#34;: 3, \u0026#34;position\u0026#34;: 1 }, { \u0026#34;token\u0026#34;: \u0026#34;ライ\u0026#34;, \u0026#34;startOffset\u0026#34;: 2, \u0026#34;endOffset\u0026#34;: 4, \u0026#34;position\u0026#34;: 2 }, { \u0026#34;token\u0026#34;: \u0026#34;イザ\u0026#34;, \u0026#34;startOffset\u0026#34;: 3, \u0026#34;endOffset\u0026#34;: 5, \u0026#34;position\u0026#34;: 3 }, { \u0026#34;token\u0026#34;: \u0026#34;ザー\u0026#34;, \u0026#34;startOffset\u0026#34;: 4, \u0026#34;endOffset\u0026#34;: 6, \u0026#34;position\u0026#34;: 4 }, { \u0026#34;token\u0026#34;: \u0026#34;ーの\u0026#34;, \u0026#34;startOffset\u0026#34;: 5, \u0026#34;endOffset\u0026#34;: 7, \u0026#34;position\u0026#34;: 5 }, { \u0026#34;token\u0026#34;: \u0026#34;の挙\u0026#34;, \u0026#34;startOffset\u0026#34;: 6, \u0026#34;endOffset\u0026#34;: 8, \u0026#34;position\u0026#34;: 6 }, { \u0026#34;token\u0026#34;: \u0026#34;挙動\u0026#34;, \u0026#34;startOffset\u0026#34;: 7, \u0026#34;endOffset\u0026#34;: 9, \u0026#34;position\u0026#34;: 7 }, { \u0026#34;token\u0026#34;: \u0026#34;動は\u0026#34;, \u0026#34;startOffset\u0026#34;: 8, \u0026#34;endOffset\u0026#34;: 10, \u0026#34;position\u0026#34;: 8 }, { \u0026#34;token\u0026#34;: \u0026#34;はど\u0026#34;, \u0026#34;startOffset\u0026#34;: 9, \u0026#34;endOffset\u0026#34;: 11, \u0026#34;position\u0026#34;: 9 }, { \u0026#34;token\u0026#34;: \u0026#34;どん\u0026#34;, \u0026#34;startOffset\u0026#34;: 10, \u0026#34;endOffset\u0026#34;: 12, \u0026#34;position\u0026#34;: 10 }, { \u0026#34;token\u0026#34;: \u0026#34;んな\u0026#34;, \u0026#34;startOffset\u0026#34;: 11, \u0026#34;endOffset\u0026#34;: 13, \u0026#34;position\u0026#34;: 11 }, { \u0026#34;token\u0026#34;: \u0026#34;な感\u0026#34;, \u0026#34;startOffset\u0026#34;: 12, \u0026#34;endOffset\u0026#34;: 14, \u0026#34;position\u0026#34;: 12 }, { \u0026#34;token\u0026#34;: \u0026#34;感じ\u0026#34;, \u0026#34;startOffset\u0026#34;: 13, \u0026#34;endOffset\u0026#34;: 15, \u0026#34;position\u0026#34;: 13 }, { \u0026#34;token\u0026#34;: \u0026#34;じ?\u0026#34;, \u0026#34;startOffset\u0026#34;: 14, \u0026#34;endOffset\u0026#34;: 16, \u0026#34;position\u0026#34;: 14 } ] } このAzure SearchのAnalyze API、使用できるオプションはすくないですが、ElasticsearchのAnalyze APIと似ています。\nデータの登録の仕方 データ登録もAPIからできます(あたりまえですね)。 APIは1件ずつではなく、バルクで登録できる形で提供されています。\nサンプルとしては、以下のような形です。 @search.actionの部分(searchがあるとわかりにくい気がするけど。。。)が、ドキュメントの登録、更新、削除の命令を書き込むところになります。 今回は単純に登録するだけなので、uploadを指定しました。 ほかにもいくつかアクションが用意されています。用途に合わせて指定する感じになります。 id、ngramはそれぞれフィールド名です。ドキュメントに登録したい値を記述します。\nPOST https://{{host}}/indexes/ngram-test/docs/index?api-version=2019-05-06 Content-Type: application/json api-key: {{api-key}} { \u0026#34;value\u0026#34;: [ { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;ngram\u0026#34;: \u0026#34;新しいAzure Searchの使い方\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;2\u0026#34;, \u0026#34;ngram\u0026#34;: \u0026#34;Elasticsearchの紹介\u0026#34; } ] } 検索クエリ 最後は検索クエリです。 検索クエリはいくつかのオプションがあります。 ざっくりだと、queryTypeがsimpleとfullという2種類が用意されており、ちょっとした検索を作る場合はsimpleで事足りそうという感じです。 入力された単語(スペース区切りで複数扱い)をフィールド(複数可)に対していずれかの単語を含むもしくは、すべての単語を含むという検索に行くというパターンですね。 このときの、「いずれか」か「すべて」の設定がsearchModeというパラメータになります。 anyの場合、Googleの検索と同様に、どれかの単語が入っているドキュメントが対象に、allの場合すべての単語が含まれるドキュメントだけがたいしょうになるといった形です。\nqueryType=fullの場合はLuceneの構文でクエリがかけます。ElasticsearchのQuery String Queryみたいな形です。\n簡単なサンプルは次のような感じです。このサンプル\nPOST https://{{host}}/indexes/multi-field-test/docs/search?api-version=2019-05-06 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#39;ngram:\u0026#34;使い方\u0026#34; ngram:\u0026#34;紹介\u0026#34;\u0026#39;, \u0026#34;queryType\u0026#34;: \u0026#34;full\u0026#34;, \u0026#34;searchMode\u0026#34;: \u0026#34;any\u0026#34; } すこしだけクエリの補足を。 searchに入力された単語をダブルクォートで囲んでいます。これは、「使い方」という文字がbi_gram_analyzerにより「使い」「い方」に 分割されるのですが、必ずこの順序で出現したものだけを検索対象にしたい(フレーズ検索)という意味になります(*bi_*gramなので、「紹介」に関してはダブルクォートは厳密には必要ないです)。\nあと、レスポンスは今回記載していませんが、@search.scoreという項目で、スコアが返ってきます。 デフォルトのスコア計算には何を使ってるんだろう?ドキュメントにはTF-IDFとの記述があるのですが。。。カスタマイズもできそうです。\n少しオモシロイと思ったのは、スキーマ(インデックスの設定)に定義されているが、ドキュメントとしては登録していない項目についても、 Azure Cognitive Searchはドキュメントのフィールドがnullという形で返ってくるようでした。 そもそもフィールドが存在しないドキュメントとフィールドの値がnullのものの違いは無いようです。\n簡単ですが、インデックスの設定、ドキュメントの登録、検索の方法の紹介でした。\nちょっと触った感想 一番売りである、Cognitiveの部分はまだ触っていないです、すみません(こっちが売りな気もするんですが)。 検索エンジンの部分としては、Elasticsearchを知っていると、「あー、そんな感じね」という気持ちになれるサービスです。 個々のAPIやデータの形式は異なるので、きちんとAPIのリファレンスなどを確認しつつという形になりますが、なんとなくこういうAPIなどがありそうだな?と予測しつつ使えるかなと。 内部的にはElasticsearchだと思いますが、独自のAPIでラップされているおかげで、バージョンの違いなどを意識せずに使えるのではないかと思います。\nまた、今回は紹介していませんが、マイクロソフト独自の各言語のアナライザー(日本語も含む)があります。 Luceneのアナライザーとマイクロソフトのアナライザーのどちらも利用できますので、ここの違いを見てみるのも面白そうだなと思いました。 緯度経度を利用した検索、フィルター検索(スコア計算対象にならない)、ファセット、スコア調整の機能なども備えているようです。\nなんにせよ、利用する場合やドキュメントを読む場合に、全文検索の仕組みをなんとなく知っておいたほうが読みやすいんじゃないかなというのが感想です。\nここ数年はElasticsearchがメインでほかはほぼ触っていない状況だったので新しい製品に触れるのは面白いですね。 時間があったら、アナライザーの違いなども調べてみたいなと思います。\n","date":1582080481,"dir":"post/2020/","id":"c3053579ae25e2fb9b967076a06373af","lang":"ja","lastmod":1582080481,"permalink":"https://blog.johtani.info/blog/2020/02/19/research-azure-cognitive-search/","publishdate":"2020-02-19T11:48:01+09:00","summary":"お手伝いしているお客さんがAzure Cognitive Searchを利用してます。 検索周り=Azure Cognitive Searchに関する手伝いをする形で入っており、 いく","tags":["azure search"],"title":"Azure Cognitive Searchでインデックスを作って検索"},{"contents":"また、ツイートから始まるお話です。 まだまだ、検索システムってどんなものかを勉強したいしということで、こんなのをツイートしてました。\n「検索システム探訪」みたいな名前がいいかな? https://t.co/sG7BDdGI9h\n\u0026mdash; Jun Ohtani (@johtani) February 6, 2020 検索について知り合いとお茶をしながら話をしていて、こういう話を聞くの面白いなぁと思ったので。 どんなことを個人的には聞きたいかな?というのをまとめといたほうがいいかと思いブログを書いています。 こんなことも面白そうだよね?\nどんなこと聞きたいかな? いまのところ思いついた内容はこんな感じかな? こんなのも聞くと面白そうだよね?などありましたら、コメント欄に書いてもらえればと。\n利用しているシステム・サービスは? 構成やどこのサービスなのか? 検索ユーザーはどんな人? ユーザーの種類 ユーザーの検索ニーズ 検索対象データはどんなもの? データ件数はどのくらい? 属性、項目がどのくらいあるか? 検索結果として出したいものは? ソートはどんなものがあるの? ランキングで重要なものは? UI/UXはどんな感じ? ハイライト、ソート、ファセット(Aggs) キーワードサジェスト、オートコンプリート 検索システムの監視(オブザバビリティ??) ビジネス的な指標 クエリログ、クリック(ユーザーに関する情報) システムメトリクス 困っていることは? ランキング クエリ 検索システム分析 第1回やりました。 ちなみに、最初のツイートに対して、すぐに返事をくれた方がいました。\nうちでよければご説明します!\n\u0026mdash; Kizashi (令和もRailsエンジニア募集中) (@kizashi1122) February 6, 2020 Twitter本当にありがとうございますという感じです。\nで、早速話を聞かせていただきました。大阪の方だったので、テレカンでやらせていただきました。 移動時間とか気にせずにできるので、テレカン形式いいですよね。\n内容は、非常に面白かったです。 使ってるシステムについて、どんなところで、どのようなように検索エンジンをつかっているのか、 どんなことで困っているのかなどをお聞きすることができました。\n2020/02/13 追記 対応していただいたIngageの永田さんから、内容を公開しても良いという承諾をいただいたので、メモを公開します。\nサービス : Re:lation 問い合わせメールなどのチームで対応する対応 利用している検索エンジン Elasticsearch (AWS Es) ノード数 8 - 3 master + 5 data データ データ数 : 約1億5千万 親子関係 : チケット - メール(=1ドキュメント) - コメント 画面としてはチケットの一覧=aggsでチケットIDの一覧を生成してリスト表示 インデックス数 : 5 = テナントごとに振り分けしてる。 8シャード - スケールアウトした場合も対応できるので。 PostgreSQLにマスターは保存 データの単位はメール。コメントはtextの配列でメールに保存されている。 EsはIDの一覧を返す。ただし、チケットのIDの一覧 機能 ハイライト Esではなく独自実装。 クエリ n-gramでやってる = kuromoji使ってない min=1, max=2 悩み事 EBS上だったものをローカルにしたので速くなった。 期間が長いと、検索結果一覧の表示が遅い aggsが遅いのかな? 検索結果一覧はチケットが持っているメールの日付の降順。結果一覧はチケットの一覧。 詳細検索はDB、左のステータスもファセットも現在はDBから生成 Es使ったほうが早いかも? マルチテナントのつらさ 検索ログ 独自ログはとっていない = アプリのログから判別 今後 アドレス帳検索 お誘いお待ちしております! 今後もこれやっていきたいなぁ。話してもいいよ!という方がいらっしゃいましたら、@johtaniまでDMもしくはメンションをください。お待ちしております!\n","date":1581344427,"dir":"post/2020/","id":"7b080dc43fce482af14de61c6ab819a5","lang":"ja","lastmod":1581344427,"permalink":"https://blog.johtani.info/blog/2020/02/10/explore-search-system/","publishdate":"2020-02-10T23:20:27+09:00","summary":"また、ツイートから始まるお話です。 まだまだ、検索システムってどんなものかを勉強したいしということで、こんなのをツイートしてました。 「検索シス","tags":["検索システム探訪"],"title":"「検索システム探訪」したいな=\u003eやりました"},{"contents":"年末、何種類かのボードゲームを家族で楽しみました。 家族の感想を交えて簡単に紹介しようかと思います。 家族や知人でボードゲームを購入するときの参考に参考にしてもらえたらと。 それぞれのゲームの詳細については、それぞれWikipediaなどのリンクを張っておくので、参考にしていただけたらと。 結構有名なボードゲームが多いのかな?\nカタン Amazon | カタン スタンダード版 | ボードゲーム | おもちゃ 簡単な紹介 プレーヤー数 : 3-4名 (拡張版を追加すると5-6名でもプレイできるみたい) 対象年齢 : 10歳以上 種類 : 対戦型 紹介 : 大航海時代に発見された無人島を複数の入植者たちが開拓していき、もっとも繁栄したプレイヤーが勝利するという内容のボードゲーム(Wikipediaより)。 特徴 : 5種類の資源を元に、道を作ったり、開拓地や都市を作ったり、サイコロを使った運も必要ですが、プレーヤー同士で手持ちの資源を交渉することも可能なゲームです。 感想 最初の配置が重要な気がします。資源の組み合わせによってできることが変わってくるので、何をやりたいかというのを元に考えて配置するのが重要そうです(私はまだうまくできてませんがw)。 プレーヤー同士の交渉も1つの手段なので、会話しながら、自然と交渉術も身についてきそうです。 戦略だけじゃなくサイコロを使った運もあるので、子供と大人が混ざっていても偏った結果にはならないです。 自分の道や町が発展していくのも楽しみの1つです。 お化け屋敷の宝石ハンター Amazon | お化け屋敷の宝石ハンター FBH20 | おもちゃ | おもちゃ 簡単な紹介 プレーヤー数 : 2-4名 対象年齢 : 8歳以上 種類 : 協力型 紹介 : お化け屋敷がおばけでいっぱいになる前に、みんなで協力して8つの宝石をみつけて、屋敷から脱出しよう!(メーカーホームページより)。 特徴 : 対戦ではなくプレーヤーみんなで協力してやるボードゲーム。おばけのフィギュアも可愛いです。サイコロを利用した運もありますが、みんなでどういった戦略で宝石を取り出すかなど会話も進むゲームです。上級編という難しめのルールも用意されているので、ハラハラ・ドキドキしながらプレイできます。 感想 負けて悔しくなったり機嫌が悪くなることがないのがいいですね。 普通のルールだと少し物足りない感じですが、上級編のルールはより、みんなで協力する必要が出てきます。 また、上級編のルールは絶妙な難易度で、もう一度やりたいと思わせるのが良い仕組みです。 ラビリンス Amazon | ラビリンス (Labyrinth) ボードゲーム | ボードゲーム | おもちゃ 簡単な紹介 プレーヤー数 : 1-4名 対象年齢 : 8歳以上 種類 : 対戦型 紹介 : 動く迷路で宝探し!通路が動く不思議な迷路の中に、「宝物」や「奇妙な生き物」が隠されています。プレイヤーはこれらを集めてこなければなりませんが、そのためには、巧みに迷路を動かさなければなりません。(メーカーホームページより)。 特徴 : サイコロがないボードゲームです。先を予測しながら人のじゃまをしつつ、自分に有利に進めていくゲームです。プレーヤー個別に難易度を変えられる仕組みがあります(子供だけに有利なルール設定が可能)。 感想 子供ルールがあるので、1度のゲームで別々の難易度が設定できるのがいいです。左右盲の人には子供ルールとかもありです。 ラビリンスが得意な人は地図を読むのが得意な人だと思います。 頭も使うけど、自分が望んだ道ができた時の快感があります。 モノポリー Amazon | ハズブロ ボードゲーム モノポリー クラシック C1009 正規品 | ボードゲーム | おもちゃ 簡単な紹介 プレーヤー数 : 2-6名 対象年齢 : 8歳以上 種類 : 対戦型 紹介 : プレイヤーは双六の要領で盤上を周回しながら他プレイヤーと盤上の不動産を取引することにより同一グループを揃え、家やホテルを建設することで他のプレイヤーから高額なレンタル料を徴収して自らの資産を増やし、最終的に他のプレイヤーを全て破産させることを目的とする。モノポリーとは英語で「独占」を意味する。(Wikipediaより)。 特徴 : 資本主義とは?みたいなのを体験できるゲーム。すごろく型ですが、ゴールがあるわけではなく、決着がつくまでぐるぐる回る感じです。 感想 資本主義を象徴しているゲーム展開。真剣勝負間違いなしです。 負けると途中退場ってのがちょっとつらいです。。。 カタンとは違った感じの交渉術になります。 コマが色んな種類があってかわいいです。 パンデミック Amazon | パンデミック:新たなる試練 (Pandemic) 日本語版 ボードゲーム | ボードゲーム | おもちゃ 簡単な紹介 プレーヤー数 : 2-4名 対象年齢 : 8歳以上 種類 : 協力型 紹介 : 『パンデミック』(Pandemic)は、プレイヤーが新型ウイルス対策チームの一員となり、協力しあい感染症の世界的流行(パンデミック)に立ち向かうというボードゲームである。(Wikipediaより)。 特徴 : プレーヤーが個別のロール(役割)を持っており、よりみんなで協力をしないとウイルスに打ち勝てない感じです。 感想 ルールが結構複雑で、理解しながらだと少し時間かかりました。 8歳以上になっていますが、少しむずかしい印象でした。 戦略、戦術が問われる形のゲームなのでしっかり理解すると楽しそう。 世界地図上で、ウイルスと戦っていく感じは臨場感があって面白いです。 ナインタイル Amazon | ナインタイル | カードゲーム・トランプ | おもちゃ 簡単な紹介 プレーヤー数 : 2-4名 対象年齢 : 6歳以上 種類 : スピード対戦型 紹介 : 「ナインタイル」の基本ルールは、それぞれの手元にある、9枚のタイルを自由に動かしたりひっくり返したりして、誰よりも早くお題どおりに並べるだけ。(公式サイトより)。 特徴 : ボードゲームというか、カードゲーム。ルールは簡単ですが、記憶力と素早さが重要です。 感想 脳トレに良さそう(子供に勝てませんでした。。。)。 瞬発力+記憶力が重要。 デザインがきれい じゃあ、家族の人気は? ラビリンス、カタン、モノポリーあたりが人気です。 ゲーム性もありますが、デザインとしてもきれいなものが多かったです。\nテレビゲームも面白いですが、ワイワイ喋りながらボードゲームをやるのも楽しかったです。 今回紹介したボードゲームはどれもある程度ルールを理解するところから始めないといけないですが、理解力や説明力なども必要になってくるので色んな楽しみがあるかなと思います。\n","date":1580558694,"dir":"post/2020/","id":"90f9355781403b92e844de8568863ae8","lang":"ja","lastmod":1580558694,"permalink":"https://blog.johtani.info/blog/2020/02/01/intro-board-game/","publishdate":"2020-02-01T21:04:54+09:00","summary":"年末、何種類かのボードゲームを家族で楽しみました。 家族の感想を交えて簡単に紹介しようかと思います。 家族や知人でボードゲームを購入するときの参","tags":["ゲーム"],"title":"ボードゲーム紹介"},{"contents":"実践Rust入門という本を買っていた(去年の7月だ。。。)のですが、積んであったので、時間を作って読み始めようかと。\n実践Rust入門[言語仕様から開発手法まで] | κeen, 河野 達也, 小松 礼人 |本 | 通販 | Amazon 経緯 もともとは、言語処理100本ノックはじめました(Rust)という感じで、触っていたのですが、場当たり的にやってても時間を持っていかれるだけだなということに気づいたのが最初です。\n今年の目標は、覚えられなので、ちょっとずつでもアウトプットしていこうってのもあり、 読書記録をつけつつ、読んでいこうかなぁと。\nどこまで読んだ? 2章の2-2-5までです。 前回、Rustの環境はセットアップしていたのですが、新PCに切り替わったので、rustupからはじめました。\nrustup rustupではデフォルト設定のままではなく、PATH変数の書き換えだけはしない形でインストールを行いました。\nPATH変数は.zshrcファイルで変更したかったためです(rustupコマンドに変更して貰う場合は.profileなどのファイルが変更されそうだったため)。\nインストールが終わったあとに.zshrcに以下の行を追加しました。\n### For Rust env source $HOME/.cargo/env 疑問点 ここまで読んだ疑問点です。\ncargo new helloしたあとにmain.rsに以下のmain()関数が出来上がっている!? fn main() { println!(\u0026#34;Hello, world!\u0026#34;); } 驚きましたが、cargo new hogeってやっても、おなじmain.rsができてました。デフォルトで出来上がるんですね。どんな超能力!?と思ってしまいましたw\ncargo new helloして出来上がったCargo.tomlに著者名が入力されていた。 authors = [\u0026#34;Jun Ohtani \u0026lt;メアド\u0026gt;\u0026#34;] なんで?と思いました。まだ解明してないです。 本を読んでいけばわかるかな?\n予想:gitの設定(~/.gitconfig)に氏名とメアドが設定されているので、これを利用しているのかな? ","date":1580475492,"dir":"post/2020/","id":"7fcfaa8dd34dbd508f19e8ca0fcfda0f","lang":"ja","lastmod":1580475492,"permalink":"https://blog.johtani.info/blog/2020/01/31/start-reading-bicycle-book/","publishdate":"2020-01-31T21:58:12+09:00","summary":"実践Rust入門という本を買っていた(去年の7月だ。。。)のですが、積んであったので、時間を作って読み始めようかと。 実践Rust入門[言語仕","tags":["rust","読書"],"title":"実践Rust入門はじめました"},{"contents":"12月に退職しますブログを書きましたが、その後どうなったのか?という話をしてないなと思ったので、一応現在の状況を書き留めておこううかと。\n結論 実際にはフリーランスとして働き始めてます。検索周りをお手伝いするお仕事を。読解いとこあれば所属するつもりでもいるし。\n\u0026mdash; Jun Ohtani (@johtani) January 27, 2020 フリーランスとして最初の仕事はElasticsearchではなく、Azure Cognitive Searchの支援だったりします。Esで困ってる方の手伝いもしますので、興味ある方はDMください。\n\u0026mdash; Jun Ohtani (@johtani) January 31, 2020 2020年1月24日が、正式なElasticの退職日でした(有給休暇消化してた)。 で、現在のステータスはこのツイートです。\n現在の心境 どこかに就職してガッツリ検索もやりたいし、いろんな会社の検索やElastic Stackに関するお手伝いをするのにも興味があるし、どちらにも興味がある状況です。まぁ、検索に興味が尽きないというのだけは決まってますかね。\n悩んでいるところに、幸いにもAzure Search周りで手伝ってほしいという話が舞い込んできたので、フリーランスとしてお手伝いをさせていただいてます(現時点で、半稼働で、が3月末まで)。\nElastic Stackなどの知見もあるのでのお手伝いをするというのもありかなぁと。お仕事発注してもいいな?という方があれば、TwitterのDMなど、連絡をいただければと。\n現在の状況でした。\n副業ができる会社に就職するのがどっちもできていいのかも?\n","date":1580470659,"dir":"post/2020/","id":"c61a5bda3f1667498626ae52ad0362e0","lang":"ja","lastmod":1580470659,"permalink":"https://blog.johtani.info/blog/2020/01/31/start-freelance/","publishdate":"2020-01-31T20:37:39+09:00","summary":"12月に退職しますブログを書きましたが、その後どうなったのか?という話をしてないなと思ったので、一応現在の状況を書き留めておこううかと。 結論","tags":["転職"],"title":"フリーランスはじめました(仮)"},{"contents":"ブログ移行日記(その4)です。その他の記事はこちら。\nブログ移行日記(その1) ブログ移行日記(その2) ブログ移行日記(その3) ブログ移行日記(その5) 前回までで、なんとなく移行は終わってます。 今回はテーマで使えるようになっているブログの検索機能の導入の話です。\n検索サービスはAlgoliaを利用します。 OctopressのころはElastic社のサービスであるElastic Site Searchの機能を利用して、クローリングしてから検索できるようにしていましたが、Hugoで導入できるモジュール?があったので、今回からこちらに移行しました。\n参考記事 Clean White ThemeのREADME(Algoliaの設定方法) 参考ブログ:hugoで作ったblogにalgoliaで全文検索機能を追加する Algoliaとは? 検索のas-a-serviceをやっている会社です。Wikipediaによると本社はサンフランシスコにあるみたいですね(フランスの会社のイメージでした。起業された方がフランス出身だからかなぁ?)。 クラウドで検索インデックスを保持でき、API経由で検索したり登録したりできる感じのサービスです。内部で使われているのはOSSではない独自の検索エンジンです。\nクラウドで提供されているサービスなのでサクッと検索を使い始めることができるのがいい点ですね。 また、小さな非商用のプロジェクトにフリーで利用できるプランも提供されているようです(2020年1月現在)。\nAlgoliaのサービス登録からインデックス作成 私が利用しているテーマで設定する方法の記載があったので手順の通りにやってみました。 大きく2つの作業(Algolia側とHugo側)が必要です。まずは、Algoliaで必要な作業から。作業の流れだけ記載しておきます。詳細は「Static site search with Hugo + Algolia」の3)を確認してください。\nAlgoliaのサインアップ(すでにアカウントがあれば不要) New Applicationの作成(名前とプランの指定) リージョンの指定 インデックス名の指定 APIキーを確認 です。これで、Algolia側の準備は完了です。\n今回は関係ないですが、Algoliaの管理画面で、利用状況(データ登録などの操作回数、クエリの回数、インデックスに保存されているレコード数)の確認が可能です。 ほかにも有料プランを利用するとAnalyticsなどもできるようです。\nHugo側で必要な設定 今度はHugo側です。Hugoのサイトのディレクトリに移動してからの作業です。\n仕組みとしては、\nHugoのoutput機能でAlgolia向けのJSONファイルを生成する Node.jsのライブラリを使用してAlgoliaに1.で生成したJSONを登録、更新する 検索画面の作成 という流れになります。 ですので、作業としては以下のとおりです。\nOutput出力の設定(すでにテーマ側で設定されているので、特に作業は必要なし) npm環境の構築(Hugoのconfig.tomlと同じディレクトリ階層) Node.jsのインストール(必要であれば) npm環境の初期化 npmでatomic-algoliaのインストール atomic-algolia向けの設定(登録のためのAPI関連の設定) Algolia向けJSONの出力設定 検索関連の設定 content/search/placeholder.mdの作成 検索用のAPIキーなどを設定 npm関連の作業 以下、npm関連の作業です。\nNode.jsのインストール(必要であれば) 割愛します。環境に合わせてインストールしてください。私はnvm経由でインストールしています。 npm環境の初期化 Hugoのディレクトリでnvm initを実行 npmでatomic-algoliaのインストール Hugoのディレクトリでnpm install atomic-algolia --save atomic-algolia向けの設定(登録のためのAPI関連の設定) Hugoのディレクトリに.envファイルを作成し、以下を設定します。 Algolia向けJSONの出力設定 特に変更なし(config.tomlに少し設定があります)。 ALGOLIA_APP_ID=AlgoliaのApplication ID ALGOLIA_ADMIN_KEY=AlgoliaのAdmin API Key ALGOLIA_INDEX_NAME=先程作ったインデックス名 ALGOLIA_INDEX_FILE=public/algolia.json 最後のALGOLIA_INDEX_FILEは固定文字列でいいと思います。 hugoコマンドを実行するとpublicディレクトリ配下にalgolia.jsonというファイルが生成され、Algolia登録用のJSONが出力されています。\n余談 : algolia.jsonの出力の設定は、config.tomlに記載があります。また、JSONファイルのテンプレート自体はthemes/hugo-theme-cleanwhite/layouts/_default/list.algolia.jsonにあります。Algoliaに登録するデータの構造など変更をする場合はこのテンプレートをカスタマイズすれば良さそうです。\n検索関連の設定 実際に検索の画面を表示するために、検索用の画面と、検索用のAPIの設定が必要です。\ncontent/search/placeholder.mdの作成 /search/が検索用のページになります。空のファイルです。実際にはJavaScriptが検索用の窓を表示したりしてくれます(これが必要な理由がまだ不明だなぁ)。 検索用のAPIキーなどを設定 検索のためのAPIキーなどの設定が必要となります。テーマ作者の方のサンプルのconfig.tomlにパラメータは用意されています。 以下の値を設定します。\nalgolia_search = true algolia_appId = \u0026#34;AlgoliaのApplication ID\u0026#34; algolia_indexName = \u0026#34;作成したインデックス名\u0026#34; algolia_apiKey = \u0026#34;AlgoliaのSearch-Only API Key\u0026#34; 以上でAlgolia関連の設定などの作業が終了です。\nAlgoliaへのデータ登録方法 最後に、実際にデータを登録する必要があります。 手順は、以下のとおりです。\nhugoコマンドの実行(htmlと一緒に登録データのalgolia.jsonを生成) npm run algoliaコマンドの実行(atomic-algoliaを利用してAlgoliaにデータを登録) 設定などが問題なければ、Algoliaの管理画面で登録ができているはずです。 実際にブログのデプロイにはdeploy.shというファイルをこちらを元に作成して使っています。このなかで、hugoコマンド実行後にnpm run algoliaを実行するようにしいます。\n今後の課題 Hugoで生成された記事はそれぞれのブログポスト以外に、タグごとのページも生成されています。 こちらも実はAlgoliaのインデックスに登録されていて、タグを入力すると、タグ名のリンクが出てきます。\nこちらはelasticsearchで検索したときの検索結果です。1件目はタグページです。\nこれらのページはAlgoliaに登録しないようにするのが良さそうかな?と考えているところです(考えてるだけ)。\n2020/01/29更新\nlist.algolia.jsonを編集して、記事だけをインデックスするように修正しました。 テーマに存在するlayouts/_default/list.algolia.jsonを、自分のところにコピーし、次のように変更しました。if文を1行追加して、postという種類のものだけを出力するようにしました。\n{{/* Generates a valid Algolia search index */}} {{- $.Scratch.Add \u0026#34;index\u0026#34; slice -}} {{- $section := $.Site.GetPage \u0026#34;section\u0026#34; .Section }} {{- range .Site.AllPages -}} {{- if or (and (.IsDescendant $section) (and (not .Draft) (not .Params.private))) $section.IsHome -}} {{- if (and (eq .Section \u0026#34;post\u0026#34;) (ne .URL \u0026#34;/post/\u0026#34;)) -}} {{- $.Scratch.Add \u0026#34;index\u0026#34; (dict \u0026#34;objectID\u0026#34; .UniqueID \u0026#34;date\u0026#34; .Date.UTC.Unix \u0026#34;description\u0026#34; .Description \u0026#34;dir\u0026#34; .Dir \u0026#34;expirydate\u0026#34; .ExpiryDate.UTC.Unix \u0026#34;fuzzywordcount\u0026#34; .FuzzyWordCount \u0026#34;keywords\u0026#34; .Keywords \u0026#34;kind\u0026#34; .Kind \u0026#34;lang\u0026#34; .Lang \u0026#34;lastmod\u0026#34; .Lastmod.UTC.Unix \u0026#34;permalink\u0026#34; .Permalink \u0026#34;publishdate\u0026#34; .PublishDate \u0026#34;readingtime\u0026#34; .ReadingTime \u0026#34;relpermalink\u0026#34; .RelPermalink \u0026#34;html\u0026#34; .Params.Description \u0026#34;title\u0026#34; .Title \u0026#34;type\u0026#34; .Type \u0026#34;url\u0026#34; .URL \u0026#34;weight\u0026#34; .Weight \u0026#34;wordcount\u0026#34; .WordCount \u0026#34;section\u0026#34; .Section \u0026#34;tags\u0026#34; .Params.Tags \u0026#34;categories\u0026#34; .Params.Categories \u0026#34;author\u0026#34; .Params.authors \u0026#34;content\u0026#34; .Params.Description \u0026#34;excerpt_html\u0026#34; .Params.Description \u0026#34;excerpt_text\u0026#34; .Params.Description \u0026#34;summary\u0026#34; .Summary)}} {{- end -}} {{- end -}} {{- end -}} {{- $.Scratch.Get \u0026#34;index\u0026#34; | jsonify -}} まとめ これで、ブログ内記事検索ができるようになります。 Algoliaは個人の非商用利用の場合、フリープランが用意されているのがありがたいですね。 まだ、Hugoと連携しただけで、Algolia自体でどんな機能があって、どんなことができそうかといったところは調べていませんが、簡単に利用できるのはとても助かります。\nまぁ、個人ブログの検索機能ってそんなに使う人はいないんですが、自分としては便利かなぁと。\n","date":1580186404,"dir":"post/2020/","id":"d9018f459d3c94a91e92b459e152f7e7","lang":"ja","lastmod":1580283604,"permalink":"https://blog.johtani.info/blog/2020/01/28/introduce-algolia/","publishdate":"2020-01-28T13:40:04+09:00","summary":"ブログ移行日記(その4)です。その他の記事はこちら。 ブログ移行日記(その1) ブログ移行日記(その2) ブログ移行日記(その3) ブログ移行日記(","tags":["ブログ"],"title":"ブログ移行日記(その4) - 検索機能(Algolia)の導入"},{"contents":"ブログ移行日記(その3)です。その他の記事はこちら。\nブログ移行日記(その1) ブログ移行日記(その2) ブログ移行日記(その4) ブログ移行日記(その5) 今回は、Hugoの設定とテーマの一部変更した点について記載します。\n設定ファイル(config.toml) Hugoの設定ファイルはconfig.tomlになります。hogo new siteコマンドで生成したディレクトリの中にデフォルトで含まれていますが、こちらではなく、テーマの作者が用意してくれたconfig.tomlを元に変更を加えました。\nちなみにテーマの作者の方が設定とコンテンツを含めたサンプルも公開してくれています。設定やディレクトリの構成はこちらを参考にしました。\n設定ファイルで変更した項目は以下のとおりです。\nサイトのタイトルや説明など 特記することはありません。好きなように変えました。\nbaseurl title SEOTitle description keyword slogan sidebar_about_descrption 画像関連(ヘッダーや著者近影) 画像の置き場はstatic/images/ディレクトリですが、設定ファイルには images/から設定します。\nheader_image : ブログのヘッダー背景 sidebar_avatar : 著者近影 言語周り(特に多言語対応する予定は無いのですが) languageCode = \u0026ldquo;ja\u0026rdquo; defaultContentLanguage = \u0026ldquo;ja\u0026rdquo; オフにした機能、削除した項目 freands = false bookmarks = false 上記の設定変更以外に、[[params.bookmark_link]]や[[params.friend_link]]も削除。\n中国のサービスや、特化した設定など。\nBaidu Analytics関連 Disqus proxy関連 Reward(wechat pay \u0026amp; alipay関連) params.social関連 rss = true twitter linkedin github ほかはすべてコメントアウト。\n外部サービス関連 disqusShortname : Disqusのショートネーム googleAnalytics : Gooogle AnalyticsのトラッキングID algolia関連 : 別のブログ記事として、設定方法などを書きます。 追加した設定(昨日のブログで説明済み) Octopressと同じ形のパーマリンク [permalinks] post = \u0026#34;/blog/:year/:month/:day/:slug\u0026#34; Markdownファイル中のHTMLタグ表示 [markup.goldmark.renderer] unsafe = true 以上が設定ファイル関連です。\nテーマの変更点 テーマそのままでは問題があったり、独自に変更したいという点があったので、いくつか変更をしています。\nフォントの変更 そのままテーマを適用するだけでうまく行けばよかったのですが、フォントの問題が発生しました。テーマの作者の方が中国の方だから?かどうかはわかりませんが、デフォルトのままだと中華フォントになってしまいました。\nあー、中華フォントだな。 pic.twitter.com/OvHpY4LSp1\n\u0026mdash; Jun Ohtani (@johtani) January 16, 2020 config.tomlにcustom_cssという設定があり、こちらで指定したCSSのファイルがテーマのlayouts/partials/head.htmlから読み込まれる仕組みがあるようなので、フォントに関するCSSをこの機能を使用して指定するようにしました。\nconfig.tomlの設定は次のとおりです(リスト)になっているので、複数のファイルに分割して、読み込ませることも可能なのかな?。\ncustom_css = [\u0026#34;css/custom-font.css\u0026#34;] cssファイルについては、static/css/custom-font.cssというファイルを作成し、次のような記載になっています。 フォントの指定と右側サイドバーの自己紹介の部分の文字色を変更するためのものです。\nbody, h1, h2, h3, h4, h5, h6, .navbar-custom { font-family: Helvetica,\u0026#34;Sawarabi Gothic\u0026#34;,Meiryo,\u0026#34;メイリオ\u0026#34;,\u0026#34;Hiragino Kaku Gothic ProN\u0026#34;, \u0026#34;ヒラギノ角ゴ ProN\u0026#34;,YuGothic,\u0026#34;游ゴシック\u0026#34;,Arial,sans-serif; } .sidebar-container { color: #404040; font-size: 14px; } faviconの変更 テーマにfavicon.icoが含まれていたのですが、せっかくなので独自のものに変えてみようかと。 ただ、残念ながら、こちらはパスおよびファイル名がlayouts/partials/head.htmlに直書きされていました。\n画像はimages配下にと思っていたのですが、このパスだけを変更するためにhead.htmlを自分の配下にコピーしてカスタマイズするのもどうかと思った(テーマに変更やバグ修正が入るたびに手動でコピーするのはなぁと思った)ので、static/img/favicon.icoファイルを作成しました。\nテーマよりもHugoのプロジェクトにあるファイルを優先するようなので、ファイルだけをプロジェクトに作成しました。\n記事一覧のテンプレート 記事の一覧で表示される、作成者と作成日時が英語表記でかつ、冗長な感じがしたので、スッキリさせるために、layouts/partials/post_list.htmlをテーマからコピーして、次のように変更しました。\n元の形式は : Posted by author Monday, January 2, 2006 現在の形式 : 2006-01-02 by author 記事のテンプレート 今回採用したテーマでは、記事の先頭に記事のセクションを元に目次を生成してくれるものでした。\n目次をコンテンツから自動で作ってくれるの便利だな。 pic.twitter.com/9bU3sLnUrm\n\u0026mdash; Jun Ohtani (@johtani) January 16, 2020 とても便利です。ただ、表示が「TOC」なんです。 英語でしかも「ToC」という表記ならまだ気にならなかったかもですが、大文字だと流石に気になったので、プロジェクトのlayouts/_default/single.htmlにコピーして「目次」という日本語に書き換えました。 このHTMLにテーマで修正が入った場合はどうしようかなぁ。。。というのが目下の悩みです。。。\nArchetypeテンプレートの追加 最後は新規記事を書くときに生成されるMarkdownのメタデータの追加です。 HugoにはArchetypesというのが存在します。\nHugoではhugo new 記事としたときに、記事の種類(content/ディレクトリ名=記事のタイプ)によって、作成するmarkdownファイルをテンプレートから生成する機能があります。この生成時に使われるのがarchetypesというディレクトリにあるファイルです。\n私のブログサイトでは、今のところcontent/postというブログの記事だけを書く予定ですので、archetypes/post.mdというファイルを作って以下のようなメタデータをhugo newしたときに自動で生成するようにしました(テーマにあったpost.mdファイルの代わり)。\n--- layout: post title: \u0026#34;{{ replace .Name \u0026#34;-\u0026#34; \u0026#34; \u0026#34; | title }}\u0026#34; slug: \u0026#34;{{ substr .Name 11 }}\u0026#34; author: johtani date: {{ .Date }} comments: true tags: [] draft: true --- タイトルはファイル名のハイフンを空白に変換したもの(実際にはファイル名は英語にしているので、使いませんが。。。) slugはファイル名の先頭からYYYY-MM-DD-という11文字を除いたもの。これは、OctopressのURLに合わせるために使用するURLの一部の文字列です。 author: johtani : 著者は私だけだから固定文字列 comments: true : ブログ記事にはDisqusのコメント機能を利用 tags: [] : 各内容によってタグを付けるが、生成時には空 draft: true : 明示的にこの行を消すまではドラフト記事としたいため という感じです。ほかにどのよなメタデータがあるのかまではまだ調べていないので、今後また適宜変更していくと思います。\nまとめ Hugoの設定や、テーマそのままではなく独自の変更を加えた部分を思い出して書き出してみました。\nこれで、Algoliaに関する部分以外はだいたい思い出して書いたと思います。 次は、Algoliaの使い方と設定について書き残す予定です。\n","date":1579853081,"dir":"post/2020/","id":"99c9c80a6532e4ea3b535c5a92d07a25","lang":"ja","lastmod":1579853081,"permalink":"https://blog.johtani.info/blog/2020/01/24/setting-hugo/","publishdate":"2020-01-24T17:04:41+09:00","summary":"ブログ移行日記(その3)です。その他の記事はこちら。 ブログ移行日記(その1) ブログ移行日記(その2) ブログ移行日記(その4) ブログ移行日記(","tags":["ブログ"],"title":"ブログ移行日記(その3) - Hugoの設定と微調整(テーマに合わせた)"},{"contents":"その他の記事はこちら\nブログ移行日記(その1) ブログ移行日記(その3) ブログ移行日記(その4) ブログ移行日記(その5) ブログ移行日記(その2)です。前回はHugoとは?というのと、自分が選んだテーマについて記載しました。 本家の手順などを参考にすると、Hugoにテーマを適用し、でHTMLを生成して、表示するところまでできるはずです。\n今回は、OctopressのmarkdownファイルをHugo用に変換する方法について紹介します。お手製ですが、Pythonスクリプトを作ったので、そちらも合わせて簡単に紹介する予定です。\n参考ブログ 「Octopress Hugo 移行」でググるといくつか出てきます。先人の知恵ありがたいですね。 ということで、私はこちらの2つのブログを参考にさせていただきました。ありがとうございます。\nOctopress から Hugo へ移行した - iriya-ufo\u0026rsquo;s blog OctopressからHugoへ移行する方法 | gam0022.net 画像のコピー 画像はそのまま上記参考ブログを元にsource/imagesからstatic/imagesにコピーしました。特にディレクトリ構造の変更とかもしませんでした。\nコンテンツのコピー こちらは、コピーのタイミングでいくつか変換などの処理を行いました。 ファイルの変換にはPythonのスクリプトを書きました。 自分向けの移行ツールなんで、ディレクトリ名とか引数にすらしてないです。。。\n参考ブログと同様の変換\nメタデータの日付変換 categoriesをtagsに変換 画像タグの変換 タイトル、画像のサイズなどに合わせていくつか分岐があります。 参考ブログとは異なる変換、変更\nコードブロックは無変換 0.60.0からCode Fencesに対応したみたいなので不要でした。 ディレクトリ構造の変更 ファイルを年ごとのディレクトリに格納(これまでは、全てのファイルが同一ディレクトリにあった) 拡張子の変更 (.markdown -\u0026gt; .md) メタデータにauthorの追加(自分しか書かないんですけどね) URLをOctopressに合わせる Google検索からの流入もあり、これまでのURLに変更はかけたくないなと。 こちらも参考ブログに記載があるので、そのまま参考にさせていただきました。\nslugについては、移行ツールでファイル名を元に追加する処理を書きました。\nHTMLを含んだMarkdownの対応 TweetやAmazonのアフィリエイトのリンクがHTMLタグでいくつかの記事に含まれており、デフォルトの設定だと表示されません。 config.tomlファイルに以下の設定を追記することで、出力されるようになりました。\n[markup.goldmark.renderer] unsafe = true 名前がunsafeなので、ちょっと気になりますが。。。 すべての記事を表示してチェックしてみたわけではないので、おかしな記事を見つけた方は連絡をいただけると助かります。\nまとめ OctopressのファイルをHugo用にコピーや変換した方法を思い出しながら書いてみました。基本的には参考ブログに上げた2つのブログを真似したものになります。\n次は、利用したテーマのサンプル設定を元に、自分用に変更した点などについて書き残しておこうかな?\n","date":1579775514,"dir":"post/2020/","id":"018b365b00dd3a6ad17c813d21590549","lang":"ja","lastmod":1579775514,"permalink":"https://blog.johtani.info/blog/2020/01/23/convert-md-from-octopress-to-hugo/","publishdate":"2020-01-23T19:31:54+09:00","summary":"その他の記事はこちら ブログ移行日記(その1) ブログ移行日記(その3) ブログ移行日記(その4) ブログ移行日記(その5) ブログ移行日記(その2)","tags":["ブログ"],"title":"ブログ移行日記(その2) - Markdownファイルの変換"},{"contents":"その他の記事はこちら\nブログ移行日記(その2) ブログ移行日記(その3) ブログ移行日記(その4) ブログ移行日記(その5) 起因 いつものツイートから始まる私の行動です。\n(もしかしたら前に一度おすすめしたかもですが) Goのtemplate構文に拒絶反応がなければHugo割と良いですよ〜。\n\u0026mdash; Nobuyuki Kubota (@nobu_k) October 10, 2019 ってことで、Hugo勧められたし、テーマが豊富だしということで、乗り換えた次第です。\n(元)同僚に教えてもらった記事を見てる。Gatsbyも気になるんだけど、デザインセンスないし、テーマが豊富なのがいいなぁ。/ Comparison of Gatsby vs Jekyll vs Hugo | GatsbyJS - https://t.co/yUbKiBmtMS\n\u0026mdash; Jun Ohtani (@johtani) January 9, 2020 一応Gatsbyのサイトにあった比較も見たのですが、テーマの豊富さが勝ちました。デザインを自分でやれるほどではないので。\n理由 乗り換えるに至ったのは主に2つの理由です。\nOctopressが更新されていない ページが増えてきてサイトの生成に時間がかかる 前に使っていたOctopressもJekyllというものがベースになっていました。 Jekyllは今でも更新があるのですが、Octopressが更新されなくなってしまったのと、Rubyがベースになっているため?なのかはわかりませんが、 ブログのページ数が増えてきて、サイトのビルドに時間がかかってくるようになりました。\n結果 まだ、改良点があるかもですが、とりあえず公開できる感じになったと思ったんで切り替えました。\n前のブログはこんな感じで、\n移行後はこんな感じです。\nHugoとは? 公式サイト こちらにあるように、Go言語で実装されているウェブサイト構築フレームワークです。 Go言語で実装されているのもあり、インストールが簡単でした。 Macを使っていますが、Homebrewでインストールができてしまいます。 他の方法もあるようでしたが、Emacsをインストールするのにbrewを入れているので、brewでインストールしました。\n使い方は色んな人が書いてるし、公式ドキュメントを見ていただけばいいかな。\nテーマとは? Hugoのサイトにテーマの一覧があります。 一応、個人のブログなので、それなりにデザインを入れつつ、他の人と違う感じにしたいなと。 テーマ一覧をざっと眺めて良さそうなのをピックアップしたら、最終的にこちらのテーマになりました。\nClean White それなりに更新されてますし、DisqusとSearch(Algolia)が使えるのでこのテーマに決めました。 テーマのインストール方法などはGitHubのREADMEの「Quick Start」に記載があります。\n私は、Hugo自体の設定などをGitHubで管理したかったので、git submoduleを利用して、次のような構成になりました。\nhugo - main repository ├── archetypes ├── content ├── data ├── layouts ├── public - github.com/johtani/johtani.github.io ├── resources ├── static └── themes └── hugo-theme-cleanwhite - github.com/zhaohuabing/hugo-theme-cleanwhite.git hugo : hugo new siteコマンドで作成されたディレクトリです。このディレクトリでまずgit initしました(このリポジトリはプライベートで管理してます)。 themes/hugo-theme-cleanwhite : テーマのQuick Startにあるgit submodule addコマンドでサブモジュールとしてテーマをインストールしました。 public : hugoが生成するHTMLのトップのディレクトリがこちらです。私はGitHub pagesを利用してブログを公開しているので、git submodule addでjohtani.github.ioをサブモジュールにしました。 Hugoで生成したHTMLなどをGitHub pagesで公開するときの手順などはHugoのドキュメントに記載がありました。\nまとめ Hugoに移行した理由や、Hugoとテーマの簡単な紹介でした。 テーマが豊富なのはデザイン力(りょく)がない身としてはありがたいですよね。 次はOctopressのmarkdownファイルをHugo用に変換したり、それに関する設定周りの話を書く予定です。\n","date":1579659814,"dir":"post/2020/","id":"a65bd31d4c3dab0a41712823a5d6002b","lang":"ja","lastmod":1579659814,"permalink":"https://blog.johtani.info/blog/2020/01/22/intro-hugo-and-theme/","publishdate":"2020-01-22T11:23:34+09:00","summary":"その他の記事はこちら ブログ移行日記(その2) ブログ移行日記(その3) ブログ移行日記(その4) ブログ移行日記(その5) 起因 いつものツイートから","tags":["ブログ"],"title":"ブログ移行日記(その1) - Hugoとテーマ"},{"contents":"5年くらい、Octopressを使用していましたが、更新されなくなっているのと、コンテンツの生成に時間がかかることもあり、 ほかのプラットフォームを使用するように変更しました。\nとりあえず、今回の移行で参考にした記事とかURLをリストアップしてみました。 詳細についてはまた明日以降で。\n参考記事 移行関連 : https://iriya-ufo.net/blog/2018/12/27/octopress-to-hugo/#github-pages- 移行関連 : https://gam0022.net/blog/2016/09/25/migrated-from-octopress-to-hugo/ Hugo自体の日本語紹介記事 : https://knowledge.sakura.ad.jp/22908/ Hugo概要 https://gohugo.io/ テーマ 一覧 : https://themes.gohugo.io/ 利用したテーマ : https://github.com/zhaohuabing/hugo-theme-cleanwhite データ移行 作ったスクリプト : https://github.com/johtani/from-octopress-to-hugo favicon 作ったサイト : http://emblemmatic.org/markmaker/#/ Algoliaセッティング 参考 : https://blog.uni-3.app/2019/01/02/hugo-algolia-search/ GitHub Pagesでの運用 https://gohugo.io/hosting-and-deployment/hosting-on-github/#types-of-github-pages 残タスク Amazonのアフィリンクをきれいに表示するlayoutか何かを用意する? ","date":1579166617,"dir":"post/2020/","id":"3c299a4d77be8b4f886ce9fcd23a2561","lang":"ja","lastmod":1579166617,"permalink":"https://blog.johtani.info/blog/2020/01/16/moving-to-hugo/","publishdate":"2020-01-16T18:23:37+09:00","summary":"5年くらい、Octopressを使用していましたが、更新されなくなっているのと、コンテンツの生成に時間がかかることもあり、 ほかのプラットフォ","tags":["hugo","ブログ","octopress"],"title":"OctopressからHugoへ移行中(まだ途中)"},{"contents":"今年も振り返りブログ書いてます。Sasukeがついてる。\n振り返り(2018年に書いた抱負から) まずは去年の抱負を元に。\nTOEIC 受けました。\nお。TOEICの点上がってた(まだまだだけど。。。)\n\u0026mdash; Jun Ohtani (@johtani) October 21, 2019 無事、上がってました。テストの点数を上げるのが目的ではなく、今の実力が どんな感じかというのを確認するために受けました。 前回までが低かったのもあるんですが。 また、数年後に受けてみるのかな?\nCfP見つけて応募 \u0026amp; いろんな場所に顔を出す 色んな所には顔を出しました。 CfPはそれほど出せていなく、とちぎRubyとDevRelJPで喋った程度かと。 12月に最終出社日を迎えたので、今後は顔を出したりCfP見つけて応募も、 一旦休憩に入る予定です。\nもっとブログ! 12月に入ってから、一気に増えてますねw Elasticでは結局それほどかけなかったなぁ。\nRustの継続 こっちは、書籍も買ったのに手がついてないです。 来年に書籍を読みながら再入門する予定です。\n開発の継続 一応ほそぼそと続けてますが、メンテナンスですね。 Analyzer向けのKibanaのプラグインのバージョンアップにだけ対応していたり。 年初にReact化には着手しました。 あとは、Luceneにちょっとしたパッチ(Lukeの画面とKuromojiのUniDic対応)を送った感じかな。もっとLucene周りやりたいかな。\n日本でエンジニア獲得! トレーナーやエンジニアが入社してくれました! が、私が退職してしまいますが。。。 私自体が次のステップに移らないとなぁと。 Elasticに興味がある人いたら、中の人を紹介できるので声をかけてください!\n振り返り(今年あったできごと) さて、ここからは今年の出来事を。\n検索技術勉強会発足 勉強会運営座談会 初フロリダ 初カナダ\u0026amp;初ナイアガラの滝 退職(予定) 検索技術勉強会ってのをはじめました(はじめましたブログはこちら)。 やっぱり検索の話を聞いたり考えたりするのが好きなので、もっといろんな話を聞く機会がほしいなぁと。ツイートすると何人かの知り合いが手を上げてくれたので、初めて見たのが2月でした。 所属会社もあったので、自分が全面に出ない形で運営に協力するという形式でやっています。なんだかんだでもう4回も開催できています。スピーカーへの声掛けなど、複数人で運営するとそのあたりが多様性が出るし、楽になるのですごくいいなぁと。 来年も2月か3月にやりたいねと話をしているところです。興味のある方は、ぜひスピーカーを!\nで、その流れで、他の勉強会の運営ってみんなどうしてるんだろう? という疑問も出てきたので、勉強会運営座談会なるものもやってみました。少人数で集まって、勉強会の運営ってどんなやり方してます?どんなことに困ってます?みたいなのを共有してみました。 自分自身がそれほど、ほかの勉強会の運営に顔を出してたわけでもなく、やり方をみんなはどうやって共有してるのかなぁ?というのが気になったので。 思った以上に属人化してるのかもなぁというのが感想でした。 ドタバタしてたので、あれからやってませんが、共有する勉強会みたいなのも面白いのかも?\n今年も2回ほどElasticの社内イベントで海外に行かせてもらいました。 5月にフロリダと11月にトロントでした。 フロリダでは、NASAにも行けたし、トロントでは足を伸ばしてナイアガラの滝を見に行くなどもしてみました。こういう機会が定期的にあるのは、いいですよねぇ。\n最後は、退職イベントですね。5年5ヶ月勤めたElasticでの仕事が、12/6で最終出社日でした。実際の退職日は1/24となっています(現在有給休暇消化中)。長かったような、短かったような。日本で1人目で入社してさまざまなことをやらせてもらい、本当に色んな経験ができました。英語も上達したし。 ただ、外にいることでできることがありそうだなと感じたこともあってのこの決断でした。\n最終出社日以降、色んな人とランチさせてもらったりしています。 次に何をやろうかな?ってのんびり考えながら休んでいるところなので。 やっぱり、検索周りのことをやりたいなぁというのが念頭にあるので、そのあたりで模索中という感じです。 が、せっかくの機会なので、少しのんびりしようかなとも思ってます。 なので、プラモデルの作成や配達業(デス・ストランディング)をやってみたり、16インチMacbookのセットアップしながらブログ書いたりしています。 年明けに入ったら、プログラミングもちょっとやりたいな。\nあとこの場を借りて、ブログの欲しい物リストのものを送っていただいた皆様に感謝を述べさせていただきます。本当にありがとうございました!この感謝はまた何かの機会にでも!\n来年の抱負 ということで、来年の抱負です。\n職につく ブログプラットフォームの移行 プログラミング Rust再入門 検索の勉強 検索技術勉強会の継続 まぁ、まずは職につかないとですね。どこかに在籍しつつ、副業で検索周りのこととかやるのもありかもなぁと考えたりしています(プラモデルつくりながらw)。\nブログのプラットフォームをOctopressからHugoあたりに移行しようかなと思ってます。Octopress自体がもう開発がされてないようですし。Hugoだとテンプレート?テーマ?がそれなりにありそうなので良さそうかなぁと。移行プログラムも書かないとかな。新しいものを調べるのって楽しいですよね。\nプログラミングも復活させたいなと。どうしてもこれまでは、しゃべるのをメインにしていたので、後回しにしてしまっていたのもあります。まぁ、向いてないのかもと思ったりもしますが、下手の横好きなりに少しずつでも何かを改善したり作ったりしたいなと。 勉強会の運営周りですこし楽をするためのプログラム書いたりもしているので、この辺もブログに書こうかな?\nRustはTantivyというプロダクトも出てきているし、勉強しようと思って、自転車本を買いつつ、Kindleの肥やしにしているので、手を動かそうとおもいます。 ブログ書いてサボった場合の可視化しないとなw\n検索の勉強もやりたいなと。これまではElasticsearchに注力していましたが、ほかのプロダクトやサービスも調べてみたいなと。教えを請いに皆さんのところにお邪魔するかもしれないので、そのときは優しくしてください。\n今年始めた検索技術勉強会を今後も継続できるようにしたいなと。 で、運営周りを楽にできるような仕組みをもう少し導入できればなぁと考えていきたいなと思います。\nさて、嵐の曲も始まったし終わりです。\n今年も様々な方々に助けていただきました。また、最終出社日以降にランチを一緒にさせていただいたり、遊びに行かせていただいたりとありがとうございました。年明けもひましてるので、ぜひランチしましょうw\n来年はなにやってるんだろうなぁ? 今後も皆さんよろしくおねがいします!!\n","date":1577764743,"dir":"post/2019/","id":"35aa9e09db936aee7ec407c431816573","lang":"ja","lastmod":1577764743,"permalink":"https://blog.johtani.info/blog/2019/12/31/looking-back-2019/","publishdate":"2019-12-31T12:59:03+09:00","summary":"今年も振り返りブログ書いてます。Sasukeがついてる。 振り返り(2018年に書いた抱負から) まずは去年の抱負を元に。 TOEIC 受けました。 お。TO","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2019)"},{"contents":"このブログ書こうと思って、これまでMacのセットアップしてたんだった。。。\n普段、macOSの標準ターミナルを使ってます。 で、ターミナルを使うシーンは次のような感じです。\nブログのデプロイ(参考:Octopress環境のDockerイメージ化) ElasticsearchとKibanaの動作確認 Elasticsearchの起動用ターミナル Kibanaの起動用ターミナル プラグインの開発(elasticsearch-ingest-csv と analyze_api_ui) elasticsearchのリポジトリ kibanaのリポジトリ ingest-csvのリポジトリ analyze_api_uiのリポジトリ 上記のように1.以外については複数のターミナルをそれぞれのディレクトリで起動して使っています。 これらの3つのパターンのときに、毎回ターミナル(シーンによっては複数のウィンドウ)を開いて、ディレクトリに移動って大変だなと。\nウィンドウグループって? そこで、ターミナルに便利な機能がないのかな?と思い、メニューを見ていたところ「ウィンドウグループ」というのがあったので調べて、現在の使い方に至っています。\nウィンドウグループの使い方の説明はこちらです。\n使い方にあるようにウィンドウの場所、設定、タブなどを保存できます。 そして、「ウィンドウグループを開く」というメニューから保存しておいたグループを開くと、簡単に作業環境が再現可能になります。\n開くときのメニューはこんな感じです。\n作り方 ウィンドウグループの使い方に載ってます。 まずは、保存したいターミナルを開いて、開いたときに移動していたいディレクトリに移動します。 複数のタブやウィンドウを開いた状態にしたい場合は、複数ターミナルを起動して、それぞれ移動したいディレクトリに移動しておきます。\nグループとしてまとめたいウィンドウが起動できたら、あとは、「ウィンドウ」メニューの「ウィンドウをグループとして保存」を選択します。\nこれだけです。あとは、使いたくなったときに開くだけです。 簡単ですよね?\n作るときの注意点としては、複数のウィンドウグループを作りたいときは、 それぞれグループごとに作成しては、個別にやる必要があります。 現在開いているターミナルのうち、あれとこれをウィンドウにしたいというやり方はできないので、そこだけ注意点です。 環境ごとにプロファイル(バックグラウンドの色やテーマ)を覚えさせることができるので、1.のシーンだとIceberg、2.のシーンではBasic、3.のシーンではHomevrewで設定していたりします。 (ただ、Preztoのテーマをagnosterにしてしまったので、Basicだとプロンプトが見にくくてしょうがないのですが。。。)\n設定はどんな感じ?? ウィンドウグループの管理については、ターミナルの「環境設定」に管理用の画面があります。\nこの画面でいらないグループを削除したり、設定のエクスポート/インポートも可能です。\n私の使い方 3つの利用シーンは説明しました。 すべてのウィンドウグループを変更するたびにインポート/エクスポートしてます。 上記1.と3.のユースケースはほぼ変更がないので、エクスポートしたものを移植用に管理していますが、2.のユースケースについては、頻繁に更新しています(ElasticsearchとKibanaのバージョンをアップしないといけないので)。\nこのとき、MacのGUIで毎回設定をしているわけではありません。 エクスポートしたファイルは、.terminalという名のXMLファイルになっています。\nその中に、次のようなパスが記述されています。このバージョン番号の部分をアップデートのたびにemacsなどで変更し、ターミナルの管理画面で、削除してからインポートし直すだけで、バージョンアップに対応している感じです。\n\u0026lt;key\u0026gt;Tab Working Directory URL\u0026lt;/key\u0026gt; \u0026lt;string\u0026gt;file://johtani-mac-15.local/Users/johtani/tmp/elastic_stack/v7.5/elasticsearch-7.5.1/\u0026lt;/string\u0026gt; \u0026lt;key\u0026gt;Tab Working Directory URL String\u0026lt;/key\u0026gt; \u0026lt;string\u0026gt;file://johtani-mac-15.local/Users/johtani/tmp/elastic_stack/v7.5/elasticsearch-7.5.1\u0026lt;/string\u0026gt; まとめ ということで、標準ターミナルのウィンドウグループを使うと、よく開くディレクトリやウィンドウ、タブを覚えて置かせることができるので、それぞれの環境向けのターミナルを、好きなときに開くことができるようになります。 私は、ウィンドウは1つで複数のタブをウィンドウグループという形で覚えさせておくことで、各シーンの切り替え、もしくは併用を閉じたり開いたりを簡単にできるようにしています。\n他のターミナルソフトを使うと似たようなことが簡単にできたりするのかな? みなさんがどうやってこのような作業やってるのかな?ってのはちょっと気になるところです。\n余談(いつものようにツイートとその反応) ちなみに、みんなどんなターミナル環境なんだろう?と思いツイートしてみた結果はこちらです。 (コメントRTってうまいことひろえないのかなぁ?)\nMac標準のターミナル使ってる人ってどのくらいいるんだろ?iTermとか入れてるのかな?tmuxとか?\n\u0026mdash; Jun Ohtani (@johtani) December 11, 2019 Iterm2使ってtmux使って今はIterm2だなー\ncommand2回押すだけでターミナル出すくせが抜けん https://t.co/P8o4M1HSoj\n\u0026mdash; GO☆ | TAFDATA (@_gogoponz) December 11, 2019 Alacritty + tmux やなー。標準はもう使ってない。 https://t.co/HI7hPCg3uo\n\u0026mdash; Ryo HIGASHIGAWA (@biwakonbu) December 11, 2019 標準です https://t.co/W27e2pcq3j\n\u0026mdash; shin higuchi @Acroquest (@shin0higuchi) December 11, 2019 Macを買って以来、ずっと結局標準ターミナル以外使っていない感じ。珍しかったのか。。 https://t.co/Zjz32SgjC6\n\u0026mdash; Kazuhiro Hara™ (@kara_d) December 11, 2019 ","date":1577063679,"dir":"post/2019/","id":"1a1a8cc0040b356d06eacd22e0526476","lang":"ja","lastmod":1577063679,"permalink":"https://blog.johtani.info/blog/2019/12/23/whats-window-group-of-terminal/","publishdate":"2019-12-23T10:14:39+09:00","summary":"このブログ書こうと思って、これまでMacのセットアップしてたんだった。。。 普段、macOSの標準ターミナルを使ってます。 で、ターミナルを使う","tags":["misc"],"title":"macOS標準のターミナルのウィンドウグループが便利"},{"contents":"ドットファイル系(.emacsとか)をこれまでは、PCを引っ越すたびにコピーしてたんですが、いいかげん、GitHubとかで管理したいなと。\nで、ツイートしたところ(こればっかりだなw)、homeshick(homesick)が便利だよとの情報を得たので使ってみました。\nhomesick、正確にいうとhomeshickを使ってます。悪くないです\n\u0026mdash; 🤓k.bigwheel🤓 (@k_bigwheel) December 10, 2019 使い方とか 実物はGitHubで公開されていました。\nhttps://github.com/andsens/homeshick\n何者かというと、ホームディレクトリにあるドットファイル(.zshrcなど)をgitコマンドで管理するのを楽にしてくれるシェルの関数群みたいです。 インストールは至ってかんたんで、git cloneで持ってくるだけです。homeshickのリポジトリのREADMEに記載があります。\n使い方はTutorialsにあります。\nhomeshick generate ほげほげで管理する単位(castle)を作ります。ほげほげが名称です。今回私はdotfilesにしました。 homeshick track ほげほげ .zshrcで管理したいファイルを指定します。すると、homeshickが対象のファイル(ここでは.zshrc)をcastleの保存先ディレクトリにコピーしてから、シンボリックリンクをホームディレクトリ上に作ってくれます。 homeshick cd ほげほげで、castleの実際のディレクトリに移動します。実態は.homeshick/repos/ほげほげです。 git remoteコマンドでcastleとGitHubの関連をつけて、あとは、普通にgitコマンドでコミットしたりすればOKです。 すごく簡単に導入できました。あとは、実際にtrackしたいファイルを追加していく感じです。 現状は、.zshrc、.gitconfigあたりを管理しています。 ついでに、homebrewでインストールしたものもbrew bundle dumpで出力して、homeshickで管理することで、brewでインストールしたものの管理もできそう(参考)。\nってことで、至極かんたんでした。すばらしい。\n参考 homeshick Tutorials Qiita : homeshickを使ったdotfilesの管理 ","date":1576624266,"dir":"post/2019/","id":"80c8fca02ebfecc7a931dad1ec38466e","lang":"ja","lastmod":1576624266,"permalink":"https://blog.johtani.info/blog/2019/12/18/introduce-homeshick/","publishdate":"2019-12-18T08:11:06+09:00","summary":"ドットファイル系(.emacsとか)をこれまでは、PCを引っ越すたびにコピーしてたんですが、いいかげん、GitHubとかで管理したいなと。 で","tags":["misc"],"title":"homeshick導入"},{"contents":"Macbook Proが新しくなり、OSがCatalinaになっちゃいました。 これまで使ってた、.bash_profileをコピーしてターミナルを立ち上げたところ、 なんか色々と設定が動いてないな?と思ったら、zshがデフォルトに切り替わってました。\nということで、デフォルト変わったし、時間あるしzshってどんな感じなのか調べてみようと。\n準備前(ツイート) で、ツイートをしたところ、海外の方?より返信が来ました。\nI have a series of posts explaining the transition: https://t.co/dz8QNjxxGf\n\u0026mdash; Scripting OS X (@scriptingosx) December 10, 2019 おもしろそうなので、ざっくりと読んでみました。zshを利用されているTwitterの知り合いの何人かからはzsh + oh-my-zshがいいよとコメント頂いてたんですが、\nMoving to zsh Catalinaからzshがデフォルトになるからと、手元の環境を変更するための話をブログにまとめてくれてます。\nMoving to zsh\nサラッと読んだので、いくつか抜粋すると\nbashでいくつか今設定しているものがあるのでその説明 alias - ファイルをそれぞれの拡張子ごとにアプリを切り替えてる(openコマンドの利用例があって参考になりました)。 functions - manコマンドのときに新しいWindowひらいたりとか shell settings - 大文字小文字関係なくファイル名をTabで候補を表示したり、historyをターミナル個別ではなく共有できるような設定にしたり prompt - 現在のディレクトリがどこかとか表示したり zshの設定ファイル群の説明 shellオプションの抜粋 といった感じでした(途中で読むのやめましたが。。。)\n面白かったのは、Suffix Aliasesです。 ファイル名だけをターミナルで指定すると、拡張子に応じて起動するコマンドを切り替えたりできると(結局まだ採用はしてないですがw)\n結局? 結局、上記ブログを読んでいろんなオプションあるんだなぁ。と思ったのですが、手っ取り早く試すためにPreztoをインストールしました。 以下のような構成になってます。\nなるほど、これがzsh + prezto + powerline fontか。前までgit-promptを拾ってきてbashに組み込んでたけど、ブランチ表示されるし便利だな。 pic.twitter.com/Z2ArBgRZey\n\u0026mdash; Jun Ohtani (@johtani) December 12, 2019 Mac標準ターミナル Iceberg プロファイル Powerline font Prezto agnoster theme - prompt agnoster or ~/.zpreztorc の変更 .zshrcにいくつかaliasなどを追加。参考:gist Preztoのデフォルトでlessなどからエディタを立ち上げるとnanoが起動したので、vimに変更 Preztoが作る設定と自分の設定を混ぜたくなかったので、.zshrcでinit.zshを呼び出し になりました。フォントサイズだけはちょっと大きくしました(老眼ェ。。。) ターミナルの参考にさせていただいたブログは「preztoでzsh構築した時のメモ 」です。\nターミナルソフト(余談?) terminalも人によっては、色んなものを使ってたなと思いツイートしました。 結構みなさん標準のterminalを使ってるみたいでした。ただ、私が聞いたこともないターミナルソフトもちらほらあったので、色々あるんだなぁと。\nMac標準のターミナル使ってる人ってどのくらいいるんだろ?iTermとか入れてるのかな?tmuxとか?\n\u0026mdash; Jun Ohtani (@johtani) December 11, 2019 ","date":1576542903,"dir":"post/2019/","id":"f3ef819656f68b87a91c53afbd441fec","lang":"ja","lastmod":1576542903,"permalink":"https://blog.johtani.info/blog/2019/12/17/move-to-zsh/","publishdate":"2019-12-17T09:35:03+09:00","summary":"Macbook Proが新しくなり、OSがCatalinaになっちゃいました。 これまで使ってた、.bash_profileをコピーしてターミナルを立ち上げ","tags":["misc"],"title":"zshへの移行"},{"contents":"最近使っていたPCが手元からなくなったので、16インチ Macbook Proをセットアップしているところです。 で、時間もあるのでこれまでほったらかしてきた、このブログの環境をちょっと変更しようかなと。\nまずは、変更するにしても、Octopressのブログの環境自体は必要です。 実際に、移行する前のこの記事自体も書いているわけですし。\nただ、今後なくなる環境をローカル環境にセットアップするのもどうかと思い、Docker環境にしてみました。\n参考 \u0026ldquo;Octopress Docker image\u0026quot;でググって出てきたサイトを参考にしました。\n参考ブログ:Octopress in a Docker Container\nセットアップからDockerイメージのビルドまで Docker for Mac自体もインストールしていなかったので、インストールしておきます。 参考ブログの方がGitHubのリポジトリにDockerfileをアップしてくれているので、手順に従い、cloneします。 cloneしたDockerfileの3行目にENV LC_ALL C.UTF-8を追加します(UTF-8でブログを書いており、previewした場合にエラーが出たため) 参考ブログにある「Build the docker image」の手順に従い、Gemfile、.gitconfigをコピーしてイメージをビルドします。 参考ブログの「Rakefile」にあるように、自分のoctopress/RakefileのProcess.spawn(...)にアドレスを追加します(Dockerコンテナの外からアクセスできるように) 自分のoctopressにあるGemfile.lockを削除しました(ビルドしたイメージにはいるGemと一部バージョンが異なる記載のものがあったため) ここまでで、\nDocker run 実際にコンテナを実行するためのスクリプトを書きました(書いたと言っても参考ブログにある起動コマンドを叩いてるだけですが。。。)\nlaunch-octopress-docker.shというファイル名で以下のコマンドを実行してるだけです。\n!/bin/sh docker run -p 4000:4000 --rm --volume /Users/johtani/projects/blog/octopress:/octopress --volume /Users/johtani/.ssh:/home/blogger/.ssh -ti blog/octopress /bin/bash このシェルを起動すると、Dockerコンテナにbashで接続し、/octopressディレクトリにログインしています。 あとは、いつものようにrake new_post[\u0026quot;....\u0026quot;]で新規記事のテンプレートを作成したりすればOKです。\nrake generate; rake previewと実行してからローカルのブラウザでhttp://localhost:4000に接続すればプレビューも可能。\nということで、このDockerファイルとかを持っておけば、他の環境でもかんたんにOctopressの環境が再現できそうです。 先人の知恵有り難し。 これで、クリーンなまま他のブログ環境に移行できそう。\n追記(2019/12/17) Docker環境でいくつか問題があったので、追記しておきます。\nDocker for Macが再起動しない Docker for MacがCatalina環境だと問題があるみたいでした。 CPUの数やメモリの数を変更してDockerを再起動したところ、ずっとStartingのまま。\n解決方法としては、launchctlの設定に$PATHを追加するみたい。これで、問題なく起動するようになった気がする\nsshの設定ファイルの問題 .ssh/configにMacのKeyChainを利用する設定を記載してるんですが、Ubuntu上だとこの設定のせいで、エラーが出てしまいます。 IgnoreUnknownという設定で、知らないオプションがあったら無視するという設定になる模様。ということで、Dockerコンテナ上でrake deployのときにエラーが出てたのが解消できました。\n","date":1576458061,"dir":"post/2019/","id":"1abc586d67f0b6c05fd5e60f25492340","lang":"ja","lastmod":1576458061,"permalink":"https://blog.johtani.info/blog/2019/12/16/dockernize-octopress/","publishdate":"2019-12-16T10:01:01+09:00","summary":"最近使っていたPCが手元からなくなったので、16インチ Macbook Proをセットアップしているところです。 で、時間もあるのでこれまでほったらかしてきた","tags":["octopress"],"title":"Octopress環境のDockerイメージ化"},{"contents":"本日、Elasticでの最終出社日でした。実際の退職日はまだ先ですが、有休消化という感じです。\n思い返せばもう5年と5ヶ月も前ですが、Elastic(当時はElasticsearchって社名だった)に参加しました。\n社名も変わりましたし、プロダクトの数も増えたし、IPOもしました。 初の外資+スタートアップということもあり、ものすごくエキサイティングな5年半でした。 Elasticを離れはしますが、検索自体にはまだまだ興味があるので、LuceneやElasticsearchになにかしら関わる感じのことをする予定です。 検索技術勉強会も今後もやっていきますし。\nただ、激動の5年半だったので、退職日までちょっとゆっくりしようと思っています。 次にどんなことをするのかはまた、別の機会にでも。\nおまけ ということで、まぁお約束です。\nほしい物リストはこちら\n","date":1575615090,"dir":"post/2019/","id":"1bbf2ef67f096960e13d8578fa544536","lang":"ja","lastmod":1575615090,"permalink":"https://blog.johtani.info/blog/2019/12/06/leaving-elastic/","publishdate":"2019-12-06T15:51:30+09:00","summary":"本日、Elasticでの最終出社日でした。実際の退職日はまだ先ですが、有休消化という感じです。 思い返せばもう5年と5ヶ月も前ですが、Elas","tags":["転職"],"title":"退職します"},{"contents":"これは、情報検索・検索エンジン Advent Calendar 2019 の 4 日目の記事です。\n1日目から、質の高いエントリーが続いていましたが、一旦休憩して頂く感じの記事になってます。気軽に読んでくださいw。Advent Calendarつくらないの?と煽ったのもあり、穴を埋めようかなと。 発端 ちょっと先ですがこういうのやります。実装寄りの話やOSS開発に興味がある方,きてください~ / Lucene 版 #Kuromoji のコードを読む会(辞書ビルダー編) https://t.co/NgEmUohoPo #kuromoji\n\u0026mdash; Tomoko Uchida (@moco_beta) September 6, 2019 「Lucene 版 #Kuromoji のコードを読む会(辞書ビルダー編)」という勉強会があり、参加したところ、UniDicの辞書のビルドがコケるという話を聞いたんで、ちょっとやってみるかと。\nちなみに、Kuromojiとは、Apache Luceneに入っている、日本語向けの形態素解析ライブラリです。IPAdicの辞書を内包しており、SolrやElasticsearchといった、Apache Luceneを利用している検索エンジンで手軽に使える形態素解析ライブラリになっています。が、対応している辞書がデフォルトだとIPAdicなのです。\n問題点 LUCENE-4056というIssueが上がっています。\nbuild.xmlには記載はないけど、辞書のビルダーは対応していそうな雰囲気を醸し出しているので、試してみたというのが発端?かと。で、実際に動かしてみると動かない点がありましたと。\nまた、Issueの会話で出ていたUniDicの辞書のライセンスの話もありました。 ただ、UniDicがライセンスを変更したので、このあたりはクリアできそうかなと。\nパッチ ということで、動かしてみていくつか修正してパッチを作りました。\nhttps://github.com/apache/lucene-solr/pull/935\n最近のLuceneはGitHubでプルリク遅れるのが便利ですね。 そんなに大したことはやってないです。以下の点が問題だったので直しています。\nIPAdicとUniDicで語彙定義ファイルのCSVの形式(カラムの数)が異なる unk.defのカラム数も異なる あとは、辞書のダウンロードの部分やbuild.xmlでの処理を追加した形です。 このプルリクを適用したlucene-solrのソースディレクトリを持ってきて、手元でjarをビルドすれば普通はIPAdicの辞書を内包したkuromojiのjarファイルが出来上がります。\nlucene/analysis/kuromoji/build.xmlファイルを、このGistにあるように変更して、ant build-dictとやれば辞書のビルドが可能です。 また、cd lucene/;ant jarとすれば、UniDicの辞書を内包したjarファイルもビルドできます(lucene/build/analysis/kuromojiの下にjarファイルができあがります)。\n確認? 一応、パッチは動くのですが、パッチ自体はUniDicの辞書をビルドする仕組みはオフのままです。なので、テストをどうやろう?というところでやなんで止まっています。。。\nただ、実際に作ったパッチできちんとIPAdicとUniDicがそれぞれビルドできているかの確認はしないとなと。\nということで、2つのjarファイルを読み込んで、それぞれトークナイズして、その出力を表示するツールを作ってみました。\n上記パッチを適用したlucene-solrのソースを持ってきて、IPAdicの辞書を内包したkuromojiのjarファイルと、UniDicの辞書を内包したjarファイルを用意し、ツールの支持に従って、ファイルをディレクトリに配置して、実行すれば以下のような出力がされるようになっています(とりあえず作ったものなので、Javaファイルにトークナイズしたいテキストを書かないといけないのですが)。\nたとえば、「自転車と自動車の違いはなんでしょう?」という文字列を入力すると、以下のような出力になりました。\n+++ ipadic ++++++++++++++ token[0] is [自転車] token[1] is [と] token[2] is [自動車] token[3] is [の] token[4] is [違い] token[5] is [は] token[6] is [なん] token[7] is [でしょ] token[8] is [う] +++ unidic ++++++++++++++ token[0] is [自転] token[1] is [車] token[2] is [と] token[3] is [自動] token[4] is [車] token[5] is [の] token[6] is [違い] token[7] is [は] token[8] is [なん] token[9] is [でしょう] UniDicは[短単位]で語彙が扱われるため、「自転車」や「自動車」がそれぞれ「自転」「車」、「自動」「車」という形でトークナイズされていることがわかります。\nどちらがより便利なのか?というのは用途によっても変わってくるかと思いますが、検索の転置インデックスとしては、より短い単語で区切られている方が、より多くの文書にヒットする可能性が高くなるので、便利な可能性が高いです。\nまとめ ということで、パッチを作ってみたものの、まだ取り込まれていない状況です。 着地点をどうするかって話かなと思っています。興味があれば遊んでみていただければと。\n将来的には、辞書をjarから切り離して別のディレクトリやjarとして使えるようにしようというIssueも作られています。こちらがすすめば、UniDicだけでなく、その他の辞書を切り替えながら使えるようになる日が来るのではないでしょうか?\n","date":1575385200,"dir":"post/2019/","id":"c2d39f2f7fe6cb69fc8efb6c5495c932","lang":"ja","lastmod":1575385200,"permalink":"https://blog.johtani.info/blog/2019/12/04/about-lucene-4056/","publishdate":"2019-12-04T00:00:00+09:00","summary":"これは、情報検索・検索エンジン Advent Calendar 2019 の 4 日目の記事です。 1日目から、質の高いエントリーが続いていましたが、一旦休憩して頂く感じの記事になって","tags":["Lucene"],"title":"Apache LuceneのKuromojiのUniDicビルド対応パッチについて"},{"contents":"Elastic stack (Elasticsearch) Advent Calendar 2019の1日目の記事になります。\nまだ、1ヶ月を残してますが、簡単に今年起こったことを振り返ってみようと思います。毎年恒例ですね、ここ数年。\nElastic Stack 6.6.0リリース(1月) リリース記事はこちら\nElastic APMが6.6のリリースと同時にElastic CloudでAPM Serverが無料で利用できるようになったのが地味に便利でした。APMのデモをやるために、それまでは手元にAPM Serverの起動が必要だったので。。。\nユーザーの方たちにはIndex Lifecycle Management(インデックスライフサイクル管理:ILM)がリリースされたのが便利だったと思います。 まだ、ベータでしたが、インデックスの世代管理を格段に便利にしてくれるツールになり、現在では必須アイテムとなっています。 もう一つ、地味に便利なのは、KibanaからElasticsearchへの接続を複数指定できるようになった点かと思います。\nElatic Common Schemaのベータリリース(2月) リリース記事はこちら\nElastic Stackではメトリック、APM、ログなど、様々なデータを一元的に可視化することができるという利点があります。ただ、一元的にデータを可視化、検索するためには異なるデータセットに統一されたフィールド名が欠かせません。そのための手段としてElasticが公開したのがElastic Common Schemaです。 各種データの項目名、型などを共通化する仕様をGitHub上で公開しています。最近のBeatsのモジュールはこのElastic Common Schemaに則ってデータが定義されるようになってきています。これにより、ログからメトリックへ、APMからログデータへというシームレスな移動ができるようになっています。\nElastic Stack 6.7.0リリース(3月) リリース記事はこちら\nElastic MapsやUptimeといった、これまでの可視化とは異なる便利なアプリが増え始めました。Mapsでは地図の表現が格段にアップしたので、コレまで以上に地理情報と合わせた可視化が楽しくなりました。\nもちろん、基本的に必要な技術が着実にGAされていくのもElastic Stackの素晴らしい点です。\nIndex Lifecycle Management(ILM)がGA Cross Cluster Replication(CCR)がGA CanvasがGA Logs \u0026amp; Infra UIがGA Elastic Stack 7.0.0リリース(4月) リリース記事はこちら\nメジャーバージョンのリリースです。 KibanaのUIが刷新されたり、Elasticsearchのクラスター管理の機能が新規に構築されたり、様々な改善がこのリリースでも入っています。また、メジャーバージョンのリリースのタイミングが、さまざまな大きな仕様の変更や改善が入るタイミングでもあります。これまで以上にパフォーマンスが改善(Top-Nクエリ高速化など)されたり、新しい機能の追加(ナノ秒のサポート)されたりしました。\nElasticsearchのセキュリティの主要な機能が無料に(5月) リリース記事はこちら\n6.8.0および7.1.0のリリースはこの機能の無償提供となりました。 結構衝撃的な話だったのではないかなぁと。これ以前は有償の機能だったセキュリティの以下の機能をElastic License配下で無料で提供する形に変わりました。まだ、ご存知でない方は、データの安全のためにもセキュリティ機能を利用することをおすすめします。\nTLSによる通信暗号化 ユーザー作成と管理にファイルおよびネイティブのレルム認証を使用可能 クラスターAPIとインデックスに対するユーザーアクセスの管理にロールベースのアクセス制御を使用可能、またSpaces機能でKibanaのマルチテナンシーの安全性を向上 Elastic{ON}19開催(5月) 今年も東京で開催しました。ビデオなどはこちらで公開されています。 https://www.elastic.co/elasticon/tour/2019/tokyo\n今回も偉そうにElatic Stackの新しくなった点を紹介するなどしてました。。。\nElastic Stack 7.2.0リリース(6月) リリース記事はこちら\nElastic SIEMがベータリリースされたのがこのタイミングです。 2月の発表したElastic Common Schemaをフルに活用していると言ってもいいのがこの機能になります。まだ今後もどんどん改善が入るであろうきのうになります。\nまた、Elasticsearchをバックエンドにした検索ミドルウェアとして利用いただけるElastic App Searchのセルフマネージド版もこのタイミングでリリースされています。\nさらに、このリリースの直前にはElastic Cloud on Kuberunetes(ECK)というものベータリリースされました。少しわかりにくいかもですが、ElasticsearchやKibanaをKubernetesのOperatorとして利用できるようになっています。こちらもElastic Licenseでリリースされているのでk8s上でKibanaやEsを管理しようとしている方は触ってみると面白いかもです。\nElastic Cloud Elasticsearch ServiceがGCP日本で利用可能に(7月) リリース記事はこちら\nElastic Cloudもプラットフォームが拡大した年でした。 Google Cloud Platformの東京リージョンを選択できるようになりました。さらなる統合(支払いをGCP経由にまとめたり、GCPのコンソールから利用できたりなど)も進んでいます。\nElastic Stack 7.3.0リリース(8月) リリース記事はこちら\nデータフレームと呼ばれるデータ取り込み時のピボット機能が導入されました。また、MapsのGAリリース、Elastic APMの.NETエージェント正式リリースなど、細かいですが様々なものがリリースされています。\nElastic Cloud Elasticsearch ServiceがAzureで利用可能に(9月) リリース記事はこちら\nMicrosoft Azureへのデプロイも可能になりました。残念ながらまだ日本リージョンには来ていないですが、今後出てくるはずです!さまざまなクラウドベンダーのサポートにより、より多くの人に使っていただけるようになるのかと。\nElastic Stack 7.4.0リリース(10月) リリース記事はこちら\nもう7.4.2まで出ていますが、いい感じの間隔で7.0、7.2、7.3と来ていますね。 7.4では、スナップショットリストアがKibanaから簡単に行えるようになりました。これまではKibanaのConsoleでJSONを見ながら管理されていたかもですが、GUIにより今どんなスナップショットがあるのか、どれをリストアするのかといった操作が簡単にできるようになっています。\nKibanaについてはPKI認証のサポートなども始まり、様々な認証方式でより便利にKibanaが使えるようになっています。\n12月? 12月ですし、Elasticsearch勉強会では「LT&忘年会」ということで、懇親会がメインの勉強会として12/6に開催します。悪路クエストの緑川さん、吉岡さんに主体となっていただき、マイクロソフトさんを会場に借りて開催予定です。興味のある方はぜひご参加ください。 LTもおまちしています!\nまとめ 駆け足でしたが今年を振り返ってみました。 今年も色々ありました。残すところあと1ヶ月です!\nさて、Elastic Stack Advent Calendar 2019は今日から25日まで続きます。今年はその2もできています!こらからの記事を楽しみにしています! 本日はその2で[kaibadash@github]さんが「5分でできるElastic stack環境構築」というのを書いてくれてるはずです!\nということで、次はKunihikoKidoさんの「 Elastic Cloud を使うようになって設計方針やら変わったことについて書きます。」になります。お楽しみに!\n","date":1575126000,"dir":"post/2019/","id":"78da47d61c91c82809a3c97a791d26d2","lang":"ja","lastmod":1575126000,"permalink":"https://blog.johtani.info/blog/2019/12/01/whats-happen-at-elastic-in-2019/","publishdate":"2019-12-01T00:00:00+09:00","summary":"Elastic stack (Elasticsearch) Advent Calendar 2019の1日目の記事になります。 まだ、1ヶ月を残してますが、簡単に今年起こったことを振り返ってみようと思います。毎年恒例ですね、","tags":["elasticsearch"],"title":"2019年のElastic StackとElastic"},{"contents":"Bonfire Data \u0026amp; Science #1にブログ枠で参加してきました。 ということで、メモです。\n日時 : 2019/10/25 19:00 - 21:30 場所 : Yahoo! Japan サイト : https://yj-meetup.connpass.com/event/148121/ ハッシュタグ: #yjbonfire 概要 Data \u0026amp; Scienceとは? データとサイエンスに関わる人達の情報共有のための勉強会/交流会\nサイトから引用です。\n第1回のテーマは「画像検索」です! 最近EC系のサイトで類似画像検索が出来るようになったけどどうやってるの? 画像検索のモデルってどうしてるの? 画像検索のインフラはどうしてるの? 私たちの会社でも画像検索を用いたサービスを構築できるだろうか? こういった疑問に答えたり、いま抱えている悩みを解決するヒントを得る場になればと思っています。 今回は、画像検索を行なっているヤフー, メルカリ, ZOZOテクノロジーズの3社に事例と基盤技術について登壇いただきます。 QAはこちら。https://app.sli.do/event/w3wayjmv/live/questions\nMercari画像検索について(仮) 発表者:荒瀬晃介(株式会社メルカリ / AIエンジニアリングチーム)\nAIエンジニアチーム\n写真検索プロジェクトのTech Lead\niOSのみで提供の写真検索\nシステムオーバービュー\nMobileNet v2で特徴抽出 ANNのインデックスを使ってDBに入れる 論文も発表済み(3本)\n今日の発表はこの内の2本を元に話をします。 C2Cでの問題点 商品は床やテーブル上で撮影 クエリは着用(着ている)画像が使われやすい。 人が写ってる写真が結果に多いと業者が出展しているように見えてしまう。 提案手法 人が写ってるものから人の代表ベクトルを抜き取る (クエリ時にのみ処理を実施しているので変更が容易) 特徴変換ベクトル トップスなど、分類ごとに学習させてからベクトルを構成 なんでMobileNet v2? エッジデバイスでの処理を見据えて選択 インフラ Docker + k8s\nCRDを使ってる?\ntraining\nコンテナベースパイプライン いくつかのバッチ処理を工程ごとにパイプライン化 バッチ実行情報をカスタムリソースとしている=再実行が簡単(復旧作業が容易) 画像を扱う=ダウンロードが時間がかかる -\u0026gt; 復旧しやすいようにPVにある程度キャッシュさせている Serving\u0026hellip;\nGCP側 なぜ2つに別れてるんだろう?実際のサービスも2つに分かれてたりするんだろうか?\n将来の展望 Realtime Image Search カメラでものを写している状態でそれが何かを検索できる。 物体検出+特徴抽出をエッジで行うためできる エッジの性能により違いが出てきたりするっぽい QA Q: 業者が想定されると、購入意欲を下げるというのは実験した結果?それとも想像? A: 実験はしていないが、e-commerceにおいての研究がある Q: どういう理由でマルチクラウドにしたんでしょう? A: 画像のマスターがAWS。メルカリのマイクロサービスはGKEなので、サービング環境がGCP Q: 画像の内、服のエリアが大部分で体の面積が少ない場合と、メガネや帽子のように、アイテムの方の面積が少ない場合で、トレーニングに必要なデータ数は変わりましたか? A: カテゴリによる性質の違うはある。ので、改善は必要。 ZOZO画像検索について(仮) 発表者:平田拓也(株式会社ZOZO / AIエンジニアリングチーム)\n(聞き逃した。。。)\nWEAR\nマルチサイズ\nチーム構成 研究所+ML Opsチーム 使用しているアルゴリズム 物体検出アルゴリズム 特徴量抽出アルゴリズム 近似最近傍探索(approximate nearest neighbor, ANN) インフラ GCPを採用。 BigQuery上にデータ基盤がある Managed GPUが必要 なんでk8s? コンテナ Cloud Runがなかった アーキテクチャ マイクロサービス化されている Google Cloud Next 2019 Tokyoでsonotsさんの発表があるよ 監視項目 CPUなどは見ていない レスポンスタイムとステータス監視 リクエスト数 APM 使ってるものStackdriver + Datadog + Sentry Warningが30分で続けたら通知などができるのがStackdriver 画像検索の改善のためにやっていること 課題 レイテンシーが大きい 推論が大変? 急激なトラフィックの増加に対応できない GPUのスケールアウトが問題 -\u0026gt; 先行投資が必要 流れ キャッシュありなし 物体検出 (GPU) 特徴量抽出 (GPU) 近似最近傍探索 DBから取得 2と3が問題\n2と3を特徴量DBという形でデータが登録された時点で特徴量などを計算してしまうことでGPUへの依存をなくした。 Apache AirFlowが便利? Cloud ComposerとApache AirFlow Cloud Composerに関するいくつかのTipsがありました。\nQA Q: 推論をCPUでやったらどれぐらい遅いんだろう A: GPUインスタンス代金 \u0026lt; それと同等の速度を出すためのCPUインスタンス代金 Q: k8sスケールアウト時のリソース割当を最適化する為、resource limit / request標準化 or 時系列分析などから自動調整するなどはされていますか? A: \u0026hellip;聞き逃した Q: (TCOを考慮したクラスタ構成) Cloud Composerの値段が高いようなパプリッククラウド利用の課題対策としてプライベートクラウドとのハイブリッド構成にされているのでしょうか?もしハイブリッド構成でしたら、パブリック or クラウドを切り分ける基準はございますか。 A: GKEオンリー Q: cloud composerでairflowを使う辛い点は? A: 不安定さ。。。 Yahoo!ショッピングにおける画像検索(仮) 発表者:佐藤 純一(ヤフー株式会社) 商品検索APIの開発とか検索エンジンの保守とか 類似画像検索システムの開発が直近の仕事 類似画像検索 ヤフーショッピング 3億の商品 ファッション系はビジュアルが重要=言語による表現が難しい iOSとAndroid Androidだとカメラで撮影してから検索みたいなことも可能 システム概要 物体検出 ノイズ除去 特徴抽出 インデックス(NGT) -\u0026gt; https://github.com/yahoojapan/NGT 1000万件を超える 検索 アプリの画像をAPIに投げてベクトルから、近いものn件を取得 ベクトル化/インデックス更新 GPUマシン Kafka使ってる クラウドストレージに日次?バックアップみたいに保存 差分更新の仕組みがある メンズとレディースは分けている 絞り込み検索のために分離(インデックスのメタデータとしてタグがある) システム構成 Python Kafka TensolflowServing 可視化?監視?はGrafana+Prometheus 開発を通しての学び 自動デプロイとかテスト 検索精度の確認ツールを作る コレ重要だよね。何が変更してるかとか、何が正しいかってのが必要だし。。。 復旧可能、早期復旧の仕組みを容易 今後の方針 対象商品の拡大 物体検出特徴抽出モデルの性能改善 NGTの検索システムをValdに移行 Vald k8s上で動作、分散検索、分散インデキシングなどの機能を提供予定 QA Q: iOS(既存の画像)とAndroid(カメラで撮る)で画像検索の方式が違うのはなぜ? A: アプリの違い Q: 1枚の写真に沢山写っている中で、対象の商品をどう識別しているんでしょう。靴もトップスもボトムスも写っていたら、かなり難しそう A: Yahooブラウザの場合は1番大きな領域のものを選択。Yahoo shoppingだと選択可能 NGTについて(仮) 発表者:岩崎 雅二郎(ヤフー株式会社) 類似画像検索を20年くらいやってる 近傍検索ライブラリ https://github.com/yahoojapan/NGT\n高次元ベクトルの近傍検索 ツリーとグラフによるインデックス 近傍検索とは?\n距離空間上でのクエリの近傍のオブジェクトを取得 k最近傍検索(通常はこっち) 範囲検索(あんまり使われない) NGTの特徴\n世界トップレベルの高速高精度な近似近傍検索 OSS 追加削除が可能(削除がとくに難しいらしい) 多様な利用形態(Python、C++、C、Go、コマンドライン) サーバ版NGT(ngtd、vald)を提供 共有メモリ版でメモリサイズ以上のデータ登録可能 量子化版NGT(NGTQ)により。。。 ANNベンチマークによりテスト\n実行環境が決められているらしい。誰が実行しても比較可能 グラフベースの検索の仕組みのほうが性能がいいというのがベンチマーク結果からわかる なんではやいの? インデックス生成 ツリー(グラフの探索起点の取得に利用する。DVP-tree) グラフ(ANNG) ノードを逐次追加しつつ、近傍ノードを検索してから接続するというのを繰り返している 検索 ツリーから絞り込みつつ、グラフを検索する ANNGに課題があるのでONNG(Optimized Nearest Neighbors Graph)に ノード単位の次数(入出)を最適化 データセットによって有効な次数が違う。。。 NGTを利用した深層学習で。。。 Yahoo!ラボ FavNavi 特徴量の構成(低次特徴量(300次元)、カテゴリ特徴量(128次元)、領域アスペクト比(1次元)) 個別の特徴量だけだとイマイチな結果になるが、組み合わせるといい感じになる モデル性西洋学習データ スライドがあればいいなぁ(表書くの大変だし。。。)\nQA Q: 実際のお客さまの利用を考えると、近似近隣の密度が異なるので、近いものばかりの検索結果や遠いものも含んでしまった検索結果が出ると思うのですが、遠いものが含まれてしまうと、閾値でフィルタしたりするのでしょうか? A: NGTは近いものしかないので、外れ値ってなんでしょう。。。 検索のフィルタリングをある程度している(カテゴリとか)。 まとめ 慣れない分野の話を聞きながらざっとメモを取ったものなので役に立つかはわかりませんが。。。\nアルゴリズムとかまでは得意ではないんですが、画像「検索」ということで参加してみました。 実際に画像検索の仕組みがどんな感じでできているのか、どんな技術がつかわれているのか?ってのがわかったのは 面白かったです。確かに検索のためのキーワードって出てこないことあるしなぁと。 あー、こんなかばんほしいとか、これなんだろ?みたいなのあるからなぁ。\n","date":1572000002,"dir":"post/2019/","id":"11b3a28b536f34d3606427f835bd3ddf","lang":"ja","lastmod":1572000002,"permalink":"https://blog.johtani.info/blog/2019/10/25/bonefire-01/","publishdate":"2019-10-25T19:40:02+09:00","summary":"Bonfire Data \u0026amp; Science #1にブログ枠で参加してきました。 ということで、メモです。 日時 : 2019/10/25 19:00 - 21:30 場所 : Yahoo! Japan サイト : https://yj-meetup.connpass.com/event/148121/ ハッシュタグ: #yjbonfire 概要 Data \u0026amp; Scienceと","tags":["勉強会"],"title":"Bonfire Data \u0026 Science #1に参加しました"},{"contents":"この間のElasticsearch勉強会でAcroquest Technologyの人たちが技術書展7で販売されていた書籍を頂いてしまいました。なので、軽く読んでの感想と宣伝です(これ、電子版とかで買えないのかな?)。\nElasticのパートナーとしても活躍していただいてますが、こういう感じでさまざまなところでElastic Stackを広めていただいていて感謝しかありません。\n章立てとしては以下の通りです。\nElasticsearchでエンタープライズサーチを実現する 同僚が作成、メンテナンスしているFSCrawlerを使った例も書かれています。ローカルのファイル(PDFやJSONとか)をサクッとElasticsearchにインストールしたりするのには便利です。 Kibana Canvasによる柔軟な可視化 Canvasについてどんなものなのか?というのとelasticcofeeというサンプルを元に、その変更の仕方などが説明されています。 Elastic APMによるアプリケーションパフォーマンス監視 Go AgentとAPM自体の使い方の説明です。最近強化されている他の機能との連携(AlertingやMachine Learning)についても触れてくれています。 Kubernetesクラスタのメトリクス・ログ・性能情報の可視化 Azure上でAzure Kubernetes Serviceの上で動いているアプリなどをBeats、APMでデータを取りつつ、他のAzure上にAzure Marketplaceのテンプレートを用いて起動したElasticsearchとKibanaの環境を用いて可視化する方法が説明されています。 ということで、薄い本ですが、手順をおって説明されていたり、7.3と新しいバージョンで書かれているのですばらしいなぁと。 前作の「Elasticsearch NEXT STEP」に引き続きインプレスさんから出たりするのかなぁ?\nちなみに、Elastic APMのRubyに関して興味がある方は、私が前に発表したときの資料がありますので、こちらを参考にしてみてください。\n","date":1570690589,"dir":"post/2019/","id":"d8041ae308961666b15aa1e57b0f9f35","lang":"ja","lastmod":1570690589,"permalink":"https://blog.johtani.info/blog/2019/10/10/review-es-next-step-2/","publishdate":"2019-10-10T15:56:29+09:00","summary":"この間のElasticsearch勉強会でAcroquest Technologyの人たちが技術書展7で販売されていた書籍を頂いてしまいました","tags":["書籍"],"title":"Elasticsearch NEXT STEP 2を頂きました"},{"contents":"Twitterで「Meetup.comに切り替えたらー」みたいな話があったので、 受付用アプリとかなくてという話になったので、普段Elasticsearch勉強会で使用している QRコード生成の仕組みを紹介してみようかと。\nHTMLだけで済むようにQRコードを生成するjquery.qrcode.min.jsってのを使用してます。\nHTMLコードはこちら。\n仕組み 1枚だけのHTMLを生成 MeetupのOAuth2の仕組みを利用(consumer keyを発行する必要あり。) Meetup APIを利用してユーザー情報取得 取得したユーザー情報をGoogle Formに埋め込んだ形で表示するURLを組み立てる 組み立てたURLをQRコードにしてHTMLに表示 受付で、QRコードリーダーを使って、QRコードを読み込むとGoogle Formが開くので、「送信」ボタンを押す 1. HTMLの作成 QRコードを表示するためのHTMLを作成します。Gistに貼り付けてあるので、参考にしてもらえれば。 いくつか埋め込まないといけないものがあるので、個別にそれは説明します。\n2. Google Formの準備 Elasticsearch勉強会では、出席者の情報として、IDと氏名をリストとして保存しています。 目的としては、何人実際に参加したかを計測するのが目的です。 ですので、参加者リストのGoogle Formを作成します。 で、作成した後に、プレビューを表示する。こんな感じ。\nこの時のプレビューのURLをQRコードのURLとして使いたいので、このURLをQRコード表示のHTMLに埋め込みます。\nfunction createGoogleFormURL(data) { var obj = { \u0026#34;entry.1744035444\u0026#34; : data.id, \u0026#34;entry.2031666715\u0026#34; : data.name }; return \u0026#34;https://docs.google.com/forms/d/e/\u0026lt;GOOGLE_FORM_ID\u0026gt;/viewform?\u0026#34; + $.param(obj); } ここら辺です。 returnに書いてあるhttpsで始まる文字列をまず、先ほどのURLで置き換えます。 次に、プレビューのHTMLの中から\u0026lt;input\u0026gt;タグを探して、nameの値を抜き出します。 それをobjのキーに利用します。entry.で始まる文字列が該当します。\nこれで、このURLをQRコードにすれば、値(ここだとIDと氏名)が埋め込まれた形のGoogle Formがスマホのブラウザで起動します。\n3. Meetup APIの準備 MeetupのAPIを利用できるようにします。Meetup.comにログインするとみれるAPIのページがあります。 https://secure.meetup.com/meetup_api\nまず、OAuthを利用するためのConsumer Keyを発行します。\nメニューのOAuth Consumersをクリックして、\n\u0026ldquo;Create New Consumer\u0026quot;をクリックします。 すると、次のような画面が開きます。\nConsumer nameとRedirect URIが重要です。\nConsumer nameはユーザーがMeetup経由で認証するときに、その認証画面で表示される名前になります。 わかりやすい名前を表示してあげると良いかと。\nRedirect URIが一番重要です。実際にOAuthで認証が通った後に表示するHTMLを提供しているURLを指定します。 Elasticsearch勉強会の場合は、私のドメインにwwwをつけた\u0026quot;https://www.johtani.info\u0026quot;を指定しています。 実際にQRコード表示用のHTMLを配置するHTTPサーバーのトップのURLを指定します。 (ちなみに、私のウェブサーバーはS3で運用してます。ですので、HTMLをS3のバケットにアップロードしてあるだけです)\n必須項目を入力したあと、最下部にあるRegister Consumerボタンを押せばキーが生成されます。 生成されたキーがOAuth2のURLのパラメータに必要になります。\nこれで、リダイレクトの準備が整いました。\nOAuth2のURLには、Implicit Flowを利用します。 これで、リダイレクト先のHTMLにトークンがわたるので、Meetup APIにこのトークンが使えるようになります。\n認証用のURLはこちらです。このURLを参加者宛のメールに入れて毎回送信しています。\nhttps://secure.meetup.com/ja-JP/oauth2/authorize?response_type=token\u0026amp;redirect_uri=\u0026lt;QRコード表示HTMLのURL\u0026gt;\u0026amp;client_id=\u0026lt;コンシューマーキー\u0026gt; 参加者はこのリンクをクリックすることで、次のような画面が出てきます。 ログインしていない場合はLog in画面が表示され、まずはログインを促されます。\nで、Allowをクリックすれば、redirect_uriに指定されているページが表示されるわけです。\nQRコード表示用のHTMLでは、次のAPIを使用して、ログインしているユーザーの情報を取得してきています。\nfunction getMemberId() { $.getJSON(\u0026#39;https://api.meetup.com/2/member/self/?only=id,name\u0026amp;access_token=\u0026#39;+ getToken(), displayQRCode); } ここで取れた値が、先ほどの「2. Google Formの準備」で説明したコードのdataの部分に渡ってくるわけです。\nfunction createGoogleFormURL(data) { var obj = { \u0026#34;entry.1744035444\u0026#34; : data.id, \u0026#34;entry.2031666715\u0026#34; : data.name }; return \u0026#34;https://docs.google.com/forms/d/e/\u0026lt;GOOGLE_FORM_ID\u0026gt;/viewform?\u0026#34; + $.param(obj); } 4. QRコードの表示 あとは、jquery.qrcode.min.jsを使用してURLを表示するだけです。\nfunction displayQRCode(data) { $(\u0026#39;#qrcode\u0026#39;).qrcode({width: 128,height: 128, text:createGoogleFormURL(data)}); } サイズとURLを指定するだけですね。\nまとめ あとは、受付で、参加者の方が表示してくれたQRコードをスマホのQRコードリーダーやカメラで読み込めばGoogle Formが開いて必要な情報は入っているので、「送信ボタン」を押せば参加者リストが出来上がっていくという形になります。\n毎回勉強会の前日に、前回のGoogle Formを「コピー」してから、各回の勉強会の登録者フォームを作成しています。 コピーすることにより、Google Formの\u0026lt;input\u0026gt;タグに使用されるnameもそのままコピーされるので、 QRコード生成用のHTMLを書き換える部分の手間が減る形になっています(気づくまで数回かかったw)。\nですので、QRコードのHTMLの中身としては、「勉強会のページへのリンク」、「Google Formへのリンク」の2つを書き換えてから毎回アップロードしているだけとなっています。\nこのやり方が、スマートかどうかはわからないですが、受付アプリがない中、Meetup.comから取得した参加者リストのExcelやプリントアウトしたリストを元に参加者をチェックするよりは、手間が省けてるんじゃないかなぁと。\n残念ながら、QRコードの存在を知らないでそのまま勉強会にくる人がいるので、受付で最低一人はMeetup.comの参加者リストから、 名前を検索してチェックするという作業もやってもらってます。 QRコードを持ってきた方がすんなり受付を通過できるようになってますので、ぜひQRコードを持って勉強会にきてもらえればと。\n","date":1560939044,"dir":"post/2019/","id":"d96f80f23543850a2ee9fff8cd2cc53f","lang":"ja","lastmod":1560939044,"permalink":"https://blog.johtani.info/blog/2019/06/19/qr-code-with-meetup-dot-com/","publishdate":"2019-06-19T19:10:44+09:00","summary":"Twitterで「Meetup.comに切り替えたらー」みたいな話があったので、 受付用アプリとかなくてという話になったので、普段Elasti","tags":["勉強会"],"title":"勉強会の受付自作?アプリ?HTMLについて"},{"contents":"Elasticsearch勉強会や検索技術勉強会やってるんだけど、独学で勉強会やってるなーと思い、みんなはどうやってるんだろうとツイートしてみたところ。\nあー、勉強会運営座談会したい。\n\u0026mdash; Jun Ohtani (@johtani) 2019年4月2日 面白そう\n\u0026mdash; 機械の体を手に入れるのよ鉄郎 (@tetsuroito) 2019年4月2日 やってみるか。\n\u0026mdash; Jun Ohtani (@johtani) 2019年4月2日 やりましょう\n\u0026mdash; 機械の体を手に入れるのよ鉄郎 (@tetsuroito) 2019年4月2日 ってことで、何人か釣れたので、勉強会運営座談会をやってみました。 会場提供していただいた、Classiさんありがとうございました!\n参加してくれた人たちはまぁ、勉強会のサイトを見ていただければなんとなくわかるかなと。 自己紹介とどんな勉強会、読書会運営してますってとこから始めて、次のようなトピックについてピザ食いながら3時間くらい話しました。\nスピーカーの募集方法 運営側から声かけてる?それとも公募してる? 登壇時間とかどうしてる? スピーカーになってもらうためになんかやってる? スケジュール管理 会場探し、スピーカー探し、イベントページ作るタイミングは? 複数拠点開催したことある? ハンズオンとかはどうしてる? 土日開催?平日開催? アンケートとってますか? 使用してるイベントサイトは? ドタキャン対応どうしてる?出欠とったりしてる?懇親会の規模とかどうやって見積もってる? 運営費用関連はどうしてる? グッズとか、ツールとか、スピーカーへの謝礼とか 運営って複数でやってる? その時のツールは? 運営メンバーにはどうやってなってもらう? 録画配信とかまで手が回る? 会場探すの大変じゃない? 会場の部屋の使い方はどうしてる? 行動規範とかどうしてる? 読書会の場合に人が減ってったりしない? まぁ、こんな感じです。色々話してメモしてたんですが、まぁトピックくらいで。\nそもそもは、勉強会の運営って本業ではない(はずな)ので、いかに楽をしつつうまく運営できるかってのを知りたいのと、 他の人どうやってるかってのからアイデアもらえるといいなーと思ったんでやってみました。 他のツールがどんなものかとか知れたし、あー、そういうやり方すればいいのねーみたいなのも知れたので、次回以降の勉強会に活かせればなーと。 自分がやってるやり方とかもブログ書くといいのかなぁ?\n残念です!次回もやるかもしれないので、 @johtani さんに期待してください!\n\u0026mdash; 機械の体を手に入れるのよ鉄郎 (@tetsuroito) 2019年4月25日 次回やるのかなぁ?興味ある人いるのかなぁ?\n","date":1556204526,"dir":"post/2019/","id":"538e38fbc3f78cd61e1841d8141ddcc1","lang":"ja","lastmod":1556204526,"permalink":"https://blog.johtani.info/blog/2019/04/26/meetup-organizer-drinkup/","publishdate":"2019-04-26T00:02:06+09:00","summary":"Elasticsearch勉強会や検索技術勉強会やってるんだけど、独学で勉強会やってるなーと思い、みんなはどうやってるんだろうとツイートして","tags":["勉強会"],"title":"勉強会運営座談会ってのをやってみた"},{"contents":"どーも、johtaniです。\nSearch Engineering Tech Talkという勉強会に運営として参加して、第1回の勉強会を開始しました。 本日(2/26)は第1回目だったので、ブログを残しておこうかと。\n勉強会自体の資料については第1回の勉強会のページにあるし、勉強会の感想とかブログはツイートやみんながブログを書いてくれると思うので、勉強会開催の経緯などについてブログを残しておこうかと。\nなんで始めたの? 私自身が古くはFAST Searchに始まり、何か縁があって、 検索のシステムに長く携わってきたこと(Apache Solrの本書いたり、Elasticsearch勉強会始めたり)もあり、 検索が面白いなと日々思ってます(思ってるだけかもしれないが)。\nで、これまでElasticsearch勉強会をやっているのですが、検索エンジン固有の話ではない、 いわゆる検索の共通の課題というのがあるなぁと。 そういう課題やノウハウって、製品に限らず共有できれば面白いことがもっとできるんじゃないだろうか? と感じることが多々ありまして。 オープンソースのコミュニティをソースコードをベースではなく、共通の課題・話題を中心としたコミュニティが あってもいいんじゃないかなぁと。\nまぁ、要は、私がみんなの検索で困ってることとか、どうやって検索システム考えてるのかが聞きたかったわけですよ。\nということで、一人でやっても面白くないので、興味ありそうな人を募ってやってみようということを始めたのが2018年12月くらいです。\n運営とかどうしてるの? まずは、共同主催者(コアメンバー)を募集してみようということで、Googleフォーム作って、 興味ありそうな人がいる場所に投稿してみました。(TwitterとかFBとか) で集まったのが今回紹介したメンバー(スライド参照)です。 ユーザー企業の人もいれば、私みたいな検索エンジンの人もいるので面白い感じにできたかなぁと。 で、スピーカーを運営や知り合いに声をかけて第1回をやってみたという感じです。\n今後どうするの? 残念ながら次回はまだ未定です。 2ヶ月に1回くらいのペースで開催できればなーと思ってますが、スピーカーが集まるかなどによるかなぁと。 ということで、勉強会のグループのページにスピーカー応募フォームのリンクがありますので、スピーカーに興味がある方は入力していただければと。\nもちろん第2回はやりたいので、勉強会のページからの連絡をお待ちください!!\n","date":1551191880,"dir":"post/2019/","id":"b27bdabd8e1a6b7dc06886867331ceb3","lang":"ja","lastmod":1551191880,"permalink":"https://blog.johtani.info/blog/2019/02/26/start-search-engineering-tech-talk/","publishdate":"2019-02-26T23:38:00+09:00","summary":"どーも、johtaniです。 Search Engineering Tech Talkという勉強会に運営として参加して、第1回の勉強会を開始しました。 本日(2/26)は第1回目だったの","tags":["勉強会","検索"],"title":"Search Engineering Tech Talk(検索技術勉強会)の運営として参加して始めてみました。"},{"contents":"今年も振り返りブログをかけてます。よかったw\n振り返り(2017年に書いた抱負から) まずは去年の抱負を元に。\nもっと英語の継続&TOEIC まぁ、継続してます。英会話も続けてますし、海外TVドラマや映画見てます。 ただ、昨年書いたTOEICはイベントが被りまくってて受けれてないです。。。 来年は受けれればいいが。 ちなみに見たドラマはこの辺。あんまり見てないなぁ。 「はじまりのうた」は飛行機の中で見たんですが、よかったです。 最近は音楽系の映画が好きなのかなぁ。グレーテストマンショー(ミュージカル風)とかもハマったし。\nGame of Thrones はじまりのうた BEGIN AGAIN (映画) 24 シーズン4まで 今は、ボキャブラリのなさに苦しんでる感じです。キクタンとかするべきなのかもなぁ。 基本勉強が下手だからなー。\n継続的にイベントに登壇 & CfPもっと出すぞ! OSCには出てました。あとは、いくつかに呼ばれて出たりでしょうか。 CfPはJJUGしか出せてない気がするんで、もっと出さないとですね。。。 春のJJUGでは20分で短すぎた「オープンソースとビジネスモデル」の話(同僚のネタ)が 今年面白かった内容かなぁと。 もっと話を作るのをうまくしないとだろうなぁ。 ユースケースが増えてるんで、もっといろんなところに出ていかないとなぁと。 ブースの出し方とかもちょっと考えないといけないかもなーと思ってたり。 マンネリになってきてる気がするんで、なんか取り入れないとなぁ。\nもっとブログ! 出だしはよかったんですが、途中でRustネタのブログも止まってしまいましたね。。。 業務が忙しくなったのを言い訳にして時間が取れなくなってるんで、 もっと習慣つけないとなぁ。\n雑誌やWeb系雑誌で記事を。 できてないです。。。どうすっかなぁ。 重い腰上げないのが問題なんですけどね。。。 自社のウェビナーとかはそこそこやってましたが。\nコミュニティを別の方法で盛り上げ フォーラムは皆さんのおかげで盛り上がってきてる気がしてます。 別の方法ではなく、勉強会を9月から毎月開催にして、ユースケースごとに切り替えてみました。 あとは、スピーカー登録用のフォームの用意とかして、継続的に楽にスピーカーの人たちが見つけられるようにと。 私は「全然」関わってないんですが、技術書典でいろんな方に書籍を書いていただきました。 また、Elasticloverという毎週いろんな記事をまとめていただけ助かりました。 少しでも感謝をということで、コミュニティランチというイベントで、フォーラムで回答していただいてる方や、書籍を出していただいた方を招いてCEOのShayとランチするというイベントもやってみました。 少しは盛り上げられたかなぁ。 次は、ハッカソンみたいなのとかやってみるのもありなのかなぁ?(サポートしきれない気がするんだよなぁ)\nElasticsearchなど検索系の開発にも参加 開発。。。 Analyzer向けのKibanaのプラグインの開発は継続してますが、あんまり開発してないですねぇ(GitHubの草をみながら)。 ちょっとしたPRはやったりしてますが、もっとやりたい。。。 とりあえず、来年しょっぱなは、検索系じゃないですが、KibanaのプラグインのReact化をやらないとなぁと。\n振り返り(今年あったできごと) さて、反省が多かったですが、ここからは今年の出来事を。\n初スノーシュー in US オフィス引越し パリで料理w K8sとde:code QNAPとか IPO! 初のオンライン登壇 初アイルランド! Pixel3 XL 今年も初モノがちらほら。\nアメリカでスノーシューやりました。昨年は釣りでしたが、今年はスノーシューでした。 スノーシューはすごくよかったんですが、サンフランシスコから社内ミーティングのある場所までの 移動に10時間バスに缶詰という変な初モノもありました。。。 スノーリゾートのある山の上にバスで移動だったんですが、前日までの天候の生でチェーン規制が出てしまい、登りかけた山を降りて、違う経路で登り直すという長旅でした。。。 途中からずっとゲームオブスローンズみてました。。。\nオフィスが引っ越しました。人数が増えてきたのもあり、銀座のWeWorkに引っ越しました(私はあんまり行かなかったりしますがw)。 ただ、すでに手狭になってきて、来年はまた引っ越してるかもなぁ。 今年の終わりで日本のメンバーが22名に増えました!すごい!4年半前の22倍!\nパリで料理もしましたwセールスのキックオフミーティングがパリで開催され、なぜか参加してきました。 そこで、DevRelチームのミーティング&ディナーがあったんですが、ディナーがアクティビティ付きで、チームのみんなとパリで料理やカクテル作ってきました。 まさか、パリで手巻き寿司作るとは思わなかった(怖くて食べてないですw)\n今年はイベントが連続することが多かったです。パリから帰ってすぐにde:codeでMSの川崎さんと登壇したりしました。Kubernetesを触る機会ができたんでよかったですが、時差ボケは辛かったw今年は他にもカンファレンス直後にトレーニングだったりと、夏に喉やられちゃいました。喉に負担をかけない話し方の練習すべきなんだろうなぁ。\n自宅の環境もちょっと整えました。10年前から使ってた、TeraStationをQNAPに刷新。快適に検索できるわ、クラウドにバックアップとれるわで、すごく快適です。 あとは、自室のディスプレイをディスプレイアームにつけたり、壊れたモニタースピーカーをYamahaのパワードスピーカーに買い替えたりと。 ちょこちょこ自宅で作業したりするんで、快適です。\n今年はめでたいことに会社がIPOしました。ニューヨーク証券取引所で株式公開しました。 転職して4年、初体験なんで何がどうってのはいまいち実感わかないんですが、順調にきてるのは嬉しい限りです。今後も頑張りますよ!\n自社のウェビナーでは、オンライン登壇してたんですが、インフラ勉強会でオンライン登壇させていただきました。 Elastic Stackの入門的な話をさせていただいたので、興味があればみていただければと。 こういうのにはマイクが非常に重要だなというのが結論です。ウェビナーで使ってるShureのマイクで話したので聞き取りやすかったです。 来年はもっと手軽にちょっとしたウェビナーとかポッドキャストやろうかな、ということで、持ち運び用にSAM SONGo Micを購入してみたのでどっかで試してみたいなー。\nアイルランド(ダブリン)にも行きました。これまた、社内のミーティングなんですけどね。半年に1度エンジニアが集まる社内イベントがあるので、いろんなところに旅をさせてもらっていて、すごく楽しいです。 みんなにも会えるし。ただ、アイルランドの英語はきつかった。。。\n最後はPixel3です。SonyのXperiaをここ数年は使ってたんですが、電池の持ちなどが悪くなったんで、気になってたPixel3に変えました。すごくいい。いらないものが入ってないのもいい。あとカメラがすごくいい。他の機能をまだちゃんと調べてないんで、誰か便利機能知ってたら教えてくださいw\nとまぁ、こんな感じでした。\n来年の抱負 最後は来年の抱負を。\nTOEIC CfP見つけて応募 \u0026amp; いろんな場所に顔を出す もっとブログ! Rustの継続 開発の継続 日本でエンジニア獲得! まぁ、英語ですね。これは地道にやるしかないんだろうなと思いつつ、コツコツが苦手でw とりあえず、今年はどこかでTOEIC受けないとな。\nいつも行かないけど、弊社プロダクトに関係のあるカンファレンスのCfPを見つけ出して、 応募しまくって、少しでもしゃべらないとなぁ。喋れなくても、Elasticsearchがらみで登壇していただいてる方がいるカンファレンスには顔を出していきたいなぁと。 登壇される方いたら、ぜひ連絡ください!あとは、CfPのサイトを探す仕組みを作らないとなぁ。 検索サイト作るかなぁ。 あとは、カンファレンスではなく、いろんな会社に遊びにいきたいと思ってます。 入門的な話をしてほしいような方、こんな使い方してますっていう話をしていただける方、大募集です。 これもGoogle Formでも作ってみるか。\nブログなぁ。小さな習慣を読んだのに、習慣化できてないので、なんとかしないとという意味で。。。が、頑張ります。。。\nRustの継続&開発の継続もですね。Java歴が長いので、他の言語を勉強しようと思ってRustやってますがなかなか身についてないというか、時間を取れてない。これもコツコツやらないとなー 検索関連の開発もちょっとずつやりたいなと思ってるんで、LukeへContributeしようかな。\n切実なんですが、日本に弊社のエンジニアを増やしたいなと。特に人前で喋ってもらえる人が増えると助かるんです。弊社最近、ユースケースが増えてきてて、追いつかなくてwダレカタスケテーw\nさーて、そろそろ紅白のサザンが始まるんで終わりです。\n今年も様々な方々に様々な面で助けていただきました。本当にお世話になりました。 この場を借りてお礼申し上げます。\n来年ももちろん、助けてもらうんで、よろしくお願いいたします! あと、話聞きたい方、声かけてくださーい。\n","date":1546240485,"dir":"post/2018/","id":"6c226ee1519fbf910197cc1d5c5a5756","lang":"ja","lastmod":1546240485,"permalink":"https://blog.johtani.info/blog/2018/12/31/looking-back-2018/","publishdate":"2018-12-31T16:14:45+09:00","summary":"今年も振り返りブログをかけてます。よかったw 振り返り(2017年に書いた抱負から) まずは去年の抱負を元に。 もっと英語の継続&TOEIC まぁ、","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2018)"},{"contents":"Elastic stack (Elasticsearch) Advent Calendar 2018の25日目の記事になります。 今年最後のAdvent Calendarです!来年も忘れてなければやるはず!\n今日は、すでにalpha2までリリースされた7系でどんな変更が入るのかをちょっとだけ紹介します。 ほんとにちょっとだけですよ。\nKibanaのk7 design (kibana) Kibanaの新デザインです。K7って呼ぶのかな?\nまだ、メニューと一部が実装されているだけですが、7.0.0でガラッと変わりそうです。 そのほかの画面のIssueはこちらです。 \u0026ldquo;k7\u0026quot;で検索しただけですが。メタIssueが見つからなかったんで。例えば、こんな感じでアプリとかのスイッチとかがこんな感じになるよというデザイン案が観れたりします。\nZen2 (elasticsearch) Elasticsearchの新しいクラスター管理機構アルゴリズムになります。 Zenと呼ばれる独自実装のものを6系までは使っていましたが、7系向けに変更がかかりました。 実際には、Nodeを探す仕組み、Masterの選出アルゴリズム、クラスター状態の管理などを行います。 上記のリンクにあるようにドキュメントも詳しくなりました。 信頼性をさらに向上し、設定ミスを起こしにくくして、より使いやすくという目的で様々な変更が加えられています。 これが、メタIssueかな? アルゴリズムの変更や、クラスターの状態の管理の方法などの変更に関するIssueやPRにリンクが貼ってあります。\n新しいデータタイプ (elasticsearch) Feature/Feature vector datatype ドキュメントはこちらとこちら\nfeature queryと合わせて使用するためのフィールドで、しかもクエリのスコア計算「のみ」に使用するフィールドになります。 検索条件やソート、Aggregationの対象ではなく、クエリのスコアに影響させたい値を入れておくためのフィールドです。 6から追加された機能の「track_total_hits」をfalseにした時と合わせると、function_scoreなどで計算をしていた場合よりも、検索性能が上がるという利点まであります。 ちなみに、「track_total_hits」は検索ヒット数を計算しないで、上位のデータを取得する時にクエリを早くするといったことができる機能になります。 Index Sortingと組み合わせることで威力が発揮できる仕組みになるはずです。\nFilebeat supports NetFlow (beats) NetFlowが入力として追加されます。 Filebeatと言いつつ、File以外の入力が徐々に増えてきてますね(UDPやTCPにも対応しましたし)。 ネットワーク機器などの監視を行う方などにはさらに便利になってくるのではないでしょうか? (私はこの辺りは不得手なので、誰か使ってみてもらえればと!)\nまとめ まだ、序の口って感じですが、今年はこの辺で。7系ではここであげた以外にも様々な機能が追加されています(もしくは予定です)。 Elasticのドキュメントの良いところは、masterブランチのドキュメントも公開されていることです。 ドキュメントのバージョンを7.0.0-alpha2にすれば、masterブランチで追加されたページが見れるので、 興味のある方は眺めてみていただければと。物によって、リリースノートが書かれていなかったりするので注意は必要ですが。\n今年もあと数日になりましたが、Advent Calendarへの参加ありがとうございました! 来年ももちろんやりますので、年始からネタを考えてくださいね。\n来年一発目は、第28回Elasticsearch勉強会 - 6.5機能紹介 -になります。ウェビナーでも紹介しましたが、6.5で入った様々な新機能をデモありで紹介する予定です。 興味のある方はぜひご参加ください。\nでは、来年もよろしくお願いいたします。\n","date":1545663601,"dir":"post/2018/","id":"ee62cb0b9a97f990df1ed0266a7027e2","lang":"ja","lastmod":1545663601,"permalink":"https://blog.johtani.info/blog/2018/12/25/whats-new-in-elastic-stack-7/","publishdate":"2018-12-25T00:00:01+09:00","summary":"Elastic stack (Elasticsearch) Advent Calendar 2018の25日目の記事になります。 今年最後のAdvent Calendarです!来年も忘れてなければやるはず! 今日は、すでにalp","tags":["elasticsearch"],"title":"Elastic Stack 7.0で入ってくる新機能をちょっと紹介"},{"contents":"Elastic stack (Elasticsearch) Advent Calendar 2018の1日目の記事になります。\nちょっと遅れちゃいました。。。 まだ、1ヶ月を残してますが、簡単に今年起こったことを振り返ってみようと思います。毎年恒例ですね、ここ数年。\nElastic Stack 6.2.0リリース(2月) リリース記事はこちら\nAPMがGAリリースされ、Beats monitoring UIも追加されました。Stackとしての統一度がちょっとずつ上がってきた感じですね。 Kibanaのホーム画面(左メニューのKibanaアイコンをクリックした時)にデータ登録のチュートリアル的な画面が追加されています。 特にBeatsを利用する時の流れが簡単にわかるのがいい感じです。Metricsなどはローカルでちょっと試すのにも簡単な流れですので、ぜひ一度やってみてもらいたいなと。 個人的にはtermsを使ったパイチャートで、その他の数値がどのくらいあるかといった表示ができるようになって、やっと帰ってきた!(Kibana 3の頃にはあった機能)という印象でした。\nElastic{ON}18開催(2月) 第4回目のユーザーカンファレンスがSFで開催されました。 今年のキーノートが今年最大のニュースですね。 X-Packのコードの公開が発表されたのがこの時でした。 個人的に今後もオープンソースに携わっていきたいと思いながら日々働いていますが、 Elasticのオープンソースへのこだわりと、シンプルな考え方を再確認して素晴らしい会社で働けてるなーと。 商用のソースコードを公開してユーザーや顧客の皆さんとより良いものを作っていきたいという形ですので、今後もよろしくお願いします! キーノートの動画はこちらからご覧いただけます。\nそのほかにも次のような発表が行われました。\nSQL for elasticsearch Canvas Elastic App Search(旧Swiftype) Elastic Stack 6.3.0リリース(6月) リリース記事はこちら\n2月末のElastic{ON}で発表されたX-Packのコードの公開にはやはり時間がかかりました。 有償コードのリポジトリとの統合やライセンスの変更、テスト環境などなど、色々大変だったみたいです。 ようやく公開され、ベーシックのライセンスの扱いなども変わり、より使いやすくなったのがこのタイミングです。\nX-Packをプラグインとしてのインストールが不要に ベーシックライセンスがデフォルトでONに。6.3から登録などが不要に。 Apache 2.0ライセンスの部分のみのディストリビューションも別途ダウンロードできるようになどなど 日本でもリリースウェビナーをやりました。ご覧いただけましたかね?\nElastic Cloud Elasticsearch Serviceがより使いやすく(8月) リリース記事はこちら\nこれまでは、メモリとストレージの比率だけしか指定できなかったのですが、 このリリースで様々なユースケースに応じた組み合わせが可能になりました。 CPUやメモリリソースよりもストレージを大きくしたりなどです。 専用マスターノードを追加できたり、待望の機械学習(Machine Learning)が提供されたりと色々と変更があり使いやすくなったかと。 昔からよく聞かれる、Kuromojiなどのカスタム辞書を登録する機能もあるので、Elastic Cloud便利です。 ご存知ない方は、14日間のトライアルもありますので試していただければと!\nElastic Stack 6.4.0リリース(8月) リリース記事はこちら\nフィールドエイリアスや韓国語のアナライザーがElasticsearchに追加されました。 Kibanaはデザインがここからさらに少しずつ変更が入ってたりします。 Elastic UIフレームワークと呼ばれるデザイン用のライブラリが、ElasticのプロダクトのUIに取り込まれていってる感じです。統一感が取れてきてますよね。私が開発しているAnalyze UIのプラグインにも取り込みました。 あとは、マイクロソフトのde:codeで話をさせていただいた、Logstash向けのAzure Moduleがリリースされたのもこのバージョンでした。AzureのEvent Hubからデータを取り込んで、SQLデータベースのモニタリングや、ユーザーの認証などをとってKibanaで可視化するものです。\nもっとも気に入っているのはサンプルデータの登録が簡単になったことです。これまでは、KibanaとElasticsearchを用意した後に、データを入れるためにFilebeatなどを使ってから、ようやくKibanaで遊べるという形でした。 6.4からは、ElasticsearchとKibanaを立ち上げて、Kibanaのホーム画面の「Sample Data」のリンクを押した後に、「Sample flght data」の「Add」ボタンを押せばKibanaからデータが登録されます(サンプルデータについてはこちら)。とりあえず触ってみたいという方への敷居がさらに下がったのではないかなぁと。\nElastic認定エンジニア第1号(8月) ブログ記事はこちら\n認定制度も始まりました。Elasticsearchの知識、経験を問われるテストを受けていただき、合格すると認定されるというやつです。 なんと、社外で世界初の認定エンジニアがアクロクエストの吉岡さんでした(上記ブログ参照)。 私もトレーナーやってるのもあり、慌てて認定をとったりしましたw。 認定テストは筆記ではなく、実際に作業をするテストなので実践的です。 トレーニングの受講が必須ではないのも面白いなぁと思いました。 トレーニングや認定エンジニアに興味がある方は、Elasticのトレーニングのサイトをご覧ください。 1月末にはまた、日本語でElasticsearchのトレーニングも開催されます!\nElastic Cloud Enterprise 2.0リリース(9月) リリース記事はこちら\nElastic Cloud Enterpriseをご存知ない方もいらっしゃるかもしれません。 Elastic Cloudの裏側で利用しているクラスターの起動などの仕組みを製品として提供しているのがこちらになります。 Elastic Cloudで機械学習や様々な構成ができるようになったものがリリースされたのがこの2.0です。 複数のElasticsearchクラスターを管理したい場合には、こちらが便利なツールになってるんじゃないかなぁと。 部署ごとにクラスターを提供するといったことが可能になるので、乱立する前に利用するのも便利かなーと。\nニューヨーク証券取引所で株式を公開(10月) ブログ記事\n日本語でブログ(10月) Elasticsearchの運用に関する典型的な4つの誤解というブログを書きました。4年も働いてるのに、会社のブログに翻訳以外で書いたことなかったので。。。 Twitterや勉強会、ブログ記事などで見かけるよくある誤解に関する記事を書いてみました。 Elasticは英語のブログも活発に書かれているのですが、今後もこのような形で日本語でのブログも頑張りますので、 読んでみたいものなどあればコメントいただければと。\nまぁ、弊社の大輪は色々書いてるんで、私がもっと頑張れって話ですかね。。。\nElastic Stack 6.5.0リリース(11月) リリース記事はこちら\n昨日(11/30)のウェビナーでも話をさせていただきましたが、Elastic Stack 6.5は「本当にマイナーリリース???」と思うほど盛りだくさんの機能がリリースされました。\nインフラUI、ログUI Elastic APMの分散トレーシング対応 Java \u0026amp; Go APM Agent GAリリース Cross Cluster Replication ODBCドライバー Kibana Canvas Kibana Spaces Data Visualizer for files Functionbeat LogstashのApp Search output リストアップしただけでもこれです。45分のウェビナーでは伝えきれてないなぁとも思ってますので、何か検討しようと思います!\nElasticsearch勉強会(3月から12月) Elasticsearch勉強会ページ\n今年は、6回の勉強会を開催(1つは12月19日開催)しました。 9月からは、ユースケースなど、もっと参加者の皆さんの興味があることにフォーカスしながら開催をしてみ始めました。 参加しやすくなってればいいのですが。。。 そろそろまたアンケートをとったりして、参加しやすいか、どんな改善がしてほしいかなどを聞きたいなと思っています。\n12月はもっと皆さんと喋りたいなということで、スピーカーなしの「LT\u0026amp;忘年会」にしてみました。 私やElasticのものも参加するので、ぜひ色々聞いたり、他のコミュニティの方達の使い方を聞き出して、 新しい発見をしていただければなーと思います。LTでスピーカーの練習をするってものありですよ!(まだ誰も応募してくれてない。。。) 発表することで、フィードバックがもらえて、自分の使い方に自信が持てたり、その他の視点を得ることができると思いますので、 ぜひ発表してみていただければと。\n12月のjohtani出没イベント 12月は以下のイベントにブースを出してます。イベントに参加される方ははぜひブースにお立ち寄りください!!\n12/4-5 : Japan Container Days - 東京 12/8 : OSC福岡 - 福岡 12/15 : JJUG CCC 2018 Fall - 東京 12/19 : 第27回Elasticsearch勉強会 - 東京 なんか、忙しそうだな。。。\nまとめ 駆け足でしたが今年を振り返ってみました。 今年も色々ありましたが、今後もよろしくお願いいたします。\nさて、Elastic Stack Advent Calendar 2018は今日から25日まで続きます。こらからの記事を楽しみにしています!\nということで、次はkaibadash@githubさんの「ぼくの考えた最強のElasticsearch index設定を最強にわかりやすく書くぞ!!!」になります。お楽しみに!\n","date":1543628918,"dir":"post/2018/","id":"ba45ddd3042dad59a12e5937644f7246","lang":"ja","lastmod":1543628918,"permalink":"https://blog.johtani.info/blog/2018/12/01/whats-happen-at-elastic-in-2018/","publishdate":"2018-12-01T10:48:38+09:00","summary":"Elastic stack (Elasticsearch) Advent Calendar 2018の1日目の記事になります。 ちょっと遅れちゃいました。。。 まだ、1ヶ月を残してますが、簡単に今年起こったことを振り返ってみよ","tags":["elasticsearch"],"title":"2018年のElastic StackとElastic"},{"contents":"(転職する少し前までパスポートすら持ってなかったのに)今の会社に転職してから、半年に1度の割合で海外への出張が発生する生活を送っています。 4年目になりますが、今回いくつか新しいガジェット?アイテム?を出張用に導入したので感想を書いておこうかなと。\nとりあえず、以下の4つです。\nFelimoa ネック ピロー これまでは、無印で購入した「フィットするネックピロー」を使ってました。 特に使ってる間は問題ないのですが、どうしてもかさばります。。。 そんな時、FBで見かけたのがこちら。\n厚みがないので、持ち運びが便利でした(商品紹介の中にありますが、リュックにつけると邪魔にならない)。 飛行機の中で使うので、それほど暑くない場所なので、ムレる感じでもなく。 ただ、ヘッドフォン+真横にフレームがくる形になるとヘッドフォンに干渉するので、 私はフレームを顎の下の方に寄せた形で使ってました。 軽さと場所を取らないのがよかったです。\nノイズキャンセリングヘッドフォン これまでは、SONYのNW-A847という ノイズキャンセリング機能付きのウォークマン+アクセサリーで外部入力を取り込む形で、飛行機で映画を見ていました。 これ自体が8年前の製品ですね。。。 これとは別に、冬の寒い時期は防寒も兼ねてヘッドフォンを使用しています。 MDR-10Rを使ってたんですが、昨年こんな感じになりまして。。。\n応急処置 pic.twitter.com/uDErZWpPVC\n\u0026mdash; Jun Ohtani (@johtani) 2017年11月10日 で、ヘッドフォンの買い替えを検討してたんです。 そこへ飛び込んできたのがSonyの新しいノイズキャンセリングヘッドフォンでしたと。\nせっかく買い換えるし、今度はいいものを長くということでフライト前日に購入してしまいました。 結論としては高いけど買ってよかったと。よかった点はこんな感じです。\n軽い イヤーパッドが耳を抑えることがないので長時間でも気にならない 人の声だけノイズキャンセリングをオフにする(騒音などはキャンセルしてくれる) バッテリーが長時間 ヘッドフォンを外さないでも案内を聞くことができる「クイックアテンションモード」 などなど。行きのフライトで5時間も遅れが出ましたが、空港、飛行機内で非常に快適に過ごせました。 大事に使おう。。。\ncw-x 知り合いがFBにアップしてて、立ちっぱなしの仕事だったり、長時間のフライトでも足が疲れないという噂を聞いて購入しました。\n長時間のフライトの後に、ホテルで1泊しても足の疲れって結構残ってるんです。 今回、12時間のフライトでズボンの下に履いて行きましたが、足の疲れがほぼありませんでした。 デブになりつつあり、足太くなって来てるので、履くのはちょっと苦労しますが。。。もともときつめに作ってるんじゃないかなぁ(希望的観測)。 帰りも使用しましたが、帰りはフライト前に1万歩ほどダブリンの街中を歩き回ってたので、流石に疲れが出てます。。。 今度は、カンファレンスのブースなどで立つことが多いシーンでも使ってみて、疲れがどうなるかを試してみようと思います。\n携帯ウォシュレット 初めて購入しました。海外のホテルで1週間とか連泊するんですが、トイレットペーパーがやはり硬めなのが気になって。。。\n世界に誇る日本の技術の一つだと確信してますw ドイツに長期出張してた友人が便利だよと言ってたので、思い切って購入して持って行きました。 硬めのトイレットペーパーも気にならなくなるのでとても幸せな気分ですw\nまとめ とりあえず、今回はこんな感じです。 総じて導入してよかったなという感じでした。 他にもおすすめ出張グッズとかあればコメントいただけると嬉しいです。\n普段使ってるものとか、どういうものを持っていってるとか興味ある人いるかなぁ? ではでは。\n","date":1539794095,"dir":"post/2018/","id":"3fd9052870778e14ab4a5acbc8c24af4","lang":"ja","lastmod":1539794095,"permalink":"https://blog.johtani.info/blog/2018/10/18/items-for-long-businesstrip/","publishdate":"2018-10-18T01:34:55+09:00","summary":"(転職する少し前までパスポートすら持ってなかったのに)今の会社に転職してから、半年に1度の割合で海外への出張が発生する生活を送っています。 4","tags":["misc"],"title":"新規導入した長期出張用のアイテムをいくつか紹介"},{"contents":"毎月開催の2回目になります。 今回は日経さんの会場をお借りしての開催となりました。\n前回から、スピーカーの募集をhttp://bit.ly/SpeakerElasticTokyoMeetup で行なっております。 ぜひ皆さんのノウハウを共有していただけると助かります。 また、次回もすでにスケジュール済みです。次回は「ログ/メトリック分析」回になります。\n以下は、個人的なメモになります。\nメディアコンテンツ向け記事検索DBとして使うElasticsearch / Future Architect 株式会社 村田 靖拓さん (twitter: @famipapamart) メディア記事コンテンツ検索 全ての情報が1indexに入っているようにすること。 typeは少し悩んだ。 範囲検索にはならない場合がある。(文字列で登録してWildcard検索できるようにした) kuromojiで基本対応 異体字についてはchar filterでマッピング 細かな設定とかもスライドにて公開予定。 基本的なプラグインだけで対応した Dynamic Field mappingを有効にしたまま対応 パフォーマンス検証 初回のインデックスのロードはこの辺かなぁ?。 自力でQueryのoffset-limitを構築するのかぁ。 ソート条件が固定らしいのでできる方法 minne での検索運用(仮) / @_shiro16 さん ハンドメイドなものをマーケットプレイスがminne SolrからElasticsearchに切り替えた話 2016/02以降はEs 昔は、DBからSolrへ同期 Es版ではDBからの同期ではなく、Workerに対してリクエストを入れる 現状は独自にEC2で運用中 ユーザーが求めているものがきちんとでているかを計測している 行動ログはどんな感じ? TDにログを入れて、CTRとかを計算してre:dashで可視化 A/Bテストも実施 指標はキャンペーンなどが実施されている場合にブレる場合もある トレンドをログから知ることができる Function Scoreでスコアを変更してる 季節的な単語でスコアを変更したりする ドリンクの対応などをして聴けてないところが。。。 query_stringのはなし / 加藤遼さん (日本経済新聞社) 電池が切れそう+ピザとかの手配をしていたらメモが取れず。\n苦労が滲み出る感じのセッションでした。 query_string queryが実際にどんなクエリになっているかの説明を交えて説明してもらえたのはすごくよかったんじゃないかと。 まとめ 検索は話してくれる人が多いし話題に事欠かないなぁという印象でした。 今回も、スピーカーの皆さん、会場提供をしていただいた日経さんありがとうございました。\n他のユースケースのスピーカーも募集してます。ぜひMeetup.comの概要に記載してあるリンクからスピーカーの応募をお願いします!\n","date":1539765230,"dir":"post/2018/","id":"d3fa23c9066f943f10e8883de9340dea","lang":"ja","lastmod":1539765230,"permalink":"https://blog.johtani.info/blog/2018/10/17/26th-elasticsearch-tokyo-meetup/","publishdate":"2018-10-17T17:33:50+09:00","summary":"毎月開催の2回目になります。 今回は日経さんの会場をお借りしての開催となりました。 前回から、スピーカーの募集をhttp://bit.ly/Sp","tags":["elasticsearch","勉強会"],"title":"第25回Elasticsearch勉強会を開催しました。"},{"contents":"7/25にJJUGナイトセミナーでElastic Stackの紹介とAPMのJava Agentの紹介をしたので、補足のブログです。 (久々に書くな。。。)\nスライドとサンプルアプリのリポジトリはこちら。\nスライド:https://speakerdeck.com/johtani/intro-elastic-stack-and-elastic-apm-java リポジトリ:https://github.com/johtani/apm-beats-kubernetes-demo/tree/master サンプルアプリ 勉強会の頭でサンプルアプリへのアクセス用QRコードを用意して質問してもらう感じにしました。\nアプリ自体が質問の受付と、そこにある質問に対して聞きたいかどうかのVoteができる仕組みになっています。 セッション最後にこの画面をみながら答えました。 手を挙げていただくよりも、匿名(名前入れるようになってますが、実名である必要はない)で登録できるし、 みんなが聞きたいかどうかもわかるので便利だなぁと。\n元は、Elastic{ON} 2018であった「Docker \u0026amp; Kubernetes Log Collection and Monitoring with Beats and Elasticsearch」のサンプルアプリです。 これをSpring Bootに移植して、ちょっとだけサンプルコードを追加したものになります。\n構成とかの補足 スライド、GitHubのリポジトリのREADMEにある図は、k8s上のサンプルアプリケーションの構成だけでした。 ElasticsearchとKibanaを含めた図はこんな感じです。\nk8s上の各種Beats、APM Serverは一旦Elastic CLoud Elasticsearch Service(AWS Tokyoリージョンにデプロイ)に対してデータを投げます。 で、KibanaはGKE(k8s on GCP)で動かして、実際に勉強会ではkubectl proxyで接続してから表示していました。 この構成にしている理由は次の理由です。\nElastic CloudのElasticsearchクラスターにデータを投げている理由 クラスターの起動が簡単。 データを永続化したい。k8sのアプリは必要がなくなったらデータを削除したいから。 k8sのdeploymentを書く手間を省く 普段使ってるので。。。 KibanaをGKEで動かした理由 Elastic Cloudでは*「現時点(7/29現在)」*で、KibanaでAPM専用のUIを起動できない ローカルである必要はない といったところです。 Elastic Cloudのインスタンスを起動したままにしておけば、デモをしなくても、このタイミングのログ、メトリクスを 再利用して話をすることも可能です。\nまとめ ということで、簡単ですが、構成の補足でした。 勉強会では告知したのですが、今後の勉強会はトピックスごとでやりたいなと。ということで、どんなトピックスに興味があるのか、スピーカーの応募にはどんなツールが話しやすいかなどといったことのアンケートを集めております。ぜひご協力ください! また、アンケート、このブログに関する質問がある場合は、@johtani、もしくはブログへのコメントでお願い致します。\n今後の勉強会のやり方などについてアンケートを実施中です。https://t.co/XU15CHro0n 皆さん是非ご協力ください。ここにない項目については返信をお願いします。 #elasticsearchjp\n\u0026mdash; Jun Ohtani (@johtani) 2018年7月23日 ","date":1532843130,"dir":"post/2018/","id":"10ae016e19fff6ae9cfaeb8534fa47f9","lang":"ja","lastmod":1532843130,"permalink":"https://blog.johtani.info/blog/2018/07/29/apm-java-at-jjug/","publishdate":"2018-07-29T14:45:30+09:00","summary":"7/25にJJUGナイトセミナーでElastic Stackの紹介とAPMのJava Agentの紹介をしたので、補足のブログです。 (久々に書く","tags":["勉強会"],"title":"JJUGナイトセミナーで話しました"},{"contents":"第2回から少し間が空いてしまいましたが、templateで作成したプラグインのディレクトリ構成とどういう流れでデータがやり取りされるかについてみていきます。 (2018/02月時点で作成したディレクトリ構成にしたがって説明します) ちなみに、JavaScriptの優れた開発者ではないので、誤解している点や、効率の悪い書き方などがあるかもしれません。見つけた場合は、連絡をいただければと思います。\nでは、まずは作成したディレクトリ構成についてみていきましょう。\nディレクトリ構成 simple-sample-kibana-pluginがプラグインのプロジェクトのトップディレクトリになります。このディレクトリに次のような構成でサブディレクトリが存在します(なお、画像はIntelliJに取り込んだ後のディレクトリになっているので、.imlなど、不要なファイル/ディレクトリが存在しています)。\n主要なディレクトリ、ファイルについて簡単に一覧で説明します(順不同)。\nファイル/ディレクトリ名 説明 index.js プラグインの本体。Kibanaはこのファイルのオブジェクトを読み込みプラグインを起動。設定などの読み込みもこちら。 package.json npm/yarnのパッケージに関する情報を定義するファイル README.md README。プラグインの説明などを記載する。インストール方法なども記載すると便利 public ブラウザ側に配布されるプログラムや画像一式 public/less/main.less LESS用のファイル。アプリ固有のスタイルなどを記載 public/app.js ブラウザ側で読み込まれるプラグインのモジュールなど。 public/template/index.html HTMLのテンプレート。ブラウザ上での描画に利用 server/routes Kibanaサーバー側で動作するプラグイン。hapi.jsを利用してREST APIを実装する 重要なファイルについて少しだけ説明します。\npackage.json npmやyarnでビルドなどをするときに使用するパッケージ情報を記載するためのファイルです。 プラグインの名前、バージョン、説明などを記載します。 Kibanaのバージョンについてもこちらで管理します。この情報を また、ライブラリなどの依存関係についてもこちらで記載しています。 以下、抜粋。\n{ \u0026#34;name\u0026#34;: \u0026#34;simple-sample-kibana-plugin\u0026#34;, \u0026#34;version\u0026#34;: \u0026#34;0.0.0\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Sample plugin for explaining how to make kibana app\u0026#34;, \u0026#34;main\u0026#34;: \u0026#34;index.js\u0026#34;, \u0026#34;kibana\u0026#34;: { \u0026#34;version\u0026#34;: \u0026#34;6.2.1\u0026#34;, \u0026#34;templateVersion\u0026#34;: \u0026#34;7.2.4\u0026#34; }, \u0026#34;scripts\u0026#34;: { \u0026#34;lint\u0026#34;: \u0026#34;eslint **/*.js\u0026#34;, ... }, \u0026#34;devDependencies\u0026#34;: { \u0026#34;@elastic/eslint-config-kibana\u0026#34;: \u0026#34;^0.14.0\u0026#34;, \u0026#34;@elastic/eslint-import-resolver-kibana\u0026#34;: \u0026#34;^0.9.0\u0026#34;, \u0026#34;@elastic/plugin-helpers\u0026#34;: \u0026#34;^7.1.3\u0026#34;, ... \u0026#34;expect.js\u0026#34;: \u0026#34;^0.3.1\u0026#34; } } ちなみに私は、versionなどをリリースするたびに変更しています。\nindex.js 最初にKibanaに読み込まれるオブジェクトになります。 Kibanaのアプリの名前や、必要なモジュールなどを記載します。\nまた、kibana.ymlから設定など読み込む処理なども書くことができます。\n2行目のexampleRouteはサーバー側のAPIとして利用するhapi.js用のファイルのパスになります。\nuiExportsはこのアプリの画面に関する設定などの記載になります。 appの部分が実際にアプリの情報で、 mainがあとで説明するこのプラグインのUIのためのJavaScriptファイル(public/app.js)になります。mainですので、最初に読み込まれる処理が記載されているものを指定します。app.jsというファイル名を変更する場合は、こちらのappの部分を変更したファイルに合わせましょう。\nconfig(Joi)の関数が設定ファイルの読み込みなどの処理を記載する場所です。\ninit(server, options)の関数が初期化処理を記載する場所になります。 このサンプルアプリでは、2行目のimportで読み込んだhapi.js用のファイルの関数を呼び出しています。引数で渡しているserverがhapi.jsのserverオブジェクトになります。 routeメソッドを使用して作成しているプラグイン用のREST APIを追加しています。\nimport { resolve } from \u0026#39;path\u0026#39;; import exampleRoute from \u0026#39;./server/routes/example\u0026#39;; export default function (kibana) { return new kibana.Plugin({ require: [\u0026#39;elasticsearch\u0026#39;], name: \u0026#39;simple-sample-kibana-plugin\u0026#39;, uiExports: { app: { title: \u0026#39;Simple Sample Kibana Plugin\u0026#39;, description: \u0026#39;Sample plugin for explaining how to make kibana app\u0026#39;, main: \u0026#39;plugins/simple-sample-kibana-plugin/app\u0026#39; }, ... }, config(Joi) { return Joi.object({ enabled: Joi.boolean().default(true), }).default(); }, init(server, options) { // Add server routes and initialize the plugin here exampleRoute(server); } }); }; public/app.js 画面用のモジュールです。 uiRoutesという機能を使用して、アプリの呼び出しURLを定義します。テンプレートで作成したばかりの場合は、/というURLが追加されるのみです。\n実際に画面を表示する際に動くコントローラーの部分はその下の uiModules.controllerに指定してあるfunctionが画面描画の 処理を書く部分になります。 templateで作成したプラグインでは、\u0026ldquo;title\u0026quot;など表示に必要なデータを$scopeというオブジェクトに詰め込んでいます。 これはAngularJS(1系)でのモデルオブジェクトになります。\nimport moment from \u0026#39;moment\u0026#39;; import { uiModules } from \u0026#39;ui/modules\u0026#39;; import uiRoutes from \u0026#39;ui/routes\u0026#39;; import \u0026#39;ui/autoload/styles\u0026#39;; import \u0026#39;./less/main.less\u0026#39;; import template from \u0026#39;./templates/index.html\u0026#39;; uiRoutes.enable(); uiRoutes .when(\u0026#39;/\u0026#39;, { template, resolve: { ... } }); uiModules .get(\u0026#39;app/simple-sample-kibana-plugin\u0026#39;, []) .controller(\u0026#39;simpleSampleKibanaPluginHelloWorld\u0026#39;, function ($scope, $route, $interval) { $scope.title = \u0026#39;Simple Sample Kibana Plugin\u0026#39;; $scope.description = \u0026#39;Sample plugin for explaining how to make kibana app\u0026#39;; ... $scope.$watch(\u0026#39;$destroy\u0026#39;, unsubscribe); }); server/routes/example.js hapi.jsというNode.jsのためのサーバーフレームワークです。 このフレームワークをKibanaは使っており、Kibanaのサーバーとブラウザとのやり取りに使用するREST APIを記述するために使用しています。 例えば、Elasticsearchとのやり取りを実際に行うAPIなどをこのREST API内部で記述します。\nexport default function (server) { server.route({ path: \u0026#39;/api/simple-sample-kibana-plugin/example\u0026#39;, method: \u0026#39;GET\u0026#39;, handler(req, reply) { reply({ time: (new Date()).toISOString() }); } }); } pathの部分がブラウザ側からアクセスするURLになります。 実際にElasticsearchとやり取りする処理の書き方については、次回の記事で説明します。\nアーキテクチャ(簡易版) ざっくりですが、ファイルやディレクトリについて説明しました。 簡単なデータのやり取りについての流れを説明します。\nKibana自体はNode.jsで実装されサーバーとして動作していますが、ブラウザでアクセスすることで画面を描画しています。 簡単なコンポーネントを並べるとデータのやり取りはこのような形です。\nすごく簡易で大雑把な絵ですが。。。\n実際のプラグインとしては大きく、2つの処理があります。\nブラウザ上の処理 クリックなどのイベント処理 HTMLなどのレンダリング処理 Kibanaサーバー上の処理(Elasticsearchなどとの通信が必要な場合) 外部との通信処理 ブラウザ上では重い処理 絵に記載しましたが、ブラウザ上の処理についてはAngularJSが主なフレームワークで、サーバー上の処理についてはhapi.jsがフレームワークとなっています。\nまとめ ということで、今回はディレクトリ構造とファイルの説明、どういったフレームワークが使われ、データのやり取りがどのように行われているか説明しました。\n次回からは、実際に私が作成したAnalyze UIを元にElasticsearchとのデータのやり取りなどについて紹介していきます。\n","date":1524205801,"dir":"post/2018/","id":"04d818cbaac08b2915db15e0bffdcb5b","lang":"ja","lastmod":1524205801,"permalink":"https://blog.johtani.info/blog/2018/04/20/directory-layout-and-architecture/","publishdate":"2018-04-20T15:30:01+09:00","summary":"第2回から少し間が空いてしまいましたが、templateで作成したプラグインのディレクトリ構成とどういう流れでデータがやり取りされるかについ","tags":["Kibana","plugin"],"title":"Analyze UIとKibanaのプラグインの作成方法(第3回)"},{"contents":"#MANABIYA のブースでセッション時間の合間はお客さん少ないので、ブログを書いてみたり。 ここ数年、スポンサーとして色々なカンファレンスに参加してるんですが、それについてちょっと気なることがあったので。\nスポンサー情報ってどうやって探してます? 職業柄、カンファレンスにCfP出してセッションしてみたり(落ちること多いけど)、スポンサーとしてブースを出したりしています。\nで、疑問があるんですが、みなさんどうやってカンファレンスの情報をゲットしてます?\n数年やって来て、検索したりして見つけてスポンサーした結果、 これまでスポンサーしていたので、情報が流れてくるという感じになりました。 それ以外だと、@yusuke さんに教えてもらったりと言うのがあったんですが。。。\n自分が知らない、自分のTwitterで流れてこないという情報をどうやったら集められるかな?と言うのが今の課題になってます。 と言うことで、ブログを書いてみました。\nカンファレンスを検索できるサイトとか便利? で、私の会社は検索エンジンの会社なんで、検索できると便利では?と考えるんです。\nCfPの応募期間で絞り込みできたり、場所で検索できたり、スポンサー情報を取得する方法が載ってたりすると便利なのではないかなと。 便利に思うのが自分だけでは?と言うのがあるんですが。。。\nあると嬉しい人、データを掲載したいなと言う人いますでしょうか? Google Formなどで入力してもらえるようにして何か作るのもありかなぁと考えているところです。 それとも、スポンサーを募っているカンファレンスのスタッフや企業の人は、こういう情報は特定の人にだけ知ってもらったりしたいでしょうか?\n自分だけではわからないことが多いので、懸念事項や、それダメでしょ? あると便利!などのフィードバックをいただけると助かります。\nそれ以外に、カンファレンス自体の場所、開催日程、サイトへのURLなどが検索できると便利だったりするかも?というのもあります。\nとりあえず、自分が知ってるものだけ、個人的に検索できるようにしたりするのがいいかなぁ。。。 コメントお待ちしてます!\n","date":1521867012,"dir":"post/2018/","id":"8cc6b19cd410e638f4beaf1642f4f52a","lang":"ja","lastmod":1521867012,"permalink":"https://blog.johtani.info/blog/2018/03/24/how-to-find-conferences/","publishdate":"2018-03-24T13:50:12+09:00","summary":"#MANABIYA のブースでセッション時間の合間はお客さん少ないので、ブログを書いてみたり。 ここ数年、スポンサーとして色々なカンファレンスに参加してるんです","tags":["カンファレンス","スポンサー"],"title":"カンファレンス情報の探し方(CfP、スポンサー応募、開催期間など)?"},{"contents":"Rustで言語処理100本ノックの続きで、05と06です。\n05. n-gram 問題はこちら。\nみんな大好きn-gramです。単語と文字があるので、それぞれ別関数として実装しました。問題はbi-gramとn=2だったのですが、一応、nを引数に取る形にして実装しました。\nまずは、単語です。\n前に実装した時は、自分で頑張って、先頭から数えたりしてたんですが、Rustにはwindows(n)という便利なメソッドがsliceにあり、これを利用したらこんな簡単になりました。 sliceは特定のシーケンス(配列)に対してある特定のサイズのViewを作ってくれます(説明あってる?)。 ということで、文字列から、単語の配列(スペース区切りで単語にしている)を作り出して、windows(n)メソッドを通すと、 nで指定した数字の個数だけの単語の配列を先頭から、1単語ずつずらして作ってくれます。まさに、n-gram! 戻り値は配列の配列です。 1点だけ疑問点があるのは、「空白で区切ったものが単語」という考え方で良いかどうか?という点です。特に問題文にはそれが明示されていなかったので、このような前提を置いてあります。\ninvalid_n(text, n)はnの値や入力された文字列をチェックする関数です。入力チェックですね。nが1よりも小さい場合、入力文字列が空文字の場合は、warningでメッセージを出して、空の配列を返す仕組みになっています。\n次は、文字です。\n単語とほぼ一緒ですが、入力文字列を、1文字ずつの配列にしているところが異なります。 また、windowsメソッドで取り出された、1文字ずつのn個の配列を文字列に修正してから、結果の配列に入れています。 ここでも疑問は空白をどう扱うか?になります。 現時点では、空白も1文字とカウントして扱うことにしてあります。 どっちがいいのかなぁ?\n06. 集合 問題はこちら。\nまずは、文字n-gramで出てきた文字列をSetに入れる関数から。\nn-gramの問題で実装した文字n-gramの関数の戻り値を配列ではなく、BTreeSetに変えたものになります。比較などがしやすいように?と思い、BTreeSetを利用していますが、実装としてはHashSetでも問題ないかと。 この関数の集合(Set)を元に、和集合、積集合、差集合を求める関数を実装しました。\nSetのメソッドとして、それぞれ、union=和集合、intersection=積集合、difference=差集合のメソッドが用意されているので、特に困ることはなかったです。 差集合については、1-2と2-1で結果が異なるはずなので、それぞれをテストケース、main.rsで出力するようにしてあります。\n所感 今回は、Rustがすでに実装してくれているメソッドがあったので楽ができました。 やりたいことに相当するメソッドがあるかどうかを調べるためにリファレンスを探さないといけないのがちょっと苦労しましたが。。。 ということで、今日はこの辺りまで。\n","date":1521549285,"dir":"post/2018/","id":"d791eaca9375ca1b36a987af22ee71dd","lang":"ja","lastmod":1521549285,"permalink":"https://blog.johtani.info/blog/2018/03/20/nlp100-ch01-05to06/","publishdate":"2018-03-20T21:34:45+09:00","summary":"Rustで言語処理100本ノックの続きで、05と06です。 05. n-gram 問題はこちら。 みんな大好きn-gramです。単語と文字があるので、それぞれ別関","tags":["Rust","nlp100"],"title":"第1章の05から06までやってみた(言語処理100本ノック)"},{"contents":"Rustで言語処理100本ノックの続きで、03と04です。\n03. 円周率 問題はこちら。\n入力文字列を.split_whitespace()で分割しておいて、単語ごとのベクタを作り出し、そこに対して文字を数えました。「アルファベットの」という注意書きがあるので\u0026quot;,\u0026ldquo;や\u0026rdquo;.\u0026ldquo;は含めずに数えるのかなということで、 charの.is_alphabetic()でA-zまでの判定をしつつ、文字のベクタを作ってから、そのベクタの長さを詰め込むという感じでやりました。\nこれ、ひょっとして、collectでベクタにしなくても、i32とかの変数でカウントするとベクタ作らなくてもいいなじゃにか?というのに書きながら気づいた。。。 必要じゃないオブジェクトを作ってるよなぁ。\n.filter().mapとかかな?この辺りの操作がイマイチ苦手。Javaでもまだ馴染めてないところなんだよなぁ。頭固すぎ。\n04. 元素記号 問題はこちら。\n大作ですね。何だろう、大作。。。 最終的に連想配列(辞書型もしくはマップ型)」ということだったので、BTreeMapに詰め込んでます。 HashMapでもいいんですが、文字列で出力した時にキーが並んで見やすいからという理由で、BTreeMap使いました。それ以上の理由はないです。普通にやるなら、HashMapかな?\n入力として、1文字だけの出力をする場所(インデックス番号)の配列を受け取ってます。1点だけ、チェックしていない、けど入力値の想定をしていて、idx_one_symbolsがソートされていて、小さいものから順番に出てくるものとしてます。関数作って、チェックすべきかな?\nで、指定された場所の最後のものが入力文字列よりも大きいかどうかというチェックもしています。(あー、テストケース書いてないな)この辺りのせいでちょっと長めになってます。\n単語の配列を作るのは03の時と同じやり方です。 回しかたがちょっと違って、.iter().enumerate()で回して、添字と値をタプル?でとりだしてます。添字を見ながら1文字取り出すのか、2文字取り出すのかの判断が必要だからです。あとは一緒ですね。1文字取り出すときは、.first()を使って見ました。 実は、2文字取り出す時と、1文字の時と同じロジック使った方が共通化できて、短くなった???\nということで、こんな感じでした。いつものようにツッコミお待ちしてます。\n所感 問題それぞれについてではなく、 やってて思ったのですが、問題に対して想定される結果が記載されていると嬉しいなと思いました。 ロジックについては、各自実装者に寄ったり、言語によって違いが出たりするし、議論するベースになっていいかなと思うんですが、 問題で想定されている結果(出力)があると、自分の実装にケアが足りないところがないのか?とか、ケアしなくていい点とかがわかるのかもなぁと。 ユニットテスト相当のものがあると楽かなぁと。\nこのケースどうするんだろ?みたいなのが、ところどころコメントに残ったりしてます。 出題の意図としては、その部分も議論の対象ということなのかな?\n","date":1519032848,"dir":"post/2018/","id":"e6684944c37dbdd4c08d978af9e47bed","lang":"ja","lastmod":1519032848,"permalink":"https://blog.johtani.info/blog/2018/02/19/nlp100-ch01-03to04/","publishdate":"2018-02-19T18:34:08+09:00","summary":"Rustで言語処理100本ノックの続きで、03と04です。 03. 円周率 問題はこちら。 入力文字列を.split_whitespace()で分割して","tags":["Rust","nlp100"],"title":"第1章の03から04までやってみた(言語処理100本ノック)"},{"contents":"「鉄は熱いうちに打て」ということで、言語処理100本ノックの第1章の00から02を実装してみました。\nさて、これが効率がいいのかどうかはさておき。\n00. 文字列の逆順 問題はこちら。\n最初、Vecのreverse()で逆順にして0からlen()まで回してたんですが、pop()がいい感じに後ろから取れることがわかったんで、切り替えました。 シンプルかな?\n01. 「パタトクカシーー」 問題はこちら。\n1文字ずつ取り出して、インデックスの番号が2で割ってあまりが0なら文字列に追加していくってのでやってみました。 (ブログ書いてるところで、i in 0..char_array.len()じゃなくて、(i, x) in char_array.iter().enumerate()に切り替えました。) matchとか使って綺麗に書けたりするのかなぁ?\n02. 「パトカー」+「タクシー」=「パタトクカシーー」 問題はこちら。\nだいぶ思考錯誤してる感じがソースに現れてます。 とりあえず、両方の文字列をcharsの配列にして個々のイテレータを回しながら、next()の戻り値があれば追加していく感じにして、 終了条件が両方Noneを通ったらにしてるけど、、、 なんか、もっと綺麗にできないのかなぁ。。。 next()のタプル返す関数作って、とかでなんかできたりするかなぁ?\ngist-it 関係ないですが、GitHubのコードを貼り付けるのに便利なサービスがあるみたいです。\nhttp://gist-it.appspot.com\nこれほんと便利だな。行数指定もできるし。 説明するのが簡単だ。\nとりあえず、今日はこの辺まで。なんか、いい知恵あれば教えてください!\n","date":1518699541,"dir":"post/2018/","id":"bbe1deec11d459bdb348051b970abdaf","lang":"ja","lastmod":1518699541,"permalink":"https://blog.johtani.info/blog/2018/02/15/nlp100-ch01-00to02/","publishdate":"2018-02-15T21:59:01+09:00","summary":"「鉄は熱いうちに打て」ということで、言語処理100本ノックの第1章の00から02を実装してみました。 さて、これが効率がいいのかどうかはさてお","tags":["Rust","nlp100"],"title":"第1章の00から02までやってみた(言語処理100本ノック)"},{"contents":"ども。新しいもの始めないと頭が退化する。。。ということで、こちら( happy new year and new language - katsyoshiのめもみたいなもの)のブログに触発されて、言語処理100本ノックをはじめてみました。\n言語処理100本ノックとは、自然言語処理になるのかな、東北大学の研究室の先生が公開している言語処理に関する実践的な課題をベースにプログラミングなどのスキルを学んでいくための問題集です。 元々はPythonを対象とされているようですが、Rustでやってみようかと。 まぁ、先ほどあげたブログの二番煎じです。。。 ちなみに、インスパイアされた元のブログの方はRust book 2nd editionを読み終えたらしいですが、私はかじった程度です(ダメかも?)。\nNLPもRustもかじった程度なので、苦戦しそうですが、ちょっとずつやっていこうかなと。 ということで、準備運動の第1章から始めようかと。 GitHubにちょっとずつあげていく予定です。 https://github.com/johtani/nlp100-rust\nまぁ、まずは宣言のブログを書いてみただけです。 続いてなかったら、叱咤激励してください。叱咤だけかも?\n","date":1518605551,"dir":"post/2018/","id":"a673b3829e62477e01abc75465416b86","lang":"ja","lastmod":1518605551,"permalink":"https://blog.johtani.info/blog/2018/02/14/start-nlp100-with-rust/","publishdate":"2018-02-14T19:52:31+09:00","summary":"ども。新しいもの始めないと頭が退化する。。。ということで、こちら( happy new year and new language - katsyoshiのめもみたいなもの)のブログに触発されて、","tags":["Rust","nlp100"],"title":"言語処理100本ノックはじめました(Rust)"},{"contents":"第1回では、Analyze UIというプラグインの紹介をしました、ごく簡単にですが。\n第2回では、Kibanaのプラグインの作成方法を順を追って見ていこうと思います。今回は、プラグインのプロジェクトの作り方を説明します。 どんなファイルがあるのかなどについては第3回で説明します(2018/02月現在の方法になります。残念ながら、Kibanaのプラグイン作成自体はまだExperimentalな話になっていますので、変更がある可能性があります)。\n実はそれほど難しいというわけではありません。Kibanaのプラグインを作成するためのテンプレートが用意されています。template-kiban-pluginです。 テンプレートのリポジトリのREADMEに作業手順の記載があります。\nKibanaのリポジトリをClone、Checkout Node.jsの環境を用意する Kibanaを起動できるようにする SAOのインストール テンプレートによるプロジェクトファイルの生成 順を追って説明します。 PLUGIN_DEV_DIRというディレクトリ配下で作業をしている想定になります。\n1. KibanaのリポジトリをClone、Checkout 開発環境として、Kibanaが必要です。Kibanaのプラグインを作るので。 手順などはKibanaのCONTRIBUTING.mdに記載があります。 ということで、まずはKibanaのリポジトリをCloneします。\ncd PLUGIN_DEV_DIR git clone git@github.com:elastic/kibana.git このままだと、masterブランチなので、開発したい対象のKibanaのバージョンのブランチもしくはタグをcloneします。今回は6.2.1向けということで、次のようになります。\ngit checkout v6.2.1 これで、ソースが6.2.1向けになりました。\n2. Node.jsの環境を用意する Node.jsをインストールします。 Kibanaのリポジトリに.node-versionというファイルがあります。 こちらにNode.jsのバージョンが記載されています。 Kibanaが使用しているNode.jsを利用できるようにします。ローカルではnvm利用してインストールしました。後から、切り替えが可能だからです。 nvm自体のインストールについてはnvmのサイトをご覧ください。 nvmがインストールできたら、次のコマンドで、Kibanaが使用しているバージョンをインストールします。\ncd kibana nvm install \u0026#34;$(cat .node-version)\u0026#34; すでにnvmを利用している場合などは、Kibana起動時にKibanaのバージョンに合わせたNode.jsに切り替えるようにしてください。\n3. Kibanaを起動できるようにする Kibanaではyarnというjavascript向けのパッケージマネージャーを利用して起動やビルドなどを行います。まずはyarnをインストールします。最近npmからyarnに切り替えたようです。 私はMacだったので、brewでインストールしました。 インストールできたら、次のコマンドを実行します。\nyarn これにより、package.jsonから必要なライブラリなどをダウンロードして来てくれます。 問題なければ「✨ Done in 439.30s.」というような表示がされます(結構時間かかりますね)。 では、Kibanaを起動できるか確認してみましょう。 さらに、Elasticsearchも起動してみます。 Kibanaのpackage.jsonの中にはElasticsearchを起動するためのスクリプトも用意されています。実際にはgruntを利用してタスクを実行しているようです。Elasticsearchの起動にはJavaが必要になります。 今回は6.2.1なので、JDK 8以降がインストールされている必要があります。 こちらはインストールされているものとします。\nyarn elasticsearch で起動できます。\n\u0026gt;\u0026gt; Started 1 Elasticsearch nodes. という表示が出てればOKです。 次にKibanaです。別のTerminalを起動して、以下のコマンドで起動できます。\nyarn start これだけです。\nserver log [06:58:56.930] [info][listening] Server running at http://localhost:5603 この辺りが出てればKibanaのServerは起動済みです。また、Elasticsearchに接続できていれば、次のログが出ているはずです。\nserver log [07:02:18.010] [info][status][plugin:elasticsearch@6.2.1] Status changed from red to green - Ready Elasticsearch接続用のKibanaのプラグインの状態になります。 これで、Kibanaの環境が整ったことが確認できました。 もちろん、Elasticsearchに関しては、yarnで起動せずに、tar.gzなどでダウンロードして来たElasticsearchを起動しておき、アクセスするといったことも可能です。プラグインなどをElasticsearchにもいれてテストしたい場合などはそちらの方が便利かもしれません。\n4. SAOのインストール では、一度、ElasticsearchとKibanaを停止しましょう。フォワグラウンドで起動しているので、それぞれのTerminalでCtrl+Cで停止できます。 Kibanaのプラグイン作成むけに、テンプレートが作られています。sao.jsというGitHubのリポジトリやnpmのパッケージをテンプレートとして使うことができるツールを利用してプラグインのプロジェクト(リポジトリ)を作成します。 実際にテンプレートとなるリポジトリはtemplate-kibana-pluginになります。 まずはSaoのインストールです。\nnpm install -g sao プラグインのテンプレートのページには上記のようにnpmを利用したインストール方法になっていますが、次のようにyarnでも可能です。\nyarn global add sao これで、saoがインストールできました。\n5. テンプレートによるプロジェクトファイルの生成 あとは、テンプレートを元にプロジェクトを作成します。 PLUGIN_DEV_DIRディレクトリ配下に、kibanaと同じ階層で作成するプラグイン用のディレクトリを作成します。\nmkdir simple-sample-kibana-plugin 以下のような構成になります。\nkibana simple-sample-kibana-plugin 次にテンプレートを適用していきます。\ncd simple-sample-kibana-plugin sao kibana-plugin@7.2.4 2行目がsaoを利用してプロジェクトを作成しているコマンドになります。 すると、次のような質問が出て来ます。 これらに答えるとプロジェクトに必要なファイル(package.jsonやREADME.mdなど)に入力した情報を適用したものを作ってくれます。\n? Name of your plugin? ? Provide a short description ? What Kibana version are you targeting? ? Should an app component be generated? ? Should translation files be generated? ? Should an hack component be generated? ? Should a server API be generated? 実際に答えた内容はこちら。\n? Name of your plugin? simple-sample-kibana-plugin ? Provide a short description Sample plugin for explaining how to make kibana app ? What Kibana version are you targeting? 6.2.1 ? Should an app component be generated? Yes ? Should translation files be generated? Yes ? Should an hack component be generated? Yes ? Should a server API be generated? Yes プラグインの名前などは、ディレクトリ名と同じものを入力補完してくれているので、そのままEnterでもOKです。 Descriptionについてはわかりやすいものを入力しましょう。 バージョンは、先ほどのKibanaのリポジトリに合わせて、6.2.1にしてあります。 あとは、作るプラグインの種類に応じて、必要なコンポーネントを作るかどうかの質問にYes/Noで答えます。 今回はサンプルの説明ということもあるので、全てYesで答えました。 ちなみに、私が実際に作成したanalyze-api-ui-pluginでは、appとtranslationとserverの3つを作成しました。 ただし、translationについては現在はテンプレートで作成したままのファイルが入っており、実際には利用してないです。\n完了したら、プラグインのサンプル入りのプロジェクトが完成です。 もう一度、Elasticsearchを立ち上げて、プラグインのプロジェクトからKibanaを起動してアクセスしてみます。まずは、PLUGIN_DEV_DIR/kibanaディレクトリの下で、Elasticsearchを起動します。\nyarn elasticsearch 次に、PLUGIN_DEV_DIR/simple-sample-kibana-pluginディレクトリの下で、以下のコマンドを実行し、プラグインが入った状態のKibanaを起動します。\nyarn start 問題なく起動すれば、ブラウザでアクセスすると次のような画面が表示されるはずです。\n左側にメニューが1つ増えています。 クリックすると、上記画像のような画面が表示されるはずです。\nこれで、カスタムプラグインの開発ができる環境ができました! 次回は、プロジェクトのディレクトリ構成や、どんなツールが内部で使用されてデータのやり取りが行われているかについて説明します。お楽しみに。\n","date":1518167857,"dir":"post/2018/","id":"7b6cb59a177abe9767fd22da5a03b1e6","lang":"ja","lastmod":1518167857,"permalink":"https://blog.johtani.info/blog/2018/02/09/getting-started-template-kibana-plugin/","publishdate":"2018-02-09T18:17:37+09:00","summary":"第1回では、Analyze UIというプラグインの紹介をしました、ごく簡単にですが。 第2回では、Kibanaのプラグインの作成方法を順を追って","tags":["Kibana","plugin"],"title":"Analyze UIとKibanaのプラグインの作成方法(第2回)"},{"contents":"あけましておめでとうございます。今年はサボりがちだったブログをちょっとずつ復活させようかと。 ということで、第1弾として、昨年少し作っていたKibanaのプラグインを何度かに分けて紹介したいと思います。\n今回はAnalyze UIというプラグインの紹介です。\n今回はインストール方法と簡単な機能紹介です。 細かな紹介は個別にやりたいと思います。\nAnalyze UI pluginとは? Elasticsearchの_analyzeというAPI\u0002(個人的に好きなAPIです)をご存知でしょうか?\nElasticsearchは全文検索エンジンで、データの検索には転置インデックスというものを使用します。 Elasticsearchにデータを登録する際に、text型のデータの場合、この転置インデックスのキーとなる単語を決める処理のことをAnalysisと呼びます(Analysisの詳細については割愛します。後日説明するかも?)。 このAnalysisの処理が、入力されたデータの文字列に対してどのように行われて、結果としてどんな単語がキーとして用いられているかを確認できる機能が_analyze APIです。検索で単語がうまくヒットしないな?とか、なんで、こんなので検索結果に出てくるんだ?といった場合、このAPIを利用すると、どのような単語で転置インデックスが作られているかがわかるので、検索にヒットしない/する理由を見つけることができます。\nElasticsearchの便利な点はRESTfulなAPI+JSONでやりとりができる点なのですが、_analyze APIの結果をJSONで受け取っても、見るのにちょっと苦労します。。。こんな感じ。\nリクエスト:\nPOST _analyze { \u0026#34;analyzer\u0026#34;: \u0026#34;kuromoji\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;今年はブログをいっぱい書きますよ!\u0026#34; } レスポンス:\n{ \u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;今年\u0026#34;, \u0026#34;start_offset\u0026#34;: 0, \u0026#34;end_offset\u0026#34;: 2, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 0 }, { \u0026#34;token\u0026#34;: \u0026#34;ブログ\u0026#34;, \u0026#34;start_offset\u0026#34;: 3, \u0026#34;end_offset\u0026#34;: 6, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 2 }, { \u0026#34;token\u0026#34;: \u0026#34;いっぱい\u0026#34;, \u0026#34;start_offset\u0026#34;: 7, \u0026#34;end_offset\u0026#34;: 11, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 4 }, { \u0026#34;token\u0026#34;: \u0026#34;書く\u0026#34;, \u0026#34;start_offset\u0026#34;: 11, \u0026#34;end_offset\u0026#34;: 13, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 5 } ] } このくらいの量であればまだなんとかなりますが、文章が長くなると辛いですよね。\nということで、GUIがあると便利だろうなぁと。で、作ってみましたというのが今日紹介するKibana用のAnalyze UIプラグインです。 こんな感じで、Kibanaのアプリの一部として動作しブラウザ上で、入力テキストの文字列がどのようにanalyzeされて、単語になるかがわかります。\n(先ほどのAPIのサンプルと同じものを画面で入力した結果になります)。\nインストール方法 現時点の最新版Kibana(6.1.2)に対応しています。 Kibanaのディレクトリでkibana-pluginコマンドを利用してインストールします。\n./bin/kibana-plugin install https://github.com/johtani/analyze-api-ui-plugin/releases/download/6.1.2/analyze-api-ui-plugin-6.1.2.zip これだけです。 で、Kibanaを起動していただくと、左のメニューに「Analyze UI」という項目が増えています。\nクリックすると、Analyze UIが表示されます。\n初期画面は入力された文字を特定のAnalyzerで処理した場合の結果を見るための画面です。綱目の説明は画像をご覧ください。\n先ほどのJSONよりは見やすくなったかと思います。 そのほかにもいくつか画面や機能があるのですが、今日はこの辺りで。 「_analyze API便利なんだけど、JSONは。。。」とか「検索うまくできないなぁなんでだろう?」と思っている方は、ぜひ試して見ていただければと。 問題点などありましたら、GitHubのIssueを登録してください。\n","date":1516343806,"dir":"post/2018/","id":"4afcb20d4d95bcd1bde3aa6b7f552660","lang":"ja","lastmod":1516343806,"permalink":"https://blog.johtani.info/blog/2018/01/19/how-to-make-kibana-plugin-example-analysis-ui/","publishdate":"2018-01-19T15:36:46+09:00","summary":"あけましておめでとうございます。今年はサボりがちだったブログをちょっとずつ復活させようかと。 ということで、第1弾として、昨年少し作っていたK","tags":["Kibana","plugin"],"title":"Analyze UIとKibanaのプラグインの作成方法(第1回)"},{"contents":"今年は紅白を見ながら書いてます。 今年はいろんなところに出張に行ったなぁ。\n振り返り(2016年に書いた抱負から) まずは去年の抱負を元に。\nもちろん英語の継続 もちろん継続してます。英会話しながら海外TVドラマや映画を見てます。 ちょっとずつ英語字幕でも見ようとしてますが、まだまだだなぁ。 あと、TOEICを受けてないんで、それは受けないと。 見たドラマはこの辺です。\nER ウォーキング・デッド Agent of Shield SUITS Mr.Robot(いまいち話の展開についていけなかった) 継続的にイベントに登壇 OSCに今年もブース出してセッション持ってました。 勉強会ももちろんやりました。 あと、外部のカンファレンス(FOSS4G、BigData Analytics、db tech showcaseなど)や 勉強会(monitoring勉強会やCA.ioなど)にも登壇させていただきました。 もっと外部から読んでいただいたり、CfPに応募して通過できるようにしないとなぁ。\nもっと開発&ブログ ブログはすみません。。。来年頑張ります。。。 ブログの代わりに書籍を出せました。データ分析基盤系の書籍になるので、興味のある方はのぞいて見ていただければ。\n開発はちょっとやってます。今年後半はKibanaのプラグインとかをちょっと書いてました。 Ingest-CSVもちょこちょこバージョンアップに追従してたりします。\nサポートエンジニア獲得! 獲得しました!(自分の成果かどうかはわかりませんが。。。) 今は3名体制でサポートしてもらってます。おかげさまでだいぶサポートする機会が減ってきました。 開発は世界各地どこでも募集中だったりしますので、ぜひ連絡いただければと。\n個人的な検索勉強会の再開 再開しました。検索エンジン自作入門を知人と隔週くらいで読んでます。読んでるだけではあれなんで、実装もしてたり。全然違う言語でトライして見ようと思ったのでRustで書き始めてます。まずは、単純なところからと思ったんですが、 Rustの書き方の違いにだいぶ戸惑ってます。。。\n振り返り(今年あったできごと) ここからは今年の出来事を。\n初アメリカで釣り Nintendo Switch! 初Japanチームオフサイト チーム変更 初Berlin Buzzword! 母校(大学)訪問 Kibanaプラグイン開発 今年も初モノがちらほらとありますね。 今年もカレンダー振り返ってたら「え?これ今年だったの?」ってのがちらほらありました。。。\nアメリカで釣りやりました。自社のカンファレンスElastic{ON}のあとに、エンジニアが集まるミーティングがあるんですが、そこで1日Fun Dayがあって、そこで釣りをやりました。 魚群探知機とかで魚探すんですね、最近のは。2、3匹釣ったので非常に楽しかったです。 来年はスノーシューにチャレンジする予定。\nNintendo Switch買って、ゼルダやりました。今はイカやってます。 イカ欲はちょっと減ってるかもなぁ、1に比べると。 あとは、子供に買ったマリオやったりしてるかな。\nここ10年くらい行きたいと思っていたカンファレンス、Berlin Buzzwordに行ってきました! これが今年一番嬉しかった出来事です。Luceneコミッターの方々にも会えたし。特にPoliceman JenkinsのUweさんに会えたのが本当に感激でした。。。 来年も行けるといいなぁ。。。\n今年も出張が多めだったのであちこち飛び回ってたなぁ。 そんな飛び回っている中で、故郷である広島(出身地?)に出張で行ったので、母校に顔を出してきました。 変わってなかった。。。自分が一期生なので、自分が入学した時はまだクレーンとか立ってるような新校舎だったんだけど、それが20年くらい経て、だいぶ古くなってました。。。 広島市内は港近くに高速道路とか出ててだいぶ様変わりしてました。 ただ、小学校も高校も変わってなかったなぁ。久々に高校の同級生にも会えたし。 また、機会があればぜひ行きたいなと。帰省する場所ではなくなったので、行く機会がないんですよね。。。\n開発もちょっとやってます。Kibanaのプラグインに挑戦して見てます。 いまだにJavaScriptは苦手なんですが。。。 ちょっとずつ改良して、ひょっとすると本体とかに取り込めるかな? あとは、今年始めたRustをちょっとずつ継続して行きたいなと。\n来年の抱負 最後は来年の抱負を。\nもっと英語の継続&TOEIC 継続的にイベントに登壇 CfPもっと出すぞ! もっとブログ! 雑誌やWeb系雑誌で記事を。 コミュニティを別の方法で盛り上げ Elasticsearchなど検索系の開発にも参加 英語はもちろんですね。今年は12月の自社イベントに合わせて多くのAPJチームの人が来て、 チームで会話できたし、もっと英語やらないとなぁと。前よりもちょっとは喋れるようになった気がしてます(気がしてるだけで、喋れてるかどうかは不明)。あとは、TOEIC受けて、実力チェックしてみないとなぁ。\nイベント登壇はまぁ、DevRelですから、一応。 来年もとりあえず、3月までは毎月どこかでブース出してます。 Ask Me Anything的なブースの出し方を今年はしてみようかなと思ってるので、 ちょっと使い始めたけど、この辺よくわからないと思ってる方、ぜひ質問しに来てください。 ブース出すだけじゃなくて、スピーカーとしていろんな場所で喋れるようにしないとなぁと。 もっと幅広く知ってもらえるように雑誌とかで連載できるようにしたいなぁと思ってます。 また、日本語の入り口の情報を増やすためにブログも書かないとなぁ。\n勉強会も継続しますが、別の方法でも盛り上げて行きたいなぁと。 勉強会はどうしても聞く人が多くて、ユーザーの間での交流や情報交換とまでは行ってない気がするし、discuss.elastic.coというフォーラムで質問は増えて来てるけど、もう少し交流しやすい場があると使ってもらえるかなぁ?と思っていたり。 何かおすすめとかあれば、連絡ください。 meetup.comの勉強会のページにも掲示板はついてるんだけど交流しにくそうだし。\n来年は自分が最も興味のある検索系の開発にも参加したいなぁと。 Elasticsearchをちょっとずつ時間見つけてやってたりはしますが、もう少し首を突っ込んで行きたいなぁと。Swiftypeもジョインしたし。もっと検索やって行きたい気持ちが強いので。\nさて、ということで、今年もあと1時間なくなりました。 今年も様々な面で色々な方々に助けていただけました。本当にお世話になりました。 この場を借りてお礼申し上げます。\n来年ももちろん、色々な方に助けてもらうと思いますが、よろしくお願いいたします!\n","date":1514723443,"dir":"post/2017/","id":"7c21b70f9e9c782c1f5153268e0cc1c1","lang":"ja","lastmod":1514723443,"permalink":"https://blog.johtani.info/blog/2017/12/31/looking-back-2017/","publishdate":"2017-12-31T21:30:43+09:00","summary":"今年は紅白を見ながら書いてます。 今年はいろんなところに出張に行ったなぁ。 振り返り(2016年に書いた抱負から) まずは去年の抱負を元に。 もちろ","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2017)"},{"contents":"Merry Christmas! Elastic Stack Advent Calendar 2017の24日目の記事になります。\nちょっとですが、2018年のElasticについて書いてみようかと思います。\nイベント いくつか出展が決まっているイベントがあるのでまずは宣伝を。\nOSC Osaka 2018 まずは、1月25日、26日にOSC Osaka 2018に出展し、話をします。参加者がいそうであれば、25日や26日の夜に勉強会もありかなぁと思っています。 セッションでは入門的な話をする予定です。ブースにいますので、色々質問がある関西の方はぜひご参加ください。\nDeveloper Summit 2018 2月15日、16日はDeveloper Summit 2018に出展します。 こちらでもブースにいますので、AMA(Ask Me Anything)的に使っていただくのもいいかなと。 デブサミに参加される方はぜひお立ち寄りください。\nManabiya 3月23日、24日はManabiyaに出展します。 こちらでもAMAのつもりでブースを出す予定です。質問がある方はぜひお立ち寄りください。 こちらのイベントは初めての開催になるようなので、どんなイベントになるか楽しみにしています。\nイベント回りはこの辺りで。 また、1月末に勉強会を予定しています。決まり次第またMeetup.comの方々にメールを出す予定です。\nElastic Stackの2018年は? Canvas! 昨年のElastic{ON}でみなさんをCanvasがリリースされるかなぁと。 現在、みなさんにテストしてもらえるようにcanvas.elastic.coというサイトを公開中で、実際にインストールして試すことができるようになっています。 ぜひ、触って、全く新しいUIを体験して見てください。\nSQL? こちらも昨年のElastic{ON}でみなさんから反響があったものです。 もう直ぐでてくるのではないかなぁと。\nその他は? いくつか面白そうで、取り込み済みのものをピックアップしておきます。\nAdd ranking evaluation API 検索クエリなどに対して検索結果のランクのクオリティを評価するためのAPIの追加(7.0予定) JDK9サポート? 6.2でサポートされそうです。が、LTSのJDK8が推奨のままの予定です。 High-level REST ClientでいくつかAPIが追加 https://github.com/elastic/elasticsearch/pull/27574、https://github.com/elastic/elasticsearch/pull/27351 APM正式リリース? ベータ版がリリースされているので、秒読み段階? ということで より詳しく知りたい方は、サンフランシスコで開催されるElastic{ON} 2018に参加するのが一番です!(ステマ) 私も参加予定ですので、ぜひ、現地でお会いし、色々な情報をゲットしましょう。\n明日で、今年のAdvent Calendarも最後です。micci184さんの記事を楽しみにしましょう!\n","date":1514124616,"dir":"post/2017/","id":"f3a9b931b7f552a4f9dfa61ce4f39f0e","lang":"ja","lastmod":1514124616,"permalink":"https://blog.johtani.info/blog/2017/12/24/elastic-2018/","publishdate":"2017-12-24T23:10:16+09:00","summary":"Merry Christmas! Elastic Stack Advent Calendar 2017の24日目の記事になります。 ちょっとですが、2018年のElasticについて書いてみようかと思います。 イベント いくつか","tags":["elasticsearch"],"title":"2018年のElasticは?"},{"contents":"Elastic stack (Elasticsearch) Advent Calendar 2017の1日目の記事になります。\nまだ、1ヶ月を残していますが、簡単に今年起こったことを振り返ってみようかと思います。思った以上に色々ありましたね。。。\nElastic Stack 5.2.0リリース (1月) リリース記事はこちら\nHeatmapがKibanaで追加されたり、Heartbeatがベータですが追加されました。 個人的には、Terms aggregationのFiltering Valuesによるパーティションが便利になったと思います。Terms Aggsでページングに似たことができるようになりました。\nElastic{ON}17開催 (3月) 第3回目のユーザカンファレンスが開催されました。 バレーダンサーの踊りから始まったキーノート、様々なユーザ企業によるユースケース発表などいろいろありました。 セッションはこちらのサイトからから録画を見ることができます。 SQL for ElasticsearchやAwardが目を引いたと思います。SQL対応まだ出てきていないですが、もうすぐじゃないかと!\nElastic Stack 5.3.0リリース (3月) リリース記事はこちら\nFilebeat moduleが導入され、ログファイルを取り込んでKibanaで可視化するまでの手順がより簡単になりました。Elasticの目指しているものの一つに、シンプルな使い方、簡単にはじめられることといったものがあります。KibanaのTimepickerもより便利になったのも、このバージョンからです。\nShayがCEOに (5月) 2月にすでに発表されていましたが、Elasticsearchの生みの親のShay BanonがCEOに正式に就任しました。CEOになってさらに、精力的に様々なことをやっていて、本当にすごいなと思います。\nElastic Stack 5.4.0、6.0.0-alpha1リリース (5月) 5.4.0リリース記事はこちら、6.0.0-alpha1リリース記事はこちら\n5.4.0は節目になるリリースでした。Machine Learningがベータリリースとして、X-Packに追加されましたし、ElasticsearchではCross Cluster Searchの改善が進みました。LogstashではPersistent QueueがGAになりましたし、KibanaにはTime Series Visual BuilderやEvent Contextなどが追加されますます使いやすくなりました。\nまた、6.0.0のalpha版も同時にリリースされ、様々な方からのフィードバックが集まり始めました。\nElastic Cloud Enterprise GAリリース (5月) Elastic Cloudのバックエンドの技術を製品に採用したものになります。 多くのElasticsearchクラスタを管理しないといけない方には朗報でした。\nOpbeatがJoin (6月) Opbeatチームがジョインしたのが6月です。Elastic StackがAPM\u0002(Application Performance Monitoring)でも活躍することになりそうです。APMの仕組みとしては、APM Agentをアプリ側に配置し、APM Serverへデータを送信し、Elasticsearchに保存、Kibanaで可視化するという流れになります。\nElastic Stack 5.5.0リリース (7月) リリース記事はこちら\nMachime LearningがGAリリースになったのが5.5.0です。色々な方から質問を受けました。それ以外にも、ElasticsearchのWindows MSI InstallerやKibanaのFilter editorなどが追加されました。Filter editorはこれまで検索条件を記述するのが難しいと感じていたKibanaユーザにとても喜んでもらえたものじゃないかなと。 GrokDebuggerが導入されたのもこのタイミングです。\nElastic Stack 5.6.0リリース (9月) リリース記事はこちら\n5系最後のマイナーリリースであり、6へのアップグレードが楽になる様々な仕組みが用意されたのがこのバージョンです。ElasticsearchのJava High level REST clientが導入されたのもこのバージョンです。本当に様々な機能が次のメジャーバージョンとの互換性のために組み込まれています。。。\nElastic Cloud on GCP (9月) リリース記事はこちら\nこれまで、AWS上のみで展開していたElastic CloudがGCP上でも展開されることになりました。残念ながら、日本リージョンはまだありませんが、問い合わせなどが増えれば今後サポートされる可能性が高くなると思います!\nElastic APM alpha (9月) リリース記事はこちら\nOpbeatチームによりElastic StackのAPMがAlphaですがリリースされました。APMがOpen Sourceで利用できるんです!Agentがもっと増えてくると色々なことに使えるようになると思います。ぜひAgentを作成してみてください!\nElastic Stack 6.0.0リリース (11月) リリース記事はこちら\n待ちに待った6.0.0のリリースです。新機能については本日(12/1)の昼に行われるウェビナーをご覧ください!\nSwiftypeがJoin (11月) ニュースリリースはこちら\nSwiftypeと呼ばれる検索のSaaSを提供している会社がジョインしました。 個人的には今年一番嬉しいニュースです。やはり、検索が好きなので。 簡単にSite Searchを構築できる仕組みは非常に面白いものです。 興味のある方は、ぜひ触ってみてください。日本語固有の機能などはまだないので、今後関わっていければなーと。\nElastic{ON} Tour Tokyo開催 (12月) まだ開催前ですが、今年も東京で1dayイベントを開催します。 残念ながら、もうSold outなので、キャンセル待ちになってしまっているみたいですが。私もスピーカーとして喋りますし、AMAブースにも立っています。 参加される方はぜひ声をかけていただければと思います。\nOSC 2017.Enterprise (12月) オープンソースカンファレンスで今年も様々な都市に出張しました。 今年の締めくくりということで、12/8に渋谷で開催されるカンファレンスに出展します。時間のある方は、ぜひブースに遊びに来てください。入門者向けのセッションもあるので、こちらもお待ちしております。\nまとめ 超駆け足ですが、今年を振り返ってみました。 今年もいろんなことがありました。書くのが大変だったw。 OSCなどイベントで声をかけていただいた皆様、ありがとうございました。\nさて、Elastic Stack Advent Calendar 2017は始まったばかりです。これからの記事を楽しみにしています!\nということで、 次はaeroastroさんの「Elasticsearchのインデックスを本当の意味で無停止再構築する方法」(Advent Calendarのページはこちら)になります、お楽しみに!\n","date":1512054000,"dir":"post/2017/","id":"fa0486610d8a02cea245c13c85b6de27","lang":"ja","lastmod":1512054000,"permalink":"https://blog.johtani.info/blog/2017/12/01/whats-happen-at-elastic-in-2017/","publishdate":"2017-12-01T00:00:00+09:00","summary":"Elastic stack (Elasticsearch) Advent Calendar 2017の1日目の記事になります。 まだ、1ヶ月を残していますが、簡単に今年起こったことを振り返ってみようかと思います。思った以上に","tags":["elasticsearch"],"title":"2017年のElastic StackとElastic"},{"contents":"Swiftypeでサイト内検索? プレスリリース:Elasticがサイト内検索サービス最大手のSwiftypeを買収が出ましたが、SwiftypeチームがElasticにジョインしました!\n自分のブログ検索に導入してみる? SwiftypeはSite Searchをサービスとして提供しています。 実際に指定したサイトのデータをクロールして、インデキシングし、検索できるようになります。 ものは試しということで、自分のブログを登録してみました。検索窓はつけてないですが。 14日間のFree trialがあるのでそちらで試してみましょう。 検索窓はデモとか作れたらかな。\nということで、Free trialへ まずはユーザ登録です。Googleのアカウントと連携するか、Swiftypeにメルアドを登録するかが選択できます。 登録できたら、次にどちらのプロダクトを使うかという選択画面が出てきます。 今回はサイト検索して見たいので、「Site Search」の「START FREE TRIAL」をクリックします。\nEngineの指定 Web Crawlerを利用するか、独自にSwiftypeのAPIを利用してデータを登録するかを選択します。\n今回は、お手軽な方のCrawlerを選択します。 すると次に、クロールしたいURLの指定画面が出てきます。\n今回は自分のブログなので、\u0026lsquo;http://blog.johtani.info\u0026rsquo;を指定します。\nで少し待つと、URLのチェック(存在チェックとか、接続チェックとか)が終わり、今回作成するEngineに名前をつける画面が出てきます。 「My Blog search」という名前にしてみました。\nsitemapがあるかどうかをCrawlerがチェックしています。 私のBlogはOctopressでできていて、sitemap.xmlも作ってくれているので、これを元にCrawlerはクロールをしてくれます。そのほかにもRSSやAtomサポートもあるみたいですね。 「COMPLETE SETUP」を押すと、Engineの管理画面が出てきます。\n「CRAWLING」という表示が出ています。クロールしている最中です。これが終われば、「PREVIEW」に代わり、検索できる準備ができたことになります。 実際にPREVIEWして見ると、次のような検索ができるようになります。\nそのほかにはWeightの調整画面などもありますね。フィールド毎に重み付けを変えて見たりもできます。\n日本語独自のAnalyzerなどはまだないので、そのあたりができてくるともっと便利になりそうです。 とりあえず、気になる方は触って見てはいかがでしょうか? 個人的は検索に関するサービスが出てきたのですごく楽しみにしています!\n","date":1510280089,"dir":"post/2017/","id":"c20d71627e66a044b21780f56f2f9504","lang":"ja","lastmod":1510280089,"permalink":"https://blog.johtani.info/blog/2017/11/10/welcome-swiftype/","publishdate":"2017-11-10T11:14:49+09:00","summary":"Swiftypeでサイト内検索? プレスリリース:Elasticがサイト内検索サービス最大手のSwiftypeを買収が出ましたが、Swifty","title":"Swiftypeがジョインしたので触ってみました"},{"contents":"久々に執筆しました。といっても、以前の書籍の更新版です。 まぁ、更新版といっても、私以外の方々は結構な量を書き直しor新規書き起こしされてますが。。。\nということで、みなさん「買って」から感想をいただけるとうれしいです!\u0002(以下の画像でAmazonにジャンプできます!Kindle版も発売中です。)\n今回もElasticsearchの章を担当しました。 5.4ベースで書きましたが、ちょっとずつ6でどう変わるかなども記載してあります。 また、付録ではLogstashやBeatsにもちょっと触れています。 また、自分が一番好きなKibanaの機能であるDev ToolsのConsoleについても記載してあります。こちらも合わせて目を通していただければと。\nみなさんのフィードバック(ツイート、ブログ、Amazonのコメントなどなど)をお待ちしております!\n","date":1505955750,"dir":"post/2017/","id":"4f88f3eebe44285ded812939553ef94c","lang":"ja","lastmod":1505955750,"permalink":"https://blog.johtani.info/blog/2017/09/21/release-intro-logging-analysis-system/","publishdate":"2017-09-21T10:02:30+09:00","summary":"久々に執筆しました。といっても、以前の書籍の更新版です。 まぁ、更新版といっても、私以外の方々は結構な量を書き直しor新規書き起こしされてます","tags":["elasticsearch","kibana","本"],"title":"データ分析基盤構築入門 を一部執筆しました。"},{"contents":"久々のブログ。 Elasticsearch勉強会を主催してますが、 プロダクトを超えて、検索で共通してある課題とか、悩みとか、あるかなぁと。 その辺りを話す場所を考えてみるのいいかもと思い、検索座談会ってのを5人でやってみた。\nとりあえず、初めてなので、5名ほどで。プロダクトはかぶってない感じでした。\n話した議題はこの辺り。 形態素解析の辞書は何を使ってる?有償のもの? そもそも形態素解析? 辞書の更新とかは? シノニムってどうしてる? サジェストとかのデータはどう作ってる?どうしてる? 検索ログとかから作ってる? 検索結果のランキングって検索結果だけで決めるの? 検索漏れとかキーワードのミスマッチとかどうしてる? 今後話したい内容はこの辺かな? 緯度経度系の検索 画像検索、音声検索 検索のキーワードの調査とかしてる人とかいるかな? どんな機能が欲しい? 前処理としてはどんなことをしてる? このあとどうしていくかはまだ考え中。知り合いを捕まえて、どんなことしてるかを聞きにいくのもいいし、議題みたいなことを決めて、それを話してくれそうな人にコンタクトして議論するのもありかなぁ。 普通の勉強会みたいなのにするかもしれないし。 とりあえず、どのくらい興味を持ってる人がいるのかがわからないので。。。\nもちろん、Elasticsearch勉強会は別でやっていきますよ。\n","date":1495639453,"dir":"post/2017/","id":"29b4c2b5adcd80ced1612128b3ca95a9","lang":"ja","lastmod":1495639453,"permalink":"https://blog.johtani.info/blog/2017/05/25/search-meetup/","publishdate":"2017-05-25T00:24:13+09:00","summary":"久々のブログ。 Elasticsearch勉強会を主催してますが、 プロダクトを超えて、検索で共通してある課題とか、悩みとか、あるかなぁと。 その","tags":["勉強会"],"title":"検索座談会ってのをやってみた"},{"contents":"今年はRioのプレイバック\u000e見ながら書いてます。 今年はなんか長い一年だった気が。\n振り返り(2015年に書いた抱負から) まずは去年の抱負を元に。\n英語の継続 継続してます。まぁ当たり前ですが。もう少し話す機会増やさないとだなぁと思いつつ。英会話しながら、海外TVドラマ見ながら。 見たドラマはこの辺かな?\nER SUITS メンタリスト Numb3rs エレメンタリー Agent of Shield あと、映画も見てます。とりあえず、耳を慣らすために字幕ありで見てるので、 英語だけでとは行きませんが。。。 そろそろ同じ映画を英語字幕で見るとかしたほうがいいのかもなぁ。\nもっとElasticsearchの開発に参加 一応参加してます。ちょっとずつですが。 イベントが重なるとできなくなるので、小さなPRとかを細々とって感じですが。。。\n人員の倍増? 倍増したかな?現時点で日本は8名になりました。そのうち1人は完全リモートです。 来年も倍増とは行かないだろうなぁ。取り急ぎ、サポートエンジニアが足りてないのでそこを埋めないと。。。\n日本語情報発信 これはちょっと足踏みしてるかも。ブログの翻訳とかはやってるんですが、もう少しなんとかしないとなぁ。ブログも書かないと。。。\nSplatoon S+? なりました!とりあえずS+とSを行ったり来たりしてる感じです。 メインはノヴァネオですが、Sに落ちたら違う武器でS+に上がるまでチャレンジするってのをやってます。わかば、バケスロソーダ、プライム、ワサビくらいはやったかな? そろそろまた違う武器かなぁ。S+99は無理そうなんで。。。\n振り返り(今年あったできごと) その他の今年の出来事。\n初香港 初プラハ OSCなど、東京以外でのカンファレンス参加 厄年 東京オフィス! BBLとかトレーニング lucene-gosenをちょっとメンテ Podcastデビュー? 初モノ今年も多いかな。 今年は、昨年よりは長く感じた一年でした。 月1くらいで出張してたのもあるのかなぁ? 香港、プラハはもちろん会社のイベントです。 香港はジャッキーチェンの映画を彷彿とさせるところがちょくちょくあって面白かったです。 ビルとかの補修の足場が竹竿とか。 プラハも面白かったです。やっぱりヨーロッパの古い町は歴史のある建物が多くて楽しいです。\nOSCなどのイベントも色々行きました。福岡、名古屋、大阪、京都、札幌と回りました。 それとは別に大阪、福岡も行ったかな。 来年は沖縄と広島に行きたいなぁ。。。 出張のついで?じゃないですが、御朱印集めし始めました。神社仏閣もいいですよねぇ。\n厄年はきつかった。。。たまたまだとは思うけど、お祓いに行ったのが効いたのかなぁ。後半は特に問題なかったかな。腕時計無くしたと思ったら見つかったりしたし。\n弊社東京オフィスができました。(あんまり行ってないけど) ときどきアクロクエストさんがセミナーを開いたりしてます。 昨年のTour Tokyo後のMeetupでもイベントスペースを使って、Drinkup(勉強会の懇親会だけバージョン)もやりました。 今後もちょこちょことイベントをやってみようかな?\nBBLも始めました。あまりきちんと宣伝してないからそれほど依頼は来てないですが。 あとは、今年も2回日本語でトレーニングしました。 前回はほぼ満席にまでなりました。 来年も頑張りたいかな。ショートカットするためにもいいと思うんで、トレーニングを受けて欲しいんです。。。\nlucene-gosenのメンテもしました。 といってもプログラムではなく、ビルドシステムをAntからGradleに変更したんですが。 来年もちょっとずつ触りたいな。機能面で拡充するかはわからないですが。。。\nPodcastにもデビューさせていただきました。 wyukawaさんのPodcastです。「johtaniさんとElasticsearchについて話しました」楽しかったです。 また出たいなぁというか、喋るの面白かった!\n来年の抱負 もちろん英語の継続 継続的にイベントに登壇 もっと開発&ブログ サポートエンジニア獲得! 個人的な検索勉強会の再開 英語はまぁ、当たり前ですね。会社の人つかまえてもっと喋る時間増やさないとだな。\n来年もいろんなカンファレンスなどに出てブース出したり、セッション持ったりして もっともっと広めていかないとなぁ。 あとは、勉強会とMeetupもやっていかないと。入門編と上級編みたいに分けてみるのもありかなぁと考えて見たり。 スピーカー、ご意見募集しております。\n開発に時間をさくための時間の活用をしていかないとなぁと。 どうも時間の使い方がまだ上手くないので。ブログも一緒ですね。。。 月1くらいのペースではかきたいな。。。 ブログもそうだけど書籍もかな???? あと、外資系の他の会社の人ともまた飲みたいなー。\n開発の時間を確保という面ではサポートエンジニアも募集中です。 最近、クライアントが増えて来てチケットが増えて来てるんで、サポートしたりもしてるんです。。。 自分の時間を増やすためにもサポートエンジニアを確保しないと。誰かいい人いないかなぁ。\n個人的にやってた勉強会を忙しいって言って中断してるので、再開しないと。。。\nということで、今年もあと數十分になってしまいました。 今年も色々な方に助けていただけました。お世話になりました。 この場を借りてお礼申し上げます。\n来年もいろんな方々に助けてもらうと思いますが、よろしくお願いいたします。\n","date":1483190534,"dir":"post/2016/","id":"16f1046144ad9ee7bb96214ba7ae7516","lang":"ja","lastmod":1483190534,"permalink":"https://blog.johtani.info/blog/2016/12/31/looking-back-2016/","publishdate":"2016-12-31T22:22:14+09:00","summary":"今年はRioのプレイバック\u000e見ながら書いてます。 今年はなんか長い一年だった気が。 振り返り(2015年に書いた抱負から) まずは去年の抱負を元に","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2016)"},{"contents":"Merry Christmas! Elastic stack Advent Calendar 2016 最終日の記事になります。\n簡単に今年の変遷を振り返ってみます。\nElasticsearch 2.2 (2月) Elasticsearch 2.2.0、2.1.2、1.7.5リリース クエリプロファイラやGeo系の性能改善などが取り込まれました。 また、同時期にリリースされたKibana 4.4ではColor pickerやShare用のURLの短縮化機能なども追加されました。\n第2回目のユーザカンファレンス、Elastic{ON}開催(2月) サンフランシスコで、弊社第2回目のカンファレンスが開催されました。 2015年の会場よりも大きくなり、多数の方に参加いただきました。 ここで、以下の発表がありました。\nElastic StackとX-Packの紹介 これまで、ELK stackと呼ばれて意味明日が、Beatsチームの参加により、ELKだけではなくなったこともあり、Elastic Stackと呼び名を変える事になりました。 また、Marvel、Shield、Watcherなどの商用の拡張機能についても、 単体の名称ではなく、X(Extension)-Packと1つの名前になる事に。 詳細については公式のブログをご覧ください。\nElastic CloudとElastic Cloud Enterpriseの発表 2015年にElasticにジョインし、 これまでFound.no(Found)と呼ばれていた弊社のElasticsearch as a ServiceがElastic Cloudと名称変更しました。 また、Elastic Cloudで培っているノウハウを詰め込んだElastic Cloud Enterpriseも発表しました。実際に利用可能になるまでには まだもう少しかかってしまいますが、アルファ版が公開されていますので、興味のある方は触ってみてください。\nElastic{ON}2016で撮影された、「Elasticsearchがないあなたの人生はどうなりますか?」 といった面白い動画も公開されています。\nElasticsearch 2.3リリース(3月) Elasticsearch 2.3.0および2.2.2をリリース Reindex APIが登場し、Mappingの変更やShard数の変更など、色々とデータの更新などがやりやすくなりました。 また、Task Managementの機能も追加され、長時間かかる処理を間違った場合などの対処が楽になりました。 個人的には、Deprecation Loggingの機能が導入されたことが嬉しいこととなります。次期メジャーバージョンで廃止される機能についてログに出力されるようになりました。 実際に運用されているアプリで利用している機能が今後なくなるかどうかをログを見るとわかるという仕組みです。\nRally登場(4月) Rally登場:Elasticsearchのベンチマークツール Elasticsearchのベンチマークツールがリリースされました。 定期的にElasticsearchの性能を計測することは問題点を見つける事に役に立ちます。そういった手助けをしてくれるツールが公開されることは非常に便利なことかと。\nElastic Stack 5 alpha1 リリース(4月) Elastic Stack 5.0.0 alpha 1 リリース Ingest NodeやLucene 6、新しいKibanaのUIなど多くのものが詰まっていました。ここから多くのユーザにテストしてもらい、5.0の正式リリースを迎えることができました。\nElasticsearch 2.4.0リリース(8月) 2.xの最後のマイナーバージョンリリースです。 Reportingなどの追加とドットつきフィールド名の復活がありました。\nElastic Stack 5.0.0 beta1 リリース(9月) Elastic Stack Release - 5.0.0-beta1 ついにベータです。Painlessがスクリプトのデフォルトになったり、TimelionがKibanaに取り込まれるなど、正式リリースまであと少し!\nPrelertチームジョイン(9月) Welcome Prelert to the Elastic Team Machine Learningエンジンを開発し、Elasticsearch,Kibanaとの組み合わせの製品をリリースしていたPrelertという会社がジョインしました。 Elasticsearchに保存された多くのデータをより活用していただくことができるかと思います。 Elastic{ON} Tour 2016 Tokyoで弊社SAの大輪の発表も人気があるものでした。まだベータ段階ですが、利用して見ることも可能です。 ビデオなどが公開されたらまたツイートしようと思います。\nElastic{ON} Tour Tokyo 2016開催(12月) 今年で2回目のTokyoローカルの1日イベントでした。 ブログは「まだ」書いてませんが、、、今回も盛りだくさんのイベントになりました。 早朝のトレーニング(ハンズオンではない)にも80名近くの方に参加していただけましたし、私はKibanaのキーノート+デモという大役をもらいましたし、ちょっと大変でした。 今年もAMA(Ask Me Anything)ブースが大盛況でした。 色々な方から、弊社のサポート、開発者が色々な質問を受け、それに答えるという形です。楽しんでいただけたかと思います。 来年もぜひ開催したいなと思っています。\nまた、Elastic{ON}17のセッションもいくつか発表されています。 ぜひ、サンフランシスコで行われる本場のカンファレンスにもご参加ください!\n来年は? 1月後半か2月にElasticsearch勉強会を検討しようと思っています。スピーカーに興味のある方は連絡いただければと。\n会社としては、Elastic{ON}2017が3月にまた開催されます。これで3回目となります。もちろん私も参加予定なので、参加される方は、現地で会いましょう!\nそのほかにもBIG DATA ANALYTICS TOKYOやオープンソースカンファレンス(大阪)、デブサミといったカンファレンスに参加(登壇・ブースなど)予定です。 参加される方は、ぜひブースまでお越しください。\nでは、また来年のAdvent Calendarでお会いしましょう!\n","date":1482591830,"dir":"post/2016/","id":"002d980d74d19b43ff4e2446665e2fe5","lang":"ja","lastmod":1482591830,"permalink":"https://blog.johtani.info/blog/2016/12/25/elasticsearch-6-features/","publishdate":"2016-12-25T00:03:50+09:00","summary":"Merry Christmas! Elastic stack Advent Calendar 2016 最終日の記事になります。 簡単に今年の変遷を振り返ってみます。 Elasticsearch 2.2 (2月) Elasticsearch 2.2.0、2.1.2、1.7.5リリース クエリプロ","tags":["elasticsearch"],"title":"2016年のElastic Stack"},{"contents":"Elastic stack Advent Calendar 1日目の記事になります。\nElasticsearch 5.0が10月末にリリースされました。 リリースのブログでいくつか紹介されているのですが、そこでは紹介されていない機能について2、3紹介しようと思います。\nその前に、5.0、あれ?その前は2.xじゃなかったっけ??と困惑されている方もいるかと思うので、簡単に5となった経緯の紹介をしようかと。\nバージョン番号 なぜ2から5に飛んだのかという話ですが、このスライドがその紹介になっています。\nhttps://speakerdeck.com/johtani/elastic-stack-5-dot-0-alpha1-alpha5?slide=5\nElastic{ON} 2016のキーノートでも紹介がありましたが、KibanaやLogstashとElasticsearchを組み合わせて使うときにバージョンのミスマッチで動かないというユーザの声が上がっていました。 2.xのリリースから、同じ日にKibana、Logstash、Beatsもリリースするようになったのですが、 やはり、バージョン番号が異なるため、ミスマッチで動かないというユーザが時々いました。\nElastic Stackという名称にもなったため、バージョン番号をそろえようという事になり、 Elasticsearch、Kibana、Logstash、Beats全てが5.0.0としてリリースされ、 今後は同じバージョン番号になります。\nちなみに、「5」になった理由はKibanaのメジャーバージョンが「4」だったためです。\nさて、では、いくつか機能の紹介を。\nReindex from remote cluster Reindexが2.3から導入されました。データの再登録ができるようになり、マッピングの変更や Shardの数の変更などが柔軟に行えるようになりました。 便利でしたが、あくまでも同一のクラスタでデータを登録し直す形でした。\n5.0からはこの機能に加えて、異なるクラスタからデータを取得してReindexを行うことができるようになりました。 こんな形になります。\nPOST _reindex { \u0026#34;source\u0026#34;: { \u0026#34;remote\u0026#34;: { \u0026#34;host\u0026#34;: \u0026#34;http://otherhost:9200\u0026#34;, \u0026#34;username\u0026#34;: \u0026#34;user\u0026#34;, \u0026#34;password\u0026#34;: \u0026#34;pass\u0026#34; }, \u0026#34;index\u0026#34;: \u0026#34;source\u0026#34;, \u0026#34;query\u0026#34;: { \u0026#34;match\u0026#34;: { \u0026#34;test\u0026#34;: \u0026#34;data\u0026#34; } } }, \u0026#34;dest\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;dest\u0026#34; } } usernameとpasswordはリモートのクラスタに認証の気候が存在する場合に利用できるオプションです。 また、ReindexのAPIはクエリを使用して、必要なデータだけを取得することが可能です。 この機能により、1.xや2.xのクラスタからデータを移行することが可能になります。\nCustom analyzer test using Analyze API もう一つ、ちょっとだけ便利な機能を紹介します。 独自にAnalyzerを定義(TokenizerとToken Filterなどを個別に設定)して、その挙動を確認するとき、2.xまでは、インデックスを作成してそのインデックスに対して_analyze APIを呼び出す必要がありました。\n5.xからは_analyze APIの読み出しのパラメータで指定できるようになりました。 こんな感じです。ここでは、lowercaseフィルタのあとに、{...}でstopフィルタを パラメータの中で、指定しています。\ncurl -XGET \u0026#39;localhost:9200/_analyze\u0026#39; -d \u0026#39; { \u0026#34;tokenizer\u0026#34; : \u0026#34;whitespace\u0026#34;, \u0026#34;filter\u0026#34; : [\u0026#34;lowercase\u0026#34;, {\u0026#34;type\u0026#34;: \u0026#34;stop\u0026#34;, \u0026#34;stopwords\u0026#34;: [\u0026#34;a\u0026#34;, \u0026#34;is\u0026#34;, \u0026#34;this\u0026#34;]}], \u0026#34;text\u0026#34; : \u0026#34;this is a test\u0026#34; }\u0026#39; ちょっとだけですが、Analyzerなどを試すのが楽になるのではないでしょうか?\nということで、以上が1日目の記事でした。 Logstashなど、他の5.0.0に関する記事もAdvent Calendarに空きがあるようなので、個別にかこうかなと思います。お楽しみに!\n","date":1480581270,"dir":"post/2016/","id":"550becdd08d00fb1e7fd00c2adc3d3d6","lang":"ja","lastmod":1480581270,"permalink":"https://blog.johtani.info/blog/2016/12/01/elasticsearch-5-dot-0-highlight/","publishdate":"2016-12-01T17:34:30+09:00","summary":"Elastic stack Advent Calendar 1日目の記事になります。 Elasticsearch 5.0が10月末にリリースされました。 リリースのブログでいくつか紹介されているのですが、そこでは紹介されて","tags":["elasticsearch"],"title":"Elasticsearch 5.0の便利機能紹介?"},{"contents":"久しぶりに、技術的なブログ書いてます。\nIngest Processorのプラグインを作ってみたくなったので、書いてみました。 ただ書いてみるんじゃ3番煎じになりそうなので、cookiecutterを使ってみました。\nと言っても、同僚のAlexがcookiecutter-elasticsearch-ingest-processorと言うテンプレートを作ってくれているのを使っただけですが。(https://discuss.elastic.co に投稿された記事で、使い方がアニメgifで説明されててわかりやすいです)\ncookiecutterとは、コマンドラインで質問に答えると、テンプレートからプロジェクトが生成できるツールです。 Elasticでは、カスタムBeatを作る時に利用する例がいつかの日本語ブログや発表資料で話題になっていました。 これのIngest Processorのプラグインバージョンです。\n今回は、NEologdも使ってみたかったので、Lucene Kuromoji for NEologdを利用して 指定した品詞の単語だけを抽出するProcessorを作ってみました。\nGitHubのプロジェクト:https://github.com/johtani/elasticsearch-ingest-kuromoji-pos-extract\nCookiecutterの使い方 Cookiecutterのインストールはサイトをご覧ください。\ncookiecutter gh:spinscale/cookiecutter-elasticsearch-ingest-processor あとは、出てくる以下の項目を指定するだけです。\nprocessor_type : Ingest Processorのタイプ名です。kuromoji_part_of_speech_extractとしました。(Alexのだと_を使うとちょっと問題があるので後述) description : readme.mdに利用されます。 developer_name : 名前を記載。Javaのファイルのヘッダに利用 elasticsearch_version : デフォルトで5.0.0-alpha4が指定されているので、特に指定せず 以上の質問に答えたら、プロジェクトのディレクトリ構造が出来上がってます。 プロジェクトのビルドなどにはGradleを利用します。\nプロジェクトのIntelliJ IDEA用のファイルを生成 build.gradleファイルでGradleのideaプラグインがapplyされているので、以下のコマンドを叩けばIntelliJ IDEAのプロジェクトファイル(?)が生成され、IntelliJで開けばすぐに開発ができる状態にできます。\ngradle idea コーディング あとは、必要処理をコーディングします。 実際にコーディングするクラスはorg.elasticsearch.plugin.ingest.kuromoji_part_of_speech_extractのパッケージにある以下の2つです。(パッケージ名にはprocessor_typeの名前が指定されている)\nIngestKuromojiPartOfSpeechExtractPlugin KuromojiPartOfSpeechExtractProcessor IngestKuromojiPartOfSpeechExtractPlugin Pluginというクラスは、プラグインをNodeのModuleとして登録する処理を書くクラスとなります。 生成してすぐは、次のような形になっています。(※importやクラス定義の部分は省略しています。)\n... public static final Setting\u0026lt;String\u0026gt; YOUR_SETTING = new Setting\u0026lt;\u0026gt;(\u0026#34;ingest.kuromoji_part_of_speech_extract.setting\u0026#34;, \u0026#34;foo\u0026#34;, (value) -\u0026gt; value, Setting.Property.NodeScope); @Override public List\u0026lt;Setting\u0026lt;?\u0026gt;\u0026gt; getSettings() { return Arrays.asList(YOUR_SETTING); } public void onModule(NodeModule nodeModule) throws IOException { nodeModule.registerProcessor(KuromojiPartOfSpeechExtractProcessor.TYPE, (registry) -\u0026gt; new KuromojiPartOfSpeechExtractProcessor.Factory()); } ... YOUR_SETTINGプロパティとgetSettings()メソッドはelasticsearch.ymlで指定したい設定を記述する場合の例になります。今回は特に必要ないので両方削除しました。 最終系はGitHubのコードをご覧ください。\nKuromojiPartOfSpeechExtractProcessor Processorは実際にIngest Nodeで行う処理を書くところです。\npublic static final String TYPE = \u0026#34;kuromoji_part_of_speech_extract\u0026#34;; private final String field; private final String targetField; public KuromojiPartOfSpeechExtractProcessor(String tag, String field, String targetField) throws IOException { super(tag); this.field = field; this.targetField = targetField; } @Override public void execute(IngestDocument ingestDocument) throws Exception { String content = ingestDocument.getFieldValue(field, String.class); // TODO implement me! ingestDocument.setFieldValue(targetField, content); } @Override public String getType() { return TYPE; } public static final class Factory extends AbstractProcessorFactory\u0026lt;KuromojiPartOfSpeechExtractProcessor\u0026gt; { @Override public KuromojiPartOfSpeechExtractProcessor doCreate(String processorTag, Map\u0026lt;String, Object\u0026gt; config) throws Exception { String field = readStringProperty(TYPE, processorTag, config, \u0026#34;field\u0026#34;); String targetField = readStringProperty(TYPE, processorTag, config, \u0026#34;target_field\u0026#34;, \u0026#34;default_field_name\u0026#34;); return new KuromojiPartOfSpeechExtractProcessor(processorTag, field, targetField); } } TYPEがIngest APIのPipelineでProcessorを指定するときに使う名前になります。ここは、cookiecutterの時にprocessor_typeに入力した文字列になっています。 kuromoji_part_of_speech_extractだと長いので、kuromoji_pos_extractに変えました。\nexecute()メソッドに// TODO implement me!とあります。 この部分に実際の処理を記述していきます。\nあとは、FactoryクラスでIngest APIで指定された設定項目を読み込みます。 今回作成したelasticsearch-ingest-kuromoji-pos-extractでは品詞を指定する必要があるので、pos_tagsを指定できるように処理を追加しました。\n私が実装したものの説明をするとちょっと長くなりそうなので、GitHubのコードをご覧ください。\nテストのコーディング テストのクラスもテンプレートで生成されています。\nKuromojiPartOfSpeechExtractProcessorTests KuromojiPartOfSpeechExtractRestIT KuromojiPartOfSpeechExtractProcessorTests Processorクラスのテストになります。生成直後は次のような感じです。\npublic void testThatProcessorWorks() throws Exception { Map\u0026lt;String, Object\u0026gt; document = new HashMap\u0026lt;\u0026gt;(); document.put(\u0026#34;source_field\u0026#34;, \u0026#34;fancy source field content\u0026#34;); IngestDocument ingestDocument = RandomDocumentPicks.randomIngestDocument(random(), document); KuromojiPartOfSpeechExtractProcessor processor = new KuromojiPartOfSpeechExtractProcessor(randomAsciiOfLength(10), \u0026#34;source_field\u0026#34;, \u0026#34;target_field\u0026#34;); processor.execute(ingestDocument); Map\u0026lt;String, Object\u0026gt; data = ingestDocument.getSourceAndMetadata(); assertThat(data, hasKey(\u0026#34;target_field\u0026#34;)); assertThat(data.get(\u0026#34;target_field\u0026#34;), is(\u0026#34;fancy source field content\u0026#34;)); // TODO add fancy assertions here } テストメソッドも実装されていますが、パラメータの追加の設定処理やアサーションが書かれてません。 実装に合わせて、アサーションや設定処理を追加しましょう。\nKuromojiPartOfSpeechExtractRestIT こちらはIntegration Testになります。 実際にElasticsearchに対して外部からAPIを叩くような感じです。 APIを叩くときに利用するJSONの設定やアサーションはsrc/test/resourcesにyamlファイルがあります。\n10_basic.yaml 20_kuromoji_part_of_speech_extract_processor.yaml 10_basic.yamlはプラグインがインストールされているかの確認のテストです。特に変更する必要はないです。\n20_kuromoji_part_of_speech_extract_processor.yamlは実際にコーディングしたProcessorが動くかどうかのテストです。\nテストの内容については、GitHubのコードをご覧ください。\nテストの実行とZipの生成 テストの実行とZipの生成は次のコマンドを実行すればOKです。\ngradle check テストに問題があった場合は、コケますし、問題なければSUCCESSと表示が出ます。 成功した場合はbuild/distributions/というディレクトリにzipファイルができています。 これをElasticsearchのpluginコマンドでインストールすれば動きます。\nbin/plugin install file:///path/to/elasticsearch-ingest-kuromoji-pos-extract/build/distribution/ingest-kuromoji_part_of_speech_extract-0.0.1-SNAPSHOT.zip kuromoji_pos_extractの利用方法 Ingest APIには便利なSimulate Pipeline APIがあります。\nということで、mecab-ipadic-NEologdにあったサンプルの文章を使って、使い方の説明です。\nPOST _ingest/pipeline/_simulate { \u0026#34;pipeline\u0026#34; : { \u0026#34;description\u0026#34; : \u0026#34;kuromoji neologd extract test\u0026#34;, \u0026#34;processors\u0026#34; : [ { \u0026#34;kuromoji_pos_extract\u0026#34; : { \u0026#34;field\u0026#34; : \u0026#34;body\u0026#34;, \u0026#34;target_field\u0026#34; : \u0026#34;noun_field\u0026#34;, \u0026#34;pos_tags\u0026#34; : [ \u0026#34;名詞-固有名詞-組織\u0026#34;, \u0026#34;名詞-固有名詞-一般\u0026#34;, \u0026#34;名詞-固有名詞-人名-一般\u0026#34;, \u0026#34;名詞-固有名詞-地域-一般\u0026#34;, \u0026#34;名詞-固有名詞-地域-国\u0026#34; ] } } ] }, \u0026#34;docs\u0026#34; : [ { \u0026#34;_index\u0026#34;: \u0026#34;index\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;type\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;id\u0026#34;, \u0026#34;_source\u0026#34;: { \u0026#34;body\u0026#34; : \u0026#34;10日放送の「中居正広のミになる図書館」(テレビ朝日系)で、SMAPの中居正広が、篠原信一の過去の勘違いを明かす一幕があった。\u0026#34; } } ] } 結果はこちら。\n{ \u0026#34;docs\u0026#34;: [ { \u0026#34;doc\u0026#34;: { \u0026#34;_index\u0026#34;: \u0026#34;index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;id\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;type\u0026#34;, \u0026#34;_source\u0026#34;: { \u0026#34;noun_field\u0026#34;: [ \u0026#34;10日\u0026#34;, \u0026#34;中居正広のミになる図書館\u0026#34;, \u0026#34;テレビ朝日\u0026#34;, \u0026#34;SMAP\u0026#34;, \u0026#34;中居正広\u0026#34;, \u0026#34;篠原信一\u0026#34; ], \u0026#34;body\u0026#34;: \u0026#34;10日放送の「中居正広のミになる図書館」(テレビ朝日系)で、SMAPの中居正広が、篠原信一の過去の勘違いを明かす一幕があった。\u0026#34; }, \u0026#34;_ingest\u0026#34;: { \u0026#34;timestamp\u0026#34;: \u0026#34;2016-07-22T06:18:49.007+0000\u0026#34; } } } ] } noun_fieldに固有名詞の単語が抜き出せているのがわかるかと思います。\nAlexのテンプレートで困った点 テンプレートは便利だったのですが、processor_typeに_を使用したタイプ名を指定すると次のような問題(?)が発生しました。\nクラス名がKuromoji_part_of_speech_extractProcessorとなってしまう 深刻な問題ではないのですが、JavaだとCamel Caseが普通なのでちょっと気になって。 ということで、プルリク作って出してみました。まだ取り込まれてないかな。\n取り込み前に使いたい方は以下のコマンドを実行してください。 processor_class_nameという項目が増えています。 デフォルトだとprocessor_typeの_の部分を取り除きつつCamel Caseにしたものが入ります。\ncookiecutter gh:johtani/cookiecutter-elasticsearch-ingest-processor まとめ ということで、とりあえず作ってみましたというものになります。 特徴的な単語(固有名詞だけ)を抜き出して、別のフィールドにできるので、タグみたいなものをこれを使って前処理で作れるようになるかなぁと。\n参考ブログ(元ネタ?) インスパイア元となったブログです。\nUser Agentを解析するIngest Pluginを書いてみた Elasticsearch 5.0.0のIngest Node用プラグインを書いた話 ","date":1469161616,"dir":"post/2016/","id":"a62186ea292d6db03a087bd5dfcc3f1e","lang":"ja","lastmod":1469161616,"permalink":"https://blog.johtani.info/blog/2016/07/22/making-ingest-processor-plugin-with-cookiecutter/","publishdate":"2016-07-22T13:26:56+09:00","summary":"久しぶりに、技術的なブログ書いてます。 Ingest Processorのプラグインを作ってみたくなったので、書いてみました。 ただ書いてみるんじゃ3番煎じ","tags":["elasticsearch","plugin"],"title":"Lucene Kuromoji for NEologdで指定した品詞の単語を抜き出すIngest Pluginを書いてみた #elasticsearchjp"},{"contents":"なんか、今年はよく物が壊れる、厄年だからかなぁ?\nということで、記念に何が壊れたかをブログに残しておこうかと。\n腕時計(壊れてないかな) 電波腕時計を使ってたんだけど、電池がへたってたのでオーバーホールしてもらった。 Moto 360(壊れたというか。。。) 何度かバージョンアップしてるんだけど、数ヶ月前から、ちょっと触っただけで電源が落ちる現象が。ファームウェアのせいかAndroid Wearのバージョンアップのせいかわからないけど。。。挙げ句の果てに、電源を入れるために充電器にセットしないといけないと言う酷い仕様。。。 自転車前輪 自転車で車道を横切る側溝の蓋の間に前輪がはまってすっ転んでしまい、タイヤのスポークがちょっと曲がってしまう ジーンズその1 自転車で転んだ時に、膝とかこすって破れる ジーンズその2 福岡出張中に雨で滑って派手に転んで、膝に大きな穴が。。。 リュック あー、怪しいなと思ってたんだけど、やっぱりこわれた、、、 pic.twitter.com/CD2Y7t6AOD\n\u0026mdash; Jun Ohtani (@johtani) 2016年6月16日 怪しいとは思ってたんだけど。。。 ということで、リュックを新調しつつ修理に出してるところ。 5. Xperia Z3 * 先週金曜日にカメラのレンズが結露してるなぁと思ったら、電源が入らなくなった。補償サービスに入ってたんで、新しいZ3を次の日に送付してもらい復旧。いろいろなアプリがログインしないといけないのでかなり大変だった。。。\nまだ、半年残ってるので他にも壊れるのかなぁ。。。 お祓いしてもらったので、何もなければいいんだけど。\nということで、なんとなく欲しいものリストを貼っておきますね。\n","date":1467251858,"dir":"post/2016/","id":"167e2a6833d49ce198cb3b88f521991e","lang":"ja","lastmod":1467251858,"permalink":"https://blog.johtani.info/blog/2016/06/30/broken-something-in-this-year/","publishdate":"2016-06-30T10:57:38+09:00","summary":"なんか、今年はよく物が壊れる、厄年だからかなぁ? ということで、記念に何が壊れたかをブログに残しておこうかと。 腕時計(壊れてないかな) 電波腕時","tags":["misc"],"title":"よく物が壊れる年"},{"contents":"第16回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 今回は、司会だけに注力してみました()。\nチェックイン数など チェックインした人:141名 キャンセルしなかった人:67名 でした。\n今回は、参加希望者が多くて、当日にも100名近いキャンセル待ちの方がいたので、 240名まで、参加者枠を増枠(会場キャパ190名程度)して対応しました。 まぁ、読み通り、1/3の方はキャンセルしない形でした。 天気も良く電車の遅延などもなさそうだったので、ちょっとドキドキしてたのですが。\n以下は簡単なメモです。\n「LogstashとElasticsearchで作るEnterprise Search Platform」/ Elastic Kosho Owa スライド:https://speakerdeck.com/kosho/enabling-enterprise-search-platform-with-elastic-stack\n使ってるLogstashの設定ファイルを elastic-japan at elastic dot co に送るとTシャツがもらえるらしい。 Logstashのfilter-rubyはここで、evalしてcallしてるから、特にforkとかしてないかと。 「企業・業界情報プラットフォームSPEEDAにおけるElasticsearchの活用」 / 株式会社ユーザベース 北内 啓さん スライド:http://www.slideshare.net/tau3000/speedaelasticsearch-63510388\nアルゴリズム関連の開発担当 企業データをいろんな軸で検索したい データ数が約70億レコードになりそう(通貨 x MySQL) 300万企業データ+Nestedとかで持ってる。 11万フィールド??? 10台の物理サーバに24仮想マシン 企業名の検索 recall重視 NewsPicksの検索機能 「日本 化粧品 売上高」業界のデータとかも観れるのかな?有料会員向け機能 登録済みキーワードかどうかをRDB+Esに検索して、ID化するっぽい ID(Analyze必要ない)検索だから、termクエリだった、サンプルが。 ノードの役割分担 更新はMasterNode経由でDataNodeへ。 検索はClientNode経由でDataNodeへ。 1.xかぁ。。。 「Elasticsearchベースの全文検索システムFess」 / 株式会社エヌツーエスエム 菅谷信介さん スライド:http://www.slideshare.net/shinsuke/elasticsearchfess\n10.xからSolrをやめてElasticsearchへ。 日本語検索 bigram+形態素(1文字検索とかに対応するため) NeologDに対応したkuromojiを利用 DBFluteをESFluteとしてEs対応 KOPFを組み込んで使ってる configをREST API経由で更新できるプラグインあり LT 「ElasticsearchとGCPのネットワークでハマった話」 株式会社サイバーエージェント 平田大地 さん @daichild スライド:https://speakerdeck.com/daic_h/gcpfalsenetutowakudehamatutahua\nhhkb2 2刀流! networkのKeep-alive周りで困ったよというお話。 後で聞いたけど、GCE Cloud Pluginは使ってるそうです。 06/28 17:00追記\nPingを定期的に実行させることで回避も出来るようです。 transport.ping_scheduleに時間を指定します。通常のNode(Transport以外)は\u0026rsquo;-1\u0026rsquo;が指定してあり、動作してません。 「スクリプトフィールドで作るランキングみたいな何か」iwag さん スライド:https://speakerdeck.com/iwag/elasticsearch-dezuo-rurankingu\n1.xかぁ。。。 あとは、function_scoreとかも面白いですよ! その他、感想などのブログ 第16回elasticsearch勉強会に参加してきた 第16回Elasticsearch勉強会に参加してきた まとめ+宣伝? 1.xがまだまだいますねぇ、早く2.xにアップしましょう!(5.0ももう直ぐだし)。懇親会でも色々と話しましたが、https://discuss.elastic.co というフォーラムあるので、ぜひ活用してください。\n次回は8月末か9月頭かでしょうか。 7月末にOSC京都に出没するので、京都で勉強会やりたいと思ってます! 会場とかスピーカーとか興味ある人連絡ください。\n東京の勉強会のスピーカーも随時募集中ですので、連絡ください。\n","date":1467089755,"dir":"post/2016/","id":"993e58f132740b464ecf06ee289dc7b2","lang":"ja","lastmod":1467089755,"permalink":"https://blog.johtani.info/blog/2016/06/28/16th-elasticsearch-meetup/","publishdate":"2016-06-28T13:55:55+09:00","summary":"第16回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズ","tags":["elasticsearch","勉強会"],"title":"第16回Elasticsearch勉強会を開催しました。 #elasticsearchjp"},{"contents":"第15回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 今回は、Elastic{on} 2016開催直後ということで、大半はElastic{on}に関する話でした。\nチェックイン数など チェックインした人:114名 キャンセルしなかった人:62名 でした。 今回は、少しおそめで1時間前にキャンセル待ちがいない状態にしました。 まぁ、いつもの感じでしょうか。数値も安定してきた感じですかね。\n\u0026ldquo;Elasticsearchと機械学習を実際に連携させる\u0026rdquo; / Preferred Networks America, Inc. CTO 久保田展行(Kubota Nobuyuki) さん スライド:Elasticsearchと機械学習を実際に連携させる\n前回の続きの話で、今回が本題でした。\n勉強会直前に発表されたSensorBeeをElasticsearchと一緒に使うとどんなことができるかというお話です。 まぁ、前処理重要ですよねというのが、いつものことですが、印象的でした。 いつものようにわかりやすい説明だったので、使ってブログを書いて欲しいなと。\n発表の中で、説明に出てきたデモとか。\nCES2016でロボットカーのデモを展示してきました \u0026ldquo;Elastic{ON} 2016レポート\u0026rdquo; / Elastic Jun Ohtani スライド:elastic{on} 2016 レポート\n写真多めで、キーノートをメインに話をしました。\n簡単なまとめとしては\nプロダクトロゴができました。ロゴ画像などはこちら 次のメインバージョンは全て5.0。(5.0に関する通知が欲しい人はこちらで登録できます) elastic{on} 2016のビデオなどはこちら BBL始めます。連絡ください \u0026ldquo;Elastic{ON}の過ごし方\u0026rdquo; / クラスメソッド株式会社 藤本 真司 さん スライド:Elastic{ON}の過ごし方\n印象に残ったのは\n「自他共に認めるブログの会社」 4/12にSAPさんに会場を借りてElastic&クラスメソッドでイベントやります。 やっぱりご飯が美味しいんですねぇ。 早速ブログが書かれてました。\n\u0026ldquo;Elastic{ON} 2016 見るべきセッション資料 7選\u0026rdquo; / Acroquest Technology株式会社 谷本 心 さん スライド:Elastic{ON} 2016 見るべきセッション資料 7選 #elasticsearchjp\n印象に残ったのは\n東京でハンズオンやる会場提供者募集中! Ingest Node(参考:Ingest Nodeのドキュメントは公開中。) Reindex API(参考:Backport reindex to 2.x ) その他、感想などのブログ 第15回elasticsearch勉強会にLTで登壇しました #elasticsearch #elasticsearchjp 第15回elasticsearch勉強会に参加してきました #elasticsearch #elasticsearchjp まとめ+宣伝 来年のElastic{ON}に参加したいと思っていただけたらよかったなと。\n4/12にクラスメソッドさんとイベントを行います。また、ツイートすると思います。\n次回はいつも通りだと5月中旬になるかと思います(大丈夫かな?OSC 2016 Nagoyaでしゃべったり、ブース出したりとかするけど)。 5末に名古屋に出没します。名古屋で勉強会できればやりたいと思ってます。会場とかスピーカーとか興味がある方は連絡ください。\n","date":1458186180,"dir":"post/2016/","id":"c56a76ef8f604a8d87be2a32b1f81fac","lang":"ja","lastmod":1458186180,"permalink":"https://blog.johtani.info/blog/2016/03/17/15th-elasticsearch-jp/","publishdate":"2016-03-17T12:43:00+09:00","summary":"第15回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズ","tags":["elasticsearch","勉強会"],"title":"第15回Elasticsearch勉強会を開催しました。 #elasticsearchjp"},{"contents":"久々のポスト。。。\n久々に、技術書読んでます。「自然言語処理の基本と技術」という本です。\n監修の方のツイートを見て気になったので、買ってみました。 書籍のサイトの説明はこんな感じでした。\n本書は、この未来に不可欠となるに違いない自然言語処理の、技術的、ビジネス的基礎知識をくまなくコンパクトに図解した一冊です。 著者陣もそれぞれの分野の第一線で活躍するエキスパート揃い!\n確かに著者陣がすごいです。\nまだ、「はじめに」と自分に関係のある「情報検索」の章を流し読みしただけなんですが、次のような特徴がある本です。\n平易な単語で説明してある(難しい専門用語が少ない) 数式が出てこない(多分。少なくとも読んだ部分では見てない) 説明には例と図解がある 情報検索の章で言うと、全文検索でよく使われる転置インデックス(索引という単語が使われてる)がなぜ必要なのか、どういう感じで作られるのか、 転置インデックスに利用する索引の単語をどうやって作るのか(文字N-Gramや形態素解析)、単語の正規化(ステミングやストップワード)などの説明が 本当にわかりやすく書かれています。 スコアリングについても触れられています。\nElasticsearchも転置インデックスを用いた検索を行っており、 MappingでAnalyzerの指定をしている理由などの理解に役に立つと思います。\n全文検索システムがどのように検索を処理しているかをざっくり理解するのにはもってこいじゃないかと。 1点残念だなと思ったのは、書籍に「索引」がありませんでした(本の索引を思い浮かべてくださいっていう説明あったんだけど)。。。 Kindle版を購入すれば「検索」できるのかな?\nということで、まだ、流し読みしただけなんですが、「すごく」オススメです。 購入はこちらから!\n","date":1457962452,"dir":"post/2016/","id":"3fc7462a83fa55885067fee629287e8a","lang":"ja","lastmod":1457962452,"permalink":"https://blog.johtani.info/blog/2016/03/14/review-basics-and-tech-of-nlp/","publishdate":"2016-03-14T22:34:12+09:00","summary":"久々のポスト。。。 久々に、技術書読んでます。「自然言語処理の基本と技術」という本です。 監修の方のツイートを見て気になったので、買ってみました","tags":["本"],"title":"「自然言語処理の基本と技術」を読んでる"},{"contents":"あけましておめでとうございます、johtaniです。\n第14回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 今年もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\nチェックイン数など チェックインした人:122名 キャンセルしなかった人:58名 でした。 今回も当日の昼の時点でキャンセル待ちがない状態にしていました。 いくつか電車が止まっていたという話を聞いていたので、開始を5分遅らせ、 受付は45分くらいまで開けておくという対応をしてもらいました。\n\u0026ldquo;ココが辛いよelasticsearch\u0026rdquo; / 株式会社リクルートテクノロジー @tatakaba さん スライド:ココが辛いよelasticsearch\n実際にいくつかのサービスで運用されている内容とどういった機能を利用しているか、 どういったものを独自に作っているかという話をしていただきました。\n独自PluginでA/Bテストしてる Snapshotの活用 Index作成は環境に合わせて行っている。 バージョンは混在 PusnaRSのバージョンアップの話。 2つのバージョンのクラスタを用意してリアルタイムに切り替え。 Elasticsearchの活用 QueryのRewrite: SolrのリクエストをEsで受け付けたり。 辛い話。 バージョンアップが辛い Riverなくなるのつらい データずれるのつらい 補足:\nバージョンアップについて 1.x系から2.x系にアップされるのであれば、こちらを必ず試してください。\nhttps://github.com/elastic/elasticsearch-migration\n「.」が使えなくなるという話は、Solrとの大きな違いになるのかもなぁと。 ネスト構造のデータの表記を「.」で行うというのを厳密に行えるように、 「.」を使えなくしたというのがあるかと。\nRiverについて Riverがなくなった理由については、https://www.elastic.co/blog/deprecating-rivers で記載があります。 便利なのですが、負荷が偏ったり、スケールしないとかいう問題点があるかなと。\n良いサンプルとしては、JDBC Riverなどは、Javaのプログラムとして起動できるように変更されていたりします。\nhttps://github.com/jprante/elasticsearch-jdbc/wiki/jdbc-plugin-feeder-mode-as-an-alternative-to-the-deprecated-elasticsearch-river-api\n(個人的 には、SolrのDIHもRiverもあんまり好きではなかったです。データの変換処理と、ロード処理は別々にしたい人だったので。)\nデータのズレなど 耐障害性とか信頼性に関しては、どういった問題点があるのか、どういった対応をしているのかというのがまとめられたページが用意されています。\nhttps://www.elastic.co/guide/en/elasticsearch/resiliency/current/index.html\n「機械学習を利用したちょっとリッチな検索」 / Preferred Networks America, Inc. CTO 久保田展行(Kubota Nobuyuki) さん スライド:機械学習を利用したちょっとリッチな検索\n来日していただき、機械学習と検索の話をしてもらいました。 本編は次回の発表かもw\n機械学習を元に、検索対象の情報を元の情報から増やしてあげる。 増えた情報を検索できるようにする 今日のゴール: 機械学習とはどういうものか? データの集め方とか、アノテーションとか 学習の方法(ツールやライブラリに依存) Esでの活用方法 オフラインで学習させて、情報を付与した後に、Elasticsearchに入れる Jubatus+fluentdで ChainerサポートのOSSのツールを公開予定 「ここからが本当の地獄だ。。。」ってのが聴きたいw\n「Lucene Query 再考 - Domain Specific Query 実装 -」 / Supership株式会社 インフラ事業開発本部検索グループ 大川真吾 さん スライド:Lucene Query 再考 - Domain Specific Query 実装 -\nLuceneのクエリに関する話と、クエリパーサーに関する話でした。 こういった濃い話も勉強会でしてもらえると、色々な参加者に楽しんでいただけるかなぁと。 次回も続きを話してもらう予定です。\n補足:\n参考までにですが、Elasticsearchに入門したての人向けに、 Analyzerとか転置インデックスとかの話をした時のスライドになります。 https://speakerdeck.com/johtani/lucenetori-ben-yu-falsejian-suo\nLT: Fluentd meets Beats / @repeatedly さん スライド:http://www.slideshare.net/repeatedly/fluentpluginbeats-at-elasticsearch-meetup-14\n参考Qiita:http://qiita.com/repeatedly/items/77af41788f0b3ccdefd2\nBeatsの説明をTDの人からしてもらうなどw FluentdにBeatsからのデータを流し込めるようにしたプラグインが出たという話でした。\nfilebeatの性能の件は社内で聞いてみようかと。\nElasticsearchインデクシングのパフォーマンスを測ってみた / 日本IBM 黒澤亮二さん スライド:Elasticsearchインデクシングのパフォーマンスを測ってみた\n参考Qiita:http://qiita.com/rjkuro/items/e79eec7ffb0511b7c678\n細かな性能測定の結果を駆け足で話してもらいました。 皆さんもこの指標をもとに、手元の環境を計測してみたりしてみてもらえればと。\nあとは、2.x系になってるので、同じ方法で計測してもらってまた 発表してもらえると嬉しいなー(棒)\nその他、感想などのブログ Elasticsearch勉強会 第14回フィードバック まとめ+宣伝 久々に(初めてかな?)、ゲストがいないのに自分が喋りませんでした。 次回は3月中旬を予定してます。 次回は、Elastic{ON}16の報告をする予定です。いろいろと発表あるだろうし。\nあと、今月末の1/29にオープンソースカンファレンス 2016.enterprise@Osakaにブース出展します。 セミナー枠でも弊社OSSプロダクトの概要を話しする予定です。 関西の方は、ぜひ参加していただければと。ブースでお待ちしております。\nまた、スピーカーや場所が用意できたら、出張勉強会もまたやりたいなと思っています。 興味ある方は、連絡ください!\n","date":1452220496,"dir":"post/2016/","id":"4b0a768585da8f9f8f8db1ca409e7ebd","lang":"ja","lastmod":1452220496,"permalink":"https://blog.johtani.info/blog/2016/01/08/14th-elasticcsearch-jp/","publishdate":"2016-01-08T11:34:56+09:00","summary":"あけましておめでとうございます、johtaniです。 第14回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆","tags":["elasticsearch","勉強会"],"title":"第14回Elasticsearch勉強会を開催しました。 #elasticsearchjp"},{"contents":"今年は紅白見ながら書いてます。 早い一年だったなぁ。\n振り返り(2014年に書いた抱負から) まずは去年の抱負を元に振り返りをば。\n英語の継続 海外のイベントへの参加 多岐にわたるイベントでのスピーカー 日本の人員の倍増!? Elasticsearchに関する日本語の情報発信 Elasticsearch座談会みたいなものの開催 英語はまぁ、継続してます。亀の歩みですが。。。\n海外のイベントへの参加は、自社のイベントだけでした。来年のElastic{ON}ももちろん参加です。来年こそBerlin Buzzwords行きたいな。。。\n多岐にわたるイベントとまではいってないですかね。。。来年はOSC(大阪や東京)に出没予定です。参加される方は、声をかけていただければと。\n人員は倍増しました!営業の方が参画されたのがかなり助かってます。 今現在で4名です!来年も倍増できるかなぁ?\n日本語の情報発信はリリースブログの翻訳が多めでした。来年は独自コンテンツも増やさないとなぁ。 あとやっぱ書籍かなぁ。。。座談会は来年の課題に。。。\n振り返り(今年あったできごと) その他の今年の出来事。\n初渡米 初バルセロナ 東京以外で勉強会 初自社イベント(日本で) 初トレーナー 不惑 今年も初モノ多いですね。今年も楽しい一年でした。 自社イベントでアメリカやバルセロナなどに行きました。40年近く、海外に行ったことないせいか、海外に行って経験することが面白いです。\n東京以外での勉強会もやりました。名古屋、大阪、京都、北海道と。 来年もOSCで訪れた場所で勉強会を開催したいなぁと。\n自社のイベント(Elastic{ON} Tour Tokyo)も東京でやりました。 どうなることかと思っていましたが、朝から大勢の方に来ていただけてホッとしました。 自分のトークがどうだったのかという反応も気になりますが。。。 せっかくShayたちが来ていたので、もっとブースに話しに来てもらえるともっと嬉しかったかもなぁと。\nTour Tokyoを挟んで自社の公式トレーニングのトレーナーもやりました。 日本で3回目にして、初の日本語でのトレーニングでした。前の2回は逐次通訳だったんですが。 トレーニングって大変だなぁと思ったのと、やはり日本語でトレーニングを受けられるとだいぶ違うだろうなという実感がありました。 来年もできればいいなと。トレーニング自体があったことを知らない人もいたのかなぁ?\n来年の抱負 英語の継続 もっとElasticsearchの開発に参加 人員の倍増? 日本語情報発信 Splatoon S+? 英語あいかわらず出来てないので、頑張らないと。 もっと喋ったりしないとなんだろうなぁ。\n来年は開発をもっとやりたいなと。 来年1月にはセールスのエンジニアが加入するので、開発にもっと時間を割きたいなと。\n人員は倍増できるように頑張りたいです。少なくとも、2人が1月に入ることは決まってるんで、後二人!\nブログももっと書かないとですね。新機能とかこんな使い方できるよとか。 どんな記事が欲しいかとかコメントもらえると楽なので、突っ込みくださいw\n最後は、完全に私用ですね。Splatoonにはまってますw SとA+を行ったり来たりで。。。\nということで、今年はあと、数時間ですが、色々とお世話になりました。 この場を借りてお礼申し上げます。\n来年も、いろんな方に絡んでいくとは思いますが、よろしくお願いいたします。\n","date":1451565182,"dir":"post/2015/","id":"c54909ecf4fb3e9afeea36200fe95dce","lang":"ja","lastmod":1451565182,"permalink":"https://blog.johtani.info/blog/2015/12/31/looking-back-2015/","publishdate":"2015-12-31T21:33:02+09:00","summary":"今年は紅白見ながら書いてます。 早い一年だったなぁ。 振り返り(2014年に書いた抱負から) まずは去年の抱負を元に振り返りをば。 英語の継続 海外の","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2015)"},{"contents":"今年最後のAdvent Calendarとなります。\nこの記事はElasticsearch Advent Calendar 2015の最終日のエントリです。\n簡単に今年の変遷を、Elasticsearchをベースに振り返ってみようかと思います。\nKibana 4リリース(2月) Kibana 4(日本語訳) いきなり、Elasticsearchではない話題ですが。 AggregationベースのKibanaがリリースされました。 画面が黒くないというので、話題になりましたw 12月末時点では、4.3.1になっています。 Sub Aggregationによる強力なグラフ表示や異なるインデックスに対するグラフを 一つのダッシュボードに表示できるといったことができるようになりました。\nセキュリティ向けプラグインShieldのリリース(2月) セキュリティ向けプラグインShieldのリリース(日本語訳) 商用向けのプラグインの第2弾です。 セキュリティ強化のためのプラグインで、いろいろなところで引き合いがあったりします。\n初のユーザカンファレンス、Elastic{ON}開催(3月) #elasticon に参加中 サンフランシスコで、弊社初のカンファレンスが開催されました。(来年(2016年)もサンフランシスコで開催されます。) また、ここで、以下の2点の発表がありました。\nロゴ及びドメイン名などの変更 Foundのジョイン 約1300名が参加する大イベントでした。 初の渡米で楽しんできましたが、ドメインの切り替えなどは大変でした。。。 まだ、ロゴを変えて1年経ってないということが実感できてないです。\nFoundのジョインはまだまだ、日本で知名度が出てないかもなぁと。 もっと広めないと。 利点としては以下の通りです。\n新バージョンがすぐに利用可能に。また、バージョンアップも画面で指定可能 公式プラグイン+その他いくつかのプラグインが利用可能 Elasticsearch 1.5 リリース(4月) Elasticsearch 1.5.0リリース(日本語訳) 主に、resiliencyに関する改良になります。 毎リリースで信頼性向上につながる改良が含まれる形になっています。 このリリースの近くで初の東京の外での勉強会を名古屋で開催したりもしました。\ndiscuss.elastic.coをオープン(5月) https://discuss.elastic.co これまでは、Google Groupsを使っていましたが、Elasticが提供しているプロダクトが 別々のグループであったために、プロダクトにまたがった質問がやりにくかったり、検索がしにくかったりという問題点がありました。 今では、過去のGoogle Groupsのデータも移行されているので、是非参加して、質問・回答してみてください。 日本語でやりとりできるカテゴリもあるので、どんどん、やりとりしていただければ。\nElasticsearch 1.6 リリース(6月) Elasticsearch 1.6.0リリース(日本語訳) 2.0に向けたUpgrade APIが含まれるなど、次期リリースに向けた準備が整いつつあるリリースでした。 他にもsynced flushの取り込みやレスポンスのJSONのフィルタリングなど細かな改善も取り込まれています。\nFound PremiumとStandardリリース(7月) さらに進化したFound(日本語訳) Foundに弊社のサポートチームがサポートできるプレミアムが追加されました。 これにより、商用プラグインとして提供しているShieldが(現在はWatcherも)利用できるなど、 より便利になりました。また、Kibana 4も無料で提供されていたりします。\n小さなサイズのものですと、無料で試していただけるものもあるので、試してみてもらえればと。\nElasticsearch 1.7 リリース(7月) Elasticsearch 1.7.0 および 1.6.1リリース(日本語訳) 1.x系、最後のリリースでした。 小さい改善ですが、セキュリティフィックス、クラスタの安定化に寄与する機能改善が含まれています。\nこのリリース直前に大阪、京都で勉強会も開催してみました。\nElasticsearch 2.0.0-beta1 リリース(8月) Elasticsearch 2.0.0-beta1リリース(日本語訳) 待ちに待った、Lucene 5ベースのElasticsearchの登場でした。 doc_valuesがデフォルトになったり、エラーが構造化されて見やすくなったり、 Pipeline Aggregationが導入されたりしています。 また、問題点の洗い出しも兼ねて、ベータリリースとして、本リリースまでに多くのIssueをあげていただきました。\nElasticsearch 2.0.0 リリース(10月) 2.0の本リリースです。リリースまでに、beta1、2及び、rc1がリリースされました。\n追加された機能や目玉の改善については「Elasticsearch 2.0の紹介」のスライドを参考にしていただければと。\nまた、Elasticsearch 2.0のリリースに合わせて、商用プラグインやLogstash、Kibanaの新しいバージョンがリリースされました。 Kibanaなどは、プラットフォームとしての機能を備え、SenseやTimelionと言ったプラグインアプリもリリースされています。\nLogstash 2.0.0リリース(日本語訳) Kibana 4.2.0リリース(日本語訳) Senseの歴史 - Sense 2.0.0-beta1の紹介(日本語訳) Shield、Watcher、Marvel 2.0.0 GAリリース(日本語訳) Elasticsearch 2.1.0 リリース(11月) Elasticsearch 2.1.0 and 2.0.1 released Beats 1.0.0のリリース(11月) The Beats 1.0.0 Go言語で書かれた軽量データシッパーになります。 パケットをキャプチャしてElasticsearchに送るPacketbeat、 topコマンドで取れるデータなどをTopbeat、 ログファイルなどを取り込み配送するFilebeatがリリースされました。\nlibbeatと呼ばれる、 ベースとなるライブラリを元にしたプロダクトで、Logstashのエージェントのような使い方もできるようになっています。\nGo言語に興味のある方などは、調べてみてはいかがでしょう?\n来年は? 日本では、1/7に第14回Elasticsearch勉強会を開催します。 すでに、38名のキャンセル待ちとなっていますが、おそらく、年明けにキャンセルがそこそこ出ると思うので、まだ間に合うんじゃないかなぁと。\n会社としては、Elastic{ON}16が控えています。参加される方は、ぜひ現地で声をかけてください!!\nその他にもイベント、オープンソースカンファレンス(まずは、大阪、東京)などに出没する予定ですので、こちらも参加していただければと。\nでは、また来年のAdvent Calendarでお会いしましょう!\n","date":1451017794,"dir":"post/2015/","id":"d819cea5197e9b8673d6c0b16659a5ea","lang":"ja","lastmod":1451017794,"permalink":"https://blog.johtani.info/blog/2015/12/25/about-elasticsearch-in-2015/","publishdate":"2015-12-25T13:29:54+09:00","summary":"今年最後のAdvent Calendarとなります。 この記事はElasticsearch Advent Calendar 2015の最終日のエントリです。 簡単に今年の変遷を","tags":["elasticsearch"],"title":"2015年のElasticsearch"},{"contents":"こんにちは、@johtaniです。\n早いもので、師走です。今年もあと少しとなりました(今月が一番忙しかったりしますが。。。)。 ということで、Advent Calendarの季節が始まりました。\nこの記事はElasticsearch Advent Calendar 2015の1日目のエントリです。\n今日は、最近公開されたTimelionの紹介をしたいと思います。\nTimelion? 11/12に公開されたばかりのアプリになります。(公式のブログはこちら。ブログでは動画による説明もあり)\nKibanaにプラグインとしてインストールすることで使用することができるようになるアプリです。 Timelionと書いて「Timeline」と読むようです。 Kibanaとは異なるグラフ描画のプラグインになっています。\nKibana 4.2からプラットフォーム化 Kibana 4.2から、Kibanaにプラグイン機構が導入されました。 Kibanaとしての機能以外にも、プラグインとして、アプリを追加できるようになっています。 Timelionもその一つです。\nインストール Timelionを試してみるには、ElasticsearchとKibanaが必要になります。(こちらは、すでにインストールされているとして。。。)\nKibanaのコマンドを利用して、プラグインをインストールします。\nbin/kibana plugin -i kibana/timelion インストールしたら、Kibanaにアクセスして、Timelionを呼び出します。\nTimelionへアクセス ブラウザでlocalhost:5601にアクセスすると、Kibanaが出てきます。 Kibanaのプラグイン選択のアイコンをクリックし、Timelionのアイコンをクリックします。\nすると、初期画面はこんな感じです。 直近15分のElasticsearchに入っているデータがが全部出てきます。 チュートリアルも出てきてます(初回起動時に出たはず)\nKibanaでの検索窓の部分に関数を指定していくことで、グラフが描画できるツールになっています。\nサンプル:気温データを可視化 百聞は一見に如かずということで、 気象庁のデータを使って、 ちょっとしたグラフを書いてみました。 1年間の気温の推移と日照時間になります。\n上のグラフが那覇、下グラフが札幌の気温のグラフになります。\n赤いライン:最高気温 青いライン:最低気温 黄色い棒グラフ:日照時間 最低気温と日照時間はグラフは次のような式で描画しています。\n青いラインの最低気温 気温のグラフになります。\n.es(index=\u0026#39;tenki2\u0026#39;, q=\u0026#39;city:naha\u0026#39;, metric=\u0026#39;avg:temperature_min\u0026#39;).label(\u0026#39;min\u0026#39;), .es()がelasticsearchに対するデータ取得の関数です。 引数は次のような意味になります。\nindex:対象とするインデックス名 q:検索クエリ。ここでは、cityというフィールドにnahaで検索。 metric:描画対象となっているデータの入ったフィールド。temperature_minというフィールドの1日毎の平均値を取得 最低気温と最高気温は別々のフィールドに格納してあります。最高気温の場合は(temperature_max)を指定します。\n.label(min)で、グラフの凡例の指定です。 残念ながら、日本語の指定は現時点(2015年12月01日時点)ではうまくいかなかったです。(https://github.com/elastic/timelion/issues/17)\nデフォルトでは、線グラフが選択されているので、グラフの種類は特に指定はしていません。 明確に指定する場合はlines()を指定します。\n黄色い棒グラフの日照時間 .es(index=\u0026#39;tenki2\u0026#39;, q=\u0026#39;city:naha\u0026#39;, metric=\u0026#39;avg:sunlight\u0026#39;).label(sunlight).bars() .es()に関しては最低気温のグラフとほぼ一緒です。異なるのは、metricの取得対象のフィールド名です。\n.label()で凡例を指定しています。先程と同様です。\n最後に、棒グラフにしたいため、.bars()を指定しています。\nその他に用意されている関数について知りたい場合は、Timelionのヘルプを表示すると説明が出てきます。 cusum()のような値を累積して表示するような関数も用意されています。\nまとめ Kibanaとは少し違うアプローチで時系列データを描画するためのツールとなっています。 線グラフと棒グラフを一つのグラフに描画したりもできますし、 累積のグラフなんかも描画できるようになっています。\n実験的なプロジェクトである、Timelionの紹介でした。 ここでのノウハウがkibanaにフィードバックされると色々と面白いことになるんじゃないかなと。\nということで、 明日は、zoetroさんの「Kibanaのプラグインの話」になります。 お楽しみに!\n","date":1448936891,"dir":"post/2015/","id":"1b56132638912a1ca54fcf7cd38b8e23","lang":"ja","lastmod":1448936891,"permalink":"https://blog.johtani.info/blog/2015/12/01/introduction-timelion/","publishdate":"2015-12-01T11:28:11+09:00","summary":"こんにちは、@johtaniです。 早いもので、師走です。今年もあと少しとなりました(今月が一番忙しかったりしますが。。。)。 ということで、A","tags":["kibana","timelion"],"title":"Timelionの紹介 - Elasticsearch Advent Calendar 2015 1日目"},{"contents":"第13回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 来年もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\n7月同様、サムライズムの@yusukeさんに テキスト翻訳していただき、大変助かりました。\nチェックイン数など チェックインした人:100名 キャンセルしなかった人:36名 でした。 今回は当日の時点でキャンセル待ちがない状態にしていました。 雨もあって、これなかった人もいるのでしょうか。\n\u0026ldquo;Beyond the basics with Elasticsearch\u0026rdquo; / Honza Král / Elastic スライド:https://speakerdeck.com/elasticsearch/beyond-the-basics-with-elasticsearch\n参考ビデオ(別のカンファレンスで話した時のビデオ):https://www.youtube.com/watch?v=yIixWzjTNog\nPycon HKでアジアに来ていたHonzaに、ついでに日本で話をしてもらうという企画で、 前回から1カ月足らずでの開催となりました。 Elasticsearchの基本的な検索機能とは別の機能に関して少し話をしてもらった感じです。 PercolatorとAggregationの話でした。\n詳しくはビデオやスライドを見てもらうのがいいかなと。\n\u0026ldquo;How did we use Found.no for our services?\u0026rdquo; / 株式会社アイリッジ Takuya Noguchi さん @tn961ir スライド:未定\nFoundユーザー。1.7までの話。 社内で独自にクラスタを構築していたが、managed serviceを利用したいと思っていた。 Found用のACLがShieldに マルチバイトのインデックス名とかも使いたいが、Nginxとの連携でちょっと。。。 セキュリティ関連の話も。Securityに関する報告はこういうものも用意されてるので、こちらに相談してもらうのがいいかも。https://www.elastic.co/community/security 要望がいくつか。 \u0026ldquo;ログ収集の仕組みを再考しよう! あとマウンテンビューに行ってきました。\u0026rdquo; / Acroquest Technology株式会社 谷本 心さん @cero_t スライド:http://www.slideshare.net/shintanimoto/lets-reconsider-about-collecting-logs-plus-visiting-elasticmoutain-view\nログの小話から始まり、ログに関する考え方とかを披露してもらいました。 さらに踏み込んだログの活用の方法の話になるかと思いきや、 思いっきり話が飛んで、マウンテンビューのElasticオフィスに遊びに行った写真が出てきましたw\n写真の後は、弊社のTanya(来月のElastic{ON} Tour Tokyoで来日予定)から 聞いた弊社製品に関する話をしていただきました。 きっと、Beatsに関して次は話してくれるんだろうなぁ(棒)。 流れ的には、来年の2月にサンフランシスコで開催されるElastic{ON}16につながりそうだったので、ここで宣伝しときますね。 今年3月に開催されたイベントには残念ながら日本の方はいなかったので、次回は日本の方がいると嬉しいなぁと。\nLT \u0026ldquo;「Elasticsearch を使った単語共起頻度の計算」\u0026rdquo; / 株式会社はてな id:takuya-a さん スライド:未定\n一風変わったElasticsearchの使い方的な話でした。 検索用にデータを登録してあるElasticsearchから単語の頻度情報を抜き出して、 別のインデックスに登録するという感じでしょうか。 こういうのが、実は、Elasticsearchに機能としてあると便利だったりするのかもなぁと思ってみたり。\nLTよりはちょっと長かったですかねw\nその他、感想などのブログ elasticsearch勉強会 まとめ+宣伝 今回も@yusukeさんのテキスト翻訳に助けていただきました。ほんとありがとうございます。 今年の勉強会はこれがラストになります。 来月は、トレーニングとElastic{ON} Tour Tokyoがあるので忙しくなりそうですが、 参加予定の方は楽しみにしていてください!\nOperations : http://training.elastic.co/class/Operations/Japan/Dec Developer : http://training.elastic.co/class/Developer/Japan/Dec ","date":1447143778,"dir":"post/2015/","id":"2ea86ae5093670df1d4502ea82efa1ac","lang":"ja","lastmod":1447143778,"permalink":"https://blog.johtani.info/blog/2015/11/10/13th-elasticsearch-jp/","publishdate":"2015-11-10T17:22:58+09:00","summary":"第13回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズ","tags":["elasticsearch","勉強会"],"title":"第13回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:The Story of Sense - Announcing Sense 2.0.0-beta1\n誕生 よくある良いプロジェクト同様、Senseもビールを飲みながら考えつきました。 Amstelでの手漕ぎボートのセッションの後で。 友人のJasperと私はJasperの会社で毎年行われる ハッカソンについて話をしていました。 このハッカソンはどのようなアイデアでどんなチームで行うかを聞き取りされる、厳密なハッカソンです。 その時、私とJasperはChromeブラウザに別のヒストリーを表示するという作業をやるとAnne Velingに話をしていました。\nJasperと私はElasticsearchのユーザでしたが、リッチなREST APIにリクエストを送信するための 便利なツールがないと知っていました。 恥ずべきことに、cURLコマンドを利用するターミナルがその時の一番良いツールでした。 皆さん、ターミナルでボディつきのリクエストをサブミットするのがどのくらい不便かというのをわかるために、 5秒ほどターミナルで実行してみてください。 タイプミスのような単純なことでさえ、すべてのコマンドを再タイプしなければならなかったり、 複数行サポートのターミナルと戦ったりです。 ウェブベースのJSONエディタを見つけ出して、それをベースにすることが必要でした。\n終わりなきウィークエンド リサーチをして、Anneに電話しました。 私は彼に、History Pageのプロジェクトにもコミットするが、 Elasticsearchユーザなので、便利なコンソールを開発する時間も欲しいという話をしました。 私たちは、Aceオンラインエディタを利用して、 自動でAPIを認識するナレッジベースを構築し、 コンテキストに沿ったサジェストを大なうようにしました。 Anneはすぐに、それが素晴らしいと同意してくれました。 しかし、彼は、ハッカソンの基本的なルール(週末にそれが終わる必要がある)に違反しているので、 そのアイデアを却下するしかありませんでした。 確かに、私たちが提案していたものは行えませんでした。 最後に、私たちは、ChromeのHistory Pageの素晴らしい置き換えについて実装しました。\nそれでも、私はチャレンジし、それが終わるであろうことを終わるであろうことを証明しなければなりませんでした。 次の週末(といくつかの終業後 :))に、私はそれを作りました。 Senseの誕生です。 それは、まだバグだらけでしたが、動きました。 これを見せるとみんな興奮しました。\n初期 Knowledge Baseの拡張とバグのフィックスで数日を過ごしました。 Senseは広まり始め、ずっと古いバグのあるバージョンを利用しないといけないのかと私は恐れました。 SenseをChromeのExtentionとしてリリースすることを決め、リリースすると自動的に更新されるようにしました。 History Panelのような機能を一つづつ追加するようにしました。\nElasticにジョインしてから、会社の人たちがSenseを使用しているということを聞き、とても幸せでした。 特に、Clintと話をしたときのことを覚えています。 彼は、\u0026ldquo;You know what Sense should do? It should use this format and allow you to have multiple requests in the editor\u0026rdquo; 「Senseになにをすべきかわかる?フォーマットを使うべきだし、エディタで複数のリクエストを持つようにするべきだ」 と言いました。 もちろん、その他のチャレンジも行いました。これは、簡単なものではなく、Aceの詳細を知る必要がありました。 それは新しいAceモード(Aceによって利用されているハイライティングロジック)です。 これは、Senseのサジェストエンジンに密に統合されました。\n次のものが古いSenseのスクリーンショットです。\n画像あり。Figure 1. Sense 0.7 ※画像に関しては原文をご覧ください。\nAPIのURLを入力すると、JSONのボディが入力されます。 うまく切り離すことができ、AceのスタンダードJSONモードを使っていました。 しかし、ここで、次のようなフォーマットをどうやってサポートするか考える必要がありました。\nGET _cluster/health POST index/_settings { \u0026#34;index\u0026#34;: { \u0026#34;number_of_replicas\u0026#34;: 3 } } これは、Aceが3つの異なるものをどうやってパースするかを知る必要があるということです。 HTTPメソッドとURLとJSONボディです。 また、困ったことに、前に説明した前に説明した通り、明らかに別々にはならないものでした。 JSONボディが完全であることを知る唯一の方法はかっこを数えることです。 それは、いくつかの作業とAceのカスタマイズが必要でしたが、それらを切り離すことができました。 そして、Senseのシンタックスが生まれたのです(Thanks Clint!)\nMarvel時代 就業時間中、私の優先すべき仕事はMarvelの開発になりました。 これは、Elasticsearchのための管理と監視のためのソリューションです。 (side note: Marvelは生まれ変わっています。(\u0026quot;Shield, Watcher, and Marvel 2.0.0 GA Released\u0026quot;)) Marvelは開発環境ではフリーなので、MarvelにSenseを組み込むことにしました。 これにより、Senseの開発が日中も行えるようになり、多くのユーザに利用され始めました。 また、Senseは実際に真のJavaScript開発者によって開発されました。 彼は、コードをクリーンにし、ブラウザにおける最新の技術を私に教えてくれました。\nこの期間のSenseは数回書き換えられています。 最も顕著なものは、個別のURLとJSONのサジェストエンジンを書き換えて、 1つのサジェストエンジンにしこれらのコンテキストで動作するようにし、さらに3つ目のコンテキスト(URLパラメータ)を追加したことです。\n新しいエンジンはまた、複数のサジェストコンテキストをメンテナンスするのが簡単になりました。 例えば、_search APIのソートパラメータを考えます。\nGET _search { \u0026#34;sort\u0026#34;: [ \u0026#34;timestamp\u0026#34;: \u0026#34;desc\u0026#34;, \u0026#34;price\u0026#34;: { \u0026#34;order\u0026#34;: \u0026#34;desc\u0026#34;. \u0026#34;missing\u0026#34;: \u0026#34;last\u0026#34; }, \u0026#34;nested_filter\u0026#34;: { \u0026#34;term\u0026#34;: { ... }}, \u0026#34;_score\u0026#34; ] } ユーザがどこにいるかによって、Senseは単純な値(_scoreのような)か、 複雑な構造(orderとmissingのような)やフィルタ(nested_filterのような)も サジェストする必要があります。 これらのサジェストのパスが一度に処理され、無関係なものは除外されます。\nSense 2.0の紹介! Marvel 1.xはKibana 3.0をベースにしていました。 これは、データの探索やダッシュボードツールとして素晴らしいものでした。 しかし、Kibanaチームはさらに素晴らしいものを出しました。 Kibana 4.xはElasticsearchをバックエンドとするUIアプリを簡単に構築することができる プラットフォームとして設計されています。 実際に、Marvel 2.0はKibanaの プラットフォームで利用できる最初のアプリです。\nSenseの話に戻します。 ElasticsearchのAPIとやりとりする一般的なコンソールです。 これをKibanaのアプリぴったりだと気付きました。 ということで、Sense 2.0をKibanaアプリとしてオープンソースで公開しました。 開発及び本番環境で利用してください。\nFigure 2. Screenshot Sense 2.0 ※画像に関しては原文をご覧ください。\nリリースのハイライト Sense 2.0の新しい機能をここで簡単に紹介します。 (すべての変更点についてはこちらをご覧ください。)\nElasticsearch 2.0 SenseのナレッジベースをElasticsearch 2.0サポートに更新しました。 新しいPipeline aggregationにも対応しています。\n複数リクエストの実行 テストやいくつかの一連のコマンドを繰り返し実行したい時があるでしょう。 その時に、それら全てをSenseに記述し、 実行したいリクエストを選択状態にしてElasticsearchにリクエストできます。\nFigure 3. Submit multiple requests ※画像に関しては原文をご覧ください。\nSenseは、Elasticsearchにリクエストを一つずつ送信し、それぞれの出力結果を右のパネルに表示します。 これは、問題のデバッグや複数のシナリオでのクエリの組み合わせの実行に非常に便利です。\n複数リクエストのコピーペースト 複数リクストを選択し、フォーマットしたり、cURLのコマンドとしてコピーすることも可能です。\nFigure 4. Copy multiple requests as cURL ※画像に関しては原文をご覧ください。\n# Delete all data in the `website` index curl -XDELETE \u0026#34;http://localhost:9200/website\u0026#34; # Create a document with ID 123 curl -XPUT \u0026#34;http://localhost:9200/website/blog/123\u0026#34; -d\u0026#39; { \u0026#34;title\u0026#34;: \u0026#34;My first blog entry\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;Just trying this out...\u0026#34;, \u0026#34;date\u0026#34;: \u0026#34;2014/01/01\u0026#34; }\u0026#39; もちろん、複数のcURLコマンドをコピーしてSenseにペースとすると、Senseはそれらをパースしてくれます。\nまとめ Sense 2.0.0のベータリリースです。 実際に多くの作業が終わった認識です。すぐにGAが出るでしょう。\nSense 2.0を知り、試していただくために、新しいドキュメントを参考にしてください。 バグやリクエストがある場合は、フォーラムやGitHubのIssueに登録をお願いします。\n","date":1446195306,"dir":"post/2015/","id":"5912529cfd6ce14c5ede5c6c83dae7e8","lang":"ja","lastmod":1446195306,"permalink":"https://blog.johtani.info/blog/2015/10/30/sense-2-0-0-beta1-ja/","publishdate":"2015-10-30T17:55:06+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:The Story of Sense - Announcing Sense 2.0.0-beta1 誕生 よくある良いプロジェクト同様、Senseもビールを飲みながら考","tags":["elasticsearch","sense"],"title":"Senseの歴史 - Sense 2.0.0-beta1の紹介(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Shield, Watcher, and Marvel 2.0.0 GA Released\n本日(10/28)Shield、WatcherおよびMarvel 2.0をリリースしました。 これが、Elasticsearch 2.0に対応したこれらのプラグインの最初のリリースです。\nElasticsearch 2.0対応のほかに、ShieldとWatcher 2.0は、 セキュリティとアラートを拡張するいくつかの新しい素敵な機能も備えています。\nShield 拡張可能なレルム - Sheild 1.xはユーザ認証のコア的なものを定義するのにフォーカスし 3つの認証メカニズム(esusers、LDAP/AD、PKI)を提供しました。 これらを提供することで、多くのユーザおよびユースケースをカバー出来ましたが、 追加の認証メカニズムを統合する必要があることもわかっていました。 ということで、Shieldのレルムベースの認証システムをユーザが利用、拡張できるようにオープンにし、 ユーザ認証を扱うためのレルム実装をプラグインとして拡張できるようにしました。 特定もしくはプロプライエタリな認証メカニズムが必要なユーザもShieldの強力な セキュリティ機能(ロールベースの認証、セキュアな通信など)をフルに活用できるようになりました。 カスタムレルムの詳細については、こちらをご覧ください。\nフィールドとドキュメントのACL - Shield 2.0はフィールドとドキュメントレベルのアクセス制御機能を提供します。 これは、ロールごとにアクセス可能なフィールドやドキュメントを定義できます。 この新しい機能は、設定の変更するよりも便利です。 このアクセス制御はElasticsearchのLuceneインデックスという最も低レベルで実装されています。 その結果として、このメンテナンスがより簡単であるだけでなく、より良くなっています。 詳細についてはこちらをご覧ください。\nユーザなりすまし - Shield 2.0で、ユーザなりすましの機能が実装されました。 これは、ユーザ(適切なパーミッションを持った)が、他のユーザになることができ、 それらのユーザのためにリクエストを実行できます。 これは、Elasticsearch上に構築されたアプリケーションがすでにユーザ認証を行いますが、 認可はElasticsearchサイドで行う必要があるような場合に有用です。 このシナリオで、アプリケーションの\u0026quot;main\u0026quot;ユーザを設定でき、正しくなりすましを割り当て、 ElasticsearchにアプリケーションユーザとしてリクエストをElasticsearchに実行させることができます。 詳細については、こちらをご覧ください。\nWatcher SlackとHipChatインテグレーション - SlackとHipChatはチーム/グループコラボレーションツールです。 これらは、急速に主流になり、組織の主な内部コミュニケーションハブとなっています。 Watcher 2.0はチャンネル/ルームやユーザにこれらのコミュニケーションチャネル経由で、Watchの通知を行うことができるアクションを 実装しました。 slackやhipchatアクションについてはドキュメントをご覧ください。\nArray Compare Condition - 新しいconditionはタイムシリーズのデータのスパイクを検知するのを簡単にします。 compare conditionは1.xで導入されましたが、このコンディションはElasticsearchのダイナミックスクリプト機能を有効にする必要がアンク使えます。 詳細についてはarray_compare conditionをご覧ください。\nWatchの有効・無効化 - ユーザからの多かったリクエストとして、Watchの無効化がありました。 1.xには、登録済みのWatchを無効にする機能がありませんでした。 これは、Watchを消すか、Watchのトリガーを変更することで回避していました。 これは、全体としてはWatchを管理するのを難しくする回避方法でしかありません。 2.0では、APIを呼び出すだけで、Watchの変更をすることなく、簡単にWatchの有効化・無効化が可能になりました。 これは1.0からあるべき基本的な機能でしたが、ついにこの問題を解決しました。 詳細はこちらをご覧ください。\nMarvel Marvel 2.0を紹介するのに興奮しています。 Kibana 4をベースとした、再設計されたUIを持っています。 Marvel 1.xで学んだ多くのことを導入し、より使いやすく監視しやすいUIになっています。 ShieldとWatcherと同様に、最初のMarvelのリリースは将来的な成長の基盤となり Elasticsearch2.0を効率的に管理するための主要なメトリックにフォーカスしています。\n画像あり。 ※画像に関しては原文をご覧ください。\n再設計により、インタフェースを6ページに減らしています。\nCluster list 画像あり。 ※画像に関しては原文をご覧ください。\nユーザやカスタマーの多くは複数のクラスタを利用しています。 新しいMarvelはそれらを集中的にモニタリングする一つのクラスタからそれらを簡単に監視できます。 各クラスタのデータ送信先をこのモニタリングクラスタにするだけです。\nCluster Overview 画像あり。 ※画像に関しては原文をご覧ください。\nクラスタオーバービューはある一つのクラスタの主要な性能メトリックを見ることができ、 素早くスパイクを発見できます。 このページはまた、アクティブなシャードのリカバリやリロケーションも見ることができます。\nIndices List 画像あり。 ※画像に関しては原文をご覧ください。\nインデックスのリストにはクラスタにあるすべてのインデックスとその属性が表示されます。 テーブルはライブでアップデートされ、フィルタリングやソートも可能です。 一番大きなインデックスは?といったことも調べられます。\nIndex Detail 画像あり。 ※画像に関しては原文をご覧ください。\nインデックス詳細ページはインデックスの主な性能メトリックを見ることができ、シャードの配置についても表示します。\nNodes List 画像あり。 ※画像に関しては原文をご覧ください。\nノードリストはクラスタにあるノードとその主な性能メトリックを見ることができます。 テーブルはライブでアップデートされ、フィルタリングも可能です。 高いCPU利用率やディスクの残り容量なども簡単にわかるようになっています。\nNode Detail 画像あり。 ※画像に関しては原文をご覧ください。\nノード詳細ページは個別のノードに関する主な性能メトリックを見ることができ、ノードにあるシャードのリストも見ることができます。\n新しいMarvelはKibana 4の上に構築されたので、管理方法が変わっています。 Marvelのインストールは2つのステップがあります。 marvel-agentとmarvel user interfaceです。\nMarvel Agent marvel-agentはElasticsearchクラスタにプラグインとしてインストールします。 主なパフォーマンス情報を取得し、ローカルもしくは分離されたモニタリングクラスタにデータを保存・送信します。\nMarvel User Interface Marvel UIはKibanaのプラグインとしてインストールします。 これは、Kibana 4.2の新しいプラグインインフラを利用し、 Marvel Appとして、Kibanaのインタフェースとは個別に提供されます。 Kibanaのアプリの切り替えは次の画像の通りです。\n画像あり。 ※画像に関しては原文をご覧ください。\n2.0リリースは私たちのプロダクトの大きな一歩です。またユーザの意見を常にお待ちしています。 ぜひ、Webフォーラム(https://discuss.elastic.co)やメール(info@elastic.co)でご意見を。\n","date":1446189691,"dir":"post/2015/","id":"15700442e957951307bbcec5fff8643d","lang":"ja","lastmod":1446189691,"permalink":"https://blog.johtani.info/blog/2015/10/30/shield-watcher-and-marvel-2-0-ga-released-ja/","publishdate":"2015-10-30T16:21:31+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Shield, Watcher, and Marvel 2.0.0 GA Released 本日(10/28)Shield、WatcherおよびMarv","tags":["elasticsearch","shield","watcher","marvel"],"title":"Shield、Watcher、Marvel 2.0.0 GAリリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 2.0.0 GA released\nElasticsearch 1.0.0のリリース以降、 477のコミッター2,799のpull requestがあった、 **Elasticsearch 2.0.0 GA(Lucene 5.2.1ベース)**をリリースしました。\nそれだけでなく、Shield(セキュリティプラグイン)とWatcher(アラーティングプラグイン)、 新しくなったMarvel(モニタリングプラグイン)(プロダクション環境でフリー!)、 また、新しくオープンソースとなったSense editorの2.0.0もリリースしました。\nElasticsearch 2.0.0のダウンロードはこちらから。 また、2.0.0での重要な変更点についてはこちらをご覧ください。 全ての変更点については、次をご覧ください。\nChanges list for Elasticsearch 2.0.0 Changes list for Elasticsearch 2.0.0-rc1 Changes list for Elasticsearch 2.0.0-beta2 Changes list for Elasticsearch 2.0.0-beta1 商用プラグインについてはこちらです。\nShield 2.0.0 change logs Watcher 2.0.0 change logs Elasticsearchの新機能 Elasticsearch 2.0.0には素晴らしい新機能があります。\nPipeline Aggregations Aggregationsで導関数や移動平均のような他のAggregationの結果に対する計算が可能となります。 この機能はクライアントサイドで実装しなければなりませんでしたが、 Elasticsearchに計算させることで、より強力な解析のクエリを簡単に組み立て、クライアントのコードを簡略化できます。 これは、予測解析や予測解析や例外検知といった可能性をもたらします。 Pipeline Aggregationについては次をご覧ください。\nOut of this world aggregations. Staying in Control with Moving Averages - Part 1. Staying in Control with Moving Averages - Part 2. Query/Filter merging フィルタはもうありません。 全てのフィルタ条件はクエリとなりました。 クエリコンテキストで使用した場合、関連度のスコアに影響し、フィルタコンテキストで使用した場合、 これまでのフィルタのように、ヒットしなかったドキュメントを除外するだけとなります。 この変更はクエリの実行時に自動的に最も効率的な順序で実行するように最適化されることを意味します。 例えば、遅いクエリ(フレーズやgeo)の最初の実行は速い近似フェーズで実行され、 それから、遅い正確なフェーズで結果を修正します。 フィルタコンテキストでは、直近でよく使われた条件が自動的にキャッシュされます。 詳細については、\u0026quot;Better query execution coming to Elasticsearch 2.0\u0026ldquo;をご覧ください。\n設定可能な圧縮率 _sourceのようなStored fieldsは高速なLZ4(デフォルト)で圧縮するか、インデックスサイズを小さくできるDEFLATE で圧縮できます。 これは、特にロギングのケースで便利です。 古いインデックスをオプティマイズする前にbest_compressionに変更することができます。 詳細については\u0026rdquo;Store compression in Lucene and Elasticsearch\u0026ldquo;をご覧ください。\n堅牢に 新しいElasticsearchはJava Security Managerの元で実行されます。 これは、セキュリティの観点で大きな前進です。 Seciruty ManagerはElastcsearchにより制限をかけ、ハッカーによりシステムに対して何でもできるようなものを制限します。 Elasticsearchはまた、インデキシングの観点でも堅牢になっています。\nドキュメントはインデキシングリクエストに答える前に、耐久性のためにディスクにfsyncされます。 すべてのファイルはチェックサムにより、早期に障害を検知します。 すべてのファイルはどんなファイルへの書き込みもアトミックです 最後に、システム管理者から要請の多かった変更として、 設定されて居ないノードがパブリックなネットワークから参加しないようになりました。 Elasticsearchはデフォルトではローカルホストのみにバインドします。マルチキャストは無くなりました。(プラグインとして残っています。)\nパフォーマンスと信頼性 上記以外にも細かな修正がElasticsearchとLuceneにはあります。 より安定し、信頼性をあげ、簡単に設定できるようにするものです。例えば、次のようなものです。\nヒープの使用率の低減(doc valuesがデフォルト、マージ時のメモリ使用率の削減、 roaring bitsetsによるフィルタキャッシュ) 構造化され読みやすくなった例外 設定の代わりに、フィードバックループを使用した自動調整 安全で明確で信頼性のあるタイプマッピングの大きな修正 クラスタ状態の差分変更による伝搬の高速化および、大きなクラスタでのより安定的に normsの圧縮の改善。これまではヒープスペースを大きく利用していた。 マージの自動的な調整(不可解な設定の微調整が必要ない) より詳細なLuceneのメモリリポート 最適化されたクエリ実行を活用するためにParent/childを書き換え コアプラグイン 公式にサポートされたコアプラグインはElasticsearchと同じバージョン番号で同じタイミングでリリースされます。 インストールするプラグインとElasticsearchの複雑なバージョンの対応表に悩まされる必要はもうありません。 コアプラグインのインストールは次のように簡略化されています。\nbin/plugin install analysis-icu ShieldとWatcherの新機能 商用プラグインも新しい機能をリリースしました。\nShield フィールドおよびドキュメントレベルのアクセス制御 ユーザのなりすまし カスタム拡張可能な認証レルム Watcher 個別のWatchを有効/無効に SlackやHipChatへの通知 これらの詳細については“Shield, Watcher, and Marvel 2.0.0 GA Released”をご覧ください。\nコアプラグイン同様、商用プラグインもElasticsearchのバージョンと同じものが同時にリリースされます。 インストールは次の通りです。\nbin/plugin install license bin/plugin install shield bin/plugin install watcher Marvel 2.0.0はプロダクションでの利用もフリーに Marvelモニタリングプラグインはカスタマに非常に価値のあるもので、 ユーザの発展とともに問題を診断したり見つけたりするのに役に立ってきました。 私たちは、何を改善でき、Mαrvelを一から書き直すことで、いろいろとわかったことがあります。\nMarvel UIを新しいKibanaプラットフォーム上に構築 ダッシュボードにはより簡単に問題を発見するために、最も重要なメトリックを可視化 1つのインストールで、複数のクラスタのモニタリングをサポート(商用サポート対象) 一番良い点はMarvelがすべてのElasticsearchユーザに対してプロダクション環境でフリーになったことです! ライセンスが必要ですが、課金の必要はありません。 もし、マルチクラスタモニタリングサポートが必要な場合、それは商用サポート対象となります。\n詳細に関しては“Shield, Watcher, and Marvel 2.0.0 GA Released”をご覧ください。\nSense editorがオープンソースに Sense(ブラウザベースのElasticsearchリクエストとDSL向けのエディタ)を Kibanaプラットフォームのアプリとして、オープンソースにしました。 また、このリリースで新しい機能が追加されています。\n複数のcURLリクエストをペースとすると、Sense表記に変更 複数のSenseリクエストをcURL表記にしてコピー 複数のリクエストを一度に実行可能 Elasticsearch 2.0サポートとなった自動補完機能 SenseはKibanaのアプリとして次のようにインストールします。\n./bin/kibana plugin --install elastic/sense Senseの詳細については、\u0026quot;The Story of Sense - Announcing Sense 2.0.0-beta1\u0026ldquo;をご覧ください。\nElasticsearch Migration Plugin Elasticsearch Migration PluginはElasticsearch 1.xから2.0にアップグレードする時の良い出発点となります。 1.xのElasticsearchクラスタにサイトプラグインとしてインストールすると、 アップグレードする前に解決すべき問題があるかどうかを検知してくれます。 (例えば、Lucene 3のような古いインデックスや、2.0.0にした場合に動作しない問題のある マッピング(The Great Mapping Refactoring)のような問題)\nプラグインに関してElasticsearch Migration repositoryをご覧ください。\nまとめ ぜひ、Elasticsearch 2.0.0をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)やWebフォーラムなどで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1446103243,"dir":"post/2015/","id":"018e32a8010960eb17e368a6fdd5a51b","lang":"ja","lastmod":1446103243,"permalink":"https://blog.johtani.info/blog/2015/10/29/elasticsearch-2-0-0-released-ja/","publishdate":"2015-10-29T16:20:43+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 2.0.0 GA released Elasticsearch 1.0.0のリリース以降、 477のコミッター2,79","tags":["elasticsearch"],"title":"Elasticsearch 2.0.0リリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Kibana 4.2.0 released\nElasticsearch 2.0 + Kibana 4.2 = 💚 Elasticsearch 2.0サポートのKibanaの最初のリリースです。 これが何を意味するでしょう? 速さ、安定さ、新しい機能。 試してみたい方は、いますぐダウンロードしてください。 そうでない方は、Kibana 4.2の楽しい機能について読んでみてください。\n暗黒面は怖い? そんなことありません。 私たちは常にチャートチャートとダッシュボードを組み立てている組み立てている間は明るいバックグラウンドを使うことを推奨してきましたが、 時々、巨大なスクリーンで暗い部屋で誰も明るい画面から目を背けないようにしたいでしょう。 その影響を小さくするためにダークモードを導入しました。 あなたは、NOCや天文台、その他の暗い場所でKibanaのダッシュボードを楽しむことができます。\n画像あり。 ※画像に関しては原文をご覧ください。\n地図のカスタマイズ Kibanaの地図は素晴らしいですが、もっと多くのオプションが望まれていると聞きました。 もし地図に関して知識があるなら、Kibana 4.2のWMSバックグラウンド地図サポートを試してみてください。 WMSは非常に強力で、US Geological Surveyを含む多くの無料サービスがあります。 http://viewer.nationalmap.gov/example/services/serviceList.html\n画像あり。 ※画像に関しては原文をご覧ください。\nシナリオは? 何かおかしい時、何が起こっているかを正しく知ってもらいたいので、Kibanaがそのタイミングで注目したいコンポーネントがあるなら、 どのように動いているかという概要を知るためのサーバステータスページを作りました。 もちろん、全てがOKであるというのを知りたいだけの場合でも、settingメニューのStatusタブからいつでも呼び出せます。\n画像あり。 ※画像に関しては原文をご覧ください。\n全てにおいて速く ブラウザリフレッシュはKibana 4.2の新しいコードビルディングシステムのおかげで、さらに早くなりました。 また、メモリを覚えてます?Pepperidge FarmKibanaが覚えています。 Kibana 4.2は小さな小さな小さなメモリフットプリントを管理している間、長い長い長い時間実行されているダッシュボードを見ることができるような 大きなメモリのクリーンアップも含んでいます。\nもっとありますが。。。 小さな微調整がいくつもあります。また、今後紹介する本当に刺激的なものの基礎を気づき上げてきました。 これからもElasticのブログ、Twitter、KibanaのGitHubリポジトリに注目し、モンスタートラックアナリティクスの瞬間に立ち会ってください。\n","date":1446103219,"dir":"post/2015/","id":"e159a35d1b9a46e03072a3d54780edcb","lang":"ja","lastmod":1446103219,"permalink":"https://blog.johtani.info/blog/2015/10/29/kibana-4-2-0-ja/","publishdate":"2015-10-29T16:20:19+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Kibana 4.2.0 released Elasticsearch 2.0 + Kibana 4.2 = 💚 Elasticsearch 2.0サポートのKibanaの最初のリリースです。 これ","tags":["elastic","kibana"],"title":"Kibana 4.2.0リリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Logstash 2.0.0 released\nLogstash 2.0.0が本日(10/28)リリースされました。 このリリースは いくつかの設定に関する重要な変更があります。 詳細については、changelogまたは、新しいbreaking changesドキュメントをご覧下さい。\nこれまでの2.0.0直前のリリースに関する変更点はこちらをご覧ください。\nbeta1 beta2 beta3 RC ここでは、2.0の主な変更点の概要を説明します。\nElasticsearch 2.0との互換性 多くの機能および改善を含んだElasticsearch 2.0がリリースされました。 Logstash 2.0はこのリリースに対応しています。 Logstashのこれまでのリリースでは、デフォルトで、Javaの node clientをElasticsearchとの通信として 使用してきました。 2.0では、HTTPクライアントがデフォルトになります。 これにより、シームレスにユーザのデータを取り込み、付加価値をつけ、Elasticsearchに保存して解析することができます。\nHTTPは他のプロトコル(nodeやtransport)同等の機能を持っていますが、 単一のクライアントに接続する時に、少しだけ遅いですが、管理や動作がより簡単です。 HTTPプロトコルを使うことで、Elasticsearchのバージョンのアップグレードが、Logstashのアップグレードすることなく 行うことができます。 デフォルトをHTTPに変更したさらに詳しい情報についてはbeta1のブログをご覧ください。\n他のプロトコル(nodeとtransport)もサポートしますが、これらを利用する場合には、 プラグインを別途インストールする必要があります。\nbin/plugin install --version 2.0.0 logstash-output-elasticsearch_java 互換性のマトリックス LogstashとElasticsearchのバージョンの互換性は次のようになります。\n画像あり。 ※画像に関しては原文をご覧ください。 #Image https://www.elastic.co/assets/bltde5b69e2164aa82f%2Fcompat_matrix.png\nShield 2.0との互換性 このリリースはShield 2.0リリースにも対応しています。 HTTPプロトコルで、追加のプラグインは必要ありません。 こちらのドキュメントをご覧ください。 transportプロトコルでは、Shield 2.0対応のプラグインを個別にインストールする必要があります。\nbin/plugin install --version 2.0.0 logstash-output-elasticsearch_java_shield パフォーマンスの改善 このリリースはまた、多くの部分のパフォーマンスの改善を含んでおり、Logstashを利用してデータをより早く処理することができます。 いくつかをここで説明します。\nUserAgentとGeoIPフィルタ:これらのフィルタで、LRUキャッシュを追加して改善しています。 これにより、IPとユーザエージェントがまとまって現れるというWebリクエストの特性を用いています。 ユーザエージェントフィルタのケースでは、サンプルデータセットにおいて3.7倍ほど早くなりました。 GeoIPでは、1.69倍早くなっています。\nJSONプロセシング:LogstashでJSONのsiriaraizu/でシリアライズに利用しているJrJacksonを新しいバージョンにしました。 これにより、JSONの処理が改善されています。\nフィルタワーカーのより良い値をデフォルトに:以前のリリースでは、filter_workersの設定は1がデフォルトでした。 これは、フィルタの処理を行うワーカーが1つであるという意味です。 filter_workersの設定のデフォルト値はCPUコア数の半分の値を設定します。フィルタ実行の並列性が上がります。 ですので、複雑なgrokパターンやuseragentフィルタの処理がにとっては重要です。\nFilebeat Support Filebeatのベータバージョンを先日リリースしました。 これは、Logstash Forwarderの次期バージョンです。 Filebeatはファイルベースのログをさらに処理するためにLogstashに送るためのエージェントです。 2.0.0はlogstash-input-beatsプラグインを使えばFilebeat 1.0.0-beta4とすぐに動作します。\nシャットダウン操作 これまでのLogstashでは、シャットダウンが開始した時に、例外の機構でシャットダウンが開始したことを プラグインに通知していました。 この処理はサードパーティのコードを使ったプラグインで問題を起こしていました。 Logstashはどの例外を処理するか知らないため、予期しない動作をしていました。 これを修正するためにAPI呼び出し(例えばstop)を各プラグインにシャットダウンのイベントを通知し、 プラグイン自身がきちんと停止するようにしました。 これは、200以上のプラグインに新しいAPIを利用するように修正しないといけないことを意味しました。 しかし、Logstashの停止についてはまだ完全にはフィックスしていません。 とちゅうでおわっているoutputがシャットダウンを遅らせる可能性があるからです。 2.0でAPIの破壊的な変更は適切なリリースでの変更を繰り返すことができる出発点です。\nプラグインの開発者へ:もし、Logstash 1.5のプラグインを開発しているなら、 シャットダウンに関する新しいAPIのリストに関するbreaking changesのドキュメントに助言をください。 また、example inputリポジトリにて、新しいシャットダウンメカニズムの使い方のサンプルコードを提供しています。\nドキュメント 2.0に更新されたドキュメントはこちらです。設定の変更についてもこちらをご覧ください。\n2.0へのアップデート 2.0へアップデートする前に、アップデートガイドもご覧ください。\nフィードバック 2.0のリリースできたことに、多くのコントリビューター、ユーザに感謝しています。 このリリースに含まれている多くのパッチと全てのプレリリースのテストにも感謝しています。 将来の修正やリリースなどについてはロードマップをご覧ください。 2.0は今日リリースされました。 ご意見ご感想はWebフォーラムで!\n","date":1446103197,"dir":"post/2015/","id":"cc64c2fcdecdb505b3797e1aaaa59adc","lang":"ja","lastmod":1446103197,"permalink":"https://blog.johtani.info/blog/2015/10/29/logstash-2-0-0-released-ja/","publishdate":"2015-10-29T16:19:57+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Logstash 2.0.0 released Logstash 2.0.0が本日(10/28)リリースされました。 このリリースは","tags":["elastic","logstash"],"title":"Logstash 2.0.0リリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Relase, we have ※画像に関しては原文をご覧ください。\nElasticにとって大きな1日(社内では「release bonanza」と呼んでいる)です。 多くの主要なプロダクトを新たにリリースしました。 そして、本日、それらを一緒に利用する時にそれらを一緒に利用する時にユーザの体験についてまとめてみました。\n次の通りです。\nElasticsearch 2.0リリース。 大きなマイルストーン、チームによる改善、そして、コミュニティからの素晴らしい貢献。 Pipeline Aggsと呼ばれる新しいタイプのaggregations、 クエリとフィルタのコンセプトを統合することにより簡素化されたクエリDSL、 better compressionオプション、 JavaのSecurity Managerを有効にすることによる強化されたセキュリティ、 FSの挙動に関する強化(fsync、checksum、atmicなリネーム)、 パフォーマンス、マッピングの挙動の一貫性などなどです。 また、我々のチームによる改善も含まれているLucene 5ベースにアップグレードしています。\nKibana 4.2リリース。 Elasticsearch 2.0対応、ダークテーマ、カスタマイズ可能な地図、多くの改善。 Kibana 4.2の多くに作業については外部プラグインサポートといった、内蔵に関するものでした。 この後の説明に続きます。\nMarvel 2.0リリース。 Elasticsearch 2.0対応、合理化されたメトリックス、簡素化されたUI、 多くはKibanaプラグイン(Kibanaプラットフォーム上に構築)としての書き換えです。 このKibana拡張の最初の努力は、Kibanaのプラグインをどうやって書くか、 Kibanaユーザに公式に何をする必要があるかといったものを特定するのに役立ちました。 おっと、忘れるところでした、Marvelを全てのユーザにフリーで使えるようにしました。 マルチクラスタサポートについては有償となります。\nSense 2.0リリース。 2つ目のKibanaプラグインがこれです。 SenseをKibanaプラグインとして書き換えました。 Elasticsearch 2.0サポート、複数リクエストの実行、 curlへのコピーなどです。 おっと、忘れるところでした。オープンソースとすることにしました!\nShield + Watcher 2.0リリース。ElasticsearchのためのセキュリティプラグインであるShieldと、アラート管理のためのプラグインであるWatcherにも 多くの結果が入っています。 最も要求のあった機能である、フィールドお呼びドキュメントレベルでのセキュリティについて、Luceneに落とし込んで実装しました。 また、セキュリティの操作についてプラガブルに実装できるように変更しました。 Watcherは監視の無効化、SlackやHipChatへの通知(bot ops向け)が可能です。\nLogstash 2.0リリース。 Elasticsearch 2.0のサポート、クリーンな停止、全面的なパフォーマンス改善、Beatsサポート。\nご覧の通り、すべてのプロダクトに関する大きな結果です。 チーム間およびFoundの開発者との間での密な連携に感謝します。 これらが私たちが公式にElasticsearch / KibanaをホストしているFoundで 利用可能です。\nひゅう、息切れしました。 チームがしてきたことは、感動的で、謙虚で、刺激的です! Elasticが会社として、全てのユーザ、コントリビュータがどのように私たちの大きなミッションに対する結果をもたらしたかという素晴らしい良い例です。 ユーザに愛され、楽しまれ、成功に導き、革新させる製品を是非ご利用ください。ありがとうございます。\n\u0026ldquo;A Lion, in Africa?\u0026rdquo; - まだまだ終わりではありません。この文言で終わりにしますが、すぐに(本当にすぐに)戻ってきます。;)\n","date":1446095939,"dir":"post/2015/","id":"4cc08ca51ecf0f963035f039de6194c5","lang":"ja","lastmod":1446095939,"permalink":"https://blog.johtani.info/blog/2015/10/29/release-we-have-ja/","publishdate":"2015-10-29T14:18:59+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Relase, we have ※画像に関しては原文をご覧ください。 Elasticにとって大きな1日","tags":["elasticsearch","kibana","logstash"],"title":"Release, we have(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 2.0.0-beta2 released\n本日(9/17)、Lucene 5.2.1ベースのElasticsearch 2.0.0-beta2をリリースしました。 本リリースが2.0.0のRCの前の最後のベータリリースになります。\n注意事項 本リリースはベータリリースであり、テストを目的としたものとなります。 Elasticsearch 2.0.0-beta2はElasticsearch 2.0.0-beta1と互換がありません。 また、Elasticsearch 2.0.0 GAと互換性があるかどうかの保証はありません。\n本番環境には利用しないでください。\nElasticsearch 2.0.0-beta2のダウンロードおよび、すべての変更についてはリンクをごらんください。\n2.0.0-beta1をテストし、問題点を報告していただいた皆様、ありがとうございます。 2.0.0-beta1のあとのElasticsearchのコアの部分の修正のほとんどはバグフィックスになりますが、 geo_shapeフィールドのpoints_only最適化のようなちょっとした改善も含んでいます。\nまた、本リリースでは、商用プラグインの重要な新機能もあります。 こちらについてはShield and Watcher 2.0.0-beta2 releasedをごらんください。 簡単な紹介は次の通りです。\nShieldの新機能 ドキュメントおよびフィールドレベルのセキュリティ Shieldは、クエリを利用したインデックスにあるドキュメントへのアクセスを制御するためのロールを定義できるようになりました。 また、ドキュメントにある特定のフィールドに関するアクセス制限も可能です。 フィルタされたエイリアスのような形ではなく、ドキュメントを検索したり、IDで取得したりする場合にこれらの制限が利用できます。 詳細はField- and Document-level Securityをごらんください\nユーザなりすまし 特定のユーザーに他のユーザーに扮して、彼らのためにリクエストを実行する能力を与えることが、現在できます。 これは、認証がアプリケーションによって実行される場合に便利です。 そして、それは、ユーザの許可レベルを考慮するようにElasticsearchにリクエストします。 詳細はSubmitting Requests for Other Usersをごらんください。\nプラガブルな認証レルム このリリースで、サードパーティの拡張のための認証レルムのインフラを公開しました。 もし、特定の認証要求があり、Shieldがサポートしていない(が、内部の認証管理システムを使いたいような)場合、 これらの要求に見合う新しい認証レルムを利用するプラグインを作成可能です。 詳細はCustom Realmsをごらんください。\nWatcherの新機能 監視の一時 新しく、active / inactive の状態がwatchに追加されました。 これらは、Watchを中断したり、要求に応じて再開させたりできます。 詳しくは、Active Stateをごらんください。\nチャットのための新しいアクション slackとhipchatアクションが追加されました。 これは、Watcherが通知を、SlackやHipchatのユーザに直接送ったり、 チームのチャットルームに送ったりすることが出来るようにします。 詳細については、Slack actionおよび、Hipchat actionをごらんください。\n2.0に関するこれまでのブログ記事 これまでのリリースについての情報はこれらのブログ記事をごらんください。\n\u0008* Elasticsearch 2.0.0.beta1 released\nElasticsearch 2.0.0.beta1 coming soon! The Great Mapping Refactoring Store compression in Lucene and Elasticsearch Better query execution coming to Elasticsearch 2.0 Out of this world aggregations Staying in Control with Moving Averages - Part 1 Staying in Control with Moving Averages - Part 2 The Delete by Query API Is now a plugin Elasticsearch unplugged - Networking changes in 2.0 また、Elasticsearch 2.0.0-beta2のドキュメントや2.0のbreaking changesのリストもごらんください。\nElsticsearch Migration Plugin Elasticsearch Migration Pluginは、既存のインデックスをアップグレードする 必要があるか、他に必要な行動がないかについて、Elasticsearch 2.0.0-beta2を試す前に確認する助けとなります。 Lucene 3のような古いインデックスや、2.0.0にした場合に動作しない問題のある マッピングのような問題を発見できます。\nプラグインの動作に関しては[Elasticsearch Migration repository](Elasticsearch Migration repository)をごらんください。\nテストしましょう! Elasticsearch 2.0.0 GAをすぐにリリースできるようにより多くのベータテスターをお待ちしています。\nぜひ、Elasticsearch 2.0.0-beta2をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)やWebフォーラムなどで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1442565101,"dir":"post/2015/","id":"4b227d61f33182579cd3edd0ac6c7c44","lang":"ja","lastmod":1442565101,"permalink":"https://blog.johtani.info/blog/2015/09/18/elasticsearch-2-0-0-beta2-released-ja/","publishdate":"2015-09-18T17:31:41+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 2.0.0-beta2 released 本日(9/17)、Lucene 5.2.1ベースのElas","tags":["elasticsearch"],"title":"Elasticsearch 2.0.0-beta2リリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch unplugged - Networking changes in 2.0\nElasticsearchをローカルのマシンで起動します。 そして、昨日試したデータを削除するためにDELETE *を実行します。 すると、悲しそうな叫びを同僚が発していることに気づき、なぜそんなことになっているのか不思議に思うでしょう。。。\nElasticsearchはいつも、親しみやすいものでした。 複数ノードのクラスタがどのように機能するのかをテストするには、 ローカルのマシンでいくつかのElasticsearchのインスタンスを起動するだけでした。 起動したインスタンスはマルチキャストを利用して自動的にお互いを見つけて、1つのクラスタになり、負荷を共有し始めます。 しかし、これは親しみやすすぎました。 カンファレンスなどで、ローカルのマシンでElasticsearchを起動してみてください。 すると100ノードのクラスタに参加しているのがすぐにわかるでしょう。\nもうすぐリリースされる、2.0.0-beta1では、Elasticsearchが通信先を選択するネットワークの機能に関する変更があります。 ただし、これまで通り、簡単に開発者が経験できる機能も残っています。\nlocalhostへのバインド 以前、Elasticsearchはデフォルトで、利用可能なネットワークインタフェース全てにバインドしていました。 そこから、一番適したインタフェースをpublish_hostとして選択しようとします。 このアドレスはElasticsearchがクラスタの他のノードとやりとりするためのアドレスです。\nElasticsearch 2.0では、デフォルトでは、localhostにのみバインドします。 127.0.0.1(IPv4)と[::1](IPv6)の両方にバインドしようとします。 また、どちらかのみの環境でも動作します。 この変更は、特に指定がない限り、Elasticsearchがネットワーク上の他のノードと接続しません。 本番環境に移行する場合は、network.hostパラメータを使って設定しましょう。 設定は、elasticsearch.ymlに記述するか、コマンドラインで指定します。\nbin/elasticsearch --network.host 192.168.1.5 bin/elasticsearch --network.host _non_loopback_ network.hostの全てのオプションについては、network settingsのドキュメントをごらんください。\nマルチキャストは廃止 Elasticsearch 1.xはネットワークの他のノードに接続・探索するためにマルチキャストを使用しました。 マルチキャストは魔法のような挙動です。。。 残念ながら、マルチキャストのサポートは良くも悪くもあります。 Linuxはローカルホストでマルチキャストの待ち受けをしていません。 OS/Xは構成されたアドレスの全てのインタフェースにマルチキャストで配信できます。 また、ネットワークによってはマルチキャストはデフォルトでは使用できなくなっています。\nElasticsearch 2.0は異なるアプローチを採用しました。 マルチキャストを廃止します(ただし、新たにプラグインとして提供します)。 代わりに、ローカルホストでは、Elasticsearchはtransport.tcp.portで指定されている範囲(デフォルトは9300-9400)の最初の5ポートに対してユニキャストを使用できるようにします。\nこれは、開発者のための、設定することなく自動的にクラスタを組むという機能を残しています。 しかし、本番に移行するときは、unicast hostsで次のようにリストを指定する必要があります。\ndiscovery.zen.ping.unicast.hosts: [ 192.168.1.2, 192.168.1.3 ] unicast hostsとしてクラスタにあるノードの全てのリストを指定する必要はありません。 少なくとも、マスタノードとして選出されるべきものを指定します。 巨大なクラスタでは、3つの専用のマスタノードを持っており、この3つをunicast hostsとして設定することを推奨しています。\nこれにより、開発の知識・経験が、私たちの推奨する本番でのネットワーク設定に、より近いものとなります。\nノード情報の変更 最後に、inet[/127.0.0.1:9200]といったシンタックスを廃止します。 これは、Elasticsearchがnodes-info APIなどで、使用していたIPアドレスのためのシンタックスです。 今は、RFCに準拠した形で表示します。 127.0.0.1:9200(IPv4)や[::1]:9200(IPv6)のようにです。\n質問がある場合は、ElasticsearchのWebフォーラムで質問してください。ベータはもうすぐです!(翻訳した時点で、すでにベータリリースされています。)\n","date":1440730890,"dir":"post/2015/","id":"0de0edbf2a506143c1739b12e94c0ef9","lang":"ja","lastmod":1440730890,"permalink":"https://blog.johtani.info/blog/2015/08/28/elasticsearch-unplugged-ja/","publishdate":"2015-08-28T12:01:30+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch unplugged - Networking changes in 2.0 Elasticsearchをローカルのマシンで起","tags":["elasticsearch"],"title":"Elasticsearch unplugged - 2.0におけるネットワークの変更(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 2.0.0-beta1 released\n本日(8/26)、Lucene 5.2.1ベースのElasticsearch 2.0.0-beta1をリリースしました。 本リリースは469名のコミッターからの2,500以上ものpull requestを含んでいます。 pull requestのうち、約850が2.0のための新規のものとなります。\n注意事項 本リリースはベータリリースであり、テストを目的としたものとなります。 Elasticsearch 2.0.0-beta1は Elasticsearch 2.0.0 GAと互換性があるかどうかの保証はありません。\n本番環境には利用しないでください。\nElasticsearch 2.0.0-beta1のダウンロードおよび、すべての変更についてはリンクをごらんください。\nElasticsearch 2.0.0-beta1には次の新しい変更が含まれています。\nPipeline Aggregations:これは、他のaggregationsの結果に対するAggregationを実行できます(導関数、移動平均、Holt Winter予測アルゴリズムなども含む) ディスクやファイルシステムキャッシュにより適したより良いデータの圧縮 doc-valuesがデフォルトになったこと、マージ実行時のメモリ使用量の低減、フィルターキャッシュのためのroaring bitsetsなどにより、ヒープの使用率がより効率的に。 構造化された例外 最適化されたクエリ実行順序、フィルタの自動キャッシュ、より高速なクエリに書き換えられたparent-child 設定の代わりに、フィードバックループを使用した自動調整 トランザクションログへの書き込みがデフォルトで、アトミックでかつ冗長に 安全で明確で信頼性のあるタイプマッピング デフォルトでローカルホストでのみクラスタを構成 クラスタ状態の差分によりより高速に変更を伝搬 上記の変更以外にも、多くのElasticsearchおよびLuceneに対する継続的な変更が含まれています。 これらは、Elasticsearch 2.0をより安全に、より簡単に、より良いものにしています。 本リリースに関するより詳しい情報が次のブログにあるので、参考にしてください。\nElasticsearch 2.0.0.beta1 coming soon! The Great Mapping Refactoring Store compression in Lucene and Elasticsearch Better query execution coming to Elasticsearch 2.0 Out of this world aggregations Staying in Control with Moving Averages - Part 1 Staying in Control with Moving Averages - Part 2 The Delete by Query API Is now a plugin Elasticsearch unplugged - Networking changes in 2.0 また、Elasticsearch 2.0.0-beta1のドキュメントも参考になります。 特に、2.0での重大な変更点については必ずごらんください。\nCore plugins コアプラグインの開発の方法を変更しました。 公式にサポートしているプラグインは、現在elasticsearchのリポジトリに含まれています。 これにより、コアと一緒にテストされ、Elasticsearchと同じタイミングでリリースされます。 コアプラグインはElasticsearchと同じバージョン番号隣ます。 インストールは次のようになります。\nsudo bin/plugin install analysis-icu プラグインの新しいドキュメントは私たちのWebサイトのGuideにあります。\nCommercial plugins 私たちの商用プラグインもElasticsearchと同じバージョン番号となり、Elasticsearchと一緒にリリースされます。 ShieldやWatcherはすでに2.0.0-beta1が利用可能です。 インストールのコマンドはは次のようになります。\nsudo bin/plugin install license sudo bin/plugin install shield sudo bin/plugin install watcher MarvelおよびSenseに関する新しい情報もありますが、もう少しお待ちください。\n2.0.0-beta1の商用プラグインに関するドキュメントは次のリンクからごらんください。\nShield 2.0.0-beta1 Watcher 2.0.0-beta1 Elasticsearch Migration plugin Elasticsearch 2.0.0-beta1を試す前に、 既存のインデックスのアップグレードするためになにか行う必要があるかどうかを確認するためのElasticsearch Migration Pluginもリリースしました。 2.0.0では機能しない、問題のあるマッピングなどを見つけるために便利なプラグインです。\nこのプラグインの利用方法についてはElasticsearch Migration repositoryをごらんください。\n既知の問題 同じインデックスの異なるタイプに、同じ名前のipタイプのフィールドを追加した時に、問題があることがわかっています。 この問題は次のリリースでフィックスされます。詳細は#13112をごらんください。\nテストしましょう! Elasticsearch 2.0.0 GAをすぐにリリースできるようにより多くのベータテスターをお待ちしています。\nぜひ、Elasticsearch 2.0.0-beta1をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)やWebフォーラムなどで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1440638952,"dir":"post/2015/","id":"744554499cb7880086fbd9b1f080e7e1","lang":"ja","lastmod":1440638952,"permalink":"https://blog.johtani.info/blog/2015/08/27/elasticsearch-2-0-0-beta1-released-ja/","publishdate":"2015-08-27T10:29:12+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 2.0.0-beta1 released 本日(8/26)、Lucene 5.2.1ベースのElas","tags":["elasticsearch"],"title":"Elasticsearch 2.0.0-beta1リリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:The Delete by Query API Is now a plugin\nElasticsearchの2.0.0-beta1では、これまであった Delete by Query APIが削除され、 新しく Delete by Query pluginに置き換えられています。\nもし、Delete by Query を利用する場合、2.0にアップグレードしたあとは、プラグインをインストールし、ドキュメントに従ってください。\nbin/plugin install delete-by-query なぜプラグインに? ElasticsearchのコアなAPIの品質を保つためであり、以前のDelete by Queryの実装は簡単にはフィックスできない大きな問題がありました。\n各リクエストのあとに、refreshを実行します。これは、削除されたデータが想定外に検索に出てこないようにするためです。\nまた、セグメントが大量にでき、マージが大量に発生し、ヒープが大量に消費されてインデキシングが劇的にスローダウンし、クラスタの複数のノードがクラッシュしてしまう状況も引き起こしました。 このクエリは、プライマリ、レプリカの両方で実行されるため、ことなるドキュメントを削除し、矛盾したレプリカ(データの破損)を引き起こしました。 アップグレードが不安定になります。これは、Delete by Queryリクエストがトランザクションログの中にクエリとして残るためです。そのため、アップグレードのあとに正確にパースされなかったり正確に実行されないかもしれません。例えば、インデックスエイリアスに対するリクエストで、それが削除された後の場合にこのようなバグが発生します。 対照的に、新しいプラグインは、安全な実装です。 scanとscrollリクエストでクエリにマッチしたIDを見つけ、そのIDを使って、bulk indexing APIで削除します。\nこの実装は、遅い必要があります。特に、クエリが多くのドキュメントを削除する場合です。 もし、多くのドキュメントをこのAPIを利用して削除する場合、アプリケーションをテストしてください。 そして、代わりにインデックス全体を消すようなアプローチに切り替えることができないか検討してください。\nDelete by Query pluginのドキュメントに、新しい実装についての違いなどのより詳しい説明があります。\nElasticsearch coreを最小限に プラグインに切り替えることは、簡単な決断ではありませんでした。 多くのユーザは問題なく、Delete by Queryを利用していました。 しかし、危険が常にそこにあり、些細とは言い切れない数のユーザが上記のような深刻な問題に遭遇していました。\nさらに、Elsticsearchのコアは信頼できるものでなければなりません。 他のコアAPIを利用して実装できる機能は、コアに含みません。特に、それがバグを含んでいる場合。 コアのすべての機能は強固であるべきで、Delete by Queryは人気があり、高性能ですが、そうではありませんでした。\n必要に応じて、このような難しいトレードオフの末、信頼性と品質を選びます。\nマッピングの削除の廃止 タイプのマッピングを削除する機能も2.0で廃止されます。 これは、同じフィールド名を、異なるフィールドのタイプで再利用した場合に、インデックスの破損を引き起こす可能性があるためです。\nしかし、Match All Queryで、Delete by Queryプラグインに対してタイプを指定することで、タイプのすべてのドキュメントを削除することはできます。 または、1つのインデックスに異なるタイプを複数含める代わりに、個別のインデックスに分割するようなアプローチに変更することを検討してください。\n","date":1440044644,"dir":"post/2015/","id":"5a9e950f4ac186925e5de978c5f72062","lang":"ja","lastmod":1440044644,"permalink":"https://blog.johtani.info/blog/2015/08/20/core-delete-by-query-is-a-plugin-ja/","publishdate":"2015-08-20T13:24:04+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:The Delete by Query API Is now a plugin Elasticsearchの2.0.0-beta1では、これまで","tags":["elasticsearch"],"title":"Delete by Query APIはプラグインへ(日本語訳)"},{"contents":"第11回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズさん、そして、Shayありがとうございました! 次回もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\n今回は、CTOのShayが来日していたので、英語でいろいろと喋ってもらいました。 4月同様、サムライズムの@yusukeさんに テキスト翻訳していただき、大変助かりました。 今回はQAベースのトークだったのでちょっときつかったですね、申し訳ない。。。\nチェックイン数など チェックインした人:141名 キャンセルしなかった人:51名 でした。 今回はあらかじめ220名(全員が来たらキャパオーバー)としていたので、キャンセル待ちの人は 当日の午後にはいなくなっていた状態です。まぁ、こんなもんかな。結構入りましたね。ありがたいです。\nLT 今回は、少し趣向を変えて、4社の方達にLTをしていただきました。 Shayが来日しているのもあり、事前に英語でスライドを作っていただけると助かりますとお願いさせていただきました。 英語でスライドを作っていただいていたので、伝わりやすくて助かりました、スピーカーの方々ありがとうございました!\n(海外のユーザにもリンクを紹介しやすいので、英語でスライド作ってもらえるといろいろと知ってもらえるのかも。)\nElasticsearch and Recruit Technologies Co., Ltd. / 株式会社リクルートテクノロジーズ 守谷 純之介さん スライド:未定\nN-Gramと形態素のハイブリッドの話などをしていただきました。 @ITで連載もされてますね。ありがとうございます。\nリクルート全社検索基盤のアーキテクチャ、採用技術、開発体制はどうなっているのか (1/2) ElasticsearchとKuromojiを使った形態素解析とN-Gramによる検索の適合率と再現率の向上 (1/3) Shayからは、elasticsearch-hadoopがあるから検討してねと質問(お願い?)がありましたw。\nElasticsearch as a DMP / 株式会社インティメート・マージャー 松田和樹さん @mats116 スライド:Elasticsearch as a DMP\nいくつかのデータソースからAEROSPIKE経由でelasticsearchにデータを登録しているようです。 Data Management Platformのエンジンの一部として、elasticsearchを利用しているようです。\nShayからの質問:「どの機能を使って関心のある単語を抽出していますか?」\n回答:「Significant Term Aggregation」です。\nShay:「おぉ、チェックしてみますw」。\nReal-time social big data analytics using elasticsearch / 株式会社ホットリンク宮田洋毅さん @kakka_jp スライド:未定\nソーシャルメディアのデータを解析するのにelasticsearchにデータを入れて解析。 時間軸での解析やテキストマイニングなんかをしているみたいでした。 いろいろと独自のプラグインを作ってるようです。(興味あるなぁ)\nShayからの質問:「ノード数は?」「30ノードで30シャード」\nElasticsearch in Hatena Bookmark / 株式会社はてな id:skozawa スライド:Elasticsearch in Hatena Bookmark\nはてなブックマークの検索の歴史(MySQL -\u0026gt; Sedue -\u0026gt; Solr -\u0026gt; Elasticsearch) はてなブックマークの検索(ユーザが利用)と社内利用と、ログ解析で利用してる Shayからの質問:「昨年会いましたよね?今はクラスタのサイズはどのくらいのサイズですか?」「メインクラスタは9データノード」\nOpen QA with Shay 思い出せるものだけ。。。(あとで追記します)\nElasticsearch 2.0の話 Pipeline Aggregationとか。 Spark Streaming対応してる? まだ検討中 elasticsearch-hadoopってどんなもの?HDFSにインデックス作ったりするの? いえ、Hadoopの入出力先としてelasticsearchが使える感じ 個人的にAWSのCloudSearchとAWSでElasticsearchはどっちがいい? 時系列データはCloudSearchだと難しいだろうし、AWS上ならfound.noがあるよ! PostgreSQLみたいに信頼性の高いデータストアを目指してる(まだ、プライマリデータストアには使わないで) その他、感想などのブログ Elasticsearch勉強会でLTしてきました | Intimate Merger Engineer Blog 『第11回elasticsearch勉強会』のまとめ #elasticsearchjp \u0008* [Elasticsearch] 第11回 Elasticsearch 勉強会へ参加してきた - 雑文発散(2015-07-28) 第11回 Elasticsearch 勉強会に参加したら英語力に危機感を覚えて最高だった まとめ 今回はShayが来日したので特別バージョンでした。 もっと英語を翻訳するサポートしないとですね、反省してます。。。ぜんぜん流暢じゃないしw\n次回は9月に開催予定ですが、12月にまたShayが再度来日する予定です。 丸1日のイベントを検討中で、Shay以外にも開発者が来日すると思います。 どんな話が聞きたい、どんな人と話をしたいなどあれば、コメントいただければ(対応できるかは。。。)\n勉強会のスピーカーは随時募集中ですので、コメント、メール、ツイートなど、コンタクトしていただければと思います。 よろしくお願いいたします。\n","date":1438321313,"dir":"post/2015/","id":"73b8194ad8fce0cabb01cd21d5e18500","lang":"ja","lastmod":1438321313,"permalink":"https://blog.johtani.info/blog/2015/07/31/11th-elasticsearch-jp/","publishdate":"2015-07-31T14:41:53+09:00","summary":"第11回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズ","tags":["elasticsearch","勉強会"],"title":"第11回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 1.7.1 and 1.6.2 released\n本日(7/29)、Lucene 4.10.4ベースのElasticsearch 1.7.1およびElasticsearch 1.6.2 のバグフィックス版をリリースしました。 これらのリリースは稀ですが、データの欠損が発生する重要なバグのフィックスを含んでいます。 すべてのユーザにアップグレードを推奨します。\nダウンロードおよびすべての変更については次のリンクをごらんください。\n最新安定版:Elasticsearch 1.7.1 1.6系バグフィックス:Elasticsearch 1.6.2 問題のバグ(#12487)は、 同時に複数のノードが故障またはリスタートをした場合の非常にまれな状況で、 シャードのすべてのコピーがクラスタから削除されてしまう状況を発生させます。 このバグは1.5.0から含まれています。\nこのリリースはまた、IPv4アドレスのCIDRマスクのバグのフィックス、 Shieldユーザがmore-like-this APIを利用できないバグのフィックスなど、 いくつかの変更も含んでいます(詳細は更新リストをごらんください)。\nぜひ、Elasticsearch 1.7.1をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1438173353,"dir":"post/2015/","id":"100c0a69bea7f02a0f4540ecaa37d0e3","lang":"ja","lastmod":1438173353,"permalink":"https://blog.johtani.info/blog/2015/07/29/elasticsearch-1-7-1-and-1-6-2-released-ja/","publishdate":"2015-07-29T21:35:53+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 1.7.1 and 1.6.2 released 本日(7/29)、Lucene 4.10.4ベースのE","tags":["elasticsearch"],"title":"Elasticsearch 1.7.1 および 1.6.2リリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 1.7.0 and 1.6.1 released\n本日(7/16)、Lucene 4.10.4ベースのElasticsearch 1.7.0およびElasticsearch 1.6.1 のバグフィックス版をリリースしました。 これらのリリースはセキュリティフィックスを含んでおり、すべてのユーザにアップグレードを推奨します。\nダウンロードおよびすべての変更については次のリンクをごらんください。\n最新安定版:Elasticsearch 1.7.0 1.6系バグフィックス:Elasticsearch 1.6.1 1.7.0が1.x系の最後のリリースとなります。 今後の新機能については、Elasticsearch 2.0以降で取り込まれる予定です。\nElasticsearch 1.7.0は小さなリリースですが、2つの重要なセキュリティフィックスと クラスタの安定化とリカバリに関する2つの重要な機能を含んでいます。\nセキュリティフィックス シャードアロケーションを遅らせる インデックスリカバリの優先度 セキュリティフィックス Elasticsearch 1.6.1 と 1.7.0 は次の2つのセキュリティフィックスを含んでいます。\nリモートコード実行の脆弱性 Elasticsearch 1.6.1より前のバージョンには、transport protocol(ノードとJavaクライアント間での通信に利用)により、 リモートでコードが実行される脆弱性があります。 これは、CVE-2015-3253でのGroovyに関係しています。\nGroovyのダイナミックスクリプティングがオフでも脆弱性があります。 アップグレードをしないユーザは、transport protocol のポート(デフォルトで9300)信頼したエージェントからのみの アクセスに限定することで、脆弱性から保護できます。\nこの問題をCVE-2015-5377としました。\nディレクトリ探索の脆弱性 Elasticsearch 1.0.0から1.6.0までのバージョンで、ElasticsearchのJVMプロセスによって読み込みが可能なファイルを 取得することができるディレクトリ探索攻撃の脆弱性があります。 アップグレードをしないユーザは、信頼できない場所からのSnapshot-Restore APIの呼び出しを防ぐためにファイアウォール、リバースプロキシやShieldを使用することができます。\nこの問題をCVE-2015-5531としました。\nシャードアロケーションを遅らせる Elasticsearch 1.6.0でSynced Flushingが導入されました。 これは、ノードのリスタート時に、更新が止まっているシャードのリカバリを劇的にスピードアップします。 しかし、この変更は、シャードの配置を無効にしている環境でのみうまく実行されます。 ノードが一時的にクラスタから外れている場合や予期せぬリブートの場合には役に立ちません。\nこのシナリオとは次のようなものです。\nノードの想定外のシャットダウン マスタがたのノードにシャードを再配置 各シャードが新しい場所にネットワーク越しにコピー その間に、外れていたノードが再度クラスタにジョイン マスタは新しいノードにシャードを再配置。新しいノードに存在する既存のシャードが全く再利用されない可能性がある ノードレベルとクラスタレベルの両方の並列的なリカバリを抑制しても、 この\u0026quot;シャードシャッフル\u0026quot;がクラスタに対して負荷をかける可能性があります。 これは、外れたノードが再度ジョインするのを単に待つことにより防げるかもしれません。\n待ちましょう! Elasticsearch 1.7.0はindex.unassigned.node_left.delayed_timeout設定を追加しました。デフォルトでは1分です。 これは、ノードがクラスタから外れたとき、ほかのノードにこれらのノードを再配置するまでマスタが1分待つということです。 ノードがこの1分の間に復帰した場合、マスタはローカルにあるシャードを再度配置します。\nなぜ1分? ノードがシャットダウンし、リスタートし、復帰するために十分な時間が1分だからです。 しかし、ノードが復帰しない場合にはまだ再配置が発生することを意味します。 デフォルト値を決定するのは難しいです。 この設定をどのくらいに減らすか、増やすかを決める必要があるかもしれません。\nこのデフォルト値は、config/elasticsearch.ymlファイルに設定できますが、インデックス設定の更新APIを使って設定することも可能です。\nこのデフォルトに関する知見をぜひフィードバックしてください。\nインデックスリカバリの優先度 1.7.0の2つ目の重要な機構はフルクラスタリスタートのような後に、 どの順番でインデックスをリカバリするかという優先度をつけることができるという機能です。\n電源故障による、ロギング用のクラスタのダウンを想像してください。 クラスタが普及した場合、500個のインデックスをリカバリするような場合、499個のインデックスのデータは古く、 500番目のインデックスが重要です。 もっとも最近作成されたインデックスがリカバリされるまで、インデキシングを待つというようなことはできません。\nこれまでは、インデックスはランダムな順序でリカバリされ、重要なインデックスがリカバリされるまで待つしかありませんでした。 1.7.0では、インデックスは優先度の順番でリカバリされます。 この優先度は次のプロパティで指定できます。\nindex.priority設定(大きな値が優先度が高い) インデックス作成日(新しいものが優先度が高い) インデックス名 既存のクラスタについて特に変更せずとも、最も最近作成されたインデックスが古いものよりも復旧されます。 古いインデックスの優先度を上げるためには、index.priority設定に0よりも大きな値を設定します。\nPUT important_index/_settings { \u0026#34;index.priority\u0026#34;: 5 } この設定は、存在するインデックスに対して更新できます。リカバリ中にもです。\nまとめ ぜひ、Elasticsearch 1.7.0をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1437546817,"dir":"post/2015/","id":"809925e891b0456231c374b09cbe4a90","lang":"ja","lastmod":1437546817,"permalink":"https://blog.johtani.info/blog/2015/07/22/elasticsearch-1-7-0-and-1-6-1-released-ja/","publishdate":"2015-07-22T15:33:37+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 1.7.0 and 1.6.1 released 本日(7/16)、Lucene 4.10.4ベースのE","tags":["elasticsearch"],"title":"Elasticsearch 1.7.0 および 1.6.1リリース(日本語訳)"},{"contents":"東京以外での勉強会の第2弾として、関西で勉強会を開催してきました。\nElasticsearch勉強会 in 大阪 Elasticsearch勉強会 in 京都 会場提供をしていただいた、Yahoo!大阪、はてなのみなさん、ご協力ありがとうございました!\nここからはいつものメモです。 ちなみに、大阪の勉強会に、@takuya_aさんと@5kozawaさんの両名にお越しいただき話をしていただきました。 なので、勉強会の内容はほぼ同一になります。\nIntroduction Elastic @johtani スライド:Introduction Elasticsearch\n初めての関西での勉強会ということで、ElasticsearchのOSSおよび商用プラグインの紹介をしてきました。 もちろん、Kibanaのデモもちょっとだけ。スプラトゥーンに関するデータをKibanaでちょっとだけ。 突貫でデータをかき集めたのでもう少し改良しないとですが。\nElasticsearch での類似文書検索と More Like This API 詳解 / 株式会社はてな id:takuya-a スライド:Elasticsearch での類似文書検索と More Like This Query API 詳解\nElasticsearchのMore Like Thisのソースコードリーディングみたいな感じで、 内部でどうやって処理されているかの説明を詳しくしてもらいました。\n前のはてなエンジニアセミナーで話をされていた検索精度の件に絡んだ内容になっているかと。 (大阪で発表してもらった時より京都での発表が分かりやすくなってました。1日で改善されたのすごい!) MoreLikeThisだとチューニングつらいので、自分で作るためにTermVectorAPIでやってみたという流れかと。\n以下は発表後に出てきた質問のいくつかです。\nQ:MoreLikeThisに対してTermVectorで柔軟にできる? A:TermVectorのAPIで統計情報が取れるので、それを使うことでさらなるデータの更新ができる。\nQ:TFとかの統計情報が必要なら、すべてインデックスをしたあとじゃないとちゃんとした値はとれないのでは? A:TermVectorで取得したものをどうやって使うか\nQ:TermVectorAPi\u0026hellip;聞こえなかった A:。。。\nElasticsearchを用いたはてなブックマークのトピック生成 / 株式会社はてな id:skozawa スライド:Elasticsearchを用いたはてなブックマークのトピック生成\nSignificant Terms Aggregationを活用してる話。 トピックページの生成のために、Significant Terms Aggregationをどうやって利用しているかなどのお話でした。\nトピックの集合の重複だったり、精度の判定方法とかいろいろ詳しく説明していただきました。\nQ:2011年と12年で11年の方が多いのは? A:ブックマークの件数に比例\nQ:Significant terms aggsのsizeはいくつをつかってますか? A:20を指定してます。\nQ:Yahooとかニュースをストップワードとしてますが、Yahoo自体のニュースに関してはどーしてるんですか? A:本文とタイトルから別々に作っていて、タイトルからは弾かれますが、本文から作った時に出てきます。\nはてなブックマークにおける Elasticsearch の運用まわりの話 / 株式会社はてな id:hagihala スライド:未定(おそらく公開される)\n体調が回復しきっていない中の発表ありがとうございました。 大幅に修正された資料が出てくるかなと。(ツイートできない数値がちらほらあったので)\nElasticsearchのクラスタの構成、どういった点で困ってたのでどういう調べ方をしたのか、どういった対処をしたのか。 どのあたりが次の課題かなどの話もありました。\n感想・反省点など 大阪、京都ともに30名弱の方の参加をしていただきました。ありがとうございました。 反省点としては、ハッシュタグを告知し忘れてました。。。\n勉強会はやはり、東京が異常に活発で、大阪や京都はまだそれほどでもないのかなぁとも。 大阪はエンジニアの人や会社も多い気がするんですが。私の告知の仕方もあるかもなぁと。 次回があれば、大阪での事例も聞きたいので、スピーカーをもっと探さないとなと。\n関連ブログなど 見つけたら、リンク追加していきます。\nElasticsearch勉強会 in 大阪/京都で発表しました \u0008* 「Elasticsearch での類似文書検索と More Like This Query API 詳解」というタイトルで発表しました その他(余談) 大阪のYahoo!さんは立地条件(梅田のすぐそば)がよく、\n夜景も綺麗でした。大阪城とかも見えてました。(夜景じゃないけど。。。)\n京都は祇園祭の真っ最中。\n水曜日はお休みをいただいて、観光してました。ちょっと日焼けが。。。 おかげで、リフレッシュできました。三十三間堂とか良かった:)\nあまり、関西に縁がない(大阪15年ぶり、京都10年ぶり)ので、 もっとユーザが増えて勉強会の機運が高まると嬉しいなと。:)\n","date":1437010857,"dir":"post/2015/","id":"dd6c32a722dc815273cd9ed8cd6c671b","lang":"ja","lastmod":1437010857,"permalink":"https://blog.johtani.info/blog/2015/07/16/kansai-1st-elasticsearch-jp/","publishdate":"2015-07-16T10:40:57+09:00","summary":"東京以外での勉強会の第2弾として、関西で勉強会を開催してきました。 Elasticsearch勉強会 in 大阪 Elasticsearch勉強会 in 京","tags":["勉強会","elasticsearch"],"title":"大阪と京都でElasticsearch勉強会を開催しました。 #elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:The Great Mapping Refactoring\nElasticsearchのユーザの悩みの最も大きなものの一つは、 タイプとフィールドのマッピングに関する多義性です。 この多義性は、インデックス時の例外やクエリ時の例外、 正しくない結果、リクエストからリクエストへ変化する結果、 また、インデックスの故障やデータのロスを結果として引き起こします。\nElasticsearchをより強固で予測可能な振る舞いをするようにする作業において、 フィールドやタイプのマッピングをより厳格でより信頼性を高くするかといったことに 多くの変更を費やしました。 多くのケースで、Elasticsearch v2.0で新しいインデックスを作るときにのみ、 新しいルールを強制し、これまでのインデックスに関しては後方互換性を保つようにします。\nしかし、幾つかのケースでは、先ほど説明したようなフィールドマッピングの コンフリクトなどが存在するため、それらを利用できないです。\nコンフリクトしたフィールドのマッピングをもつインデックスはElasticsearch v2.0にはアップグレードできません。\nもし、これらのインデックスのデータが必要ない場合は、インデックスを消せばいいです。 そうでない場合はマッピングを正しくして再度インデックスする必要があるでしょう。\nマッピングを正しく変更することは、私たちが簡単に決めることではありません。 ここからは、現在ある問題点と、私たちがどのように実装して解決したかについて説明します。\nフィールドマッピングのコンフリクト あいまいなフィールドのルックアップ タイプのメタフィールド アナライザ設定 index_nameとpath 同期的なマッピングの更新 マッピングの削除 2.0のための準備 フィールドマッピングのコンフリクト これまで、わたしたちはドキュメントのタイプは「データベースのテーブルのようなもの」と説明していました。 タイプの目的を説明する簡単な方法だったからです。 しかし、残念なことにこれは、真実ではありません。 「同じ」インデックスの「異なるタイプ」にある同じ名前のフィールドは、 内部的に、Luceneのフィールド名が同じものになります。\nもしerrorフィールドとして、ドキュメントタイプがapacheのものには数値(integer)を、 ドキュメントタイプがnginxのものには文字列(string)を割り当てた場合、 Elasticsearchは同じLuceneのフィールドに数値と文字列のデータをもつことになります。 このフィールドに対して、検索やaggregationを行う場合、おかしな結果を受け取るか、例外が帰ってくるか、 インデックスが破損することになります。\nこの問題を解決するために、まず、ドキュメントタイプの名前をフィールドの名前の前に追加することを考えました。 各フィールドは完全に別のものとなります。 このアプローチの利点はドキュメントタイプが実際のテーブルのようになることです。\nしかし、この方法には多くの欠点があります。\nフィールドは常に、他のタイプとは異なるものであると区別するためもしくは、複数のタイプに同じフィールドのクエリのためにワイルドカードをつけた場合、 ドキュメントタイプを前につける必要があります。 複数のドキュメントタイプに対して同じフィールド名で検索する場合、クエリを個別に発行しなければならなく遅くなります。 多くの検索で、既存の多くのクエリを壊してしまうために、単純なmatchやtermクエリの代わりに、multi-fieldクエリを使う必要があります。 圧縮の効率の悪さから、ヒープ利用量、ディスク使用量、I/Oなどが、増加します。 複数のドキュメントタイプに対するaggregationは、global ordinalの利点を利用できなくなるために、遅くなり、メモリの使用量も増えます。 解決方法 最終的に、同じインデックスの同じ名前を持つ全てのフィールドは、同じマッピングを持つ必要があるというルールを採用することに決めました。 ただ、copy_toやenabledのようなパラメータはタイプごとに指定することができるようになっています。 これにより、データの破損、クエリ時の例外そして、おかしな結果が発生する問題を防ぎます。 クエリとaggregationは現在でも高速なままで、圧縮率を最大化し、ヒープ使用量やディスク使用率の低減させます。\nこの解決方法の欠点は、個別のテーブルとしてタイプを扱いたいユーザが彼らの考え方を変える必要があるということです。 これは、思ったよりも問題ではありません。 実際には、多くのフィールド名はデータの明確なタイプを表現しています。 created_dateは常に、日付ですし、number_of_hitsフィールドはいつも数値です。 フィールドマッピングがコンフリクトしているユーザはデータを失ったり、おかしなデータを受け取ったり、データを欠損させています。 ベストプラクティスにユーザが従っているかどうかによらず、インデックス時に正しい振る舞いを強制することが現在の違いです。\nユーザの多くがコンフリクトしていないフィールドマッピングをもっていれば、 コンフリクトが起きた場合、技術がこれらのシチュエーションを扱うことが可能になると思いませんか? そこにはいくつかの解決方法があります。\nタイプの代わりにインデックスを別々に 最も簡単な解決方法です。インデックスを別々のインデックスとし、実際のデータベーステーブルのようにします。 インデックスをまたいだ検索はタイプをまたいだ検索のように動作しますし、 ソートやaggregationも同じデータタイプへのクエリのように動作します。これまでと同じ制限です。\nコンフリクトしたフィールドの名前の変更 コンフリクトがごくわずかな場合、(Logstashやアプリケーションで使っているものも一緒に)よりわかりやすいフィールド名に変更することで解決できます。 例えば、2つのerrorフィールドがあった場合に、error_codeとerror_messageに変更します。\ncopy_toもしくはmulti-fieldsを利用 異なるドキュメントタイプのフィールドは別々のcopy_toを設定できます。 元のerrorフィールドはindexの設定にnoが設定してあり、全てのドキュメントタイプで無効化されていますが、 特定のタイプだけ、errorフィールドの値を数値のerror_codeフィールドにコピーすることができます。\nPUT my_index/_mapping/mapping_one { \u0026#34;properties\u0026#34;: { \u0026#34;error\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;no\u0026#34;, \u0026#34;copy_to\u0026#34;: \u0026#34;error_code\u0026#34; }, \u0026#34;error_code\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34; } } } 他のタイプでは文字列のerror_messageにコピーします。\nPUT my_index/_mapping/mapping_two { \u0026#34;properties\u0026#34;: { \u0026#34;error\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;no\u0026#34;, \u0026#34;copy_to\u0026#34;: \u0026#34;error_message\u0026#34; }, \u0026#34;error_message\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } } 同様の解決方法としてmulti-fieldも使えます。\n各データタイプに対してネストしたフィールドに ときどき、Elasticsearchに送ったドキュメントやドキュメントがもっているフィールドを制御できない場合があります。 部分的なコンフリクトに加え、闇雲に、ユーザが送ってきたフィールドを受け入れると、マッピングが肥大化します。 タイムスタンプやIPアドレスをフィールド名に使うようなドキュメントがあると考えてください。\nnested フィールドにすることで、str_val、int_val、date_valというような各データタイプを利用できます。\nこのアプローチによって、次のドキュメントは\n{ \u0026#34;message\u0026#34;: \u0026#34;some string\u0026#34;, \u0026#34;count\u0026#34;: 1, \u0026#34;date\u0026#34;: \u0026#34;2015-06-01\u0026#34; } アプリケーションによって、次のようにフォーマットしなおす必要があります。\n{ \u0026#34;data\u0026#34;: [ {\u0026#34;key\u0026#34;: \u0026#34;message\u0026#34;, \u0026#34;str_val\u0026#34;: \u0026#34;some_string\u0026#34; }, {\u0026#34;key\u0026#34;: \u0026#34;count\u0026#34;, \u0026#34;int_val\u0026#34;: 1 }, {\u0026#34;key\u0026#34;: \u0026#34;date\u0026#34;, \u0026#34;date_val\u0026#34;: \u0026#34;2015-06-01\u0026#34; } ] } この解決方法は、アプリケーションサイドでより多くの作業が必要ですが、コンフリクトの問題とマッピングの肥大化の問題を同時に解決します。\nあいまいなフィールドのルックアップ 現在、フィールドの指定には\u0026quot;short name\u0026quot;、フルパス、ドキュメントタイプを前につけたフルパスが利用できます。 これらのオプションがあいまいさをもたらしています。 サンプルとして次のマッピングをご覧ください。\n{ \u0026#34;mappings\u0026#34;: { \u0026#34;user\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;title\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, \u0026#34;blog\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;title\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;user\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;fields\u0026#34;: { \u0026#34;title\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } } } } } } titleはuser.title、blog.title、blog.user.titleのどれでしょう? user.titleはuser.titleまたはblog.user.titleのどちらでしょう? 答えは「場合によります。」です。Elasticsearchが最初に見つけたものになります。 フィールドはリクエストごとに変わるため、各ノードでマッピングがどのようにシリアライズされたかに依存します。\n2.0では、フィールドを指定する時に、ドキュメントタイプを除いたフルパス名を使用するべきでしょう。\nuser.titleは、blogタイプのuser.titleを意味します。 titleは、userとblogタイプのtitleフィールドを意味します。 *titleはuser.titleとtitleフィールドの両方にマッチします。 userタイプのtitleフィールドとblogタイプのtitleの違いはどのように指定するのでしょう?\n指定できません。フィールドマッピングのコンフリクトで説明した変更により、 titleフィールドは両方のタイプで同じフィールドになります。 本質的にtitleと呼ばれる1つのフィールドになります。\nuser.やblog.のようなタイプのプレフィックスはタイプを指定することによるフィルタリングで効果があります。 クエリのblog.titleフィールドはblogタイプのドキュメントだけを検索し、userタイプのドキュメントを検索しません。 このシンタックスは誤解を招きやすいです。なぜなら、いつでも動作するわけではないからです。 aggregationやsuggestionはすべてのタイプに関する結果を含みます。 この利用のため、上記の例のあいまいさがあるので、タイプのプレフィックスはサポートしません。\n重要 short nameやタイププレフィックスを利用したpercolatorは更新する必要があります。\nタイプのメタフィールド すべてのタイプはメタフィールドを持っています。_id、_index、_routing、_parent、_timestampなどです。 これらのほとんどはindex、store、pathのような幾つかの設定をサポートしています。 これらの設定について次のようにシンプルにしました。\n_idと_typeは変更不可 _indexは、ドキュメントのもつインデックスを保存するためにenabled _routingはrequiredのみを指定 _sizeはenabledのみ _timestampはデフォルトで保存される _boostと_analyzerは廃止。古いインデックスのものは無視される ドキュメントのフィールドから_idと_routingと_timestampの値を抽出することができました。 この機能は廃止されます。これは、ドキュメントのパースとコンフリクトを起こすためです。 代わりに、これらの値はURLもしくはquery stringで指定可能です。\n_boostと_analyzerフィールドは例外で、すでにあるメタフィールドの設定は古いインデックスのものが採用されます。\nアナライザ設定 これまで、indexとsearchのアナライザがインデックス、タイプ、フィールド、ドキュメント(_analyzerフィールドで)の それぞれのレベルで指定可能でした。 同じフィールドに対して異なるanalysis chainの組み合わせができることにより、おかしな関連度を引き起こしていました。 フィールドマッピングのコンフリクトを解消することに加え、アナライザの設定も簡略化します。\nAnalyzedな文字列フィールドは、analyzer設定とsearch_analyzer設定(analyzer設定の値をデフォルトとする)を指定できます。index_analyzer設定はanalyzerとなります。 複数のタイプで同じ名前のフィールドがある場合、フィールドはすべて、同じアナライザの設定を持たなければなりません。 タイプレベルのデフォルト設定のanalyzer、index_analyzer、search_analyzer設定は廃止されます。 デフォルトアナライザはインデックスごとにインデックスのanalysis設定で設定します。これらはdefaultもしくはdefault_searchという名前で設定します。 ドキュメントごとの_analyzerフィールドはサポートしません。既存のインデックスのものは無視されます。 index_nameとpath index_nameとpath設定は(Elasticsearch v1.0.0から利用できる)copy_toによって置き換わりました。 既存のインデックスについてはこれらは機能しますが、新しいインデックスでは指定できません。\n同期的なマッピングの更新 現在、これまで存在していないフィールドを含むドキュメントをインデキシングするとき、 フィールドはローカルのマッピングに追加され、それから、マスターに変更(新しいマッピングをすべてのシャードに適用する更新)が送信されていました。 同時に2つのシャードに同じフィールドを追加することができます。 また、そのとき、異なる2つのマッピングがある可能性があります。 1つはdoubleでもう1つはlongだったり、stringとdateだったりと。\nこのような場合、マスターに最初に届いたマッピングが採用されます。 しかし、「負けた」マッピングをもつシャードでは、すでに異なるデータのタイプを利用しているため、 これを利用し続けます。 そのご、ノードをリスタートしたときに、シャードが別のノードに移動し、マスターにあるマッピングを適用します。 このとき、インデックスが破損したりデータを失ったりします。\nこれを防ぐために、シャードはインデキシングを続ける前に、新しいマッピングがマスターによって採用されるかどうかを待つようになりました。 これはすべてのマッピングが安全に更新されます。 新しいフィールドをもっているドキュメントをインデキシングすると、前よりも処理が遅くなるでしょう。 受け入れられることを待つ必要があるためです。 しかし、クラスタの状態の更新処理のスピードが次の2つの新しい機能によって大きく改善されています。\nクラスタ状態の差分:可能であれば、クラスタの状態の変更はクラスタ状態全体の変更ではなく、部分的なものとする。 シャードへのリクエストの非同期化:シャードアロケーション処理中に、マスタノードは、 割り当てられていないシャードのコピーの日付が最新のものを持っているかを見つけるために、リクエストをデータノードに対して送信します。 ここで、クラスタ状態を変更する呼び出しがブロッキングで行われていました。v1.6.0から、このリクエストはバックグラウンドで非同期で実行されます。 これにより、マッピング更新のようなペンディングタスクをより早く処理できるようになります。 マッピングの削除 (そのタイプのドキュメントがある場合)タイプマッピングを削除できないようにします。 マッピングを削除した後に、削除されたフィールドの情報は、Luceneレベルでは存在し続け、 もし、後から同じ名前のフィールドが追加されたときにインデックスの破損を引き起こします。 そのようなマッピングは残しておくか、新しいインデックスに再インデックスすることができます。\n2.0のための準備 マッピングがコンフリクトしているかどうかを決めることは、手動で行うには慎重に行う必要があります。 私たちは、Elasticsearch Migration Pluginを提供します。 これは、2.0で非推奨になったり廃止された機能を利用しているかどうかを見つけるために役に立つでしょう。\nもし、コンフリクトしたマッピングを持っている場合、 正しいマッピングを持つ新しいインデックスにデータを再インデックスするか、 必要ないなら削除します。 これらのコンフリクトを解決しない限り2.0にはアップグレードできないでしょう。\n","date":1436346691,"dir":"post/2015/","id":"ee4ff9e4e8a1948795e26af2f3f8a30f","lang":"ja","lastmod":1436346691,"permalink":"https://blog.johtani.info/blog/2015/07/08/great-mapping-refactoring-ja/","publishdate":"2015-07-08T18:11:31+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:The Great Mapping Refactoring Elasticsearchのユーザの悩みの最も大きなものの一つは、 タイプと","tags":["elasticsearch"],"title":"Mappingのすばらしいリファクタリング(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 2.0.0.beta1 coming soon!\nElasticsearch 2.0.0.beta1のリリースの準備をしています。 これは、Lucene 5.2.1に含まれる多くの改善が利用できるようになります。 このリリースに関するいくつかの機能は次のようなものです。\nPipeline Aggregations 差分や移動平均、他のAggregationsの結果に対する series arithmeticのようなaggregationが利用可能になります。 この機能は、これまでは、クライアントサイドで実行する必要がありました。 しかし、この計算をより強力な解析クエリを構築してElasticsearchで 実行することができるようになります。 クライアントのコードをより簡潔にすることができます。 これにより、予測解析や異常検知のようなことができるようになります。\nQuery/Filter merging Filterはなくなります。全てのフィルタは、クエリになります。 クエリコンテキストで利用されると、効率的に関連度スコアを計算し、 フィルタコンテキストで利用されると、単に、 マッチしていないドキュメントを除外する(今のフィルタのようなもの)だけです この変更は、クエリ実行が自動的に、より効率的な順番で実行されるように 最適化されることを意味します。 例えば、フレーズやgeoクエリのような遅いクエリは まず、近似フェーズを実行し、それから、より遅い実際のフェーズが 結果に対して行われます。 フィルタコンテキストにおいて、頻繁に利用される条件は自動的にキャッシュされます。\nConfigurable store compression index.codec設定により、高速化のためのLZ4圧縮(default)か インデックスサイズを小さくするためのDEFLATE(best_compression)を 選択できます。これは、ロギングでとくに役に立ちます。 これにより、古いインデックスオプティマイズする前にbest_compressionに 変更できます。\nこれらに関するブログ記事がすぐに公開されるでしょう。\nPerformance and resilience 以降では、新しいメジャーリリースに関して簡単に紹介します。 2.0の変更の多くは内部の機能に関するものであり、 直接ユーザに関連するわけではないからです。\n新しいメジャーバージョンのテーマは、パフォーマンス、安定性、 堅牢性、予測可能性、そして使い勝手の良さです。\n物事が予測した通りに動作する 何か問題があった場合に、Elasticsearchから役立つフィードバックがある ローレベルの設定を扱う必要はなく、Elasticsearchが良い設定を決定する これらに加え、データがより安全に これらの目標は完全ではありません。 まだ、多くの改善があります。しかし、2.xブランチで、 すでに500コミットを超える大きな改善が実施されています。\non-diskの doc valuesをデフォルトで利用(これまではfielddata)。 ヒープ使用量を減らして、スケーラビリティを向上 セグメントマージ処理中のメモリ使用量の削減 normsの圧縮率の改善。ヒープスペースを利用している大きな処理のひとつだったため。 全てのリクエストの後に、transaction logをfsyncすることで、デフォルトで耐久性を向上 全てのファイル変更をアトミックに(部分的なファイルの書き出しはなし) マージを自動で制限 フレーズクエリやスパンクエリを高速化 フィルタキャッシュをより効率化するための圧縮されたビットセット クラスタ状態の差分更新 構造化されたJSON形式の例外 よりきめ細かいLuceneのメモリレポート デフォルトではlocalhostにのみバインド。開発のノードが他のクラスタにジョインするのを防ぐ parent/childのクエリ実行最適化のためにリライト Java Security Managerで必要最小限なパーミッションで実行 全てのコアなプラグインをelasticsearchリポジトリに移行し、Elasticsearchのバージョンに同期してリリースされる予定 アップグレード前に メジャーバージョンのアップグレードは問題のあるものを一掃する機会を与えてくれます。 できる限り、これらの変更をアップグレードするために、簡単な方法を提供しようとしています。 しかし、Elasticsearch 2.0にアップグレードする前に、必要な処理が2つあります。\n1つ目は、フィールドとタイプマッピングに関することです。 mapping APIは、現在、それほど厳密ではありません。 内蔵された保護機構を提供する代わりに、ユーザがベストプラクティスを知っていると信頼していました。 2.0では、mappingはより厳密で安全ですが、いくつかの変更では、後方互換性を保っていません。 詳細についてはThe Great Mapping Recatoringをごらんください。\n2つ目はElasticsearch 0.20以前のユーザに関する変更です。 これは、Lucene 3.xを使っています。 Elasticsearch 2.xはLucene 5をベースにしています。 Lucene 5はLucene 4.xによって作成されたインデックスの読み込みはサポートしていますが、 Lucene 3.xに関してはサポートしていません。\nElasticsearch 0.20以前のバージョンによって生成されたインデックスを持っている場合、 Elasticsearch 2.xのクラスタをスタートすることはできません。 これらの古いインデックスを削除するか、Elaticsearch 1.6.0以上に含まれている upgrade APIを使用してアップグレードする必要があります。\nupgrade APIの実行は2つのジョブを実行します。\n古いLuceneフォーマットのセグメントを最新のフォーマットで書き換えます Elasticsearch 2.xによって読み込めるようという印をインデックスに追加します 全てのセグメントを最新バージョンにアップグレードするのも良い案ですが、 アップグレード前に必要な処理を最小限に抑えることも可能です。 (Lucene 3.xのセグメントだけをアップグレード) その場合は、only_ancient_segmentsパラメータを指定します。\nElasticsearch Migration Plugin Elasticsearch 2.0 に移行する前に、インデックスがアップグレードが必要なのか、 ほかになにかするべきことがあるのかをチェックする助けになる Elasticsearch Migration Pluginをリリースしました。\nまず、プラグインをインストールします\n./bin/plugin -i elastic/elasticsearch-migration プラグインのインストール後はノードのリスタートは必要ありません。\n以下のリンクをブラウザで開きます。\nhttp://localhost:9200/_plugin/migration\n(localhost:9200はインストールしたホスト名に変更してください。)\nMigration pluginに関してバグやご意見がある場合は、GitHubのIssueにお願いします。\n","date":1436250300,"dir":"post/2015/","id":"f887e1aabf801e351bfb39698f208af1","lang":"ja","lastmod":1436250300,"permalink":"https://blog.johtani.info/blog/2015/07/07/elasticsearch-2-dot-0-0-dot-beta1-coming-soon-ja/","publishdate":"2015-07-07T15:25:00+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 2.0.0.beta1 coming soon! Elasticsearch 2.0.0.beta1のリリースの準備をしています。","tags":["elasticsearch"],"title":"Elasticsearch 2.0.0.beta1リリース間近(日本語訳)"},{"contents":"4ヶ月前に、Found joined our team at Elasticをアナウンスしました。 Foundの素晴らしいチームと一緒に仕事をしていますが、彼らによって、より素晴らしい hosted Elasticsearchを提供することになりました。\n私たちがともに密接に働くことにより、本日(2015/7/1)、 新しい2つのFoundを提供することになりました。 Found StandardはこれまでのFoundの機能に加え、さらに低価格を提供します。 Found Premiumは、SLAサポートと、ShieldやWatcherを将来Found上で提供します。\nFound Standard Foundは素晴らしいです。専用のElasticsearchクラスタ、簡単なスケール、 ビルトインのセキュリティそして、時間単位での課金などを持っています。 私たちは、hosted Elasticsearchを探している方に、 Foundが適したソリューションであると思っていますし、 すべての方に利用できて手頃な価格であるということを確信したいと思っています。\n本日(2015/07/01)からFoundの価格をかなり低価格にし、 月額50ドル以下でhosted Elasticsearchを簡単に試してもらえるようにしました。\n価格を下げることは正しい重要なステップですが、 Foundを利用している全ての人に、より良い経験を持っていただきたいと考えています。 低価格化と一緒に、free backupsとbuilt in SSDもFoundで提供を始めることになります。\nFoundの重要な特徴の一つが、高可用性のために、クラスタをいくつのデータセンターに持つかを 選択できることです。 データは重要です。これが正しい選択でユーザの助けになると考えています。 これにより、私たちの価格は、複数のデータセンターにより安価に配置することができます。\nまた、KibanaもElasticsearchのデータを可視化する素晴らしい方法だと考えています。 Kibana 4が最新バージョンですが、 これは、サーバサイドコンポーネントを持っています。 これは、サービスとしてこれを提供するために、追加の料金がかかることを意味します。 Foundチームが築いた素晴らしい基盤とKibanaチームの努力により、 hosted Elasticsearchクラスタで無料のKibana 4を7月15日より提供することになりました。\nFound Premium また、私たちは、オープンソースプロダクトに関してサブスクリプションを提供していますが、 Found Standardに対しても提供することになりました。 これが、Found Premiumです。\nフォーラムベースのサポートよりもSLAベースのサポートを望んでいる場合、 プロダクトを開発しているチームからのサポートを受けることができるオプションを 提供し始めました。 クリティカルなイベントを持っていたり、私たちのプロダクトに関する 問題を予測するためのベストなヘルプやガイダンス、アドバイスを探しているような場合にサポートします。\nさらに近い将来、サブスクリプションの一部として、Shield(Elasticasearchのセキュリティプラグイン)やWatcher(アラーティングプラグイン)が利用できるようになります。\n私たちのチームがともに働き、多くのことを可能にし、すばらしい仕事をユーザに提供したかを 将来も楽しみです。 私は非常に誇りに思っていますし、気に入っていただけたらと思っています。 ぜひ、7/15のWebnarに参加してくわしい話を聞いていただき、疑問を解消してください。\n","date":1436250000,"dir":"post/2015/","id":"9cc2a0b6c8be1405cddcdeb4487c59fe","lang":"ja","lastmod":1436250000,"permalink":"https://blog.johtani.info/blog/2015/07/07/we-just-made-found-more-awesome-ja/","publishdate":"2015-07-07T15:20:00+09:00","summary":"4ヶ月前に、Found joined our team at Elasticをアナウンスしました。 Foundの素晴らしいチームと一緒に仕事をしていますが、彼らによって、より","tags":["elasticsearch","found.no"],"title":"さらに進化したFound(日本語訳)"},{"contents":"JustTechTalk#02 形態素解析のあれやこれや@ジャストシステム\nに参加してきました。 ジャストシステムさんの形態素解析器JMATの話とKagome、Janome、Kuromoji.js、ssslaの開発者の パネルディスカッションでした。\nということで、いつものメモです。\nジャストシステムの形態素解析その2(機械学習編) JMATの話\n前回は辞書の話 今回は学習の話 教師あり/教師なし\nJMATは教師あり 教師なしは研究段階 ラティス構造を辞書ベースで構築して、コストの総和が最小の経路を求める\n連接、単語生成とか。 学習は3フェーズ\nベース、能動、部分アノテーション ベース 300万文のコーパスから1万文のみを利用(なぜ?今から説明) 64GBマシン買ってみたけど、複数実験するには追いつかない オンライン学習がメジャーでない時代に作り始めたので、つかってない CRF学習器を改善 結果として50万文くらいで精度が良くなる 辞書チームからNGがでて、方向転換 方向転換した結果が3つのフェーズらしい ピタジョブに採用? 疑問 \u0008* JMATって、Webの検索の前処理とか分類とかに主に利用するのかな?\nATOKでもこのノウハウって利用してるんかな? 辞書もあるらしいけど、辞書更新されると学習器のデータとかどーなるんだろ? 形態素解析器の実装言語Talkについて kuromoji.jsの@takuya_aさん\nTyped Arrayサポートが高速にできてる理由でもあるらしい Kagomeの@ikawahaさん\nGoはいろいろないらしい Janomeの@moco_betaさん\nsssla(茶筌のRuby clone)\nなんで作ったの?\n形態素解析のライブラリ「解析部分」はNLPのHelloWorldだから なんで、その言語?\nPython 3系は文字列とバイト配列の扱いがすごく楽! その言語で困った点は?\nGoだと、辞書を内包するのが大変 JSは苦労したところしかない(1hくらいしゃべれるぞ!)。基本的なデータ構造とかもない Pythonはパフォーマンスを考えないと Ruby(1.6だったので)もパフォーマンスが その言語を開発するときに必須のものは?\nGoはとくにない。エディタはどれでもOK browserifyが便利 \u0008* ほかの人たちの言語をdisってください * JSは論外。Pythonのコードフォーマッターが揺れるのが。。。Rubyはバージョンが。。。 * Goはブラウザで動かない。Pythonもブラウザで動かない。Rubyも(ry * ほかのは触ったことないので。。。 * Pythonは2.xか3.xか決めてくれ!\nなんで、Kuromojiベースなの? Java読みやすいから。 MeCabとKuromojiの違いは? 未知語の処理が結構違う 感想 きれいなロビーで良かったのですが、マイクがあると嬉しかったかもしれません。 前回の辞書の話も聞いてみたかったかも。\n","date":1436147341,"dir":"post/2015/","id":"18b7998a871950ebc36c415a53630477","lang":"ja","lastmod":1436147341,"permalink":"https://blog.johtani.info/blog/2015/07/06/attend-justsystem-techtalk-no2/","publishdate":"2015-07-06T10:49:01+09:00","summary":"JustTechTalk#02 形態素解析のあれやこれや@ジャストシステム に参加してきました。 ジャストシステムさんの形態素解析器JMATの話とKagome、Janome、","tags":["勉強会"],"title":"JustTechTalk#02 形態素解析のあれやこれや@ジャストシステムに参加しました。"},{"contents":"ひさびさに、勉強会メモ。 Hatena Engineer Seminar #5 @ Tokyoに当選したので行ってきました。\nいつもは近寄らないオシャレな街をドキドキしながら行ってきました。\nということで、簡単なメモです。\nはてなブックマーク全文検索の精度改善 id:takuya-a 問題:検索精度がよくない 京都で検索 → 「ポーランドの京都」「京都大学のまるまる教授」のようなもんがヒット 京都っぽいエントリが出て欲しい。 京都っぽい??? 問題点をブレイクダウン 課題 クエリ考えるの大変だよね 順序が新着順なのが辛い 適合率と再現率の両立 そして(ドラムロール)、できました!(さすが)\nアイデア:はてブのタグを利用する。 関連キーワードを抽出して、クエリ拡張する。\n関連キーワードとは? タグ検索する 検索にヒットしたTerm Vectorsを取得 特徴語をTop25件取得 もっともスコアが高いタームを特徴語とする 英語のストップワードとかが問題点となってたり。 →Dynamic stop word listというのを利用して排除(IDF、RIDF、Gain) 今後の課題 再現率の向上 解析用のフィールド・辞書を追加(精度向上や解析ミスなど) トークに出てきた機能など トークに出てきたElasticsearchの機能については、こんなツイートをしてたので、参考にしてもらえれば。\nこれのkuromoji_stemmerを使ってるっぽい? #hatenatech / elastic/elasticsearch-analysis-kuromoji - https://t.co/3F2sBYXLPH\n\u0026mdash; Jun Ohtani (@johtani) 2015, 6月 16 #hatenatech Term Vectors APIのドキュメントはこちら - https://t.co/HhBmTDr46i\n\u0026mdash; Jun Ohtani (@johtani) 2015, 6月 16 #hatenatech min_score - https://t.co/Sc0exzJRC1\n\u0026mdash; Jun Ohtani (@johtani) 2015, 6月 16 個人的な疑問 Q:クエリにヒットするタグがそもそもなかったら?\nはてなブックマークに基づく関連記事レコメンドエンジンの開発 id:skozawa 課題:一部のエントリに対して関連記事が出ない タグがない記事について関連エントリが出ない=既存はタグを利用している 例:レシピで考える\n現行システム ユーザがつけたタグ情報を利用してMoreLikeThisで計算 新規システム 類似記事検索 特徴語の抽出 特徴語を分類 関連記事検索 関連記事をスコアリング 個人的な疑問 Q:毎回計算してるのかな?記事登録とかされたタイミングでやってるのかな? Q:Termの精度などどうなんだろ?\n『BrandSafe はてな』のアドベリフィケーションのしくみ id:tarao BrandSafeはてな:とか。 広告の配信先をフィルタリング\n複数の素朴なフィルタの組み合わせ→AdaBoost\n個人的な疑問 Q:海外とかもいけるのかな?\nまとめと感想 ということで、簡単なメモでした。ピザごちそうさまでした! 聞いてて少し思ったのは、データ量があるサイトだからうまくいく手法だというのもあるんだろうなというところでした。 あとは、クエリを暗に改善するのとは別に、サジェスト的に表示するのにも使えたりするかも?と思ってみたり。 できるかどうかはわからないですが。。。\nElasticsearchをいろいろと活用してもらってるのがわかって、楽しい勉強会でした。 もっともっといろんなところで宣伝してくださいw\n今日の勉強会を聞いて、俄然、京都・大阪でElasticsearch勉強会を開催したい気になってきました。 特に大阪に知り合いがいないので、だれか紹介してもらえると嬉しいです。 お待ちしてます。\n","date":1434468093,"dir":"post/2015/","id":"ddab6357ff522c0c956ebd7669e83454","lang":"ja","lastmod":1434468093,"permalink":"https://blog.johtani.info/blog/2015/06/17/attend-hatena-engineer-seminar-5/","publishdate":"2015-06-17T00:21:33+09:00","summary":"ひさびさに、勉強会メモ。 Hatena Engineer Seminar #5 @ Tokyoに当選したので行ってきました。 いつもは近寄らないオシャレな街をドキドキしながら行ってきました。 と","tags":["勉強会"],"title":"Hatena Engineer Seminar #5 @ Tokyoに参加しました。 #hatenatech"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 1.6.0 released\n本日(6/9)、Lucene 4.10.4ベースのElasticsearch 1.6.0をリリースしました。 このリリースはElasticsearchの最新の安定バージョンとなります。 また、素晴らしい新機能がいくつか追加されています。\nsynced flushによるリスタートの高速化 \u0008* シャード配置は保留中のタスクをブロックしない レスポンスボディのJSONのフィルタリング 共有ファイルシステムリポジトリに対するセキュリティフィックス 古いインデックスのためのUpgrade API Kibanaユーザのためのハイライトの強化 Windowsユーザのためのmlockall より詳細なスクリプト設定 すべての変更リストとダウンロードはこちらをごらんください。\nsynced flushによるリスタートの高速化 1.6.0より前のバージョンでは、メンテナンスやローリングアップグレード時の ノードの再起動で、必要であるかどうかに関わらず、多くの場合、 ノードのすべてのシャードのすべてのデータを再度コピーする必要がありました。 この新しいsynced flush機能により、 sync-flushされたインデックスに対して、既存のデータを再利用し、 より早くクラスタを正常な状態にすることができるようにします。\nここで、この変更以前にどのように動いていたかを説明します。 すでにあるレプリカシャードは、ノードがリスタートした後に、 プライマリから復元するときに、 最初のステップはプライマリにあるセグメントとレプリカにあるセグメントを 比較することです。そして、セグメントに違いがあった場合にコピーされます。 問題は、セグメントプライマリのセグメントのマージと レプリカのセグメントのマージが別々に起こっており、 各シャードのセグメントが完全に異なるが、 それらが同じデータを持っているという点です。\n新しいsynced-flush機能では、sync_idがプライマリと レプリカシャードに、シャードのコンテンツが同一であるという判別するために、 書き込まれます。これは、リカバリがセグメントの比較のステップを スキップできることを意味します。 リカバリのスピードを高速にします。\nsynced flushはアイドル状態のインデックスで自動的に実行されます。 直前の5分間でデータが登録、更新削除されていないインデックスに対してです。 これは、ロギングのユースケースで特に役に立ちます。 機能のインデックスはインデキシングがストップしたあとの5分で自動的に syncされるでしょう。\nノードのリスタートやクラスタのリスタートが必要で、 自動的に発生するsyncを待てない場合は次のようなことが可能です。\nインデキシングを停止(実行中のリクエストが停止するのも待つ) シャードのアロケーションを停止 synced-flushリクエストの発行 ノードのリスタート シャードのアロケーションの再開 クラスタの状態がグリーンになるまで待つ インデキシングの再開 NOTE: \u0026ldquo;シャードのアロケーションを停止\u0026quot;のステップが必要です。 これがない場合、Elasticsearchはノードの再起動が始まると、 異なるノードにシャードの再配置を始めます。 これは、新しいノードにシャードデータの全てをコピーする必要があります。\nドキュメントのインデキシング、更新、削除のあとに最初のフラッシュが 発生したときに、 シャードのsync_idが自動的に無効化されます。 詳細については#11336と#11179をごらんください。\nシャード配置は保留中のタスクをブロックしない 多数のノードやインデックスを持っているユーザは クラスタ全体のリスタートのあとのシャードのリカバリで、 長い間、リカバリが止まって見えることに気づいたかもしれません。 これらのリカバリが止まって見える間は、クラスタ設定の更新のような軽微なアクションでさえ、 例外が発生したり、その設定が反映されるまでに長時間かかるといったことが起きていました。 この問題の兆候は保留中のタスクのキューが大きくなることです。\nこれらの遅延の原因はシャードの配置のプロセスにあります。 配置されるべきシャードのコピーを 持っているのがどのノードかを全てのデータノードに聞きます。 多くのシャードや遅いディスクを持ったデータノードは 反応するのに時間がかかります。 特に、シャードのリカバリがすでにI/Oを利用しているような時です。 このバージョン以前のものは、シャード情報のためのリクエストを 同期的に処理していました。 クラスタ状態の更新はアロケーションプロセスを続けるために 必要な情報を待っている間、ブロックされます。\n#11262での変更は この情報のためのリクエストを非同期にします。 クラスタ状態の更新はこのタスクによってブロックされません。 これは、保留中のタスクがより早く処理でき、 クラスタが変更に対してより早く反応できます。 処理中のshard infoリクエストの数は number_of_in_flight_fetchキーとしてcluster-health APIで取得できます。\nさらに、シャードがある理由で復旧に失敗すると、 クラスタは、シャードのリカバリが成功するまで、同じノードに対して シャードをアロケーションしないようにします。\nレスポンスボディのJSONのフィルタリング Elasticsearchは全ての情報を返します。 例えば、検索リクエストは_index、_type、_id、 _score、_sourceを返します。 しかし、全ての情報が必要でない場合があります。 また、これらのデータを遅いネットワークで転送することは 遅延の原因となります。\nユーザはこの検索メタデータを無効にするための特殊な設定を 行ったり、他のAPIのレスポンスのフォーマットを コントロールするための設定があります。 #10980の変更で、任意のレスポンスボディのJSONに対して、 必要な要素だけを取得する機能が追加されました。 filter_pathパラメータを使用します。\n例えば、検索リクエストからはtotal数と、各要素のhitsの配列を欲しい場合、 次のように指定します。\nGET _search?filter_path=hits.total,hits.hits nodes-info APIから各ノードのhttp_addressだけを取得したい場合は、 ノード名の部分にワイルドカード(*)を使用します。\nGET _nodes?filter_path=nodes.*.http_address 単一の*がJSON階層の1つの階層に対しての ワイルドカードとして機能します。 2つの**は複数階層に対してとなります。 複数のフィルタはカンマ区切りで指定可能です。 詳細についてResponse filteringをごらんください。\n共有ファイルシステムリポジトリに対するセキュリティフィックス 本リリースはsnapshot-restoreで使われる 共有ファイルシステムリポジトリに関するセキュリティ強化の変更が含まれます。 現在、Elasticsearchのユーザは、Elasticsearchプロセスによって書き込み可能 任意のディレクトリに.snapshotファイルを書き込むことができます。 #11284の変更で、リポジトリのために使用できるディレクトリを 強制的に指定できるようになりました。 適切なディレクトリがconfig/elasticsearch.yml設定ファイルの path.repoに指定される必要があります。\n次のように設定されたElasticsearchインスタンスはこのセキュリティ問題に対して影響を受けにくいです。\nrootではなくelasticsearchユーザとしてElasticsearchを実行 elasticsearchユーザがdataディレクトリに対してのみ 書き込み権限を持っていて、共有ファイルシステムリポジトリに対しても利用できる ファイアウォールやプロキシ、Shieldを使って、snapshot APIの実行を任意のユーザから実行されるのを防いでいる この問題をCVE-2015-4165としています。\n古いインデックスのためのUpgrade API Elasticsearch 2.0以降では、 Lucene 5ベースとなり、Lucene 3 (Elasticsearchのバージョンでは0.90以前) によって書き出されたセグメントを含んだインデックスを読み込むことが できなくなります。 これらの「古いインデックス」はLucene 4にアップグレードする必要があり、 2.0-compatibleとして印をつける必要があります。 そうしなければ、Elasticsearch 2.0に以降できないでしょう。\nupgrade APIは 、最新のLuceneフォーマットにインデックスにある全てのセグメントを アップグレードするためにすでに利用できます。 また、最新のフォーマットは性能向上やバグフィックスといった利点もあります。 さらに、2.0-compatibleとして古いインデックスをマークする設定も 書き込むことができます。 さらに、upgrade_only_ancient_segmentsオプションが Lucene 3のセグメントだけをアップグレードするために利用でき、 移行前の必要な処理を減らすことができます。\nKibanaユーザのためのハイライトの強化 KibanaユーザはElasticsearchのハイライトについて2つの点で問題を見つけていました。\nワイルドカードでフィールド名を指定した場合に、ハイライトに適さないフィールドも帰ってくる(日付や数値のフィールドなど) 古いインデックスが非常に大きなターム(\u0026gt; 32kB)を含んでいて、ハイライトが失敗する。 最近のバージョンでは、これらの大きなタームはインデックス時に除去される #11364の変更で これらの問題が修正されました。 ワイルドカードを利用したフィールド名では、stringフィールドのみを返し、非常に長いタームによる例外は無視するようになります。\nWindowsユーザのためのmlockall 速いGCはノードの安定性と性能について重要です。 小さなバイトのヒープでさえ、ディスクにスワップすることを許可してしまうと、GCに対して大きな影響が出てしまいます。 ですので、これらのコストは排除されるべきです。\nLinuxユーザはbootstrap.mloclall設定による恩恵を受けています。 これは、RAMにJVMのヒープを起動時にロックします。 #10887では、同様の機能をWindowsユーザにも提供します。\nより詳細なスクリプト設定 Scriptsはリクエストにインラインで指定できます。 .scriptsインデックスにインデックスもでき、config/ディレクトリ配下にファイルとして保存もできます。 これまでは、インラインかインデックスされたスクリプトの両方を同時に有効無効にすることが選択できましたが、 .scriptsインデックスをプロキシやShieldで保護することもできました。\n#10116で追加されたより詳細なスクリプトの設定で、インラインか、インデックスされたものか、ファイル化を個別に言語ごとに設定できるようになりました。 また、例えば、search APIではスクリプトを許可するが、update APIでは許可しないといったような設定も可能です。\n最後に ぜひ、Elasticsearch 1.6.0を試してみてください。 そして、感想をTwitter(@elastic)やWebフォーラムなどで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1433910662,"dir":"post/2015/","id":"55188a318c5998989255253e15ccc1f6","lang":"ja","lastmod":1433910662,"permalink":"https://blog.johtani.info/blog/2015/06/10/elasticsearch-1-6-0-released-ja/","publishdate":"2015-06-10T13:31:02+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 1.6.0 released 本日(6/9)、Lucene 4.10.4ベースのElas","tags":["elasticsearch"],"title":"Elasticsearch 1.6.0リリース(日本語訳)"},{"contents":"第10回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 次回もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\n今回も新規の方が結構いたような気がしました。 最終的に、124人がアプリでチェックインした形になりました。 直前にキャンセル待ちから繰り上がると来れない人がいますよねぇ。 多少キャパシティオーバーするくらいの人数で募集するのがいいのでしょうか。 あと、カードが2枚不明で。。。心あたりある人いないでしょうか?\nさて、いつもの通り簡単なメモです。\nElastic{ON}報告+有償プラグインの紹介 Elastic Jun Ohtani @johtani スライド:elastic{ON}報告と商用プラグインの紹介\n少し時間が経ってしまいましたが、弊社初のカンファレンスelastic{ON}の紹介をしました。 約1300名の方に参加していただいたカンファレンスで、非常に盛り上がりました。 Microsoft、GitHubなど、いろいろな会社の方が話をしたり、弊社のエンジニアが濃い話をしたりと。 今回は、日本の方はいなかったですが、次回は日本からも参加してもらえると嬉しいです!\nあとは、5月に弊社にも日本の営業の人が入社したので、有償プラグインについて簡単ですが説明をしました。 プラグインなどに興味があるかたがいらっしゃいましたら、Twitterなどで連絡いただければと。 もちろん、弊社サイトからの問い合わせでも大丈夫です。\nカンファレンスの資料やビデオが弊社サイトで公開されています。 ぜひ一度見ていただければと。\nAWSで実現するelasticsearchの大規模運用 株式会社インティメート・マージャー 松田和樹さん @mats116 スライド:第10回elasticsearch勉強会 公開用資料\nパブリックDMPのサービスの裏側でElasticsearchを利用しているというお話でした。 AWS Auto Scalingに詳しくないので、勉強しないといけないんですが、 リバランスがどのくらいの頻度で発生するのかはちょっと気になります。\nSSDを利用したり、doc valuesを利用したりと、性能を気にしながら利用されている点、負荷試験を行って検証されていたりと、 参考になる話でした。 今回はインフラ側の話に寄っていたので、今度はアプリ側でどんな使い方をしているかといった話を聞いてみたいですね!\nSpark in small or middle scale data processing with Elasticsearch 株式会社ビズリーチ 島本 多可子さん @chibochibo03 スライド:Spark in small or middle scale data processing with Elasticsearch\nScalaとSparkとElasticsearchで検索サービスを作っている話でした。 サービスのアーキテクチャの選別についての説明を順を追って説明していただきました。 失敗と言われていたアーキテクチャを見た時に、「あー、それは。。。」と思っていたら、 思った通りの改善案のアーキテクチャが出てきたので少しホッとしましたw\nJSONのクエリが辛いという話がありましたが、validate APIなどを利用してもらって、事前にチェックをしてもらうと 少しは改善できるかもなぁと。\nSparkをぼんやりとしかわかってないので、もう一度話を聴きたいなぁと思ったので、 押しかけて話を聴きたいと思います。\n話の中で出てきた自作のScalaのElasticsearchクライアントがHTTPのクライアントになった理由が知りたかったです。\nLT Elasticsearchのサジェスト機能を使った話 株式会社アイスタイル 渡邊 紘太朗さん @ktaro_w スライド:Elasticsearchのサジェスト機能を使った話\nぴったり5分でしたwまだ2年目なのにこんなにうまく話をしていただけるとは。。。\nGatling便利そうですね。サーバが1台しかないので、単一インデックスの方が性能が出るだろうなと。 Elasticsearchは1インデックスに対してデフォルトだと5シャードで、シャード単位でLuceneのインデックスが作成されます。 この話で行くと、18インデックスを作ると、かなりの数のファイルI/Oが発生するので、いろいろなインデックスに検索をすると キツいだろうなと。\nサジェストについての日本語の資料が少ないという事だったので、ブログを書いてもらえると嬉しいですw\nElasticsearchで作る形態素解析サーバ 株式会社エヌツーエスエム 菅谷信介さん スライド:Elasticsearchで作る形態素解析サーバ\nいつも発表ありがとうございます。私以外の最多発表者じゃないかという話でした。 今回はElasticsearchを形態素解析サーバにしてしまおうという話で、ちょっと面白い話でした。 Elasticsearch以外の場所で形態素解析したい場合には手軽に使えるかもしれないですし、Elasticsearchと同じ解析結果を別の場所で欲しい場合にも便利かも。\nextended analyze APIの紹介までしていただいて。。。\nちなみに、今は、extended analyze プラグインも指定したAttributeの情報だけ返せるようになってたり、 マルチバリューへの対応もしていたりします。 そのうち本家のanalyze APIに機能を取り込む予定です。(早くしないと)\n開発効率UP! Elasticsearch Client Tool 作ってみた ナレッジワークス株式会社 木戸国彦さん @9215 スライド:開発効率アップ!Elasticsearch Client Tool 作ってみた\nHello Elasticsearch!にはお世話になっている人が多いんじゃないかなと。 今回はSublime Textのプラグインのお話でした。(すみません、Sublime Text使ってなくて。。。) AtomとかIntellijのプラグインもあるとうれしいなー\n変わり種プラグインの作り方 日本IBM 黒澤亮二さん スライド:変わり種プラグインの作り方\nElasticsearchの拡張ポイントの話と、簡単なプラグインの作り方と少しElasticsearch内部の話をしていただきました。 Foundの資料が上がってました。さすが。あそこのブログは面白い話が多いんですよね。 社内で実際に使われてる話とかも聞いてみたい!\nその他、感想などのブログ 第10回 Elasticsearch 勉強会へ参加してきた昨日の話 第10回elasticsearch勉強会 #elasticsearch #elasticsearchjp 第10回elasticsearch勉強会に行ってきました elasticsearch勉強会に登壇してきました まとめ 懇親会で24Fに移動していただくということで、少し手間をかけてしまいました、すみませんでした。 今回も初参加の方がそこそこいたんじゃないかなと。 あとは、AWSサミットがあるために上京してて参加しましたという方もいらっしゃいました。 大きなカンファレンスの期間の前後に行うとこんなメリットもあるんですね、今後の参考にしたいと思います。 次回は7/27を予定しています。CTOのShayが来日予定です!\nあと、東京以外の勉強会も検討しつつあります。興味のある方はコメントやTwitterで反応をいただけると嬉しいです。\nスピーカーは随時募集中ですので、コメント、メール、ツイートなど、コンタクトしていただければと思います。 よろしくお願いいたします。\n","date":1433225196,"dir":"post/2015/","id":"75d9268739fe7787ac02d389ac605feb","lang":"ja","lastmod":1433225196,"permalink":"https://blog.johtani.info/blog/2015/06/02/10th-elasticsearch-jp/","publishdate":"2015-06-02T15:06:36+09:00","summary":"第10回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさ","tags":["elasticsearch","勉強会"],"title":"第10回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Reindex Elasticsearch With Logstash\nThanks David!\nマッピングを変更したり、インデックスの設定を変更したり、あるサーバから他のサーバや、 あるクラスタから他のクラスタ(例えば複数のデータセンターのような場合)にデータを再インデックスしたくなることがあるでしょう。\n後者のような場合はSnapshotやRestoreの機能を利用することもできますが、インデックスの設定を変更をしたい場合は その他の方法が必要になります。\nLogstash 1.5.0で、 elasticsearch inputとelasticsearch outputを使うことで、とても簡単に再インデックスができます。\nではやってみましょう。\n古いクラスタ elasticsearch 1.5.2 はすでにダウンロード済みとして、localhost:9200でoldという名前のクラスタを起動します。\nbin/elasticsearch --cluster.name=old クラスタにpersonという名前のインデックスが存在します。 これは、5シャードで、100万件のドキュメントを持っています。\n新しいクラスタ 次に新しいクラスタを起動します。 localhost:9201でnewという名前のクラスタを起動します。\nbin/elasticsearch --cluster.name=new こちらは、空です。\ncurl -XGET \u0026#34;http://localhost:9201/person\u0026#34; { \u0026#34;error\u0026#34;: \u0026#34;IndexMissingException[[person] missing]\u0026#34;, \u0026#34;status\u0026#34;: 404 } Logstashのインストール 次に、Logstash 1.5.0をダウンロードして、インストールします。\nwget http://download.elastic.co/logstash/logstash/logstash-1.5.0.tar.gz tar xzf logstash-1.5.0.tar.gz cd logstash-1.5.0 logstashの設定ファイルlogstash.confを次のように設定します。\ninput { # We read from the \u0026#34;old\u0026#34; cluster elasticsearch { hosts =\u0026gt; [ \u0026#34;localhost\u0026#34; ] port =\u0026gt; \u0026#34;9200\u0026#34; index =\u0026gt; \u0026#34;person\u0026#34; size =\u0026gt; 500 scroll =\u0026gt; \u0026#34;5m\u0026#34; docinfo =\u0026gt; true } } output { # We write to the \u0026#34;new\u0026#34; cluster elasticsearch { host =\u0026gt; \u0026#34;localhost\u0026#34; port =\u0026gt; \u0026#34;9201\u0026#34; protocol =\u0026gt; \u0026#34;http\u0026#34; index =\u0026gt; \u0026#34;%{[@metadata][_index]}\u0026#34; index_type =\u0026gt; \u0026#34;%{[@metadata][_type]}\u0026#34; document_id =\u0026gt; \u0026#34;%{[@metadata][_id]}\u0026#34; } # We print dots to see it in action stdout { codec =\u0026gt; \u0026#34;dots\u0026#34; } } 実行と修正 実行します。\nbin/logstash -f logstash.conf ドキュメントのチェックと修正 何が起きたでしょう?\ncurl -XGET \u0026#34;http://localhost:9200/person/person/AU1wqyQWZJKU8OibfxgH\u0026#34; { \u0026#34;_index\u0026#34;: \u0026#34;person\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;person\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;AU1wqyQWZJKU8OibfxgH\u0026#34;, \u0026#34;_version\u0026#34;: 1, \u0026#34;found\u0026#34;: true, \u0026#34;_source\u0026#34;: { \u0026#34;name\u0026#34;: \u0026#34;Tali Elyne\u0026#34;, \u0026#34;dateOfBirth\u0026#34;: \u0026#34;1955-05-03\u0026#34;, \u0026#34;gender\u0026#34;: \u0026#34;female\u0026#34;, \u0026#34;children\u0026#34;: 2, \u0026#34;marketing\u0026#34;: { \u0026#34;cars\u0026#34;: null, \u0026#34;shoes\u0026#34;: null, \u0026#34;toys\u0026#34;: null, \u0026#34;fashion\u0026#34;: null, \u0026#34;music\u0026#34;: null, \u0026#34;garden\u0026#34;: null, \u0026#34;electronic\u0026#34;: null, \u0026#34;hifi\u0026#34;: null, \u0026#34;food\u0026#34;: 846 }, \u0026#34;address\u0026#34;: { \u0026#34;country\u0026#34;: \u0026#34;Germany\u0026#34;, \u0026#34;zipcode\u0026#34;: \u0026#34;0099\u0026#34;, \u0026#34;city\u0026#34;: \u0026#34;Bonn\u0026#34;, \u0026#34;countrycode\u0026#34;: \u0026#34;DE\u0026#34;, \u0026#34;location\u0026#34;: [ 7.075943707068682, 50.72883500730124 ] } } } もう一方のクラスタと比較してみましょう。\ncurl -XGET \u0026#34;http://localhost:9201/person/person/AU1wqyQWZJKU8OibfxgH\u0026#34; { \u0026#34;_index\u0026#34;: \u0026#34;person\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;person\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;AU1wqyQWZJKU8OibfxgH\u0026#34;, \u0026#34;_version\u0026#34;: 1, \u0026#34;found\u0026#34;: true, \u0026#34;_source\u0026#34;: { \u0026#34;name\u0026#34;: \u0026#34;Tali Elyne\u0026#34;, \u0026#34;dateOfBirth\u0026#34;: \u0026#34;1955-05-03\u0026#34;, \u0026#34;gender\u0026#34;: \u0026#34;female\u0026#34;, \u0026#34;children\u0026#34;: 2, \u0026#34;marketing\u0026#34;: { \u0026#34;cars\u0026#34;: null, \u0026#34;shoes\u0026#34;: null, \u0026#34;toys\u0026#34;: null, \u0026#34;fashion\u0026#34;: null, \u0026#34;music\u0026#34;: null, \u0026#34;garden\u0026#34;: null, \u0026#34;electronic\u0026#34;: null, \u0026#34;hifi\u0026#34;: null, \u0026#34;food\u0026#34;: 846 }, \u0026#34;address\u0026#34;: { \u0026#34;country\u0026#34;: \u0026#34;Germany\u0026#34;, \u0026#34;zipcode\u0026#34;: \u0026#34;0099\u0026#34;, \u0026#34;city\u0026#34;: \u0026#34;Bonn\u0026#34;, \u0026#34;countrycode\u0026#34;: \u0026#34;DE\u0026#34;, \u0026#34;location\u0026#34;: [ 7.075943707068682, 50.72883500730124 ] }, \u0026#34;@version\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;@timestamp\u0026#34;: \u0026#34;2015-05-20T09:53:44.089Z\u0026#34; } } Logstashは@versionと@timestampフィールドを追加してしました。 これらを除去したいので、Mutate filter pluginのremove_fieldを使います。\nfilter { mutate { remove_field =\u0026gt; [ \u0026#34;@timestamp\u0026#34;, \u0026#34;@version\u0026#34; ] } } マッピングのチェックと修正 実際に、logstashは_sourceフィールドを既存のドキュメントから読み込み、 それらを新しいクラスタに直接投入しています。 しかし、logstashはマッピングについてはケアしていません。\n古いマッピングと新しいマッピングを比較するために、マッピングを取得してみましょう。\ncurl -XGET \u0026#34;http://localhost:9200/person/person/_mapping\u0026#34; { \u0026#34;person\u0026#34;: { \u0026#34;mappings\u0026#34;: { \u0026#34;person\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;address\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;city\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;country\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;countrycode\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;location\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;geo_point\u0026#34; }, \u0026#34;zipcode\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, \u0026#34;children\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;dateOfBirth\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;date\u0026#34;, \u0026#34;format\u0026#34;: \u0026#34;dateOptionalTime\u0026#34; }, \u0026#34;gender\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;marketing\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;cars\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;electronic\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;fashion\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;food\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;garden\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;hifi\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;music\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;shoes\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;toys\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; } } }, \u0026#34;name\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } } } } } curl -XGET \u0026#34;http://localhost:9201/person/person/_mapping\u0026#34; { \u0026#34;person\u0026#34;: { \u0026#34;mappings\u0026#34;: { \u0026#34;person\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;address\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;city\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;country\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;countrycode\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;location\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;double\u0026#34; }, \u0026#34;zipcode\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, \u0026#34;children\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;dateOfBirth\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;date\u0026#34;, \u0026#34;format\u0026#34;: \u0026#34;dateOptionalTime\u0026#34; }, \u0026#34;gender\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;marketing\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;cars\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;electronic\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;fashion\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;food\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;garden\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;hifi\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;music\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;shoes\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;toys\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; } } }, \u0026#34;name\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } } } } } これにより、いくつかの相違を発見できます。\n\u0026#34;location\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;geo_point\u0026#34; } \u0026#34;location\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;double\u0026#34; } データをインデックスする「前」に、実際に利用したいマッピングでインデックスを作成しておくことで、 この問題に対処できます。 この時点で、オリジナルのマッピングを望んだ形に変更することができます。例えば、アナライザを変更したりです。 また、インデックスの設定を新しく定義することもできます。 デフォルトでは、Elasticsearchは5つのシャードと各シャードに対して1つのレプリカを作成します。 しかし、この時点でもう一度変更することが可能です。\ncurl -XDELETE \u0026#34;http://localhost:9201/person\u0026#34; curl -XPUT \u0026#34;http://localhost:9201/person\u0026#34; -d\u0026#39; { \u0026#34;settings\u0026#34;: { \u0026#34;number_of_shards\u0026#34;: 1, \u0026#34;number_of_replicas\u0026#34;: 0 } }\u0026#39; curl -XPUT \u0026#34;http://localhost:9201/person/person/_mapping\u0026#34; -d\u0026#39; { \u0026#34;person\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;address\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;city\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;country\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;countrycode\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;location\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;geo_point\u0026#34; }, \u0026#34;zipcode\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, \u0026#34;children\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;dateOfBirth\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;date\u0026#34;, \u0026#34;format\u0026#34;: \u0026#34;dateOptionalTime\u0026#34; }, \u0026#34;gender\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;marketing\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;cars\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;electronic\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;fashion\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;food\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;garden\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;hifi\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;music\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;shoes\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;toys\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; } } }, \u0026#34;name\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } } }\u0026#39; さて、もう一度再インデックスしましょう!\nbin/logstash -f logstash.conf インデックスやタイプ名の変更 もちろん、インデックス名やタイプ名、IDを変更したい場合も変更が可能です!:)\nelasticsearch { host =\u0026gt; \u0026#34;localhost\u0026#34; port =\u0026gt; \u0026#34;9201\u0026#34; protocol =\u0026gt; \u0026#34;http\u0026#34; index =\u0026gt; \u0026#34;europe_people\u0026#34; index_type =\u0026gt; \u0026#34;someone\u0026#34; document_id =\u0026gt; \u0026#34;%{[@metadata][_id]}\u0026#34; } ","date":1432624090,"dir":"post/2015/","id":"23a22d1411afb787810d68210e6fad4f","lang":"ja","lastmod":1432624090,"permalink":"https://blog.johtani.info/blog/2015/05/26/reindex-elasticsearch-with-logstash-ja/","publishdate":"2015-05-26T16:08:10+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Reindex Elasticsearch With Logstash Thanks David! マッピングを変更したり、インデックスの設定を変更したり、あるサ","tags":["logstash","elasticsearch"],"title":"Logstashを使ったElasticsearchの再インデックス(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Join the Conversation: Discuss.Elastic.Co\n3つのOSSプロジェクトの開発をスケールアップし始め、 コミュニティサポートのために必要なやりとりに対してメーリングリストでは難しいということがわかってきました。 私たちは複数のメーリングリストを持っています。Elasticsearch、Logstash、そして英語以外の様々な言語のメーリングリストです。 このような状況では、あたらしい人たちはどこで質問をするのが良いのか混乱します。\nまた、メーリングリストの流量が増え、「参考になる話題」を見つけるのが難しくなってきました。 様々なユーザに採用してもらい、様々なユースケースが出てくることで、様々な質問が出てきています。 汎用的なメーリングリストではノイズの中から望んだ情報を見つけるのは難しいです。 また、ユーザ全てがメーリングリスト満足しているわけではありません。\nElasticは、ユーザの問題を解くことが大好きです。 コミュニティのメンバー皆さんに気に入っていただけるであろうソリューションを見つけ、フォーラムを https://discuss.elastic.co に移すことにしました。 ぜひ参加して、この新しいツールについてのご意見を聞かせてください。\nメーリングリストは好きだけど、ウェブフォーラムは苦手?問題ありません。 フォーラムにユーザプロファイル(GitHub、Facebook、Twitter、Google Appsのアカウントと連携するか、emailアドレスを利用すれば簡単に作れます)を作り、 email通知の設定をすればOKです。 これで、emailでのやりとりができるようになります。\n利用して、議論を楽しんでください。 もちろん、改善案などにかんするご意見もお待ちしています!\n","date":1432197903,"dir":"post/2015/","id":"615db1a24f36d19a8eaf18d4dceed6b2","lang":"ja","lastmod":1432197903,"permalink":"https://blog.johtani.info/blog/2015/05/21/join-the-conversation-ja/","publishdate":"2015-05-21T17:45:03+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Join the Conversation: Discuss.Elastic.Co 3つのOSSプロジェクトの開発をスケールアップし始め、 コミュニティサポー","title":"discuss.elastic.co にぜひ参加を"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 1.5.2 Released\n本日(4/27)、Lucene 4.10.4ベースのElasticsearch 1.5.1およびElasticsearch 1.4.5 をセキュリティバグフィックス版をリリースしました。 ダウンロードおよびすべての変更については次のリンクをごらんください。\n最新安定版:Elasticsearch 1.5.2 1.4系バグフィックス:Elasticsearch 1.4.5 本リリースはディレクトリトラバーサルの脆弱性のフィックスです。すべてのユーザにアップグレードを勧めます。\n過去のリリースに関するブログは以下のリンクを参照してください。\n1.5:1.4.1, 1.5.0 1.4:1.4.4,1.4.3, 1.4.2,1.4.1, 1.4.0, 1.4.0.Beta1 すべての1.5.2および1.4.5の変更についてはリンクをごらんください。以下では、セキュリティの問題について紹介します。\nディレクトリトラバーサル脆弱性の発見 1.5.2および1.4.5以前の全バージョンのElasticsearchで、ディレクトリトラバーサル攻撃に対する脆弱性がみつかりました。 攻撃者はElasticsearchを実行しているサーバからファイルを取得することができます。 この脆弱性はインストールしたばかりのElasticsearchには存在しません。 この脆弱性は\u0026quot;site plugin\u0026quot;がインストールされると露呈します。 ElasticのMarvelプラグインおよびコミュニティサポートの多くのプラグイン(例:Kopf、BigDesk、Head)がsite pluginです。 Elastic Shield、Licensing、Cloud-AWS、Cloud-GCE、Cloud-Azure、analysis pluginおよびriverプラグインはsite pluginではありません。\nこの問題をCVE-2015-3337としました。\nバージョン1.5.2と1.4.5はこの脆弱性に対して対策済みで、私たちはすべてのユーザにアップグレードを勧めています。\nアップグレードを望まないユーザはいくつかの方法でこの脆弱性に対して対応可能ですが、これらの方法はsite pluginを動作させなくします。\nsite pluginをインストールしているノードのelasticsearch.ymlのhttp.disable_sitesをtrueに設定し、Elasticsearchのノードを再起動 ファイアウォールもしくはプロキシを利用して、/_pluginへのHTTPリクエストをブロック すべてのsite pluginをすべてのElasticsearchノードからアンインストール この問題を報告していただいた、DocuSignのJohn Heasmanに感謝いたします。\n他の変更について インデックスされたスクリプトおよびテンプレートを上書きもしくは削除時に、キャッシュからも完全に削除する。 geo-shapeの多数のフィックス(distance_error_pctを利用した場合の、重要なprecisionに関するフィックスを含む) インデックステンプレートのデフォルトマッピングがバルクインデキシング中にも考慮するように修正 Shadowレプリカがファイルシステムの遅延に対する対障害性を向上し、プライマリシャードのよりスムーズなリロケーションをサポート geo-contextsをcompletion suggesterで使用した場合のマッピングのリフレッシュループを改善 いくつかの重要な変更がv1.4.5にバックポートされています。\n大きなシャードのリカバリを早くするためのシャードリカバリ中のマージを可能に \u0008* truncated translogsの操作をグレースフルに マージが遅くなる場合に、delete-by-queryを減速 ぜひ、Elasticsearch 1.5.2をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1430201648,"dir":"post/2015/","id":"8d7caf84b3a51cca27291c1f7cfc2d40","lang":"ja","lastmod":1430201648,"permalink":"https://blog.johtani.info/blog/2015/04/28/elasticsearch-1-5-2-and-1-4-5-released-ja/","publishdate":"2015-04-28T15:14:08+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 1.5.2 Released 本日(4/27)、Lucene 4.10.4ベースのEla","tags":["elasticsearch"],"title":"Elasticsearch 1.5.2 および 1.4.5リリース(日本語訳)"},{"contents":"第9回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 次回もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\n今回はトレーニングで来日していたIgorとNathanによる特別公演でした。 昨年同様、サムライズムの@yusukeさんに テキスト翻訳していただき、大変助かりました。ほんとうにすごかった。。。\nチェックイン数など 今回はチェックインした人:119名 キャンセルしなかった人:45名 でした。今回はキャンセル待ちのまま当日を迎えた人もいなかったので良かったかなと。 今回から懇親会ページを別にしてみました。本編の勉強会に参加登録していた方には何度かメールを出していたので、 見つけていなかった人は以内とは思うのですが、勉強会のページと間違える人がいたらしいという話を聞きました。 Doorkeeperで1イベントで複数のチケットにそれぞれの参加者数を設定できるようになると嬉しいかもなぁ。\nさて、いつもの通り簡単なメモです。 本当に簡単にですが。\nResiliency in Elasticsearch and Lucene / Igor Motov スライド:https://speakerdeck.com/elastic/resiliency-in-elasticsearch-and-lucene\n※上記スライドは少し古いバージョンです。公開されたら差し替える予定です。\nサンフランシスコで行われたElastic{ON}(弊社初のカンファレンス)で行われたセッションの 改良版といったところでしょうか。 話の中で登場した機能などのリンクをざっとアップしておきます。\nFielddata Doc Values Resiliency Status Kibana4: What\u0026rsquo;s New ? / Nathan Zamecnik スライド:未定\nKibana4の紹介をデモを交えてという感じでした。 こちらは、スライドよりもデモを見てもらうのが一番いいのですが。。。\nいくつかQAがあったので補足を。ちなみに、Issueのラベルに実装される予定のバージョンが付与されてたりします。\nQ:グラフをPDFでエクスポートとかできますか? A:4.3.0で実装される予定です。関連Issueはこちら。https://github.com/elastic/kibana/issues/509 Q:巨大な数値の場合にKB、MBなどといった表示は可能ですか? A:4.1.0で実装される予定です。関連Issueはこちら。https://github.com/elastic/kibana/issues/1543 Q:地図のズームを固定することはできますか? A:4.1.0で実装される予定です。関連Issueはこちら。https://github.com/elastic/kibana/issues/1442 その他、感想などのブログ [Elasticsearch] 第9回 Elasticsearch 勉強会へ参加してきた まとめ 今回は特別バージョンでした。かなり詳しい話だったので面白かったと思います。 Kibanaはデモを見ていただけましたし。また、海外から人を呼べるといいなぁ。\n次回は6月ごろをめどに計画しようかと。 スピーカーは随時募集中ですので、コメント、メール、ツイートなど、コンタクトしていただければと思います。 よろしくお願いいたします。\n","date":1429249314,"dir":"post/2015/","id":"7249710187cc2d983709e044dbc78d9d","lang":"ja","lastmod":1429249314,"permalink":"https://blog.johtani.info/blog/2015/04/17/9th-elasticsearch-jp/","publishdate":"2015-04-17T14:41:54+09:00","summary":"第9回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん","tags":["elasticsearch","勉強会"],"title":"第9回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 1.5.1 Released\n本日(4/9)、Lucene 4.10.4ベースのElasticsearch 1.5.1 をリリースしました。 このリリースはElasticsearchの最新の安定バージョンとなります。\nすべての変更についてはdownload Elasticsearch 1.5.1 hereをごらんください。\n本リリースはシャードを新しいノードに配置するスピードを改善するためのバグフィックスを含んでいます。 シャードのリカバリーの最初のフェーズで、コピー元のノードからコピー先のノードへすべてのセグメントをコピーします。 このフェーズ中には登録、更新削除のリクエストはトランザクションログに記録され、リカバリが終了したあとに コピー先のノードでトランザクションログが再生されます。 シャードが大きい場合、トランザクションログに多数のイベントがたまってしまいます。\n以前では、新しいセグメントのマージはリカバリ中のコピー先のノードでは、実行できませんでした。 大きなトランザクションログは結果として、小さな新しいセグメントを多く生成し、リカバリのスピードに非常に影響を与えます。 Issue #10463は リカバリ中のコピー先のシャードのマージを可能にする変更です。\nその他の注目すべきバグフィックスは次のものになります。\n多くの削除によりバージョンマップがいっぱいになった場合にrefreshを実行するように変更(#10312) 多数のスナップショットを含んだリポジトリの管理の改善(#10366) 実験的な機能であるinner hitsのバグフィックス(#10388, #10353, #10309, #10235) 最後に、Riverが非推奨となりました、まだ見ていない場合は記事をご覧ください。\nぜひ、Elasticsearch 1.5.1をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1428892471,"dir":"post/2015/","id":"563864a949924c505985a168191dcb84","lang":"ja","lastmod":1428892471,"permalink":"https://blog.johtani.info/blog/2015/04/13/elasticsearch-1-5-1-released-ja/","publishdate":"2015-04-13T11:34:31+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 1.5.1 Released 本日(4/9)、Lucene 4.10.4ベースのElas","tags":["elasticsearch"],"title":"Elasticsearch 1.5.1リリース(日本語訳)"},{"contents":"Elasticsearch勉強会 in 名古屋を開催しました。 初の東京以外での勉強会です。 企画、セッションなどお手伝いいただいた@smogamiさん、@mzpさんありがとうございました!\nElasticsearch/ELK stack紹介 @johtani スライド:Introduction Elasticsearch\n初回(次回があるかはわかりませんが。。。)ということもあり、Elasticsearchの説明を行いました。 あと、LogstashとKibanaも。 Kibanaについては、手元の環境でいつものアクセスログのデモやなどを行いました。 また、LTの後に時間があったので、前回の勉強会で利用したチェックリストの説明なども。\nスタンドファームにおけるElasticsearch導入事例 @mzp さん スライド:後日アップ?\n\u0008* 使ってるのはKibana3\nアクセスログが保存されてたけど、活用できてなかった。 Fluentd、Elasticsearch、Kibanaをいれて、可視化してみた。 普通にログ検索が簡単にできて嬉しい システムのレスポンスの性能値などを可視化できるようにして性能改善中 Kibanaでログ分析を1年続けてみたら業務システムの保守と運用が捗った(仮) @smogami さん スライド:「Kibanaでログ分析を1年続けてみたら業務システムの保守と運用が捗った」\n名古屋でJavaの勉強会を主催してみたり(最近できてないけど) 導入するのになかなか大変だった(ファイアウォールだったりが)。。。 Kibanaを使ってどんなことをしてるのか?\n既存システムなどの機能の実行回数やレスポンス時間の推移 曜日ごとにもチェック どの機能がよく使われるのか? 対象となっているシステムはJavaのシステム。 QA\nQ:ログの出力は新規に追加したのか? A : ログの出力自体はLog4Jの設定を変更しただけ。もともと、各メソッドの開始と終了にそれぞれ時間が出力される仕組みがある。\nログの読み込み自体は自作ツールを利用。 飛び込みLT @dabits さん スライド:未定\nKibanaの使い道\nKPIツール エゴサーチツール - Twitterや2chなどのデータを解析ソーシャル分析みたいな感じ? \u0008* ダッシュボードを用意してあげる場合もあるが、触っていろんな機能を試す人も。 感想・反省点など 30名弱の方に参加していただきました。ありがとうございました。 東京の勉強会でもそうですが、半分くらいが検索、半分くらいがログ解析関連に興味がある感じでした。 飛び込みLTもしていただけましたし。会場内限定の話もいくつか。\n場所 場所が少しわかりにくかったかなと。。。建物の入り口に看板がないので、1名に看板役として立っていただきました。 ただ、設備は充実していましたし、室内も綺麗でよかったです。\n懇親会 11名(+私)でした。美味しい手羽先などをいただきながら、Elasticsearch以外のことでも盛り上がりましたw。 また、名古屋の観光名所なども教えてもらったりと有意義な時間でしたw。\nということで、少しでもElasticsearch、Kibana、Logstashなどのユーザが増えてくれればうれしいかなと。 私抜きでも勉強会はできると思うので、今後も開いてもらえるとうれしいかぎりです。 初めての東京以外での勉強会でどんな感じの方が利用しているのか、興味があるのかといったことも知ることができました。\n関連ブログなど Kibana4活用事例を話しました その他(余談) コンパルという喫茶店のアイスコーヒー。ちょっと新鮮な体験でした。 あとは、日曜日に観光場所として教えてもらった、トヨタ産業技術記念館にも行ってみました。 一人だったけど、非常に楽しめました。実演とかあって、わかりやすいし。 トヨタが自動織機の会社が始まりだってのは知らなかった。\n","date":1428108439,"dir":"post/2015/","id":"24357fe145c869ec82fdfc8134a1a6d1","lang":"ja","lastmod":1428108439,"permalink":"https://blog.johtani.info/blog/2015/04/04/elasticsearch-study-session-at-nagoya/","publishdate":"2015-04-04T09:47:19+09:00","summary":"Elasticsearch勉強会 in 名古屋を開催しました。 初の東京以外での勉強会です。 企画、セッションなどお手伝いいただいた@smogamiさ","tags":["elasticsearch","勉強会"],"title":"Elasticsearch勉強会 in 名古屋を開催しました。#elasticsearch #elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 1.5.0 Released\n本日(3/23)、Lucene 4.10.4ベースのElasticsearch 1.5.0 をリリースしました。 このリリースはElasticsearchの最新の安定バージョンとなります。 多くのresiliency(復元性、弾力性) enhancementとバグフィックスを含んでおり、 すべてのユーザにアップグレードを推奨しています。\nすべての変更についてはdownload Elasticsearch 1.5.0 hereをごらんください。\n460PRという大量の変更を含む本リリースは、Elasticsearchをよりresilient(弾力のあるもの)にするために 費やされています。\nInner hits 本リリースで追加された、Elasticsearchに最もリクエストされたものの一つがinner hitsです。 これは、has_childもしくはnestedクエリにマッチした子のドキュメントを、各親ドキュメントと一緒に返すことができます。\n例えば、blogという親ドキュメントとcommentという子ドキュメントを持っているとします。 この時、\u0026ldquo;full text search\u0026quot;というコメントを持ったブログ記事を検索したいとします。\nGET /my_index/blog/_search { \u0026#34;query\u0026#34;: { \u0026#34;has_child\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;comment\u0026#34;, \u0026#34;score_mode\u0026#34;: \u0026#34;sum\u0026#34;, \u0026#34;query\u0026#34;: { \u0026#34;match\u0026#34;: { \u0026#34;body\u0026#34;: \u0026#34;full text search\u0026#34; } } } } } 上記のリクエストは、親のblogドキュメントを返します。 しかし、どのコメントが関係しているのかはわかりません。 関連しているコメントを検索して親ごとにグルーピングするために、 少し手間のかかる2回目のクエリを実行する必要があります。\nInner hitsがこれを変えてくれます。 inner_hitsパラメータを次のように、上記のクエリに追加するだけです!\nGET /my_index/blog/_search { \u0026#34;query\u0026#34;: { \u0026#34;has_child\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;comment\u0026#34;, \u0026#34;score_mode\u0026#34;: \u0026#34;sum\u0026#34;, \u0026#34;query\u0026#34;: { \u0026#34;match\u0026#34;: { \u0026#34;body\u0026#34;: \u0026#34;full text search\u0026#34; } }, \u0026#34;inner_hits\u0026#34;: {} } } } 検索結果の各blog記事に、inner_hitsという項目があり、そこに検索にヒットしたコメントの 上位3件(デフォルト値)が返ってきます。\n... \u0026#34;hits\u0026#34;: [ { \u0026#34;_index\u0026#34;: \u0026#34;my_index\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;blog\u0026#34;, \u0026#34;_id\u0026#34;: 1, \u0026#34;_score\u0026#34;: 3.68, \u0026#34;_source\u0026#34;: { ... }, \u0026#34;inner_hits\u0026#34;: { \u0026#34;comment\u0026#34;: { \u0026#34;total\u0026#34;: 16, \u0026#34;hits\u0026#34;: [ { \u0026#34;_type\u0026#34;: \u0026#34;comment\u0026#34;, \u0026#34;_id\u0026#34;: 5, \u0026#34;_score\u0026#34;: 2.79, \u0026#34;_source\u0026#34;: { \u0026#34;body\u0026#34;: \u0026#34;Full text search is the bomb\u0026#34; } }, { ... }, { ... } ] } } } ] ... inner_hits部分は、第2の検索リクエストに似ています。 sizeやfromパラメータを含めるくことで、挙動をカスタマイズできます。 また、検索から想像するであろう、ページネーション、ソート、ハイライト、_sourceフィルタリングなどといった機能もサポートします。\nInner hitsはparent-childおよび、nestedドキュメントをサポートします。 この機能は、現時点ではexperimentalラベルが付与されています。 このラベルは、この機能が将来変更されたり、削除されたりする可能性があるかもしれないことを意味します。 詳細については、Inner Hits documentationをごらんください。\nShadow replicas Elasticsearchはそれ自身の冗長性に常に気をつけています。 それは、レプリカシャード(各プライマリシャードの冗長なコピー)を持っています。 これは、プライマリシャードを失った時に、データをロスしないようにするためのものです。 レプリカシャードはまた、検索のスループットをスケールアウトするためにも利用できます。 多くのレプリカ(ノードを伴うことで。)はスループットを増加させます。\nしかし、ユーザによってはElsticsearchを分散ファイルシステム上でホスティングしており、すでに、 ファイルシステムがレプリケーションと冗長性を担当しています。 ファイルシステムが同じことしているので、各シャードのコピーを複数持つことはあまり意味がありません。\nShadowレプリカはノードを追加することによる検索スループットをスケールアウトすることが、 余分なストレージやインデキシングのコストを払うことなく、可能になります。 代わりに、各シャドーレプリカはプライマリシャードを持っている共有ファイルシステムにread-onlyでアクセスします。 Shadowレプリカは定期的にファイルシステムのビューをリフレッシュし、プライマリシャードのどんな変更も検知するでしょう。\nプライマリシャードが失敗したら、Shadowレプリカがプライマリに昇格し、 失敗したプライマリによって書き込まれたトランザクションログを読み込みリプレイできます。\nこの機能はexperimentalマークが付いています。詳細についてはShadow Replicas documentationをごらんください。\nResiliency improvements Elasticsearch 1.1 から 1.3では、インデックスのすべてのファイルのチェックサムを追加し、 それらのファイルが壊れているかどうかをチェックするために利用することにフォーカスしました。 1.4では、Zen discoveryと分散モデルについて大きな改良を加えました。\nこれらの変更にともなう、より詳細な統計情報やより詳細なロギングがElasticsearchやLuceneの以前のバージョンに存在した 未知の問題を明るみに出しました。 Elasticsearch 1.5.0では、これらの問題の多くに対処しています。\nElasticsearchとLuceneの以前のバージョンにあるバグがインデックスの故障を引き起こしていました。\nチェックサムコードのおかげで、これらを発見できました。現在は、Elasticsearchの起動時に自動的にLucene3.x\n(Elasticsearch 0.20.x以前)が作成したセグメントを検知して、シャードをオープンする前に、新しいフォーマットを使って、 新しいコミットポイントを書き出します。(#9899)\n1.3.xもしくは以前のバージョンからローリングアップグレードは、ローカルのシャードデータを再利用しようとせずに、\nシャード全体をコピーしようとします。1.3.2と以前のバージョンが実行されているノードからローリングアップグレードすることは 圧縮をオフにしない限りできなくなりました。(#9925)\n1.3.xやそれ以前のバージョンからアップグレードする場合、ローリングアップデートする代わりにクラスタの再起動を考えたほうがいいかもしれません。\n非同期環境は予測することが難しいです。時に、最も予測していないことが起きるからです。\nシャード配置、リカバリ、削除のコードの多くが単純化され、状態変更をよりアトミックで決定的にするための変更によりリファクタリングされました。\n(#8720, #9799, #9784, #9801, #9083, #8579, #8436, #8092, #9902, #6644, #8350, #9770, #9616, #9439, #8350, #8494)\n同様に、変更はクラスタ状態の更新が常に前進するということを確実にしました。更新の受け取り順序が順不同であったり、\nマスターだったノードからの更新を受け取った場合に混乱させていました。 (#9632, #9541, #9503)\nチェックサムとチェックサムのバリデーションの強化(#8723,\n#8599, #8587, #8407, #8010, #8018)\ndisk threshold allocation deciderを速く(#8803)、賢く(#7785)、自動化(#8270)\nauto-generated IDの利用時のインデキシングのスピードアップのためのに追加された最適化を除去。\nたまにドキュメントを重複して登録するため(#7729)\nDownload now ぜひ、Elasticsearch 1.5.0をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1427859496,"dir":"post/2015/","id":"19ecbaa5e12f7a9ebcff703c79534a52","lang":"ja","lastmod":1427859496,"permalink":"https://blog.johtani.info/blog/2015/04/01/elasticsearch-1-5-0-released-ja/","publishdate":"2015-04-01T12:38:16+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 1.5.0 Released 本日(3/23)、Lucene 4.10.4ベースのEla","tags":["elasticsearch"],"title":"Elasticsearch 1.5.0リリース(日本語訳)"},{"contents":"サンフランシスコからこんにちは。\n今、私は、弊社初のユーザカンファレンスelastic{ON}に 参加するために、初のアメリカ出張中です。 初のユーザカンファレンスですが、世界各国から約1300人!の登録がありました。\n本日が初日(Welcome Receptionが昨晩開催されましたが)です。 初日のキーノートで重要な発表が2つありました。\nブランド名の変更(Elastic: For - You Know, More Than Search) Found.noの加入(Welcome Found) です。\n昨日までは、elasticsearchでした。 本日からは、elasticになります。 ブランド名の変更と同時にサイト、ロゴなども変更されました。\nもう一つのビッグニュースがFoundの加入です。 found.noはElasticsearchをクラウドサービスとして提供している会社です。 彼らがジョインすることで、elasticsearchをより気軽に利用できるような環境ができてきます。\nKeynoteでの驚きのニュースこれらでした。 もちろん、このカンファレンスはそれだけには止まりません。\nNetflixやGitHub、Verison Mobile、WikimediaといったElasticsearch,ELKスタックのユーザの話や、 弊社の人たちによる今後のロードマップや私たちの考え方など多岐にわたる話を聞くことができます。\nこのような機会を今後も提供できるような会社になれるよう、頑張っていきたいなと思っています。\nちなみに、弊社のカンファレンスは私がこれまで経験したことのないカンファレンスになっています。 DJや各種ゲーム(ビリヤードとかパックマンとか)が楽しめるようなパーティが 懇親会として開催されたり、スポンサーブースでウェルカムレセプションが行われたりと、 面白い取り組みにあふれています。 次回開催されることがあれば、ぜひ日本の方達にも参加してもらえたらうれしいなと。\n","date":1426059991,"dir":"post/2015/","id":"ced9df0d8c8ed14de91c509b31b4c4ae","lang":"ja","lastmod":1426059991,"permalink":"https://blog.johtani.info/blog/2015/03/11/attend-elasticon/","publishdate":"2015-03-11T16:46:31+09:00","summary":"サンフランシスコからこんにちは。 今、私は、弊社初のユーザカンファレンスelastic{ON}に 参加するために、初のアメリカ出張中です。 初のユ","tags":["elastic","elasticon"],"title":"#elasticon に参加中"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:you know, for security: shield goes ga\n1/27にShield 1.0 をリリースしました。 Elasticsearch向けの私たちのセキュリティプラグインの最初のリリースです。 11月にShieldについてアナウンスしてから、Elsaticsearchのためのセキュリティの機能は、 一般的に望まれているものから始まり、具体的な考えと実行できる計画へと変遷し、それが、いま現実となりました。\n十分にセキュアな環境に、Elasticsearchクラスタをセキュアな状態でデプロイできるようにするため、 私たちは継続的にカスタマーやユーザーからのリクエストを受け取り、統合されたソリューションになるようにしてきました。\n私たちは、そのようなプロダクトがどうあるべきか調査することから始め、 カスタマーとユーザが必要とするセキュリティとはどんなものかを理解するために多くの時間を費やしました。 その結果がShieldです。 Shieldは、ElasticsearchクラスタをセキュアにするElasticsearchの有償プラグインです。 私たちは、ShieldをDev、Gold、Platinumサブスクリプションの一部として、追加料金なしで提供します。\n最初のリリースでは、基本的な機能と基盤にフォーカスしています。 Elasticsearch自身に対しても、セキュリティに対して準備してきました。 拡張性の側面だけでなく、Elasticsearchにあるデータフローについても再考してきました。 Elasticsearchクラスタをセキュアにする場合に、具体的な価値を即座に届けるだけでなく、素早く拡張できるようにも開発しました。\n機能 Shield 1.0は次の5つにフォーカスしています。\n認証(Authentication) 認可(Authorization) 暗号化通信とノードの認可(Encrypted Communication \u0026amp; Node Authentication) IPフィルタリング 監査証跡(Audit Trail) 認証(Authentication) セキュリティの大部分はアイデンティティについてです(例えば、だれがこのAPIを呼び出したのか?システムに何のサービスが接続するか?など) サービスのライフタイムのある時点で、サブジェクト(例えばユーザー)を現在実行中のサブプロセスなどに結びつけることです。 この関係性を持つためには、サブプロセスを実行する前にユーザの身元を確認するように命じます。 ユーザの身元の確認のプロセスをAuthenticationと呼び、ElasticsearchのすべてのAPIコールでそれが実行されます。\n認証の手法は多くの異なるものがあります。 それぞれの手法は、ユーザが認証されたという資格(Authentication Token)を、それぞれのタイプで提供するようにユーザに要求します。 Shield 1.0ではシンプルに、必要なauthentication tokenをユーザ/パスワードペアとしています。 (これは、Shieldの認証基盤が簡単に拡張でき、将来は異なるauthentication tokenもサポートできることを意味します。)\nユーザの資格を受け取ることだけでは不十分で、次に、それらをチェックする必要があります。 Shieldでは、これはレルムの責務です。 レルムは認証プロバイダ/サービスとしてみることができます。 妥当なユーザであると判断/解決されたか、 authentication tokenが適切な資格を持っていない/単に知らないユーザであるということで、拒否されたかです。 Shieldの認証メカニズムでは、複数のレルムを設定でき、さらに、あるレルムの戻り値を扱う他のレルム、というようなchainとすることもできます。 Shield 1.0は3つのレルムをサポートします。\nesusers - Elasticsearchによって管理されるファイルベースのレルムです。 これは、ファイルにユーザを定義することができます。(Apacheサーバのhtpasswdファイルのようなもの) このレルムは外部への依存はなく、Shieldをインストールすれば、デフォルトで使用できます。 このレルムは配置が簡単で、マルチテナントなElasticsearchクラスタに対して使用できます。 マルチテナントなElasticsearchクラスタとは、クラスタを複数のアプリでシェアすることをテナントと言います。 また、すべてのユーザがパスワードを忘れてしまうような\u0026quot;emergency\u0026quot;な代替レルムも対応可能です。 (誰もシステムに入れないような状況のことです) LDAP - 外部のLDAPサーバでユーザを認証するレルムです。 このレルムは組織のLDAPサーバで管理/保存されているユーザをすでに持っている組織を対象としています。 Active Directory - LDAPのタイプの1つで、Active Directoryに対する設定になります。 レルムはelasticsearch.yml設定ファイルで、次のように設定可能です。\nshield.authc realms:\nesuser: type: esusers order: 0 ldap: type: ldap order: 1 url: ldaps://url/to/ldap1/server ldap_fallback: type: ldap order: 2 url: ldaps://url/to/ldap2/server 上記のようにrealmsが一つのチェインとして参照されます。 レルムごとに、設定された順序で、それらは参照されます。\nNOTE : Shieldには、esusersファイルに保存されたユーザを管理するためのコマンドラインツールもあります。\n認可(authorization) 認可(Authorization)は保護されたリソースにアクセスするユーザを許可するか拒否するかということです。 モダンなシステムは、ユーザのパーミッションのために、ロールベースのアクセスコントロール(RBAC)モデルを利用します。 このモデルでは、各ユーザはロールの集合に関連していて、それぞれのロールには、パーミッションの集合が定義されています。 これは、洗練された設定で、パーミッションを機能的なグループで共有させることができます。 例えば、次のようなロールを定義したとします。\nemployee - すべての従業員は部門をまたいだ会社のデータへアクセスできます(例えば、コンタクトやディレクトリ情報など) sales - すべての営業職は営業データにアクセスできる(例えば、流通ルート、ルート、顧客) finace - すべての財務の従業員は財務データにアクセスできる(例えば、予算、経費、伝票) 財務部門のAnnは従業員と財務のロールを持っており、会社のディレクトリと財務データにアクセスでできます。\n認可プロセスはユーザがリクエストに関連したユーザが必要で、このプロセスのために、認証フェーズの後に直接実行されます。\nShieldは2つのタイプのリソースを定義します。クラスタとインデックスです。 これらは、すべてのAPIコールで保護されます。 さらに、それらに関連したパーミッションとロールも定義できます。 一度定義をすると、ロールはユーザもしくはLDAP/ADのグループに関係します。 ロールはroles.yml設定ファイルで定義されます。 設定のサンプルは次のようになります。\nadmin: cluster: all indices: \u0026#39;*\u0026#39; : all monitor: cluster: monitor indices: \u0026#39;*\u0026#39;: monitor employee: indices: \u0026#39;company_directory\u0026#39; : read sales: indices: \u0026#39;opportunities\u0026#39; : read, write \u0026#39;accounts\u0026#39; : read, write finance: indices: \u0026#39;expenses\u0026#39; : read, write \u0026#39;purchases\u0026#39; : read, write 上記のサンプルで、次の5つのロールを定義しています。\nadmin - 管理者のロールで、すべてのクラスターレベルの操作とすべてのインデックスに対してすべてのインデックスレベルの操作を実行可能です。 (¥*インデックスはすべてのインデックスにマッチするワイルドカード) monitor - システム/クラスタのモニタリングのためのロール。このロールのユーザはすべてのクラスタとインデックスレベルの情報の読み取りの APIにアクセス可能だが、インデックスのデータへの読み書きや設定の更新は不能 employee - compnay_directoryにあるすべてのデータへの読み取りアクセスを与えられたロール。このロールはクラスタレベルへのアクセスやデータの書き込みアクセスは持っていない (特にcompany。洗濯されたグループの人々はcompanyディレクトリの更新は可能だが、employeeは読み取りのみが可能) sales - opportunitiesとaccountsインデックスの読み書きができるロール finance - expensesとpurchasesの両方に読み書きができるロール 上記のサンプルで定義されているallとreadとwriteとして名前がつけられた権限です。 これらは、予約語で、Elasticsearchのローレベルのアクションを複数含んだ権限です。 (writeはindex, delete, delete_by_query, bulk, updateの操作を含んでいます。) 多くのケースで、これらのハイレベルの名前が付けられた権限で十分ですが、特定のロールに特定のアクションを明示的に指定することもできます。 次のようになります。\nhr: indices: \u0026#39;company_directory\u0026#39; : indices:data/write/index, indices:data/write/update ここまで説明した認可のレルムは、各ユーザに関連するロールを識別するためのものです。 内部のesuserレルムでは、提供されるesuserコマンドラインツールを使ってロールはユーザに割り当てたり変更したりもできます。 LDAPやActive Directoryでは、LDAP/ADグループにShieldのロールを割り当てることができます。\n認証と認可の両方を用いることで、ユーザリクエストに対して、ユーザごとに許可/不許可をすることができます。\n暗号化通信 認可はElasticsearchのデータを機能的な観点(許可されたユーザだけが操作を可能にする)で保護しますが、 クライアントからElasticsearchクラスタへ、もしくはクラスタのノード間では暗号化されていないデータを送るためまだ危険があります。 第三者が登頂したり、オンザフライでデータを書き換えたりといった可能性やクラスタを壊すことができます。\nShield 1.0はElasticsearchのすべての通信チャネルをセキュアにすることができます。 クラスタ内のノード間のチャネルやクライアントに公開されているチャネルです。 これは、SSL/TLS通信を導入して実現します。\nShieldで使えるSSLはElasticsearchのtransportサービスをSSL/TLSで通信できるものに置き換えます。 これは、ノード間通信チャネルと、HTTP transport(REST APIを提供するもの)のそれぞれに設定可能です。\nShieldのSSL/TLSは、スタンダードなJavaのものとkeystoreとtruststoreを基本にしたものが利用可能です。 SSL/TLSを設定すると、各ノードのキーストアに証明書をインポートする必要があります。 CAがサインした証明書を使うことも、CAが信頼したものとして許可許諾されたものを使うことが可能です。 これは、信頼されたすべてのCAとして知られているtrust storeが必要です。 新しいノードをクラスタに追加するときに、すべての必要な少なくとも一つの信頼されたCAから発行されてサインされたものが必要になります。 クラスタで個別のノードがすべてのkeystore/truststoreを更新する必要性なしに。??\n通信チャネルを安全にする方法やSSL/TLS設定をどのように行うかはShieldのドキュメントをご覧ください。\nノード間認証 強く推奨しますが、許可されたノードだけがクラスタに接続できるようにするために、ノードの認証をSSL transportに設定することができます。 これは、shield.transport.client.authにtrueを設定することで可能です。 設定した場合、ノード間でSSLハンドシェイクが行われ、接続されたノードが接続に来たノードのクライアント認証を要求しチェックします。 もし、チェックに失敗した場合は、SSLシェイクハンドが失敗し接続が拒否されます。\nSSLクライアント認証 transportレベルでノード認証が必要なようなら、次のような疑問がわくでしょう。 Elasticsearchはクラスタに接続するTransportクライアントを使うときはどのように振る舞うのか? Transportクライアントはクラスタの他のノードと同じチャネルを使うため、コネクションを確立するときに、ノードが他のノードと異なるかどうかを見極めることはできません。\nこの時、もっとも単純な解決は、Transportクライアントも同様に許可を与えることです。 それは、認証を解決するときに、他の問題(潜在的な悪意)を引き起こします。 Transportクライアントが他のクラスタのノードを偽装しようとすることです。これは望んでいません。\n幸いなことに、良い解決方法があります。 トランスポートプロファイルです。 Elasticsearch 1.4で導入されたトランスポートプロファイルは、トランスポートレイヤー(異なるホスト/ポートにバインドされる)のために複数のネットワークチャネルを設定することができます。 Shieldはこのサポートを、プロファイルごとに異なるSSL設定をできるように拡張します。 また、ノードのタイプとクライアントプロファイルタイプの間に明確な違いを設定することも可能です。 これを用いると、2つのプロファイルを設定できるようになります。 ひとつは、クライアントのためのもので、もうひとつはクラスタのノードのためのものです。 これにより、クライアントのための認証の問題が必要なくなり、Shieldはクライアントプロファイルをもった限定されたクライアントからのリクエストを保証します。\nIPフィルタリング これは、厳密には、認証カテゴリではありませんが関係しています。 Shieldはそれ自身がIPフィルタリングのメカニズムを持っています。 これは、許可/不許可のIPのリストを設定することができます。 これらのフィルタリングのルールは複数のレベルで設定可能です。 transportチャネル、transportプロファイルレベル、そして、HTTPチャネルです。 次の設定は、それらの設定のサンプルです。(設定ファイルはelasticsearch.ymlになります)\nshield: transport.filter: allow: - \u0026#39;127.0.0.1\u0026#39; - \u0026#39;2001:0db8:1234:0000:0000:8a2e:0370:73 deny: - \u0026#39;10.0.0.0/8\u0026#39; - \u0026#39;2001:0db8:1234::/48\u0026#39; - \u0026#39;*.google.com\u0026#39; http.filter: allow: [ \u0026#39;10.0.0.0/8\u0026#39; ] deny: [ \u0026#39;127.0.0.1\u0026#39; ] transport.profiles: client: shield.filter.deny: [ \u0026#39;_all\u0026#39; ] このように、IPv4とIPv6、CIDR、ホスト名、ワイルドカードが利用できます。 また、この機能はホストOSのIPテーブルに設定することで追加できるが、Shieldにそれを保持し、それらの設定を単純化し、 デプロイの全体から除去できることにも注意してください(詳細はドキュメントのIPフィルタリングをご覧ください)。\n監査証跡(Audit Trail) セキュアなシステムの必須機能の一つで、監査硝石により、Elasticsearchに発生した重要なイベントをトラッキングすることが可能です。 これらのイベントを保存することは、Elasticsearchクラスタの重要なアクティビティの証拠を提供でき、 不審な/悪意のある可能性のあるイベントを追跡するときの診断ツールにもなります。\nShield 1.0.0で、監査証跡は監査/アクセスlogを一般的なElasticsearchのログとは個別に保存します。 それらは、構造化されているため、読んだりパースするのが容易で、イベントのタイプも分類されています。 また、情報のレベルを設定することができ、各イベントをlogレベルの設定で書き出すことができます。 以下が、イベントのリストです。\nanonymous_access_denied - 認証トークンがないユーザからのリクエストがあった時のログ authentication_failed - リクエストされたユーザの認証に失敗した時のログ access_denied - 認証されたユーザが許可されていない操作を実行した時のログ access_granted - 認証されたユーザが許可された操作を実行した時のログ tampered_request - 不正に書き換えられたリクエストが到着したのを検知した時のログ connection_granted - ノードもしくはtransportクライアントがIPフィルタのルールにパスした時のログ connection_denied - ノードもしくはtransportクライアントがIPフィルタリングルールの制限により却下された時のログ Shieldの監査証跡についてより詳しく知りたい方は、ドキュメントをごらんください。\n次のバージョンでは? ここまで紹介したように、これはまだ始まりにすぎません。 Shieldに追加される多くの機能があり、しっかりとした基盤を構築したところです。 Shieldの次のバージョンでは、以下の機能の追加にフォーカスするでしょう。(これらだけに限ったわけではありません。)\nAPIによる設定、管理 より拡張され、柔軟なLDAP/Active Directoryサポート レルムタイプの追加(kerberos、anonymous、certificatesなどなど) セッションベースの認証 ShieldはElasticsearch社の2番目の(Marvelに続く)商用プロダクトです。 ダウンロードして開発環境で評価してください。 インストールは他のプラグインと同様の方法です(インストール方法についての詳細はこちら)。 一度インストールすると、30日の試用ライセンスが始まります。 もし、さらに時間が必要な場合は、sales@elasticsearch.comまで連絡してください。\n私たちのすべてのプロダクトについてフィードバックをお待ちしています。 Shieldの商用利用、機能、ロードマップ、その他のセキュリティに関するトピックなど、質問がありましたら、 サイトからご連絡ください。\n","date":1425030596,"dir":"post/2015/","id":"cb13b64d0127c13bb466c4d4677a7b8a","lang":"ja","lastmod":1425030596,"permalink":"https://blog.johtani.info/blog/2015/02/27/you-know-for-security-shield-goes-ga-ja/","publishdate":"2015-02-27T18:49:56+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:you know, for security: shield goes ga 1/27にShield 1.0 をリリースしました。 Elasticsearc","tags":["elasticsearch","shield"],"title":"セキュリティ向けプラグインShieldのリリース(日本語訳)"},{"contents":"4月13日から3日間、ElasticsearchのCoreトレーニングが東京で開催されます。 Early Birdということで、3/14までに申し込みすると割引があります。 興味のある方は、見ていただければと。\nまた、4/15にElasticsearch勉強会を開催します。 トレーニングに弊社のエンジニアが来日しますので、なにか話をしてもらう予定です。\n募集は後日、Elasticsearch勉強会のDoorkeeperで行います。 興味のある方は、登録しておいていただければと。\nトレーニングや勉強会でお待ちしております。\n","date":1425024629,"dir":"post/2015/","id":"f2cbe07bf2ff16d5a5860b4d6edbc5e8","lang":"ja","lastmod":1425024629,"permalink":"https://blog.johtani.info/blog/2015/02/27/2nd-tokyo-training/","publishdate":"2015-02-27T17:10:29+09:00","summary":"4月13日から3日間、ElasticsearchのCoreトレーニングが東京で開催されます。 Early Birdということで、3/14までに申し込みす","tags":["elasticsearch"],"title":"Elasticsearch Coreトレーニング開催"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:kibana 4. literally.\nKibana 4は現在、文字通り、抽象的に、概念的に、精神的に、そしてとても楽しく、プロダクションレディになりました。 1週間前に準備はできていましたが、満足できるものであるという確信を得たいと思っていました。 そして、Kibana 4.0.0 GAをリリースしました。 次のものはサンプルのスクリーンショットと前日譚です。 これらに興奮してしまった方のために、2ステップのプランを用意しました。\nダウンロードする:Kibana 4 downloadsページからダウンロードします。 理解する:Kibana 4 docsページを読んで理解します。 Tip : もし、まだ、あなたのクラスタがElasticsearch 1.4.4でない場合は、アップグレードする必要があります。\nTip2 : Kibana 4 RC1からアップグレードする場合は、configを移行する必要があります。こちらのgistを参照\n前日譚 - the back story Kibanaはすでに問題解決のためのツールになっています。 なぜ、毎晩2時に呼び出されるんでしょう? そのコードがプロダクションに入ったのはいつですか? その結果、何を壊しました? 私たちはそれらを解決しました。 世界的に、長い間、だれも夜中の2時に呼び出されませんでした。知ってます?。\n*しかし、ここには落とし穴があります。*答えが簡単になれば、問題が難しくなります。 楽な勝利は簡単でした。では、難しい問題(深さが3層の問題)を解きましょう。 複数の要素、複数のフィールドそして、複数のデータソースを分析する必要がある問題を解きましょう。 Kibana 4は少ない時間と労力で最も難しい問題を解決してくれます。\nKibana 3で学んだことをKibana 4に取り込みました。 なぜ10億のデータを持っているのに、地図には1000個しかプロットできないのでしょう? 1つのチャートに1つのフィールドなんでしょう? なぜ、1つのパネルに1つのチャートなんでしょう? なぜ、1つのダッシュボードに1つのインデックスなんでしょう? 5つのシナリオを用意し、2つのフィールドにまたがったデータを比較し、 1つのダッシュボードに3つのインデックスのデータを表示してみましょう。 さぁ、やりましょう。終わったらアイスクリーム(トッピング付きの)を取りに行きましょう。\nthe plot アイスクリームのように、問題には多くの種類があります。 そのために、Kibanaをナポリ風アイスクリーム(3色アイス)のように分割しました。 嫌いな種類は除いて。 もし、あなたがKibanaのユーザ歴が長い場合、最初のタブのDiscoverがホームであることが正しく感じるでしょう。 これにより、短時間で、検索し、レコードを見つけ、簡単な問題を解決できます。 簡単な問題とは、すべてを物語る1行のデータを見つけることによって解決する問題です。\n物事が簡単な検索で説明できるものよりも複雑になった時、チャートとグラフで魔法を作る時間です。 Visualizeタブを開き、Elasticsearchのaggregationの力を利用してデータを解析しましょう。 Visualizeは複数の次元の性質のデータを見せ、今まで尋ねたことがないような質問に対して素早く回答するチャートやテーブル、 地図を作成できます。 あなたが最初に尋ねる質問は「先週サイトが遅かったのはなぜ?」でした。 しかし、データによって明らかにされた質問は「なぜ、クリスマスに東京からの平均ファイルサイズリクエストがスパイクしたのか?」です。\n最後に、Dashboardでこれらを1つにします。\n大きなスクリーンに配置して、こう言います。 「あなたの答えはこのリンクにあります。また、Wikiに埋め込んで、データをCSVにエクスポートしてメールしました。 アイスクリームを食べた後に、自叙伝の第1章を書きました。もっとアイスを持ってきてください。かき混ぜますから。」\nそれぞれのタブで見てきた詳細については、Kibana 4 Beta 1 : Releasedをごらんください。\nto be continued\u0026hellip; 居眠りをする時間はあります?いいえ、Kibana 4.1についてすでに作業中で、将来の大きなプランを持っています。 多くの労力はKibana 4の土台の安定と実用性を構築することに使われました。 また、Elasticsearchアプリケーションの将来を構築するプラットフォームを作りました。 すべてのものは拡張できるように設計されています。 例えば、可視化はより良くなるように構築されています。 オープンソースは私たちのGitHubアカウント以上のものです。 それは、新しく素晴らしいものを誰もが作ることができる構造を作ることが私たちの約束です。\nKibanaでグラフなどを構築したり、Elasticsearchを利用したアプリケーションを作成するために、 私たち開発者のブログを参考にしてください。 ちょっと見てみたいですか? Elastic{ON}15のSpencer Algerのトークをチェックしてください。\nあなた方なしでは、私たちはここにはいないですし、あなた方の助けがなければ何もできません。 ぜひ、GitHubでのissueや提案、貢献をお待ちしています。 もしくは、IRCでFreenodeの#kibanaに参加してください。\nextra credit Kibana 4のすべての話に興味がありますか?私たちのKibana 4ベータに関する過去のブログをチェックしてください。\nKibana 4 Beta 1: Released Kibana 4 Beta 2: Get it now Kibana 4 Beta 3: Now more filtery Kibana 4 RC1: Freshly baked 最後に、Kibanaの利用に関する話をお持ちなら、ぜひ聞かせてください。 stories at elasticsearch dot comもしくは@elasticsearchに連絡をください。 あなたの話を世界にどのようにシェアしているかごらんください。\n","date":1424408752,"dir":"post/2015/","id":"eee039f49a5b570599cf459c55c649f3","lang":"ja","lastmod":1424408752,"permalink":"https://blog.johtani.info/blog/2015/02/20/kibana-4-literally-ja/","publishdate":"2015-02-20T14:05:52+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:kibana 4. literally. Kibana 4は現在、文字通り、抽象的に、概念的に、精神的に、そしてとても楽しく","tags":["elasticsearch","kibana4"],"title":"Kibana 4(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:elasticsearch 1.4.4 and 1.3.9 released\n本日(2/20)、Elasticsearch 1.4.4とElasticsearch 1.3.9をリリースしました。 これはバグフィックスリリースとなります。 主に、Lucene expression scriptsを使う場合のRPMとDEBパッケージの パッケージング問題のフィックスをしたものです。 1.4.4のダウンロードこちらのリンクからアクセスできます。\nfixes 1.4.3のRPMおよびDEBパッケージにはAntlrとASMの依存関係の不足がありました。 この依存はElasticsearchでLucene expression scriptsを利用する場合に必要になります。 Groovyに関する1.4.3の変更により、多くのユーザがLucene explression scriptsを利用することが予想されるため、すぐに、1.4.4をリリースしました。\nまた、このリリースには、クラスタの保留タスクに関するいくつかのバグフィックスも含まれています。 さらに、date histogramで負のインターバルの場合にOutOfMemoryErrorを引き起こすバグも 修正されています。\nすべての変更については1.4.4のリリースノートおよび1.3.9のリリースノートをごらんください。\nフィードバック 私たちはフィードバックをお待ちしています。 Twitter(@elasticsearch)もしくはGitHub issues pageで教えてください。\n","date":1424408734,"dir":"post/2015/","id":"ddd3e6f6e298d3884abc4d888a043664","lang":"ja","lastmod":1424408734,"permalink":"https://blog.johtani.info/blog/2015/02/20/elasticsearch-1-4-4-and-1-3-9-released-ja/","publishdate":"2015-02-20T14:05:34+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:elasticsearch 1.4.4 and 1.3.9 released 本日(2/20)、Elasticsearch 1.4.","tags":["elasticsearch"],"title":"Elasticsearch 1.4.4および1.3.9リリース(日本語訳)"},{"contents":"来る、4月4日の土曜日の午後に名古屋でElasticsearch勉強会を開催予定です。 「初」の東京以外の勉強会です。\nTwitterでこのようなツイートを見かけまして。\n名古屋でElasticsearchの勉強会やりたい機運(今のところ2人)。\n\u0026mdash; mogami (@smogami) 2015, 2月 4 これは!ということで、名古屋で勉強会をやろうかと思います。30名程度の場所を借りて実施予定です。 募集はいつもの、elasticsearch勉強会のDoorkeeperで行う予定です。 ページの準備まで少々待ちください。(おそらく、3月中旬くらい) 私自身はElasticsearchやELKについて話をしようと思っています。そのほかに、2,3名のスピーカーの方を予定しています。 LTなど興味がある人がいたら、連絡ください。\nこれを機に(?)他の場所でも勉強会を開催したいと考えています。 ニーズがどのくらいありそうなのかが、まだよくわかっていませんが、関西などでニーズがあるんじゃないかと期待していたり。\n興味のある方は、コメント欄、Twitterなどでコンタクトしてもらえればと。 (連絡来るとうれしいなぁ。)\n","date":1424240573,"dir":"post/2015/","id":"5b97ead91c0dd0bad57b4f43a89149a2","lang":"ja","lastmod":1424240573,"permalink":"https://blog.johtani.info/blog/2015/02/18/preparing-elasticsearch-meetup-in-nagoya/","publishdate":"2015-02-18T15:22:53+09:00","summary":"来る、4月4日の土曜日の午後に名古屋でElasticsearch勉強会を開催予定です。 「初」の東京以外の勉強会です。 Twitterでこのよう","tags":["elasticsearch","勉強会"],"title":"名古屋でElasticsearch勉強会を開催します"},{"contents":"第8回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 次回もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\n今回は出足が好調で、早々に180人の枠を超えるという嬉しい事態でしたが、 キャンセル待ちが残っているにもかからわらず、来られていない方が67名もいるということで、キャンセル待ちの方には申し訳なかったです。 もうすこし、キャンセルをしてもらえると嬉しいんですが。。。 今回はメールを当日に1度しか打ってないからかなぁ。\nさて、いつもの通り簡単なメモです。 本当に簡単にですが。\n「Elasticsearch導入チェックリスト?」 Elasticsearch株式会社 Jun Ohtani @johtani スライド:Elasticsearch導入チェックリスト?\nElasticsearchを開発環境や本番に導入する前に気にかけて欲しいことについて発表しました。 元ネタはelasticsearch pre-flight checklistです。 少々古いのですが、私が今回話した内容以外にもモニタリングなどについての話も盛り込まれています。 時間がある方は、見ていただければと。\n「Elasticsearch クエリとスキーマ定義のすごい細かい話」株式会社ドワンゴ 藤堂淳也 さん スライド:Elasticsearch クエリとスキーマ定義のすごい細かい話\nフィールドのチェックを別途インデキシングするアプリで行っている。利用できるものだけElasticsearchに投げる 実際に本番環境で利用しているマッピングに対してフィールドを追加する手順について 「これもドキュメントに書いてあるんですが」という感じでドキュメントに色々書いてあるので読みましょうというありがたい発表でした。 実際に試行錯誤したり検証するときに行ったことを喋ってもらえたので、どういった点を気にしながら運用、設計するかというのがわかりやすかったです。\n「ElasticsearchとKibanaで実現する、30億req/dayのリアルタイム分析」株式会社サイバーエージェント 山田直行さん @satully スライド:ElasticsearchとKibanaで実現する、30億req/dayのリアルタイム分析\n会場が21時までしか抑えられていないという失態で、ドタバタしてて前半は聞けてないです。。。\n前回の発表では30日分Elasticsearchに入れていたが、今は3日分のみ保存 レポートなどにはRedshift+Tableauを利用 Kibana3をメインに使っているが、Kibana4も検討予定? QA\nQ:なぜ、ELBを挟んでいるのか? A:特に考えておいているわけではない。 Q:インデックスの構成は? A:1日に2つのインデックス。Bitされたもの、入札されないもの Q:searchのnodeをやめたのは? A:前回発表した勉強会での懇親会で話を聞いたり、他の方と話を聞いて、不要と判断したため 「はてなのメディア面を支えるElasticsearch」株式会社はてな 山家雄介さん @yanbe スライド:未定。おそらく、開発者ブログに公開されるかと。\n\u0008* アドテク系にもやってるらしい。BrandSafeはてな\nはてなブックマークのデータを魅せ方を変える機能などで大活躍。B!KUMAとか その日の話題の見出し自動生成機能。Significant Terms Aggregationsを利用。 こちらの「自然言語処理技術を用いたはてなブックマークの新機能「トピック」をベータリリースしました」エントリに関係あるのかな? 記事の魅せ方を検索できる管理画面ではElasticsearchのクエリDSLを活用されているとのことでした。 検索専門の人でなくても検索式を簡単にくみたてられる画面を用意して、ElasticsearchのクエリDSLに変換するようにしていると。 確かに、クエリをそのまま組み立ててもらうよりも利用しやすい画面がある方がいいですよね。バックエンドはJSとPerlのライブラリとのことでした。\nその他、感想などのブログ 2015-02-13 第8回 elasticsearch 勉強会 @ 丸の内 リクルート 41Fアカデミーホール [Elasticsearch] 第8回 elasticsearch 勉強会へ参加してきた 第8回elasticsearch勉強会 #elasticsearch #elasticsearchjp 第8回 Elasticsearch 勉強会に行ってきた #elasticsearch #elasticsearchjp 勉強会メモ - 第8回elasticsearch勉強会 まとめ 今回も検索からログまでいろんな話になったので、面白かったかと。 参加された方は新しい方が多かったんじゃないかなぁと。(集計結果で見れないのかな、Doorkeeper)。\n今回は、みなさんに21時に41Fから33Fへ移動していただくという大失態があったので、大変申し訳なかったです。 次回(4月中旬)は、このようなことがないように気をつけますので、今後もよろしくお願いいたします。\nあと、東京以外の勉強会も検討しつつあります。興味のある方はコメントやTwitterで反応をいただけると嬉しいです。\nスピーカーは随時募集中ですので、コメント、メール、ツイートなど、コンタクトしていただければと思います。 よろしくお願いいたします。\n","date":1424066543,"dir":"post/2015/","id":"997acc135d01b54f7de77a432fb9133f","lang":"ja","lastmod":1424066543,"permalink":"https://blog.johtani.info/blog/2015/02/16/8th-elasticsearch-jp/","publishdate":"2015-02-16T15:02:23+09:00","summary":"第8回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん","tags":["elasticsearch","勉強会"],"title":"第8回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:running groovy scripts without dynamic scripting\nElasticsearch1.3.8と1.4.3のリリースにより、デフォルトで、リクエストに含まれるGroovyスクリプトや インデックスに保存されたスクリプトを動的に実行する機能をオフにしました。 しかし、Groovyはまだデフォルトのスクリプト言語です。 本ブログ記事では、少しだけダイナミックだが、サンドボックスではない言語のためのスクリプトを どのように使い続けるかを説明します。\n本ブログ記事は、それが何を意味し、さらに重要なのは、安全に重要なタスクを実行させるためにスクリプトを どのように使用し続けるかを理解する助けとなるはずです。\nダイナミックスクリプトとは? Elasticsearchに詳しくない方のために、Elasticsearchでは、 さまざまなリクエストの一部としてスクリプトを送信することができます。 search、aggregation、update、upsert、delete by queryなどです。 あなたのユースケースのために、通常の動作よりも拡張した動作をさせるためにスクリプトを追加できます。\n例えば、以下のリクエストは、ダイナミックスクリプトを含んでいます。 field1とfield2 + shiftが同じ値を持っている時だけドキュメントを返します。\nGET /_search { \u0026#34;query\u0026#34;:{ \u0026#34;filtered\u0026#34;:{ \u0026#34;filter\u0026#34;:{ \u0026#34;script\u0026#34;:{ \u0026#34;script\u0026#34;:\u0026#34;doc[\u0026#39;field1\u0026#39;].value == (doc[\u0026#39;field2\u0026#39;].value + shift)\u0026#34;, \u0026#34;lang\u0026#34;:\u0026#34;groovy\u0026#34;, \u0026#34;params\u0026#34;:{ \u0026#34;shift\u0026#34;:3 } } } } } } 言語を変えることもできます。 それは、当然、シンタックスが変わったり、制限が追加(例えば、Groovyスクリプトの代わりにLucene Expressionsに変更)されることもあります。 langパラメータによって言語を指定できます。\nなぜそれはダイナミック? 上記の例はダイナミックスクリプトです。 それは、実際のスクリプトの部分はサーバサイドで動的に解釈されコンパイルされる必要があるからです。 ダイナミックスクリプトはElasticsearchのAPIによってデータノードに送信されます。 これは、インデックスされたスクリプト(indexed script)も含みます。\n言い換えると、もし、スクリプトがデータノード全てに保存されていなければ、 それは、ダイナミックスクリプトとして扱われます。\ndynamic scriptingをオフにするとどうなるか? 最新のリリースでの変更により、Groovyのdynaic scriptingはデフォルトでオフになりました。 先ほどのスクリプトについても同様で、もし、先ほどのリクエストを実行すると、次のようなエラーが発生します。 (一部省略してあります。)\n{ \u0026#34;error\u0026#34;:\u0026#34;SearchPhaseExecutionException[Failed to execute phase [query], all shards failed; shardFailures {[8FJ02MofSnqVvOQ10BXxhQ][test][0]: SearchParseException[[test][0]: from[-1],size[-1]: Parse Failure [Failed to parse source [{...}]]]; nested: ScriptException[dynamic scripting for [groovy] disabled]...\u0026#34;, \u0026#34;status\u0026#34;:400 } エラーメッセージの重要な箇所は「ScriptException[dynamic scripting for [groovy] disabled]」です。\nスクリプティングを使い続けるには? Elasticsearchでスクリプトを実行するには3つの方法があります。 2つのダイナミックな方法は、リクエストごとのスクリプト(上述)かインデックスされた スクリプト(indexed script)を使う方法です。 インデックスされたスクリプトを使うことは、Elasticsearch自身にGroovyスクリプトを保管することで 利用で、それらを要求に応じて利用することです。 (これは、実際には十分機能しますが、これではまだ、信頼できないユーザに対して彼らのスクリプトを実行できます) RDBのように保存されたプロシージャとして同じ方法で実行させるものと同様です。 前もって、スクリプトを記述しておき、リクエストの一部として後から、名前で呼び出して実行可能です。\nGET /_search { \u0026#34;query\u0026#34;:{ \u0026#34;filtered\u0026#34;:{ \u0026#34;filter\u0026#34;:{ \u0026#34;script\u0026#34;:{ \u0026#34;script_id\u0026#34;:\u0026#34;your_custom_script\u0026#34;, \u0026#34;lang\u0026#34;:\u0026#34;groovy\u0026#34;, \u0026#34;params\u0026#34;:{ \u0026#34;shift\u0026#34;:3 } } } } } } あまり変わっていないことに気づくでしょう。 scriptの部分が、前もって記述されたスクリプトの名前script_idに変更されただけです。\nElasticsearchにスクリプトを提供するダイナミックではない方法はインデックスに保存する代わりに、 ディスクにファイルとしてスクリプトを保存することです。 そうすることで、各スクリプトを設定として保存します。 これは、どのようなスクリプト言語に対してもダイナミックスクリプティングをオフにしたまま、 サンドボックス化されないスクリプトを使い続けることができる方法です。\n最初のサンプルで、Groovyスクリプトはdoc['field1'].value == doc['field2'].value + shiftでした。 これを、.groovy拡張子を持ったファイルとして書き出すことができます。\ndoc[\u0026#39;field1\u0026#39;].value == (doc[\u0026#39;field2\u0026#39;].value + shift) もし、このファイルにyour_custom_script.groovyちう名前をつけて、 Elasticsearchのすべてのデータノードのconfig/scriptsディレクトリに保存すると、 Elasticsearchは60秒(elasticsearch.ymlのwatcher.intervalで変更可能)でこのスクリプトを認識し、今後のリクエストに利用できるようにプリコンパイルするでしょう。 そのファイルはElasticsearch実行ユーザによって読み込みができる必要があります。 これをディスクに書き込んだ後、あなたの設定ディレクトリは次のようになっています。\nconfig/ elasticsearch.yml logging.yml scripts/ your_custom_script.groovy これは、各リクエストやインデックスされたスクリプトをスクリプトとして動的に送信しませんが、 信頼された環境にスクリプトを追加することでダイナミックスクリプトとなることを許します。\nディスクに書かれたスクリプトを使用する スクリプトは、ロードされたスクリプトになるまでは、利用できません。 ログファイルに次のようなログが表示されるまではです。\n[2015-02-11 11:14:47,066][INFO ][script ] [Sergei Kravinoff] compiling script file [/path/to/elasticsearch-1.4.3/config/scripts/your_custom_script.groovy] すべてのElasticsearchのデータノードでスクリプトが読み込まれたら、 それを利用することができます。 利用するために、file(script_idではありません!)としてスクリプト名を指定します。\nGET /_search { \u0026#34;query\u0026#34;:{ \u0026#34;filtered\u0026#34;:{ \u0026#34;filter\u0026#34;:{ \u0026#34;script\u0026#34;:{ \u0026#34;file\u0026#34;:\u0026#34;your_custom_script\u0026#34;, \u0026#34;lang\u0026#34;:\u0026#34;groovy\u0026#34;, \u0026#34;params\u0026#34;:{ \u0026#34;shift\u0026#34;:3 } } } } } } Note:langは必須ではありません。Groovyがデフォルトの言語のためです。 もし、違うスクリプト言語を使いたい、もしくは、デフォルトの言語を(例えば、Lucene Expressionsへ) 変更したい場合、言語が正しいスクリプトを見つけるために提供されている必要があります。 一番良い方法は、アプリケーションがlangパラメータを含んでいることを勧めます。 これは、将来、デフォルトのスクリプト言語が変更されても、問題ないからです。\n質問? もし、質問があれば、遠慮なくTwitter(@elasticsearch)で教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1423721589,"dir":"post/2015/","id":"1fed22e99b0e11a50eb7b92cb1644e8a","lang":"ja","lastmod":1423721589,"permalink":"https://blog.johtani.info/blog/2015/02/12/running-groovy-scripts-without-dynamic-scripting-ja/","publishdate":"2015-02-12T15:13:09+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:running groovy scripts without dynamic scripting Elasticsearch1.3.8と1.4.3のリリースによ","tags":["elasticsearch"],"title":"Groovyスクリプトをダイナミックスクリプトなしで実行(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:elasticsearch 1.4.3 and 1.3.8 released\n本日、Lucene 4.10.3をベースにしたElasticsearch 1.4.3と、セキュリティとバグフィックスリリースである、Elasticsearch 1.3.8をリリースしました。 ダウンロードおよび変更リストはそれぞれ次のリンクからアクセスできます。\n最新ステーブルリリース:Elasticsearch 1.4.3 1.3.x系バグフィックス:Elasticsearch 1.3.8 過去のリリースに関するブログ(公式)はこちら。\n1.4:1.4.2, 1.4.1, 1.4.0, 1.4.0.Beta1 1.3:1.3.7, 1.3.6, 1.3.5, 1.3.4, 1.3.3, 1.3.2, 1.3.1, 1.3.0. すべての変更については1.4.3のリリースノートおよび1.3.8のリリースノートをごらんください。 以下では、セキュリティの問題について紹介します。\ngroovy scripting の脆弱性 Elasticsearchのバージョン1.3.0から1.3.7および1.4.0から1.4.2で、Groovyスクリプトエンジンに脆弱性が発見されました。 脆弱性は、攻撃者がGroovyスクリプトをサンドボックスを避けて構築でき、 ElasticsearchのJava VMを実行しているユーザとしてシェルコマンドを実行できます。\nこの問題をCVE-2015-1427として報告済みです。\nバージョン1.3.8と1.4.3では、デフォルトで、Groovyに対してのサンドボックスをオフにしました。 結果として、ダイナミックスクリプトの実行はGroovyに対してもオフとなります。\nもし、脆弱性のあるバージョンで実行している場合、v1.3.8かv1.4.3にアップグレードするか、ダイナミックなGroovyスクリプトをクラスタの すべてのノードに対して次の設定を追加することで、オフにします。\nscript.groovy.sandbox.enabled: false これは、Groovyのサンドボックスをオフにし、リクエストの一部としてインラインで受け付けるダイナミックなGroovyスクリプトや 特殊な.scriptsインデックスに保存されているスクリプトを実行しません。\nそれまでは、各データノードのconfig/scriptsディレクトリにファイルとして保存されたGroovyスクリプトは まだ、利用可能です。詳細の情報についてはRunning scripts without dynamic scriptingをごらんください。\nfuture scripting plans 安全なダイナミックスクリプティング言語としてGroovyを失うことは、Elasticsearchにとって痛手です。 update APIやsearch APIやaggregationsフレームワークの一部としてScriptを使います。 それらは、静的なAPIでは簡単に表現できない、カスタムなトリックをユーザに実行できるようにします。\n残念ながら、Groovyチームとこの問題を議論した後、Groovy言語もサンドボックスによってきちんと保護されている というにはあまりにもダイナミックであるという結論に達しました。 Groovyは、デフォルトでは利用できなくなります。 利用可能なダイナミックスクリプト言語としてはLucene Expressions言語のみとなります。 Expressionsははやいですが、それらは非常に限定されています。数値のフィールドでのみ実行可能で、ループをサポートしていません。\nより強力で(しかし安全な)ミニ言語になるようにExpressionsを拡張することを調査しています。 これは、Scriptユーザが現在持っている最も一般的なユースケースを少なくとも助けるでしょう。 この拡張は長期間のプロジェクトであり、進化には時間がかかるでしょう。\nぜひ、Elasticsearch 1.4.3をダウンロードして、試してみてください。 そして、感想をTwitter(@elasticsearch)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1423712393,"dir":"post/2015/","id":"5badf61ecb9cfadd7d6af58712fa5f6f","lang":"ja","lastmod":1423712393,"permalink":"https://blog.johtani.info/blog/2015/02/12/elasticsearch-1-4-3-and-1-3-8-released-ja/","publishdate":"2015-02-12T12:39:53+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:elasticsearch 1.4.3 and 1.3.8 released 本日、Lucene 4.10.3をベースにしたElas","tags":["elasticsearch"],"title":"Elasticsearch 1.4.3および1.3.8リリース(日本語訳)"},{"contents":"今年もCROSS参加しました。そして、話もしてきました。 今年は横浜の大さん橋でした。横浜はあんまりこないので、乗り換えでおたおたしてしまいましたが。。。\nなかなかいい景色でした。(寒いけど) 「おおさんばし」って読むんですね。「だいさんばし」だと思ってた。。。\n以下はいつもの、自分用メモです。\n俺はどうしてそのデータストアを選択したのか 〜銀河と小宇宙を語る会〜 http://2015.cross-party.com/program/c1\n遅れて入ったので、ちゃんと聴けてないです。\n最近注目しているデータストアは? Postgresql。JSON型が気になってる。 AiroSpike。データ型のあるデータストアが気になってる。 MongoDB。JSON使いたいなら、これじゃないの? AWSのAurora。インスタンスタイプを選ばなくていい(選ばないといけないらしい)とか、勝手にスケールしてくれるし、MySQL互換。 今こそ語るエンジニアの幸せな未来 http://2015.cross-party.com/program/x3\n「無職初日です。」 Web系の人?とか質問されて、自分が何系かいつもわからなくなるなぁ。 「働きがいは会社が提供するのか、個人が見つけるのか?」 個人かなぁ。会社がなにをやってるかにもよる気がするかなぁ。 「辞めると伝えると、やりたいようにやれって言われるw」 リモートできるかできないか。 「働きがい」というキーワードが出てると普通は怪しい会社w 今は、働きやすさを高くしないと人が雇えなくなってきている。 欧米のミドルウェアだと、35歳定年説はない。→日本でもそうじゃないですか? 漫然と進んでるとダメ。→そりゃそうだ。 全文検索エンジン群雄割拠〜あなたが使うべきはどれだ!〜 http://2015.cross-party.com/program/c4\nスライド:https://speakerdeck.com/johtani/elasticsearchfalseshao-jie-tote-zheng-cross-2015\n楽しんでいただけましたでしょうか? ちょっと話が長くなってしまい、あとの方の時間が少なかった気がしますが。。。\nKibanaのバックエンドとして認識されている人もいたので、検索エンジンですよというのをアピールするいい機会になったので良かったです。 もちろん、Kibanaとの組み合わせも面白いので、少しでも興味をもっていただき、触っていただけたらなぁと。\n話をする機会を用意していただいた、やまかつさん、その他のスピーカーのみなさん、ありがとうございました!。\nElasticsearchに関して何か興味質問などありましたら、気軽にコンタクトしてください。Twitterとかブログコメントなどで。\nプレモルタイム以降 プレモルの写真撮るの忘れてました。。。重要なのに。。。\n美味しくプレモルをいただきながら、何人かの方に声をかけていただき、話をすることができました。 こういう時間がとってあるのがいいですよね。 色々なところでElasticsearchを使っていただいているようで、うれしい限りです。 DMMの方とも話ができたし。\nまとめ 今年はプレモルを飲みに行くだけかなぁと思っていたのですが、話をする人になってました。(おかしいなぁ) 来年もあれば、きっと参加するかなぁと。ではまた来年!\n夜景きれいですね。(端っこに写ってる船は飛鳥IIでした。)\n","date":1422500368,"dir":"post/2015/","id":"fe6ba10cc6c9509b4b22e9d59e029775","lang":"ja","lastmod":1422500368,"permalink":"https://blog.johtani.info/blog/2015/01/29/talk-at-cross2015/","publishdate":"2015-01-29T11:59:28+09:00","summary":"今年もCROSS参加しました。そして、話もしてきました。 今年は横浜の大さん橋でした。横浜はあんまりこないので、乗り換えでおたおたしてしまいま","tags":["勉強会","elasticsearch"],"title":"CROSS 2015で話をしてきました #cross2015"},{"contents":"今年は大晦日になってしまいました。しかも、ちょっと飲んでたり。。。 第9流しながら書いてます。\n振り返り(2013年に書いた抱負から) まずは昨年書いた抱負からの振り返りです。\nElasticsearch勉強会の継続、Solr勉強会の継続+ミックスした検索勉強会の開催 IDEAのさらなる活用 もっと開発(プラグインとか) AWSをもう少し活用 海外のイベントに行ってみたい 読書と英語を継続 AWS活用できてないです、、、 ミックスした勉強会は、ドタバタしててできませんでした。\nIDEAはさらなる活用までいってるかは不明ですが、最近は隣にとても詳しい人が座っているので色々と教えてもらってます。 開発については、ちょっとずつですが、PR書いたりしてます。\n振り返り(今年あったできごと) 初海外(ベルリンとアムステルダム) Elasticsearchに転職 初献本? Elasticsearch勉強会の定期開催 ElasticSearch Serverの翻訳 サーバ/インフラエンジニア養成読本の執筆 勉強会以外でもスピーカー 英語の継続(切実) 初ものが多かったです。 初の海外の会社、初の海外旅行(仕事)、初の献本(著者の人から、多分、初)、初の翻訳本、初のムック本執筆などなど。\n初の海外でした。なのに、夏には海外の会社に転職してみてるとか、ちょっと自分でも信じられません。 ベルリンでは、海外の勉強会にも参加できて非常に有意義でした。 ヨーロッパの街並みは、日本では経験できない雰囲気で、向こうの方には普通の街並みも自分にはとても新鮮でした。\n転職自体は2回目ですが、海外の会社というのは初めてです。日々、英語\u0008の勉強になりますし、いろんな刺激を受けています。 英語の勉強自体も継続中です。英語力が不足しているのは自覚してるので、少しでも英語に触れるようにDLifeで海外ドラマを録画して、通勤時間帯にみるなどを試みてます。\n書籍には、昨年につづき関わることができました。来年も何かしらの書籍に関われることができればなと。 (\u0008気になる人は以下のリンクから。。。)\n分かりきったことですが、Elasticsearchな1年でした。 転職してあっという間の半年です。まだまだやりたいことがいっぱいあるので、来年もバランスよく頑張らないと。\n来年の抱負 英語の継続 海外のイベントへの参加 多岐にわたるイベントでのスピーカー 日本の人員の倍増!? Elasticsearchに関する日本語の情報発信 Elasticsearch座談会みたいなものの開催 英語の継続については書くまでもないですね。 海外のイベントへの参加もかなぁ。3月にサンフランシスコに行くとは思います。 そのほかには、今度こそBerlin Buzzwordsに行きたいです。\nElasticsearch勉強会以外のイベントでもElasticsearchを広めるべく色々なところでスピーカーをしたいなと思っています。 検索、ログ解析で少しは知名度が上がってきていますが、別の言語のコミュニティやイベントでは、まだまだ、elasticsearch自体を知らない人もいると思います。まずは知ってもらうところからかなと。\n日本の人員の倍増については、今年も達成してます(一人が二人になりましたw)。 来年も倍増できればうれしいなと。同じ母国語の同僚がいるのはやっぱりうれしいし、心強いですから。\n来年は(も)、日本語での情報をどんどん発信していきます。サイトやガイドなども 日本語にしたいなと。 あとは、これまで、勉強会でスピーカーをしていただいた人だけを集めた座談会のようなものも開催したいなと考えています。 私自身も色々と聞きたいことがありますし。 そのほかにも色々と要望をお待ちしています。Twitterやブログのコメント欄などで気軽にコンタクトしていただければと。\n最後は、いつものようにですが、来年も勉強会やいろんなイベントに参加する予定です。 ブログも週1程度で書く努力しないとなぁ。 こんな話を書いてくださいとかのリクエストもお待ちしています。\n今年はあと、数時間ですが、色々とお世話になりました。 この場を借りてお礼申し上げます。\n来年も、いろんな方に絡んでいくとは思いますが、よろしくお願いいたします。\n","date":1420026086,"dir":"post/2014/","id":"b36abffbe5d6a0de73a9968604a1a3f9","lang":"ja","lastmod":1420026086,"permalink":"https://blog.johtani.info/blog/2014/12/31/looking-back-2014/","publishdate":"2014-12-31T20:41:26+09:00","summary":"今年は大晦日になってしまいました。しかも、ちょっと飲んでたり。。。 第9流しながら書いてます。 振り返り(2013年に書いた抱負から) まずは昨年","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2014)"},{"contents":"この記事はElasticsearch Advent Calndar 2014の25日目のエントリです。\nあっという間に最終日です。来年につなげるという意味で、Elasticsearchの2系のIssueをいくつかピックアップして紹介してみます。\n現在、ElasticsearchのGitHubリポジトリは、大きく3つのブランチで作業しています。 master、1.x、1.4です。masterと1.xの大きな違いとしては、masterはLuceneの5.x系を採用している点です。\nなお、これから紹介するIssueは現在、確定していない項目も含んでいます。実際に2.0がリリースされるタイミングでは 採用されない場合もあります。\nUpgrade master to lucene 5.0 snapshot #8347 (closed) https://github.com/elasticsearch/elasticsearch/pull/8347\n先ほど書きましたが、Luceneの5に対応するためのPRです。 Lucene 5に関してはLuceneのコミッターのMikeさんのブログ記事も参考になります。\nLucene 5に変更することで、BitSetに関する改善が多く含まれることになります。 メモリの利用量、圧縮などの改善が多く含まれています。 もう1点大事な点としては、Lucene 5系ではLucene 3系のインデックスを読み込むことができなくなる点です。 Luceneの下位互換の範囲は1つ前のメジャーバージョン(5.x系の場合は4.xまでが対象)となっています。\nFilter cache: add a _cache: auto option and make it the default.(closed) https://github.com/elasticsearch/elasticsearch/pull/8573\nFilter cacheは、trueもしくはfalseの設定が利用できますが、filterの種類にも依存します。 その辺りの条件を加味しつつ、よしなにCacheをコントロールしてくれます。\nRemove and/or/not in favour of bool filter #8960(open / discuss) https://github.com/elasticsearch/elasticsearch/issues/8960\n似ているが少し異なるand、or、notフィルタとboolフィルタが存在しています。 これらをわかりやすくするために、boolフィルタに統一しましょうという話し合いをしています。\nInput validation #9059(open / discuss) https://github.com/elasticsearch/elasticsearch/issues/9059\n色々な入力に関するチェックを追加しようというIssueです。 たとえば、ディレクトリ名やファイル名、URLのパスやクエリストリング、フィールドのパスやスクリプトなどです。 Validationがあると、変な設定をして頭をかかえることもなくなるかなぁと。\nRefactor analysis framework #8961(open) https://github.com/elasticsearch/elasticsearch/issues/8961\n新しくAnalyzerを作った場合に、色々な場所に登録必要があったりします。インデックスレベルとノードレベルです。(Kuromojiプラグインなどが参考になります。) また、インデックスごとにカスタムのAnalyzerを設定するので、1つのノードに同じAnalyzerを何度も設定しないといけません。 よりシンプルにするために、Analyzerをノード単位で設定しようという提案です。\nRemove possibility for conflicting field definitions and ambiguous field resolution #8870(open) https://github.com/elasticsearch/elasticsearch/issues/8870\n同じインデックスに、異なるtypeで、同じフィールド名があった場合、いろいろと良くないことがあったりします。 たとえば、フィールドのタイプがintegerとstringと異なる場合に、インデックスレベルで検索を行うとうまく検索できなかったりと。 この問題を解消するために、より明確にしようというIssueです。 たとえば、フィールド名を指定するためには、フルパスで記述をするだとか、フィールドマッピングに関してはインデックスレベルで内部で保持をするなど。\nValidation of mappings request to reject unsupported fields #7205(closed) https://github.com/elasticsearch/elasticsearch/issues/7205\n1.xでも取り込まれますが、嬉しい機能なので紹介します。 これまでは、mappingsでスペルミスをした場合(たとえば、field設定で\u0026quot;indexx\u0026quot;といったミス)には、その項目は単に無視されるだけでした。 これが、v1.xでは、エラーに\nまとめ ということで、簡単ですが、v2.0.0に向けたIssueをピックアップして紹介してみました。 上記以外にも多くの改善、提案が2.0に向けて行われています。 興味のある方は、v2.0.0ラベルでIssueを検索してみてはいかがでしょうか?\n今年もあとわずかとなりました。 今年の2月にElasticsearchの1.0がリリースされ、あっという間に1.4なりました。まだまだ改善しています。\n来年もElasticsearchに興味をもっていただければ嬉しいです。 Elasticsearch初のユーザカンファレンスのサイトもオープンしました。 Elasticsearchに関するいろいろな話が聞ける機会だと思います。登録をお待ちしています。\n","date":1419490380,"dir":"post/2014/","id":"cb9649eca3dfbd356527ffc88f1dcb94","lang":"ja","lastmod":1419490380,"permalink":"https://blog.johtani.info/blog/2014/12/25/pickup-elasticsearch-2-0-0-labels/","publishdate":"2014-12-25T15:53:00+09:00","summary":"この記事はElasticsearch Advent Calndar 2014の25日目のエントリです。 あっという間に最終日です。来年につなげるという意味で、Elasti","tags":["elasticsearch"],"title":"Elasticsearch 2.0系のIssueの紹介"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:marvel 1.3.0 released\n12/17に、Elasticsearch Marvel 1.3.0をリリースしました。 Marvelの以前のリリースから、Elasticsearchでは様々なことがありました(Elasticsearch 1.4のリリースなど)。 このバージョンでは、モニタリングにクエリキャッシュや新しいcircuit breakerなどのような機能を追加してあります。 Senseのナレッジベースは最新のAPIを含むものに拡張されています。 また、Shieldのリリースに向けた準備として、HTTPsのサポートも追加しました。\nアップグレードのために、Elasticsearchの全てのノードに最新版のMarvelプラグインをインストールする必要があります。 また、他のJavaプラグインと同様に、Marvelの新バージョンを有効にするために、各ノードを(1台ずつ)リスタートする必要があるでしょう。 アップグレードプロセスについての詳細は、Marvelドキュメントをごらんください。\nまとめとして、ここに本リリースに関する改善点をいかにリストアップしておきます。\nagent 追加: httpsのサポート デフォルトのMarvelの設定(以前は常に9200)ではなく、ローカルノードのポートを自動的に検出 改善: marvelインデックステンプレートに関するエラーチェックと耐障害性(それに対するチェックと追加時のチェック) エラーログに関するくり返しの抑制 URLパラメータによるインデックス名を指定する_bulk exportコマンド。これは、rest.action.multi.allow_explicit_indexがfalseに設定されているときに有用 修正: ES 1.4.0のtribe nodeがMarvelのインストール時に初期化されない問題 削除: UIで表示されないoptional shard level statsを除去 monitoring ui 追加: ES 1.4.0で導入された新しいcircuit breakerを追加 circuit breakerのlimitをグラフにプロット QueryCacheのグラフを追加 index throttlingのグラフの追加 Index writerとバージョンのmapのメモリ使用量のグラフの追加 修正: Network Transport Bytes Receivedグラフに実際の送信量を表示 Node Statsダッシュボードでいくつかのスレッドプールの不足 sense 追加:\nmappingsをインデックスでオートコンプリートするしないの設定を可能に Cluster Reroute API Search APIのQuery Cacheパラメータ Analyze API Validate Query API Put Percolator API cluster.routing.allocation.*設定 Function Scoreクエリのweightパラメータ Flush API Terms Aggregationのshow_term_doc_count_errorパラメータ Update API _geo_distanceソートオプション Significant Terms aggregationを1.4.0にアップデート Mapping APIにメタデータフィールドを追加 Get Index API Scripted Metric Aggregation simple_query_stringクエリ More Like Thisクエリを1.4.0にアップデート has_childクエリ/フィルタのmin_childrenとmax_childrenオプション terms aggs/significant terms aggsのヒントオプション Mappings APIのtransform インデックスされたscriptとtemplate \u0008* Geo Bounds aggregation Top Hits aggregation Terms aggregationのcollect_modeオプション Percentiles Rank aggregation Disk Threshold Allocator設定 修正:\nURLオートコンプリートの挙動(プロトコルとホストのような組み合わせ) nested typeマッピングのinclude_in_parentとinclude_in_rootの不足 Rangeフィルタでのgt、gte、lt、lte Existsフィルタのオートコンプリート Snapshot、Restore APIのリポジトリ設定の時オートコンプリートの失敗 いつものように、Elasticsearch Marvelを改善するために、フィードバックをお待ちしています。 ElasticsearchユーザMLやTwitterに質問や意見お送りください。\n","date":1418890008,"dir":"post/2014/","id":"7dea465ad52758b10cbceb08c81d1760","lang":"ja","lastmod":1418890008,"permalink":"https://blog.johtani.info/blog/2014/12/18/marvel-1-3-0-released-ja/","publishdate":"2014-12-18T17:06:48+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:marvel 1.3.0 released 12/17に、Elasticsearch Marvel 1.3.0をリリースしました","tags":["elasticsearch","marvel"],"title":"Marvel 1.3.0リリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:elasticsearch 1.4.3 and 1.3.8 released\n本日、Lucene 4.10.3をベースにしたElasticsearch 1.4.3と、セキュリティフィックスとバグフィックスリリースである、Elasticsearch 1.3.8をリリースしました。 ダウンロードおよび変更リストはそれぞれ次のリンクからアクセスできます。\n最新ステーブルリリース:Elasticsearch 1.4.3 1.3.x系バグフィックス:Elasticsearch 1.3.8 過去のリリースに関するブログ(公式)はこちら。\n1.4:1.4.1, 1.4.0, 1.4.0.Beta1 1.3:1.3.6, 1.3.5, 1.3.4, 1.3.3, 1.3.2, 1.3.1, 1.3.0. すべての変更については1.4.2のリリースノートおよび1.3.7のリリースノートをごらんください。 以下では、重要な変更について紹介します。\nbug fixes Elasticsearchに対して広範囲にわたってランダムなテストを行っています。以下の問題を見つけ、修正するのに役立っています。\nプライマリシャードを持つnodeがレプリカシャードをプライマリから復旧している間に、リスタートした場合に、プライマリ上のトランザクションログが削除されデータをロスする(#8917) scriptインデックスが普及した場合に、ScriptService全体がデッドロック(#8901) Index Writerのロックを強制的に解放することによるシャードの破損(#8892) パフォーマンス改善 複雑な設定をもつ大きめのクラスタをもつユーザは、小さなスケールではわからない性能ボトルネックに直面します。 彼らの報告が次の改善をもたらす助けとなりました。\n使用可能なディスク空間に基づいてシャードの配置を決定する、disk allocation deciderの速度改善とクラスタリスタート後のリカバリ速度の改善(#8803) 以前よりも高速な共有ファイルシステムでのSnapshot生成(#8749) 不要なクラスタ状態変更の削減とそれによるネットワークトラフィックの削減およびリカバリの速度向上(#8933, #8413) index stats APIはシャードリカバリによるブロックしない(#8910) 試してみてください。 ぜひ、Elasticsearch 1.4.2をダウンロードして、試してみてください。 そして、感想をTwitter(@elasticsearch)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1418880374,"dir":"post/2014/","id":"bce2fa6458f39a75e2713f3d687271a1","lang":"ja","lastmod":1418880374,"permalink":"https://blog.johtani.info/blog/2014/12/18/elasticsearch-1-4-2-released-ja/","publishdate":"2014-12-18T14:26:14+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:elasticsearch 1.4.3 and 1.3.8 released 本日、Lucene 4.10.3をベースにしたElas","tags":["elasticsearch"],"title":"Elasticsearch 1.4.2および1.3.7リリース(日本語訳)"},{"contents":"「【東京】JJUG ナイト・セミナー「機械学習・自然言語処理特集!」12/17(水)開催」でLuceneの話をしてきました。 本当にごく簡単な入門です。 Luceneをさわるきっかけにしてもらえたら嬉しいです。\nそのほかにも面白い話が聞けましたので、簡単ですがメモを。\nJJUGの2014年振り返り だいたい、毎月ナイトセミナーかCCCを開催 イベント系に、のべ3100名が参加 Java でカジュアルにはじめる機械学習 小宮 篤史さん(スマートニュース株式会社) スライド:#JJUG - Java でカジュアルにはじめる機械学習\nブログ:#JJUG ナイトセミナー「機械学習・自然言語処理特集!」で Java でカジュアルに機械学習する話をしてきました\nガチの人は寝ててください。 機械学習でできること 分類・識別 予測・回帰 パターンマイニング・アソシエーションルール クラスタリング 上2つは教師あり学習/下2つは教師なし学習 データとしては、日構造では扱えないので、「特徴量」を抽出して「特徴ベクトル」を作って、処理をするのが機械学習 得られた結果の正しさの測定などなど\n機械学習の実装は辛いので、車輪の再発明をやめましょう! \u0008Javaで使える機械学習\nWeka:とりあえず使ってみるならこれ? MLlib:Sparkで使われてる Mahout:オワコン? SAMOA:Stormの上で利用できる Jubatus:Javaクライアントあり。 h2o:Deep learningをJavaでやるなら、これ。 ほかにもあったけど、スライド見ていただければ。 機械学習をはじめるのに使えるデータセット\nUCI Machine learning repository\nIris(アヤメデータ)は機械学習界のHello world Wekaを使ったサンプルコード\nSpark/MLlibではじめるスケーラブルな機械学習 猿田 浩輔さん(株式会社エヌ・ティ・ティ・データ) スライド:(後日、リンクがあれば更新予定)\n\u0008* Spark+MLlibを語る上で外せない話題\nHadoopとの違い?\nまずはHadoopの話\nHadoopによるK-meansのデモ\nHadoopの問題点に対するSparkの解決策\nSpark 1.0系からJava8で書ける\nQA:\nQ: データをキャッシュできるという話でしたが、キャッシュするということは、ジョブが途中で失敗した場合は最初からやり直しになるのでしょうか? A: キャッシュしたデータが残っている場合は、途中から再開出来ます。キャッシュしたデータを持ったマシンがこけたら、最初からやり直しです。\nLuceneと日本語の検索 自分 スライド:Luceneと日本語の検索 サンプルのリポジトリ:jjug-example\n自然言語処理にからめて何か話をしてくださいと話を受けていたのですが、自然言語処理については「形態素解析」くらいしか出てこなかったですけど。。。 Luceneがどんなものかを超概要で話をしてみました。少しでもLuceneがどんなものかをわかってもらえたら嬉しいです。\nもっと詳しく知りたい方は、スライドにある参考資料などを見ていただければと。\nJavaで書くのもいいんですが、もっと簡単に検索したい場合はElasticsearchを使うのが便利ですよ!で締めくくりたかったのですが、発表では失敗してしまいました。。。 Elasticsearchの起動からデータ登録、検索まではこちらのスライドを見ていただければ簡単さがわかると思います。\nまた、Kuromojiを利用した時に、Tokenizerなどが出力するTokenの品詞情報を見たい場合に便利なElasticsearch用プラグインも作っています。 こちらも、Elasticsearchと一緒に使ってみてください。\nまとめ 機械学習に関していろんなツールがあるのだなぁと。 懇親会でもちょっと話しましたが、アルゴリズムの選定とか、アルゴリズムに適したデータの作成など、前処理のノウハウとかが大変そうだなぁといつも思います。 機械学習はいつもぼやーっとしか理解してないので。。。\nJJUGさんはYouTubeの動画もあるようなので、過去の面白そうなセミナーも合わせてみてみると面白いと思います。\n毎度のことですが、なんでも良いので、発表した後のフィードバックをいただけるとうれしいです。 今後の励みや改善につながるので。\n","date":1418809314,"dir":"post/2014/","id":"e5390751969ab21df280b7591854b89f","lang":"ja","lastmod":1418809314,"permalink":"https://blog.johtani.info/blog/2014/12/17/jjug-night-seminar-dec-2014/","publishdate":"2014-12-17T18:41:54+09:00","summary":"「【東京】JJUG ナイト・セミナー「機械学習・自然言語処理特集!」12/17(水)開催」でLuceneの話をしてきました。 本当にごく簡単な入","tags":["elasticsearch","jjug"],"title":"JJUG ナイトセミナーでLuceneの簡単な紹介をしてきました。#JJUG"},{"contents":"たまには、他愛のないブログを。\n仕事しながら、コーヒーを飲んでます。\n最近は、サムライズムさんのオフィスに入り浸って仕事してます。 オフィスには、コーヒーミル付きのコーヒーメーカーがあるんです。\n↓こんな感じ(現物は違うけど)\nで、近所のコーヒー問屋で豆を買ってきてます。 そこのマスターに、いつもサジェストされるんです。\n「この豆は、日が経つにつれて、細かく挽いて飲んでください。」\n「この豆は、細かめに挽いて飲むのがオススメです。」\nなどなど。 オススメされるんですが、全自動のコーヒーメーカーは残念ながらここまでやってくれません。\nということで、手動のミルを買ってみました。家でも使えるし。\nちょっと考え事しながらとか、頭の切り替えに、ミルを回すのもいいかなと。 気持ち、美味しいコーヒーな気がします(気のせいかも)\n","date":1418698892,"dir":"post/2014/","id":"05330c3703d0e2c96cfe657ab33f130c","lang":"ja","lastmod":1418698892,"permalink":"https://blog.johtani.info/blog/2014/12/16/a-coffee-break/","publishdate":"2014-12-16T12:01:32+09:00","summary":"たまには、他愛のないブログを。 仕事しながら、コーヒーを飲んでます。 最近は、サムライズムさんのオフィスに入り浸って仕事してます。 オフィスには、","tags":["misc","coffee"],"title":"コーヒーブレイク"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:exciting logstash plugin ecosystem changes\nLogstash 1.5.0 Beta 1(お試しはこちら)のリリースで、 プラグインのインストール、管理、公開の方法を変更しています。 ユーザやコミュニティからフィードバックをもらいました。 その目的は、プラグインの利用や開発をより簡単にすることです。 このプロジェクトは始まったばかりです。プラグインのコミュニティを探し、 共有するためのワンストップソリューションを提供するこのアイデアを改善していく予定です。 このブログで、この決定を行った理由を説明し、新しいワークフローをと今後のロードマップを説明します。\nプラグインがあります! Logstashは、プラグイン(input、filter、output、codec)が豊富にあります。 これらは、Elasticsearchにより開発されたものと、コミュニティからコントリビュートされたものです。 Logstashの主な特長の1つは、これらのプラグインの有効性と動作を拡張するプラグインを追加するのが簡単なことです。 現在、165以上のプラグインがエコシステムにあり、これらは、2つのプロジェクトに分かれています。\nlogstash-coreは最もよく使われるプラグインで、Logstashにデフォルトで含まれます logstash-contribはコミュニティにより開発されたプラグインを含み、別途ダウンロードできます 新プラグインエコシステムの変更 1.5.0では、全てのプラグインは、Logstashコアから分離され、rubygemsを使って個別にパッケージングされます。 rubygemsを選択したのは、依存関係のあるライブラリの配布とパッケージングがパワフルで一般的なものだからです。 さらに、rubygems.orgプラットフォームは配布や探索に影響があります。 また、Logstashにプラグインをインストール、アップデート、削除するのが簡単な基盤も追加しました。 contribプロジェクトは徐々に終了します。全てのプラグインは個別のプロジェクトになります。\nプラグインエコシステム変更の理由 多数のプラグインをもっていると、配布と公開に関して難題が出てきます。 私たちが変更するに至った理由は次のようなものです。\n現在は、プラグインの更新に伴い、Logstashの新バージョンのリリースが必要 開発者は、Logstashのリリース間隔とは別に、新バージョンをリリースをしたい プラグイン開発者は、外部依存を記述できるようにしたい Logstashコアの配布パッケージのダウンロードサイズを小さくし、ユーザは必要なプラグインのみインストール logstash-contribを1つのリポジトリとして管理するのは難しい 詳細: ソースコードの場所 Logstashのソースコードは、今後も現在のGitHubのリポジトリのままです。 しかし、プラグインに関するコードやテストコードは含まなくなります。 この分離により、個別のプラグインの改善と同様にコアの改善に集中できます。 これにより、Logstashプロジェクトの全体の品質も向上します。\n全プラグインのソースコードは、新しいGitHub organization、logstash-pluginsにて管理します。 各プラグインは個別のリポジトリとして、ここに配置されます。 一見すると、これはメンテナンスが難しくなるように思えます。しかし、テスト、Issue、依存関係を明確にすることができます。 私たちの目的は、テスト、ドキュメント、gemの公開の自動化であり、これを簡単にするためのツールを追加します。\nしかし、プラグインの開発者はプラグインのソースコードソースコードをlogstash-pluginsに置く必要はありません。 ー コミュニティで利用可能にするために、rubygems.orgでそれを公開するだけで良いです。\nワークフロー ここで、新プラグインエコシステムのやりとり/ワークフローについて、いくつかの観点から説明します。\nlogstashユーザ: ユーザは、これまでのリリース同様にLogstashのバイナリをダウンロードします。 Logstash 1.5.0は、1.4.2でパッケージされていたプラグインと同等のものが含まれています。 新しいシステムに簡単に移行できるようにです。 そして、ユーザは、最初のデプロイの後に、Logstashプラグインのをインストール、アップグレードできるようになります。\n$LS_HOME/bin/pluginスクリプトがプラグイン操作に関連するコマンドになります。\nプラグインのインストール プラグインのほとんどはgemとしてrubygems.orgにアップロードされます。 例えば、もしユーザがApache Kafka outputプラグインをインストールする場合、次のコマンドを実行します。\nbin/plugin install logstash-output-kafka または、ファイルをダウンロード済みの場合は次のコマンドとなります。\nbin/plugin install /path/to/logstash-output-kafka-1.0.0.gem プラグインの削除 bin/plugin uninstall logstash-output-kafka 1つまた全プラグインのアップデート bin/plugin update bin/plugin update logstash-output-kafka プラグインのリストアップ bin/plugin list bin/plugin list elasticsearch ( List all plugins containing a name ) bin/plugin list --group output ( list all outputs ) ドキュメント プラグインが個別に管理されても、全プラグインのドキュメントは1カ所です。\nlogstash plugin開発者: プラグイン開発者と作者は、Logstashエコシステムのためにプラグインを公開することができます。 プラグインは、gemやJavaライブラリの依存関係を宣言できます。 より重要なのは、Logstashのリリース間隔に関係なく、プラグインの改善版をリリースできます。\nRubygemsテクノロジはパッケージングシステム、依存関係管理、ホスティングのために選択されてきました。 Rubyのgemを公開することに慣れている開発者は、Logstashプラグインを簡単に公開することができます。 Elasticsearchはこれらの機能に関して開発者を支援するために、ツールを提供、メンテナンスします。\n開発およびローカルでのテスト JRuby 1.7.16がプラグインを開発するための唯一の前提条件です。 プラグインにパッチを提供するのは以前と同様です。 例えば、logstash-output-kafkaにパッチを送るのは次のようになります。\ngit clone https://github.com/logstash-plugins/logstash-output-kafka.git 変更 プラグインをローカルでテスト bundle install bundle exec rspec Logstashの他のバージョンもしくはローカルでテストする場合、Gemfileを編集し、 次のように別のロケーションを加えます。gem \u0026quot;logstash\u0026quot;, :github =\u0026gt; \u0026quot;elasticsearch/logstash\u0026quot;, :ref =\u0026gt; \u0026quot;master\u0026quot; 新しいPull Requestをlogstash-output-kafkaに対して作成 コミュニティでコードレビューを受け、Elasticsearchがパッチを受け入れ バージョン バージョン情報は、それぞれのプラグインの.gemspecで管理します。 例えば、Apache Kafka outputのgemspecはこちらです。 バージョニングはsemantic versioningのルールに従い、 Logstashのバージョニングとは別に、プラグインの開発者によって管理されます。 Logstash 1.5.0がリリースされると、マイルストーン1のプラグインはバージョン1.0.0となり、マイルストーン2のプラグインはバージョン2.0.0となるでしょう。\n公開 開発者が変更を加えプラグインを公開したいと思った時、.gemspecのバージョン番号を変更します。 全テストが成功した時、Elasticsearchはrubygems.orgにプラグインを手動で公開します。 もし、テストが失敗した場合、プラグインは公開されません。 長期的には、プラグインの公開の自動化を行いたいと思っています。 この変更は新しいため、公開の自動化を提供する前に、自動化についてより理解し、プラグインのテスト基盤を改良したいと思っています。\nIssue Issueは、各プラグインのGitHubリポジトリに対してオープンなければなりません。 Logstashコアのリポジトリは、コアのパイプラインや共通的な機能に関連するIssueについて扱います。\nドキュメント プラグインのドキュメントはソースコード自体から生成されます。 それぞれのプラグインのドキュメントは、そのプラグインのリポジトリに含まれます。 Elasticsearchは elasticsearch.org/guideに全てのプラグインのドキュメントを集め生成できる基盤を提供します。\n移行 全ての新しいpull requestとissueはlogstash-plugin organisation配下にある各プラグインのリポジトリに対してオープンする必要があります。\nすでにあるPRはどうすれば良いですか? 気にしないでください。すでにあるpull requestは開発者によって移行する必要はありません。 LogstashチームがLogstashコアリポジトリに対してのPRを、個別の関連するプラグインのリポジトリに対してマージします。\ngit clone … # clone the specific plugin repo # now apply the patch curl -s https://github.com/elasticsearch/logstash/pull/XXXX | git am --3way git push Note:このプロセスはすでにあるPRに対してgit historyを管理します\nGitHub Issue 現在、LogstashリポジトリにオープンされているIssueは、それぞれのプラグインのリポジトリに移行します。 Logstashチームがgithub.com APIを利用してこの処理を自動的に行います。 安心してください。私たちが個別のプラグインに対する既存のIssueを移行します。\n今後のロードマップ これは、最初のステップであり、これらの変更は、ユーザや開発者に対してエコシステムをよりよくするために、 しっかりとした基盤を提供します。\n短期的には、開発者のためにpull requestのフィードバックでテスト自動化を提供する基盤を追加していきます。 プラグインリポジトリのブートストラップや管理のためのツールも提供していきます。\n長期的には、すべてのLogstashプラグインを探し、公開するためのコミュニティポータルを提供したいと思っています。 このアイデアは、Puppet ForgeやAWS marketplaceのようなものです。\nLogstash 1.5.0 Beta 1をリリースし、これは新しいエコシステムを提供します。 ぜひ、試していただき、これらの変更に関して感じたことを教えてください。 あなたのフィードバック(TwitterもしくはGitHub)はとても貴重です!\n","date":1418486440,"dir":"post/2014/","id":"4a3c42c9c5ac29db268010bbebf4f579","lang":"ja","lastmod":1418486440,"permalink":"https://blog.johtani.info/blog/2014/12/14/plugin-ecosystem-changes/","publishdate":"2014-12-14T01:00:40+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:exciting logstash plugin ecosystem changes Logstash 1.5.0 Beta 1(お試しはこちら)のリリースで、 プラグインのインストー","tags":["logstash"],"title":"Logstashプラグインのエコシステムの変更(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:logstash 1.5.0.beta1 released\nLogstash 1.5.0 Beta1をリリースしました。こちらのページからダウンロードできます。\nNote: ベータリリースです。本番環境では使用しないでください。\n1.5.0の主な変更点は? 1.5.0の主なテーマはプラグイン管理、パフォーマンス改善、Apache Kafkaインテグレーションです。Logstashの主な特徴の1つは プラグインを利用できることであり、パイプラインの動作を拡張するためにプラグインを追加するのが簡単なことです。 このリリースで、プラグインの開発、管理、公開がより簡単になります。 また、Logstashの速度をより良くしたため、より多くのデータを短時間に処理することができます。 興味ありませんか?では、詳細を見ていきましょう。\nplugin ecosystemの変更 Logstashは165ものプラグイン(inputs、filters、outputs、codecs)を持っており、 これらはElasticsearchとコミュニティからのコントリビュートで開発されています。 多くのプラグインを管理することは、使いやすさと素早さの間のトレードオフがあります。 Logstashの全てのプラグインをまとめることは使いやすさがある一方、プラグインの更新を取り込むために Logstashの新しいリリースを待ってもらうことになります。 Logstashからプラグインを分離して個別に配布する場合、更新は簡単になりますが、使いやすさ(特に新しいユーザに)に影響が出ます。\n私たちは、プロジェクトを前進させるために、これらのバランスをとることを考えました。 これまで、全ての利用可能なプラグインは’core’と\u0026rsquo;contrib\u0026rsquo;の2つに分割していました。 \u0026lsquo;core\u0026rsquo;にあるよく使われるプラグインは、Logstashに含めていました。 コミュニティによりコントリビュートされたプラグインは\u0026rsquo;contrib\u0026rsquo;パッケージとして分離して配布していました。 1.5.0のリリースで、ユーザに対してより良いプラグイン管理をできるように変更しました。 全てのプラグインは、それ自身によるパッケージに移行しました。 パッケージングフレームワークとしてrubygemsを使い、rubygem.org経由でこれらのプラグインを配布、公開します。 また、Logstashにプラグインのインストール、更新、削除を簡単にするための構造も追加しました。\n例えば、S3 output pluginをインストールするには、以下のコマンドを実行します。\n$LS_HOME/bin/plugin install logstash-output-s3 それだけです!Logstashがgemと依存するgemをrubygems.orgからダウンロードし、インストールします。 あなたは、S3にデータを送ることができるようになります。\nダウンロード可能なLogstashリリースはプラグインをまだ多く含んでいますが、 いつでも、個別にプラグインをアップグレードし、インストールすることができます。 プラグインエコシステムの変更に関する詳細のブログ記事をお待ち下さい。\nパフォーマンス改善 Logstash 1.5.0はより高速になっています。パフォーマンスが改善された2カ所について説明します。\ngrok filter Grok filterはLogstashで、構造化データを抽出するためにパターンを記述するのに使われます。 本リリースで、人気のある幾つかのパターンのgrok filterのスループットを100%に改善しました。 言い換えると、grok filterを使うときに、Logstashを通してより多くのデータを処理することができます。\n私たちのベンチマークテストで、1.5.0と1.4.2のスループットの比較をしました。 利用したデータは690万件のApache Webアクセスlogで、COMBINEDAPACHELOGのgrok patternです。 1.5.0で、スループットは34,000 event per sec(eps)から50,000 epsに増加しました。 両方のテストを8コアのマシンでLogstashで8つのワーカーを実行しました。 これらのテストで、一つのgrok filterを実行し、 stdinとstdoutを使ったパイプラインでイベントのスループットを計測しました。 全体的なパフォーマンスは、様々なハードウェアやLogstashのコンフィグによって変化することに注意してください。\njson serialization / deserialization JSONのシリアライズ/でシリアライズをJrJacksonライブラリを利用して実装しました。 これにより、100%以上のスループットの改善がありました。 先ほど説明したパフォーマンステストにおいて、1.3KBのサイズの500,00 JSONイベントを送信し、 16,000 epsから30,000 epsにスループットが改善しました。 45,000サイズのイベントで、850 epsから3500 epsにスループットが増加しました。 すばらしいです。\napache kafka integration いまでは、Apache Kafkaが大規模スケールデータ処理システムでよく利用されます。 Logstashの配備のスケーリングにおいて、Kafkaもまた、shippingインスタンスとindexingインスタンス間の データを保存するための中間メッセージバッファとして使うことができます。\n1.5.0で、Logstash Kafkaのinputとoutputのプラグインのビルトインサポートを追加しました。 これは、Joseph Lawsonによって最初に開発されました。 私たちは、これらのプラグインにインテグレーションテストとドキュメントを追加することにより改良し、 新しいKafkaの機能を開発し続けます。 また、Apache Avro codecを追加することで、Kafkaに保存されたイベントを 簡単に取得でき、ELKスタックを使ってそれらを解析できるようにしました。\nKafka inputを追加するのは次のコマンドです。\n$LS_HOME/bin/plugin install logstash-input-kafka Kafka outputは次のコマンドです。\n$LS_HOME/bin/plugin install logstash-output-kafka セキュリティに関する改善 認証と経路暗号化のサポートを追加し、Elasticsearchのoutput、input、filterのセキュリティを改良しました。 例えば、HTTPプロトコルでSSL/TLSにより暗号化を有効にでき、 HTTPベーシック認証をユーザ名とパスワードをリクエストに与えることで設定できます。 これらの機能は、時期にリリースされるElasticsearch ShieldセキュリティプロダクトとLogstashを統合できます。\nドキュメント これまで、Logstashのドキュメントは[logstash.net])(http://logstash.net/)に置いてあり、 他のELKスタックと一緒に動かす時に、情報を探すのが厄介でした。 1.5.0および、今後のバージョンのドキュメントはelasticsearch.orgのLogstash Guideに移行します。 この移行でelasticsearch.org/guideにELKスタックを利用、 学習するためにドキュメントが1つになりました。 このベータリリースのイテレーションで、私たちはプレゼンテーションとドキュメントの品質を改善することに活発に取り組んでいきます。 (過去のLogstashのドキュメントの全てはいままでのlogstash.netで引き続き公開していく予定です。)\nバグフィックスと改善 ここまでの新しい機能に加えて、Logstash 1.5.0では、多くのバグフィックスと多くの機能改善があります。 ここで、これらのいくつかを紹介します。\n出力しない\u0026rsquo;metadata\u0026rsquo;をイベントに格納可能に。これは、例えば、date filterに使う中間フィールドのために必要。(#1834, #LOGSTASH-1798) HTTPを利用しているときのファイルデスクリプタリークの修正。Logstashがストールするのを防ぎ、OOMエラーからクラッシュするケースも防ぎます。(#1604) Twitter input:full_tweetオプションの追加、Twitter rate limitingエラーのハンドリング(#1471) イベントを生成するfilter(multiline、clone、split、metrics)により、 後続の条件文にこれらのイベントを正しく伝搬(#1431) Elasticsearch output:Logstashはデフォルトでmessage.rawフィールドを作成しない。messageフィールドはElasticsearch によりnot_analyzedでマルチフィールドとして追加される。マルチフィールドはディスクスペースが2倍必要だが、利点がない。 bin/logstashの複数のサブコマンドを除去(#1797) これらの機能、改善、バグフィックスについては、Logstash 1.5.0.Beta1 のchangelogをごらんください。\n試してみてください! ぜひ、Logstash 1.5.0 Beta 1をダウンロードして試してみてください。 そして、感想をTwitter(@elasticsearch)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1418372246,"dir":"post/2014/","id":"1bc36080b2493aab78c26e4f2152542c","lang":"ja","lastmod":1418372246,"permalink":"https://blog.johtani.info/blog/2014/12/12/logstash-1-5-0-beta1-released-ja/","publishdate":"2014-12-12T17:17:26+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:logstash 1.5.0.beta1 released Logstash 1.5.0 Beta1をリリースしました。こちらのページからダウンロードで","tags":["logstash"],"title":"Logstash 1.5.0 Beta1リリース(日本語訳)"},{"contents":"早いもので、師走です。今年もあと少しとなりました。ということで、Advent Calendarの季節が始まりました。\nこの記事はElasticsearch Advent Calndar 2014の1日目のエントリです。\n1日目ということで、簡単に今年の変遷を振り返りつつ、今年導入された新機能についてピックアップしてみようかと思います。\n1.0リリース(Lucene 4.6.0) 今年一番の目玉と思いますが、1月にRCが公開されて、1.0.0が2月にリリースされました。 (ElasticSearch Serverの翻訳が昨年末に終わってレビューをしていた段階での発表だったので個人的にはきついタイミングでした) 1.0の主な変更点はこちら。\nElasticsearch(Sが小文字に) 1.0からSが小文字になりました。(#4634) 0.90以前のバージョンについては、Sが大文字になっています。 ややこしいですが、今年の3月に出版された黒いElasticSearch Server日本語版は原著が0.20で日本語版にするタイミングで0.90に対応しました。 このため、こちらの書籍のタイトルはSが大文字となっています。 (なお、原著の2nd Editionは小文字になっています)\nSnapshot/Restoreの導入とGatewayの廃止 0.90以前のバージョンでは、gatewayというモジュールで、S3などにインデックスのメタデータなどを保存する機能がありました。 この機能は、0.20からlocal以外はdeprecatedとなりました。\nインデックスのバックアップ、リストアのために、1.0で実装されたのがSnapshot/Restoreです。 Snapshot/Restoreでは、インデックスごと、もしくはクラスタ全体をリモートにあるリポジトリにスナップショットを取ることが可能となりました。 初期リリースの段階では、共有ファイルシステムのみでしたが、現在は、S3やHDFSなどに保存が可能となっています。\nAggregation Facetをより強力にしたものです。Facetでは、指定したフィールドの集計のみでした。 データの解析などを行うには、独自で集計する必要がありました。 この機能をより柔軟に行えるように実装したのがAggregationです。\nたとえば、アクセスログを日毎に集計し、さらに日毎の集計に対して国別の集計やユーザエージェントごとの集計をさらに行うといった感じです。 Facetの場合は、日毎の検索結果に対して個別に集計するのみでしたが、Aggregationを使うことで、1週間の検索結果に対して、 日毎に国別の集計を行うといったことが可能になっっています。\ncat API \u0026ldquo;=^.^=\u0026ldquo;猫が出てくるAPIです。(違う)\nElasticsearchでは、クラスタの状態などが全てREST APIで取得でき、JSONで結果が帰ってきていました。 JSONはプログラムなどで処理を行う場合は便利ですが、コンソールで確認したり、管理系のツールでメールで通知する場合などは見にくいことがあります。 これを解消したのが_cat APIです。(公式の紹介ブログはこちら)\nCircuit Breaker OOMが発生しそうなfielddataの読み込みを検知して、事前に防ぐ機構になります。 初期段階ではFielddataに対してのものから実装されました。\n1.1リリース(Lucene 4.6.1) 3月にリリースされました。Elasticsearchはまだまだ発展しているため、リリースのサイクルが短いのが特徴です。\n1.x系では、Rolling Upgradeが導入されました。このため、クラスタ全体を停止することなく、クラスタのアップグレードが可能になりました。\nsearch templates 検索クエリをテンプレートとして登録することができるsearch templatesです。 JSONでクエリを記述できるのは便利ですが、毎回組み立てるのは大変かもしれません。 特に、固定のクエリをプログラムから利用するような場合などです。 テンプレートとして登録しておくことで、検索時に値を埋め込むだけで検索ができるようになりました。\nAggregationの強化 Aggregationの種類が増えました。\ncardinality:ユニークユーザ数の集計などが行えるaggregationです。HyperLogLog++アルゴリズムを利用した実装になっています。 significant_terms:単語の数による集計ではなく、コレクション全体に対する単語の頻度と、検索結果に対する単語の頻度を計算することで、重要度を計ることができます。 percentiles:パーセンタイル値を計算できます。 1.2リリース(Lucene 4.8系) Java 7必須 利用しているLuceneがJava 7必須となったためです。また、Java 6のEOLも切れてますし。\ndynamic scriptingがデフォルトオフ 採用していたMVELがサンドボックス化に対応していないため、危険を回避するためにオフとなりました。\nインデキシングとマージング インデキシングとマージ処理に関するさまざまな改善。\nflushのthreasholdを操作回数ではなく、サイズや時間によるものに変更 デフォルトをConcurrentMergeSchedulerに変更 1.3リリース(Lucene 4.9.0系) セキュリティ関連 JSONPのデフォルトオフ MVELの非推奨化(1.4で削除)+script.disable_dynamicのデフォルト値がsandbox aggregationの強化 top hits:Field Collapsing/combiningと呼ばれる機能です。たとえば、いくつかのサイトのHTMLを収集して検索機能を提供する場合に、ドメインごとに1件ずつ検索結果に出したい場合などに利用できる機能です。 その他にも以下のaggregationが追加されています。\npercentile ranks geo bounds mappingのtransform Mappingにtransform機能が追加されました。 mappingにドキュメントの値を元に、インデキシング時に変換処理を記述できます。 たとえば、特定のフィールドにある値がある場合にだけ、あるフィールドに値を入れるなどといったことが可能になります。\nディスク関連 disk based shard allocation deciderが導入されました。ノードのディスクの使用率を元に、シャードを配置しても良いかといった決定を行う機構です。 チェックサムによるファイルのチェック(Lucene4.9で導入されたコードへの切り替え) 1.4リリース(Lucene 4.10系) ベータ版が出されるほど、多くの改善が入っています。\nresiliency メモリ使用量の低下によるノードの安定性向上 DocValues、リクエストごとのcircuit breakerなど discoveryアルゴリズムの改善によるクラスタの安定性向上 チェックサムの導入による破損したデータの検知 セキュリティ関連 CORSをデフォルト無効 Groovyがデフォルトのスクリプト言語に。 Aggregationの強化 以下のaggregationが追加されています。\nfilter、children、scripted_metric Upgrade API インデックスを最新のバージョンのものにアップグレードするためのAPIです。 Luceneは下位互換を保ってくれているため、古いバージョンのインデックスも読み込むことが可能です。 ただ、最新バージョンで使える機能が制限されていたりということもあります。 クラスタにあるインデックスをアップグレードするのにかかる時間や必要かどうかといったことを取得できる仕組みも提供します。\nまた、Lucene自体は、1つ前のメジャーバージョン(4.x系だと3.x系まで)までの互換性は提供していますが、 2つ前のメジャーバージョンの互換性がなくなります。 Luceneも5.x系のブランチが作成されており、5系のリリースにより、3系との互換性がなくなります。 5系のリリースに対応する場合にも、こちらのAPIが助けになるかと。\n1.4.1 11\u0008/27に1.4.1がリリースされました。 シャードの配置やparent/child、nestedドキュメントの改善などが行われています。\nまとめ ということで、駆け足で、1月から11月までのElasticsearchの流れを追ってみました。 1.0で大きな機能追加、改善が行われ、その後も活発に開発が行われています。 要望などがあれば、MLで聞いてみたりやGitHubに登録するなどを行っていただければと。\nあと、今年から来年にかけての大きなイベントとして、 Elasticsearch初のユーザカンファレンスのサイトがオープンしました。 Elasticsearchに関するいろいろな話が聞ける機会だと思うので、興味のある方は見ていただければと。\nでは、また次のAdvent Calendarで!(最終日の予定ですが、空きがあるのでなにか書くかも)\n","date":1417424748,"dir":"post/2014/","id":"2de582c67fca31500621ecd6d3917a07","lang":"ja","lastmod":1417424748,"permalink":"https://blog.johtani.info/blog/2014/12/01/about-elasticsearch-in-2014/","publishdate":"2014-12-01T18:05:48+09:00","summary":"早いもので、師走です。今年もあと少しとなりました。ということで、Advent Calendarの季節が始まりました。 この記事はElastics","tags":["elasticsearch"],"title":"2014年のElasticsearch"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:elasticsearch 1.4.1 and 1.3.6 released\n本日、Lucene 4.10.2をベースにしたElasticsearch 1.4.1と、バグフィックスリリースである、Elasticsearch 1.3.6をリリースしました。 ダウンロードおよび変更リストはそれぞれ次のリンクからアクセスできます。\n最新ステーブルリリース:Elasticsearch 1.4.1 1.3.x系バグフィックス:Elasticsearch 1.3.6 過去のリリースに関するブログ(公式)はこちら。\n1.4:1.4.0, 1.4.0.Beta1 1.3:1.3.5, 1.3.4, 1.3.3, 1.3.2, 1.3.1, 1.3.0. すべての変更については1.4.1のリリースノートおよび1.3.6のリリースノートをごらんください。 以下では、重要な変更について紹介します。\nshard allocation Elasticsearch 1.3.0で、disk based shard allocationが デフォルトで有効になっています。 もし、ノードのディスクの使用量がlawで指定された値(85%)を超えた場合、ノードにはシャードが配置されません。 また、highで指定された値(90%)を超えた場合、シャードを他のノードへ移動します。\nElasticsearch 1.4.1では、disk based shard allocationに3つの改良が追加されました。\nディスク使用量のチェックはシャードがクラスタに配置されるタイミングでのみ実施していた。現在は60秒ごとに使用量をチェック。(#8270) ディスクフルメッセージはDEBUGレベルでログに出力されていました。なぜ、新しいシャードが配置されないのかを説明するのが困難でした。現在はWARNレベルで30秒ごとにログに出力されます。(#8382) 以前は、シャードをもう一つのノードへ動かすべきかどうか決めるとき、allocation deciderはノードにあるシャードのサイズを考慮するだけでした。現在は、動かされるシャードのサイズも考慮します。これにより、必要最小限のシャードの移動量となります。(#8569) parent/child and nested documents Elasticsearch 1.4.0で、parent/childとnestedドキュメントに対して(新しいセグメントを開くときに)固定長ビットセットフィルタを構築しキャッシュしました。クエリ、フィルタおよびAggregationを常に速くするためにです。 多くのnestedフィールドを持つユーザにとっては、以前のバージョンよりもヒープの使用量が大きくなってしまいました。\nnested aggregationによって処理されるドキュメントの順序を変更すること(#8454)によって、固定長ビットセットフィルタが子のドキュメントに対して必要でなくなりました。 現在は、親のドキュメント(つまり、nestedではないドキュメント)を表すフィルタのみをキャッシュしています。これにより必要なキャッシュ空間のサイズを減少しました。(#8414、#8440)\ndate ranges 2つの日付範囲に関する問題がこのリリースで修正されました。 1つ目は、日付を丸めるかというものです。例えば、timestampフィールドに1秒の解像度の値があるとします。 {\u0026quot;lt\u0026quot;: \u0026quot;2014/11/26||/d\u0026quot;}というrangeフィルタは2014/11/26 00:00:00未満のタイムスタンプのデータを結果として返しました。 しかし、ltをlteに変更した場合、2014/11/27 00:00:00以外の値も含めたいです。\n以前は、lteは2014/11/27 00:00:00のタイムスタンプも含めてしまっていました。現在は、想定通りの動作をします。(#8556)\n2つ目のバグは日付の範囲条件にnow()を利用したaliasとpercolatorフィルタです。 now()の値を、フィルタが作成したタイミングで決定していました。フィルタが実行されるたびに更新せずにです。 #8534で、now()はaliasとpercolatorで想定通りの動作をします。\n試してみてください。 ぜひ、Elasticsearch 1.4.1をダウンロードして、試してみてください。 そして、感想をTwitter(@elasticsearch)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1417056212,"dir":"post/2014/","id":"0a8183ced0e9e3e895b41286e54e8e4d","lang":"ja","lastmod":1417056212,"permalink":"https://blog.johtani.info/blog/2014/11/27/elasticsearch-1-4-1-released-ja/","publishdate":"2014-11-27T11:43:32+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:elasticsearch 1.4.1 and 1.3.6 released 本日、Lucene 4.10.2をベースにしたElas","tags":["elasticsearch"],"title":"Elasticsearch 1.4.1および1.3.6リリース(日本語訳)"},{"contents":"前回の「Logstashを利用したApacheアクセスログのインポート」の続きです。 前回の記事では、Logstashの設定ファイルについて説明しました。 今回は「Elasticsearchに設定するインデックステンプレート」について説明します。\nテンプレートの設定 Elasticsearchでは、登録するデータの特性に合わせてMappingを定義する方がデータを効率良く扱うことができる場合があります。 この場合、通常ですと、インデックス作成時にMappingを指定します。\nただ、今回は、インデックス名に「年」を含める形で指定してあります。 「年」はLogstashで処理したデータによって決まります。このため、あらかじめMappingを指定してインデックスを作成するのは難しいです。\nこのような場合に便利な機能として、「インデックステンプレート」があります。\nインデックステンプレートとは 実際のテンプレートの説明に入る前に、少しだけ説明を。 インデックステンプレートとは、インデックスが作成されるタイミングで自動的に適用される設定をテンプレートとして登録できる機能のことです。 実際にテンプレートが適用されるかどうかは、インデックス名で判断されます。\n例えば、大して重要でもなく、データ量も少ないインデックス用のテンプレートとして、シャード数が1、レプリカ数が0、\u0026quot;_source\u0026quot;を保存しない設定のテンプレートを登録する場合、 次のようになります。\ncurl -XPUT localhost:9200/_template/template_1 -d \u0026#39; { \u0026#34;template\u0026#34; : \u0026#34;te*\u0026#34;, \u0026#34;settings\u0026#34; : { \u0026#34;number_of_shards\u0026#34; : 1, \u0026#34;number_of_replicas\u0026#34; : 0 }, \u0026#34;mappings\u0026#34; : { \u0026#34;type1\u0026#34; : { \u0026#34;_source\u0026#34; : { \u0026#34;enabled\u0026#34; : false } } } } \u0026#39; _templateがインデックステンプレートを登録するためのエンドポイントです。 template_1がこのテンプレートのIDです。削除などについては、このIDを利用します。\nそして、重要なのは、\u0026quot;template\u0026ldquo;の設定です。 \u0026ldquo;template\u0026ldquo;には、このテンプレートが適用されるべきインデックス名を記載します。 上記サンプルではte*となっているため、teで始まる名前のインデックスを作成した場合にテンプレートにある設定が適用されます。\n今回利用するテンプレート 私がJJUG CCCや第7回Elasticsearch勉強会のKibana4のデモで利用したインデックスのテンプレートは次のものになります。 \u0026ldquo;template\u0026ldquo;には、前回の記事で紹介したoutput/elasticsearchの設定 に合致するnew_demo_access_log-*を指定しています。\ncurl -XPUT localhost:9200/_template/new_access_log_for_demo -d \u0026#39; { \u0026#34;template\u0026#34;: \u0026#34;new_demo_access_log-*\u0026#34;, \u0026#34;settings\u0026#34;: { \u0026#34;number_of_shards\u0026#34;: \u0026#34;2\u0026#34;, \u0026#34;number_of_replicas\u0026#34;: \u0026#34;0\u0026#34; }, \u0026#34;mappings\u0026#34;: { \u0026#34;_default_\u0026#34;: { \u0026#34;dynamic_templates\u0026#34;: [ { \u0026#34;string_template\u0026#34;: { \u0026#34;mapping\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;match_mapping_type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;match\u0026#34;: \u0026#34;*\u0026#34; } } ], \u0026#34;properties\u0026#34;: { \u0026#34;path\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;multi_field\u0026#34;, \u0026#34;fields\u0026#34;: { \u0026#34;no_analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, \u0026#34;referer\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;multi_field\u0026#34;, \u0026#34;fields\u0026#34;: { \u0026#34;no_analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, \u0026#34;agent\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;multi_field\u0026#34;, \u0026#34;fields\u0026#34;: { \u0026#34;no_analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, \u0026#34;geoip\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;location\u0026#34;: { \u0026#34;geohash\u0026#34;: true, \u0026#34;geohash_precision\u0026#34;: 10, \u0026#34;type\u0026#34;: \u0026#34;geo_point\u0026#34;, \u0026#34;lat_lon\u0026#34;: true, \u0026#34;geohash_prefix\u0026#34;: true } } }, \u0026#34;response\u0026#34;: { \u0026#34;copy_to\u0026#34;: \u0026#34;response_int\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;bytes\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;response_int\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34; } } } } } \u0026#39; settings設定 デモ用であり、手元で2台のノードを起動するということもあり、number_of_shardsに2を、number_of_replicasに0を指定してあります。\nmappings設定 インデックスのタイプ Mappingsの指定は通常、特定のタイプを指定します。 今回のデモでは、1種類しかないのですが、タイプ名を特に意識しないために、_default_を使用しました。 この場合、任意のタイプに適用されることとなります。 タイプを指定してMappingの設定を行う場合は_default_の部分に特定のタイプ名を記入します。\n\u0026#34;mappings\u0026#34;: { \u0026#34;_default_\u0026#34;: { ... ダイナミックテンプレート 次はダイナミックテンプレートです。 インデックステンプレートはインデックスの設定をテンプレート化しました。ダイナミックテンプレートはフィールドに対してテンプレートを設定できます。\n以下のダイナミックテンプレートでは、stringタイプのフィールドのデフォルト設定を変更しています。 通常、stringタイプのフィールドはanalyzedとなりますが、not_analyzedに変更してあります。 詳しく検索したいフィールドの方が少ないためです。\n... \u0026#34;dynamic_templates\u0026#34;: [ { \u0026#34;string_template\u0026#34;: { \u0026#34;mapping\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;match_mapping_type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;match\u0026#34;: \u0026#34;*\u0026#34; } } ], ... multi_field指定 検索もしたいし、Terms Aggregationでも利用したいフィールドについては、multi_fieldを利用して、 analyzedとnot_analyzedの2種類のフィールドを用意しています。 multi_field設定を用いることで、1つのJSONのデータから、異なる形のフィールドを用意することが可能です。\n今回のテンプレートでは、path、referer、agentにmulti_fieldを指定しました。\n... \u0026#34;path\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;multi_field\u0026#34;, \u0026#34;fields\u0026#34;: { \u0026#34;no_analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, ... 例えば、上記の設定の場合、入力のJSONはpathというデータのみですが、インデックス上にはpath.no_analyzedと path.analyzedというフィールドができあがります。 実際に検索する場合は、path.analyzed:検索したい文字列という形で検索をすることで、いわゆる部分一致のような検索が可能です。 また、完全一致をしたい場合はpath.no_analyzed:検索したい文字列という指定になります。 用途を考えると、requestも指定したほうが良いかもしれません。\ngeoip Logstashでgeoipデータを付与していました。 このgeoipのデータをKibana4で利用するために、geoデータとして登録する必要があります。\n\u0026#34;geoip\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;location\u0026#34;: { \u0026#34;geohash\u0026#34;: true, \u0026#34;geohash_precision\u0026#34;: 10, \u0026#34;type\u0026#34;: \u0026#34;geo_point\u0026#34;, \u0026#34;lat_lon\u0026#34;: true, \u0026#34;geohash_prefix\u0026#34;: true } } }, 上記の設定がgeoデータの指定です。 typeにobjectが指定してありますが、これは、geoipのデータがネストしているためです。 geoipオブジェクトのうち、緯度経度のデータはlocationに入っているため、こちらに緯度経度関係の設定を指定します。\n\u0026quot;type\u0026quot;: \u0026quot;geo_point\u0026quot;:geo_pointタイプであることを指定 \u0026quot;geohash\u0026quot;: true:緯度経度のデータをもとに、geohashの値もインデックス \u0026quot;geohash_precision\u0026quot;: 10:geohashの精度の指定 \u0026quot;lat_lon\u0026quot;: true:緯度経度を個別の.lat、.lonというフィールドにもインデックス \u0026quot;geohash_prefix\u0026quot;: true:該当するgeohashのみでなく、その親にあたるgeohashについてもインデックスする response、response_int、bytes 最後は、response、response_int、bytesです。\nresponseには、HTTPステータスコードが入ります。 文字列としても扱いたいですが、integerとして、Renge Aggregationなどを行いたいので、 response_intというフィールドにも値を入れています。 multi_fieldでも可能ですが、ここでは、copy_toを利用しました。 copy_toを用いることで、異なるフィールドに値をコピーすることができます。\nbytesについては、longで扱いたいとういう理由だけです。\n\u0026#34;response\u0026#34;: { \u0026#34;copy_to\u0026#34;: \u0026#34;response_int\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;bytes\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;response_int\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34; } まとめ 今回はデモに利用したインデックスてプレートについて説明しました。 前回の、Logstashの設定とこのインデックステンプレートを用いることで、Kibanaで解析するデータの準備ができます。 実際の操作などについては、また次回の記事で説明しようかと思います。\n不明な点、誤植などありましたら、コメント欄へお願いします。\n","date":1416900346,"dir":"post/2014/","id":"4d8f5e581eee602c7fd21da8eb68df9a","lang":"ja","lastmod":1416900346,"permalink":"https://blog.johtani.info/blog/2014/11/25/import-apache-accesslog-using-logstash-2/","publishdate":"2014-11-25T16:25:46+09:00","summary":"前回の「Logstashを利用したApacheアクセスログのインポート」の続きです。 前回の記事では、Logstashの設定ファイルについて説","tags":["logstash","kibana","elasticsearch"],"title":"インデックステンプレートとLogstash"},{"contents":"JJUG CCCや第7回Elasticsearch勉強会のKibana4のデモにアクセスログを利用しました。\nただ、セッションでは、どうやってElasticsearchに投入したのかという詳しい話をしていませんでした。 本記事では、データ取り込み時に利用したLogstashの設定ファイルについて説明します。\nLogstashの設定の説明に入る前に、全体の流れを。 「ApacheアクセスログをKibana4により可視化」です。\n材料の準備 「ApacheアクセスログをKibana4により可視化」に必要な材料は次の通りです。 (今回は起動するところまでいかないので、実際に必要なのは次回以降になります。)\nJava 7(u55以上を1つ) Logstash 1.4.2(1つ) Elasticsearch 1.4.0(1つ) Kibana4 Beta2(1つ) Apacheのアクセスログ(適量) Apacheのアクセスログ以外は、公式サイトからダウンロードできます。 それぞれをダウンロードして、起動できるようにしておきましょう。\n※1台のマシン上で行う場合は、アクセスログの量を少なめにするなどの対策をとりましょう。 ※今回は、1台のマシン(Mac)上で、VMなどを利用せず、それぞれ直接起動するものとします。\n可視化の手順と流れ 可視化の流れとしては、\nLogstashでファイルを読み込み、各種処理(パースしたり、情報を追加したり、切り出したり) Elasticsearchに保存 Kibanaでグラフを作ったり、検索してみたり です。\n今回は、1のLogstashでファイルを読み込んだりする設定ファイルの説明です。\nLogstashの設定 Logstashの基本 まずは、Logstashの設定ですが、簡単にLogstashの説明を。 Logstashは大きく3つのパーツに分かれています。\ninput:データの入力処理 filter:inputで読み込んだデータに対する操作など output:データの出力処理 inputでデータを読み込み(複数可)、filterでデータに対して各種処理を行い、outputでデータを指定されたところに出力(複数可)します。\nアクセスログの読み込み設定 アクセスログの読み込み処理は大まかに次のようなものとなります。\nアクセスログを読み込む(input/file) 読み取ったアクセスログを各フィールド(IPアドレス、ユーザエージェントなど)に分割(filter/grok) 日付のパース(filter/date) クライアントIPアドレスにgeoipの情報を付加(filter/geoip) リクエストのパスの第1階層の抽出(filter/grok) ユーザエージェントのパース(filter/useragent) Elasticsearchへの出力(output/elasticsearch) 設定ファイルは次のようなものになります。\ninput { file { path =\u0026gt; \u0026#34;/Users/johtani/demo_access_log/*/*.log\u0026#34; start_position =\u0026gt; \u0026#34;beginning\u0026#34; } } filter { grok { match =\u0026gt; { \u0026#34;message\u0026#34; =\u0026gt; \u0026#34;%{COMBINEDAPACHELOG}\u0026#34; } break_on_match =\u0026gt; false tag_on_failure =\u0026gt; [\u0026#34;_message_parse_failure\u0026#34;] } date { match =\u0026gt; [\u0026#34;timestamp\u0026#34;, \u0026#34;dd/MMM/YYYY:HH:mm:ss Z\u0026#34;] locale =\u0026gt; en } geoip { source =\u0026gt; [\u0026#34;clientip\u0026#34;] } grok { match =\u0026gt; { \u0026#34;request\u0026#34; =\u0026gt; \u0026#34;^/%{WORD:first_path}/%{GREEDYDATA}$\u0026#34; } tag_on_failure =\u0026gt; [\u0026#34;_request_parse_failure\u0026#34;] } useragent { source =\u0026gt; \u0026#34;agent\u0026#34; target =\u0026gt; \u0026#34;useragent\u0026#34; } } output { elasticsearch { host =\u0026gt; \u0026#34;localhost\u0026#34; index =\u0026gt; \u0026#34;new_demo_access_log-%{year}\u0026#34; cluster =\u0026gt; \u0026#34;demo_cluster\u0026#34; protocol =\u0026gt; \u0026#34;http\u0026#34; } } 1. アクセスログを読み込む(input/file) inputのfileモジュール(a)を使用してアクセスログのファイルを読み込みます。 pathでアクセスログのファイルのパスを指定します。 今回利用したアクセスログはdemo_access_log/2010/access20100201.logといった日毎のファイルに分割されていたため、 *を利用してファイルのパスを指定しました。 また、今回は既存のファイルの読み込みだけのため、start_positionにbeginningを指定してあります。 デフォルトではendが指定されるため、Logstashを起動後に追記されたログから対象になってしまうためです。 その他の設定については、公式ガイドをご覧ください。\ninput { file { # a path =\u0026gt; \u0026#34;/Users/johtani/demo_access_log/*/*.log\u0026#34; # b start_position =\u0026gt; \u0026#34;beginning\u0026#34; # c } } Logstashでは、ファイルをどこまで読み込んだかという情報を保持するために、sincedbを利用しています。 設定変更後に同じファイルを最初から読み込みたい場合などは、こちらのファイルを一旦削除するなどの対応が必要です。\nちなみに、読み込んだデータは次のようなJSONになっています。\n{ \u0026#34;message\u0026#34;: \u0026#34;読み込んだアクセスログ\u0026#34;, \u0026#34;@version\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;@timestamp\u0026#34;:\u0026#34;2014-11-21T06:16:21.644Z\u0026#34;, \u0026#34;host\u0026#34;:\u0026#34;jupiter.local\u0026#34;, \u0026#34;path\u0026#34;:\u0026#34;/Users/johtani/demo_access_log/2010/access20100201.log\u0026#34;} } 特に指定がない場合は、messageに読み込んだデータが入ってきます。 @timestampがLogstashが読み込んだ時刻、hostはLogstashが動作しているホスト名です。 pathはfileモジュールが読み込んだファイルのパスを設定しています。 この後の処理で、どこの項目に対して処理を行うかといったことが重要になるので、\n2. 読み取ったアクセスログを各フィールド(IPアドレス、ユーザエージェントなど)に分割(filter/grok) 2.〜6.の処理は、inputで読み込んだ1アクセスログに対する処理となります。\nここでは、grokフィルタを使用して Apacheのアクセスログを各フィールドに分割します。 Logastashでは、簡単に使えるようにいくつかのパターンが用意されています。 Apacheのログのために、COMBINEDAPACHELOGというのが用意されています。 今回はこちらを使用しています。その他にも日付などパターンが用意されているので、試してみてください。\nmessageにアクセスログが入っているので、こちらの項目に対してCOMBINEDAPACHELOGのパターンを matchで適用してフィールドに抜き出します。 tag_on_failureは、matchでパースに失敗した場合に、tagというフィールドに指定した文字列を出力する機能になります。 デフォルトだと_grokparsefailureが付与されますが、ここでは、どの処理で失敗したがを判別するために文字列を変更しています。\nfilter { grok { match =\u0026gt; { \u0026#34;message\u0026#34; =\u0026gt; \u0026#34;%{COMBINEDAPACHELOG}\u0026#34; } break_on_match =\u0026gt; false tag_on_failure =\u0026gt; [\u0026#34;_message_parse_failure\u0026#34;] } ... clientip、ident、auth、timestamp、verb、request、httpversion、response、bytes、referrer、agentがgrokフィルタにより抜き出された項目です。\n{ \u0026#34;message\u0026#34;:\u0026#34;アクセスログ\u0026#34;, \u0026#34;@version\u0026#34;:\u0026#34;1\u0026#34;, \u0026#34;@timestamp\u0026#34;:\u0026#34;2014-11-21T07:20:54.387Z\u0026#34;, \u0026#34;host\u0026#34;:\u0026#34;jupiter.local\u0026#34;, \u0026#34;path\u0026#34;:\u0026#34;/Users/johtani/demo_access_log/2010/access20100201.log\u0026#34;, \u0026#34;clientip\u0026#34;:\u0026#34;クライアントのIPアドレス\u0026#34;, \u0026#34;ident\u0026#34;:\u0026#34;-\u0026#34;, \u0026#34;auth\u0026#34;:\u0026#34;-\u0026#34;, \u0026#34;timestamp\u0026#34;:\u0026#34;01/Feb/2010:00:00:26 +0900\u0026#34;, \u0026#34;verb\u0026#34;:\u0026#34;GET\u0026#34;, \u0026#34;request\u0026#34;:\u0026#34;/images/favicon.ico\u0026#34;, \u0026#34;httpversion\u0026#34;:\u0026#34;1.1\u0026#34;, \u0026#34;response\u0026#34;:\u0026#34;200\u0026#34;, \u0026#34;bytes\u0026#34;:\u0026#34;318\u0026#34;, \u0026#34;referrer\u0026#34;:\u0026#34;\\\u0026#34;-\\\u0026#34;\u0026#34;, \u0026#34;agent\u0026#34;:\u0026#34;\\\u0026#34;Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)\\\u0026#34;\u0026#34; } 3. 日付のパース(filter/date) Logstashは特に指定がない場合、inputでデータを取り出した日付が@timestampとなります。 そして、このフィールドが特に指定がない場合は、Elasticsearchのデータの日付となり、Kibanaで利用する日付となります。\nリアルタイムにアクセスログを読み込む場合は、読み込んだ日時でもほぼ問題はありませんが、過去データの場合はそうもいきません。 そこで、dateフィルタを使用して、@timestampの値を書き換えます。\ndate { match =\u0026gt; [\u0026#34;timestamp\u0026#34;, \u0026#34;dd/MMM/YYYY:HH:mm:ss Z\u0026#34;] locale =\u0026gt; en } 上記では、timestampという項目に対してdd/MMM/YYYY:HH:mm:ss Zという日付パターンの場合に値を書き換える設定となります。 なお、日付の月の部分がFebとなっているため、localeにenを指定しています。Logstashが動作するマシンのlocaleがjaなどの場合にパースに失敗するためです。\n4. クライアントIPアドレスにgeoipの情報を付加(filter/geoip) どの国からのアクセスかなどを判別したいので、IPアドレスを元にgeoipを利用してより詳細な情報を付与します。 Logstashでもこの機能が用意されており、簡単に利用ができます。\ngeoip { source =\u0026gt; [\u0026#34;clientip\u0026#34;] } これだけです。対象とするIPアドレスのフィールドを指定しているだけです。 geoipというフィールドが追加され、次のような情報が付与されます。 国名、緯度経度、タイムゾーンなどです。\n{ ... \u0026#34;geoip\u0026#34;: { \u0026#34;ip\u0026#34;: \u0026#34;IPアドレス\u0026#34;, \u0026#34;country_code2\u0026#34;: \u0026#34;JP\u0026#34;, \u0026#34;country_code3\u0026#34;: \u0026#34;JPN\u0026#34;, \u0026#34;country_name\u0026#34;: \u0026#34;Japan\u0026#34;, \u0026#34;continent_code\u0026#34;: \u0026#34;AS\u0026#34;, \u0026#34;latitude\u0026#34;: 36, \u0026#34;longitude\u0026#34;: 138, \u0026#34;timezone\u0026#34;: \u0026#34;Asia/Tokyo\u0026#34;, \u0026#34;location\u0026#34;: [ 138, 36 ] } ... } 5. リクエストのパスの第1階層の抽出(filter/grok) リクエストされたURLはrequestフィールドにありますが、個別のURLだと、大まかな集計が大変です。 もちろん、クエリで処理することもできますが、Logstashで処理するついでに、第1階層のディレクトリ名を抽出しておくことで、 検索や集計を行いやすくしておきます。\ngrok { match =\u0026gt; { \u0026#34;request\u0026#34; =\u0026gt; \u0026#34;^/%{WORD:first_path}/%{GREEDYDATA}$\u0026#34; } tag_on_failure =\u0026gt; [\u0026#34;_request_parse_failure\u0026#34;] } また、grokフィルタの登場です。 今回は、WORD:first_pathという記述方法で、WORDパターンにマッチした文字列をfirst_pathというフィールドに展開する指定をしています。\n例えば、サイトのスクリプトなどがscriptsというディレクトリにある場合は、first_pathの値を利用して、 後続のフィルタでログデータを出力しないといった処理にも使えます。\n6. ユーザエージェントのパース(filter/useragent) Logstashではユーザエージェントの文字列から、いくつかの情報を付与するフィルタも用意されています。 useragentフィルタです。\nuseragent { source =\u0026gt; \u0026#34;agent\u0026#34; target =\u0026gt; \u0026#34;useragent\u0026#34; } agentというフィールドにユーザエージェントの文字列があるので、このフィールドに対してフィルタを適用します。 元の文字列も取っておきたいので、useragentという別のフィールドに出力するように指定してあります。\n\u0026#34;useragent\u0026#34;: { \u0026#34;name\u0026#34;: \u0026#34;Firefox\u0026#34;, \u0026#34;os\u0026#34;: \u0026#34;Windows XP\u0026#34;, \u0026#34;os_name\u0026#34;: \u0026#34;Windows XP\u0026#34;, \u0026#34;device\u0026#34;: \u0026#34;Other\u0026#34;, \u0026#34;major\u0026#34;: \u0026#34;17\u0026#34;, \u0026#34;minor\u0026#34;: \u0026#34;0\u0026#34; }, このように、OS名やバージョン名などが抽出できます。\n7. Elasticsearchへの出力(output/elasticsearch) 最後は、Elasticsearchへのデータの出力設定です。\nindexにて、出力するindex名を指定してあります。 また、年毎のインデックス名にするために%{year}を利用しています。 sprintf formatです。\nelasticsearch { host =\u0026gt; \u0026#34;localhost\u0026#34; index =\u0026gt; \u0026#34;new_demo_access_log-%{year}\u0026#34; cluster =\u0026gt; \u0026#34;demo_cluster\u0026#34; protocol =\u0026gt; \u0026#34;http\u0026#34; } まとめ ということで、今回はアクセスログをLogstashにて読み込む時の設定について説明してきました。 次回は、実際にLogstashを起動してElasticsearchにデータを登録するところまでを説明します。\nJJUG CCCや勉強会のデモに用いたデータは、 Elasticsearchにデータを登録する前にテンプレートも設定してありました。こちらについても、次回説明しようと思います。\n不明な点、誤植などありましたら、コメント欄へお願いします。\n","date":1416558639,"dir":"post/2014/","id":"937a597a8b399fd32caba88a3c1c7bc4","lang":"ja","lastmod":1416558639,"permalink":"https://blog.johtani.info/blog/2014/11/21/import-apache-accesslog-using-logstash/","publishdate":"2014-11-21T17:30:39+09:00","summary":"JJUG CCCや第7回Elasticsearch勉強会のKibana4のデモにアクセスログを利用しました。 ただ、セッションでは、どうやってElas","tags":["logstash","kibana","elasticsearch"],"title":"Logstashを利用したApacheアクセスログのインポート"},{"contents":"第7回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 次回もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\n昨日も紹介しましたが、Elasticsearch Advent Calendar 2014を用意してみました。まだ、空きがありますので、登録お待ちしております!\n今回は出足が好調で、早々に180人の枠を超えるという嬉しい事態でした。 最終的な参加人数は130名程度で、懇親会参加者が50名弱といったところです。\n「Kibana4」 Elasticsearch Inc. Jun Ohtani @johtani スライド:Kibana4\nということで、Kibana4の紹介と、Kibana4のBeta2を利用したデモを行いました。 デモの開始のところで少し環境がうまく動いてなくて手間取ってしまいましたが。。。\n発表で1点だけ修正があります。JRubyを選択しているのがElasticsearchのライブラリを使用するためという説明をしましたが、 こちらは、Logstashに関する話でした。Kibana4は現時点では、ElasticsearchへのProxyとしての動作が主なものとなります。Rubyでも動作可能です。 bin/kibanaについてはJavaを使った起動になります。 参考:https://github.com/elasticsearch/kibana/tree/master/src/server\n発表でも主張しましたが、ダウンロードして、Elasticsearchを用意すれば簡単に動作させることが可能です。 ぜひ、ローカルで試して見てもらえればと思います。 今回のデモのデータを入れるのに利用したLogstashの設定などについては、ブログで記事を書こうと思います。\nniconicoの検索を支えるElasticsearch 株式会社ドワンゴ 伊藤 祥 さん スライド:niconicoの検索を支えるElasticsearch\nリアルタイム検索の実現、新しい検索への対応 検索のアーキテクチャとか。 Capistranoでデプロイとかを管理 1.4.1が出たら、クラスタを更新予定 ということで、実際に導入した話から、現在の運用の仕方、クラスタのアップグレードなど多岐にわたる内容でおもしろかったです。 遭遇した問題点とかもあったので。 Marvel便利なのでぜひ導入を検討してもらえればw\nElasticsearch at CrowdWorks\u2028株式会社クラウドワークス 九岡 佑介 さん @mumoshu スライド:Elasticsearch at CrowdWorks\n会社の紹介 仕事が検索対象 検索時間が1桁減少! Graceful Degradationで失敗したら、InnoDB FTSで代替:Gracefully found.noのサービスを利用 elasticsearch-modelの拡張を作成してOSSとして公開:elasticsearch-model-extensions Gracefullyで切り替えとかは面白いなと思いました。 検索での利用の話でしたが、他のシーンでも使えそうですよね。 日本にFoundユーザがいるのも初めて知りました。 彼らの開発者ブログも質の良い情報が載っているので、参考になりますよね。\n次は、どんなMappingで運用しているのかとか、どういった工夫をしているかといった点を詳しく聞きたいなと思いました。 またお待ちしております。\n1分で作るElasticsearchプラグイン 株式会社エヌツーエスエム 菅谷 信介 さん スライド:Elasticsearchプラグインの作り方\n\u0008\u0008* プラグインの作り方とか。\n十数個のプラグインの紹介。プラグインはこちらで公開中。https://github.com/codelibs/ 実際に、業務で必要なものから作成 まだまだ作りたいものがある コミュニティ還元できるものはPR送ってもらえるとうれしいです。 前よりは体制も増えてるので、PRも目にとまるようになってるはずです。\nあとは、使ってみたいと思う方も多数いると思うので、ぜひ、OSSなので、貢献しましょう! フィードバックがあるだけで、OSS活動やってるものにとってはやる気につながると思いますし。\nLT:GISとして活用するElasticsearch\u2028船戸 隆さん スライド:GISとして活用するElasticsearch\u2028java-jaからIngressの青(Registance)の勧誘に来られた方w APIをハックして、情報を取得し、Kibanaで可視化 残念ながら、APIが変更されて見れなくなったらしい。 Ingress実際にやったことはないのですが、おもしろそうでした。 発表される方の会社の採用紹介ではなく、Ingressの勧誘をされるとは想定外でしたw\n興味のあるデータをKibanaで可視化するのも面白い例だと思うので、活用してもらえればと思います。\nその他、感想などのブログ 適当に見つけたブログを列挙してあります。これもあるよ!などあれば、教えてください。\n勉強会メモ - 第7回elasticsearch勉強会 第7回elasticsearch勉強会 #elasticsearch #elasticsearchjp まとめ JJUGの時とは違い、Elasticsearch勉強会ではさすがに、企業としてのElasticsearchの知名度が高かったのはありがたいことでした。 自分の発表のために始めた勉強会でもありますが、まだまだ、発表するときは緊張しますし、分かりにくいんじゃないかなぁと思うことも多々あります。 この辺がわかりにくかった、この辺をもっと知りたいなど、フィードバックをお待ちしております。\n冒頭にも書きましたが、Elasticsearch Advent Calendar 2014の登録をお待ちしております。どんなことでも歓迎なので、Elasticsearch、Kibana、Logstashなどについて書いてもらえるとうれしいです。\n次回ももちろん2ヶ月後くらいに行います。 スピーカー募集中ですので、コメント、メール、ツイートなど、コンタクトしていただければと思います。 よろしくお願いいたします。\n","date":1416363547,"dir":"post/2014/","id":"2a8412aa50d07330f1298f0243fa79d3","lang":"ja","lastmod":1416363547,"permalink":"https://blog.johtani.info/blog/2014/11/19/hold-on-7th-elasticsearch-jp/","publishdate":"2014-11-19T11:19:07+09:00","summary":"第7回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん","tags":["elasticsearch","勉強会"],"title":"第7回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:elasticsearch-1.4.0 and 1.3.5 released\n本日、Lucene 4.10.2をベースにしたElasticsearch 1.4.0と、バグフィックスリリースである、Elasticsearch 1.3.5をリリースしました。 ダウンロードおよび変更リストはそれぞれ次のリンクからアクセスできます。\n最新ステーブルリリース:Elasticsearch 1.4.0 1.3.x系バグフィックス:Elasticsearch 1.3.5 1.3ブランチに関する過去のリリースについてのブログは次のとおりです:1.3.4, 1.3.3, 1.3.2, 1.3.1, 1.3.0.\nBeta1リリースでも言及しましたが、1.4.0の主なテーマは*resiliency(復元性、弾力性)*です。 Elasticsearchをより安定し信頼性のあるものにし、メモリ管理を改善し、ディスカバリアルゴリズムを改善し、破損したデータの検知を改善しました。 Beta1リリースからのハイライトも含んでいます。\nDoc values (インデックス時にディスクに保存されるfielddata)がヒープ利用率を激減 Request circuit breaker: メモリを消費しすぎる検索リクエストの中断 Bloom filterのデフォルト無効、高速なインデキシングのためにもはや必要とされないため。 ノードディスカバリ、シャードリカバリの数多くのバグフィックス及び改善 データ破損の早期検知のためのチェックサムのさらなる利用 GroovyをMVELの代わりにデフォルトスクリプト言語に CORSをデフォルト無効に。XSS攻撃防止の為。 クエリキャッシュ、変更されていないシャードからすぐにaggregation結果を返す 新しいAggregation:filter(ドキュメント)、children(ドキュメント)、scripted_metric(ドキュメント) 新しいGET /indexAPI。インデックスのsettings、mappings、warmers、aliasesを1回のリクエストで返却(ドキュメント) 自動付与ドキュメントIDのためのFlake ID。プライマリキーの探索パフォーマンスの改善。 ドキュメントに変更のない更新によるドキュメントの再インデックスの防止 function_scoreクエリの関数でweightパラメータによる個別の改善を可能に。(ドキュメント) 詳細については1.4.0.Beta1のブログ(英語)(日本語訳)をご覧ください。\nBeta1以降の1.4.0の変更の全てについては、1.4.0 release notesでご覧いただけます。 以下では、2つの主な変更について紹介します。\nHTTP Pipelining HTTP pipeliningは複数のリクエストを1回のコネクションで、関連するレスポンスを待つことなく送信することができます。 そして、レスポンスは、受け取ったリクエストと同じ順序で返却されます。 HTTP/1.1の仕様で、pipeliningのサポートが必要です。ElasticsearchはHTTP/1.1であるとしてきましたが、pipeliningはサポートしていませんでした。この問題は.NETユーザで問題を引き起こしました。\n現在、HTTP pipeliningは公式にサポート済みで、デフォルトで利用できます。#8299をご覧ください。\nUpgrade API Luceneのすべてのリリースではバグフィックスや最適化が提供されます。しかし、多くのユーザは古いバージョンのLuceneで作成されたインデックスを持っており、より最新の改善による利点を利用できないことがあります。 新しいupgradeAPIは、あなたのインデックスすべてもしくは一部を最新のLuceneフォーマットに透過的にアップグレードできます。\nGET _upgradeリクエストは、インデックスのアップグレードが必要かどうかを提示し、アップグレードに必要なセグメントのサイズをリポートすることによって、どのくらいの時間が必要かの目安を提供します。 POST _upgradeコマンドはバックグラウンドでインデックスを最新のLuceneフォーマットに書き換えます。\nより詳しい情報はupgradeAPIドキュメントをご覧ください。\n試してみてください。 Beta1リリースを利用し、経験・体験を報告していただいたベータテスターの方々に感謝します。 1.4.0がこれまでの最高のリリースになると確信しています。 ぜひ、Elasticsearch 1.4.0をダウンロードして、試してみてください。 そして、感想をTwitter(@elasticsearch)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1415205033,"dir":"post/2014/","id":"d266a2023c67b7a20c3bd01055b223bc","lang":"ja","lastmod":1415205033,"permalink":"https://blog.johtani.info/blog/2014/11/06/elasticsearch-1-4-0-ja/","publishdate":"2014-11-06T01:30:33+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:elasticsearch-1.4.0 and 1.3.5 released 本日、Lucene 4.10.2をベースにし","tags":["elasticsearch"],"title":"Elasticsearch 1.4.0および1.3.5リリース(日本語訳)"},{"contents":"久しぶりに翻訳ではないブログを。書こうと思いながらかけてなかったので。。。\n今回はvalidate APIの紹介です。\n背景 ElasticsearchのクエリはQuery DSLというJSONで クエリを定義できるものを提供しています。 これは、様々なクエリ、フィルタを定義するために必要です。\n自分の望んでいる条件を記述するために、JSONのネストと格闘することも必要となります。。。 また、クエリ、フィルタには様々なパラメータが用意されています。 これらのパラメータをすべて覚えるのは無理でしょうし、タイプミスなどもありますよね。 タイプミスやカッコのミスマッチなどで格闘して1時間が経過してしまったなどもあると思います。\nそんな時に便利なAPIとして用意されているのがvalidate APIです。\n利用方法 APIが用意されています。\nhttp://ホスト名:ポート番号/インデックス名/タイプ名/_validate/query インデックス名やタイプ名は省略可能ですが、マッピングが異なると思うので、タイプ名まで指定するほうが良いと思います。 上記のAPIに対してクエリを送信するだけです。\nクエリの確認 たとえば、こちらのGistにあるようなマッピングのインデックスに対して 検索クエリを組み立てていて、エラーが出るとします。 ※このクエリはmatch_allのところをmatch_alと、lが1文字足りないクエリになっています。\n検索クエリのリクエスト(エラーあり)\nGET pref_aggs/_search { \u0026#34;query\u0026#34;: { \u0026#34;match_al\u0026#34;: {} } } 実行結果のレスポンス\n{ \u0026#34;error\u0026#34;: \u0026#34;SearchPhaseExecutionException[Failed to execute phase [query], all shards failed; shardFailures {[rwkb01chTZq2V7FD0Tlwrw][pref_aggs][0]: SearchParseException[[pref_aggs][0]: from[-1],size[-1]: Parse Failure [Failed to parse source [{\\n \\\u0026#34;query\\\u0026#34;: {\\n \\\u0026#34;match_al\\\u0026#34;: { }\\n }\\n}\\n]]]; nested: QueryParsingException[[pref_aggs] No query registered for [match_al]]; }{[rwkb01chTZq2V7FD0Tlwrw][pref_aggs][1]: SearchParseException[[pref_aggs][1]: from[-1],size[-1]: Parse Failure [Failed to parse source [{\\n \\\u0026#34;query\\\u0026#34;: {\\n \\\u0026#34;match_al\\\u0026#34;: { }\\n }\\n}\\n]]]; nested: QueryParsingException[[pref_aggs] No query registered for [match_al]]; }]\u0026#34;, \u0026#34;status\u0026#34;: 400 } とこんなかんじで、エラーが帰っては来るのですが、非常に読みづらいです。\nそこで、validate APIを利用します。 リクエスト先を/_searchから/_validate/queryに変更します。\nvalidate API\nGET pref_aggs/_validate/query { \u0026#34;query\u0026#34;: { \u0026#34;match_al\u0026#34;: {} } } validate APIのレスポンス\n{ \u0026#34;valid\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;failed\u0026#34;: 0 } } すると、非常にシンプルな結果が返ってきます。 \u0026quot;valid\u0026quot;: falseとなっているため、クエリに問題があることがわかります。\nエラーの詳細 問題がある事自体はわかりましたが、エラーの内容も知りたいですよね? その場合は、explainというパラメータを追加します。 (正しくはexplain=trueを追加しますが、=trueを省略可能です。)\nvalidate API(explainあり、クエリ自体は省略)\nGET pref_aggs/_validate/query?explain {...} validate APIのレスポンス\n{ \u0026#34;valid\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;explanations\u0026#34;: [ { \u0026#34;index\u0026#34;: \u0026#34;pref_aggs\u0026#34;, \u0026#34;valid\u0026#34;: false, \u0026#34;error\u0026#34;: \u0026#34;org.elasticsearch.index.query.QueryParsingException: [pref_aggs] No query registered for [match_al]\u0026#34; } ] } explanationsという項目が追加されました。 ここにerrorという項目として、エラーの詳細が返ってきます。_searchの時よりも見やすいですね。 今回のエラーは、match_allが正しいクエリですの、match_alというクエリは登録されていないというエラーでした。 では、クエリを修正して実行しましょう。\nvalidate API(エラー無し)\nGET pref_aggs/_validate/query?explain { \u0026#34;query\u0026#34;: { \u0026#34;match_all\u0026#34;: {} } } validate APIのレスポンス\n{ \u0026#34;valid\u0026#34;: true, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;explanations\u0026#34;: [ { \u0026#34;index\u0026#34;: \u0026#34;pref_aggs\u0026#34;, \u0026#34;valid\u0026#34;: true, \u0026#34;explanation\u0026#34;: \u0026#34;ConstantScore(*:*)\u0026#34; } ] } 今度はクエリに問題はありません。\u0026quot;valid\u0026quot;: trueです。 そして、explanationsの項目には、errorの代わりにexplanationという項目が返ってきました。 これが、実際にElasticsearch内部で実行されるクエリになります。\n実際のクエリに利用される単語の確認 この機能はこの他に、クエリの解析にも利用できます。 思ったとおりに検索にヒットしない場合があって、困ったことはないですか? フィールドに指定されたアナライザによっては、単語を変形したりするものが存在します。\nサンプルマッピング\nPUT /validate_sample { \u0026#34;mappings\u0026#34;: { \u0026#34;several_analyzer\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;title\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;body_ja\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;kuromoji\u0026#34;}, \u0026#34;body_en\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;english\u0026#34;} } } } } 例えば、このようにkuromoji、english、デフォルト(standard)アナライザを利用したマッピングがあるとします。 このフィールドに対してpowerfulという単語で検索したとします。\nvalidate API\nGET /validate_sample/_validate/query?explain { \u0026#34;query\u0026#34;: { \u0026#34;multi_match\u0026#34;: { \u0026#34;fields\u0026#34;: [\u0026#34;body_en\u0026#34;,\u0026#34;body_ja\u0026#34;,\u0026#34;title\u0026#34;], \u0026#34;query\u0026#34;: \u0026#34;powerful\u0026#34; } } } この場合、レスポンスは次のとおりです。\nvalidate APIのレスポンス\n{ \u0026#34;valid\u0026#34;: true, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;explanations\u0026#34;: [ { \u0026#34;index\u0026#34;: \u0026#34;validate_sample\u0026#34;, \u0026#34;valid\u0026#34;: true, \u0026#34;explanation\u0026#34;: \u0026#34;(title:powerful | body_en:power | body_ja:powerful)\u0026#34; } ] } title、body_jaについては入力された単語がそのままクエリとして利用されています。 body_enについては、powerという単語に変換されて実行されています。 これは、englishアナライザがステミングを行った結果がクエリとして利用されるという意味です。 また、powerfulを秋葉原といった日本語に変更して実行すると次のようになります。 日本語はstandardアナライザなどでは、1文字ずつ区切られてしまうことがわかります。\nvalidate APIのレスポンス\n{ \u0026#34;valid\u0026#34;: true, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;explanations\u0026#34;: [ { \u0026#34;index\u0026#34;: \u0026#34;validate_sample\u0026#34;, \u0026#34;valid\u0026#34;: true, \u0026#34;explanation\u0026#34;: \u0026#34;((title:秋 title:葉 title:原) | (body_en:秋 body_en:葉 body_en:原) | ((body_ja:秋葉 body_ja:秋葉原) body_ja:原))\u0026#34; } ] } このように、クエリの単語がどのような単語に変換されてクエリに利用されているかなども知ることが可能です。\nまた、クエリを組み立てて、ヒットするはずが、0件となってしまうという場合にも、どのようなクエリが組み立てられているかを確認するという点で、 validate APIが役立ちます。 検索がヒットするが、望んだクエリになっていないのでは?という場合は_search APIのexplainパラメータを 利用すれば、クエリの構成がわかるのですが、検索結果が0件の場合はクエリの構成は表示されません。\n解決できない問題は? 便利なvalidate APIですが、以下の問題に対しては残念ながら確認できません。\nquery以外の項目のvalidate不可 たとえば、_search APIのsizeなどの項目についてはチェックできないです。 存在しないフィールドの指定 上記validate_sampleのマッピングの例でクエリにbody_engという存在しないフィールドを指定してもエラーとはなりません。 まとめ 書いたクエリがうまく動かない、JSONのタグがおかしいといった場合は、 まずはこのvalidate APIで確認してみるのがオススメです。\n","date":1414402951,"dir":"post/2014/","id":"bc2709406a9bb19e8d83a78f81e36244","lang":"ja","lastmod":1414402951,"permalink":"https://blog.johtani.info/blog/2014/10/27/how-to-use-validate-api/","publishdate":"2014-10-27T18:42:31+09:00","summary":"久しぶりに翻訳ではないブログを。書こうと思いながらかけてなかったので。。。 今回はvalidate APIの紹介です。 背景 Elasticsear","tags":["elasticsearch"],"title":"validate APIの利用"},{"contents":"Elasticsearch 1.4.0.Beta1がリリースされました。\n個人でelasticsearch-extended-analyzeというプラグインを開発してます。 こちらも1.4.0.Beta1に対応するべく作業をしてて、少し戸惑ったことがあったので、メモをば。\nここ最近はプラグインのバージョン番号をElasticsearchのバージョン番号と同じものを利用していました。 (プラグインの機能追加をサボってる??) その時に、1.4.0.Beta1という番号を指定したのですが、意味不明なエラーに悩まされてしまいまして。\nプラグインのリリースでは、以下のコマンドを実行します。\n$ mvn release:prepare $ mvn release:perform 最初のコマンド(prepare)で、パッケージングを実施し、Githubにリリースタグを打ったバージョンがpushされます。 次のコマンド(perform)で、パッケージングされたzipファイルがsonatypeのサイトに公開するためにアップロードされます。\n1.4.0.Beta1というバージョン文字列を利用した場合、prepareは問題なく実行できたのですが、 performで以下の様なエラーが返ってきました。\nReturn code is: 401, ReasonPhrase: Unauthorized. バージョン番号が1.3.0では特に問題はなかったのですが、、、 結局、バージョン番号を1.4.0-beta1に変更すると問題なくリリースが完了しました。\nmike_neckさんと話をしていて、Semantic Versioningに関係しているのかなぁという話にはなったのですが、 詳しく調べていません。。。\nそのうち調べようかなぁ。。。。\n","date":1413354368,"dir":"post/2014/","id":"998eda745d07fd8608f251138384a0b9","lang":"ja","lastmod":1413354368,"permalink":"https://blog.johtani.info/blog/2014/10/15/versioning-of-sonatype/","publishdate":"2014-10-15T15:26:08+09:00","summary":"Elasticsearch 1.4.0.Beta1がリリースされました。 個人でelasticsearch-extended-analyzeというプラグインを開発してま","tags":["Elasticsearch","plugin","sonatype"],"title":"Sonatypeのバージョン番号で困ったので"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:elasticsearch 1.4.0.beta1 released\n本日、Lucene 4.10.1をベースにした、Elasticsearch 1.4.0.Beta1をリリースしました。 Elasticsearch 1.4.0.Beta1からダウンロードできます。 また、すべての変更点に関してもこちらをご覧ください。\n1.4.0のテーマは*resiliency(復元性、弾力性)*です。 resiliencyとはElasticsearchをより安定し信頼性のあるものにすることを意味します。 すべての機能が正常に機能している場合は信頼することは簡単です。 予想外のことが発生した時に難しくなります:ノードでout of memoryの発生、スローGCや重いI/O、ネットワーク障害、不安定なデータの送信によるノードのパフォーマンス低下など。\n本ベータリリースは、resiliencyの主な3つの改善を含んでいます。\nメモリ使用量の低下によるノードの安定性向上 discoveryアルゴリズムの改善によるクラスタの安定性向上 チェックサムの導入による破損したデータの検知 分散システムは複雑です。 決して想像できないような状況をシミュレーションするために、ランダムなシナリオを作成する広範囲なテストスイートを持っています。 しかし、無数のエッジケース(特殊なケース)があることも認識しています。 1.4.0.Beta1はこれまで私たちが行ってきた改善のすべてを含んでいます。 これらの変更を実際にテストしていただき、何か問題があった場合は私たちに教えてください。\nメモリ管理 ヒープ空間は限られたリソースです。 上限を32GBとし、利用可能なRAMの50%をヒープの上限にすることを推奨します。 この上限を超えた場合、JVMは圧縮したポインタを使用することができず、GCが非常に遅くなります。 ノードの不安定性の主な原因は遅いGCです。それは、次のようなことから発生します。\nメモリプレッシャー スワップ(参照:memory settings) 非常に大きなヒープ 本リリースは、メモリ管理の改善し、(結果として)ノードの安定性を改善するいくつかの変更を含んでいます。\ndoc values メモリの利用の最も大きなものの1つはfielddataです aggregation、ソート、スクリプトがフィールドの値に素早くアクセスするために、フィールドの値をメモリにロードして保持します。 ヒープは貴重なため、1ビットも無駄にしないためにメモリ内のデータは高度な圧縮と最適化を行っています。 これは、ヒープスペース以上のデータをもつまでは、非常によく動作します。 これは、多くのノードを追加することによって常に解決できる問題です。 しかし、CPUやI/Oが限界に達してしまうずっと前に、ヒープ空間の容量に到達します。\n最近のリリースは、doc valuesによるサポートがあります。 基本的に、doc valuesはin-memory fielddataと同じ機能を提供します。 doc valuesの提供する利点は、それらが、非常に少量のヒープ空間しか使用しない点です。 doc valuesはメモリからではなく、ディスクから読み込まれます。 ディスクアクセスは遅いですが、doc valuesはカーネルのファイルシステムキャッシュの利点を得られます。 ファイルシステムキャッシュはJVMヒープとはことなり、32GBの制限による束縛がありません。 ヒープからファイルシステムキャッシュにfielddataを移行することによって、より小さなヒープを使うことができます。これは、GCがより早くなり、ノードが更に安定することを意味します。\n本リリースより前は、doc valuesはin-memory fielddataよりもかなり遅かったです。 本リリースに含まれる変更は、パフォーマンスをかなり向上させ、in-memory fielddataとほぼ同じくらいの速度になっています。\nin-memory fielddataの代わりにdoc valuesを利用するために必要なことは、次のように新しいフィールドをマッピングすることです。\nPUT /my_index { \u0026#34;mappings\u0026#34;: { \u0026#34;my_type\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;timestamp\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;date\u0026#34;, \u0026#34;doc_values\u0026#34;: true } } } } } このマッピングで、このフィールドに対するfielddataの利用は、メモリにフィールドをロードする代わりに、自動的にディスクからdoc valuesを利用します。 *注意:*現時点で、doc valuesはanalyzedなstringフィールドはサポートしていません。\nrequest circuit breaker fielddata circuit breakerはfielddataによって利用されるメモリの上限を制限するために追加され、OOMEの最も大きな原因の1つを防ぎました。 そして、リクエストレベルのcircuit-breakerを提供するために、コンセプトを拡張しました。 これは、単一のリクエストによって使用されるメモリの上限を制限します。\nbloom filters Bloom filters はインデキシング(前のバージョンのドキュメントが存在するかどうかのチェックのため)や、 IDによるドキュメントの検索(ドキュメントを含むセグメントがどれかを決定するため)に関する重要な性能最適化を提供しました。 しかし、もちろんそれらはコスト(メモリ)を必要とします。 現在の改善は、bloom filterの必要性を取り除きました。 現在では、Elasticsearchはまだ、インデックス時にそれらを構築します(実世界の経験がテストシナリオにそぐわない場合に備えて)。 しかし、デフォルトではメモリにはロードされません。 すべてが予定通りに運べば、将来のバージョンで完全にこれらは除去します。\nクラスタの安定性 クラスタの安定性向上のために私たちができる最も大きなことは、ノードの安定性の向上です。 もし、ノードが安定しておりタイミングよく反応すれば、クラスタが不安定になる可能性が大いに減少します。 私たちは不完全な世界に住んでいます。- 物事は予想外にうまく行きません。クラスタはデータを失うことなくこのような状況から回復できる必要があります。\n私たちは、improve_zenブランチ上で、Elasticsearchの障害からの復旧するための能力の向上に数ヶ月費やしてきました。 まず、複雑なネットワークレベルの障害を繰り返すためのテストを追加しました。 次に、各テストのための修正を追加しました。 そこには、より多くの行うことが存在します。しかし、私たちは、issue #2488(\u0026ldquo;分割が交差している場合、minimum_master_nodesはsplit-brainを防げない\u0026rdquo;)に含まれる、ユーザが経験してきた大部分の問題を私たちは解決しました。\n私たちはクラスタのresiliencyを非常に真剣に取り組んでいます。 私たちは、Elasticsearchが何ができるか、その上で何が弱点であるかを理解してほしいと思っています。 これを考慮して、私たちはResiliency Status Documentを作成しました。 このドキュメントは、私たち(または私たちユーザ)が遭遇したresiliencyの問題の、何が修正済みで、何が修正されないまま残っているかを記録します。 このドキュメントを慎重に読み、あなたのデータを保護するために適切な方法を選択してください。\nデータ破損の検知 ネットワークをまたいだシャードリカバリのチェックサムは、圧縮ライブラリのバグを発見する助けとなりました。 それは、バージョン1.3.2で修正済みです。 それ以来、私たちはElasticsearchのいたるところにチェックサムとチェックサムの確認を追加しました。\nマージ中に、あるセグメント内すべてのチェックサムの確認(#7360) インデックス再オープン時に、あるセグメント内の最も小さなファイルの完全な確認と、より大きなファイルの軽量な打ち切りチェック(LUCENE-5842) トランザクションログからイベントを再生するとき、各イベントはチェックサムを確認される(#6554) シャードのリカバリ中もしくは、スナップショットからのリストア中にElasticsearchはローカルファイルとリモートのコピーが同一であるか確認する必要がある。ファイルの長さとチェックサムのみを使うのは不十分であることが確認された。このため、現在はセグメントのすべてのファイルの同一性を確認(#7159) その他のハイライト Elasticsearch 1.4.0.Beta1のchangelogに本リリースの多くの機能、改善、バグフィックスについて読むことができます。 ここでは、特筆すべきいくつかの変更について述べます。\ngroovyによるmvelの置き換え Groovyは現在、デフォルトのscripting languageです。 以前のデフォルトはMVELで、古くなってきており、サンドボックス内で実行できないという事実は、セキュリティ問題でした。 Groovyはサンドボックスであり(それは、ボックスの外へは許可が必要)、メンテナンスされており、速いです! 詳しくはscriptingについてのブログ記事をご覧ください。\nデフォルトでcorsはオフ Elasticsearchのデフォルト設定はクロスサイトスクリプティングに対して脆弱でした。 私たちはデフォルトでCORSをオフにすることで修正しました。 Elasticsearchにインストールされたサイトプラグインはこれまで同様に機能します。 しかし、CORSを再度オンにすることがない限り、外部のウェブサイトがリモートのクラスタにアクセスすることはできません。 ウェブサイトがあなたのクラスタにアクセス可能に制御できるように、さらにCORS settingsを追加しました。 詳しくはsecurity pageをご覧ください。\nクエリキャッシュ 新しい試験的なshardレベルのクエリキャッシュは、静的なインデックスのアグリゲーションをほとんど即座に反応できます。 ウエブサイトのアクセスの日毎のページビュー数を見るダッシュボードを持っていると想像してみてください。 これらの数値は古いインデックスでは変更がありません。しかし、アグリゲーションはダッシュボードのリフレッシュのたびに再計算されます。 新しいクエリキャッシュを利用すると、シャードのデータが変更されない限り、アグリゲーションの結果はキャッシュから直接返却されます。 キャッシュから古い結果を決して取得することはありません。それは、常に、キャッシュされていないリクエストと同じ結果を返します。\n新しいaggregations 3つの新しいaggregationsがあります。\nfilters\nこれはfilter aggregationの拡張です。複数のバケットを定義し、バケット毎に異なるフィルタを利用できます。 children\nnestedアグリゲーションの親子版。children aggは親のドキュメントに属する子のドキュメントを集計できる scripted_metric\nこのaggregationは、データによって計算されたメトリックを完全にコントロールできます。これは、初期化フェーズ、ドキュメント収集フェーズ、shardレベル結合フェーズ、global reduceフェーズを提供します。 get /index api 以前、ある1つのインデックスのaliases、mappings、settings、warmersを取得出来ました。しかし、それらを個別にです。 get-index API はこれらのすべてもしくは一部を、複数もしくはひとつのインデックスに対して一緒に取得できます。 これは、既存のインデックスと同一もしくはほぼ同一であるインデックスを作成したいときに非常に役に立ちます。\n登録と更新 ドキュメントの登録と更新にいくつかの改善があります。\n現在、ドキュメントIDの自動生成のためにFlake IDを使用しています。これは、プライマリキー探索時に素晴らしい性能向上を提供します。 detect_noopにtrueを設定すると、ドキュメントに変更を与えない更新が軽量になります。この設定を有効にすると、_sourceフィールドのコンテンツを変更する更新リクエストだけ、ドキュメントの新しいバージョンを書き込みます。 更新はスクリプトから完全に操作できます。以前は、スクリプトはドキュメントがすでに存在しているときだけ実行可能で、それ以外は、upsertドキュメントで登録しました。script_upsertパラメータでスクリプトから直接ドキュメントの作成が操作できます。 function score すでに非常に便利なfunction_scoreクエリが、新しくweightパラメータをサポートします。 これは、それぞれの指定された関数の影響をチューニングするのに使われます。 これは、人気度よりも更新日時により重みをかけたり、地理情報よりも価格により重みをかけるといったことを可能にします。 また、random_score機能はセグメントマージによる影響を受けません。これにより、より一貫した順序が提供されます。\n試してみてください。 ぜひ、Elasticsearch 1.4.0.Beta1をダウンロードして、試してみてください。 そして、感想をTwitter(@elasticsearch)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1412244840,"dir":"post/2014/","id":"853cac0f2d1f90b7c986e7d1dcdbbfde","lang":"ja","lastmod":1412244840,"permalink":"https://blog.johtani.info/blog/2014/10/02/elasticsearch-1-4-0-beta-released-ja/","publishdate":"2014-10-02T19:14:00+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:elasticsearch 1.4.0.beta1 released 本日、Lucene 4.10.1をベースにした、Elast","tags":["Elasticsearch"],"title":"elasticsearch 1.4.0.Beta1のリリース"},{"contents":"第6回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 次回もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。 今回は、スタッフが私を含めて3,4名ということで、ドタバタしてしまってスミマセンでした。\n今回はキャンセルが多く、最終的には90人弱の参加となりましたが、今回も多数の方にお集まりいただきありがとうございました。 同じ日に他の勉強会もあった影響でしょうか?\n「Aggregationあれこれ」Elasticsearch Inc. Jun Ohtani @johtani スライド:Aggregationあれこれ\nちょっと長かったですかね。。。 Aggregationの概要、内部動作、種類などを簡単に紹介してみました。 個々のAggregationもいろいろなオプションなどがあるので、色々と試してみていただければと思います。 アニメーション入りのスライドになってましたが、UpしてあるスライドはPDF版になります。 「秒間3万の広告配信ログをElasticSearchでリアルタイム集計してきた戦いの記録」 株式会社サイバーエージェント 山田直行さん @satully スライド:秒間3万の広告配信ログをElasticSearchでリアルタイム集計してきた戦いの記録\nディスプレイ広告配信DSPの話 システム: Fluentd、S3、Elasticsearch、Redis、MySQL 7月に秒間3万〜4万のリクエストをさばいている。 なぜElasticsearchを選んだのか、今の構成など 実際に苦労された点なども交えて話していただき面白かったです。 7月時点のお話ということで、現時点ではまた違う構成っぽかったので、また話を聞きたいなぁ。 「Elasticsearch 日本語スキーマレス環境構築と、ついでに多言語対応」ナレッジワークス株式会社 木戸国彦さん @9215 スライド:Elasticsearch 日本語スキーマレス環境構築と、ついでに多言語対応\nDynamic TemplateやIndex Templateの説明 日本語や多言語化するときのMappingのサンプルになりそうなものがゴロゴロ紹介されてました。 いくつかの例があって、後で見直したいなと。 途中で出てきた、fielddata(インデックスに入っている単語区切りのデータ)を見るのに使ってたクエリはfield data fieldsだったかな。 「elasticsearchソースコードを読みはじめてみた」@furandon_pig さん スライド:elasticsearchソースコードを読みはじめてみた\nリクエストを受けて検索してる部分から読むといいって言われたらしいが、起動スクリプトから読み始めてみた。 時間かかりそうw ただ、人がどんな感じでソースを読んだり理解してるかがわかりやすかったので面白かったです。 定期的に続きを聞いてみたいです。 LT 「reroute APIを使用してシャード配置を制御する」 株式会社富士通ソフトウェアテクノロジーズ 滝田聖己さん @pisatoshi スライド:reroute APIを使用してシャード配置を制御する\nシャードの再配置が自動で行われるので、それをオフにしないと、せっかく移動しても無駄になることがというあるあるネタ Bonsaiロゴを作成するLT 実際にいくら掛かったのかが知りたかった。 「検索のダウンタイム0でバックアップからIndexをリストアする方法」株式会社ドワンゴモバイル 西田和史さん スライド:検索のダウンタイム0でバックアップからIndexをリストアする方法\n擬似無停止のやりかた。 aliasを活用して、かつ、Restoreで再構築するという方法。 aliasまで一緒にリストアされるので注意が必要っていうのは、実際にやってみたからわかることという感じですね。 その他、感想などのブログ 適当に見つけたブログを列挙してあります。これもあるよ!などあれば、教えてください。\n第6回elasticsearch勉強会に行ってきましたのでそのメモ elasticsearch 勉強会 第6回 まとめ 今回も、ためになる話がいっぱい聞けたかなと。 個人的な印象としては、いつものメンバーよりも新しい方が多かった印象です。 また、ほとんどの方が、Elasticsearchをご存知でした。 そこそこ知名度は上がってきているようで嬉しい限りです。(東京以外での知名度なども知りたいかなと。)\nあと、懇親会の部屋の案内が遅くなってしまってスミマセンでした。 さすがにスタッフ3名はきつかったです。。。\n19時半開始にしてみましたが、懇親会の時間がやはり短めになってしまうなぁという印象でした。\n次回ももちろん2ヶ月後くらいに行います。 スピーカー募集中ですので、コメント、メール、ツイートなど、コンタクトしていただければと思います。 よろしくお願いいたします。\n","date":1410927720,"dir":"post/2014/","id":"4616fbea6a6dbc1074bc3f1016bbc73b","lang":"ja","lastmod":1410927720,"permalink":"https://blog.johtani.info/blog/2014/09/17/hold-on-6th-elasticsearch-jp/","publishdate":"2014-09-17T13:22:00+09:00","summary":"第6回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん","tags":["elasticsearch","勉強会"],"title":"第6回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"先日2014年9月9日(火)に『サーバ/インフラエンジニア養成読本 ログ収集〜可視化編』 出版記念!執筆者が語る大講演会!で、 「elasticsearch.もうちょっと入門」というタイトルで発表してきました。 会場のGMOのみなさま、Treasure Data、技術評論社のみなさま、どうもありがとうございました。\n書籍に興味のある方は、右のリンクから購入してもらえるとうれしいです。Kindle版も用意されています。\n提供のTDの方に目をつぶってもらいながらLogstashについての発表となってしまいましたが、楽しんでいただけたかなぁと。 書籍では主にKibana3をメインにしたElasticsearchの使い方だったので、それ以外の機能ということで、Aggregationについて説明してみました。\nそのあとは、おそらく初めてですが、パネルディスカッションにも参加しました。 @naoya_itoさんをモデレーターに、rebuild.fm風に進めていただき、話しやすかったかなと。 (少なくとも私は楽しめました!) ただ、私だけバックグラウンドが少し異なることもあり、話をうまく繋げられなかったかもと気にしていたりもしますが。。。\nパネルディスカッションでもありましたが、エンジニアが「趣味」で入れて試してみるのにはもってこいのツール群だと思います。 ちょっと入れてみて、可視化をしてみるといろいろと発見があると思います。 何かを発見するためにもまず試してみるのが何事も重要かなと最近思ってるのもあるので、気軽に試してみてもらえればと。\n不明点などあれば、著者陣に気軽に聞いていただけると良いかと思います(いいですよね、みなさんw)。 Fluentd(もちろん、Logstashも)、Elasticsearch、Kibanaを利用して、データについて試行錯誤してもらって、 システムやビジネスに必要なものを探索して見てください。\n参考 他の方々のブログをメモとして。\nサービス改善とログデータ解析について発表してきました Kibanaではじめるダッシュボードについて発表してきました #gihyo_efk Fluentdのお勧めシステム構成パターンについて発表しました ","date":1410841260,"dir":"post/2014/","id":"f15702ae9e55bad42182cf18724d1863","lang":"ja","lastmod":1410841260,"permalink":"https://blog.johtani.info/blog/2014/09/16/book-publication-event/","publishdate":"2014-09-16T13:21:00+09:00","summary":"先日2014年9月9日(火)に『サーバ/インフラエンジニア養成読本 ログ収集〜可視化編』 出版記念!執筆者が語る大講演会!で、 「elastics","tags":["勉強会","本"],"title":"elasticsearch.もうちょっと入門という話をしてきました #gihyo_efk"},{"contents":"Elasticsearchのインデキシングに関するパフォーマンス検討\n原文:performance considerations for elasticsearch indexing\nElasticsearchユーザは様々な楽しいユースケースを持っています。小さなログを追加することから、Webスケールの大きなドキュメントの集合をインデキシングするようなことまでです。また、インデキシングのスループットを最大化することが重要で一般的な目標となります。 「典型的な」アプリケーションに対して良いデフォルト値を設定するようにしていますが、次のちょっとした簡単なベストプラクティスによってインデキシングのパフォーマンスをすぐに改善することができます。それらについて記述します。\n第一に、制御できないならば、巨大なJavaヒープを使用しない:必要なサイズ(マシンの持つRAMの半分以下)のheapだけを設定しましょう。Elasticsearchの利用方法のために必要な全体量を設定します。これは、OSにIOキャッシュを制御するためのRAMを残すことを意味します。OSがjavaプロセスをスワップアウトしていないことも確認しましょう。\n最新バージョン(現時点では1.3.2)のElasticsearchにアップグレードしましょう:多数のインデキシングに関連する問題点が最新リリースで修正されています。\n詳細に入る前に警告:ここで述べるすべての情報は現時点での最新(1.3.2)の情報です。しかし、Elasticsearchの更新は日々行われています。この情報をあなたが見た時点では最新ではなく、正確ではなくなっているかもしれません。自信がない場合はユーザメーリングリストで質問してください。\nクラスタのインデキシングスループットをチューニングする場合、Marvelは非常に有用なツールです:ここで述べている各設定を継続的に試し、変更の影響がクラスタの挙動をどのように変更されたかを簡単に可視化することが可能です。\nクライアントサイド bulk APIを常に使いましょう。1リクエストで複数のドキュメントをインデキシングでき、各バルクリクエストで送るのに良いドキュメント数を試しましょう。最適なサイズは多くの要因に依存しますが、最適サイズからずれるならば多すぎるよりも少なすぎる方が良いでしょう。クライアントサイドのスレッドで並列にbulkリクエストを使うか、個別の非同期リクエストを使ってください。\nインデキシングが遅いと結論付ける前に、クラスタのハードウェアの性能を引き出せているかを確認して下さい:すべてのノードでCPUやIOが溢れていないかを確認するためにiostatやtop、psといったツールを使いましょう。もし、溢れていなければ、より多くの並列なリクエストが必要です。しかし、javaクライアントからのEsRejectedExecutionExceptionや、RESTリクエストのHTTPレスポンスとしてTOO_MANY_REQUESTS (429)が返ってきた場合は並列リクエストを多く送りすぎています。もしMarvelを利用しているなら、Node Statistics DashboardのTHREAD POOLS - BULKにリジェクトされた数が表示されます。bulkスレッドプールサイズ(デフォルト値はコア数)を増やすのは得策ではありません。インデキシングスループットを減少させるでしょう。クライアントサイドの並列度を下げるか、ノードを増やすのが良い選択です。\nここでは、1シャードに対してインデキシングスループットを最大化する設定に注目します。1つのLuceneインデックスのドキュメントの容量を測定するために、単一ノード(単一シャード、レプリカなし)で最初にテストをして最適化し、クラスタ全体にスケールする前にチューニングを繰り返します。これはまた、インデキシングスループットの要件を見つけるために、クラスタ全体にどのくらいのノードが必要かをラフに見積もるためのベースラインを与えてくれます。\n単一シャードが十分機能したら、Elasticsearchのスケーラビリティの最大の利点や、クラスタでの複数ノードによるレプリカ数やシャード数の増加の利点が得られます。\n結論を導き出す前に、ある程度の時間(60分)くらいクラスタ全体の性能を計測しましょう。このテストは、巨大なマージ、GCサイクル、シャードの移動、OSのIOキャッシュ、予期しないスワップの可能性などのイベントのライフサイクルをカバーできます。\nストレージデバイス 当然ながらインデックスを保存するストレージデバイスはインデキシングの性能に多大な影響を及ぼします:\nSSDを利用する:これらは最も速いHDDよりも速いです。ランダムアクセスのための消費電力が低いだけでなく、シーケンシャルIOアクセスも高いです。また、同時に発生するインデキシング、マージや検索のための並列的なIOも高速です。 インデックスをリモートマウントされたファイルシステム(例:NFSやSMB/CIFS)上に配置しない:代わりにローカルストレージを使う 仮想化されたストレージ(AmazonのElastic Block Storageなど)に注意:仮想化されたストレージはElasticsearchで十分に動作します。また、十分早く簡単に用意できることから魅力的です。しかし、残念なことに、ローカルストレージと比較すると本質的に遅いです。最近の非公式なテストでは、最高の性能を持つプロビジョニングされたIOPSのSSDオプションのEBSでさえ、ローカルインスタンスにあるSSDよりも遅いです。ローカルインスタンスにあるSSDは物理マシン上のすべての仮想マシンから共有されてアクセスされます。もし他の仮想マシンが急にIOが集中した場合に不可解なスローダウンとなることがあることを覚えておいてください。 複数のSSDを複数のpath.dataディレクトリにインデックスをストライピング(RAID0のように):2つは同様で、ファイルブロックレベルでストライピングする代わりに、個別にインデックスファイルレベルでElasticsearchの\u0026quot;stripes\u0026quot;となります。これらのアプローチは、いづれかのSSDの故障によりインデックスが壊れるという、1シャードが故障する(IO性能を高速化することとトレードオフ)というリスクを増加させることに注意してください。これは、一般的に行うのに良いトレードオフです:単一シャードで最大のパフォーマンスを最適化し、異なるノード間でレプリカを追加すると、ノードの故障への冗長化ができます。また、snapshotやrestoreを使って保険のためにインデックスのバックアップを取ることもできます。 セグメントとマージ 新しくインデキシングされたドキュメントは最初にLuceneのIndexWriterによってRAMに保存されます。RAMバッファがいっぱいになった時もしくは、Elasticsearchがflushもしくはrefreshを実行した時など定期的にこれらのドキュメントはディスクに新しいセグメントとして書き込まれます。最後に、セグメントが多くなった時に、Merge PolicyとSuchedulerによってそれらがマージされます。このプロセスは連続的に生じます:マージされたセグメントはより大きなセグメントとなり、小さなマージが幾つか実行され、また、大きなセグメントにマージされます。これらがどのように動作するかをわかりやすく可視化したブログはこちらです。\nマージ、特に大きなマージは非常に時間がかかります。これは、通常は問題ありません。そのようなマージはレアで全体のインデックスのコストと比べればささいなものです。しかし、マージすることがインデキシングについていけない場合、インデックスに非常に多くのセグメントがあるような深刻な問題を防ぐために、Elasticsearchはやってくるインデキシングリクエストを単一スレッド(1.2以降)に制限します。\nもし、INFOレベルのログメッセージにnow throttling indexingと表示されていたり、Marvelでのセグメント数が増加しているを見た場合、マージが遅れているとわかります。MarvelはIndex Statistics dashboardのMANAGEMENT EXTENDEDの部分にセグメント数をプロットしており、それは、非常にゆっくりと指数対数的に増加しており、大きなマージが終了したところがのこぎりの歯のような形で見て取れます。\nセグメント数 なぜマージが遅れるのでしょう?デフォルトでElasticsearchはすべてのマージの書き込みのバイト数をわずか20MB/secに制限しています。スピニングディスク(HDD)に対して、これはマージによって典型的なドライブのIOキャパシティを飽和させず、並列に検索を十分に実行させることを保証します。しかし、もし、インデキシング中に検索をしない場合や、検索性能がインデキシングのスループットよりも重要でない場合、インデックスの保存にSSDを使用している場合などは、index.store.throttle.typeにnoneを設定して、マージの速度制限を無効化するべきです(詳細はこちらをご覧ください)。なおバージョン1.2以前には期待以上のマージIO制限の発生といったバグが存在します。アップグレードを!\nもし、不幸にもスピニングディスク(それはSSDと同等の並列なIOを扱えません)をまだ使っている場合、index.merge.scheduler.max_thread_countに1を設定しなければなりません。そうでない場合は、(SSDを支持する)デフォルト値が多くのマージを同時に実行させるでしょう。\n活発に更新が行われているインデックスでoptimizeを実行しないでください。それは、非常にコストの高い操作(すべてのセグメントをマージ)です。しかし、もし、インデックスにドキュメントを追加が終わった直後はオプティマイズのタイミングとしては良いタイミングです。それは、検索時のリソースを減らすからです。例えば、時間ベースのインデックスを持っており、新しいインデックスに日々のログを追加している場合、過去の日付のインデックスをオプティマイズするのは良い考えです。特に、ノードが多くの日付のインデックスを持っている場合です。\n更にチューニングするための設定:\n実際に必要のないフィールドをオフにする。例えば_allフィールドをオフ。また、保持したいフィールドでは、indexedかstoredかを検討する。 もし、_sourceフィールドをオフにしたくなるかもしれないが、インデキシングコストは小さい(保存するだけで、インデキシングしない)、また、それは、将来の更新や、前のインデックスを再インデキシングするために非常に価値があり、それはディスク使用率の懸念事項がない限り、オフにする価値はあまりない。それは、ディスクが比較的安価であるので価値がない。 もし、インデックスされたドキュメントの検索までの遅延を許容できるなら、index.refresh_intervalを30sに増やすか、-1を設定して、オフにする。これは、巨大なセグメントをフラッシュし、マージのプレッシャーを減らすことができる。 Elasticsearch 1.3.2(稀に、フラッシュ時に過度のRAMを使用するという問題を修正した)にアップグレードすることで、index.translog.flush_threshold_sizeをデフォルト(200mb)から1gbに増加し、インデックスファイルのfsyncの頻度を減らす。 MarvelにIndex Statistics dashboardのMANAGEMENTにフラッシュの頻度がプロットされている。 インデックスバッファサイズ 巨大なインデックスを構築中はレプリカ数を0にし、あとから、レプリカを有効にする。レプリカが0ということは、データを失った(ステータスがred)時に冗長性がないので、ノードの故障に注意すること。もし、optimize(ドキュメントの追加をすることがないので)を計画するなら、インデキシングが終わったあとで、レプリカを作成する前に実行するのが良いでしょう。レプリカはオプティマイズされたセグメントをコピーするだけになります。詳細はインデックス設定更新を参照。\nもし、ノードがヘビーなインデキシングを行っているだけなら、アクティブなシャードのインデキシングバッファに多くてい512MBをindices.memory.index_buffer_sizeに与えてください。(超えてもインデキシングのパフォーマンスは一般的には改善されません。)Elasticsearchはその設定(Javaヒープのパーセンテージもしくはバイト数)を受けて、min_index_buffer_sizeとmax_index_buffer_sizeの値を前提にノードのアクティブシャードに均等に割り当てます;大きな値はLuceneが最初のセグメントをより大きくし、将来的なマージのプレッシャーを減らすことを意味します。\nデフォルトは10%で、それで十分です;例えば、もし、5つのアクティブなシャードがノードにあり、ヒープが25GBの場合、各シャードは25GBの10%の1/5=512MB(すでに最大値)を持っています。ヘビーなインデキシングのあと、この設定をデフォルトに下げましょう。検索時のデータ構造のために十分なRAMを確保するために。この設定はまだ動的な設定変更はできません。Issueがここにあります。\nインデックスバッファによって現在利用されているバイト数は1.3.0のindices stats APIに追加されています。indices.segments.index_writer_memoryの値を見ることができます。これはMarvelではまだプロットされていませんが、将来のバージョンで追加される予定です。しかし、自分でグラフに追加することもできます。(Marvelはデータは収集しています)\n1.4.0では、indices.segments.index_writer_max_memoryとして、indices stats APIにアクティブシャードにどのくらいのRAMバッファが割り当てられているかも表示されます。これらの値はインデックスのシャード事の値として見ることができ、http://host:9200/\u0026lt;indexName\u0026gt;/_stats?level=shardsを使ってみることができます;これは、全シャードに対する合計と、各シャードごとのstatsを返すでしょう。\nオートIDの利用もしくは良いIDの利用 もし、ドキュメントのIDがなんでも良い場合、Elasticsearchで採番することができます:これは、(1.2以降)ドキュメントIDをバージョンを探さずに保存できるように最適化され、Elasticsearchの日毎のベンチマークで異なるパフォーマンスを見ることができます。(FastとFastUpdateのグラフを比較)\nもし、IDを自身が持っていて、自分の支配下でLuceneに対して素早く選ぼうとしているなら、1.3.2にアップグレードしましょう、IDのルックアップがさらにオプティマイズされています。JavaのUUID.randomUUID()はやめましょう。それは、セグメントに対してどのようにIDを割り当てるかという予測やパターン性がないため、最悪のケースでセグメントごとのシークが発生します。\nFlake IDsを利用した時のMarvelによるインデックス性能の違い:\nflakeIDsPerf ランダムUUIDを利用した場合:\nuuidsPerf 次の1.4.0では、ElasticsearchのID自動採番をUUIDからFlake IDに変更します。\nもし、Luceneのローレベル操作がインデックスに対してなにをやっているかについて興味があるなら、lucene.iwをTRACEログレベルで出力できるようにしてみましょう(1.2から利用可能)。これは、多くの出力がありますが、LuceneのIndexWriterレベルで何が起きているかを理解するのに非常に役に立ちます。出力は非常にローレベルです:Marvelがインデックスに何が起きているかをよりリアルタイムにグラフを描画してくれます。\nスケールアウト 我々は、単一シャード(Luceneインデックス)性能のチューニングに注目してきました。しかし、一旦それに満足できたならば、Elasticsearchはクラスタ全体にわたってインデキシングや検索を簡単にスケールアウトすることに長けています。シャード数(デフォルトでは5)を増やすのは可能です。それは、マシン全体に対して並列度、巨大なインデックスのサイズ、検索時のレイテンシの低下など得ることができます。また、レプリカを1位上にすることは、ハードウェア故障に対する冗長性を持つことを意味します。\n最後に、このドキュメントを見ても問題解決しない場合はコミュニティに参加しましょう。例えば、ElasticsearchのユーザMLに投稿するなど。おそらく、修正すべきエキサイティングなバグがあるでしょう。(パッチも常に歓迎です!)\n","date":1410250260,"dir":"post/2014/","id":"77d965afaebd7193badc746d52b4173f","lang":"ja","lastmod":1410250260,"permalink":"https://blog.johtani.info/blog/2014/09/09/performance-considerations-for-elasticsearch-indexing/","publishdate":"2014-09-09T17:11:00+09:00","summary":"Elasticsearchのインデキシングに関するパフォーマンス検討 原文:performance considerations for elasticsearch indexing Elasticsearchユーザは様","tags":["Elasticsearch"],"title":"Elasticsearchのインデキシングに関するパフォーマンス検討"},{"contents":"懲りずにまた、執筆してみました。みなさん「買って」から感想をいただけるとうれしいです!\n本書について 共著者の方々のブログが詳しいので、そちらを読んでもらいつつ。 実際にログを収集して解析されている方々と一緒に書かせていただくことで色々と勉強させていただいています。\n共著者の方々のブログ @suzu_vさん:サーバ/インフラエンジニア養成読本 ログ収集~可視化編 を書きました @yoshi_kenさん:ログ収集や可視化で話題のFluentd、Elasticsearch、Kibanaを徹底解説したムック本が発売となります @harukasanさん:書きました: サーバ/インフラエンジニア養成読本 ログ収集~可視化編 どの辺を書いたの? 「特集3:Elasticsearch入門」(なんか、入門ばっかりだなぁ)を書かせていただきました。 データストア入門ということで、ほんとうに簡単な他のデータストアを説明し、Elasticsearchってどんなものかを単語の説明をしつつ紹介してみました。\nElasticsearch自体は多くの機能を持っており、それ単体で分厚い書籍がかけるので、ログ検索に関係ありそうな部分をピックアップしてみました。 あとは、運用時に気をつける点や便利なツール(Curatorなど)の紹介をしています。\nまた、Hadoopと合わせて利用してみたい、すでにHadoopにあるデータも活用してみたいという話もありそうだということで、elasticsearch-hadoopについても簡単ですが紹介してあります。\nその他感想 個人的に、忙しい時期(参考記事)だったので、あんまり力になれてないので大変申し訳なく思っています。。。 ただ、素晴らしい出来(カラーでKibanaの解説が日本語で読めたり、Fluentdの逆引きのリストがあったり、ログを貯めて可視化する意義を説明してあったり)です。\nぜひ、読んだ感想をいただければと!\n","date":1407156840,"dir":"post/2014/","id":"bdea71d64cdfcc405e65e750fe8d9b86","lang":"ja","lastmod":1407156840,"permalink":"https://blog.johtani.info/blog/2014/08/04/release-magazine-book-of-log-aggs-and-viz/","publishdate":"2014-08-04T21:54:00+09:00","summary":"懲りずにまた、執筆してみました。みなさん「買って」から感想をいただけるとうれしいです! 本書について 共著者の方々のブログが詳しいので、そちらを","tags":["elasticsearch","kibana","本"],"title":"サーバ/インフラエンジニア養成読本 ログ収集~可視化編 を手伝いました"},{"contents":"Proxy環境で働いている方も結構いると思います。 Twitter上で、Elasticsearchのpluginコマンドでプラグインがインストールできなくて困っている方がいたので、 調べてみたのでメモしておきます。\nプラグインコマンド Elasticsearchでは、プラグインという形でいくつかの便利な機能が公開されています。 形態素解析ライブラリのKuromojiを使うためのプラグインや、クラスタの管理がGUIで可能なkopfプラグインなどがあります。 公式、サードパーティいろいろです。\nこれらのプラグインをElasticsearchにインストールする場合、以下のコマンドを実行すれば 自動的にダウンロードしてpluginsディレクトリにインストールしてくれます。\n./bin/plugin -i elasticsearch/elasticsearch-analysis-kuromoji/2.3.0 ここで、elasticsearch/elasticsearch-analysis-kuromoji/2.3.0がプラグインのパスになります(例では、提供元/プラグイン名/プラグインバージョンとなっています。)。\nこのpluginコマンドがダウンロード元にアクセスに行くのですが、プロキシ環境だとプロキシの設定が必要になります。\nプロキシの指定(Mac/LinuxとWindowsでの違い) Mac/Linux(shコマンド) 以前の記事でプロキシのポート番号などの指定方法を 以下のように説明していました。 (※昔の記事のため、kuromojiプラグインのバージョンが古いです)\nElasticsearchのpluginコマンドはJavaで実装されています。(org.elasticsearch.common.http.client.HttpDownloadHelper) プラグインのダウンロードには、java.net.URL.openConnection()から取得URLConnectionを使用しています。\nですので、pluginのインストールを行う際に、Proxy環境にある場合は以下のようにコマンドを実行します。\n./bin/plugin -DproxyPort=ポート番号 -DproxyHost=ホスト名 -i elasticsearch/elasticsearch-analysis-kuromoji/1.5.0 LinuxやMacの環境であれば、こちらのコマンドでプロキシの指定が可能です。 ただし、Windows環境ではうまくいきません。\nElasticsearchは、環境の違いにより、ダウンロードするファイルが異なります。 Windows環境の方は、zipファイルをダウンロードしてもらうようになっています。 elasticsearchコマンドおよびpluginコマンドがbat形式で提供されているのがzipファイルとなるからです。\nWindows(batコマンド) Windows環境では次のように指定します。\nset JAVA_OPTS=\u0026#34;-DproxyHost=ホスト名 -DproxyPort=ポート番号\u0026#34; bin\\plugin -i elasticsearch/elasticsearch-analysis-kuromoji/2.3.0 コマンドの実装方法が少し異なるために、このようになっています。\nまとめ プロキシ環境で利用される場合は、プラグインコマンドは上記のように実行していただければと。\n公式ガイドには、これらの情報を追記するPRを送る予定です。 また、WindowsのコマンドでもMac/Linuxと同様にできたほうがいい気がするので、Issueをあげようと思います。\n不明点などあれば、コメントいただければと。\n","date":1406874240,"dir":"post/2014/","id":"7cc605e721fdd1d2ccc16f5b6490e830","lang":"ja","lastmod":1406874240,"permalink":"https://blog.johtani.info/blog/2014/08/01/plugin-using-under-proxy-env/","publishdate":"2014-08-01T15:24:00+09:00","summary":"Proxy環境で働いている方も結構いると思います。 Twitter上で、Elasticsearchのpluginコマンドでプラグインがインスト","tags":["elasticsearch","plugin"],"title":"プロキシ環境でのpluginコマンドの実行"},{"contents":"原文:Elasticsearch 1.3.1 Releasedを日本語に翻訳したものです。\nバグフィックス版のElasticsearch 1.3.1をリリースしました。 ダウンロードおよび変更履歴はElasticsearch 1.3.1からお願いいたします。\nこのリリースはインデックスリカバリ時の後方互換性バグ(#7055)への対応です。 このバグはデータの欠損は起こりません。 Elasticsearch 1.3.1へアップグレードすることで問題を回避できます。 このバグは、以下のElasticsearchのバージョンで作成されたセグメントを含むインデックスを1.3.0へアップグレードしようとすると発生します。\nElasticsearch 0.90.7 Elasticsearch 0.90.2 Elasticsearch 0.90.0以前のバージョン このバグは、これらの古いインデックスをレプリカからリカバリできなくします。 これらのバージョンのセグメントを持つインデックスが、レプリカは可能ですが、 ステータスがYellowのままGreenに決してなりません。 ログには次のようなExceptionが発生します。\nIllegalArgumentException[No enum constant org.apache.lucene.util.Version.x.x.x]\nLuceneの特定のバージョンではLuceneのマイナーバージョンを含んでおらず、誤ったバージョン番号がセグメントに記録されました。 LUCENE-5850のチケットがこの問題に対処するためにオープンされています。 この問題は我々の後方互換テストで見つかるべき問題ですが、Luceneで不足しているため発見されませんでした。 テストスイートは今後の可能性のために改良されます。\nこのリリースはその他に、Aggregationのマイナーバグフィックスも含まれています。 詳細はリリースノートをご覧ください\nElasticsearch 1.3.1をダウンロードし、試してください。 もし問題を見つけた場合はGitHubのIssuesへご報告をお願いいたします。\n","date":1406604120,"dir":"post/2014/","id":"fb1da4a6ed74705ad98bb60ad4badaf2","lang":"ja","lastmod":1406604120,"permalink":"https://blog.johtani.info/blog/2014/07/29/elasticsearch-1-3-1-release/","publishdate":"2014-07-29T12:22:00+09:00","summary":"原文:Elasticsearch 1.3.1 Releasedを日本語に翻訳したものです。 バグフィックス版のElasticsearch 1.3.1をリリー","tags":["elasticsearch","release"],"title":"Elasticsearch 1.3.1 リリース(日本語訳)"},{"contents":"Curatorの1.2.0がリリースされました。\n前回のCuratorの記事が古くなってしまった(1.1.0からコマンドのI/Fが変更された)ので 1.1.0および1.2.0に関する記事を翻訳しておきます。\nちなみに、Curatorとは、Elasticsearchに時系列のインデックス(例:LogstashやFluentdでログを保存)を保存している場合にそれらのインデックスを管理(削除したり、クローズしたり)するための便利なツールです。 Curatorの概要については、GitHubリポジトリか前回の記事をご覧ください。\nCurator 1.1.0リリース (2014/06/13公開) 元記事:elasticsearch curator - version 1.1.0 released\nElasticsearch 1.0.0がリリースされ、新しい機能、Snapshot \u0026amp; Restoreが利用できるようになりました。 Snapshotはある時点でのインデックスの写真を撮るように、バックアップを作成することができます。 1.0.0が発表されてすぐに、この機能に関するリクエストが寄せられるようになりました。 「Curatorにスナップショットを追加して!」もしくは「いつCuratorでスナップショットが使えるようになる?」といった感じです。 これがあなたの要望なら、それはついに叶えられました。しかも他の追加機能も一緒にです。\n新機能 Curatorの新機能は以下のとおりです。\n新CLI構造 スナップショット(Snapshot) エイリアス(Aliases) パターンによる除外インデックス指定 配置ルーティング(Allocation Routing) インデックスとスナップショットの表示 リポジトリ管理(個別のスクリプトによる) ドキュメントWiki 新コマンドライン構造 注意:コマンドライン構造の変更とは、Curator 1.1.0以前のcron記述が動作しないことを意味します。Curator 1.1.0にアップグレードする場合はコマンドも修正が必要となるので注意してください。\nシンプルにするために、commandsという概念を追加しました。 また、ヘルプの出力もわかりやすくなっています。 前のバージョンと同じタスクをCuratorは実行できますが、異なるフォーマットを用いるようになりました。\n旧コマンド:\ncurator -d 30 新コマンド:\ncurator delete --older-than 30 コマンドは、フラグとは異なりハイフンを前に付けないことに注意してください。 また、似たような名前のフラグがあることに気をつけてください。 例えば、--older-thanフラグは多くのコマンドに利用できます。 指定される値は各ケースにおいて同一です。「指定された数よりも古いインデックス」となります。\n新しいコマンドのリストは次のとおりです。\nalias allocation bloom close delete optimize show snapshot コマンドのヘルプは次のコマンドで表示されます。\ncurator [COMMAND] --help コマンドに関係あるフラグがすべて表示されます。\nスナップショット(snapshots) snapshotコマンドで、存在しているリポジトリにインデックスのスナップショットを保存することができます。\nCuratorはインデックス毎に1つのスナップショットを作成し、インデックスから名前をつけます。 例えば、インデックスの名前がlogstash-2014.06.10の場合、スナップショットの名前はlogstash-2014.06.10となります。 指定した条件を元に、シーケンシャルに、1つずつインデックスのスナップショットを作成していきます。\ncurator snapshot --older-than 20 --repository REPOSITORY_NAME このコマンドは、20日以上古いインデックスすべてのスナップショットを作成し、REPOSITORY_NAMEで指定されたリポジトリに保存します。\nes_repo_mgrと呼ばれるリポジトリ作成を支援するスクリプトがCuratorには含まれています。 ファイルシステムおよびS3タイプのリポジトリ両方の作成を支援します。\nさらに、古いインデックスのスナップショットを取ることができることに加えて、Curatorは最新のインデックスをアップロードする方法も提供します。 これは、Elasticsearch Marvelのインデックスをアップロードするときに便利です。 トラブルシューティングを目的として、パフォーマンスデータを他の人に見せる場合などです。\ncurator snapshot --most-recent 3 --prefix .marvel- --repository REPOSITORY_NAME このコマンドでは、最新の3つのMarvelインデックスのスナップショットを指定されたリポジトリに保存できます。\nエイリアス(aliases) Curatorはすでに存在するエイリアスにインデックスを追加することも、削除することもできるようになりました。 ただし、エイリアスがすでに存在している必要があります。エイリアスの作成はできません。\nlast_weekという前の一週間のインデックスのエイリアスを保持していること想像してください。 この場合、次の2つのコマンドを利用することで、エイリアスを管理できます。\ncurator alias --alias-older-than 7 --alias last_week curator alias --unalias-older-than 14 --alias last_week 新しく作られたインデックスがインデックステンプレートによって 自動的にエイリアスの一部となるようにElasticsearchに設定しておくと、さらに便利です。 この場合、新しいインデックスが自動的にthis_weekというエイリアスの一部になるようにしてあれば、以下のコマンドのみとなります。\ncurator alias --unalias-older-than 7 --alias this_week this_weekとlast_weekのエイリアスのアップデートを保持できます。\nパターンによる除外(exclude pattern) 時には、指定したインデックスを操作から除外したくなる場合もあるでしょう。 ここまでは、プレフィックスや日付によって選択されたインデックスのみを対象にしてきました。 そこで、--exclude-patternオプションです。これは、指定したインデックスを除いて処理を行うことができます。\nlogstash-2014.06.11というインデックスを決して削除したくないとします。 この場合、次のコマンドのようになります。\ncurator delete --older-than 15 --exclude-pattern 2014.06.11 Curatorはデフォルトでlogstash-というプレフィックスにマッチしますが、2014.06.11というインデックスは対象外となります。\n配置ルーティング(allocation routing) Elasticsearchはノードにタグを付けることができます。 これらのタグはインデックスやシャードをクラスタのどこに配置するかをコントロールするために役立ちます。 一般的なユースケースだと、高性能なSSDドライブを持ったノードをインデキシングのために、ハードディスクを持った性能の低いマシンは検索頻度が低い古いインデックスを配置するといった場合です。 この場合、HDDノードには、elasticsearch.ymlにnode.tag: hdd、SSDノードにはnode.tag: ssdと設定されているべきです。 Curatorはこの時、インデックスをタグに基づいてオフピークの時間帯に再配置させることができます。\nコマンド:\ncurator allocation --older-than 2 --rule tag=hdd index.routing.allocation.require.tag=hddという設定が2日よりも古いインデックスに適用されます。 これは、インデックスのシャードがnode.tag: hddというノードに再配置される必要があると、Elasticsearchに伝えます。\nインデックスとスナップショットの表示(show indices and snapshots) これは、単にあなたの持っているインデックスやスナップショットがどんなものかを表示します。\ncurator show --show-indices これは、デフォルトプレフィックスのlogstash-にマッチするすべてのインデックスを表示します。\ncurator show --show-snapshots --repository REPOSITORY_NAME これは、指定されたリポジトリにある、デフォルトプレフィックスのlogstash-にマッチするすべてのスナップショットを表示します。\nリポジトリ管理(repository management) 前に説明したとおり、es_repo_mgrと呼ばれるヘルパースクリプトをCuratorは含んでいます。 現時点では、fsとs3タイプをサポートしています。 リポジトリを作る前に利用したいタイプのドキュメントを読むようにしてください。 例えば、fsタイプのリポジトリを各ノードで使う場合は、同じ共有ファイルシステムに、同じパスでアクセスできなければなりません。 パスの指定は--locationです。\nfsタイプリポジトリの作成\nes_repo_mgr create_fs --location \u0026#39;/tmp/REPOSITORY_LOCATION\u0026#39; --repository REPOSITORY_NAME 削除\nes_repo_mgr delete --repository REPOSITORY_NAME ドキュメントWiki Curatorのドキュメントが更新され、オンラインにWiki形式でだれでも更新できるようになっています。 コマンドやフラグのより詳細の情報はこちらで見つけることができます。また、もし、興味があれば、ドキュメントを追加することもできます。\nインストールと更新 Curator 1.1.0はPyPiリポジトリにあります。 インストールは以下のとおりです。\npip install elasticsearch-curator バージョン1.0.0からアップグレードする場合は以下のとおりです。\npip uninstall elasticsearch-curator pip install elasticsearch-curator バージョン1.0.0よりも古いバージョンからのアップグレードは以下のとおりです。\npip uninstall elasticsearch-curator pip uninstall elasticsearch pip install elasticsearch-curator pip uninstall elasticsearchで、古いパイションモジュールをを削除します。 適切なバージョンが依存関係により再インストールされます。\nまとめ Curatorの新機能は素晴らしいです!このリリースは大きな改善です。 もし、トラブルや足りないものを見つけた場合はGitHub Issueに報告してください。 また、Curatorが便利だと思ったら、私たちに伝えてください。#elasticsearchタグを付けてツイートしてください!\nCuratorはまだ、始まったばかりです。Curator 2.0のロードマップを作業中です。ここまで読んでいただきありがとうございます。 Happy Curating!\nCurator 1.2.0リリース(2014/07/24) 元記事:curator 1.2.0 released\nCurator v1.1.0のリリースから、数週間が経ちました。 私たちは、Curator 1.2.0をリリースしました。\n新機能(new features) ユーザ指定の日付パターン:長い間リクエストされていた機能 ウィークリーインデックスのサポート:これも長い間リクエストされていた機能 複数のログフォーマットオプション:Logstashフォーマットが利用可能 これらの変更はCuratorドキュメントにも記載されています。\n更新(updates) ログ出力の整理:デフォルトのログ出力を整理しました。デバッグログはすべて表示されます。 ドライランのログ出力の詳細化:テスト実行時に何が起きたかをわかりやすくしました。 日付パターンと--timestring(date patterns and \u0026ndash;timestring) 前のリリースで、セパレータ文字を利用して、インデックス名のエレメントを分離することで、日付を計算しました。 この設計の決定は、プログラムが管理するために設計されたLogstashのインデックスを使うのには簡単でした。 しかし、Curatorは時系列インデックス管理に成長しています。これは、異なる命名規則のインデックスを意味しています。\nまた、インターバルによって、日付の計算が必要になる場合もあります。 --time-unitオプションが残っており、weeksという単位を指定することもできます。 デフォルトの--timestringオプションは、以前のコマンドと同様の動作をしなければなりません。次のようになります。\nTime Unit Timestring days %Y.%m.%d hours %Y.%m.%d.%H weeks %Y.%W これが意味するものは、もし、単位にhoursをした場合、--timestringを指定しなかった場合は%Y.%m.%d.%Hとなります。 これは、Pythonのstrftimeフォーマットで\u0026quot;年.月.日.時\u0026quot;を意味します。 同様に、weeksを単位に指定した場合、Curatorはデフォルトの--timestringは%Y.%Wとなります。\nこの機能は、日付の間にセパレーター文字のないインデックスでも機能します。 例えば、production-20140724のような日時インデックスがある場合、2日よりも古いインデックスに対するブルームフィルタっキャッシュのオフのコマンドは次のようになります。\ncurator bloom --prefix production- --older-than 2 --timestring %Y%m%d この例で、デフォルトの単位はdaysであることに注意してください。hourly-2014072414のような時間インデックスの場合は次のようになります。\ncurator bloom --prefix hourly- --older-than 2 --time-unit hours --timestring %Y%m%d%H --separatorの置き換え もし、Curatorの前のバージョンでカスタムセパレータ文字を利用していた場合、次のように変更すべきです。 前のコマンドでcerberus-2014-07-24のようなインデックスがある場合、コマンドを--separator -の用に置き換える必要があります。 新しいコマンドは次のとおりです。\ncurator delete --prefix cerberus- --older-than 30 --timestring %Y-%m-%d 年(%Y)と月(%m)と日(\u0026rsquo;%d\u0026rsquo;)の間にセパレータ文字を置くだけです。\nこれは、また、Curatorで以前は不可能であったことをできるようにもします。 異なるセパレータ文字の混在です。 logs-2014.07.24-14というようなインデックスを処理するときに--timestringは%Y.%m.%d-%Hのようになります.\n--timestringの詳細はCuratorのドキュメントをご覧ください。\nフィードバック これらの新しい機能はユーザのコメントやリクエストから来ています。もし、機能のリクエストやバグを発見したら、こちらまで連絡してください。\nまた、Twitterでもお待ちしています。私たちのTwitter IDは@elasticsearchです。\nHappy Curating!\n","date":1406524740,"dir":"post/2014/","id":"0c1821d1069578551d0e3c7d9275f16b","lang":"ja","lastmod":1406524740,"permalink":"https://blog.johtani.info/blog/2014/07/28/curator-2-0-and-1-1/","publishdate":"2014-07-28T14:19:00+09:00","summary":"Curatorの1.2.0がリリースされました。 前回のCuratorの記事が古くなってしまった(1.1.0からコマンドのI/Fが変更された)","tags":["elasticsearch","curator"],"title":"Curator 1.2および1.1について"},{"contents":"第5回Elasticsearch勉強会を開催しました。 遅くなってしまいましたが、まとめてみました。\n今回は、Elasticsearchに入って初の勉強会でした。タイミングが良いことに、Honza、Igor、Shayの3名がトレーニングのために 来日していたため、特別回ということにして、話をしてもらいました。\nそして、サムライズムの@yusukeさんにテキスト翻訳してもらいました。 早くて正確なタイピング+翻訳、本当にありがとうございました。\n開場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 次回もよろしくお願いします! 参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\namazing turnout to the elasticsearch at Tokyo #elasticsearchjp pic.twitter.com/Aa88eVf5dF\n\u0026mdash; Shay Banon (@kimchy) 2014, 7月 14 動画があとで、アップされる予定です。お楽しみに。\nHonza\u0026rsquo;s talk djangoの開発者!であり、ElasticsearchのPythonクライアント、Curatorの開発者 Python Clientを利用しながら、ライブコーディングのような形で説明する方法が新鮮 Aggregationの便利さについての説明 Python Clientがクエリを組み立てるのにすごく便利そうだった Pythonユーザが結構いたので助かりましたw Igor\u0026rsquo;s talk スライド:elasticsearch data/\nSnapshot/Restoreの開発などを行っている開発者 Elasticsearchのデータ、ディレクトリ構造に関するお話 シャードの話から、ディレクトリ構造、メタデータに関する説明 transaction logの挙動の説明 検索のフェーズの説明 Igorは、実は私がElasticsearch社の人とコンタクトがとれた最初の人だと思います。 第1回Elasticsearch勉強会が開催する当日に帰国されるという不運だったのですが、1年越しでトークしてもらえました!\n@johtani I am so bummed! I am leaving Tokyo Thursday morning.\n\u0026mdash; Igor Motov (@imotov) 2013, 8月 27 QA ShayをメインにいくつかのQAをしてもらいました。 NetflixなどのMeetupの動画で見てたのですが、こんな形で日本でも実現できるとは。\nQ: なんで、ファイルデスクリプタの設定を大きくするの? A: Luceneのインデックスは複数のセグメントから構成されている。メモリに作られたあと、ファイルにfsyncされる。 Q: KibanaでAggregation使いたいんだけど? A: Kibana 4で対応するよ!異なるフィールドの値を1つのグラフにすることも出来るよ! Q: なんでElasticsearch作ったの? A: 暇だったからw奥さんのレシピ検索を作ってみようと思って作り始めて、Luceneを触って感動して。。。検索すげー、Compassってのを触ってこれもすごいと思いつつ、もっとLucene活用できるんじゃないかということでElasticsearch作ったんだ。奥さんのレシピ検索?まだ完成してないよw Q: 2000くらいスナップショット撮ったらパフォーマンスが悪くなっててなんで? A: 差分でスナップショットを作るんだけど、差分の計算に昔のスナップショットを見るので、定期的に新しくしたほうがいい。もし、気になることがあったらIssue上げたりMLに投げてくれるとうれしい。\n(あとでちょっと聞いたけど、古いスナップショットを消すのも有効っぽい。差分でスナップショットを作るけど、昔のを消した場合は、新しいスナップショットが利用しているファイルは残る仕組みになっているから。) Q: Relevancyのチューニングってどうすればいい?ドキュメントが少なくない? A: ドキュメンテーションは頑張ってるので、応援してねwあとは、definitive guideも参考になるよ。スコアはfunction_scoreクエリがすごいのでいろいろ使ってね。MVELをGroovyに帰る予定。性能もだけど、サンドボックス的な意味もあります。 Q: 次のVisionは?現時点は検索だけど。(最後の質問がとてもナイスで、助かりましたw私がしたほうがいい気がするww) A: 今後はアナリティクスのプラットフォームに向かってる。Aggregationとかね。メモリ効率よくしたりしてるよ。あとは、Field-collapsionも実装中だよ。あと、マシンラーニングとかもね。データを探索するための機能を色々作ってくよ。障害性にも。チェックサム機能をLuceneに入れて、ESにも入れていく予定。Zenの機能も改善している。 まとめ 今週は、トレーニングがあったり、いろいろな打ち合わせがあったりと、テンパってたので至らない点が多かったかもしれないですが。。。 楽しんでいただけと思います。 数日、Shay、Honza、Igorと行動を共にして、本当に情熱のあるチームでユーザのことを気にかけているなと感じることができました。 少しでもその片鱗を勉強会で感じてもらえたんじゃないかと。特に、QAでのShayによる情熱が伝わったんじゃないかと。\n懇親会でも数人の方から、日本語のサポートを望んでいるという声も頂きました。 興味のある方は私までコンタクトいただければと。\nあと、@yusukeさんのテキスト翻訳が素晴らしくて、参加してもらった方たちも絶賛してました。 次回も英語スピーカーの場合に助けてもらえると嬉しいです(私もそこまで出来るように頑張ります)\nその他のブログ ブログ記事ありがとうございます!\n第5回elasticsearch勉強会にいってきました - はやさがたりない。 感想戦:aggrigation から見える検索エンジンの次 - 第5回 Elasticsearch勉強会 - よしだのブログ 「第5回elasticsearch勉強会 #elasticsearch #elasticsearchjp」(2014年07月14日)の参加メモ - uchimanajet7のメモ ","date":1405774320,"dir":"post/2014/","id":"e3e146469ed4318eaa2ffbca3510c054","lang":"ja","lastmod":1405774320,"permalink":"https://blog.johtani.info/blog/2014/07/19/hold-on-5th-elasticsearch-jp/","publishdate":"2014-07-19T21:52:00+09:00","summary":"第5回Elasticsearch勉強会を開催しました。 遅くなってしまいましたが、まとめてみました。 今回は、Elasticsearchに入って","tags":["elasticsearch","勉強会"],"title":"第5回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"ということで、転職しました。 どーしてもやりたいことが出てきたので、無理を言って転職することにしてみました。\nサムライズムではなく、Elasticsearchにジョインします。(というか、しました。)\n初出社 #サムライズム\n\u0026mdash; Jun Ohtani (@johtani) 2014, 7月 1 冗談でツイートしたのですが、その前に英語アカウントのツイートがRTされてしまっていまいちでした。。。\nスキポール空港 先週、アムステルダムに行っていたのも退職前に休みをいただき、Elasticsearchの全社会議に参加していたためです。 とてもエキサイティングな経験(英語漬けとか)ができ、もっと精進しないとなという気持ちにもなり、ますます頑張らないとなと。\nということで、今後は日本中にElasticsearchやLogstash、Kibanaを広めるべく、いろいろな場所で話をしたいと思います。 興味のある方は、声をかけていただければと。\nあと、東京でElasticsearchのCoreトレーニングが行われます。 通常は2日間ですが、通訳の方が付く関係で3日間の開催となっています。 開発者2名がトレーナーとして来日します。開発者に質問をできる良い機会ですので、興味のある方は参加してみてはいかがでしょうか。 また、CTOのShay Banonも来日する予定です。\nトレーナー2名とShayは7/14の勉強会でも話をしてくれます。 こちらも興味のある方は参加してみてください。(参加登録はこの後、すぐに開始します。)\nまだまだ、勉強しなければいけないことだらけですが、ElasticsearchのいろいろなプロダクトやOSSについて広めていきたいと思いますので、よろしくお願いいたします。\nおまけ ということで、一度やってみたかったのでリンクを貼ってみます。\nほしい物リストはこちら\n","date":1404181800,"dir":"post/2014/","id":"21a8e6324e9330d4f8ebade604c62b6e","lang":"ja","lastmod":1404181800,"permalink":"https://blog.johtani.info/blog/2014/07/01/join-elasticsearch/","publishdate":"2014-07-01T11:30:00+09:00","summary":"ということで、転職しました。 どーしてもやりたいことが出てきたので、無理を言って転職することにしてみました。 サムライズムではなく、Elasti","tags":["転職"],"title":"転職しました"},{"contents":"退職しました。\n色々と書きたいんですが、時差ボケで頭痛いので、このくらいです。 余裕出たら書くかも。\nほしい物リストはこちら\n新天地についてはまた明日。\n","date":1404137940,"dir":"post/2014/","id":"40abea0a87a64bd832a1fad69458b293","lang":"ja","lastmod":1404137940,"permalink":"https://blog.johtani.info/blog/2014/06/30/resignation/","publishdate":"2014-06-30T23:19:00+09:00","summary":"退職しました。 色々と書きたいんですが、時差ボケで頭痛いので、このくらいです。 余裕出たら書くかも。 ほしい物リストはこちら 新天地についてはまた明","tags":["転職"],"title":"退職しました"},{"contents":"Elasticsearch server 2nd editionが発売されています。\n私が翻訳したのは前のバージョンですが。。。 まずは、目次を元にどのくらい変わってるかを見てみました。 (全部まだ読んでなくて。。。)\n1章 Getting Started with the Elasticsearch Cluster 冒頭に、全文検索とは、転置インデックスとはどんなものか、 Luceneの簡単なアーキテクチャの仕組みについて説明が追加されています。 検索の仕組みを知らない人が読んでもわかりやすくなっています。\nインストール方法なども少し追記されています。 バージョニングと簡単なデータ登録と検索方法についてもここで触れられています。 検索結果の構造の説明もちょっとあります。 まず簡単に触ってみるというところまでが1章でまとめられた感じです。\n2章 Indexing Your Data 新しく、切りだされた形です。 前のバージョンでは1章で説明されていた、Mapping周りが切りだされています。 シャードやレプリカの説明もこちらです。\nIPアドレスタイプ(IPv4のみ)とtoken_countタイプの説明も追加されてます。 similarityやpostingsフォーマットなどは新しく追記されています。 また、メタフィールドと呼ばれる_typeなどはこちらに移動しているようです。 マージ処理などの説明も追記されています。このあたりは、Mastering ElasticSearchに 記載されているものが移植された感じでしょうか。\n3章 Searching Your Data 前のバージョンでは2章だった章です。 クエリについては1.0で追加されたsimple_query_stringなどが追記されています。 constant_scoreやdismaxなどもです。\nまた、前のバージョンの3章で説明されていたハイライトや8章で触れられていたvalidate APIについても 移動しています。\n4章 Extending Your Index Structure 前のバージョンの3章で触れられていた、データの構造に関する部分がこの章になります。 親子や配列、ネスト等のデータのインデックスや検索の方法です。\n5章 Make Your Search Better スクリプティングや言語判定などの仕組みが記載されています。 また、ブーストについても同様です。Synonymについてもここです。 スパンクエリについては省略されたのかな?\n6章 Beyond Full-text Searching 1.0の目玉機能の一つであるAggregationの説明から始まります。 その後、ファセットやPercolatorについてです。メモリに関する注意点もありそうです。 また、Geoについての説明がこちらに移動されていました。 scroll APIについてもこちらで説明されています。\n7章 Elasticsearch Cluster in Detail 前の7章で記載されていたElasticsearchの分散の仕組み(Node Discovery)についての記載があります。 また、1.0で追加されたcircuit breakerやスレッドプール、インデックスのリフレッシュレートなど、Mastering ElasticSearchの 内容も追記されている気がします。\nインデックスやマッピングのテンプレート機能についてもここで説明があるみたいです。\n8章 Administrating Your Cluster 1.0で追加されたsnapshot/restoreの説明から始まります。 あとは、前のバージョンの7章で説明されていたクラスタ管理用のAPIについての説明です。 いくつか(例えばcat API)、1.0で追加されています。\nまた、シャードのリバランスの話も追加されているようです。 エイリアスやプラグインの話はこちらに移動してるみたいです。\n感想 ということで、とりあえず、駆け足で目次ベースで違いを見てみました。 Mastering ElasticSearchでの 知見がフィードバックされ、しかも1.0(すでに1.3が出そうな勢いですが。。。)にバージョンアップされた内容になっています。 冒頭がわかりやすくなっているので、検索をやったことのない方にもおすすめな書籍になった気がします。 英語が苦にならなければ、おすすめの一冊だと思います。\n来月から読み進めるつもりなので、また、面白い内容があったら感想を書いていこうと思います。 (また翻訳できるといいかもなー)\n","date":1402908420,"dir":"post/2014/","id":"916bda59bc7621d5c1790c040572a3c0","lang":"ja","lastmod":1402908420,"permalink":"https://blog.johtani.info/blog/2014/06/16/first-impression-elasticsearch-server-2nd-edition/","publishdate":"2014-06-16T17:47:00+09:00","summary":"Elasticsearch server 2nd editionが発売されています。 私が翻訳したのは前のバージョンですが。。。 まずは、目次を元にどのくらい変わってるかを見てみました。 (","tags":["elasticsearch","本"],"title":"Elasticsearch server 2nd editionのファーストインプレッション"},{"contents":"可視化ツール現状確認会に参加して、カジュアルウォーターじゃなくて可視化ツールの現状を確認してきました。\nということで、いつものメモです。\nMackerel と Graphite について (y_uuk1さん) Graphite 時系列 工夫すればスケーラブル SensuやCollectdと組み合わせたり GrafanaとGrapheneでGUI Mackerel素敵だよと。 架空のわかりやすいグラフが見れた Kibana \u0026amp; Grafana \u0026amp; Influga (hakoberaさん) Kibana\nかっこいい。 JVM大変。 Grafana\nGraphiteがカッコ悪いのでKibanaをフォーク なぜか、ESが必要。 InfluxDBに浮気しそう Influga\n@haoberaさん作 InfluxDB Queryサポート 迷ったら、Kibana入れとけ。\nDistinctがKibana出できないけど、それ以外はある程度行けるらしい。\naggregationがサポートされたら、できると思う。 Kibana以外は、バックエンドがタイムシリーズなので、縛りがある\n可視化ツール紹介(仮) (showyouさん) 誰がチャートを作るの? 誰が見るの? 一覧化されてて、あとで眺めたい IPython Notebookのデモ R shiny Serverのデモ Pentaho CE+Saikuのデモはネットワークがダメだったので割愛 分析側の視点を見せたかったので。 可視化とは何だったのか (harukasanさん) インフラ モニタリング、アナライズ、可視化どれ? 可視化は目的ではないよねと。 熱く、ユーザとサービスプロバイダ間の距離のお話。 ログ 生ファイルで残すのが重要 トータルで必要とか考えないといけないことがわかって面白かったw\nあなたの知らないrrdtool (shoichimasuharaさん) すげー! いろいろできるらしい(ノートPCの前にいなかったw) D3.jsとジオマッピング (Takaki_さん) 時空間推進課!すげー! ジオデータのおはなし。 TopoJSONとかGeoJSONとか Zipkinについて (synkさん) ものすごい数のJVMがThriftで殴りあってるらしい。 ZipkinはTwitterが作ったもの Brave、HTraceというのが、PureJava用のZipkinトレーシングプラグイン 見積もりする必要がないくらいでかいHBaseがあるので、そこにためてる。 まとめ LINEはエンジニアを大募集中 Graphiteについて (mickey19821 さん) ドリコムさんのGraphiteのおはなし Metricsの収集はCollectd Graphite-webがスケールできなくて困ってるらしい。 Graphiteで可視化ツラいw まとめ RRDTool最高\nあと、クックパッドの技術力がすごいという発表なんかもありました。\n","date":1401884100,"dir":"post/2014/","id":"5bb6f8322cdbda7a21e4aecbe04462b7","lang":"ja","lastmod":1401884100,"permalink":"https://blog.johtani.info/blog/2014/06/04/attending-visualize-study/","publishdate":"2014-06-04T21:15:00+09:00","summary":"可視化ツール現状確認会に参加して、カジュアルウォーターじゃなくて可視化ツールの現状を確認してきました。 ということで、いつものメモです。 Mackerel と Graphite","tags":["勉強会"],"title":"可視化ツール現状確認会に参加してきました。#可視化"},{"contents":"今月2回目の目黒で、初のドリコムさんです。 「最新インフラエンジニア技術勉強~Fluentd, Elasticsearch,Chefの実践実例~」に参加してきました。 もちろん、Elasticsearchってキーワードがあったからです。\nざっくりメモです。\nドリコムのInfrastructure as Code/ひらしーさん CM:jojoss、トレクル、など サーバ300台、クラウド○○台。月30〜50台の割合で増加中。 少人数でいかに回すか。 Chef Rubyが書ける人が多いから。 serverspec テストだよと。 すみません、色々と聞き逃しました。。。\nWinning the metrics battle/mickeyさん Graphiteとかを触っている。 1300台超えたら、色々大変だった。 失敗談 Cactiを利用して、色々と運用が大変だった。DCが別なのでProxyとか。 成功例?現行システム? 最大値、平均値、最小値などをプロット collectdを収集、送信に採用して、独自で開発? 受信して保存するのに、Graphite(carbon-relay、carbon-cache、DRBD、graphite-web)ってなってる。 1300台程度のサーバから、5分間隔で、問題ない。 Graphite良いツールだよ。 Q:過去データはどのくらい? A:5分間隔で1年分。\nQ:移動平均とかを使ったグラフとか時間かかりませんか?100台だと A:100台でもほとんど時間はかからない。\nFluentd プラグイン開発講座/外山 寛さん Fluentdプラグインを作ることができると威力倍増 Elasticsearchの勉強会の話までしてくれました! 勉強会スペース貸出しています。 未公開だけど、sedueのプラグインもあるらしい。 CHUNKとBUFFERとか覚えときましょう プラグインの作り方的なのがなかった気がしたので、今回の発表です。 gem作らなくてもディレクトリにおけば使えるよと。 td-agent使ってる人が大多数だよね。(fluentdを素で使ってる人は会場にはいなかった) エンジニア募集中 Q:エラー処理どうしてますか? A:今は、スルーしています\nQ:単体テストの書き方は? A:人によってバラバラみたいですね。\nMySQLと組み合わせて始める全文検索エンジン「elasticsearch」/yoshi_ken スライド:http://www.slideshare.net/y-ken/introduce-elasticsearch-mysql-importer\nElasticsearch歴は1年位です。\nMySQLを使っていて、モダンな検索がほしいですよね?ね?\nサジェスト、ファセット、位置情報、ネスト検索などなど。\nGoogleトレンドだとSolrに迫る勢いと。\n実データを用いて、手軽にElasticsearchと連携。\nBinaryLogではなく、SQLの結果を同意する方式。yamabiko\n今日は、新しいものを公開します。\nbulk import file generator as well as nested document from MySQL for elasticsearch bulk api 東京トレーニング\nElasticsearch本については、右にあるリンクをクリックしてくれるとうれしいなぁ。\n","date":1400840280,"dir":"post/2014/","id":"a578acf825a595ce95fe8f804b7208f0","lang":"ja","lastmod":1400840280,"permalink":"https://blog.johtani.info/blog/2014/05/23/attending-drecom-infra-study/","publishdate":"2014-05-23T19:18:00+09:00","summary":"今月2回目の目黒で、初のドリコムさんです。 「最新インフラエンジニア技術勉強~Fluentd, Elasticsearch,Chefの実践実例~","tags":["勉強会","elasticsearch"],"title":"最新インフラエンジニア技術勉強に参加しました。"},{"contents":"どうやら、中身がSolrベース?Luceneベース?になったらしいということで、 今日は「AWSプロダクトシリーズ|よくわかるAmazon CloudSearch」に行ってきました。\n※ElasticSearchではありません!\nということで、いつものメモ。\nCloudSearch Overview Amazon Web Services, Inc. Pravin Muthukumar(Product Manager) / Vivek Sriram (Business Development) Introduction to Search 検索の紹介。アイアンマンのDVD?のページにいろんな項目(フィールド)があるよねと。(もちろん、Amazonのページ) ファセット、Geo、テキスト処理(Analysis処理)、Postings listとか。とかとか ランキングも Amazon CloudSearch 独自実装orRDB拡張もある。 OSSもあるよね。 Legacy Enterprise SearchとしてFASTとかもある。 Building with CloudSearch 他のサービス同様、コンソールとかあるし、色々できるし、すぐ起動できるよと。 自動で、データが増えたら、パーティションが増えると。\n日本語の形態素解析があるらしい。何を使ってるのかな? ICUのノーマライズとかもやってくれるらしい。これかな?http://lucene.apache.org/core/4_8_0/analyzers-icu/index.html ユーザが辞書を指定できるのかな? 備えてる機能の説明\nファセット SimpleQuery Autocomplete Highlight などなど\nMulti-AZにも対応 QA Q:NGramありますか? A:今はないです。 Q:ユーザ辞書対応してますか? A:今はないです。 Q:lang-detectあるか? A:今はないので、自分で判定して、適切なフィールドに入れてね。 Expectation for CloudSearch Apache Solr contributor 大須賀 稔氏 Solr本の宣伝ありがとうございます!(右のアイコンから買ってもらえると更に嬉しいですw) Kinesisとかとの組み合わせとか、自然言語処理とか、いろいろとあるAWSのコンポーネントと組み合わせる例が欲しいと。 すばらしい、最後はManifoldCFがらみに持っていくとは。ACLがらみのクローリングとかあるといいじゃないでしょうかと。 Impression of using CloudSearch 吉田 匠氏 (@yoshi0309 http://blog.yoslab.com/) スライド:https://speakerdeck.com/yoshi0309/impression-of-using-cloudsearch\nお見かけしたことある気がするなぁ。 全部置き換えできる!わけではなさそう。。。 いいところ。 UIがいいし、セットアップが簡単 auto scaleがうれしい マルチドメイン、マルチスキーマがいい Luceneのdismaxサポートがいい。(edismaxじゃないのかな?) dismaxって書いてあるな。\nhttp://docs.aws.amazon.com/cloudsearch/latest/developerguide/search-api.html\nフィードの仕方に気をつけて!\nバッチサイズで課金されるので、1件ずつじゃなくて、複数件送ったほうがいい。 いきなりスケールアウトできるわけじゃない?\nウォームアップ機能がない。インスタンス上限がデフォルト50件\nVPC対応してほしい。\nインターネット経由になってしまう フィードのスピードが セキュリティグループ機能が使えない CloudSearch UseCase - SnapDish Vuzz Inc. 清田 史和氏 独自辞書をもって、Tokenizeは独自でやって、空白区切りでデータ登録している。 インデックス更新はSQSを使ってる。 古いAPIを使ってるらしい。 移行が結構大変らしい。 感想 使ったことないんですが、きめ細かい検索したい場合はちょっとテクニックが要るかもと思いました。 AWS初心者なんで、なんとも言えないんですが。。。\nといあえず、テキスト処理(アナライズ処理)で、単語がどうやって区切られるのかってのがわからないのはキツイんじゃなかろうかと。 ただ、簡単に起動できて、オートスケールできるのは素晴らしいと思います。\n","date":1400143800,"dir":"post/2014/","id":"706c033b4483b6d062b66d6e4ea0236a","lang":"ja","lastmod":1400143800,"permalink":"https://blog.johtani.info/blog/2014/05/15/amazon-cloud-seaarch-study-session/","publishdate":"2014-05-15T17:50:00+09:00","summary":"どうやら、中身がSolrベース?Luceneベース?になったらしいということで、 今日は「AWSプロダクトシリーズ|よくわかるAmazon Cl","tags":["勉強会","CloudSearch","AWS"],"title":"「よくわかるAmazon #CloudSearch 」に行ってきました!"},{"contents":"酔っ払ってなんとなく書きたくなったスピリチュアルなブログなので、流していただければと。\n最近、勉強会やTwitterで知り合いになって話をする人が増えたりで、 その方たちに色々と教えてもらうことが多いなぁと感じてます。 また、知り合いに恵まれてきたなぁとも。\nそもそも私が勉強会に参加し始めたきっかけはSolr勉強会(第1回から参加してて、気づいたら主催者になってた)で、 そのころは、Solr初心者で色々とやってる人、知ってる人がいて無料で話が聞けるのすごいと興奮したのを覚えてます。 (もちろん、ぼっちでしたが)\nSolr勉強会が定期的に開かれて、それに参加しているうちに少しずつ知り合いもできて、 面白そうな勉強会(Hadoopとか)が他にもあるんだ、参加してみようかって思うようになってと。\nそこにプラスで、関口さんと知りあえてSolr本を書く話が出てきて、本を書いてみたら、 今度は勉強会で話してみませんかとなって。\nスピーカーやると、顔を覚えてもらえるようで、また知り合いが増えてと。\n人のつながりって大事だし、自分が発信することで教えてもらえることもあるしと。 前にも書いた気がするけど、Solr勉強会(当時の主催の方)や関口さんやElasticsearch勉強会のスタッフの方や スピーカーやってくれた方、会場提供を心よくしてくれてるVOYAGE GROUP、リクルートテクノロジーズさん、という具合にどんどん頭が上がらなくなってきてるなぁと。\nということで、外の世界を知ると色々とつながりが出来て面白いですよという、個人的な感想でした。 ま、自分が思ってるだけで、違う意見もいっぱいあると思うけど。\nあー、なんか、酔って勢いで書いてしまった。。。 脈略のない文章なきがするけど、エイヤで公開しちゃおう。\n","date":1399999440,"dir":"post/2014/","id":"72df0bf7853e05560d94208817b83468","lang":"ja","lastmod":1399999440,"permalink":"https://blog.johtani.info/blog/2014/05/14/spiritual-entry1/","publishdate":"2014-05-14T01:44:00+09:00","summary":"酔っ払ってなんとなく書きたくなったスピリチュアルなブログなので、流していただければと。 最近、勉強会やTwitterで知り合いになって話をする","tags":["スピリチュアル"],"title":"外の世界を知るということ"},{"contents":"「アジャイルデータサイエンス」の見本をいただいてしまいました。\nなので、感想文でも書いてみようかと。\nどんな本? 想像以上に薄かったです、物理的に。 なのに、とても幅広い範囲をカバーしています。\nデータの分析にどんな人が関わっているのか、アジャイルにデータを分析する目的から始まり、 データから何かを見つけるための手順、考え方などをさらっとですが、 システムに取り込む流れから取り込んだあとに改良するという流れまで紹介してくれます。 流れはこんな感じ。\nイベント:ログとかのイベントの発生 コレクタ:イベントの収集 バルクストレージ:イベントの一時保存 バッチ処理:ストレージにあるデータに対して処理 分散ストア:処理結果をWebアプリなどで表示するために保存 Webアプリ:処理結果をユーザに提供 Webアプリでデータを見えるようにして、そこから更にフィードバックを受けることで、データの分析などを進めていくという流れです。\n私はデータサイエンス系の人ではないのでこの流れで作業をされているかはわからないのですが、 検索のシステムについてもこの流れに似ているなと感じました。\n検索システムでも、検索したいデータを収集して、加工(検索したい項目の洗い出しやファセットにする項目の選定とか)して、 インデックスを生成するといった処理が必要になるからです。\nこの本では、Python、Hadoop(Pig)、MongoDB、ElasticSearch(バージョンが0.90だから)、d3.jsなどが出てきます。 また、日本語版の付録では、Fluentd、Kibana+Elasticsearchといった組み合わせの紹介もあります。\nコードも書かれていますが、すみません、そこまでちゃんと読んでません。。。\n後半では、データを活用して行くためには順序があるという話が書かれています。\nレコード:レコード1件のアトミックな処理と表示 グラフ:レコードを元に集計したりグラフ作ったり レポート:関係性やトレンドを抽出し、インタラクティブに探求 予測:構造を利用して、推論やレコメンドとか 行動:上記の結果を元にユーザに行動を促す 前のステップがおろそかだと次のステップがうまくいかないという話です。 後半はこの流れに沿って、先ほどのシステムの流れを変更していく方法が展開されます。\n注意点 ちょっとだけ気になる点があったので。\nElasticsearch周りについては少し注意が必要かと。(Pigとかは詳しくないので不明です。) 紹介されているElasticsearchのバージョンが0.90と少し古いのと、 Hadoopとの統合(Pigで処理したデータをElasticsearchに出力)に利用されているWondordogというツールも最近更新がされていないみたいです。 おそらく、1.0系では動かないのではないかと。\n1.0系の場合は、Elasticsearchが提供しているelasticsearch-hadoopを利用するのが良いと思います。\n付録については1.0系で記載されているので問題ないかと。ただし、Elasticsearchは更新が早いので、公式サイトで最新情報を入手するのが良いと思います。\n感想 データを解析するシステムってどんなことやってるの?という全体像を 俯瞰するのに良い本なのではないかと思います。 また、データの解析を活かすために、必要な順序と疎かにできない点もあって面白かったです。\n紹介されているツール類については、OSSのトレンドや開発速度が早いので、参考程度にとどめておいて、 自分たちで使いやすいものを探してきて検討するのがいいと思います。\n付録がとても豪華です。FluentdやKibanaがわかりやすく解説されてます。\nあと、薄いのでさらっと読めます。w\n","date":1399563900,"dir":"post/2014/","id":"91fe03f994e8e85cede4e3bd62f4d6b7","lang":"ja","lastmod":1399563900,"permalink":"https://blog.johtani.info/blog/2014/05/09/reading-agile-data-science/","publishdate":"2014-05-09T00:45:00+09:00","summary":"「アジャイルデータサイエンス」の見本をいただいてしまいました。 なので、感想文でも書いてみようかと。 どんな本? 想像以上に薄かったです、物理的に","tags":["感想文","オライリー"],"title":"アジャイルデータサイエンスが届きました"},{"contents":"こんなツイートを見つけたので、Aggregationのサンプルでも書こうかなと。(前から書こうと思ってたんですが。。。)\n@elasticsearch Hi, Would you please tell me the way to do \u0026quot;Pivot Faceting\u0026quot; like Solr-4.0 in elasticsearch-1.1.1 or prior version? Thank you.\n\u0026mdash; Y.Kentaro (@yoshi_ken) 2014, 5月 2 ちなみに、Aggregationは1.0.0から導入された機能なので、ElasticSearch Server日本語版には掲載されていない機能になります。(ごめんなさい)\n公式ガイドのAggregationsのページはこちらになりますが、実例があったほうがいいかなと。\n@yoshi_ken さんから実例のサンプルの指定もいただいたので、ブログを書くのが非常に楽です。ありがとうございます。\n問題 元ネタ(gist)\n次のような不動産系のデータがあるとします。\nid 物件名 都道府県(東京、神奈川、\u0026hellip;..) 物件種別(賃貸、売買、\u0026hellip;..) この時、都道府県別に、物件種別ごとの件数を取得したいという趣旨です。\n東京 賃貸: xxx件 売買: yyy件 神奈川 賃貸: xxx件 売買: yyy件 \u0026hellip; これを、Elasticsearchでどうやって取得するかという問題です。\nインデックスとデータの登録 まずは、インデックスを作ります。 あくまでもサンプルなので、全部not_analyzedにしてますが、そのへんは適宜変更してください。\n# create index PUT /pref_aggs { \u0026#34;settings\u0026#34;: { \u0026#34;number_of_shards\u0026#34;: 2 }, \u0026#34;mappings\u0026#34;: { \u0026#34;japan\u0026#34; : { \u0026#34;_id\u0026#34; : { \u0026#34;path\u0026#34; : \u0026#34;id\u0026#34; }, \u0026#34;properties\u0026#34;: { \u0026#34;id\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;}, \u0026#34;name\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;}, \u0026#34;pref\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;}, \u0026#34;type\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;} } } } } _idを使用して、データ登録時にidフィールドにある文字列をそのままIDとして登録できるように指定してあります。\n登録するデータは次のようなものを適当に100件程度作ってりました。\n{\u0026#34;id\u0026#34;: \u0026#34;id0\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;name0\u0026#34;, \u0026#34;pref\u0026#34;: \u0026#34;01_北海道\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;売買\u0026#34;} {\u0026#34;id\u0026#34;: \u0026#34;id1\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;name1\u0026#34;, \u0026#34;pref\u0026#34;: \u0026#34;09_栃木県\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;売買\u0026#34;} {\u0026#34;id\u0026#34;: \u0026#34;id2\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;name2\u0026#34;, \u0026#34;pref\u0026#34;: \u0026#34;38_愛媛県\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;賃貸\u0026#34;} {\u0026#34;id\u0026#34;: \u0026#34;id3\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;name3\u0026#34;, \u0026#34;pref\u0026#34;: \u0026#34;40_福岡県\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;賃貸\u0026#34;} {\u0026#34;id\u0026#34;: \u0026#34;id4\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;name4\u0026#34;, \u0026#34;pref\u0026#34;: \u0026#34;35_山口県\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;売買\u0026#34;} {\u0026#34;id\u0026#34;: \u0026#34;id5\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;name5\u0026#34;, \u0026#34;pref\u0026#34;: \u0026#34;12_千葉県\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;賃貸\u0026#34;} ... データの登録には、前に紹介した方法「stream2esと複数データの登録」を用いました。\nファセット このようなデータがある場合に、まず思いつくのはファセットによる取得です。 いささか強引ですが。。。\nGET /pref_aggs/japan/_search { \u0026#34;size\u0026#34;: 0, \u0026#34;query\u0026#34;: { \u0026#34;match_all\u0026#34;: {} }, \u0026#34;facets\u0026#34;: { \u0026#34;type_賃貸\u0026#34;: { \u0026#34;terms\u0026#34;: { \u0026#34;order\u0026#34;: \u0026#34;term\u0026#34;, \u0026#34;field\u0026#34;: \u0026#34;pref\u0026#34;, \u0026#34;size\u0026#34;: 50 }, \u0026#34;facet_filter\u0026#34;: {\u0026#34;term\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;賃貸\u0026#34; }} }, \u0026#34;type_売買\u0026#34;: { \u0026#34;terms\u0026#34;: { \u0026#34;order\u0026#34;: \u0026#34;term\u0026#34;, \u0026#34;field\u0026#34;: \u0026#34;pref\u0026#34;, \u0026#34;size\u0026#34;: 50 }, \u0026#34;facet_filter\u0026#34;: {\u0026#34;term\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;売買\u0026#34; }} } } } facet_filterを使用して、typeフィールドによる個別の絞込を行っています。 あとは、prefフィールドのファセットを取得すれば、出力は次のようになります。\n{ \u0026#34;took\u0026#34;: 6, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 2, \u0026#34;successful\u0026#34;: 2, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 100, \u0026#34;max_score\u0026#34;: 0, \u0026#34;hits\u0026#34;: [] }, \u0026#34;facets\u0026#34;: { \u0026#34;type_賃貸\u0026#34;: { \u0026#34;_type\u0026#34;: \u0026#34;terms\u0026#34;, \u0026#34;missing\u0026#34;: 0, \u0026#34;total\u0026#34;: 52, \u0026#34;other\u0026#34;: 0, \u0026#34;terms\u0026#34;: [ { \u0026#34;term\u0026#34;: \u0026#34;00_北海道\u0026#34;, \u0026#34;count\u0026#34;: 1 }, { \u0026#34;term\u0026#34;: \u0026#34;01_青森県\u0026#34;, \u0026#34;count\u0026#34;: 2 }, { \u0026#34;term\u0026#34;: \u0026#34;03_宮城県\u0026#34;, \u0026#34;count\u0026#34;: 3 }, ... }, \u0026#34;type_売買\u0026#34;: { \u0026#34;_type\u0026#34;: \u0026#34;terms\u0026#34;, \u0026#34;missing\u0026#34;: 0, \u0026#34;total\u0026#34;: 48, \u0026#34;other\u0026#34;: 0, \u0026#34;terms\u0026#34;: [ { \u0026#34;term\u0026#34;: \u0026#34;00_北海道\u0026#34;, \u0026#34;count\u0026#34;: 2 }, { \u0026#34;term\u0026#34;: \u0026#34;02_岩手県\u0026#34;, \u0026#34;count\u0026#34;: 1 }, { \u0026#34;term\u0026#34;: \u0026#34;04_秋田県\u0026#34;, \u0026#34;count\u0026#34;: 1 }, ... } 望んでいた形式とは少し異なりますが、facet_filterする回数を少なくするため、 ファセットは都道府県のフィールドを指定したためです。 アプリで頑張って入れ替えてください。。。\nこの場合、\u0026rsquo;type\u0026rsquo;の個数がわかっているので、頑張ってこのような記述ができました。 ただ、typeが増えた時にアプリの修正とかが必要になりますよね。\nAggregations ということで、Aggregationsの出番です。 ファセットよりも柔軟に、検索結果に対していろいろな集計が行える機能になります。 一見に如かずということで、クエリを紹介します。\nGET /pref_aggs/japan/_search { \u0026#34;size\u0026#34;: 0, \u0026#34;query\u0026#34;: { \u0026#34;match_all\u0026#34;: {} }, \u0026#34;aggs\u0026#34;: { \u0026#34;pref\u0026#34;: { \u0026#34;terms\u0026#34;: { \u0026#34;order\u0026#34;: { \u0026#34;_term\u0026#34;: \u0026#34;asc\u0026#34; }, \u0026#34;field\u0026#34;: \u0026#34;pref\u0026#34;, \u0026#34;size\u0026#34;: 50 }, \u0026#34;aggs\u0026#34;: { \u0026#34;type\u0026#34;: { \u0026#34;terms\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;type\u0026#34;, \u0026#34;size\u0026#34;: 10 } } } } } } ファセットよりもシンプルですし、賃貸といったような値を指定していません。 aggsというのがaggregations機能を指定している部分になります。 検索結果は次のように出力されます。\n{ \u0026#34;took\u0026#34;: 4, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 2, \u0026#34;successful\u0026#34;: 2, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 100, \u0026#34;max_score\u0026#34;: 0, \u0026#34;hits\u0026#34;: [] }, \u0026#34;aggregations\u0026#34;: { \u0026#34;pref\u0026#34;: { \u0026#34;buckets\u0026#34;: [ { \u0026#34;key\u0026#34;: \u0026#34;00_北海道\u0026#34;, \u0026#34;doc_count\u0026#34;: 3, \u0026#34;type\u0026#34;: { \u0026#34;buckets\u0026#34;: [ { \u0026#34;key\u0026#34;: \u0026#34;売買\u0026#34;, \u0026#34;doc_count\u0026#34;: 2 }, { \u0026#34;key\u0026#34;: \u0026#34;賃貸\u0026#34;, \u0026#34;doc_count\u0026#34;: 1 } ] } }, { \u0026#34;key\u0026#34;: \u0026#34;01_青森県\u0026#34;, \u0026#34;doc_count\u0026#34;: 2, \u0026#34;type\u0026#34;: { \u0026#34;buckets\u0026#34;: [ { \u0026#34;key\u0026#34;: \u0026#34;賃貸\u0026#34;, \u0026#34;doc_count\u0026#34;: 2 } ] } }, ... Aggregationsの結果は、望んでいた通りの出力になっています。\nクエリの構成を見てみましょう。\n\u0026#34;aggs\u0026#34;: { \u0026#34;pref\u0026#34;: { #1 \u0026#34;terms\u0026#34;: { \u0026#34;order\u0026#34;: { \u0026#34;_term\u0026#34;: \u0026#34;asc\u0026#34; }, \u0026#34;field\u0026#34;: \u0026#34;pref\u0026#34;, \u0026#34;size\u0026#34;: 50 }, \u0026#34;aggs\u0026#34;: { #2 \u0026#34;type\u0026#34;: { \u0026#34;terms\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;type\u0026#34;, \u0026#34;size\u0026#34;: 10 } } } } } 最初の#1のprefは出力を扱いやすくするためにつけているラベルになります。好きな名前をつけることが可能です。 次のtermsがAggregationのタイプ(どのような集計をして欲しいか)になります。 今回は、prefフィールドにある単語(term)毎に、集計をしたいので、termsを指定します。 その他にどんなタイプがあるかは、公式ガイドをご覧ください。\n次に、さらにtypeフィールドで集計したいので、#2の部分で後続のAggregationを指定しています。 都道府県同様、typeフィールドにある単語毎に集計するために、termsを指定します。\nこれで、先ほどのような結果が出力できます。 ちなみに、さらにtypeの中に他の種別で集計したいという場合は、さらにaggsを追加していけばOKです。\nAggregationは非常に柔軟な集計を可能にする機能です。ただし、検索結果に対して集計処理を行っているため、 メモリやCPUなどのリソースを消費するので注意が必要です。\nAggregationの説明については、こちらのFound.noのブログ(英語)がわかりやすかったので参考にしてみてください。\nまとめ 非常に簡単ですが、Aggregationsについて紹介しました。 その他にもAggregationsでできることがあるので、後日別のサンプルを用意して説明しようかと思います。\n100件のデータやここまでの操作については、gistにあるので、興味がある方はご覧いただければと。 stream2esの操作以外は、Marvelに付属のsenseを利用しています。\n","date":1399456620,"dir":"post/2014/","id":"ed4f5a398056eef1cf6caa90786b340a","lang":"ja","lastmod":1399456620,"permalink":"https://blog.johtani.info/blog/2014/05/07/aggregation-example/","publishdate":"2014-05-07T18:57:00+09:00","summary":"こんなツイートを見つけたので、Aggregationのサンプルでも書こうかなと。(前から書こうと思ってたんですが。。。) @elasticsearch Hi, Would you please tell me the way to","tags":["elasticsearch"],"title":"Aggregations - ファセットよりも柔軟な集計"},{"contents":"今日はelasticsearch-kopfのAnalysis画面の紹介です。\n(簡単なところから。。。その3)\nちょっとあいだが開いてしまいましたが、再開です。 メニューのaliasesを選択すると、次のような画面が表示されます。\nAliases画面 Elasticsearchのaliasを画面で確認できます。\nエイリアスは、インデックスに別名をつけることができるElasticsearchの機能です。 1エイリアス=1インデックスでも良いですが、1エイリアスに対して複数のエイリアスを付与することもできます。 この機能を利用することで、次のようなことが可能となります。\nインデックスの切り替えをアプリ側に意識させずに実施(アプリはエイリアス名に対して検索すればOKなので) 直近1週間のログを検索するためのエイリアスの作成(複数のインデックスを1つのエイリアスに割り当て可能) 特定のルーティングによる検索(特定のデータに対する検索だけに絞るためにfilterを指定する) エイリアスについて詳しく知りたい方は公式ガイドをご覧いただくのが良いかと。\n画面は非常にわかりやすい作りになっているので、特に説明必要ないんですよね。。。\n","date":1399132860,"dir":"post/2014/","id":"2824bef72110575c78aeb979170212b8","lang":"ja","lastmod":1399132860,"permalink":"https://blog.johtani.info/blog/2014/05/04/intro-elasticsearch-kopf-alias-percolator/","publishdate":"2014-05-04T01:01:00+09:00","summary":"今日はelasticsearch-kopfのAnalysis画面の紹介です。 (簡単なところから。。。その3) ちょっとあいだが開いてしまいまし","tags":["elasticsearch","plugin"],"title":"elasticsearch-kopfの紹介(aliases画面)"},{"contents":"kopfの記事の続きも書く必要があるんだけど、こんなツイートを見つけてしまったので。。。\nElasticsearchのBulk APIの仕様、JSONファイルをいい感じに加工して置かなければならないしハマりどころ多い。 http://t.co/hmfycqZlqk\n\u0026mdash; Kenta Suzuki (@suzu_v) 2014, 4月 24 前に思いついたけど、放ったらかしにしてた疑問が再浮上してきたので、せっかくだから調べてみようかなと。\n複数JSONデータがある場合にもっと楽にデータを入れる方法ないかなぁと思って、これかな?というのがあったのですが、 そのまま手を動かさずに放置してたので、一念発起してブログ書いてます。\nBulk APIって? ElasticsearchはURLにアクセスしてデータを登録できます。 基本的には次のように1件毎の登録になります。\n$ curl -XPUT http://localhost:9200/bookshop/books/1 -d \u0026#39; { \u0026#34;book_id\u0026#34; : 1, \u0026#34;title\u0026#34; : \u0026#34;ElasticSearch Server Japanese Edition\u0026#34;, \u0026#34;price\u0026#34; : 3024, \u0026#34;publisher\u0026#34; : \u0026#34;KADOKAWA\u0026#34; }\u0026#39; これでもいいのですが、大量のデータを登録するときは、Elasticsearch側での効率が悪いです。 そこで、Elasticsearchは大量データを登録するためにBulk APIというものを用意しています。\nこれは、次のような形式のJSONを作ってデータを登録します。\n{ \u0026#34;index\u0026#34; : { \u0026#34;_index\u0026#34; : \u0026#34;bookshop\u0026#34;, \u0026#34;_type\u0026#34; : \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34; : \u0026#34;1\u0026#34; } } { \u0026#34;book_id\u0026#34; : 1, \u0026#34;title\u0026#34; : \u0026#34;ElasticSearch Server Japanese Edition\u0026#34;, \u0026#34;price\u0026#34; : 3024, \u0026#34;publisher\u0026#34; : \u0026#34;KADOKAWA\u0026#34;} { \u0026#34;index\u0026#34; : { \u0026#34;_index\u0026#34; : \u0026#34;bookshop\u0026#34;, \u0026#34;_type\u0026#34; : \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34; : \u0026#34;2\u0026#34; } } { \u0026#34;book_id\u0026#34; : 2, \u0026#34;title\u0026#34; : \u0026#34;Introduction of Apache Solr\u0026#34;, \u0026#34;price\u0026#34; : 3888, \u0026#34;publisher\u0026#34; : \u0026#34;gihyo\u0026#34;} これは、次のような構成になっています。\nコマンド データ コマンド データ ... これで効率よくデータが登録できるのですが、このようなJSONデータを別途作って上げる必要が出てきます。 結局、複数のJSONがあるのに、特殊なJSONを生成しないといけないということでプログラム書いて実行することになります。 これだと、Elasticsearchへのアクセスをプログラムで書くのとあまり大差がないかもしれません。\nstream2es もっとお手軽に複数のJSONを登録できないかな?と目をつけていたのが、stream2esです。\nどんなもの? Clojureで作られた、Elasticsearchにデータを流し込むためのツールです。 Java 7がインストールされていれば、ダウンロードしてくれば動作せることができます。\nインストール 公式ページに載っている方法そのままです。\n$ curl -O download.elasticsearch.org/stream2es/stream2es; chmod +x stream2es 実行したディレクトリにコマンドがコピーされます。 あとは、コマンドを実行すればOKです。\n実行 データは次のような形式でsample.jsonに保存してあるとします。\n{ \u0026#34;book_id\u0026#34; : 1, \u0026#34;title\u0026#34; : \u0026#34;ElasticSearch Server Japanese Edition\u0026#34;, \u0026#34;price\u0026#34; : 3024, \u0026#34;publisher\u0026#34; : \u0026#34;KADOKAWA\u0026#34;} { \u0026#34;book_id\u0026#34; : 2, \u0026#34;title\u0026#34; : \u0026#34;Introduction of Apache Solr\u0026#34;, \u0026#34;price\u0026#34; : 3888, \u0026#34;publisher\u0026#34; : \u0026#34;gihyo\u0026#34;} 先ほどのBulk APIで利用したJSONよりも、スッキリしていますね。 1行1ドキュメント1JSONです。\nあとは、次のコマンドを実行するだけです。\n$ ./stream2es stdin --target http://localhost:9200/bookshop/books \u0026lt; sample.json ファイルをstream2esに流し込んで、stream2esが1行ずつパースして、Elasticsearchに投げ込んでくれます。\n登録されたデータは次のようになります。 IDは自動で付与されています。\n{ \u0026#34;_index\u0026#34;: \u0026#34;bookstore\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;0Hvy4IJCRkKrvGb4Dgam_w\u0026#34;, \u0026#34;_version\u0026#34;: 1, \u0026#34;found\u0026#34;: true, \u0026#34;_source\u0026#34;: { \u0026#34;book_id\u0026#34;: 1, \u0026#34;title\u0026#34;: \u0026#34;ElasticSearch Server Japanese Edition\u0026#34;, \u0026#34;price\u0026#34;: 3024, \u0026#34;publisher\u0026#34;: \u0026#34;KADOKAWA\u0026#34; } }, { \u0026#34;_index\u0026#34;: \u0026#34;bookstore\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;b9M6TooFQzGYyJeix_t_WA\u0026#34;, \u0026#34;_version\u0026#34;: 1, \u0026#34;found\u0026#34;: true, \u0026#34;_source\u0026#34;: { \u0026#34;book_id\u0026#34;: 2, \u0026#34;title\u0026#34;: \u0026#34;Introduction of Apache Solr\u0026#34;, \u0026#34;price\u0026#34;: 3888, \u0026#34;publisher\u0026#34;: \u0026#34;gihyo\u0026#34; } } せっかく、book_idがあるんだし、_idをインデックスの設定に指定します。\n$ curl -XDELETE http://localhost:9200/bookshop $ curl -XPUT http://localhost:9200/bookshop -d \u0026#39; { \u0026#34;mappings\u0026#34;: { \u0026#34;books\u0026#34; : { \u0026#34;_id\u0026#34; : { \u0026#34;path\u0026#34;: \u0026#34;book_id\u0026#34; } } } }\u0026#39; あとは、登録すればbook_idが_idに採用されます。\n{ \u0026#34;_index\u0026#34;: \u0026#34;bookshop\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;_version\u0026#34;: 1, \u0026#34;found\u0026#34;: true, \u0026#34;_source\u0026#34;: { \u0026#34;book_id\u0026#34;: 1, \u0026#34;title\u0026#34;: \u0026#34;ElasticSearch Server Japanese Edition\u0026#34;, \u0026#34;price\u0026#34;: 3024, \u0026#34;publisher\u0026#34;: \u0026#34;KADOKAWA\u0026#34; } }, { \u0026#34;_index\u0026#34;: \u0026#34;bookshop\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;2\u0026#34;, \u0026#34;_version\u0026#34;: 1, \u0026#34;found\u0026#34;: true, \u0026#34;_source\u0026#34;: { \u0026#34;book_id\u0026#34;: 2, \u0026#34;title\u0026#34;: \u0026#34;Introduction of Apache Solr\u0026#34;, \u0026#34;price\u0026#34;: 3888, \u0026#34;publisher\u0026#34;: \u0026#34;gihyo\u0026#34; } } 複数ファイル ディレクトリに複数のJSONファイルが有った場合は、次のようなコマンドでOK\n$ cat sample_data/*.json |./stream2es stdin --target http://localhost:9200/bookshop/books まぁ、catして流してるだけですが。。。\nダメだったケース JSONが複数行になっているようなデータだとエラーが出てしまいました。\n(jqコマンドで1行に整形したりできるかなぁ?)\nまた、1行に2つのJSONが書いてある場合は、1つ目のJSONをパースしたら、そこでおしまいみたいで、その後に記述されたデータは登録されませんでした。\nインデックスがない場合 stream2esで登録するインデックスがElasticsearchに存在しない場合、stream2esがインデックスを作成してくれるのですが、 この時、シャード数などはstream2es内部に記述があるので注意が必要です。 以下がその設定です。\nindex.number_of_shards : 2 index.number_of_replicas : 0 index.refresh_interval : 5s 課題? 内部的にはおそらく、Bulkでデータを登録していると思うのですが、まだよくわかっていません。 Clojureが読めないので、せっかくだから、Clojureの勉強も兼ねてちょっとソースを読んでみようかなと思います。 それほど量があるわけでもないので。\nあとは、その他にWikipediaのデータやTwitterのデータ登録、 ElasticsearchからデータをScrollで読み出しつつ、別のElasticsearchに流しこむといったこともできそうなので、そちらも試してみようかと。 他にもオプションがいくつかありそうです。\n今回は2件ほどでしたが、大量データを流し込んだ時にどうなるか(stream2esが悲鳴を上げるのか、Elasticsearchで詰まることがあったらどうなるか)なども 気になるので、なんか適当なデータで試してみるのもいいかなぁと。 (ということで、だれか、いろいろ試してみてもらえると楽できるなぁ。)\n","date":1398341460,"dir":"post/2014/","id":"e396cbf9274b590a1d94ee43d823a0bd","lang":"ja","lastmod":1398341460,"permalink":"https://blog.johtani.info/blog/2014/04/24/usage-stream2es/","publishdate":"2014-04-24T21:11:00+09:00","summary":"kopfの記事の続きも書く必要があるんだけど、こんなツイートを見つけてしまったので。。。 ElasticsearchのBulk APIの仕様、J","tags":["elasticsearch","stream2es"],"title":"stream2esと複数データの登録"},{"contents":"第4回Elsticsearch勉強会を開催しました。 今回から、遅刻厳禁にしてみました。 それほど困った人もいないと思うので、次回からも遅刻厳禁で。\nということで、今回も多数の方にお集まりいただきありがとうございました。\nスタッフの皆さん、スピーカーの皆さん、プレゼント用に書籍を用意してくれたKADOKAWAさん、開場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 次回もよろしくお願いします! 参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\nさて、ブログですが司会業とかやってたので、あんまり書けてないけど。。。\n134番までチケットがはけていたので+スタッフで140〜150名くらいの参加者だったのではないかと思います。 懇親会まで残っていただいた方々も片付けなどありがとうございました。\nさて、感想とか補足です。\n「アナライズ処理の仕組みとクエリDSL」株式会社シーマーク 大谷 純 @johtani スライド:アナライズ処理の仕組みとクエリDSL※スライドはPDFです。\nプラグイン:elasticsearch-extended-analyze\nプラグインの紹介記事:http://blog.johtani.info/blog/2013/10/25/developing-es-extended-analyze-plugin/\nMarvel:http://www.elasticsearch.com/marvel/\n日本語版メーリングリスト:https://groups.google.com/forum/#!forum/elasticsearch-jp\nなんか、宣伝(本+プラグイン)ばっかりですみません。 「プラグインの紹介記事」に簡単な使い方が書いてあります。が、情報が古いので、Elasticsearchのバージョンに合わせたバージョンを使ってください。\nまだまだ発表に慣れてないので、頑張ろ。\nアンケート取ってみましたが、ログ検索と全文検索と半々くらいで興味がある人がいるみたいでした。 あと、有料トレーニングは人気ないっすね。。。\n「elasticsearch-hadoopを使ってごにょごにょしてみる」 株式会社マーズフラッグ R\u0026amp;D部 やまかつ さん @yamakatu スライド:elasticsearch-hadoopを使ってごにょごにょしてみる\nelasticsearch-hadoop:https://github.com/elasticsearch/elasticsearch-hadoop\nQAとして、Elasticsearchにプライマリデータを保存するのは的な話が出てました。 ESにのみデータを入れるのは個人的には考えたことないかなぁ。 どうしても、ElasticsearchのWriteが遅いんじゃないかという懸念事項を持ってる人がいるなぁと。(実際ツラいという話もちらほら)\nお腹痛い中の発表ありがとうございました。。。 次回はMapRの方に紹介してもらえそう(交渉中)なので楽しみです。やまかつさんの続きも聞きたいなぁ。\n「CouchbaseとElasticsearchが手を結んだら」株式会社アットウェア 佐竹雅央さん @madgaoh 河村康爾さん @ijokarumawak スライド:CouchbaseとElasticsearchが手を結んだら\nCouchbaseのElasticsearchに関するページ:http://docs.couchbase.com/couchbase-elastic-search/\nCouchbaseに入れたら、自動的にElasticsearchにもデータを入れてくれる。 デモがあるの、いいっすね。\n最新版はmasterを落としてきてビルドしないとダメらしい。確かに、上のページには0.90.5って書かれてる。 ここでも、やはり、Elasticsearchが詰まった時にどうするの?みたいな話が出てました。 CouchbaseのXDCRだと、後ろが詰まってる時によしなに?データを流すのを制御してくれるってのがあるみたいですが、 Elasticsearchだと悲鳴を上げているのがわかりにくいと。\nあと、Elasticsearchがインデキシングでキューを取りこぼしているのがログからわかりにくいってのも出てました。 (なにか、分かる方法があるかとかも調べてみようかなぁ。)\n自分の宿題:Transportプラグインって何かについて調べてブログに書くこと。\n「Elasticsearch at Wantedly」(タイトルあってるか不安) Wantedly, Inc 内田誠悟さん @spesnova スライド:Elasticsearch at Wantedly\n参考文献:Elasticsearchチュートリアル\n参考文献:Elasticsearch Workshop\n参考文献:elasticsearch-rails\nWantedlyでどうやって使ってるのか。 あと、オートコンプリートでも使ってます。(この話は次回聞けるといいなぁw)\nデータ数は少ないので、参考にまだならないかも。\n公式のサイト見難いですよねと。 ペンギン先生のブログが素晴らしかった! マッピングすごいw\n最後は、苦労して作ってもらったautocompleteの資料は放ったらかしにして、質疑応答してもらいました。 辞書とか、検索漏れとかの話は今後の課題っぽかったですね。\n「Elasticsearchのみに決めてました!」ってセリフがカッコ良かったw\nアクセスコントロール周りのノウハウもブログで共有してくれそうなので楽しみにしています!\nあと、「tireがretire」の話が出てましたが(この発表だっけ?)参考文献にあげてある、elasticsearch-railsが今は本流なんじゃないかなぁ?\nLT ###「ElasticsearchのScripting」株式会社富士通ソフトウェアテクノロジーズ 滝田聖己さん @pisatoshi\nスライド:ElasticsearchのScripting\n参考文献:elasticsearch-native-script-example\n色々とScriptがあるという話を説明してもらい感謝です。 もちろん、ElasticSearchServerにも書いてあるので、そちらも参考にしてください!\n「Elasticsearch 向け多言語解析プラグイン」ベイシス・テクノロジー株式会社 江口天さん スライド:Elasticsearch 向け多言語解析プラグイン\n参考文献:Elasticsearchで使えるRosette基本言語解析モジュール\n参考文献:Elasticsearch-inquisitorプラグインの紹介\nベイシステクノロジさんが提供しているRosetteをElasticsearchで活用できるモジュールみたいです。 いまなら、無料で体験できるみたいなので、どんなものか触ってみると面白いかもしれません。\nあと、デモで使用されていたプラグインについて、私が昔に書いた記事があるので、興味のある方は参考にしていただければと。 このプラグインはクエリがどのように内部でLuceneのクエリになっているか、どのフィールドでどうトークンが生成されるか? といったものが見ることができるプラグインになっています。\n関連ブログ 適当に見つけたブログを列挙してあります。これもあるよ!などあれば、教えてください。\n勉強会メモ - 第4回elasticsearch勉強会 2014/04/21\ntogetter 第4回elasticsearch勉強会 #elasticsearchjp\n参加レポート:第4回elasticsearch勉強会 #elasticsearchjp\n第4回elasticsearch勉強会に参加しました\nまとめ しつこいくらい宣伝してしまいましたが、「ElasticSearch Server日本語版」よろしくお願いします!\n今回も楽しい話が聞けました。メモがちょっと少ないんですが。。。\n次回は6末を目処に、MapRの方などと調整して開催しようと思います。 聞きたい話とか、発表したい方とかあれば、連絡くださいー!\n","date":1398077040,"dir":"post/2014/","id":"50562b09417cd8c4a2348a0a5aabe754","lang":"ja","lastmod":1398077040,"permalink":"https://blog.johtani.info/blog/2014/04/21/hold-on-4th-elasticsearch-jp/","publishdate":"2014-04-21T19:44:00+09:00","summary":"第4回Elsticsearch勉強会を開催しました。 今回から、遅刻厳禁にしてみました。 それほど困った人もいないと思うので、次回からも遅刻厳禁","tags":["elasticsearch","勉強会"],"title":"第4回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"今日はelasticsearch-kopfのAnalysis画面の紹介です。\n(簡単なところから。。。その2)\nメニューのanalysisを選択すると、次のような画面が表示されます。\nAnalysis画面 Elasticsearchの_analyze APIを画面で確認できます。 画面で動作の確認ができるのは嬉しいですよね。\n入力文字列:入力となるドキュメントに含まれる文字列や検索キーワードを入力 フィールドの指定:対象とするインデックス名、タイプ名、フィールド名を選択 analyze:ボタンを押す トークナイズされた結果:入力文字列がどのようなトークンに分割されるか start、end:入力文字列中の文字列の位置 pos:トークンの位置 という形でElasticsearchが指定されたフィールドで入力文字をどのようにトークナイズしたかを確認することができます。\nElasticsearchは内部でこのトークナイズされた単語を元に転置インデックスを作成し、検索に利用します。 ですので、特定のデータが検索に上手くヒットしないときに、この画面でデータの文字列をトークナイズしてみるといった用途に使えます。\nフィールドの設定がどのようにして入力文字列をトークンにしているかといった点については、今度のElasticsearch勉強会で話す予定です。\nフィールドの設定を利用する以外に、アナライザを指定してどのようにトークナイズされるかを見ることもできます。 「ANALYZE BYANALYZER」をクリックすると利用できます。\nANALYZE BY ANALYZER トークナイズしたい文字列を入力し、インデックス名と、インデックスに設定されているアナライザ名を選択してanalyzeボタンを押すと 結果が表示されます。 (例では、kuromojiアナライザを利用して出力になっています。また、出力結果のposの表示位置がFIELD TYPEの時と違うのが少し気になりました。)\nただ、残念ながら、インデックスのマッピングで指定したアナライザしか利用できないみたいなので、 どのアナライザがどんな挙動かを調べたい場合は、以前紹介したelasticsearch-inquisitorを 利用したほうが良さそうです。\nということで、今日はanalysis画面の説明でした。\n","date":1397011260,"dir":"post/2014/","id":"76a1fb7f21fda9eddb95426b65124517","lang":"ja","lastmod":1397011260,"permalink":"https://blog.johtani.info/blog/2014/04/09/intro-elasticsearch-kopf-analysis/","publishdate":"2014-04-09T11:41:00+09:00","summary":"今日はelasticsearch-kopfのAnalysis画面の紹介です。 (簡単なところから。。。その2) メニューのanalysisを選択","tags":["elasticsearch","plugin"],"title":"elasticsearch-kopfの紹介(analysis画面)"},{"contents":"JVM Operation Casual Talksに参加しました。 あんまり、運用とかやってないので、ついていけるか不安ですが、楽しそうだったので。 懇親会は予定されてないらしい。\n@stanaka\t15分でわかるJVMのメモリ管理 スライド:https://speakerdeck.com/stanaka/understanding-memory-management-of-javavm-in-15-minutes\nJVMの基礎知識\n某研究所で。。。\nElasticsearch、Solrの名前が!\nJVM困りどころ。ネットの情報が古いのが多いとか。\n使いこなすにはきちんと知識が必要。\nMemory Model 困ったらJava8に。。。\nHeapのチューニングが重要\nHeapの構成やGC処理の説明\nCMSでもすべて並列ではない\nOlgGenがフラグメントして確保が遅くなっていく G1GCの概念図。YoungやOld、Survivorの区別がない?\nリージョン? リファレンスリストすばらしい。\n@oranie\tCassandra運用で実施しているJVM監視について スライド:http://www.slideshare.net/oranie/jvm-operation-casual-talks-33218856\nCassandra(1.1)で運用中。 35TBとか エンジニアブログ読め。 Cassandraの監視って何すればいいの? GC頻度とかグラフで見れる VisualVM便利って教えてもらった。 VisualVMでどんな値があるか見ながら調べて、取りたい値を考える。 SNMPで頑張るの辛い=JMXかな?=Javaで叩くの?=Jolokia どんなことやってる? Nagios+Jenkins+。。。あとでスライド yohoushi+GrowthForecastも便利。 @waysaku\tSpray(Akka)運用でJVMをCPUスケールさせるために行った事 スライド:http://www.slideshare.net/waysaku/jvm-operation-casual-talks\nSpray Akkaアプリケーションの運用を任されちゃった人 カットオーバー直前の負荷試験でびっくりするくらいスループットでない。。。 いろんなActorが特定のActorに処理を投げた状態で待ってるという状況。。。 スレッドダンプ追っかけてる様子を追体験してる。 ログ出力がBLOCKしてた I/Oを伴う処理は非常にセンシティブ 以下、LT @oinume\t運用に効く!JVMオプション三選 スライド:http://www.slideshare.net/oinume/jvm-operationcasualtalks20140407\nサーバに入らなくても見れるのは VisualVM 最終形Java Mission Control Flight Recorder(商用だと有償) @y_uuki1\tなにもわからないところから始めるJVMモニタリング スライド:https://speakerdeck.com/yuukit/nanimowakaranaitokorokarashi-merujvmmonitaringu\nブログ:http://yuuki.hatenablog.com/entry/2014/04/08/074507\nなんでここにいるかわかりませんが。 色んな所記事とかのリンクがある。 Graphiteに放り込んでるらしい。 @tagomoris\tNorikraのJVMチューンで苦労している話 スライド:http://www.slideshare.net/tagomoris/norikrajvm\nNorikraで困ったので開催したらみんなしゃべりに来てくれてありがたい世の中ですね。 デフォルト設定で運用。mx4096mで4ヶ月は元気に動いてた 年末に崩壊 -\u0026gt; harukaさんのQiita見ながら設定してほったからした。 3月にまた崩壊OOM SoftRefが悪さしてるのか? nekopさんのブログにヒントが。 @shot6\tJVM的なナニカを話す、GC戦略をそえて スライド:http://www.slideshare.net/shot6/jvm-33248312\n某A社からきました。 CMSを中心が良い CPUコア少ないとCMS Incremental G1GCは6GB以上とかもっと大きい場合のほうが良さそう(雑感) 基本的に、ドキュメントに書いてあるけど、つらいので、まとめてみました。 後で見たいな、このスライドも。 @kazeburo\tWebアプリケーションとメモリ スライド:http://www.slideshare.net/kazeburo/jvm-casual\nJavaは1行も書いたことありません。 Java運用したけど、まぁ、ひどい目にあってます。 ということで、PerlとApacheの話? bumpyなんとかってのは頭良くプロセスの処理回数とかをなんとかしてくれる JVMとかどうなの? ということで、CA社の人が釣れたので良かったですね。 TBD\tJVMの運用について話す会(パネル) なんでJVM?\n全文検索だとJVMだなぁ。SolrとかElasticsearchとか 入社したらあった。 JVMこまったところは?\n突然Dioが出てくる JVMいいところは?\nうーん、あえて言うと。。。スレッド処理 型がある言語を調べるとJVM。というよりScala。 飛び入り参加。落ちないところ。人殺しは良くないw 簡単には殺せないところに使えるのは良いのでは。 チューンはどこまでやる?\n7,8割でやめたほうが良い? そんなに突き詰めなくてもいいのかな。 Cassandraだと、FullGCが走ってる時点で再起動しかない場合が多いです。 言語のランタイムについてチューンすることってJVMの他ある?\nRubyくらい? 自分たちで何とかできないものを相手にしている人たちは苦労してるんじゃないか\nCaなんとかさんとかHBなんとかさんは困ってる人が多い 最後に一言\nモニタリングツール参考にしたい 最後に 「やりたくなったら誰かやってください。」ということみたいです。\n基礎から監視まで結構幅広くキーワードが出てきたので楽しかったです。\nその他に話に出てきてた方のブログもリンクしとこうかな。\nnekopの日記\n","date":1396866240,"dir":"post/2014/","id":"299abcee56b05b312ed5700f686f79b8","lang":"ja","lastmod":1396866240,"permalink":"https://blog.johtani.info/blog/2014/04/07/attend-jvm-casual-1/","publishdate":"2014-04-07T19:24:00+09:00","summary":"JVM Operation Casual Talksに参加しました。 あんまり、運用とかやってないので、ついていけるか不安ですが、楽しそうだったので。 懇親会は予定されてないらしい","tags":["JVM","Java","勉強会"],"title":"JVM Operation Casual Talksに参加しました #jvmcasual"},{"contents":"今日はelasticsearch-kopfのREST画面の紹介です。\n(簡単なところから。。。)\nメニューのrestを選択すると、次のような画面が表示されます。\nElasticsearch自体が、さまざまな操作をRESTでできる仕組みになっています。 検索にも利用しますが、それ以外の設定などにつてもリクエストを送ればOKです。\nですので、リクエストや設定を自分で組み立てて送ることができる画面が用意されているととても便利です。 (もちろん、curlコマンドでもいいのですが、画面があると便利ですよね)\nREST画面 History 履歴表示画面です。 これまで、kopfのrest画面を利用して送信したリクエストが一覧で表示されます。\nHistoryという文字をクリックすることで、表示/非表示の切り替えが可能です。(最初は非表示) マウスオーバーすると、リクエストボディがポップアップで表示されます。\nHistory 履歴にあるURLはクリック可能で、クリックすると実行されます。 履歴はlocalStorageに保存されるみたいです。(ブラウザの仕様?あんまり詳しくないので。。。) たぶん、30件が上限かと(ソースで確認しただけ)\nURL rest画面でリクエストを送信する先のURLを指定します。 メソッドは右側のSELECTで選択可能です。\nリクエストパラメータも指定が可能です。\nリクエストボディ 検索や設定のJSONを記述するところです。 一応、JSON的にエラーがある場合は行数の左側にバツ印が出てきておかしなところもわかるようになっています。\nインデントなどは行ってくれますが、senseみたいな補完などはないので、少し辛いところです。\nレスポンス 送信したリクエストに対するレスポンスが返ってきます。 インデントされた状態で表示されるので読みやすいかと。 また、入れ子になっているJSONについては、閉じたり開いたりすることも可能です。 (開始のカッコの右側に-が表示されていて、クリックすると閉じることができます。閉じると+に変わります)\n簡単ですが、rest画面の説明でした。 KOPFを使っていて、ちょっとしたクエリを送ったりするのには便利だと思います。\n複雑な検索クエリなどについては、やはりsenseを使うのが良いかと思いますが。。。\n","date":1396837440,"dir":"post/2014/","id":"670744b945088de05866864f7d57bee7","lang":"ja","lastmod":1396837440,"permalink":"https://blog.johtani.info/blog/2014/04/07/intro-elasticsearch-kopf-rest/","publishdate":"2014-04-07T11:24:00+09:00","summary":"今日はelasticsearch-kopfのREST画面の紹介です。 (簡単なところから。。。) メニューのrestを選択すると、次のような画面","tags":["elasticsearch","plugin"],"title":"elasticsearch-kopfの紹介(rest画面)"},{"contents":"なんだか、ドタバタしてて久しぶりの更新です。 ベルリンの旅行記みたいなのも書きたいのですが、まずはこちらかと。\nelasticsearch-kopfプラグインの紹介です。\n今回は概要の説明だけになります。機能が結構多いので。\nelasticsearch-kopfとは? _siteプラグインの一つで、クラスタ管理用のプラグインになります。 headプラグインやHQプラグインと同様です。\nプラグインの画面 このようにシンプルな画面で、スッキリとしています。 緑を基調にした画面構成はElasticsearchの緑色を意識してるんでしょうか?\n上記の画像に簡単なコメントを入れてあります。\nメニュー KOPF:KOPF自体の設定(接続先とリフレッシュインターバルの変更) cluster:クラスタ管理、情報(デフォルト表示画面) rest:RESTリクエスト送信、結果表示画面 aliases:エイリアス管理 analysis:analysis API percolator:パーコレータ管理 warmup:ウォームアップクエリ管理 上記のようなメニューです。各メニューについては、今後のブログで少しずつ紹介しようかと。 このメニューの色が、クラスタの状態も表しています。ステータスがYELLOWなら黄色、REDなら赤色に変わります。\nインデックス インデックスは列として表示されます。先ほどの画像では、2つのインデックスが表示されている状態です。 インデックス毎に、シャードも表示されます。これは、各ノードがどのシャードを保持しているかという情報です。 色の濃いシャードがプライマリでしょう。 インデックス名やシャードの箱はクリックできるようになっていて、それぞれの情報がJSONで表示されます。 その他にもドキュメント数、サイズなども表示されます。 インデックスの各種操作(closeやdeleteなど)もここからメニューが表示されます。(これも次回詳しく)\nノード ノードの情報が行として表示されます。ノードが増えると下に追加されていきます。 node1というのが、ノード名です。(ヒーローの名前とかが出てくるやつです。)\nその他に、IPアドレス、ポート番号、負荷、ヒープサイズなども表示されています。 電源ボタンはノードのシャットダウンを行うためのボタンです。(確認用のダイアログが表示される)\nその他 その他に、クラスタの概要として、ノード数、インデックス数、シャード数、ドキュメント数なども表示されます。 インデックスの作成などは、アイコンから操作が可能です。 大規模なクラスタを管理している場合、検索ボックスを利用することで、インデックス名やノード名による絞込もできるようになっています。\n感想 シンプルな構成の画面で、個人的にはheadよりも好きな画面です。 HQよりもシャードの分散具合がわかりやすいので、今後はこのプラグインを利用していこうと考えています。\nまずは、簡単な紹介です。今後、各画面についてもう少し説明をブログに書いていこうかと考えています。 待てない方は、触ってみてもらうのが良いかと。 もちろん、続きを書いてもらってもいいですよ!!\n","date":1396707480,"dir":"post/2014/","id":"c1241374502f200cf9fc49c8d6fb5822","lang":"ja","lastmod":1396707480,"permalink":"https://blog.johtani.info/blog/2014/04/05/intro-elasticsearch-kopf-1/","publishdate":"2014-04-05T23:18:00+09:00","summary":"なんだか、ドタバタしてて久しぶりの更新です。 ベルリンの旅行記みたいなのも書きたいのですが、まずはこちらかと。 elasticsearch-ko","tags":["elasticsearch","plugin"],"title":"elasticsearch-kopfの紹介(概要)"},{"contents":"先日、「ElasticSearch Serverを翻訳しました」という記事を書きました。\nこの中で電子版も出ますよと書いていましたが、電子版も発売されたので、再告知も兼ねてブログを書いています。\nなお、最近よく「ElasticsearchのSは小文字」とツイートしていますが、本書は原著のタイトルが「ElasticSearch Server」となっているため、Sは大文字になっています。原著が出版された時期にはまだSが小文字に統一されていなかったためです。\n紙の書籍はすでに書店に並んでいたり、Amazonでも発送されているようです。\n私自身が電子書籍が場所を取らなくて好きというのもあり、電子版も出版していただけるようにお願いしていました。\n電子版についてはAmazonでKindle版、達人出版会からEPUBとPDFが購入可能です。\n達人出版会のElasitcSearch Serverのページ AmazonのKindle版ページ こちらのリンク(Amazonはアフィリンク)を参考にしていただければと。\n書籍の写真入りツイートしたら、原著者の方からレスを頂きました。\n@johtani Thanks for the great work out there :)\n\u0026mdash; Rafał Kuć (@kucrafal) 2014, 3月 23 また、原著者のサイトでも紹介してもらいました(結構うれしい)。 私が窓口をやっていた関係で、私の名前しか入っていませんが。。。 編集者と翻訳者の方々のお陰で良い本が出版できたと思っています。\nThanks for sharing! / ElasticSearch Server book in Japanese | ElasticSearch Server Book Blog http://t.co/fhCP1vVBd3\n\u0026mdash; Jun Ohtani (@johtani) 2014, 3月 24 ということで、Elasticsearchの導入の手助けになればと。 感想(賛否問わず)など、あればコメント、ツイート、ブログなど書いていただければうれしいです。 (その際に、連絡してもらえるとさらにうれしいです)\n","date":1395722580,"dir":"post/2014/","id":"d51032bef3e7117a94336fea18a3fad7","lang":"ja","lastmod":1395722580,"permalink":"https://blog.johtani.info/blog/2014/03/25/release-elasticsearch-server-ja-ebook/","publishdate":"2014-03-25T13:43:00+09:00","summary":"先日、「ElasticSearch Serverを翻訳しました」という記事を書きました。 この中で電子版も出ますよと書いていましたが、電子版も発","tags":["elasticsearch"],"title":"ElasticSearch Server日本語版(電子版も)が発売されました"},{"contents":"GOTO Night elasticsearchに参加しました。 初の海外の勉強会です(海外自体が初だし)。\nベルリンにあるWoogaという会社で開催された勉強会です。\nFull house at the #gotonight about @elasticsearch in the auditorium of @wooga pic.twitter.com/r2Vx2aMcEn\n\u0026mdash; GOTO Berlin (@GOTOber) 2014, 3月 18 会場はこんな感じで、とってもおしゃれです。(なんか、写ってますね、最前列にw) ベルリンの古い建物をリノベーションしたオフィスみたいで、そこにこういったひな壇を用意して発表するスペースにしているみたいです。\n内容としては、Elasticsearch1.0の新機能の話として、snapshot/restore、cat、aggregationなどの話題でした。簡単にどういったものかの説明です。\n一人目の発表が終わったら、ブレイクタイムとして上のフロアに用意されている軽食+ドリンクで軽く交流の時間が用意されていました。 ベーグルなどのサンドイッチとハイネケンやクラブマテ?と呼ばれるチープなレッドブルとかが飲めました。\nちょっと食べて談笑したあとに、次はLogstashとKibanaのお話でした。Logstashってどんなもの?という話がメインで、Kibanaは簡単な紹介という感じでしょうか。最後に、ライブデモがありました。 Kibanaを使ったライブデモはインパクトがあるなというのが感想です。 フィールド名の補完をしてくれたりと便利な機能が操作をしているところでわかるので。\nYoutubeなどでも見てても思っていた感想ですが、こちらの勉強会は質問が結構出てきます。 今日参加した勉強会も質疑応答が結構されてました。\nelasticsearchの方たちと少しだけ話しをできたので、かなり興奮気味でブログを書いています(ミーハー)。\nただ、やっぱり英語のヒアリングがまだまだだなぁとも実感出来ました。 場数踏むしかないと思うので少しずつ耳にしてなれるしかないかなぁと。 はぁ、ちゃんと高校とか大学の頃に単語を覚えとくんだったと軽く後悔。\nこんなツイートもしてもらって、興奮気味です。明日早起きしないといけないので寝ないといけないのにw\nMeeting @johtani finally in #berlin watching @spinscale talking about #elasticsearch\n\u0026mdash; Simon Willnauer (@s1m0nw) 2014, 3月 18 ","date":1395151860,"dir":"post/2014/","id":"65453a1ae403679bd2e47398a04205ca","lang":"ja","lastmod":1395151860,"permalink":"https://blog.johtani.info/blog/2014/03/18/attend-goto-night-elasticsearch/","publishdate":"2014-03-18T23:11:00+09:00","summary":"GOTO Night elasticsearchに参加しました。 初の海外の勉強会です(海外自体が初だし)。 ベルリンにあるWoogaという会社で開催された勉強会","tags":["elasticsearch","勉強会"],"title":"GOTO Night elasticsearchに参加しました"},{"contents":"Berlinからおはようございます。\nということで、人生で初めての海外に来ています。\n人生初の海外なのに、一人で乗り換えがあるようなBerlinに来ています。 今年はチャレンジの年になりそう。初めてづくしですが、楽しみたいなと。 会社に感謝です。ESのトレーニングを受けに来たのがメインなのです。 ついでに、Berlinでの勉強会にも参加してみようかなと。\n幸いにも時差ボケはなさそうなので、色々と見て回ろうと思います。 ただ、日曜日はお店が軒並みしまってそう。。。\n","date":1394916660,"dir":"post/2014/","id":"abc5ca9856a61831fd4ed06b402875d2","lang":"ja","lastmod":1394916660,"permalink":"https://blog.johtani.info/blog/2014/03/16/post-from-berlin/","publishdate":"2014-03-16T05:51:00+09:00","summary":"Berlinからおはようございます。 ということで、人生で初めての海外に来ています。 人生初の海外なのに、一人で乗り換えがあるようなBerlin","tags":["misc","travel"],"title":"Berlinからおはようございます"},{"contents":"elasticsearchに、このへん入れるときっと幸せになれるはず・たぶん。\u0026#10;elasticsearch/elasticsearch-analysis-kuromoji/1.6.0\u0026#10;oyrusso/elasticsearch-HQ\u0026#10;mobz/elasticsearch-head\n\u0026mdash; toshi_miura (@toshi_miura) 2014, 3月 5 こんなツイートを見かけたので、普段入れてるプラグインを簡単に紹介してみようかと。\nローカルの環境に普段入れているプラグインの紹介です。 ちゃんとクラスタを管理しているというよりは、最新版の動作などを確認するための環境になります。なので、ちょっと視点が異なるかもしれませんが参考になればと。\nelasticsearch-analysis-kuromoji URL : elasticsearch-analysis-kuromoji\nKuromojiという日本語形態素解析のTokenizerなどを使えるようにするためのプラグインです。 今度、発売される「ElasticSearch Server」日本語版には付録として、利用方法を執筆しました。参考にしていただければと。 READMEにもサンプルは掲載されてるので、こちらを参考にするのもありですが。\nelasticsearch-extended-analyze URL : elasticsearch-extended-analyze\n私が開発しているプラグインです。 ElasticsearchにはanalyzeというAPIが用意されています。 文章を渡すと指定したanalyzerなどでどのような単語に区切られるかがわかるAPIです。\nただ、analyzerの内部ではchar filter、tokenizer、token filterという個別のパーツがそれぞれ入力された文字列に対して処理を実施します。 この過程がanalyze APIではわかりません。 それをわかるようにしてみたのがelasticsearch-extended-analyzeプラグインになります。\n詳細については過去の記事を見ていただければと。 画面があると便利だよなぁと思いつつ、作ってない。。。\npolyfractal/elasticsearch-inquisitor URL : elasticsearch-inquisitor\nクエリのデバッグとかに便利なプラグイン。\nこちらも詳細は過去の記事を見ていただければと。\nmobz/elasticsearch-head URL : elasticsearch-head\nクラスタ管理に便利なプラグインです。クラスタに存在するノードに対してインデックスのデータ(シャード)がどこに配置されているかなどが一目瞭然になる便利なプラグインです。 プライマリシャードやレプリカなどもわかります。 インデックスの削除もできるし、クエリを投げることもできるし、全部入りな感じのプラグインです。\n私個人は、シャードの配置を見るのに主に利用しています。クエリを投げたりインデックスを消したりするのには殆ど使っていません。\nroyrusso/elasticsearch-HQ URL : elasticsearch-HQ\nこれも管理系のプラグインです。こっちのほうが個人的にスッキリしていて好きなプラグインです。 インデックスの管理やノードの停止などはこちらを主に使用しています。 あくまでもローカルの簡易クラスタを管理する目的というのもあります。\npolyfractal/elasticsearch-segmentspy URL : elasticsearch-segmentspy\nこちらはモニタリングでしょうか。 ElasticSearch Serverで紹介されていたのが主な理由で、入れてますがあんまり見てないかも。 インデックスのSegment単位の情報が見ることが可能です。 あと、ちょっと更新されてない感じがしますね。\nelasticsearch/marvel Elasticsearch社から提供されている、モニタリングなどに使えるプラグインです。 開発環境では無償提供という感じです。 渡しの場合、モニタリング目的ではなく、senseと呼ばれるクエリの補完をしてくれるツールの目的のために使用しています。 モニタリング部分を停止する方法とかないかなぁ。\n詳細については過去の記事を参考にしていただければと。\nまとめ? ということで、簡単にローカルに入っているプラグインの紹介でした。 他にもいっぱいあるので、おすすめがあれば、教えてもらえると助かります。\n","date":1394515380,"dir":"post/2014/","id":"386dc9d1b647a9f3965f1fbe29c7dfb9","lang":"ja","lastmod":1394515380,"permalink":"https://blog.johtani.info/blog/2014/03/11/es-plugin-installed-to-my-env/","publishdate":"2014-03-11T14:23:00+09:00","summary":"elasticsearchに、このへん入れるときっと幸せになれるはず・たぶん。\u0026#10;elasticsearch/elasticsearc","tags":["elasticsearch","plugin"],"title":"いつも入れているElasticsearchのプラグイン"},{"contents":"第3回Elasticsearch勉強会で、軽く触れていましたが、ElasticSearch Server日本語版が発売されます。 ツイートなどもちらほらとして頂いているみたいで嬉しい限りです。\n本書は、私自身、初の翻訳本となります。\nなお、ElasticSearchはAWSのサービスではなく、全文検索・解析サーバのOSSです\n内容、概要 PacktPublishingから発売されているElasticSearch Serverの日本語版となります。 以下の点が、原著とは異なる点になっています。\n0.90.xに対応(原著は0.20) Kibana、Kuromojiに関して追記 もちろん日本語 残念ながら、つい最近、Elasticsearchについては1.0がリリースされました。 1.0で追加された機能(SnapshotやRestore、Aggregatorなど)については触れていませんが、Elasticsearchの機能を網羅的にカバーした良書となっています。 どんな機能があるのか、どんなプラグインがあるのか、どういったことに使えるのかなど、幅広くまとめられた本になっていますので、 Elasticsearchに興味がある方はぜひ読んでいただければと思います。\nまた、現段階では予定ですが電子版の出版も予定されています。電子版が気になる方は、少しお待ちいただければと。\nElasticSearch?Elasticsearch? 1.0.0がリリースされた現在は、Elasticsearch(SearchのSは小文字)が正式な名称となっています。 ただ、原著が発売された当初(2013年2月時点)では、まだSは小文字と大文字が混在した状況でした(コミットログなどを見るとわかります。) このため、日本語版でもElasticSearchという表記に統一してあります。\n翻訳に関して 初の翻訳書ということもあり、大変でした。英語に精通しているわけではないので(むしろ苦手)。。。 他の翻訳者の方々には大変助けていただきましたし、勉強になりました。 また、監修社であるリクルートテクノロジーズにも色々とサポートしていただき、感謝の限りです。 (Elasticsearch勉強会の開場提供にも協力して頂いています。)\nわかりにくい日本語となっている部分などありましたら、ご指摘いただければ今後の参考にさせていただきます。 英語やElasticsearchについて、学ぶという目的もあって、本書の翻訳を買って出たのが本音です。\n翻訳作業について Githubのリポジトリを編集の方に用意してもらい、翻訳原稿を管理、校正していきました。 Github自体をあまり触っていなかったので、作業をしながらGithubも覚えられ一石二鳥でした。 Issueやプルリクエストによる校正、チェックも便利ですね。 他の原稿を書くようなことがあれば、またこの経験を活かしていきたいなと。 (翻訳の進め方や原稿のチェックなどについてはまた後日何か書こうかと。)\n原著について 原著のサイトが用意されています。 http://elasticsearchserverbook.com/elasticsearch-server-errata/\n原著を翻訳するにあたって見つけた、誤植などを報告し、掲載して頂いています。 原著をお持ちの場合はこちらも参考にしていただければと思います。\nご購入はこちらから ということで、簡単ですが書籍の紹介(というより宣伝!?)でした。 Elasticsearchに関する何かしらの助けになる書籍であれば嬉しい限りです。\n「ElasticSearch Server日本語版」をよろしくお願いします。 (もちろん、購入は下のリンクからですよね!)\n","date":1393836900,"dir":"post/2014/","id":"9ad72c2a5157f21741bd4581a562dfc7","lang":"ja","lastmod":1393836900,"permalink":"https://blog.johtani.info/blog/2014/03/03/release-elasticsearch-server-japanese-edition/","publishdate":"2014-03-03T17:55:00+09:00","summary":"第3回Elasticsearch勉強会で、軽く触れていましたが、ElasticSearch Server日本語版が発売されます。 ツイートなども","tags":["elasticsearch"],"title":"ElasticSearch Serverを翻訳しました"},{"contents":"今年初の「突撃!隣のElasticsearch」ということで、Wantedlyさんにおじゃましました。\n※写真を自分でも撮ったのですが、画像が壊れてたので、一緒に行ったペンギン先生の写真を拝借しました。\n第3回のElasticsearch勉強会を開催中にES使ってるってツイートを見つけたので、アタックかけて遊びに行きました。 交渉に快諾いただきありがとうございました!\nWantedlyさんがどのようにElasticsearchを使用されているかはきっと、ブログを書いてくれると思うので期待しておくとして、書いてくれました!! 「実践!Elasticsearch」 そこで、nestedでハイライトがなんかうまくいかないって話があったので、ちょっと調べてみました。 (※まだ、調査中です)\n前提条件 再現する手順はgistにあります。(Senseに貼り付ければ動作します。ただし、elasticsearch-analysis-kuromojiが必要です。)https://gist.github.com/johtani/9184287\nなお、このマッピングやデータはWantedlyさんとは全く関係ありません。\nnestedフィールド内部のデータに対して、検索しハイライトしようとするとうまく動作しないという状況です。 マッピングは以下のとおり。\n\u0026#34;books\u0026#34; : { \u0026#34;properties\u0026#34;: { \u0026#34;book\u0026#34; : { \u0026#34;type\u0026#34;: \u0026#34;nested\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;title\u0026#34; : { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;kuromoji\u0026#34;, \u0026#34;store\u0026#34;: \u0026#34;no\u0026#34;}, \u0026#34;contents\u0026#34; : {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;kuromoji\u0026#34;, \u0026#34;store\u0026#34;: \u0026#34;yes\u0026#34;} } } } } } このマッピングの特徴は以下のとおり。\n_sourceは保存される(デフォルト値) bookがnestedなオブジェクト titleはstore : no contentsはstore : yes 動作の挙動をわかりやすくするため、titleとcontentsのstore属性に違いを持たせてあります。\n問題点 nestedクエリを使って、検索した時にハイライトが返ってきません。 次のクエリを実行するとわかります。\nGET /bookstore/books/_search { \u0026#34;_source\u0026#34; : [\u0026#34;book.title\u0026#34;,\u0026#34;book.contents\u0026#34;], \u0026#34;fields\u0026#34;: [ \u0026#34;book.title\u0026#34;, \u0026#34;book.contents\u0026#34; ], \u0026#34;query\u0026#34;: { \u0026#34;nested\u0026#34;: { \u0026#34;path\u0026#34;: \u0026#34;book\u0026#34;, \u0026#34;query\u0026#34;: { \u0026#34;query_string\u0026#34; : { \u0026#34;query\u0026#34; : \u0026#34;Solr\u0026#34;, \u0026#34;fields\u0026#34; : [\u0026#34;book.title\u0026#34;, \u0026#34;book.contents\u0026#34;] } } } }, \u0026#34;highlight\u0026#34;: { \u0026#34;pre_tags\u0026#34;: [\u0026#34;\u0026lt;b\u0026gt;\u0026#34;], \u0026#34;post_tags\u0026#34;: [\u0026#34;\u0026lt;/b\u0026gt;\u0026#34;], \u0026#34;fields\u0026#34;: { \u0026#34;*\u0026#34;: {} } } } 結果はこちら。 ハイライトがありません。\n{ \u0026#34;took\u0026#34;: 3, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 5, \u0026#34;successful\u0026#34;: 5, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;max_score\u0026#34;: 0.5, \u0026#34;hits\u0026#34;: [ { \u0026#34;_index\u0026#34;: \u0026#34;bookstore\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;_score\u0026#34;: 0.5, \u0026#34;_source\u0026#34;: { \u0026#34;book\u0026#34;: { \u0026#34;title\u0026#34;: \u0026#34;Apache Solr入門\u0026#34;, \u0026#34;contents\u0026#34;: \u0026#34;Apache Solrについて日本語で書かれた唯一の書籍です。SolrはLuceneをコアにした検索サーバです。\u0026#34; } } } ] } } 次に、ハイライトが帰ってくるパターン。 nestedクエリではなく、_allを対象としたクエリを投げます。\n{ \u0026#34;_source\u0026#34; : [\u0026#34;book.title\u0026#34;,\u0026#34;book.contents\u0026#34;], \u0026#34;fields\u0026#34;: [ \u0026#34;book.title\u0026#34;, \u0026#34;book.contents\u0026#34; ], \u0026#34;query\u0026#34;: { \u0026#34;query_string\u0026#34; : { \u0026#34;query\u0026#34; : \u0026#34;Solr\u0026#34;, \u0026#34;fields\u0026#34;: [ \u0026#34;_all\u0026#34; ] } }, \u0026#34;highlight\u0026#34;: { \u0026#34;pre_tags\u0026#34;: [\u0026#34;\u0026lt;b\u0026gt;\u0026#34;], \u0026#34;post_tags\u0026#34;: [\u0026#34;\u0026lt;/b\u0026gt;\u0026#34;], \u0026#34;fields\u0026#34;: { \u0026#34;book.title\u0026#34; : {}, \u0026#34;book.contents\u0026#34;: {} } } } この場合の結果は次の通り。\n{ \u0026#34;took\u0026#34;: 2, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 5, \u0026#34;successful\u0026#34;: 5, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;max_score\u0026#34;: 0.27063292, \u0026#34;hits\u0026#34;: [ { \u0026#34;_index\u0026#34;: \u0026#34;bookstore\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;_score\u0026#34;: 0.27063292, \u0026#34;_source\u0026#34;: { \u0026#34;book\u0026#34;: { \u0026#34;title\u0026#34;: \u0026#34;Apache Solr入門\u0026#34;, \u0026#34;contents\u0026#34;: \u0026#34;Apache Solrについて日本語で書かれた唯一の書籍です。SolrはLuceneをコアにした検索サーバです。\u0026#34; } }, \u0026#34;highlight\u0026#34;: { \u0026#34;book.title\u0026#34;: [ \u0026#34;Apache \u0026lt;b\u0026gt;Solr\u0026lt;/b\u0026gt;入門\u0026#34; ] } } ] } } ハイライトが返ってきています。\n考察(原因は未特定) 残念ながら、まだ調査してません。 まずは、現象が理解できたというだけです。 問題点が実は2つありそうです。\n問題点1:nestedクエリの場合に、ハイライトされない。 nestedクエリではハイライトが動作していないようです。 想像ですが、検索に利用されたクエリで指定されているフィールドをハイライタ(ハイライトを実行するモジュール)が認識できてないのではないかと。 なぜ認識できていないのかという点を調査する必要がありそうです。\n考察(試してみたパターン) nestedではないクエリで、ハイライトが動作しているのですが、 \u0026quot;book.title\u0026quot; : {\u0026quot;require_field_match\u0026quot; : true},にした場合は、ハイライトが返ってこないです。 このオプションは、検索対象のフィールドでマッチした文字列だけがハイライトされるオプションになります。 したがって、book.titleフィールドに対する検索でSolrという文字を検索していないことになります。 _allに対するクエリであるためです。 このため、例えば、titleだけを検索対象にしたのに、contentsにSolrという文字が入っていてもハイライトされてしまうという状況が発生します。\n問題点2 store : yesのデータがハイライトできない。 GithubにIssueをあげました。https://github.com/elasticsearch/elasticsearch/issues/5245 (2014/02/25追記)\nnestedオブジェクトにあるデータのうち、store : noのものだけがハイライト結果として返ってきました。\n考察 なぜ、store : yesのデータがハイライトされないかを調べるために、fieldsパラメータをリクエストに追加してみました。\n{ \u0026#34;_source\u0026#34; : [\u0026#34;book.title\u0026#34;,\u0026#34;book.contents\u0026#34;], \u0026#34;fields\u0026#34;: [ \u0026#34;book.title\u0026#34;, \u0026#34;book.contents\u0026#34; ], ... } すると、fieldsの戻り値は次のとおりです。\n... \u0026#34;fields\u0026#34;: { \u0026#34;book.title\u0026#34;: [ \u0026#34;Apache Solr入門\u0026#34; ] }, ... このことから、store : noのデータの場合、_sourceから値を取得して返却しているというのがわかります。 ハイライトがされない原因も、fieldsで値が取れていないのも同じ原因であると思われます。 なぜなら、ハイライトは、保存された文字列を内部で取り出し利用して、ハイライトタグを埋め込むという動作をするためです。\n参考? これらの問題点についてですが、次のIssueが関係あるかもしれません。\nReturn matching nested inner objects per hit #3022\n今後? 残念ながら、現時点では、問題点がどんなものかというのを理解しただけとなります。 デバッグしたりソースを追っかけたりして何が問題なのかを調べて行ってみようかなぁと。\nなにか、気づいたことなどあればコメントしてもらえると助かります。\n","date":1393231920,"dir":"post/2014/","id":"f55d33371dcff207fd7d201128df2ea3","lang":"ja","lastmod":1393231920,"permalink":"https://blog.johtani.info/blog/2014/02/24/strange-behavior-of-field-in-nested-obj/","publishdate":"2014-02-24T17:52:00+09:00","summary":"今年初の「突撃!隣のElasticsearch」ということで、Wantedlyさんにおじゃましました。 ※写真を自分でも撮ったのですが、画像が","tags":["elasticsearch"],"title":"Nested Objectのフィールドの奇妙な動作"},{"contents":"今回はたまたま日本にいたElasticsearchの人をスペシャルゲストに呼べたので、大満足ですw 英語の通訳とかちゃんと勉強しないとなぁ。。。\nとりあえず、てきとーなメモですが、残しておきます。 参加者数は130人+スタッフ+リクルートテクノロジーズ社内の人。という感じでした。アンケート集計はもう少々おまちを。\nスライドがそろったら、また、更新すると思いますが、第一報という感じで公開しておきます。 懇親会にも50名も参加していただけて、非常に楽しかったです。 話ができてない方が多数いるかもしれませんが、次回以降、声をかけていただければと。 (物覚え悪いんで、あれですが。。。) 盛り上がってきてて楽しいなぁ。 スタッフの人達の練度も上がってきてるので、すごく楽ができてます。\n至らない点とかあれば、こちらにコメントしてもらったりしていただければと。\nGeohashing with Elasticsearch Florian Schilling, Elasticsearch Inc, スライド:https://speakerdeck.com/chilling/tokyo-es-study-session-iii-geohashes\n自己紹介 Geoのスタッフ Elsticsearchの概要 転置イデックスやREST APIなどの説明 マイクの調子が良くなくて申し訳なかったっす。。。 平賀さん、通訳ありがとう! Solr本もよろしくお願いします!!\nAWSで構築するsharding 株式会社イプロス 外山 寛さん @toyama0919 スライド:http://toyama0919.bitbucket.org/elasticsearch.html\nAWS対応の話 ルーティングが重要だよ。(宣伝ありがとうございますw) type指定しないとルーティングできない。(内部でtypeも使ってハッシュ値取ってたかなぁ?) 苦労話とかいくつか。 tireはre-tire\u0026hellip; 実サービスでのElasticsearch設定・使用例(仮) 株式会社じげん 多田 雅斗さん @tady_jp スライド:https://speakerdeck.com/tadyjp/tesutoqu-dong-jian-suo-falsesusume-at-tady-jp\n検索とは的な話がわかりやすい。 全文検索のお話。ログ検索じゃないよと。 書籍ないですよねー(ふふふ) specで検索条件記述しといて、ってのいいですよね。絶対必要だと思う Mapping変更した時にテストやり直す方法とかどうしてますか? 特にフレームワークは使ってないです。\nMySQLユーザ視点での、小さく始めるElasticsearch 株式会社リブセンス 吉田 健太郎さん @yoshi_ken スライド:http://www.slideshare.net/y-ken/introducing-elasticsearch-for-mysql-users\nやっぱりkuromoji便利だよね MySQLとかと連携したい。 river-pluginもいまいち安定しない なので、Yamabiko作ってみました。 Geo検索とKuromojiの話をしてくれました。(作者とか開発者がいるってのを狙ってたのかすごいなぁ。) Mappingとかはちゃんと指定したほうがいろいろいいですよ。 nodeJS+DynamoDB+Elasticsearchで全社基盤を作った話 株式会社リクルートテクノロジーズ 相野谷 直樹さん @naokiainoya スライド:http://www.slideshare.net/recruitcojp/elasticsearchnodejsdynamodb-7\nちょっと変わった使い方のElasticsearchで面白いです。 Scroll/Scanについては、Solrでもない機能なので、そういう意味でもElasticsearchなのかもしれないですね。 参加していただいた方々のブログ 第3回elasticsearch勉強会 [2014/02/07(Fri.)]に参加してきました - ほわいとぼーど\nhttp://a3no.hatenablog.com/entry/2014/02/09/022405\n第 3 回 elasticsearch 勉強会に行ってきた - ようへいの日々精進\nhttp://inokara.hateblo.jp/entry/2014/02/07/233057\nhttp://www.smokeymonkey.net/2014/02/3elasticsearch.html\n第3回elasticsearch勉強会でトークしました #elasticsearchjp\nhttp://y-ken.hatenablog.com/entry/elasticsearch-meetup-vol3\n第3回elasticsearch勉強会にいってきました #elasticsearchjp\nhttp://blog.livedoor.jp/ashibuya0128/archives/52058766.html\n","date":1391787720,"dir":"post/2014/","id":"229b7fc784707b1d2c702fbeba080e86","lang":"ja","lastmod":1391787720,"permalink":"https://blog.johtani.info/blog/2014/02/08/hold-3rd-elasticsaerch-meetup-in-tokyo/","publishdate":"2014-02-08T00:42:00+09:00","summary":"今回はたまたま日本にいたElasticsearchの人をスペシャルゲストに呼べたので、大満足ですw 英語の通訳とかちゃんと勉強しないとなぁ。。","tags":["elasticsearch","勉強会"],"title":"第3回elasticsearch勉強会を開催しました! #elasticsearchjp"},{"contents":"すずけんさんがVagrant+puppet使って、VM起動してElasticsearchのクラスタを組んでる記事を書いているのを見て、試してみたくなりました。 ということで、VagrantとかPuppetなに?くらいの私ですが、クラスタを起動するところまで行ったので、その時のメモを残しておきます。\n元記事とか参考 Vagrant環境にpuppet moduleを利用してさくっとelasticsearchをインストールする Vagrant環境にpuppetを利用してさくっとelasticsearchのclusterを作成する puppet-elasticsearch なんとなくの理解 VagrantやPuppetについては、何度か勉強会で話を聞いてはいたのですが、 想像していたレベルだったので良い機会でした。 今のところの認識はこんな感じです。\nVagrant VMを起動したり、VM周りの設定をあれこれできるツール。 VMのネットワーク設定や、インスタンス名?などを指定できる。\nPuppet 起動後のVM(VMとは限らないか。)のゲストOS側の設定周りやアプリのインストールなどを 実行できるツール。\n詰まった箇所 すずけんさんのブログを元に作業をしましたが、自分がVagrantやPuppetに疎いため、以下の部分で躓いたので、備忘録のために残しておきました。\nその1:Puppetのファイルの場所 search01.vm.localのVMを設定(というか、elasticsearchのインストール?)するときに、manifests/search.appとroles/search/manifests/init.ppファイルが必要で作成します。\nこのファイルの配置場所は/vagrant配下に作成する必要がありました。 ssh search01.vm.localでVMにログインした場合は/home/vagrantにログインしており、この場所でファイルを作ってもPuppetがエラーを吐いたためです。\nと思ったのですが、あれ?これひょっとしてVagrantfileがあるところにディレクトリとファイル作ると勝手にVMにコピーしてくれるんですか?destroyして、upしたら、ファイルが勝手にコピーされてる。ひょっとして、/vagrantってディレクトリはVagrantfileがあるディレクトリを共有してたりするのかな?そのうち、Vagrantについても調べてみようかな。\nその2:ネットワーク周り curl http://192.168.10.114:9200/ をホストOSから実行してみましたがうまく行きませんでした。。。 ネットワーク周りの設定だと思うんですが。 少なくとも「sshによるログイン」「ping」コマンドの応答は返ってきてます。\nまた、VM内でcurlコマンドを実行したらレスポンスが返ってきました。\nなんで?ってツイートしたら各所から「iptables」という単語が飛んできて、 service止めたら大正解でした。まぁ、そうですよね。基本ですよね。。。\nということで、Puppetがよくわかっていませんが、ググって変更してみました。\nmanifests/search.appに以下を追加\ninclude iptables roles/iptables/manifests/init.pp\nclass iptables { service { \u0026#39;iptables\u0026#39;: enable =\u0026gt; false, ensure =\u0026gt; stopped, } } iptablesを停止するmanifests?です(良くないことなんですが、よくわかってない)。\nということで、ローカルで1個のVM起動して、elasticsearchにアクセスできることは確認できました。\nと、書いてるそばから、元記事が修正されてしまいましたw\nクラスタ編(変更点) クラスタを組むときに、追加でプラグインを入れたのでroles/search/manifests/init.ppは次のようにしました。\nclass search { class { \u0026#39;elasticsearch\u0026#39;: package_url =\u0026gt; \u0026#39;https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.0.0.RC2.noarch.rpm\u0026#39;, java_install =\u0026gt; true, config =\u0026gt; { \u0026#39;cluster\u0026#39; =\u0026gt; { \u0026#39;name\u0026#39; =\u0026gt; \u0026#39;test-es-cluster\u0026#39; }, \u0026#39;network.host\u0026#39; =\u0026gt; \u0026#39;_eth1:ipv4_\u0026#39;,, \u0026#39;marvel.agent.exporter.es.hosts\u0026#39; =\u0026gt; [\u0026#39;192.168.10.114:9200\u0026#39;,\u0026#39;192.168.10.115:9200\u0026#39;] } } elasticsearch::plugin{\u0026#39;elasticsearch/marvel/latest\u0026#39;: module_dir =\u0026gt; \u0026#39;marvel\u0026#39; } elasticsearch::plugin{\u0026#39;mobz/elasticsearch-head\u0026#39;: module_dir =\u0026gt; \u0026#39;head\u0026#39; } elasticsearch::plugin{\u0026#39;royrusso/elasticsearch-HQ\u0026#39;: module_dir =\u0026gt; \u0026#39;HQ\u0026#39; } elasticsearch::plugin{\u0026#39;elasticsearch/elasticsearch-analysis-kuromoji/2.0.0.RC1\u0026#39;: module_dir =\u0026gt; \u0026#39;analysis-kuromoji\u0026#39; } elasticsearch::plugin{\u0026#39;info.johtani/elasticsearch-extended-analyze/1.0.0.RC1\u0026#39;: module_dir =\u0026gt; \u0026#39;extended-analyze\u0026#39; } elasticsearch::plugin{\u0026#39;polyfractal/elasticsearch-inquisitor\u0026#39;: module_dir =\u0026gt; \u0026#39;inquisitor\u0026#39; } } とりあえず、今日はクラスタ組んでMarvelやプラグインの動作確認でおしまいです。\n疑問点 いくつか疑問点が。試してみてもないんでなんとも言えませんが。気が向いたら、調べて追記するかも。\n:private_networkはVirtualBox内で完結する(Macから外には影響しない)ネットワークが構築される?たぶん、VagrantというよりはVM、仮想化周りの知識なんだろうけど どこから再開可能?elasticsearch.ymlの設定を書き換えた場合に、最後のコマンドだけ実行するとちゃんとやりなしてくれたりするのかな? VMのディスク増やすのもVagrantでできるんかな?まぁ、できると思うけど。 :forwarded_portのauto_correctとかわかってない。 JVMをSunのJVMでかつ、7u25に変更したいのだがどうしたものか?(現時点での推奨バージョン) 感想 Vagrantって便利ですね。あれ?って思ったら、destroyして、やり直すのがすごく簡単です。 元記事があるので、なんとなくですが、構成とかどうすればいいかがわかるのは本当に助かりました。 これで、あれこれと検証する環境が簡単に構築できることがわかったので、色々と楽できるかも。ありがとうございます、すずけんさん!\n","date":1391695740,"dir":"post/2014/","id":"c98cbc333fb7d95c6c9fc4924b0526e1","lang":"ja","lastmod":1391695740,"permalink":"https://blog.johtani.info/blog/2014/02/06/es-cluster-start-using-vagrant-and-puppet/","publishdate":"2014-02-06T23:09:00+09:00","summary":"すずけんさんがVagrant+puppet使って、VM起動してElasticsearchのクラスタを組んでる記事を書いているのを見て、試して","tags":["elasticsearch","vagrant","puppet","marvel"],"title":"すずけんさんのメモを元にVagrantでElasticsearchクラスタを起動してみた"},{"contents":"改訂新版Solr入門出版記念ということで、第13回Solr勉強会 #SolrJP 新Solr本出版記念を開催しました。\n出版記念なので、技術評論社様より、プレゼント用にSolr本を用意していただきました!ありがとうございます!! 書籍をゲット出来た方は、ツイートしたりブログ書いたり書評書いたりして、宣伝してください!!!\n今回は、私は手を抜いて他の人に喋ってもらいました!\n今回は、著者陣(関口さんは特別ゲスト)でスピーカーを固めてみました。 以下は、いつもの簡単なメモです。 スライドが集まったらまた更新していきます。\n1. 「はじめての検索エンジン&Solr」 株式会社NTTデータCCS 鈴木 教嗣さん スライド:はじめての検索エンジン&Solr 第13回Solr勉強会\n鈴木さんの発表初めて聞きましたw。 趣味が多いなぁ。 ちょこちょこと、宣伝を入れてるのが流石ですw\n入門らしい概要 クエリの概要とかも。 スコア計算とか 導入するとうれしいところとか Solr盛り上げましょう! 2. 「Solr SearchComponent 再訪」 株式会社ロンウイット 関口 宏司さん スライド:公開待ち\nベン図で検索の評価指標の説明 理論的なお話 Solrのサーチコンポーネントを使って何ができるか。ベン図で。 サーチコンポーネント以外にも NGramTokenizerも SynonymFilterも パーソナライズ検索 いきなり話をふられたのでちょっとびっくりしましたw\n3. 「自動補完(Autocomplete)ともしかして?(Did You Mean?)」 株式会社 ロンウイット 大須賀 稔さん スライド:Solr AutoComplete and Did You Mean?\nデモ:https://github.com/mosuka/solr-suggester-demo-ui\n職歴が相変わらずおもしろい 編集距離のお話 素晴らしいCM! 候補のランキングを変更できる? SpellcheckComponentのパラメータで指定できるものなら楽ですが。。。\n4. 「Lucene Revolution 2013 Dublin振り返り」 楽天株式会社 平賀 一昭さん スライド:公開待ち\nダブリンどこ?(間違ってベルリンって言っちゃいましたw) スタジアムで開催。グランドにも入れるのかなぁ? まずはTwitter Luceneの改良版 ちょっと特殊。140文字とか 青いRさんのライバル。Careerbuilder 元FASTユーザ 企業向けに検索キーワードとかの解析画面を用意 検索精度の改良の話とか 転職で引っ越す意思があるかとか。 最後はLinkedIn Luceneのユーザ まとめ ということで、スピーカーの方々のスライドにもありましたが、 改訂新版Apache Solr入門は良い本なので、購入していただけると嬉しいです。\n感想、コメントなど、いつでもお待ちしています!\n","date":1390988760,"dir":"post/2014/","id":"c6107ff57e96a1373c019d252c00ad84","lang":"ja","lastmod":1390988760,"permalink":"https://blog.johtani.info/blog/2014/01/29/hold-to-japan-solr-meetup/","publishdate":"2014-01-29T18:46:00+09:00","summary":"改訂新版Solr入門出版記念ということで、第13回Solr勉強会 #SolrJP 新Solr本出版記念を開催しました。 出版記念なので、技術評論社様より、プレ","tags":["Solr","勉強会"],"title":"第13回Solr勉強会を開催しました"},{"contents":"昨晩、Elasticsearchから初のプロダクトとなるMarvelがリリースされました。ということで、さっそく触ってみて、簡単な紹介と感想を書いてみました。\nMarvelって? Elasticsearch社が初のプロダクトとしてリリースした、Elasticsearchクラスタモニタリングツールです。 次のような特徴があります。\nplugin形式で提供 GUIがKibana メトリックスはElasticsearchに保存 SenseがChrome以外でも使える プロダクション環境で利用する場合は有料ですが、開発用途では無料で利用できます。 現時点(2014/01/29)では、0.90.9以上のバージョン(1.0.0.RC1含む)で利用が可能です。\nなにができるの? Elasticsearchクラスタに関するメトリックスを保存、可視化できるプロダクトです。 ドキュメント数やJVMの状況、クラスタの状態など、いろいろなメトリックスが保存されます。\n保存先は、別のElasticsearchクラスタにすることも可能です。 お試しでインストールして見る場合は、同一クラスタにサービスに利用するインデックスとMarvel用のメトリックス保存先インデックスを入れても良いです。\nただ、プロダクション環境では、Marvel用インデックスはあくまでもモニタリングに使用するため、サービスのクラスタへの影響を最小にしたくなります。\nこのような場合、Marvelのプラグインの設定を変更することで、メトリックス送信用のエージェントとして動作させることができます。\n詳しくは、Marvelのドキュメントにあるinstalling a secondary monitoring clusterを御覧ください。\n1/29 16時時点で、上記ドキュメントのエージェントの送信先の設定に関する部分に誤記がありました。 おそらく、configuration optionsの記述が正だと思います。 もう、なおってました。(1/30朝時点)\nキャプチャいろいろ 日本語WikipediaのデータをRiverで登録しながら各画面の動作などを見てみました。\nMarvel Overview 日本語WikipediaをRiverで登録してる途中。Loadが高くなってることなどがわかります。\nOverview (クラスタの状態が変化) クラスタの状態が変化したところに、タグが付くみたいです。 ここでは、ノードの一つを停止、起動しました。\nインデックス終了後に、クラスタを再起動してしまい、クラスタ内のシャードの再配置が実行されてしまったため、クラスタの状態がYellowになってしまうとこんな感じ。ちょっとわかりにくいです。\nSense Chromeプラグインとしてリリースされていたクエリ実行コンソールがMarvelのサイトプラグインとして提供されています。これがあるだけで、Elasticsearchへのクエリの実行が格段に効率良くなります。\nIndex Statistics インデックスに関する情報のグラフが見れるページです。ドキュメント数の他に、容量やリクエスト数なども見れます。\nインデックス終了後のグラフはこんな感じ。\nインデックス終了後のOverviewはこんなかんじです。\nCluster Pulse クラスタで発生したイベントとイベントの詳細を見ることができるページです。各種インデックスがYELLOWからGREENに変わっていっているのがmessageで分かります。\nすべて再配置が終わったらGREENになりました。\nNode Statistics 各ノードに関する情報を見ることができる画面です。 ノードごとにグラフの色を分けることもできます。\nその他 Marvelプラグインにブラウザから接続できなくなるとこんなメッセージが出ました。\n参考までに、elasticsearch-headの画面も。こちらのほうが、シャードの再配置中であるのがひと目で分かります。\n感想 綺麗です。まぁ、Kibanaが綺麗ですから。 クラスタ内で発生したイベントが時系列で保存されるため、あとからどんなことが発生したのかといった原因の追求などには非常に役に立ちそうです。\nただ、インデックスの状態や状況(クラスタ再起動やノード追加時にshard再配置などが実行されている状況とか)はelasticsearch-headのほうがわかりやすかったです。 インデックス単位でのStatusがMarvelの画面ではわからないため、shard再配置が完了したかどうかなどのタイミングがわかりにくかったです。\nある程度、多くのノードを利用したクラスタを利用する場合に、モニタリングツールとして利用するのは便利なのではないでしょうか? 時系列でログやイベントが保存されるので、ノードが追加されたり外れたりといった状況があとからでも追跡可能なのが便利です。\n疑問点 インデックスの情報などは、5s毎にMarvelのインデックスに保存されているようです。ただ、GUI上では5分毎のデータしか表示されません。 どうやって変更するんだろう?\nまた、Marvelのクラスタへの接続が切れた時のデータはどうなるのか?という部分も気になります。Marvelのクラスタを更新している時や、ネットワークが遮断されてしまった場合のデータがどうなるのかという点です。\n疑問点への回答(2014/01/30追記) 疑問点に対して中の人から回答を頂いたので、追記です。\nQ:GUI上で5分毎のデータしか表示されないんですが? A:ブラウザの負荷を高くしないようにするために、1つのグラフに20のプロットしてるだけです。ズームしたりすると、もっと細かなデータが見れますよ。 Q:Marvelのクラスタへの接続が切れた時のデータはどうなるんだろう? A:接続が切れた場合は、ローカルに保存されるけどデータは無視されます。接続が戻ると、戻った後のデータは記録されていきます。将来的には改善するかも。 ちなみに、昨日試してた環境が、足元Linux環境(監視対象のクラスタ)+手元Mac環境(Marvelモニタリングデータ格納クラスタ)という環境でした。 確かに、出社してから、手元Mac環境を起動すると、データが流れてくるようになりました。 ただ、監視対象のクラスタでは、socket timeoutのログがずっと出てましたが。\n参考文献 リリースブログ プロダクトページ ドキュメント ","date":1390983240,"dir":"post/2014/","id":"f6debed350f20a2b3aa4d970e3227411","lang":"ja","lastmod":1390983240,"permalink":"https://blog.johtani.info/blog/2014/01/29/simple-introduction-and-first-impression-es-marvel/","publishdate":"2014-01-29T17:14:00+09:00","summary":"昨晩、Elasticsearchから初のプロダクトとなるMarvelがリリースされました。ということで、さっそく触ってみて、簡単な紹介と感想","tags":["elasticsearch","marvel"],"title":"Elasticsearch Marvelの紹介と第一印象"},{"contents":"Lucene/Solr 4.6.1がリリースされそう(バイナリ配布待ち)lucene-gosenの4.6.1対応版をリリースしました。\nライブラリのインタフェースなどは特に変更はないのですが、ライブラリのダウンロード先が変更になっているため、注意喚起です。\nGoogle Project Hostingの仕様変更により、Downloadsに新規ファイルがアップロードできなくなっています。(2014年から)\nこのため、プロジェクトの選択肢としては以下の3点となっています。\nGoogle Driveにファイルをアップロードしてダウンロードしてもらう 他のソースコード管理サイトなどを利用する。 他のダウンロードサイトを利用する 1.と3.は場所が違うだけで、方法は一緒です。 今回は、暫定的に1.を利用してダウンロードするように対応しました。\nダウンロード先はプロジェクトのページにリンクが有りますが、わかりにくいのでキャプチャを撮ってみました。\nダウンロード先 これまでのFeatured - Downloadsとは異なり、Links - External linksの下に Downloads lucene-gosen 4.6.1というリンクを用意してあります。\nフォルダとなっており、各種jarファイルがリストされていますので、こちらからダウンロードをお願いします。 今後は、この下にダウンロードリンクを追加していく予定です。\nただし、2.で述べたように「別のソースコード管理サイト」も検討中です。\n","date":1390880040,"dir":"post/2014/","id":"c4e7199a586a308352b7a881add7e356","lang":"ja","lastmod":1390880040,"permalink":"https://blog.johtani.info/blog/2014/01/28/release-lucene-gosen-4-dot-6-1/","publishdate":"2014-01-28T12:34:00+09:00","summary":"Lucene/Solr 4.6.1がリリースされそう(バイナリ配布待ち)lucene-gosenの4.6.1対応版をリリースしました。 ライブラリのインタフェースな","tags":["Solr","Lucene","lucene-gosen"],"title":"lucene-gosen 4.6.1のリリースに関する注意点"},{"contents":"Elasticsearchのcuratorのブログ記事を読んで、日本語でツイートしたところ、Aaron Mildensteinさんから日本語(ローマ字)で返信を頂きました。 せっかくなので、ブログ記事を翻訳してもいいかを尋ねたところ、快くOKを頂いたので、翻訳してみました。参考になればと。(誤訳など見つけたらコメントください。)\n@johtani Kore no hou ga ii. Nihongo de no Curator RT, arigatou gozaimasu! #elasticsearch #curator #logstash\n\u0026mdash; Aaron Mildenstein (@theuntergeek) 2014, 1月 22 curator: 時系列インデックスの管理 原文:curator: tending your time-series indices\n背景 数年前、Elasticsearch、Logstash、Kibana(ELK)を管理し、ここ30日よりも古いインデックスを自動的に削除する方法を必要としていました。 APIドキュメントを読み、#logstashや#elasticsearchのIRCチャネルのコミュニティの助けを借りて、簡単なスクリプトとcronを用意するのが簡単であることを知りました。\ncurl -XDELETE \u0026#39;localhost:9200/logstash-2014.01.01?pretty\u0026#39; もちろん、これも動作しますが、日付を生成するのがめんどくさいのでもっとエレガントな方法が欲しかったです。\n最初に pythonでスクリプトを書き始めました。特定の日数のインデックスを管理するだけのコマンドラインクリーナーを書いてコミュニティにシェアしました。他の人が、新しい機能を追加してくれました。私は、古いインデックスをoptimizeすることができる他のスクリプトも書きました。これは、シャードごとにnセグメント以上存在しないように各シャードのセグメントをマージすることです。これらのスクリプトで1つになるようにマージしたりエンハンスし、古いインデックスを管理する助けになるツールです。\ncuratorの紹介 Curatorで可能なインデックスオペレーション\n削除(日付もしくは、トータル容量による制限) インデックスのクローズ(Close) bloom filter cacheの無効化 Optimize(LuceneのforceMerge) curatorのインストール この記事を書いている時点で、Curator は0.5.1がリリースされ、0.90.10に対応しています。Curatorはまた、Elasticsearchの1.0(現在はRC1)へも対応しています。各リリースへの互換性の保証のためのテストも行っています。\n現時点では、gitリポジトリで配布しています。近い将来、pipによるインストール可能なパッケージにする予定です。利用することを恐れないでください。もし、pythonとpipがあなたのマシンにインストールされていれば、次のようにインストールは簡単です。\ngit clone https://github.com/elasticsearch/curator.git pip install -r requirements.txt インストール後の確認は次のコマンドです。\n$ ./curator.py -v curator.py 0.5.1 利用方法とサンプル サンプルを示す前に、オプションを見ておくとよいでしょう。このリストは長いですが(この記事の最後に含まれています)、どのようなことがコントロールできるかを説明しています。デフォルトがどうなっているかに注意してください。もし、デフォルト値で良い場合は、フラグを指定する必要はありません。\nでは、簡単なサンプルを見ながら、CuratorがELKスタックをどうやって管理するかを見て行きましょう。\n削除(delete) 90日以上のインデックスを保存したくないとしましょう。コマンドは次のようになります。\n$ curator.py --host my-elasticsearch -d 90 -dで日数を指定しているだけです。簡単でしょ?\n容量による削除(delete by space) これは、指定したギガバイト数を超えたインデックスを場合に(最も古いものから)削除を行う特殊なケースです。\n$ curator.py --host my-elasticsearch -C space -g 10024 -Cでspaceによるcurationであること、-gでギガバイト数(10024、10TB)であることを指定しているのがわかります。-gは1.5や0.5という数値を指定できます。\nその他のCuratorオプションはspaceによる削除と組み合わせて使用できないことに注意してください。\nクローズ(close) Open/Close Index APIにより、インデックスをクローズすることができます。\nopen/close index APIを利用すると、インデックスをクローズしたり、あとでオープンしたりすることができます。クローズされたインデックスはクラスタのオーバヘッドにほとんどならず(メタデータの管理を除く)、読み書き操作の妨げにもなりません。クローズされたインデックスは、リカバリプロセス時に、オープンされます。\nインデックスをクローズすることは、存在はするが検索できないという意味です。何が便利なのでしょう?\n90日のインデックスを保存する義務があるが、検索は過去30日のインデックスを対象にする以外は稀であるような場合を想像してください。このような状況で、価値のあるリソース(ヒープスペースなど)を節約するためにインデックスをクローズすることができます。これは、クラスタに検索やインデキシングのためのメモリを与えることができることを意味します。そして、もし、クローズしたインデックスのデータが必要になったら、APIを呼び出してインデックスをオープンすれば検索できます。\nこのような場合、今オープンしているインデックスが再び、クローズされないように、一時的にCuratorのスケジュール実行をオフにしておくのが懸命です。\n$ curator.py --host my-elasticsearch -c 30 -d 90 先ほど説明した例の実行方法です。これは、30日よりも古いインデックスはクローズし、90日より古いインデックスを削除します。本当に簡単でしょ?\nbloom filterの無効化 これは、0.90.9以降のバージョンで利用可能な機能です。(リンク先はIssue #4525)\n心配しないでください。このスクリプトは操作を行う前に、elasticsearchが利用可能なバージョンであるかをチェックします。\nbloom filterとは何でしょう?なぜ、無効化したくなるのでしょう?\nbloom filterはインデキシング操作を高速化するためにリソースを割り当てられます。時系列データで、インデキシングしている間もこれは有用です。インデックスは2日後には、日付が変わると新しいデータはおそらくインデックスされません。そのインデックスにはもはや必要のないリソースをbloom filterはまだ持っています。Curatorはこれらのリソースを開放することができます!\n$ curator.py --host my-elasticsearch -b 2 -c 30 -d 90 これで、bloom filterのリソースは少なくとも2日(1にもできます)よりも古いインデックスについては利用せず、30日より古いインデックスはクローズし、90より古いインデックスは削除します。\noptimizeというよりもforcemerge コマンドの説明をする前に、Elasticsearch APIのoptimizeを見ることは、生きているインデックスや\u0026quot;cold\u0026quot;インデックス(インデキシングがアクティブではないという意味)に実行する必要があるということを理解するために重要です。実際、optimizeはLuceneではforceMergeと名前が変えられ、インデックスを改善するためにoptimizeを呼び出す必要はなくなりました。Elasticsearchのセグメントをマージすることは利点がありますが、coldインデックス全てに対してoptimizeを開始する前に、コストを理解する必要があります。\nforceMerge操作はインデックスにある各シャードのセグメントの数を少なくします。各セグメントはオーバヘッドがあるため、セグメントが多いということは、より多くのリソースを使うという意味です。良さそうですね?リソースが少ない?\nそれは、可能ですが、merge操作を実行するには多くのディスクやネットワークI/Oが必要で、ディスクやクラスタの通常の書き込み操作に悪影響を及ぼします。もし、これが必要なら私のアドバイスを良く考えてください。(数%ほど)検索を速くし、リソースの使用量も減らすことができます。また、管理しているセグメント数が小さくなるということは、クラスタのリカバリを速くすることにもなります。1つのインデックスをoptimizeするためにはおそらく1時間以上の時間がかかります。「使用する前に目立たない場所で試してください」というクリーニングボトル(訳注:洗剤とか漂白剤かな?)の注意書きと同様に、ディスクI/Oが低い時にテストし、もし操作とリソースがあなたのクラスタのユースケースにあっているかを見てください。デフォルトでは、シャードごとに2つのセグメントにマージしますが、--max_num_segmentsフラグで変更可能です。\nここまでのサンプルは次のようなコマンドになります。\n$ curator.py --host my-elasticsearch -b 2 -o 2 -c 30 -d 90 これで、bloom filterは2日より古いインデックスでは向こうにし、2日より古いインデックスは\u0026quot;optimize\u0026quot;し、30日より古いインデックスはクローズし、90日より古いインデックスは削除されます。\n操作の順序 スクリプトは操作が衝突するのを防ぐために次の順序で実行されます。なぜ、クローズされたインデックスはoptimizeしないのでしょう?なぜ、削除予定のインデックスはクローズされないのでしょう?\nDelete (by space or time) Close Disable bloom filters Optimize 使用の検討 最後の例で、3つの操作を1つのコマンドで実行していますが、それらが連続ですべて実行されるのを望んでいないかもしれません。\n$ curator.py --host my-elasticsearch -b 2 -o 2 -c 30 -d 90 これは、次の操作と同様です。\n$ curator.py --host my-elasticsearch -d 90 $ curator.py --host my-elasticsearch -c 30 $ curator.py --host my-elasticsearch -b 2 $ curator.py --host my-elasticsearch -o 2 これらのコマンドを異なる時間に実行したり、異なるその他のオプション(特に、optimize実行で--timeout 3600を追加したり)を指定して実行するのは簡単です。\nまた、デフォルトのlogstash-とは異なるプレフィックスのインデックスを持っているかもしれません。\n$ curator.py --host my-elasticsearch --prefix logstash- -d 30 $ curator.py --host my-elasticsearch --prefix othername- -d 30 最後に Curatorは時系列インデックスの保存ポリシーを管理するのに役立ちます。豊富な設定オプションがインデックスを管理することを簡単にします。クラスタに存在するノードの数に関係なく。https://github.com/elasticsearch/curatorへのフィードバックやコントリビューションをお待ちしています!\n参考(全引数とオプション) $ curator.py -h usage: curator.py [-h] [-v] [--host HOST] [--port PORT] [-t TIMEOUT] [-p PREFIX] [-s SEPARATOR] [-C CURATION_STYLE] [-T TIME_UNIT] [-d DELETE_OLDER] [-c CLOSE_OLDER] [-b BLOOM_OLDER] [-g DISK_SPACE] [--max_num_segments MAX_NUM_SEGMENTS] [-o OPTIMIZE] [-n] [-D] [-l LOG_FILE] Curator for Elasticsearch indices. Can delete (by space or time), close, disable bloom filters and optimize (forceMerge) your indices. optional arguments: -h, --help show this help message and exit -v, --version show program version number and exit --host HOST Elasticsearch host. Default: localhost --port PORT Elasticsearch port. Default: 9200 -t TIMEOUT, --timeout TIMEOUT Elasticsearch timeout. Default: 30 -p PREFIX, --prefix PREFIX Prefix for the indices. Indices that do not have this prefix are skipped. Default: logstash- -s SEPARATOR, --separator SEPARATOR Time unit separator. Default: . -C CURATION_STYLE, --curation-style CURATION_STYLE Curate indices by [time, space] Default: time -T TIME_UNIT, --time-unit TIME_UNIT Unit of time to reckon by: [days, hours] Default: days -d DELETE_OLDER, --delete DELETE_OLDER Delete indices older than n TIME_UNITs. -c CLOSE_OLDER, --close CLOSE_OLDER Close indices older than n TIME_UNITs. -b BLOOM_OLDER, --bloom BLOOM_OLDER Disable bloom filter for indices older than n TIME_UNITs. -g DISK_SPACE, --disk-space DISK_SPACE Delete indices beyond n GIGABYTES. --max_num_segments MAX_NUM_SEGMENTS Maximum number of segments, post-optimize. Default: 2 -o OPTIMIZE, --optimize OPTIMIZE Optimize (Lucene forceMerge) indices older than n TIME_UNITs. Must increase timeout to stay connected throughout optimize operation, recommend no less than 3600. -n, --dry-run If true, does not perform any changes to the Elasticsearch indices. -D, --debug Debug mode -l LOG_FILE, --logfile LOG_FILE log file ","date":1390542480,"dir":"post/2014/","id":"15f501351d482ffd73985a50f5c89d1f","lang":"ja","lastmod":1390542480,"permalink":"https://blog.johtani.info/blog/2014/01/24/curator-tending-your-time-series-indices-in-japanese/","publishdate":"2014-01-24T14:48:00+09:00","summary":"Elasticsearchのcuratorのブログ記事を読んで、日本語でツイートしたところ、Aaron Mildensteinさんから日本語(","tags":["elasticsearch","curator"],"title":"Curator: 時系列インデックスの管理(日本語訳)"},{"contents":"あけましておめでとうございます。今年もSolrやElasticsearchについて色々と頑張っていく所存です。 とまぁ、お決まりの挨拶はおいておいてと。(もう、新年も22日ですが。。。)\nElasticsearchの1.0.0RC1がリリースされました。 ということで、私が作っているExtended-Analyzeプラグインも1.0.0RC1向けに修正してリリースしました。\n1.0.0RC1向けに修正したこと コミットログを見てもらえば、いいのですが、ロジック自体は変更しなくても良かったです。\nただ、正式に、Elasticsearchのつづりが決定したようで、クラス名が「ElasticSearchほげほげ」から、「Elasticsearchほげほげ」と、SearchのSが小文字になりっています。 この影響で、例外クラスなどの名称を幾つか変更しました。 また、バージョン番号を1.0.0RC1とし、0.x系をElasticsearchの0.90系向けのバージョンにしていく予定です。\n今後は、UIを追加したいと思っているので、Elasticsearchのバージョン番号とはずれてくるとは思いますが。。。\nElasticsearch 1.0.0RC1を利用してみて 1点だけですが。 これまでは、-fオプションを指定すると、デーモンではない動作で起動できていました。(デフォルトがデーモン起動)\nこれが、1.0.0から(0.90の最新もかな?詳しく見ていない)デフォルトの挙動が変更され、デーモン起動ではなくなりました。 代わりに、-dオプションを指定することで、デーモン起動ができるようになりました。\nこれで、手元でうっかりデーモン起動することがなくなって、ひと安心です。(他の人は困るかもしれないけど)\nということで 1.0.0RC1が出たので、少しずつ1.0系で追加されたAPIや機能について、ブログで紹介していけたらと思います。\nこんなこと調べてよ?、これわかんないんだけど?などありましたら、コメントいただければと。 気が向いたら記事を書くので。\nあと、Extended-Analyzeプラグインの感想などもお待ちしています!\n今年もよろしくお願いします!\n","date":1390317360,"dir":"post/2014/","id":"6425af51edead39c0e439073986043fb","lang":"ja","lastmod":1390317360,"permalink":"https://blog.johtani.info/blog/2014/01/22/release-extended-plugin-for-1-0-0rc1/","publishdate":"2014-01-22T00:16:00+09:00","summary":"あけましておめでとうございます。今年もSolrやElasticsearchについて色々と頑張っていく所存です。 とまぁ、お決まりの挨拶はおいて","tags":["elasticsearch"],"title":"Extended-Analyze 1.0.0RC1をリリースしました"},{"contents":"昨年は、大晦日に書いてました。 ちょっと進歩したかも。\n振り返り(2012年に書いた抱負から) ということで、まずは昨年書いた抱負からの振り返りです。\nIntelliJ IDEAをメインに使う JIRAを継続して活用 ブログの継続 elasticsearch Luceneのソースコードリーディング 何かOSSのソースを読む Macでもっと開発 読書と英語を継続 お。思ったよりもできてるかも。 IntelliJ IDEAについては、メインになりました。Eclipseを開くことはまずないです。 Macがメインの開発マシンにもなってきてるので。(開発してないんじゃないかという話も。。。)\nJIRAは一応、継続しているという感じです。\n唯一Luceneのソースコードリーディングができてないですね。。。 言い訳をすると、明示的にソースコードリーディングをしているわけではないですが、Luceneのソース自体は時々見ています。 SolrやElasticsearchを調べるとそのままLuceneにたどり着くことがあるので。\nポモドーロのタスク管理用に使っていますが、時々忘れていたり。あと、振り返りがまだちゃんとできてないので、そこをやらないとかなぁと。 読書と英語は今後も継続です。もっと習慣づけないと。\n振り返り(今年あった出来事など) CROSSでモデレータやりました Xperia Zに機種変 メニエール病 リクルートテクノロジーズさんのお手伝い Lucene In Action輪読やってる MIR輪読も継続 Solr勉強会を不定期開催 Elasticsearch勉強会を始めた Solr本の改訂版を執筆 AWSちょっと触った Elasticsearchプラグイン作ってみた Githubの活用 Octopressでブログ こんなかんじです。\nCROSSでは、モデレータをやらせていただきました。すこしは検索を面白いと思ってもらえたかなと思います。 来年のCROSS 2014ではスタッフとして盛り上げていく予定ですので、スタッフに興味ある方は声をかけてください! 面白い話がいっぱい聞けますし、おいしい物も飲み食いできるかも!?\nXperia Zは良い買い物でした。ただ、すでに2回電源部分が故障してますが。。。 それ以外は非常に快適です。\n2月末から3月は少し休んでました。難聴→めまい→メニエール病という流れで、ちょっとしんどかったです。 ほぼ回復しましたが、原因は不明みたいなので、長く付き合ってくのかなぁと。\n4月からリクルートテクノロジーズさんの仕事を手伝っています(Solr本の著者紹介にも書いてます)。 色々と面白いことをしているATLという部署で面白い人達と仕事させて頂いてます。 来年もよろしくお願いします!(もっと価値を出さないとなぁ。。。)\nその一環で、Lucene In Actionの輪読を社内でやっていたりも。バージョンが3.x系で書かれているので、 ちょっと大変ですが、4だとどう違うかなどの話を交えつつ少しずつ読んでいます。\n輪読会といえば、MIR(Modern Information Retirieval)の輪読も続いています。 私は深いところまでわからないのですが、色々と詳しい方たちとボチボチ読んでます。教えてもらってばかりですが、来年も頑張りますよと。\nSolr勉強会も、引き継いでぼちぼちやっています。来年は1/29に開催します。Solrの入門的な話をしてもらうので、 ぜひ、触ったことがない方や興味がある人に参加していただきたいと。\nElasticsearch勉強会も主催し始めました。興味ある人がいるだろうとは思ったのですが、想像以上でびっくりしてます。 自分が理解を深め、発表するためにも、2ヶ月程度のスパンで来年も開催する予定です。 スピーカーに興味のある方は、elasticsearch-jpのMLや私にコンタクトしてください。\nSolr入門のSolr4対応版も執筆しました。今回は全体のコーディネートもやらせていただきました。 Solr活用のお役に立てていただければと。まだ購入してない方はぜひ、以下のリンクから!(PDF版もあります。) 質問などあれば、ブログにコメントをいただくか、ツイートしていただくか、技術評論社のサポートページに問い合わせていただければと思います。\nAWSをちょっとだけ触りました。 S3にバックアップ取ってるだけですが。。。来年はもう少し。。。 JIRA(さくらVPSに立ててる)のバックアップなどをやってます。\nあとは、Elasticsearchの勉強会も始めたこともあり、Elasticsearchを色々と触っています。 elasticsearch-analysis-kuromojiプラグインのREADMEを記述してコントリビュートしてみたり、 elasticsearch-extended-analysisプラグインを作ってみたり。\n勉強会のスピーカー探しも兼ねて、いろんなところに、「突撃!隣のElasticsearch」と称してElasticsearchの話を聞きに行きたいと思っていますので、使ってるよ!とか使いたいんだけど、どうすればいい?みたいな話があれば、声をかけてください。Twitterでツイート見たら勝手に、アタックすることもあるかもですが、その時はよろしくお願いします。\n来年はSolrやElaticsearchにもっと貢献できればと。\nGithub(git)もようやくまともに触り始めました。 某データの管理やプラグインの開発などでやっと触り始めました。 まだ、チーム開発ってほどではないので、チームで開発するときのやり方なども少しずつ勉強していこうかと。 プルリクとかも少しずつやってみたりしてます。\nあとは、Octopressでブログ始めました。その前はjugemだったのですが、なんとなく。 Markdownに慣れるためというのもありOctopressにしてみました。 (Solr本の原稿もMarkdownで書いてました) 昔のブログもこっちにコピーするプログラムも書いてみようかな。\n来年の抱負 Elasticsearch勉強会、Solr勉強会の継続+ミックスした検索勉強会の開催 IDEAのさらなる活用 もっと開発(プラグインとか) AWSをもう少し活用 海外のイベントに行ってみたい 読書と英語を継続 勉強会の開催は今後も継続していく予定です。会場を毎回提供して頂いているVOYAGE GROUPさん、リクルートテクノロジーズさんには、 今後もお手数をお掛けしますが、よろしくお願い致します。勉強会の開催を通じて、色々な人のノウハウがうまく共有できて、 もっと本質的な作業(サービスの改善とか)に注力できる環境ができると面白いなぁと思ってるので。\nあと、Elasticsearch、Solrと別々の勉強会になっていますが、検索エンジン勉強会という形でそれぞれのメリット・デメリットを 共有できる勉強会も面白いかもと思っているので、春とかに開催したいなぁと考えてもいます。(まだ考えているだけで何もネタがないですが)\nIDEAは、年貢(13のサブスクリプション)を収めたので、もっと活用しないとという意味で。プラグインの開発、gitやsvnのクライアントとしては 活躍していますが、もっと開発に活用していかないとなぁと。まだ、10%くらいしか活用できてない気がするので。\nもっと開発しないとなと。毎年言ってますが。今年は書籍に注力したのもあり、ソースを読んだり英語を読んだりが多くなってました。 偉そうにしてるためか、開発する機会が減ってきているので、細かなことでもいいので、すこしずつコードを書いていこうかと。 (もっと自分で問題点を見出してそれを補完するようなコードなりプラグインなり書けばいいんだろうな。)\n開発と合わせて、AWSをもう少し触りたいなと。これも数年言っていますができてないです。。。 ネタ探すのが下手なのかなぁ。\n海外イベントにも行ってみたいです。まだ、海外行ったことないんですが。。。 Lucene Revolutionとか。その訓練も兼ねて英語でメール書いたり、プラグインのREADME書いたりしてみてます。\n最後は、毎年恒例ですが、読書と英語です。 Packtのキャンペーンで買ってしまった英語の本とか貯まっているので、読まないと。 nasneが便利で通勤時間にドラマ見てるからなぁ。ま、必要なときにボチボチと読んでいく予定です。\n最後は、いつものようにですが、来年も勉強会やいろんなイベントに参加する予定です。 ブログも週1程度で書く努力しないとなぁ。 こんな話を書いてくださいとかのリクエストもお待ちしています。\n今年もまだ、大晦日が残っていますが、色々とお世話になりました。 この場を借りてお礼申し上げます。\n来年も、いろんな方に絡んでいくとは思いますが、よろしくお願いいたします。\n","date":1388406000,"dir":"post/2013/","id":"10c715f70de25ccb493bbbb532b78ced","lang":"ja","lastmod":1388406000,"permalink":"https://blog.johtani.info/blog/2013/12/30/looking-back-2013/","publishdate":"2013-12-30T21:20:00+09:00","summary":"昨年は、大晦日に書いてました。 ちょっと進歩したかも。 振り返り(2012年に書いた抱負から) ということで、まずは昨年書いた抱負からの振り返りで","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2013)"},{"contents":"昨夜、Elasticsearchの0.90.8がリリースされました。\nリリースされた内容などについては、本家のブログ「0.90.8 released」をご覧いただくこととして。 1点注意したほうが良い点があります。\nelasticsearch-analysis-kuromojiを利用している場合は、0.90.8に対応したバージョンがリリースされるのを待つ必要があります。\nelasticsearch 0.90.8はLuceneのバージョンが4.6.0に変更されています。 Lucene 4.6.0では、TokenStreamというTokenizerのI/Fに変更があり、Tokenizerの実装を変更する必要があります。\n現時点(2013年12月19日現在)のelasticsearch-analysis-kuromojiの1.6.0にはlucene-analyzers-kuromoji-4.5.1.jarが含まれており、この部分でI/Fが異なるためエラーが発生してしまいます。 プラグインをインストールする時点ではエラーは発生せず、実際にKuromojiのTokenizerやAnalyzerを利用するタイミングでエラーが出ます。 以下、0.90.8にanalysis-kuromojiの1.6.0をインストールした状態で_analyzeを実行した時のエラー。\ncurl -XPOST \u0026#39;localhost:9200/_analyze?tokenizer=kuromoji_tokenizer\u0026amp;filters=kuromoji_baseform\u0026amp;pretty\u0026#39; -d \u0026#39;寿司が美味しかった\u0026#39; { \u0026#34;error\u0026#34; : \u0026#34;IllegalStateException[TokenStream contract violation: reset()/close() call missing, reset() called multiple times, or subclass does not call super.reset(). Please see Javadocs of TokenStream class for more information about the correct consuming workflow.]\u0026#34;, \u0026#34;status\u0026#34; : 500 } ということで、1.7.0がリリースされるのを待つか、自分でmvn packageしてビルドする必要があります。 他にも独自でTokenizerなどを造られている方は注意が必要かと。\nたぶん、すぐにリリースされるんじゃないかなぁと。\n2013/12/20追記\nとりあえず、masterブランチが0.90.8に変更されたみたいです。(と書いてるそばから、1.7.0がリリースされました) ということで、0.90.8では1.7.0を使うとエラーが出ないです。 (あと、踊り字対応のcharfilterも追加されたみたいです)\n","date":1387524240,"dir":"post/2013/","id":"c18b12fff24dc87e7f1039bd17c0c6aa","lang":"ja","lastmod":1387524240,"permalink":"https://blog.johtani.info/blog/2013/12/20/release-elasticsearch-0-90-8/","publishdate":"2013-12-20T16:24:00+09:00","summary":"昨夜、Elasticsearchの0.90.8がリリースされました。 リリースされた内容などについては、本家のブログ「0.90.8 releas","tags":["elasticsearch","kuromoji"],"title":"Elasticsearch 0.90.8がリリースされました&注意点(2013/12/20追記)"},{"contents":"Solr本が出てから、質問を受けてブログ書くと言いながら書いてなかったことを思い出しました。。。\nプラグインの配置方法についてこんな質問を受けてたので、それっぽいエントリを書いておきます。(想像と違ってたらツッコミ入れてください)\n@johtani 追加でプラグインの配置方法とかあると便利かなと思いました\n\u0026mdash; Tsubosaka (@tsubosaka) 2013, 12月 2 改定前のSolr本では、日本語の形態素解析器をjarファイルとして追加する方法が書かれていました。 ただ、改定後のSolr本では、KuromojiがLuceneで実装されているためサンプルとしてjarファイルを追加するような方法の記載が明確にはありません。\n19ページのcollection1の説明ですこしだけ、libディレクトリについて触れています。\n独自のTokenizer(lucene-gosenなど)はjar形式でSolrに追加し、schema.xmlなどに利用するFactoryを指定してから利用します。\nこのとき、追加のjarファイルを配置する先がlibディレクトリです。\nlibディレクトリは2つの種類のスコープのディレクトリが存在します。\nSolr全体で利用可能なlibディレクトリ コア単位で利用可能なlibディレクトリ Solr全体で利用するlibディレクトリ これは、起動しているSolrにある全てのコアで利用するようなjarファイルを配置するディレクトリになります。 場所は$SOLR_HOME/libです。ここにjarファイルを配置することで、この$SOLR_HOMEを利用するすべてのコアで同じjarファイルを利用することができるようになります。\nですので、例えば、lucene-gosenはすべてのコアで利用するという場合にはここに配置すれば、1つのjarファイルを配置するだけで済むことになります。\nコア単位で利用するlibディレクトリ これは、コアごとにlibディレクトリを用意する場合です。 19ページにも記載されていますが、$SOLR_HOME/コアディレクトリ名/libとなります。\n特定のコアのみで利用するライブラリについてはこちらに配置する形になります。 他のコアで利用してほしくないjarファイルなどを配置するのに利用すればよいかと。\n簡単ですが、補足記事でした。 UIMAやlangidの利用方法などもあるとうれしですかね? そのうち気が向けば書くかもしれません。(他の人に書いてもらうのもありかも。)\n","date":1387447740,"dir":"post/2013/","id":"cb5b6f7ab4d36e90d2619cb907ebb956","lang":"ja","lastmod":1387447740,"permalink":"https://blog.johtani.info/blog/2013/12/19/add-jar-file-to-solr/","publishdate":"2013-12-19T19:09:00+09:00","summary":"Solr本が出てから、質問を受けてブログ書くと言いながら書いてなかったことを思い出しました。。。 プラグインの配置方法についてこんな質問を受け","tags":["Solr"],"title":"Solrへのプラグインの配置方法について"},{"contents":"ども。 プラグインのインストールに長いURL入れるの辛いですよね?ね?\nということで、MavenでリリースしてMaven Repositoryからダウンロードできるようにしてみました。\n流れとしては\nSonatypeにリリースできるように申請する Sonatypeにリリースする SonatypeからMavenにSyncしてもらう という流れです。\nSonatypeにリリースするための方法はイケメンの人(@yusuke)がブログに簡単ですが残してくれてました。 あと、こちらの@vvakameさんのブログも参考にしながら作業しました。\n【最新版】Maven Central Repository へのライブラリ登録方法 #maven JsonPullParser が Maven Central Repository に入るようです pom.xmlについては、プラグインのpom.xmlを参考にしてもらえればと。 1.の作業が終わったら、リリースを実行します。\nこの時、\u0026lt;scm\u0026gt;タグにgithubの情報が記載されているため(?)、githubにタグを打つ作業もmavenコマンドがやってくれるみたいです。\nmvn release:prepare を実行すると、リリースするバージョンやタグ名などを聞いてくれます。 それらに答えると、pom.xmlにバージョンを指定してcommit\u0026amp;pushしてくれ、タグも打ってくれます。(なんて便利)\nその後、release:performにてSonatypeへのリリースが完了します。 あとは、Sonatypeの画面で作業したら、Mavenのリポジトリにそのうち同期してくれます。\nということで、次のコマンドを実行すればプラグインがインストールできるようになりました。0.6.0と0.7.0の違いは実装には差異はありません。リリース方法が変更されただけということになります。\nbin/plugin -i info.johtani/elasticsearch-extended-analyze/0.7.0 これで少しは活用してもらえるようになるかなぁ? (どのくらいの人が使ってくれてるのかは不明。。。)\n","date":1387249860,"dir":"post/2013/","id":"a0a00c23556fcc5dbfb7b7f43fbbb61d","lang":"ja","lastmod":1387249860,"permalink":"https://blog.johtani.info/blog/2013/12/17/release-es-extended-analyze-plugin-to-maven-and-sonatype/","publishdate":"2013-12-17T12:11:00+09:00","summary":"ども。 プラグインのインストールに長いURL入れるの辛いですよね?ね? ということで、MavenでリリースしてMaven Repositoryから","tags":["elasticsearch"],"title":"elasticsearch-extended-analyzeプラグインをMavenとSonatypeにリリース"},{"contents":"少し遅くなってしまいましたが、12/05に電子書籍も発売されました。\n技術評論社の電子書籍サイトから購入可能です。\n書籍のページへのリンク PDF版となっております。 購入の際は、技術評論社の電子書籍サイトに会員登録後購入可能となります。\n個人的には電子書籍が便利なので、こちらを普段活用しようと思っています。\nもちろん、紙の書籍も発売中です!購入の際は右の書影をクリックしていただければと!\n","date":1386554880,"dir":"post/2013/","id":"d9560caeb797b302191f667b4264da40","lang":"ja","lastmod":1386554880,"permalink":"https://blog.johtani.info/blog/2013/12/09/release-introduction-solr-ebook/","publishdate":"2013-12-09T11:08:00+09:00","summary":"少し遅くなってしまいましたが、12/05に電子書籍も発売されました。 技術評論社の電子書籍サイトから購入可能です。 書籍のページへのリンク PDF","tags":["Solr"],"title":"改訂版Solr入門のPDF版も発売"},{"contents":"勉強会で宣伝もしましたが、改めて。\nSolr入門の改訂版を執筆しました。 考えてみれば、もう3年も前なんですね、Solr入門は。 Solr勉強会などでも何度も新しいのは出ないのですか?と聞かれていましたが、やっと出ました。(お待たせしました。)\n時が立つのは早いものです。前回のSolr入門はバージョン1.4にて執筆していましたが、今回は4.4をベースにし、4.5.1への対応を行っています。\n月曜日には手元に見本が届き、今週金曜日に発売予定です!\nSolrCloud、SoftCommit、Spatial、Joinなど、多彩な機能についても記載してあります。 また、ManifoldCFというSolrにデータを登録するのに 利用できるコネクタフレームワークについても書いてあります。\nより多彩になったSolrの機能を活用するための一助となれればと思います。 (電子版も出る予定です。詳細についてはもう少々お待ちください)\nまた、出版を記念して少し時期が先になりますが、Solr勉強会を開催しようと思います。\n日時:2014年01月29日 第13回Solr勉強会 #SolrJP 新Solr本出版記念 今回はせっかくのSolr入門の書籍の出版記念ということで入門的な話をしてもらう予定です。 Solr初心者の方、Solrに興味のある方などに来ていただきたいと思っています。 (プレゼントも用意できるかも!?)\nということで、「改訂版Apache Solr入門」をよろしくお願いします。 (もちろん、購入は下のリンクからですよね!)\n","date":1385436420,"dir":"post/2013/","id":"a2012a3c9cdb1d6fd69afdbadc1e76b6","lang":"ja","lastmod":1385436420,"permalink":"https://blog.johtani.info/blog/2013/11/26/introduction-to-solr-new-edition/","publishdate":"2013-11-26T12:27:00+09:00","summary":"勉強会で宣伝もしましたが、改めて。 Solr入門の改訂版を執筆しました。 考えてみれば、もう3年も前なんですね、Solr入門は。 Solr勉強会な","tags":["Solr"],"title":"改訂版Solr入門を執筆しました"},{"contents":"どーも。以前の記事で開発中としていたプラグインですが、とりあえず、pluginコマンドでインストール出来る形にしてみました。\nインストールなどについては、READMEに記載したのでそちらを参照してもらうことにして、試行錯誤した話をメモとして残しておきます。\nプラグインの開発はしいてたのですが、やっぱりpluginコマンドでインストール出来ないと使ってもらえないよなということで、勉強会も終わったのでちょっと調べてました。\nプラグインコマンド コマンドが用意されてますが、実態はJavaで実装されてて、通常はこんなかんじでプラグインをインストールします。\n./bin/plugin -i elasticsearch/elasticsearch-analysis-kuromoji/1.6.0 この「elasticsearch/elasticsearch-analysis-kuromoji/1.6.0」という文字列ですが、「ユーザ名/リポジトリ名/バージョン」という意味になります。\nで、ダウンロードするURLは以下のものの中から選ばれます。\nelasticsearch.orgのダウンロード用サイト search.maven.org oss.sonatype.org Githubのarchive これらのサイトに先ほどのユーザ名、リポジトリ名、バージョンを利用したURLを組み立てて、ダウンロードしてくれるという仕組みになっています。\nelasticsearch.orgについては、本家の人しかアップロードできないと思うので、なし。\nmaven、sonatypeについては、Mavenのリポジトリにリリースする必要があるんじゃないかなと。 で、昔調べてググって途中で挫折したんですが、挫折してます。手順が結構手間で。。。 (参考記事:【最新版】Maven Central Repository へのライブラリ登録方法 #maven)\nということで、Githubにアップしたらなんとかなるんじゃん?ということで色々と調査して試してみました。(結果はイマイチなんですが。。。)\nその1:mvn release:prepare せっかくGithubだし、せっかくMavenなんだしなんか、pom.xmlに便利な設定したらコマンド一発でリリースできるんじゃない?という甘い気持ちで調査したググったらそれっぽい記事が見つかりました。 「MavenとGitHubの連携」って記事です。\nで、pom.xmlの設定にも他のプラグインを真似してコピペしたものに\u0026lt;scm\u0026gt;ってタグがあったなぁと。このコマンドでついでにGithubにアップロードできるんじゃないの?ということで、試してみました。\nmvn release:prepare このコマンドを叩くと、記事にあるとおりにいくつか質問をされます。 タグについては、プロジェクト名-バージョン番号という文字列がデフォルトだと指定されているので、v0.5と変更して実施してみると、Githubのreleaseにv0.5ってのができてるじゃないですか。\n※pluginコマンドはGithubを見に行く時に次のファイルをダウンロードしに行きます。\nhttps://github.com/ユーザ名/リポジトリ名/archive/vバージョン名.zip やった!と思い、早速pluginコマンドを実行してみましたが、エラーが出ました。。。\nTrying https://github.com/johtani/elasticsearch-extended-analyze/archive/v0.5.zip... Downloading ...DONE Installed johtani/elasticsearch-extended-analyze/0.5 into /Users/johtani/projects/tmp/ess_env/second_node/elasticsearch-0.90.7/plugins/extended-analyze Usage: -u, --url [plugin location] : Set exact URL to download the plugin from ...省略... Message: Error while installing plugin, reason: IllegalArgumentException: Plugin installation assumed to be site plugin, but contains source code, aborting installation. あらら、なんで?と。\nで、実際にgithubにアップされてたzipファイルをダウンロードしてみたら、githubのリポジトリにあるディレクトリ構成がそのまま入ってるじゃないですか。。。 そうですか、そうですよね。prepareだし、タグ打ってzipにかためてくれるだけなんですねと。。。\nおそらく、siteプラグインだけの場合はこの方法でpluginコマンド叩けばOKなんでしょうが、私がダウンロードしてもらいたいのは.jarファイルが入ったzipファイルなんです。\nということで、断念しました。(タグ消したりをgitコマンドで叩いて綺麗にし直すとか虚しい作業をしてました)\nその2:github.comのWebでリリース おとなしく、Sonatypeのサイトにアップロードする方向でがんばればいいんですが、とりあえず使えるようにするのが先だと思い、 github.comのページでアップロードしてしまおうと。\n「release」というタブをクリックすると、画面からアップロードできるようになります。\nzipファイルを作ってアップロードしました。(zipファイル自体はmvn packageコマンドを実行したらtarget/releaseというディレクトリに作成されてる)\nこれで行けるだろということで、またpluginコマンドを実行すると\nTrying https://github.com/johtani/elasticsearch-extended-analyze/archive/v0.5.zip... Downloading ...DONE Installed johtani/elasticsearch-extended-analyze/0.5 into /Users/johtani/projects/tmp/ess_env/second_node/elasticsearch-0.90.7/plugins/extended-analyze Usage: -u, --url [plugin location] : Set exact URL to download the plugin from ...省略... Message: Error while installing plugin, reason: IllegalArgumentException: Plugin installation assumed to be site plugin, but contains source code, aborting installation. あれ?同じエラー?なんで?jar入りのzipファイルアップロードしたのに???\nと。で、https://github.com/johtani/elasticsearch-extended-analyze/releasesにreleaseのページができてたので見てみると、あら。 アップロードしたファイルについては次のようなURLになってるじゃないですか。\nhttps://github.com/johtani/elasticsearch-extended-analyze/releases/download/v0.5/v0.5.zip で、よく見ると「Source code(zip)」というボタンもあるぞ?このリンクは?\nhttps://github.com/johtani/elasticsearch-extended-analyze/archive/v0.5.zip 。。。あぁ。そうですか。そういうことですか。理解してない私が悪いんですねと。\n結論? ということで、とりあえず、releaseにjar入りファイルはアップロードできた(手動で)ので -uオプションで直接URL指定すればインストールできるだろ!と諦めました。 いい勉強になりました。。。\nREADME見ていただくとインストール方法が分かりますが、長いです。。。\n時間をとって本腰入れてSonatypeにMavenコマンドでアップロードできるようにしようかな。。。\n","date":1384419300,"dir":"post/2013/","id":"13684d16fdd07d5f0584e29265a270e7","lang":"ja","lastmod":1384419300,"permalink":"https://blog.johtani.info/blog/2013/11/14/release-elasticsearch-extended-analyze-0-dot-5/","publishdate":"2013-11-14T17:55:00+09:00","summary":"どーも。以前の記事で開発中としていたプラグインですが、とりあえず、pluginコマンドでインストール出来る形にしてみました。 インストールなど","tags":["elasticsearch","plugin"],"title":"elasticsearch-extended-analyzeを公開?"},{"contents":"第2回を開催しました! すごい、140人くらいくらいの参加登録者(参加者は100人ちょっと!)がいて、びっくりです。 ステキな会場を提供していただいた、リクルートテクノロジーズさん、運営していただいた方々、スピーカーの皆さん、参加者の皆さん本当にありがとうございました。 今回も素敵な看板ありがとうございます。\n今回もしっかり楽しめたので、次回も頑張ります!\n今回は、elasticsearch-jpMLの紹介とかをできたのでよかったかなぁと。 ぜひ、活用してください!どんな質問でもいいので。\nあと、スライドに入ってた例の本もよろしくです。\nということで、懇親会も盛り上がったし楽しかったです。 今後も場の提供+自分の勉強のトリガーとして、開催していくので、ご協力お願いします! 聞きたい話など、MLや@ツイートしていただければと。\nelasticsearchのRouting機能:株式会社シーマーク 大谷 純 (@johtani) スライド:Routing機能※スライドはPDFです。\nド緊張で、大した発表ではなかったですが。。。 どちらかと言うとSolr本の紹介だったかもなぁ。スミマセン。\n※スライドが一部文字が消えてるので、作りなおすかも。\nElasticSearchを使ったBaaS基盤の開発(仮):株式会社富士通ソフトウェアテクノロジーズ 滝田聖己さん(@pisatoshi) スライド:https://speakerdeck.com/pisatoshi/elasticsearch-trial-and-error\n本日はお越しいただきありがとうございました!しかも静岡から!今後もよろしくお願い致します。\nEnchantMoonでシステム構成w\n0.17.0から利用されていると。(スゴイ)\nプライマリのデータストア!ただし、登録元データはMySQLにもある。\n階層も深く、大きめのドキュメント。\nレプリカ1、インデックスのバックアップも取ってないと。。。\nルーティングの機能\nDynamicMappingの問題点\nマッピング定義が肥大、型がコンフリクト。。。苦労しっぱなし\nデータ登録は1台にして、1台で一気に登録してから再配置\n実際に運用とかされてるので、いろんなノウハウがまだまだありそう!\nKibana入門:水戸祐介さん(@y_310) スライド:https://speakerdeck.com/y310/kibanaru-men\n(やっぱりru-menになってるw)\n実は、押しかけて話してもらうように説得したのでした。今後もよろしくです。\nCOOKPADの方によるKibanaのお話。 Kibanaの利点とかなんで?とか。 画面構成の説明から ダッシュボードは必ず保存して!リロードしたら悲しい思いをしてしまうので。 sparkline便利そうだなぁ。ほんとに、データサイエンティスト系のツールを目指してるのかな 一通り、ダッシュボードに配置できるパネルの説明してもらえたのですごく参考になりました! Tips周りが役に立ちそう。not_analyzedは重要ですよね。 LT 「データ集計用ダッシュボードブラウザとしても使えるElasticSearch+Kibana v3を利用する際の運用ノウハウ紹介」:株式会社リブセンス Y.Kentaro さん (@yoshi_ken) さん スライド:http://www.slideshare.net/y-ken/elasticsearch-kibnana-fluentd-management-tips\nKibanaの紹介とかFluentdの紹介。 Tips満載すばらしい。 JDBC riverは0.90.6ではうまく動かないので、気をつけてと。 「Fluentd as a Kibana」:@repeatedly さん スライド(gist)?:https://gist.github.com/repeatedly/7427856\nKibanaがfluentdの中で動くと!?\n「Authプラグインでアクセスコントロール」:株式会社エヌツーエスエム 菅谷信介さん (@shinsuke_sugaya) スライド:http://www.slideshare.net/shinsuke/es-auth-plugin\nAPI毎?インデックスごと?にアクセス制御ができるプラグイン\n","date":1384247760,"dir":"post/2013/","id":"66f43ab4b823d67f52735bbbe6ba65b0","lang":"ja","lastmod":1384247760,"permalink":"https://blog.johtani.info/blog/2013/11/12/elasticsearch-japan-user-meetup-no2/","publishdate":"2013-11-12T18:16:00+09:00","summary":"第2回を開催しました! すごい、140人くらいくらいの参加登録者(参加者は100人ちょっと!)がいて、びっくりです。 ステキな会場を提供していた","tags":["elasticsearch","kibana","fluentd","勉強会"],"title":"第2回elasticsearch勉強会を開催しました! #elasticsearchjp"},{"contents":"Cloudera World Tokyo 2013に参加してきました。\n午前中はあいにくの雨でしたが、それでも結構な人数が最初の基調講演から参加されてました。 私が参加したセッションは大盛況な感じでした。\nおみやげとしてカステラも頂いちゃいました!\nまた、色々なセッションに現れたこんなメッセージ画像も見つけました!\n昨日の写真データの整理をしていたら、こんなものが・・・ @shiumachi さんよ・・・ #cwt2013 pic.twitter.com/S0JsxSYXIx\n\u0026mdash; Kenichiro HAMANO (@hamaken) November 8, 2013 やっぱり、スーツの人が多いなという印象。\n名刺を毎回回収されるのはちょっとつらかったです。なにか、いい方法ないですかねぇ。\n以下はいつもの個人メモです。\n「ビッグデータプラットフォームとして進化するHadoop」 Cloudera株式会社 代表取締役 ジュセッペ小林氏 Costcoなどの写真を元にビッグデータを可視化 BigDataとHadoopの関係 検索、SQL、機会学習、数理処理、データ管理などにもHadoopの活用されつつある。 セキュリティ、データ管理、クラスタ上でのツールの実行なども増えてきてる。\n「今日ビッグデータは明日のスモールデータ」\nアーキテクチャとしてのビッグデータ 多種多様なデータを一箇所に集約し、生データを直接活用できる。 OSSとしての責任も。\nデータサイエンス Opsだけでないデータ解析にも活用\n「Clouderaのビッグデータプラットフォーム戦略」(仮) 講師:Cloudera, Inc. CTO Dr.Amr Awadallah レガシーな情報アーキテクチャ→スケールできない、可視化の限界、硬直したスキーマなどなど。\nエンタープライズデータハブとしてのHadoopとか。\nビッグデータの歴史と将来展望 講師:国立情報学研究所 アーキテクチャ科学研究系 教授 佐藤一郎氏 ビッグデータの歴史的経緯とか 最初の事例はアメリカの1880年国勢調査。\n「ビッグデータがコンピュータを生み出した」。コンピュータがビッグデータを生み出したんじゃない。\n少量データにもHadoopを\nバッチ処理のリアルタイム化とか(一晩から10分へ) 原点は検索データのインデクシング\nHadoopを使うのが目的じゃないんだから、構築には手を掛けないのがいいよね。\nプラットフォームと発展している\n分散システム研究者から見たHadoop 分散ししテムの難しさを、処理範囲を限定することで巧みに回避 データの近くで処理 研究レベルではリアルタイム化や逐次処理化が活発 全工程で逐次・リアルタイムが必要とは限らない 聞いてばかりじゃなくて、動かしてみましょう。 データサイエンス:超並列分散処理を活用した新たなビジネス価値の創出 講師:アクセンチュア株式会社 工藤卓哉氏 「日経BPのビッグデータ総覧2013」に記事書いてる。 多様化するデータ(社外のデータも)をどうやってうまく活用していくか。 データが教えてくれたこと→まず、データありき、まずデータためましょう。それから解析とかすればいいのでは?というはなし? 競合他社さんはNGだけど、ブースでデモ?実機?が見れますと。 Hadoopデータプラットフォーム Cloudera株式会社 嶋内 翔氏 まずは宣伝 Cloudera Implaraのフリーブックの日本語版 Hadoop Operationの書籍でるよ プラットフォームを構成するもの Flume Sqoop HBase Hive Impala データ登録してBIアナリストのお仕事にどうやって役立てる? 外部テーブル:Hiveからはテーブルのように見える仕組み。元ファイルは消えない SerDe(さーでぃー):データをHiveレコードに変換する仕組み 生データを少し加工しましょう 圧縮したりファイル結合したりはしときましょう。 Hadoop活用のポイント 富豪的プログラミング。リソースケチるな。 ローカルでできることはローカル。むりにHadoopでやんなくてもいいですよねと。バランス重要 スケジューリング実行などはOozie使うと便利。(日次集計とか) Cloudera Searchで元データにインデックス貼れるぞと。検索しながら分析ができる クラスタ管理とか Cloudera manager便利ですよ ストレージリソースの管理。 声掛け、管理者が容量チェック、Cloudera Managerのレポート 少数精鋭でHadoop使おう=手が回らなくなる。 みんなで使おう=Kerberos認証とか管理をちゃんと考えないと。けど、文化が根付けば強力。Sentry、Cloudera Navigatorとか。 Hadoopシステムの全体構成図。データの流れと各製品のつながり。 We are hiring!ということで、興味のある方は@shiumachiさんにコンタクトをとりましょうとのこと。 SQLで実現するバッチ処理とストリーム処理 LINE株式会社 田籠 聡氏 資料:Batch and Stream processing with SQL\nLINEのキャラがちらほら出てきた。\nSQL好きですか?\nログの量とか。2.1TB/Day\nバッチ処理とストリーム\n速い集計のためにHadoopが重要 エラー系のログとかはストリームで処理したい\nアーキテクチャ説明\nデータ解析する人って色々。\n管理者 プログラマ サービスディレクタ 経営陣 みんなが集計用処理を理解、編集ができるほうがいい。\n顔あげたらHiveアイコンだらけだったw\nShibとか。\nなんでHiveに限るの?\nHiveに着目したバージョンアップだけを考えれば良くなる。 スケジュールクエリが増えてきて、つらい。\nTimeWindowを固定して集計処理をすることで、回避できる。 Norikra!! スキーマレス\nOSS。Esperベース。\nインストールが楽\nクエリの動作のお話。\nhttp://norikra.github.io\nWe Are Hiring!\nHadoop コミュニティと YARN の現状 日本電信電話株式会社 小沢 健史氏 なんでHadoop? PostgreSQLでやってたけど、大きなデータにはHadoopを使おうという感じになってきた。 なんで使い分けるの? スキーマ後付け NTTDocomoのモバイル位置情報の統計処理とか? 技術的な話をするので、HiveTに着替えます!w YARNのなにが嬉しいの? ImpalaとMapReduceが同時に動くような環境の時に、リソースをうまく管理できないのがV1 そこでYARN Apache Mesosとだいたい一緒。 Apache MesosとYARNの比較 ","date":1383786660,"dir":"post/2013/","id":"a106d7c1b1b277538367f9c8140e3a75","lang":"ja","lastmod":1383786660,"permalink":"https://blog.johtani.info/blog/2013/11/07/cloudera-world-tokyo-2013/","publishdate":"2013-11-07T10:11:00+09:00","summary":"Cloudera World Tokyo 2013に参加してきました。 午前中はあいにくの雨でしたが、それでも結構な人数が最初の基調講演から参加されてました。 私が参加したセッショ","tags":["Cloudera","Hadoop","Norikra"],"title":"Cloudera World Tokyo 2013に参加しました! #cwt2013 "},{"contents":"またまた、Riak Meetup Tokyo #3に参加してきました。Riak2.0のYokozunaの話があると聞いたので。\nということで、いつものように個人メモです。\n今日は自重して、懇親会はアルコールなしにしました。思いがけずfluentd+elasticsearch+kibanaという組み合わせの話も聞けて大満足です。 Yokozunaのデモが見れなかったのがちょっと残念だったかなぁ。\n少しだけSolr本の宣伝もしてきちゃいました。\n古城さん@Mixi 「RiakCSとmixi プライベートクラウド環境」 プライベートクラウドとは? 計算リソースが安い(ストレージは微妙) 開発者が好きに使える環境+運用側のチケットに追われる毎日からの開放 Riak CSの概要 S3互換の分散ファイルストレージ 検証とか 検証時はRiak CS 1.3\n5ノードで2Mファイルを40万個\n削除は遅延で削除される\nPUT性能とか。\nRiak CSの死活監視にはRiakのstatsとか\n障害対応とか\nクラスタ クラスタは3つ。ログ、サービス(画像) 、バックアップ保存用 ログの収集にfluentd、解析にelasticsearchやkibanaを使っているらしい。 篠原@Basho 「Riak 2.0: 分散データ型、セキュリティ、そしてより容易な運用へ」 riak 2.0 pre5をリリース アプリ向け機能強化、運用の容易性 設計ポリシーとか、1.xとか 運用、高可用性、水平拡張性 Capabilityネゴシエーションとか 2.0の機能強化 バケットタイプ キーの名前空間としてバケットがあったけど、同種のバケットをまとめて管理とかしたくなった。 データ型の導入(CRDT) Setデータ型 セキュリティとか 強い整合性\u0026hellip; 鈴木@Basho 「Yokozuna: Riak 2.0の新しい全文検索機能」 YokozunaやSolrの概要 1ノードにRiakとSolrが1プロセスずつ SolrプロセスはRiakが管理してくれる SolrCloudは使ってません。 Riakのノードに届いたデータをSolrに裏で書き込んでくれる。 検索時にはRiakのノードが分散検索をしてくれる X-Riak-Metaもインデクシングしてくれる。jsonやxmlの各要素をSolrのフィールドとして認識してくれる。 Extractor Solrは4.4で、JVMは1.7をユーザが入れるらしい。\n","date":1383746460,"dir":"post/2013/","id":"9dca844d353efed03fbaddfc0fab7c76","lang":"ja","lastmod":1383746460,"permalink":"https://blog.johtani.info/blog/2013/11/06/riak-meetup-tokyo-no3/","publishdate":"2013-11-06T23:01:00+09:00","summary":"またまた、Riak Meetup Tokyo #3に参加してきました。Riak2.0のYokozunaの話があると聞いたので。 ということで、いつものように個人メモで","tags":["Riak","Yokozuna"],"title":"Riak Meetup #3 #riakjp に参加しました。"},{"contents":"開発中ですと書きました、elasticsearch-extended-analyzeですが、改良しました。\n改良と変更は以下のとおりです。\nソースのパッケージをorg.elasticsearchからinfo.johtaniに。MLで気になったので質問したら、変えたほうがいいよとのこと。ダウンロード化については、もう少々お待ちを。 出力形式を変更。可能な限りCharFilter、Tokenizer、TokenFilterそれぞれが出力する内容を返すようにしました。 ただし、既存のAnalyzer(JapaneseAnalyzerクラスとか)に関しては、現時点では出力しません。CharFilterなどを取得するI/Fが見えないためです。(改良できるかの調査は未着手) 現時点でできてないのは以下の項目\npluginコマンドでインストール 出力したいAttributeの指定 TokenizeChainで変更されたTokenの追跡(現状はどのTokenがStopFilterで消されたかなどが不明) 画面の用意(簡単に確認できる画面) ということで、README.mdに出力サンプルは貼り付けてるので、興味のある方は試してみてください。 不明点などあれば、コメントかIssueかツイートでも。\n","date":1383570720,"dir":"post/2013/","id":"b5c628b0c1dbf857a475c4be5de4690d","lang":"ja","lastmod":1383570720,"permalink":"https://blog.johtani.info/blog/2013/11/04/improve-output-extended-analyze/","publishdate":"2013-11-04T22:12:00+09:00","summary":"開発中ですと書きました、elasticsearch-extended-analyzeですが、改良しました。 改良と変更は以下のとおりです。 ソー","tags":["elasticsearch","plugin"],"title":"elasticsearch-extended-analyzeの改良"},{"contents":"お久しぶりです。 気づいたらまた、結構ブログを書いてなかったです。。。\n今回は、今開発しているElasticsearchのプラグインに関するお話です。\nいやぁ、名前決めるの難しいですね。これで英語的に合ってるか不安ですが、elasticsearch-extended-analyzeというプラグインを作っています。\nどんなもの? Solrの管理画面のanalysisに相当する機能が欲しくて作り始めました。\nElasticsearchにはanalyze APIというAPI(名前あってるのかなぁ?)が存在します。\nこれは、文字列を投げると、指定したアナライザやトークナイザでどのようなトークンに分割されるかを調べることができるAPIです。\n例えば、elasticsearch-analysis-kuromojiをインストールしたElasticsearchに対して、以下のcurlコマンドを実行します。\ncurl -XPOST \u0026#39;localhost:9200/_analyze?tokenizer=kuromoji_tokenizer\u0026amp;filters=kuromoji_baseform\u0026amp;pretty\u0026#39; -d \u0026#39;寿司が美味しい\u0026#39; すると、トークナイズされた結果が次のようなJSONで返ってきます。\n{ \u0026#34;tokens\u0026#34; : [ { \u0026#34;token\u0026#34; : \u0026#34;寿司\u0026#34;, \u0026#34;start_offset\u0026#34; : 0, \u0026#34;end_offset\u0026#34; : 2, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 1 }, { \u0026#34;token\u0026#34; : \u0026#34;が\u0026#34;, \u0026#34;start_offset\u0026#34; : 2, \u0026#34;end_offset\u0026#34; : 3, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 2 }, { \u0026#34;token\u0026#34; : \u0026#34;美味しい\u0026#34;, \u0026#34;start_offset\u0026#34; : 3, \u0026#34;end_offset\u0026#34; : 7, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 3 } ] } トークナイズの結果がわかるのは嬉しいのですが、どんな品詞なのかといったKuromoji固有のTokenの属性情報がなくなってしまいます。\nSolrでは、こんな画面が用意されていて、品詞情報とかが出力されます。あとは、各TokenFilterでどのトークンがなくなっているかなどもわかるようになっています。\nこれって結構役立つと思うんですよ。 ということで、Pluginも作ってみたかったので、いい機会だから作ってみようかと。\n出力サンプル まずは、その他のAttribute(品詞とか)を表示するところを実装してみました。\ncurl -XPOST \u0026#39;localhost:9200/_extended_analyze?tokenizer=kuromoji_tokenizer\u0026amp;filters=kuromoji_baseform\u0026amp;pretty\u0026#39; -d \u0026#39;寿司が美味しい\u0026#39; 先ほどとほぼ一緒のcurlコマンドを実行します。違う点は**「_analyze」が「_extended_analyze」**となっている点です。\nで、実行結果はこんな感じです。(長いですがそのまま載せてます。続きの文章がしたにあります。)\n{ \u0026#34;tokens\u0026#34; : [ { \u0026#34;token\u0026#34; : \u0026#34;寿司\u0026#34;, \u0026#34;start_offset\u0026#34; : 0, \u0026#34;end_offset\u0026#34; : 2, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 1, \u0026#34;extended_attributes\u0026#34; : [ { \u0026#34;org.apache.lucene.analysis.tokenattributes.TermToBytesRefAttribute#bytes\u0026#34; : \u0026#34;[e5 af bf e5 8f b8]\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.tokenattributes.PositionLengthAttribute#positionLength\u0026#34; : 1 }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.BaseFormAttribute#baseForm\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.PartOfSpeechAttribute#partOfSpeech\u0026#34; : \u0026#34;名詞-一般\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.PartOfSpeechAttribute#partOfSpeech (en)\u0026#34; : \u0026#34;noun-common\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#reading\u0026#34; : \u0026#34;スシ\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#reading (en)\u0026#34; : \u0026#34;sushi\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#pronunciation\u0026#34; : \u0026#34;スシ\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#pronunciation (en)\u0026#34; : \u0026#34;sushi\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionType\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionType (en)\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionForm\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionForm (en)\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.tokenattributes.KeywordAttribute#keyword\u0026#34; : false } ] }, { \u0026#34;token\u0026#34; : \u0026#34;が\u0026#34;, \u0026#34;start_offset\u0026#34; : 2, \u0026#34;end_offset\u0026#34; : 3, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 2, \u0026#34;extended_attributes\u0026#34; : [ { \u0026#34;org.apache.lucene.analysis.tokenattributes.TermToBytesRefAttribute#bytes\u0026#34; : \u0026#34;[e3 81 8c]\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.tokenattributes.PositionLengthAttribute#positionLength\u0026#34; : 1 }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.BaseFormAttribute#baseForm\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.PartOfSpeechAttribute#partOfSpeech\u0026#34; : \u0026#34;助詞-格助詞-一般\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.PartOfSpeechAttribute#partOfSpeech (en)\u0026#34; : \u0026#34;particle-case-misc\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#reading\u0026#34; : \u0026#34;ガ\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#reading (en)\u0026#34; : \u0026#34;ga\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#pronunciation\u0026#34; : \u0026#34;ガ\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#pronunciation (en)\u0026#34; : \u0026#34;ga\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionType\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionType (en)\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionForm\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionForm (en)\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.tokenattributes.KeywordAttribute#keyword\u0026#34; : false } ] }, { \u0026#34;token\u0026#34; : \u0026#34;美味しい\u0026#34;, \u0026#34;start_offset\u0026#34; : 3, \u0026#34;end_offset\u0026#34; : 7, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 3, \u0026#34;extended_attributes\u0026#34; : [ { \u0026#34;org.apache.lucene.analysis.tokenattributes.TermToBytesRefAttribute#bytes\u0026#34; : \u0026#34;[e7 be 8e e5 91 b3 e3 81 97 e3 81 84]\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.tokenattributes.PositionLengthAttribute#positionLength\u0026#34; : 1 }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.BaseFormAttribute#baseForm\u0026#34; : null }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.PartOfSpeechAttribute#partOfSpeech\u0026#34; : \u0026#34;形容詞-自立\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.PartOfSpeechAttribute#partOfSpeech (en)\u0026#34; : \u0026#34;adjective-main\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#reading\u0026#34; : \u0026#34;オイシイ\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#reading (en)\u0026#34; : \u0026#34;oishii\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#pronunciation\u0026#34; : \u0026#34;オイシイ\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.ReadingAttribute#pronunciation (en)\u0026#34; : \u0026#34;oishii\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionType\u0026#34; : \u0026#34;形容詞・イ段\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionType (en)\u0026#34; : \u0026#34;adj-group-i\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionForm\u0026#34; : \u0026#34;基本形\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.ja.tokenattributes.InflectionAttribute#inflectionForm (en)\u0026#34; : \u0026#34;base\u0026#34; }, { \u0026#34;org.apache.lucene.analysis.tokenattributes.KeywordAttribute#keyword\u0026#34; : false } ] } ] } 先ほどの結果に**「extended_attributes」**という配列のオブジェクトが追加された形になっています。 ちょっと長くなってしまいましたが。。。\nSolrの処理を真似して作ったので大したことはやってないんですが、少しは便利になるかもなぁと。\n現時点では、最終的な結果しか取得できないですが、今後は次のような機能を作っていこうかと思っています。 できるかどうかは、やってみてって感じですが。\npluginコマンドでインストール pom.xmlはありますが、まだMavenとかに登録はされていません。ですので、mvn packageしてからjarファイルをpluginsフォルダに配置しないといけません。pluginコマンドでインストールできるともっと使ってもらえるはず? 出力したいAttributeの指定 リクエストパラメータで、出力したいAttribute名を指定するとか。 出力形式の変更 今は、Solrの真似をしていますが、せっかくJSONだったりするので、もう少し検討しようかと(同じAttributeの異なる値も1オブジェクトとして出力されてる) TokenizeChainの出力 Solr同様、CharFilter、Tokenizer、TokenFilterが動作して、最終的なTokenがインデックスに登録されます。ですので、各処理の直後のTokenがどうなっているかもわかったほうが嬉しいと思うので、それらも取得できるようにしたいなぁと 画面の用意 せっかくプラグインなんだし、画面で見れると嬉しいかなと。これは当分先になっちゃうと思いますが、Webページで確認できるような画面を作ると確認しやすくなるかなぁと。上記対応が終わってから取替かかると思いますが。 とりあえず、思いつくのはこんなかんじです。\nElasticsearchの_analyze APIを真似しただけのコードだし、テストも実装もまだまだですが、とりあえず公開してみました。\n要望などあれば、コメント、Issue、ツイート(もちろん、テストコードなども!)なんでも受け付けてますので、お気軽に。\n","date":1382695560,"dir":"post/2013/","id":"0302e8a57a5e8604342a925b2dc60737","lang":"ja","lastmod":1382695560,"permalink":"https://blog.johtani.info/blog/2013/10/25/developing-es-extended-analyze-plugin/","publishdate":"2013-10-25T19:06:00+09:00","summary":"お久しぶりです。 気づいたらまた、結構ブログを書いてなかったです。。。 今回は、今開発しているElasticsearchのプラグインに関するお話","tags":["elasticsearch","plugin"],"title":"elasticsearch-extended-analyzeプラグインを開発中"},{"contents":"不定期開催ですが第12回Solr勉強会を主催しました。\n今回は、前回ほどの過熱ぶりでは無かったですが、70人ほどの参加者の方がいらっしゃったかと。 ありがとうございます!\n今回は聞きたかったYokozunaの話をしてもらいました。あと、リベンジManifoldCF。 一部、追記しました。Bashoさんからツッコミがあったので。あと、4.5.1の話とか。\nManifoldCFのとSolrの組み合わせ(仮)株式会社 ロンウイット 大須賀 稔さん 前回お休みだったのでリベンジですw。\n英語だ。。。やっぱ英語がいいですか、スライド。。。\nManifoldCFの概要から。 最新版は1.3です。色々サポートしてるなぁ。\nデモもありました。(やっぱりちゃんと動かないので、鬼門みたいですが)\nデモ ManifoldCFのGUIで操作しながら。 いまいちちゃんと動かなかった。。。\nQA Q:Zipはうまく動かなかった A:Solr側で処理してくれてる。 Q:Notes対応するの? A:いまのところない。 Q:ExcelとかPDFはTika? A:Tika次第です。 Q:認証周りどこから取ってくるの? A:クローラ側にはなくて、SharePointとかの権限をみてる。 Q:Web系の認証は? A:まだないのでは。。。(調査します) あー、デモの続き忘れてましたね。。。\nSolrを組み込んだRiak 2.0の全文検索機能 -Yokozuna- Bashoジャパン株式会社 鈴木 一弘さん Riak色々使われてるよ!アングリーバードとか、Y!とか。 Riakで提供されている1機能としてのYokozuna。単独製品ではないですよと。\nRiakの説明。スケールするよ、いつでもRead/Writeできるよ、運用にフォーカスしてるよと。 マスターレスですよ。 Riak2.0のリリースは2013年末。Yokozunaもかな?\nダイナミックフィールド使ってるので、Yokozunaをonにするだけで簡単に使えるよ。\nRiakがSolrのプロセスを管理。\nインデックスの不整合の検知とかってどうやってるのかなぁ? インデックス比較用のハッシュツリーをノード間でコピーしつつ検査してる。(Active Anti-Entropy)\n(デモには魔物がいるようだ。。。)\nQA Q:JSONの属性を元にしてフィールドにインデックス可能か? A:可能です。IIJさんの発表で話が出ます。 Q:ProtocolBufferでSolrにアクセス可能? A:そのうちできそうです。リリース時にはできるようになっています。 Q:コアのスワップは?スキーマの変更は? A:事前に設定するのは可能。 Q:RiakのデータとSolrでデータがずれるってのはあるの? A:可能性はありますが、極力ずれAAEで修復。 Q:復旧中のインデックスにアクセスが行かないようにする仕組みなどはある? A:今はないです。 Yokozuna ベンチマークしました 株式会社インターネットイニシアティブ 曽我部 崇さん、田中 義久さん いいとこ取りで楽だなぁと。いうことで、試してみてます。 デモが動いてる。\nextractorでXMLやJSONをパースできる。 ベンチマーク結果。\nRiak Meetup Tokyo #2の時のQAも入ってるので助かります。素晴らしい。\nQA Q:スナップショットは両方取れるの? A:Riakは取れますが、インデックスは今は無理です。 フォロー:0.8はYokozunaにボトルネックがあったので、0.9以降だともっと性能が出るはずですとのこと。また次回とかに発表してもらうのもありですかねぇ。 Solr 4.5の新機能など @johtani 発表資料のPDFです。\nツイート見てて誤解を招いたなと思ったのですが、7u40は4.5限定ではなく、すべてのバージョンと考えてください。 チケットを見ると分かりますが、影響バージョンの記載はありません。\n※あ、4.5のChangesを紹介しましたが、4.5.1が出るかも。このへんが困ってるらしいです。\nSOLR-5306: can not create collection when have over one config SOLR-5317: CoreAdmin API is not persisting data properly LUCENE-5263: Deletes may be silently lost if an IOException is hit and later not hit (e.g., disk fills up and then frees up) LT @haruyama さん 資料:http://haruyama.github.io/solr_20131009/#(1)\n記号が捨てられるTokenizer困るので、捨てないのを作ってみました。\nKuromojiの困ったこと。全角数字を分解しちゃう。→MappingCharFilterFactoryで全角から半角にしましょう。 lucene-gosenデフォで半角記号が未知語になってしまい、半角カナと混ざるので、記号を全角にしましょう。\n","date":1381372500,"dir":"post/2013/","id":"76e127a44931bfefab991be3dd7a08b7","lang":"ja","lastmod":1381372500,"permalink":"https://blog.johtani.info/blog/2013/10/10/solr-meetup-memo/","publishdate":"2013-10-10T11:35:00+09:00","summary":"不定期開催ですが第12回Solr勉強会を主催しました。 今回は、前回ほどの過熱ぶりでは無かったですが、70人ほどの参加者の方がいらっしゃったか","tags":["Solr","Riak","Yokozuna","ManifoldCF"],"title":"第12回Solr勉強会を主催しました。#SolrJP"},{"contents":"今日は、ElasticSearchのMLで見つけたelasticsearch-inquisitorプラグインの紹介です。\nElasticSearchはREST API形式で簡単にコマンドラインからいろいろな処理を実行できて便利ですが、 GUIがあったほうが楽なこともまた事実です。 今回紹介する、inquisitorプラグインもSiteプラグイン(Webブラウザでアクセスできるプラグイン)の1つです。 (ただし、ローカルにインストールしてローカルのElasticSearchにしか接続できませんが。。。)\nインストール プラグインですので、以下のコマンドでインストールが出来ます。インストール後はElasticSearchの再起動が必要です。\nbin/plugin -install polyfractal/elasticsearch-inquisitor ElasticSearch再起動後に、以下のURLにアクセスすればOKです。 ※ローカルでのみ動作可能なプラグインです。(内部で呼び出しているJSにlocalhostと記載があるため)\nhttp://localhost:9200/_plugin/inquisitor/#/ 何ができるの? 自分の書いたQueryが正しく動作するかや、Analyzerによって文章がどのように、Term(Token)に分割されるかといった挙動をWebブラウザ上で確認することができます。用意されている画面は「Queries」「Analyzers」「Tokenizers」の3種類です。\nQueries クエリの確認、実行が可能な画面です。\n「Index」「Type」はプルダウンになっており、現在ElasticSearchに存在しているものが選択可能です。 その下のテキストエリアがクエリを入力する画面です。\nクエリを入力していると、入力しているクエリがValidかどうかをクエリのコンソール部分(右側上部)に表示してくれます。\n少し残念なことに、Tabを押すと、フォームのフォーカスが切り替わってしまうので、クエリを入力するのがちょっと面倒です。。。(私は通常の検索には、ChromeプラグインのSenseというものを利用してます。)\nクエリに問題がない場合は、「Query」ボタンを押すことで実際の検索が実行されます。 この時、画面真ん中のブルーのテーブル(内部で実行されるクエリ)の部分に、QueryがElasticSearch内部で解釈されたあとの、Luceneで実行されるレベルのクエリに変換されたクエリが表示されます。\nこれが便利です。JSONで記述したり、色々なタイプのクエリがElasticSearchでは実行できますが、望んだ形に単語が区切られているかなどを確認することができるため、非常に便利です。\nElasticSearchのQuery DSLではexplainをtrueにすることで、ヒットしたドキュメントのスコア計算に用いられた単語などがわかるのですが、そもそもヒットしないクエリの場合は、explainでは単語の区切られ方などがわかりません。\nその場合に、このプラグインで確認すると、想定と違う単語の区切られ方やクエリの造られ方がわかるかと思います。\nAnalyzers Analyzerによる文章のアナライズ結果の確認が出来る画面です。 ElasticSearchやSolrにあまり詳しくない場合、どんなAnalyzerが文章をどのように単語に区切って、転置インデックスのキーワードとして利用しているかがわからないと思います。\nこのAnalyzerが文章をどのように単語に区切っているかを確認することができるのがAnalyzers画面です。 こんなかんじの画面になります。\n一番上のテキストエリアが文章を入力する場所です。 文章を入力していくと、その下のテーブルの「Analyzed Text」の部分が変化していくのが分かります。 このグレーの単語が転置インデックスのキーワードとなります。\n予め用意されているAnalyzer以外に、用意されているTokenzier+Filterの組み合わせも簡単ですが確認可能です。(Tokenizer、Filtersとあるテーブル) ただし、ここまでのどちらも細かな設定は画面上ではできません(Filterの細かな引数の指定など)\n一番下の部分が、ElasticSearchに存在しているインデックスごとに定義されたAnalyzerやフィールドを元にした解析結果を表示することができる領域です。\n自分でマッピングを記述してフィールド定義したものの動作確認や、インデックスを適当に作ったけど、うまくヒットしない場合など、ここで、単語の区切れ方を確認することで、検索になぜヒットしないのかといった問題のヒントを得ることができると思います。\nAnalyzerによっては、インデックス対象の文字として扱わない文字があったりしますので。 先ほどのQueries画面のLuceneに投げられる直前のクエリと、Analyzersでの単語の区切られ方を確認することで、検索がうまくヒットしていないことが判明すると思います。\nTokenizers 最後はTokenizers画面です。Analyzersとほぼ同様ですが、ちがいは、デフォルトで用意されているTokenizerの挙動の確認ができるというだけになります。\n簡単な確認ならここで可能かと。\n注意点は? まだ開発途中のようで、つぎの部分が課題かと。\nローカルでのみ実行可能 Queries画面の結果の「Explain Result」リンクが未実装 Queries画面のクエリ入力が使いにくい(タブが打てないので) カスタム登録のAnalyzersはインデックスを用意しないと確認できない。(Kuromojiのプラグインを登録しただけでは確認できなかった) 細かな設定のフィールドも用意しないと、Analyzers画面では利用できない まとめ ということで、Inquisitor(読みがわからない)プラグインの簡単な説明でした。 検索にうまくヒットしないという理由は大体の場合、 クエリに入力した文字列が単語に区切られたものと、登録したデータが単語に区切られたものが異なるために検索にヒットしないというものです。\nそのクエリ、データの単語の区切られ方を確認するのに役に立つプラグインじゃないでしょうか。\nちなみに、このプラグイン自体はHTML+JSで作成されており、実際にはElasticSearchが持っているREST APIをキックしているだけになります。 ですので、Web画面なんか要らないという方は、このプラグインが実際に送信しているリクエストを参考にするとcurlコマンドでどういったリクエストを投げればいいかというのがわかると思います。\n私は軟弱者なので画面があったほうがいいですが。\n","date":1379906820,"dir":"post/2013/","id":"e1870dde155be1a375f155dd1f7ead13","lang":"ja","lastmod":1379906820,"permalink":"https://blog.johtani.info/blog/2013/09/23/intro-elasticsearch-inquisitor/","publishdate":"2013-09-23T12:27:00+09:00","summary":"今日は、ElasticSearchのMLで見つけたelasticsearch-inquisitorプラグインの紹介です。 ElasticSea","tags":["elasticsearch","plugin"],"title":"elasticsearch-inquisitorプラグインの紹介"},{"contents":"river-wikipediaの前々回の記事で書きましたが、bulk_sizeに関連して登録件数がやけにきりが良いのが気になると書いていました。\nで、Riverの仕組みを勉强がてら、elasticsearch-river-wikipediaのソース(1.2.0)を読んでみました。\nRiverの作り Riverはorg.elasticsearch.river.Riverというinterfaceを実装することで作らています。 ただ、Riverがinterfaceとなっていますが、o.e.river.AbstractRiverComponentというクラスを継承して作られています。\nAbstractRiverComponentにはRiverの名前や設定などが用意されています。 ま、ここはそれほど重要じゃないので、軽く流してと。\nRiverの設定関連は実装したRiverクラス(ここでは、WikipediaRiverクラス)のコンストラクタで、設定値の読み取りなどの記述を記載します。 このコンストラクタが、_river/hogehoge/_metaをPUTした時のJSONを元にElasticSearchから呼ばれて、Riverのインスタンスが作成されます。(たぶん、このへんがその処理だと思う。。。このあたりはまた今度)\n実際のRiverの処理はWikipediaRiverクラスのstart()メソッド内部に記述されています。\n@Override public void start() { logger.info(\u0026#34;starting wikipedia stream\u0026#34;); try { ① client.admin().indices().prepareCreate(indexName).execute().actionGet(); } catch (Exception e) { if (ExceptionsHelper.unwrapCause(e) instanceof IndexAlreadyExistsException) { // that\u0026#39;s fine } else if (ExceptionsHelper.unwrapCause(e) instanceof ClusterBlockException) { // ok, not recovered yet..., lets start indexing and hope we recover by the first bulk // TODO: a smarter logic can be to register for cluster event listener here, and only start sampling when the block is removed... } else { logger.warn(\u0026#34;failed to create index [{}], disabling river...\u0026#34;, e, indexName); return; } } ② currentRequest = client.prepareBulk(); ③ WikiXMLParser parser = WikiXMLParserFactory.getSAXParser(url); try { ④ parser.setPageCallback(new PageCallback()); } catch (Exception e) { logger.error(\u0026#34;failed to create parser\u0026#34;, e); return; } ⑤ thread = EsExecutors.daemonThreadFactory(settings.globalSettings(), \u0026#34;wikipedia_slurper\u0026#34;).newThread(new Parser(parser)); thread.start(); } 内部では\nインデックスの作成 バルクアップデート用クライアントの設定 WikiXMLのパーサの初期化 ページごとにキックされるコールバック処理の登録 デーモンスレッドの起動と起動 といった処理の流れになっています。\nで、このスレッドの起動後は、4.で用意したparser.parse()処理がグルグル回ります。\n1ページがパースされるたびに、WikipediaRiver.PageCallbackクラスのproess()メソッドが呼ばれます。 このメソッドの最後で、processBulkIfNeeded()メソッドが呼ばれています。ここで、実際にパースしたページをインデックスに登録する処理が実行されます。\nこのメソッドの1行目が鍵でした。 bulkSize以上の件数がバルクのリクエストに貯まった時だけ、実際にインデックスに登録する処理が実行されます。 このため、スレッドが回っている間は、bulkSize以上のデータが貯まらないと、インデックスへの登録は行われないわけです。\n次に、このスレッドを止めるには、前々回書いたように、_riverにPUTした、Riverの設定をDELETEするしかありません。(あとは、ElasticSearchを停止するとかでしょうか。)\nで、DELETEが実行される呼ばれるのが、WikipediaRiverクラスのclose()メソッドです。\n@Override public void close() { logger.info(\u0026#34;closing wikipedia river\u0026#34;); closed = true; if (thread != null) { thread.interrupt(); } } 見ていただくと分かりますが、スレッド止めて終了です。\n問題点は? ということで、\nWikipediaのXMLを読み込んでもRiverは停止しない Riverの停止を行ってもスレッドが止められるだけ。 bulkSize以下の件数がcurrentRequestに残っているけど、破棄される とまぁ、こんな流れになっているので、最後の端数のドキュメントがインデックスに登録されないようです。 (まだ、ちゃんと確認してないんですが、備忘録のため先に書いちゃいました。。。)\nじゃあ、全部うまく登録するにはどうしたもんかなぁと。 いまのところ思いついたのはこんな感じです。 他にいい案があったら教えて下さい。\n案1:close()処理の中で、スレッド停止後に、currentRequestに貯まっているデータをインデックスに登録しちゃう 案2:bulkSize以外に、定期的(指定された時間)で登録処理を実行してしまう。 簡単なのでとりあえず、案1を実装してみるかなぁと。 (さっさとコード書けよって話ですね。。。スミマセン) その前にMLで質問ですかねぇ、英語で。\nWikipediaのRiverをざっと眺めてみた感じですが、わかりやすい作りだなぁと。 他のRiverがどうなってるかをちゃんと見てませんが、他にもbulkSize指定をするRiverの場合は、このように件数がbulkSizeに満たない状態ではデータが登録されないといったことがあるかもしれません。\nElasticSearchのソースを読み始める取っ掛かりとしては面白いかと思いますので、興味ある方は読んで作ってみるといいかもしれません。(私は読んだだけですがw)\n追記(2013/09/13 21:00) MLで質問してみました。とりあえず、案1を。\nriver-wikipedia does not index all pages\n他のRiverでは対応してるしバグだね、Issue上げてとのことで、あげときました。 ついでにプルリクも出せばいいんでしょうが、プルリクまだやったことないヘタレです。。。\nあと、案2についても同じトピックで質問してます。 どうやら、BulkProcessorにその機能があるよと。 flushintervalというプロパティがありそうです。どうやって設定して、どうやって動くのかとか見てないので、 調査してブログorLTかな。\nbulk udpにはその値を設定できそうなのがあるんだよなぁ。\n追記その2(2013/09/16 23:50) さっそく修正版がコミット(コミットログ)されてました。 結構変わってます。BulkProcessorにflush_intervalの設定をすれば、よしなにやってくれる仕組みがすでに実装されているようです。 bulkSizeについても同様に、BulkProcessorに設定すれば良いようです。 Riverの仕組みが結構スッキリしています。 もともと実装されていた、bulkSizeごとの処理も消されています。 確かに、BulkProcessorの仕組みとして実装されている方がしっくりきますね。\nということで、考える暇もなくコミットされてしまいました。 こうやって質問しつつ、少しずつソースを読んでいこうかなと思ってるとこです。\n","date":1378921080,"dir":"post/2013/","id":"d2e805472f79f0b558f75b90b5e7b4ee","lang":"ja","lastmod":1378921080,"permalink":"https://blog.johtani.info/blog/2013/09/12/question-river-wikipedia/","publishdate":"2013-09-12T02:38:00+09:00","summary":"river-wikipediaの前々回の記事で書きましたが、bulk_sizeに関連して登録件数がやけにきりが良いのが気になると書いていまし","tags":["elasticsearch","wikipedia"],"title":"elasticsearch-river-wikipediaの疑問点"},{"contents":"前々回紹介した、日本語Wikipediaのデータをインデックス登録する記事の続きです。\n今回は、Kuromojiのアナライザを利用してインデックス登録してみます。\n余談(Proxy環境でのプラグインインストール) ElasticSearchのpluginコマンドはJavaで実装されています。(org.elasticsearch.plugins.PluginManager) プラグインのダウンロードには、java.net.URL.openConnection()から取得URLConnectionを使用しています。\nですので、pluginのインストールを行う際に、Proxy環境にある場合は以下のようにコマンドを実行します。\n./bin/plugin -DproxyPort=ポート番号 -DproxyHost=ホスト名 -i elasticsearch/elasticsearch-analysis-kuromoji/1.5.0 elasticsearch-analysis-kuromojiのインストール WikipediaのデータをKuromojiを使って、形態素解析ベースの転置インデックスを作成していきます。 まずは、Kuromojiを利用するために、Analysisプラグインのインストールです。 ElasticSearchのバージョンに対応したプラグインのバージョンがあります。(プラグインのページに対応したバージョンの記載あり) 今回はElasticSearchの0.90.3を利用しているため、1.5.0をインストールします。\n./bin/plugin -i elasticsearch/elasticsearch-analysis-kuromoji/1.5.0 インストール後は再起動しておきます。 なお、Kuromojiを利用して、Wikipediaのデータを登録するばあい、デフォルトの設定では、ヒープが足りなくなるおそれがあります。 ElasticSearchの起動時に以下のオプションを指定して、最大ヒープサイズを2Gとしておきます。\nexport ES_HEAP_SIZE=2g;./bin/elasticsearch Indexの作成(デフォルトでKuromojiのAnalyzerを利用する) Wikipediaのデータを登録する際に、Kuromojiのアナライザを利用したいのが今回の趣旨でした。 一番ラクな方法として、Wikipediaデータのインデックスの設定として、デフォルトのアナライザをKuromojiにしてしまいます。 (きちんと設計する場合は、必要に応じてフィールドごとに指定しましょう)\ncurl -XPUT \u0026#39;localhost:9200/ja-wikipedia-kuromoji\u0026#39; -d \u0026#39;{ \u0026#34;settings\u0026#34;: { \u0026#34;analysis\u0026#34;: { \u0026#34;analyzer\u0026#34;: { \u0026#34;default\u0026#34; : { \u0026#34;type\u0026#34; : \u0026#34;kuromoji\u0026#34; } } } } }\u0026#39; これでkuromojiのアナライザがデフォルトで利用される形となります。 あとは、Riverを起動して登録するだけです。\nRiverの実行 前回と一緒です。 インデックス名(_river/\u0026lt;インデックス名\u0026gt;/_meta)だけは、先ほど作成した「ja-wikipedia-kuromoji」に変更してください。\ncurl -XPUT localhost:9200/_river/ja-wikipedia-kuromoji/_meta -d \u0026#39; { \u0026#34;type\u0026#34; : \u0026#34;wikipedia\u0026#34;, \u0026#34;wikipedia\u0026#34; : { \u0026#34;url\u0026#34; : \u0026#34;file:/home/johtani/src/jawiki-latest-pages-articles.xml\u0026#34; }, \u0026#34;index\u0026#34; : { \u0026#34;bulk_size\u0026#34; : 10000 } }\u0026#39; あとは、インデックスされるのを待つだけです。\nデータ量とか 5.8gbになりました。Kuromojiを利用したため、形態素解析により単語にきちんとトークないずされた結果でしょう。 Uni-gramだと、転置インデックスのボキャブラリも単語に対してヒットするドキュメント数も大きくなるため、 インデックスサイズも大きくなっているのかと。\n検索クエリのサンプルなどはまた後日。(夜遅いので。。。)\n","date":1378138500,"dir":"post/2013/","id":"79e647a3f8b36a1221897f5837c84aff","lang":"ja","lastmod":1378138500,"permalink":"https://blog.johtani.info/blog/2013/09/03/ja-wikipedia-with-kuromoji/","publishdate":"2013-09-03T01:15:00+09:00","summary":"前々回紹介した、日本語Wikipediaのデータをインデックス登録する記事の続きです。 今回は、Kuromojiのアナライザを利用してインデッ","tags":["elasticsearch","kuromoji","wikipedia"],"title":"日本語Wikipediaをインデクシング(Kuromojiバージョン)"},{"contents":"ElasticSearch勉強会 第1回を主催しました。 昨年のpyfesでなんちゃって資料で喋って、1年たちました。\nElasticSearchの書籍(英語)も出てきて、今年はElasticSearchが面白くなりそうだし、使ってる人たちから話も聞きたいなぁということで、主催しました。\n思った以上に興味のある方がいらっしゃったようで、100人応募のところ、チケットがすぐ完売してしまうほど。。。 しかも、当日もほぼ満員ということで、大変な盛況ぶりでした。\nスピーカーの皆様、参加された皆様、会場を提供していただいたリクルートテクノロジーズさん、ありがとうございました!(たぶん、90人くらいいらっしゃってたかと。)\nこんなステキな案内板も用意してもらいました。スタッフのみなさんありがとうございます! トゥギャっても頂きました。まとめていただいてありがとうございます!\n自分の発表や個々の発表に関する感想は以下のメモに。\nElasticSearch入門 @johtani スライド:ElasticSearch入門※スライドはPDFです。\n緊張しまくりでわかりにくかったですかね。。。 とりあえず、AWSのサービスじゃないってのだけでも覚えて帰っていただければ満足です。 途中で見せたChromeプラグインのSense わからなかった点や質問、ご意見などは、当ブログのコメント、私宛の@ツイート、なんでもいいので、反応ください。なんでもいいので反応があると、今後の励みになりますので! ということで、発表でも言いましたが、わからないことがアレば、@johtaniまで投げてもらえれば、「知らない」「ブログのネタにします」「ソレはこんなかんじですかねぇ?(テキトー)」みたいに答えると思います。 Elasticsearch in Actionは帰宅中に、4章追加されたよというメールが届きました。 宿題 クラスタへのノードの追加の処理方法とか、シャーディングの実装とか。 elasticsearchプラグイン入門 ~ mocksolrpluginでSolrと入れ替えてみよう 菅谷さん スライド:elasticsearchプラグイン入門 slideshare\nプラグイン構成とか(公式でまとまってるの見つけられないので助かります。) 作る上でのポイントうれしいです。 パッケージ名変えられるとか、つらい。。。 Solr APIプラグインについて(Solrの振りしてくれる便利なヤツ) 感想 まだ、プラグインを書いたことがないのですが、ちゃんとプラグインはどういう構成で書くんですよというまとまった資料って本家のサイトにもない気がしています。 なので、スライドが公開されたらすごく役に立つかと。 そのまえに、何かプラグイン書いてみます。。。\nDebugging and testing ES systems Chris Birchallさん スライド:Debugging and testing ES systems slideshare\nテストの方法とか便利なお話(最後のほうしか聞いてなかったですが。。。。) クエリのデバッグは色々とやらないと、なんでヒットしないのってよくあるので。とくに形態素解析を利用した検索の場合、短い文章(クエリ)と長い文章(ドキュメント)で切れ目が変わってうまくヒットしないとかありますよね。 最後に少しだけ話しましたが、n-gramとKuromojiを組み合わせてOR検索とかすると良い場合があります。 インデックスが大きくなったり、OR検索なので遅くなったりというデメリットもありますが。 感想 実際に使われているノウハウを元に話をしていただいたので助かりました。 最初に席を外してたのですが、戻ってきて日本語で普通に発表されててほんとにびっくりしましたw テスト用プラグインがあるのとかは知らなかったです。 あと、使われてたIDEがIntelliJ IDEAでしたね!私も使ってます!\nニコニコ動画データセット 25億件を検索可能にしてみよう @PENGUINANA_ スライド:ニコニコ動画を検索可能にしてみよう slideshare\nkibana@cookpadのお話 どういう挙動するかをやってみればいいじゃんってことで、やってみるのカッコイイ! http://goo.gl/FYtO5T bigdeskとか。プラグインいろいろ。 感想 さすがです、ペンギン先生。大きなデータセットつかって、構築した環境に関する数値も書かれてる資料ができて素晴らしすぎです。 思った以上にサクサク動いてて、4hでインデクシングできるのもすごいなぁと。 私も見習ってこのくらいがサクッとできるようになりたい。。。 あと、発表後にムチャぶりしましたが、次回はぜひ検索側の性能とかも話してもらえたらと。\n反省点 イベントアテンドだと、キャンセル待ちができない+どのくらいの方が興味をもっているのかわからない。 イベントページの主催者は複数指定できる方がいい。(土壇場の登録の人が管理できない。私が司会やってたから) マイクが聞こえにくかった(音量調節とかちゃんと調べないと) 懇親会は立食のほうがやはり動きやすい。 懇親会が1時間ちょっとしかできなかった 雑感 ということで、ES勉強会、主催の私が一番楽しめました。ありがとうございます。 (あと、気前よく調べて答えますと言ってしまいました。。。まぁ、いいトリガーになるので、ウェルカムですが)\nやっぱりKibanaについて興味を持ってる人も多いのかなぁという感触がしたので、次回はぜひKibana3の話をしてもらえるように頑張ります。 あと、elasticsearch-headを使われてるんだなぁと。私はelasticsearch-HQを入れて使ってみてます。大きなクラスタ管理まではまだやってないので。\nあとは、やはりいろんな人に助けられてるなぁと実感しつつ、今後も開催するので助けてください!ということで。 (もちろん、Solr勉強会もがんばりますよー)\n関連ブログ ElasticSearch勉強会 第1回 - Go ahead! タムタムの日記 - ElasticSearch勉強会 の参加メモ #elasticsearchjp 第1回ElasticSearch勉強会に行ってきた! #elasticsearchjp - #侍ズム 第1回 ElasticSearch 勉強会に参加 #elasticsearchjp - seratch 他にもブログを書かれた方がいらっしゃいましたたら、リンクしたいので連絡いただければ。\n","date":1377798120,"dir":"post/2013/","id":"5931f8e3acdac724742c4ee0960d8d40","lang":"ja","lastmod":1377798120,"permalink":"https://blog.johtani.info/blog/2013/08/30/hold-first-elasticsearch-meetup-in-japan/","publishdate":"2013-08-30T02:42:00+09:00","summary":"ElasticSearch勉強会 第1回を主催しました。 昨年のpyfesでなんちゃって資料で喋って、1年たちました。 ElasticSearch","tags":["elasticsearch","勉強会"],"title":"第1回ElasticSearch勉強会を開催しました! #elasticsearchjp"},{"contents":"久々のブログはElasticSearchネタです。勉強会開催する予定だったりすので、もう少し触っておきたいなと。 お手軽に検索するデータとして、よくWikipediaのデータを使っています。 ElasticSearchにはelasticsearch-river-wikipediaという便利なプラグインがあり、Wikipediaのデータを簡単に検索可能な状態にできます。このRiverを利用して日本語のWikipediaのデータを入れたので、メモを取っておきます。 まずは、river-wikipediaで日本語のデータをインデクシングしてみるまでの説明です。 日本語特有の設定(Kuromojiを利用したインデクシング)などはまた後日。\nプラグインのインストール 対象とするElasticSearchは現時点で最新版の0.90.3とします。 最新版でRiver動かないなぁとつぶやいた影響かどうかはわかりませんが、2013/08/19に最新版のElasticSearchで動作するプラグインが公開されました。\nまずはインストールです。 HPにも書いてありますが、以下のコマンドを実行すればインストールされます。\n$ ./bin/plugin -install elasticsearch/elasticsearch-river-wikipedia/1.2.0 -\u0026gt; Installing elasticsearch/elasticsearch-river-wikipedia/1.2.0... Trying http://download.elasticsearch.org/elasticsearch/elasticsearch-river-wikipedia/elasticsearch-river-wikipedia-1.2.0.zip... Downloading ..........DONE Installed river-wikipedia into /opt/elasticsearch/plugins/river-wikipedia ElasticSearchが起動している場合はプラグインをインストール後、認識させるためにElasticSearchを再起動します。\n日本語Wikipediaのインデクシング 通常は英語のWikipediaがインデクシングされますが、対象となるファイルを変更することで日本語のWikipediaもインデクシング可能です。 手元に日本語Wikipediaのダンプファイルがあるものとします。(ダウンロードはWikipediaデータベースダウンロードのページにあるpages-articles.xml.bz2のファイルです)\nファイルを指定してインデクシングするには、つぎのcurlコマンドを実行します。 コマンドを実行するとすぐにインデクシングが始まりますので注意が必要です。\ncurl -XPUT localhost:9200/_river/ja-wikipedia/_meta -d \u0026#39; { \u0026#34;type\u0026#34; : \u0026#34;wikipedia\u0026#34;, \u0026#34;wikipedia\u0026#34; : { \u0026#34;url\u0026#34; : \u0026#34;file:/home/johtani/src/jawiki-latest-pages-articles.xml\u0026#34; }, \u0026#34;index\u0026#34; : { \u0026#34;bulk_size\u0026#34; : 1000 } }\u0026#39; ここでURLに含まれる「ja-wikipedia」がインデックス名になります。 また、JSONの\u0026quot;url\u0026quot;にはファイルの場所を指定するため、file:で開始するパスを指定します。 例では、bz2を解凍したファイルを指定していますが、bz2のままのファイルでもOKです。\n上記コマンドを実行すると、_riverというインデックスにつぎのようなエントリが増えています。 (curl -XGET 'localhost:9200/_river/ja-wikipedia/_search?pretty)\n{ \u0026#34;took\u0026#34;: 5, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 2, \u0026#34;max_score\u0026#34;: 1, \u0026#34;hits\u0026#34;: [ { \u0026#34;_index\u0026#34;: \u0026#34;_river\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;ja-wikipedia\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;_status\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;ok\u0026#34;: true, \u0026#34;node\u0026#34;: { \u0026#34;id\u0026#34;: \u0026#34;gdyvwpiAR52lqUCcRhVwsg\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Blitzschlag, Baron Von\u0026#34;, \u0026#34;transport_address\u0026#34;: \u0026#34;inet[/192.168.100.7:9300]\u0026#34; } } }, { \u0026#34;_index\u0026#34;: \u0026#34;_river\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;ja-wikipedia\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;_meta\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;wikipedia\u0026#34;, \u0026#34;wikipedia\u0026#34;: { \u0026#34;url\u0026#34;: \u0026#34;file:/home/johtani/src/jawiki-latest-pages-articles.xml\u0026#34; }, \u0026#34;index\u0026#34;: { \u0026#34;bulk_size\u0026#34;: 100 } } } ] } } \u0026quot;_id\u0026quot;: \u0026quot;_meta\u0026quot;というエントリがさきほど登録したWikipediaのRiverに関する設定です。 \u0026quot;_id\u0026quot;: \u0026quot;_status\u0026quot;というエントリが起動したRiverの状態になります。\nRiverの停止 日本語Wikipediaは結構サイズが大きく、手元のAirでインデクシングするのに30分程度かかりました。(bz2圧縮されていないファイルで、何もしていない状態)\n途中でRiverを停止したくなった場合は、以下のcurlコマンドを実行します。\n$ curl -XDELETE \u0026#39;localhost:9200/_river/ja-wikipedia\u0026#39; 先ほど設定した_river/ja-wikipediaの情報を削除すると、エントリが削除されたのを検知してRiverが停止します。ログにはつぎのようなメッセージが表示されます。\n[2013-08-26 18:26:50,130][INFO ][cluster.metadata ] [Blitzschlag, Baron Von] [[_river]] remove_mapping [ja-wikipedia] [2013-08-26 18:26:50,130][INFO ][river.wikipedia ] [Blitzschlag, Baron Von] [wikipedia][ja-wikipedia] closing wikipedia river Riverを停止してもそれまでインデクシングされたデータは検索できます。 データはちょっとだけで良いという場合は、先ほどの_riverのデータを削除してください。 (◯件だけ登録したいとかできるかは調べてないです。)\nサイズとかマッピングとか サイズ インデックス前のXMLのサイズが5.7Gのとき、ElasticSearchのインデックスサイズ(Optimize後)は7.2Gとなりました。すこし古いファイルを利用しているため、最新版とはサイズが異なるかもしれません。\nあと、データ数が、1540000件とやけにきりがいいのがちょっと気になっています。。。 bulkのサイズを10000で指定してインデックスしたので、切れてるのかなぁと。\nということは、データが欠落しているような気がするのでRiverの作りの問題なのか、ElasticSearchの問題なのかはちょっと調べてみないとわからないなと。\nマッピング 出来上がったインデックスのマッピング(Solrでいうスキーマみたいなもの)は次のようになっています。\n{ \u0026#34;ja-wikipedia\u0026#34;: { \u0026#34;page\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;category\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;disambiguation\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;boolean\u0026#34; }, \u0026#34;link\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;redirect\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;boolean\u0026#34; }, \u0026#34;special\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;boolean\u0026#34; }, \u0026#34;stub\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;boolean\u0026#34; }, \u0026#34;text\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;title\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } } } } Wikipediaの各種データが上記のフィールドに入っています。 また、マッピングタイプはデフォルトで「page」というタイプになっています。\n検索 先ほどのマッピングを元に検索すればOKです。例えばつぎのような感じです。\ncurl -XPOST \u0026#39;localhost:9200/ja-wikipedia/_search?pretty\u0026#39; -d \u0026#39; { \u0026#34;size\u0026#34; : 3, \u0026#34;script_fields\u0026#34;: { \u0026#34;title_only\u0026#34;: { \u0026#34;script\u0026#34;: \u0026#34;_source.title\u0026#34; } }, \u0026#34;query\u0026#34; : { \u0026#34;query_string\u0026#34;: { \u0026#34;default_field\u0026#34;: \u0026#34;title\u0026#34;, \u0026#34;query\u0026#34; : \u0026#34;千葉\u0026#34; } } }\u0026#39; 結果はこんな感じ。\n{ \u0026#34;took\u0026#34;: 51, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 5, \u0026#34;successful\u0026#34;: 5, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 8616, \u0026#34;max_score\u0026#34;: 5.8075247, \u0026#34;hits\u0026#34;: [ { \u0026#34;_index\u0026#34;: \u0026#34;ja-wikipedia\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;page\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;3582\u0026#34;, \u0026#34;_score\u0026#34;: 5.8075247, \u0026#34;fields\u0026#34;: { \u0026#34;title_only\u0026#34;: \u0026#34;千葉\u0026#34; } }, { \u0026#34;_index\u0026#34;: \u0026#34;ja-wikipedia\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;page\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;2352241\u0026#34;, \u0026#34;_score\u0026#34;: 4.94406, \u0026#34;fields\u0026#34;: { \u0026#34;title_only\u0026#34;: \u0026#34;千葉千枝子\u0026#34; } }, { \u0026#34;_index\u0026#34;: \u0026#34;ja-wikipedia\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;page\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;14020\u0026#34;, \u0026#34;_score\u0026#34;: 4.8754807, \u0026#34;fields\u0026#34;: { \u0026#34;title_only\u0026#34;: \u0026#34;千葉千恵巳\u0026#34; } } ] } } 結果を見やすくするため、タイトルだけを「title_only」という表示にしています。 ただ、この検索だと、一見「千葉」できちんとヒットしているように見えますが、ElasticSearchのフィールドの定義はstring型になっています。なので、実は「千」や「葉」だけのデータもヒットしています。 マルチバイト文字は1文字ずつインデックスされてしまい、query_stringというクエリでは、フレーズ検索などができていないためです。\nまとめ プラグインいれて、XMLファイルがあれば、検索できるデータが出来上がるので、 暇があったら、お試しで触ってみるデータを簡単に入れてみてはどうでしょうか。\nただ、いくつか気になる点も。\n日本語が検索しにくい(string型のフィールドなのでuni-gramっぽくなっている) bulk_sizeの影響で端数が登録できてない(バグ?どうなの?) ということで、ちょっと使いにくいかもなぁということで、つぎはKuromojiを利用してインデックスしてみてみようかなと。次回のエントリで書く予定です。\n","date":1377226920,"dir":"post/2013/","id":"3931327ed463d1568868c5ab8e839148","lang":"ja","lastmod":1377226920,"permalink":"https://blog.johtani.info/blog/2013/08/23/index-wikipedia-ja-to-elasticsearch/","publishdate":"2013-08-23T12:02:00+09:00","summary":"久々のブログはElasticSearchネタです。勉強会開催する予定だったりすので、もう少し触っておきたいなと。 お手軽に検索するデータとして","tags":["elasticsearch","wikipedia"],"title":"ElasticSearchにプラグインで日本語Wikipediaデータを入れてみました"},{"contents":"宿題その2?かな。Solr勉強会でCloudera Searchのスキーマ周りってどうなってるの?という質問が出てて、 なんか調べることになってたので、関係しそうなMorphlinesのLoadSolrコマンドを調べてみました。 こいつが、Solrへの書き込みを実行するコマンドみたいだったので。\n(※Cloudera Searchのスキーマの設定方法とかは調べてないです。)\n(※めんどくさかったので、パッケージ名すっ飛ばしてクラス名書いてます。githubへのリンクを代わりに貼ってます。)\nRecord=Solrのドキュメント convert()メソッドにて、MorphlinesのRecord(コマンドの処理するデータの1単位)に格納されているKey-ValueデータをSolrInputDocumentクラスのフィールドとして格納しています。 Recordにもフィールドという概念があり、Recordのフィールド=Solrのフィールドという事みたいです。\nということで、Solrのフィールドは事前に定義しておき、Morphlinesの処理内部でSolrのフィールド名に値を詰めていく感じでしょうか。 別途、sanitizeUnknownSolrFildsというコマンドが用意されていて、Solrのスキーマにないものはこのコマンドを使って、無視するフィールド名に変えたり、雑多なデータを入れるためのフィールド名にするといった処理ができるようです。このコマンド内部で、Solrのスキーマ設定を元に、Solrのフィールドに合致する物があるかをチェックして処理しています。\nSolrへの登録処理は? Solrへの登録処理自体はLoadSolrクラス内部でDocumentLoaderというクラスのload()メソッドを呼び出しているだけでした。ということで、DocumentBuilderクラスを少し調査。\nDocumentLoader IFでした。。。実クラスは次の条件\nSolrMorphlineContextにDocumentLoaderがあればそちらを採用(他の種類はなにがあるんだろ?) なければ、SolrServerDocumentLoaderをnewしたものを利用 2.の場合がおそらくMapReduceではないパターンのloadSolrだと思われます。SolrServerDocumentBuilderはSolrJのAPIを利用して、Solrへデータ登録していく普通のアプリです。(対象とするSolrは外部に起動しているもののはず=FlumeのSolrSinkではこちらを採用かな?)\nSolrへの接続情報とか設定ファイルとかSolrCloud用のZooKeeperとかはSolrLocatorクラスに設定される内容が利用されます。\n1.のパターンは、どうやら、Cloudera SearchのMapReduceIndexerToolのクラスにあるMyDocumentLoaderかなぁと。 こちらは、MapReduceを利用する場合に、利用されてるっぽいです(ちゃんと見てないけど) 内部処理は、HadoopのContext.writeメソッドにでSolrInputDocument(=MorphlinesのRecord)を書きだして、ReducerでSolrOutputFormatでインデックス作成の流れかなと。たぶん、MorphlineMapRunnerあたりを読みこめば解読できるかと。 ちなみに、こちらは、2.とは異なり、SolrLocatorの設定は無視されそう。\n感想+妄想? ということで、Morphlinesのデータ流れを考える上で、現時点ではSolrのスキーマを頭の片隅に置きつつ、 Recordの中にあるデータをゴニョゴニョしてデータを形成していくって感じになりそうです。 うまく処理できなかったものとかのカウントとかもとれたりするのかなぁ?とか、また色々と気になるところが出てきますが、一旦ここまでで。。。(だれか、続きを調べて書いてみてくれてもいいんですよ!コマンドもいっぱいあるし!)\nとまぁ、こんなかんじでMorphlinesをちょっとだけ読みました。 よくよく考えたら、こんなの作ったことあるなぁと(こんなに汎用的じゃないけど)。 みんな同じ事考えるんですねぇ。 コマンドパターン?みたいな感じで、I/F決めてSolrとか別のシステムとかにデータ入れる処理を順番に記述できる的なバッチ処理良くかいてます(書いてましたのほうが正解かなぁ)。\n","date":1375434120,"dir":"post/2013/","id":"33e01e2271be22b5ed330045fe6aff50","lang":"ja","lastmod":1375434120,"permalink":"https://blog.johtani.info/blog/2013/08/02/morphlines-loadsolr/","publishdate":"2013-08-02T18:02:00+09:00","summary":"宿題その2?かな。Solr勉強会でCloudera Searchのスキーマ周りってどうなってるの?という質問が出てて、 なんか調べることになって","tags":["Cloudera Search","Morphlines","Solr"],"title":"MorphlinesのloadSolrをちょっとだけ調べてみた"},{"contents":"今朝起きたら、Xperia Zが故障してしまいました。 電源ボタンを押してもスリープにならないんです。しかも、スリープからの復帰もできない。。。\nということで、ドコモショップに行って来ました。対応も良かったです。 やっぱり、ボタンがおかしく再起動してもNGでした。 ということで、トントン拍子で交換品に変更してもらえました。\n2、3回繰り返し言われましたが、データなくなりますよ&交換品なので、復旧はご自分でとのこと。 ドコモショップ行く前に「Sony Bridge for Mac」というSony製のアプリでバックアップ取ってたし問題ないですと回答して、交換してもらいました。 最後に使ってないオプションとか要らないのでやめたほうが安くなりますよなどの提案もいただき満足でした。 さらに、前の機種に貼ってたフィルムもきちんと張り替えてもらえたし。時間はちょっとかかったけど。\nで、先ほど帰宅して、朝とっておいたバックアップから復旧しようとしたら。\n**「そんなバックアップありません」**みたいなメッセージが表示されて復旧出来ません。。。\nえ?なにそれ?と思い、とりあえず現時点のデータをバックアップ取ってみるかと。 バックアップ取ったあとに、再度復旧しようとしたらちゃんとリストがでてくるじゃないですか。\nなんだこれ?ということで、ファイル探しです。。。\n「Sony Bridge for Mac」バックアップファイルは次の場所に保存されるみたいです。\n/Users/ユーザ名/Library/Application Support/Sony Ericsson Bridge for Mac/Backups/製品番号みたいな文字列/日付 この最後のディレクトリが製品番号?ごとのディレクトリっぽく、2つありました。 どうせ初期化された状態だしということで、古い日付フォルダを新しい製品番号のフォルダにコピーしたら復元は可能でした。 壁紙の設定は再起動したら復活しましたが、復活してないものも。。。 復活してないのは以下のものです。\nインストールしてたアプリ ホーム画面の配置 アカウント色々(Google Playとか) ということで、スマホでインストールするのもだるくなってきたので、PCで黙々とGoogle Playのサイトからインストールしてますが、これもだるいですね。。。\n必要なアプリインストールし直したら、またSonyのアプリで復旧してみて、設定が復活するのを祈って。。。\n続き インストールしなおして、ホーム画面での配置をがんばりました。 Google Playのサイトから既存アプリをインストールするときに、ブラウザバックで戻ってたのですが、 一覧から別タブにインストールしたいアプリのページを開きまくってから、インストールボタン押すのが楽でした(半分くらい終わった所で気づいた。。。)\n一通りインストールしたあとに、ホーム画面の配置をやり直して、「Sony Bridge for Mac」もう一回復元。 twiccaやブクログなど、個別にアカウントとか設定を管理しているアプリについては復活しました。\nけど、Androidがアカウントを管理するもの(例:Facebookなど)については、残念ながら、一部のものはアカウントを再登録しないといけませんでした。\n写真や音楽についてはもともとSDカードに入れていたのもあったので、まぁ、被害は少なかったかなぁと。\nただ、iPadやiPhoneの用に簡単にバックアップ(アプリの情報、配置まで)ができて復元できると助かるなぁと思いました。(今度はホーム画面のキャプチャ撮ってから修理に出すかなぁ。。。)\n","date":1375364280,"dir":"post/2013/","id":"cd9ba1f582642d9cbe500f018afab341","lang":"ja","lastmod":1375364280,"permalink":"https://blog.johtani.info/blog/2013/08/01/replace-xperia-z/","publishdate":"2013-08-01T22:38:00+09:00","summary":"今朝起きたら、Xperia Zが故障してしまいました。 電源ボタンを押してもスリープにならないんです。しかも、スリープからの復帰もできない。。。","tags":["Xperia Z"],"title":"Xperia Zが故障したので交換したのでメモ"},{"contents":"Morphlinesについてちょっとだけ、さらに調べました。\n誤解 Solr勉強会でなんとなく私の認識を話しましたが、ちょっと誤解してたみたいです。スミマセン。\n誤解:Morphlineというプラットフォーム/ミドルウェアがありそうなイメージ まぁ、書いてあるのでちゃんと読めって話ですが、Morphlineはあくまでライブラリだということでした。 私はなんとなくManifoldCFのようなミドルウェアorプラットフォームが存在して、 そこにFlumeのSinkとかMapReduceによるIndexerが動作するのかと思ってました。\nまぁ、これが間違いでした。正解のイメージはこっちですね。\n各プラットフォーム(FlumeとかHadoopとか)に組み込んむライブラリで、 それぞれ組み込んだ先でMorphlineの設定を記述することで、パイプライン処理ができるっぽいです。\nFlumeについては、MorphlineSolrSinkというクラスでMorphlineの設定ファイルを読み込み、いろいろ処理出来ます。\nMap/ReduceだとCloudera Searchに含まれてるMapReduceIndexerToolがMorphlineの設定を読み込んでコマンド実行してくれるみたいです。 MapReduceIndexerToolはまだちゃんと読んでないのですが、MapperとしてMorphlineのコマンドが実行されるのかなぁ?という感じです。 (結構入り組んでるので、ちゃんと読まないとわからない。。。)\nということで、Morphlineというプラットフォームがあって、一元的にFlumeやMap/Reduceに対するコマンドをパイプライン化するという話でありませんでした。\n※ちなみに、上の画像ですが、愛用しているNUBoardを使って書いてます。 考えをまとめるのにすごく役立つ一品です。持ち運び可能なノート型ホワイトボードです。\n疑問点 ただ、読んでてまだ不明な点があります。まぁ、ぼちぼち調べるかなぁと。。。\nSolrのschemaはどーなってんの? MorphlineにSolrへロードするコマンド(loadSolr)があるけど、FlumeのMorphlineSolrSinkってのもSolrに書き込みそうだけど? Map/ReduceでSolrに書き込むもMorphlineのコマンドとの違いは?(前にソースを見たときはSOLR-1301がベースになっていて、SolrOutputFormatってクラスがEmbeddedSolrServer起動してインデクシングしてた) GoLiveってなんだろ?(MapReduceIndexerToolに入ってて、M/Rでインデックス作ったあとにSolrのクラスタに配布+マージするやつっぽい) どんなコマンドがあるの?(Cloudera Morphlines Ref Guide) 以下は、参考資料と参考資料にあるSlideshareの資料を一部訳したものになります。\n参考資料 Using Morphlines for On-the-Fly ETL(slideshare) cloudera/cdk/cdk-morphlines(github) メモ 現在のコマンドライブラリ(スライド 18-19ページ) Solrへのインテグレートとロード フレキシブルなログファイル解析 1行、複数行、CSVファイル 正規表現ベースのパターンマッチと展開 Avro、JSON、XML、HTMLのインテグレーション Hadoop シーケンスファイルのインテグレーション SolrCellとApache Tikaパーサすべてのインテグレーション Tikaを利用したバイナリデータからMIMEタイプの自動判別 動的Javaコードのスクリプティングサポート フィールドの割り当て処理、比較処理 リストやセット書式のフィールド処理 if-then-else条件分岐 簡易ルールエンジン(tryRules) 文字列とタイムスタンプの変換 slf4jロギング Yammerメトリックとカウンター ネストされたファイルフォーマットコンテナの解凍 などなど プラグインコマンド(スライド 20ページ) 簡単に新しいI/Oや変換コマンドが追加可能 サードパーティや既存機能のインテグレード CommandインタフェースかAbstractCommandのサブクラスを実装 Javaクラスパスに新規作成したものを追加 登録処理などは必要ない 新しいプラグインコマンドとして考えられるもの(22ページ) RDBやKVSやローカルファイルなどの外部データソースをレコードにjoin DNS名前解決とか短縮URLの展開とか ソーシャル・ネットワークからリンクされたメタデータのフェッチ(??) レコードの感情分析とアノテーション? 31ページの図がわかりやすいかも\n以上。\n","date":1375265520,"dir":"post/2013/","id":"b875f24d3d444fdda82b6bbfb75a4c92","lang":"ja","lastmod":1375265520,"permalink":"https://blog.johtani.info/blog/2013/07/31/introduction-morphlines/","publishdate":"2013-07-31T19:12:00+09:00","summary":"Morphlinesについてちょっとだけ、さらに調べました。 誤解 Solr勉強会でなんとなく私の認識を話しましたが、ちょっと誤解してたみたいで","tags":["Cloudera Search","Morphlines","Solr"],"title":"Morphlines入門?"},{"contents":"不定期開催ですが第11回Solr勉強会を主催しました。\n今回も大入り90人くらい?の参加者の皆さんがいらっしゃいました。ありがたいことです!(20時時点で最終的に補欠17人でした。)\nとりあえず、第一報です。このあと懇親会なので。\nということで、帰りの電車でいくつか感想を(忘れちゃうから)。\n小林さんの苦労話は細かいですが、結構はまりがちな点を共有していただいたので良かったかなぁと。 Solrのexampleの設定とか、ManifoldCFとかちょっとずつ罠があったりするので、あるあるネタはありがたいと思いますw\nCloudera Searchについては、安定の嶋内さんの喋りに圧巻でした。検索だけの視点とは異なる観点についての 話は私には足りないしてんだったりするので参考になります。 なんか、気づいたらMorphlineやスキーマ周りを調べてブログ書くことになっちゃったけど。。。 一つ質問しそこねたのがあって、Cloudera社は基本的に公開したOSSについてのトレーニングも立ち上げているイメージです。Cloudera Searchについてもトレーニングが立ち上がるのかなぁと密かに期待をしてみたり(予算の関係上参加できるかは不明ですが。。。)\n牧野さんの話は画像系について、私は詳しくないので、また関口さんのalikeと比較とかしてもらえると面白いかなぁと。とりあえず、青いロボットがちゃんと検索できるようになるといいですねww\n秀野さんの空間検索は緯度経度以外のPOLYGONなどを利用した検索で、実は私も知らない機能でしたw\nなとなくは知ってたんですが、そこまでちゃんと検索できるとは!地図以外にも活用できるような気がします(想像つかないんだけど。。。)\n最後は私の発表で、簡単な資料ですみませんでした。しかも発表よりも宣伝が。。。(ブログの宣伝だったりとか。。。) 最後に宣伝した「「ビッグデータ活用を支えるOSS」特集への論文投稿のご案内」もご検討ください!\n懇親会も楽しかったです。また思いついたら開催しますー\n最後に、今回の発表者の皆様、会場提供していただいたVOYAGE GROUPの皆様ありがとうございました!\n以下はいつものメモです。\nManifoldCFのとSolrの組み合わせ(仮)株式会社 ロンウイット 大須賀さん 残念ながら、発熱のため発表は次回に持ち越しに。\n##社内ファイル及びWEBコンテンツの検索システム構築時に苦労したこと ソフトバンクBB㈱ 小林さん\nManifoldCF+Solrを使って社内ファイルの検索システム構築 約1000万ドキュメント さまざまなDCにドキュメントがある クロールジョブのハング。。。 ログをDEBUGにしたら。。。ログファイル150GB。。。 一定時間ごとにAgentをリスタートするバッチを。。。(力技) MCFエラーによるジョブの停止 CONNECTORS-590 エラーが発生して止まったジョブを起動するバッチをcronで。。。 自作リアルタイムインデクシングの問題 MCF使わないでSlaveにインデックス openSearcher=falseだとautoCommitが実行されてもSearcherを再起動しないので検索にでてこない リプリケーションのNW負荷 別DCからのレプリケーションが複数が一度に実施される→ネットワーク負荷が。。。 cronで別々にレプリすることでNW負荷を分散できてるかな。。。 Cloudera Search 入門(仮) Cloudera 株式会社 嶋内さん マサカリ画像がw SolrのコミッターMark Millerさんもジョインしてる ClouderaとHadoop入門とか。 いろいろあるよ、エコシステム 4つの分類。 データの取り込み データの保存 データの活用 Search 検索エンジンなら数十億人が使い方を知ってる(Clouderaのチャールズ・ゼドルースキ) Cloudera Search Hadoopのためのインタラクティブな検索\nCDHとSolrの統合\nOSS!\n利点とか。\nデータ解析にも使えるよね、検索 非構造化データの検索にもいいよね 単一プラットフォームによるコスパ Cloudera Searchの事例 バイオテクノロジー企業で画像検索とか 医療系企業でいろんなログイベントの管理とか Cloudera Searchのアーキテクチャ Flumeでストリーミングで登録 HBaseデータの登録 M/Rでバッチ登録 HueのWebインタフェース Morphlines、HBaseはLinyプロジェクトのもの\nSolr使うならCDH!!\nQA Q:デモで使われたTwitterの検索のデータ料とかは?\nA:デモ環境ですので小さい。\nQ:スキーマってどうするの?\nA:スキーマは。。。私が書こうかなぁ、ブログ。。。\nコンピュータビジョン 株式会社 Curious Vehicle 牧野さん 色々やってます コンピュータビジョンの説明(某ネコ型ロボットのいろんな画像がw) 画像検索の流れ 特徴情報の抽出 特徴情報のクラスタリングによるword化 Solrによる画像情報の検索 1. 特徴情報の抽出 SIFT特徴点解析 グレースケールしてからSIFT 注意!SIFTは商用ライセンスが必要です 2. 特徴情報のクラスタリングによるword化 K-meansでクラスタリング クラスタ情報をヒストグラム化してSolrへ 3. Solrによる画像情報の検索 物体認識ベンチマークセット(ケンタッキー大)を使って。 やっぱり良し悪しある。データセットに特化したチューニングしてます。 つぎのステップ 文字認識とか顔認識 つぎはドラえもんじゃねぇ、検索とかも。。。 ガウシアンによる画像ぼかしの例 QA マイク回しててメモ取れず。。。\n国土交通省のデータをSolrで検索 株式会社ネクスト 秀野さん スライドはこちら\n評価の関係で。。。 Spatial検索の話 デモの想定機能 地図上の小学校を起点に物件検索 地図上をクリックしたところを中心に検索 デモ環境 Solr4.3.0、PostGIS 2.0.3、東京都のデータ 事前知識 ジオメトリーデータ(点、線、面がある) WKB/WKT、Intersects(しらなかった。こんなのもあるのか) 環境 EC2上にPostGIS+Solrで構築 WKT形式でDIHでインポートできるらしい。 Solr+S3をJSでGoogleMapへ Solr 4.4新機能をちょっと紹介 @johtani 紹介というよりも宣伝。。。\n","date":1375107300,"dir":"post/2013/","id":"59d1b7206e7664e76672d3de4dc9a8ed","lang":"ja","lastmod":1375107300,"permalink":"https://blog.johtani.info/blog/2013/07/29/study-of-solr/","publishdate":"2013-07-29T23:15:00+09:00","summary":"不定期開催ですが第11回Solr勉強会を主催しました。 今回も大入り90人くらい?の参加者の皆さんがいらっしゃいました。ありがたいことです!(","tags":["Solr","Cloudera Search","ManifoldCF"],"title":"第11回Solr勉強会を主催しました。#SolrJP"},{"contents":"Hadoopとか離れちゃってるし、Hive触ったこと無いにもかかわらず参加しました!\n(たまたま近くにいるからって理由なのは内緒で)\n玉川さんの四方山話を聞くのが主目的で参加しました。(ちょっと翻訳が気になってるので)\nイベントページはこちら\n刊行記念イベントにも関わらず、想像以上の人の入りでびっくりしました。Hadoop、Hive界隈はまだまだ人気なんだなぁと。\nプレゼントじゃんけん大会もあったのですが、そうそうに負けてしまったのが悔やまれます。。。\nTeam Geek欲しかったなぁ。もちろん、懇親会まで参加しました。\n以下、いつものメモです。\nHiveの正しい使い方(Cloudera 嶋内さん) 残念ながら、マサカリは持ってなかったです。\nスライドの各所に本の章番号が書いてあるのがうれしい。 Hiveロゴが回ってたのでスライドの時に集中できなかったw Impalaの話も出てきた。 速いけど、色々足りない。Hiveの置き換えじゃないよと。 HiveとImpalaのおいしいとこ取り(セラン 須田さん) スライド:http://www.slideshare.net/sudabon/20130724-oreilly-org\nオンプレだとCDH便利だよと教えてもらう いくつかSlideshareにImpalaの性能評価の資料を上げてある(必要になったら検索で。。。) リリースされたその日に性能評価やってレポート書くとかすごすぎ! 翻訳の四方山話(玉川さん) 翻訳=写経です 締め切り駆動勉強法w 4page/day 自分から電突してオライリーさんに翻訳させてくださいと。 他の方の本が読めない(チェックしちゃうのでw) 動機があるから読めるってのはあるだろうなぁ。 選び方:わくわくするもの、仕事に活きるもの 今年もあと2冊やる予定(Hadoop Operations、Vagrantを翻訳中) 来年の候補(Chefとか) 高可用性HDFSのご紹介(Cloudera 小林さん) スライドにどの版で書いてあったかがわかりやすく書いてある。 3段階の開発フェーズを経てる QJMのお話 Cloudera UniversityとHadoop認定試験(Cloudera 川崎さん) Clouderaデータアナリスト向けトレーニング(3日間、10月日本語で開催予定) Hive、Pig、Impalaなど Data Science入門コースも準備中 出版記念! 8月管理者向け先着20 or 30名にHadoop第3版贈呈予定 先着20名にプログラミングHive贈呈予定 ","date":1374685860,"dir":"post/2013/","id":"1b9c5ae60ec46be64a1877f0c6920edc","lang":"ja","lastmod":1374685860,"permalink":"https://blog.johtani.info/blog/2013/07/25/hadoop-hive-publication-party/","publishdate":"2013-07-25T02:11:00+09:00","summary":"Hadoopとか離れちゃってるし、Hive触ったこと無いにもかかわらず参加しました! (たまたま近くにいるからって理由なのは内緒で) 玉川さんの","tags":["Hadoop","Hive","Cloudera","オライリー"],"title":"『プログラミング Hive』 『Hadoop 第3版』刊行記念セミナーに参加しました! #oreilly0724"},{"contents":"Yokozunaの気になる点というか、自分だったらこのへん調べるだろうなって観点を上げてみます。 別に調べるわけじゃないので、完全に自己満足なメモですけど。\nちなみに、分散システムとかRiakの仕組みは詳しくないので、ズレてる点がいっぱいあるかも。\nというか、分散システムでテストというか、検討する点とかってまとまってる資料とかあるのかなぁ?\nスキーマ変更時の挙動 フィールド型変更とか、フィールド追加とか 既存RiakクラスタにYokozunaの機能を追加する方法と制限 タイムラグとかも Riak+Yokozunaクラスタに対してノード追加時に発生するオーバーヘッド(ネットワークとかディスクIOとか) 性能検証のためのシナリオ(どっちが先に悲鳴をあげるかとか) Riakメインで、Yokozunaはおまけ程度に検索するというシナリオ Yokozunaメインで使うシナリオ 更新が多い場合のシナリオ Riakのみ、Riak+Yokozunaの各種統計情報(CPU、メモリ、ディスクサイズ、ネットワークIO) 運用系(監視とか)の手法とか機能?とか バージョンアップなどの対応方法 Solrがコケた時とかの対処 とりあえず、こんな感じかなぁ。\n","date":1373474580,"dir":"post/2013/","id":"50557b455cba1a3ce9b4555fc3fd5433","lang":"ja","lastmod":1373474580,"permalink":"https://blog.johtani.info/blog/2013/07/11/yokozuna-check-point/","publishdate":"2013-07-11T01:43:00+09:00","summary":"Yokozunaの気になる点というか、自分だったらこのへん調べるだろうなって観点を上げてみます。 別に調べるわけじゃないので、完全に自己満足な","tags":["Riak","Solr","Yokozuna"],"title":"Yokozunaの気になる点というかなんというか"},{"contents":"先日、Bashoさんにおじゃましたのもあり、Riak Meetup Tokyo #2に参加しました。\nYokozunaの話も聞けるということで。 懇親会も参加しました。Vさん&リピさんと話し込んじゃってあんまり他の人と話せなかったけど。。。\n以下はいつものメモです。\nFreakOut 久森さん 「Riak環境をプロダクションで構築&運用してみた(仮)」 FreakOutとRTB ディスプレイ広告の新しい配信の枠の話 この人には何出すの?いくらで?みたいな感じ 純広告:表示保証、期間保証など RTB:1回の広告表示ごとに買い付け DSP(デマンド・サイト・プラットフォーム) 広告表示は大体0.1秒で表示しないといけない。この間に色々やってる。 50ms or die.で戦ってます。 RTBはCPUバウンド 多コアを安く並べたい Tokyoなんとかとか使ってた。 スケーラビリティがキツイ(クライアント側でアルゴリズム分散してる) データ解析もしたいけど、検索ができない RTBに適したRiakがうまくハマるのではと。 構成とかとか アプリはPerlなので、PerlでRiakクライアントが必要。Memcached互換とかあると嬉しい。 ProtobufサポートもPurePerlしかなかった。 ないなら、作ろうと。githubに上がってます。このへんかな? 監視はcloudforecastとかでやってる。 課題 Redirectがつらい(haproxy?がつらい?) Setが詰まるとつらい(ケースがまだわからない) 対策1 memcached+Riak 対応2(案) hashからpartitionに直接取りに行くとか まとめ 素のままRiakはちょっとつらい QA 聞き取れたやつだけ\nQ:1台いくら位ですか? A:10万から11万くらい Q:どのくらいの性能ですか? A:同時1000くらいをさばいてる? Q:50ms以下を出すのに、ネットワーク周りで近さとかを考えることありますか? A:国内だと10msあればなんとかなる。それよりもアプリ側のチューニングのほうがまだ重要 Q:Cassandraとか候補に挙がらなかったんですか? A:苦しんでる人が知人にいるので。。。あと、用途的に違うので。 Q:バックエンドとしてはなにを? A:bitcaskにしてる Q:サーバ構成、ネットワーク構成がどうなってる? A:。。。 Q:Redirectとは?RiakがやってるRedirect? A:はい。 Q:他に候補にあがったのは? A:商用のaerospike(これかな?)がスケールできそうだったけど、クライアントがいまいち。。。 感想 広告業界のことをよくわかってないので、微妙にピンときてなかったりもするのですが、以下に素早く返すかって観点でどこに注力して、問題点を潰していくのかってのは面白そうだなぁと。 リクエスト処理の性能がクリアできたらつぎはスケールの観点(ノード追加時の挙動とか)で検証していくんだろうなと。次回の話も聞いてみたい感じです。\nIIJ 曽我部さん、田中さん 「Yokozuna 日本語検索性能を評価しました」 Yokozunaって? Riak+Solrでいいとこ取り データの登録とかはRiakのAPIで。 SolrのAPIが使える。 YokozunaがSolrの分散検索の部分を隠してくれる。 Yokozunaのインストールとか。 SolrのAPIっぽい形で検索できるし、戻りもSolrのXMLっぽいのが出てくるよ。 Wikipediaデータってstoreの性能とか。 Riakのノード32台。(Xeon、メモリ24GB、HDD。。。) yz_extractor:Riakのコンテンツタイプを見てSolrにデータを入れる処理が書いてある。 自分でschema.xmlを書いてYokozunaに指定することもできる。 スキーマの変更とか登録とか。 すでに指定済みスキーマを変更した場合の挙動ってどうなるの? デモではSolrからid取って、Riakからその他のデータを取り出していた。 Rubyでの性能評価 ベンチマークプログラム側の問題が先に影響が出てしまった。 QA Q:Riak単体とYokozunaつかった時でディスク容量がどのくらい増えた? A:ちゃんと調べてないが、10%くらい増えた気がする。 Q:Solr側の設定でstored=trueだけど、falseにしてもいいんじゃないの? A:デモはfalseにしてます。 Q:スキーマってあとから変更できるんですかね? A:まだ良くわかってないです。 Q:ノードの追加、削除時の挙動とかも気になります。 感想 今回はStore性能に関してでしたが、今後は検索性能やシナリオによる性能(KVSの処理メインで、時々全文検索とか、全文検索の処理も結構あるパターンとか)の測定とか、耐障害性とかの観点で調査を進めてもらってSolr勉強会で話をしてもらえると面白そうだなぁと勝手に思ってみたり。 Solr勉強会へのコンタクトお待ちしてます!w\n","date":1373450220,"dir":"post/2013/","id":"146e8ca40c0d37f36eecea822028dd9e","lang":"ja","lastmod":1373450220,"permalink":"https://blog.johtani.info/blog/2013/07/10/riak-meetup-tokyo-no2/","publishdate":"2013-07-10T18:57:00+09:00","summary":"先日、Bashoさんにおじゃましたのもあり、Riak Meetup Tokyo #2に参加しました。 Yokozunaの話も聞けるということで。 懇親会も参加しました。","tags":["Riak","Yokozuna","Solr"],"title":"Riak Meetup Tokyo #2に参加しました。#riakjp"},{"contents":"Solr 4.4に取り込まれる予定のチケットで、気になるものを見つけたのでいつものごとく調べてみました。\n元となるチケットはこちら。SOLR-4897。\nスキーマレス? Solrはschema.xmlにデータの定義(フィールドタイプやフィールドなど)を記述して、データを登録する全文検索システムです。 これまでのSolrではこの設定ファイルを元にデータを登録するフィールド名を決定しており、 変更を行う場合はSolrのコアを再起動するなどの手順が必要でした。(※ダイナミックフィールドはすこし特殊)\nそれだと、Solrを管理するのがめんどくさいですね?という感じで現れたのがSchemaREST APIです。(たぶん。)\nSchema REST API Solr 4.2から導入されたSolrのスキーマに関する情報を提供するためのREST APIです。 4.2で導入されたのはあくまでもschema.xmlの情報を取得するためのAPIでした。 たとえば、Fieldの一覧を取得するとか。\n4.4から、フィールドの追加(変更、削除はできない)ができるようになりました。あくまでも、フィールドの追加で、フィールドタイプなどの追加はまだできません。(できるようになるのかもわからないですが。) フィールドの追加方法などはWikiに記載がありました。\nということで、簡単に試してみることに。\n起動方法 exampleディレクトリの下にexample-schemalessというディレクトリが新設されています。 ここに、スキーマレスモード用の設定がされているファイルが入っているので、こちらを利用します。\ncd $SOLR/example java -Dsolr.solr.home=example-schemaless/solr -jar start.jar ログにいくつかWARNが出ますが、影響の内パス設定ミスなので無視してOKです。\n最初に定義されているフィールドは「id」と「_version_」のみになります。(Schema Browserなどで確認できます。あ、REST APIでもいいですね。http://localhost:8983/solr/schema/fields)\nスキーマの更新 さて、フィールドを追加してみます。 PUTを利用すると1フィールドの追加が可能です。 「fugatext」というフィールド名でフィールドを追加しています。今のところJSONのみ対応みたいです。\n$ curl -X PUT http://localhost:8983/solr/schema/fields/fugatext -H \u0026#39;Content-Type: application/json\u0026#39; -d \u0026#39;{\u0026#34;type\u0026#34;:\u0026#34;text_ja\u0026#34;,\u0026#34;stored\u0026#34;:false,\u0026#34;multiValued\u0026#34;:true}\u0026#39; { \u0026#34;responseHeader\u0026#34;:{ \u0026#34;status\u0026#34;:0, \u0026#34;QTime\u0026#34;:18}} 追加できたかどうかもREST APIで取得してみます。\n$ curl http://localhost:8983/solr/schema/fields { \u0026#34;responseHeader\u0026#34;:{ \u0026#34;status\u0026#34;:0, \u0026#34;QTime\u0026#34;:0}, \u0026#34;fields\u0026#34;:[{ \u0026#34;name\u0026#34;:\u0026#34;_version_\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;long\u0026#34;, \u0026#34;indexed\u0026#34;:true, \u0026#34;stored\u0026#34;:true}, { \u0026#34;name\u0026#34;:\u0026#34;fugatext\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;text_ja\u0026#34;, \u0026#34;multiValued\u0026#34;:true, \u0026#34;stored\u0026#34;:false}, { \u0026#34;name\u0026#34;:\u0026#34;id\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;string\u0026#34;, \u0026#34;multiValued\u0026#34;:false, \u0026#34;indexed\u0026#34;:true, \u0026#34;required\u0026#34;:true, \u0026#34;stored\u0026#34;:true, \u0026#34;uniqueKey\u0026#34;:true}]} 追加できました。 ちなみに、同じフィールド名を追加しようとするとエラーが帰ってきます。\n$ curl -X PUT http://localhost:8983/solr/schema/fields/fugatext -H \u0026#39;Content-Type: application/json\u0026#39; -d \u0026#39;{\u0026#34;type\u0026#34;:\u0026#34;text_ja\u0026#34;,\u0026#34;stored\u0026#34;:false,\u0026#34;multiValued\u0026#34;:true}\u0026#39; { \u0026#34;responseHeader\u0026#34;:{ \u0026#34;status\u0026#34;:400, \u0026#34;QTime\u0026#34;:1}, \u0026#34;error\u0026#34;:{ \u0026#34;msg\u0026#34;:\u0026#34;Field \u0026#39;fugatext\u0026#39; already exists.\u0026#34;, \u0026#34;code\u0026#34;:400}} 設定の違い example-schemalessのsolrconfig.xmlは以下の設定が通常のexampleとは異なるようです。\nschemaFactoryの設定 schemaをAPIから変更可能にする設定です。これまでの変更しない設定の場合はClassicIndexSchemaFactoryを指定します。\n... \u0026lt;schemaFactory class=\u0026#34;ManagedIndexSchemaFactory\u0026#34;\u0026gt; \u0026lt;bool name=\u0026#34;mutable\u0026#34;\u0026gt;true\u0026lt;/bool\u0026gt; \u0026lt;str name=\u0026#34;managedSchemaResourceName\u0026#34;\u0026gt;managed-schema\u0026lt;/str\u0026gt; \u0026lt;/schemaFactory\u0026gt; ... update.chainの設定 更新処理(update関連のリクエストハンドラ「/update」とか)には次のような設定が追加されていました。(1006行目あたり)\n\u0026lt;requestHandler name=\u0026#34;/update\u0026#34; class=\u0026#34;solr.UpdateRequestHandler\u0026#34;\u0026gt; \u0026lt;!-- See below for information on defining updateRequestProcessorChains that can be used by name on each Update Request --\u0026gt; \u0026lt;lst name=\u0026#34;defaults\u0026#34;\u0026gt; \u0026lt;str name=\u0026#34;update.chain\u0026#34;\u0026gt;add-unknown-fields-to-the-schema\u0026lt;/str\u0026gt; \u0026lt;/lst\u0026gt; \u0026lt;/requestHandler\u0026gt; 「add-unknown-fields-to-the-schema」というupdate.chainが指定されています。このchainの定義自体は1669行目くらいに存在します。 (長い。。。)\n\u0026lt;!-- Add unknown fields to the schema An example field type guessing update processor that will attempt to parse string-typed field values as Booleans, Longs, Doubles, or Dates, and then add schema fields with the guessed field types. This requires that the schema is both managed and mutable, by declaring schemaFactory as ManagedIndexSchemaFactory, with mutable specified as true. See http://wiki.apache.org/solr/GuessingFieldTypes --\u0026gt; \u0026lt;updateRequestProcessorChain name=\u0026#34;add-unknown-fields-to-the-schema\u0026#34;\u0026gt; \u0026lt;processor class=\u0026#34;solr.RemoveBlankFieldUpdateProcessorFactory\u0026#34;/\u0026gt; \u0026lt;processor class=\u0026#34;solr.ParseBooleanFieldUpdateProcessorFactory\u0026#34;/\u0026gt; \u0026lt;processor class=\u0026#34;solr.ParseLongFieldUpdateProcessorFactory\u0026#34;/\u0026gt; \u0026lt;processor class=\u0026#34;solr.ParseDoubleFieldUpdateProcessorFactory\u0026#34;/\u0026gt; \u0026lt;processor class=\u0026#34;solr.ParseDateFieldUpdateProcessorFactory\u0026#34;\u0026gt; \u0026lt;arr name=\u0026#34;format\u0026#34;\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd\u0026#39;T\u0026#39;HH:mm:ss.SSSZ\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd\u0026#39;T\u0026#39;HH:mm:ss,SSSZ\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd\u0026#39;T\u0026#39;HH:mm:ss.SSS\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd\u0026#39;T\u0026#39;HH:mm:ss,SSS\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd\u0026#39;T\u0026#39;HH:mm:ssZ\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd\u0026#39;T\u0026#39;HH:mm:ss\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd\u0026#39;T\u0026#39;HH:mmZ\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd\u0026#39;T\u0026#39;HH:mm\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd HH:mm:ss.SSSZ\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd HH:mm:ss,SSSZ\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd HH:mm:ss.SSS\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd HH:mm:ss,SSS\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd HH:mm:ssZ\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd HH:mm:ss\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd HH:mmZ\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd HH:mm\u0026lt;/str\u0026gt; \u0026lt;str\u0026gt;yyyy-MM-dd\u0026lt;/str\u0026gt; \u0026lt;/arr\u0026gt; \u0026lt;/processor\u0026gt; \u0026lt;processor class=\u0026#34;solr.AddSchemaFieldsUpdateProcessorFactory\u0026#34;\u0026gt; \u0026lt;str name=\u0026#34;defaultFieldType\u0026#34;\u0026gt;text_general\u0026lt;/str\u0026gt; \u0026lt;lst name=\u0026#34;typeMapping\u0026#34;\u0026gt; \u0026lt;str name=\u0026#34;valueClass\u0026#34;\u0026gt;java.lang.Boolean\u0026lt;/str\u0026gt; \u0026lt;str name=\u0026#34;fieldType\u0026#34;\u0026gt;booleans\u0026lt;/str\u0026gt; \u0026lt;/lst\u0026gt; \u0026lt;lst name=\u0026#34;typeMapping\u0026#34;\u0026gt; \u0026lt;str name=\u0026#34;valueClass\u0026#34;\u0026gt;java.util.Date\u0026lt;/str\u0026gt; \u0026lt;str name=\u0026#34;fieldType\u0026#34;\u0026gt;tdates\u0026lt;/str\u0026gt; \u0026lt;/lst\u0026gt; \u0026lt;lst name=\u0026#34;typeMapping\u0026#34;\u0026gt; \u0026lt;str name=\u0026#34;valueClass\u0026#34;\u0026gt;java.lang.Long\u0026lt;/str\u0026gt; \u0026lt;str name=\u0026#34;valueClass\u0026#34;\u0026gt;java.lang.Integer\u0026lt;/str\u0026gt; \u0026lt;str name=\u0026#34;fieldType\u0026#34;\u0026gt;tlongs\u0026lt;/str\u0026gt; \u0026lt;/lst\u0026gt; \u0026lt;lst name=\u0026#34;typeMapping\u0026#34;\u0026gt; \u0026lt;str name=\u0026#34;valueClass\u0026#34;\u0026gt;java.lang.Number\u0026lt;/str\u0026gt; \u0026lt;str name=\u0026#34;fieldType\u0026#34;\u0026gt;tdoubles\u0026lt;/str\u0026gt; \u0026lt;/lst\u0026gt; \u0026lt;/processor\u0026gt; \u0026lt;processor class=\u0026#34;solr.LogUpdateProcessorFactory\u0026#34;/\u0026gt; \u0026lt;processor class=\u0026#34;solr.RunUpdateProcessorFactory\u0026#34;/\u0026gt; \u0026lt;/updateRequestProcessorChain\u0026gt; 使ってるUpdateProcessorはこんな感じみたいです。最後の2つはこれ用じゃないので省略。\nプロセッサ名説明 RemoveBlankFieldUpdateProcessorFactory値がないフィールドは除去 ParseBooleanFieldUpdateProcessorFactoryスキーマに定義されていないフィールドで、値がBooleanとしてパースできたら、Boolean型とする。 ParseLongFieldUpdateProcessorFactoryスキーマに定義されていないフィールドで、値がLongとしてパースできたら、Long型とする。 ParseDoubleFieldUpdateProcessorFactoryスキーマに定義されていないフィールドで、値がDoubleとしてパースできたら、Double型とする。 ParseDateFieldUpdateProcessorFactoryスキーマに定義されていないフィールドで、値がDateとしてパースできたら、Date型とする。(パースの形式がformatで列挙されてる) AddSchemaFieldsUpdateProcessorFactory入力されたドキュメントの中でスキーマに定義されていないフィールド(静的、動的両方)を見つけた時に、フィールドの値の型を元にフィールド型をマッピングする。 とここまで見てきたところで、スキーマレスという名前の意図がちょっとわかったかも。\n定義されてないフィールドを持ったデータを登録 起動時には定義されてないフィールドをもったデータを登録してみます。 boolean型で試してみることに。以下のデータを管理画面のデータ登録画面から登録します。(http://localhost:8983/solr/#/collection1/documents) (タイトルでbooleanってわかりにくいですが)\n{\u0026#34;id\u0026#34;:\u0026#34;change.me\u0026#34;,\u0026#34;title\u0026#34;:true, \u0026#34;price\u0026#34;:1.25, \u0026#34;fuga\u0026#34;:\u0026#34;100,200\u0026#34;} エラーは出ません。で、またフィールド一覧を取得すると。\n$ curl http://localhost:8983/solr/schema/fields { \u0026#34;responseHeader\u0026#34;:{ \u0026#34;status\u0026#34;:0, \u0026#34;QTime\u0026#34;:1}, \u0026#34;fields\u0026#34;:[{ \u0026#34;name\u0026#34;:\u0026#34;_version_\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;long\u0026#34;, \u0026#34;indexed\u0026#34;:true, \u0026#34;stored\u0026#34;:true}, { \u0026#34;name\u0026#34;:\u0026#34;fuga\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;tlongs\u0026#34;}, { \u0026#34;name\u0026#34;:\u0026#34;fugatext\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;text_ja\u0026#34;, \u0026#34;multiValued\u0026#34;:true, \u0026#34;stored\u0026#34;:false}, { \u0026#34;name\u0026#34;:\u0026#34;id\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;string\u0026#34;, \u0026#34;multiValued\u0026#34;:false, \u0026#34;indexed\u0026#34;:true, \u0026#34;required\u0026#34;:true, \u0026#34;stored\u0026#34;:true, \u0026#34;uniqueKey\u0026#34;:true}, { \u0026#34;name\u0026#34;:\u0026#34;price\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;tdoubles\u0026#34;}, { \u0026#34;name\u0026#34;:\u0026#34;title\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;booleans\u0026#34;}]} おー、最後にtitleが追加されてます。他にもfugaやpriceも。(日付は手を抜きました。。。)\n感想 詳細までは追いかけてないですが、こんなかんじです。 フィールド追加が可能になるのはいいんじゃないでしょうか。SolrCloudの機能との関連もあるのかもしれません。ZooKeeperへの出力も実装されてそうなので。\nただ、機械的に出力されたschema.xml(exampleだとmanaged-schemaというファイル)には_「DO NOT EDIT」_との記述があるので、修正するとなにかおきてしまうかもしれないですねぇ。 現時点では、フィールドタイプの変更やフィールドの更新、削除に関してはSolrCoreの再起動などの手順が必要です。 あと、変なデータ(タイプミスとか)が登録されたりしないかってのは気になりますね。\n※ちなみに、別の人が気づいたんですが、ちょっとバグが有ったみたいで、代わりにチケットつくったらキリ番(SOLR-5000) ゲットしましたw\n","date":1372867920,"dir":"post/2013/","id":"a98d42be181c01b8077e060b1b5080ec","lang":"ja","lastmod":1372867920,"permalink":"https://blog.johtani.info/blog/2013/07/04/schemaless-example/","publishdate":"2013-07-04T01:12:00+09:00","summary":"Solr 4.4に取り込まれる予定のチケットで、気になるものを見つけたのでいつものごとく調べてみました。 元となるチケットはこちら。SOLR-4897","tags":["Solr"],"title":"スキーマレスモード?(SOLR-4897)を調べて見ました。"},{"contents":"SolrのチケットをML経由で眺めてるんですが、便利そうなチケットが流れてきたのでブログを書いてみみようかと。 元になってるチケットはこちらです。昨日だか、今朝にtrunkとbranch_4xにコミットされたみたいです。試してみたい方は、branch_4xかtrunkをチェックアウトすると触ることができます。\nデータ登録用の画面(JSON) branch_4xをチェックアウトしてexampleを起動し、Solrにアクセスします。\n管理画面に「Dcuments」という項目が追加されてます。開くとこんなかんじです。\nなんと、デフォルトはJSONになってます。これも時代の流れでしょうかw\nSolrでは、これまで設定ファイルやデータ登録もXMLがメインになっていました。(Apache Solr入門もXMLを基本に書いてます。このころはまだデフォルトでは対応してなかったので)\n登録するデータをテキストエリアに記述して、「Submit Document」をクリックすればデータは登録されます。基本的には単件登録の画面でしょうか。 (登録されたデータを確認するには「Query」画面を利用すればいいです。) また、JSONのデータ形式はSolrのWikiを参照してください。\nCSVやXMLも この管理画面ではJSON以外の形式でもデータの登録が可能です。 「Document Type」の項目をクリックすると以下のように選択肢があられます。\nCSV、XMLについては、先ほどのJSONの画面の用に、テキストエリアが表示されます。 テキストエリアにCSV(データの形式はこちら)やXML(データの形式はこちら)を入力してボタンを押せば登録できます。\nSolr Command形式も(JOSNかXML) Solr Command というのはXMLやJSONで登録、コミット、削除などを実行するための画面になります。 JSONのコマンドはこちら、XMLのコマンドはこちらをご覧ください。\nあと、便利なのがファイルアップロードです。 こんなかんじで、ファイルを選んでSubmitすればデータが登録出来ます。\nファイルのサイズが大きいとちょっと時間がかかりますが、コマンドを打つより簡単かもしれません。 post.jarツールと違って、デフォルトでコミットをしてくれるわけではないので、「Extracting Req. Handler Params」に「commit=true」をつけないと、データが登録されてない?と思ってしまうかもしれませんが。\n組立もできるみたい(Document Builder) 最後に紹介するのが「Document Builder」というタイプです。\nもっと簡易にデータを記述できるようにということで用意されているようです。 フィールドの情報はSolrに接続して利用できるフィールド?(ダイナミックはないのかな?)が表示されます。\n追記していくとこんなかんじになります。\n日本語のデータもちゃんと登録できました。 ただ、まだ、開発中なんでしょうがないかもしれませんが、以下の様な制約があるようです。\nmultiValuedなフィールドに値を追加できない(上書きされる) 改行が入ったデータをテキストエリアにいれると「Add Field」を押しても反応しない ダイナミックフィールドは自分で書きましょう ただ、これまでXMLでファイルを作ってコマンドで登録したり、curlコマンドでJSON書いたりして登録していたよりはお手軽にさわれるようになるかと思います。つぎの4x系のバージョンが出たときはこちらからデータを登録してみてください。\n","date":1372318080,"dir":"post/2013/","id":"ecf3ac80454654d990d9c07d33d35d1c","lang":"ja","lastmod":1372318080,"permalink":"https://blog.johtani.info/blog/2013/06/27/upload-docs-solr-admin/","publishdate":"2013-06-27T16:28:00+09:00","summary":"SolrのチケットをML経由で眺めてるんですが、便利そうなチケットが流れてきたのでブログを書いてみみようかと。 元になってるチケットはこちらで","tags":["Solr"],"title":"Solrの管理画面でデータ登録"},{"contents":"前回は3番煎じぐらいでしたが、今回は初記事かな?(だといいな)\nKibanaには、前回の記事で書いたものとは別に開発中のKibana3というのが存在します。\nKibana3って? Kibana2はRubyで書かれていましたが、Kibana3はHTML+JavaScriptで構成されています。 ですので、ApacheなどのWebサーバに配置することで、利用が可能となります。 ただ、HTML+JavaScriptのため、ブラウザ上で動作するためブラウザが動作するマシンからElasticSearch(通常だとhttp://マシン名orIPアドレス:9200/とか)にアクセスできなければいけないという制限があります。\nこの条件さえクリア出来れば、Kibana3ではKibana2よりも様々なパネルが用意されていて、色々できそうなのでお勧めです。\nインストール ElasticSearchやログについては、前回の記事の環境を利用しました。 ですので、Kibana3のインストールのみです。(ApacheもCentOSのサーバに入っていたので。)\nダウンロードして、Apacheの公開ディレクトリに置いただけです。(お試し環境のため、権限とかは大目に見てください。\n$ git clone https://github.com/elasticsearch/kibana.git kibana-javascript $ cp -R kibana-javascript /var/www/html 今回はApacheとElasticSearchが同一マシン(=同一IPアドレスでアクセス可能)で動作している+ElasticSearchへのアクセスのポートがデフォルト(9200)のため特に設定が必要ありませんでした。\nElasticSeachサーバとKibana3のApacheのサーバが別のサーバの場合やElasticSearchサーバのポートが異なる場合はkibana-javascript/config.jsファイルの編集が必要になります。 cloneしてすぐのconfig.jsは、以下のとおりです。\n/* elasticsearch: URL to your elasticsearch server. You almost certainly don\u0026#39;t want \u0026#39;http://localhost:9200\u0026#39; here. Even if Kibana and ES are on the same host kibana_index: The default ES index to use for storing Kibana specific object such as stored dashboards modules: Panel modules to load. In the future these will be inferred from your initial dashboard, though if you share dashboards you will probably need to list them all here If you need to configure the default dashboard, please see dashboards/default */ var config = new Settings( { // By default this will attempt to reach ES at the same host you have // elasticsearch installed on. You probably want to set it to the FQDN of your // elasticsearch host elasticsearch: \u0026#34;http://\u0026#34;+window.location.hostname+\u0026#34;:9200\u0026#34;, // elasticsearch: \u0026#39;http://localhost:9200\u0026#39;, kibana_index: \u0026#34;kibana-int\u0026#34;, modules: [\u0026#39;histogram\u0026#39;,\u0026#39;map\u0026#39;,\u0026#39;pie\u0026#39;,\u0026#39;table\u0026#39;,\u0026#39;stringquery\u0026#39;,\u0026#39;sort\u0026#39;, \u0026#39;timepicker\u0026#39;,\u0026#39;text\u0026#39;,\u0026#39;fields\u0026#39;,\u0026#39;hits\u0026#39;,\u0026#39;dashcontrol\u0026#39;, \u0026#39;column\u0026#39;,\u0026#39;derivequeries\u0026#39;,\u0026#39;trends\u0026#39;,\u0026#39;bettermap\u0026#39;], } ); ポート番号が異なる場合は、1つ目の「elasticsearch:」で指定されている「9200」を環境に合わせて編集するだけになります。 Kibana3とElasticSearchのホストが異なる場合は、1つ目の「elasticsearch:」の行をコメントアウトし、2つ目を有効にしてから環境に合わせたURLに修正して保存すればOKです。\n以上で、インストールは完了します。あとは、以下のURLにアクセスするだけです。\nhttp://hogehoge/kibana-javascript/ 画面構成 アクセスすると次のような画面が表示されます。\n初期画面 左上に赤い帯で、「 Oops! Could not match index pattern to any ElasticSearch indices」とエラーが表示されました。\nKibanaはElasticSearchに「logstatsh-年.月.日」という日付ごとのインデックスが存在することが前提となっています。 Kibanaに初めてアクセスした場合、「logstash-当日日付」で始まるインデックスを描画しようとします。 これは、私が前回利用したElasticSearchの環境に古いデータ(試したのが19日、データは10日のみ)しか入っていないために出たエラーです。\n日付は「Options」というエラーが出ている付近の「Absolute」というリンクをクリックすると、特定の日付をカレンダーで指定することができるようになります。データは6/10にしか入っていないので、6/10(12時くらいから20時くらいまで)のを指定します。\n日付指定 選択すると無事データが見えるようになりました。\nデータ描画 ダッシュボードの構成(初期) Kibana3では、この画面をダッシュボードというようです。 このダッシュボードは初期状態では、以下のパーツが表示されています。(子要素があとで説明するパネル名です)\nOptions:描画対象の日付の指定やダッシュボードの保存などを行うRow timepickerパネル:日付の指定 dashcontrolパネル:ダッシュボードの制御(保存とか) Query:ログ検索式を入れるところ stringqueryパネル Graph:ヒストグラムの描画(X軸:時間、Y軸:ログ件数) histogramパネル Events:検索にヒットしたログデータの描画領域 fieldsパネル:表示するフィールドの選択(左側。チェックを入れると右側のログ表示領域のカラムが増える) tableパネル:ログデータ(右側。左側でチェックが入ったカラムだけが表示される。) あくまで初期表示です。各パーツの設定アイコン(歯車のマーク)をクリックすると色々と設定が可能です。 また、「Events」など名称はクリック可能となっていて、クリックすると、そのパーツが折りたたまれた状態にすることも可能です。\n折りたたんだ状態 ダッシュボードの設定 ダッシュボードには独自のパネルを簡単に追加することができます。 ダッシュボードの構成はページの一番上にある「Logstash Search」の設定アイコンをクリックすると設定画面が開きます。\nダッシュボード設定 「New row」にタイトル名を適当にいれて「Create Row」するとあたらしくパネルを追加することができるRowが追加されます。「Rows」の「Move」にある矢印でRow自体の表示場所を上下に移動することも可能です。\nRowの設定 追加した「Hoge」にパネルを追加する場合はHogeの上にある設定アイコンをクリックすると設定画面が開きます。\nRowの設定 ここでKibana3で用意されているパネルの追加ができます。\nPanel追加ボタン パネルを選んでボタンを押せばすぐに表示されます。\nパネルの羅列 こんな感じです。とりあえず、ポコポコと追加してみました。\n利用できるパネルの種類は以下の様なパターンです。 適当ですが、表にしてみました。\nパネル名概要 columnRowの中にパネルを配置するコンテナを用意するためのパネル dashcontrolダッシュボードの保存、保存したダッシュボードの表示などの操作ボタン textmarkdown形式などで記述が可能な文章を表示できるパネル stringquery検索クエリ入力用パネル derivequeriesフィールドと検索式がわかれた形式の検索入力用パネル timepickerログ表示の期間を指定するパネル histogramログの件数のヒストグラム表示用パネル hitsヒット件数表示用パネル pieパイチャート表示用パネル trends指定された時間でデータの増減を%表示するパネル sortソート条件指定用のプルダウン表示用パネル(変更したらtableの内容がソートされる) tableログデータ表示用パネル fieldstableパネルに表示するフィールドを選択するための補助パネル bettermapなんか地図が出てきたパネルGeoJSONデータをゴニョゴニョ(表示かな?)できるみたい mapなんか世界地図が出てきたパネル2文字の国コード(jaとかか?)かU.S.の州コードのデータを元に地図に色をつけるのかな? これらのパネルは個々に色々と設定が可能です。他にもdebug、map2など有りそうでしたがまだ使えないみたいです。\n適当に触ってて気づいた注意点です。\ntableは1ダッシュボードで1つだけが良さそう。 2つあると、どちらかにしか描画されない。columnに入れるとグルーピングできたりするのかなぁ? stringquery、timepickerも1ダッシュボードで1つが良さそう。 これもtableと似たような理由です。 ダッシュボード保存し忘れて泣きそうになる JSで実装されてて、自分で色々とカスタマイズできるのですが、保存するのを忘れて泣きそうになりましたw カスタマイズしたダッシュボードについては、ローカルに保存する以外にElasticSearchにも保存ができるみたいです。チームで共有することもできそうです。 derivequeriesを表示するとグラフがカラフルに derivequeriesを追加したらグラフが急にカラフルになりました。 どうもderivequeriesのFieldの部分を変更すると、そのフィールドの値を元にグラフを細分化してくれるようです。色の数の上限はderivequeriesのLength属性の数値で制御出来ます。(5だと5個まで色が出る) histogramのパネルで自分でクエリを記載することも可能です。ただ、derivequeriesのフィールド変更すると書き換わっちゃいます。。。 derivequeriesを追加したらカラフルに ヒストグラムは色々なパターンのグラフを描画できました。ラインによる描画(histo1)、総数を100%としたパーセンテージでの表示(histo2)、ライン+点による描画(histo3)などです。\nヒストグラムのいくつかのパターン 感想 ということで、適当にですが触ってみました。 Kibana2はApacheのアクセスログとかの表示しかできない感じがしましたが、Kibana3だといろいろなデータを描画できそうだなと。 logstash形式のインデックスを用意するのが前提になってるので、時系列データをグラフ描画するのに向いてるんでしょうか。 お手軽にグラフ化できるし、自分でダッシュボードをカスタマイズできるのは素敵です。 ただ、クエリとグラフの関係などはちょっと癖があるかもしれないので、色々と試してみないといけないかもしれないです。 (たとえば、特定のフィールドの値について「A、B、その他」みたいなグラフの描画とかをどうするかとか)\n地図の描画は試してみたいかなぁ。\n","date":1371652980,"dir":"post/2013/","id":"26c47355cbe966a94826cbe2fbf2b355","lang":"ja","lastmod":1371652980,"permalink":"https://blog.johtani.info/blog/2013/06/19/introduction-kibana3/","publishdate":"2013-06-19T23:43:00+09:00","summary":"前回は3番煎じぐらいでしたが、今回は初記事かな?(だといいな) Kibanaには、前回の記事で書いたものとは別に開発中のKibana3というの","tags":["elasticsearch","kibana"],"title":"Kibana3というのもありまして"},{"contents":"ちょくちょく書こうと言いながら、前の記事が1週間以上前になってる。。。\n昨日は、Basho Japanに遊びに行って来ました。 (Riak触ったことないのに。。。Erlangも。。。ゴメンナサイ)\nRiakにSolrを組み合わせたYokozunaというものの名前を最近耳にしていたので、どんなものなのかなぁと興味がありまして。Solrがどんな使い方をされているのかってのが気になったので、 情報交換したいなぁと思っていたところ、Vの人が調整してくれたので色々と有意義な話ができたかなぁと。 (Yokozunaについての最新のスライドはBerlin Buzzword 2013のものがここに) Twitter上で見かけたことのある方々と話ができたり面白かったです。(やっぱ英語で会話できたりスラスラと読めるの必要だよなぁと痛感したりもしました。。。)\nということで、遊びに行ったのに美味しいピザやこんなおみやげまでもらってしまいました。 (ピザの写真撮るの忘れてたw)\nRiak&Bashoグッズ ちなみに、Yokozunaですが、Riakに登録したデータを裏で起動しているSolにデータを流しこんでくれるものになります。 Solrの機能としては分散検索(Distributed Search)と呼ばれる仕組みを利用しているようです。 YokozunaのI/Fとしては、Solrのインデックスの分散構成は隠してくれていて、かつ、Solr(っぽい?)リクエストを投げれば裏の分散構成に問い合わせた結果をSolrのレスポンスの形で返してくれます。 KVSに全文検索の機能がついてくるお得感が満載な気がしますw。\nRiak自身のデータの取り扱いがどんなものかをまだちゃんと理解していないので(ゴメンナサイ。Little Riak Bookは開いてるんですが読んでなくて。。。)またおじゃましてもう少し情報交換したいかなぁとw。\nCloudera Searchといい、Yokozunaといい、Solrを利用したものが少しずつ増えてきて嬉しい限りです。 Solrの作りがしっかりしている?活発?、だから取り込む形が多いんですかねぇ。 Solr本を書いてから数年たちますが、やっと検索のニーズが出てきたのかもしれないなぁと思ってみたり。 (流れのつながりはあまりないですが)ElasticSearchも少しずつ人気が出てきてるし、日本語の本とかのニーズあったりするかなぁ?\n","date":1371603780,"dir":"post/2013/","id":"33919e866426ce8e7b2ce06f19bbf889","lang":"ja","lastmod":1371603780,"permalink":"https://blog.johtani.info/blog/2013/06/19/visited-basho/","publishdate":"2013-06-19T10:03:00+09:00","summary":"ちょくちょく書こうと言いながら、前の記事が1週間以上前になってる。。。 昨日は、Basho Japanに遊びに行って来ました。 (Riak触ったこ","tags":["Riak","Basho","Yokozuna","Solr"],"title":"Basho Japanに遊びに行きました"},{"contents":"Lucene/Solr 4.3.1のRCのVoteが始まっていますが、そのMLできになったコトがあり、ちょっと調べたので メモを残しておきます。\nマルチコアの設定ファイルであるsolr.xmlの記述方法と、コアの探索ロジックが4.4(実装的には4.3から入っている)から変更されるようです。4.x系の最新版である、branch_4xのexampleディレクトリにあるsolr.xmlも新しい記述に変更されていました。\n参考URL 新しいCore探索(4.4以降) 新しいsolr.xml(4.4以降) 4.3までのsolr.xml ちなみに、最後のold styleと呼ばれる4.3までの記述方法はつぎの5.0ではDeprecatedになるようです。(5.0がいつ出るのかはわからないですが。)\nCore探索ロジック 4.4から、$SOLR_HOMEディレクトリ以下の探索ロジックは次のようになるようです。 以下では、「新スタイル」(4.4以降の書式)、「旧スタイル」(4.3以下の書式)として記述します。\nsolr.xmlファイルの存在チェック solr.xmlが存在しない場合→旧スタイルとして処理→3へ(旧スタイル) solr.xmlが存在し\u0026lt;cores\u0026gt;タグが存在しない場合→2へ(新スタイル) solr.xmlが存在し\u0026lt;cores\u0026gt;タグが存在する場合→3へ(旧スタイル) 新スタイルのロジック SOLR_HOMEディレクトリに存在するディレクトリについて以下の処理を繰り返す SOLR_HOME/ディレクトリ/core.propertiesファイルが存在する→後続処理へ。存在しなければ終了 SOLR_HOME/ディレクトリ/conf/solrconfig.xmlを読み込み、コアを起動 旧スタイルのロジック これまで同様、solr.xmlの\u0026lt;core\u0026gt;タグの記載内容を元にコアを起動(instanceDir以下のconf/solrconfig.xmlを使って) solr.xmlが存在しない場合はSOLR_HOME/collection1/conf/solrconfig.xmlが存在するものとしてコアを起動 このようなロジックになります。\nちなみに、以下の場合はエラーとなりSolrは起動しますがログや管理画面にエラーである表示がされます。\n2.3でsolrconfig.xmlが見つけられなかった場合 3.1で\u0026lt;core\u0026gt;タグが存在しなかった場合(この場合、ログにはエラーが出ません) propertiesに記述できる内容やsolr.xmlの記述内容については、Wikiを見てもらうということで。。。 CoreAdminHandlerでコアを生成したりした場合に、新スタイルの設定がどのように出力されるのかといった点が気になりますが、また今度にでも。\n","date":1370945460,"dir":"post/2013/","id":"78292d953eafbdf9e57cc4bbbe6e8964","lang":"ja","lastmod":1370945460,"permalink":"https://blog.johtani.info/blog/2013/06/11/new-solr-xml/","publishdate":"2013-06-11T19:11:00+09:00","summary":"Lucene/Solr 4.3.1のRCのVoteが始まっていますが、そのMLできになったコトがあり、ちょっと調べたので メモを残しておきます。 マルチコアの設定ファ","tags":["Solr"],"title":"新しいsolr.xmlとCore探索ロジック"},{"contents":"もう何番煎じだ?ってくらい書かれてますが、コリもせず書いてみました。 Elasticsearch+Kibanaの環境を作って、タムタムさんのログ生成ツールからApacheのダミーログを流しこんで入れてみました。\n参考URL memorycraftさんのブログ Kibana Elasticsearch fluentd apache-loggen インストールと起動 今回はCentOSへのインストールです。 基本的にはmemorycraftさんのブログの流れのままです。\nelasticserchのインストールと起動 ダウンロードして、起動するだけ。 お試しということで、-fオプションにてコンソールにログ出力。\ncurl -OL https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-0.90.1.tar.gz tar zxvf elasticsearch-0.90.1.tar.gz cd elasticsearch-0.90.1 ./bin/elasticsearch -f Kibanaのインストールと起動 git cloneしてbundleインストール\ngit clone --branch=kibana-ruby https://github.com/rashidkpc/Kibana.git cd Kibana bundle install ruby kibana.rb これで、Kibana+ESのインストール+起動が完了。 下地が完了。\ntd-agentのインストールと起動 ログの流し込みはlogstashなのですが、fluentdのelasticsearchプラグインにて流しこむこともできます。 td.repoとしてtd-agentのリポジトリを登録してから以下を実行します。\nyum install td-agent -y /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-elasticsearch vim /etc/td-agent/td-agent.conf /etc/init.d/td-agent start これで、td-agentがインストール出来ました。 次は設定です。\n\u0026lt;source\u0026gt; type tail format apache path /var/log/httpd/dummy_access_log tag dummy.apache.access \u0026lt;/source\u0026gt; \u0026lt;match *.apache.*\u0026gt; index_name adminpack type_name apache type elasticsearch include_tag_key true tag_key @log_name host localhost port 9200 logstash_format true flush_interval 10s \u0026lt;/match\u0026gt; 以上が設定です。td-agentはtd-agentというユーザで起動されるので、/var/log/httpdディレクトリにアクセスできるかだけ確認が必要です。\nいくつかの設定値について気になったので調べました。\nindex_name:adminpackとなってるが、elasticsearchではlogstash-xxxとなってる。 これは、logstash_formatがtrueの場合は、利用されないので、指定しなくてもいい。 type_name:Elasticsearchのタイプ名 * これはlogstash_formatを指定しても有効。ただし、Kibana側で画面からのtype指定は不可能。KibanaConfig.rbにて指定することは可能。 logstash_format:Kibana用にlogstashフォーマットで出力するオプション この指定があるときは、index名が「logstash-YYYY.mm.dd」となる record(ログ)に@timestampとして時刻が追加される。 tag_key:include_tag_keyがtrueと指定されているため、record(ログ)にtag_keyで指定した文字列をキー、値としてtagの値(上記例だとdummy.apache.access)が付与されて登録される。 apache-loggenのインストールと起動 タムタムさんが作成されたApacheのログのダミーを生成するツールです。\ngem化されてるので、インストールは非常に簡単です。\ngem install apache-loggen で、ログを出力します。出力先は先程設定したdummy_access_logです。\napache-loggen --rate=10 --progress /var/log/httpd/dummy_access_log 秒間10アクセスログを出力してくれます。 これで、Kibanaでログが見れるようになりました。 なんて簡単なんでしょう。。。 簡単なログの検索ができてしまいました。 他の形式のログがどうなるのかとかは、また時間があれば。。。\n感想とか 非常に簡単でした。素敵です。いくつかこうなるのかな?というのを試してみたのでメモを。\nいくつか疑問点です。\n溜まったログの削除は手動? おそらく。日付ごとにindexが出来上がっているので、削除は楽そう。「logstash-年月日」なので。 認証とかかけれるの? ログ検索は内部でするだろうから、まぁ、なくていいのかな。ログインすらないし。 複数行のログとかってどーすんだろう?(JavaのExceptionとかが混ざるやつ) 本格的に触るようになれば調べるかなぁ。。。\nあと、ログが増えてきた時にどういった分割構成ができるだろう?って思って考えてみたのが以下になります。\n構成パターン ログを複数扱う場合は次のようなパターンがありそうかと。\nタグ(fluentdのタグ)で識別 「@log_name」という名前=fluentdのタグにてログを識別することで、異なるログを検索することができそうです。 タグであれば、プラグインによってはログ出力時に制御も可能だと思うので、td-agentの設定を変更したりすることもなく対応が可能かと。 ただ、ログの種別ごとにKibanaのプロセスを別にして起動したいといった用途には向いてなさそうです。\ntype_nameによる識別 ElasticSearchの機能であるtypeを利用したログの識別パターンです。\nfluent-plugin-elasticsearchの設定でtype_nameを指定しました。 ここを別の名前にすることで、識別することも可能です。\nただし、この場合はKibanaの画面から指定して検索することができません。 →コメント頂きました。検索条件に「_type:タイプ名」と検索することでtypeを利用した検索が可能です。\nタグ(@log_name)でも識別できるようにするなどの工夫が必要です。 その代わり、タグ識別ではできなかったKibanaのプロセスを別にして起動することは可能になります。\nKibanaConfig.rbのTypeに値を設定することで、起動したKibanaが対象とするログを絞り込むことが可能です。 こうすることで例えば、apache用のKibanaとtomcat用のKibanaは別プロセスにして、ElasticSearchのクラスタは1つという構成も可能になります。\nElasticSearchサーバを別立て ElasticSearchサーバをそもそも別のプロセスor別のサーバで起動し、Kibanaも別々にすればログの識別も可能です。 可能ですが、色々と管理するものが増えてめんどくさそうですね。。。\nインデックス名変更 最後は、fluent-plugin-elasticsearchの設定で「logstash_format」をfalseにすれば、好きなindex_nameを付与できるので、 ログ種別ごとに名前を変更することで識別できます。\nただ、logstash形式でないインデックス名の場合、日付ローテーションができなかったり、Kibana内部で検索時に日付で検索対象を絞り込んで検索することで高速化するといった処理など、使えない機能が多々出てきてしまうのであまりおすすめじゃないかと。。。\nということで、流行りものは触っておこうということで、さわってブログ書いてみました。\n開発中に立てておいて、各サーバのログを流しこんでおくなどにも利用できるかもしれないです。 アラート通知などの機能が出てくるともっと便利かもしれないです。\n","date":1370874840,"dir":"post/2013/","id":"c4d3a917f623f58646ce93015d79e8e0","lang":"ja","lastmod":1370874840,"permalink":"https://blog.johtani.info/blog/2013/06/10/fluent-es-kibana/","publishdate":"2013-06-10T23:34:00+09:00","summary":"もう何番煎じだ?ってくらい書かれてますが、コリもせず書いてみました。 Elasticsearch+Kibanaの環境を作って、タムタムさんのロ","tags":["kibana","elasticsearch","fluentd"],"title":"apache-loggen + fluentd + elasticsearch + kibana = ログ検索デモ"},{"contents":"昨日に引き続き、AWS Summit Tokyo 2013に行ってきました。\n@ryu_kobayashiさんからパシリを仰せつかるなどあり、忙しかったのですが楽しかったです。\n今日もすごい人出で、昼時の展示ブースは人だかりで、TDの方たち忙しそうでした。 後半はちょっとつかれたなぁ。 1日目よりも空調の温度が上がってたので快適でした。 飲物忘れたので、ちょっと喉がやられ気味でしたが。\nAWSはやっぱり勢いがあるんだなぁってのを実感しました。JAWS-UGまで残った感想です。 あとは、セルフハンズオンに参加するんだったかなぁというのもちょっとあります。あんまり触ったことないんで。\n以下はいつものメモです。\nAmazon Redshiftが切り開くクラウド・データウェアハウス 自己紹介と流れとニュース 6/5からTokyoリージョンでも利用可能に! Redshiftどんなもの? Redshift=クラウド型データウェアハウス オンプレの課題 初期投資、運用管理、費用対効果 EMRと同じで、分析処理向けのサービス 簡単な利用例 各種データストア→S3→Redshift 各種データストア→EMR→Redshift Data Pipelineでデータの流れの処理がかける。 データロードはパラレルに実行可能 バックアップは管理コンソールからボタンででも可能。 クラスタのリサイズも管理コンソールからできるよ。 NRIでの評価 2012年末の限定公開してすぐに先行評価に参加\nRedshiftの性能は?\n500億件からの検索処理(1週間分のデータを抜き出して処理するSQL) 8XLノード2ノードで43秒、4ノードで27.8秒、8ノードで19秒 データロドも線形に性能が上がる 1.2億件の検索処理は4ノードより8ノードのほうが性能劣化 EMRとRedshiftの比較。1.5TB、500億件でのJOIN+集計処理でRedshiftのほうが早かった。 Redshiftのチューニングポイント\nインデックスが存在得ず、Distribution Keyでノードに分散 Sort Keyも重要。データロード時間はSort Keyをつけると遅くなる ニガテなデータ形式もあるよ。EMRとかの組み合わせにすると安く済むこともあるよ\n簡単につくれるので、気をつけましょう。セキュリティとか。統制されないものが乱立してくるんで。\nそこでNRIですよ!(宣伝) 出てきた性能に関するものだけど、「ケース1」「ケース2」とかってなってるので、その部分の詳細が書かれたレポートが公開されないとどんなのがニガテなのかとかわからなかった。\n事例紹介とか オンプレのデータをどうやってRedshiftに持ってくの? インフォテリアのASTERIA WARP GUIツールでデータの変換とかして、S3に持って行って、Redshiftと連携できるよと。 無料セミナーの紹介 6/21、8/2にRedshiftの無料セミナーやりますよ。 インターネット上のユーザーの行動の可視化を実現したAWSによるビックデータ解析基盤 C-Finderのサービス紹介 元オプトの方。C-Finderの紹介。 10万ユーザの行動履歴の可視化。\nサイトに来たけど、行動せずに他サイトに移動したとか、サイトに来る前の状態ってのがわからない。これをC-Finderで可視化。\n例1:自動車業界 ライバル企業の動向を自社と比較したい。 Audi、BMW、ベンツで可視化。 例2:化粧品業界 Web上での化粧品のトレンドが見たい。 @cosmeサイトのPVとかから。 ユーザって会員登録とかしてる人を追っかけてるってことなのかなぁ? よくわかってない。。。\nレポーティングサービスしてたけど、納品まで1ヶ月かかってた。 リアルタイムにみたいという要望が多かったのでASPをTISと開発 ASPサービスの開発したよ AWSで。 可視化というタイトルだったんだけど、期待してた可視化の話ではなかった。。。\nネット選挙クラウド ~オバマ大統領選挙の事例:データ解析からネット募金まで~ ボランティアで構成ってすごいな。 本番まで1年 みんな髭の人だw GoogleとかFacebookとかの人がボランティアで開発に参加。 予算は抑えながら、スケールアップダウンがすぐ出来てとか。 秒間10万回のI/OのDB SQSとEC2のSoftware queueの比較。Softwareキュー選ぶと、さらにドレがいいのかってのを選ばないとい。 AWSにあるサービスなら、造らなくてもいいのではとか。 CloudSearchはつかわなかったのかなぁ? tsunami S3に静的ページをおいて、最後のとりでにしたり。 コードとか、ノウハウってどこまで公開されてるんだろ? 同時通訳もあったんですが、英語を聞いてみようと聞いてましたが、まだまだダメですねぇ。\nパネルディスカッション「ウェブテクノロジーをエンタープライズで活かすには?」 趣旨 B2B、B2C間でのトレンドのやり取りが加速されてるよねと。 ICTはもはやコモディティ? TD太田さん Consumerization Of IT 色々なものがSaaSになってきてる TD:Consumerization of Data Infrastructure オンプレ<AWS<TD 三井物産黒田さん 三井クラウド(プライベート&パブリック) ユビキタス これまで使ってきたものがクラウドで動くのかとかが観点 電通平川さん マーケティングダッシュボードはsalesforceでは厳しかった? ビジネスに注力したいので、柔軟で、質実剛健なICT基盤がほしい。 ディスカッション 新しい技術に対するスタンスは?\nいかにダメな部分を潰していくか(太田さん) R\u0026amp;Dを予算化して評価して取り組んでいく。評価でダメならつぎ。(黒田さん) 消費者の方たちがネットですごい勢いで活動してる。その人達へのアプローチが重要。(平川さん) コンシューマ系技術の懸念事項は?\nセキュリティ面。レベルがある。自分の所だけじゃなく、クラウドベンダーと二人三脚が必要。丸投げはNG(黒田さん) セキュリティ面の攻撃を受けたつぎの手をどう打つかが重要。堅牢性上げると、ユーザビリティが下がる。(平川さん) 法規制的に出せないとかもある。持ちきれないデータもあるよね。(太田さん) 何を見分けてどうやって取り組むか?\nとりあえず、やってみる。そこで見える課題に対応していく。見極めるのは難しい(平川さん) ということは、すぐに出来る環境ってのは当たり前になってますよね。\n尖った技術=セキュリティ面が弱い?みたいな印象があるのかなぁ?\nJAWS-UG AWSアップデート AmazonのCTO登場 Game Day Game Day。土曜日にやるよ。 障害を発生させて、それを復旧させる。 最もひどい壊し方をしたらかちw 最後はかるくボッチでした。。。 AWSあんまり使ってないからなぁ。。。\n","date":1370527200,"dir":"post/2013/","id":"d12c1c2a68be4c7fda5a7737d5493b4d","lang":"ja","lastmod":1370527200,"permalink":"https://blog.johtani.info/blog/2013/06/06/aws-summit-tokyo-day2/","publishdate":"2013-06-06T23:00:00+09:00","summary":"昨日に引き続き、AWS Summit Tokyo 2013に行ってきました。 @ryu_kobayashiさんからパシリを仰せつかるなどあり、忙しかったのですが楽しか","tags":["AWS","勉強会"],"title":"AWS Summit Tokyo 2013に行って来ました。(Day2) #awssummit"},{"contents":"ざっとインストールガイドとかCloudera Searchのソース眺めて、テキトーにメモを書いてみました。 (ユーザガイドはまだ読んでないです。)\nざっくりメモ ストリーム処理でインデックス作るときはFlume経由でSolrに SinkとEventの両方が用意されてる?(Flumeを良く知らないので、違いがわからない) FluemeからはリモートのSolrに対してインデックス登録するクラスがある。SolrServerDocumentLoaderがソレだと思う。 バッチ処理でインデックス作るときはMapReduceIndexerToolsってのを使ってSolrに SOLR-1301がベースになっている。色々と改良されてるようだけど、コアとなってる処理はSOLR-1301。 GoLiveってクラスの処理の中で、現在動作してるSolrに配布したバッチで作成されたIndexをマージする処理が書いてある。 HDFSへ出力されたインデックスはリモートのSolrからアクセスするとオーバヘッドとかどーなるのかなぁ? 検索処理自体はHueでもできるけど、基本的にSolrCloud任せ インデキシングの処理のフローについてはCloudera Mrophlinesで定義 ということで、 2つの流れがありそう。\nHDFS→Flume→Solr HDFS→MapReduce→Solr で、まだ、わかってないですが、構成要素として\nHadoop(HDFS):データソース Hadoop(MapReduce):データ変換処理、バッチインデキシング Zookeeper:SolrCloudのクラスタ管理 Solr:インデキシング、検索エンジン Flume:データをストリーミングでSolrへ Coudera Morphlines:HDFSからSolrまでのETLデータ処理を定義実行する環境 って感じでしょうか。 SolrCloudのクラスタとHadoopのクラスタが同一マシン上なのか、別なのかとか。組み合わせがどんなものができるのかがまだわかってないです。 ユーザガイド読んでみたらなにか出てくるかなぁ。\nちなみに、Cloudera SearchのgithubリポジトリにあるソースはCloudera Morphlinesのコードがメインで、SolrのHDFS対応版のソースがあるわけでは無かったです。\nSolrのHdfsDirectoryってのがClouderaのリポジトリにあるSolrには追加されていて、これが、HDFSのインデックスを読み込んだりする処理が出来る仕組みっぽい。 一応、SolrCloud以外(分散検索)も考慮された形になってるっぽい。 ってとこでしょうか。\n感想 読んでて思ったんですが、Cloudera Searchの肝はじつは、検索じゃなくて、Morphlinesにあるんじゃないかなぁと。今はSolrが出力先ですが、 その他のデータ変換処理とかが増えてくると、処理の流れがMorphlinesで定義できてデータ変換処理が簡便になりそうな気が。\nその他に気になる観点 CDH経由でSolrCloudのクラスタの管理するのかな? SolrCloud用のクラスタとCDHのクラスタって同一マシンに載るの?別マシンにもできるの? 併存したらIOがキツそうだけど Hueで検索アプリとか組めるの?(そもそもHueがわかってないんだけど。。。) ま、とりあえず、こんなとこで。 つぎは余力があれば、ユーザガイドかなぁ。 英語力。。。\n","date":1370489160,"dir":"post/2013/","id":"f45069216cd934b80ce882c9a2f2a08a","lang":"ja","lastmod":1370489160,"permalink":"https://blog.johtani.info/blog/2013/06/06/cloudera-search-memo2/","publishdate":"2013-06-06T12:26:00+09:00","summary":"ざっとインストールガイドとかCloudera Searchのソース眺めて、テキトーにメモを書いてみました。 (ユーザガイドはまだ読んでないです。","tags":["Cloudera Search","Hadoop","Solr"],"title":"Cloudera Searchメモ(妄想版)"},{"contents":"AWS Summit Tokyo 2013に行って来ました。\n@cocoatomoさんに行き掛けに出会ったので、アンデルセンの講演を一緒に聞いてました。 TDブースの@ryu_kobayashiさんに挨拶に伺ったりも。\nすごい人で、セッション間の入れ替え時には会場前のスペースが大変なことになってました。もう少し余裕のある建物のほうが良かったのかもしれないですねぇ。\nいつものように以下はメモです。\nRoad to AWS アンデルセンサービス とてもおいしいランチボックスでした。\n広島(ここ重要!)に本社のあるパン屋さん。\n2003年に汎用機からOpenシステムに 内製ではなく外注に。複数のSIerにお願いしてるとデータセンタに マスタ管理と生産管理はオンプレ 2004年に稼動時のネットワーク整備。店舗はISDNで、設定ミスとかを防ぐためにIIJのSMFサービスに PCはレンタル契約にしたので入れ替えを強制できる→レガシーシステムの対応が必要なくなる ネットワーク広帯域化→基本システムにデータセンターに。 2009年にリース満了などで、OSの変更とかミドルの変更という移行SI費用だけで結構な値段が。ものによっては会社もない。 データセンターの月額手数料にして、機器変更などの費用を平準化。仮想化など。 けど、サイジングにどうしても安全係数をかけてしまうことに。結構値段がかかる そこで、今後の方向性 SIerどっぷりのOLTP受発注基幹システムはSIerのホスティングで それ以外のシステムは外に出したい バッチの計算を早くすることができるとノーチラスさんから提案された バッチを外部化するか、性能あげるか。IOネックなどもありスペック上げるとコストになるから、外部化したい Hadoopを組むけど、オンプレじゃなくてAWSにした。ノウハウがないので、ノーチラスさんにお任せした。 AWSのEMRを利用。4時間かかっていたものが40分で。 EDIのサーバを6ヶ月でAWSに移行 S3絡みで2度の問題が。性能劣化があった。 パッケージ開発環境がAWSにあるなら、AWSでも動くでしょ?(NTTイントラマートとか) SIerどっぷりの部分もAWSに持っていく? アンデルセンサービスの部長さんからのAWSへの要望 メールサーバなどの基本サビスとか、コントロールパネルを充実して欲しい。 クラウド技術を活用したリアルタイム広告\u0026quot;Logicad\u0026quot;の入札・配信・ログ解析 Web広告の歴史 最初は広告主がWebサイト単位で契約 アドネットワークによる仲介 聞きそびれた。。。DSP? アドネッエクスチェンジ SSP(Supply Side Platform) リアルタイムビッティング(RTB) RTPの仕組みを説明。 AWSとオンプレでシステムを構築してる。\nSSP事業者との取引はオンプレ 配信はAWS オンプレとAWSはAWS Direct Conectで接続 S3とHadoopの接続が安くなったり速くなったりするらしい。 オンプレミス側 Bidリクエスト:秒間数万件。。。 KVSのユーザ数は3億件。。。 AEROSPIKEというSSD向けのKVSを利用してる AWS側 ログはS3に。溜まったデータは定期的にEMRで解析。DynamoDBに入れてレポート作成 RabbitMQを使ってる。 ELBで外部からのリクエストはバランシング データセンタ間通信 遅延を複数コネクションを貼る方法で回避? 非同期で、複数のMsgとAckをやり取りする。RabbitMQがこれに相当する機能を持ってる QueueとConsumerで多重送信が可能。 配信結果をオンプレ側に送るのにRabbitMQを使ってるのかな? ハイブリッド構成を支えるAWSテクノロジー 聞くつもりだったんだけど、すごい人だったので、諦めて充電してた。\nAWSクラウドで構築する、ワールドクラスの分散クラウドアーキテクチャ エマージングソリューション部の部長のshot6さん。\nマルチAZ(アベイラビリティゾーン)モデル AWS固有のコンセプト。 ELBやDynamoDBやRDS、S3とか。\nマルチリージョンとは違うよと。マルチリージョンは結構難しいので。 マルチリージョンがどんなに大変かをこれから説明。\nマルチリージョンアーキテクチャ(これは別物) 複数のリージョンを利用して作る。 AWSのビルディングブロックではカバーしない範囲をカバーしないとダメとか。 リージョン間の通信は基本的に非同期 ディザスタリカバリ コストバランス見てから決めるよね。 CAP定理とかもいろいろと出てくるよね。 合意プロトコル。正確性、生存性(時間が制限されても大丈夫)、理論的にパフォーマンス出る? 非同期レプリケーションになる(1トランザクション当たりのオーバヘッドが大きいから)けど、復旧の難しさがある。 GlusterFSとかでやってるとこもある。 NetflixはCassandraをクオラム+Geo-Replicationでマルチリージョンを構成してる。 マルチリージョンでのデータ一貫性は維持がむずい 注意点 必要になるまで分散させない。 まずは、マルチAZを考えましょう 物理制限を考慮する 同期型だとタイムラグあるし。 複合障害の伝搬をどう抑えるか。 NetflixはHYSTRIXというのがいて遮断できるようにしている 自動化が重要。ロールバックとかロールアウトとか。 テストをどーするの? 本番環境でアクティブ/アクティブ構成でのテスト。 ちゃんとフェイルオーバするかなどを実環境でやってる。DB落としたり。。。 障害は避けられないので、受け入れて日常に取り込むべきだよねと。\nAmazon.comではGameDay NetflixはChaos Monkey(OSS) Obama for America リカバリーオリエンテッドコンピューティングパターン\nボーアバグ:再現可能なソフトウェバグ ハイゼンバグ:通常ではありえないパターンで発生するバグで、調査が大変 ということで、マルチAZがいいよ 同期式レプリケーションを前提にできる。 アプリ開発者がアプリにフォーカスできる。分散系の難しいところはAWSが隠蔽してくれるから。 ","date":1370424600,"dir":"post/2013/","id":"1fe14e2e02b6e65e6e6e2ae3d8ddcc9f","lang":"ja","lastmod":1370424600,"permalink":"https://blog.johtani.info/blog/2013/06/05/aws-summit-tokyo-day1/","publishdate":"2013-06-05T18:30:00+09:00","summary":"AWS Summit Tokyo 2013に行って来ました。 @cocoatomoさんに行き掛けに出会ったので、アンデルセンの講演を一緒に聞いてました。 TDブースの@ry","tags":["勉強会","AWS"],"title":"AWS Summit Tokyo 2013に行って来ました。(Day1) #awssummit"},{"contents":"Cloudera Searchは次のようなモジュールから構成されています。 これはCloudera Searchのモジュールで、さらにこれらがSolrとかを使ってるみたいですね。pom.xmlを見たら何を使ってるかがわかるかな。\ncdk-morphlines search-contrib search-core search-flume search-mr search-solrcell てきとーに、README.mdみながらメモを残してみました。ソースとかはまだ読んでないです。 ざっと眺めたけど、インデキシング処理の話がメインで、検索側がどうやって動くかってのがわからなかったなぁ。 ユーザガイド(注:PDF)ってのがあるから、これを読んでみるか。。。\n各モジュールについては、以下。\ncdk-morphlines(Cloudera Morphlines) Cloudera Morphlinesという名前みたい。 検インデキシングアプリの構築、変更をラクにするためのフレームワーク。 ETLの処理チェインを簡単にCloudera Searchにデータを入れる設定(Extract/Transform/Load処理)がかけると。 バッチ処理、Near Real Timeのために使えるみたい。検索結果をさらに入れるとかもできるんかなぁ。?\nUnixパイプラインのの進化版みたいなもので、一般的なレコードに対するStream処理から、Flueme、MapReduce、Pig、Hie、SqoopのようなHadoopコンポーネントも使えるみたい。\nHadoop ETLアプリケーションのプロトタイピングにも使えて、リアルタイムで複雑なStreamやイベント処理やログファイル解析とかに使えるの?\n設定ファイルのフォーマットはHOCONフォーマット。AkkaやPlayで使われてる。\ncdk-morphlines-core Cloudera Morphlinesのコンパイラ、実行環境、コマンドのライブラリを含んでる。 ログファイル解析やsingle-lineレコード、multi-lineレコード、CSVファイル、正規表現パターンマッチ、フィールドごとの比較とか条件分岐とか、文字列変換とか色々なコマンドを含んでる。\ncdk-morphlines-avro Avroファイルやオブジェクトの抽出、変換、読み込み処理コマンド\ncdk-morphlines-tika バイナリデータからMIMEタイプを検出して、解凍するコマンド。Tikaに依存\n雑感 Cloudera Searchへのデータの流し込みを設定ファイルに記述して実行するとデータの変換処理とかが記述できるって感じかな? Morphlinesのコマンドとして独自処理や使えそうな処理を作ることで、いろんな処理ができるって感じかなぁ。\nsearch-core Solrに対するMorphlineコマンドの上位モジュール\nsearch-solrcell Tikaパーサを使ったSolrCellを使うためのMorphlineコマンド。 HTML、XML、PDF、Wordなど、Tikaがサポートしてるものがサポート対象。\nsearch-flume Flueme Morphline Solr Sink。 Apache Flumeのイベントから検索ドキュメントを抽出、変換し、SolrにNearRealTimeで読み込むためのコマンド\nsearch-mr HDFSに保存されたファイルに含まれる大量データをMapReduceで処理してHDFS上の検索インデックスに焼きこむモジュール。\nMapReduceIndexerToolは入力ファイルの集合からSolrのインデックスシャードの集合を作るためのmorphlineのタスクで、MapReduceのバッチジョブドライバー。 HDFSにインデックスを書き込む。 動作してるSolrサーバに対して出力されたデータをマージするのもサポートしてる。\nとりあえず、Near Real Time検索するにはFlueme使って、バッチ処理でインデックス焼くのはMapReduceIndexerToolみたいだなぁ。\n","date":1370412720,"dir":"post/2013/","id":"e30258aeb8475d4c27f7935945671856","lang":"ja","lastmod":1370412720,"permalink":"https://blog.johtani.info/blog/2013/06/05/cloudera-search-modules/","publishdate":"2013-06-05T15:12:00+09:00","summary":"Cloudera Searchは次のようなモジュールから構成されています。 これはCloudera Searchのモジュールで、さらにこれらがSolrとかを使っ","tags":["Cloudera","Hadoop","Solr","Cloudera Search"],"title":"Cloudera Searchのモジュールたち"},{"contents":"AWS Summitに来ていたのですが、TLでは、Cloudera Searchが賑わってました。 ということで、軽くどんなものか読んだり調べたりしたメモを残しとこうかと。 英語力はあやしいので、おかしいとこがあったらツッコミを。\nCloudera Searchとは? CDH4.3に対応したCDHユーザ向けの検索システム(beta版)なのかな? CDHに統合された検索フレームワークなのかな?\n基本はLucene/Solr 4.3でHadoopのペタバイトデータを検索することができるようになるみたいです。\nどんな仕組み? 次のものを利用しているようです。(GithubのREADMEから。)\n使ってるもの Apache Solr(4.3.0+α?) Apache Lucene(Solrつかってるからね) Apache SolrCloud(うーん、Solrに含まれるのに別に出してるのなんで?) Apache Flume Apache Hadoop MapReduce \u0026amp; HDFS Apache Tika SolrCellとしてSolrにも組み込まれてる、いろんな文書(WordとかHTMLなどなど)からメタデータと本文データとかを取り出せるライブラリラッパー。実際にはさらにpdfboxとかを使って各文書からのデータを取り出してる。 何ができるの? HBaseやHDFSの用にZookeeperを使ってインデックスのシャーディングや高可用性ができる。(SolrCloudがZookeeperを使ってるからね。) MapReduceのジョブの出力から自動的にSolrのインデックスにデータをマージできるらしい。 Cloudera Managerを使って、デプロイ、設定モニタリングなどが可能。\nFlumeのフィードをつかって、ストリーミングしてインデックスを作れる。FluemeがデータをSolrに流しこむのかな? 将来的にはHiveやHBaseのテーブルをインデックスすることも可能になるらしい。Impalaクエリの結果もフィードできるのか?\nApache Blurってキーワードも出てきた。HDFSのデータからLuceneのインデックス作るのかな? NGDataのチームがSolr/HBaseの統合とかしてるみたい。\n参考URL Cloudera社のブログ Cloudera SearchのFAQ(注:PDF) Githubのリポジトリ ","date":1370412300,"dir":"post/2013/","id":"cd90bce912f5743226af94c1efaaa4a7","lang":"ja","lastmod":1370412300,"permalink":"https://blog.johtani.info/blog/2013/06/05/what-is-cloudera-search/","publishdate":"2013-06-05T15:05:00+09:00","summary":"AWS Summitに来ていたのですが、TLでは、Cloudera Searchが賑わってました。 ということで、軽くどんなものか読んだり調べたりした","tags":["Cloudera","Hadoop","Solr","Cloudera Search"],"title":"Cloudera Searchってのが出たらしい(とりあえず、雑感?)"},{"contents":"憧れ?のfluentを使ってみました。 こちらの記事で紹介したZoomdataを最近触っているのですが、お試しにfluentdでデータ流し込むプラグインを作ってみようかなぁと。(今は、Javaでの接続も書いていて、主にそっちを使っています。) ということで、作ってみました。fluent-plugin-zoomdata。\n基本的にはtagomoris先生のfluent-plugin-growthforecastを参考(パクリ?)にさせてもらいました。 作っている最中もここわからんってツイートに反応していただき、大変助かりました。 私はベースがJavaの人間なので、手探り状態でRubyを書いています。そこおかしいんじゃないの?とかあればコメントもらえると嬉しいです。\nZoomdataのAPI ZoomdataのAPIはこんなかんじで、JSONをHTTPSでPOSTするものになります。\n指定する必要があるものは、以下の項目です。\nsource:Zoomdataのデータ保存先(Zoomdataでのデータを保存する単位。) user:Zoomdataのユーザ名 password:Zoomdataのユーザのパスワード JSONデータ:Zoomdataでグラフ化するデータ sourceはデータ保存先の名称で、この単位でZoomdataはデータを保存、描画します。fluentdのタグをこれにするとわかりやすいかなぁ?と考えていったん、実装してみています。\nで、作成したプログラムを使いつつ、Zoomdataの検証をしたかったので、つぎのような簡単なプログラムを作って動かしてみました。\nサンプルプログラムの構成 基本的にJavaの人なので、クライアントはJavaで書いてます。 CLIプログラムで適当なJSONを作って、fluent-loggerを使って、fluentdに投げ込みます。\nfluentdにfluent-plugin-zoomdataを設定して、localのZoomdataサーバに対してHTTPSでJSONをPostする仕組みです。(初keynote)\n利用しているライブラリなどのバージョンは次の通り\ntd-agent.x86_64:1.1.12-0 fluent-logger:0.2.8 Zoomdata:1.0.3 バグ? で、Zoomdataにいろんなデータを流し込んでみたのですが、つぎのようなエラーが出て、エラーが出力されたあとはZoomdataにデータが流れ込まなくなってしまいました。\n2013-06-03 14:42:33 +0900 [warn]: emit transaction failed error=\u0026#34;SSL_connect returned=1 errno=0 state=SSLv3 read finished A: sslv3 alert handshake failure\u0026#34; 2013-06-03 14:42:33 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/1.9.1/net/http.rb:799:in `connect\u0026#39; 2013-06-03 14:42:33 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/1.9.1/net/http.rb:799:in `block in connect\u0026#39; 2013-06-03 14:42:33 +0900 [warn]: /usr/lib64/fluent/ruby/lib/ruby/1.9.1/timeout.rb:54:in `timeout\u0026#39; 全ログはこちら。\nまだきちんと問題を調査しないでブログを書いています、すみません。\n現象 ログが発生した時の症状です。\nクライアントプログラムは送信が続いており、エラーは出ない td-agent.logに先ほどのエラーが出力 別途type fileにて出力しているログも停止 想像 とりあえず、ログを見た想像、所感です。\n問題の箇所はfluent-plugin-zoomdataからZoomdataサーバへのデータ送信部分 emit処理内部で、HTTPSでデータをPOSTする処理でエラーが起きて リトライ処理とか書いてないので、emitがコケて、その後データが送信されなくなる emitで例外をつかみそこねてるのがあるから止まってる? とまぁ、ちゃんと仕組みを理解しないでRubyとか書くからこうなるんですねぇ。 あとでちゃんと調べて考えて、改良してブログ書きます。\n悩んでいる点、今後手を入れたい点 上記バグとは別に作りの点でいくつか悩んでる点も書いてみます。\nBufferedOutputにしてみたい fluentdのバッファリングを使って、Zoomdataが落ちていても使えるようにしたいと思っているのでBufferedOutputで書くのがいいのかなぁとか。 ちょうどいいスライドがあったので、読みながらまずは中身を理解してみよう。\nZoomdataのsource、userなどの扱い 基本的には設定ファイルで切り替えるのが妥当かなぁと思っています。\nただ、Zoomdataのsourceやuserが増えるたびにfluentdの設定を書き換えて再起動するのかなぁと。userはしょうが無いにしても、sourceは設定じゃない所で切り替えたいなぁと。\nで、切り替えるのにつぎの案があるかなぁと。\nタグで指定(今実装してるもの) メッセージにメタ情報とボディ構造を設ける 設定をどんどん増やす(やりたくない) 1と3はまぁ、いいかと。2.のパターンはどうなのかなぁと。 毎回のメッセージでヘッダ部分が送信されるのはなんだか無駄だなぁというのが否めないので悩ましいところです。1、2の両方対応できるように作るのもありか。\n{ \u0026#34;header\u0026#34;: { \u0026#34;source\u0026#34;: \u0026#34;source_name\u0026#34;, \u0026#34;user\u0026#34;: \u0026#34;userid\u0026#34;, \u0026#34;password\u0026#34;: \u0026#34;userid\u0026#34;, }, \u0026#34;body\u0026#34;: { \u0026#34;label\u0026#34;: \u0026#34;label1\u0026#34;, \u0026#34;count\u0026#34;: 1 } } ということで、fluent触って遊ぶの楽しいですね。Rubyの勉強にもなりそうだし。 ちょっとずつ頑張ってみようかなぁと。 まぁ、まだ私以外にニーズは無さそうなプラグインですが。\n","date":1370234580,"dir":"post/2013/","id":"494557db52824555864d1106278cd1f0","lang":"ja","lastmod":1370234580,"permalink":"https://blog.johtani.info/blog/2013/06/03/fluent-plugin-zoomdata-0-0-1/","publishdate":"2013-06-03T13:43:00+09:00","summary":"憧れ?のfluentを使ってみました。 こちらの記事で紹介したZoomdataを最近触っているのですが、お試しにfluentdでデータ流し込む","tags":["Zoomdata","fluentd"],"title":"fluent-plugin-zoomdata作りました+悩み事とか"},{"contents":"最近、Markdownで文章を書くのに慣れてきました。 ということで、ブログをMarkdownで書けないかなぁと思い、TLの人たちのブログを見たりしていると 「Octopress」というキーワードがあるじゃないですか。 ということで、Github Pages作って、Octopressを使ってブログを書いてみました。 こちらです。\n独自ドメインは昨年から使っているものがあったので、ついでに独自ドメインの設定もしてみました。 ケチなので、.comなどではなく、.infoですが。。。\nということで、徐々にOctopressに移行していこうと考えているところです。 こちらのブログも当面は残しておく予定です。(有料会員は解約して、広告が出る形になると思いますが。。。)\nOctopressでこんなの便利だよとかアレば教えてもらえると助かります。\n","date":1370228038,"dir":"post/2013/","id":"16f10764f0ccce42d5be8cfeac36b446","lang":"ja","lastmod":1370228038,"permalink":"https://blog.johtani.info/blog/2013/06/03/octopress%E3%82%92%E8%A9%A6%E3%81%97%E4%B8%AD/","publishdate":"2013-06-03T11:53:58+09:00","summary":"最近、Markdownで文章を書くのに慣れてきました。 ということで、ブログをMarkdownで書けないかなぁと思い、TLの人たちのブログを見","tags":["misc"],"title":"Octopressを試し中(Jugemより移植)"},{"contents":"昨年から、ブログをどうしようかって話をしていて、そのままになっていたのですが、Octopress+Github Pagesというのがあるらしいと聞きつけて(Twitterで見かけたのかなぁ?)ちょっとやってみました。\n最近は、ドキュメントをMarkdownで記述しようとして癖をつけているのもあり、 ちょうどいい練習になるかなぁと。\nということで、まずは手始めのエントリーでした。 いくつか書きたいこともあるので、調べながら書いていこうかと。 まだ、イメージできてないこと\n画像をどうやって貼るの? About meみたいなのも貼り付けたい bitbucketやTwitterのリンクとかも アフィリエイトも貼る(とりあえずSolr本を) 検索とかは? デザインは? などなど。ちょっとずつ調べていこうかなぁと。 あ、調べたことも書いてくのもありか。\n","date":1370098620,"dir":"post/2013/","id":"dbcc4002c15afefef853a08a0804ba3a","lang":"ja","lastmod":1370098620,"permalink":"https://blog.johtani.info/blog/2013/06/01/first-octopress/","publishdate":"2013-06-01T23:57:00+09:00","summary":"昨年から、ブログをどうしようかって話をしていて、そのままになっていたのですが、Octopress+Github Pagesというのがあるらしい","tags":["octopress","misc"],"title":"Octopress始めました"},{"contents":"Lucene/Solr 4.3.0がリリースされた(LuceneのChanges、SolrのChanges)ので、lucene-gosen 4.3.0をリリースしました。(ダウンロードはこちら) なお、lucene-gosen 4.3.0ですが、Lucene/Solr 4.2.1以下のバージョンのLucene/Solrでは利用できません。 注意してください。 また、lucene-gosen 4.2.1もLucene/Solr 4.3.0では動作しませんので注意が必要です。\n現時点(2013/05/06)では、lucene-gosen 4.3.0はLucene/Solr 4.3.0でのみ利用できます。 これは、先日のエントリにも書きましたが、LuceneにてAPIの変更が行われたためとなります。 いくつかのクラスおよびメソッドが廃止されたため、下位互換が保てない変更が入っているためです。\n独自のTokenizerやTokenizerFactory、TokenFilterFactory、CharFilterFactoryを作成されている方は、Lucene/Solrのバージョンアップを行う際は注意が必要です。\n","date":1367850324,"dir":"post/2013/","id":"11d4726484be418849e1f4200ade9535","lang":"ja","lastmod":1367850324,"permalink":"https://blog.johtani.info/blog/2013/05/06/lucene-gosen4-3-0%E3%82%92%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E3%81%97%E3%81%BE%E3%81%97%E3%81%9Flucene-solr4-3-0%E4%BB%A5%E4%B8%8A%E3%81%A7%E3%81%AE%E5%88%A9%E7%94%A8%E3%81%8C%E5%8F%AF%E8%83%BD%E3%81%A7%E3%81%99/","publishdate":"2013-05-06T23:25:24+09:00","summary":"Lucene/Solr 4.3.0がリリースされた(LuceneのChanges、SolrのChanges)ので、lucene-gosen 4.3.0をリリースしま","tags":["lucene-gosen"],"title":"lucene-gosen4.3.0をリリースしました。(Lucene/Solr4.3.0以上での利用が可能です)(Jugemより移植)"},{"contents":" アジャイルな時間管理術 ポモドーロテクニック入門 ポモドーロテクニック入門という本を読みました。 きっかけは、Twitter上で何度か「ポモドーロ」という単語を何度か見ていたためです。 最初は、なんだろう?というのが発端です。 「ポモドーロ=トマト」なのですが、実際にはトマト型のキッチンタイマーが元になっているらしいです。 このタイマーを使った時間(タスク)管理術がポモドーロ・テクニックです。\n私は、ここ数年、複数の仕事がパラで走ることが時々ありました。 このような場合に、日によって異なる複数のタスクが存在します。 このとき、異なるタスクにスイッチするのに結構な時間を取られます。。。 また、急な割り込みが入った時も同様に、以前のタスクに戻るのになにしてたっけ?となることが多々あります。 普通に自己管理ができている方なら問題ないのでしょうが、私は結構ニガテでした。 そのようなときに、Twitter上で「ポモドーロ」という単語を見かけて、軽くググってみたところ、 タスク管理、時間管理によさそうな本だったので、その点を矯正するのも兼ねて、読んだ次第です。 また、タスクに集中できるという利点もあるそうです。\n本については、少し読みにくいところがありました。 ポモドーロテクニックとはどんなものかという全体像や単語に関する説明がないままに、話が進んでいくので。。。 1度読み終わったあとに実践しながらパラパラめくっているような状況です。 実際には、個々人のやり方などを考慮しながら、改善していくべきなのもあり、型を説明してないのかもしれないですが、もうすこし概観がわかる感じのほうが良かったです。\nで、4月初旬くらいから実践してみています。 効果が実際にあるかというと、まだわからないです。\n私がポモドーロテクニックに利用しているのはキッチンタイマーではなく、pomodairoというAdobeAIR上で動くアプリになります。 ほかにもPomodoroAppというのもあるのですが、Free版だと登録できるタスクの上限があったので、pomodairoを選びました。(今見たら、3.0にバージョンが上がって、Limitがなくなってるかも) AIRだと、WinでもMacでも動作するのというも決定した要因です。\nまだ、1ヶ月経ってませんが、私が実践してきて良かった点、できてない点、うまくいってない点はつぎのような感じです。\n良かった点 目の前のタスクに集中できる。(25分スパンなので、Twitterを意識的に見なくできる。。。) 適度な休憩が挟める。25分に5分の休憩が入るので、適度な没頭になる(没頭し過ぎない) 自宅で作業するときにかなり有効。(5分の休憩時にTwitterやFB以外に漫画をパラパラ読んだりもできるので) ということで、自宅で作業するときには結構いいです。 自宅ですと、pomodairoを使っていてタイマーの音を気兼ねなく出せるので、きちんとポモドーロが回せます。\nできてない点 アクティビティ在庫管理。個人的にJIRAを使っていて、そこで管理しようと思っているのですが、うまくできてないです。pomodairoのアプリにもタスクを登録しているのもあり2重登録などを手間に思ってしまって。。。 レコーディングと今日のTodo作成。 インタラプトの記録 アクティビティ在庫管理ができてないのは、レコーディングがきちんと出来てないためでしょう。。。 二重管理になっている+pomodairoで統計情報が出るが、当日分の統計情報がレコーディングできてないというのが痛いです。 また、このレコーディングが出来てないので、効果が出ているかがわからないという問題かと。。。 きりが悪かったりして、どうしても、仕事時間ギリギリまでタスクをこなしてしまい、レコーディング+アクティビティ在庫の管理の時間が取れていません。 ここは意識してちゃんとやらないと意味がないよなぁと。今後の大きな課題です。\nうまくいってない点 できてない(やろうとしてできてない)点とは別に、どうもしっくり来ていないのがつぎのような点です。\nプログラミングしていると、25分のタイマーで区切りがすごく悪い時がおおい 自宅以外でのタイマー音が出せない 自宅以外での休憩の取り方 プログラミングをやっていて、乗ってきたタイミングでタイマーが鳴ってしまったり、 ちょっと頭のなかで整理していたあとの今まさに、頭のなかにある処理の流れをコードに落としている途中でタイマーがなってしまったり。 このような状況だと、休憩に入れなくて、ずるずるとコーディングを続けてしまうということが多々あります。 メモ(ソース上のコメントや手元)を残して休憩すればいいのでしょうが、どうしても今までの癖もありズルズルとやってしまい、すごく時間が経ってることが何度もあります。 ポモドーロテクニック的にはやはりNGなんでしょうが、なかなか治らない+治したくない気もしています。 また、自宅以外の場合、基本的には自社ではなく客先に出ていることが多いのでどうしても音を出すことができません。 これもまた、切り替えができない要因になっています。 タイマーだけ携帯のアプリを使用しするという手もあるのでしょうが、この場合さらにレコーディングが出来ない状況に陥りそうで。。。 また、スマホだと電池が持たないのも問題点です。(Twitterを見るのに利用してるから電池が持たないという話もあるのですが。。。) レコーディングに関しては、手描きのメモを使うのがいいのかなぁと。本では+や◎などの印を付けるだけにしておけば良いとありますが、アプリのタイマーだと自動でそれができるので、悩みどころです。 最後の休憩の取り方も、ネットやTwitterを見るのもありなのですが、画面から離れる休憩を取りたいなぁと思うところもあり。。。 職場だと技術書やWEB+DBのような雑誌はあるのですが、休憩にはあまり向いていないなぁと。\nつらつらと書いて来ましたが、本を読んで、1ヶ月実践してきた(できてないとこも多いが)現状をメモしておきます。 こうやってるよ、こうしたら良かったよ、こうしてみれば?などありましたら、コメントいただけると助かります。\n来週以降はとりあえず、JIRAできちんとアクティビティ在庫管理をしながら、1日の結果をレコーディングしていくのを意識していこうと思います。\n","date":1367592139,"dir":"post/2013/","id":"db97311c24809f103575d8a7fee19680","lang":"ja","lastmod":1367592139,"permalink":"https://blog.johtani.info/blog/2013/05/03/%E3%83%9D%E3%83%A2%E3%83%89%E3%83%BC%E3%83%AD%E5%9B%9E%E3%81%97%E3%81%A6%E3%81%BE%E3%81%99%E3%83%9D%E3%83%A2%E3%83%89%E3%83%BC%E3%83%AD%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF%E5%85%A5%E9%96%80%E8%AA%AD%E3%81%BF%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2013-05-03T23:42:19+09:00","summary":"アジャイルな時間管理術 ポモドーロテクニック入門 ポモドーロテクニック入門という本を読みました。 きっかけは、Twitter上で何度か「ポモドーロ","tags":["読書"],"title":"ポモドーロ回してます。(ポモドーロテクニック入門読みました)(Jugemより移植)"},{"contents":"まだ、Vote公開されていない、Solr 4.3(2013/04/25 11:00現在)ですが、 ひさびさに訳してみた。詳細まで追っていないので、誤訳があるかもしれないですが。 おかしいとこあったらツッコミを。\n○Solr 4.3.0のChanges ・Upgrading from Solr 4.2.0 1.schema REST APIのcopyFields、dynamicFieldsの出力パスをCamelCaseに。他も同様。(SOLR-4623) 2.Slf4j/logging jarをSolrのwarに含めないことに。すべてのlogging jarはexample/lib/extに。(SOLR-3706、SOLR-4651) 3.SolrCloudでハードコードされてたhostContextとhostPortをdeprecatedに。Solr5.0で削除する。(SOLR-4622)\n・New Features 1.SOLR-4648 PreAnalyzedUpdateProcessorFactoryでPreAnalyzedFieldの機能をほかのフィールドタイプでも使えるようにした。詳しくはJavadocとexampleを見て。 2.SOLR-4623 REST APIで現在のschemaのエレメントをすべて読めるように。REST APIの返却の形式として、XMLとJSONとschema.xmlの形式を追加REST APIのパッケージを変更。 クラス名も変更しschemaにフォーカスした機能も除去。今後のschema以外のREST APIのために。 copyFieldsとdynamicFieldsの出力パスをすべてlowercaseのものからCamelCaseに変更。他のREST APIも同様。 3.SOLR-4658 REST APIリクエストでschemaを変更できるようにするために、「managed schema」を導入。solrconfig.xmlに「\u0026lt;schemaFactory class=\u0026ldquo;ManagedSchemaFactory\u0026rdquo; mutable=\u0026ldquo;true\u0026rdquo;/\u0026gt;」を追加。REST APIリクエストでスキーマ変更が可能にするために。 4.SOLR-4656 2つのハイライトパラメータ(hl.maxMultiValuedToMatch、hl.maxMultiValuedToExamine)を追加。 hl.maxMultiValuedToMatchは指定された数のsnippetが見つかったらそれ以降の探索を停止する設定。multiValuedフィールドがどんなに離れてても探索する。 hl.maxMultiValuedToExamineは指定された数のmultiValuedのエントリ数を調査したら探索を停止する設定。 両方を指定した場合、最初のlimitに達したら停止する。ドキュメント全体をハイライトするためにコピーされるのを削減する。これらの最適化はmultiValuedフィールドに大量のエントリが存在する時に効く。。。 5.SOLR-4675 PostingsSolrHighlighterでper-field/クエリ次のパラメータ指定のサポート 6.SOLR-3755 既存のshardを動的にsplitしてshardを追加するための新コレクションAPI(shard splitting) 7.SOLR-4530 DIH:TikaのIdentityHtmlMapperを使う設定の提供 8.SOLR-4662 solr.xmlにあるSolrCoreの定義よりもディレクトリ構造で見つける。また、solr.xmlのフォーマットを変えて、solrconfig.xmlに近くする。Solrのこのバージョンは旧スタイルの例で提供するが、新しいスタイルも試すことができる。Solr 4.4では、新しいスタイルで提供し、Solr 5.0では旧スタイルは廃止する予定。 SOLR-4347 Adminハンドラで新しく生成されたコアがsolr.xmlに永続化される SOLR-1905 Adminリクエストハンドラで生成されたコアもsolr.xmlに永続化される。また、solr.solr.datadirのようなプロパティの用にsolr.xmlに永続化される問題のfix。 9.SOLR-4717/SOLR-1351 SimpleFacetで同じフィールドに異なるファセットを適用出来るlocalParamsを追加 10.SOLR-4671 CSVResponseWriterのpseudoフィールドのサポート 11.SOLR-4358 HttpSolrServerでuseMultiPartPostでstream名を送信できる ・Bug Fixes 1.SOLR-4543:solr.xml/solr.propertiesでshardHandlerFactoryの設定が動作しない 2.SOLR-4634:Java 8\u0026quot;Nashorn\u0026quot;JavaScript実装の動作に関するscripting engineのテストのfix 3.SOLR-4636:SolrIndexSearcherをオープンする時に何かの理由でreaderがオープンできない時に、ディレクトリがリリースされない 4.SOLR-4405:Admin UIのadmin-extraファイルでcore-menuが表示されない 5.SOLR-3956:group.facet=trueでfacet.limitがマイナスの時の動作 6.SOLR-4650:copyFieldでダイナミックフィールドや暗黙的なフィールドがsourceでマッチしない。4.2で入ったバグ 7.SOLR-4641:Schemaで、illegalなフィールドパラメータで例外が発生するようにする。 8.SOLR-3758:SpellCheckComponentが分散groupingで動作しない。 9.SOLR-4652:solr.xmlプラグインのresource loaderで共有ライブラリの挙動がおかしい 10.SOLR-4664:ZkStateReaderがaliasを更新しても見えない 11.SOLR-4682:CoreAdminRequest.mergeIndexが複数コアやindexDirが複数の場合にマージできない 12.SOLR-4581:Solr4.2で数値フィールドのファセットでマイナスの値があるとソートがおかしい 13.SOLR-4699:Admin Handlerでデータディレクトリの場所がファイルシステムだと思い込んでる。(RAMの場合もある) 14.SOLR-4695:non-cloudセットアップでもコア管理のSPLITが使えるように 15.SOLR-4680:exampleのspellcheck設定のqueryAnalyzerFieldTypeの修正 16.SOLR-4702:exampleの/browseの「Did you mean?」のサジェストをFix 17.SOLR-4710:Zookeeperから全ノードをアップせずにコレクションを削除できないのを修正 18.SOLR-4487:HttpSolrServerからのSolrExceptionがリモートのサーバから戻るHTTPステータスコードを含んでない 19.SOLR-4661:Admin UIのレプリケーションで現在のレプリカ可能なマスタのバージョンを正確に表示 20.SOLR-4716,SOLR-4584:SolrCloudリクエストプロキシがTomcatなどJetty出ないコンテナで動作していない 21.SOLR-4746:Distributed groupingのトップレベルグループコマンドでSimpleOrderedMapの代わりにNamedListを使う。non-distributed groupingと出力形式が異なるため。 ","date":1366856040,"dir":"post/2013/","id":"286a9a4ee373398d7d2c93862c5f6661","lang":"ja","lastmod":1366856040,"permalink":"https://blog.johtani.info/blog/2013/04/25/solr4-3-0%E3%81%AEchanges%E3%82%92%E8%A8%B3%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F/","publishdate":"2013-04-25T11:14:00+09:00","summary":"まだ、Vote公開されていない、Solr 4.3(2013/04/25 11:00現在)ですが、 ひさびさに訳してみた。詳細まで追っていないので、","tags":["solr"],"title":"Solr4.3.0のChangesを訳してみた。(Jugemより移植)"},{"contents":"現在、RC3のVoteをやっている最中(2013/04/24 16:00時点)で、まだリリースされていない、4.3.0についてです。 開発者MLでChangesの書き方を考えないとね、みたいなエントリーが流れてて気になっていたので、訳してみた。 lucene-gosenの実装を変更しないといけないっぽいなぁ。Lucene/Solr 4.2.1以前と4.3.0でI/Fとかが変わることになりそうです。(3.とか8.とか) (ここで力尽きて、それより下はまだ読んでないです。。。)\n○Changes in backwards compatibility policy 1.LUCENE-4810:EdgeNGramTokenFilterが同じ入力tokenから複数のngramを生成した時にpositionを増加させていないのを修正 2.LUCENE-4822:KeywordMarkerFilterがabstractクラスで、サブクラスがisKeyword()メソッドを実装する必要がある。新しく、SetKeywordTokenFilterというクラスにすでにある機能を分解した。 3.LUCENE-4642:TokenizerとサブクラスのAttributeSourceのコンストラクタを削除。代わりにAttributeFactoryをもつコンストラクタを追加。 4.LUCENE-4833:IndexWriterConfigがsetMergePolicy(null)の時にLogByteSizeMergePolicyを使っているのをデフォルトmerge policyをTieredMergePolicyに。また、nullが引数に渡されたらExceptionを返す。 5.LUCENE-4849:ParallelTaxonomyArraysをDirectoryTaxonomyWriter/Readerのためのabstractとして作成。あと、o.a.l.facet.taxonomyに移動。 6.LUCENE-4876:IndexDeletionPolicyをInterfaceではなく、abstractクラスに。IndexDeletionPolicy、MergeScheduler、InfoStreamでCloneableをimplement。 7.LUCENE-4874:FilterAtomicReaderと関連するクラス(FilterTerms、FilterDocsEnumなど)でフィルタされたインスタンスをforwardしないように。メソッドが他のabstractメソッドを実装している場合に。(?) 8.LUCENE-4642, LUCENE-4877:TokenizerFactory、TokenFilterFactory、CharFilterFactoryの実装者は、少なくともMap\u0026lt;String,String\u0026gt;(SPIフレームワーク(Solrとか)によってロードされる)を引数にするコンストラクタを提供する必要がある。さらに、TokenizerFactoryはcreate(AttributeFactory,Reader)メソッドを実装する必要もある。\n","date":1366786800,"dir":"post/2013/","id":"99f5219da22485d0872a2529599c8440","lang":"ja","lastmod":1366786800,"permalink":"https://blog.johtani.info/blog/2013/04/24/lucene-4-3-0%E3%81%AEchanges%E3%81%AB%E3%81%82%E3%82%8Bchanges-in-backwards-compatibility-policy%E3%81%8C%E6%B0%97%E3%81%AB%E3%81%AA%E3%81%A3%E3%81%9F%E3%81%AE%E3%81%A7%E8%A8%B3%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F/","publishdate":"2013-04-24T16:00:00+09:00","summary":"現在、RC3のVoteをやっている最中(2013/04/24 16:00時点)で、まだリリースされていない、4.3.0についてです。 開発者ML","tags":["solr"],"title":"Lucene 4.3.0のChangesにあるChanges in backwards compatibility policyが気になったので訳してみた。(Jugemより移植)"},{"contents":"第2回目も参加しました。 とりあえずメモ。 自分には欠けてる視点の話しなので面白かった。 ちょっと寒かったなぁ。\nエンジニアのためのスキルアップ勉強会『Tech Compass』 #tecomp ― Vol.2 「人気Webサービスの作り方教えます!」 ― 日時:2013/04/23 19:00 場所:パレスサイドビル9F マイナビルーム ◎自己紹介 ●株式会社Zaim/閑歳孝子 小学校3年からFMVで草の根チャットとかにつないでた。(すげー) これがいい記事ですよ。http://www.1101.com/umeda_iwata/ テレビとかで紹介されてるZaimやってます。 3つの基準 ・日常的に使うもの ・普通の人が使うもの ・少なくとも自分は使うもの サービスの良さの基準 縦軸:影響の深さ 横軸:影響する人数 この面積が大きいのがいいんでは。 ●株式会社ワディット/和田裕介 いろいろ作ってます「カウントダウンチューブ」とか「君のラジオ」とか30~40くらい作ってます。 ・「ボケて」ってのやってます。 600万ボケ。アプリ120万DL 僕らがつくるための5Wについて ・なぜ? ・サービスの根本となる「哲学」をみんなで共有できるかが重要 ・内向けのビジョンも大事 ・何を? ・ユースケースで整理する ・いつ? ・つくろう!すぐ作れるようにしようねって感じ ・誰と? ・最強のチーム。意思決定がはやい。 自分主体でサービス設計して、作りなおすのをためらわない ◎ディスカッション Q:どうしてサービス作ったの? A:エンジニアへのあこがれから、サービスを作った(閑歳さん) ものづくりという意味では、Webサービス以外もあるけど?(馬場さん) 学内のSNSのようなものを作ってて、アクセスが伸びるのが面白かった。(閑歳さん) 大学でlastfmみたいなものを研究してて。。。(和田さん) 社会に出てサービスを作るまでの話は?作って稼ごうって思ったのは?(馬場さん) あんまりなかった。(閑歳さん) すでに起業してた。サービス作ると実績として認められて仕事が入ってきてた。(和田さん) 直接あった時に反応がもらえるのが楽しい。(和田さん) Q:どうやって、チームを組み立てたりして開発とかしてきたのか?(馬場さん) A:「ボケて」まとめサイトでブレイクしたけど、アクセス数が落ちてない。 同年代の知人で色々とチームが組めてて楽しい(和田さん) はじめは一人でやってて、しかも構想とか。あとロゴだけ最初に作ってた。 ノマド的に作業してました。(閑歳さん) Q:チームがバラバラですが、困らないですか? A:今のところ困ってないです。もっと人が増えると困るかもしれないですけど。(閑歳さん) それぞれが他に職を持ってるので特に困ってないです(和田さん) 向き不向きはあるんじゃないかなぁ。10人とかになるとどうなるか不明(閑歳さん) GoogleのMLでレスが早ければ問題ないかな。(和田さん) あとは、チームが大きくならないように上手く分割してる(?)(ふたりとも) Q:ユーザの声の吸い上げ方、サービス改善の判断材料は? A:ユーザの声は聞くけど、全部取り込むものではない。 細かな点はユーザの声を取り込むけど、軸はブレないようにしてる(閑歳さん) 古参ユーザよりも新しいユーザを取り込むのが大事。(和田さん) nanapiのけんすうさん Q:品質はどうしてる? A:セキュリティは絶対。(閑歳さん) 品質を気にするってのは難しい。品質を担保できる仕組みを作るとこまでいけるようにしたい。 投稿される画像はチェックしている。(和田さん) ","date":1366717542,"dir":"post/2013/","id":"36ff37ced0d3211db95a5ac0daac0c35","lang":"ja","lastmod":1366717542,"permalink":"https://blog.johtani.info/blog/2013/04/23/%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%82%B9%E3%82%AD%E3%83%AB%E3%82%A2%E3%83%83%E3%83%97%E5%8B%89%E5%BC%B7%E4%BC%9Atech-compass--tecomp--vol-2-%E4%BA%BA%E6%B0%97web%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%81%AE%E4%BD%9C%E3%82%8A%E6%96%B9%E6%95%99%E3%81%88%E3%81%BE%E3%81%99%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2013-04-23T20:45:42+09:00","summary":"第2回目も参加しました。 とりあえずメモ。 自分には欠けてる視点の話しなので面白かった。 ちょっと寒かったなぁ。 エンジニアのためのスキルアップ勉強","tags":["勉強会"],"title":"エンジニアのためのスキルアップ勉強会『Tech Compass』 #tecomp ― Vol.2 「人気Webサービスの作り方教えます!」に参加しました。(Jugemより移植)"},{"contents":"だいぶ、ブログを書くペースが落ちてきてて、危機感を感じている今日このごろです。。。 今回は、個人的に利用しているJIRAのバックアップについて、ブログに残しておこうかと。\nさくらVPSのサーバを借りてJIRAを運用しています。 運用といっても、自分の備忘録のためというのが大半の理由です。 タスクを忘れないように管理するのと合わせて、その作業を行ったときのメモも残したいなと。\nバックアップといっても、同じサーバ内に保存しても意味がない+AWSを触ると言いつつ1年以上経ってしまったので、 このへんで本腰を入れるという意味も込めてAWSのS3(ゆくゆくはGlacier)にバックアップを取る仕組みを作りました。 「作りました」というと凄そうですが、Cronとシェルだけで終わりました、なんて便利な世の中。 ということで、以下は作業の備忘録です。\n1.AWSのアカウント作成 アカウントを作ってください。ここは特に説明しなくてもいいかと。。。クレジットカードの登録が必要なのが注意点でしょうか。 アカウント作成後の1年間は無料枠と呼ばれる仕組みが用意されており、いろんなことが無料で行えます。 (まだ、S3しか使ってないので、他にももっと使わないと。。。)\n2.S3のバケット作成 AWSのアカウントが作成できたら、Amazon S3(Simple Storage Service)のバケットと呼ばれる、データの保存先を作成します。 作成手順はこちらの公式入門ドキュメント(英語)をそのまま行いました。 簡単な手順はこちら\nAWS Management Consoleと呼ばれるところから、S3のコンソールにアクセス 「Create Bucket」ボタンをクリック 「Bucket Name」を入力し、リージョンを選択したら「Create」ボタンをクリック 以上でバケットが作成されました。これだけです。WebのConsoleからファイルをアップロードすることも可能です。 ただ、今回はさくらVPSから定期的にバックアップしたいのでシェルでアクセスできるようにします。\n3.AWSのアクセスキーとシークレットアクセスキーの取得 次に紹介するs3cmdというツールを利用するのに、AWSのアクセスキーとシークレットキーが必要になります。 取得方法はこちらを参考にしましたが、今は日本語のページが用意されています。 セキュリティ証明書(Security Credentials)のページで、「アクセス証明書」というタブで、「新しいアクセスキーを作成する」リンクをクリックしてください。 アクセスキーIDが新しく表示されます。このアクセスキーIDとシークレットアクセスキー(表示リンククリック後に表示される)をメモしておきます。\n4.s3cmdのインストール 世の中には便利なものを作ってくれる方がいるもので。 s3cmdと呼ばれるS3へアクセスできるコマンドラインツールが存在します。 ということで、こちらをインストール。これまた、便利なものでインストール手順を書いてくれれてるブログもありました。(あれ、なんか、見たことある名前がURLにはいってるなぁ) インストールはこちら。\n# yum -y --enablerepo epel install s3cmd インストール後に、先ほど取得したアクセスキーIDを設定します。\n$ s3cmd --configure Access Key: xxxx Secret Key: xxxx 以上で、s3cmdが使えるようになりました。\n5.バックアップスクリプトの作成 つぎは、本題のJIRAのバックアップです。 バックアップ方法はこちらを参考にしました。ちょっと古いみたいですが。 おもなデータは「JIRAのXMLバックアップユーティリティ」にてバックアップするか、「データベースのバックアップツール」を利用する方法があります。 推奨は「データベースのバックアップツール」のようなので、私の場合は「pg_dump」にてJIRAのデータベースをまるごとバックアップすることにしています。 また、データベースには添付ファイルが保存されていないようなので、別途「/var/atlassian/application-data/jira/data」というディレクトリをtarコマンドで圧縮して保存すようにしました。 あとは、pg_dumpの結果と添付ファイルの保存先の圧縮したデータをまとめてディレクトリに保存して圧縮します。 さいごは、S3にアップロードすればおしまいです。 一応、ファイルが連綿と残り続けるのは嫌だなぁということで、ファイル数で世代管理することにもしました。 これまた、ググって見つけてきたサイトを参考にしただけですが。。。 ということで、こんなかんじのスクリプトを日時でcronに設定して動かしてます。\n#!/bin/sh TODAY=`date +%Y%m%d` BACKUP_HOME=\u0026#34;/var/atlassian/backups\u0026#34; S3SYNC_DIR=\u0026#34;/var/atlassian/backups/s3sync\u0026#34; AGE=7 mkdir -p ${BACKUP_HOME}/${TODAY}/ /usr/bin/pg_dump -U postgres -Fc jiradb \u0026gt; ${BACKUP_HOME}/${TODAY}/jiradb_backup.dump tar zcvf ${BACKUP_HOME}/${TODAY}/attachment.tgz /var/atlassian/application-data/jira/data tar zcvf ${S3SYNC_DIR}/jira_backup_${TODAY}.tgz ${BACKUP_HOME}/${TODAY} rm -rf ${BACKUP_HOME}/${TODAY} NUM=`ls ${S3SYNC_DIR} | wc -l` while [ ${NUM} -ge ${AGE} ] do DEL_FILE=`ls -lt ${S3SYNC_DIR} | tail -1 | awk \u0026#39;{print $9}\u0026#39;` rm -r ${S3SYNC_DIR}/${DEL_FILE} NUM=`ls ${S3SYNC_DIR} | wc -l` done s3cmd sync --delete-removed ${S3SYNC_DIR}/* s3://my_jira_backup/s3sync/ そこへんだよとかあれば、ツッコミを。 今のところ、S3へのsyncだけなので、このあとは、月1くらいでGlacierに落とすとかの仕組みも考えるかなぁ。これまた何かあるんだろうけど。 あとは、この応用で家のNASに溜まっている写真をS3経由もしくは直接Glacierにバックアップする仕組みを考える予定です。\n","date":1366639648,"dir":"post/2013/","id":"1ca04e5339ed1826c12fe61fd984e949","lang":"ja","lastmod":1366639648,"permalink":"https://blog.johtani.info/blog/2013/04/22/jira%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92s3%E3%81%B8%E3%83%90%E3%83%83%E3%82%AF%E3%82%A2%E3%83%83%E3%83%97/","publishdate":"2013-04-22T23:07:28+09:00","summary":"だいぶ、ブログを書くペースが落ちてきてて、危機感を感じている今日このごろです。。。 今回は、個人的に利用しているJIRAのバックアップについて","tags":["備忘録"],"title":"JIRAのデータをS3へバックアップ(Jugemより移植)"},{"contents":" HerokuではじめるRailsプログラミング入門 heroku気になってるのに使ってなくて、TDのアカウント作ってデータアップしてない軟弱者ですが、参加して来ました。。。 とりあえず、大事なことです。まずは、上記の書籍を買ってください(って中の人が言ってました。) イベントページはこちら。\n総じて、herokuの中のエンジニアの方たちがすごく情熱があって、ユーザと会話をしたがっているという感想だったようで、まだまだ、よくなりそうだなぁと。 私は、ベースがJavaなので、JavaやScala、Playで使ってる方の感想とか聞きたいかなぁ。 あと、herokuとS3の組み合わせだと思うんですが、料金とかはAmazonとheroku両方に別々に払うのかな?とかはちょっと気になりました。 AWSのアカウントも作ってS3にバックアップあげるの作ろうと思って手をつけてない軟弱者ですが。。。 今月は余裕がありそうなので、TDとか触ってみようと思います。。。\n懇親会ではTDのmuga-sanとお話できて、いくつか気になってた話ができたのでスッキリしました。 あと、株式会社サムライズムの名刺頂きました。写真載せろって言われたけど、また今度w\n最後に、大事なことです。まずは、上記の書籍を買ってください(って中の人が言ってました。)\n以下は、いつものようなメモです。最後の方はちょっとくたばってたのでメモがおざなりになってます、すみません。\n日時:2013年04月04日(木) 18時30分 - 21時00分 場所:日本創生ビレッジ 事業開発支援オフィス 東京21cクラブ コラボレーションスペース ◯Ayumu Aizawa(Heroku, Inc.) ・■ PostgreSQLが9.2になりました。 ・◆ メモリが2倍。βテスタ向けにスケールアップ。 JavaとかJavaとかJavaとかデプロイしてもいいよね。 けど、メモリ2xは価格も2x! ・● Heroku OAuthを提供。Experimentalだけど。 heroku-bouncer使うとOAuthが楽になる。 ◯Treasure Data and heroku Masahiro Nakagawa(TreasureData) ・会社紹介 ・フロントエンド部分の担当(fluentd) ・1500億レコード!? ・投資家の中にHerokuの方がいる。 ・ターゲットは? Cloud + Big Dataが対象 Hadoopは立ち上げるのはいいんだけどメンテナンスコストが。 Hadoopの処理基板を提供 ・Hadoop生ではなく、Plazmaを使っていたりする。 ・Viki herokuにtd-agent入れて、TDにデータ送って、Postgresに書き出して使ってる。 ・TDはどうやってheroku使ってるの? Webコンソール。 http://console.treasure-data.com Webサイトは大体heroku fluentdとかも ・herokuのaddonとしてtd-agentを提供してる。 ・STDOUTからTDにデータ送るのもできるよと。 ◯Waza Report ◯吉田雄哉さん(co-meeting) ・まずは、co-meetingの紹介。 1文字ずつ送信してるよと ・Chief Talk Officerらしいw ・MongoDB使ってるって言ったら、herokuのPostgreSQLの人と話して、鼻で笑われたw ・すごく熱意のある人達がエンジニアとして働いてる ・ユーザの声をきちんと聞いてくれる体制ができてるミーティングだった。 ・「クラウド」って単語を聞いてない。勉強会のレベルもすごい。 ◯山本裕介さん(株式会社サムライズム) ・ニッチなブログ書いてます。 ・Java屋が見るWaza Tシャツプレゼント! ・OSS好きが多い。 Java/Scala系の話が少なかった。Scala界隈では人気みたい ◯岡村純一さん(株式会社シャノン) ・スライド1枚も作らずに喋る人とかいました。 (すごい。。。) ・Django Playに似てて面白いかもと ・Ruby2.0 Matzが喋ってたとか ・クロージングはビールが出てきてた。 交流パーティみたいになってた。CROSSがそれに似てますね。日本でやってるイベント ◯小西俊司さん(株式会社フレクト) ・バックエンドの性能とかを収集して見ることができるツールがあるらしい。 ・クエリを登録しておくと監視ができるツールとか。(TDとかぶってる?) ・やっぱり、情熱的だし、OSS好きでオープンな感じのエンジニアが多い。 ◯Heroku LT 無慈悲なLTです。3分たったらケーブル引っこ抜きます。 (最後はくたばっててあまり聞けてない。。。) ◯山本 裕介(株式会社サムライズム) ・herokuでJava7! Java6終わってますからherokuも移行してね! ◯竹野 淳(Grow!) ・BoxTo? ・コラボレーター募集! ◯小西 俊司(株式会社フレクト) ・ExcelのテンプレートをアップロードしてGETでパラメータわたせばいいよみたいなの作ってる。 ◯大久保英樹(Job-Hub) ・CarrierWaveとかの注意点 ","date":1365128443,"dir":"post/2013/","id":"73d2fce4efa52675b35a11ee97bc2db0","lang":"ja","lastmod":1365128443,"permalink":"https://blog.johtani.info/blog/2013/04/05/heroku-meetup--8-treasuredata--waza-report-%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-herokujp/","publishdate":"2013-04-05T11:20:43+09:00","summary":"HerokuではじめるRailsプログラミング入門 heroku気になってるのに使ってなくて、TDのアカウント作ってデータアップしてない軟弱者","tags":["勉強会"],"title":"Heroku Meetup #8 TreasureData + Waza Report!! に参加しました。#herokujp(Jugemより移植)"},{"contents":"記念すべき!?第10回のSolr勉強会です。\n発表者が無事あつまり(本当にありがとうございました!)、今回も盛況な感じでほぼ満員でした。 ツイートのおかげか、キャンセル処理もちゃんと行なってもらえて助かりました。 開場直後にドタバタしてしまい、すみませんでした。。。\nとりあえず、第一報の記事をアップしておきます。 懇親会での話とか感想はまたあとで。\n関口さんの資料は実は、前もって見たことがある資料でした。 最初の発表にしては、少しむずかしいと思った方もいるかなぁと。 ただ、類義語の辞書は結構作るのが大変だし、探しても出てこないものなので、面白い話だったんではないかなぁと。 「ミスチル」はできないけど、「マツケン」ができるのは読みがあるからとかなんですかねぇ?って質問するの忘れてた。\n尾形さんの話は結構、みんな通ってきた道かもなぁと思いました。他の方も同じ経験してるんじゃないかなぁと。 ただ、一人でやるのはすごいですよね。検索って結構人数が割かれてない場合が多いのかなぁ。 あんまり使われていないというのが少し悲しい話でしたが。。。 サーバを要求すれば結構なスペックが用意してもらえるのはうらやましい限りですねぇ。 スキーマ変更については、レプリケーション機能を使うと追加などならうまくいくんじゃないでしょうか。(そんなツイートもありましたよ。togetter読み返すと出てきます。) フィールド名を変更しないで型を変更するなどしたらおかしくなると思いますが。\n野口さんの話はなかなかチャレンジングでいいなぁと思いました。よく挫けずに頑張られているなぁとw 試行錯誤した仮定も発表してもらえると同じ轍を踏んだ人が助かると思います。 大きな企業で本格的に横断的な社内検索が出来る仕組みが出来上がっているって話はなかなかきかないかなと。 どうしても、社内検索とかお金が出なくて手を付けられないといいう悲しい話が多いので、こういう話は共有したい情シスの方がいっぱいいるんじゃないかなぁと。 ManifoldCFが結構地雷を多く含んでいるのは大変そうですね。。。 SolrにもTikaが入っていたりしますが、個人的にはTikaがやるべき処理は前処理と思っているので、Solrとは別の場所でやりたいとか考えていたりします。 ManifoldCFがその辺りまでやってくれるかまではちゃんと調べてないんですが。 Solrは検索だけに注力させることで、役割を分割できるので、性能の対処とかを行うのが楽になるんじゃないかなぁとか。 ManifoldCFで困ってる人は他にもいるようなので、ジャンジャン使って、どんどんチケット上げて貢献してもらうといいかと。 また、定期的に発表してもらうと面白そうだなぁと。\n弘瀬さんの話は結構興味ある方がいたんじゃないかなと。 SolrCloudは壮大だなぁと思いつつ、手を出しづらいと思ってる方が多いと思います。 実際のサービスに投入して試行錯誤された話を細かな数値も上げて発表してもらえるのは検証をやる方の助けになります。 残念ながら、私もSolrCloudは興味有りつつちゃんと追っかけてないので、途中でnodeとshardとcoreの関係がわからなくなってしまいましたので。。。 もう一度勉強して、スライドを見たいと思います。。。 分散検索(1つのインデックスが複数のcoreやshardに分割された状態)が絡んでくると、複数台の検索の性能のうち、一番遅い性能が最終的な検索性能に響いてくるので、検索リクエストの偏りとかも影響が出たりするかもしれないなぁと。 そういった意味でも試行回数を3以上で計測した結果で再度発表してもらうと面白そう!(なんか、下心見え見えですがw)\n前回、今回も感じたのですが、もう少し質問をしてもらえると発表された方も励みになるかなぁと思いました。 質問しにくい雰囲気になってるのでしょうか?参加者が結構いるから質問しにくく感じたりするのでしょうか? そのあたりをもう少しうまくやれるようになにかコメントもらえると嬉しいかなぁと。 運営で気になった点などもコメントやツイートをいただけると今後の改善にも役立てますので気兼ねなく連絡いただけると助かります。 開場がドタバタしすぎとか、ハッシュタグがわからなかったとか。\n今回は思ったよりも懇親会に残る方が少なめでした。 コミッターの方(LuceneやManifoldCFとかlucene-gosenとか)が複数いたり、Solrを結構触ってる方がいたりと面白い話が聞けそうだったのですが。。。 Kuromojiのユーザ辞書の改良点をチケットにあげるって約束したのでやらないとなぁ。 早く帰るつもりだったのに気づいたら23時でしたwやっぱり色々と話ができるのが楽しくて。。。 駅前の機動隊とかびっくりしながら帰りました。 今回、お話ができなかった方もいらっしゃるかと思いますが、気兼ねなく、ツイートしてもらったり、声をかけていただければと。\nあと、常に発表していただける方は歓迎しておりますので、連絡いただけると非常に助かります! こんな話が聞きたいなどでもいいかと思いますので、連絡いただければと。\n#SolrJPもtogetterにまとめてもらいました。ありがとうございます。 以下は、いつものメモになります。\n日時:2013/03/26 19:00 to 21:00 場所:VOYAGE GROUP 会議室 1. 株式会社 ロンウイット 関口 宏司さん タイトル:Wikipediaからの類義語知識の自動獲得について 発表資料はこちら\n・「辞書型コーパス」という単語は造語かもしれません。 ・なんでこんなことを? →類義語辞書を自動生成したいから。 ・自賠責保険、自動車賠償責任保険を例にSynonymFilterの説明。 ・Wikipediaを入力として、類義語辞書を作成するときにLuceneのインデックスを活用してる。 ・類義語候補の見つけ方 いくつかヒューリスティクスな処理とかも入れてます。 日本語Wikipedia固有なもの。 ・実際に導出された単語も載ってる。 FTPなども導出で来てる。 丸ビルとかも。 ・導出できなかったものもあります。 「十六進法」が「十進法」になってる 「ミスチル」も無理。 ・ミスもあるけど、類義語が存在しない場合になんとなく、使う辞書としては採用できるのでは? 類義語検索対象のブーストを小さくするなどをすれば役に立つ Q:類似度にしきい値を用意したりしてますか? A:min.scoreという値を用意し、足切りをしている。 Q:ベクトルを作るという話があったが、品詞でフィルタリングとかしてる? A:名詞に限って処理してます。名詞に限らなくてもいいかも。。。(若干聴き逃しました) 重みの高いn件をベクトルの対象にしてます。 2. グリー株式会社 尾形 暢俊さん タイトル:GREEにおける全文検索の歴史 発表資料はこちら\n・GREEさん、検索はないがしろにされてる。。。 一人でつくって、一人でメンテナンスしてる。 ・GREEの検索は右上の検索ボックスが ・2007年はSennaつかってました。 Tritonnに移行。2009年くらいまで。 やっぱり安定しない+MySQLのバージョンアップしたいけど、追従できない ・2012年初頭までLuceneでやってた。(結構古い) フラグメントが発生してOptimizeすると、検索サーバが使えなくなる。。。 検索しにくるサーバが1000台いるので、Optimizeかけるときに、1000台のサーバの設定を書き換えるとかしてた。。。 ・現在まではSolrをつかってる。 Luceneのバージョンも古かったので100倍くらい速くなった。 ・Solr本が必須ですよ!!! ・Lucene+Tomcatから移行。 移行に気をつける点として、I/FをそのままSolrに置き換えると。 Solr返却のXMLをカスタマイズしたり、クエリをSolr向けに書き換えたり。 あと、メンテナンスが楽になるように。 40数台のインデックスサーバがあると。 一人でメンテナンスしてるから、楽になる方法が重要 ・レプリケーションで、Optimizeの影響が出ないように。 キューをつかって、マスタに登録して、スレーブにレプリカを配布 ・スキーマが7つ あんまり使われてなくてかなしい。。。 ・負荷のグラフもありました。 ・RangeQueryを結構使う。 ・作りこんだ部分 インデックスのMasterへ分散させる処理とか クエリの変換とか人力監視処理とかNGワードとか サーバ監視のための仕組み ・今でも大変なこと スキーマ変更が大変 スレーブをマスタに昇格とかが手動 ・今後改善したいこと 精度を上げたい 辞書を使ってみたいけど、各国語対応 あと、自動化とか 3. ソフトバンクBB株式会社 野口 勝義さん タイトル:企業内の大規模ファイルサーバ検索事例 ・情シスの企画版?という立場のかた。 ・売上に貢献したいのでクラウドサービスとして検索をオプションとして立ち上げてみた! ・Solr+ManifoldCFで作ってみたよと ・なんでSolr? OSSだし、機能が充実 ・なんでManifoldCF? Active Directory連携が使いたかったと。 社内検索ってやっぱりアクセス権がうるさいので。 ・ManifoldCFの説明はロンウイットさんの画像を使わせてもらいましたw ・ファイルサーバが、70TB。。。 ・困ったこと。 ・その1 ・クローラージョブの構成の最適化どうする? ・マルチコアで、クローラーとファイルサーバを1対1の構成にしてみた。 ・その2 ・ファイル数が増えるとまた問題が。。。 ・ファイルサイズが大きい→Heapが足りないエラーとか、MCFのタイムアウトとか。。。 ファイルサイズのリミットを設けてみた。 mp4とかでエラーがでるとか。既知のエラーでしたとか。 ulimitがたりないとか。 MCFの稀に出るバグとか。。。 ファイルサーバの不良ブロックとか。。。 ・その3 ・クロールに時間がかかる ・MySQLでスロークエリとか MySQLよく知らないとか言われながらコミッターに対応してもらうなど。 SSDつかうとか考え中 ・フルクロールで1週間 差分でも1日強かかる。 ManifoldCFだけで対応できないから、ファイルの特徴を元に →ManifoldCFを経由しないリアルタイムインデックス更新のAPIを経由してMasterじゃなくて、更新かけると。(特定のクライアントからの方法) ・その4 ・本文データをstored=falseに けど、ハイライトできないから、どうにかしたい ・ユーザの要望 ・もしかして検索 類義語?じゃないよねぇ。テザリング、tezaringuとか フロント側で頑張った。(Solr諦めました) ・検索スコアも弄りたいとか 外部データでブーストとかもしたい。External Fieldとか使うといいのでは?とか。 4. 株式会社サイバーエージェント 弘瀬 健さん タイトル:SolrCloudの導入事例 発表資料はこちら\n・Webエンジニアだったのに、検索エンジニアに! ・SolrCloudもサービスインしてると。 ・SolrCloud概要 4.0以降の機能とか。 ・SolrCloudの構成要素 概念的なもの。Collection、Shard 物理的なもの。Node、Core ・ Simplogってサービスに導入済み。 ZooKeeperが3台、6Shard、3nodeという形式 ・性能 平均レスポンスタイム50msec 思ったより出てないので、調べてみた。node数とかshard数を変えてみて調べてみた(まだ、模索中。) ・色々テストケース試したけど、試行回数が1回だけです。 詳細なデータが出てるのありがたい(全部はまだ理解できてないですw) ・検証まとめ ノード当たりのcore数が少ないほうが検索、更新性能がいい 1コレクション当たりのshard数が少ないほうが検索性能がいい ・まとめ ・SolrCloudの利点 クライアントが色々意識しなくていいのがうれしい。 ・SolrCloudの注意点 shardの分割機能がまだないので、大変。 コレクション情報が壊れると検索更新できないとか。4.0だとバグが有った ・性能的には素のSolrのほうがいいよと。 ","date":1364300160,"dir":"post/2013/","id":"26d0c0d8c465087cf160a3bdc479f2b4","lang":"ja","lastmod":1364300160,"permalink":"https://blog.johtani.info/blog/2013/03/26/%E7%AC%AC10%E5%9B%9Esolr%E5%8B%89%E5%BC%B7%E4%BC%9A%E3%82%92%E4%B8%BB%E5%82%AC%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-solrjp/","publishdate":"2013-03-26T21:16:00+09:00","summary":"記念すべき!?第10回のSolr勉強会です。 発表者が無事あつまり(本当にありがとうございました!)、今回も盛況な感じでほぼ満員でした。 ツイー","tags":["勉強会"],"title":"第10回Solr勉強会を主催しました。#SolrJP(Jugemより移植)"},{"contents":"なんか、とても久しぶりにイベント参加メモ以外の投稿です。 elastic searchのMLを見てたら、KuromojiのAnalyzerを使うときにユーザ辞書使うのどうするの?という投稿を見かけました。\nKuromojiのユーザ辞書にもちょうど興味があったり、elasticsearchもちょっとずつ触りたかったのでちょっと試してみました。(返信もしてみましたが、テキトーな英語です。。。)\nelasticsearch-kuromoji-pluginのインストールなどはElasticSearch で kuromoji を使う (ES 0.90.Beta1 + kuromoji 1.2.0篇)を参考にしてください。 私もこちらに記述のある組み合わせ(elasticsearch-0.90.0Beta1 + elasticsearch-analysis-kuromoji/1.2.0)を利用しました。 KuromojiのAnalyzerはデフォルトで「kuromoji」として登録済みですが、こちらはユーザ辞書の指定がありません。 ということで、「kuromoji_user_dict」というユーザ辞書指定をしたtokenizerと、それと使う「my_analyzer」というanalyzerを登録したIndexを作成します。 定義する前に、「userdict_ja.txt」を用意して、elasticsearch-0.90.0Beta1/config/ディレクトリに配置しておきます。 (以下のサンプルでは、SOLE_HOME/example/solr/collection1/conf/lang/userdict_ja.txtをコピーして使いました)\n$ curl -XPUT \u0026#39;http://localhost:9200/kuromoji_sample/\u0026#39; -d\u0026#39; { \u0026#34;index\u0026#34;:{ \u0026#34;analysis\u0026#34;:{ \u0026#34;tokenizer\u0026#34; : { \u0026#34;kuromoji_user_dict\u0026#34; : { \u0026#34;type\u0026#34;:\u0026#34;kuromoji_tokenizer\u0026#34;, \u0026#34;user_dictionary\u0026#34;:\u0026#34;userdict_ja.txt\u0026#34; } }, \u0026#34;analyzer\u0026#34; : { \u0026#34;my_analyzer\u0026#34; : { \u0026#34;type\u0026#34; : \u0026#34;custom\u0026#34;, \u0026#34;tokenizer\u0026#34; : \u0026#34;kuromoji_user_dict\u0026#34; } } } } } \u0026#39; 「user_dictionary」というのがユーザ辞書の定義ファイルになります。 注意点としては、6行目で指定した名前「kuromoji_user_dict」を14行目の「tokenizer」に指定しないとちゃんと動かないという点でしょうか。\n上記で指定したAnalyzerを利用して「朝青龍」という単語をを解析してみます。\n$ curl -XGET \u0026#39;http://localhost:9200/kuromoji_sample/_analyze?analyzer=my_analyzer\u0026amp;pretty\u0026#39; -d \u0026#39;朝青龍\u0026#39; { \u0026#34;tokens\u0026#34; : [ { \u0026#34;token\u0026#34; : \u0026#34;朝青龍\u0026#34;, \u0026#34;start_offset\u0026#34; : 0, \u0026#34;end_offset\u0026#34; : 3, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 1 } ] 「朝青龍」という単語がユーザ辞書に登録されているので、1単語として出力されます。 ちなみに、デフォルトの「kuromoji」のanalyzerを指定すると以下の様な出力です。\n$ curl -XGET \u0026#39;http://localhost:9200/kuromoji_sample/_analyze?analyzer=kuromoji\u0026amp;pretty\u0026#39; -d \u0026#39;朝青龍\u0026#39; { \u0026#34;tokens\u0026#34; : [ { \u0026#34;token\u0026#34; : \u0026#34;朝\u0026#34;, \u0026#34;start_offset\u0026#34; : 0, \u0026#34;end_offset\u0026#34; : 1, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 1 }, { \u0026#34;token\u0026#34; : \u0026#34;青龍\u0026#34;, \u0026#34;start_offset\u0026#34; : 1, \u0026#34;end_offset\u0026#34; : 3, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 2 } ] とまぁ、こんなかんじです。 ユーザ辞書を書き換えたあとは「close/open」しないと読み込めないのかなぁ?そのへんはまたあとで調べようかな。\nちなみ、以下のページを参考にさせてもらいました。 elasticsearch kuromoji plugin - natural days ElasticSearch で kuromoji を使う (ES 0.90.Beta1 + kuromoji 1.2.0篇)\n","date":1363765380,"dir":"post/2013/","id":"f5f28f42ad234b4389af4cbea54ff60d","lang":"ja","lastmod":1363765380,"permalink":"https://blog.johtani.info/blog/2013/03/20/elasticsearch-analysis-kuromoji%E3%81%A7%E3%83%A6%E3%83%BC%E3%82%B6%E8%BE%9E%E6%9B%B8%E3%81%AE%E5%88%A9%E7%94%A8%E6%96%B9%E6%B3%95/","publishdate":"2013-03-20T16:43:00+09:00","summary":"なんか、とても久しぶりにイベント参加メモ以外の投稿です。 elastic searchのMLを見てたら、KuromojiのAnalyzerを使うときにユーザ","tags":["elasticsearch"],"title":"elasticsearch-analysis-kuromojiでユーザ辞書の利用方法(Jugemより移植)"},{"contents":"久々にブログ+イベント参加です。 知り合いが開催+出演したので参加してみました。 「スマホ」ってキーワードはあまりなかったけど、面白かったです。\nとりあえず、メモ。 余力があれば感想追加します。\n日時:2013/03/19 19:00 場所:パレスサイドビル9F マイナビルーム (東京都千代田区一ツ橋1-1-1) URL:http://atnd.org/events/36966 登壇者:@naoya_ito @yusuke ◯@naoya_itoさんの発表 最近、感心してること。 ・RubyMotionやってます。 今年5月に ・AWSもやってるよ。 ・「継続的デリバリー」の話 GREEでは毎日デリバリーしてるよと。 ・Chefの話 DevOpsとか。 ・Obama for Americaの話 GitHubとか使ってた。 身に付けるべきものは? 「変化に適応する力」が必要だよね。 最近は Ruby、クラウド、AWS、iOS開発とかやってる、どうしてこうなったw 先は予測してないけど、変化に適応するには5分でいいからやり続けること。 ◯@yusukeさんの発表 自己紹介が難しい ・今やってること ブログ執筆 刺さるツイート研究 ソフトウェア販売代理店 思わぬ収穫。InDesign/Illustratorのスキル、ビジネスの仕方w 会社設立中。 Webサイト構築・運用 ・ハッタリが大事 ・プログラム好き プログラミング以外を仕事にしてる。 ・人と違うことがしたい。市場がない場所での差別化はしない=トレンドに逆行し過ぎない。バランス。 ・今は種まき中。 ◯ディスカッション ・2,3年後とか何やってると思いますか? @naoya_itoさん ドラクエやってると思ってるかもしれませんが、サービス作るコード書いてます。 将来的な見通しでやってるのか?って言われるとそうでもない。 ツールとかよりは、コミュニティとかのサービスを作るほうが好き。 @yusuke 一定の収入がありつつ、プログラミングしてたい。あわよくばサービス作ったのが当たるといいなぁ ・そもそもフリーランスをどう捉えているか? @naoya_ito いいところ。自由に自分の時間をコントロールできる。 悪いところ。自分でコントロールしないといけない。 自分をコントロールしないと厳しい。 フリーになってわかったのは、会社は人間を働かせるための仕組みをよく考えて出来てる。 フリーでいいのは、選択した結果に自分が責任を持つというのがいい。 @yusuke セフルマネージメントできたほうがいい。 しがらみを捨てるためにフリーになるのはおすすめしない。 ・情報発信を継続してるけど、必要なことか? @naoya_ito 必要とは思わないけど、みんな書いたらいいと思う。 検索すれば自分が助かるからw セルフブランディングのために重要?かなぁ。あまりそれが唯一の方法ではないと思う。 @yusuke 発信することで、何に興味を持ってるかをわかってもらえるから、便利かな。 ブログに残したほうがググって引っかかるよと。 ・技術の方向性?見つけ方?は? @naoya_ito 直近は、クラウド流行るしiOSはまだ伸びてるしと。 そっから先はどうするの? わからないよね。じゃあ、どうするの?って変化に対応してボトムアップで見つけてくのがいいんじゃないかなぁ。 人がやってないところを先にやらないと武器にならないけど、どうやって見つけるのか? プログラミングやってる時に、その先に必要なこととか、気付きがあるので、手を動かさないとだめだよねと。 @yusuke トレンドを追いかけつつ、知ったかぶりするのは重要 ある程度ハッタリ+手を動かす ","date":1363692480,"dir":"post/2013/","id":"5412fb82160d0f6093e4b6670f505c13","lang":"ja","lastmod":1363692480,"permalink":"https://blog.johtani.info/blog/2013/03/19/%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%82%B9%E3%82%AD%E3%83%AB%E3%82%A2%E3%83%83%E3%83%97%E5%8B%89%E5%BC%B7%E4%BC%9Atech-compass%E7%AB%B9%E6%A9%8B--vol1-%E3%82%B9%E3%83%9E%E3%83%9B%E6%99%82%E4%BB%A3%E5%88%B0%E6%9D%A5%E3%81%93%E3%81%AE%E5%85%88%E7%94%9F%E3%81%8D%E3%81%AE%E3%81%93%E3%82%8B%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E3%81%AF%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-tecomp/","publishdate":"2013-03-19T20:28:00+09:00","summary":"久々にブログ+イベント参加です。 知り合いが開催+出演したので参加してみました。 「スマホ」ってキーワードはあまりなかったけど、面白かったです。","tags":["勉強会"],"title":"エンジニアのためのスキルアップ勉強会『Tech Compass』@竹橋 ― Vol1 「スマホ時代到来、この先生きのこるエンジニアとは!?」に参加しました。#tecomp(Jugemより移植)"},{"contents":"技術ブログから離れていってますが。。。 Xperia Zを購入しました。\n前に使っていたのはXperia arcになります。 もうすぐ2年だったのですが、容量不足に悩まされていたため+芸の肥やし(仕事の足し)という名目で Xperia Zの購入に踏み切りました。 予約しての購入です。\nいくつか戸惑いなどを感じているので備忘録としてブログに残しておきます。 サイズが大きい___ まぁ、わかっていたことですが、5インチと大きいです。 ステータスバーを表示するのがちょっときついくらいです。 私は手が大きい方なのですがそれでもキツイので、普通の人は両手じゃないと厳しいんじゃないかと。。。 一応、ステータスバーを表示するためのアプリなんかもあるようなので、その辺を検討するのもいいかなぁと(まだインストールもしてませんが。) また、Angry Birdを演ってびっくりしたのですが、解像度が大きいため、startボタンなどが小さくて押しづらいですw\n移行がめんどくさい___ iPadも持っていて、ソレと比較するとひどくめんどくさかったです。 実は方法を知らないだけかもしれないんですが。。。 iPadだと、初期化したりしてもiTunesにインストールしたアプリなども覚えていてくれます。 ですので、すぐに同じ環境が出来上がります。 Xperiaに関しては、arcでインストールしてたアプリをインストール履歴を元に一つずつインストールして、 それぞれのアプリやアカウントを設定して行きました。 これが結構面倒で、まだ完全にはアプリがインストールできてないかも(他にも新しいものを入れたいなぁと思いつつ、探す手間を惜しんでます。。。おすすめアプリお待ちしてます。)\nZite、Angry Bird star warsがインストールできない___ Ziteは英語の勉強も兼ねて入れていたのですが、対応していないバージョンですと言われます。 AngryBirdもいっしょですね。 starwarsじゃない奴はインストールできたのですが、肝心のやってみたいstar warsがインストールできなくて。。。\nドコモアプリがいっぱい___ ドコモのアプリやプリインストールアプリがいっぱいあったので、どうしようか悩んでいます。 いくつかはアンインストールしました。HotpepperBeautyとか間違いなく使わないし SFA-QRというよくわからないアプリも入っていたのでこれまたアンインストールしました。\n通知に出さないアプリとか選択できない?___ 容量不足だったのも有り、TwitterクライアントにはTwiccaのみをインストールしていたのですが、今回はTwitter純正のクライアントもインストールしました。 お気に入り登録されたりといった状況も見れるので重宝するのですが、基本的にはtwiccaを使うつもりです。 ですが、通知バー(ステータスバー)に@ツイートが届いたなどといった通知は見なくてもいいと思っているんですが、なにか方法あるんでしょうか。\ndビデオが危険___ いわゆる携帯ショップで機種変更したため、いくつかのサービスに登録しないといけませんでした。 で、dビデオ(月額525円で映画とか見放題)に登録したので、せっかくだからと映画をダウンロードしてみたのですが、危険です。。。 ただでさえ、本読むのが遅かったり、コーディングしてないのにビデオ見ると更に時間ががが。。。 けど、面白くて。。。危険です。(スターシップ・トゥルーパーズ見ちゃいました。。)\nクレードルがもう一つほしい___ 防水なので、あまりキャップを開けたくないんです。 そして、dビデオとか見てるとやっぱり電池の減りがはやいんです。(ディスプレイが大きいのもあるのかなぁ。要らないサービス切るとかしないと) 結局、出先でも充電をしないといけなくて。 ただ、純正のクレードルが2100円と結構な値段でして。。。 あと、イヤホンを指すところもキャップがあるので、Bluetoothレシーバーも気になってたりします。 こちらも結構な値段でして。。。\nとまぁ、新しいものを手に入れて、色々悩んでますが、楽しいですね。購入したての色々と悩む時間がw おすすめアプリとかあったらコメントください\n","date":1360687980,"dir":"post/2013/","id":"b051fd352847c06e748b345e8ed0738b","lang":"ja","lastmod":1360687980,"permalink":"https://blog.johtani.info/blog/2013/02/13/xperia-z%E8%B2%B7%E3%81%84%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2013-02-13T01:53:00+09:00","summary":"技術ブログから離れていってますが。。。 Xperia Zを購入しました。 前に使っていたのはXperia arcになります。 もうすぐ2年だったのですが、容量不","tags":["備忘録"],"title":"Xperia Z買いました(Jugemより移植)"},{"contents":"金曜日に引き続き、イベントに参加して来ました。(仕事。。。これも仕事だよ。)\n「Hadoop Conference Japan 2013 Winter」です。 普段、Hadoopを触るのも少ないのですが情報を仕入れときたいなぁということで。 今年はビッグサイトですよ。そろそろ無料のカンファレンスもキツイのではないでしょうか。。。 こちらの写真はセッション会場。今回もすごいです。。。 簡単ですが、聞いていた感想です。 全体的に、Hadoop本体の話ではなく、エコシステムと呼ばれる周辺のプロダクトの話や実際に運用している実例が増えていました。 だいぶ普及期に来たのかなぁと。そして、自分の不勉強を実感できたなぁと。 (あと、TreasureDataに絡む話が多いなぁと言うのも印象です。そういうセッションを選んで出ていたのかもしれませんが) 懇親会まで残っていたのですが、結構、すごい方たちの顔ぶれだなぁというのを今更ながらに実感するとか。 (ハチ象Tシャツを着ているすごい集団でもありましたが。。。)\n以下はいつものメモになります。だいぶ金曜日のイベント後で腑抜けてるのでメモが雑ですが。\n◯ご挨拶 Doug Cuttingさんのビデオ(あんまり聞けてない) さすがのhamakenさんのトークの安定感。 後援はリクルートテクノロジーズさんが大半。 リクルートテクノロジーズの米谷さんが軽く発表 ◯LINEのHBaseを利用した大規模なメッセージストレージ:NHN Japan 中村 俊介 まずは、LINEの紹介が続く。 New Yearのメッセージは3倍位だったけど、何とかなっったよと。 データロスがない。 サーバ故障からのデータリカバリも自動でやってくれる 書き込み1ms、読み出し1-10msでできてる ・IDC onine migration クライアントベースで2つに書き込み Incremental replication(新データ)、BulkMigration(旧データ) 元のHBaseのレプリケータは利用してない(pushだったから。スループットコントロールしたかったから) ・NN failover 2012.10にNameNode障害発生 HA構成にしてたから問題が発生。 VIPはHDFSにつかうとリスキー 現在: 少ないダウンタイムを許容する ・Stabilizing LINE message cluster ※あとでHBase触るときに資料見直すくらいで。。。 Case1:Too many HLogs Case2:Hotspot問題 まぁ、けど1億ユーザのインフラとして使えるってすごいよな。。。 ◯Hadoop meets Cloud with Multi-tenancy: Treasure Data 太田 一樹 TDもFluentdも有名だなぁ Hadoopのメンテナンスとか、つらいよねというのを見てきたのでTD作った ・なぜ、BigData+Cloud? Hadoopだけみてもバージョンが混在してる+ディストリビューターも多くなってる 十徳ナイフみたいになってきてるけど、必要なのはナタだよね。というのを提示するためにTD立ち上げた。 ・なぜCloud? ・IaaSベンダーの対象としてるのはSCM。 オンプレだとHWが陳腐化してくよね→HWはクラウドが主流に ・PaaS、SaaSの対象は時は金なり バージョンアップとか大変だよねと ・TDのご紹介 唯一の解析用DBを目指して ・哲学とアーキテクチャ 解析とか運用をいかに楽にしていくかというのを主体においたサービスを提供したい? いかに速くレポーティングシステムを簡単に構築していくかとかの話 簡単なインタフェースと目的に集中することで、価値を提供 ・AWSとの違いは? ・アーキテクチャとか技術的な話 データを集める処理がデータ解析に実際には重要なフェーズ ・カラム指向でデータ保存 実装がどーなってるのかとか、TD内部のHadoopクラスタの運用、バージョンアップとかがどうなってるのかもきになる。(企業秘密だろうけど) ◯Amazon Elasti MapReduceとHadoopコミュニティの関わり:Amazon Web Services Peter Sirota ・3つのV Volume、Velocity、Variety ・yelpのAuto-suggestの例 カスタマーのレコメンデーションにElasticMapReduce使ってるよと。 ・razorfishの広告インプレッションの解析に使ってる ・Amazon.comでの話 AWS Public Datasetsの話 http://aws.amazon.com/jp/publicdatasets/ IonFluxのDNA解析の話 ・いろんな分野でのBig Data 事例がちらほら ※わかりやすい英語なんだけど寝不足が。。。 ◯ランチ! サンドイッチと豚汁とあとなんとかライス。 TDブースにて、fluentdのTシャツもらったよ! ◯Hadoop\u0026#39;s Power to Transform Business:MapR Ted Dunning ・Mahaut+Solrの単語が。8時間のレコメンデーションデータの作成が3分に?? ・Stormにてリアルタイム処理と連携。バッチ処理はMRで。 ・バッチ処理とリアルタイム処理の間としてのDrill ・Drillの概観とできるところの話。 (あとでスライドで)データ解析のために機会学習の処理とかも投げられそう。 Q:ImplaraとDrillの違いは? コミュニティベースかなどが違うよね(あまり聞き取れず) Q:Drillの開発はどのくらいすすんでるの? A:。。。 Q.クエリ言語としてSQLがいいの? A.No。というのも、単独の言語ですべてにベストというのはないから。SQLはわかりやすくて良いが、実行が非効率な場面も。 ◯Introduction to Impala~Hadoop用のSQLエンジン~:Cloudera 川崎 達夫 ・Impalaとは 分析に特化した低レイテンシクエリ実行基盤 Apacheライセンス バッチ処理要ではなく、データサイエンティストが試行錯誤するときに利用するのを想定 パフォーマンスが良い 実行エンジンはC++とかで実装されてる MapReduceに依存してない ・MapReduceの問題点 MR直接は難しい→Hiveとか、M/Rの実装を隠して使いやすくするものが増えてきた Hiveを例に説明。MRがベースなので高レイテンシ ・Impalaのアーキテクチャ 機能制限やGA版について言及されてる資料なのが良い ・GA以降の話もあり ピンチヒッターなのに落ち着いて発表とか凄すぎです。 jdbcサポートも入ると。 プランナーはjava実装 Hiveとの互換性は?→完全互換を目指す。 開発のプロセスが見えにくいのでは?開発主体がcloudera ◯Flumeを活用したAmebaにおける大規模ログ収集システム:CyberAgent 飯島 賢志 立ち見。 Flumeのコミッターの人がCAにいたんだ。 ◯Log analysis system with Hadoop in livedoor 2013 Winter:NHN Japan 田籠さん@tagomorisさん ・NHNJapanのお話 ・Webサービスのログ解析について話していく 400+Webサービス ・2011年8月にLTしました。 ・1.5TB/day。。。 ・batchとstream Batch集計も重要だし、Stream処理も重要なので、ハイブリッドシステム ・システムーバービュー FluentdClusterを中心にして各種ツール、保存先に転送してる。 これが結構重要。だけど、今日はFluentdの話ではない ・Fluentd周りを一人でやってるのか。。。 ・処理の流れ ・ログの収集と、生ログ保存 ・パース(主にHive用に)、変換、フラグ追加(分類しておくとあとで集計したいとか、保存すべきかを処理可能に) ・Hiveにロード ・第1世代のはなし すべてbatch処理、Scribe 遅延が1時間ちょっとあるため、Hiveクエリで結果が見れないとか。 ・第2世代の話 Fluentdのstream処理にHadoop Streamingを呼び出せるようなプラグインを書いた Fluentd+HoopServerの構成 ・第3世代 HoopをWebHDFS Fluentdでのオンライン集計 GrowthForcast、HRForcast ・第4世代(ここ1週間でやったこと) CDH4でQJMベースのNameNode(Failoverは手動) Hiveのスキーマを変更(これはブログに今度書くよ) とりあえず、現時点で改善点が思いつかない ・総括 HTTPベースでRPCベースにしたのでコンポーネント切り替えが結構楽 OSSで公開されてるからいいよね 公開することにより色々とドライブするよ! ◯いかにしてHadoopにデータを集めるか:Treasure Data 古橋 貞之 ・自己紹介 ・ビッグデータ収集の問題点 ・壊れたデータが入ってる ・読み書きの時間がかかる ログはサブケースである。メインはサービスとかだから。 ・トライ&エラー処理が時間かかる ・データを分割するのが基本的なアイデア 失敗した時のリトライが楽になる。さらに、それをStream処理すれば良いよねと。 ・flumeのお話 ・fluentdのお話 バッファリングは性能アップも兼ねてる 設定のクラスタへの伝搬とかインストールはpuppetとか使おうねと。 プラグインのインストールが楽 ・いくつかのプラグインの紹介 ・TDへのデータ投入のお話 ・最後にmuddydixonさんのプラグインの宣伝がw ◯Hadoopの次に考える分散システム技術:Microsoft 萩原 正義 ・CAP定理の克服をどうしていくか ・CAPのおさらい ・Lease クライアント主導、サーバ手動とか (理論重視の話で最後のセッションには辛かった。。。頭が疲れててついていけませんでした) おまけ 今回頂いたノベルティなどを写真に撮ってみました。(ランチはお腹すいてて写真取らずに食べちゃいました。。。) Hiveロゴへの愛を語ってHive Tシャツをゲット。 FluentdのTシャツももらいました! Hiveステッカーなどもゲット あと、メッセージボードなるものがあったので書いてみました。一応、Hadoopに絡んだことですよね!?\n","date":1358783400,"dir":"post/2013/","id":"bf4f86812812dab8d39db9aaefe94a78","lang":"ja","lastmod":1358783400,"permalink":"https://blog.johtani.info/blog/2013/01/22/hadoop-conference-japan-2013-winter%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-hcj13w/","publishdate":"2013-01-22T00:50:00+09:00","summary":"金曜日に引き続き、イベントに参加して来ました。(仕事。。。これも仕事だよ。) 「Hadoop Conference Japan 2013 Winter」です。 普段、Hadoopを触る","tags":["勉強会"],"title":"Hadoop Conference Japan 2013 Winterに参加しました。#hcj13w(Jugemより移植)"},{"contents":"1/18(金)に開催された、エンジニアサポートCROSS 2013で「検索CROSS」セッションのセッションオーナー(モデレータ)をやって来ました。\n@muddydixonさんに昨年の夏くらいに声をかけていただいたのがきっかけです。 こういったイベントの運営のお手伝い(ほとんど何もしてない)も初めてでしたし、セッションオーナー(モデレータ)も初めての経験で色々といい勉強をさせて頂きました(自分の足りない所とか、考慮すべき点がどういったところにあるとか)。本当にありがとうございます。\nスピーカーとして登壇していただいた久保田さん、佐藤さん、安田さんほんとうにありがとうございました。 頼りないオーナーで、モヤッとした内容を提示したにもかかわらず、意図を汲み取って話の内容をふくらませていただいてすごく助かりました。 また、会場にお越しいただいたみなさん、ありがとうございました。すこしでも検索に興味をもっていただければ、セッションは成功だったと思っています。 朝一だったのと、私の認知度の低さもあったのとで残念ながら満席とはいきませんでしたが。。。\n後日、録画されたセッションの内容を見て色々と反省しようかなぁと。。。 緊張していたので、うまくモデレートできてたのか、話ができていたのか不安ですが。 忌憚ない感想をお待ちしています。\nということで、反省終わり!ここからは、イベントの感想と聞いたセッションに関する感想です。\n###聞いたセッション\n####企業CROSS DeNA x グリー x Aiming: 大企業・ベンチャーが語る「スクラム」開発 (仮)\nGoogleの及川さん見たさで参加しました。 スクラム自体は名前くらいは聞いたことある程度だったのですが、その程度の私でもわかりやすいディスカッションで楽しかったです。 聞いていて感じたのは、次のようなこと。\n「スクラム」という開発手法の話しなんだけど目的はそこじゃなくて、どうやってうまくプロジェクトを回して(ドライブして)、目的(サービスを作るとか顧客の要望を叶えるとか)を達成するかというのが重要だなぁと。 「スクラムマスター」の仕事は子育てに似てる 「スクラムマスター」になりたい人はなかなかいないらしい 「スクラムマスター」の人は、俯瞰してプロジェクト全体を見渡して落穂拾いをしていく人なのかもなぁと 個人的には「スクラムマスター」の仕事がちょっとおもしろそうと思いました。(いつもいろんなことを面白そうと思う自分なのでなんともいえないですが。。。)\n####データ理解を助けるビジュアライゼーション\n昨年からビジュアライゼーションには興味だけ(実践とかできてない)は持っていたので、参加しました。 スピーカーの方々の対立軸がはっきりしていたのが面白かったかと。 聞いていて感じたのは、次のようなこと\nビジネスの視点からのビジュアライゼーションはコスパがどうなのかというのがまだ不明 可視化できたらおしまいじゃなくて、お金につながる可視化に心がけるのが重要そう 可視化して楽しむのも有りだとは思うけど、それは趣味だったり芸術の話かもなぁ 異なるコンテキストの人にでも誤解を与えない可視化というのが重要 何をどう可視化するかというのが実は統計学知ってると必要ないこともある 基本的にはCAの方の内容が一番しっくり来ました。やっぱりビジネス的な視点と学術的な視点は違うのかもなぁと。\n####継続的システム運用のゲンバのハナシ\n面白かったです。のっけから燃料がテーブルにならんでるしw 運用とかインフラはそこまで詳しくないのですが、少しは作業したりするので気になってましたが、ぶっ飛んだ話が聞けて楽しめました。 聞いていて感じたのは、次のようなこと\nサービス内容によっては夜中にアクセス数が低いものもある(cookpadは夜中はアクセス数が低い) アプリを修正することでインフラを楽にするという考えもある インフラエンジニアは実はリア充 cookpad面白い人多いw このあとは、おまちかねのプレモルタイムだったので、プレモル片手(失礼だろw)にTech10の池本さんに挨拶してきました。(Solr本のときはお世話になりました!) あとは、RedBull片手に知り合いの方々(Twitter上のみやいつもお世話になってる人)に挨拶をして回ってました。(プレモルも美味しかったのですが、プレモルおつまみも美味しかったです!) また、ちょっとつかれて座るために入った「体系的に学ぶ安全な利用規約の作り方」でも、面白い話を聞けました。 (利用規約をきちんと考えて変更している企業のほうが炎上をしてしまうとか無駄だしおかしいよねとか)\nイベント終了まで、会場にいて(いただけで大した手伝いしてないです、すみません。)その後打ち上げに向かって楽しみました。\n####さいごは、イベント通じて感じたことと気になったこと。(若干、意図的なものが入り込んでますが。。。)\n題材にもなってる「CROSS」ですが、ここ数年特に、エンジニアとして複数の技術や考えなどを身につけないといけないなぁと 有名人に会える!(ミーハーです。。。) プレモル美味しい!(いつも飲んでるビールが「え?」って思った) ケンタッキー美味しい! RedBull美味しい! いろんな技術分野に触れられる機会ができそう Wi-fiは用意してもらえると助かる。(参加者の方々が一斉にLTEとかでつなごうとするのでみんなが繋がらなくなってツイートされないとかちょっとつらいかも) 各会場が覗けるようになってたのは良かった(ただ、会場の後ろの人はざわつきを感じるためスピーカーの声が聴こえないことも) スクリーンはもう少し高い位置にあると良かった(後ろに座ると下のほうが見えないことも) 飲食の配布は会場内でできたほうが良かったのかも(NGなのかな?)。プレモルやRedBullは配ってくれたので良かったのだが、食べ物を取りに行くために入口付近が混雑してた気がした。 (これで、メッキ剥がれたかなぁ) 会場入り口の写真とか撮ってくるんだった。。。 ということで、総じて楽しかったので来年もあるならまた、手伝いたいです!\nおまけ\nプレモル! Amebaウォーター プレモル+プレモルおつまみ+RedBull いただいたスタッフTシャツとプレモル!\n","date":1358600940,"dir":"post/2013/","id":"322264a17ef7182eb1475bd2eaebc2eb","lang":"ja","lastmod":1358600940,"permalink":"https://blog.johtani.info/blog/2013/01/19/%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%82%B5%E3%83%9D%E3%83%BC%E3%83%88cross-2013%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%8A%E6%89%8B%E4%BC%9D%E3%81%84%E3%83%A2%E3%83%87%E3%83%AC%E3%83%BC%E3%82%BF%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F--cross2013/","publishdate":"2013-01-19T22:09:00+09:00","summary":"1/18(金)に開催された、エンジニアサポートCROSS 2013で「検索CROSS」セッションのセッションオーナー(モデレータ)をやって来ま","tags":["勉強会"],"title":"エンジニアサポートCROSS 2013に参加(+お手伝い+モデレータ)しました #cross2013(Jugemより移植)"},{"contents":"いまさら感満載ですが、今週の金曜日(1/18)に開催されるCROSS 2013というイベントで「検索CROSS」のセッションを担当することになってます。\nここ数年、検索に携わっていますが、検索は色々な技術の組み合わせ(検索用インデックス、自然言語処理、機械学習などなど)でなりったていて奥が深いなぁと感じる毎日です。 そこで、実際のサービスで検索をやられている方、検索プラットフォーム製品を開発している方、自然言語処理や検索に長けた方を招いてつぎのような話をしてもらおうかと。\n・現在の事例(検索とその周辺技術) ・今後の検索にクロスすると面白い技術\nがっつり検索をやられている方々に登壇していただきますので、検索に興味のある方はぜひ、ご参加を! 登壇者の方々についてはこちらを御覧ください。\n検索CROSS以外にも楽しみなセッションが多数ありますので、参加をご検討いただければと。 あと、実はこっちがメインなのですが、夕方からのプレモルタイムも期待できるのでこちらへの参加だけでもぜひ!!\n","date":1358267340,"dir":"post/2013/","id":"20110c8f8da8304b6d9d3c2845a38128","lang":"ja","lastmod":1358267340,"permalink":"https://blog.johtani.info/blog/2013/01/16/%E3%81%84%E3%81%BE%E3%81%95%E3%82%89%E3%81%A7%E3%81%99%E3%81%8Ccross-2013%E3%81%A7%E6%A4%9C%E7%B4%A2cross%E3%81%A8%E3%81%84%E3%81%86%E3%82%BB%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E6%8B%85%E5%BD%93%E3%81%97%E3%81%BE%E3%81%99/","publishdate":"2013-01-16T01:29:00+09:00","summary":"いまさら感満載ですが、今週の金曜日(1/18)に開催されるCROSS 2013というイベントで「検索CROSS」のセッションを担当することにな","tags":["勉強会"],"title":"いまさらですが、CROSS 2013で検索CROSSというセッションを担当します(Jugemより移植)"},{"contents":"年末から年始にかけて、「コード・シンプリシティ」を読みました。\n先日の記事にも書きましたが、Kindle paperwhiteを思いかけず入手できたので、eBookを読みたいなぁと思いまして。 Kindleのお試しも兼ねて読んでみました。\nまずは、本の感想。 短めの書籍+読み物なので、サクっと読めました。 題名に「コード」と書かれていますが、コードの実例が出てくる書籍ではありません。 「ソフトウェア」を以下にシンプルに保って、管理しやすくするか、機能追加、テストをやりやすくするかといった指針について書かれています。 機能追加に関して検討しないといけないバランス(先読みしすぎずと実装しすぎないとか)の話や定期的なデザインの見直しなどについても書かれています。 ソフトウェアに関しては動くこともだが、デザインが重要であること。(確かに。) すでにあるソフトウェアについて、どのように簡潔にしていくかという話もありました。 ただ、読んでいて一番重要だと思ったのは、「悪いプログラマーと良いプログラマーの違いは理解力だ」という一文です。 何をしているかを「理解」していないと、根本的な問題点の解決もできないですし、どうすればコードが簡潔になるかといったこともわからないです。 また、やっている作業がどんなもので、何のためにやっているのか、それを行うことで今後にどのような影響があるのかといったことも理解しておく必要があるかと。 ま、ある程度考えながら作業とかしましょうってことですかね。(強引なまとめかも。。。)\nで本題です。 Kindle paperwhiteとiPadの使い分けを検討するのも兼ねて本を読んでました。 iPadを持っているのもあり、Kindleはそもそも眼中になかったのですが、めっけ物でした。 やはり実際に使ってみないとわからないことありますねぇと。 paperwihteはつぎのような利点があるかと。\n読書に没頭できる。→本を読むというシンプルな目的を達成するものだけが実装されている 目が疲れない→Twitterでも話に上がったのですが、液晶とは異なり字が読みやすいです 軽いし小さい→電車で立っていても楽に持てるし、カバンからの出し入れも楽です(iPadに比べて) 複数の端末のKindleアプリで同期できる。→あまり異なる端末では読まないですが、paperwhiteで読んだところが、iPadでも同期されるのですんなり続きが読めます 電池長持ち ということで、本を読むのに没頭できるし目が疲れないと。 ただ、つぎの点では不満もあります。\nPDFは読みにくい。→画面のサイズが小さいので大きめの書籍のPDF版は読みにくいです。 PDFは読みにくい。→文字のサイズを変更できないのもキツイです。Kindle専用のmobi形式の書籍が読みやすいです ページめくりに一定時間がかかる→紙の書籍やiPadで書籍を読むのとは異なり、ページをめくるのに時間がかかります。e-inkの再描画の問題かと。パラパラと書籍を読みたい場合は厳しいです 白黒。カラーの電子書籍は読めないですねぇ ソースコードなどもキツイ→長めのコードが書いてある本だとコードが頭に入ってこないです。。。 という感想でした。 今後は基本Kindle paperwhiteを持ち歩きmobi形式の本を読むようにすると思います。 iPadは自炊本やカラーの本を読むとき、映像、ネットを見るような場合に持ち歩くことになりそうです。 私は基本的にMBAを持ち歩いているというのもあるので、paperwhiteのほうが主流になりそうです。 ネットを見るときなどは最悪、MBAを開くでしょうし。 小説とかをメインに読むのであれば断然、paperwhiteだと思います(最近読んでないなぁ)\n","date":1357658880,"dir":"post/2013/","id":"992a00c30242b6217243f3c387ea18b7","lang":"ja","lastmod":1357658880,"permalink":"https://blog.johtani.info/blog/2013/01/09/%E3%82%B3%E3%83%BC%E3%83%89%E3%82%B7%E3%83%B3%E3%83%97%E3%83%AA%E3%82%B7%E3%83%86%E3%82%A3%E3%82%92%E8%AA%AD%E3%81%BF%E3%81%BE%E3%81%97%E3%81%9Fkindle-paperwhite%E3%81%AE%E4%BD%BF%E3%81%84%E5%8B%9D%E6%89%8B%E3%81%AE%E7%A2%BA%E8%AA%8D%E3%82%82%E5%85%BC%E3%81%AD%E3%81%A6/","publishdate":"2013-01-09T00:28:00+09:00","summary":"年末から年始にかけて、「コード・シンプリシティ」を読みました。 先日の記事にも書きましたが、Kindle paperwhiteを思いかけず入手で","tags":["読書"],"title":"「コード・シンプリシティ」を読みました。(Kindle paperwhiteの使い勝手の確認も兼ねて)(Jugemより移植)"},{"contents":"書こうと思いながら、気づいたら大晦日。 よくないですね、思いついた時に書かないと。\n昨年も書いたので、昨年書いた抱負から振り返りをと。\nMongoDB触ってみる Scala触ってみる なんかWebサービス作ってみる(Amazonとかで) elasticsearch、IndexTankを調べてみる NewSolrCloudDesignを読み込んで自分なりにまとめる Junsaiに参加する 「7つの言語7つの世界」の続き えーと。。。できてないことばかりですねw MongoDBはインストールすらしてないですし、Webサービスも作ってないです。(さくらVPSは借りたんですが) Junsaiは参加したけど何もできてないし。7つの言語もそのままですね。。。 SolrCloudDesignはまとめられてないですしね。 Scalaは少しだけ触りました。結局Javaみたいな記述をしてしまうという良くないくせが出てしまうので、 見送ってしまいましたが。。。 elasticsearchは少しだけやりました。#pyfesで話をさせて貰える機会があったので。\n興味がコロコロ変わってしまうのが問題点かもしれないです。少しは地に足をつけてなんかやったほうがいいのになぁ\n###今年の振り返り 今年はこんなかんじでしょうか。\nいろんな勉強会に出没 #pyfesでelasticsearchのさわりを紹介 個人的にJIRA導入 MIR輪読会開始 Solr勉強会の主催を引き継ぐ Kindle paperwhite当たった 相変わらずいろんな勉強会に出てました。最近は勉強しに行くのもありますが、人に会いに行ってるような気がします。 勉強会から帰ってきて復習したりしないとすぐ忘れちゃうんですよね。。。\n#pyfesではelasticsearchの入門中という話をしてきました。 人の多さに緊張しまくりでよくわかりにくい発表になってしまったのが反省点かと。。。 もっと話をする機会を増やすとなれるのでしょうか。\nJIRAの導入はパラで仕事をしているとタスク管理がおろそかになってくるので導入しました。 フリーのredmineを考えていたのですが、インストールが簡単なJIRAを導入しました。 有料ですが、1-10人までなら、ダウンロード版が$10ですし。いろんな時間を買ったと考えると安いかと\n検索に関してもまだまだ初心者に近いということでModern Information Retrievalという英語の本の輪読を主催しました。 Twitterでの呼びかけに答えてくれた方々に感謝です。 まだ、半分も行ってないですが、何周かしたいと思っています。\nSolr勉強会の主催者も引き継ぎました。Atnd立てるの手伝おうか?って言ったら主催者になってましたw 来年も開催するので、喋りたい方、こんな話を聞きたいなどTwitterやブログでコンタクトいただければと。\nあと、会社の忘年会で思いがけずKindle paperwhiteが当たりました!(やったー!) iPadを持っていることもあり、完全に購入する気も無かったのですが。。。 使ってみると結構いいです。画面のギラツキがないのと、他のソフトがないのがいいです。 読書に没頭できます。通常はKindleを持ち歩くことになるかと。(没頭できるけど、読むスピードが遅い+すぐ忘れるのが難点。。。)\n###来年の抱負 来年の抱負も書いておきます。 昨年の前科があるのでどこまでできるかわかりませんが。 すぐに興味が変わってしまうのもありますし\nIntelliJ IDEAをメインに使う JIRAを継続して活用 ブログの継続 elasticsearch Luceneのソースコードリーディング 何かOSSのソースを読む Macでもっと開発 読書と英語を継続 IDEA(アイデア)は11をインストールしてたのですが、使えていませんでした。 イメケンが主催したJetBrainsユーザー会で洗脳されて+タイミング良い75%オフセールにやられて購入しました。 普段はEclipseを使っているのですが、これを機にチャレンジしようかと。 少し変化をしてかないとすぐ取り残されちゃうので。。。\nJIRAはまだタスクを登録してクローズするという初歩段階の使い方しかできてないので、少しずつ研究してフィールド追加したり、ワークフローを変更してみたりと研究したいです。\nブログは、今年後半が勉強会参加ブログしかないのを反省して来年は、もう少しSolrやLucene、lucene-gosenについて書いて行きたいです。 (すくなくとも、4.0で動かす話を書かないと。。。)\nelasticsearchはまぁ触れる環境を維持しようという話です。 どこかで導入できればいいんでしょうが、なかなか。 (勉強会開いてみるのも面白いかな?)\nLuceneソースコードリーディングは誘われてるのに、ちゃんと返事をしていなかったので。 来年2月のどこかの土日を候補日にする予定です。\n何かOSSのソースも読もうと思ってます。 「何か」はまだ決めてないですが、人のソースを実はあまり読んでないなぁと。 Vさんと話をした時に人のソースを読むのがいいですよという話になったので。 真似をするためにもなんか読みたいなぁと。Javaになるのかなぁ。\nとある事情で週4はWindowsで開発してます。 Macはちょっとしか触ってないのでMacの環境が成長していないのが難点です。 できれば、Macで開発を継続できる環境を作りたいなぁと。Kobitoとか入れてるけど触ってないし。。。 IntelliJも入れたのでMacで開発したいものです。\n最後は毎年のことですが、本を読むスピードが買うスピードに追いついてないと。。。 英語の本もかってるんですが、これまた読むスピードが。。。 ということで、ざっくり目を通す読書をもっとやりたいなぁと。 買うのはいいのですが、必要にならないと呼んだ内容を忘れてしまうので、読んだあとに実践する機会も設けたいと思ってます(思ってるだけかもしれないですが)\nあと、来年もいろんな人に会うためにいろんな勉強会に出没すると思いますので、声をかけていただければと また、不抜けているのを見かけたらカツを入れてください。(技術内容のブログ書けとか、本読んだ感想をブログにかけとか) 来年もTwitterなどで絡みまくると思いますが、よろしくです。\n","date":1356908460,"dir":"post/2012/","id":"4c08b67e0c1fdeef50b1fdcc32cdcee2","lang":"ja","lastmod":1356908460,"permalink":"https://blog.johtani.info/blog/2012/12/31/%E4%BB%8A%E5%B9%B4%E3%81%AE%E6%8C%AF%E3%82%8A%E8%BF%94%E3%82%8A%E3%81%A8%E6%9D%A5%E5%B9%B4%E3%81%AE%E6%8A%B1%E8%B2%A02012/","publishdate":"2012-12-31T08:01:00+09:00","summary":"書こうと思いながら、気づいたら大晦日。 よくないですね、思いついた時に書かないと。 昨年も書いたので、昨年書いた抱負から振り返りをと。 Mongo","tags":["備忘録"],"title":"今年の振り返りと来年の抱負(2012)(Jugemより移植)"},{"contents":"Atlassian Advent Calendar 2012の20日目。(急遽参戦) (某イケメンにMT(改変リツイート)されたので書いてみました) 久々に、勉強会以外のエントリです。(Solrとかlucene-gosenじゃないんだが。。。)\n私は、最近忘れっぽくなってきてしまったので、さくらVPSを借りてJIRAを立てて、タスク管理とかに使い始めました。 有料ツールなので、まずは、評価版から入れましたと。 評価版をインストールするときに、楽なのでHSQLDBを選択していました。が、 インストール時に「HSQLDBは評価版だけで使用してください。正式版ではサポートしてないです」みたいなことを言われていたので、PostgreSQLに切り替えようかと。 ちなみに、MySQLも選択肢としてはあったのですが、PostgreSQLのほうが触ってるし(つかいこなせてるわけではない)、補完機能になれてるというのもありPostgreSQLを選んでみました。\n作業のログとして、ブログ書いとこうと思いたったのでメモ的に残しておきます。\n作業の流れはこんなかんじでした。 (基本的にはサポートサイトのここに載ってます。サポートいいね。) この手順通りでいいみたい。\n###1. JIRAのデータのバックアップ(JIRAの管理画面からバックアップ)\nまずは管理画面へ。ページ右上に管理へのリンクがあるのでクリック。 開いた管理画面の右下あたりにエクスポート(バックアップ)へのリンクがあります。 クリックしたあとに、エクスポートのファイル指定画面が現れるので、ファイル名を指定してバックアップボタンを押します。 バックアップが完了するとバックアップファイルの場所が表示されます。 ###2. JIRAの停止\nバックアップが終わったのでJIRAを停止します。\n###3. PostgreSQLのインストール(yum) PostgreSQLが入ってないので、yum installします。(軟弱者なので)\nyum install postgresql-server ####initdbで四苦八苦 PostgreSQLはインストールしただけでは起動できません。なので、初期化をします。 yumでインストールしたPostgreSQLだとつぎのコマンドでinitdbできるようです。(これが罠でした)\nservice postgresql initdb このコマンドでinitdbすると、encodingが指定できませんでした。(私がしらないだけという話も。。。) encodingを指定できていないと、このあと4.を実行するときにエラーが出ました。(これも回避方法あるのかも。) ということで、結局、昔とった杵柄なやり方でinitdbコマンドで\u0026ndash;encoding=UTF8 \u0026ndash;no-localeを指定しました。\ninitdb --encoding=UTF8 --no-locale -D/var/lib/pgsql/data service postgresql start これで初期化が完了するので、PostgreSQLを起動します。\n###4. JIRA用DBとユーザの作成\nまずは、ユーザの作成。そして、DB作成\ncreateuser jirauser createdb -E UNICODE jiradb テーブルなど作成しません。あとの処理がやってくれます。\n###5. JIRAにJDBCドライバを入れる(必要なかった。)\nwarじゃないJIRAをインストールした場合はすでに入ってるみたいです。 ここを見るとわかります。JIRA Installation Directoryの下のlibですかね。\n/opt/atlassian/jira/lib ###6. マニュアルでPostgreSQLの接続設定(あれ、これいらないのか。)\n~~ コンソールオンリーなので、JIRAが提供してくれているツールが使えないため、手で設定。 /var/atlassian/application-data/jira にあるdbconfig.xmlを修正~~ ちゃんと英語読めってことですね。。。必要なかったです。。。\n###7. JIRAのdbconfig.xmlを削除\nDB接続の設定を初期セットアップウィザードで再設定するため、dbconfig.xmlを消します。 (一応、インストールディレクトリとホームディレクトリとかバックアップしたほうがいいみたい) 場所はここ。 中身はdbcpとかのデータソースの設定に似てました。 今は、HSQLDBのJDBCドライバが記載されてました。\nrm /var/atlassian/application-data/jira/dbconfig.xml ###8. JIRAの起動\n7.のファイルを消したあとにJIRAを起動します。\nservice jira start ###9. JIRAにアクセスとDB接続設定\nアクセスすると、インストールした時と同じDB接続の指定を行うセットアップウィザードの画面が現れます。 今回はJIRAサーバの外にあるPostgreSQLなので、「外部」を選んで四角で囲んだ部分を入力します。 入力したら、「接続テスト」を押して接続できることを確認したら「次へ」を押します。 マシンのスペックにもよると思いますが、ここでJIRAサーバがDBに接続してテーブルのCREATEなどDBのセットアップを実行してるのでちょっと時間がかかります。\n###10. バックアップしたデータのインポート\nDBのセットアップが終わったら、アプリケーションのセットアップ画面が出てきます。 新規インストールではないので、「ここ」にある「既存のデータをインポート」リンクをクリックします。 すると、インポートファイルの指定画面が現れるので、1.でバックアップしたファイル名を指定してインポートします。 すると、インポート中画面が出てきます。 で、インポートが完了すると無事JIRAにログインできますと。\nとこんなかんじです。 私の場合は、まだJIRAをインストールしてから間もないため、チケットの数が少なかったり、添付ファイルが無かったりなので、すぐにインポートが完了しました。 添付ファイルがある場合は、別途添付ファイルが保存されているディレクトリのバックアップと復旧などもあるみたいです。 最初にも書きましたが、ドキュメントのサイトに「Switching Databases」という項目があり、そのページの手順で問題なく切り替えできました。 次は、定期的にデータをバックアップするのを考えないとですかね。\nいやぁブログ書くのが、思いの外、手こずりました。 手こずった原因はスクリーンショットだったんですけどね。。。 safariでページ全体のスクリーンショットがとれなかったので、結局ChromeでAwesome Screenshotプラグイン使いました。 safariの拡張もあるんですが、ページ全体のスクリーンショットがうまく動かないみたいです。。。 ということで、備忘録でした。(次はちゃんとSolrとかの記事書かないとなー。その前に忘年ブログかな)\n","date":1356002280,"dir":"post/2012/","id":"4a30eeb083acec8460150068ba0c6743","lang":"ja","lastmod":1356002280,"permalink":"https://blog.johtani.info/blog/2012/12/20/jira%E3%81%AEdb%E7%A7%BB%E8%A1%8Chsqldb%E3%81%8B%E3%82%89postgresql%E3%81%B8-augj/","publishdate":"2012-12-20T20:18:00+09:00","summary":"Atlassian Advent Calendar 2012の20日目。(急遽参戦) (某イケメンにMT(改変リツイート)されたので書いてみました) 久々に、勉強会以外のエントリです。(So","tags":["JIRA"],"title":"JIRAのDB移行(HSQLDBからPostgreSQLへ)#augj(Jugemより移植)"},{"contents":"イケメンが主催した「第一回 JetBrainsユーザーグループ #jbugj」に参加してきました。\nいろんな製品があるんだなぁと。入り口には良いイベントだったと思います。 個人的に、WebStorm、IntelliJが気になっていたので、参加しました。(あとは、イケメンがやってるイベントだからというのもあるかも) ちなみに、MBAにしてからインストールはしていたのですが、ほぼ触っていなかったのでこれを機会にちょっと触ってみようかなぁと。\n発表は、全般的な製品紹介、ライセンスの紹介から、ライブコーディングあり、ここがいいよ!という話ありという感じでした。\nMTLさんのおしゃれな空間で発表を聞いたので、いつもとは少し違った感じでしたでしょうか。\n私自身は、発表を聞きつつ、IDEAのCEで色々やってました。 一応、Lucene/SolrのSVNからチェックアウトしたり、lucene-gosenのtrunkをチェックアウトしたり、個人のbitbucketからlucene-gosen-wikiparseとかcloneしてました。 Eclipseで作ったプロジェクトなので、cloneとかチェックアウトしたあとに、Eclipseと並行開発するとどうなるのかなぁ?というのがちょっと気になります。(普通は移行しておしまいなんだろうけど。。。) ちなみに、lucene-gosenのプロジェクトもSVNからチェックアウトしたらすんなり使えそうでした。 こんな感じ。(lucene-gosenのプロジェクト) とりあえず、見た目がカッコイイw\nいくつか触ったり、聞いていて気になったのはつぎのような点です。ちょっとずつ触る機会を作った時に調べてみようかなぁと\nEclipseのワーキングセット相当の機能はどうするのか?→モジュールとかでやればいいらしい。 プラグインってどんなものがあるの?探す方法とインストールの仕方 JDKの複数の切り替え方とか Eclipseでやってる人とIntelliJでやってる人の混在チームでの開発とか で、いつものごとく、懇親会に参加しました。 @mike_neckさんや@sue445さんとお話できたのですが、VCSにEclipseの設定ファイルとか挙げないほうがいいですよねとか、テストが無いプロジェクトってないわーなどの話を聞いて、やっぱり自分はまだまだなんだなぁと認識できるとか面白かったです。 lucene-gosenのSVNにはEclipseの設定ファイルとかアップされてるからなぁ。ホントはAntとかMavenのターゲットでこれらの設定ファイルができるようにしとくのがいいんでしょうねぇ。 まだまだ勉強することだらけですが、コツコツ教えてもらいます\nちなみに、イベント参加者にはショートカットキーが印字されたキートップシールや2ヶ月有効な評価ライセンスがあとからもらえるなどの特典もありました。 普段はEclipseなのですが、運良くライセンスが当たったら本気で乗り換えようかなぁw\nちなみに、Eclipseでもそうですが、私自身はショートカットキーをほとんど覚えてない軟弱者ですので、メニューの場所などを覚えれば乗り換え自体はこんなんじゃないかと。 Mac自体にKeyRemap4MacBookを入れていて、Emacsっぽいショートカットを使うので、覚えられないというのもありますが。 ライセンス当たらないかなぁー\n以下はいつもの通り、聴きながら自分用にメモしたものになります。\n日時:2012/12/11(火)19:00-21:00 場所:メディアテクノロジーラボ イベントサイト:http://www.zusaar.com/event/450003\n◎JetBrains製品群、ライセンス形態などの紹介 - @yusuke ・日本でヤル気あるの!?→あるある!→じゃあ、ユーザグループ立ち上げるぜー ・あくまで情報交換の場を設けるだけ。 ・アンケート結果 IntelliJが1番人気 WebStromが2番 ・ステッカー(ちょっとかっこ悪いかも。。。) ・2名限定でIDEAのライセンスプレゼント! ブログ書いて、応募用フォームに登録してランダム抽選 ◎IntelliJの基本(インストール~プロジェクト作成、テスト、実行までのウォークスルー) @yusuke ・JetBRAINSはチェコの会社 ・IntelliJはなんでもできる(AppCodeは違うけど) ・.Net系もある(書きそびれた) ・YouTrack:課題追跡 ・TeamCity:継続インテグレーション ・読み方は「イデア」じゃなくて「アイデア」だよ! ・Community Editionはあんまり機能がない。 OSSライセンスだと、Ultimateの機能が使えるよと。 ・仙台の人が一人アドベント・カレンダーやってます。 http://d.hatena.ne.jp/masanobuimai/20121201\n・ライブデモ 黒いインタフェースにするのどーすんだろう? →Preferences→AppearancesでThemeで「Darcula」を選択すると黒くなる。 ・やべ、時間過ぎてたw終わり! ◎IntelliJのここが気持ちいい!→普通IntelliJでしょ? @mike_neck ・DQXやってます。 ・僕とeclipse ・新規クラス作成:3ステップかかる ・補完の素早さ: ・SprintFramework:Ultimateなら対応してるよ。 関係ないけど、TLで質問したので。 Eclipseのワーキング・セットに相当するもの。 http://d.hatena.ne.jp/masanobuimai/touch/20121024\n◎LT ◯WebStormとRubyMineについて @sue445 ・JavaScriptのIDEとして最強 jsの補完が素晴らしい。(外部のJSはプロジェクトに入れないと難しい。) jsTestDriver pluginがデフォルトで入ってる! ・RubyMine RubyのIDE ソースを追うのが楽。 erbのインポートしたものも追っかけられるの便利。 viewからhelperクラスにも飛べる。 QA UMLとか出せるの?→出せるよ。 DBクライアントもあるよ。 ◎JetBrains発のJVM言語Kotlinの紹介 - @ngsw_taro アドベントカレンダー(一人)http://atnd.org/events/34627\n・社畜してます ・Androidアプリとか作ってる。 ・Kotlinな活動 Pull Requestしてる ・マイルストーンなど。 M4が3時間前に出た! ・どんな言語? 静的型付け、オブジェクト指向、関数型プログラミング的、JSへコンパイル可 産業利用目的(初めて聞いたかも、この言葉w) ・Java大変だよね。 互換性問題とか ・ライブコーディング 大変そうだwKUnitってのもあるらしい。 (ゴメンナサイ、IDEA触ってて、流してました。。。Eclipseで作ってたプロジェクトをBitbucketから落としてきて四苦八苦してた) (参考にしたサイト(ググった):http://d.hatena.ne.jp/waman/20100506/1273166533)\n◎AppCodeについて ・IDEAには含まれないので、別途ラインセンス購入が必要。 ・XcodeとAppCodeの違いをライブコーディングで説明。 ・XCodeよりも補完が良くできてるっぽい。 GUIはXCodeで作って、コーディングはAppCodeでやるってのがいいですよ。 ※私が、iOS系のアプリの開発ってやったこと無いからよくわかってないです。。。 XCodeはコードフォーマットがないのが辛い by @yusuke ","date":1355228520,"dir":"post/2012/","id":"898d25a2ab9c0ba1fa9bad462405e475","lang":"ja","lastmod":1355228520,"permalink":"https://blog.johtani.info/blog/2012/12/11/%E7%AC%AC%E4%B8%80%E5%9B%9E-jetbrains%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%82%B0%E3%83%AB%E3%83%BC%E3%83%97--jbugj-%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%A6%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-12-11T21:22:00+09:00","summary":"イケメンが主催した「第一回 JetBrainsユーザーグループ #jbugj」に参加してきました。 いろんな製品があるんだなぁと。入り口には良いイ","tags":["勉強会"],"title":"第一回 JetBrainsユーザーグループ #jbugj に参加してきました(Jugemより移植)"},{"contents":"ヒカリエに行ってみたいという不純な理由で参加してきました。 新しいということもあり、おしゃれで綺麗なカフェでした。 入り口にはおっきな人形も立ってたし。 渋谷の夜景も見下ろせて素敵な場所でした。\nで、内容です。残念ながら、本編の3回めには参加していなかったのですが、 今回も濃い話が聞けたので楽しかったです。 論文読まなかったり、基礎を勉強したのに忘れてたりと抜けてる部分が多いので、 こういう機会が与えてもらえるというだけで目からうろこです。\n@kumagiさんの「あなたの知らないハッシュテーブルの世界」はハッシュテーブルの基本的な話から、最近の論文で発表されてる内容までをカバーする幅広いお話で面白かったです。 (大学でやってると思うんだけどすっかり抜けてる自分がなんとも。。。) こういうコアな中身も知ってると、色々とプログラム書いたりするときの見方や考え方も変わってきますよね。 (そんなプログラム書いてないけど。。。) で、随分おとなしい内容だなぁ?と思いきや、途中からちゃんとLock-Freeの話も出てきてさすがと感心させられましたw 最後はJubatusの宣伝まで入ってたし。(某氏のすごい写真入りで。。。)\n@hitoshi_niさんの文書要約の話は、NLPに興味があるので、楽しみにしていた内容でした。 今回もなめらかによどみなく喋られる発表にただただ感心させられるばかりでした。 内容は中級編ということで、文書要約のキモになる処理の文章の短縮の話です。 係り受け木を元にする手法をわかりやすく説明されて、もうなんか、すぐに実装できちゃうんじゃないかと錯覚してしまう始末でした。 係り受け解析というと、CaboChaを思い浮かべてしまうんですが、きっと違う実装なんだろうなぁ。 入門編と次回の重要文抽出の話も聞きたいなぁと。\n最後に、技術評論社さんから「Emacs実践入門」など3冊の書籍のプレゼントまでありました。 その他の2冊は購入済みだったのですが、Emacs本は購入したいリストに入れたままでした。 ということで、欲しいですというアピールをしてゲットしてきました! Emacsはなんだかんだで、もう10年以上使っていますが、そこまで深入りしないような使い方をしていました。 これを機に、再入門してもっと使いこなせるようになろうかと。 また、読了したタイミングでブログに感想かきます。\nということで、以下はいつもの自分用のメモになります。おかしいところ、それ書いちゃダメでしょ的なところのツッコミをいただければ。\n日時:2012年11月28日(水) 19:00 場所:渋谷ヒカリエ27F NHN Japan カフェ ◎開会、諸注意など @overlast 人材募集、会場説明など。 前回、本をもらった人はブログ書いてね。オライリー様より 今回も本のプレゼントあり。技術評論社様より ◎あなたの知らないハッシュテーブルの世界(30分 + 質疑応答10分) @kumagi さん ・まずは前提。 データの集合を扱いたいよね 配列でもできるね。けど、データ増えるとキツイね。 ・ハッシュ関数の話から。 リハッシュとかの話 ・ClosedAddressingとOpenAddressingの話 ・ClosedAddressingの場合、ポインタ使ってるからキャッシュミスあり。 メモリとかの話 ・OpenAddressingメモリに乗るのでキャッシュミスは少ないけど、削除データの扱いがちょっと大変 →削除がいっぱい有ると処理が面倒 ・RubyはClosedAddressing、PythonはOpenAddressing memcachedはClosedAddressing ・Cuckoo Hashing(2001) 密度50%以上になると急にコストが高くなる。 挿入がすごく遅くなる。追い出し操作が増えるから? ・そこで、Hopscotch ググった参考ページ:http://shnya.jp/blog/?p=639 http://en.wikipedia.org/wiki/Hopscotch_hashing 密度が上がっても性能劣化がない。 ・C++でHashtableが欲しくなったら、google_sparse_hashとdense使うよと。 ・ConcurrentHashmapのお話 テーブル部分がvolatile、Chain部分はfinal insertはChainの先頭に。 削除は遅い。ReadCopyUpdate。 空でも1.7M(K?)持ってく ・ここからはLock-free系 ・Lock-Free Hash Table http://www.azulsystems.com/events/javaone_2007/2007_LockFreeHash.pdf HotSpot VMの人のもの?こんなのやってる。http://www.0xdata.com/faq.html ・(聞きそびれた) ・日立謹製Lock-free hashtable 日立のDBで使ってる部品? ベンチマークが胡散臭い ・最後はJubatusのCM ◎文書要約入門 中級編(40分 + 質疑応答10分) @hitoshi_ni ・画数が少ないです。 ・ヒカリエ綺麗ですね。 ・文書要約とは? 「機械に」要約させる。 ・なんで要約? 長い文章読みたくない。人件費の削減 ・どうやって要約? 1.文分割:文書を文に分割 2.文短縮:就職説を削除するなどして、原文より短い文の亜種を出す。 3.重要文抽出:要約にふさわしい文を選び出す。 ・今回は文短縮について ・動機 長い文は文抽出で扱いにくい 文の中にも重要なところとそうでないとこがある ・係り受け木の剪定すると短くできると。 剪定のルール 中間ノードは落としちゃダメ 除去の時に考えること 重要度 言語 ・重要度? 文節に点数を付ける 文書集合中の出現頻度とかを採用。訓練データからでもいいよ(ロジスティック回帰とか)。 ・言語尤度 言語としての尤もらしさ 典型的にn-gram言語モデルを使う ・そして探索 基本的には2値ラベリング ビタビアルゴリズムではだめ。係り受け制約が考慮できない ナイーブいはビームサーチをする。 ・文短縮の評価 ・人間が書いた短縮文と比較 ・ROUGE-Lという尺度などで評価(これしらないなぁ。) ・幾つかの論点 係り受け解析しない 文節じゃなくて、単語単位でもいいよねとか。 Q:硬い文章以外の要約ってやってるの? A:あります。 技術的な話だと、係り受け解析がうまく出来ればできる。 係り受け解析がうまくいけば、そこまで大変じゃない。 Q:短さが短くなるほど難易度があがるけどどこまでやってます? A:短くすればするほど難しい。これは情報の欠落が激しくなるから。 文法性を担保するのも難しい。 10文字くらいならできそう。 Q:実例としてどのくらいの長さをどのくらい短くしてる? A:ある程度の長さを20文字にしてくれとか。Twitterに入るくらいにしてくれとか。 頂いちゃいました! Emacs実践入門 ~思考を直感的にコード化し、開発を加速する (WEB\u0026#43;DB PRESS plus) ","date":1354122000,"dir":"post/2012/","id":"e01e01d18582c7f69e1b0db7e1b111a0","lang":"ja","lastmod":1354122000,"permalink":"https://blog.johtani.info/blog/2012/11/29/dsirnlp-3-5%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9Femacs%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80%E3%82%92%E9%A0%82%E3%81%84%E3%81%A1%E3%82%83%E3%81%84%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-11-29T02:00:00+09:00","summary":"ヒカリエに行ってみたいという不純な理由で参加してきました。 新しいということもあり、おしゃれで綺麗なカフェでした。 入り口にはおっきな人形も立っ","tags":["勉強会"],"title":"#DSIRNLP 3.5に参加しました。&「Emacs実践入門」を頂いちゃいました!(Jugemより移植)"},{"contents":"第9回Solr勉強会に参加しました。 皆勤賞です!というか、主催者になってしまいました。 まだ不定期の開催になると思いますが、話をされたい方などいらっしゃいましたら連絡いただければ助かります。\n今回も面白い話が聞けました。\n最初はKuromojiの開発者でSolrのコミッターでもあるChristianの発表です。 Solr勉強会では初の英語の発表だったんじゃないでしょうか。 Atilikaでやってることの紹介から、Kuromojiの紹介、今後の改良に関する話とひと通り話してもらいました。 途中でKuromoji使ってる人?などの質問があったのですが、残念ながら反応が薄かったです。 漢数字をアラビア数字でも検索できるようにするチケットなど、今後のKuromojiの発展も楽しみです。 (コメントとかパッチを送れというプレッシャーもあったので、パッチ頑張って書きます。。。)\nつぎはニコ生でのSolrのお話。結構、赤裸々(前任者がいない状態で引き取ったとか)に語っていただき、ハラハラしながら聞いてました。 やはり、新語や略語で苦労されてるんだなぁと。 複数のサービスや開発者に対してSolrの環境を提供するという話はなかなか興味深かったです。 いろんな人がSolrを触るような状況になってきてるんだなぁと。 基盤となるラッパーのようなフレームワークとかも作ってるのかなぁ? 今後は台湾語や英語への展開も考えられているようなので、Language Detectionなどを利用してみた感想とその内容を今度発表してもらいたいですねw\nつぎはFacetPivotの話です。 昔から要望が出ていたのですが、4.0系でやっと使えるようになりました。 ファセットはSolrの売りの一つだと思います。 最初はこの考え方がしっくりこない人もいるかもなぁと。特にデータをどのように作れば、いいのかって悩むこともあります。 その悩んだ内容について発表してもらいました。 実際にどうやって使うかを悩んだ内容を発表してもらうのもいいなと思いました。\n最後はSolr勉強会なのに、elasticsearchの洗脳会になってましたw elasticsearchはSolrと同じ、Luceneをコアに採用した検索エンジンサーバーになります。 Solrとは別のアプローチでLuceneをラップし、REST APIでアクセスしやすくしたプロダクトです。 Luceneのコミッターの方もelasticsearchの開発に参加しています。 分散インデックスを念頭においた設計や、インストールが簡単なプラグイン構造といったSolrとは違ったアプローチがなされており、面白いものになっています。 残念ながら日本で利用されているという話はまだ聞いた事ないですが、だからこそ、触ってみて事例を紹介してみるのも面白いのではないでしょうか。 今回紹介したKuromojiも使えるようになっていたりしますので、日本語でもある程度使えると思います。\n以上が簡単ですが感想です。主催者だったのに、@hirotakasterさんや@ajiyoshiさんに受付などをやっていただいたので、いつもの様にしっかり話を聞いてしまいました。 発表者の方、会場提供いただいたVOYAGE GROUP、お手伝いいただいた皆さんに感謝です!\n今回初の主催でしたが、本当に助かりました。たどたどしい説明や紹介など至らない点も多々有ったかと思いますが、今後もよろしくお願いいたします。\n主催者的な立場として感じたことも書いておこうかと。 無料の勉強会で、ATNDという参加しやすい環境というのもあるかもしれないのですが、キャンセルをきちんとしていただくほうがいいなと思っています。 幸いにもSolr勉強会はここ数回は盛況で、キャンセル待ちの方が結構いらっしゃいます。 ギリギリまで業務との兼ね合いを見つつ、参加しようと思っていらっしゃる方もいると思うのですが、キャンセル待ちで行けるかな?どうかな?と思っている方もいらっしゃいます。 ドタキャンは問題ないのですが、キャンセルせずに欠席は出来れば避けていただけると助かるなぁと。 (残念ながら、きちんと集計をとれなかったので、次回からは集計取ってみようかなぁと)\n次回の開催は今のところ未定です。発表してみたい方、こんな話を聞いてみたいなど、気兼ねなく連絡いただければと思います。 このブログにコメントを頂いてもいいですし、ツイートしていただいてもいいので、反応をいただけると嬉しいです。 また、今回至らない点があったなどのツッコミ、批判も気兼ねなく言っていただければと思います。 今後の反省点にもしたいので、ぜひ反応をいただければと!\n懇親会でも色々な方とお話できました。(もう少し、Christianと英語で話す努力とかしないとなぁ。。。)\nとりあえず、メモをアップしときます。 リンクとか感想とかはまた(飲んだ)後で。。。\ntogetterでまとめてももらったみたいです。ありがたいです。\n第9回Solr勉強会 場所:VOYAGE GROUP 会議室 日時:11/26(月) 19:00~21:00 1. Atilika Inc. Christian Moenさん タイトル:Who we are, what we do, and a little bit about Kuromoji ◎Atilikaの紹介。 会社の目指すもの ・BigData、検索、NLP ◎プロダクト Kuromoji:形態素解析エンジン Akahai:日本語クエリサジェストエンジン Keywords:日本語キーフレーズ抽出 ◎Kuromojiの紹介 3.6からデフォルトで使える。 ◎将来の改良の話。 ・踊り字対応(コミット済み) ・漢数字に関するチケット&パッチのお話。 ・ユーザ辞書の重複エントリ改良とか(すみません、パッチ書きます。。。) 2. 株式会社ドワンゴ 吉村総一郎さん(@sifue) タイトル:Solr@ニコニコ生放送 ◎ニコニコ生放送の紹介 ・1日に10万番組。。。 ・10/17にバージョンQをリリースしたら、トップはひどい叩かれようでした。。。 ◎これまで。 Jackrabbit→Lucene→Solr→ニコ生のSolr ◎退職者と入れ替わりでSolr担当。。。 今回は資料と環境を調べて発掘した機能のお話。。。 ◎機能 キーワード検索。論理クエリ、などなど。 ◎利用してる環境 3.4ベース+Jetty マスタスレーブ構成(スレーブ2台) 途中は分散インデックスを自分で実装? ボトルネック自体がDBからのデータ収集だった ◎インデックス対象 ・見れるのは過去1週間と過去の公式番組すべて。 この部分だけ検索可能。 ・更新頻度の高い情報に「来場者数」「コメント数」 ◎インデックス作成 ・バッチにて更新 ◎アナライザ CJKTokenizerFactoryを利用 HTMLStripCharFilterFactory Bi-gramなので、「FF」とか「DQ」に弱い(FF1でFF13とかヒットしちゃう) 検索精度は悪いと言われてるみたい。 ◎1日のリクエスト ピーク時40QPS程度 5分おきにスパイクがある。(ユーザが作ったツールによる検索とか。。。) ◎UPDATEリクエスト ピーク時は80QPS ◎開発用のJettyのマルチテナント機能を利用したSolr環境の提供 ◎台湾語とか英語もやりたいなぁ。 3. 株式会社マーズフラッグ 柳吾朗さん(@hitode7456) タイトル:ドリルダウン色々 ◎Facetの紹介から ◎楽天でのドリルダウン例(これはFacetの紹介での例であり、実際にSolrが利用されているかはわからないです。) ◎多段ドリルダウン(ファセット)のお話。 アプリを実装するときの考え方とか。 ◎実直形、工夫形、PivotFacet Q\u0026amp;A Q:3つの性能系のコストは? A:まだ調べてないです。残り2つは工夫形がいいですよ。と 次回、調べた結果の発表もやってほしいなぁ。 4. 兼山元太さん (@penguinana_) https://speakerdeck.com/penguinco/solrtoelasticsearchfalsebi-jiao タイトル:SolrとElasticsearchの比較 ◎クックパッド! ◎elasticsearchの紹介 ◎比較サイトもあるよ! http://solr-vs-elasticsearch.com ◎サンプルデータ・セット(ライブドアグルメ)でサンプル実装。 https://github.com/penguinco/ld_gourmet_search ◎APIの紹介 REST APIがちゃんと造られてますよと。 設計時点でコレクションなどがURLに含まれてるのがいいよねと。 ◎_analyzeによりアナライザーもAPIとして公開されてるよと。 ◎Kuromojiも対応してるよ! ◎DynamicFieldよりも便利だよ。 ◎クエリのDSLが違うのでちょっとアレ。 ◎スコアリングも色々できるよ。 ◎感想 ・機能面の不足なし ・APIがいい コア追加とか、curlだけでできるのがいい。 ・習得が容易(Solrやってると機能とか似てる) ・大規模じゃなくても使えそう ◎分散検索がデザイン時に組み込まれてるのがいいよね。 write consistencyなどがインデックスごと(コレクションごと?)に設定可能なので便利。 ◎multi-tenant open/closeなどができる(時系列データとか) shard allocationなどの細かな制御も可能ですよと。 ◎plugin 色々プラグインがあるよ。管理画面もプラグインであります。 プラグインもコマンド一発で追加可能。 ◎クエリキャッシュがないので、自前でnginx、varnishなどでキャッシュが必要。 ","date":1353923040,"dir":"post/2012/","id":"7e23419e4fc69b5b533815681c9bb1a9","lang":"ja","lastmod":1353923040,"permalink":"https://blog.johtani.info/blog/2012/11/26/%E7%AC%AC9%E5%9B%9Esolr%E5%8B%89%E5%BC%B7%E4%BC%9A%E3%82%92%E4%B8%BB%E5%82%AC%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-solrjp/","publishdate":"2012-11-26T18:44:00+09:00","summary":"第9回Solr勉強会に参加しました。 皆勤賞です!というか、主催者になってしまいました。 まだ不定期の開催になると思いますが、話をされたい方など","tags":["勉強会"],"title":"第9回Solr勉強会を主催しました。#SolrJP(Jugemより移植)"},{"contents":"初目黒(たぶん)で、初Amazonな感じで、流行りの「ビッグデータ」のセミナーに参加してきました。\nとりあえず、いつもの自分用のメモを残しておきます。 感想はまた後日。。。(たぶん、頑張れ私。。。)\nAWS ビッグデータ活用事例セミナー 日時:2012/11/09 [ 金 ] 9:30 - 12:00 場所:アマゾンデータサービスジャパン目黒オフィス ★AWSビッグデータ概要 @understeer ○Amazonの紹介 ○Amazon Web Serviceの紹介 ・オンプレミスと比べ、初期費投資が不要 ・コストダウンを促進 過去6年で21回の値下げを実施 ・IaaSだけじゃなく、PaaSもやってますよ。 ・OSより上の層は好きに選べるよ。 ○AWSのサービスだけで20ある。 ○3つのV Volume 2012年で1.2ZB。95%が非構造データ。今後も非構造データが増加 Velocity デバイスの増加、パーソナライゼーション系の増加 Variaty 素粒子のデータの解析とか、地質学、気象予報とかいろいろやってるみたい。 ○BIG DATAの4つのプロセス。 収集、保存、分析、共有を繰り返しやりましょう。 そこで!AWS使いましょう。 ○収集 AWSへのデータアップロード オンプレにあるデータをAWS(S3)にアップロード ・インターネット経由 ・専用線サービス(AWS Direct Connect、1/10Gbps)も可能 ・AWS Import/Export(HDDを送りつけてS3にアップロードしてくれる。Tokyoリージョンにはだない) ・インターネットVPN経由も可能 ・EC2上のデータももちろんできる。 ※WAN高速化ソリューションも利用可能。 ○保存 ・AmazonS3 99.999999999%の耐久性。 同一リージョン内の3箇所以上のDCに自動複製 容量無制限で低コスト(1G 約10円/月) ・Amazon Glacier データの利用準備に3.5~4.5時間かかる。 S3の約1/10という低コスト ○分析 オンプレミスだと運用が大変。 ・Amazon EC2 スケールアップ/ダウン、アウト/インが即座に可能。ライセンス持ち込みや従量課金に対応 スペックの種類が豊富(SSDとかもあるよと) ・Elastic MapReduce Hadoopをサポートしたの仮想サーバが簡単に用意可能。 S3、Dynamoとの連携も可能 ディストリビューションも選択可能(Apache、MapR) 追加のアプリ(Hive、Pig、HBase)なども利用可能。 ジョブの大きさに合わせてクラスタサイズを適切にすることでコスパがよくなる。 →HadoopのMRのデータのローカリティとかはどうなってるんだろう? ○共有 ・AWS RDS MySQL、Oracle、SQLServerをサポート(PostgreSQLはないのかな?) 自動バックアップ、フェイルオーバー、パッチ適用機能があるよ ・Amazon DynamoDB AmazonオリジナルなNoSQLデータベース。論文有るよ。 運用管理は気にしなくていい。 性能については客指定の性能が出せるようになる。しかも変えられるよと。 ※データサイズに応じて以下を選択しましょう RDS、HBase on EMR、DynamoDB、S3 他にもEC2上で、CassandraやmongoDB、GlusterFSを使ってる事例もありますよ。 ○以上を繰り返すのが意味があります。そこで! ・Simple Queue Service マネージド分散キューサービス 最低1度のメッセージ到達の保証。複数DC間で複製保存 ・Simple Workflow Service 進捗などの管理も可能 NASAのCURIOSITYの制御に利用?10m前進するのに10時間のバッチ処理がある。。。 データがなくて試せない!そんなあなたに! ○AWS Public Data Sets すぐ使えるPublic Dataが用意されてるよ。 http://aws.amazon.com/jp/publicdatasets/ ★AWSのビッグデータ事例紹介 @shot6 ○NETFLIX ・どんな会社? 2500万人以上のストリーミング会員 500億以上のイベント ・AWSの利用は?(保存) 8TB/日のイベントデータを収集しS3に。 Cassandra上の顧客データもS3に。 1PB以上のデータがS3に保存。 ・AWSの利用は?(解析) EMRでレコメンデーション、アドホック分析、パーソナライゼーションなど。 本番クラスタ(ずっと動かしている) アドホック分析用クラスタ(必要に応じて構築) 解析用のアルゴリズムをAPIで叩けて、ジョブとして定義されてるらしい ・Cassandraを使ってるよ。 Cassandraのクラスタをマルチリージョンで対応したりもしてる。 CassandraのBackupもやってる。OSSで公開されてる? ※HBaseのものもあるよ。 ※AWS上のCassandra事例もいくつか広告系で出てるみたい。 ・High I/O Instances for EC2(SSDのインスタンスまだ東京に無いらしい。) ・AWSスケールアウトだけでなく、スケールアップも徐々に増えています。 ○yelp ・どんな会社? 口コミサイト。 スペルミスの自動修正、検索ワード自動補完、 ・AWSの利用は? WebサイトのログをS3に保存。 EMRを利用してHadoopClusterで解析してS3に保存している。 EMRは処理終了後にシャットダウンしてる。 ・データ解析が日常になった ○SHAZAM ・どんな会社? 広告配信、モバイル系の配信をやってる会社。 Super Bowlの広告配信でAWS、DynamoDBを利用。 ※マイネット・ジャパンでもDynamoDBを利用している ○CLIMATE Corporation ・どんな会社? 天候保険の会社 ・AWSの利用は? 200TBの地質、天候データを解析して ○THOMSON REUTERS ・どんな会社? 情報提供の会社。データの提供が元だけど、解析した結果の情報も提供してるみたい。 ・AWSの利用は? MarketScanという18年分の個人の医療データ(個人情報自体はないみたい)を販売する、販促ールとして利用。 1500万人分の患者データを提供。 マーケットの分析に使えるデータの提供。 KARMASPHEREとEMRの組み合わせで、ソリューションを提供していますよと。 ・事例 1.MarketScanをS3にアップロード。 2.分析官が、KARMASPHERE経由でEMRにアクセス。 3.EMRにS3からデータロードされ、結果がRDS(Oracle)に保存 4.RDSに他の人達もアクセスして使ってるよと。 ○RANGESPAN ・どんな会社? ECサイト向けのPaaSサービスを提供してるロンドンの会社。 ・AWSの利用は? NLP、機械学習にEMRを利用? mongoDBのクラスタを構築してる。 ※mongoDBの日本の事例としてCAがあるらしい。 ★Huahin Framework活用事例 on AWS @ryu_kobayashi ○Cassandra本とかもやられてるみたい。 ○EMRとは PaaSなんだけど、中身を自分でいじれるらしい。 Management Consoleでは3つのバージョンが使えるが、コマンドラインからだと他にも使えるみい。 ・HBaseはAmazonのDistributionのものだけ。 ・EMRのメリットは? インフラの面倒を見なくていい。 クラスタの立ち上げも複数あげられるので簡単。本番実行と同じ環境 ・EMRのデメリット オンプレミスにすでにデータがあるとアップロードが大変。実際に物理HDDを送ったこともある(2,3日でAWS上にアップロードされた) 外に出せないデータがあると。。。 ○EMRのTips(EMRの連載に載ってますよ!http://gihyo.jp/dev/serial/01/emr) ・Bootstrapを設定 EMRのクラスタの起動前にメモリ設定とかHadoopの設定が可能にできる。 ・ファイルサイズを適切に Map数=splitを決めるコード を指定することで、処理が早くできるのかな? ○EMRの起動には いろいろあるけど、HuahinEManagerを使うと使いやすいよ? ○Huahin Frameworkの構成 ・Huahinの名前の由来は? 社内のコードはワインの産地にするという決まり。 タイの観光地Hua Hinがワインの産地。 ・他のHadoop関連のマスコットより可愛いでしょ!? ・Huahin Core MRのプログラムを簡易化 WritableとかSecondary Sortとか書かなくていい 考え方がSQL寄り 素のMRも書ける。Pig、Hiveだとパフォーマンスが難しい Huahin UnitというMRUnitをラップしたものもある ・Huahin Tools 汎用的な処理を集めたツール群だけど、Apache Logの成形のみ。 オンプレミスHadoop、スタンドアロン環境でも動かせるようになってる。 ・Huahin Manager Jobを管理するマネージャ Jobの実行 キューを持ってるので、複数の実行が可能だよ。 EMR対応してる。bootstrapに設定するとできるらしい。 ・Huahin EManager EMRのいろいろが管理できるみたい。 初期設定20までしかインスタンスが挙げられない上限があるらしいので気をつけましょうと。 キュー登録のPOST機能は便利そうだ。(EMR触る機会まだまだないけど。。。) EMRにはJobのkillがない→Job FlowをターミネートすればOK→実際にはEMRのマスタノードにSSHすればできるよ。→めんどくさいよね。。。 EManagerなら可能ですよと。これは必須だよなぁ。 ","date":1352477220,"dir":"post/2012/","id":"98c640616f997a323af625e34ba34850","lang":"ja","lastmod":1352477220,"permalink":"https://blog.johtani.info/blog/2012/11/10/aws-%E3%83%93%E3%83%83%E3%82%B0%E3%83%87%E3%83%BC%E3%82%BF%E6%B4%BB%E7%94%A8%E4%BA%8B%E4%BE%8B%E3%82%BB%E3%83%9F%E3%83%8A%E3%83%BC%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-jawsug/","publishdate":"2012-11-10T01:07:00+09:00","summary":"初目黒(たぶん)で、初Amazonな感じで、流行りの「ビッグデータ」のセミナーに参加してきました。 とりあえず、いつもの自分用のメモを残してお","tags":["勉強会"],"title":"AWS ビッグデータ活用事例セミナーに参加しました。#jawsug(Jugemより移植)"},{"contents":"##Lucene/Solr 4.0.0リリース ついに、Lucene/Solr4.0.0がリリースされました。 MLで流れていましたが、3年越しのリリースだったようです。 コミッターの方々、JIRAにバグ報告をした方々、お疲れ様でした。\nということで、ちょっと忙しくなりそうです。。。 4.0の機能を調べたりもしたいですし、すこしずつ紹介もしたいです。\n本家サイトのニュースはこちら\n##lucene-gosenの4.0対応版について lucene-gosenも4.0正式版のjarを利用したバージョンを公開する予定です。 branches/4xでは、すでに作業を行なっており、jarファイルの差し替えは終了しています。 お急ぎの方は、branches/4xをエクスポートして、ビルドしていただくと利用可能となっています。 なお、Lucene/Solrのバージョンが上がっているため、lucene-gosenのメジャーバージョンも変更し、lucene-gosen-4.0.0としてリリースする予定ですしました。。(順当に行けば、3.0.0ですが、Luceneのメジャーバージョンに合わせたほうがわかりやすいかと思いまして。) また、現在、trunkが3.6.x対応のソースになっていますが、このあと、現在のbranches/4xのソースをtrunkにする予定です。 3.6.x対応のlucene-gosenについては、branches/lucene-gosen-rel2.0にて作業を行うこととなります。 今後は注意してチェックアウトするようにお願いいたします。\nということで、ダウンロードできるようにしました。 lcuene-gosen-4.0.0*.jarとついているものがLucene/Solr 4.0.0に対応したライブラリになります。\n","date":1350031500,"dir":"post/2012/","id":"922cc71fd28b1dac8f407f1d517f5595","lang":"ja","lastmod":1350031500,"permalink":"https://blog.johtani.info/blog/2012/10/12/lucene-solr-4-0-0%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9lucene-gosen%E3%81%AE4-0%E5%AF%BE%E5%BF%9C/","publishdate":"2012-10-12T17:45:00+09:00","summary":"##Lucene/Solr 4.0.0リリース ついに、Lucene/Solr4.0.0がリリースされました。 MLで流れていましたが、3年越しのリリースだったようです。","tags":["lucene-gosen"],"title":"Lucene/Solr 4.0.0リリース&lucene-gosenの4.0対応(Jugemより移植)"},{"contents":"このイベントにウチダスペクトラムの枠でMahoutのコミッターである、Grant Ingersollさんが講演されるということで、興味があったので聞いて来ました。 (この枠だけ)\nLucidWorks社が現在展開している、LucidWorks BigDataの概要とコンセプトといった話の内容でしょうか。 LucidWorks社(元Lucid Imagination)はLucene/Solrのコミッターの方々が多く在籍している会社です。 検索システムに関するノウハウを元に、発見や解析といった部分にニーズが広がってきているという話の ざっくりした概要のはなしでした。 検索システムを中核にして、ログや検索で提供しているデータの解析などの重要そうなポイントが散りばめられて いるお話でした。\nもっと詳しい話を聞きたいなぁ。\n講演では日本語の資料でしたが、サイトに英語の資料がアップされているとのことでした。 原文が読めるのは非常に助かります。他のイベントなどでもこのように英語の資料も見れるようになると嬉しいです。\n以下は、いつものメモになります。\n場所:富士ソフト アキバプラザ5Fホール 日時:16:10- ◯サーチ技術による情報の可視化 通常、検索と言うとWebサーチだけど、ウチダスペクトラムのやっている部分はエンタープライズ向け ナイスガイ=Grant S. Ingersollという紹介 ◯サーチからSDAへ LuceneやSolrのお陰で、検索自体は簡単になってきている。 ◯サーチの進化 ユーザとデータを結びつける意味での検索の進化が必要 ユーザインタラクションや、アクセスの方法とか ◯SDA Search, Discovery and Analytics ・ユーザからのニーズ 検索、優先順序付け、新たな気づき、フィードバックによる学習 ・ビジネスからのニーズ ナレッジの有効活用 ◯ユーザ事例 保険会社での請求に関する不正利用分析を含んだクレーム処理と分析 ◯事例:個人に最適化された医薬品 DNAをベースに検索やファセットで医薬品を検索したり。 ◯事例:通信会社における通話記録処理 ログを元に検索して、不正通話などを解析 ◯SDA基盤に必要な要素 高速で拡張性のある、検索 大規模でのコスト効率が高いストレージと処理 NLPとMLにより解析などが向上 ◯SDAのアーキテクチャ 基盤 LucidWorks Search、Hadoop、HBase、ApachePig、Mahout、 NLP、 管理 Zookeeper インフラ ZABBIX、AWS、Chef データの流し込み Twitterからのデータとか ◯検索部分にフォーカス ・LucidWorks Search SolrCloudによる簡単なshard処理 ・Hadoop ログ、生データ、中間ファイルの保存 WebHDFS 小さなファイルには向いていない ・HBase メトリック、ユーザ履歴などのストレージ 課題 どこに正式に保存する? リアルタイム処理 vs バッチ処理 分析はどこで行われるべきか? ◯検索の実装に関連すること 3つのポイント 性能と拡張性 関連性 オペレーション(モニタリング、フェイルオーバーなど) ビジネス側では検索結果の適合性を重要視する 開発側は性能を重視する傾向がある。 ◯適合性に関して テストが重要。 クエリ、クリック、表示したドキュメントなど、すべて保存すべき! ◯Discoveryにフォーカス ◯MahoutによるDiscovery 3つのC ・協調フィルタリング ・クラシフィケーション ・クラスタリング 追加事項 課題 収束を伴う計算コストの高い機械学習アルゴリズム Mahout ◯余談:Experiment Management ◯Analyticsにフォーカス Rとか、うまく活用 検索エンジン自体でもできることがある。ファセット、TF、DF/IDF SearchとDiscoveryの定量化 ログ、ナビゲーション分析 ","date":1348650492,"dir":"post/2012/","id":"43501cdf0de25278a208cbb9aad80012","lang":"ja","lastmod":1348650492,"permalink":"https://blog.johtani.info/blog/2012/09/26/lucid%E3%81%AEgrant-ingersoll%E3%81%95%E3%82%93%E3%81%AE%E8%AC%9B%E6%BC%94%E3%82%92%E8%81%9E%E3%81%84%E3%81%A6%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-09-26T18:08:12+09:00","summary":"このイベントにウチダスペクトラムの枠でMahoutのコミッターである、Grant Ingersollさんが講演されるということで、興味があった","tags":["勉強会"],"title":"LucidのGrant Ingersollさんの講演を聞いてきました(Jugemより移植)"},{"contents":"PFIオープンセミナー2012に参加してきました。 対象から微妙に外れてたり、話の内容についていけるか自信がありませんでしたが、参加してきました。 PFIさんは前から面白そうなことやってる会社だなぁと思っていたので。\n面白い話がいっぱい聞けました。 電池が切れそうなので、とりあえず、まずはメモをアップしときます。 かろうじてついていけたという感じですが。 丸山先生の話はアーキテクチャの話に入る前のビッグデータの光と影の話がよかったです。 ビッグデータと言っても、まずは、サンプリングなどで小さなデータで処理できるかもしれないと考えるのも必要なのでは?という話や、相関があるからといって、因果が有るわけではないとか、おそらく、統計やってる人や、数学やってる人にしてみれば、当たり前の事なんでしょうが、その部分に警鐘を鳴らす話が聞けたのは良かったです。 もちろん、ビッグデータでなければ意味が無い解析などもありますという話もきちんと出ていました。\n伊藤さんの話は、Screwと呼ばれる、多言語解析基盤のお話です。その前にSedueの紹介で、SolrとSedueの比較の話も出ていました。(若干、強引な感じもしましたが。。。) 多言語解析基盤は、Solrでも少し入ってきています。ただ、それよりも汎用的な作りになるようなので、今後Solrと組み合わせて使うといったことも可能になるかもしれません。 まだ、対応言語などが少ないので今後に期待という感じでしょうか。 複数の言語が混ざった時の挙動がどうなるのかや、身近な文章での言語判定の正確さは少し気になります。\nサイバーセキュリティの話も面白かったのですが、話が多岐にわたるのと、スライドの情報量の多さに少しついていけませんでした。 資料が公開されたら、もう一度見直したいかなぁと。\n比戸さんの話は、Jubatusと関連のある話でした。機械学習の実際の利用の話が特に興味深かったです。 最近になって、ようやく、実際のデータを利用した話が出てきているみたいで、もっと事例が出てくると機械学習も身近になりそうだなぁと。\n最後は、日経BPの中田さんの話でした。これが、一番想像していたものと内容が違って、驚きつつ、楽しめた話でした。 ビッグデータというバズワードがいかにして生まれたのかがよく分かりました。 私は、バズワードだなぁと思う程度だったのですが、出てきた背景にある程度意味があるという考察に感心して聞き入ってしまいました。\nということで、思っていたよりも話の内容についていけたので、講演された方々の話しのされ方が良かっただと思います。\n少し無理をして参加してよかったと。\n残念だったのは、会場が地下だったため、携帯が入らなかったことでしょうか。 私はe-mobileで接続していたので大丈夫でしたが、docomoの携帯は圏外でした。 ツイートがもう少し盛り上がれば、もっと質問も出たのかもしれないです。\nhttp://preferred.jp/news/seminar/\n資料が公開されたので、リンクを貼っておきます。 PFIの方たちの資料へのリンク: http://preferred.jp/news/?id=1139\nゲスト講師の資料へのリンク: http://preferred.jp/news/?id=1159\n◯「多様化する情報を支える技術」 講師:西川徹(株式会社プリファードインフラストラクチャー 代表取締役) ・PFIの説明 VCに頼らない。製品につながるビジネスにこだわる(受託開発しない)、技術の多様性を重視 ・PFIの技術領域、ビジネス 製品開発(Sedue/Bazil/Jubatus)、自然言語処理、機械学習、分散システムなど ・”人”が生み出すデータと\u0026#34;機械\u0026#34;が生み出すデータ ビッグデータの発端はGoogleが元じゃないか?→最後の公演で解説があるよ 人:質が高いけど、量が少ない 機械:質は低いけど、量が多い ・検索システムについてのお話 社内の資料とか情報が、人によって、まちまちなデータの保存(形式、場所など)が実施されてしまう。 情報検索技術と大規模データ ・人のデータへ必要なアプローチ より検索システムを活用してもらうために、楽に整理できる仕組みなどをどう提供するか 質の高いデータなのに、形式的な共有しかできていないのはもったいない ・機械のデータへ必要なアプローチ 大量データと高度な解析が重要(CEPとか) デバイスが性能向上→流れてくるデータが大量に→蓄積するだけでも問題になってくる →蓄積したデータを扱うだけでも処理コストが高くなる 分析をオンライン化、ストリーム化すること→Jubatusで貯めずに高度な解析をしましょう。 Edge-Heavyになりつつある。 ◯「ITアーキテクチャはどこへ向かうのか」 講師:丸山宏氏(統計数理研究所 副所長 モデリング研究系教授 工学博士) ・ビッグデータの光と影 「その数学が戦略を決める」という本がオススメ ・大量データでも、ランダムサンプリングでとければ、ビッグデータじゃなくてもいいよね。 もちろん、ランダムサンプリングだけじゃダメな場合もある。 ・Hadoopが解ける問題領域って少ないのでは。 ・TVを見る時間が長い人ほど、方言の使用率が高い 因果関係と相関関係の違いをきちんと理解しましょう。 ・データをきちんと理解して意思決定などをしたほうがいいよと。 ・つぎのアーキテクチャは何か? ・コンピュータ・アーキテクチャの歴史 ConnetionMachine CM-1(1985) SPARC Transputer(CSPによる並列性、Occam) SymbolicsLispMachine Intelアーキテクチャの台頭により、アーキテクチャの研究が廃れてくる ・クラサバ、スマホ・クラウドなどのアーキテクチャの話 ・じゃあつぎは? Edge-Heay Data=スマホなどデータが保存される場所がEdgeになりつつある ビッグデータのほとんどが廃棄されるデータ ・Edge-Heavy Dataに特化したアーキテクチャとは? 分散マッチング・プロトコル→サマリ情報を交換することで、絞り込みが可能 X=3とした場合、センサーとかなら、ピンポイントな値ではなく、範囲では。 分布表現を1stクラスオブジェクトとするプログラミング言語が必要では? ・アーキテクチャの変節点を見極めよう QA: Q:スパースネス問題がランダムサンプリングやフィルタリングじゃ解けないんでは? A:はい。ただ、その前にやることがあるはずですよねという注意喚起の意味での発表です。 価値に応じて、EdgeにあるデータをCenterに持ってくるという考え方が必要。 今は価値が見いだせないのなら、Centerにまで持ってこなくてもいいのでは。 ◯「グローバル化する情報処理」 講師:伊藤敬彦(株式会社プリファードインフラストラクチャー 研究開発部門 リサーチャー) ・Sedueの説明 NHKニュースなどで ・提供する機能 ・検索補助 レコメンド、サジェストなど ・レコメンド機能の紹介 ・Sedue/Solrの比較 サポート体制:開発チームがサポートしてくれる 安定性:GCがないのがいい 付加機能: 検索の完全性:接尾辞配列による検索 ・多言語処理の話 ・翻訳ではなく、任意の自然言語言語で動作・精度を向上させる処理の話。 ・背景 サービスのグローバル化、会社組織のグローバル化 ・複数言語を扱う場合の難しさ 多言語解析基盤Screwの開発。 1.必要な処理を順番に適用する 処理の順序は設定で。出力はJSONで。 例:言語同定、単語分割、単語正規化 →言語同定処理で 2.言語ごとに必要な処理を適用 ・疑問 ScrewはSolrとの組み合わせもできる? 複数言語が混ざった文章の場合にどういう形で動作する? 言語判定は独自実装? ◯「BigData処理技術とサイバーセキュリティ」→題名変更されてた 講師:桑名栄二氏(NTTセキュアプラットフォーム研究所 所長) ・経歴 Jubatusプロジェクト立ち上げに参画 ・攻撃に関する話 原因のわかっていないケースが多い。 ・端末の初期設定のパスワードとかが狙われるケースも多い ・変化する攻撃、変化するシステム・サービス、変化するデータ ・マルウェアの分類にJubatus ・不正IPアドレスを機械学習して ・ABC 「あたりまえ」のことを「ばかみたいに」「ちゃんとやる」 ◯「先進ビッグデータ応用を支える機械学習に求められる新技術」 講師:比戸将平(株式会社プリファードインフラストラクチャー 研究開発部門 リサーチャー) ・ビッグデータ分析はより深い地検を得られるビッグデータ「解析」へ ・ビッグデータ分析プロセス Volume、Variety、Velocity 蓄積(NoSQL系)、分析(CEP)、両方やるのがHadoop ・分析から深い解析へ 予測、カテゴリ分類、レコメンド、異常検知 これを機械学習で解決する方向で ・機械学習を応用している例 クレジットカードの不正利用検知:FICO ネットワーク攻撃/侵入検出 Jeopardy!でクイズ王に勝利 医療診断支援 ・データ解析技術への過度な期待と現実とのギャップ いろいろできるみたいだけど、何が必要? ・ビッグデータ処理系を使える人 ・データサイエンティスト ・機械学習ツール ・ビッグデータ処理系での機械学習への対応状況 Hadoop本体(YARN) MapReduce系(Mahout、AllReduce or Vowpal Wabbit、SystemML) 非MapReduce系(Spark) ・機械学習からビッグデータへの歩み寄り ベンチマーク性能への固執とか、応用との乖離を批判する論文もあるらしい。 ・機械学習の応用例 Machine Lerning for the New York City Power Grid[Rudin et al., TPAMI, 2012] 電力配電設備の障害予測・検知 実データを用いた例が今後増えていくのでは。 ・今後重要になる技術とPFIの取り組み ・データ解析の敷居を下げるためのトレーサビリティ 機械学習向けスクリプト言語は敷居が高い WekaやSPSSのようなアイコンベースのデータ処理プロセスの記述は前処理には強力だけど、機械学習とは相性が良くない 結果が見える化部分との統合が不十分。 ・Bazil Farm学習結果分析例 Tweet年齢推定、Tweet性別推定 ◯「“ビッグデータ”が話題になった理由」 講師:中田敦氏(株式会社日経BP社 記者) ・自己紹介 ・バズワードができるまで まずは、「クラウド」のバズワードの歴史 「バズワードはIT企業やThe Economist誌の煽りでなく一般企業の経営陣が納得すると生まれる」 ・なぜ経営者がビッグデータに興味を? 「ザ・クオンツ」という書籍に金融業界のルールの変化が書かれてる。面白いよ。 Google/Amazonに対する警戒心から。 破壊的な新規産業者へ対抗して行かないといけない思うところからビッグデータが流行ってるのでは。 「買ってきたIT」は差別化要因にならないのでは?→自分で作ったITなら差別化できる。 ・競争力は自分で作るしか無い 日本のとある特殊事情 ITエンジニアの所属先が日米で割合がぜんぜん違う。米国はユーザ企業が75%、日本は25%くらい ・ビッグデータの次はなに? 3次元プリンタがあれば、好きなモノが作れちゃう。=消費地の近くで作成しちゃえば良くなるのでは。 ","date":1348214700,"dir":"post/2012/","id":"89abaa7f21cf788ce4744e3e61173291","lang":"ja","lastmod":1348214700,"permalink":"https://blog.johtani.info/blog/2012/09/21/pfi%E3%82%AA%E3%83%BC%E3%83%97%E3%83%B3%E3%82%BB%E3%83%9F%E3%83%8A%E3%83%BC2012%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%A6%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F--pfiopen2012/","publishdate":"2012-09-21T17:05:00+09:00","summary":"PFIオープンセミナー2012に参加してきました。 対象から微妙に外れてたり、話の内容についていけるか自信がありませんでしたが、参加してきまし","tags":["勉強会"],"title":"PFIオープンセミナー2012に参加してきました。 #pfiopen2012(Jugemより移植)"},{"contents":"友人にお値打価格で購入したMac miniはMountain Lionにアップデートしてたのですが、手元のAirはまだアップデートしていませんでした。\n夏休み中にバックアップ+アップデートをしてしまおうと思いMountain Lionにアップデートはしていたのですが、 本格的に触り始めると色々と動かないものがあったので、備忘録としてブログを書いておきます。 (まだ途中ですが。)\n###1.Eclipseが起動しない Java6が未インストール状態になったみたいで、Eclipseを起動すると、Java6をインストールしなさいと言われました。 で、私の記憶が確かなら、前はJavaコマンドを実行するとインストールされたんですが、ターミナルでjavaコマンドを実行するとjavaはすでにインストールされてる模様。。。 あれ?と思い、-versionを実行すると、JDK7u4と出るじゃないですか。 どうやら、Java7u4は別途入れてたものが残ってる模様。 さて、どーする?ということで、ツイートしたりぐぐってみて、「Java Preferences」なる設定用のアプリ?が有ることに気づき、とりあえず開いてみたらJava6ないからインストールしたら?と言われました。 結果オーライということで、インストール開始。 無事、インストールも終了。Eclipseも起動しました。(ただし、今度はMercurialのプラグインがPythonのライブラリが無いとエラーを出すことに) ###2.Xcodeが起動しない。 使ってはいないんですが、Javaの件を調べるのに、起動したらLionじゃないと駄目だよと。 ということで、Xcodeもインストールしなおし。 ###3. homebrewが動かない 1.で書いた方法で、Eclipse自体は起動したんですが、Mercurialのプラグインがエラーを吐き始めました。 で、見てみると、hgコマンドを実行しようとしてなんか、壊れていると。 で、hgコマンドってどうやってインストールしたか思い出さないまま、とりあえず、homebrewだっけ?と勘違いしたまま、「brew update」を実行したらエラーがでて、「brew install git」でしょ?って言われてしまいました。 コメントにもいただいていたように、Xcodeをインストールしたのだが、コマンドラインツールが入ってないというのが影響しているみたいです。。。 で、ググってみると、こんな情報が。[http://labs.torques.jp/2012/07/04/2830/](http://labs.torques.jp/2012/07/04/2830/) ただ、そこに有るようにPreferenceのダウンロードを開いてもなーんにも表示されません。 で、更にググってこちらの情報に。[http://qiita.com/items/9dd797f42e7bea674705](http://qiita.com/items/9dd797f42e7bea674705)(なんだか、TLで見かける人のお名前が!) AppleのDeveloperサイトからダウンロードかぁと思いつつダウンロード用のリンクを踏んだら、アカウント登録しろとのページが。。。 なかなか遠い道のりですね。。。 Appleのアカウント自体は持ってるので、Developerへの追加登録なんですが、日本語が文字化けしまくりの確認ページが出る始末。 もう、めんどくさいので、そのまま登録しちゃいました。 で、ダウンロードする前にもう一回XcodeのPreference見てみたらなんか、ダウンロードする候補が出てきてるじゃないですか! 結局、XcodeのPereference画面からダウンロードすることにしました。 AppleのDeveloperに登録したからなのか、Xcodeのプロジェクトを作ろうとしてXcodeをきちんと起動したからなのかは結局わかっていません。。。 良くないよなぁ。(ご存知の方いたらコメントもらえると嬉しいです。) で、やっと「homebrew」を入れようかなぁと。 一応その前に「sudo brew update」ってやってみたらどうなる?と挑戦したら今度は動きました。 homebrewが何を判断してinstallでしょ?って言ってたのかもわかっていませんが、updateで良かったみたいです。 ついでに、upgradeもしときました。(こっちは後からインストールしたもののバージョンが上がってるものがあったら更新してくれるコマンドかなぁ?)\n###4. pipの更新 ただ、brewをupdateしても相変わらず、EclipseのMercurialのPluginはエラーを出してました。 で、ターミナルからhgコマンドを実行してみたら同じエラーが。まぁ、そうですよね。 エラーメッセージを頼りにこれまたググってみたら、同じ状況のひとがいました。[https://groups.google.com/forum/#!msg/mercurial-ja/MxY6lejLXxo/OgJA_knXV6cJ](https://groups.google.com/forum/#!msg/mercurial-ja/MxY6lejLXxo/OgJA_knXV6cJ)(ここにもTLでお世話になってる方のお名前が!!) で、書いてあるように「とりあえず pip install mercurial で解決しました. 」ということで、コマンドを実行して見ることに。 これが、また失敗します。。。(日頃の行いが悪い??てか、日頃MBAをメンテできてないのが悪いのか。。。) そういえば、過去のMBAセットアップのメモを残してたなぁと思い出して「johtani mercurial」でググってみるとちゃんと[書いてある](http://johtani.jugem.jp/?eid=34)じゃないですかー(偉いぞ、自分) ということで、「sudo easy_install pip」でpipを更新してから「sudo pip install Mercurial」で無事、hgコマンドもインストールし直せました。 Eclipseを起動してもエラーが出ない。(まだbitbucketに接続確認まではできてないですが。。。眠さに勝てず寝てしまいました。) ","date":1346650440,"dir":"post/2012/","id":"7604edf307a5e96120606c8dda06458f","lang":"ja","lastmod":1346650440,"permalink":"https://blog.johtani.info/blog/2012/09/03/%E3%83%A1%E3%82%A4%E3%83%B3mba%E3%82%92mountain-lion%E3%81%AB%E3%82%A2%E3%83%83%E3%83%97%E3%83%87%E3%83%BC%E3%83%88%E3%81%84%E3%82%8D%E3%81%84%E3%82%8D%E7%A2%BA%E8%AA%8D%E4%B8%AD/","publishdate":"2012-09-03T14:34:00+09:00","summary":"友人にお値打価格で購入したMac miniはMountain Lionにアップデートしてたのですが、手元のAirはまだアップデートしていませんで","tags":["備忘録"],"title":"メインMBAをMountain Lionにアップデート(いろいろ確認中)(Jugemより移植)"},{"contents":"興味をもちつつ、触っていない軟弱者ですが、興味があるので今回も話を聞きに行って来ました。\nまずは、作者古橋さんによるFluentdの魅力や次期バージョンのお話。 あいかわらずわかりやすいスライドで話もわかりやすくてよかったです。 どうしても実績という点を懸念事項として上げる人が多いというアンケートを元に、各社が使ってるし導入もしやすいですというお話。 ここまでしてもらってるのに触ってないなんてほんと申し訳ないです。。。\n次は楽天の方によるCloud Foundryのログの問題点解消のためのFluentd導入のお話。 EC2でもそうですが、ファイルが永続化されない?のでログが消えてしまうという問題があるので、 集約しましょうと。 いままでとは少し違う問題点からの話でした。\n次はドリコムの方(浴衣?甚平?でかっこ良く発表)のIDCをまたいだFluentdの活用と、Fluentd自体の監視などについてのお話。 実際にログが増殖して苦労された点を解決するために考えられた監視項目など、あとで見返したくなる資料でした。 実際に試行錯誤されたあとの話はやはりありがたいです。 あと、お子さんが可愛かったw\nつぎのCROOZの方のPCがWindowsだったため(?)プロジェクターに繋がらず、急遽QAタイム。 このあたりの@doryokujinの話のつなぎの旨さとかほんとすごいなぁと感心します。\nで、Macに乗り換えてCROOZの方の発表。 Fluentd+TreasureDataのお話。少人数(というか一人?)でも簡単にログ収集の仕組みが作れて、しかも保存先のサーバを用意せずに簡単な解析もできるというお話。 これは、ちょっとやってみようと思う人(少なくとも、私はやろうと思った)が増えたんじゃないかなぁという発表でした。 スライドがなぜか最後のほうが見えなくなってしまったので、第3回でも発表されるということになってましたw 最後は新大阪から文字通り駆けつけた玉川さんのHBase本+そのた今後の翻訳本の紹介。 つぎはHiveの本も出てくるみたいでした。 日本語の資料ってホント助かります。購入しないと翻訳本が出る機会もないみたいなので皆さん買ってくださいとのこと。 HBaseはまだ触りそうにないから9月に出るAWSの本でも買おうかなぁ。 あ、日本語で解説してあるSolrの本もあるので是非買ってください!\nその後は懇親会でした。今回もTL上でズケズケと私が勝手に絡んでいる方たちにリアルにお会いできたので楽しかったです。\n自分もフロントよりも、バックエンドに興味があるし、実際に運用されてる人の話が多く聞けるので次回も参加したいです。 それまでにどこかで触るかplugin作るかしないとなぁ。\nということで、以下はいつもの適当メモです。\n開催日時:2012/08/22 18:00 ~ 22:00 場所:グリー株式会社 14F セミナールームYosemite ◎「Fluentdの現在と未来」 Treasure Data, Inc. 古橋 貞之 (@frsyuki) ◯アンケートの内訳 ◯ドキュメント欲しい? ※思ったより日本語のドキュメントじゃなくてもよさそうだった。 ◯loggingってなんでいるの? いろいろな解析ってあるよね。 ◯ログの集約、保存、などの問題点について フォーマットが混在 集約するのもいろんなスクリプトが混在 ◯メリット ・プラグインアーキテクチャ in/outに合わせてプラグインが用意/開発可能 ・フォーマットがJSON アプリでの解析が楽 ・HA構成が可能 ◯実績がない?→ 誰が使ってる? COOKPADとか、NHNとか ◯次期バージョンの構想 ・設定ファイルで色々とらくできるよ。 ・MessagePackのv5に対応 ・td-agent-lite などなど ◯QA Q:時刻にミリ秒を持つことは可能? A:互換性も気になりますが、検討します。 Q:JSONで構造化が売りだが、Flumeとかはテキストだけど、テキスト A:ログのパース時にやるというスタンス。 Q:日本語ドキュメントがやっぱり欲しい。手伝います! A:別ブランチで翻訳しながら公開して欲しいし、バラバラにやるよりいいので。 Q:Windowsでも動かしたいけど、cool.ioの移植とか考えてないですか。 A:次期で、fluentdのコアからはcool.ioを外す予定です。 ◎「Logging Infrastructure in PaaS by Fluentd」 Rakuten, Inc. Yohei Sasaki (@yssk22), Waldemar Quevedo (@wallyqs) ◯Cloud Foundryの説明 ◯Cloud Foundryの問題点 解析しようにもログが消えてしまう。。。 なので、Fluentdでログを集める仕組みを作ったよと。 これかな? https://github.com/rakutentech/dea/ ◎「Fluentdを優しく見守る監視事例」 株式会社ドリコム 外道父 ( @GedowFather ) ◯概要: Fluentdをより穏やかに安定稼働させるための監視項目と自動処理について。また,その実運用における障害例なども紹介したいと思います。 ◯目次 ◯動作環境 ・IDCもバラバラな環境のログを一箇所に集約。 グローバルなネットで、圧縮、暗号化し、VPN使ってない ・tailのプラグインを改良して利用 copy、flow counterを利用 forwardも改良 Flume OGとは比較にならないし、FlumeNGはOGと全然違うから論外だった。 ◯ローカル監視 ・monit使って監視してる。 ログを記録してるか、内容が正しいか td-agentが正しく起動してるか、Collectorに送っているか 重複起動してないかとか、起動してるかとか。 ※重複起動でログが増えてた(@mazgi濡れ衣事件) HDFSに送ってるか、保存されてるか ◯リモート監視 アラート/グラフ作成の集約 状態の可視化 Collectorのキャパシティ管理 Agentにキャパシティの心配はほぼないが、Collectorは足りなくなる可能性がある。 ◯野望 CollectorでAgentを把握したい ◯QA Q:圧縮はどうやって? A:forwardを改造してやっている。 ◎QAタイム Q:秒間どのくらい出るの? A;秒間8000メッセージくらいらしい。 Q:ハートビートの取りこぼしは? A:案1:UDPじゃなくて、TCPにする。案2:TCP接続してたらハートビートのカウントとしてしまう。 Q:CollectorのCPUに影響があるのってなに? A:ロックがCPUを食う=ロックが影響→リクエスト量を減らす Q:Windows対応はいつ?(発生源がWindows) A:td-agent-liteをWindows対応にしたいと思ってる。 Q:F#の実装とかテストは? A:性能値の測定までは行ってない。メッセージが送れたなぁくらい。 Q:設定のDSL化はv11ではなくなったの? A:ホスト名は入れたい。設定はやっぱり設定だけにしたい(プログラムは入れたくない) プラグイン側がDSL対応してればDSLできるようなものは入れようかと思ってるが、 DSLは延期したい。 A(tagomoris):DSL化したいパターンが幾つかに絞れるなぁと思ってて、それに合わせたプラグインをいくつか作ってるよー。 ◎「Fluentd \u0026amp; Treasure Data でこっそり始めるログ集計」 CROOZ 株式会社 池田 朋大( @mikeda ) ◯概要: FluentdとTreasureDataプラットフォームを使って、1インフラエンジニアが勢いでログ集計システムを作ってみたお話です ◯アクセスログ、エラーログ、メールログ(試験中)を集めてる。 ◯TreasureData 500Gまで無料なのかー。 ◯ダマで入れてもばれないぞ! ◯最後は心の目で見えるスライドでした。 ◎祝・O\u0026#39;Reilly HBase 訳本発売。訳者本人によるPR。 Sky株式会社 玉川 竜司 ※ O\u0026#39;Reillyの新刊「HBase 」 http://www.oreilly.co.jp/books/9784873115665/ ◎懇親会 そうそう、ステッカーもらったのでアンケート書きましたw ","date":1345657200,"dir":"post/2012/","id":"775894425f5a7436f56fc5a3b4a2cfaa","lang":"ja","lastmod":1345657200,"permalink":"https://blog.johtani.info/blog/2012/08/23/fluentd-meetup-in-japan--2--fluentd-%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-08-23T02:40:00+09:00","summary":"興味をもちつつ、触っていない軟弱者ですが、興味があるので今回も話を聞きに行って来ました。 まずは、作者古橋さんによるFluentdの魅力や次期","tags":["勉強会"],"title":"Fluentd meetup in Japan #2 #fluentd に参加しました。(Jugemより移植)"},{"contents":"またまた飲みに行って参加してきました。 今回は、Rails、iOSでのTwitter連携の話から、ツイート分析、クライアントアプリの開発の苦労?楽しい話と、 幅広い話題でこれまた面白かったです。\nRailsはあとで、もう一回資料+ビデオがみたいかも。あと、発表者の方が言ってたけど他の言語の似たようなサンプルがあると面白いかも。(Solr入門みたいに同じ題材で違う言語のサンプルとか)\nツイート分析は、私の使い方とは異なる分析結果がちょっと意外でした。土日はあんまりツイートしないからなぁ。 利用時間帯とかは、他のSNS(Facebookとかmixiとか)の分析と比較してみると面白いのかも。 まぁ、深夜帯はそれほど利用は無いだろうけど。\nAttaccaは自社や自宅でコーディングするときに利用させてもらってます。 どうしても自分のお気に入りのリストを作ってそれを聞くので満足しちゃうんで、 他の人のお気に入りも一緒にシャッフルして再生とかできると面白いかもなぁ。 もう少し、他にも曲を発見したいんだけど、その導線がもう少しうまく行くと嬉しいかも。\nチャーハン諸島の話は開発者の原点みたいな話で面白かった。やっぱり、自分で作るの大事だよなぁと。 作りたいと思うものがあるのはいいことだし、実際作ってみないとわからないこともいっぱいありますよねぇ。 ただ、何か作ろうかなぁと思うものがあるのはちょっとうらやましいとも思いました。 なかなかサービスとか、ほしいものを作ろうと思うところまで行かないからなぁ。年取ったのかなぁ。\n懇親会では、いつものように@twtrfkさんと喋って、あと Lytroを触らせてもらいました! 思ったよりも大きいのが第一印象。 ぱっと見で、何の変哲もないところがズームするところだったりと、インタフェースがちょっとおもしろかったです。 ピントが後から合わせられるということで、どうしても同じ構図になっちゃうのがなぁという話も聞けましたw けど、ちょっと欲しいかもなぁ。動くものを撮るとどんな感じなのかも聞くんだった。\n次回は9月中旬!らしいので、余力がありそうだったらまた遊びに行きます。\n日時:2012/08/01 19:00 ~ 21:00 場所:デジタルハリウッド東京本校 1Fセミナールーム\nいつもの自己紹介タイム\n@i7a16k(@_gifteeの中の人) スライドはこちら\n「RailsでTwitter連携アプリをサクっと作る」 ・まずは、Railsの紹介 MVC+routes.rbの紹介 ・Dev Twitterの登録する必要なとことか。 ・Railsのインストールから起動まで。 ・実際にログイン画面を作成するまでの紹介 コーディングするコマンドの紹介。動画付き omniauth_twitter ってのを使うみたい。 ・サインイン、サインアウトまで。 ツイートは次回! 録画がよくできてて、それに合わせてしゃべるのもうまいなぁ。 @teapipin(ツイッター分析シリーズ の方) スライドはこちら\n「約173万ツイートを調査して分かったTwitterの利用動向」 ・ハンドル名は午後の紅茶からきてる?+ピピン@ ・ブログで色々公開してます。 ・サービス作るのに、下調べをしてみましたというお話 情報が無かったから、自分で調べてみたよと。(すばらしい) ・Streaming APIで取得 タイムゾーンとか言語設定の取得でもうまく取れない。。。 ということで、UnicodeBlockで判定してみたけど、、、 最後は手作業で不要データを除去(すごい!) ・4日間で172万ツイート (金環日食とかスカイツリーのイベントがあったので、4日間で我慢) ・上位5個で50%を占めるクライアントみたい ・日曜日が多いらしい ・携帯が60%くらい ・位置情報(Geoタグつき) 日本が多い。4sqが40%占めてる。 店舗情報や天気情報などもあるらしい。 人口と関係した相関が散布図でわかった。 そこで、ツイート内容との関係を分析 あとで資料みたいなー @i2key(#attacca の関係者) スライドはこちら\n「iOSのTwitterFrameworkを使ってみたら・・・・」 ・Twitter4Jのほうが楽だったよー デモがいいね! ・アーキテクチャ play!をバックエンド。Amazonとか。 iOS Twitter framework ・Reverse Authの使い方とか。 申請してから、20日間かかった。 @Mocel(チャーハン諸島 開発者) スライドはこちら\n「(仮)Twitter クライアントの開発とかについて」 ・趣味プログラマー ・「ラーメン大陸」のクローン:「チャーハン諸島」を開発 Excel溶けこむGUI Javaで実装 コマンドライン風のTL画面もある(自分では使ってないけど) 「電力会社の電力使用量モニター」もクライアント初搭載! ラーメン大陸のバージョンチェックも可能w ・開発したことで 自分のニーズにジャストフィット 優しい気持ちになれる(苦労がわかる) Twitter APIのテストとかもすぐ試せる ・GUIアプリ開発のノウハウも手に入るからオススメ ・API利用規約は読んどこうね ・自動アップデート機能がいるよ。→バージョンごとのサポートがなくなるよ。 ・通信エラー前提で作りましょう ・鍵付きの非公式RTはやめなさい。 ・Twitterクライアントの作成はおもしろいよ! 反応がプレッシャーになることもあるけど。 おもしろ機能をつけるのがいいよーと 話が上手で聞きやすかった。 ","date":1343875800,"dir":"post/2012/","id":"8a29f62d1bebfe7b8008d7f264b56b4e","lang":"ja","lastmod":1343875800,"permalink":"https://blog.johtani.info/blog/2012/08/02/twitter-%E5%8B%89%E5%BC%B7%E4%BC%9A--twtr_hack-%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-08-02T11:50:00+09:00","summary":"またまた飲みに行って参加してきました。 今回は、Rails、iOSでのTwitter連携の話から、ツイート分析、クライアントアプリの開発の苦労","tags":["勉強会"],"title":"Twitter 勉強会 #twtr_hack に参加しました。(Jugemより移植)"},{"contents":"ということで、ステッカー欲しさ?に勉強中の話を恥ずかしげもなく偉そうにしゃべってきました。 #pyfesは以前から、気になっていたんですが、タイミングがあわず初の参加になりました。 TwitterのプロフィールにSenseiDBに興味あると書いていたら、@voluntusさんに声をかけていただけて、 さらになぜかelasticsearchの話をすることにして話をしてきました。 まだまだ、いろんな意味(プレゼン的にも内容的にも)で至らない所だらけだったので反省しまくりですが、 これでまた経験値が稼げたかなと。次回に活かしたいと思いますです。 やっぱり、しっかり勉強して、シナリオを練ってから発表しないとダメですね。。。\n発表のスライドは一番最後にリンクを用意しておきましたので、興味があれば見てもらえればと思います。\nということで、いつものメモを残しておきます。\n日時:日本オラクル青山センター 場所:2012/07/28 10:00 - 20:00 概要:こちらにページあり\n前半(10時から15時)はハンズオンなどをやられてました。参加せずにスライドを微調整して、他の勉強会のスライドをいじったりしてました。 以下は、15時から行われたスライドのメモになります。\n◯PyConJP の宣伝 @shomah4a(LT) 9/15-17 PythonカンファレンスJapan App Engine、Django、Sphinxなどのカンファレンスも併設 遠方参加者支援制度があるらしい。 ◯elasticsearch 入門 @johtani わかりにくい話でしたかねぇ。。。 ◯たのしいうぇっぶくろーら @tokoroten(LT) index.htmlをクロールしまくってる社畜2.0の人らしい。 ◯Sphinxを使って翻訳してたら本が出てた話 @ymotongpoo(LT) OSSでもドキュメント翻訳でお手伝いできるよ。 そしたら、いつのまにか書籍も出せたよ。 スライド\n◯iOS関連のお話 @Seasons バイナリ解析をしてゴニョゴニョする話。 解析するのに何を使ったとか思考の遷移を説明してくれるのでわかりやすい。 スライドが大きなマインドマップを切り出した形。 ◯HBaseのお話 @shiumachi HBase 分散DB 列ファミリ思考 HBaseなんで? RDB→シャーディング→だるい。。。 シャーディング→スケールできねー nandeHBase? 書き込みスケールできるよ。 KVS HBaseのデータ構造 キーがいろいろな情報を含んでる キーがソートされてる HBaseのテーブル構造 リージョンがシャーディングの情報もと? リージョン見つけなど スライド\n◯PythonではじめるGit @mkouhei GitPython LXCホスト? GitもPythonも初心者だわー ◯勉強会を成長させる参加者になろう @sawonya イラストレーター(スタートアップRubyのイラスト書いた人。サインもらいましたw)。 参加者が増えるとなにがいいの?など。 勉強会参加に向けた勉強会の講師とかやられてるらしい。 スライド\n◯IT 系勉強会ネタ(仮) @tmmkr アジャイルサムライを読んだ情報を共有したくなって読書会を開催してみた! ビアバッシュのケータリングとかは楽天デリバリーとか、カクヤスがいいよ。 かなり、いいスライドなので、あとで見返す。 今、読書会やったりしてるし、Solr勉強会の役にも立てそうだし。 スライド\n◯Do not invent your RNG... @kenji_rikitake Androidの乱数のコードがすごいらしい(ひどい) Pythonの乱数ではos.urandomを使うのが安全です。 オレオレ乱数は作っちゃ駄目! ◯分散ファイルシステム(LeoFS) @yosukehara LeoFSの開発者の方。 Erlangで98%書いてある。 Masterノードは存在しない。SPOFになるから。 分散システムとして元にした概念とか論文ってあるんだろうか? ◯継続的デリバリー @troter CIとデリバリーの話。 いいこと書いてあるんだけど、実際のツールの話しがないのが辛いこともある ということで、Python周りのツールをこうして見たよというお話。 Rubyの方がものがいろいろ揃ってるらしい ◯クライアントサイドのみで作ったダッシュボード @takufukushima RESTアクセス用のUIのフロントエンドの話? JSのお話の?node.jsとかの話。 MVCにしたり、CSSフレームワーク使ったり。 backbone.jsつかってるらしい。 実際の画面がみたいなぁ。 現状の話なので、 ◯Meinheld @mopemope Python3対応とかLoggerとかやってから秋くらいに出るみたい。 このあたりは未知の領域です。。。 ◯3分間で開発環境構築 @tk0miya Vagrant+Chefみたい。 VeeWeeってのでIOSイメージからVMイメージを作ってくれる。 (githubから持ってこないといろいろ古いらしい) これ、重要だと思う。 実践するようにしよう。 手順書がわりにChefのレシピを書こうよと。 環境マニア募集中! 継続的デリバリー座談会やってます ◯筋トレ講座 @hiroki_niinuma ジムに通い続けるのはキツイ。 成功率5% 以下の条件に ・10時間以下の仕事時間 ・ジムが近い ・ジムという環境が好き ベンチマークw先入観を捨てましょうとw ジムで筋トレとかよりも歩くのが全然いいよと。 togetterがあったのでリンク。 http://togetter.com/li/346242 http://togetter.com/li/346270\nスライドはこちら。\n** [Elasticsearch入門 pyfes 201207](http://www.slideshare.net/JunOhtani/elasticsearch-pyfes-201207) ** from **[Jun Ohtani](http://www.slideshare.net/JunOhtani)** それにしても発表するといういい機会を与えてもらえて良かったです!。 継続的にelasticsearchも調べていきたいので、興味ある人は声をかけてくださいー\n","date":1343466900,"dir":"post/2012/","id":"7fa2f0877831b4c924438396760f1841","lang":"ja","lastmod":1343466900,"permalink":"https://blog.johtani.info/blog/2012/07/28/python-developers-festa-2012-07%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%A6%E3%81%97%E3%82%83%E3%81%B9%E3%81%A3%E3%81%A6%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F--pyfes/","publishdate":"2012-07-28T18:15:00+09:00","summary":"ということで、ステッカー欲しさ?に勉強中の話を恥ずかしげもなく偉そうにしゃべってきました。 #pyfesは以前から、気になっていたんですが、タ","tags":["勉強会"],"title":"Python Developers Festa 2012.07に参加してしゃべってきました #pyfes(Jugemより移植)"},{"contents":"今日はSolr 4.0 ALPHAの興味深い機能があったので紹介です。 数日前に「Solr 4.0: Partial documents update」という記事を見つけました。\nSolrには、ドキュメント(RDBで言うレコード)のデータを更新したい場合には、特定のフィールドだけを更新するという機能がありませんでした。 ですので、特定の項目(例えば、priceなど)を更新したい場合、ドキュメントの全データをSolrに再度上書き登録するという処理をしなければなりませんでした。 RDBを触っていた方が、Solrを始めた場合に必ず使いづらいと思われる点だと思います。\nで、4.0でその機能がありますという、「Solr 4.0: Partial documents update」の記事を見つけました。 ただ、SolrのWikiや4.0 ALPHAの紹介のページには「partial update」という記述が見当たりません。 (あれ、これかな?Update semantics) あと、まだ完成していないので、載っていないのかもしれないです。(このチケットSOLR-139が部分更新に関するもののはず。チケット番号をみても古くから望まれている機能だということがわかります。)\nということで、調べてみました。\n###機能概要\nSolrの機能として、特定のフィールドのみを更新するという機能です。 あくまでも、Solrレベルでの機能となり、Luceneの機能を利用したものではありません。 つぎのような流れになっています。\nSolrに対して特定フィールドを更新したいという形のドキュメントを投げる Solrはドキュメントを受け取ると、内部のインデックスに保存してあるデータを取り出す 取り出したドキュメントオブジェクトに対して、更新対象フィールドの値だけデータを更新する ドキュメントオブジェクトをインデックスに保存する このような流れです。 まぁ、言われてみれば当たり前な処理です。 ただし、この機能を使う場合はいくつかの前提条件があります。\n###前提条件\n前提条件はつぎのとおりです。\nすべてのフィールドをstored=\u0026ldquo;true\u0026quot;にする 「version」という特殊なフィールドを用意する 1点目は、データの保存方法についてです。 先ほど流れに書きましたが、Solrが内部に保存してあるデータを取り出して、更新対象以外のデータを保存しなおしてくれます。 このため、stored=\u0026ldquo;true\u0026quot;にしておかないと、元のデータがSolr内部で取得できません。\n2点目の「version」というフィールドは4.0から導入されたフィールドです。 SolrCloudに必要な機能としてドキュメントのバージョン管理を行うために導入されたフィールドだと思います。(あまり詳しく調べていない。。。) SolrCloud内でレプリカの更新などに使ってるのかなぁと(そのうち調べます。) 以上の2点が前提条件です。すべてのデータをstored=\u0026ldquo;true\u0026quot;としなければならない点は、インデックスのサイズや性能に関わってくるので考えて利用するほうがいいかと思います。\n###利用方法\nSolrのサンプルデータ(exampledocs/mem.xml)を例として利用します。 部分更新を行うにはつぎのような形のデータを投げると部分更新が可能です。 (JSONでの更新のサンプルについては、こちらの記事を参考にしてください。) ####XMLのサンプル(partial_update.xmlというファイルで保存する)\n\u0026lt;add\u0026amp;gt; \u0026lt;doc\u0026amp;gt; \u0026lt;field name=\u0026#34;id\u0026#34;\u0026amp;gt;VS1GB400C3\u0026lt;/field\u0026amp;gt; \u0026lt;field name=\u0026#34;_version_\u0026#34;\u0026amp;gt;バージョン番号\u0026lt;/field\u0026amp;gt; \u0026lt;field name=\u0026#34;cat\u0026#34; update=\u0026#34;add\u0026#34;\u0026amp;gt;cats_and_dogs\u0026lt;/field\u0026amp;gt; \u0026lt;field name=\u0026#34;popularity\u0026#34; update=\u0026#34;inc\u0026#34;\u0026amp;gt;10\u0026lt;/field\u0026amp;gt; \u0026lt;!-- set empty for SOLR-3502 bug --\u0026amp;gt; \u0026lt;field name=\u0026#34;price_c\u0026#34; update=\u0026#34;set\u0026#34;\u0026amp;gt;0.0,USD\u0026lt;/field\u0026amp;gt; \u0026lt;/doc\u0026amp;gt; \u0026lt;/add\u0026amp;gt; 上記サンプルのうち、バージョン番号の部分は、現在Solrに登録してある値を指定します。(Solrの管理画面で検索すれば表示されます。) 上記ファイルを「SOLR_HOME/example/exampledocs」に保存し、同フォルダにてつぎのコマンドを実行すると、部分更新されるのがわかります。 Solrに更新であるというフィールドがわかるように、fieldタグにupdateという属性を指定してあります。\njava -Durl=http://localhost:8983/solr/update?versions=on -Dout=yes -jar post.jar partial_update.xml ちなみに、上記post.jarのオプションで、「-Durl」「-Dout」を追加してあります。 「-Durl」はverions=onというパラメータを追加したいためです。 「-Dout」はPOSTした結果をターミナルに表示するために追加しています。 これらのオプションを指定すると、データ更新後のバージョンが取得できるようになります。\n####更新に利用できるコマンド? 部分更新にはつぎの3つのコマンド?(正式名は不明)が用意されています。fieldタグのupdate属性に指定します。\nコマンド? 説明 add 値を追加します。multiValuedのフィールドでない場合はエラーが出ます。 set 値を新規に登録しなおします。現在入っているデータは無くなります inc 指定された数値を加算(数値形式のみ) 以上が、部分更新の機能になります。 ちなみに、登録されているバージョンと更新データに入っているバージョンが異なる場合はエラーが発生する仕組みになっているようです。 それとは別に、この機能を調べていて、copyFieldのバグにぶつかってしまいました。。。 multiValuedでない、copyFieldを利用しているしている場合には注意が必要です。\n###copyFieldのバグ(SOLR-3502)\n4.0-ALPHA(3.6.0でも再現しました。)のexampleのデータで部分更新の機能を確認できると言いました。 ただし、「price_c」というフィールドのせいで、2回部分更新を行うと2回目にエラーが発生します。 根本的な問題は、部分更新ではなくcopyFieldのバグのようです。(部分更新の処理にも問題は有るような気がしますが。。。)\nバグの内容はつぎのとおりです。\nmultiValued=\u0026ldquo;false\u0026quot;のフィールドをdestに指定 srcに指定されたフィールドに値を設定(exampleのpriceフィールドに「1」を指定) destに指定されたフィールドに値を設定(exampleのprice_cフィールドに「2,USD」を指定) 上記のように設定した場合、「price_c」フィールドに、指定された値+「price」の値がcopyにより追加されます。 通常は「price_c」フィールドはmultiValued=\u0026ldquo;false\u0026quot;なのでエラーが出るはずなのですが、エラーが発生せず2つの値が登録されてしまいます。\nこのバグのため、exampleのデータを利用して部分更新を行うとつぎのような状態が発生します。 更新を行う対象のデータはprice、price_cフィールド以外のフィールドとします。\n1回目の登録後:priceフィールド「\u0026ldquo;185.0\u0026rdquo;」、price_cフィールド「\u0026ldquo;185.0,USD\u0026rdquo;」 2回目の登録後:priceフィールド「\u0026ldquo;185.0\u0026rdquo;」、price_cフィールド「[\u0026ldquo;185.0,USD\u0026rdquo;,\u0026ldquo;185.0,USD\u0026rdquo;]」 3回目の登録:エラーが発生 部分更新の処理で、すでに登録済みのデータをSolrが自動で取り出すため、2回目の登録処理にて「price_c」の登録済みの値がSolrから取り出され、さらにcopyField設定により、「price」の値が追加されます。 本当は2回目の登録でエラーが発生すべきなのですが、バグのためエラーが発生せずに登録できてしまいます。 部分更新の処理としては、copyフィールドのdestに指定されているフィールドの値を取り出さないほうがいいような気もしますが、きちんと考えてないのでなんとも言えないです。(制約事項とする形のほうがいいかもしれません)\n","date":1342177320,"dir":"post/2012/","id":"68a8f34c240a42ab521d2f885f7aa33c","lang":"ja","lastmod":1342177320,"permalink":"https://blog.johtani.info/blog/2012/07/13/partial-update%E3%81%A8copyfield%E3%81%AE%E3%83%90%E3%82%B0solr-4-0-alpha/","publishdate":"2012-07-13T20:02:00+09:00","summary":"今日はSolr 4.0 ALPHAの興味深い機能があったので紹介です。 数日前に「Solr 4.0: Partial documents update」という記事を見つけました。 Solrには、","tags":["solr"],"title":"Partial UpdateとcopyFieldのバグ【Solr 4.0 ALPHA】(Jugemより移植)"},{"contents":" Modern Information Retrieval: The Concepts and Technology behind Search (2nd Edition) (ACM Press Books) いやぁ、蒸し暑くてなかなか寝れない日がはじまりましたね。(あんまり関係ないですね。。。)\nModern Information Retrieval 2nd Editionを輪読会という形で読み始めました。 Solrに関わって数年ですが、昔から検索をやっていたわけではありません。 なので、そろそろ基礎的、理論的なところも勉強して行かないとなと思い、この本を買いました。 ただ、約1000ページある英語の本でして。。。 一人で読むと間違いなく挫折するし、理解不能になりそうだなと。。。\nということで、Twitterで呟いたら賛同してくれる方が現れ、輪読会を開催することにしました。 イベントの開催とか初めてなので、手さぐりしながらです。(それにしても、ほんと、Twitterは素晴らしい。賛同してもらえる人が見つかったのもTwitterのおかげだし。)\nさすがに細かく読んでいくと終わらなそうなので、1周目(できれば、2周目もやりたいなぁと思ってる。1週目が1年でも終わりそうにない感じだけど)は公開されているスライドを元に進めようと思ってます。 それにしても検索周りはいろんな技術が必要なのだなぁと分厚い書籍を見て、途方に暮れつつ、楽しみでもあるなと思いながら、輪読会後の飲みを楽しんでましたw\nということで、各分野の専門家もいそうなので、特別ゲストとして読んできて話に混ざってもらうのも面白いかもと夢想しつつブログを書いています。 だれかいないかなーw\n参考URL: 書籍のHPで公開されているスライドのページです。 http://grupoweb.upf.es/WRG/mir2ed/contents.php\n","date":1342111298,"dir":"post/2012/","id":"9ac7bb94e60dc30a023ce433de027364","lang":"ja","lastmod":1342111298,"permalink":"https://blog.johtani.info/blog/2012/07/13/mir%E8%BC%AA%E8%AA%AD%E4%BC%9A%E5%A7%8B%E3%82%81%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-07-13T01:41:38+09:00","summary":"Modern Information Retrieval: The Concepts and Technology behind Search (2nd Edition) (ACM Press Books) いやぁ、蒸し暑くてなかなか寝れない日がはじまりましたね。(あんまり関係ないですね。。。) Modern Information Retrieval 2nd Editionを","tags":["勉強会"],"title":"MIR輪読会始めました(Jugemより移植)"},{"contents":"Lucene/Solrの4.0.0-ALPHAが7/3にリリースされました。\nこれに伴い、lucene-goenの4xブランチのjarファイルも4.0-ALPHAのものに置き換え、現在のtrunkの修正もマージしました。 こちらにあります。チェックアウトしてビルドしてから利用してください。\n※さすがに、jarをダウンロードできるようにすべきかもなぁ。 あと、Maven登録も。。。\n","date":1341457909,"dir":"post/2012/","id":"dcc2e24df32287e89ee3b0f64d617f57","lang":"ja","lastmod":1341457909,"permalink":"https://blog.johtani.info/blog/2012/07/05/lucene-gosen%E3%81%AElucene-solr4-0-alpha%E5%AF%BE%E5%BF%9C/","publishdate":"2012-07-05T12:11:49+09:00","summary":"Lucene/Solrの4.0.0-ALPHAが7/3にリリースされました。 これに伴い、lucene-goenの4xブランチのjarファイル","tags":["lucene-gosen"],"title":"lucene-gosenのLucene/Solr4.0-ALPHA対応(Jugemより移植)"},{"contents":"またまた参加しました。いまだ皆勤賞です。 感想などはあとで。とりあえず、メモとったので第一弾です。\nということで、感想です。 まずは、参加人数。 今回は今までで一番、ATND登録した人が多かったんじゃないかなぁと。 埋まるのも早かったですし。やっとSolrというキーワードが多くの方に触れられるようになってきたんですかねぇ。\nmixiの事例はやはり、SSDを使った11億文書のインデックスが圧巻です。 実際にマイニングに利用していて、ネガポジ分析なども行われているようで楽しそう。 TLにもありましたが、「ヤバイ」はネガ?ポジ?など、そのへんの分析方法をもう少し詳しく聞いてみたい感じもしました。 あとは、Luceneソースコードリーディングの開催が楽しみです!(候補日知らせないと。。。)\nLucene Revolution 2012の参加レポートは、自己紹介がおもしろかったですw ずっと検索をやらてているのもあり、色々と理論ではなく、実践的なノウハウを持っていそうで、つぎはそのあたりの話を聞いてみるのも面白そうです(発表してくれないかなーw) 残念ながら、私はまだスライドを見ていないので、事例を中心にピックアップして見てみようかなぁと(時間がトレない。。。)\n最後は阿部さんの4.0の紹介です。タイムリーに、前日に4.0-ALPHAがリリースされたので、 資料がすごく参考になりそうです。 SolrCloudについても詳しく書かれてたし。(ちゃんと動くのかなぁ?)\n最後は懇親会です。最近知り合った方から、発表者、昔からの勉強会の参加者といろいろな方と今回も話ができて楽しかったです。 TL上で知り合った方にもお会いできたし。 次回もしゃべってもらえそうな人を捕まえつつあるので、また企画してもらうようにつついてみようかな。\n※そういえば、毎度のことながら4.0ベースで、書籍は出さないのかって言われましたw\n※ちなみに、4.0-ALPHAが出たので、lucene-gosenも4xブランチの更新作業をしています。 終わったらまたブログに書くと思います。\n第8回Solr勉強会 場所:VOYAGE GROUP 会議室 日時:7/4(水) 19:00 ~ 1. @haruyamaさん mixi での Solr の利用 ・mixiの全文検索 2011年以前:Hyper Etraier、Tokyo Dystopia、Senna 2011年以降:Solrを利用して新規案件の検索システムの構築、入れ替えを行なっている。 ・Anuenueの論理構成など。 ・物理構成 1マスター、2スレーブ インデックスが小さい、QPSが100以下 インデックスサイズが大きいものは今後構築予定 ・今後やりたいこと ・ログ分析 ・パーソナライズ ・外部ストレージ参照のカスタム関数 ・外部ストレージをファンクションカスタム関数クエリ FunctionQueryを活用したい。 ・上記のデモ(検討中のもの?) 現在はjar内部のファイルを読んでるよと。 速度的な面がどうなるかがきになるところ。 ・テキストマイニング mixiボイス haruyamaさん入社前:ダンプして解析してた haruyamaさん入社後:Solrに載せちゃえば 600GのSSD 約11億文書 約450GB 利用してるもの:Solr 4.0(2012/01) lucene-gosen 1.2.1 自作フィルタ haruyama/solr-filter - GitHub ・利用統計の説明。 女性が多い。 「AKB」だと20代前半が多い。男性はおっさんも頑張ってる。 ・mergeindex機能を利用して、過去データとマージしてる。 1日分だけ集計したいこともあるかもしれないから。 updateじゃなくて、mergeindexなのは、ソッチのほうが早かったから。 ・拡張してる分析 ・ポジネガ分析 形容詞>絵文字>顔文字でスコアが効く 機械学習して辞書を調整してる ・Luceneソースコードリーディングまたやりますよ! 2. 楽天株式会社 大須賀 稔さん Lucene Revolution 2012 in Boston参加レポート(仮) ・まずは自己紹介。 infoseekに転職→楽天→Ask.com→楽天(そして英語) ・Lucene Revolutionってなに? ・トレーニング Scaling Search with Big Data \u0026amp; Solr Hadoopの紹介 SolrとHadoopのMapReduceを利用したインデキシングのハンズオン Solrのスケーリング(Sharding、Replication)、マルチテナント ※http://www.lucidimagination.com/services/training/big-data-training-scaling-solr 日本ではやってない、残念。 ・カンファレンス スライドとかはlucidimaginationのサイトで見れるよと。 http://www.lucidimagination.com/devzone/events/conferences/lucene-revolution-2012 ・Lucidworks Big Dataの紹介 Hadoopとかいろいろ組み合わせて使えるよと ・Microsoftの人がAzureでSolrの紹介 IEとかWindows8の話ばっかり。 ・Kuromojiの紹介 やはり、マイノリティ。 内容は日本語勉強会w 中国語とかは対応するの?日本語しか知らないです。。。 ・ErickさんのSolrCloudの話 4.0は2012年にリリースする予定 スコアリングをプラガブルに。 管理系画面がリッチだよと。 ・一番重要だなぁと思ったのは。。。 「英語」!(会社的な感想ではありません。。。) Q:これはみとけ的なスライドは? A:Hadoop上でインデキシングして、ビットトレントとかで連携してるという例が面白かった。 Q:FASTとかと比べてSolrってどーなの? A:ESPは洗練されてる。クローラーとか、ベイシスのトークナイザーを内包してるとか。 Solrは言語処理系が弱かったとかあるけど、そろってきてるのでは。 4.0は互角になるんじゃないかなぁ。 ESPがWindowsオンリーになるので、LinuxユーザがSolrに行きつつある。 3. 株式会社 ロンウイット 阿部さん Solr 4.0の紹介 ・Solr 4.0の主な機能の紹介 3.xは3.6が最後4.0-ALPHAが7/3に出た ・プラガブルなスコアリング BM25、Language Models、Divergence from Randomness、Information-based Models 関口さんがスライド作ってる ・FST対応 Finite State Automata/Transducer オートマトン理論を活用したもの。 TokenStreamはFSAで実装 SynonymFilterがFSTになると、オフセットが変わってくるらしいと。 ・Codecプラグイン Luceneレベルのお話。 ドキュメントをファイルに保存するときの形式をプラガブルに変更可能。 SimpleTextなどもあるらしい。テストに利用できそう。 APIレベルで、マイグレーションの必要があるかも。 ・NRT Near Real Time Search softCommitのお話 Realtime-get:IDを入れたらGETできるよと。 KVSとしても活用できるぞ~と。 ・PivotFacet Facetが階層的(?)な感じで取れる ・JOIN、pseudo-join ローカルパラメータでできるよーと。 ・SolrCloud インデックスの分散配置をやってくれる(3.6まではやってくれない) shardがダウンしたらフェイルオーバーしてくれそう Master/Slave環境 リアルタイムインデクシングとリアルタイム検索とか ・ZooKeeperIntegration実装 リーダー選出、コンフィグの管理などなど ・ManifoldCFの近況 5月にトップレベルに昇格! http://manifoldcf.apache.org/ja_JP/index.html 0.6は7月に出そう。日本語にもなってる。すげー Alfresco Connector、ElasticSearch Connectorなども Solr Plugin for Enterprise Searchとか ","date":1341402000,"dir":"post/2012/","id":"8acc78be63e27e938ee53ec2c0b90c61","lang":"ja","lastmod":1341402000,"permalink":"https://blog.johtani.info/blog/2012/07/04/solr%E5%8B%89%E5%BC%B7%E4%BC%9A%E7%AC%AC8%E5%9B%9E%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F--solrjp/","publishdate":"2012-07-04T20:40:00+09:00","summary":"またまた参加しました。いまだ皆勤賞です。 感想などはあとで。とりあえず、メモとったので第一弾です。 ということで、感想です。 まずは、参加人数。 今","tags":["勉強会"],"title":"Solr勉強会第8回に参加しました。 #SolrJP(Jugemより移植)"},{"contents":"Hadoopからはちょっと離れているのに、面白そうなネタなので参加しました。 Data Science Summit、HBaseCon、Hadoop Summitのイベント参加レポートです。\n最初の草薙さんの発表が実は一番興味を惹かれていたので、参加しました。 データの解析に関するサミットというのはなかなか聞いたことが無いのでどんな内容なのかなぁと。 ちょうどVisualizeなどに興味を持っていたり、データ解析、今後重要ですよねという話が出ていたりしていたので。 実際にデータ解析が今後重要で、どんなことに使えるのかなど、製品に偏らない内容のようで色々とためになりました。 この内容をずっと聞くのは私には無理ですw英語も数学もイマイチなので、ついていけない自信がありますw。 「データ分析の結果をビジネスに結び付けられる人とかが今後重要になります」という話が一番気になったキーワードでした。\nHBaseConもかなり濃い内容だったようです。 私は残念ながら、HBaseの概要の概要くらいしか知らないので、内容にはついていけてないですが。。。 Facebookがかなり活用しているようですが、残念ながらスライドが上がっていないようです。 Solrに関連する話もあったようです。HBaseとSolrを組み合わせたLilyプロジェクトに関連する話のようでした。 スライドは登録しないと見れないみたいです。\n最後はHadoop Summitの参加レポートです。 まずは、ユーザ寄りの内容を@muddydixonさんから。個人的に、Twitterの話が多いのかなぁと。 ここでも、Visualizeの話が出ていたとか。 Lucidの話もあったようです。LucidWorks BigDataの話かな?\n最後は@shiumachiさんのHadoopのプロダクト寄りのお話。 YARN(Map/Reduce2.0?)やHBaseの今後の展望など。YARNはキーワードだけ知っていたので、わかりやすい解説で、やっと理解できました。 全体を通して、HBaseが今後もっといろんな局面で使われそうだなぁと。日本語の本も7/24に出るし。(まだページが無いみたいなので、英語のほうを。)\nいつものごとく、途中でビールが入ったので後半はメモが適当ですが、楽しかったです。皆さんお疲れ様でした。\n帰り着いたら、さっそくスライドが上がってました。すごい! スライドはこちら(2012/06/26 0時現在)\nData Science Summit / EMC Worldレポート HBaseCon 2012 参加レポート』の発表スライドをアップしました。(NTTデータ 猿田 @raspberry1123 /岩崎) @muddydixonさんのHadoopSummit2012参加レポート @shiumachiさんのHadoopSummit2012参加レポート @muddydixonさんのブログ いろんなキーワード、特に、データサイエンス寄りの話が面白かったです。 次回はJenkins関連のようで、7/30開催みたいです。\n以下はいつものメモです。\n日 時: 2012年6月25日(月) 19:00~21:00 (受付開始 18:40) 場 所: 豊洲センタービルアネックス(NTTデータ、豊洲駅直通) ◯ Data Science Summit / EMC World レポート (EMC Japan 草薙) ・Data Science Summitのレポート 揃ってるようで揃ってないスロットの写真w EMC World2012と併設 今回2回目。 ・OpeningKeynote: What We Can Predict About Prediction by Nate Silver 研究者は不確実性やリスクを包含した、現実的な予測モデルを開発すべき いろいろ ・Roundtable: Economic, Political, \u0026amp; Societal Roles of Social Data ユーザの「query-like intent」を自然言語解析と機械学習で捉える 属性だけじゃなく、活動を コンテンツからコンテキストへ、コンバージョンからカンバセーション ・Big Data Transformation - HealthMap ウィルスのアウトブレイクの検知(160日→20日)に。 ウィルス=コンピュータじゃない方 ・Big Data Transformation - Intuit int.com? データがあるから、こういうことが知りたいなどの新しいプロセスが 「https://www.mint.com/」 ・Big Data Transformation - InfoMotion Sports Technologies バスケのボールにセンサーつけて、試合や選手の解析に利用して、 チームが強くなったりしてるらしい。 ・Big Data Transformation - Decide.com アメリカ?の価格比較サイト ソーシャルデータを元に、買い時、売り時を予測して教えてくれる。 もうすぐ新しいモデル出るかもよ?などの噂を利用してる。 ・Analytics Maturity: Master or Novice? 2010年のアメリカの教育事情のレポート データサイエンス系の統計とかがもっと必要なんじゃないか。 ・Keynote: Navigating the Road from Business Intelligence to Data science Piyanka Jain BIの限界とか、データサイエンスの恩恵を受け入れるのに必要なもの?など システムじゃなくて、人やスキルに投資しましょう。 データ分析の結果をビジネスに結び付けられる人とか。 Panel: From Raw Data とValue Data プライバシー問題 データ品質の問題 異常値を除外するなと。最も興味深いデータになることもある。 \u0026#34;Data exhaust\u0026#34;の問題 個人が日々インターネット上で行う様々なインタラクションに関するデータの集合 相関と因果関係の区別が大変難しい。 Panel: Tapping Into the Pulse of the Data Science movement ストーリを持ってデータを語れるのが重要。 Keynote: Data Visualizeation at the Point of Influence by Adam Bly Closing Keynote: The Promise and Peril in the Human / Technology Relationship by Jonathan Harris TEDで有名な人 まとめ アメリカはこの分野での投資は回り始めている. http://www.greenplum.com/datasciencesummit/ ◯ HBaseCon レポート (NTTデータ 猿田/岩崎) ・GeneralSession HBaseの開発に参加してね。 ・レプリケーション、セキュリティ、セカンダリインデックス、スナップショット、バックアップなど特に貢献して欲しいと。 ・HBaseによりカバーできるアプリケーション領域 メッセージング、位置ベースアプリケーション、リアルタイムレコメンデーション、広告最適化 ・開発者への要望 メッセージをちゃんとして 解析用メトリクス 管理ツール ・M/Rジョブとの連携の改善 ・自動チューニングなど ・Applications ・GAPの事例 色々試してHBaseにした。 クラスタ構成、16Slave、3Master、NN Failover via NFS ※ZKはスレーブに置くと、アウト。 ・Tumblr 最初は失敗した。 OpenTSDBを経験して、Motherboy V1に。 テストフェーズまでが目的 →幾つかの知見が得られたよーと。 Motherboy V2を構築中。 ・Facebook ひと月250TBペースで増加中。。。 なんで、HBaseにしたの? 低レイテンシ、水平スケール、一貫性重視の設計、M/Rとの親和性とか Schema V1=Snapshot Schema Schema V2=Split Snapshot Schema Schema V3=Hybrid Schema HBaseのデータにさらにインデックス作ったりとか。 Schema Vertion Current=Finer grained schema and Indexer 読み書きの単位を分析して、スキーマを分割して細かくして行っていた。 ・Operations ・HBaseで困ったよ at Facebook ・リージョンサーバに特定データ入れると連鎖的に死亡 ・サーバが死に切らないとか。 ・HBaseは落ちるときは落ちるので、しぶとく生き残れるアプリを作ってねと。 ※Facebook関連のスライドなどがあがってませんと。 ・HBaseバックアップについて Clouderaの人とFacebookの人 ・選択肢 DistCP /hbaseディレクトリまるごとコピー。一貫性が保証されない exportツール MRジョブ。1度に1つのテーブルのみ copytableツール データを別クラスタに保存 exportツールに似てる。 レプリケーション 。。。 アプリケーションから複数クラスタへの書き込み 。。。 ・ユースケース ・HBASE-5509を利用したバックアップ ・開発中バックアップ HBASE-6055スナップショット、HBASE-4618など ・Development ・HBase Schema Design Salesforce.comの人 非正規化でやりなさいと。Joinはおすすめしないと 最後にデザインパターンが載ってると。 0.行キーの設計がすべて 1.Design for the questions, not the answers. 2.データサイズは2種類しかない。大きすぎるか、そうじゃないか。 3.コンパクトに詰め込め 4.行単位の原子性を活用する。 5.属性は行キー内に移動することができる。(Lars Georgeがfoldingと読んでいる手法) 6.エンティティをネストさせると、データを事前に集計できる。 ・HBase Performance Tuning And Organizations Facebookの中の人 テーブルの事前スプリット オフピーク時間を設定する。(0.94で入った) コンパクション設定が効いてくるよ ・SolrのバックエンドにHBase??? ◯ Hadoop Summit レポート (@muddydixonさん) ・オープニングビデオは必見 ・ショーケース ・Datameerを注目した。Visualizationの専任チームがいる。 UIじゃなくて、解析部隊だけで60名 お値打価格。$2900/年 ・Azure Big Data JavaScriptで ・ショーケースLucid Solr、HBaseとかいろいろ組み合わせて。 ・Session Hadoop... 2015までにApache Hadoopに世界のデータの半分が乗るらしいと。 ・Session Realtime analytics with Storm and Hadoop フォロワのフォロワをunique処理したり。 ・Session Scalding Twitter\u0026#39;s new DSL for Hadoop ※Zipkinにも出てきたな、名前。 ・Hadoop Plugin for MongoDB ・Hadoop and Vertica The Data Analytics Platform at Twitter Twitter社でのHadoop周りのデータフローとか。 Verticaは速度がいるものの処理に利用 80-100TB/dayとか。。。 ・Keynotes ・Big data analyzing system is censor of company. ・It is difficult in blind and deaf. ・Session Large Scale Search, Discovery and Analytics with Hadoop, Mahout and Solr ※@muddydixonさんのブログにセッションに対応するスライドのリンクを公開中。http://d.hatena.ne.jp/muddydixon/20120617/1339919125 ◯Hadoop Summit レポート (@shiumachiさん) ・Hadoop1.x MapReduce 非常に安定 ・課題。。。 ・YARN(Yet Another Resource Negociator) ターゲット:6000~10000ノード 100,000以上のタスクの同時実行 10,000ジョブの同時実行 性能は倍以上 Q:これは同じプログラムを動かして? A:。。。倍以上です!(わかんないっす。) 今後の予定 幾つかのJIRAの紹介 MAPREDUCE-4327とかHBASE-4329とか まとめ YARNは「汎用」分散処理基盤に向けて一歩踏み出したもの! 更なる進化に注目と ・HBaseの可用性とリペア ダウンタイムを短くしよう。 障害停止7割くらい。 設定ミスが44% 不安定な機能は使うな、推奨構成を推奨! HBase 0.92+Hadoop 2.0 HDFS HAによる高可用性とか 将来:HBase 0.96+Hadoop 2.x 計画停止時間削減:オンラインスキーマ変更(HBASE-1730) ローリングアップデート:バージョン間互換性が必須 HBase本読みなさい。 金があれば、サポート買ってください。 日本語HBaseトレーニング開催予定(来月) ・HBase NameNode HighAvailability ``` ","date":1340642460,"dir":"post/2012/","id":"9f29c6d9719fc6bc09a2981057642b69","lang":"ja","lastmod":1340642460,"permalink":"https://blog.johtani.info/blog/2012/06/26/hadoop%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89%E3%83%AA%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0%E7%AC%AC10%E5%9B%9E%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-hadoopreading/","publishdate":"2012-06-26T01:41:00+09:00","summary":"Hadoopからはちょっと離れているのに、面白そうなネタなので参加しました。 Data Science Summit、HBaseCon、Hadoop Summitのイ","title":"Hadoopソースコードリーディング第10回に参加しました。#hadoopreading(Jugemより移植)"},{"contents":"Issue 32で上がってきたlucee-gosenのUniDic対応の最初のパッチを書いたので、ブログに残しておきます。\n###UniDicとは___ UniDicとは、日本語テキストを単語に分割し,形態論情報を付与するための電子化辞書です。 UniDicの詳細や特長についてはHPを御覧ください。\n残念ながら、UniDicは利用者登録をして、利用規約に従うと利用が可能となります。 ですので、lucene-gosenでは、Ipadicやnaist-chasenの辞書とは異なり自動で辞書をダウンロードする機能はありません。\n###利用手順___ 以下が、Unidicの辞書を利用したjarファイルの作成方法となります。\n1. lucene-gosenをダウンロードし、パッチを当てる lucene-gosenのリポジトリからソースをエクスポートし、パッチをダウンロードし、パッチを適用します。 コマンドは以下のとおりです。\nsvn co . lucene-gosen-trunk-readonly cd lucene-gosen-trunk-readonly patch -p0 \u0026amp;gt; ...patch (パッチに関しては今後正式版をリリースされたら手順からは必要なくなります。)\n2. Unidic辞書生成のためのディレクトリを作成「$GOSEN_HOME/dictionary/unidic」\nmkdir dictionary/unidic 3. 対象となるUnidicの辞書のソースファイルをダウンロード 利用者登録をし、利用規約に同意の上、以下のファイルをダウンロードします。 「/」に添ってダウンロードページから遷移してダウンロードしてください。\n1.3.12個別ファイル/unidic-chasen/unidic-chasen1312src.tar.gz 4. ダウンロードしたtar.gzファイルを「dictionary/unidic/」にコピー\ncp .. lucene-gosen-trunk-readonly/dictionary/unidic/ 5. Antを実行してjarファイルの作成\nant -Ddictype=unidic 成功すれば、lucene-gosen-trunk-readonly/dist/lucene-gosen-2.1-dev-unidic.jarファイルが生成されます。 あとは、通常通り、SolrやLuceneで利用することが可能です。\n以上がjarファイルの作成手順となります。\n###制約事項(2012/06/18現在)___ 現在(2012/06/18)時点で公開しているパッチは、以下の制約が存在します。\nCOMPOUNDエントリー未対応 品詞情報(発音)の内容の制限 COMPOUNDエントリー未対応 Unidicの辞書のエントリーの中に1件だけ、COMPOUNDと呼ばれるエントリーが1件だけ存在します。 別々の単語を組み合わせて1単語として扱うことができるようになっているようです。 lucene-gosenでは、残念ながら、このような辞書の形式には対応していません。 1件しか存在しないデータでもあることを鑑みて、今回の辞書構築処理では、スキップするようにしました。\n品詞情報(発音)の内容の制限 lucene-gosenの実装上、単語の読みのバリエーション数と発音のバリエーション数には以下の制限が存在します。\n「読み」バリエーション数 < 「発音」バリエーション数 「読み」に対応する形で、「発音」がlucene-gosenでは品詞情報としてデータ登録されています。 UniDicのデータには上記制約を満たさないデータが5件ほど存在します。 現在、これら5件のデータについて、「読み」に対応した「発音」データには空文字が表示されるようになっています。\nまだ、簡単に動作確認をしただけです。UniDicを利用していて問題など有りましたら連絡、Issueへのアップをしていただけると助かります。\n","date":1340028180,"dir":"post/2012/","id":"d13aa56e27fe71ef40ff153c093ecdf8","lang":"ja","lastmod":1340028180,"permalink":"https://blog.johtani.info/blog/2012/06/18/lucene-gosen%E3%81%AEunidic%E5%AF%BE%E5%BF%9C/","publishdate":"2012-06-18T23:03:00+09:00","summary":"Issue 32で上がってきたlucee-gosenのUniDic対応の最初のパッチを書いたので、ブログに残しておきます。 ###UniDicとは___","tags":["lucene-gosen"],"title":"lucene-gosenのUniDic対応(Jugemより移植)"},{"contents":"「鉄は熱いうちに打て」ということで、残りも勢いでメモ。 まだ、見直しとかしてない状態なのでおかしいところとかありますが。。。 図とか入れるのはまた今度。\nTransport(転送)\nZipkinとHadoopに異なるサービスからのトレースを送信するのにScribeを利用します。 ScribeはFacebookにより開発されました。 システムの各サーバで実行できるデーモンとして作成されています。 ログメッセージをListenし、カテゴリごとのcorrectレシーバーに配送します。 Zipkin collector daemon\nトレースデータがZipkinコレクターデーモンに配送されたらvalidかどうかをチェックしてから保管し、インデックスを作成します。 Storage\nストレージにはCassandraを選びました。 スケーラブルで、柔軟なスキーマをもっており、Twitter内部で大変使われています。 このコンポーネントをプラガブルにしようと試みましたが、困難なため、ここでは公開しません。 Zipkin query daemon\n保存、インデックスされたデータを探す方法が必要です。 クエリーデーモンはユーザに対して簡単なThriftAPIを公開しており、トレースを探すことが可能です。Thrift fileを見て下さい。\nUI\n多くのユーザはUI経由でデータにアクセスします。 VisualizeにD3を利用したRailsアプリケーションです。 UIの認証は実装していないことに注意してください。\nモジュール Zipkin内部のモジュール関連図\n##インストール___ Cassandra\nZipkinはCassandraをストレージにしています。Cassandraクラスタが必要になります。 1. Cassandraサイトを参考にしてクラスタを構築してください。 2. Zipkin Cassandraスキーマを利用します。つぎのコマンドでスキーマが作成できます。 bin/cassandra-cli -host localhost -port 9160 -f zipkin-server/src/schema/cassandra-schema.txt Zookeeper\nZipkinは協調のためにZooKeeperを利用します。 これは、保存すべきサーバをサンプルレートで決定し、サーバを登録します。? 1. ZooKeeperのサイトを参考にインストールしてください。 Scribe\nScribeはトレースデータを配送するのに利用するロギングフレームワークです。 ネットワーク保存先としてZipkinコレクターデーモンを指定する必要があります。 Scribeの設定は次のようにします。 \u0026lt;store\u0026amp;gt; category=zipkin type=network remote_host=zk://zookeeper-hostname:2181/scribe/zipkin remote_port=9410 use_conn_pool=yes default_max_msg_before_reconnect=50000 allowable_delta_before_reconnect=12500 must_succeed=no \u0026lt;/store\u0026amp;gt; 注意:上記設定は、カテゴリーにより送信ホストを見つけるためにZooKeeperを利用するサポートのScribeのTwitterバージョンを使用する方法です。 コレクターのためのDNSエントリーを利用したりもできます。 Zipkinサーバ ZipkinサーバはScala 2.9.1、SBT 0.11.2そしてJDK6で開発しました。\n1. git clone https://github.com/twitter/zipkin.git 2. cd zipkin 3. cp zipkin-scribe/config/collector-dev.scala zipkin-scribe/config/collector-prod.scala 4. cp zipkin-server/config/query-dev.scala zipkin-server/config/query-prod.scala 5. Modify the configs above as needed. Pay particular attention to ZooKeeper and Cassandra server entries. 6. bin/sbt update package-dist (This downloads SBT 0.11.2 if it doesn\u0026#39;t already exist) 7. scp dist/zipkin*.zip [server] 8. ssh [server] 9. unzip zipkin*.zip 10. mkdir -p /var/log/zipkin 11. zipkin-scribe/scripts/collector.sh -f zipkin-scribe/config/collector-prod.scala 12. zipkin-server/scripts/query.sh -f zipkin-server/config/query-prod.scala SBTでコレクターとクエリサービスを起動します。 Scribeコレクターサービスの起動方法は次の通り。 bin/sbt \u0026#39;project zipkin-scribe\u0026#39; \u0026#39;run -f zipkin-scribe/config/collector-dev.scala\u0026#39; クエリサービスは次の通り bin/sbt \u0026#39;project zipkin-server\u0026#39; \u0026#39;run -f zipkin-server/config/query-dev.scala\u0026#39; Zipkin UI\nUIはRails3アプリです。 1. 設定をZooKeeperサーバでアップデートします。これはクエリデーモンを見つけるのに利用します。 2. Rails3アプリケーションサーバにデプロイします。テストの場合は次のようにすることもできます。 bundle install \u0026amp;amp;\u0026amp;amp; bundle exec rails server. zipkin-tracer gem\nzipkin-tracer gemをトレースしたいRailsアプリケーションにRack Handlerで追加します。 config.ruにつぎの記載をします。 use ZipkinTracer::RackHandler run \u0026lt;YOUR_APPLICATION\u0026gt; もし、アプリケーションのstatic assetsがRailsで提供されれば、リクエストがトレースされます。 ## Running a Hadoop job\nScribeからHadoopにログを保存する設定をすることも可能です。 これをすると、Zipkin自身でオンザフライで簡単に作れないデータから様々なレポートが作成可能です。 ScalaでHadoopのジョブをかけるScaldingというライブラリを利用します。\n``` 1. Hadoopジョブを実行するためのfatなjarを作成します。 2. scald.rbをjarをコピーしたいホスト名とjobを実行するホスト名に書き換えます。 3. 必要なら、scald.rbのjarファイルのバージョンを更新します。 4. scald.rbスクリプトを利用してジョブを実行できます。\n./scald.rb \u0026ndash;hdfs com.twitter.zipkin.hadoop.[classname] \u0026ndash;date yyyy-mm-ddThh:mm yyyy-mm-ddThh:mm \u0026ndash;output [dir]\n##計測ライブラリの利用方法\u0026lt;hr\u0026gt; 計測のためのライブラリとプロトコルがちょっとだけあります。 しかし、もっと計測するための役に立つものを望んでいます。 開始する前にトレースデータがどんな構造なのかを知る必要があります。\n・Annotation - 値、タイムスタンプ、ホストを含みます。 ・Span - 特定のRPCに相当するAnnotationの集合 ・Trace - あるルートSpanにぶら下がるSpanの集合\nZipkinに送信するトレースデータです。\nこれらの詳細な記述は[こちら](https://github.com/twitter/zipkin/blob/master/zipkin-thrift/src/main/thrift/zipkinCore.thrift)を見て下さい。 その他にトレースデータの重要なものは、トレースされたサービス間でやり取りされる情報である、軽量なヘッダーです。 トレースヘッダは次のものから構成されます。\n・Trace Id - トレース全体のID ・Span Id - 個々のリクエストのID ・Optional Parent Span Id - このリクエストが他のリクエストの一部として生成されたら付与される ・Sampled boolean - トレースすべきかどうかを表すフラグ\nデータタイプについて、理解したので、どのように計測が行われるかを順をおってみてみましょう 例はFinagleのHTTPがどのようにトレースされるかを示しています。 他のライブラリやプロトコルはもちろん、異なりますが、基本的な部分は一緒です。\n\u0026lt;b\u0026gt; サーバサイド\u0026lt;/b\u0026gt; 1. 到達したリクエストのトレースヘッダー存在するかどうかを調べます。存在すれば、なら、このリクエストに対して関連するIDとします。トレースヘッダーがなければ、サンプリング対象かどうかを決めて、新しいTrace Id、Span Idを生成します。参考には[HttpSererTracingFilter](https://github.com/twitter/finagle/blob/master/finagle-http/src/main/scala/com/twitter/finagle/http/Codec.scala)を見て下さい。 2. もし、現在のリクエストがサンプリングされる場合、サービス名、ホスト名、スパン名(例えば、http get/put)、その他のAnnotationのような情報を集めます。 リクエスト受信時には「server received」というAnnotationを生成し、処理が終了して結果を返すときに「server send」というAnnotationを生成します。 参考には[HttpServerTracingFilter](https://github.com/twitter/finagle/blob/master/finagle-http/src/main/scala/com/twitter/finagle/http/Codec.scala)を見てください。 3. 生成されたトレースデータはServerBuilderにより設定されたトレーサーに渡されます。 デバッグのためのConsoleTracerが例としてありますが、ZipkinTracerになります。 トレースデータを[ZipkinTracer](https://github.com/twitter/finagle/tree/master/finagle-zipkin)が受け取った時、Span Idにより集約されます。 4. ZipkinTracerが\u0026#34;end of span\u0026#34;イベント(\u0026#34;server received\u0026#34;アノテーションやタイムアウトのような)を受け取ると、Thrift構造としてデータを集約してScribeに送ります。もし、そのようなイベントが発生しない場合、ZipkinTracerはいつかそのデータを送信します???おかしい?。データ送信のための他の方法も追加します。 ThriftやScribeのようなものですが、JSONやHttpかもしれません? \u0026lt;b\u0026gt; クライアントサイド\u0026lt;/b\u0026gt; 1. リクエストを送る前にそれがトレースの一部かどうかをチェックします。 サーバで利用されているとします。 サーバは、リクエストを処理してすでに付与されているトレースIDを割り当てます。 トレースIDを再利用しますが、この新しいリクエストには新しいスパンIDを生成します。 また、親のスパンIDが存在すれば、前のスパンIDに設定します。 [ここ(TracingFilter)](https://github.com/twitter/finagle/blob/master/finagle-core/src/main/scala/com/twitter/finagle/tracing/TracingFilter.scala)や[ここ(Trace)](https://github.com/twitter/finagle/blob/master/finagle-core/src/main/scala/com/twitter/finagle/tracing/Trace.scala)が参考になります。 2. サーバサイドと同様に、送信されるHttpリクエストにトレースヘッダーを追加するための[HttpClientTracingFilter](https://github.com/twitter/finagle/blob/master/finagle-http/src/main/scala/com/twitter/finagle/http/Codec.scala)があります。 3. リクエスト送信前の「client send」やサーバからの返信を受信した「client receive」のようなアノテーションを生成します。 4. サーバサイドと同様に、データがZipkinにデータを送るZipkinTracerに到達します。 ","date":1339772520,"dir":"post/2012/","id":"9ccda414c322ebcdf875eacbba2e4b7e","lang":"ja","lastmod":1339772520,"permalink":"https://blog.johtani.info/blog/2012/06/16/zipkin%E3%81%AEreadme%E8%AA%AD%E3%82%93%E3%81%A7%E3%82%8B%E3%81%9D%E3%81%AE%EF%BC%92%E6%AE%8B%E3%82%8A/","publishdate":"2012-06-16T00:02:00+09:00","summary":"「鉄は熱いうちに打て」ということで、残りも勢いでメモ。 まだ、見直しとかしてない状態なのでおかしいところとかありますが。。。 図とか入れるのはま","tags":["Zipkin"],"title":"ZipkinのReadme読んでる(その2、残り)(Jugemより移植)"},{"contents":"ZipkinのGithubにあるReadmeを読んでます。 せっかくというか、頭が悪いので読みながら内容をメモ。 まずは、アーキテクチャとトレースデータ送信のためのクライアント側あたりです。 (誤訳とかおかしいだろというツッコミ大歓迎です。) あとで、リンク貼ったり絵を入れたりするかもしれませんが、とりあえず。\n◯アーキテクチャ(図はこちら)\n・対象とするサービスからScribeでデータを収集し、ZipkinのCollectorに投げる ・CollectorはCassandraにデータを格納 ・WebUIからはQueryでCassandraに問い合わせを行なってデータ取得 ・Scripe、CollectorはZookeeperと連携している(妄想) ◯計測用ライブラリ(図はこちら。図のSと書かれた青い箱)\n・各ホストの計測用ライブラリがトレースデータを集めてZipkinに送信する。 ・ホストは他のサービスへリクエストを飛ばすときに、リクエストにトレース用のIDを付与してます こうすることで、データをあとで、束ねることが可能となります。 ◯計測ライブラリの利用方法 ・Finagle\nJVMのための非同期ネットワークスタックである。 それは、JVMベース言語(JavaやScalaなど)で非同期RPCのクライアント・サーバを構築するのに利用できる。 FinagleはTwitterの内部ですごく利用されていて、トレースサポートを実現するのに当然のポイントです。 現時点で(Finagleは)ThriftやHTTP、Memcache、Redisのクライアント・サーバサポートも持っています。 ScalaでFinagleサーバをセットアップするのはつぎのようなコードになります。 トレースを追加するには、finagle-zipkinを追加して、ServerBuilderのtraceFactory関数を呼ぶだけです。\nServerBuilder() .codec(ThriftServerFramedCodec()) .bindTo(serverAddr) .name(\u0026#34;servicename\u0026#34;) .tracerFactory(ZipkinTracer()) .build(new SomeService.FinagledService(queryService, new TBinaryProtocol.Factory())) クライアント側も同様です。 上記のようにサンプリングしたリクエストにZipkinトレーサーを指定することで 自動的にトレースできるようになります。 サービスやホストでのリクエストの開始と終了を記録できます。 さらに付加的な情報を記録したい場合は、つぎのようなコードを追加します。 Trace.record(\u0026#34;starting that extremely expensive computation\u0026#34;) 上記コードは、上記コードが実行された時間に文字列を付加できます。 キーバリュー情報を付加したい場合は次のようになります。 Trace.recordBinary(\u0026#34;http.response.code\u0026#34;, \u0026#34;500\u0026#34;) Ruby Thrift\nリクエストのトレースに利用できるgemもあります。 リクエストに対してトレースIDを生成し、リクエストに付与し、トレーサーにプッシュするのにRackHandlerのgemを利用できます。 トレーサをトレースするサンプルはzipkin-webを参照。\nRubyからトレースクライアントをコールするのに、Twitter Ruby Thrift clientを使います。 つぎのようなコードを書きます。\nclient = ThriftClient.new(SomeService::Client, \u0026#39;127.0.0.1:1234\u0026#39;) client_id = FinagleThrift::ClientId.new(:name =\u0026gt; \u0026#34;service_example.sample_environment\u0026#34;) FinagleThrift.enable_tracing!(client, client_id), \u0026#34;service_name\u0026#34;) Querulous\nQuerulousはScala用のSQLデータベースのインタフェースライブラリです。 SQLクエリの実行のタイミング情報をトレースに追加できます。 Cassie\nCassieはFinagleベースのCassandraクライアントライブラリです。 CassieのトレーサーはFinagleの例とほぼ一緒ですが、 CassieではKeyspaceBuilderに設定します。 cluster.keyspace(keyspace).tracerFactory(ZipkinTracer()) とりあえず、ここまで。___ 2012/06/22 リンクを貼って体裁を修正\n","date":1339721820,"dir":"post/2012/","id":"69f755dd5b9e90a99c3086543790541c","lang":"ja","lastmod":1339721820,"permalink":"https://blog.johtani.info/blog/2012/06/15/zipkin%E3%81%AEreadme%E3%82%92%E8%AA%AD%E3%82%93%E3%81%A7%E3%82%8B%E3%82%AF%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%B3%E3%83%88%E5%91%A8%E3%82%8A%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/","publishdate":"2012-06-15T09:57:00+09:00","summary":"ZipkinのGithubにあるReadmeを読んでます。 せっかくというか、頭が悪いので読みながら内容をメモ。 まずは、アーキテクチャとトレー","tags":["Zipkin"],"title":"ZipkinのReadmeを読んでる(クライアント周りについて)(Jugemより移植)"},{"contents":"久々にSolrの話です。 といっても、結構前からの話でして。。。\nschema.xmlのfieldTypeの設定に「autoGeneratePhraseQueries」という属性があります。 Solr3.1で導入されました。動作に関しては関口さんのブログで説明されています。 Solr 1.4までは、Analyzerがトークンを複数返してくる場合(例:lucene-gosenで「Solr入門」という文字列を入れた場合など)にフレーズクエリとして処理していました。 Lucene 3.1.0から、この処理がデフォルトfalse(つまり、フレーズクエリにならない)という挙動になりました。(詳しくは関口さんのブログで。) ただ、Solr 3.1.0では、下位互換性を考慮して、autoGeneratePhraseQueriesの設定値はデフォルトが「true」でした。\nこのデフォルト値がSolr 3.3以降で提供されているschemaのバージョン(1.4以上)からデフォルト値が「false」に変更されています。 schemaのバージョンを1.3以前のものから1.4以上に移行する場合は注意が必要です。\nとまぁ、偉そうに書きましたが、私もちゃんと追えてませんでした。 Solr勉強会第6回で、関口さんの発表できちんと説明されていて、参加してたのに聞けてなかったですし。(メモ取ってるのに、書いてない。)\nということで、Solr入門のサンプルschemaも少し修正しました。 こちらとこちらの記事に追記してありますので、参考にしてください。\n","date":1339603740,"dir":"post/2012/","id":"277f7f2177e2a265a62680ea0158f9b9","lang":"ja","lastmod":1339603740,"permalink":"https://blog.johtani.info/blog/2012/06/14/autogeneratephrasequeries%E3%81%AE%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88%E5%80%A4%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/","publishdate":"2012-06-14T01:09:00+09:00","summary":"久々にSolrの話です。 といっても、結構前からの話でして。。。 schema.xmlのfieldTypeの設定に「autoGeneratePh","tags":["solr"],"title":"autoGeneratePhraseQueriesのデフォルト値について(Jugemより移植)"},{"contents":"すでに読まれた方もいるかも知れませんが、気になったのでメモを書いてみようかと。\n先週の木曜日にTwitterのエンジニアブログでZipkinというOSSを公開したという記事がでました。 非常に興味深いシステムだったので、ちょっとずつ読み解いていきたいなという宣言(というか、ハッパをかけてもらうため)も兼ねて、まずはブログの内容をメモ程度に残しておきます。\nZipkinは分散トレースシステム(distributed tracing system)です。Twitter APIの1リクエストを構成する様々なサービスのタイミングデータ(計時データ)を集めるために作りました。 Firebugのような性能プロファイラのよなもので、しかもバックエンドのサービスもプロファイル可能です。 ZipkinはAPLv2ライセンスでOSSとしてGithubで公開しています。\nZipkinはWebのユーザインタフェースを持っています。(元記事参照) 各サービス(縦軸)でどのくらい時間がかかっているか(横軸)がわかり、クリックすることでより詳細な情報が得られます。 Zipkinはパフォーマンス改善の余地のある部分(遅いMySQLのSELECTなど)を見つけるのに役立ちます。\nZipkinはどのように動くの? Twitterに届いたリクエストからサンプリングしたリクエストに対してトレース可能なIDを付与して、すべてのサービスに渡していきます。 全リクエストの一部をサンプリングすることで、トレースのオーバヘッドを減らし、常に本番環境で利用できるようにしています。 Zipkinコレクタ(collector)が、Scribe経由でタイミングデータを受け取り、Cassandraに保存してインデックスを作成します。 Zipkinクエリデーモンがインデックスを利用して、WebUIにトレースデータを見つけます。\nZipkinはHack Weekで開始されました。 最初はThriftに対するGoogle Dapperの論文の基本的な部分の実装から始まり、現在ではHttp、Thrift、Memcache、SQL、Redisリクエストをサポートしています。 これらはFinagleライブラリで経由で動作します。Rubyのgemも用意してあります。\nということで、ほぼ直訳ですが、何かの役に立てればと。 ちょっとずつですが、Githubのページやソースを読みながら記事を書いていこうと思っています。\n","date":1339515600,"dir":"post/2012/","id":"ee48516e57684c5a4c22adccac34be92","lang":"ja","lastmod":1339515600,"permalink":"https://blog.johtani.info/blog/2012/06/13/twitter%E3%81%8C%E5%85%AC%E9%96%8B%E3%81%97%E3%81%9F%E5%88%86%E6%95%A3%E3%83%88%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%B3%E3%82%B0%E8%BF%BD%E8%B7%A1%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0zipkin/","publishdate":"2012-06-13T00:40:00+09:00","summary":"すでに読まれた方もいるかも知れませんが、気になったのでメモを書いてみようかと。 先週の木曜日にTwitterのエンジニアブログでZipkinと","tags":["OSS"],"title":"Twitterが公開した分散トレーシング(追跡?)システム、Zipkin(Jugemより移植)"},{"contents":"lucene-gosenの最新版(2.0.1)をリリースしました。\nプロジェクトページよりダウンロードが可能です。\n今回の修正では、@haruyama さんからいただいていたパッチの取り込み(リソース周りの改善など)が主な対応となっています。 また、コンパイルに利用するjarファイルがLucene/Solr3.6.0に変更になっています。(Issueはこちら) 3.6.0から追加されたテストケースにて、発生する問題への対処も施したものとなっています。\n","date":1339059234,"dir":"post/2012/","id":"216db319052b5742fc68862cb2f39905","lang":"ja","lastmod":1339059234,"permalink":"https://blog.johtani.info/blog/2012/06/07/lucene-gosen-2-0-2%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9%E5%91%A8%E3%82%8A%E3%81%AE%E6%94%B9%E5%96%84%E3%81%AA%E3%81%A9/","publishdate":"2012-06-07T17:53:54+09:00","summary":"lucene-gosenの最新版(2.0.1)をリリースしました。 プロジェクトページよりダウンロードが可能です。 今回の修正では、@haruy","tags":["lucene-gosen"],"title":"lucene-gosen 2.0.2リリース(リソース周りの改善など)(Jugemより移植)"},{"contents":"昨晩に引き続き、情けない内容のブログになってしまいますが。。。\n昨晩、書いた記事の調査をしていた時に気づいた、問題になるケースがあったので調査をしていました。 Issue32に登録した内容になります。 拙い英語を振り絞って書いた英語なので、伝わらないかもしれないのでブログに残しておきます。 昨晩の問題点となったクラス(StreamTagger2.java)の内部処理についてです。 lucene-gosenのLucene向けのTokenizerの内部処理では入力文字列の処理を行うのに、「char buffer[]」を用いて 入力文字列をReaderから読み込むときにバッファリングしています。 このバッファリングにて、特定のケースにて、想定していない場所を単語の切れ目と認識してしまう問題が実装上存在しました。 Issue32に記載した内容は次のようになります。\n上記バッファは4096文字というサイズで固定になっています。 StreamTagger2クラスでは、この4096文字をオーバーするような文字列の場合に、つぎの処理により、4096文字以下の場所に文章の区切りを探そうとします。\n4096文字以上の文字列が入力される バッファに入れられるだけの文字(4096文字)をバッファにコピーする。 バッファの後ろから、つぎの5種類の文字を探索し、見つかった場合(場所をkとし、k>0の場合)は、その場所を文章の切れ目と判定して、0からk+1文字目までの文字をStringTaggerを利用して形態素解析する。 あとは、繰り返し 上記条件に合致しない場合は、4096文字を文章とみなして形態素解析を行います。 ここで、5種類の文字は以下のとおり。\n0x000D:CARRIAGE RETURN(CR) 0x000A:LINE FEED(LF) 0x0085:NEXT LINE (NEL) 0x2028:LINE SEPARATOR 0x2029:PARAGRAPH SEPARATOR 見ての通り、制御文字ばかりです。 この5文字以外は切れ目と判断してくれません。 ということで、4097文字の文字列が存在し、上記5種類の文字が一度も出てこない場合、バッファのサイズで文字列が途切れてしまい、想定しない区切り位置で区切られた文章に対して形態素解析が実行されてしまいます. HTMLから文字列を抜き出して解析したり、長い文書を解析する場合に、改行文字を削除して処理するといったことも考えられます。 上記5種類の文字列のみで文章の区切り位置を判断してしまうのは問題ではないかと。 まずは、4096文字内に「。」句点が存在した場合に、その部分を区切り位置として認識するようなパッチを記載して、Issue32に添付しました。\n「。」句点を採用した理由はつぎのとおりです。 StreamTagger2では、上記バッファリングした文字列を更に、BreakIterator.getSentenceIterator(Locale.JAPANESE)にて取得したBreakIteratorにて文節単位に区切ってから、各文節ごとに形態素解析を実施しています。 ということは、BraekIteratorにて分節の区切りとして判断される文字については、上記の文字種に追加しても問題無いという判断からです。 ただし、この修正でも、純粋に4096文字以上、句点が出てこない場合には区切り位置がおかしなことになってしまいますが。。。 もう少し、BreakIteratorの挙動を調べて、他にも利用可能な区切り文字が存在しないかを調査していく予定です。。。\n1年以上コミッターをやっているのに、こんなことも理解していないのかよいうツッコミを受けてしまいそうでなんとも情けない話です。。。 まずは、現状報告でした。\n","date":1338913260,"dir":"post/2012/","id":"cbf9587a8187985725963b8bfc67004d","lang":"ja","lastmod":1338913260,"permalink":"https://blog.johtani.info/blog/2012/06/06/issue32%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A64096%E3%81%AE%E5%A3%81/","publishdate":"2012-06-06T01:21:00+09:00","summary":"昨晩に引き続き、情けない内容のブログになってしまいますが。。。 昨晩、書いた記事の調査をしていた時に気づいた、問題になるケースがあったので調査","tags":["lucene-gosen"],"title":"Issue32について(4096の壁)(Jugemより移植)"},{"contents":"久々にlucene-gosenを触っています。 trunkのlibにある、jarファイルが3.5ベースだったので、3.6ベースにしてテストをしたところ、 いくつかある、ランダムテストで結果の不整合が検出されたので、調査していました。 先程、trunkに対応版をコミットしました。もう少しテストケースを追加してからリリースします。 おそらく、通常の使い方では問題無いと思います。\nLuceneでは、ランダムな文字列を利用したテストが実装されています。 lucene-gosenでもこのテストを利用してランダムなテストをしています。 実際にはtest/以下のorg.apache.luceneパッケージにテストケースがあります。 今回、jarファイルを差し替えた時に、このランダムなテスト実施にて、assertが失敗するケースが発生しました。\n原因究明までに、いくつかフェーズがあったので、忘れないように書いておきます。\n1.ランダムテストのテストケースにてエラーがassertが失敗するケースが発生 ※ただし、成功する場合もあり。 2.該当のテストを再現しつつデバッグ+該当のテストがどんなものかを解読(勉強不足。。。) ※テストは、失敗した場合につぎのようなメッセージが表示され、同じテストが再現可能です。 以下、エラーの出力例。「NOTE: reproduce with: 」のあとにあるantコマンドを実行すれば、同じテストが再現可能です。\n[junit] ------------- Standard Error ----------------- [junit] TEST FAIL: useCharFilter=false text=\u0026#39;wgxznwk\u0026#39; [junit] [junit] ===\u0026gt; [junit] Uncaught exception by thread: Thread[Thread-3,5,main] [junit] org.junit.ComparisonFailure: term 0 expected:\u0026lt;w[gxznwk]\u0026gt; but was:\u0026lt;w[]\u0026gt; [junit] at org.junit.Assert.assertEquals(Assert.java:125) [junit] at org.apache.lucene.analysis.BaseTokenStreamTestCase.assertTokenStreamContents(BaseTokenStreamTestCase.java:146) [junit] at org.apache.lucene.analysis.BaseTokenStreamTestCase.checkAnalysisConsistency(BaseTokenStreamTestCase.java:565) [junit] at org.apache.lucene.analysis.BaseTokenStreamTestCase.checkRandomData(BaseTokenStreamTestCase.java:396) [junit] at org.apache.lucene.analysis.BaseTokenStreamTestCase.access$000(BaseTokenStreamTestCase.java:51) [junit] at org.apache.lucene.analysis.BaseTokenStreamTestCase$AnalysisThread.run(BaseTokenStreamTestCase.java:337) [junit] \u0026lt;=== [junit] [junit] NOTE: reproduce with: ant test -Dtestcase=TestGosenAnalyzer -Dtestmethod=testReliability -Dtests.seed=4ad9618caecb9fb2:d5476c03b8172df:-9c569f70013ffbb -Dargs=\u0026#34;-Dfile.encoding=SJIS\u0026#34; [junit] ------------- ---------------- --------------- [junit] Testcase: testReliability(org.apache.lucene.analysis.gosen.TestGosenAnalyzer):\tCaused an ERROR 3.デバッグの結果、Luceneのtest-frameworkにある「MockReaderWrapper」というクラスの影響を確認 LuceneのJIRAのLUCENE-3894にて追加されたクラスであるとわかる。 このクラス、Readerのreadメソッド内部で、ランダムな値を元に長さを途中で返すという実装のReaderになっている。 (全部で18文字の文字列なのだが、ランダムな値を元に、12文字として結果を一旦返すという仕組みが実装されている) 4.lucene-gosenの問題箇所を特定。 Readerが途切れた部分を分節として扱ってしまう実装になっていた。 該当の部分に修正をいれてコミット。 という具合です。 一応、テストを数回走らせてランダムテストが問題なく終了するのを確認はしてあります。 今回の問題に対する、個別のテストケースを追加してから近日中リリースする予定です。 対応が遅くなって申し訳ないです。。。\n","date":1338827340,"dir":"post/2012/","id":"0dcb6d0f17794bbca56b6cdb9e20b932","lang":"ja","lastmod":1338827340,"permalink":"https://blog.johtani.info/blog/2012/06/05/trunk%E3%81%AE%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E5%B7%AE%E3%81%97%E6%9B%BF%E3%81%88lucene-solr3-6-0%E3%81%A8%E3%83%A9%E3%83%B3%E3%83%80%E3%83%A0%E3%83%86%E3%82%B9%E3%83%88%E3%81%AE%E5%A4%B1%E6%95%97%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/","publishdate":"2012-06-05T01:29:00+09:00","summary":"久々にlucene-gosenを触っています。 trunkのlibにある、jarファイルが3.5ベースだったので、3.6ベースにしてテストをし","tags":["lucene-gosen"],"title":"trunkのライブラリ差し替え(Lucene/Solr3.6.0)とランダムテストの失敗について(Jugemより移植)"},{"contents":"録画してたEテレのスーパープレゼンテーションを見ててふと書きたくなったので、書いてます。 あとから読んだら恥ずかしくなりそうだけど。。。 「\u0026ldquo;知力の余剰\u0026quot;が世界を変える」というClay Shirkyさんの話を見て思ったことです。 社会的に貢献できる仕組みが最近増えているという話の内容でした。そこで、OSSについても同じことが言えるよなぁと思った次第でして。\n昔からいろんなかたが言ってると思うし、今さら何をとおもわれるかもしれないですが、なんとなく書きたくなってしまったので。\n私はシステム開発を生業にしています。特にOSSにはお世話になっています。 実際に、OSSを利用している方はかなりいると思います。 幸いにも、私はOSSのコミッターもやっています。 OSSに色々と関わってきて常々思っていることがありまして。\nOSSは基本は有志の方々が開発やメンテナンスを行なっています。(最近では会社で行なっているところもありますが。) そんなOSSに貢献する方法はいくつかあるのかなぁと。\nバグを発見したら報告したり、こんな機能を作ってみたけどどうですか?とパッチを送ってみたりするのは素晴らしい貢献だと思います。 ただ、なかなかアクションを起こすのって勇気がいるかなぁと。 実際、私もパッチ書いたりバグ報告するのは気後れすることがありしました。 ただ、貢献する方法ってこれだけじゃないよなぁと、コミッターをやり始めて思いました。\nもちろん、バグ報告してもらえるともっとありがたいですし、新機能とかリクエストを送ってもらえるともっと嬉しいです。 MLに質問するのもありです。ただ、ちょっとハードルが高いと思うこともあります。\nそんな時は、ただ使っているよと、ツイートしたりブログを書いてくれるだけでもありがたいし、ヤル気が出るものです。 使い勝手が悪いなぁというツイートでも、なんでこんなに使いにくいんだというブログでもいいんです。 気になるなぁという形でもいいと思っています。 githubでフォローするだけでもいいかと。 反応があれば、使ったり触ってもらえていることがわかります。 なので、使っているよとかアピールしてもらえると嬉しいよなぁと。\nなんか、締りのない感じになっちゃいましたが、反応があるとうれしいので、お気楽に反応しましょうよというお話です。\n","date":1338394320,"dir":"post/2012/","id":"ffdbd6a7d28c9a63976e9eec38cab0f5","lang":"ja","lastmod":1338394320,"permalink":"https://blog.johtani.info/blog/2012/05/31/%E3%82%AA%E3%83%BC%E3%83%97%E3%83%B3%E3%82%BD%E3%83%BC%E3%82%B9%E3%81%B8%E3%81%AE%E8%B2%A2%E7%8C%AE%E3%81%AE%E3%82%B9%E3%82%B9%E3%83%A1/","publishdate":"2012-05-31T01:12:00+09:00","summary":"録画してたEテレのスーパープレゼンテーションを見ててふと書きたくなったので、書いてます。 あとから読んだら恥ずかしくなりそうだけど。。。 「\u0026l","tags":["misc"],"title":"オープンソースへの貢献のススメ(Jugemより移植)"},{"contents":"JJUG CCC 2012 Springに参加してきました。 昨年のFallに続き、2回目です。 概要や、タイムテーブルはこちらを御覧ください。 今回は、午後一から参加しました。 色々と迷いましたが、つぎのを聞いて来ました。\nHotSpot vs JRockit ~ HotRockit到来の前に予習しよう! Play! Framework - モダンで高速なWeb開発 Grails/Groovyの開発活用術 Scala 最新状況報告 From Swing to JavaFX SwingからJavaFXへのマイグレーションガイド JRockitは使ったことがなく(たぶん)、新鮮でした。いろいろなコマンドが用意されているなぁと。 あと、jvisualvmの使い方も知らないこともあったのでいい話が聞けました。 プレゼンに慣れているようで、プレゼン中に、コマンドラインの拡大+コマンドのオプションに赤い下線を入れるなど、どうやってやっているのか、プレゼンの内容よりも気になってしまったのが本音です\nPlayは今回の目玉の一つでした。まだ、手元でPlayを触り始めたばかりだったので、概観がつかめたのが良かったです。 あとでスライドを見なおさないと。 頭がどうしてもServlet、JSPのため、未だにPlayに切り替えができてないので、もっと触ってみないとなぁと。 ちなみに、紆余曲折してまして、Play 1.2.4→Play 2.0(Javaアプリ)→Play 2.0(Scalaアプリ)と心変わりしまくりで、まだ完全に作ってないのに、ふらふらしてます。。。\nGrailsはGrailsを現場にどのように投入していくのがいいかという、技術よりは、政治的な話でしたが面白かったです。 実際に、あまり有名でないプロダクトを現場に導入するのに、Javaだからと無理やり説得してみたりw、開発コストがこれくらい下がりますという話をしてみたりと、いろいろやられているようでした。 あと、PlayのあとにGrailsということもあり、すこしPlayを意識した話もされていました。\nScalaはScalaDaysの話+Scalaの最近の動向ということで、ある程度Scalaを知っている人がターゲットのようでした。 少し触っただけなので、何となく分かる部分もありましたが、最後の方はついていけてないです、すみません。。。 一番感じたのは、発表者の水島さんのScalaに対する愛情でしょうか。\n最後は桜庭さんのJavaFXのお話です。 一応、昔、JFreeChart+Swingでちょっとしたものを作ったことがあるので面白かったです。 プレゼン自体もJavaFXで作成されていたり、オープニングがStarWars風だったりと凝ったプレゼンでした。 JavaFXとしては、JavaOneでも聞いたのですが、グラフやHTMLがリッチに書けるようになったことがびっくりです。\n実際のSwingアプリからJavaFXへの移行に関して、注意する点などがわかりやすく聞けました。 FXMLは確かに便利ですよねぇ。レイアウトをJavaで組むのがすごくめんどくさかったもんなぁ。\nさて、簡単ですが、感想でした。 今回一番残念だったのは、長丁場の割に電源の確保が難しかったことでしょうか。 ツイートしたり、メモ取ったりしたかったのですが、電源が乏しいので、Wi-fiオフにしてメモ取るのが限度でした。。。\n場所:オリンピック記念青少年総合センター 日時:2012/05/28 10:00 - 19:00 ◎13:10 - 14:00 C-1 HotSpot vs JRockit ~ HotRockit到来の前に予習しよう! 谷本 心 @cero_t ◯HotSpot from Sun ◯JRockit from BEA 今は、どちらもOracle ◯違いは? 1.歴史 2.プラットフォーム JRockitはMacではNG。Solarisは一部。 2.1Oracleさん曰く Solaris/Mac → HotSpot Windows/Linuxのサーバ → JRockit Windows/Linuxのクライアント → HotSpot 2.2谷本さんは? WebLogic → JRockit 1.4、5の時の開発環境はJRockit 当時はJRockitの解析ツールがカッコ良かった 3.解析ツール 3.1コマンドラインツール プロセス HotSpot : jps JRockit : jrcmd スレッドダンプ HotSpot :jstack JRockit : jjrcmd \u0026lt;pid\u0026gt; print_threads ヒープ解析 HotSpot:jmap -histo \u0026lt;pid\u0026gt; JRocket:jrcmd \u0026lt;pid\u0026gt; heap_diagnostics HotSpot: JRockit:jrcmd \u0026lt;pid\u0026gt; 他にもJRockitは色いろある。 print_utf8poolとか(内部の文字列が出てくる) 3.2GUIツール HotSpot:jvisualvm NetBeansベース JRockit:Mission Control Eclipseベース メモリリークの解消をツールを使ってみてみましょうデモ。 ・hprofファイルを吐き出して、jvisualvmで読みこむのが楽な方法 ・jrmcはヒープダンプファイルを読み込む機能がない。 memleakというツールがある。アプリを起動してから、プロセスを右クリックして選択可能。 タイプグラフや割当てトレースみたいなものが使えるよ。 フライトレコーダーというのもあるよ。 4.HotRockitの紹介 まだいつ出るのかなぁという状態だけど、HotSpotにJRockitのツールも使えるようになるVMが出る模様。(2013?) ※デモ中に画面拡大した時に、赤線でラインを引いているのがすごく気になった。(便利なツールなのかな?そこだけ?) ◎14:15 - 15:05 C-2 Play! Framework - モダンで高速なWeb開発 池田尚史 @ikeike443 ◯自己紹介 Play!Frameworkコミッター 日本Playframeworkユーザ会 ◯アンケート メイン言語は?Java多数 触ったことある?半分くらい? Play1?Play2?半々くらい プロダクションで使ってる人?3人 ◯Playframeworkって? JEEではないよ。 Webだよ。 ServletとかXML使ってないよ。 ◯JEEは難しいよね。RailsとかDjangoから流れてくると。 ◯Webフレームワーク なので、Webアプリが作れればいいよね。 開発すべきものに注力して、抽象化とかを頑張らないようにと。 ◯ライブコーディング! Play2.0のScalaアプリみたい。 プロジェクト作成~編集して起動まで。 エラーを起こして、エラーがどのように表示されるか。 エラーのリンクをクリックして、エディタを起動するということも可能みたい。 TODOとかで、まだ終わってないのも記述可能。 パラメータとControllerの関数の引数が勝手にひもづけられますよと。 ◯歴史 Servletとかもあった。 1.2からNetty、Websocket、Scalaサポート 2.0.1:Scalaで書き直し。Netty+Akkaで非同期 ◯1と2のちがいは? ・Play1 Javaで書かれたJavaのフレームワーク。Scalaはプラグインサポート ・Play2 Scalaで書かれたScala/Javaのフレームワーク ◯Playの特徴 ステートレスとかノンブロッキングとかリアクティブとか ・高生産性 XMLがないし、unzipするとすぐ使えるよ。 ホットスワップできるよ。 CoffeeScript、LESSサポートも。assetsに入れとくとコンパイルしてくれて静的コンテンツにしてくれる。(Railsにも似たようなのあったっけか?) ・ステートレス HttpSessionがない→必要ならMemcachedとかで管理してね。 「デプロイ→ニーズ・状況に応じて即時スケールアウトという時代じゃないか?」という主張 Playはステートレス養成ギブスであり、時代の要請にマッチ ・広範囲な型安全 コンパイルしてエラー検知 ・ノンブロッキングI/O 非同期処理が手軽に書けるように考えられている。 →リアルタイムWebの時代 NettyやAkkaにより実現されてるのがいい Akkaを使ったアプリを書くと、長い処理のActorを別サーバにするなども設定で変更が可能。 ◯テスタビリティ BDDフレームワーク(Specs2?) Viewもテストできるぞと。 ◯事例 Klout:ソーシャルスコアリング イギリスのガーディアン:コンテンツAPIの実装がPlay2 MinecraftのWebサイト ◎15:20 - 16:10 C-3 Grails/Groovyの開発活用術 ~Java EE資産を活かして開発を加速する~(仮) 上原潤二 山本剛 ◯充電中のためお休み ◎16:25 - 17:15 C-4 Scala 最新状況報告 ~或いはScala Days 2012リポート~ 水島宏太 ◯自己紹介 言語を作るのが夢みたい。 ◯Scala最新状況報告 ScalaDaysの雰囲気を伝えるよと。(どっちかというと、旅行記かも) ◯Scala? ・オブジェクト指向関数型言語 ハイブリッドじゃなくて、統合したもの ・強力な静的型付け NullPointerExceptionなども起きにくい ・超強力なコレクションフレームワーク ・Javaと同等の実行速度 ・コードが簡潔(1/4くらい) ◯Scala採用企業 Twitter、Amazon.com(どこに使ってるかは不明)、Foursquare、LinkedIn、VMWare、Klout、Tumblrなど ◯Scalaのバージョンは? 2.10が開発版。2.9.2がステーブル版。 ◯開発体制 Typesafe+世界のContributor Typesafeメンバの議決でいろいろ決定 githubでオープンに開発 ◯ScalaDays2012の目玉 豪華ゲスト(私は、わからなかった) Scala2.10の新機能紹介 今後のScala、多数の応用例 ◯ScalaDays2012を見ての方向性 ・All-in-oneパッケージの提供 Typesafe Stackの提供 重要なツール sbt(Simple Build Tool) gitter8(プロジェクトテンプレート生成ツール。githubを元に色々取ってくる?) Akka Play 2.0 Framework ・学習コストの削減 言語機能のモジュール化 高度な開発者が使う昨日はデフォルトOff ・バイナリ互換性問題への対処 ・Minor Release間での互換性を維持 MIMAでジドウテキに非互換性を検出 ・Major Release間では互換性は保証しない。 No more java.util.Date ソース互換性は「概ね」保証される deprecatedは次期メジャーバージョン時に削除される。 ・Scala IDEへの注力 インクリメンタルにコンパイルしてくれるから、遅いのも気にならなくなるかも。 デバッガとか、できるよと。 ・さらなるパフォーマンス改善 Value classes AnyValを継承したクラスが作成可能 該クラスのオブジェクトがインライン化 Pimp my libraryによるヒープ使用料が0に! ◯2.10最新機能紹介 \u0026#34;1+2=#{1+2}\u0026#34;ができない s\u0026#34;1+2=${1+2}\u0026#34;ができるように String = 1 + 2 = 3 f\u0026#34;1=${1}%03d\u0026#34;もできるようにSring = 1 = 001 自分でStringコンテキストにメソッド追加できるらしい(聞き取った日本語が合ってるか?) とか。(かなり不安。。。まだまだわかってない。。。) ◎17:30 - 18:30 BOF-B-1 From Swing to JavaFX SwingからJavaFXへのマイグレーションガイド 櫻庭 祐一 ◯JavaFX 次世代のJava GUI Library Swing+Java2D+α JavaSE8から標準(JavaFX3.0) ◯サンプル クラス名がいろいろ変わってる。 ◯はまりそうなところ コンテナへの追加がちょっと違う イベントリスナは1種類のみになった。(Genericsを使うようになったよと。) ◯Bind 値が変わるとModelが勝手に検知して変わるみたい。 双方向もあり。これだとEventを書かなくても良くなりつつ有るよと。 ◯シナリオベースでマイグレーション考えましょう 1.JavaFX in Swing JavaFXにSwingを埋め込むことはできないぞと。 SwingでできないことをJavaFXでやりますよと。 おー、グラフが動く。JavaDocのHTMLも綺麗に出てる。 使い方:JFXPanelを使う シーングラフを記述可能 データのやり取りが大変。Threadが違うから。 パフォーマンスが落ちます。Java2Dで画像を書くので遅いですよと。 新規のものはJavaFXで書きましょうと。 2.Swing to JavaFX w/o FXML SwingをJavaFXに置き換える。 使い方が違うものはTableViewなど、◯Viewとついてるもの。 ちょっと考えるのはLayout Swing:コンテナ+レイアウトマネージャー JavaFX:コンテナがレイアウトを含む BorderPaneクラスとか。 問題はTableとか Swing:TableModel JavaFX:BeanをColumnにバインド 3.Swing to JavaFX w/ FXML ・FXML GUIの構造をXMLで表す。 シーングラフを表現。 スキーマレス クラス:要素 プロパティ:属性 or 要素 アノテーションバリバリです。これで、FXMLとJavaのバインディングができるよと。 ツール Java :NetBeans e(fx)clipseってのがあるかも。 FXML:Scene Builder ","date":1338259500,"dir":"post/2012/","id":"de734259dfb9addebe2b226d96b4f744","lang":"ja","lastmod":1338259500,"permalink":"https://blog.johtani.info/blog/2012/05/29/jjug-ccc-2012-spring%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%A6%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-05-29T11:45:00+09:00","summary":"JJUG CCC 2012 Springに参加してきました。 昨年のFallに続き、2回目です。 概要や、タイムテーブルはこちらを御覧ください。 今回は、午後一から参加","tags":["勉強会"],"title":"JJUG CCC 2012 Springに参加してきました。(Jugemより移植)"},{"contents":"PlayFramework2.0を触ってみてます。 ちょっとコーディングしたくなったのと、最近のアプリの作成の調査も兼ねて。 まぁ、せっかくなので、Solr検索のアプリでも作ってみようかと言うことで触ってます。 ただ、Solr検索アプリでしかなく、今のところDBを使わないので、実はPlay Frameworkじゃなくてもいいのではないかという疑問も。。。\nまだ、触り始めたばかりなので、なんともですが。感想を。 たぶん、Ruby on Railsに似ているのかなと。 RoRは仕事で少し関わったので、なんとなく知っていますが、アプリの作成手順や、ディレクトリ構成などが似ている気がします。\nコントローラーの生成のタイミングとか、内部でオブジェクトをSingletonで保持する方法とかのイメージがまだ良くつかめていない状態で、まずは、Solr検索部分(Palyにあんまり関係ないところ)を実装しているところです。\n現状で一番の疑問点は、Eclipseプロジェクト化した時の参照ライブラリのパスに関するところでしょうか。 Play Frameworkは「play new ほげほげ」コマンドを実行するとアプリのディレクトリ構成が作成されます。 このあとに、eclipsfyというplayのコマンドを実行すると、Ecilpseのプロジェクトファイルが作成されます。 この時、PlayFrameworkが利用するjarファイルたちが参照ライブラリとしてクラスパスに設定されます。\nこのパスには、PlayFrameworkのインストールディレクトリが含まれた絶対パスが記述されるのですが、 複数人で開発するときにはどうしているのかなぁと。 あと、BitbucketやGitHubにアップするときもどうするのかなぁと。 以前、この疑問ツイートして、頂いた回答としては、環境変数として定義して、各自で設定してもらうというものでした。 私も同じ事を考えていたので、腑に落ちたのですが、他にもっといい方法があったりするんでしょうか? クラスパスやEclipseプロジェクトのファイルをアップしないというのもあると思いますが、それもちょっとなぁと。 なにか、オススメとかあれば、教えていただけると嬉しいです。\n最近、ブログ更新してなかったのもあったので、まずは、導入編でした。\n","date":1337151314,"dir":"post/2012/","id":"78f002cc3d512ea302c900d1da4dfeec","lang":"ja","lastmod":1337151314,"permalink":"https://blog.johtani.info/blog/2012/05/16/playframework-2-0-java%E3%81%AE%E6%96%B9-%E3%82%92%E8%A7%A6%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%A6%E3%82%8B/","publishdate":"2012-05-16T15:55:14+09:00","summary":"PlayFramework2.0を触ってみてます。 ちょっとコーディングしたくなったのと、最近のアプリの作成の調査も兼ねて。 まぁ、せっかくなの","tags":["備忘録"],"title":"PlayFramework 2.0(Javaの方)を触ってみてる(Jugemより移植)"},{"contents":"lucene-gosenの最新版(2.0.1)をリリースしました。\nプロジェクトページよりダウンロードが可能です。\n今回の修正では、Java7でUnicodeのバージョン変更に伴う対応(詳細はこちらを参照)を行なっています。\nリソース周りの対応はまた後日。。。すみません。2012/05/16 遅くなりましたが、昨晩、JavaDocをアップしました。\n","date":1336494900,"dir":"post/2012/","id":"c4b418764dca70aebfc965899a3fa7e5","lang":"ja","lastmod":1336494900,"permalink":"https://blog.johtani.info/blog/2012/05/09/lucene-gosen-2-0-1%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9java7%E5%AF%BE%E5%BF%9C/","publishdate":"2012-05-09T01:35:00+09:00","summary":"lucene-gosenの最新版(2.0.1)をリリースしました。 プロジェクトページよりダウンロードが可能です。 今回の修正では、Java7で","tags":["lucene-gosen"],"title":"lucene-gosen 2.0.1リリース(Java7対応)(Jugemより移植)"},{"contents":" IDの秘密 (丸善ライブラリー―情報研シリーズ) 非常に面白く読めました。 バーコードの話に始まり、最後はシステムで付与するIDに関する考慮点まで幅広くIDについて語られています。\n適度に配置されたコラムがまた面白く、ここまで書いてもいいのかな?と思いながらも楽しく読ませて頂きました。 2次元バーコードが汚れに強いのも知らなかったし、チロルチョコの話は知らなかったし、指コレクションとか面白すぎです。 また、JRのSuicaの導入に7年もかけている点などは、やはりすごい技術なのだなぁというため息混じりの感想です。 それほど長い期間のテストや設計は想像がつかないです。\n最後の2章(7,8章)については、エンジニアの以外のシステムに関わる方やエンジニアになられたばかりの方たちにぜひ読んで欲しいと思いました。 もちろん、エンジニアの方にも読んでほしい内容です。\nいくつか疑問点や気になる点もあったので。\n「静脈や指紋が人によって異なるって確率はどうやって決めたんだろう?」 Twitterの説明文のあとにFBの画面の図番号が書いてある。 日本語がデコードされたけど、QRコードの文字コードって、この中に含まれてるのかな?それとも規格で決まってるのかな? 最後に、書影がNIIに合ったので撮影しました。写真へのリンクです。\n","date":1335794635,"dir":"post/2012/","id":"95c0a5b8a66950b5f22dd82a8dfe0ce5","lang":"ja","lastmod":1335794635,"permalink":"https://blog.johtani.info/blog/2012/04/30/id%E3%81%AE%E7%A7%98%E5%AF%86%E3%82%92%E8%AA%AD%E3%81%BF%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-04-30T23:03:55+09:00","summary":"IDの秘密 (丸善ライブラリー―情報研シリーズ) 非常に面白く読めました。 バーコードの話に始まり、最後はシステムで付与するIDに関する考慮点まで","tags":["読書"],"title":"「IDの秘密」を読みました。(Jugemより移植)"},{"contents":"WebSolrの話があるらしいというのを嗅ぎつけて、初めてHeroku JP Meetupに参加しました。 herokuもWebSolrも知りつつ、手を出していなかったので、いい機会でした。 (SignUpだけ、勉強会直前に済ませましたw)\nHerokuはAWS上に構築されたアプリケーションプラットフォームで、簡単にアプリをデプロイして動作させることができるようです。 Ruby on Railsを使うのが多いみたいですが、他の言語も利用できると。 で、herokuの面白いところは、アドオンとして、開発が簡単にできるようなしくみが用意されていることみたいです。 今回発表のあった、IronMQ、WebSolr、PaperTrailもアドオンとして用意されており、簡単に利用することが可能です。 IronMQはメッセージキューとして利用できます。\nWebsolrはSolrを簡単に利用できる形で提供しているものになります。 今、利用できるのは3.5.0のようで、最新版(3.6.0)になるのはまだ未定のようです。 今回の発表はWebSolrの話しもありましたが、基本は全文検索の仕組みとKuromojiの説明でした。 ただ、残念ながら、Kuromojiは3.6.0からの提供となるので、現時点では利用できないようです。 あとで、聞いた話だと、schema.xmlを自分で変更できるようです。 ただ、jarファイルを置いたりはできないようなので、lucene-gosenを利用するとかはできないみたいですが。。。 ほかにも、bonsai.ioとして、ElasticSearchの提供も行うようです。 まだ、利用はできないようですが。\n最後がPapertrailです。 こちらは、ログを保存して、検索、グラフ化(視覚化)してくれるアドオンです。 まだ、ベータのようですが、ログを保存してくれるようです。無料版もあるようです。 アドオンとしての機能もそうですが、利用しているグラフ化のツールなど、面白そうなものが利用されていました。\nLTはRuby使いの方が多かったです。\nRuby使いではないのですが、いろいろなアドオンが用意されており、サービスを簡単に提供することができそうだという印象をうけ、ちょっと使ってみたいなぁと思いました。 普段参加していない勉強会だったので、普段では知りえない興味ある話が聞けて面白かったです。\n余談ですがPapertrailの人が利用していた、slideshareのようなサービスのSpeaker Deckもよさそうなので登録してみました。 次に何か発表があった時には資料はこっちにアップしてみようかなぁと\n以下は、いつものように自分用のメモです。\n日時2012/04/20 19:00 to 21:00 会場:パソナグループ本部 呉服橋 ◎オープニング – Ayumu AIZAWA (Heroku Evangelist) ◎新入社員からの挨拶 – Koichi SASADA (Ruby Developer) 前職:大学教員 仕事:CRuby開発 Heroku使った事無いですwRailsもよく知らないですw RUby2.0のリリースがゴール。2013/Feb 性能アップのことやってます。 ◎IronMQ – Chad Arimura (Iron.IO)\n「メッセージキューは涼しいです。」 (Google翻訳による日本語訳付きのスライド) Aggregation、Distribution。。。 IronMQ Elastic、RESTful heroku addon ironmq:rust 簡単にheroku上にキューが用意できるアドオンです。 Q:メッセージがキューに到達したのを確認する方法か? A:ステータスコードが帰ってくる。 Q:データのサイズのリミットは? A:postのリミットはある。S3とかに巨大データをおいて、ポインタを渡すとかしてほしい。 Q:キューへの到達の成功の保証は? A:アプリケーション側で判断してください? ◎Search \u0026amp; Indexing on Heroku – Nick Zadrozny (Websolr) スライドはこちら。\n※ツイートしてて、メモとってなかったので、ツイートをコピペ。 次はWebsolrのお話 Bonsai.io? Bonsai by onemorecloud - http://bit.ly/JjCuaE SQLのLIKE検索はO(n)でおそいねぇと。 クエリのパースについての話。 今度は転置インデックスのお話。 Termへの分割ってどーすんの?というお話。Tokenizeのお話。 その1:N-GramというTokenizeの方法。N文字ずつ先頭からTermを切り出す。開始位置は1文字ずつずらしていくと。 N-Gramはノイズがのるし、多くのTermがでてきちゃうよと。 その2:そこで、次は形態素解析ですね。 先週、Lucene/Solr 3.6.0がリリースされて、Kuromojiという日本語向けの形態素解析器がでましたよ。 Kuromojiはこちら。(Lucene版とは少し違うけど。)http://atilika.org/ Kuromojiのサーチモードのお話。 通常は、「関西国際空港」という単語になってしまうのを、Kuromojiでは「関西」「国際」 「空港」という切り方の単語も出してくれると。 ちなみに、lucene-gosenでは、サーチモードはないんですねぇ。。。 「の」はどこに消えたんだ??そこの説明は? ElasticSearchやSolrのコアの部分でLuceneを使ってるよ。 ElasticSearch http://bit.ly/qjjvWp Kuromojiはユーザ辞書をサポートしてるよ。 Q:まだ、3.5.0では? A:もうすぐやります ◎log analysis for your Heroku app – Eric Lindvall (Papertrail)\nheroku上にログを貯めて、検索したりグラフ化したりできるようになりそうなもの。 [スライドはこちら](http://speakerdeck.com/u/lindvall/p/log-analysis-for-your-heroku-app) ログを貯めて、検索や可視化できるようにするサービスみたいです。 まだ、アイデアレベルのものも発表資料には含まれていました。 内部で利用しているツールなど、資料の最後に出てきますが、色々と面白そうなものがありました。 ◎Lightning Talks ◯Receibo ( @shu_0115 ) デザイナーxエンジニアハッカソンでの成果らしい。 Webベースの家計簿アプリ。 買ったものの名称と料金を入れるだけ。 ◯Heroku + Pusherで作る!リアルタイムアプリケーション ( @satococoa ) WebSocketみたいなことが、Pusherでできるらしい。 http://www.slideshare.net/satococoa/heroku-pusher ◯Herokuアドオンを作ってみてわかったこと ( @takkam ) ◯heroku client のちょっと進んだ使い方 ( @hsbt ) ◯love heroku? – we love herokuのご紹介 ( @ppworks ) ","date":1334935380,"dir":"post/2012/","id":"c92c12a28fa219ad1aab60865046ff05","lang":"ja","lastmod":1334935380,"permalink":"https://blog.johtani.info/blog/2012/04/21/heroku-jp-meetup-4%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-herokujp/","publishdate":"2012-04-21T00:23:00+09:00","summary":"WebSolrの話があるらしいというのを嗅ぎつけて、初めてHeroku JP Meetupに参加しました。 herokuもWebSolrも知りつつ、","tags":["勉強会"],"title":"Heroku JP Meetup #4に参加しました。#herokujp(Jugemより移植)"},{"contents":"先日、Solr入門のサンプルschema.xmlの3.6.0対応版の作成をしていて、気になったことがあったので、 メモとして残しておきます。\nSynonymFilterFactoryの属性「tokenizerFactory」に関連する話です。 (「Apache Solr入門」の36-37ページに記載があります。)\nSynonymFilterFactoryでは、類義語設定ファイルを読み込む際に利用するTokenizerFactoryを「tokenizerFactory」という属性で指定できます。(以下は書籍の記述を抜粋)\n\u0026lt;filter class=\u0026#34;sold.SynonymFilterFactory\u0026#34; synonyms=\u0026#34;synonyms.txt\u0026#34; ... tokenizerFactory=\u0026#34;solrbook.analysis.SenTokenizerFactory\u0026#34;/\u0026gt; このように、TokenizerFactoryが指定できます。\nただ、こちらの記事で書いたように、 Solr 3.6.0のexampleのschema.xmlではCJKのフィールドは次のように設定されています。\n\u0026lt;!-- CJK bigram (see text_ja for a Japanese configuration using morphological analysis) --\u0026gt; \u0026lt;fieldType name=\u0026#34;text_cjk\u0026#34; class=\u0026#34;solr.TextField\u0026#34; positionIncrementGap=\u0026#34;100\u0026#34;\u0026gt; \u0026lt;analyzer\u0026gt; \u0026lt;tokenizer class=\u0026#34;solr.StandardTokenizerFactory\u0026#34;/\u0026gt; \u0026lt;!-- normalize width before bigram, as e.g. half-width dakuten combine --\u0026gt; \u0026lt;filter class=\u0026#34;solr.CJKWidthFilterFactory\u0026#34;/\u0026gt; \u0026lt;!-- for any non-CJK --\u0026gt; \u0026lt;filter class=\u0026#34;solr.LowerCaseFilterFactory\u0026#34;/\u0026gt; \u0026lt;filter class=\u0026#34;solr.CJKBigramFilterFactory\u0026#34;/\u0026gt; \u0026lt;/analyzer\u0026gt; \u0026lt;/fieldType\u0026gt; 3.6.0以前は、solr.CJKTokenizerFactoryを利用していましたが、3.6.0からはCJKTokenizerFactoryがdeprecatedになってしまい、代わりにStandardTokenizerFactory+CJKBigramFilterFactoryの組み合わせになっています。 exampleのCJKのフィールドタイプ設定を利用して、かつ、そのフィールドにSynonymFilterを利用する場合に、 StandardTokenizerFactoryを指定してしまうと、類義語が展開できなくなってしまうので注意が必要です。\nCJKのフィールドでSynonymFilterを利用する場合は、類義語の設定ファイル内の記述を自力でCJKTokenizerが分割する形で記述する(まぁ、やらないでしょうが)か、deprecatedですが、CJKTokenizerFactoryを利用するのが現時点での対応でしょうか。\nなお、これに絡んで、このようなチケットもできています。\nSyntaxHighlighterを導入してみました。 ちょっとはみやすくなってますかね? まだ、SyntaxHighlighterの設定を調べながら使っているので、コロコロ変わるかもしれないですが、気にしないでください。 ","date":1334592971,"dir":"post/2012/","id":"12d1e0cf7396dd33a9bbbca8da4cbc68","lang":"ja","lastmod":1334592971,"permalink":"https://blog.johtani.info/blog/2012/04/17/solr-3-6-0%E3%81%AEcjk%E3%81%AE%E8%A8%AD%E5%AE%9A%E3%81%A8synonymfilterfactory%E3%81%AE%E6%B0%97%E3%81%AB%E3%81%AA%E3%82%8B%E7%82%B9/","publishdate":"2012-04-17T01:16:11+09:00","summary":"先日、Solr入門のサンプルschema.xmlの3.6.0対応版の作成をしていて、気になったことがあったので、 メモとして残しておきます。 S","tags":["solr"],"title":"Solr 3.6.0のCJKの設定とSynonymFilterFactoryの気になる点(Jugemより移植)"},{"contents":"先日の続きです。「Apache Solr入門」の2章から4章の説明について、Solr3.6.0で動作させる時の変更点を以下に書いていきます。 なお、前回も説明しましたが、3.6.0からKuromojiという形態素解析器がSolrに同梱されるようになりました。 これから説明する2章の変更点の手順ですが、Kuromojiとlucene-gosenそれぞれの利用方法について説明します。 添付のschema.xmlについては、基本的にKuromojiを利用する形に変更してあります。 それに加えて、lucene-gosen用のフィールドを別途追加で定義しました。 これらのフィールド名については、次の表の用になります。 適宜、書籍のフィールド名と置き換えながら読み進めたり、試したりしてください。\nKuromojiフィールド lucene-gosenフィールド title title_gosen author auther_gosen summary summary_gosen intended_reader intended_reader_gosen from_author from_author_gosen toc toc_gosen 2章 2.1.3 schema.xmlのバージョン(27ページ) Solr3.xではschema.xmlのファイルの最新バージョンは**1.5**になっています。\n2.2.3 代表的なトークナイザ(35ページ) solrbook.analysis.SenTokenizerFactoryは必要ありません。 Solr 3.6.0からはKuromojiと呼ばれる形態素解析器が用意されています。 solr.JapaneseTokenizerFactoryがそれに該当します。 これとは別に、lucene-gosenを利用する場合、Solr向けのトークナイザが用意されています。 solr.GosenTokenizerFactoryがそれに該当します。\n2.2.4 代表的なトークンフィルタ(37ページ) 以下の2つについてはKuromojiが同等のトークンフィルタを提供しています。 また、lucene-gosenを利用する場合は、lucene-gosenに同等のトークンフィルタが存在します。\nsolrbook.analysis.KatakanaStemFilterFactory solrbook.analysis.POSFilterFactory 次のものがSolr 3.6.0に用意されているので、こちらを利用します。\nsolr.JapaneseKatakanaStemFilterFactory solr.JapanesePartOfSpeechStopFilterFactory それぞれ、次のものがlucene-gosenにあるので、こちらを利用します。\nsolr.GosenKatakanaStemFilterFactory solr.GosenPartOfSpeechStopFilterFactory 2章向けのschema.xmlはこちらです。その他のtxtファイルについては、特に変更はありません。\n3,4章は特に変更はありません。Solrの起動の仕方にだけ注意してください。(-Dsen.homeは必要ありません)\n以上が4章までの修正点になります。\n昨日に引き続き、眠い目をこすりながら修正したので、おかしいかも。 動かない、意味がわからないなどあれば、コメントorツイートいただければと思います。\n2012/06/14提供しているschema.xmlに関して修正を加えました。こちらの記事で説明しているautoGeneratePhraseQueriesの値をtext_gosen、text_cjkのフィールドに対してtrueを設定する記述を追記しました。\n","date":1334339880,"dir":"post/2012/","id":"d77cdb466c5063b99c5aea58e6da4d32","lang":"ja","lastmod":1334339880,"permalink":"https://blog.johtani.info/blog/2012/04/14/apache-solr%E5%85%A5%E9%96%80%E3%81%AE%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%81%AEkuromoji%E3%81%A8lucene-gosen%E5%AF%BE%E5%BF%9C2%E7%AB%A04%E7%AB%A0/","publishdate":"2012-04-14T02:58:00+09:00","summary":"先日の続きです。「Apache Solr入門」の2章から4章の説明について、Solr3.6.0で動作させる時の変更点を以下に書いていきます。 な","tags":["solr"],"title":"「Apache Solr入門」のサンプルのKuromojiとlucene-gosen対応(2章~4章)(Jugemより移植)"},{"contents":"以前より、アナウンスしていた、Kuromojiという日本語形態素解析が含まれるLucene/Solr 3.6.0がリリースされました。\n以下、各リリース内容について簡単に説明されているページへのリンクです。\nSolrリリースのお知らせ\nLuceneリリースのお知らせ\nSolr 3.6.0の変更の目玉は各言語のAnalyzer/Tokenizerの設定がexampleのschema.xmlに含まれるようになったことです。 Kuromojiという日本語用の形態素解析器もexampleを起動すればすぐに利用できる形になっています。 Kuromojiを利用する場合は、exampleのschema.xmlが参考になるでしょう。\nあと、大きな変更は、Ivyに対応した点です。ソースをダウンロードするとわかりますが、依存するjarファイルが含まれない形に変更されています。 SVNからチェックアウトした場合も同様です。ビルドにはネットワークに接続している環境が必要になりました。\nまた、このリリースに合わせて、以前書いた「Apache Solr入門」のサンプルについての記事も変更が必要かと思い、 前回の記事をベースに以下に変更した記事を書いたので、参考にしてください。 今回は、Kuromojiという日本語形態素解析がデフォルトで含まれるようになったので、 Kuromojiの利用方法とあわせて、lucene-gosenの利用方法も記載します。 サンプルのschema.xmlについては、Kuromoji、lucene-gosenが同時に利用できる形のものを用意しました。\nサンプルのschema.xmlを最新版(Solr 3.6 + lucene-gosen-2.0.0-ipadic)のものを用意しました。 なお、あくまでも、3.xでlucene-gosenを利用する場合の「Apache Solr入門」のサンプルプログラムの変更点(とりあえず、4章まで)の違いについて記述します。 申し訳ございませんが、1.4と3.xの違いについての説明はここでは行いません。\n以下では、各章でschema.xmlに関連する記載のある部分を抜粋して、変更点と変更したschema.xmlのリンクを用意しました。参考にしてもらえればと思います。\n1章 1.6.1 N-gram(17ページ) 1.6.1の手順に変更はありません。 サンプルプログラムが入っているZip「solrbook.zip」のintroduction/ngram/schema.xmlファイルの代わりに こちらのschema.xmlを利用してください。 ※なお、Solr 3.6.0から、SOLR_HOME/example/solr/conf/schema.xmlにデフォルトでN-gramで利用しているCJKTokenizerの設定が入るようになっています。 (実際にはCJKTokenizerではなく、CJKBigramFilterとCJKWidthFilterに変更されています。)\n1.6.2 形態素解析(18ページ~20ページ中盤まで) CJKと同様、exampleにKuromojiを利用した設定がすでに記述されています。text_jaというフィールドタイプになります。書籍の21ページ1行目に記載のある、 「Field」のテキストボックスに入力する文字列を「text_ja」とすると、Kuromojiを利用した形態素解析結果が表示されます。exampleですでに幾つかのフィルタも設定されているため、書籍の出力結果とは異なる表示となるはずです。\nlucene-gosenを利用する場合は手順が大きく変わります。 Senを利用する場合、Senの辞書のビルド、Senのjarファイルの配置、Senを利用するためのTokenizerクラスを含んだサンプルjarの配置という作業があります。 lucene-gosenではコンパイル済みの辞書がjarファイルに含まれています。 また、Solr向けのTokenizerもlucene-gosenのjarファイルに含まれています。 lucene-gosenを利用して形態素解析を体験するための手順は次の流れになります。 なお、schema.xmlについては上記N-gramでダウンロードしたschema.xmlに形態素解析の設定もあわせて記載してあります。\njarファイル(lucene-gosen-2.0.0-ipadic.jar)をダウンロードして、$SOLR/example/solr/lib(libディレクトリがない場合は作成)にコピーします。 コピーが終わりましたら、次のように$SOLR/exampleディレクトリでSolrを起動します。 (-Dsen.homeは必要なし)\n$ java -jar start.jar あとは、書籍の記述にしたがって管理画面のAnalysis画面で動作を確認します。 ほぼ、図1-6と同じ結果になっていると思います。 (lucene-gosenで出力される情報には本書のサンプルよりも多くの情報が含まれています。また、サンプルでは、形態素解析の後の単語に基本形を採用しているため、「な」が「だ」として出力されています。基本形を出力する場合は後述するこちらで紹介したTokenFilterを利用すれば可能です。)\n2章については後日説明することにします(眠くなってきた。。。)\n動作しないなどあれば、コメントください。\n2012/06/14追記提供しているschema.xmlに関して修正を加えました。こちらの記事で説明しているautoGeneratePhraseQueriesの値をtext_gosen、text_cjkのフィールドに対してtrueを設定する記述を追記しました。\n","date":1334339100,"dir":"post/2012/","id":"904b07170a0ce481b7491e7fecce4f79","lang":"ja","lastmod":1334339100,"permalink":"https://blog.johtani.info/blog/2012/04/14/lucene-solr-3-6-0%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9---apache-solr%E5%85%A5%E9%96%80%E3%81%AE%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%81%AEkuromoji%E3%81%A8lucene-gosen%E5%AF%BE%E5%BF%9C1%E7%AB%A0/","publishdate":"2012-04-14T02:45:00+09:00","summary":"以前より、アナウンスしていた、Kuromojiという日本語形態素解析が含まれるLucene/Solr 3.6.0がリリースされました。 以下、各","tags":["solr"],"title":"Lucene/Solr 3.6.0リリース / 「Apache Solr入門」のサンプルのKuromojiとlucene-gosen対応(1章)(Jugemより移植)"},{"contents":"Twitterでこのブログ流れてきて、気になったので、流し読みして簡単にメモ。 Amazonのサービスでスケールする検索サービスみたい。\n主に、機能面です。価格とかはみてないです。\nデータと検索トラフィックに対して自動でスケール(※automaticってのがどういう感じかは調べてないです) CloudSearch APIsでアクセス可能。AWS管理コンソールからオペレーションできる。コマンドツールもある データ登録にHTTPSも使えますよ。データ形式はJSON、XML、SDF(Search Document Format)と呼ばれるものに準拠したもの near real-timeで検索可能になる。RAMにインデックスを保持して更新処理が早くなる(Lucene/Solrと一緒か?) ステミングとかストップワードの設定変えたらre-index ファセット、フィールド指定検索が可能。(ファセットはファセットクエリみたいなのもできるのかな?) データ量が増えたら、サーチインスタンスを追加するか、インスタンスタイプを大きくしてスケールする? トラフィックが増えたら新しいインスタンスにデータをレプリケートしてインスタンスを追加する 簡単に実現できるよ。ファセット検索、全文検索、And/OR検索式、ランキングのカスタマイズ、フィールド指定ソート、フィールド指定検索、テキスト処理オプション(ストップワード、類義語、ステミングのような) ここから詳細のドキュメントが見れるみたいなので、また、見てみます。\nあと、WikipediaをCloudSearchで動かしてるデモとそれに関する記事もあるみたいです。これも暇を見つけて眺めてみます。\n","date":1334241069,"dir":"post/2012/","id":"bed3b7fcc1294e23639057435ac8756a","lang":"ja","lastmod":1334241069,"permalink":"https://blog.johtani.info/blog/2012/04/12/%E3%83%A1%E3%83%A2amazon-cloudsearch%E3%81%8C%E5%87%BA%E3%81%A6%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F%E3%82%88/","publishdate":"2012-04-12T23:31:09+09:00","summary":"Twitterでこのブログ流れてきて、気になったので、流し読みして簡単にメモ。 Amazonのサービスでスケールする検索サービスみたい。 主に、","tags":["備忘録"],"title":"【メモ】Amazon CloudSearchが出てきましたよ(Jugemより移植)"},{"contents":"JavaOne Tokyo 2012に参加してきました。 4/4-4/5の2日間開催されていたのですが、子供が体調を崩してしまい、4/5のみの参加となりました。 4/4はTwitterのTLを眺めて、羨ましがってました。\n7年ぶりに日本で開催されたJavaOneみたいです。 そういえば、7年前くらいに参加した記憶があるなぁと。\n会場入りして最初の感想は年齢層が高いなぁと。 最近、勉強会によく顔を出すようになったのですが、勉強会とは年齢層が少し異なりました。 まぁ、私も年齢層を上げている一人ではあるのですが。。。 Javaも熟成してきてるなぁというのが最初の感想でした。 あと、思ったよりもスーツ率は低かったと思いました。(5割はいましたが) 一番違和感を感じたのは、会場の所々の色が「赤い」ことです。。。\n以下は私が参加したセッションのカンタンな感想です。\nJava EE6 Modeling JS2-01 #jt12_s201\nJavaEEから離れてはや数年。私が関わっていた頃はEJB2.0が出たくらいのタイミングだったので、 色々と変わってきているなぁというのが第一印象です。 CDI、Singleton EJBなど、知らない単語もちらほらと。 earではなく、warファイル1つで済む、jQueryをリソースjarとしてパッケージングしてwarファイルに入れられるなどは簡易になっていいなぁと。 web.xmlがアノテーションで記述できて要らなくなるという話は一長一短だと思いました。 一覧性があるからいいと思うこともあるので。 中国の方?の英語だったので少し特徴的でした。すこしは頑張ってみたものの、やはり同時通訳を聞いてしまって反省しています。。。\nマルチコアCPU時代のJavaプログラミング JS2-14 #jt12_s214\nF社の方が実際に経験されてきた性能関連のプログラミングについての話でした。 現時点のJavaでマルチコアCPUで気をつけるべきプログラミングの観点をわかりやすく説明されたいいセッションでした。 詳細は下のメモを見ていただけるといいですが、色々とプログラミングで気をつけるべき点を説明されていました。 いいおさらいになりましたし、忘れていることや知らないこともあって勉強になりました。 TLでも見かけましたが、モダンJavaプログラミングみたいな、今のJavaでのプログラミングの気をつけるべき点を書いた書籍があるといいかもなぁと思いました。 あと、もうひとつ私が好印象だと思ったのは、F社の製品の紹介などがなかったからかもしれませんw\nサービス維持・発展を踏まえた楽天オークションのJava EEによる開発と運用 JS2-23 #jt12_s223\n楽天オークションの開発をサれている方の立ち上げから現在に至るまでの開発メンバーの管理の仕方や 実際に利用している開発手法、気をつけている点のお話です。 スライドに書いてあること以外のことを発表者の方が話をされており、もう少し、喋る内容に関連した図などを入れてもらえるとわかりやすかったかもしれません。 あとは、WebLogicの管理画面が使いやすくていいという話のあとに、GlassFishに移行していますという話があったりと、少し「?」が浮かぶ部分がありました。。。\nJSR 353: Java API for JSON Processing JS2-33 #jt12_s233\n最近、Twitterで遊んでもらっている(勝手に絡んでいるだけという話も。。。)@yusukeyさんの発表です。 結構な数の立ち見が出るほどの盛況ぶりで、発表者の@yusukeyさんもびっくりしていました。 JSRがどういった形で実際の仕様として公開されていくのかという話がわかりやすく紹介されていて勉強になりました。 所々で笑いが入るなど、さすがの安定感でした。立ち見が出るはずです。 ようやく、JavaもJSONに関する処理を仕様として取り入れようとしているのはいい傾向かと。 ※残念ながら資料は公開されないようです。\nUI Controls and Charts: Drag-and-Drop, Filtering, Sorting, Table Hookup with Charts JS2-42 #jt12_s242\n最近、Chartに興味を持っていたので、登録したセッションです。 内容としてはJavaFXのコンポーネントをリストアップして紹介していくというお話でした。 グラフ(Chart)周りも数種類が用意されるようです。 JavaFXをあまり知らないのですが、Swingをすこしやっていたのでなんとかついていくことが出来ました。 発表者の方が、実際にJavaFX内部の実装を行われている方だったようで、QAでいくつかこんなコンポーネントはないのか?という質問に、「私のPCでは動いているのですが、ドキュメントなどの整備が追いついていないので公開できていないです」という回答が出て、なかなか大変なのだなぁとw Chartに関しては、グラフの重ね合わせなどがまだできないということで、JFreeChartを触ったことがある身としてはすこし物足りなさそうだなぁというのが印象です。\nLearn how the JVM is fundamental to our architecture. BoF2-03 #jt12_b203\n今回JavaOneに参加した一番の理由がこのセッションです。 Twitterのアーキテクチャに関するセッションでした。 思った以上に濃い内容で、ツイートしたデータがどんな流れで登録されるのか、登録されたデータを各ユーザのTimelineにどのようにアクセスして表示しているのかが説明されました。 今回は主にFinagleについての話でしたが、非同期処理をどのように活用しているかというお話でした。 負荷分散を行なっているポイントやキャッシュについての考え方などです。 メモを取るのに夢中になってしまい、英語をヒアリングするという目的を見失ってしまいましたが。。。 期待以上の話が聞けて満足しています。\nパネルディスカッション\n最後はJavaに関連するコミュニティを運営されている方々のコミュニティ運営に関するディスカッションです。 コミュニティの運営の苦労している点や、心がけている点など、運営も大変そうだなぁと。 どうしても長くやっているとメンバーが固定化してしまうという話なども出ていました。 これは難しいですよね。会社も同じことが言えますし。 一番印象に残ったのは桜庭さんの「動くものが作れるのが楽しい」という一言でした。 エンジニアをやってるのは確かにそこが面白いからだなぁと。最近忘れかけているので、もっと色々と作っていきたいですね。\n以上がカンタンな感想です。 少し残念なのですが、事前に参加登録していたセッションについては、マイページと呼ばれるところから資料がダウンロードできるものもあるみたいですが、参加登録してないものについてはダウンロードが出来ない様でした。(4/6現在) 参加できなかったセッションの資料こそ見たいと思うのが普通だと思うのですが、どうでしょう?そのうちどこかに公開されるのかなぁ。\n以下は、いつもの通り個人のメモです。\n場所:六本木ヒルズ アカデミーヒルズ49F 日時:2012/04/05 ○Java EE6 Modeling JS2-01 #jt12_s201 スーツ禁止。Eva好き? ・特徴 Web Profile Pruing POJO、Annotation、Less XML Java EE6の半分のAPIは変更なし。新規が11% ・JavaEE6 Web Profile CDI、Interceptors、JSR 250 Singleton EJB JPAはEntityBeanの代わりかな? ・パッケージングがearではなく、war一つで済むように。 war(ウォーファイル) web.xmlはアノテーションで行えるようになり、要らなくなる。 ◯マルチコアCPU時代のJavaプログラミング JS2-14 #jt12_s214 HotSpotVM依存のお話ですよ。 ・GCとか ・java.util.concurrent.ForkJoinPool デフォルト並列数は論理CPU数 ・メモリアロケーション TLABが非効率に。先にある程度大きめにスレッドに割り当てを行うため、 スレッド数が上がるとTLABが非効率になる-\u0026gt;Eden全体では未使用領域があるんだけどGC発生とか ・JNIでの問題 GetStringCriticalとReleaseStringCritical間はGCが抑止されるため。 ・無意識のロック HashTableやStringBufferなど。 String#getBytes()も。 InetAddress#getAllByName()が内部でキャッシュを持ってる=ロック File#renameTo()も内部でキャッシュ(ExpiringCache)持ってる。 Javaでは時間がかかる処理にはキャッシュを利用するという仕組みなので。スレッド数を増加させる場合は注意が必要 ・フェアネスロック lock = new Object(); for (int i=0;i\u0026lt;100;i++0{ synchronized(lock){ System.out.println(\u0026#34;i=\u0026#34;+i+\u0026#34;tid=\u0026#34;+Thread.currentThread().getId()); } } 上記を実行してもかたよることがあるよ。=フェアじゃない モニターによるスレッド割り当ての説明。 RentrantLockでフェアネスになるよ。 ・性能分析 println()で区間分析。複数スレッドで実行したら実行時間にずれが。 println内部でもsynchronizedを利用している。=ロックのせいで処理時間が遅くなるスレッドが出てきたりする。 JVMTIで性能分析する場合RawMonitorEnter,RawMonitorExitでロックとりあいなるのでもマルチスレッッドだと正しい値がでない。GetThreadLocalStrage使え。 ・まとめ: ハードウェア更改時にプログラムの変更が必要になることもあるよ。 わずかのロックが命取りに(ロックをあんまり使わない、無意識なロックを見極めなさい) ロックポリシーの選択(レスポンス重視なのか、スループット重視なのか) QA Q:事例が合ったという話でしたが、コードの修正しかないんですか? A:はい。やっぱり治すのがいいです。あとは、チューニングですが。。。 Q:ReentrantLockが昔はスレッドダンプにでなかったのですが、今は? A:今は出ます。 Q:各世代とJavaのバージョンのマッピングは? A:第3世代が1.5くらいから。第2世代が1.3とか1.4? ◯サービス維持・発展を踏まえた楽天オークションのJava EEによる開発と運用 JS2-23 #jt12_s223 ・短期で人材が参加できるようにしているというお話 ・楽天オークションの成り立ち(郵政とdocomoと楽天) ・商品、コミュニティ系(出品とか検索とか)と流通系(入出金、配送など)の2軸 ・メンバー30人くらい ミドルエンジニア エンジニア プロデューサー ・楽天市場をベースとして機能追加 ・巨大でリリースが大変に。 ・この5年で機能分解して機能ごとのリリースをめざして改善している ・JavaEEを使う理由 WebLogic上にバッチが動いているなどの仕組みをしている? 管理機能が充実している(WebLogic) ・GlassFishへ移行中 あれ?Weblogicの管理機能がいいんじゃなかったっけ? EJB実装はWebLogicに依存してるのでWebLogicもバージョンアップしてる。 ※メモはここまで。電池の持ちを気にして ◯ JSR 353: Java API for JSON Processing JS2-33 #jt12_s233 ・JSONとは JavaScript Object Notation 「軽量な」データ交換フォーマット ・JSON仕様のグラフ ・XMLもあるのになんで? シンプルで可読性が高い 属性がなく、複雑なスキーマ仕様がない。 ・コンパクト ・Twitter、GoogleMaps、YahooWebServicesなど ・JCP、JSRのお話 JSRの役割とか。 リファレンス実装の話。 ・JSR-353 http://jcp.org/en/jsr/detail?id=353 StAXやDOMに対応するよ。 ・ゴールではないもの JSONをJavaのドメインオブジェクトにバインドするとかもどすとか。 ・メンバー @yusukeyも一人 ・参加になったきっかけ 2011/10にTwitterがJCPに参加 2012/12/6にJSON JSR提出 年越しに採択 @yusukey「これTwitterで重要じゃない?」 @cra 「やりましょう」 ・JSRのコミュニケーション 世界各地の人なので、基本メールベース(今は自己紹介したくらい。。) ・既存のJSONライブラリ json.org、jackson、google-gson ・なんで、いろいろあるのにJSR? 標準化、クラスパスにデフォ、シンプル、ライセンスで悩まないとか。 ・ロードマップ エキスパートグループ作成→アーリードラフト→パブリックレビュー→ファイナルリリース いま、アーリードラフト ・最新仕様 javax.json.* javax.json.spi.* javax.json.stream.* javax.json.tree.* メソッドチェインできるみたい。 JsonObject.create(reader);みたい JsonObject obj = …; JsonWriter writer = obj.accept(writer.) ・改善案 JSON***にしたいな。 spiはらないんじゃないかな?(いま、一個しか無い) treeもいらないんじゃないかな?(そんなに増えないし) parseじゃないかな? メソッド追加(asStringで文字列化とか、create(String)とか) QA Q:JSONのスキーマ決めないの?バリデータとか A:JSONスキーマはあんまりもてはやされてない。一応あるのはある。 さすがの安定感。適宜笑いが入ってて楽しかったです。 ◯UI Controls and Charts: Drag-and-Drop, Filtering, Sorting, Table Hookup with Charts JS2-42 #jt12_s242 ◯JavaFX 2.0のControls ◯Label、Button、ToggleButton、RadioButton、Hyperlink、CheckBox ◯Slider、ScrollBar、ScrollPane、ProgressIndicator、ProgressBar ◯TextField、PasswordField、TextArea ◯新しい機能 TitledPaneとAccordion TabPaneとSplitPane ◯Charts XYChartとPieChart XYChartにはLineChart、AreaChart、BarChart、ScatterChart、BubbleChartがある。 ◯Menu MenuItemの下に色々ある。 CheckMenuItem、RadioMenuItem、CustomMenuItem(SeparatorMenuItemとか) ◯ChoiceBox、ContextMenu、ToolTip ◯ListView ◯2.1の新機能 ComboBox、http://fxexperience.com/2012/03/new-in-javafx-2-1-combobox/ StackedBarChart、 StackedAreaChart MenuBarのMac OSへの対応(窓の中じゃなく、画面上部にちゃんと出る。) LCD Text QA: Q:テキストエリアの日本語入力とかは? A:JavaFX3.0で対応 Q:FXML(Scene Builder)を使ってコードが生成されるのか? A:ドラッグ・アンド・ドロップでやる場合はScene Builderでもできるでしょう。私はNetBeansとかでやりますけどね。 Q:Dialogはいつ対応されるんでしょうか? A:私は使ってるんですけど、JavaFXに入れてもらえませんwコードは出来てますw Q:Chartがありますが、pngやsvgでの出力は可能? A:できません。そのうちできるかも。 Q:Chartの結合はできる?Axisの時間を便利に使うツールはありますか? A:できないです。ありません。 Q:FX2.0でカスタムコントロール作るの大変? A:私のマシンでは動いてるんですがw Q:ChartにCSSを適用することは可能? A:可能です。データはJavaから出力されたものだけですけどね。 Q:JavaFX2.0の起動速度が上がったけど、どういう仕組? A:私は上の方のエンジニアなのでよくわからないですが、GPUをうまく使ってるみたいです。 ◯Learn how the JVM is fundamental to our architecture. BoF2-03 #jt12_b203 Java、Scala、Linuxのカーネルまで担当してます。 ・Twitterのアーキテクチャ ・スパイクが急にあがる場合にも対応できるスケールの話。 なでしこ、#バルス、大震災など ・Twitterはプラットフォーム ・最上位層:HTTP Proxy(Routing) ・中層:Twitter App(Models/Biz Objects、Composition) UserService、TweetService、TimelineServiceに分解(Models/Biz Objects) API(Composition) ・最下層:TimelineStorage、TweetStorage、SocialGraph、UserStorage(Storage/Retrieval) ・NEEDS サーバ負荷をハンドルできる必要がある。 言語のフレキシビリティ(JavaとかScalaとか) 成熟したコンカレンシーモデル ・Java が提供してるもの 開発者のエコシステムが素晴らしい。例:Nettyを使っている。Non-blocking I/O world class JITとコンカレンシーモデル メモリ管理 利点:メモリ管理を意識しなくていい 課題:GC。OpenJDKのコミュニティで参加してる。 複数の言語が実行可能な環境 ・OpenJDKについて ・Finagleのお話。 Netty上に作られた非同期なRPCサーバクライアントのライブラリ http://twitter.gthub.com/finagle/ ・TimelineServiceのお話 340M/day 10K/sec(イベント時) ・ツイートが入ってくる仕組み HTTP Proxy → tweet API → queue → tweet daemon → fanout (social graph)→ delivery → timeline cache → redis ・fanout 4000フォロワーごとにdeliveryにツイートが渡される。 ・Timelineを見る仕組み HTTP Proxy → timeline API(user service、) →timeline service →timeline cache ・timeline、tweets、users ・timeline serviceとtimeline cacheの関係 Finagleで負荷分散している ・timeline serviceからtimeline cacheへのリクエストを監視して、 高頻度のリクエストについては、timeline serviceのin-process cacheに入れる仕組み ・Service[Request, Response] Scalaの記述 service(request).onSuccess {response =\u0026gt; println(\u0026#34;got response! \u0026#34; + response) } ・Finagleのコンポーネント コネクション管理 プロトコルデコード ThriftでService以降がつながってる。 分散トレース オーバーヘッドを抑えて全体を監視(RPCトレース(呼び出しと処理時間のタイムラインチャート)) サービスディスカバリ observability ◯パネルディスカッション ・JGGUG、JRuby、Scala、Groovyのコミュニティ運営に関係している方々によるディスカッション。 ","date":1333698660,"dir":"post/2012/","id":"56d5711303378bd333ddb611a53ece94","lang":"ja","lastmod":1333698660,"permalink":"https://blog.johtani.info/blog/2012/04/06/java-one-tokyo-2012-%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-javaonejp/","publishdate":"2012-04-06T16:51:00+09:00","summary":"JavaOne Tokyo 2012に参加してきました。 4/4-4/5の2日間開催されていたのですが、子供が体調を崩してしまい、4/5のみの参加となりました。 4/4","tags":["勉強会"],"title":"Java One Tokyo 2012 に参加しました。#JavaOneJp(Jugemより移植)"},{"contents":"先日、2.0.0リリースの記事にも記載しましたが、Java7でテストケースが失敗する問題がありました。\n@haruyamaさんと@hideaki_tさんの協力により問題を解消し、trunkと4xブランチにコミットしました。\nissueにも記載しましたが、Java6からJava7にバージョンアップするタイミングで変更されたUnicodeのバージョンが原因でした。 Java6ではUnicodeのバージョンが4.0です。Java7ではUnicodeのバージョンが6.0に変更されています。 今回の問題は「・」(0x30FB)の文字列のCharacter.getType()がCONNECTOR_PUNCTUATIONからOTHER_PUNCTUATIONに変更されたのが原因です。(この変更自体はUnicode 4.1で変更されたみたい) カタカナ文字種の判別をlucene-gosenのnet.java.sen.tokenizers.ja.JapaneseTokenizerのgetCharClass(char c)メソッドで行なっています。 修正前は、ここで、charの範囲が0x30A0~0x30FFにある文字でかつ、Character.getType()がCONNECTOR_PUNCTUATIONでないものがカタカナとして判別されていました。 issueの添付ファイルにJava6とJava7で上記範囲の文字のCharacter.getType()のリストを生成して、該当する文字を探した所、「・」(0x30FB)のみであることがわかりました。 ということで、このコードの意図としては、「・」はカタカナではないと判別したかったのだと。 上記の確認を行えたので、ソースコードを修正してコミットしました。 2.0.1としてリリースするかは、Issue29のボリュームを見て考えますので、もう少しお待ちください。\n参考にしたサイト: JavaSE 7でメソッド名に使えなくなった文字 UNICODE CHARACTER DATABASEのHistory\n","date":1333552800,"dir":"post/2012/","id":"c7937b6b4bde2a96191dc31db913e1ab","lang":"ja","lastmod":1333552800,"permalink":"https://blog.johtani.info/blog/2012/04/05/lucene-gosen%E3%81%AEjava7%E3%81%A7%E3%81%AE%E3%83%86%E3%82%B9%E3%83%88%E5%A4%B1%E6%95%97%E5%95%8F%E9%A1%8C%E3%81%AE%E5%AF%BE%E5%BF%9C/","publishdate":"2012-04-05T00:20:00+09:00","summary":"先日、2.0.0リリースの記事にも記載しましたが、Java7でテストケースが失敗する問題がありました。 @haruyamaさんと@hideak","tags":["lucene-gosen"],"title":"lucene-gosenのJava7でのテスト失敗問題の対応(Jugemより移植)"},{"contents":"先日、宣言したとおり、lucene-gosenのパッケージ名+クラス名の変更を行ったlucene-gosen 2.0.0をリリースしました。 Lucene/Solr 3.6.0のリリースを待つつもりだったのですが、なかなか出ないので先にリリースを行いました。 現時点では、branches/4xについては、パッケージ名、クラス名の修正が追いついていません。 明日までに4xブランチについても修正を反映する予定です。\n参考までに、1.2.1から2.0.0への変更点について以下にまとめました。 また、変更に伴い、Solrのschema.xmlに記述するクラス名も変更になります。 schema.xmlのサンプルについてはこちらをご覧下さい。\n変更点 まずは、パッケージ名の変更点です。 左が旧パッケージ名、右が新パッケージ名となります。\n旧パッケージ名 新パッケージ名 org.apache.lucene.analysis.ja org.apache.lucene.analysis.gosen org.apache.lucene.analysis.ja.tokenAttributes org.apache.lucene.analysis.gosen.tokenAttributes また、パッケージ名とは別に、以下のクラス名も変更になっています。 まずは、org.apache.lucene.analysis.gosenのクラス名の変更点です。\n旧クラス名 新クラス名 JapaneseAnalyzer.java GosenAnalyzer.java JapaneseBasicFormFilter.java GosenBasicFormFilter.java JapaneseKatakanaStemFilter.java GosenKatakanaStemFilter.java JapanesePartOfSpeechKeepFilter.java GosenPartOfSpeechKeepFilter.java JapanesePartOfSpeechStopFilter.java GosenPartOfSpeechStopFilter.java JapanesePunctuationFilter.java GosenPunctuationFilter.java なし GosenReadingsFormFilter.java JapaneseTokenizer.java GosenTokenizer.java JapaneseWidthFilter.java GosenWidthFilter.java 次は**org.apache.solr.analysis**です。 旧クラス名 新クラス名 JapaneseBasicFormFilterFactory.java GosenBasicFormFilterFactory.java JapaneseKatakanaStemFilterFactory.java GosenKatakanaStemFilterFactory.java JapanesePartOfSpeechKeepFilterFactory.java GosenPartOfSpeechKeepFilterFactory.java JapanesePartOfSpeechStopFilterFactory.java GosenPartOfSpeechStopFilterFactory.java JapanesePunctuationFilterFactory.java GosenPunctuationFilterFactory.java なし GosenReadingsFormFilterFactory.java JapaneseTokenizerFactory.java GosenTokenizerFactory.java JapaneseWidthFilterFactory.java GosenWidthFilterFactory.java また、上記クラスに関連するテストクラスの名前も変更になっています。\n以上がクラス名、パッケージ名の対応に関する修正ついてでした。\nまた、現在、Java7にてテストケースが失敗する問題が見つかっています。 こちらの問題の対応版についても近日中にリリースを行う予定です。\n問題点、質問などありましたら、コメントしていただくと回答いたします。\n2012-04-03追記 忘れてました、すみません。今回のリリースで、以下の機能が追加されています。\nAntのパラメータにproxy.user、proxy.passwordの追加 GosenReadingsFormFilterの追加 TokenAttributeの修正(PronunciationsAttributeImpl、ReadingsAttributeImpl) Antは認証が必要なプロキシ環境で辞書のビルドを実施するときにユーザ名、パスワードを指定できるようにしました。\nGosenReadingsFormFilterは単語を読みに変換するTokenFilterになります。 よみは、辞書に登録してある読みになります。オプションとして、romanizedが指定可能です。指定をすると、よみをローマ字に変換します。\nTokenAttributeの修正は、バグフィックスになります。Issueはこちらです。\n","date":1333362120,"dir":"post/2012/","id":"06731164684f90f33ce4017eca9d8ec1","lang":"ja","lastmod":1333362120,"permalink":"https://blog.johtani.info/blog/2012/04/02/%E9%87%8D%E8%A6%81lucene-gosen-2-0-0%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9/","publishdate":"2012-04-02T19:22:00+09:00","summary":"先日、宣言したとおり、lucene-gosenのパッケージ名+クラス名の変更を行ったlucene-gosen 2.0.0をリリースしました。 Lucene/Solr","tags":["lucene-gosen"],"title":"【重要】lucene-gosen 2.0.0リリース(Jugemより移植)"},{"contents":"lucene-gosenを利用して頂いてる皆様に連絡があります。\n連絡事項 次期lucene-gosenのリリース(2.0を予定)にて、org.apache系のパッケージ名および、クラス名の変更を行います。 Lucene/Solrの次期リリース版である3.6.0以降では、lucene-gosen 2.0(予定)を利用するようにしてください。\n経緯 Twitterでは少しずつツイートしていますが、Lucene/Solr 3.6から日本語の形態素解析器がLucene/Solrにて用意されることになりました。 ベースとなっているのは、Atilika社が開発したKuromojiという形態素解析器です。 Lucene/SolrにコントリビュートされたタイミングではKuromojiAnalyzerなど、Kuromojiという名称が残った形で取り込みが行われました。 その後、LUCENE-3909にて、Kuromojiではなく、一般的な名称(Japanese*)に変更する提案が行われました。 この提案で、luene-gosenが利用しているクラス名、パッケージ名と大半のクラスが衝突してしまうこととなりましす。 今後も、lucene-gosenを利用していただけるように、lucene-gosenのIssueを発行し、 現在、lucene-gosenのtrunkにてパッケージ名の変更及びクラス名の変更作業を行なっています。 正式にリリースするタイミングになりましたら、再度連絡いたします。\nブランチなどについて 現時点ではパッケージ名、クラス名の変更はリポジトリの以下のものについてのみ作業を行う予定です。\ntrunk branches/4x 現時点でのリリース版(1.2系)のソースについてはbranches/rel-1.2にて、これまで同様のクラス名、パッケージ名のまま変更を行いません。 1.2系についてはこちらをご覧下さい。\nまた、当ブログにて、提供しているSolr入門のサンプルに利用可能なschema.xmlなどの記事についてもLucene/Solr3.6がリリースされた際には再度修正して掲載いたします。 Kuromojiの利用方法もあわせて記載したいです。\n参考: lucene-gosenとKuromojiの機能などの比較についてはこちらを参考にしてください。\n","date":1332783540,"dir":"post/2012/","id":"f8327953a0f0b80011b939111807999a","lang":"ja","lastmod":1332783540,"permalink":"https://blog.johtani.info/blog/2012/03/27/%E9%87%8D%E8%A6%81lucene-gosen%E3%81%AE%E6%AC%A1%E6%9C%9F%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/","publishdate":"2012-03-27T02:39:00+09:00","summary":"lucene-gosenを利用して頂いてる皆様に連絡があります。 連絡事項 次期lucene-gosenのリリース(2.0を予定)にて、org.","tags":["lucene-gosen"],"title":"【重要】lucene-gosenの次期リリースについて(Jugemより移植)"},{"contents":"子供の寝かしつけしてたら、寝かしつけされてしまって、2時に目が覚めてしまいました。 TSUTAYAでCD借りてきてウォークマンに入れようと思っていたのに。。。 ということで、今作業してます。\nMBAを買う前から使っている、もう9年目のWindows自作デスクトップで基本的にはCDの取り込みをしています。 ファイルサーバ(BuffaloのTeraStation)がLionから接続できないというのと、 X-アプリで曲管理していたのでという理由です。 あと、ウォークマンなのでMac用のソフトがなかったりというのも理由です。\nで、眠い目をこすりながらWindowsマシンを起動すると、ネットワークにつながらないじゃないですか。。。 再起動してもダメでした。\nとなってしまったので、せっかく、譲ってもらったMac miniも活用しないといけないなと思い、iTunesでアルバムを取り込んでみています。 ここ数年はWAV形式でデータを取り込んでいたので、WAVでの取り込みを設定して、iTunesで取り込みました。\nとまぁ、ここまでやってから、件のWindows機を再度、再起動したらネットワークに繋がってしまいました。。。 なので、残りのCDはWindows機で取り込みしてます。 けど、そろそろこのPCも危なそうなので、データをサルベージして、Mac miniで作業できるようにしないとなぁ。 Macでウォークマンを運用している人はどうやってるんだろう? ちなみに私が利用しているウォークマンはNW-A847です。 エンコードはWAV形式で取り込んで、X-アプリでウォークマンに入れています。 iTunes使ってる人は、アップルのロスレスエンコードをつかってるのかなぁ? ということで、調査・検討したい項目はこんなところですか。\n調査:TeraStationにMacからつなぐ方法(Lionで利用できそうなソフトなにかないかな?) 調査:iTunesでウォークマンに曲転送(やってみればすぐわかるだろう。。。) 調査:iTunesの曲をCDに焼く方法(車で曲聞くのにCDだから) 検討:ファイルサーバのリプレース対象となる機種(ファイルサーバは導入してまだ5年だから余裕がないと買い換えない) 検討:iPodに鞍替え(Sony好きだし、ウォークマン好きだし、買ったばっかりだからまず無い選択肢) 検討:Mac miniにVirtualBox入れて、WindowsからX-アプリ使うとか。(ファイルサーバが見えるようになるかな?) 検討:Mac miniをWindowsとして運用(もったいなさすぎる気がする) とまぁ、まだ悩んでるだけで、取り留めもない事を書いて、しかも結論が出ないままですが、ご容赦ください。 ご意見、提案を大募集してます!!\n","date":1332618420,"dir":"post/2012/","id":"8b76101d185700a8efed148d8722d926","lang":"ja","lastmod":1332618420,"permalink":"https://blog.johtani.info/blog/2012/03/25/%E4%B9%85%E3%80%85%E3%81%ABmac-mini%E3%81%AE%E3%81%93%E3%81%A8%E3%81%A7%E3%82%82/","publishdate":"2012-03-25T04:47:00+09:00","summary":"子供の寝かしつけしてたら、寝かしつけされてしまって、2時に目が覚めてしまいました。 TSUTAYAでCD借りてきてウォークマンに入れようと思っ","tags":["備忘録"],"title":"久々にMac Miniのことでも(Jugemより移植)"},{"contents":"はい。またまた、Twitter API勉強会に参加してきました。(今回から開催回数の記載がなくなった?) 今回は直前でタイムテーブルが変わってしまう波乱がありましたが、個人的には楽しめる内容でした。 Twitterの国際化や形態素解析などの話が聞けたのがすごく面白かったです。 アーキテクチャや利用されている形態素解析器の話など、また、現状の問題点なども話が聞けました。 日々、進化しているんだなぁと。 残念ながら、発表者の方が懇親会にいらっしゃらなかったので、詳しく聞けませんでしたが、挨拶だけは出来ました。 実際のテスト環境や導入方法、A/Bテストとかやってるのかなど、ブログをかきながら色々と気になることが出てきてしまいますw 頭の回転がよくないので、話を聞いてる間は質問があんまり思い浮かばなかったなぁ。。。\nその他にも(使ったことなくてすみません。。。)「昼会」のサービスの話、他の言語でのTwitterの活用の話も聞けました。\n途中で帰ってしまいましたが、懇親会でも数人の方とお話できて、楽しかったです。 (今回の懇親会会場はちょっと人数の割に手狭だったかもなぁ)\n次回は4月末を予定しているようでした。今度こそ、利用規約の話になるんですかね? 忙しさを見つつ、また参加しようかと思います。\nということで、いつものメモです。\n開催日時:2012/03/21 19:00 ~ 21:00場所:ハロー会議室shibuya Zusaarのページ\n◎Twitterの日本語検索、ハッシュタグについて @keita_f\n◯アーキテクチャ ・Twitterバックエンドの国際化 Before 各言語ごとに独自実装。 After 共通テキスト処理ライブラリ:Penguin ・アーキテクチャ:検索 Firehose → ingester → Earlybird ⇔ Blender ← ユーザの検索 Firehose:ツイートの受信 ingester:ツイート解析 Earlybird:Luceneベースのインデクサ Blender: ・アーキテクチャ:トレンド TrendsはGeo(ユーザ位置情報)を利用してるっぽい。 Term Statisticsは過去ツイートからHadoopで頻出フレーズを解析する。 今頻出しているフレーズ+過去頻出しているフレーズ ◯日本語関連 ・ツイートの言語判定 言語判定にはIndigenous Tweets(Kevin Scannell)をベースに実装。 50言語サポート、Javaで実装 ・文字種チェック ・エンコーディングチェック ・Ngram(the→英語、das→ドイツ語) 問題点: 2つ以上の言語が混じってる場合 絵文字が入ってる場合 Unicodeアルファベット ・形態素解析 日本語:Gomoku 中国語:LuceneのSmartCN その他:N-Gram 問題点: 形態素が小さすぎる →そのままだと細かすぎるので品詞情報を元に大きめに区切るようにしている iPhone4Sなどが数字で区切られる →ASCIIの数字とアルファベットは連結しなおす ・フレーズ抽出 他の言語もあったけど、キー入力間に合わず 日本語の場合: トークンに分割 トークンでNgramを生成 品詞情報を使ってフィルター 最初、最後が助詞はNG、接頭詞で終わるのはNG ・やりたい事はまだまだたくさん ・形態素解析の品質向上 辞書への単語追加 韓国語、タイ語のトークなイザー ・同義語、類義語、翻訳、音訳、略語などのサポート ・フレーズ・トピックのクラスタリング ・Sentiment Analysis ・日本語のできるエンジニア募集中w QA Q:顔文字を手動で抜き出すと言われたんですが、どのくらいあるんでしょうか? A:正規表現なので、なんとも言えませんが、パターンを Q:Gomokuの選択の理由は? A:Javaだから。jarに辞書が入るから。スピードが出るから。 ◎ランチタイム共有サービス「昼会(http://www.hirukai.jp/)」のご紹介 @setomits\n◯前提 ・ネットワーキングは重要 ・出会いも重要 ・飲み会だとコスパが悪い ◯ランチだと ・金額が限られる ・必ず食べる ということで、昼会だ! ◯画面でサービスの説明 パブリックな昼会、プライベートな昼会がある。 ◯なんでTwitter? LinkedInのOAuthを使ったログイン検討してた。 ビジネス目的+ 敷居が高いのでTwitterに変更 ◯Twitterのapiで利用しているものなど ◯ユーザの声 ・DMを使ってる=自分からのDMが気持ち悪い APIの使用制限やフォローしてもらう必要があるのが辛い。 - スパムかと思った - 乗っ取られたかと思った。 - エンジニアからは、「まぁ、こうするよね」 ・OAuthについて - ユーザ登録しなくていいのは嬉しい - イベント参加のためにOAuthでの書き込み権限まで与えたくない ◯8ヶ月経って ・新しい出会いがあった ・昼会を開催する敷居が高い =なかなか使ってもらえない ◯今後の計画 募集中! QA Q:AppEngineで月額どのくらい? A:料金改定前:数千円/1ヶ月、料金改定後:2万円くらい/1ヶ月 処理数を減らして、現時点では数千円/1ヶ月に最適化した Q:夜会はないんですか? A:設計していたら、出会い系サイト?になりそうなので、昼にした。 ドメイン的になぁ。まだ悩み中 Q:GAE特化したもの?AWSに移行できる作り? A:できない作りです。(pythonで書いてます。) GAEが楽なので、移行可能な作りにするのがつらい。 ◎LT ◯Twitter 4 contact @inda_re ・広告!アジャイルサムライの道場\n・問い合わせフォームをTwitterにしちゃう 今あるHTMLにフォームを入れる方法(MySQLとPHP) githubにサンプルあるよ。 ◯PerlのTwitterモジュールについて @xtetsuji\n・前回出席したら、ムチャぶりが! ・いまどきのPerl 進化してるよ、古い情報が検索で出てきてしまうのがネック ・perlbrewってのがある http://perlbrew.pl/ ・AnyEvent::Twitter::Streamをよく使ってます。 ・gistにサンプルあげてあるよ! ◯KotlinでもTwitter4J @ngsw_taro ・Kotlinの説明 ・以下のサイトでインストールしなくても動かせるよ! http://kotlin-demo.jetbrains.com/ ・NULL安全 Nullを許容する型、許容しない型がある。 ・一応、Twitter4Jのサンプルも作ったけど、ブログ見てね http://d.hatena.ne.jp/ngsw_taro/\n◯締め Twitter API勉強会ではスピーカーを常に募集中です。登録はこちら!\n","date":1332343680,"dir":"post/2012/","id":"16b3c9445539e9274282a612dea354c2","lang":"ja","lastmod":1332343680,"permalink":"https://blog.johtani.info/blog/2012/03/22/%E7%AC%AC5%E5%9B%9E-twitter-api%E5%8B%89%E5%BC%B7%E4%BC%9A--%E6%B8%8B%E8%B0%B7--twtr_hack/","publishdate":"2012-03-22T00:28:00+09:00","summary":"はい。またまた、Twitter API勉強会に参加してきました。(今回から開催回数の記載がなくなった?) 今回は直前でタイムテーブルが変わってし","tags":["勉強会"],"title":"第5回 Twitter API勉強会 @渋谷 #twtr_hack(Jugemより移植)"},{"contents":"TLで面白いと見かけて、Amazonで買ってしまいました。 SEやってるのに、つい最近Amazonを使い始めた軟弱者です。 それにしてもAmazon危険です。スマートフォンにAmazonの Androidアプリを入れたのですが、これがまた、レコメンドに面白そうな本が出てきて危険です。\n話がそれてしまいましたが、面白い本でした。 久々に、小説でも技術書でもない本を短期間で読みました。 「箱」と呼ばれる概念の中と外について、とある会社に転職した管理職の人が学んでいくという物語風の作りです。 いくつか、自分の経験にカブるシーンがあったので、サクサク読めました。 今までの自分になかった考えである「箱」という視点が得られたのがよかったです。\nただ、いくつか気になる点もあるので、また少し時間を開けてからサラっと流し読みしたいと思います。\nあと、すこしだけ、キリスト教チックな考え方でもあるかなぁと思う部分もありました。(キリスト教をちゃんと勉強してるわけではないので認識が間違ってるかもしれないです)\n人によっては共感出来なかったり、読みにくかったりすると思いますが、私は面白いと思った本でした。 なんとなく、人間関係に違和感を感じていることがある場合は目を通してみるといいかもしれません。\nTwitterで読み終えたというツイートをしたら、「自分を変える気づきの瞑想法」を読むとまた面白いですという@ツイート(これがmentionの日本語の正式名称らしい?)を@ledsunいただきました。 箱に入る原理が別の視点で書かれているようです。 読んでみたいです。(本会過ぎてる気がするので、図書館で探そうかなぁ。。。)\n自分を変える気づきの瞑想法【増補改訂版】 自分を変える気づきの瞑想法【増補改訂版】 ","date":1332253920,"dir":"post/2012/","id":"ee623aaa99b429863f89da313fffed97","lang":"ja","lastmod":1332253920,"permalink":"https://blog.johtani.info/blog/2012/03/20/%E8%87%AA%E5%88%86%E3%81%AE%E5%B0%8F%E3%81%95%E3%81%AA%E7%AE%B1%E3%81%8B%E3%82%89%E8%84%B1%E5%87%BA%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%E3%82%92%E8%AA%AD%E3%81%BF%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-03-20T23:32:00+09:00","summary":"TLで面白いと見かけて、Amazonで買ってしまいました。 SEやってるのに、つい最近Amazonを使い始めた軟弱者です。 それにしてもAmaz","tags":["読書"],"title":"「自分の小さな「箱」から脱出する方法」を読みました。(Jugemより移植)"},{"contents":"えーと、ブログ更新してないなぁとふと思ったので。 1年前くらいからずーっと、つぶやいてましたが、やっとScalaを始めました。 長かった。。。 とある、サンプルデータを作成するので、ついでにScalaを勉強してしまえという感じで始めました。\nScalaで学ぶ関数脳入門を買ってもう1年以上経ってました。。。 とりあえず、CSVデータからInsert文を作ってます。 書籍を見ながら、四苦八苦してるところです。 今日は、csvファイルを読み込んで適当に出力した所で終了でした。 現状を忘れないようにというのと、いくつか気になった点があったので、備忘録のため上げておきます。\nscala IDE for Eclipseを利用(もっさりしてる) classとは別にobjectというものがある点に慣れない セミコロンいらないのに、ついつい打ってしまう usingを利用しようとしたが、Eclipseに怒られた(なんで?) メソッドの戻り値を省略出来る場合とできない場合がよくわかってない Javaが混ざる(ファイル出力にBufferedWriterを使う)のがまた戸惑う ということで、四苦八苦してますw 7つの言語、7つの世界も参考にしつつ、コップ本をパラパラしながら、ググって書くといった感じです。 Javaだととっくにできていると思うのですが、まだ、読み込んで出力できただけです。\n新しいものに触れるのは頭を使って面白いのですが、思い通りに行かず(とくにIDEがもっさりしてたり、上手く使えなかったり)イライラもしていますw まぁ、ちょっとずつ勉強していきます。\n(ほかにもいろいろやらないとなぁ。。。)\nScalaスケーラブルプログラミング第2版 Scalaスケーラブルプログラミング第2版 ","date":1331652421,"dir":"post/2012/","id":"116c9be6d760b4befa6d51ce9e96604c","lang":"ja","lastmod":1331652421,"permalink":"https://blog.johtani.info/blog/2012/03/14/scala%E5%A7%8B%E3%82%81%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-03-14T00:27:01+09:00","summary":"えーと、ブログ更新してないなぁとふと思ったので。 1年前くらいからずーっと、つぶやいてましたが、やっとScalaを始めました。 長かった。。。 と","tags":["Scala"],"title":"Scala始めました(Jugemより移植)"},{"contents":"森ビルに行ったことなかったので、参加してみました。 あと、最近まともにコーディングしてないので、そのへんを矯正するためにもと思って。 (まぁ、遊びに行きたかっただけなんですけどね)\nすこし遅刻して参加です。 会場は、Twitter Japanさんの@yakitoriでした。ここだけ、撮影可でした。 で、肝心のハッカソンの中身です(ハッカソン自体、初参加!)。 Twitter APIもTwitter4Jも触ったことがありません。 なので、ソファーに座ってMac Book AirでTwitter4Jのサンプルを眺めながら、とりあえず、Solrに流しこむってのを作ってみました。 今回、Solrに用意したのはlucene-gosenによる形態素解析を行うフィールドとあとは、Solrのexampleについてるダイナミックフィールドたちです。 Twitter4Jからどんなデータが取れるかわからないので、ダイナミックフィールドで型だけ指定してSolrを起動しておきます。 次に、Twitter4Jにあるsample()にてパブリックなツイートの1%を取得(適当なのがこれくらいしか思い浮かばなかったから)。 あとは、SolrJのStreamingUpdateSolrServerを利用して、流し込みです。 あんまり時間がなかった(準備とかウォーミングアップで時間かかった)ので、結局、Screan名とツイート本文を SolrInputDocumentに無理やり詰め込んで登録しただけでした。 ほかにも色々と情報が取れるはずなので、そのへんも格納してファセットとかで遊びたかったなぁ。 とまぁ、こんな感じでタイムアップです。(コードは大したことないので文章だけでw) 画面も用意出来なかったので、発表はSolrのダサい管理画面で検索でした。 次回は、もう少し中身を勉強して画面もbootstrapで作ってとかやってみたいですね。 あと、自己紹介スライドに書きましたが、Scalaから使ってみるのもやってみたいです。(その前に、Scalaに入門しないといけないんですけど。。。)\nということで、個人的にいろいろと反省点があるハッカソンでした。 反省点:\n立ち上がりに時間がかかった(普段からコーディングしてないから) Twitter4Jについて事前に勉強してない(ごめんなさい) 環境面が整備しきれてない Twitter API ポケットリファレンス(右の本)を忘れた。。。 スターウォーズのピザの箱の写真取り忘れた>< 普段、コーディングをしていない仇が出てしまいました。 もっと、すぐにコーディングをできる環境、体質を日頃から鍛えておかないといけないなぁと。 (SolrやTwitter4JのJavaDocをオロオロしながら探すとか情けないです。。。)\n場所や雰囲気は全然問題ありませんでした。 ピザを@yusukeyさんからごちそうになったり、飲み物、お菓子が用意されていたりと至れり尽くせりでした。 iPadで音楽も流してくれてたし。 他のハッカソンに参加したことないので比較はできないですが、集中できてよかったです。 あと、ソファーでコーディングもなかなかいいなぁと実感出来ました。(初めて!) 人数的にもこのくらいのほうが話がしやすくていいかなぁと。発表も時間かからないですし。 ただ、帰り道に誰かが言っていましたが、「マラソンというよりは短距離走だったね」というのは否めないかなぁと。 時間は限られちゃうので、準備をしっかりしないとなぁと。 私としては、土日のハッカソンだと参加しづらいので、平日開催がうれしいのですが。 いやぁ、楽しかったです。みなさんの面白いネタも見れたし。(自分のやったのは普通すぎて少し恥ずかしかったです。。。) あと、GoogleDocsの使い方(自己紹介スライドとかアンケートの集計とか)も学べたのが収穫でした。 @yusukeyありがとうございます! 次回もありそうなので、懲りずに参加しようかな。\nさて、他の方たちのブログやtogetterは@yusukeyさんのページからたどってくださいw。 第0回Twitterハッカソンを開催しました #twtr_hack\n今日購入したCD聴きながらブログ書いてます。 タワレコで視聴して購入したCDです。 なかなか大人な雰囲気でオススメです。 Heaven ","date":1331230200,"dir":"post/2012/","id":"4d6c95b0b3ea2ddb30fdd3edf3b82391","lang":"ja","lastmod":1331230200,"permalink":"https://blog.johtani.info/blog/2012/03/09/%E7%AC%AC0%E5%9B%9E-twitter-hack--twtr_hack-%E3%81%AB%E9%81%8A%E3%81%B3%E3%81%AB%E8%A1%8C%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-03-09T03:10:00+09:00","summary":"森ビルに行ったことなかったので、参加してみました。 あと、最近まともにコーディングしてないので、そのへんを矯正するためにもと思って。 (まぁ、遊","tags":["勉強会"],"title":"第0回 Twitter Hack #twtr_hack に遊びに行きました。(Jugemより移植)"},{"contents":" Clean Coder プロフェッショナルプログラマへの道 Clean Coderを読みました。 理由はTwitterで「Clean Code」がいい本だと流れてきたためです。 「Clean Code」はまだ読んでいないのですが、クリーンなコード(メンテナンスしやすく、修正などもやりやすいコード?)を書くために必要な話が書いてあるのだと思います。(まだ妄想)\nそして、何も考えずに、「Clean Code”r”」という本が新しく出ていたので、新しい方に手を出しました。 まぁ、軽い勘違いですw(コードの構造の話などは出てこなかったです。) それほど分厚くなく、軽く読めそうだということで読み進めると軽い衝撃を受けました。 Clean Coderはプロのプログラマとして、どのような意識を持つべきか、立ち居振る舞いをするべきかなどが書かれています。 「~したい」はまず守らない約束だという話、ユニットテストを書くことはプロとして当たり前の行為だ、目的意識を明確に持つことなどなど、耳の痛いことが色々と書かれています。 これは、著者の方(パンチカードのころからコーディングをされている!)の実体験を元に、失敗した経験から導きだされているようです。 ところどころ、古くてよくわからない話やちょっとだけしっくりこない表現(ビジネス、QAといった単語)もありましたが、概ねわかりやすい話でした。\n基本的にはアジャイルなスタイルの開発を行うプログラマ(設計書に基づいてコーディングするだけの人ではない)について書かれています。 この本を読んでいて、昨年、仕事をご一緒させていただいたRubyistの方たちの開発スタイルを思い出しました。 私よりもこの本に書かれているプロに近いなぁと。 ペアプロやったり、実装方法について相談していたりと。\n勘違いでしたが、良い本に出会えて本当によかったです。 私もこの本に書かれているようなチームでのプログラミングをやりたい、またなにかコーディングをしたいという気にさせてくれました。(「~したい」じゃダメって書いてあったのに。。。) 自分を戒めるためにも、定期的に読み返したい本です。 プログラマでいたい方、ある程度プログラミングができるようになってきた方にはぜひ読んでいただきたい本です。 (この流れで、アジャイルサムライやClean Codeを読んだら理解が深まりそうだなぁ)\n参考URL: 35歳定年説をブチ破れ!「Clean Coder プロフェッショナルプログラマへの道 Robert C. Martin」 - ledsunの日記 ","date":1330704840,"dir":"post/2012/","id":"10eb415a232ad4be7d05c57eb850036c","lang":"ja","lastmod":1330704840,"permalink":"https://blog.johtani.info/blog/2012/03/03/clean-coder%E3%82%92%E8%AA%AD%E3%82%93%E3%81%A0/","publishdate":"2012-03-03T01:14:00+09:00","summary":"Clean Coder プロフェッショナルプログラマへの道 Clean Coderを読みました。 理由はTwitterで「Clean Code」がいい本だと流れてきたためです。","tags":["読書"],"title":"Clean Coderを読んだ(Jugemより移植)"},{"contents":" 親子で楽しめる 絵本で英語をはじめる本 Twitterでこの本について書かれたブログ記事が流れてきて、購入しました。\n最近、英語を身につけておいたほうがいいなと思うことが多々あり、子供にも英語を勉強してもらいたいなと思っていたところでした。 あとは、私自身が英語が苦手というのもあり、子供をダシにして勉強したいというのもありまして。。。 サラっと読んでみましたが、参考になりました。 特に「多読」というキーワードが面白かったです。こちらが元のようですが。 多読とは、文章を分析しないで大意を把握する読書法だそうです。\n辞書を引かずに楽しめるものを読む わかるところをつなげて読む 自分が面白いと思う本を選んで読む という原則があるようで、確かにいいなと思いました。 絵本だと絵が書かれているので、辞書を引かなくても想像できそうですし、楽しめそうだなぁと。 また、多読は先日読んだ、速読の本に書かれていた本の読み方にも通じるものがあるなと。(まだ、実践できてないんですけどね)\nどうしても英語を勉強させたい!、勉強しないと!と思ってしまいがちですが、この本にも書いてあるように楽に楽しんでやったほうがやっぱいいなぁと。 楽しくないと続かないですからねぇ(実際、何度も挫折してるし、押し付けられるとヤル気がなくなるので。。。)\nということで、実践してみようと思います。(平日は子供が寝てしまってから帰宅なので、まずは土日から)子供のためというよりは、自分の英語の勉強のために。 まずは、簡単な絵本を購入して。 この本の後半半分は、著者の方の感想や説明がついた、オススメの絵本50冊が書かれています。 英語の絵本を入手するのは、結構大変(実際に売ってる店もなかなかないし、手にとって見る機会も少ない)だと思うのですごく参考になりそうです。 いくつかピックアップして、あわよくば本屋で手にとってみようかと。なければ、Amazonで購入しようかなぁと思ってる所です。\n","date":1330186800,"dir":"post/2012/","id":"627a0c45dd07150343c81d856855590e","lang":"ja","lastmod":1330186800,"permalink":"https://blog.johtani.info/blog/2012/02/26/%E8%A6%AA%E5%AD%90%E3%81%A7%E6%A5%BD%E3%81%97%E3%82%81%E3%82%8B-%E7%B5%B5%E6%9C%AC%E3%81%A7%E8%8B%B1%E8%AA%9E%E3%82%92%E3%81%AF%E3%81%98%E3%82%81%E3%82%8B%E6%9C%AC/","publishdate":"2012-02-26T01:20:00+09:00","summary":"親子で楽しめる 絵本で英語をはじめる本 Twitterでこの本について書かれたブログ記事が流れてきて、購入しました。 最近、英語を身につけておいた","tags":["読書"],"title":"親子で楽しめる 絵本で英語をはじめる本(Jugemより移植)"},{"contents":"今週も勉強会に参加しました。 @yusukey さんが開催してるTwitter API勉強会です。 前回とは会場が異なりましたが、広くて大画面で良い会場でした。駅も近いし。(デジタルハリウッドさいこー!) 今回はLT枠のbootstrapの話が聞きたくて参加しました。(ムチャぶり駆動勉強会の現場をTLで目撃してたのでw) あと、バーチャファイター(昔、VF目当てでセガサターンを買ったなぁ、懐かしい)の話も聞きたかったので。 (ごめんなさい、Twitter APIはまだ触る機会がなさそうです。。。) 今回も途中で参加者同士を数グループ(座席が近い人)に分けて自己紹介タイムがあり素敵でした。 ちょっと残念だったのはネームプレートが今回はなかったことでしょうか。 自己紹介でツイッターID教える+聞くのがちょっと辛かったです。(やっぱり個人名刺作ったほうがいいかなぁ) 私はPCを開いていたのでTwitterのページを見せることで対応出来ましたが。 (次やるときはお手伝いするのでこえかけてください。)\n内容はメモをとってあり、下に書いてますので見ていただければ。\nTwitter APIの説明はいろいろ新鮮でした。今回はWebページに貼るリンクやボタンの話でした。 カスタマイズも出来るようになってるってのは知りませんでした。Webサイトやってる人は簡単にカスタマイズできるのは便利ですよね。\nバーチャファイターのTwitter連携の話は結構詳細な話が出てきてびっくりでした。(テーブル名とかまで出てきましたw) ゲーム筐体の前のユーザの動きまで考えてシステム作るとかすごいなぁとか。違う業界の話って面白いです。\nBootstrap入門はbootstrapの紹介だけじゃなく、Tips(bootstrap弊害とかw)やその他の便利なサイトの紹介までありました。 スライドもあとから読んでもわかるのがすごく嬉しいです。時間を見て試してみます。 TwitterSphereは懇親会でもデモが見れました。Groovyは名前を知ってるだけだったのですが、Swingとかまで動くんですね。(JVMだから当たり前なんだけどなんか新鮮。) 最後はAndroidのAPI Demoのお話。こちらも普段Android携帯使ってるのに知らないことが多くて。。。 Macでもデモが動くんですね。やっぱり動くものを作ってLTするのって素晴らしいですねぇ(なんか作るかー)\nとまぁ、最近はキーワードだけ知ってて、いろいろ触れてもいないものが多いなぁと思ってたところに、 今日の勉強会で色々見れて面白かったです。 Twitterがいろんな人に興味を持たれているのがわかります。 (けど、Twitterってどうやって儲かってるんだろう???) 懇親会は、入り口からは想像できない貸パーティースペースで素敵でした。 開始の乾杯の音頭を取ることもできましたし(もちろん、ムチャぶり)。 学生が多かったのですが、声をかける暇なく懇親会が終わってしまったのが少し心残りですかねぇ。 毛色が違うメンバーが居て面白いので、次回も空きがあれば参加しようと思います。 スタッフとかお手伝いもしますので。\nということで、いつものメモです。\n開催日時:2012/02/23 19:00 ~ 21:00 場所:デジタルハリウッド東京本校 1Fセミナールーム Zusaarのページはこちら。他にも学生枠とかありました。\n◯ Webサイト向けAPI @yusukey\n・Webサイト向けAPI フォローボタン、ツイートボタン、Web Intents、@Anywhere サーバサイドの実装扶養、htmlのみで構成可能 ・Twitterボタン Twitterのサイトで色々カスタマイズ可能なボタンが作れます。 ツイートのカウント表示とか。 ・Web Intents @ツイート、リツイート、お気に入りが簡単にできるものが作成可能。 ツイートの埋め込み用リンクがTwitterのWeb版のツイート詳細から生成可能。 「このツイートをサイトに埋め込む」リンクをクリックするとダイアログが出てきます。 ・@Anywhere あんまりフォローされてないけど、JavaScriptでサーバサイドなしにTwitterと連携可能。 ユーザIDを辞書的に検知してTwitterの情報をホバーで出してくれる。 ・ウィジェット(検索、プロフィール、お気に入り、リストなど) これもTwitterサイトでカスタマイズ可能。 ・ツイートボタンには公式ロゴを利用しましょう ・注意点 charsetを必ず指定しましょう。 IE/Firefoxで問題が発生します。 ◯ グルーブに分かれて簡単に自己紹介\n◯ デジタルハリウッドよりご挨拶\n◯ 「Virtua Fighter5 Final ShowdownのTwitter連動機能について」@twtrfk\n部内にAmitterというSNSを構築して自由に使ってもらって、Twitterを疑似体験してもらった。 VF5FSでの開発中はTwitter4JにAmitterのラッパーを追加してテストしてたらしい。(おもしろいなー) 当時は、筐体にツイート機能を入れることも考えていたらしい。 ツイート自体はバッチで処理してます。 ゲーム筐体にお客さんが座ってる時間もシステムの性能として考慮しないといけない。 苦労した点: テストアカウントを100個地道に作成(連番、内容がバレるアカウント名はNGだから) Twitter4Jがうまく動かなかった。。。 今後の展開: まだ未定 QA Q:FB連携とかは? A:今は考えてないです。 ◯ LT ・ @making「Twitter Bootstrap入門」 スライドはこちら\n・Bootstrapとは? Twtter者が提供するWebアプリケーションのフロントエンド 一般的にCSSフレームワークと呼ばれるもの 簡単にかっこいいデザインにするための枠組み ダウンロードしてきてHTMLで読み込むだけ。 ・Bootstrapのコンポーネント紹介 いろいろおしゃれなコンポーネントあるよ。(スライド見ましょう) ・Tips examplesがあるので、それをベースに作るのが簡単です! Initializrも対応してて、こっちで作るのもいいよ! bootstrap簡単すぎて、みんな同じデザインのサイトに(弊害) 差別化のサービスが出てきてます。 ・ @kimukou_26 「TwitterSphere of Twitter4J」\nGriffon? codehausで作られてるGroovy製のMVCイメージのGUIフレームワーク codehausはJetty作ってるとこですね 地球儀にツイートを乗っけることができるアプリ。 Groovyの記述がちょっと新鮮。 ・ @bina1204 「ApiDemos of Twitter4J for Android」\nAPI DemosというAndroidのデモがあり、ここにTwitter4Jを仕込んでみた? Android系は持ってるのに知らない。。。 ","date":1330015800,"dir":"post/2012/","id":"966fe8d32b86121f8a465a21b95f7e5c","lang":"ja","lastmod":1330015800,"permalink":"https://blog.johtani.info/blog/2012/02/24/%E7%AC%AC4%E5%9B%9E-twitter-api%E5%8B%89%E5%BC%B7%E4%BC%9A--%E3%83%87%E3%82%B8%E3%82%BF%E3%83%AB%E3%83%8F%E3%83%AA%E3%82%A6%E3%83%83%E3%83%89--twtr_hack-%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-02-24T01:50:00+09:00","summary":"今週も勉強会に参加しました。 @yusukey さんが開催してるTwitter API勉強会です。 前回とは会場が異なりましたが、広くて大画面で良い会場でした。駅","tags":["勉強会"],"title":"第4回 Twitter API勉強会 @デジタルハリウッド #twtr_hack に参加しました。(Jugemより移植)"},{"contents":"久々にlucene-gosenの話です。 しかも、あんまり嬉しくない話しです。\nすでにissueをアップしていますが、lucene-gosenとSynonymFilterを併用する場合に、特定の条件下でNullPointerExceptionが発生してしまいます。\n条件は以下の組み合わせになります。\nSolr 3.5.0以前 lucene-gosen1.2.0 - 1.2.1の辞書なしjar SynonymFilterFactoryにてtokenizerFactoryを指定 根本的にはSolr側の問題のようです。SOLR-2909としてissueが上がっています。\nSynonymFilterFactoryでは、類義語の設定ファイルの単語を読み込むときにtokenizerFactoryを指定できます。 このとき、SynonymFilterFactory内部でtokenizerFactoryに指定されたFactoryのクラスが読み込まれ、 インスタンス化されて、Tokenizerが作成されます。 この、Tokenizerのインスタンス化の処理シーケンスに問題があります。 schema.xmlの\u0026lt;tokenizer\u0026gt;タグで指定されたTokenizerFactoryでは、ResourceLoaderAwareインタフェースのinform(ResourceLoader loader)メソッドが実行されます。 このinform()メソッドがSynonymFilterFactoryのToeknizerのインスタンス化の場合に実行されません。 lucene-gosenのJapaneseTokenizerFactoryではこのinform()メソッドでdictionaryDirのパスの読み込みを行なっています。(このへん)\n上記の条件では、NullPointerExceptionが発生すると書きました。 辞書を内包したjarファイルを利用している場合、NullPointerExceptionが発生しなくても次のような問題点があります。こちらの問題は見た目は動いているように見えてしまうので注意が必要です。 すべて、SynonymFilterを利用する時点でも問題点になります。\ncompositePOS設定が類義語辞書読み込み時に無効 dictionaryDir設定が類義語辞書読み込み時に無効(=jarに内包されている辞書で動作する) 一見動いているように見えるかもしれませんが、望んでいてる動作になっていない可能性があるので注意が必要です。\n解決策(まだ途中) 先程書きましたが、基本的にはSolr側の修正をするのが妥当です。 SolrのJIRAにパッチもアップされました。 こちらのパッチをSolrに適用し、SynonymFilterFactoryを次のように指定することで問題を回避することが可能になります。\n\u0026lt;tokenizer class=\u0026#34;solr.JapaneseTokenizerFactory\u0026#34; compositePOS=\u0026#34;compositePOS.txt\u0026#34; dictionaryDir=\u0026#34;dictionary/naist-chasen\u0026#34;/\u0026amp;gt; ... \u0026lt;filter class=\u0026#34;solr.SynonymFilterFactory\u0026#34; synonyms=\u0026#34;synonyms.txt\u0026#34; ignoreCase=\u0026#34;true\u0026#34; expand=\u0026#34;true\u0026#34; tokenizerFactory=\u0026#34;solr.JapaneseTokenizerFactory\u0026#34; **compositePOS=\u0026#34;compositePOS.txt\u0026#34; dictionaryDir=\u0026#34;dictionary/naist-chasen\u0026#34;**/\u0026amp;gt; ... SynonymFilterFactoryの設定にcompositePOS、dictionaryDirを追加します。 ここの設定は\u0026lt;tokenizer\u0026gt;タグで指定された設定と同じ物を指定します。以上で問題なく動作することになります。\nただし、この方法はSolrにパッチを当てなければいけません。 Solrにパッチを当てるのもなかなかな作業だと思います。 ということで、どうにかlucene-gosen側だけでも対応出来る形にしたいなぁと考えているところです。 残念ながら、まだ考えているだけですので、もう少し提供できるのは先になってしまいますが。。。 現時点では、次の方法を考え中です。\ninformメソッドを呼ぶフラグを追加して、どうにかしてinformメソッドを呼び出す SynonymFilterの修正版をlucene-gosenに内包して提供する できれば、a.にて対応できればと思っています。 最悪、b.の方法かと。 悩んでいる間にSolrの次のバージョンが出てしまわないように出来るだけ早く対応しようと思っています。 他にも問題点や気になる点があれば、日本語、英語を問わないので、気兼ねなくissueに上げてもらうか、Twitterで私宛にメンションしてもらえればと。 (あ、issue23へのパッチでもいいですよ!)\n追記: まだ、SOLR-2909のパッチを適用してからの確認はできていません。(ソース見て大丈夫だと思ってるレベル) あと、現時点での対応方法としては、「lucene-gosenとは別のjarにSynonymFilterFactoryなどを入れて提供」が妥当かなぁと考えているところです。(無理やりinformメソッド呼び出すのは骨が折れそう+パッチが思いの外早く出て、導入されたのでlucene-gosen本体に特殊処理を入れるのはあまりメリットを感じない。)\n","date":1329756060,"dir":"post/2012/","id":"4e7b945feca199bd486653fea1d0e39c","lang":"ja","lastmod":1329756060,"permalink":"https://blog.johtani.info/blog/2012/02/21/lucene-gosen%E3%81%A8synonymfilter%E3%82%92%E5%88%A9%E7%94%A8%E3%81%99%E3%82%8B%E3%81%A8%E3%81%8D%E3%81%AE%E6%B3%A8%E6%84%8F%E7%82%B9%E5%95%8F%E9%A1%8C%E7%82%B9%E7%B7%A8/","publishdate":"2012-02-21T01:41:00+09:00","summary":"久々にlucene-gosenの話です。 しかも、あんまり嬉しくない話しです。 すでにissueをアップしていますが、lucene-gosenと","tags":["lucene-gosen"],"title":"lucene-gosenとSynonymFilterを利用するときの注意点(問題点編)(Jugemより移植)"},{"contents":"また、勉強会ログです、すみません。。。 直接業務とは関係ないのですが、今回はリクルートの中野さんが話しをされるというので顔を出してきました。 もちろん、内容も気になりましたというのもありますが。 実際には中野さんは2分くらいしか喋らなかったんですけどね。。。\n今回は、最初のセッションはちゃんとしたソースコードリーディングでした。 Hadoopの入力としてデータをHDFSじゃなくて、MongoDBから取得するときに利用するMultipleInputの実装をしてみたというお話でした。 MongoDBやHadoopを知らないと(私はあんまり知らない。。。)少しきつかったかもしれないです。 幸い、HadoopのMultipleInputについては以前、すこしだけ見たことがあったので、かろうじてついていけました。 最初の部分を聞きのがしてしまったので合っているか自信がないのですが、10genから出ているmongo-hadoopの使い勝手、効率の悪そうなところに手を入れた話しがベースになっているんでしょうか?(ツッコミあるとうれしいです) 気になったのは、MongoDBのデータをHadoopから直接取りに行くというユースケースがどういう場合に出てくるのかという点です。 ネットワークやMongoDBの負荷がHadoop処理へのボトルネックになるんじゃないかしらという懸念がありそうだなと。 発表を聞いていて感じたのは、やっぱりソース書いて動かさないとダメだよねぇ、自分も手を動かそうというところです。 リクルートさんの発表は波乱万丈(?)でした。 最後まで話しを聴いたあとに思った感想は「こんなに話して大丈夫なのかな?」「いろんな人を敵に回してない?」というものです。 実際に昨年の夏くらいからEMCの草薙さんも検証メンバーに入って、リクルート社内での活用シーンをベースにMapRの検証をいろんな項目でやられたようです。(ある程度の詳細は以下のメモ参照) で、最終的な結論はまだ出ていないのですが、最後に出てきた検討中の比較対象が某C社のCDH。 どちらかというとCDHの方に傾いてる感じに取れる終わり方で心配になりました。。。 会場が会場だからというのもあったのかなぁ? mesosというキーワードが出てきたのが気になりました。単語だけは以前Twitterで流れてきたのを目にしてたのですが、どんなものかという概要がわかったのは収穫でした。 リクルートさんの資料はどこまで公開されるかわからないですが、もう一度見たい気がします。(mesosの部分だけでも公開して欲しい)\nということで、以下はいつもの自分用メモです。\n日時: 2012年2月8日(水) 19:00~21:30 (受付開始 18:40) 場所: 豊洲センタービルアネックス(NTTデータ、豊洲駅直通)\n◎日本OSS貢献者賞・奨励賞のご案内 @hamaken 日本OSS貢献者賞・奨励賞\n◎『オレオレMultipleInputを作る方法(仮)』@muddydixon さん http://www.slideshare.net/muddydixon/multipleinput\nhadoopからMongoDBを利用する方法を紹介 CDH3u2かu3で試しました。 10genからも出てるけど使いにくい?から作った? MongoMultipleInputs.addInputPath で色々簡単に使えるようにしたかった。 絞り込みしてデータをMapperにとり込みたかったため。 =絞り込みできないと必要なデータ以外も取得できてしまいJSONのパース処理がオーバヘッドになるから。 com.mongodb.hadoop.input.DelegatingInputFormat mongodbの環境にあわせて多くのsplitを生成する。 mongosへのアクセスはメタ情報の取り出しだけ。 あとは、個々のサーバにアクセスしてるのでデータ取り出しが高速? ◎『MapRってどうよ? - 実際に使ってみた感触を紹介します』 - リクルート 中野さん、高林さん、大坪さん\nMapRの説明資料がなかったので、EMCの草薙さんが出てきて説明を開始。 Greenplum MRはMapRテクノロジが開発した実装のOEM版。 EMCは特に手を加えず。 ※MapRについては前回のMapR勉強会の記事を御覧くださいな。 Q:JavaのAPI互換と言われている部分はHadoopのどのバージョン? A:CDH3u2に近いパッチが当たってるらしい。 Q:DFSIO性能の比較対象のHadoopはどのバージョン? A:手元に資料は残念ながらないです。 ここからリクルートさん。 検証内容:性能検証 中古車サイトで利用されている3つのHiveに置き換えてみた。 結果(パーティション圧縮) MapRのほうが約1.3倍高速に(そこまで速くならなかった?) 結果(非パーティション圧縮) MapRのほうが約1.7倍高速に(そこまで速くならなかった?) ビルドイン圧縮はGzip圧縮と比較して高速 ※チューニング次第では結果変わるかもね。 機能検証:マルチテナント検証 目的: 複数ユーザに対して1つのクラスタを提供する セキュリティの担保() 余剰リソースの有効活用 複数ユーザのJobの並列実行? 結果1(ユーザ権限まわり) MapRのユーザはLinuxユーザに準拠。 同じmaprユーザでもUIDがずれてるとエラーが起きる。 MapR内のPermissionは内部のクラスタ、ボリュームの権限定義が可能 ※Volumeは管理者に付加的な情報を与えるような存在 Job実行はHadoopと一緒のアクセス権。 結果2(FairScheduler) MapRではデフォルトとなっている。 複数テナントからの同時ジョブ実行の動作を確認。 poolをベースにタスクを割り当ててく。 min/max値にあわせてslotが利用される模様 結果3(Load処理(Hive)、Job実行(HiveのSelect)) じゃらんPVデータ1ヶ月分をロード。 NFS→MFS 結果4(フェイルオーバー) HA機能 ノード切り替え時間、タスクの復旧までの時間とか。 結果5(DirectNFSでの転送) NFSGatewayをクライアント側にした場合との違いなど。 クライアント側に載せた場合、通信量が減るから速度が出てる。 Mesos概要 Apache IncubatorのOSS。C++により実装 効率的なリソース分離、リソース共有機能を提供するクラスタマネージャ。 Mesosでの検証 マルチテナント(ユーザ権限)硬い。 リソース制限ができない。などなど。 MapRとMesosの比較 資料期待! リクルートとしてのMapRの評価 保守/サポート/教育が充実してるのが重要。速度だけじゃない。 けど、まだ検討中です。 Q:クラスタに対するパーミッションの権限情報はどこで管理されてるの? どこが落ちたときにそのパーミッションの情報がとれなくなる? A:CLDBで管理されてます。 Q:CLDB内部でのデータはバイナリ?DBを別途持ってる? A:HDFS上にボリュームが作られてそこに吐き出されてる。 Q:Jobのスケジュールの情報とかはどこに? A:Job管理データはJobTracker用のボリュームに保存されてる。 それを別の人が引き継ぐ。 Q:ボリュームが壊れたら? A:さすがに壊れたら引き継げない。 けど、壊れにくくしてあるのが売り? Q:MapRのチューニングのポイントはどんなものがあるの? A:チューニングに関しては256Mのchunkサイズを64Mに減らした場合の化粧しかしてない。Apache Hadoopの方は若干チューニングした。 Q:DFSのシリアライズは?ボンディングとかでもできるんじゃないの? A:そこはやってないのでやってみます。 Q:MapRでの8台構成で全部のせてみた場合、CLDBのリソースはどのくらいもっていってるの? A:結構使ってる。CLDBを3台以上にしたらサポート対象外。 Q:CLDBを3台に制限してる理由は? A:わからない。 Q:本番MapR、検証CDHというのはあり? A:M3を開発環境で利用して欲しいですね。(ステマ?)開発目的だとM5を無償提供してほしいなー(EMCへのお願い?) Q:Pigの検証は? A:リクルートではHiveを利用してたので検証してない。 次回は3月ころかなぁ?だそうです。 ","date":1328716980,"dir":"post/2012/","id":"fa16213d24273d386d22332cd01ce774","lang":"ja","lastmod":1328716980,"permalink":"https://blog.johtani.info/blog/2012/02/09/hadoop%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89%E3%83%AA%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0%E7%AC%AC8%E5%9B%9E%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F-hadoopreading/","publishdate":"2012-02-09T01:03:00+09:00","summary":"また、勉強会ログです、すみません。。。 直接業務とは関係ないのですが、今回はリクルートの中野さんが話しをされるというので顔を出してきました。 も","tags":["勉強会"],"title":"Hadoopソースコードリーディング第8回に参加しました。#hadoopreading(Jugemより移植)"},{"contents":"Fluentd meetup in Japanに参加しました。いつも面白そうな話を聞いてばっかりなので、役に立つためにスタッフとしても参加してみました。 まずは、会場が綺麗でびっくりしました。しかも電源タップまで用意されていてかなり充実してました。Ustはまだ見ていないのですが、Ustも録画までされていて素晴らしい運営メンバーでした。\n開発者の古橋さんほか、Treasure Data Inc.の方たち(太田さんはいなかった)が集まり、 Fluentdの仕組みから、プラグイン開発の方法、実際にプラグイン開発してしかも本番で利用してる実例まで 「パーフェクトFluentd」という本ががそのまま書けてしまうのではというくらい密度の濃い話が聞けました。 私個人は、いつものごとく興味を持ってるんだけど、仕事、私用では触っていないという腰抜けなので話についていくのが大変でしたが。。。 各セッションごとに、しっかりとしたQA時間が取られていて、質問者も質が高く、中の人や発表者の方も誠実に回答されている感じがすごく良かったです。 (残念ながらLTの時は懇親会の準備を手伝っていたので聞けてないです) 基本はログの中継サーバとして利用するという話でした。 個人的には性能系のデータやログ(遅いクエリのログに関するプラグインの話などもあった)をストレージに保存して、時間を軸にログとグラフを表示するとかいう仕組みに使うと面白いかもなぁと感じました。 今回はFluentdがメインなので、ログを集める部分の話が主だったところでしたが、懇親会直前の@doryokujinさんのスライドでも上がっていた集計後のビジュアライゼーションに関する部分のはなしも聞いてみたいなぁと思ってるところです。\nあとは、いくつか知りたかったことが。 Treasure Data Serviceというサービスをやってるみたいで、SQLライクな問い合わせやビジュアライゼーションされた画面があるみたいな話があがっていたんですが、画面が見てみたかったです。 また、@just_do_neetさんの構想図のその後を聞いてみたいですねぇ。\nそれにしても実例も構成から性能値まで上がっていたので、実際に利用する場合に参考になる資料だらけで普及にはずみがつきそうです。 Ust録画が上がっているようなので復習したいと思います。 (あ、内容とは関係ないけど、Ust録画にハッシュタグつきのツイートを時間軸で重ねて表示するサービスとか機能ってないのかな?)\nということで、以下はいつものメモ書きです。\n2012/02/04 12:30 ~ 19:00\nフューチャーアーキテクト セミナールーム\n参考URL:http://fluentd.org\n◎13:00~14:00 「What\u0026rsquo;s Fluentd? - The missing log collector」 http://www.slideshare.net/treasure-data/fluentd-meetup-in-japan-11410514 Treasure Data, Inc. 古橋 貞之 (@frsyuki)\nまずは、Fluentdの概要。syslogdみたいなもの Fileのtailで流すことが基本。 Clientライブラリから流すことも可能。 他との比較 ScribeとFluentd 構造化されたデータを扱う gemとかapt-get,yumでインストールあg可能 Rubyで書かれてるからカスタマイズもプラグインの追加も簡単。 FluentdとFlume FlumeはZKやマスタノードが必要=セットアップが面倒 JVMだから面倒、設定も簡単。 Fluentdのアーキテクチャ Bufferプラグイン:スレッドセーフ、バッファ処理など Outputプラグイン:出力だけ out_forwardプラグイン:Cassandraと同じアルゴリズムでHeartBeatしてる out_copyプラグイン:同じ出力を別の出力先にコピー bof_fileプラグイン:バッファ先をファイルにする。Fluentdがこけても大丈夫 out_exec_filterプラグイン:外部プログラムからの入出力を使える in_tailプラグイン:ログのパーサーが内蔵されてるみたい。 開発者用API Unitテストフレームワーク(MRUnitに似てる) TailInput(パーサカスタマイズも簡単) ドキュメントとか http://fluentd.org にあります。 会社紹介! Treasure Data Service Fluentdでは出力先がいろいろできるけど、自分で解析しないといけない !ここで、Treasure Data Service(クラウド)に保存すると。。。 データのVisualizationとかがリアルタイムで出来る。 QA: Q:ログ転送にUDP使ってますか? A:TCPです。UDPはハートビートに利用してます。 Q:文字コードはどういう扱い? A:バイナリ形式であつかってます。 文字列で扱う場合はプラグインで対応しましょう。 Q:性能大丈夫? A:Twitterで議論があがって、いろいろ対応しました。 Q:TreasureDataServiceはクラウド対応だけなの? A:データはクラウド上で管理してるので上げても大丈夫なものだけが現在は対応。暗号化などは行なっている。 Q:TreasureDataServiceはどこで動いてる? A:AWS上(S3にデータ保存) Q:解析プラットフォームを提供している?SQLだけ? A:HiveのSQLで解析可能。Visualizationのツールもある。 Q:コンサルタントもあるの?ログ出力系とか。 A:あとから解析できるように。 Q:in_tailでログローテート(iノードが変わって)も大丈夫? A:大丈夫。動かなかったら連絡ください。 Q:ファイルバッファリングされるデータの順序は保証される? A:キュー形式なので、保証される。けど、S3とかだと出力先が遅いので、 パラレルモードで対応が可能。だけど、パラレルだと順序は保証されない。 Q:実際のシステムが投げるときにFluentd側で認証とかできる? A:認証はないです。推奨は同一アプリサーバでFluentdを起動。 Q:Fluentd間のデータ通信のセキュリティ対応は? A:今はない。プラグインとか作ればOK。 Q:中間層のFluentdを置くのは推奨?なしで直接ストレージ保存も可能? A:柔軟な対応(送信先、バッファリングとか)が可能にできるように中間層を置くほうがいい。直接出すことも可能。 Q:TDAgentでのセットアップが推奨?gemは? A:gemはOSS版でtrunkに近い。TDAgentはテストとかしっかりやってる。 バージョンの対応表はリリースノート見ないとわからない。 Q:Flumeのほうが優れているのは? A:設定ファイルが一元管理ができる。大規模はFlumeのほうがいいかも ただし、includeでHTTPサーバ経由で設定ファイルを取得可能な機能あり。 Q:バッファサイズは指定可能? A:可能。 Q:ストレージがずっと停止している場合にログがあふれるのを防ぎたい場合の対処法は? A:セカンダリという機能がある。(ただし、対応できてないプラグインもある) Q:フェイルオーバーでローカルファイル出力とかはできる? A:out_forwardは対応してる? Q:Fluentdからのbuf_fileに出力してる部分で遅延、書き込み不可が発生したら? A:入力と出力がスレッドで分かれてる。 入力スレッドでのエラーはinput_plugin側にException上がる ◎14:15~15:00 「Dive into Fluent Plugin」 http://www.slideshare.net/repeatedly/fluentd-meetup-dive-into-fluent-plugin Preferred Infrastructure, Inc. Masahiro Nakagawa (@repeatedly)\n好きなプラグインとか言いましょう(発表者さん) MongoDBのプラグインをベースにプラグイン開発の説明 http://bit.ly/fluentd-with-mongo プラグイン名はfluent-plugin-xxxで統一されてます。 fluent-plugin-mongoがダウンロード数が1位に! (scribeのプラグインがデイリーでテストが走ってダウンロード数が増えるという卑怯なカウント稼ぎしてたらしいw) fluentd.confの説明 fluentdの起動は以下のとおり。開発中は-vつけるといいよ fluentd -c fluentd.conf プラグインをどう作る? Fluentdの構成図による説明 Cool.io、MessagePack、Rubyなど。 それぞれの説明を簡単に。 Cool.ioがファイル監視とかをやってくれるみたい。 プラグイン開発に関する詳細な説明 テスト、gem構成などを書いてくれてる。 QA: Q:複数行のログを扱うのはどこを作ればいい?tailプラグインの正規表現だとうまく行かなかった。 A:tailをoverrideしてparserLineを実装する。複数行のparserは難しいけどね Q:ログのアグリゲーションをやってみたいのだが、どう?CPU利用率とかを1分間バッファしてからアグリゲーションして平均出すとか。 A;fluent-plugin-aggregateってのがあって、forward-pluginを書き換えて作ってる。 TimeSlicedOutputでやると時間の期間指定とかが可能。 管理画面つくろうと思ってるので手伝ってください!@repeatedly Q:fluentd自体が処理した統計データの出力とかある? A:古橋さんが頑張ります!協力して!=\u0026gt;@tagomoris先生が書いてる! ◎15:15~16:00 「fluent を使った大規模ウェブサービスのロギング」 http://www.slideshare.net/hotchpotch/20120204fluent-logging COOKPAD, Inc. 舘野 祐一 (id:secondlife, @hotchpotch)\nCOOKPADでの基盤全般を見てる部署の人 PVログ+MySQL 1日分はオンメモリにのるから高速。けど、1週間前とかになると遅くなる blackholeエンジン(MySQLの一部?)だと速い(ときどきおそくなる) データ保存でも問題 直近データしか保存できない。大きすぎて。 今後スケールしないときつくなる(1日分もメモリに載らなくなる可能性も出てくる) 他のログはMySQLへJSONでシリアライズして出力とかもしてた。 アプリでDBにログ出力はinsertのコストが厳しい。PVとかなら、1リクエスト=1insertだけど、1リクエストで多数ログ出力とかが厳しい。 そこにFluentd登場!!! 出力先が色々使える。(MySQL以外もOK) パフォーマンス バッファリング+転送をやってくれるし、非同期で処理可能なのでレスポンスタイムへの影響が最小限にできてる。 安定性 プラグインはちょっと注意が必要。 バッファリングしてくれてるので、一時的に停止もできるのがうれしい。 6時間止めてもOKだったよ(テヘッw) 今後 PV系のログをMySQLから移行検討中 具体例!! td-agentをrpmで入れてるし、Rubyまで入ってくれる。 構成管理はpuppetを利用してる。 td-agentの設定の注意点 「retry_limit 9」に変更してる。標準だと17なんだけど、2の16乗=大体1日かかる。9だと大体10分くらい 中央転送用サーバ gitで設定ファイル管理してる。 よく変更するため。 gemfileで各種fluentd/pluginを利用してる。 自分たちで手を入れたソースを利用できるようにもしたいため。 テスト時にテストが書けるのが嬉しい(Rubyで出来てるアプリからもいじりやすいし、アプリのテストでも簡単に使える) ロガーへの実装追加もできる。 Tips バッファからすぐ処理させたい場合とかの説明 こんなのあったら嬉しいな。 設定ファイルの柔軟な設定記述方式 DSLにならないかなぁ(けど、やり過ぎも厳しいし。。。) ログの重要性 統計を考えられるエンジニアが重要。 どのデータにどんな価値があってそれを仕事(お金)に結び付けられるか? QA: Q:障害対応のノウハウとか? A:nagios、muninでサーバとか監視してる。 アラートチェックもしてる。 Fluentdの安定性は2ヶ月実際に導入してみて特に問題は出てない。 Q:MongoDBの構成は? A:master/slave構成。PVログはS3に保存してEMRで処理。 Q:パフォーマンスの測定は? A:40Mbit/sが処理できてたのは見てる。あとは、後ろの発表ですごいのがある! Q:設定ミスの防止とかをどうやった? A:今回はpuppetの設定後のリロードをチェックするような仕組みを入れた。 本来なら、データが流れてるかどうかのチェックを入れるプラグインを書いて欲しいw Q:データマイニングエンジニアの定義は? A:データの価値を見いだせるエンジニア。あとは、きちんと統計学を学んできてるエンジニア。両方募集中!! Q:DynamoDBは検討は? A:西海岸でしか動かないのでデータ転送の時間がかかってしまった+RESTで1件ずつ登録なので今回は見送った。スキーマレスなのでうまく使えそう。 A2(古橋さん):バルクインポートがないので使いにくい。 Q:ログ出力の形式をFluentdにあわせて変更したとかありますか? A:もともとアプリで出力してたから特に変更なかった。 ◎16:15~17:00 「fluentをサービスで使ってみた」 http://www.slideshare.net/naverjapan/20120204fluent-public NHN Japan株式会社 Tetsuya Ohira (@just_do_neet)\n自己紹介が面白かったw 実例の話。 事例1: 社内向けのログ解析に利用 Fluentd+Hadoop データノードにFluentdで出力して、データノードからHDFSに書き込んでる。 事例2: NAVERまとめのまとめ作成者へのデータ解析 Fluentd+Hadopo+Azkaban Azkaban(個人的にはオススメできないw) flutendの負荷は全然上がってない。 監視 tcp portの監視 転送されたデータサイズのチェック。HDFS側のデータ量でチェックしてる。 なぜか半死半生の状態になった(よくわからない。) プラグインを自分で直せるので対応が楽。(Ruby力は必要だけど。) demo 準リアルタイム解析基盤の構成案(おもろそう) fluentd、MongoDB、Hadoop、Jubatus、node.js 地図にアクセス解析結果をのっけて見せる。(maptail.js?) 提案or相談: 動的に設定ファイルの内容を変更できるようにしたい log rotateのタイミングでshell実行でfluentd再起動 必要な情報だけrelayしたい フィルタープラグインみたいなものが書きたい。 fluentd自体のメトリクスを出して欲しい jubatusプラグインはー? QA: Q:log rotateへの対応はどーしてる? A:今はログローテートのタイミングでfluentd再起動してる Q:Apps側のFluentdがコケたときにaccess_logをcopyしてるらしいけど、重複しないの? A:失敗した対象のログをストレージから一旦廃棄して、再送してる。 Q:Rubyがそこまで得意じゃないのにFluentdを選んだ理由は? A:他のモノが使いにくかった+既存システムに手を入れなくて済む+タイムリーだったという理由。 Q:構成案のデータの流れは? A:MongoDB、Hadoopへは同一ログを流して、リアルタイムが重要な場合はMongoDB、大量データ回すのはHadoop? ◎17:15~18:00 「Distributed message stream processing on fluentd」 http://www.slideshare.net/tagomoris/distributed-stream-processing-on-fluentd-fluentd NHN Japan株式会社 ウェブサービス本部 Tagomori Satoshi (@tagomoris)\nsed | grep | wc がメイン。 Hiveで集計してます。 なんでFluentd?(not Storm、Kafka or Flume?) Rubyが好き(ライブドアはJavaが入ってない環境もあるし) プラグインやTimeSlicedOutputがあるのも採用理由 ログ収集の構成図 ブログに別の勉強会の資料があるので見てください。 まだ10日間しか動いてないので実績は少ない? 127サーバからのログを流してる。 7万行/sec、ピーク120Mbpsが流れてる。 89 fluentd インスタンスが12ノード(4コアHT)で動いてる。 1行のログを1行のタブ区切りで出力する(Hiveでインポートしやすいから) Apacheのログに幾つか追加したデータなどが出力されてて、それをタブ区切りにするため設定一発では変換できない。 TimeSlicedOutputが重要 時刻単位でログ出力できないとキツイ(ログの流量が半端ないから) ログローテートでは時刻単位できちんと出力されてない。 ログから解析までの流れ図 以前は生ログをHadoopに書き出してたので25分くらいのタイムラグが出てしまっていた。(ノード数が少ないという理由もあるけど、お金的に増やしたくない)+Hadoopで他のジョブが実行されてるとさらに遅くなる。。。 fluentd でログを流しながらコンバートもかけられ、Hadoopでのデータコンバートの処理遅延が少なくなってハッピーに! ストリーミング処理の重要な点 バッチでもストリーミング処理でも同じことが可能。(out_exec_filterとHadoop Streaming) SPOFがないこと トポロジ、Fluentdの構成 ログエージェント(scribeline:お手製) pythonで書かれたscribelineというものを利用してる。 フェイルオーバーの処理(primary、secondary構成)が可能 fluentdは入れてない。(ログを拾い上げて流すだけには重い) workerノード serializerノードが必要なのは出力先の競合を減らす必要があるため。 出力先が大量のアクセスに向いてない場合があるから。 あと、ログの流れを元に監視したい項目にもここで対応可能。 watcherノード deliver、serializerからのデータを見ながら監視、統計処理を行える。 設定は自動生成してる。800行くらいになっちゃうから。 workerへの分散具合をよしなにしたいから。 remove_prefix 、add_prefixでデータの流れ先の交通整理してるのか。 GrowthForecastでグラフを出力してる。 https://github.com/kazeburo/GrowthForecast QA Q:大規模環境での移行はどうやったの? A:もともと流すような仕組みはあって、流し先を変えたので それほど大変ではなかった。ただ、アプリ側で動いてた部分に手を入れたときは配備が大変だった。 Q:workerが1サーバ8の理由は? A:4コアHT=8というので8としている。 Q:deliverのカーネルパラメータをいじってたりしない? A:ライブドア標準の設定がされてる。CentOSのデフォルトでもそれほどきびしくないかな? Q:deliverノードでラウンドロビン+out_forwardになってる理由は?out_forwardだけじゃだめ? A:バッファのタイミングでの切り替えだと溢れてしまうので、最大でも1秒でラウンドロビンしてworkerを切り替える必要がある。 ※懇親会設営の手伝いのためあんまり聞けず。 ◎18:15~19:00(Plugin紹介LT)(各10分) @shun0102: 「fluent-plugin-dstatを使ったリアルタイムクラスタモニタリング」 http://www.slideshare.net/shun0102/fluent-plugindstat\n@ixixi: 「fluent-plugin-couch」 http://www.slideshare.net/ixixi/fluent-plugins-for-couchdbamazon-sqssns\n@chobi_e: 「Fluentd \u0026amp; PHP」 http://www.slideshare.net/shuheitanuma/fluentd-and-php\n@railute:「Fluent Output Plugin for Cassandra」 https://skydrive.live.com/view.aspx?cid=D105615A0F594518\u0026amp;resid=D105615A0F594518%21333\n","date":1328367780,"dir":"post/2012/","id":"a2679a7d860a0bfb2645809ed92ce138","lang":"ja","lastmod":1328367780,"permalink":"https://blog.johtani.info/blog/2012/02/05/fluentd-meetup-japan%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-02-05T00:03:00+09:00","summary":"Fluentd meetup in Japanに参加しました。いつも面白そうな話を聞いてばっかりなので、役に立つためにスタッフとしても参加してみました。 まずは、会場が綺麗","tags":["勉強会"],"title":"Fluentd Meetup Japanに参加しました。(Jugemより移植)"},{"contents":"昨年末に今年の抱負について書いたのですが、 他にも興味あるものが増えたので備忘録&公約?を兼ねてブログに書いておきます。 (興味あるものがあれば、シェアしたりできると楽しいので、ツイート、コメント待ってます。)\nZooKeeper SolrCloud SenseiDB Lucene 検索システムのアジャイル開発? まずは、ZooKeeper。このなんとも言えないアイコンでお馴染みのヤツです。 こんな顔してますが(顔関係ない。。。)、いろんな所に出没します。 Katta、Lilly、SolrCloudにも出てくるんです。SenseiDBにも出てくるんです。分散処理にことごとく絡んできます。 で、これは、知っとかないとまずそうだと。\nSolrCloud。まぁ、妥当です。一応、Solrな人なんで。 昨年、NewSolrDesignを訳してみてもいます。訳しただけでほったらかし。。。 elasticsearchとかSenseiDBとかSolrに似たLuceneを利用している検索サーバがチラホラ話題になってます。 できれば、このあたりの分散の仕組みを比較しながら調べたいなと思ってみたり。 すべてをカバーするのはキツイので、SolrCloudかSenseiDBあたりを調べていきたいなぁと。\nで、SenseiDBです。先日、Publickeyで記事が出て飛びつきました。 Zookeeper使ってるし、分散だし、全文インデックスにLucene使ってるし。 なんだか興味あること、全部入りな感じです。\nLuceneも興味津津です。 Solrがコアとして使ってますし、昨年、Solrと同時にリリースされるようになりました。 Luceneも奥が深く、時々、Solr調べててLuceneのソースも見るのですが、本格的に全体像を把握したりは残念ながらできていません。 そのくせ、Zookeeper同様、いろんな所に出没するんです、これが。 ということで、足元を固めるためにもLuceneに入門しないとなぁと。\nで、最後に検索システムのアジャイル開発です。 lucene-gosenのコミッターをやらせてもらってたり、Solrに絡んだ仕事もしてますが、長期にわたってフィードバックをもらいながら検索システムを育てていくというのが最近興味が出てきてることです。 検索システムは作ったらおしまいとは行かないのが厄介なところです。 データは増加しますし、検索されるキーワードも変わってきます。 また、検索される方法も変わってきたりもします。 ユーザが検索したいものも変化があります。 思ったように検索にヒットしない場合とユーザが離れて行ってしまいますし、検索しにくい場合も同様です。 今日、クックパッドの方の話しを聞いて思い出した次第です。(前に、Solr勉強会でも同じ話しをされて、同じ思いに至ったのですが、いかんせん忘れやすくてw) また、ログ解析の話などをTwitterで見てることもあり、検索という側面でのログ解析ってのも重要だよなぁと。 いくつか思いつくこともあるのですが、実践出来る場も限られてます。 色々と話しをする場を設けるのも面白いかもなぁと妄想してる次第です。\n取り留めもなく、現時点で気になってることを書きだして見ました。 また、数ヶ月したら気が変わってるかもしれないですが、とりあえず書き残してみます。 興味がある方がいらっしゃったら声をかけてもらえるとうれしいですね。\n","date":1327596641,"dir":"post/2012/","id":"58e83fb33c120db338132d23b9112805","lang":"ja","lastmod":1327596641,"permalink":"https://blog.johtani.info/blog/2012/01/27/%E4%BB%8A%E8%88%88%E5%91%B3%E3%81%8C%E3%81%82%E3%82%8B%E3%81%93%E3%81%A8/","publishdate":"2012-01-27T01:50:41+09:00","summary":"昨年末に今年の抱負について書いたのですが、 他にも興味あるものが増えたので備忘録&公約?を兼ねてブログに書いておきます。 (興味あるものがあれば","tags":["備忘録"],"title":"今興味があること(Jugemより移植)"},{"contents":"ということで、いつものように勉強会に参加したメモです。\nhttp://atnd.org/events/23608 日時 :2012/01/26 19:00 to 22:00 会場 :アカデミーヒルズ(六本木ヒルズ内) 49階(タワーホールA) (港区六本木6-10-1) ハッシュタグ :#mnlgy\n■タイムテーブル 司会:CROOZLabs株式会社 研究所 所長 代表取締役社長 小俣 泰明 モーションノロジーの説明があったけど、他のことしてました。すんません。 1. 発表者: 有限会社未来検索ブラジル 森 大二郎 概要:groongaの索引構築の実装 全文検索とは。歴史から 1971:full-text。。。というキーワードが。 現代の全文検索の課題はあんまり変わってない 全文検索の手法 いくつかあるけど、転置索引の説明だけ。groongaも転置索引 groongaはインデックスの動的構築が得意 静的構築も考慮してます。 2. 発表者:CROOZ株式会社 長谷川 博紀 概要:MeCabからの脱出?(仮 CROOZ MALLの解説 MySQLとMeCabでやってます。 Tritonnつかってるのか? groongaとの性能比較検証やってみました。 MeCabが問題じゃなくて、辞書ありの形態素解析が問題。 辞書にない単語もうまく検索したい 辞書に単語登録したら形態素やり直し ソート用のデータが。。。(ここはわからなかった) QA Q:MeCabの代わりとなっているものは? A:MeCabを改善してみる? 3. 発表者 : グリー株式会社 一井 崇 概要:全文検索のちょっとちがった使い方(仮) グリーでの数値指標管理 事前集計してKVSに登録してみてみる 1億パターンのキーが存在する。。。 キーがわからなくなる問題とか事前集計できてる?とか迷子になる。 キーも全文検索に入れてみては? 「富士山の標高は何メートル?」とかでデータが取れる。 構造化されたキーをkey stringとして全文検索する。 構造化Keyに対応したKVSがあればいいんだけど。 データストアとしての全文検索もいいのでは。 4. 発表者:株式会社クリアコード 須藤 功平 概要:rroongaによる検索サービスの実装 groongaとRubyの組み合わせでrroonga。Rubyによるインタフェース? groongaとのつながり部分をRubyで書いたライブラリ 多段ドリルダウン機能 絞り込みによる検索結果の比較とかに利用可能 メタデータ抽出にドリルダウンが便利 例:番組説明から出演者を抽出 サジェスト機能もある コンテンツベース すぐできる。候補の精度がいい 統計情報ベース 元データがある程度必要 候補が増えるけど、精度の問題あり 5. 発表者: 株式会社ぐるなび 塩畑 公一 概要: groongaの位置情報検索関連について。 2010年4月からgroongaを利用し始めた レストラン検索、地図検索など 円形、矩形の緯度経度検索が可能。 距離算出もやってる。ソートとか用かな。 球面近似もやってる。 geoの検索速度についてパフォーマンステストしました。 Q:近似手法をいくつもサポートされてるけど必要? A:距離計算を正確にしないと不利になるお店が出てきちゃうから 6. 発表者: クックパッド株式会社 兼山 元太 概要: Solrを使ったレシピ検索のプロトタイピング クックパッドとは? 女性多いよ AWS上でRubyで組んであるよ プロトタイピングって? ユーザの問題を発見してから、プロトタイピング 本番デプロイ(一部ユーザに公開) 問題を抱えているユーザーに向けてそれぞれ数十のバージョンが動いている インタビューとかしてフィードバック受ける。 本番の検索エンジンのフィールドをいっぱい追加 Solrの紹介(MySQL(Tritonn)から移植しました) ダイナミックフィールドやレプリケーションの話。 JSON型でHTTP経由で検索できるのが便利。 Solr本の紹介して頂きました!あざっす! 気になってるSolrの新機能 not to cache SurroundQuery BloomFilter Q:全部AWS? A:全部AWSに移行しました。 とまぁ、参加してきました。 初六本木ヒルズで、おしゃれな場所、雰囲気にやられてしまって、あんまりちゃんと聞けてないところがありますが。。。 メモを取りましたので。参考までに。 groongaについては勉強不足のため、いまいちついていけませんでした。 ちょっと英語の記事を読んでいたのもありまして。(内職良くない。。。) MeCabに関する発表に興味があり、勝手にMeCabの代わりorMeCabよりいいものを使ってます!みたいな発表かと想像していました。(ちょっと違ったみたい、妄想は良くないですね。。。)\nグリーの方の発表は興味深かったです。ログ解析とかにも確かに全文検索の技術使えるし。 検討が進んだ次の話も聞いてみたいです groongaの位置情報の話やrroongaでのgroongaの色々な機能のはなしも出てきてgroongaの理解もちょっと進んだのはありがたかったです。\n最後のクックパッドさんの話は、今回もわかりやすくて面白かったです。 検索を成長させていくという姿勢と、実際にどんな形でそれを実施されているかが楽しそうに話されててとても羨ましかったです。 次はSolrで困ってる点とか、検索のログとか利用され方をどのように解析してるのかといった話も聞きたいですね。\nどうしてもSolrに思い入れがあるので、感想が偏ってるかもしれません、すみません。 気になる点やいや、こうなんだよ!ってツッコミがあれば、ぜひコメントやTweetしてもらえるとありがたいです。\n","date":1327593155,"dir":"post/2012/","id":"c6dc6e6567d673436ac41ebc8e79a9ec","lang":"ja","lastmod":1327593155,"permalink":"https://blog.johtani.info/blog/2012/01/27/%E3%83%A2%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%8E%E3%83%AD%E3%82%B8%E3%83%BC2012-1%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-01-27T00:52:35+09:00","summary":"ということで、いつものように勉強会に参加したメモです。 http://atnd.org/events/23608 日時 :2012/01/26 19:00 to 22:00 会場 :アカデミーヒルズ(六本木ヒルズ内) 49階(タワーホールA) (港区六","tags":["勉強会"],"title":"モーショノロジー2012#1に参加しました。(Jugemより移植)"},{"contents":"日時:2012/01/19 18:30-20:30 場所:ベルサール三田Room2シアター\nInside MapR デモ+内部のお話。 ・自己紹介 Susheel Kaushik 元YahooのHadoop系の人。製品担当責任者。 草薙さん 3台のベアボーンでMapRが動いてるデモが開始。 クラスタ管理画面の説明。 なぜか、NFSのサービスが1台落ちてますがw MapReduceなんかの実行結果なども出てくるのか。 ボリューム管理も画面から操作 レプリケーション、スナップショットも管理画面で操作、動作確認できますよ。 ミラー先はリードオンリーでボリュームの同期が可能。 スナップショットによりMapRのクラスタ内部にバックアップが保持可能。 NFSのHA構成可能。VIPの機能などもあるよ。 事前定義された各種Alertの発行も可能。 JobTrackerもMapRで拡張された表示がある。 例:MapTaskPrefetchCapacity:次のジョブのMapperを起動する準備可能な仕組み MapR内で独自に出力してる測定値をGangliaで見ることができるよ。 MapRはHadoopの置き換えとなる製品。 HDFS部分を重点的に性能アップさせるために主に置き換えた製品。 MapReduce部分にも手を入れてる。例:Direct Shuffle(HTTPじゃなくて、RPCでShuffleの通信を行ってるとか)ボリューム活用してるらしい。 分散NameNode、JavaGCの影響の排除、ビルトイン圧縮によるI/O削減など。 Mapperの出力をHDFSに置くと、メタデータ更新が多くなり、NameNodeがパンクする。(Apache Hadoop) Q:中間データもレプリケーションすると性能劣化しないんですか? A:中間データボリュームは特定ノードしか保持されない(=レプリカ数は1) ストレージプール(SP) ソフトウェアでストライピング。RAIDしなくてよい。 コンテナ(データ、ネームがある。) データブロックをグループ化したもの ※ストレージプールの数と同数のボリュームを作成すべき。 CLDBがコンテナを管理してる。 Q:トランザクション失敗するのは? A:どこかにかければトランザクションは成功。 コンテナが復旧してきたら、データがコピーされる。復旧されない場合は別途コンテナを割り当てることもある? Q:ノードが追加される場合の挙動は? A:。。。聞き逃した。 トポロジ ノードを階層的にグループ化してデータ配置をコントロール。 Q:トポロジ設定などの権限設定は? A:Permission画面があるよ。 Q:ボリューム単位のファイルシステムアクセスに関する設定は? A:???聞き逃した? ボリューム いろいろな設定が可能。 スナップショット Copy-on-Write方式による差分格納 ミラー ソースからミラーにコピー。手動orスケジュールによる起動が必要。 ミラー側はRead-only ※誤解を招きやすいので注意 読み出しが多い場合にミラーを利用することで対応が可能。 ビルトイン圧縮 LZZFの一種を高速化してる ネットワークIOにも効いてくる JobTracker HA 最大3ノードで構成可能。アクティブスタンバイ NFS HA すべてのノードで稼働可能。 NFS機能 NFSv3相当 クライアント側にNFSサービスをインストールするという構成も可能に。 Q:NFSマウントして作成したファイルもブロックサイズ分のファイルサイズになるの? A:8Kバイト単位で内部的にはファイルを作成してる。8KB単位で圧縮して管理してるので、小さいサイズでもいい。(アロケーションサイズが8KB) Q:8KBにしてしまったために大きなブロックサイズの利点がなくなるのでは? A:オーバーヘッド内容な構成になってる。シーケンシャルに8KBに並んでるから? Q:NFSによるとMapReduceによるアクセスの排他制御とかは? A:独自で頑張らないといけない。Job起動時に効果的にスナップショット取ったりはしてない。 リバランスもバックグラウンドで実行可能 Apache Hadoopが備えるJava APIは100%語幹 Q:なんで、HDFSをがりっと書き換えたの? A:運用性も、ノード管理も。。。全部です。 なくなっても良いデータなら、別にHadoopでもいいですよね。 けど、基幹システムとかだと、信頼性が必要だし、運用の効率も必要だしいろいろ必要。 Q:実績が必要なんですが、どのような試験を行われているのかという情報が公開される?EMCでやられてるテストのプロセスを適用しているなどの裏付けは公開されないの? A:内部で6ヶ月利用してデータロスはない。 品質については強化していく。 Q:MapRとしてHadoopコミュニティへの還元していく内容ってどんなもの? A:Apacheコミュニティに対して1000台のクラスタを提供してスケーラビリティテストとかやってくださいとしている。 Q:このクラスタを実際にはどう使ってもらうの? A:品質アップするためにテスト環境として使ってもらう? Q:ApacheのAPIの互換性を死守するのが必ずしもいいとは思えない場合にどうするの?MapR独自APIとかは出さないの? A:ApacheのAPIに準拠するのは非常に重要。他のHadoop上のアプリが動作しなくなるから。 Q:MapRを容量の大きなファイルシステムとしてだけ利用するなんて想定はありますか?MapReduceを利用しないパターンです。 A:いや、それはw Q:MapRはエンタープライズがターゲットだけど、Amazonはパブリッククラウドが対象。マルチテナントなパブリックサービスでMapRを利用するとかは? A:。。。 Q:ジョブ管理にも手を入れてるの? A:あんまり手を入れてません。 Q:EMCのストレージ製品でMapRのMapReduceない版みたいの出てない? A:中身はMapRじゃないですよ。 想定とは異なり、日本の草薙さんが主に説明されたのですごくわかりやすかったです。 しかもかなり内部まで理解されている方だったので突っ込んだ質問にもきちんと回答されてるので更に理解が進みました。 今回利用された資料は現時点では公開の予定はないという話でした。 ただ、かなりまとまってる資料なので、後悔して欲しいものです。 普通にviとかしてるだけなのに、すごいと思うデモってなんか新鮮でした。 MapR自体を触る機会はまだまだないと思うのですが、MapRとしてHadoopに対する思想が垣間見えたのが面白かったです。 すごいメンツが質問を投げまくるのでいろいろな側面で話が聞けました。 ただ、やっぱり英語のヒアリングがダメダメだというのが露呈しました。。。今年は少し頑張らないと、先が思いやられますね。。。 あと、疑問と言うか、感想ですが、MapR自体が結構多機能で、その機能をどう扱うか、どのようなノード構成やボリューム構成を取るかといった設計が結構大事でしかも大変なんじゃないかなぁという印象を受けました。 特にマルチテナントで利用する場合などは、想定されないミラーの利用などでデータ容量が足りなくなったりといった側面も出てくるのかなぁと。\n説明会のあと、Hadoopにあんまり絡んでないのに図々しくも飲み会にまで参加してきました。 これまた濃いメンバーだったので話についていくのも大変でしたが、面白い話が聞けました。やっぱり懇親会重要ですよねぇ。\n事前にこのブログを読んでいたので話しを聞くのが楽でした。 MapR勉強するために必須のページです。(どうやら今日説明した人がかいてるきがしますが。。。)\n追記: トゥギャってくれた人に感謝。 ","date":1326988680,"dir":"post/2012/","id":"7198e10ebcf1bb88dc479b5c5b9f2c15","lang":"ja","lastmod":1326988680,"permalink":"https://blog.johtani.info/blog/2012/01/20/mapr%E4%B8%AD%E8%BA%AB%E8%AA%AC%E6%98%8E%E4%BC%9A%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-01-20T00:58:00+09:00","summary":"日時:2012/01/19 18:30-20:30 場所:ベルサール三田Room2シアター Inside MapR デモ+内部のお話。 ・自己紹介 Susheel Kaushik 元YahooのHadoop系の人。製品","tags":["勉強会"],"title":"MapR中身説明会に参加しました。(Jugemより移植)"},{"contents":"お久しぶりです。インフルエンザで一家全滅という最悪の状況に陥っていた我が家でした。 流行してるみたいなのでみなさんも気をつけてください。\nさて、そんな中、OSSAJのミニセミナーでSolrについて簡単に話しをしてきました。 人生初Ustだったのですが、ぶっ倒れている中作成した資料だったためなんとも情けない発表だった気がします。(言い訳カッコ悪いですね。。。) 関係者の皆様、申し訳ございませんでした。\n内容としては、Solrの機能を簡単に紹介する程度の資料となっています。デモなどもないのでスライドだけ見てもなんだこれという感じかもしれませんが。\nということで、恥ずかしながら、録画もされているようなので、後で見て反省しようと思います。。。\n[オープンソースソフトウェア検索サーバ Solr入門](http://www.slideshare.net/JunOhtani/solr-11146713)** View more [presentations](http://www.slideshare.net/) from [Jun Ohtani](http://www.slideshare.net/JunOhtani) ","date":1326941184,"dir":"post/2012/","id":"a4462529ab493676987d946019a14945","lang":"ja","lastmod":1326941184,"permalink":"https://blog.johtani.info/blog/2012/01/19/ossaj%E3%81%AE%E3%83%9F%E3%83%8B%E3%82%BB%E3%83%9F%E3%83%8A%E3%83%BC%E3%81%A7%E8%A9%B1%E3%81%97%E3%82%92%E3%81%97%E3%81%A6%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2012-01-19T11:46:24+09:00","summary":"お久しぶりです。インフルエンザで一家全滅という最悪の状況に陥っていた我が家でした。 流行してるみたいなのでみなさんも気をつけてください。 さて、","tags":["勉強会"],"title":"OSSAJのミニセミナーで話しをしてきました(Jugemより移植)"},{"contents":"先日のSolr勉強会でLucene/Solr4.x系のlucene-gosenについて質問を受けていたのを忘れないように(年越しちゃいました、すみません。)先週金曜日(1/6)にissueに登録しました。 まずは忘れないようにと思って、登録だけして3連休に突入したのですが、Robertさんが1/7に対応してくれました。 Lucene/Solr 4.x系では3.x系とはパッケージやメソッドが変更されるなど少し異なる部分があります。 lucene-gosenでは、プロジェクトのページにもあるとおり、4.x系にも対応しています。 ただ、この4x系に対応したブランチが、2011年5月から放置されていました。\nということで、Lucene/Solr 4.0系でlucene-gosenを利用されている方、これから利用される方は、この4x系に対応したブランチを利用してください。 なお、このブランチにはLucene/Solrのtrunk (r1228509)のSNAPSHOT版のjarファイルが利用されています。\n今後はlucene-gosen側でバグ修正や機能追加を行った場合にも4xブランチを更新していく予定です。 ※ただし、Lucene/Solr 4.0が正式リリースされていないため、頻繁にSNAPSHOTのjarファイルを入れ替えることはこなわないと思います。\n","date":1326033660,"dir":"post/2012/","id":"f7df7b85af230b2623d3a827b0cbddd2","lang":"ja","lastmod":1326033660,"permalink":"https://blog.johtani.info/blog/2012/01/08/lucene-gosen%E3%81%AElucene-solr4-0%E5%AF%BE%E5%BF%9C%E3%83%96%E3%83%A9%E3%83%B3%E3%83%81%E6%9B%B4%E6%96%B0/","publishdate":"2012-01-08T23:41:00+09:00","summary":"先日のSolr勉強会でLucene/Solr4.x系のlucene-gosenについて質問を受けていたのを忘れないように(年越しちゃいました","tags":["lucene-gosen"],"title":"lucene-gosenのLucene/Solr4.0対応ブランチ更新(Jugemより移植)"},{"contents":"あけましておめでとうございます。(もう5日ですが。。。) 今年もlucene-gosenを中心に色々と記事を書いていきますので、ツッコミ、コメント待ってます。\nたまには会社のブログを書かないとイカンということで、会社のブログにNearRealTime検索についての記事をアップしました。 読んでやってください。\nということで、今年もいろんな勉強会に出没しますので、よろしくお願い致します。\n","date":1325735817,"dir":"post/2012/","id":"cc573488dec311655890a205aad4fb65","lang":"ja","lastmod":1325735817,"permalink":"https://blog.johtani.info/blog/2012/01/05/%E3%81%82%E3%81%91%E3%81%BE%E3%81%97%E3%81%A6%E3%81%8A%E3%82%81%E3%81%A7%E3%81%A8%E3%81%86%E3%81%94%E3%81%96%E3%81%84%E3%81%BE%E3%81%99%E4%BC%9A%E7%A4%BE%E3%81%AE%E3%83%96%E3%83%AD%E3%82%B0%E6%9B%B4%E6%96%B0/","publishdate":"2012-01-05T12:56:57+09:00","summary":"あけましておめでとうございます。(もう5日ですが。。。) 今年もlucene-gosenを中心に色々と記事を書いていきますので、ツッコミ、コメ","tags":["misc"],"title":"あけましておめでとうございます+会社のブログ更新(Jugemより移植)"},{"contents":"他の方たちよりひと足はやいですが、今年の仕事が終わりました。 せっかくブログを始めたので、振り返りと来年の抱負など書いてみようかなと。\n今年の振り返り まずは、今年1年を振り返ってみます。 今年の出来事はこんな感じでした。\n3月に仕事が一区切り lucene-gosenに参加 ブログを始める 色々な勉強会に参加 Twitterでつぶやきまくり Mac Book Airの購入 PSVita買いました 3月に一昨年から参加していた仕事が一区切りつきました。 もう少し色々とやり残した感がある中で区切りがついたのが少し心残りでした。 あと、3月は震災もあり、色々と大変でした。ただ、自分の中では震災の記憶が少し薄れつつあるのが気がかりです。 良くも悪くも忘れて行ってしまうのだなと。今でも頑張っている方々もいるので、少しでも心に留めておきたいものです。\n個人的に一番大きな今年の変化は「lucene-gosenへの参加」です。 関口さんとここ数年ずっと仕事をご一緒させていただいていることもあり、コミッターとして参加させてもらうことが出来ました。 英語が苦手な中、Robertさんへ自己紹介のメールを書いたり、Issueを英語で書いたりと苦労もしていますが、OSSに参加できることがとても楽しいです。 また、使っていただいている方たちからのフィードバックもいただけているのがすごく励みになります。 やはり、OSSは使ってもらってさらに良いものになっていくのかなぁという感想です。 ただ、自分の腰が重いため、なかなか対応が遅かったりといったところもあるなと反省するところも。\n勉強会にも色々と参加しました。Solr勉強会を始めとして、かねてより興味があるHadoopのカンファレンスやソースコードリーディング。MongoDBの勉強会やDSIRNLPといった少し研究よりの勉強会にも参加しました。 Solr勉強会に参加してきた経験もあり、他の勉強会にも気負わずに参加できたので本当にSolr勉強会には感謝しています。 おかげで、社外のいろいろな方と話ができ、様々な刺激をうけることが出来ました。\n勉強会以外にもTwitterで色々な方に絡みまくったのもまた社外の方とのつながりが出来るいい機会でした。 Twitter依存症じゃないかというくらい、つぶやいたり、人に絡んだりしてます。。。(迷惑だったら言ってください。) お陰で@doryokujinさんや@wyukawaさんが主催してくれたログ解析の飲み会に誘ってもらえたり、@nobu_kさんや@ IjokarumawakさんにSolr勉強会で講演してもらえたりしました。 あと、Twitterを通じて勉強会やHadoop関連の情報、lucene-gosenへのフィードバックなどももらえていてかなり助かってます。 @yusukeyさんや@repeatedlyさんに遊んでもらってるのも楽しいですw\n最後の大きな変化はApple製品の購入でした。 これまでもブログで書いてきましたが、私は今年の中頃までアンチApple派でした。 それがここ半年足らずでAir、Mini、iPadと3つのApple製品に囲まれています。 Emacsのショートカットが使えるのが最大の要因ですが、何ごとも毛嫌いせずためしてみるのがいいなと思いましたね。 今では、Windowsで開発したくないくらいになってきています。\n2012年の抱負 さて、来年の抱負です。 今年いくつかチャレンジしようとして挫折してるものがあります。\nMongoDB触ってみる Scala触ってみる なんかWebサービス作ってみる(Amazonとかで) elasticsearch、IndexTankを調べてみる NewSolrCloudDesignを読み込んで自分なりにまとめる Junsaiに参加する 「7つの言語7つの世界」の続き 最初の3つはセットですかね。コップ本買ったり、NoSQLの本を買ったりしてるのですが、手付かずです。。。 電子書籍の検索サービスでもつくってみようと思いつつ、腰が重い状態です。 来年は余裕を見ながらちょっとずつやりたいですね。\nelasticsearchやIndexTankは仕事がらみです。 Solr入門を書いたこともあり、検索関連には興味があります。Solrだけでも2ヶ月おきに新バージョンがリリースされたり、4.0系でいろんな機能が実装されているのですが、それ以外にもOSSの検索サーバがいくつかあります。 気になってはいるものの英語が障壁でなかなか手を出して来ませんでした。 来年はSolr以外についてももう少し知識をつけていきたいです。 個人的ですが、分散処理にも少々興味を持っています。 慣れ親しんでいるSolrでもSolrCloudという壮大な計画が上がっていて、少しずつ実装もされています。 ブログでWikiページを翻訳してもみたのですが、翻訳に注力しすぎて理解ができていないです。 このあたりをもう少し理解しつつどのような実装がされているかも調べたいところです。\nJunsaiはSolr入門の著者である武田さんが最新のMeCab(今はMeCabが新しくなってしまったので、少し前のMeCabになってしまいました)をJavaに移植したプロジェクトです。 今年頭のSolr勉強会でお披露目があり、私も一応参画しているのですが、手が出せていない状態です。 lucene-gosenで少しは経験を積んできたので、その部分を生かしつつ、こちらももっと活性化させたいところです。 最後は夏ごろにやっていた「7つの言語7つの世界」の再開です。序盤で止まってしまっています。。。 新しい技術に触れる題材としてちょうどよいので、余裕をつくって続きを再開します。 なんか、抱負と言うよりも積み残しですね。。。 他にもTwitterで情報を仕入れるとやりたいことも変わってくるかもしれませんが、それも含めてブログに少しずつでも書きためていこうと思います。\n先ほども書きましたが、今年はTwitterを通じて色々な方たちと知り合いになれた一年でした。 ここには書ききれていませんが、フォローしてもらっている方々や勝手に絡んでも相手をしてくれている方々に感謝しています。 今後も絡みますのでよろしくお願いしますw あと、様々な勉強会に今後も顔を出していくので、かまってやってください。 いやぁ、色々書いたけど恥ずかしいですね。。。 まぁ、何事も経験なので、恥ずかしいと思いつつ今後も色々書いていきます。\n","date":1325006100,"dir":"post/2011/","id":"7164823f504286e3a762ee612ff0a988","lang":"ja","lastmod":1325006100,"permalink":"https://blog.johtani.info/blog/2011/12/28/%E4%BB%8A%E5%B9%B4%E3%81%AE%E6%8C%AF%E3%82%8A%E8%BF%94%E3%82%8A%E3%81%A8%E6%9D%A5%E5%B9%B4%E3%81%AE%E6%8A%B1%E8%B2%A0/","publishdate":"2011-12-28T02:15:00+09:00","summary":"他の方たちよりひと足はやいですが、今年の仕事が終わりました。 せっかくブログを始めたので、振り返りと来年の抱負など書いてみようかなと。 今年の振","tags":["misc"],"title":"今年の振り返りと来年の抱負?(Jugemより移植)"},{"contents":"@yusukeyさんにサインをもらう目的で勉強会に参加してきました。前回もらいそびれたのでw 残念ながら、まだTwitter APIを触ってないし、利用したサービスも思いついてないんですが。。。 けど、勉強になりました。 といことで、いつものごとく、自分メモです。\n◎APIの基本と最新動向について @yusukey 資料:http://www.slideshare.net/yusukey/21twitter-api-api\n・検索APIについて http://search.twitter.com/search.json?q=*** %3Aは「:」 詳しくはリファレンスを買ってね。 ・ページ処理のベストプラクティス Pageじゃなくて、MaxIdを利用して取得すると1500件以上のデータも取れるよ。 ・最近のTwitterAPIアップデートについて - ポケリファでの変更点 ストリーミングのエンドポイントがSSLのみに。(twitter4jは2.2.5以上) - ユーザ名が検索APIのスキーマに追加(12月以降) - in_reply_toの追加(12月以降) =\u0026gt;検索結果から会話を追える。 ・include_entitiesが追加 t.coの展開したリンクも取得可能。 けど、t.coリンクの飛び先はt.coリンクにしてね。パトロールとかしてるから。 ・本当にあった怖いt.co - URLのつもりじゃないのにリンクになる。 →仕様です - 日本語を含むURLがおかしくなる。 →少しずつ治ってきてる。 - リンク先のURLがわからない(クライアント依存) そのたいろいろ? ◎Zusaarについて何か @knj77 資料:\n・特徴 - SNSアカウントでログイン トラブル抑制など - 事前決済可能。最小催行人数が決められて、払い戻しも可能。 ・利用例 旅行とか合宿に使う例がないんだけど、できるんじゃないかな? ・イベントを依頼する機能 欲しいイベントを提案可能 http://www.zusaar.com/idea/ ・アーキテクチャ GAE/Java、Twitter4j、Yahoo APIのテキスト解析 ・SNS連携 TwitterのDMが送れない。他のSNSのアカウントが主催者とか。 なので、自分からDMが届く。 ・PayPal連携 小さいアプリほど相性がいい 固定費ゼロ、マイクロペイメント(100円とか可能) 銀行口座の登録不要、返金可能。部分返金も可能。 ・トラブル - SNS側のエラーが適当 ステータスコードは信用できないw - PayPalの実装を3回変更 - GAE料金体系の変更 9$/month。追加料金はほとんど使ってない。Googleのアナウンスが下手。 - ブルーオーシャンのはずが... Q:Zusaarで返金できるポイントは? A:主催者が主導(手動?)で返金可能。 Q:無料イベントで約束手形的に課金するのはできる? A:やろうと思えば出来ます。ただ、システム的には100円は手数料としてもらっている。 Q:新しいATNDに対抗意識はありますか? A:ZusaarはCtoCをターゲットにしてる。ATNDはBtoCなので、補完できる関係だと思ってる。 Q:APIでTwitterIDとかで検索したいんですが。 A:対応予定あります。 Q:できればATNDのAPIと共通化してほしい。 A:追加してるだけのつもりです。 ◎グループに分かれて自己紹介 6人中、懇親会参加者が5人もいたw\n◎LT - OAuth Echoについて@tkawa 資料:http://www.slideshare.net/tkawa1/oauth-echo-20111221-10657954\ntwitpicで使ってる。 認証をServiceProviderに委譲する仕組み。 クライアントがOAuth登録してあれば、。。。 ・問題点 非公式仕様 OAuth1.0に基づいてて2.0では変わってそう。 ・Railsで実装してみたよ。 - GroovyとQuartzとTwitter4Jの甘い生活G @mike_neck 資料:\nベトナムから緊急来日らしい。 しかもむちゃぶりされたらしい。 - 認証なしで使えるAPIまとめ?@ts_3156 えごったーの作者で学生!\n- TDD (Twitter4J Driven Development) @sue445 資料:\nAZusaarの作者! テストドリブンなはなし。 Twitter4Jを利用するときのTDDの簡単に実装できる仕組みの話。 ここにソースがあるのかな? http:/github.com/sue445/twtrhack/ - 放射線を自動計測してTwitterにつぶやくimaocandeの紹介 @imaoca 松山の方。 とまぁ、APIの話だけでなく、実際にAPIを利用している方のサービスの話など色々と面白い話が聞けました。 厚かましくも懇親会にも参加して、そこでも今までのイベントとは違うクラスタの方たちの話が聞けたのが楽しかったです。 やはり、APIを利用して色々とやってみようと思っている方が多かったのでいつもと違う話が聞けたんですかね。 私自身はサービスを思いついたりしないタイプなので、いい刺激になりました。(まだ、特になにか作る気にはなってないですがw) ということで、次回も余力があれば参加したいなー。 ","date":1324485660,"dir":"post/2011/","id":"da67e2f049b5b6babcf7906b85653399","lang":"ja","lastmod":1324485660,"permalink":"https://blog.johtani.info/blog/2011/12/22/%E7%AC%AC2-1%E5%9B%9E-twitter-api-%E5%8B%89%E5%BC%B7%E4%BC%9A--%E6%9D%B1%E4%BA%AC%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-12-22T01:41:00+09:00","summary":"@yusukeyさんにサインをもらう目的で勉強会に参加してきました。前回もらいそびれたのでw 残念ながら、まだTwitter APIを触ってない","tags":["勉強会"],"title":"第2.1回 Twitter API 勉強会 @東京に参加しました。(Jugemより移植)"},{"contents":"lucene-gosenの最新版(1.2.1)をリリースしました。\nプロジェクトページよりダウンロードが可能です。\n今回の修正では、特定文字列でメモリの使用量が爆発してしまうバグへの対処となっています。 1.2.1以前のバージョンを利用している場合は最新版を利用するようにしてください。\n","date":1324437339,"dir":"post/2011/","id":"584b2b145f362098fc5fc1e634d57de5","lang":"ja","lastmod":1324437339,"permalink":"https://blog.johtani.info/blog/2011/12/21/1-2-1%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-12-21T12:15:39+09:00","summary":"lucene-gosenの最新版(1.2.1)をリリースしました。 プロジェクトページよりダウンロードが可能です。 今回の修正では、特定文字列で","tags":["lucene-gosen"],"title":"1.2.1リリースしました(Jugemより移植)"},{"contents":"いつものようにSolr勉強会に参加してきました。 皆勤賞を継続中です。(暇人というはなしも。。。) 今回は話しを聞きたいですねぇといったら、いやいや、話もしてくださいと言われてしまったので、 発表もしてきました。 発表資料はブログの最後に掲載してあります。\n日時:2011/12/19(月) 19:00~21:00 場所:Voyage Group 8階\n1.Fessについて N2SM菅谷さん 資料:http://www.slideshare.net/shinsuke/solr-fess\nマルチコアで構成されてる。 S2Robotでクロールしてますよ。 ※ごめんなさい、あまり聞けなかった。。。あとで資料を読んで質問します! 2.lucene-gosenについて @johtani 発表しました。 3.ApacheConに参加しました @Ijokarumawak 資料:http://www.slideshare.net/KojiKawamura/apache-con-2011report\n日本-\u0026gt;カナダ-\u0026gt;ベルリン-\u0026gt;カナダ-\u0026gt;日本 50万円。。。 キーノート1: セキュアな開発について。 キーノート2: Hortonworksのコミュニティ運営大変だよねぇ、頑張るよという話。 キーノート3: 本題:Lucene 4.0の話:Simonさん ヨーロッパの方? PostingsFormatの話。 Document内部の情報を使うためにどうする? StoredField:あんまり効率よくないね。 FieldCache(on RAM):インデックス作る動作の逆を行う。これも効率よくないね。 IndexDocValue:インデックス作成時に作られるので読み込み性能が100倍!(DocValue) Document Writer Per Thread! Automaton Query あいまい検索の処理に利用。 Solr Flair Solr同梱 Prism LucidImaginationが出してるJRubyのラッパー GitHubで公開されてるらしい。 Blacklight RoR 図書館むけのパッケージじゃなかったっけ? VUFind PHP これも図書館向け? TwigKit JSPのタグリブ おぉ。これ直接読んでるのかな? Ajax Solr Ajax用 QA Q:TwigKit、Ajax Solrは直接Solrを呼んでるんですかね? A:たぶん、そうですね。JSPのはSolrJかもしれないですが。 4.サフィックスアレイの話 @nobu_k 資料:http://www.slideshare.net/nobu_k/suffix-arraysolr\nSuffix Arrayの話 全文検索インデックスの話。 Suffix Array=検索漏れがない。 Suffix=接尾辞 RedBullがどの文書に入っているか! SuffixArrayのメリット 検索漏れがない=n-gramと同様 仕組み上n-gramよりも早くなるケースが多い。 長いクエリに対して速い THIS IS IT:全部ストップワード SuffixArrayのデメリット インデックス構築系 アルゴリズムが難しい。 メモリ上での構築はちょっとだけ楽(けど、簡単ではない) SAISなど。けど、これだとメモリがいっぱいないとキツイ HDDでの構築 ランダムアクセスを排除したアルゴリズムが必要(dc3,dc7) インデックス更新、差分更新できない。 頑張って1台100GB/day Sedueでは? SA&インメモリn-gramのハイブリッド 更新分はn-gramに 検索時にはn-gram+SAの内容をマージして出力 検索 二分探索はHDDとは相性が悪い。 メモリ上で検索できればOKだけど、サイズが大きいからきびしい。 圧縮接尾辞配列なら可能だけど、低速。。。 SSDだとはやいよ! SSD対応のクラウドはまだないけど。。。 Sedueでは最初の20段でキャッシュしてる。 VSストップワード ストップワード込でインデックス作るみたい。 1.SAを二分探索 2.該当区間から出現位置をロード 3.出現位置をソート O(n)だけど、CPUのキャッシュミスが激しく影響 4.ソートした出現位置からヒット文書を求める。 同じくキャッシュミスがやばい ・実際にはmallocした領域のページフォルトが一番やばい SAが超活躍する場面 遺伝子の検索 n-gramとか死ぬ。形態素解析も無理。区切りがわからんw 5.P2P検索 ORBIS @ceeflyer 資料:http://www.slideshare.net/ceeflyer/p2p-search-engine-orbis\nORBISとは?ラテン語で「目」 ORBISとは? リアルタイム検索エンジン 自律分散検索エンジン もともとはAmebaなうの検索のため ノード構成 比較的小規模(~1000台)\u0026lt;=しょ、小規模ですか。すごいな。 Master-Slaveの差がなし MessagePack利用 フルメッシュネットワークを構築 インデックス フィールド: Content(形態素解析対象) Appendix(形態素解析しない) Flag(属性) ハッシュレプリケーションで登録。近いハッシュ値に登録(レプリカ数を指定できるのかな?) 単語に対して転置インデックスを一定数で固定 投稿日時が新しいものだけ検索するため。 検索: マージして結果を返す。 壊れてたら取れたものだけ返す。 QA: Q:ハッシュ値が大きくて1台しか選ばれないとかあるのでは? A:ハッシュ値は循環しているという形で3台とか選ぶ。 Q:最大何台で稼働させてる? A:現在はまだ5台程度 Q:障害時にレプリケーションの維持はするのか? A:現時点はしてない。 Q;Cassandra、Lucendraとかあるけど、それをしなかった理由は? A:単純にConfigurationができるから、1から作った。 今回はSolr以外の話も聞けたのがとても面白かったです。 やはり、Solr以外の検索エンジンについても知見があると、色々と比較の話しとかしやすいので。 それにしても、一からP2Pの検索エンジンを作っているのにはびっくりしました。 他にもSuffixArray(Sedue)の話も気になっていたのが少し氷解したし、海外旅行のノウハウがApacheConの話で聞けたしw やはり、発表をすると話しをしてもらえるのもあって、いい機会だなと再認識しました。 今回も紹介ネタだったので、ちゃんと事例とか測定したものも発表できるようにならねばと。。。\nということで、私の発表資料はこちらになります。疑問点とか質問事項とか、指摘事項など、コメントorTwitterで連絡いただけるとすごく嬉しいです。\n[Lucene gosenの紹介 solr勉強会第7回](http://www.slideshare.net/JunOhtani/lucene-gosen-solr7)** View more [presentations](http://www.slideshare.net/) from [Jun Ohtani](http://www.slideshare.net/JunOhtani) ","date":1324311660,"dir":"post/2011/","id":"c6696a730f7498efb66f5ba3a8b35d08","lang":"ja","lastmod":1324311660,"permalink":"https://blog.johtani.info/blog/2011/12/20/solr%E5%8B%89%E5%BC%B7%E4%BC%9A%E7%AC%AC%EF%BC%97%E5%9B%9E%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F%E7%99%BA%E8%A1%A8%E3%82%82%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-12-20T01:21:00+09:00","summary":"いつものようにSolr勉強会に参加してきました。 皆勤賞を継続中です。(暇人というはなしも。。。) 今回は話しを聞きたいですねぇといったら、いや","tags":["勉強会"],"title":"Solr勉強会第7回に参加しました。(発表もしました)(Jugemより移植)"},{"contents":"ということで、懲りずに#DSIRNLPに参加してきました。 基礎的な部分をおろそかにしたくないけど、TokyoNLPとかWebMiningではついていけないので。。。 今回もしがみつくのが精一杯かもしれないと思いつつ、聞いて来ました。\n0. DSIRNLPについて @overlast 講演者が可能なら実装に関して言及する。 「こうやって作って結果を出す」系の発表をしましょう。 開催に際して協力してくださったみなさんへの感謝の辞。 1.自然言語処理はじめました @phyllo 資料:http://www.slideshare.net/phyllo/ngram-10539181 ブログ:http://d.hatena.ne.jp/jetbead/20111210/1323499634 某Web企業の新入社員!(すごい) で、入って自然言語処理をはじめたらしい。 N-Gramの説明 Perl? 1.ナイーブな方法 Perlでハッシュ使って数えてみたよ。これでOK? いやいや、Nが大きくなったりデータが大きくなるとキツイでしょ 2.SuffixArrayを使う ということで、Suffix Arrayを使ってみた。 SuffixArrayのデータを作ってから、上からN文字数えれば数えられる! (数式出てきたけど目も取れなかったw) これでいいじゃん?いやいや、更に大規模だとどーすんの。1TBのメモリ 3.近似カウント法 いくつかある中からLossy Countingを説明します。 ストリームデータから数えてみよう。 C++の実装? 4.分散処理を使う方法 近似じゃダメ!正確な頻度が欲しい! =>Hadoopつかえ! 色々やってみた感想が良かった。 SuffixArrayのメモリ使用量という話がありましたが、ディスクを使う方法もあります。 by ? 新人から自然言語やり始めたというが、自分が新人の頃にはこんなに出来なかった気がするなぁ。 発表とかもってのほかだったし。 2.AI で AI 創ってみた(LT) @uchumik 資料: Luaプログラミングが出てきたので、 多クラスロジスティック回帰とListNetを書いて見ました。(ただし、本は読んでないよ。) 学習器のお話。 ラグナロクオンラインのAIがLuaでかけることを思い出した。 動画の途中で終了w GitHubにあげなさい。ブログ書きなさい。動画もあげなさい。 by @overlast 資料の割に時間がw 2.5.CMコーナー 技評の方からWEB+DBのCM!(ただし、商品なし) 読者層の95%が男性w 総集編買ってね!WEB+DB plusシリーズも買ってね! 書いてor買ってね。 技評さんつぎはオライリーさんに負けないように賞品持ってきてねw 3.Mahout にパッチを送ってみた @issay 資料:http://www.slideshare.net/issaymk2/mahout-10539755 人がやめていく会社で検索やHadoopやってます。 ※今日は皆既月食です。 機械学習関連 SGDはMapReduceでの分散に対応していないので、パッチを送ってみた。 MapReduce、Shuffleなどの説明 これをベースにナイーブベイズの説明をあわせて実装を見てみる。 ・単語wのカテゴリcにおける確率 ・文書dのカテゴリcにおける確率 -文書dに出てくる単語wの確率の積と定義 単語の相関を見ない。 ゼロ頻度問題の解説 文書頻度の逆数(IDF) カテゴリ毎の文書数のばらつきに対応するために、Complement Naive Bayes BayesFeatureDriver 次はランダムフォレスト 決定木とは? ランダムフォレストとは? ここでは素性。 Mahoutでの実装は? 決定木の数だけ処理分散が可能。 Reducerは使ってない。=Mapperで計算が終わっちゃうから? 次はロジスティクス回帰 尤度関数、損失関数、確率的勾配降下法(SGD) 先程まではオンライン。バッチ学習もある。 Mahoutでの実装はオンラインで、MapReduceに向いてない! Adaptive Logistic Regrettion(アダプティブロジスティクス回帰)というのも実装されてる。 送ったパッチの概要 Iterative Parameter Mixisngというのがあるので、それをSGDに適用するパッチ 今後 MapReduce以外も増えるかも。 Q:パッチがはいったバージョンはいつでる?A:3日前に送ったのでまだです Q:ナイーブベイズのMapReduceが一段ムダでは?(文書数のカウントは同時に出来るよね)A:そうですね、ぜひパッチを送ってみてください。 Q:Mahout、Hadoopの未来は明るいんでしょうか?A:HDFSのデータをMapReduce以外のフレームワークで使えるといい。 Q:Hadoopのパッチ送るの大変ですか?どのくらいかかりました?A:4,5ヶ月かかりました。 すみません、途中から頭がパンクしてしまいました。。。 ただ、MahoutがHadoopに乗っかってるからといって、MapReduce活用できてるわけじゃないという話がわかりました。 4.GraphDBのデータ構造 @kimuras 資料:http://www.slideshare.net/skimura/graphdatabase-data-structure LTみたいな資料にになっちゃいました。すみません。 mixiではMySQLだけど、いろんなDB触ってます。 なので、GraphDBに興味持ちました。 Luceneを教科書的に読んでます。 Neo4jモダンな作りでよかった。 http://www.slideshare.net/skimura/ss-8787632 ノードデータの構造 NodeManagerというのがいて、Cache系を管理してる。 プロパティのインデックス、トランザクションManagerもいて、PersistenceManager ここからNodeにアクセス(探索、)。 キャッシュとかいいね。 Soft LRU Cacheってのもあるよ。 その他色々w Q:トランザクション周りでLRUのキャッシュはどうなるんでしょうか@kumagi A:きちんとロックしてました。 Q:分散はネットワーク、HDDどちらがキツイ?A:HDDがかなりきつい Q:プロパティもキャッシュに乗ってたほうがいい?A:プロパティも必要なら載せたほうがいい。メモリのしてはできたはず。 Luceneがほめられてました。Neo4Jの 5.冬のLock-free祭り @kumagi 資料:https://docs.google.com/viewer?a=v\u0026amp;pid=explorer\u0026amp;chrome=true\u0026amp;srcid=0B72X9w6tG5q0NzMyODgwNDYtNjY4Yy00ZDgwLTliZDMtMjQwYmViMWE5NGU5\u0026amp;hl=en_US ※資料がうまく見れないのは、アニメーションガチガチって話だからかな? http://twitter.com/#!/kumagi/status/145363169718697984 辻Lock-free活動してます。 Lock-freeとツイートすると補足されるらしい。 CPUの系譜のおさらい ポラックの系譜 最新のIntelManyCoreとか東大とかに配られてるらしい。 なんで、マルチコアのCPUがTSUKUMOとかで売ってないの? 僕らが使いこなせてないから。=マルチスレッドの対応がうまくできてないから。 CAS=Compare And Swap まずは、Lock-free stack ABA問題? Lock-free Queue QueueのEnqueueの場合は2回のCASが必要になる。 不変条件を守る。ロックだと守りやすい。 2回のCAS処理の間が危険領域 Lock-free List 色々なロックの説明。 Lock-free hash map これも気が狂ってるアルゴリズム? ConcurrentHashMapなども話が出てきたが、説明しない=Lock-freeじゃないからw Lock-free SkipList SkipList: 順序関係のあるデータをO(log n)で検索・挿入・削除ができるデータ構造(2分木ともろかぶり) DougLea先生がjava.util.concurrentに入っています。 Lock-free Btree 論文ないんですよ。簡単すぎて。 SoftwareTransactionalMemory The Art of Multiprocessor Programmingを読みましょう! 論文のお話。 http://labs.gree.jp/Top/OpenSource/Flare.html を利用しているらしい。 The Art of Multiprocessor Programming関連サイト http://www.cs.brown.edu/courses/cs176/lectures.shtml すごくわかりやすかった。資料をもっと見たいなぁ。 Q:STMはメモリ使用量が2倍になる?A: Q:STM(Clojure)使ってみたけど残念な性能しか出なかったけど、なんで?A:Clojureのものはロックベース。でうーむ。。。 6.機械学習と最適化の基礎(仮) @tkng PFIの徳永さん 日本語入力を支える技術(技評)2012年2月発売予定 最適化の話、機械学習の話、学習率の話。 大域的最適、局所的最適の説明。(言いにくそう、大域的最適w) 凸最適化問題=最適解が1つしかない? 大域的最適解=局所的最適解 機械学習なはなし。 スパムメールの例で説明 淡々と語られてましたが、わかりやすい説明でした。もっと昔にこんな形で数学の説明聞きたかった。。。 7.機械学習・言語処理技術を用いた誤り検出・訂正(LT) @mamoruk 資料: スペル誤り訂正とかに機械学習とか使われてます。 8.神の言語による自然言語処理(LT) @AntiBayes 資料:http://www.slideshare.net/AntiBayesian/ss-10539347# Lispさいこー Clojureさいこー lucene-gosenもいいよーw 9.言語判定へのいざない(LT) @shuyo 資料: Solrで採用されたlanguage-detection libraryの紹介。 アゼルバイジャン語とか大変みたい。 12.作ろう!簡潔ビットベクトル @echizen_tm 資料:http://www.scribd.com/doc/73565169/Lets-Impl-Sbv 入門編: 簡潔データ構造 データサイズをほぼ情報量的下限にまで小さくしたデータ構造 データは小さいし、速度速いというのがこれ。 実用化されてる。 mozc(LOUDSが使われてます) Sedue(圧縮接尾辞配列(デフォルトではなくなった by @tkng)) 種類: ビット列:ここの説明がこのあと 木構造:トライ木をLOUDSが結構で実装するケースが多い。データサイズが小さくなる 文字列:ウェーブレット木が有名。全文検索、転置インデックスにウェーブレット木を使う研究が多い。 中級編 簡潔ビットベクトル: rank(i)関数:i番目より前の立っているビットの数。 疎なデータ列の効率的な実装に使える。検索結果が少ない場合のFacetとかに使える? select(i)関数:? 可変長データ列の効率的な実装 上級編 ダメでした。。。ごめんなさい。。。 体力的に厳しかったです。。。けど面白いし、わかりやすい。どういった所でこれらを使うべきかを取捨選択するのがすこし難しそうです。Luceneとかの内部ソース見ると実はこのあたりで実装されてる部分があったりするのかも。 11.類似文字列検索の仕組み @overlast 資料: 使い所のはなし 例:辞書メンテナンスコストを軽減したい 架空の事例から類似検索を適用できるというストーリー 既存データが活用されるうれしさの例? Apporoのデータ構造とかの話かな? 11.5.審査委員長から賞品持って帰る人の発表 @kumagi @tkng @echizen_tm の方たちでしたー 12.懇親会 いやぁ、前回も感じましたが、基礎ができてないなぁと実感できた勉強会です。 そして幅も広い。やはり、数学的な要素が時々出てくるのでその部分をもっと身につけないといけないなぁと。。。 ついていけなかったところも多々ありましたが、頭の中にキーワードが入ってればなんとかなるかなぁと。 Neo4jやLuceneのソースコードリーディングをやるのが仕事に役立ちそうなので、少しずつでもやろう。 これから懇親会なので、とりあえず、このへんで。 あとで、見返しながら、リンク貼り直したりすると思います。\n","date":1323529475,"dir":"post/2011/","id":"16fa0e4aefe18e1446bf6baefd3ba400","lang":"ja","lastmod":1323529475,"permalink":"https://blog.johtani.info/blog/2011/12/11/%E7%AC%AC2%E5%9B%9E-%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0%E3%81%A8%E6%83%85%E5%A0%B1%E6%A4%9C%E7%B4%A2%E3%81%A8%E8%A8%80%E8%AA%9E%E5%87%A6%E7%90%86%E5%8B%89%E5%BC%B7%E4%BC%9A%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-12-11T00:04:35+09:00","summary":"ということで、懲りずに#DSIRNLPに参加してきました。 基礎的な部分をおろそかにしたくないけど、TokyoNLPとかWebMiningでは","title":"第2回 データ構造と情報検索と言語処理勉強会に参加しました(Jugemより移植)"},{"contents":"ひさびさに、MBAのお話です。 セットアップといっても、物理的な方ですね。 以前、ケース(カバー)について記載しました。 この記事にも書いてあったのですが、付属の滑り止めが簡易なシールで、カバンの中から出し入れすると剥がれるは、作業をしてるとずれるわで、悩んでいました。 今日、たまたま、東急ハンズに行くことがあったので、店員さんに相談してすべり止め対策のグッズを購入しました。 相談した所、カバーは傷がつきにくくなるような素材ですから、シールもつきにくいとのこと。(言われてみればそりゃそうか。) 対策としては紙ヤスリで傷つけたところに薄手のシールゴムをつければはがれにくくなりますよとのこと。 ということで、やってみました。まぁ、ゴムにホコリはつくかもしれませんが、今のところ滑らず快適! いやぁ、ハンズの店員さんすごいですわ。 MBAについてはこんなとこです。最近また、出先に行っていてMBA使えないので、ブログを書くかメールにしか使ってないです。。。\nで、もう一つはMac Mini(2009 late:Core2Duo 2.26GHz、メモリ4G、HDD250G)です。 前職の同期から安く譲ってもらいました。音声が出力されないという問題点があるとFacebookでつぶやいているのをみて、興味を持ったらゲット出来ましたw で、セットアップをしたのです。 大変でした。まずつまずいたのが、キーボードとマウスでした。 これまで使っていたデスクトップのキーボードがあるのですが、これがPS/2ということで使えません。(軽いジャブ) MBAのキー配列にも慣れてきていたので、ビックカメラで悩みながらもApple純正のワイヤレスキーボードとまじっくトラックパッドを購入。 で、まずは、付属のLeopardで初期化。 このときは、ワイヤレスキーボードは認識したのですが、マジックトラックパッドはこの時代に無かったらしく、反応せず(さらに軽いジャブ) さすがに前のPCのマウスはUSBだったので、これを利用してセットアップ再開 次にSnow Leopard(これもつけてくれた)にアップグレードして最後にLionです。 Snow Leopardでソフトウェアアップデートしたところでようやくトラックパッドが認識できたと。 で、やっと使い始めたのですが、MBA(2011)に慣れていたので、思いの外もっさりした動きをしているMacMiniに 戸惑ってます。(トドメのストレート。現在ここ) ということで、どうやれば快適に使えるかアイデア募集中です。 とりあえず、Lionの設定のウィンドウ復元機能やアニメーションをオフにするなど対策してます。 HDDのSSD化とかメモリ増設とか考えないとダメかなぁ。 あと、ついでにBootcampも興味があるので、せっかくだから実験する予定です。 Windowsが前のデスクトップより快適に使えるようになるなら、Windowsマシンとするのもありかなぁと。。。\nセットアップ系はこのへんで。 あとは、最近興味が有ること2点です。(技術系ではありません) 1つ目は最近発売されたゼルダ。夜な夜なやってます。 もともとゲーム好きでゼルダも欠かさずやってきてますが、ゼルダらしさを残しつつ新しい要素やアクションも取り入れとなかなか楽しいです。 ただ、Wii全般に言えることですが難しい!まぁ、楽しんでますけどね 2つ目は前からつぶやいてるのですが、電子書籍を読むためのタブレットがすごく気になってます。 最初は財布に優しく、MBAを普段持ち歩いてるのもあるから、LenovoのA1(7インチ)で決まりだと思っていたのですが、技術書を読むのは少しキツイかもという印象。 どうしてもオライリー本などの大きめのサイズになるため、7インチの画面でPDFを表示したところ、字が小さくなってしまい拡大しないと見づらいのです。 ただ、拡大してしまうと今度はパッと見るという一覧性が下がってしまいます。。。 少々重くなってもいいので10インチにしたほうがいいのかな、けど、電車で立って読むの辛いかもなどなど考えているところで最終的な決断ができない次第です。。。 最初は毛嫌いしていたiPad2もいいかもと思う始末で困ってるとこです。 安い中華パッド(2万ちょっと)に手を出すか、7インチで我慢するか、Galaxy Tab 10.1のWifi版を輸入業者から購入するかと悩んでるところ。 ただ、長く使うのを考えると、OSのバージョンアップなどを保証してくれるiPad2が実はいいじゃないかなぁなど。 皆さんからしてみればくだらないなぁと思われるかもしれないけどずーっと悩んでつぶやいたりしております。 はぁ、こまった。(そもそもそんなにスペックいらないんじゃないかというのもあるからなぁ。メインはPDF読むことだから。) ゼルダの伝説 スカイウォードソード (期間限定生産 スペシャルCD同梱) ","date":1322668828,"dir":"post/2011/","id":"6e970d0818d58ff2d50c5bf037b1a565","lang":"ja","lastmod":1322668828,"permalink":"https://blog.johtani.info/blog/2011/12/01/mba%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97%E5%82%99%E5%BF%98%E9%8C%B2%E3%81%9D%E3%81%AE%EF%BC%95%E3%81%A8mac-mini2009late%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97%E3%81%A8%E3%81%9D%E3%81%AE%E4%BB%96%E3%81%8F%E3%81%A0%E3%82%89%E3%81%AA%E3%81%84%E8%A9%B1/","publishdate":"2011-12-01T01:00:28+09:00","summary":"ひさびさに、MBAのお話です。 セットアップといっても、物理的な方ですね。 以前、ケース(カバー)について記載しました。 この記事にも書いてあった","tags":["備忘録"],"title":"MBAセットアップ備忘録その5とMac Mini(2009late)セットアップとその他くだらない話(Jugemより移植)"},{"contents":" どんな本でも大量に読める「速読」の本 Twitterで知り合った方がこの本について書かれていたブログ記事を読んで興味を持ち、読みました。 書籍(特に技術書)が山になっていたこともあり、速読に興味を持っていたところちょうど記事を目にしたのは きっと何かのタイミングなんだろうなと。\n悪い癖で、電車で読もうと本を常に持ち歩くのですが、ついついスマートフォンやゲームで遊んでしまい、今回も読むのに時間がかかってしまいました。 3章の途中までを今月頭に読んでいたのですが、そこから少しほったらかしで、読み終わったのが昨日でした。\n本の内容ですが、先ほどのブログにも書かれていますが、速読は技術ではない。 ### 速読 = 速読技術 X ストック(知識、経験、情報) であると。あとは、わからなくてもいいから、ざっと目を通す感じで繰り返し読みなさいと。 さらに、1回でわからんくてもいいから、とにかく繰り返し読むことが重要だということでした。\n確かに「速読=1回で速く読む」、「読書=1回で理解する」という意識がどこかにあったなぁと気付かされました。 プログラム組んだり、あることを覚えるときは繰り返しを意識してたのに、読書は1回読んで「はい、おしまい。」という気になってました。(マンガは繰り返し読むんですけどねぇ)\n他の速読の本は胡散臭いし、絶対無理だよなぁと思ってたのですが、この本に書かれている話は筋が通っているように感じました。 ただ、考えずにサラサラ読みなさいという部分の実践はなかなか難しいかな。どうしても頭の中で音読してしまうので。 私は間を開けてしまったせいで、時間がかかってしまいましたが普通なら1日あれば読める内容なので速読に関してちょっとと思ってる方は読んでみると面白いかと思います。\nちょっとだけショックだったのは、この本の論理だと電子書籍は速読に向いていないというところです。 せっかく溜まった書籍をPDF化して、タブレット購入して(まだ買ってない。。。)読もうと思っていたところなのに。。。\n","date":1322542620,"dir":"post/2011/","id":"0ebe78077c8b48410cf52a0bccdff866","lang":"ja","lastmod":1322542620,"permalink":"https://blog.johtani.info/blog/2011/11/29/%E3%81%A9%E3%82%93%E3%81%AA%E6%9C%AC%E3%81%A7%E3%82%82%E5%A4%A7%E9%87%8F%E3%81%AB%E8%AA%AD%E3%82%81%E3%82%8B%E9%80%9F%E8%AA%AD%E3%81%AE%E6%9C%AC%E3%82%92%E8%AA%AD%E3%81%BF%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-11-29T13:57:00+09:00","summary":"どんな本でも大量に読める「速読」の本 Twitterで知り合った方がこの本について書かれていたブログ記事を読んで興味を持ち、読みました。 書籍(","tags":["読書"],"title":"「どんな本でも大量に読める「速読」の本」を読みました(Jugemより移植)"},{"contents":"Hadoopソースコードリーディング第7回に参加しました。 いつものごとく、自分用のメモをとっていたので。 第6回(2010/12)には参加してたのですが、あれからそういえば、話が無いなぁと思っていたところに 再開するという話がTwitterに流れてきたので、即申し込みしました。 思い返せば、Hadoopに興味をもって少し触っているところで参加したのだったなぁと感慨深い思いを思い出しました。\n今回は場所を変えて豊洲のNTTデータさんで開催されました。\n日時:2011/11/28(月)19:00~22:00 場所:豊洲センタービルアネックス NTTデータ\n◎アジェンダ+導入(NTTデータ 濱野さん) ちょっと間が空きましたが隔月で行う予定。 2012/01/12くらいに次回を予定。ネタ募集中。 ◎Hadoop World NYC 2011 参加レポート - NTTデータ 下垣 徹さん (Hadoop徹底入門著者の一人です!) ・イベント概要:2011/11/08~09にNYで開催 スポンサー企業の数がどんどん大きくなってる。 ・会場の様子 最初のキーノートは立ち見が出るほど。 個別に5並列でセッションが開催されてましたと。 ・キーノート紹介 1.Hadoop World(Michael Olson) アンケートからの概観 HadoopはNext Generation DataCenterだそうで。 2.JP Morgan(Larry Feinsmith) コスト削減+収入増加のためにHadoopつかうぞと。 BigData分析の戦略 ユースケース1:ETL(Extract/Transfer/Load)ツールとして ユースケース2:共通データ基盤 検索頻度が低いデータの低コストストレージなどなど。 ユースケース3:データマイニング 異常値検出とか。 3.eBay(E. Williams) Cassini:オークション情報の検索エンジン 柔軟な検索+協力なランキング機能 Hadoopで転置インデックス作成=Luceneは使ってるってことかな? HBaseも利用。データはHBaseに登録してる。 4.Informatica(James Markarian) データとプロセス Hadoopが賑わうからRDBMSも活気づく Hadoopはプラットフォームになるよと 5.Cloudera(Doug Cutting) Hadoopの背景と今後について BigDataを分散処理するためのカーネルになりつつあるよと。 Apacheプロジェクトの良さ 類似するプロジェクトも共存させてるよと。 Hadoopの今とこれから(0.20(今)、0.23(将来)) 0.23はHDFSの性能面改善、スケーラビリティの強化、HA MapReduce2.0 CDH4のはなし。 Hadoopコミュニティはまだまだ若い ・HadoopWorldの傾向 HBaseの利用増加 利用理由? 小さいレコードにも強い。 ランダムアクセス 大手ベンダ参加 Oracleすげー。Hadoopの周りを固めていくぞと。 Hadoopの周りを各社がどう固めていくかというはなし。 事例が多い WibiData:HBaseの利用事例。Fonedoctor Walt Disney:Big Dataに対する機会損失があるから、導入するよと。 テーマパークの交通流解析にも使うぞ! イケメンによる来年(2012年)のHadoop Worldの動向!? 参加者3000人! ラスベガスで開催? スポンサー拡大で食事が美味しく!? 全方位戦略vs.特化型 BIツールベンダの巻き込み 利用事例のアピール合戦 HBaseの利用事例が続々!(Salesforce.comあたりがセッション持つんじゃね?) Hadoop対抗アプリケーション、業界特化型キラーアプリケーションがますます増える? Mahout事例の増加 データマイニング+Web勉強会 - NTTデータ 政谷さんのHadoopNYでの発表のダイジェスト まずは印象。深く使っている人は去年より減っている。バズワードになってるからかな? 今後もHadoopコミュニティは健全なコミュニティになりそう。(いろんな所が出てきたけど、大丈夫そうだなぁ) ・発表スライドのダイジェスト版 日本でのHadoopの盛り上がりの話。 Hadoopと他との住み分けの話。 Sqoopのお話。PostgreSQLに向けたインテグレーションの話。これはPostしてコミット待ち。 Low-Latency Serving Systemへの受け渡し(前処理はHadoopでGPGPU使ってデータをクラスタリングして処理速度をあげる) FujitsuのETERNUSにHDFS APIが用意されたという話。 MapRの話に似ているよと。小さめのクラスタの場合に有効?セッションの後に少し話題になった。 扇子を配りましたよと。 ※ビールが配られ始めた!(ビールじゃないという声もチラホラw) ◎『Hadoop Troubleshooting 101』 セッションレポート - Cloudera 嶋内さん (@shiumachi) Hadoopを壊す7つの方法 Hadoop設定したりしたことある人?=結構いた。さすがソースコードリーディング Clouderaでは木曜日に重要なミーティング(ボードゲームするかFPSするか)というのがあるらしい。 チケット分析 設定ミス? HadoopやOSの設定ファイルの変更を必要とするあらゆるチケットの事 35%が該当 問題の原因別のグラフ 1番は設定ミス 2番はバグ(これはベータ版リリースからチケット管理してるから) メモリの管理ミス Task Out Of Memory Error io.sort.mb \u0026lt; mapred.child.java.optsとなるように設定すること io.sort.mb = mapバッファのサイズ mapperとreducerを減らす。 mapper=ノード上のコア数 これは机にはっとけ! Total RAM = (Mappers + Reducers) * Child Task Heap + DN heap + 3GB + RS heap + ? JobTracker Out Of Memory Error JTのメモリ使用量の合計 > 割り当てRAM 原因は? タスクが小さすぎ jobヒストリが多すぎ 解決は? maximumを減らしなさい? Unable to Create New Native Thread どういう意味? プロセスが起動中にもかかわらずDNが障害ノードとして表示されている。 原因は? nprocのデフォルト値が低すぎる 対応は? /etc/seurity/limits.confの値を考えろ Too Many Fetch-Failures 元スライドの発表者はこれが大好きらしい どういう意味? Reducerのfetch操作がmapperの出力の取得に失敗 ブラックリスト入りのTTで発生するらしい 原因は? DNSの問題 対応は? mapred.reduce.slowstart.completed.maps = 0.80 reducerの開始を遅らせることで対応 tasktracker.http.threads = 80 Jetty 6.1.26は使うな!CDH3u2に上げましょう。 Not Able to Place Enough Replicas 。。。きっとどっかにスライドあるからメモはこのへんでいいか。。。 ◎Hadoop World NYC 2011 参加レポート - Acroquest Technology 阪本 雄一郎さん (@frutescens) 落合 雄介さん (@taro_x) ・RとHadoopの融合(Revolution AnalyticsのDavid Champagneさん) R言語の紹介 Rとの接続点(rmr、rhdfs、?) R言語の利点がHadoopで使えるから、記述が少なくて済むよと。 統計処理がわからなくてもRが使えると分析ができるよ。(そう言われても、その分析で正しいのかとかは結局統計とかをある程度理解してないと厳しいんじゃないか?) ・Hadoopを使った衛星画像解析 スケールとかしたいからHadoopにしたけど、ジョブ起動遅いし、科学計算ライブラリが不十分 ・Hadoopをクラウド上に展開(vmware) Hadoopだけじゃなく、NoSQLとかもスケールしてから使いたいよねぇ。 ということで、vmwareの色々なものを使ってHadoopと他をうまく構築しますよ事例紹介。 マルチテナントのHadoopの話とかもありますよねと。 ◎最後はHadoopには関係ないのが多かったけどおみやげ争奪戦。 なぜか、MongoDBのシールをもらいました。 ということで、HadoopWorld2011の総括+各スライドの紹介でした。 これまでのHadoopWorldの傾向などから、参加者などのトレンドがどうなっているかなどの話が聞けたのが面白かったです。 ClouderaのスライドはHadoopのトラブルシューティングとして必見になりそうな感じでした。 内容が濃くて、それほど触っていない私にはわからないところもチラホラ。(日本語資料の公開されるかなぁ?) 案の定、ビール(発泡酒)を飲んだので、途中から一部が飲み会状態になってたし、ピザ食べてたので、私のメモも途中から適当になってしまいました。 あとは、とある件についていろんなかたからの知見を入手できたのが良かったですね。 他にもLilyプロジェクト(Solrが利用されているOSSの話)の話もあったようなのですが(HPの方が教えてくれました)、今回の参加レポートでは含まれてなかったです。(話聞きたかったなぁ。余力があれば、スライド読むかなぁ。誰か発表してくれないかなぁ) 今日もまた、Twitterで絡んでいた方たち数人と面識が得られました。 今後は定期開催の流れになるようなので、これからもHadoopにしがみついていくためにも参加するようにがんばりますよと。\n会場提供のNTTデータのみなさん、発表者の皆さんお疲れ様でした。次回も期待してます!!\n2011/12/01追記 Togetterのまとめ\n","date":1322499060,"dir":"post/2011/","id":"924727b6f380cf3cdfe5650163e92054","lang":"ja","lastmod":1322499060,"permalink":"https://blog.johtani.info/blog/2011/11/29/hadoop%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89%E3%83%AA%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0%E7%AC%AC7%E5%9B%9E%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-11-29T01:51:00+09:00","summary":"Hadoopソースコードリーディング第7回に参加しました。 いつものごとく、自分用のメモをとっていたので。 第6回(2010/12)には参加して","tags":["勉強会"],"title":"Hadoopソースコードリーディング第7回に参加しました。(Jugemより移植)"},{"contents":"先週末から勤労感謝の日まで風邪で寝こんでました。。。 みなさん、朝晩、冷え込みが激しいので風邪には気をつけてください。\n季節の言葉も入れたので本題です。 つい最近、「Apache Solr入門」のサンプルをlucene-gosenでどうやって動かすんですかー?という質問を受けました。 確かに、「Apache Solr入門」を書いたのはSolrのバージョンが1.4が出る直前でしたし、lucene-gosenは存在せず、 当時はSenを元にした日本語の形態素解析のサンプルとなっていました。 そのSenも入手しづらくなってきており、私もlucene-gosenのプロジェクトに携わるようになってきてある程度時間が 経ちました。 せっかくなので、サンプルのschema.xmlだけでも最新版(Solr 3.4 + lucene-gosen-1.2.0-ipadic)のものを用意しました。 なお、あくまでも、3.xでlucene-gosenを利用する場合の「Apache Solr入門」のサンプルプログラムの変更点(とりあえず、4章まで)の違いについて記述します。 申し訳ございませんが、1.4と3.xの違いについての説明はここでは行いません。\n以下では、各章でschema.xmlに関連する記載のある部分を抜粋して、変更点と変更したschema.xmlのリンクを用意しました。参考にしてもらえればと思います。\n1章 1.6.1 N-gram(17ページ) 1.6.1の手順に変更はありません。 サンプルプログラムが入っているZip「solrbook.zip」のintroduction/ngram/schema.xmlファイルの代わりに こちらのschema.xmlを利用してください。\n1.6.2 形態素解析(18ページ~20ページ中盤まで) 手順が大きく変わります。 Senを利用する場合、Senの辞書のビルド、Senのjarファイルの配置、Senを利用するためのTokenizerクラスを含んだサンプルjarの配置という作業があります。 lucene-gosenではコンパイル済みの辞書がjarファイルに含まれています。 また、Solr向けのTokenizerもlucene-gosenのjarファイルに含まれています。 lucene-gosenを利用して形態素解析を体験するための手順は次の流れになります。 なお、schema.xmlについては上記N-gramでダウンロードしたschema.xmlに形態素解析の設定もあわせて記載してあります。\njarファイル(lucene-gosen-1.2.0-ipadic.jar)をダウンロードして、$SOLR/example/solr/lib(libディレクトリがない場合は作成)にコピーします。 コピーが終わりましたら、次のように$SOLR/exampleディレクトリでSolrを起動します。 (-Dsen.homeは必要なし)\n$ java -jar start.jar あとは、書籍の記述にしたがって管理画面のAnalysis画面で動作を確認します。 ほぼ、図1-6と同じ結果になっていると思います。 (lucene-gosenで出力される情報には本書のサンプルよりも多くの情報が含まれています。また、サンプルでは、形態素解析の後の単語に基本形を採用しているため、「な」が「だ」として出力されています。基本形を出力する場合は後述するこちらで紹介したTokenFilterを利用すれば可能です。)\n2章 2.1.3 schema.xmlのバージョン(27ページ) Solr3.xではschema.xmlのファイルの最新バージョンは1.4になっています。\n2.2.3 代表的なトークナイザ(35ページ) solrbook.analysis.SenTokenizerFactoryは必要ありません。 先ほども説明しましたが、lucene-gosenにはSolr向けのトークナイザが用意されています。 solr.JapaneseTokenizerFactoryがそれに該当します。\n2.2.4 代表的なトークンフィルタ(37ページ) 以下の2つについてはlucene-gosenに同等のトークンフィルタが存在します。\nsolrbook.analysis.KatakanaStemFilterFactory solrbook.analysis.POSFilterFactory それぞれ、次のものがlucene-gosenにあるので、こちらを利用します。\nsolr.JapaneseKatakanaStemFilterFactory solr.JapanesePartOfSpeechStopFilterFactory 2章向けのschema.xmlはこちらです。その他のtxtファイルについては、特に変更はありません。\n3,4章は特に変更はありません。Solrの起動の仕方にだけ注意してください。(-Dsen.homeは必要ありません)\n以上が4章までの修正点になります。 動作しないなどあれば、コメントください。 サンプルアプリについてはまた後日余裕があれば。。。\n","date":1322244000,"dir":"post/2011/","id":"26d48d68b28f927bfebad454658f9425","lang":"ja","lastmod":1322244000,"permalink":"https://blog.johtani.info/blog/2011/11/26/apache-solr%E5%85%A5%E9%96%80%E3%81%AE%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%81%AElucene-gosen%E5%AF%BE%E5%BF%9C1%E7%AB%A0%E3%81%8B%E3%82%894%E7%AB%A0/","publishdate":"2011-11-26T03:00:00+09:00","summary":"先週末から勤労感謝の日まで風邪で寝こんでました。。。 みなさん、朝晩、冷え込みが激しいので風邪には気をつけてください。 季節の言葉も入れたので本","tags":["lucene-gosen"],"title":"「Apache Solr入門」のサンプルのlucene-gosen対応(1章から4章)(Jugemより移植)"},{"contents":"今回は、触ろうと思って触れていないMongoDBの勉強会に行って来ました。 2週連続の渋谷で、さすがに今回は出口をすんなりでれました。 今回は初のGMOさんのビルへの潜入です。 ということで、いつものごとく自分のメモを残しておきます。\n日時 :2011/11/15 14:30 to 20:00 定員 :140 人 会場 :GMO Yours (セルリアンタワー(11階)) ハッシュタグ :#mongotokyo\n1.fluentd plugins for MongoDB @doryokujin スライドはこちら。\nFluentとMongoDBのコラボレーション ・Fluentとは? 解析対象のログについて。データ量が膨大 これまでのログの扱い方。日次でS3に送信して、ログ解析サーバにて前日分を解析する。 これではリアルタイム性がないのが問題!しかも1日分なので、データ量が半端ない。 そこでFluentにてストリーミングアプローチ。 リレーサーバ(Fluentd)にログを流すと、適宜、解析サーバに流れていく仕組みが可能。 これにより、ネットワークに負荷をあまりかけずにログを定期的(時次とか)で流せる。 ※splunkに近い考えかな。 ここで、Fluentのスライドで説明が入りました。http://www.scribd.com/doc/70897187/Fluent-event-collector-update ・Out Mongo For Local Back-Up MongoDBへの出力。 信頼性をあげるためにローカルにmongoDBを置いておき、スプールしておく。 リレーサーバにも配置してみるという仕組み。 バッファリングにMongoDBを使うので Aggregation Mongoってのを作ったらしい。そのせいで、スライドの作成が遅れたらしいw ・Aggregation Mongo Map/Reduceの集約のようなプラグイン。 fluentdのアプリを通して、特定のキーをベースに集計してから、outputする仕組み。 更に、キーに対してshufleが行われて、次のfluentdにデータが集まる。 fluentdを使ってM/Rっぽいことが可能なのかな。 QA 最終的な流れ込み先のMongoDBはCappedCollectionじゃなくしたほうがいい。検索とかしたくなるから。 2.about Server Density and MongoDB @davidmytton スライドはこちら\nQueuingシステムで利用。 MongoDBとRabbitMQとの比較? MongoDB関連のノウハウかな。 データ量に関する話。メモリに載せたほうがいいのかとか、ログ出力の設定とか、ジャーナルとか。 HDDの見積もりに関連しそう。 健康状態の監視方法。 コネクションプールの話とか。 rs=ReplicaSet? mongostatってコマンドがあるのか。 ServerDensityのツールとダッシュボードなどについて。 ※英語のスライド見ながら話聞くとメモがとれない。 まとめ: Keep it in Ram インデックスはメモリに載せましょう。 Watch your Strage ストレージのサイズは監視しましょう。(ログ、データ、ジャーナルなどなど) db.serverStatus() コマンドあるよ。これで見れるデータが重要なのかな? rs.stats() コマンドあるよ。これで見れるデータが重要なのかな? QA:残念ながら聞き取れなかったっすw Q:MongoDBのクエリログの統計の質問。DBごと?=コレクションごと?のクエリ統計のとり方は? A:MongoDBにはないので、ログレベルを下げて統計取ったりする方法しかないかなぁ。 3.MongoDB: Case Study for AMN @koyhoge スライドはこちら\nサービス(アジャイルメディア・ネットワーク)で利用している実例について 広告配信に関連して利用してる。 最初にPostgreSQLにて実装。5分おきにCronで再起動するはめに。。。 PostgreSQLの次にSimpleDBへ(インサートが遅い。分散インサート) SimpleDB+SQSに変更。1日130$で断念。 SaaSなKVSはやめてMongoDBに移行してみる。 負荷も軽いし、インサートも速い! EC2でMongoDB。しかもレプリカを東京A、B、シンガポールAにしてみよう。 shardingは残念ながらうまく行かず。 ストレージはEBSの1TB 4.「MongoDBとHadoopの蜜月関係」 @muddydixon スライドはこちら\nお父さんエンジニアなので、土曜日の勉強会は無理です!=同じく辛いです! HadoopとMongoDBのつなぎについて。 MongoDBからデータを読み込んで、Hadoopで計算してMongoDBに戻すものがmongo-hadoop データロストがニュースになってて心配してる。データロストはめったにない(by @doryokujin) Hadoopを計算だけに利用できるのでクラスタが落ちても気にせず立ち上げができそう。 MongoDBからデータを取得する時点でフィルタリングが可能なので、Hadoopでの演算が楽。 AdHocなクエリをMongoDBに投げれるのがうれしいのかな? HBaseとかHiveに入れてやったりはダメなんかな? QA Q:なんで、みんなMongoDBにログ入れるの?@kzk_mover A:様々な形式を入れやすいから。 Q:捨てるのどーするの? A:コンパクションが大変(ただし、2.0以降は良くなる予定) Q:MongoDBのMap/Reduceは? A:時間がかかった上に死ぬというひどい目にあったので。。。 5.Fusion-io @hasegaw\n340の仮想マシンが4台で動きます! すごそう。。。一回は触ってみたいかも。 Fusion-ioすげーーーって感じ。(Ustストップ) 6.MongoDB on Cloud Foundry @yssk22\nVMWare社のPaaSオファリングの名称 感想など: mongoDBに興味はあるのに、腰が引けてるおじさんになって結局触らずに会場入りしてしまいました。 会場に入っていきなり、Treasure Dataの太田さんがマグカップを売っているという場面に遭遇するというインパクトがあるスタート。(思わず1個購入) 最初はMongoDB JPの主催者でもある@doryokujinさんの話から。今熱いfluentdとmongoDBの組み合わせに関する話で、面白かったです。 途中でfluentdを作っている古橋さんのスライドを用いてfluentdの解説まで入りました。 TL上では、その古橋さんが時々フォローを入れているという贅沢な流れ。 なんとなく仕組みはスライドなどを見ていたのですが、更に理解が深まりました。 次が、イギリスから来日されていた@davidmyttonさん(なんと24歳という若さ!)のお話。 残念ながら英語のヒアリングは微妙な私なので、あまり理解できなかったのですが、どうやら、MongoDBの運用でのTipsのお話だったようです。スライドを後で見なおしたほうがいいかな。 次は、実際のMongoDBを利用した事例の紹介。PostgreSQLから試行錯誤してMongoDB+AWSの組み合わせのお話。 やはり実例があると面白いですね。試行錯誤された部分があるので、非常にわかりやすかったです。 次が、HadoopとMongoDBの組み合わせのお話。HadoopのMap/Reduceの部分だけを利用して、データ保存先はMongoDBにしましょうという割りきった話でした。 いくつか疑問点がメモにもありますが、残念ながら質問する勇気なしという腰抜けっぷり(もうちょっと積極的にならないと。。。) で、このあとFusion-ioとCloud Foundryの話になるのですが、体力切れ+lucene-gosenのjavadocが古いことに気づいてしまい、作業をしながら聞いていたのであまり頭に残っていません。(ほんとに申し訳ない。。。) とまぁ、最近、Twitter上でいろんな人に絡みまくってまして、@doryokujinにも絡みまくってたというのもあり、今回参加することにしたという次第でした。 懇親会にも多くの人が残っており、良いコミュニティができてるなぁというのが正直な感想です。 各セッションでも@doryokujinさんが適宜QAなどのフォローをされていて感心しっぱなしでした。 あとは、Twitter上で会話をしていた方たちとも顔合わせができたので、大収穫でした。\n次は、少しでもいいので、触ってから参加することにしようかと思います。 来年1月にはMongo Tokyo 2012というイベントも開かれるようで、ますます注目を浴びていきそうですね。主催者もミドルウェアもw\nあ、そうそう、そんなMongoDBの勉強会でしたが、CouchDBの話もちらほら出てまして、CouchConf TOKYOというチラシも@Ijokarumawakさんから頂きました。こちらも1月開催のようです。\n追記: 戦利品の画像です。マグカップ(500円)以外は貰い物です。 なんと、このUSBにはMongoDBのコマンドやクエリのチートシート(PDF)が入ってました。びっくり!\n","date":1321376880,"dir":"post/2011/","id":"bda9a5da86ec9790262e14f953bbadcb","lang":"ja","lastmod":1321376880,"permalink":"https://blog.johtani.info/blog/2011/11/16/mongodb%E5%8B%89%E5%BC%B7%E4%BC%9A%E7%AC%AC7%E5%9B%9E%E3%81%AB%E8%A1%8C%E3%81%A3%E3%81%A6%E6%9D%A5%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-11-16T02:08:00+09:00","summary":"今回は、触ろうと思って触れていないMongoDBの勉強会に行って来ました。 2週連続の渋谷で、さすがに今回は出口をすんなりでれました。 今回は初","tags":["勉強会"],"title":"MongoDB勉強会(第7回)に行って来ました。(Jugemより移植)"},{"contents":"Solr本の武田さんから教えていただいたSplunkの イベントに行って来ました。 Splunkとは様々な機器のログなどを一箇所に集めてリアルタイムに検索、分析できるようにするための製品です。(ざっくりした説明ですが。。。) ちなみに、データ量が小さければフリー版も用意されています。 以前、話しを聞いていて気になっていた所イベントが開催されるということだったので参加してきました。 以下に、その時取ったメモを記載しておきます。いつものごとく、自分用のメモなので、役に立つかはわかりませんが。\nSplunk Live! in toyosu\n日時:2011/11/02 10:00-12:00 場所:豊洲\n1.挨拶+アジェンダ紹介 2.ビッグデータ取り込み、ロードマップ(Splunk Inc.)CEO Godfrey Sullivan 英語でした。。。 データの種類と量が大きくなってきてるのに、ツールが追いつかないし、回答するのもはやくしろと言われる。 非構造化データの例としてApacheのログが出ていた。 TimeSeriesのフラットファイルがsplunkのデータのインデックス。(No RDB=スキーマいらないよと。) ※ここが重要な点かもしれない。 リアルタイムに解析できるのが売り。Jubatusとの違いとか聞くと面白いかも。 Machine Data Engine=Splunk データの関連付けの方法がどんなものか? 事前のスキーマが不要=流しこむ前には定義が必要?だよね? ?No need to filter/forward?? デベロッパーフレームワークってなんだ?? Splunkbaseと呼ばれる場所にSplunk Appsと呼ばれるアプリケーションがある。色々な場所、OS、アプリで利用できるものらしい。 ?自動監視も学習する仕組みがある?? それとも定義するのか? あくまでもMachine Dataと言っている。これは、ユーザのリレーションの解析などはないということか? Leading Social Gaming Company=Zynga Introscopeのログバージョンに似てるかもなぁ。 Cloudベースのアプリの解析にも利用(saleforce) 色々な利用シーンのお話。 3.適用事例(独立行政法人理化学研究所) 和光と神戸で利用。10G程度のデータを扱ってる? ログから情報基盤を監視するのに利用している。 syslogベースでsplunkにログを送信している。 事例1:VPNに接続できない(接続数上限がある?) CISCOのログから解析 どの研究室で発生しているかも検索。 事例2:DHCPの接続ミス?(IPアドレスロスト) ここまでは問題が発生してからログを漁るという使い方。 事例3:LINK FLAPのアラート 短時間にUPDOWNを繰り返す場合にスイッチがおかしくなってるんでは? 事例4:メール大量送信(ウィルス感染) 不特定多数のサーバに短時間でメールを配信している ※使い方としては情報基盤環境すべて(ネットワークとかサーバなど)のログを集めておいて監視+解析に利用して障害対応などに利用している?データセンターとかに入れるのか? あくまでも、ログを保存して、検索できる仕組みが1箇所にまとめられているという感じ。 そのログの解析について(どういった問題に対して、どういったクエリを投げるか?どういったトラップを仕込むか?)は利用する側の腕にかかっている印象。 ※実際に触ってみたいなぁ。500M/dayか。ご近所に入れてみるか?syslogで転送設定+入れるサーバが必要。 4.最新アプリなどの紹介(Splunk Inc.) GUIがきれいだなー(最近のgoogleっぽいが。。。) リアルタイムにデータが入っているのが見えるのか。おもろいな。 どこのフィールドにヒットしたかがファセットで表示できるらしい。おもろい。 flashでできたビューがすごくおもろかったぞ。(ドキュメントどこだ?) 5.最新の取り組み(NTTデータ先端) やっぱり武田さんだった。 複数の監視システムのメッセージを統合して検索、アラートを出せるようにする。 消費電力を算出するためにログを集めて集計する。 6.QA ロードマップ ・2年以内にビジネスサイドでの利用に向けての動きを見せていく予定。 ・アプリケーションフレームワークにして、他のパートナーのアプリを載せていきたい。 ということで、感想ですが、事例紹介などを聴いた感じだと今のところはインフラ系のログを一元化して検索、監視、アラートをあげるということに活用するためのツールの用に感じました。 当初の使い方がそういったところにあるためだとは思いますが。 開発者としての視点で話しを聞いていて、活用できそうだというのは次のシーンでしょうか。\n開発時の開発環境のログ集約 性能試験などでのログ、性能データ集約 開発時点もしくは性能試験時ですが、色々なサーバ(DBやアプリサーバ)の時間を横串にして表示検索などができると思うので、問題があった時の各種サーバの状態を一元的に見れるため、どのサーバにどういった負荷がかかっていたか、 どこに問題があったかなどをグラフ化して見ることが簡単にできるのではないかなぁという感想です。 あとは、ログが一元化されているので、問題があったときにまずログを検索すればいいのが楽ですかね。\n基本的にはログが集まってるからあとは、どう使うかはご自由にという印象でした。 どのようなログを集めておき、どういったトラップでアラートさせるか、どのような検索をすれば望んでいるログが出てくるか、どのような集計をしたいかなどについては、やはり導入してからノウハウを貯めていくか、導入時にコンサルしてもらうなどが必要かと。 また、このツールを入れることでどのようなフィードバックをどのように活用できるかをイメージしていなければ、 宝の持ち腐れになりそうです。 あとは、使い方次第ですが、サーバログ以外にアプリログ(ユーザの行動履歴とか)などを入れることで、インフラ以外での使い道もありそうです。 とりあえず、保存しておいて、あとから特定の傾向を見出すのに検索できるのはちょっと面白いかも。\nあ、そうそう、ストラップとUSBメモリ(4G)のノベルティをお土産にもらいました。無料セミナーなのに。\n","date":1320822000,"dir":"post/2011/","id":"cc1a3b2f107510ac664e491d5f2412aa","lang":"ja","lastmod":1320822000,"permalink":"https://blog.johtani.info/blog/2011/11/09/splunk-live%E3%81%AE%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%81%AB%E8%A1%8C%E3%81%A3%E3%81%A6%E6%9D%A5%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-11-09T16:00:00+09:00","summary":"Solr本の武田さんから教えていただいたSplunkの イベントに行って来ました。 Splunkとは様々な機器のログなどを一箇所に集めてリアルタ","tags":["misc"],"title":"Splunk Live!のイベントに行って来ました。(Jugemより移植)"},{"contents":"最近忘れやすいので、記録しておこうかと。 読んだスライドの簡単な内容と感想です。 ちなみに、スライドの一覧はこちらです。 ※スライドへのリンクはすべてPDFへのリンクになっていますので、注意が必要です。\nSolr 4 Highlights(PDF)\nSolrの次期バージョン4.0で採用される機能の紹介でした。 紹介されているのは次の機能。各機能について、JIRAの番号も記載があるので便利ですね。\nDirectSolrSpellChecker NRT (Near RealTime search) Realtime Get SolrCloud - search side SolrCloud - indexing side (WIP) これまでと異なるSpellChecker、Commit前のデータが検索できるNRT(なんでNRSじゃないんだろう?)、Commit前の登録済みデータを取得することが出来るRealtime Getなどの簡単な紹介です。 あと、個人的に興味のあるSolrCloud周りが絵付きで紹介されてます。ZooKeeperもちょっと出てきます。 まだ、ちゃんとまとめてないですが、NewSolrCloudDesignの翻訳したものも参考までに。(その1、その2)\nArchive-It: Scaling Beyond a Billion Archival Web-pages\nInternetArchiveの事例紹介。1996年からWebページのアーカイブを行なっているサイトですね。 その一部でSolrが利用されています。 「1,375,473,187 unique documents」との記述もあり、データ量が巨大です。 データ量が多いのに、ここでFieldCollapsing/Groupingも利用しているようで、インデックス作成、検索両方に対してカスタマイズしたものをgithubで公開している模様です。\n[**Scaling search at Trovit with Solr and Hadoop**](http://www.lucidimagination.com/sites/default/files/file/Eurocon2011/MarcSturlese_scalingsearchTrovit_eurocon2011.pdf) 次は、Trovitという会社のSolr+Hadoopの事例紹介です。 最初はLuceneをベースに検索サーバ作ってたけど、Solrが出てきたので、Solrを使うようになったようで。 データ保存先として最初はMySQLを利用してDataImportHandlerでSolrにデータ登録してたけど、 データ量が増加するが、MySQLのShardingが面倒なので、Hadoop(Hive)でデータをパイプライン処理してSolrのインデックスを作成しましょうという流れになったようです。 私が以前、Solr勉強会で紹介したSOLR-1301のパッチをベースにMap/Reduceの処理を2段階にして性能をアップさせたという話が記載されてました。 ただ、これで早くなるのかはよくわからないんですが。。。 一応、資料では、いきなり大きなSolrのインデックスを作らずに、最初のM/Rで小さなインデックスを作成し(TaskTrackerの数>>Solrのshardサーバ数だから小さくしたほうが速い?)、 2段目のM/Rでインデックスをマージしてshardサーバ数のインデックスに集約する?という形みたいです。 (英語力のなさが。。。) あとは、テキスト処理を幾つかHadoopでやってますよという紹介でした。 SOLR-1301の利用者が他にもいて、違うアプローチをとっていたのが印象的。 毎回全データインデックス生成するときは、SOLR-1301を利用してshard数が増えてもすぐに対応が可能になるので、 かなり便利ですよ。\nSolr @ Etsy\nEtsyは個人の作家(編み物とかシールとか)の方が出店するためのショッピングモールのようなサイトです。 実は、最近、MacBookAirのステッカーを購入したのがここでした。 で、検索にSolrを使っています。 面白いのが、検索サーバとWebアプリ(PHPで書かれている)の間のデータのやり取りにThriftを利用していること。 Solrの前にThriftを話すサーバを別途用意しているようです。ネットワークのデータ量を減らすことが目的らしいです。 そのあとは、少しThriftのサーバでのLoadBalancingの話が続きます。 次にレプリケーションの性能問題のはなし。定期的にレプリケーションに異様に時間がかかるのが問題になったようで、 Multicast-Rsyncを試してみたけどダメでしたというはなし。 Bit Torrent + Solrという組み合わせで回避したらしいのですが、いまいち仕組みがわからなかったです。。。 こちらもgithubに公開されている模様。 あとは、QParser、Stemmerをカスタマイズしたものの話です。\nArchitecting the Future of Big Data and Search\nLuceneのカンファレンスにHortonworksが出てきてびっくりしました。 まぁ、Luceneの生みの親=Hadoopの生みの親ですから、問題ないのかもしれないですが。 大半が予想通り、Hadoopに関する話でした。 知らないApacheのプロジェクト「Ambari」というのが出てきました。これは、HadoopConferenceJapan2011 Fallでの発表にもチラッと出てきたようです。 「Ambari is a monitoring, administration and lifecycle management project for Apache Hadoop clusters.」ということで、Hadoopクラスタの統合管理のツールになるんでしょうか? 最後の2枚くらいにLuceneが出てきます。絡めてみたって感じですかね。\nConfiguring mahout Clustering Jobs\n今度はMahoutが出てきました。はやりのものが満載です。 まぁ、MahoutもLuceneのインデックスを利用するという話もありますので。 スライドはクラスタリングとはどういうものか、Mahoutの説明とテキストクラスタリング処理のお話、最後はstuckoverflowでのMahoutとSolrの活用の仕方について。\nということで、英語力がない中、かなり流し読みな感じですが、あとで思い出すために書きだして見ました。 何かの役に立てれば幸いです。\n他に、こんなスライドが面白かったとか、このスライドについても書いてほしいなどあれば、コメントください。\n","date":1320724920,"dir":"post/2011/","id":"d9c6ab5c6630a4a84e242c5765103d2d","lang":"ja","lastmod":1320724920,"permalink":"https://blog.johtani.info/blog/2011/11/08/lucene-eurocon-2011-barcelona-%E3%81%AE%E3%82%B9%E3%83%A9%E3%82%A4%E3%83%89%E8%AA%AD%E3%81%BF%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-11-08T13:02:00+09:00","summary":"最近忘れやすいので、記録しておこうかと。 読んだスライドの簡単な内容と感想です。 ちなみに、スライドの一覧はこちらです。 ※スライドへのリンクはす","tags":["solr"],"title":"Lucene Eurocon 2011 Barcelona のスライド読みました(Jugemより移植)"},{"contents":"Bookscanというサービスがあります。 書籍を電子化(PDF)して原本を破棄してくれるサービスです。\n電子書籍にはずっと興味を持っていました。 技術書を購入するのですが、技術書は300ページ超の大きな書籍が大半です。 また、日本語の技術書については、なかなか電子書籍が見つからないもしくは、電子化されるのが遅いとうのが現状です。 海外では、Manningなど、電子書籍も同時に発売(もしくは、製本前から電子書籍が売られている)サイトがありますが、やはり英語の書籍はハードルが高いなぁと。\nそんな中、Bookscanの噂を耳にしました。 ということで、どんどん、積ん読になっていく技術書だったので、思い切って、電子化してみることにしました。 ※残念ながらまだタブレット(電子書籍端末)は持っていないのですが。。。もうすぐ発売されるlenovoの7inchタブレットを待ちかねているところです。\nBookscanでは、1冊100円で書籍をPDFにしてくれます。(ページ数により変わってくる) この場合、あくまでも書籍をスキャンするだけで、検索などはできません。 OCR処理については別途1冊100円(これもページ数による)のオプションが必要になります。 詳しいサービス内容はこちらを御覧ください。 基本的には書籍をBookscanに発送してから約3ヶ月ほど電子化するのに時間がかかります。 これでは、すぐに見たい場合に手元にないという状態になってしまいます。 この電子化までの時間を短くできる、「プレミアム会員」というオプションが存在します。 月額固定の費用(9980円)を支払うことで、50冊(※ページ数により1冊の単位が異なります)まで無料で、「スキャン+OCR+書籍名をファイル名」のPDFファイルを書籍到着後1週間以内で作成してもらうことができます。 また、プレミアム会員は月単位での契約が可能なようで、1ヶ月(=50冊)だけ早く電子化してもらうといった利用方法もできるようです。\nで、実際にプレミアム会員となって49冊の書籍を送付して電子化してもらいました。 先週金曜日に発送、Bookscanに書籍が到着したのが翌土曜日、電子化が完了したのが火曜日の夜という感じでした。 すごくはやい!かなり感動してます。自炊自体をしたことがないので、出来上がりが自炊と比べてという比較はできないのですが、ざっと見ている感じでは全然問題なく読めそうです。\nただ、1冊の2ページだけ、ページの端が文章の途中で切れているPDFがありました。 この書籍に関しては、サポートサービスにお願いして、再スキャンをしてもらいました。 昨日夜に頼んで今日の午後には問題なく電子化されているというサービスの質でとても満足しています。 なお、原本の破棄が電子化後から10日後に行われるため、問題ないかの確認はそれまでに行う必要があるようです。 大量の本を送る場合は小分けに送ったほうが確認するのが楽になると思います。(送料は小分けにした分、かかってしまいますが。)\n書籍の山になっていた机がすっきりして、とても満足しています。 せっかく電子化したので、早くタブレットが欲しいなと思う今日この頃。。。 基本的には今後は電子書籍を購入するようにしていく予定なので、プレミアム会員を継続することはないと思いますが、 家に溜まっている漫画を電子化するのもありかなぁと思っているところです 漫画の場合はOCRに掛ける必要もないですし。\n個人的にはBookscanさんには悪いのですが、もっと電子書籍が増えると助かります。 技術書はページ数が多く、重たいうえ、実際に利用するときは検索したくなることが多々ありますので。 あとは、電子書籍を検索できるサイトがあるといいなと思ってもいるところです。 現在は、各出版社が個別に電子書籍のHPを持っている状況で、会社によっては検索すらできないです。 電子書籍があるかないかだけでも簡単に検索できると、いいなと思っています。(小説などはまた別なのかもしれないですが。) みんなはどう思ってるんですかねぇ?検索したくないですか?\n","date":1320225060,"dir":"post/2011/","id":"7a9609a971a8f31685e88da563eea5ce","lang":"ja","lastmod":1320225060,"permalink":"https://blog.johtani.info/blog/2011/11/02/bookscan%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-11-02T18:11:00+09:00","summary":"Bookscanというサービスがあります。 書籍を電子化(PDF)して原本を破棄してくれるサービスです。 電子書籍にはずっと興味を持っていました","tags":["misc"],"title":"Bookscanを使ってみました(Jugemより移植)"},{"contents":"lucene-gosenの最新版(1.2.0)をリリースしました。\nプロジェクトページよりダウンロードが可能です。\n新規追加機能についてはこちらのエントリを御覧ください。\nバグなどありましたら、容赦なく報告をいただけると助かります。\n","date":1320043560,"dir":"post/2011/","id":"14cf6e75aec1ead888e7101d3d94d28a","lang":"ja","lastmod":1320043560,"permalink":"https://blog.johtani.info/blog/2011/10/31/1-2-0%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9/","publishdate":"2011-10-31T15:46:00+09:00","summary":"lucene-gosenの最新版(1.2.0)をリリースしました。 プロジェクトページよりダウンロードが可能です。 新規追加機能についてはこちら","tags":["lucene-gosen"],"title":"1.2.0リリース(Jugemより移植)"},{"contents":"すぐやりますと言いつつ、はや1ヶ月。。。 腰が重い、ダメエンジニアですね。。。\nすみませんでした。。。 ようやくtrunkにコミットしました。 すぐにリリース版を用意すると思います。\n1ヶ月もあいてしまったので、追加した機能に関するまとめと、 用途別の利用方法を記載しておきます。 (lucene-gosenのWikiにもそろそろ書かないとなぁ。日本語でもいいから。)\n追加した機能\nこれまでのlucene-gosenはjarに辞書を含む形でライブラリを提供していました。 ただ、この場合、カスタム辞書を利用している環境ではカスタム辞書を修正し、ビルドしなおすたびに、 jarファイルを作成しなければなりません。 また、jarファイルをSolrなどに配布する必要も出てきます。 この手間を考慮して、辞書を外部ディレクトリで指定することができるようにしたものが 今回の修正になります。 また、修正の過程で同一VM内で異なる辞書を使えるようにする機能も副産物として生まれました。 今回追加した機能は次のようなものになります。 辞書を含まないjarのビルドおよび提供 ディレクトリ指定による辞書の指定 同一VM内での複数辞書の利用 辞書リビルド用のAntターゲットの追加 Lucene/Solr jarファイルの最新化(3.4.0対応) ディレクトリ指定による辞書の指定ですが、以下のような形になります。 まずは、LuceneのTokenizerでの指定方法です。 「辞書のディレクトリ」という引数が追加になっています。 ここに、辞書ディレクトリ(*.senファイルが存在するディレクトリ)を相対/絶対パスで指定します。\n... Tokenizer tokenizer = new JapaneseTokenizer(reader, null, \u0026#34;辞書のディレクトリ\u0026#34;); ... つぎは、Solrでの設定の方法です。 schema.xmlにて次のような設定を行います。\n... \u0026lt;fieldType name=\u0026#34;text_ja\u0026#34; ...\u0026gt; \u0026lt;analyzer\u0026gt; ... \u0026lt;tokenizer class=\u0026#34;solr.JapaneseTokenizerFactory\u0026#34; compositePOS=\u0026#34;compositePOS.txt\u0026#34; dictionaryDir=\u0026#34;辞書のディレクトリ\u0026#34;/\u0026amp;gt; ... \u0026lt;/analyzer\u0026gt; \u0026lt;/fieldType\u0026gt; ... schema.xmlの設定については、example/schema.xml.snippetにも説明がありますので、こちらもあわせて参考に。 なお、Solrの設定については、先ほどのLuceneでの辞書のディレクトリの指定方法(絶対/相対パス)に加えて、 $SOLR_HOME/conf からの相対パスでの指定も可能になっています。\nAntのターゲットについて\n辞書なしjarファイルを作成するターゲットなどを追加しています。 実際に追加したターゲットは以下のとおりです。 ターゲット名 説明 nodic-jar 辞書なしのjarファイルを生成するためのターゲット。辞書のダウンロード、コンパイルは行いません。 rebuild-dic lucene-gosenのビルド済み辞書(.senファイル)を削除してから辞書のコンパイル(ビルド)を行います。-Ddictypeにより辞書のタイプ(ipadic|naist-chasen)の指定が必要です。また、-Dcustom.dicsによりカスタム辞書の指定もあわせて可能です。 build-dic-ipadic テスト用に追加。-Ddictype=ipadicを指定してbuild-dicを実行。 build-dic-naist-chasen ついでに追加。-Ddictype=naist-chasenを指定してbuild-dicを実行。 最後の2つはあまり関係ありません。内部的に有ると便利だったため、作りました。 重要なのは最初の2つです。 ひとつめの「nodic-jar」は辞書を含まないjarファイルをビルドします。 このjarファイル+辞書の入ったディレクトリを利用することで、辞書の外部化が可能となります。\nそして、「rebuild-dic」です。こちらは、以前記事に書きましたが、カスタム辞書のコンパイルが思いの外面倒だったので、ターゲットを追加しました。 次のように指定することで、辞書のリビルドが可能です。\n$ ant -Ddictype=naist-chasen -Dcustom.dcs=\u0026#34;custom1.csv custom2.csv\u0026#34; rebuild-dic 提供されるjarファイルについて\n提供されるjarファイルは次のようになる予定です。 1番目のjarファイルが今回追加になる、辞書なしのjarファイルになります。\nlucene-gosen-1.x.x.jar lucene-gosen-1.x.x-ipadic.jar lucene-gosen-1.x.x-naist-chasen.jar 用途別の利用方法 利用用途別に利用するjarファイルやantのターゲットを利用シーンを交えて想定を書いてみます。 Solrでの利用シーンを想定します。\nお手軽に使う。辞書ありjarファイルで一発インストール。 これまでどおりの使い方になります。 辞書込みのjarファイルを利用すれば、すぐに利用可能になります。\nカスタム辞書を使い倒す。定期的に辞書をメンテナンス。 定期的にシステム固有の単語が増える(例:製品名、新語など)場合です。\n利用するjar:lucene-gosen-1.x.x.jar 辞書のコンパイル+配置:ant -Ddictype=naist-chasen -Dcustom.dics=\u0026ldquo;custom1.csv\u0026rdquo; rebuild-dir Solrの該当コアのRELOAD Solrのマルチコア環境を利用します。なお、sharedLib設定にlucene-gosen-1.x.x.jarを配置すると、辞書の再読み込みができないので注意してください。 設定は、上記のようにTokenizerFactoryの設定でdictionaryDirにて辞書のディレクトリを設定しておきます。 カスタム辞書に単語を追加後、antにて、辞書のリビルドを行います。 リビルドした辞書ファイルを必要に応じて対象の辞書ディレクトリにコピーします。(ビルド後のディレクトリをそのまま利用している場合はコピーの必要はないです。) 最後に、Solrの該当コアのリロードを行います。(リロードの仕方はこちらを参考に。) コアのリロードにより、辞書の再読み込みが行われるので、リロード後から新しい辞書が適用されます。\n異なる辞書を使い倒す。TokenizerごとにdictionaryDir設定するぞ 1つのSolrで異なる辞書を使ったフィールドを使いたい場合です。 ipadicとnaist-chasenといった異なる場合はあまり想定できないですが、カスタム辞書の部分が異なるという形が想定できるでしょうか。(例:製品名のフィールド、企業名のフィールド。。。など)\n利用するjar:lucene-gosen-1.x.x.jar 設定:schema.xmlに異なるdictionaryDirを設定したTokenizerFactoryを設定 上記、カスタム辞書の定期更新も一緒に行うことも可能です。コアをリロードすれば、リロードしたコアで利用している 辞書がすべてリロードされます。\n最後に 遅くなってしまいましたが、ようやく、trunkにコミットしました。 できるだけ速く、リリースしますので、もう少々お待ちを。\nSolrのconfディレクトリからの指定については、@shinobu_aokiさんにパッチを提供してもらいました。 また、trunkにコミットしていないパッチを適用して記事を書いてくれた方もいらっしゃいました。こちらもあわせて参考に。私より説明が上手です。 Java製形態素解析ライブラリ「lucene-gosen」を試してみる\n","date":1319559120,"dir":"post/2011/","id":"14a6d294550c9760aec57ba29682a750","lang":"ja","lastmod":1319559120,"permalink":"https://blog.johtani.info/blog/2011/10/26/%E8%BE%9E%E6%9B%B8%E3%81%AE%E5%A4%96%E9%83%A8%E5%8C%96%E3%81%A8lucene-solr3-4%E5%AF%BE%E5%BF%9C/","publishdate":"2011-10-26T01:12:00+09:00","summary":"すぐやりますと言いつつ、はや1ヶ月。。。 腰が重い、ダメエンジニアですね。。。 すみませんでした。。。 ようやくtrunkにコミットしました。 すぐ","tags":["lucene-gosen"],"title":"辞書の外部化とLucene/Solr3.4対応(Jugemより移植)"},{"contents":"JJUG CCC 2011 Fallに参加してきました。 個人的にはかなり久々のJavaのカンファレンスです。(※あくまで「Javaの」という話で。SolrやHadoopとは別という意味です。)\n概要やタイムテーブルはこちら。 予定があったので、残念ながら最後の2つのセッション(Scala、Twitter)しか参加できませんでした。 Hadoopの話も聞きたかったのですが、しょうがないかと。 いつものごとく、メモを個人的に取ったので。\n★楽々Scalaプログラミング 浅海 ◎OOPからOFPへの道しるべ ・関数型の使い所、プログラミングのコツ ・つながりの部分 ◎最近の活動 モデリングからモデル駆動によるソース生成などに利用。 Scala、2008年から使い始めている ◎Scalaと他の機能との比較図 ◎Scalaの用途 ・高い生産性 体感で3倍。コード量が少なくなる。 IDEのサポートを考えるとまだ、Java+Eclipseのほうが高い! ・DSL ドメインモデルの記述 フレームワークAPI ・並行プログラミング Many Core 消費電力的に複数のコアで動かす=関数型のほうが並行性が上がる(スレッドさわるJavaだけだときつい) Parallel Everything Object指向+関数型が扱いやすい。 ◎関数型言語とは ・公開関数をあつかえる 関数を値として扱える、引数と返却地に関数を渡せる。(やさしめ) <=> 数学(ラムダ計算、圏論など)的にプログラムを記述できる(きびしめ) ある程度使えるはず。厳しめの部分も ◎関数型言語の長所と短所 長所 ・高階関数を使った技が使える List(???) 短所 ・メモリ、関数実行オーバーヘッド、スタックの大きさが読めない(再帰的) ◎関数型言語の系譜 純粋関数型言語 pure Lisp 伝統的関数型言語 OCaml 新世代関数型言語 Haskell Scala 型クラス 代数データ型、モナド Parametric polymorphism ◎関数型でしたいこと DSL(Domain Specific Lanuguage) 昨年の資料を参考に! ◎準備 scalaの文法 ◎並列コレクション スレッドを利用しないで並列に動作実行させるか? ※List().par.map(sitelen).sum これで並行実行させられる。 ◎Future (これってJavaでもあるよね?=あるよ) 処理を非同期で先行実行し、あとから結果を取得可能 Scalaではアクターライブラリでサポート(cala.actors) 関数合成するとFutureの実行結果を取り出す所でブロックされる!! ◎Promise Futureより強力 関数合成すると、合成関数全体が非同期実行される! scalazを利用してた ◎5つのコツ コツ1: y=f(x) 引数がひとつの関数が基本 関数合成のビルディングブロックになるよ 引数が複数ある関数は他の関数(map関数とか)で合成しにくい 対処方法:カリー化(関数の戻りを関数とする) addc(a: Int)(b: Int) : Int = a + b とすることで、 コツ2:分割統治 コツ3:演算は転換 flatMapとかfoldLeftとか ※永続データ構造 前に作ったデータ コツ4:オブジェクトの世界と関数の世界を分ける 更新指示書の形でObjectに渡す? 関数型データ構造 コツ5:新しいデザインパターン 関数型プログラミングの用語 ・Functor(関手) ・Subgroup(半群) ・Monoid(モノイド) ・Monad(モナド) OOPのデザインパターン的に考えれば、数学的なところまで理解しなくてもよさそう? ★Twitterとオープンソース @yusukey http://dev.twitter.com http://bit.ly/tdt-ja id:twj_dev ◎OSSとの関わり 支援してます。 Apache、Eclipse、Open Invention、JCP、OpenJDK パフォーマンス系のためにもOpenJDKに参画してる ◎Twitter API オープンなAPIで無償提供 13言語でAPIライブラリがあるよ ◎Twitter4Jのこれまで ほぼ全てをカバー APIはだいぶ落ち着いてきていて、追加変更は少なくなってる。 ◎立ち位置 Twitterはコミュニティを活発にするためにもライブラリを出さないらしい。 ◎Twitter4Jのこれから キャッシング ストリーミングAPI利用を簡単に モックテスト レートリミットの影響を受けると辛いから。。。 ツイート/ユーザの永続化機能 jClouds対応? ライブラリからフレームワークへ 半公式ライブラリへ github/twitter/twitter4jへ JSR Social API Twitter4Jが参照実装に??? スケーラビリティの話。 Hadoopはユーザのデータ解析とかに使ってる。 メッセージはキューイングしている。デモ。 memcachedプロトコルなんだけど、値を取ると値が消えるよ。(memcachedとは動きが違うよねー。プロトコル的にはクライアントがいっぱいあっていいよねー) RubyのGCがきつかったのでJavaベースに変更 Kestrel(Scalaで記述。) Kestrelのフォーカス外 メッセージの順序保証(してないよ) トランザクション memcachedプロトコルの拡張1 ブロックフェッチ コンシューマから取りに行くというのが特徴 memcachedプロトコルの拡張2 リライアブルフェッチ ということで感想。\nScalaは前から気になっていて、本までかってるのになかなか手を付けられていない始末でした。 そんな時にこのJJUGの話があったので、ちょうどいいと聞きに。 関数型やScalaのぼんやりしたイメージのみを持って聴いていたのですが、思った以上にキーワードが多くてついていくのがやっとというイメージ。 で、いつものごとく、Twitterでつぶやいていた所、色々な反応が。(わからずにつぶやいたのもあり、波紋を呼んだ模様) お陰で、Scala関連の方たちをフォローできたので結果オーライでした。 話の内容自体はサラっとながす感じだったので、再度資料を見る+Scalaをもっと勉強しないと理解出来ないなぁという印象でした。 ちなみに、資料はこちら。\n次は、最近Twitterの中の人になった山本さん(@yusukey)の話しを聞きました。 Twitter4Jの話と、TwitterのOSSへの関わりの話。あとは、実際にTwitterが作成しているOSSのひとつKestrelについて。 TwitterはRubyベースで色々と作ってきていたのだが、Java(JVM上で動く言語(Scalaなど))に徐々にシフトしているというのが一番の印象です。あとは、Lucene、Hadoopなど私の興味のあるOSSも利用しているなど。 Kestrelについてはデモを交えながら、実際の動きを説明されていたのでとてもわかり易かったです。 プレゼン中もTweetを表示しながらという、さすがTwitterの中の人という印象でした。 Twitterでは少し前から知り合いだったのですが、実際にお会いできた(イケメンでしたよ!)のも収穫でした。 次はStormの話も聞きたいかなぁ\nで、2セッション(山本さんの話のあとにLT大会にも参加)だけですが、全体の感想を。 「クロスコミュニティカンファレンス」というだけあり、Java以外の話題(CouchDBとか名前がありました)もちらほらあったようです。 ただ、最近の他の勉強会やカンファレンスに比べると人が少ない印象でした。 私が参加したセッションは比較的大きな部屋だったせいもあり、40~50人くらい入っていたと思うのですが、ガラガラな印象でした。良い意味で、Javaも安定してきているため、参加者が少なかったのかなぁと あとは、年齢層がHadoopなどに比べると高めかなぁという印象(かく言う私も年齢層を上げている一人ですが。。。)。Javaも長いですからねぇ。 午前中から参加していると違った印象だったかもしれないですが。。。 あと、初めて行った会場で、しかも大きめの施設でした。午後の途中から行ったせいもあるかもしれないですが、 案内が出ていなくて若干迷子に。。。 ただ、セッションの部屋自体は各席に机があり、電源も比較的多めにあったので、PC持ち込みでメモを取るには最適でした。\n","date":1318922443,"dir":"post/2011/","id":"5d827a1e8ea70edb11d946b54f076cae","lang":"ja","lastmod":1318922443,"permalink":"https://blog.johtani.info/blog/2011/10/18/jjug-ccc-2011-fall%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%A6%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-10-18T16:20:43+09:00","summary":"JJUG CCC 2011 Fallに参加してきました。 個人的にはかなり久々のJavaのカンファレンスです。(※あくまで「Javaの」という話で。SolrやHad","tags":["備忘録"],"title":"JJUG CCC 2011 Fallに参加してきました。(Jugemより移植)"},{"contents":"昨日、文章から特定の単語(リストあり)を探したいという話を聞き、lucene-gosenでもできるねぇという話になりました。 まぁ、考えてみればごくごく当たり前なのですが。。。(その筋の方たちにしてみれば常識なのかもしれないですが。。。) 一応やってみたので、こんなこともできるなという一例ですということで、記録を残しておきます。\n今回の例文として野田首相の所信表明演説の一部を活用させてもらいます。 単語のリストは次のようにします。\n内閣総理大臣 正心誠意 東日本 日本 今回も結果をわかりやすくするためにSolrのanalysis画面を利用します。 作業手順は以下のとおり。\ndictionary.csvの編集 辞書のコンパイル fieldTypeの定義(Solrのschema.xmlの設定) 文章からキーワード抽出(Solrのanalysis画面) ### **1.dictionary.csvの編集** 今回はnaist-chasenディレクトリで作業します。 なお、今回利用するlucene-gosenは[ここ](http://johtani.jugem.jp/?eid=21)で紹介した辞書分離バージョンです。(はやくtrunkにコミットせねば。。。) dictionary.csvを先ほど上げた単語だけのエントリに変更します。 キーワードだけを抽出したいので、他の単語は必要ないからです。 ``` \u0026ldquo;内閣総理大臣\u0026rdquo;,1,名詞,一般,,,,,\u0026ldquo;内閣総理大臣\u0026rdquo;,\u0026ldquo;ナイカクソウリダイジン\u0026rdquo;,\u0026ldquo;ナイカクソウリダイジン\u0026rdquo; \u0026ldquo;正心誠意\u0026rdquo;,1,名詞,一般,,,,,\u0026ldquo;正心誠意\u0026rdquo;,\u0026ldquo;セイシンセイイ\u0026rdquo;,\u0026ldquo;セイシンセイイ\u0026rdquo; \u0026ldquo;東日本\u0026rdquo;,1,名詞,一般,,,,,\u0026ldquo;東日本\u0026rdquo;,\u0026ldquo;ヒガシニホン\u0026rdquo;,\u0026ldquo;ヒガシニホン\u0026rdquo; \u0026ldquo;日本\u0026rdquo;,1,名詞,一般,,,,,\u0026ldquo;日本\u0026rdquo;,\u0026ldquo;ニホン\u0026rdquo;,\u0026ldquo;ニホン\u0026rdquo;\n\u0026lt;/div\u0026gt; \u0026lt;div\u0026gt; ### **2.辞書のコンパイル** 先ほど作成した辞書をコンパイルし、lucene-gosen用バイナリ辞書を作成します。 $ cd $LUCENE_GOSEN_HOME¥dictionary $ ant -Ddictype=naist-chasen clean-sen compile\n\u0026lt;/div\u0026gt; \u0026lt;div\u0026gt; ### **3.fieldTypeの定義(Solrのschema.xmlの設定)** Solrのschema.xmlにlucene-gosenを利用するフィールドタイプを定義します。 追加するのは次の通り \u0026lt;fieldType name=\u0026quot;text_ja\u0026quot; class=\u0026quot;solr.TextField\u0026quot; positionIncrementGap=\u0026quot;100\u0026quot; autoGeneratePhraseQueries=\u0026quot;false\u0026quot;\u0026amp;gt; \u0026lt;analyzer\u0026amp;gt; \u0026lt;tokenizer class=\u0026quot;solr.JapaneseTokenizerFactory\u0026quot; compositePOS=\u0026quot;compositePOS.txt\u0026quot; dictionaryDir=\u0026quot;keyword-dic\u0026quot;/\u0026amp;gt; \u0026lt;filter class=\u0026quot;solr.JapanesePartOfSpeechKeepFilterFactory\u0026quot; tags=\u0026quot;keeptags_ja.txt\u0026quot; enablePositionIncrements=\u0026quot;true\u0026quot;/\u0026amp;gt; \u0026lt;/analyzer\u0026amp;gt; \u0026lt;/fieldType\u0026amp;gt; また、ここで定義しているcompositePOS.txt、keeptags_ja.txtは次のようになります。 compositePOS.txt 未知語\nkeeptags_ja.txt 名詞-一般\n未知語がバラバラに出現しないようにして見やすくするためと、必要な単語(今回は「名詞-一般」しか利用しないため。)だけを抽出したいための設定です。 \u0026lt;/div\u0026gt; \u0026lt;div\u0026gt; **### 4.文章からキーワード抽出(Solrのanalysis画面)** あとは、analysis画面で解析して見るだけになります。 ということで、辞書に登録された単語だけが抽出されてますね。 この例ではインデックスに登録となりますが。 ただし、「東日本」「日本」のような一部を含む単語の場合、「東日本」が見つかった場合は「日本」は抽出されません。 あくまでも、ベストな解が見つかるのみという形です。 すべての単語を出したい場合はもう少しやり方を考えたほうがいいかもしれません。 (まぁ、このやり方でキーワードを抽出するかも考えたほうがいいかもしれませんが。。。) \u0026lt;/div\u0026gt; 最近、頭が硬くなってきてるなぁと実感してしまいました。まぁ、こんな使い方もあるかなぁと。 もっと頭を柔らかくして問題を解けるけるようになりたいなぁと。 ","date":1318389420,"dir":"post/2011/","id":"b9d4f73fa7ca8ef66891554b66b2cded","lang":"ja","lastmod":1318389420,"permalink":"https://blog.johtani.info/blog/2011/10/12/lucene-gosen%E3%81%A7%E6%96%87%E7%AB%A0%E3%81%8B%E3%82%89%E3%82%AD%E3%83%BC%E3%83%AF%E3%83%BC%E3%83%89%E6%8A%BD%E5%87%BA%E3%82%A4%E3%83%AC%E3%82%AE%E3%83%A5%E3%83%A9%E3%83%BC/","publishdate":"2011-10-12T12:17:00+09:00","summary":"昨日、文章から特定の単語(リストあり)を探したいという話を聞き、lucene-gosenでもできるねぇという話になりました。 まぁ、考えてみれ","tags":["lucene-gosen"],"title":"lucene-gosenで文章からキーワード抽出(イレギュラー?)(Jugemより移植)"},{"contents":"ちょっと間があいてしまったが、ようやくIoの1日目を終了。 なれない感じの言語なので苦労しました。 今回もセルフスタディの私の回答が最後の方に記載されてます。見たくない人は気をつけてください。 ツッコミ大募集です。コメント欄にどしどしコメントください。そこは違うだろ?こっちのほうがいいのでは?という感じで。\n感想: プロトタイプ言語であり、すべての言語はクローンだそうです。\n○手始めに スロット、オブジェクトのクローンについて。 メッセージとその送信について。 あくまでもオブジェクトだけの世界。クローンであり、クラスのインスタンスではない。(まだつかめない。。。) ### ○オブジェクト、プロトタイプ、継承 slotNamesで取れないけど、継承してる。クローンで元をコピーしてるだけか? 頭文字が大文字かどうかがtypeかどうかの違い。大文字=type(クラスもどき=) オブジェクト=スロットの入れ物 オブジェクトのクローン=オブジェクトのチェーン?(Object => Vehicle => Car => ferrari) 疑問点: 存在しないスロット名をgetSlot()で呼び出したら?=>nilが返る 存在しないスロットをメッセージとして送信したら?=>Exceptionが出る ○メソッド method()で定義 メソッドもオブジェクト=スロットに入れることができる(まだつかめない。。。) メソッドをスロットから呼び出すと実行される。 ○リストとマップ リスト、マップは簡単。幾つか(スタックやキュー)のメソッドも用意されてる。 ○true、false、nil、singleton cloneメソッドを最定義することでsingletonの動作にする。(言われてみれば当たり前か) Object cloneをオーバーライドすることもできるが、プロセス停止などしないとダメ。(恐るべし。。。) ○インタビュー SIMD(Single Instruction Multiple Data)http://ja.wikipedia.org/wiki/SIMD やりながら感想: シンタックスが全然違うのでかなり戸惑い。 ただ、考え方はシンプル。slotとか。 まだ、予約語がわかってない(cloneとかprintとかslotNamesとか)ので。 ★セルフスタディ (探してみよう) ○Ioのいくつかの問題点の例 見つけられず。。。英語がダメダメ。。。 ○質問に答えてくれるIoコミュニティ\nML:http://tech.groups.yahoo.com/group/iolanguage/ twitter:http://twitter.com/#!/iolanguage **○Ioのイディオムに関するスタイルガイド** Io Note(英語) [http://iota.flowsnake.org/](http://iota.flowsnake.org/) Ioプログラミングガイド [http://iolanguage.com/scm/io/docs/IoGuide.html](http://iolanguage.com/scm/io/docs/IoGuide.html) [http://xole.net/docs/IoGuide_ja.html](http://xole.net/docs/IoGuide_ja.html)(日本語) Ioスタイルガイド [http://en.wikibooks.org/wiki/Io_Programming/Io_Style_Guide](http://en.wikibooks.org/wiki/Io_Programming/Io_Style_Guide) [http://d.hatena.ne.jp/katzchang/20080819/p1](http://d.hatena.ne.jp/katzchang/20080819/p1)(日本語訳してくれてるブログ) (確認してみよう) ○1 + 1を評価してから、1 + \u0026ldquo;one\u0026quot;を評価する。Ioは強く型付けされた言語か?\n``` Io\u0026gt; 1 + 1 ==\u0026gt; 2 Io\u0026gt; 1 + \u0026ldquo;one\u0026rdquo;\nException: argument 0 to method \u0026lsquo;+\u0026rsquo; must be a Number, not a \u0026lsquo;Sequence\u0026rsquo; message \u0026lsquo;+\u0026rsquo; in \u0026lsquo;Command Line\u0026rsquo; on line 1\nということで、型付けは強いです。 \u0026lt;/div\u0026gt; **○0は真か偽か?空文字列はどうか?nilは真か偽か?** \u0026lt;div\u0026gt; Io\u0026gt; 0 ==\u0026gt; 0 Io\u0026gt; true and 0 ==\u0026gt; true Io\u0026gt; true and \u0026quot;\u0026rdquo; ==\u0026gt; true Io\u0026gt; \u0026quot;\u0026quot; ==\u0026gt; Io\u0026gt; true and nil ==\u0026gt; false Io\u0026gt;\n0、空文字列はtrue、nilはfalseでした。 \u0026lt;/div\u0026gt; **○プロトタイプに存在するスロットを確認するにはどうすればよいか?** \u0026lt;div\u0026gt; Io\u0026gt; Highlander := Object clone ==\u0026gt; Highlander_0x1a233a0: type = \u0026ldquo;Highlander\u0026rdquo;\nIo\u0026gt; hoge := Highlander clone ==\u0026gt; Highlander_0x1a83630:\nIo\u0026gt; hoge proto slotNames ==\u0026gt; list(type) Io\u0026gt; Highlander name := \u0026ldquo;arnold\u0026rdquo; ==\u0026gt; arnold Io\u0026gt; hoge slotNames ==\u0026gt; list() Io\u0026gt; hoge proto slotNames ==\u0026gt; list(type, name) Io\u0026gt; Highlander slotNames ==\u0026gt; list(type, name) Io\u0026gt; hoge name ==\u0026gt; arnold Io\u0026gt; hoge getSlot(\u0026ldquo;name\u0026rdquo;) ==\u0026gt; arnold\nこんな感じ。slotNamesでスロット名を確認し、スロット内部についてはgetSlotで確認できます。 \u0026lt;/div\u0026gt; **○等号(=)、コロン等号(:=)および、コロンコロン等号(::=)の違いはなにか?どのようなときに使うか?** \u0026lt;div\u0026gt; \u0026lt;table class=\u0026#34;list_view\u0026#34;\u0026gt; \u0026lt;thead\u0026gt; \u0026lt;tr\u0026gt; \u0026lt;th\u0026gt;演算子\u0026lt;/th\u0026gt; \u0026lt;th\u0026gt;説明\u0026lt;/th\u0026gt; \u0026lt;/tr\u0026gt; \u0026lt;/thead\u0026gt; \u0026lt;tbody\u0026gt; \u0026lt;tr class=\u0026#34;spec\u0026#34;\u0026gt; \u0026lt;td\u0026gt;:::=\u0026lt;/td\u0026gt; \u0026lt;td\u0026gt;スロットへの代入+setterの追加\u0026lt;/td\u0026gt; \u0026lt;/tr\u0026gt; \u0026lt;tr class=\u0026#34;specalt\u0026#34;\u0026gt; \u0026lt;td class=\u0026#34;alt\u0026#34;\u0026gt;:=\u0026lt;/td\u0026gt; \u0026lt;td class=\u0026#34;alt\u0026#34;\u0026gt;スロットへの代入\u0026lt;/td\u0026gt; \u0026lt;/tr\u0026gt; \u0026lt;tr class=\u0026#34;spec\u0026#34;\u0026gt; \u0026lt;td\u0026gt;=\u0026lt;/td\u0026gt; \u0026lt;td\u0026gt;スロットへの代入(ただし、スロットが存在しない場合は例外が発生)\u0026lt;/td\u0026gt; \u0026lt;/tr\u0026gt; \u0026lt;/tbody\u0026gt; \u0026lt;/table\u0026gt; とまぁ、記載したが、実際に動かして確認しました。 Io\u0026gt; Highlander := Object clone ==\u0026gt; Highlander_0x223b800: type = \u0026ldquo;Highlander\u0026rdquo;\nIo\u0026gt; hoge := Highlander clone ==\u0026gt; Highlander_0x21acd60:\nIo\u0026gt; hoge slotNames ==\u0026gt; list() Io\u0026gt; hoge name ::= \u0026ldquo;arnold\u0026rdquo; ==\u0026gt; arnold Io\u0026gt; hoge slotNames ==\u0026gt; list(setName, name) Io\u0026gt; hoge sword := \u0026ldquo;long sword\u0026rdquo; ==\u0026gt; long sword Io\u0026gt; hoge slotNames ==\u0026gt; list(setName, name, sword) Io\u0026gt; hoge clothes = \u0026ldquo;armor\u0026rdquo;\nException: Slot clothes not found. Must define slot using := operator before updating. message \u0026lsquo;updateSlot\u0026rsquo; in \u0026lsquo;Command Line\u0026rsquo; on line 1\n\u0026lt;/div\u0026gt; ### (試してみよう) **○ファイルからIoプログラムを実行せよ** \u0026lt;div\u0026gt; ファイル「great.io」を作成し、以下を入力。 Highlander := Object clone Highlander giveWarCry := \u0026ldquo;Woooooooo!!\u0026rdquo; println Highlander giveWarCry()\nで、以下のコマンドを実行する。 $ io great.io Woooooooo!!\n\u0026lt;/div\u0026gt; **○スロットの名前を指定して格納されているコードを実行せよ** \u0026lt;div\u0026gt; Io\u0026gt; Masason := Object clone ==\u0026gt; Masason_0x20ae7d0: type = \u0026ldquo;Masason\u0026rdquo;\nIo\u0026gt; Masason recieveNiceTweet := method(\u0026ldquo;やりましょう\u0026rdquo; println) ==\u0026gt; method( \u0026ldquo;やりましょう\u0026rdquo; println ) Io\u0026gt; Masason getSlot(\u0026ldquo;recieveNiceTweet\u0026rdquo;) ==\u0026gt; method( \u0026ldquo;やりましょう\u0026rdquo; println ) Io\u0026gt; Masason getSlot(\u0026ldquo;recieveNiceTweet\u0026rdquo;) call やりましょう ==\u0026gt; やりましょう\ncallとgetSlotが鍵ですね。 \u0026lt;/div\u0026gt; 1日目の途中で間があいてしまったのでシンタックスを忘れてしまう始末。。。 ただ、そんなに込み入った記述もないので、最初に勉強することは少ないかもしれないです。 まだメソッドをあとから追加とか、cloneしたあとにまたプロトタイプを変更して反映可能など、考え方になれないもところがありますが、良い頭の体操になってます。 間を置かずに3日目まで行かないと!! ","date":1317990120,"dir":"post/2011/","id":"dc962e34780f0374b7eb3d583f6d7eb6","lang":"ja","lastmod":1317990120,"permalink":"https://blog.johtani.info/blog/2011/10/07/7%E3%81%A4%E3%81%AE%E8%A8%80%E8%AA%9E-7%E3%81%A4%E3%81%AE%E4%B8%96%E7%95%8C-io-1%E6%97%A5%E7%9B%AE/","publishdate":"2011-10-07T21:22:00+09:00","summary":"ちょっと間があいてしまったが、ようやくIoの1日目を終了。 なれない感じの言語なので苦労しました。 今回もセルフスタディの私の回答が最後の方に記","title":"「7つの言語 7つの世界」 Io 1日目(Jugemより移植)"},{"contents":"久々に、MBAの備忘録です。 あれから色々入れました。 なので、入れたソフトの一覧を追加。\nAIR:TweetDeckをインストールするのに必要だったため TweetDeck(AIR版):TwitterとFacebookを同じ画面で見ることができるため。 TextWrangler:テキストエディタ(まだあんまり使ってない) Skitch:Evernoteに買収されて無料に。先日のSolr管理画面の説明書きにもちょっと使用 ClamXav:フリーのセキュリティソフト。 SourceTree:Twitterで知ったMac用のgit、mercurialのクライアントソフト。AtlassianがSourceTreeを買収したのを機に一時的に無料公開されていたので。 Firefox:基本はSafariを使ってます。WindowsではChromeを使ってます。ただ、Webページを表示されていない部分もまるごとキャプチャするのにChromeのプラグインだとダメだったので入れました。今のところキャプチャ用のブラウザです。 Full Screen enable for Eclipse on Lion:Eclipseをフルスクリーン対応するためのプラグイン MercurialEclipse:bitbucketにアカウントをもっているので。 mercurial:pipを使ってインストール。MercurialEclipseでコマンドが必要だから。「sudo pip install Mercurial」 pip:mercurialをインストールするためにインストール。「sudo easy_install pip」でインストール iStat pro(ウィジェット):CPUなどの情報を表示するウィジェット。ウィジェットがアップルのサイト(AppStoreではない)から検索できるというのを人から聞いた。ウィジェットってあんまり使われないのか? Mac Blu-ray Player:現時点で有料ソフトはこれだけ。こちら。もともとNASのデータのバックアップ用にBlu-rayのドライブ買ったんですが、せっかくだからMacにも使ってみようと思い、MacでBlu-rayを見るために購入しました。所用で長距離移動もあったので、新幹線で映画見てました。 このくらいです。 ほんとはリンクを貼ればいいのですが、そこまでの元気がないので、ご勘弁を。\nSkitchがおすすめです。簡単に画像編集+説明書きが入れられて、矢印などがよくある画像編集の野暮ったさがないので、画面キャプチャに説明書くのに今後活躍する予定です。\nあと、ソフトではなく、サービスなのですが、Cacooというサービスが便利です。 ここ最近、ちょっとした作図にはこのサービスを使うようにしています。オンラインで利用できるので、いろんな場所で編集できます。 また、図の作成もさることながら、図を共有することが可能です。 先日は、lucene-gosenが思ったように動かないという相談を受けて、このCacooでanalysis画面や設定をを貼ってもらったりしながら使いました。結構便利ですね。 ただ、付属のチャットを使ったのですが、このチャットの内容がテキスト形式でコピー出来なかったのが残念でした。今後の改修に期待ということで。\nあと、セットアップとは少し違いますが、ジャケット買ってつけました。 ステッカーを直接貼るのがちょっと気になったので、ジャケットつけてステッカーを貼ってます。 ただ、ステッカーは思ったよりチープな感じが。。。ジャケットの中に貼らないとダメだったかも。まぁ、それが嫌でジャケット買ったんですが。。。 エアージャケットセット for Macbook Air 13inch(クリア)PMC-81 ","date":1317968700,"dir":"post/2011/","id":"de1ab82817c0fb24e591b9a89a82f736","lang":"ja","lastmod":1317968700,"permalink":"https://blog.johtani.info/blog/2011/10/07/mba%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97%E5%82%99%E5%BF%98%E9%8C%B2%E3%81%9D%E3%81%AE%EF%BC%94/","publishdate":"2011-10-07T15:25:00+09:00","summary":"久々に、MBAの備忘録です。 あれから色々入れました。 なので、入れたソフトの一覧を追加。 AIR:TweetDeckをインストールするのに必要だ","tags":["備忘録"],"title":"MBAセットアップ備忘録その4(Jugemより移植)"},{"contents":"Lucene/SolrのMLでSolrの管理画面を新しくするというチケットが流れていたのでちょっと触って見ました。 ほんとにちょっと触っただけですが、いくつかキャプチャ撮ってみたので、アップしときます。 ※以下ではサムネイル画像に元画像(100Kくらいの画像)へのリンクが設定されています。携帯などでは見づらいかもしれませんが、ご容赦を。\nURLは旧管理画面とことなり、http://localhost:8983/solr/になります。\nまずはトップ画面 ダッシュボードと呼ばれるトップ画面。メモリの利用率や起動してからの時間、Luceneなどのバージョンが表示されます。 次は検索画面すっきりしてます。facetが指定できるようになったのは大きいかな。ただし、facet.fieldを複数指定などができないが。結果についてはとくに指定がなければXMLで帰ってきます。ただ、パラメータの追加ができなくなってる気がするなぁ ちなみに、Solrを止めて検索したらこんな感じの画面になりました。クエリの実行ならこのようにエラーがわかったのですが、停止後に左のメニューにあるSchemaなどをクリックしても白い画面が出るだけで、エラーかどうかがわかりにくいです。 Analysis画面。入力画面がシンプルになりました。フィールド名はリストで表示されるので選択するだけです。あとは、これまでどおり。サンプルはlucene-gosenの解析結果です。ハイライトもきちんと表示されます。ただし、長い文章の場合は結果部分だけがスクロールできる形になり、ちょっとわかりにくかったです。 Analysisの入力画面を表示したあとにSolrを停止して解析してみたらこんなエラー画面が出ました。ちなみに、その後、画面を切り替えずにSolrを起動して解析したら、赤い帯のエラーは出たままでした。一度別画面にすれば、元に戻りますが。 Pluginsの画面(旧管理画面のstatisticsに相当)。 キャッシュの状態が確認できます。今まであった画面と情報的には一緒かと。一段カテゴリ(CACHEとかCOREとか)の選択ができるようになり、見やすくなりました。 同じくPluginsの画面。 こちらはupdateHandlerについての情報です。commit数やoptimizeの回数、updateして、commitする前の状態のドキュメント数などが表示されます。前より表示される項目が多くなってるかな? 最後はスキーマブラウザこの画面が一番良くなっています。旧管理画面では、フィールド名がすべて大文字で表示され、しかもソートがされていない状態だったため、ダイナミックフィールドを利用しているとフィールドを探すのが一苦労でした。 今回は、プルダウンでフィールドやフィールドタイプのリストが表示され、辞書順で並んでいます。Filterなどもわかりやすい表示になっているかと。 おまけ Solritasと呼ばれるVelocityを使った、3.x系で入ってきた新しいサンプル画面です。URLはhttp://localhost:8983/solr/browseです。ファセットなどを使った簡単なサンプル画面なので、検索結果画面でこんなことができるというデモにも使えるかと。ただ、これも旧管理画面よりはましですが、デザインが。。。 とまぁ、簡単ですが、4.x系の管理画面をいくつか触ってみて、キャプチャをとって見ました。 デザインは前よりもすっきりしています。ただ、クエリについてはパラメータの追加ができなくなっているので、もう少し改良されるといいかなぁ(自分でやれよと言われそうですが。。。)\n","date":1317811380,"dir":"post/2011/","id":"09677934e13a5d728f00c6ed7c8870a9","lang":"ja","lastmod":1317811380,"permalink":"https://blog.johtani.info/blog/2011/10/05/solr%E3%81%AE%E6%96%B0%E3%81%97%E3%81%84%E7%AE%A1%E7%90%86%E7%94%BB%E9%9D%A2solr4-x-trunk%E7%B3%BB/","publishdate":"2011-10-05T19:43:00+09:00","summary":"Lucene/SolrのMLでSolrの管理画面を新しくするというチケットが流れていたのでちょっと触って見ました。 ほんとにちょっと触っただけ","tags":["solr"],"title":"Solrの新しい管理画面(Solr4.x trunk系)(Jugemより移植)"},{"contents":"遅くなりましたが、続きです。 さらに英語力のなさを痛感して凹んでいるところですが、何かの役に立てばと恥を晒すところです。。。\n一応、訳してみたのですが、訳すのに必死になってしまい、つながりがわかっていない点もちらほら。 このあと一旦見直しつつ、再度理解する「理解編」をアップしようかと思います。 できれば、シーケンス図とかも交えつつ。(そうしないと理解ができない可能性が。。。) 前回同様、原文は最後に付加しておきます。\nBoot Strapping Cluster Startup(クラスタの起動) ノードはZookeeperのホストとポートを指定することから始めます。 クラスタの最初のノードはクラスタのschema/configとクラスタの設定を指定するとこから開始します。 最初のノードはZookeeperに設定をアップロードしてクラスタをブートします。 クラスタは「ブートストラップ」状態です。 この状態ではノード-\u0026gt;パーティションマッピングは計算されず、クラスタはクラスタ管理コマンド以外のどんなread/writeリクエストも受け付けません。\nクラスタの最初のノード集合が起動した後、クラスタ管理コマンド(TBD記述???)が管理者によって発行されます。このコマンドは整数「partitions」パラメータを受け取り、次のステップを実行します。\nCluster Lockを取得 「partitions」をパーティション数として割り当て 各パーティションのためのノードを取得 ZooKeeperのノード-\u0026gt;パーティションマッピングを更新 Cluster Lockをリリース 全ノードに対して最新版のノード-\u0026gt;パーティションマッピングをZooKeeper経由で更新させる Node Startup ノードが起動すると、自分がすでに存在するシャードの一部かどうかZooKeeperでチェックします。 もし、ZooKeeperがノードのレコードを持っていない、またはどのシャードの一部でもないと判断したら、 ノードは後述の「New Node」のステップを実行します。すでに存在するノードの場合は後述の「Node Restart」のステップを実行します。\nNew Node\n新しいノードはクラスタの一部ではなく、クラスタのキャパシティを増強するためのものです。\n「auto_add_new_nodes」クラスタプロパティが「false」の場合、新しいノードはZooKeeperに「idle」として登録され、他のノードが参加してくれと言うまで待機します。 そうでない場合(auto_add_new_nods=true)は次のステップを実行します。\nCluster Lockを取得します。 適切なnode-\u0026gt;partitionエントリを選び出します。 利用可能なパーティションのリストをスキャンして「replication_factor」のノード数以下のパーティションのエントリを探します。複数ある場合はノード数が最小のエントリを選びます。それも一緒ならランダムに選びます。 全パーティションが「replication_factor」以上のノードを持っている場合、ノードはパーティションが最も多いものをスキャンします。複数ある場合はパーティション内のドキュメント数が最大のエントリを選びます。ドキュメント数が同一なら任意のエントリを選びます。 もし、選んだノード-\u0026gt;パーティションエントリを現在のノードに移動させることでがクラスタのパーティション:ノード比率の最大値を小さくするなら、現在のエントリを返します。。それ以外の場合選ばれたエントリがないので、アルゴリズムは終了です。。 ZooKeeper内のノード-\u0026gt;パーティションマッピングを更新します ZooKeeper内のノードステータスを「リカバリ」状態にします Cluster Lockをリリースします 「リカバリ」はパーティションのリーダーから開始します。 リカバリが終了したら、再度、Cluster Lockを取得します。 元のエントリはZooKeeperのノード-\u0026gt;パーティションマッピングから削除されます。 Cluster Lockをリリースします 元のノードはZooKeeperからノード-\u0026gt;パーティションマッピングを更新させられます ステップ1に戻ります。 Node Restart ノードの再起動とは次のいずれかを意味しています。\nJVMがクラッシュし、手動または自動でのリスタート ノードが一時的にネットワークから切り離された。もしくは、ZooKeeperに接続できなかった(死んでいると思われた)。または、ある一定期間、リーダーからの更新を受信できなかった。 このシナリオが表す書き込み処理のライフサイクルの間にネットワークから分断された ハード故障もしくはメンテナンスウインドウによりクラスタからノードが分断され、ノードをクラスタにrejoinさせるために起動した。 ノードが各パーティションに対してメンバーであるパーティションのリストを読み、パーティションのリーダーがリカバリプロセスを実行する。その時、ノードは「auto_add_new_nods」プロパティをチェックして、「New Node」処理のステップを実行する。 これはクラスタが。。。(元の文章が切れてて意味が不明)\nクライアントは標準的なSolrの更新形式を利用して書き込みできます。 書き込み処理はクラスタの任意のノードに送信されます。 ノードはハッシュ関数を利用して、どのパーティションに所属するか決めるためにrange-パーティションマッピングを使います。 ZooKeeperはシャードのリーダーを識別して、書き込み処理をそこに送ります。 SolrJはリーダーに対して書き込みを直接送信するための拡張がされています。\nリーダーはPartitionバージョンの操作を割り当て、そのトランザクションログの操作を書き込み、シャードに属する他のノードにドキュメントバージョンハッシュを転送します。 ノードはインデックスにドキュメントハッシュを書き込み、トランザクションログに操作を記録します。 リーダーは、min_writesの最小数のノード以上のノードが「OK」とレスポンスを返したら「OK」とレスポンスを返します。 クラスタプロパティのmin_writesは書き込みリクエスト時に指定することで、異なる値を指定できます。\nクラウドモードはコミット/ロールバック操作を明示的には行いません。 コミットは特定の間隔で(commit_within)リーダーによりオートコミットにより管理されます。 また、シャードの全メンバーのコミットはトリガーにより管理されます。 ノードが利用可能な最新バージョンはコミットの時点で記録されます。\nTransaction Log トランザクションログは2つのコミットの間にインデックスに対して実行された操作全てを記録したもの コミットはそれ以前に実行された操作の耐久性を保証するために、新しいトランザクションログを開始します。 同期は調整が可能です。例えば、flush vs fsynです。fsyncがデフォルトで、JVMクラッシュに対して保証できるが、電源異常の場合には保証できないが、速度的には早いです。 Recovery 次のトリガーにより復旧が可能です。\nBootstrap パーティション分割 クラスタの再構築 ノードは自身に「recovering」というステータスを設定して復旧を開始します。 このフェーズの間、ノードは読み込みリクエストを受けることができませんが、トランザくkションログに書きこまれるすべての新しい書き込みリクエストを受け取ります。 ノードは自身が持つインデックスのバージョンを調べて、パーティションの最新バージョンのリーダーに問い合わせます。 リーダーはシャード内の残りのノードと同期する前に実行されるべき操作の集合を返します(???)。\n最初にインデックスをコピーし、最新のノードにあるトランザクションログをリプレイします。 もし、インデックスのコピーが必要ならば、インデックスファイルをローカルにまずコピーし、その後トランザクションログをリプレイします。 トランザクションログのリプレイは通常の書き込みリクエストの流れと同じです。 この時、ノードは新しい書き込みを受け付けるかもしれません。その書き込みはインデックスに再生されるべきです。 ある時点でノードは最新のコミットポイントに追いつき、自身のステータスを「ready」にします。 この時点で、このノードは読み込みリクエストを処理できます。\nHandling Node Failures 一時的にネットワークが分断され、幾つかのノードとZooKeeperの間の通信が遮断されるかもしれません。 クラスタはデータの再構築(リバランシング)の前にしばらく待ちが発生します。\nLeader failure\nノードが故障し、もしそれがシャードのリーダだった場合、他のメンバーがリーダー選出のプロセスを開始します。 新しいリーダーが選出されるまで、このパーティションへの書き込みは受け付けられません。 この時、これはリーダー以外の故障ステップを処理します。(???)\nLeader failure\nシャードの一部に新しいノードが割り当てられる前にリーダーはmin_reaction_timeの間待ちます。 リーダーはCluster Lockを取得し、シャードの新規メンバーとしてノードを割り当てるためのノード-シャード割り当てアルゴリズムを使用します。 ZooKeeperのノード-\u0026gt;パーティションマッピングが更新され、Cluster Lockがリリースされます。 新しいノードはZooKeeperからノード-\u0026gt;パーティションマッピングを強制的にリロードされます。\nSplitting partitions 明示的なクラスタ管理コマンドもしくはSolrによる自動的な分割戦略(ストラテジ)はパーティションを分割することができます。 明示的な分割コマンド(split command)は対象となるパーティションを分割するために実行されます。\nパーティションXが100から199のハッシュの範囲を持つものとし、X(100から149)、Y(150~199)に分割するとします。 Xのリーダーは、XとYの新しい値の範囲をZooKeeperに分割アクションを記録します。 ノードはこの分割アクションもしくは新しいパーティションの存在については通知を受けません。(???)\nXのリーダはCluster Lockを取得し、パーティションY(アルゴリズムはto be determined)を割り当てるノードを決定し、新しいパーティションを知らせ、パーティション-\u0026gt;ノードマッピングを更新します。Xのリーダはノードのレスポンスを街、新しいパーティションがコマンドを受付可能な状態になったら次の処理を実行します。 Xのリーダーは分割が完了するまですべてのコミットを停止します。 Xのリーダーは最新のコミットポイント(バージョンVとする)のIndexReaderをオープンし、同じバージョンのIndexReaderもオープンするように命じます XのリーダーはYのリーダーに対してバージョンV以降のトランザクションログのうちハッシュ値の範囲が150から199のものを流します。 Yのリーダーはトランザクションログの#2(#3の間違い?)で送られたリクエストだけを記録します??? Xのリーダーはステップ#2で開いたIndexReaderに対してインデックスの分割を開始します。 #5で作成されたインデックスはYのリーダーに送られ、登録されます。 Yのリーダーは「recovery」プロセスを開始するように(シャードの)他のノード命令し、インデックスのトランザクションログを再生し始めます。 パーティションYのすべてのノードがバージョンVに到達したならば YのリーダーはXのリーダーに#2で作成されたReaderの上に、ハッシュの範囲が100から149だけに属しているドキュメントを抽出するようにするFilteredIndexReaderを準備するように頼みます。 Xのリーダーは#8aのリクエストが完了したのを検知したら、YのリーダーがCluster Lockを取得し、クラスタ全体の検索/登録リクエストの受信を開始するためにレンジ-\u0026gt;パーティションマッピングを変更します。 YのリーダーはXのリーダーに検索リクエストのために#8aで作成されたFilteredIndexReaderの利用開始を頼みます YのリーダーはXのリーダーに、ZooKeeperからレンジ-\u0026gt;パーティションマッピングを矯正リフレッシュするように頼みます。この時点で#3で開始されたトランザクションログの流しこみが停止されるのが保証されます。 Xのリーダーは自身のパーティションに存在するべきでないハッシュ値をもつドキュメントを削除し、最新のコミットポイントのsearcherを再度開きます。 この時点で分割は完全に終了し、Xのリーダーはcommit_withinパラメータによるコミットをレジュームします(???) Notes:\n分割操作が完了するまで、commit_withinパラメータによるパーティションの分割は実行されない #8b開始から#8c終了までの間の分散検索は一貫しない検索結果を帰す場合がある(例えば:検索結果が異なる) Cluster Re-balancing クラスタは明示的なクラスタ管理コマンドにより再構築(リバランシング)できる。\nTBD (to be determined)\nCluster Re-balancing TBD (to be determined)\nConfiguration solr_cluster.properties これはクラスタ内の全ノードにわたって適用される一般的なSolr設定ファイルとは別のプロパティファイルの集合である。\nreplication_factor:クラスタによって管理されるドキュメントのレプリカの数 min_writes:書き込み操作が成功になる前の最小の書き込み????。これは書き込みごとに上書き設定可能 commit_within:検索に現れるまでの書き込み操作の最大回数 hash_function:ドキュメントのハッシュ値を計算するための関数の実装 max_hash_value:ハッシュ関数が出力することができる最大値。理論的には、この値はクラスタが保持できるパーティションの最大数でもある min_reaction_time:起動、停止の後に再配分/分割にかかる時間(??) min_replica_for_reaction:レプリカノード数がこの値以下になったら、min_reaction_timeにならなくても分割が実行される。 auto_add_new_nodes:booleanフラグ。もしtrueなら新しいノードは自動的にパーティションからレプリカを読み込む。そうでない場合は新しいノードはクラスタに「idle」状態で登録される Cluster Admin Commands すべてのクラスタ管理コマンドはすべてのノードでパス(/cluster_admin)を与えることで実行できます。 全ノードは同じコマンドを受け付けることができ、振る舞いも同じものになるでしょう。 以下のコマンドはユーザが利用できるパブリックなコマンドです。\ninit_cluster:(パラメータ:パーティション)このコマンドはノードの集合の初期化後に実施されます。このコマンドが実行されるまで、クラスタは読み込み/書き込みコマンドを受け付けません。 split_partition:(パラメータ:パーティション(任意))パーティションを2つに分割します。もしパーティションパラメータが指定されない場合は、ドキュメント数が最大の add_idle_nodes:このコマンドはauto_add_new_nodes=falseの場合に利用できます。このコマンドはクラスタに対して「idle」状態のすべてのノードを追加するトリガーとなります。 move_partition:(パラメータ:パーティション、from、to)fromのノードからtoの別のノードに引数で指定されたパーティションを移動します。 command_status:(パラメータ:completion_id(任意))上記コマンドはすべて非同期で実行され、completion_idを返します。このコマンドは特定の実行中のコマンドもしくは全ての実行中のコマンドの状態を表示するために利用できます。 status:(パラメータ:パーティション(任意))パーティションのリストを表示し各パーティションの次の情報を表示します。 リーダーノード ノードのリスト ドキュメント数 平均読み込み回数(reads/sec) 平均書き込み回数(writes/sec) 平均読み込み時間(time/read) 平均書き込み時間(time/write) Migrating from Solr to SolrCloud クラウドに移行するときに幾つかの特徴は不要かもしれないし、サポートされないかもしれません。 既存の(クラウドでない)バージョンでのすべての特徴をSolrCloudでサポートし続けなければなりません。\nレプリケーション:これは必要ありません。 CoreAdminコマンド:明示的なコアの操作は許可されません。内部にコアがあるかもしれないが、暗黙的に管理されるでしょう 複数スキーマのサポート?:単純化のため、ver1.0ではサポートしないかもしれない solr.xml:SolrCloudでほんとに必要? Alternative to a Cluster Lock リーダーを選出する常設の調停ノード(masterはインデックスレプリケーションで利用している用語なので、「調停」とする)を持つほうが単純かもしれません。 「truth」状態をZookeeperの状態としてみなすような次のパターンでは、将来の柔軟性(クラスタを制御するためのZookeeperの状態を直接変更するような外部管理ツールのような)を考慮に入れることができます。 (毎回ロックを取得するよりも)調停ノードを持つことにより、よりスケーラブルになるかもしれません。 特定条件下でのみCluster Lockを利用するハイブリッドも意味があるでしょう。\nSingle Node Simplest Use Case 単一ノードでスタートして、ドキュメントをインデックス登録できないといけません。 また、あとで、クラスタに2番目のノードを追加できないと行けません。\n1つのノードから開始し、最初にZookeeperに設定ファイルをアップロードし、shard1にノードを作成+登録します。 他の情報がない状態で設定が作成され、1つのシャードのシステムとなります。 いくつかのドキュメントをインデックスします 他のノードが起動し、「まだ割り当てられていない場合、レプリカの最小の数をもつshardに割り当てられ、「recovery」プロセスを開始します」というパラメータを受け取ります。 * 出来れば、同一ホスト上に同じシャードはコピーしない * この時点の後で、ノードが停止したら、再起動し、同じ役割が再開されるべきです。(Zookeeperでそれ自身であると判別されれば) 原文はこちらからです。\nBoot Strapping Cluster Startup A node is started pointing to a Zookeeper host and port. The first node in the cluster may be started with cluster configuration properties and the schema/config files for the cluster. The first node would upload the configuration into zookeeper and bootstrap the cluster. The cluster is deemed to be in the “bootstrap” state. In this state, the node -\u0026gt; partition mapping is not computed and the cluster does not accept any read/write requests except for clusteradmin commands.\nAfter the initial set of nodes in the cluster have started up, a clusteradmin command (TBD description) is issued by the administrator. This command accepts an integer “partitions” parameter and it performs the following steps:\nAcquire the Cluster Lock Allocate the “partitions” number of partitions Acquires nodes for each partition Updates the node -\u0026gt; partition mapping in ZooKeeper Release the Cluster Lock Informs all nodes to force update their own node -\u0026gt; partition mapping from ZooKeeper The Cluster Lock is acquired A suitable source (node, partition) tuple is chosen: The list of available partitions are scanned to find partitions which has less then “replication_factor” number of nodes. In case of tie, the partition with the least number of nodes is selected. In case of another tie, a random partition is chosen. If all partitions have enough replicas, the nodes are scanned to find one which has most number of partitions. In case of tie, of all the partitions in such nodes, the one which has the most number of documents is chosen. In case of tie, a random partition on a random node is chosen. If moving the chosen (node, partition) tuple to the current node will decrease the maximum number of partition:node ratio of the cluster, the chosen tuple is returned.Otherwise, no (node, partition) is chosen and the algorithm terminates The node -\u0026gt; partition mapping is updated in ZooKeeper The node status in ZooKeeper is updated to “recovery” state The Cluster Lock is released A “recovery” is initiated against the leader of the chosen partition After the recovery is complete, the Cluster Lock is acquired again The source (node, partition) is removed from the node -\u0026gt; partition map in ZooKeeper The Cluster Lock is released The source node is instructed to force refresh the node -\u0026gt; partition map from ZooKeeper Goto step #1 Node Restart A node restart can mean one of the following things:\nThe JVM crashed and was manually or automatically restarted The node was in a temporary network partition and either could not reach ZooKeeper (and was supposed to be dead) or could not receive updates from the leader for a period of time. A node restart ine node failure. Lifecycle of a Write Operation this scenario signifies the removal of the network partition. A hardware failure or maintenance window caused the removal of the node from the cluster and the node has been started again to rejoin the cluster. The node reads the list of partitions for which it is a member and for each partition, starts a recovery process from each partition’s leader respectively. Then, the node follows the steps in the New Node section without checking for the auto_add_new_nodes property. This ensures that the cluster recovers from the imbalance created by th\nWrites are performed by clients using the standard Solr update formats. A write operation can be sent to any node in the cluster. The node uses the hash_function , and the Range-Partition mapping to identify the partition where the doc belongs to. A zookeeper lookup is performed to identify the leader of the shard and the operation is forwarded there. A SolrJ enhancement may enable it to send the write directly to the leader\nThe leader assigns the operation a Partition Version and writes the operation to its transaction log and forwards the document + version + hash to other nodes belonging to the shard. The nodes write the document + hash to the index and record the operation in the transaction log. The leader responds with an ‘OK’ if at least min_writes number of nodes respond with ‘OK’. The min_writes in the cluster properties can be overridden by specifying it in the write request.\nThe cloud mode would not offer any explicit commit/rollback operations. The commits are managed by auto-commits at intervals (commit_within) by the leader and triggers a commit on all members on the shard. The latest version available to a node is recorded with the commit point.\nTransaction Log A transaction log records all operations performed on an Index between two commits Each commit starts a new transaction log because a commit guarantees durability of operations performed before it The sync can be tunable e.g. flush vs fsync by default can protect against JVM crashes but not against power failure and can be much faster Recovery A recovery can be triggered during:\nBootstrap Partition splits Cluster re-balancing The node starts by setting its status as ‘recovering’. During this phase, the node will not receive any read requests but it will receive all new write requests which shall be written to a separate transaction log. The node looks up the version of index it has and queries the ‘leader’ for the latest version of the partition. The leader responds with the set of operations to be performed before the node can be in sync with the rest of the nodes in the shard.\nThis may involve copying the index first and replaying the transaction log depending on where the node is w.r.t the state of the art. If an index copy is required, the index files are replicated first to the local index and then the transaction logs are replayed. The replay of transaction log is nothing but a stream of regular write requests. During this time, the node may have accumulated new writes, which should then be played back on the index. The moment the node catches up with the latest commit point, it marks itself as “ready”. At this point, read requests can be handled by the node.\nHandling Node Failures There may be temporary network partitions between some nodes or between a node and ZooKeeper. The cluster should wait for some time before re-balancing data.\nLeader failure\nIf node fails and if it is a leader of any of the shards, the other members will initiate a leader election process. Writes to this partition are not accepted until the new leader is elected. Then it follows the steps in non-leader failure\nNon-Leader failure\nThe leader would wait for the min_reaction_time before identifying a new node to be a part of the shard. The leader acquires the Cluster Lock and uses the node-shard assignment algorithm to identify a node as the new member of the shard. The node -\u0026gt; partition mapping is updated in ZooKeeper and the cluster lock is released. The new node is then instructed to force reload the node -\u0026gt; partition mapping from ZooKeeper.\nSplitting partitions A partition can be split either by an explicit cluster admin command or automatically by splitting strategies provided by Solr. An explicit split command may give specify target partition(s) for split.\nAssume the partition ‘X’ with hash range 100 - 199 is identified to be split into X (100 - 149) and a new partition Y (150 - 199). The leader of X records the split action in ZooKeeper with the new desired range values of X as well as Y. No nodes are notified of this split action or the existence of the new partition.\nThe leader of X, acquires the Cluster Lock and identifies nodes which can be assigned to partition Y (algorithm TBD) and informs them of the new partition and updates the partition -\u0026gt; node mapping. The leader of X waits for the nodes to respond and once it determines that the new partition is ready to accept commands, it proceeds as follows: The leader of X suspends all commits until the split is complete. The leader of X opens an IndexReader on the latest commit point (say version V) and instructs its peers to do the same. The leader of X starts streaming the transaction log after version V for the hash range 150 - 199 to the leader of Y. The leader of Y records the requests sent in #2 in its transaction log only i.e. it is not played on the index. The leader of X initiates an index split on the IndexReader opened in step #2. The index created in #5 is sent to the leader of Y and is installed. The leader of Y instructs its peers to start recovery process. At the same time, it starts playing its transaction log on the index. Once all peers of partition Y have reached at least version V: The leader of Y asks the leader of X to prepare a FilteredIndexReader on top of the reader created in step #2 which will have documents belonging to hash range 100 - 149 only. Once the leader of X acknowledges the completion of request in #8a, the leader of Y acquires the Cluster Lock and modifies the range -\u0026gt; partition mapping to start receiving regular search/write requests from the whole cluster. The leader of Y asks leader of X to start using the FilteredIndexReader created in #8a for search requests. The leader of Y asks leader of X to force refresh the range -\u0026gt; partition mapping from ZooKeeper. At this point, it is guaranteed that the transaction log streaming which started in #3 will be stopped. The leader of X will delete all documents with hash values not belonging to its partitions, commits and re-opens the searcher on the latest commit point. At this point, the split is considered complete and leader of X resumes commits according to the commit_within parameters. Notes:\nThe partition being split does not honor commit_within parameter until the split operation completes Any distributed search operation performed starting at the time of #8b and till the end of #8c can return inconsistent results i.e. the number of search results may be wrong. Cluster Re-balancing The cluster can be rebalanced by an explicit cluster admin command.\nTBD\nMonitoring TBD\nConfiguration solr_cluster.properties This are the set of properties which are outside of the regular Solr configuration and is applicable across all nodes in the cluster:\nreplication_factor : The number of replicas of a doc maintained by the cluster min_writes : Minimum no:of successful writes before the write operation is signaled as successful . This may me overridden on a per write basis commit_within : This is the max time within which write operation is visible in a search hash_function : The implementation which computes the hash of a given doc max_hash_value : The maximum value that a hash_function can output. Theoretically, this is also the maximum number of partitions the cluster can ever have min_reaction_time : The time before any reallocation/splitting is done after a node comes up or goes down (in secs) min_replica_for_reaction : If the number of replica nodes go below this threshold the splitting is triggered even if the min_reaction_time is not met auto_add_new_nodes : A Boolean flag. If true, new nodes are automatically used as read replicas to existing partitions, otherwise, new nodes sit idle until the cluster needs them. Cluster Admin Commands All cluster admin commands run on all nodes at a given path (say /cluster_admin). All nodes are capable of accepting the same commands and the behavior would be same. These are the public commands which a user can use to manage a cluster:\ninit_cluster : (params : partition) This command is issued after the initial set of nodes are started. Till this command is issued, the cluster would not accept any read/write commands split_partition : (params : partitionoptional). The partition is split into two halves. If the partition parameter is not supplied, the partition with the largest number of documents is identified as the candidate. add_idle_nodes : This can be used if auto_add_new_nodes=false. This command triggers the addition of all ‘idle’ nodes to the cluster. move_partition : (params : partition, from, to). Move the given partition from a given node from to another node command_status :(params : completion_idoptional) . All the above commands are asynchronous and returns with a completion_id . This command can be used to know the status of a particular running command or all the current running commands status : (params : partitionoptional) Shows the list of partitions and for each partition, the following info is provided leader node nodes list doc count average reads/sec average writes/sec average time/read average time/write Migrating from Solr to SolrCloud A few features may be redundant or not supported when we move to cloud such as. We should continue to support the non cloud version which supports all the existing features\nReplication. This feature is not required anymore CoreAdmin commands. Explicit manipulation of cores will not be allowed. Though cores may exist internally and they meay be managed implicitly Multiple schema support ? Should we just remove it from ver 1.0 for simplicity? solr.xml . Is there a need at all for this in the cloud mode? Alternative to a Cluster Lock It may be simpler to have a coordinator node (we avoid the term master since that is associated with traditional index replication) that is established via leader election. Following a pattern of treating the zookeeper state as the \u0026ldquo;truth\u0026rdquo; and having nodes react to changes in that state allow for more future flexibility (such as allowing an external management tool directly change the zookeeper state to control the cluster). Having a coordinator (as opposed to grabbing a lock every time) can be more scalable too. A hybrid model where a cluster lock is used only in certain circumstances can also make sense.\nSingle Node Simplest Use Case We should be able to easily start up a single node and start indexing documents. At a later point in time, we should be able to start up a second node and have it join the cluster.\nstart up a single node, upload it\u0026rsquo;s configuration (the first time) to zookeeper, and create+assign the node to shard1. in the absence of other information when the config is created, a single shard system is assumed index some documents start up another node and pass it a parameter that says \u0026ldquo;if you are not already assigned, assign yourself to any shard that has the lowest number of replicas and start recovery process\u0026rdquo; avoid replicating a shard on the same host if possible after this point, one should be able to kill the node and start it up again and have it resume the same role (since it should see itself in zookeeper)\n","date":1317720720,"dir":"post/2011/","id":"7052598d2355984237d126afea2f6e88","lang":"ja","lastmod":1317720720,"permalink":"https://blog.johtani.info/blog/2011/10/04/new-solrcloud-design%E3%81%AE%E7%BF%BB%E8%A8%B3%E3%81%9D%E3%81%AE2/","publishdate":"2011-10-04T18:32:00+09:00","summary":"遅くなりましたが、続きです。 さらに英語力のなさを痛感して凹んでいるところですが、何かの役に立てばと恥を晒すところです。。。 一応、訳してみたの","tags":["solr"],"title":"New SolrCloud Designの翻訳(その2)(Jugemより移植)"},{"contents":"ちょっと興味があるので、訳してみました。(Wikiのページはこちら) 更新されているようなので、もとの文章も残しておきます。(ページ下部の続きはこちら部分以降) 全部訳そうと思ったのですが、終わらなかったので、まずは前半部分です。まだ、訳しただけで理解できてない。。。 (英語力のなさをさらけ出してしまうのですが、これも修行です。。。おかしいところはツッコミを。)\nWhat is SolrCloud? Solrクラウドはクラウドでの検索サービスとしてのSolrを管理、運用するための既存のSolrを拡張するものです。\n用語集 Cluster:クラスタは1単位として管理されるSolrノードの集合です。クラスタ全体で単一のschema、solrconfigをもたないといけません。 Node:ひとつのJVMインスタンスで起動しているSolrのこと Partition:パーティションはドキュメント集合全体のサブセット(部分集合)のことです。パーティションは部分集合のドキュメントが単一のインデックスに含まれるような形で作られます。 Shard:パーティションはn(=replication factor)個のノードに保存される必要があります。このn個のノードすべてでひとつのshardです。1つのノードはいくつかのshardの一部にで有る場合があります。 Leader:各Shardは1つのリーダとなるノードを持っています。パーティションに登録されたドキュメントリーダーからコピーされます Replication Factor:クラスタによって保持されるレプリカの最小限の数 Transaction Log:各ノードによって保持される書き込み処理の追記ログ Partition version:これは各shardのリーダーが持っているカウンターで、書き込み処理ごとに増加し、レプリカに送られます。 Cluster Lock:これはrange(※後述されているハッシュ値の範囲のことか?)-\u0026gt;パーティションもしくはパーティション-\u0026gt;ノードのマッピングを変更するために取得しなければいけないグローバルなロックのことです。 ※用語だけだと関係がわかりづらかったので、図を書いてみました。\nドキュメントの集合とパーティションについての考え方\nクラスタ、ノード、シャードの考え方。\n処理原則 任意の処理はクラスタにある任意のノードに実行可能です。 リカバリできないSPOFはありません。 クラスタは伸縮自在(elastic)でなければならない 書き込みが失われないこと(耐久性)を保証する 書き込み順序が保証されなければならない 2つのクライアントが2つの「A」というドキュメントを同時に送信してきた場合、すべてのレプリカで一貫してどちらか一方が保存されなければならない。 クラスタの設定は中央管理されなければならない。また、クラスタのどのノードからもクラスタ設定が更新できます。 読み込み(検索)の自動的なフェイルオーバー 書き込み(インデクシング)の自動的なフェイルオーバー ノードの故障が発生しても自動的にrepcation factorの数は守られます。(故障したら動的にレプリカを再配置?) Zookeeper ZooKeeperクラスタは次のために使用されます。\nクラスタ設定の集中管理 分散同期に必要な操作のコーディネータ クラスタ構成を保存するためのシステム Partitioning クラスタは固定されたmax_hash_value=「N」が設定されます。 max_hash_valueは1000のような大きな値が設定されます。\nhash = hash_function(doc.getKey()) % N ハッシュ値の範囲がパーティションに割り当てられ、ZooKeeperに保存されます。 次の例のような形で、パーティションに対して範囲が設定されます。\nrange : partition ------ ---------- 0 - 99 : 1 100-199: 2 200-299: 3 ハッシュはドキュメントにインデックスフィールドとして追加され、変更されない値です。 これは、インデックスを分割するときにも利用します。\nハッシュ関数はプラガブルです。これはドキュメントを受け取り、一貫した正整数ハッシュ値を返します。デフォルトのハッシュ関数として、必須でかつ変更されないフィールド(デフォルトはユニークキーフィールド)からハッシュ値を計算する関数が提供されます。\nUsing full hash range max_hash_valueは必ずしも必要ではありません。各shardはいずれにしろハッシュ値の範囲持っているので、完全な32 bitsハッシュを使うこともできます。 設定可能なmax_hash_valueを利用しないで、クライアントからの値をもとにハッシュ値を作ることができます。 例えば、電子メールの検索アプリでは次のようにハッシュ関数を作ることができます。\n(hash(user_id)\u0026lt;\u0026lt;24) | (hash(message_id)\u0026gt;\u0026gt;\u0026gt;8) ユーザIDから8bitのハッシュコードの先頭8ビットを利用することで、任意のユーザのメールがクラスタの同じ256番目(のノード?)にあるのを保証します。検索時はこの情報をもとにクラスタのその部分への問い合わせだけで情報が得られます。\nおそらく、私たちは最大値から最小値をカバーする範囲を表現するのにハッシュ空間を輪(固定のハッシュではなく)とみなしたいです。(???円状のハッシュ空間とすることで、クラスタ内のノード数の増減に耐えられるようにするよということかな?)\nshard naming シャードからハッシュ値の範囲へのマッピングを別々に管理するよりも、ハッシュコードによりパーティションを構成するときに実際にはハッシュの範囲をシャード名にします。 (シャード「1-1000」は1から1000の間のハッシュコードを持つドキュメントが含まれるという形)\n現時点では(コレクション1つに対してシングルコアの1Solrサーバと仮定して)solrコア名はコレクション名をつけるようになっています。 同一コレクションのためのマルチコアに対してのいい命名規則をつけるという課題が残っています。 (※コレクションに対する説明がここまでないかな?)\nShard Assignment ノード-\u0026gt;パーティションのマッピングはZooKeeperにあるCluster Lockを取得したノードによってのみ変更が可能です。 ノードの追加時に、まず、Cluster Lockを取得し、次にそれがどのパーティションを取得できるかを識別します。\nNode to a shard assignment 新しいノードを探しているノードはまずCluster Lockを取得しないといけません。 第一に、リーダーはシャードを決めます。 シャードが持つ、すべての利用可能なノード数で最小の値を持つノードが選び出されます。 もし、同値ならランダムにノードを選びます。\n原文はこちらからです。\nNew SolrCloud Design (Work in progress)\nWhat is SolrCloud? SolrCloud is an enhancement to the existing Solr to manage and operate Solr as a search service in a cloud.\nGlossary Cluster : Cluster is a set of Solr nodes managed as a single unit. The entire cluster must have a single schema and solrconfig Node : A JVM instance running Solr Partition : A partition is a subset of the entire document collection. A partition is created in such a way that all its documents can be contained in a single index. Shard : A Partition needs to be stored in multiple nodes as specified by the replication factor. All these nodes collectively form a shard. A node may be a part of multiple shards Leader : Each Shard has one node identified as its leader. All the writes for documents belonging to a partition should be routed through the leader. Replication Factor : Minimum number of copies of a document maintained by the cluster Transaction Log : An append-only log of write operations maintained by each node Partition version : This is a counter maintained with the leader of each shard and incremented on each write operation and sent to the peers Cluster Lock : This is a global lock which must be acquired in order to change the range -\u0026gt; partition or the partition -\u0026gt; node mappings. Guiding Principles Any operation can be invoked on any node in the cluster. No non-recoverable single point of failures Cluster should be elastic Writes must never be lost i.e. durability is guaranteed Order of writes should be preserved If two clients send document \u0026ldquo;A\u0026rdquo; to two different replicas at the same time, one should consistently \u0026ldquo;win\u0026rdquo; on all replicas. Cluster configuration should be managed centrally and can be updated through any node in the cluster. No per node configuration other than local values such as the port, index/logs storage locations should be required Automatic failover of reads Automatic failover of writes Automatically honour the replication factor in the event of a node failure Zookeeper A ZooKeeper cluster is used as:\nThe central configuration store for the cluster A co-ordinator for operations requiring distributed synchronization The system-of-record for cluster topology Partitioning The cluster is configured with a fixed max_hash_value (which is set to a fairly large value, say 1000) ‘N’. Each document’s hash is calculated as:\nhash = hash_function(doc.getKey()) % N Ranges of hash values are assigned to partitions and stored in Zookeeper. For example we may have a range to partition mapping as follows\nrange : partition ------ ---------- 0 - 99 : 1 100-199: 2 200-299: 3 The hash is added as an indexed field in the doc and it is immutable. This may also be used during an index split\nThe hash function is pluggable. It can accept a document and return a consistent \u0026amp; positive integer hash value. The system provides a default hash function which uses the content of a configured, required \u0026amp; immutable field (default is unique_key field) to calculate hash values.\nUsing full hash range Alternatively, there need not be any max_hash_value - the full 32 bits of the hash can be used since each shard will have a range of hash values anyway. Avoiding a configurable max_hash_value makes things easier on clients wanting related hash values next to each other. For example, in an email search application, one could construct a hashcode as follows:\n(hash(user_id)\u0026lt;\u0026lt;24) | (hash(message_id)\u0026gt;\u0026gt;\u0026gt;8) By deriving the top 8 bits of the hashcode from the user_id, it guarantees that any users emails are in the same 256th portion of the cluster. At search time, this information can be used to only query that portion of the cluster.\nWe probably also want to view the hash space as a ring (as is done with consistent hashing) in order to express ranges that wrap (cross from the maximum value to the minimum value).\nshard naming When partitioning is by hash code, rather than maintaining a separate mapping from shard to hash range, the shard name could actually be the hash range (i.e. shard \u0026ldquo;1-1000\u0026rdquo; would contain docs with a hashcode between 1 and 1000).\nThe current convention for solr-core naming is that it match the collection name (assuming a single core in a solr server for the collection). We still need a good naming scheme for when there are multiple cores for the same collection.\nShard Assignment The node -\u0026gt; partition mapping can only be changed by a node which has acquired the Cluster Lock in ZooKeeper. So when a node comes up, it first attempts to acquire the cluster lock, waits for it to be acquired and then identifies the partition to which it can subscribe to.\nNode to a shard assignment The node which is trying to find a new node should acquire the cluster lock first. First of all the leader is identified for the shard. Out of the all the available nodes, the node with the least number of shards is selected. If there is a tie, the node which is a leader to the least number of shard is chosen. If there is a tie, a random node is chosen.\n","date":1317210300,"dir":"post/2011/","id":"927612b57ba01ca878b2d7edce52a563","lang":"ja","lastmod":1317210300,"permalink":"https://blog.johtani.info/blog/2011/09/28/new-solrcloud-design%E3%81%AE%E7%BF%BB%E8%A8%B3%E3%81%9D%E3%81%AE%EF%BC%91/","publishdate":"2011-09-28T20:45:00+09:00","summary":"ちょっと興味があるので、訳してみました。(Wikiのページはこちら) 更新されているようなので、もとの文章も残しておきます。(ページ下部の続き","tags":["solr"],"title":"New SolrCloud Designの翻訳(その1)(Jugemより移植)"},{"contents":"Hadoop Conference Japan 2011 Fallに行ってきました。 まずは、ユーザ会の方々、運営の方々、発表された方々お疲れ様でした。こんな機会を用意していただき、ありがとうございます。 Hadoopは昨年触っていたのですが、最近は縁がなくなってしまいました。 ただ、触っていたときに面白かったので参加してきました。 ということで、今回も自分用にメモを取ったので。(今回は英語のヒアリングがあって、メモがひどい事になってます。。。) いつものことながら、おかしいところとかあれば、ツッコミなどフィードバックをもらえると嬉しいです。\n場所:ベルサール汐留 日時:2011/09/26 10:00~18:00+懇親会:18:30~21:00\nオープニングトーク:濱野、太田 参加者:1100名超!(実際は800名弱?) Hadoopの経験:利用経験なしな方が580名 カンファレンスの認知:Twitterよりも知人、その他が多かった。 会場提供:リクルート様 リクルート米谷様より一言。 Question VOTE!!サイトを用意。 http://mit.recruit.co.jpにて情報提供。 ※残念ながら地下だったため、E-mobileにつながらず、あと、電源確保が難しかったのでMBAをスタンドアロンにしてメモをとっていたので、 QAサイトにはアクセスしませんでした。もう少し活用したかったんですが、携帯でTwitterを追っかけるので精一杯。。。\n◎The role of the Distribution in the Apache Hadoop Ecosystem:Todd Lipcon(Cloudera)\n1.Introduction Todd Lipcon:Clouderaエンジニア Hadoop とHBaseのコミッター 2. Hadoop Overview HDFS+MapReduceの説明 Hadoopの生まれてきた経緯 様々な形式のデータが大量に存在し、データのハンドリングが難しくなってきたため。 Flexible, Scalable Solutionが必要に。 Hadoop の2つのユースケース 1.Advanced Analytics SNS(Web)、Content Optimization(Media)、Network Analytics(Telco)、 2.Data Processing Clickstream SessionizationEngagement 3.Cloudera Overview ClouderaCustomers ・Large National Bank ・Web-Based Media click-through dataや広告のログ ・Wireless Telecom 大量のデータ 目標:大量データからビジネスを引き出すこと。 Cloudera Japan:トレーニング。NTTDと協業して開発支援も 4.CDH Overview 100% pure Apache Hadoop SCM Epress(Service \u0026amp;amp; Configuration Manager) Free なぜ、CDHを利用するの? Linuxを利用する場合にLinux.orgからはダウンロードしないように、Hadoopも同じように提供したい。 RedHat系を目指しているみたい。 様々なパッケージの依存関係が混乱を招く。 CDHならテストが終わってるものが提供されてる。 ※SolrはLWEがLucidWorksEnterpriseがこれを目指してるのか。 5.Cloudera Enterprise Activity Monitor:Jobのパフォーマンスをリアルタイムに監視 SCM:設定のvalidateや管理。 Resource Manager:。。。 6.まとめ CDH:簡単にHadopが使えるよ。 SCM Express:簡単にHadoopの設定ができてフリーだよ Cloudera:Hadoopに関していろいろサポートしているよ。(Enterprise用ソフトやトレーニングなど) ◎About Hortonworks:Owen O\u0026rsquo;Malley(Hortonworks)\n1.About Hortonworks 2011/2月に設立 22人のYahooからのアーキテクトとコミッタにより設立 2.Credentials Yahooのクラスタの経験者がいますよ。 OSSに長けた人達によるチームです。 3.What is Apache Hadoop Hadoopの説明(別の側面が幾つかあり。) Commodity Hardwareで動く 簡単にプログラムできる 典型的なアプリケーションのタグクラウド(あとでちゃんと見る) HadoopのほとんどのソースコードはYahooで作られてるよ。 Clouderaとか目じゃないよ 4.Hadoop @ Yahoo! 各種サーバや規模など Science Hadoop Cluster \u0026lt;-\u0026amp;gt; Production Hadoop Cluster \u0026lt;-\u0026amp;gt; Serving Systems という構成で、いろいろやってます。 5.Hadoop Market ビジネス:ビッグデータを扱って色々やろうね 金融系:IT系のコストをOSSとHadoopで削減 技術系: 6.Hortonworks Strategy Hadoopを利用、管理しやすくするためのいろんなことをコミュニティに還元しますよ。 性能などについても同様。 トレーニングやテクニカルサポートやりますよ。 QA: Q:42Kのノードの管理ツールはなに? A:手で管理してます。 Q:社名の由来は? A:童話でHortonという名前の象の話がある。 Q:CDHはおすすめ?それともほかのものがいい? A:※聞き取れず。。。 Q:500万Query/月はアドホックQueryもあるの? A:幾つかのクラスタに分けて使ってる。アドホックは不明 ◎How Hadoop needs to evolve and integrate into the enterprise:Ted Dunning(MapR)\n・Quick History ・英語わからない身には辛い。。。 Zookeeperの人らしい。 Narrow Foundations HDFSとNASの間には大きな壁があり、大きなデータを移動するのはコストが掛かる。 Broad Foundation HDFSの代わりにNAS、RDBMSの下に位置するMapRを用意 ど、どんな仕組み?-\u0026amp;gt;テクニカルセッションで。 QA: Q:MapRはOSSにしないのか? A:MapRで開発したものはApacheに還元はしますが、OSSにはしないよ。フリー版は提供するかも ここで昼食。午前中からいた人にはランチボックスが提供されました。 午後からはコミュニティトラックとテクニカルトラックの2トラックがありましたが、LTが聞きたかった(それよりも英語が辛かった?)のでコミュニティトラックのど真ん中、最前列に入り浸りました。 ★コミュニティトラック ◎Elastic MapReduce Amazonが提供するHadoop:大谷晋平(Amazon)\n・Amazonとは Eコマース 流通 AWS の3つのサービス ・AWS Low-level、High-level、Cross Service、Tools to access services、アプリケーション 色々あるなー ・Bigデータが大変な理由 ケタ違いのデータ量、異なる形式データ、即時性 現状システムはスケールしない ビジネスとして成立する? 成立するならすぐスケールだめならすぐ縮小 ・Hadoopとは? これまでのお話。 スケーラブル、低価格なハード 誰でも入手可能で、実績多数。 ・Amazon EMR AWS上でスケーラブルなインフラ上に構築が可能 オンプレミスからMapReduceアプリを移行可能なため、分析、解析に集中可能 S3からデータIN/OUTするので、データ欠損がない。 Hadoopそのままではチューニングやクラスタサイズ見積もりも難しい =>クラスタサイズを動的に拡張伸縮可能。パフォーマンス最適化もできるよ。 0.18、0.20が利用可能。 EMRはHDFSとジョブ(タスク)トラッカーを別構成にしている。 EC2上にMaster、Core、タスクノードを展開 S3にデータを格納 SimpleDB(KVS)を利用 ・EMR注目機能 ジョブフローの高速化 ジョブの再起動無しにコスト/パフォーマンス比を変更可能。 タスクノードを動的に増やせる 柔軟なデータウェアハウスクラスタ タスクノードをバッチ実行時にのみ増やせる。 ※増減できるのはタスクノード Coreノードは増加のみ EMR+Spotインスタンスの活用 コスト削減効果が非常に高い AWSの余剰リソースをリーズナブルに提供(Amazon的にもウハハだ) ・その他の機能 東海岸だけだけど、スパコンレベルのインスタンスも利用可能 AWS上での最適化設計など ※ちょっと時間足りなくなってきたw ・EMRの事例 1.Razorfish ROAS(広告費用対効果)を500%改善(すげー) 2.So-net ・EMR都市伝説 物理vs仮想 そりゃ、物理が速いよ EMRの柔軟性・拡張性がセールスポイント ビッグデータは成功/失敗が読めないのもあるので、 インフラに投資する部分を少なくできるよ。 オンプレミスが安い? いやいや、HWの購入から設定など時間かかる。 ・Beyond Hadoop HadoopのIn/Out含めてスケーラブル、フレキシビリティが重要 運用管理の仕組みも重要 まだまだやってくよ。 QA Q:EMRは複数サービスから構築してるけど、一部がダウンするとどーなる?(例:SimpleDBが落ちてるとか) A:ジョブはReRunしてもらうか、SimpleDBの状態をみてリカバリをしてもらう。 Q:上記にともない、SLAの計算は? A:SLAはEMRについては定義できてない。S3などはリージョン跨いで Q:S3のセキュリティが心配だが、どう考えてるか? A:いままで脆弱性を晒してデータをロストしてない。 ユーザコントロールなどもできる。基本的には問題ない Q:EMRでS3を使う=Hadoopのローカリティの利点が失われるのでは? A:オーバヘッドはあるが、実際のデータはS3で守られているので、HDFSが飛んでも大丈夫。 Q:S3からのコピーオーバヘッドはどーなるか? A:Single5で少しずつor分割して全部送るも可能 Q:EMRはマルチテナントだけど他のユーザのネットワークの影響を受けないの? A:マルチテナントだと起こる可能性がある。 M1(?)だと内部ネットワークは専有可能らしい。 ◎LT\n・Hadoop and Subsystems in livedoor @tagomoris ピーク時に15Gbps。 10ノード(36コア) CDH3b2を利用 データマイニングではなく、ログからレポーティングをするのに利用している。 hadoop streaming + Hiveで実施 580G/dayが96サーバから来る ScribeにてHadoop Streaming(Perl)でper hourでHiveにload scribelineをWebサーバに入れててログ配送してくれる。 ** ・Lightweight @stanaka(はてなCTO:田中慎司さん)**\nEMR以前 自前20台クラスタ ジョブがあふれてきた ナマMapReduceを利用 PerlでMapper/Reducerを記述(Hadoop Streaming) EMR導入 リソース増やせて便利! 必要な台数に伸縮可能 問題点: S3にアップしないとダメ =>ログデータをS3に展開するlog2s3.plを作成。毎時実行。 起動、ジョブキック、結果改修どーする? =>Net::Amazon::EMR::Wrapperを作成した。 クラスタ起動、ジョブキック、クラスタ停止などできる 作ってみて思ったこと よかったところ: Perlでかける。Cronで実行可能。HiveQL便利。 悪かったところ。 途中で失敗してクラスタ起動しっぱなしとかがある。S3にデータを展開が大変。複雑な計算がきつい。 慣れてないエンジニアにも触れるようにしたい =>Perlで書けるようにした?。 ** ・HBaseでグラフ構造を扱う(開発中):アメーバ鈴木**\n自己紹介@brfrnl69 アメーバのソーシャルグラフ 基本はMySQL マスタ分散が難しい、シャーディング管理が面倒 =>HBaseでやってみるか。 目的 グラフデータに対して高速に更新追加したい。 隣接ノードが取れればいい(これを高速化したい) オンライン処理したい 運用コストの削減したい。 Not目的 マルチホップはどうでもいい。 アーキテクチャ JavaでGatewayつくってみる。 ・Large-Scale Graph Processing:井上さん(@doryokujin)さん Map/Reduceではグラフ計算だめ? Vertex基本だとShuffleに問題ががが。 BSPの紹介 Bulk Synchronous Processing Google Pregel SSSP:MapReduce Model すごい計算時間が掛かりそう。MRの組み合わせが何回回ることやら。 枝が少ないとこっちのほうがいいのか? SSSP:PregelModel シンプルなアルゴリズム Pregel使えるのあるの? Hama GoldenOrb Giraph YERN?YARN? ◎リクルート式Hadoopの使い方:石川(リクルート)\n@ground_beetle ・導入の課題点 バッチ処理時間対策のため。 =>実は入れたかっただけw ・導入の障壁 現行システムへの影響+開発工数 =>これへの対処がこのあとの話 ・課題の克服と活用シーン Azkaban知らなかった。ジョブスケジューリングツール Hadoop単体ではなく、エコシステム(関連ツール)が魅力 ・活用シーン:Hive SQLゆーがざ多く、HiveQLがSQLライクのため導入が簡単に! 既存機能のリプレイス系案件に活躍(低工数+簡単に高速化) とりあえず、Hive実装 =>性能アップのためにMapReduceで書きなおし Hotpepperなどのアトリビューション分析に利用 ・活用シーン:Sqoop+Hive RDBとHadoop連携のツール:Sqoop 現行システムの横にHadoopを配置でき、RDBMSの利点も利用しつつHiveも利用できるようになる。 (※気を付けないといけないけどねぇ。) ゼクシィで活用しようとしてるところ。 ・活用シーン:Mahout マイニング用ツール カーセンサーのレコメンド(同時に閲覧される車種) アソシエーション分析+クラスタリング ・活用シーン:BIツールの導入 何度か導入しようとして失敗してます。。。 BIツールの前処理(クレンジングなど)にHadoopを活用 ・インフラリソースは? 全部で118台。 最小のクラスタ構成はサーバ6台で構成してる ・Hadoopで複数処理を回す方法 ここまで紹介したものを入れてますよ。Hive、Sqoop、Solr。。。 ・Azkaban TomcatにWar配置で利用可能。 LinedInのチームにより作成 ※若干マシントラブルで中断 ・今後のHadoop導入 ログ基盤 分析エンジン・レコメンドエンジンとして バッチ処理短縮=トライアンドエラーが簡単にできるようになる。=色々な気づきが出てくる。 アジャイル的な解析が可能に。 ・開発サイクルの短縮ができるエコシステムでビジネスが回りだす。 ・今後の展開 MapRが気になってる。 マルチテナント対応ができてうはうはできそう。 EMCと共同して検証中 QA: Q:性能監視ツールの選別の理由は? A:Zabbix、Cactiです。今から利用しようと思っている段階。 Q:CDH、GreenPlum、Apacheをそれぞれ利用してるけど、使い分けのシーンは?比較は? A:CDH3u0です。GreenPlumは使ってないです。理由は言うとクビが飛ぶ可能性ががが。 Q:高度なデータ分析ができる技術者はどこからヘッドハントしてるの? A:MITに別途分析チームが存在し、高度な分析をしてくれる。 Q:NameNodeの冗長化はどーやってんの? A:象本と一緒DRBD+HeartBeat Q:EMRの導入を検討してる? A:今後、サーバ数が多くなると導入の検討をしていくと思う。 現時点は、運用ノウハウも入手するために社内で使ってる。 EMRになるかRCloud(リクルート社内クラウド)になるかは不明。 Q:HBaseを利用してる? A:してないです。スペック的にサーバが買ってもらえないと厳しいです。 ◎The history and the future of Hadoop use case at Rakuten:Tarje Marthinussen(楽天)\n・Introduction(self、rakuten) NextGeneration Search Group Norwayから来ましたよ。 ・RakutenのBigDataとは ・Hadoop at rakuten Recommendation(2009) ProductRanking、GenreRanking、Log解析、(2010) Enhance Search。。。(2011) ・PigやHiveのようなものが簡単に利用できるようになってきた ・新しい検索プラットフォームを構築中 index 10k docs/sec search 400qps ・What\u0026#39;s Next Generation Search 20%はインデックスとQuery評価の 50%がデータの前処理(データとQuery) 30%がアナライズ ・Collecting Data? ログの取得はバッチ処理だった。これをStreamingに(Flume) ・Flume Zookeeperを利用してFlumeを管理してる??? ・気になる部分があったので、改善のコーディングしてるよ。 ・セキュリティ マスタで管理できるように ・Pools Agentが送信先がコケてると他のPoolにスイッチ可能に。 ・MasterlessACKs QA Q:パッチ作成は何人でやってるの? A:50人が働いていてOSSコミッターが何人いるかはわからんです。 Q:ログはテキストだけど、パース処理はどこで?(古橋さん) A:Flumeは各ノードでうまい構成になっていて Decorator 性能問題は? HiveはJSONデータをうまく活用できてるよ。 Q:Masterlessとそうじゃないバージョンの性能比は? A:ノード数が増えると Q:HBaseじゃなくてCassandraなの? A:(※英語きつい。。。聞き取れず) ◎マーケティング向け大規模ログ解析事例紹介:原謙治(NTTコミュニケーション)\n・自己紹介 ・BizCITYというクラウドサービスを展開中 まずは、宣伝。 Bizストレージ、Bizマーケティングとして大規模データ、分散処理を実施してる。 ・Hadoop in Bizマーケティング CGMデータを解析して口コミ情報抽出 アクセスログから行動情報抽出 ・Hadoop in BuzzFinder CGM DBからHDFSにインポートして解析開始。DBはPostgreSQL 処理フローは資料参照。 リッチインデクシング技術(NTT研究所が開発した日本語解析技術) ※検索インデックスってどんなものなんだろう? ポジネガ分析気になる。 ・Fast Map-Reduce for PaaS Services アクセス解析やマーケティング解析を行う上でShuffleコストが大きくなるため大量マシンが必要 =>マシン数を減らすことが目的? Map Multi-Reduce、PJoinはNTT研究所が開発した技術!?(子象本にないっけ??) =>Multi-Reduce。同一ノード上のMap出力をReduceすることで、shuffleフェーズに渡るデータを削減している。 =>PJoin QA Q:Map multi-reduce、PJoinはどう実現してるのか?公開するのか? A:Hadoopの0.19に改造をしてる。 公開できるかどうかはわかりません。NTT研究所が研究しているものを試しに実装してみてるから。 なのでパッチにはなりませんかね(研究所に聞いてみないとわからないっす) Q:性能が向上したパターンはあったが、悪化する場合などはあるのか? A:不明 Q:Map-side Joinとの違いは? A:。。。 ※この辺で少し集中力が途切れてしまいました、すみません。(次に集中したかったので。。。) ◎ミクシィにおけるHadoopの利用:伊藤敬彦(mixi)\nLSH-Based Recommendation engine powered by hadoop ・実はmixiの話はすくないよ。 ・利用している環境。5or6台/クラスタ ・Hadoopの活用 ログデータをHDFSに保存 DBコンテンツをHDFSに入れることで、DBに負荷をかけずに解析する。 ・マイニングも検証中 検索クエリログをベースにデータマイニング では、本題。 ・LSHを利用した推薦 ・推薦とは? mixiにはいろいろ推薦(レコメンド)を付加できるサービスがある。 ・推薦するには? 類似インスタンス集合を抽出する。 インスタンスは文書だったりユーザだったり ・類似インスタンスとは? 同じ特徴を持つ集合 例:同一商品購入したユーザとか同一単語を持つ文書とか ・抽出するには? 全ユーザごとに全ユーザとの類似性をチェックすると時間がかかりすぎる! =>LSHを利用しよう! ・LSHについて 特徴: ・速い! ・精度はそれほどではない 事例: ・Google Newsのレコメンド(USロケール) ・LSHの処理ステップ 2つだけ。 1.インスタンスベクトルを計算(似ているデータは同じ値が返りやすい関数) 2.同一値が帰ってきたデータが類似インスタンス ・インスタンスベクトル例(あとでスライド見ようね) ・Likelikeがいち実装。Hadoopでうごくよ ・実験について トップページに表示されていない記事を知ってもらうために推薦してみるぞ! ・実験1 性能を測ってみた ・実験2 精度を調べてみた。 精度はほんとにひどいな。。。 =>同一カテゴリの遷移を元に計算したらそれなりになってきた。 ・今後 データソースを増やしたい。 他のアルゴリズムも実装したい ・CM 以下も作ってますよ。 Oluolu Anuenue QA Q:Mahoutは使わないんですか? A:Likelikeを作った頃にMahoutになかったので作った。 性能比較したいと思ってる。 Q:ログサーバのデータ転送はどーやってる? A:伊藤さんのところにはどういう仕組みかは上がって来てない。 Q:ベクトルの次元数はどのくらいまで耐えられる? A:高次元のデータに対して耐えられるように作られてる。 次元数が低くて良い制度が欲しければ他のアルゴリズムがいいかも。 Q:ユーザのベクトルを作るテクニックは? A:画像などであれば大変だけど、ユーザであれば、単語とかキーワードとかで Q:ニュース以外のデータは? A:まだまだ実験中。まだやってない。 Q:推薦される記事数のばらつきはどういった理由が考えられる? A:後ほど考察してQAサイトに入れます。 Q:LSHをMapReduceに載せたということだけど、関数の計算をさせてる? A:Iterationはしてない。 Map側でLSH関数計算してる。Reduceにて類似インスタンスを導出してる。 Q:今後の予定の空間木とは?R-Treeだと高次元できついのでは? A:低次元にて利用できるように用意したい。 Q:HamaとかGiraphで高速化させてみるのはどう? A:イテレーションがいらないからあまり利用用途がないかなぁ。 ◎懇親会\nAWSを採用しない企業がいくつかあったのでそのあたりを質問してみた。 AWSは通常運用に利用すると結構なコストがかかる場合があるので、ノウハウがある企業や データ量が多い場合は、オンプレミスの場合を選択しているらしい。 やはりスポットで利用する方がお得感があるみたいだった。 Twitter上だけの知り合いだった方々と面識が持てたのが一番の収穫でした。 感想+調べること\n感想\n会場規模とかQAサイトとかオープニングムービーとかすごかったです。しかも無料。さすがリクルートさん。 ランチボックスとか出てきたし。装飾もとても無料のカンファレンスと思えない出来でした。 午前中はHadoopをもとにした各社の戦略とCMという感じが色濃かったです。少しずつ各社の立ち位置が違いそれはそれで面白かったです。 AWSの説明を聞いてやはりAWSを扱える技術は必要だと再認識。 お金かけないで触ってみれるレベルでまずは触ってみるかなぁ。 洗脳されてるのかもしれないけど、自社or自前でHadoop運用するのは厳しそうです。(懇親会ですこし認識が変わった) カフェコーナーでは、リクルートのMITの冊子が配られていたり、映像や案内に使われていたHadoopマスコットのシールが配られていたりと小技も聞いてました。 あと、オライリーの販売コーナーも用意されていて、思わず子象本を買ってしまう罠にはまったりもしましたが。。。 mixiの伊藤さんの話は最後で疲れていたのですが、ストーリーが上手くできていて、実験や事例もあったのでわかりやすかったです。 Hadoopはエコシステムと呼ばれるHadoopを活用するツール群(Hiveの話が多かった?)、Hadoopの今後、Hadoopを活用したログ解析の話など、 話題が豊富でそれぞれの話が面白くて困ってしいまうくらいです。 いくつかのセッションで出てきたのですが、アクセスログなどをHDFS上に集めるための仕組みがまだ乱立(定番がまだない)している感じを受けました。 Flume、Scribe、MapR。。。などなど あとは、テクニカルセッションのビデオがアップされたらまた目を通さないと。。。 残念ながらHadoopから少し縁遠くなっていますが、これからもネタや参考になりそうな話には事欠かなそうなのでかじりついていこうと思います。 ※一番やらないといけないのは英語の勉強かもしれないです。。。 調べること 一応Solrの人なので、Solrに関連しそうな話に興味がいってしまいます。\nNTT研究所のリッチインデクシング技術 やっぱりAWS触ってみる。EMRまでとは言わないが。(herokuもちょっと興味あるが。) Mesos、GreenPlum、Scribe、Storm、Flume、Giraphこれらの概要 関連サイト 公式QAサイト。後日録画していたセッションがアップされるそうです Hadoop Conferene Japan Fall 2011 - 急がば回れ、選ぶなら近道 Hadoopカンファレンスが開催、本格普及を見据えた支援サービスや先進事例が充実 - ニュース:ITpro Hadoop Conference Japan 2011 fallで使用された資料 #hcj11f | インフラエンジニアのつぶやき(スライドをまとめてくれてます。)\n","date":1317113460,"dir":"post/2011/","id":"97402287d8c6c03f0b63848e17e9d944","lang":"ja","lastmod":1317113460,"permalink":"https://blog.johtani.info/blog/2011/09/27/hadoop-conference-japan-2011-fall%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%A6%E3%81%8D%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-09-27T17:51:00+09:00","summary":"Hadoop Conference Japan 2011 Fallに行ってきました。 まずは、ユーザ会の方々、運営の方々、発表された方々お疲れ様でした。こんな機会を用意していただき、ありがとう","tags":["hadoop"],"title":"Hadoop Conference Japan 2011 Fallに参加してきました。(Jugemより移植)"},{"contents":"台風15号すごかったですね。幸いにも(?)夏休みだったので、通勤などでひどい目に合わずにすみました。 風雨はすごくてちょっと怖かったですが。。。\nさて、夏休みに進める予定が、子供の寝かしつけで一緒に寝てしまう日が続いてしまい、 間が開いてしまいました。\n0日目というタイトルになっているのは、まだ、1日目に入ってないからです。。。 Ioという未知の言語をMBAにそのままインストールするのも抵抗があり、VirtualBox上にLinuxをインストールしてから 進めようとして思いの外手こずってしまったためです。 ということで、0日目として、VirtualBox上にScientific Linux 6.1をインストールしてIoのインストールまでではまった箇所を記録として残しておきます。\n罠その1 罠と言うよりは、私の無知に関する部類なのですが。。。 Scientific Linux 6.1のインストールは特に手こずることなくインストールでき、 起動も出来ました。 次にscpコマンドでダウンロードしてきたIoのソースをLinuxに渡そうとしてはまりました。 問題となったのはネットワーク接続が「NAT」のみだったため。 NATのため、Linux(ゲストOS)から外部への接続は可能だったのですが、Mac(ホストOS)からLinux(ゲストOS)への接続ができませんでした。 で、変更したのは以下の2点。\nVirtualBoxの環境設定-\u0026gt;ネットワーク-\u0026gt;ホストオンリーネットワークの追加 仮想マシン(Linux)の設定-\u0026gt;ネットワーク-\u0026gt;アダプタ2を有効にしてホストオンリーアダプタを割り当て 1番目のホストオンリーネットワークの追加をしておかないと、2番目のアダプタ2でホストオンリーアダプタを選択したときにエラーが出て、設定ができませんでした。割り当てるべきアダプタを先に用意しとかないとダメですよね、そりゃあ。\n罠その2 これも罠というほどではないのですが。。。 Ioのビルドにはcmakeが必要なのですが、Scientific Linux 6.1に入っているcmakeはバージョンが古い(2.6.4)ため、必要なバージョン(2.8以上)をインストールしないとダメでした。 インストール自体はcmakeのサイトにある手順通りのため割愛します。\n罠その3 これもちゃんとドキュメント読めよというレベルですが。。。 Ioのインストールは以下のコマンドを実行するという話です。 私がcmakeについて知らなかったと言われればそれまで。。。\n$ cd io $ mkdir build \u0026amp;amp;\u0026amp;amp; cd build $ ccmake .. $ make $ sudo make install 3つ目の「ccmake」の部分がIoのGetting Startedの下の方にありました。上の方に記載がある「cmake」ではエラーがでてうまく行かなかったので。 IoのGetting Startedにもありますが、ccmakeの場合はCUI上にGUIのようなものが起動するので、「c」(configure)と実行後、「g」(generate)を実行して最後に「e」(exit)でccmakeを離れます。 するとmakeが実行できるようになりました。\nあとは、/etc/ld.so.conf.d/io.confファイルを作成し、「/usr/local/lib」と記述。ldconfigを実行することで、Ioが実行可能になります。 ということで、1日目に入れず終了。。。\n明日は出来るかなぁ。\n","date":1316716440,"dir":"post/2011/","id":"62f31128a21b0e240bdb7b3d5b121c04","lang":"ja","lastmod":1316716440,"permalink":"https://blog.johtani.info/blog/2011/09/23/7%E3%81%A4%E3%81%AE%E8%A8%80%E8%AA%9E-7%E3%81%A4%E3%81%AE%E4%B8%96%E7%95%8C-io-0%E6%97%A5%E7%9B%AE/","publishdate":"2011-09-23T03:34:00+09:00","summary":"台風15号すごかったですね。幸いにも(?)夏休みだったので、通勤などでひどい目に合わずにすみました。 風雨はすごくてちょっと怖かったですが。。","tags":["読書"],"title":"「7つの言語 7つの世界」 Io 0日目(Jugemより移植)"},{"contents":"Solr/Lucene 3.4がリリースされました。(速報)\n以下、各サイトへのリンクです。\nSolrリリースのお知らせ\nLuceneリリースのお知らせ\nちなみに、先日のSolr勉強会で関口さんが話されていたインデックスが壊れるバグですが、 先日のアメリカのハリケーン(Irene)で実際に電源が落ちて見つかったみたいです。\nということで、3.4がリリースされたので、3.1~3.3は利用しないほうがいいようです。\n追記: lucidimagination.jpのサイトに日本語のリリースノートが公開されていたので、リンクを記載しておきます。\n","date":1316046660,"dir":"post/2011/","id":"54da1b916f49ef40c822fab61d37cf66","lang":"ja","lastmod":1316046660,"permalink":"https://blog.johtani.info/blog/2011/09/15/lucene-solr-3-4%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E9%80%9F%E5%A0%B1/","publishdate":"2011-09-15T09:31:00+09:00","summary":"Solr/Lucene 3.4がリリースされました。(速報) 以下、各サイトへのリンクです。 Solrリリースのお知らせ Luceneリリースのお知らせ ちなみに、先日の","tags":["solr"],"title":"Lucene/Solr 3.4リリース(速報)(Jugemより移植)"},{"contents":"ということで、Rubyの最終日の感想。 今回もセルフスタディの私の回答が最後の方に記載されてます。見たくない人は気をつけてください。 ツッコミ大募集です。コメント欄にどしどしコメントください。そこは違うだろ?こっちのほうがいいのでは?という感じで。\n感想: ◎メタプログラミングが特徴 例:ActiveRecordのhas_many、has_oneがいい例\n◎オープンクラス クラス定義をいつでも変更可能。 あらゆるクラスやオブジェクトをいつでも再定義できる 書きやすいコードのために再定義が可能=何でもできるが気を付ける必要あり。 DSLの定義に便利。 確かに便利。ただ、範囲を限定しないと予期せぬ場所で問題が発生しそう。 ※解析するための手段はいいのがあるのかな?=\u0026gt;method_missingみたい\n◎method_missing 対象メソッドが見つからない場合に最後に実行されるメソッド 通常はNoMethodErrorが発行される。\n◎モジュールによるメタプログラミング defやattr_accessorなどその一例。 DSLではモジュール内にメソッドを定義してメソッド+定数を利用 ActsAs\u0026hellip;ってそういう意味合いだったのか。 親クラスバージョン、親クラス+マクロ、モジュールそれぞれの実装の仕方の紹介。 ※マクロもinclude同様、実行順で、メソッドの上書きが発生するのか? ActiveRecordではメタプログラミングを利用してDBのカラム名からアクセサを追加。 シンタックスの美しさ=読みやすさ\n感想&疑問点: メタプログラミングはフレームワークを作成するのが便利そう。 ただし、エラーや問題が起きた時の対処をきちんと準備しておかないとひどい目に合いそう。 クラスやモジュールはわかりやすい単位で1ファイルにまとめるもの? ファイル名の規則とかあったりする? ディレクトリ構成でパッケージ構成が可能? 複数のモジュール(gemとか)を組み合わせて使っている場合にincludeの順序がどのようになるかが気になる。 予期せぬ順序でincludeされて利用しようと思ったメソッドがオーバーライドされてるとかありそう。 追っかけるのがまた大変そうだ。 異なるパフォーマンス(開発者の開発速度)の観点が一番おもしろかった。ただ、なれるまでは大変そう。すんなりinjectとかコードブロックをうまく利用するイメージがわかない。 まぁ、思考については反復練習かな。これは他の言語でも一緒かな\nようやく、Rubyの世界が終わりました。楽しかった。次は未知の言語である「Io」です。\n(試してみよう:) ○eachメソッドがCsvRowオブジェクトを返すようにCSVアプリケーションを変更せよ。そのCsvRowのmethod_mmissingを使って、与えられた見出しの列の値を返すようにせよ。 モジュールにて実装してみた。 ``` module ActsAsCsv\ndef self.included(base) base.extend ClassMethods end module ClassMethods def acts_as_csv include InstanceMethods end end\nmodule InstanceMethods\ndef read @csv_rows = [] file = File.new(self.class.to_s.downcase + '.txt') headers = file.gets.chomp.split(', ') file.each do |row| @csv_rows \u0026lt;\u0026lt; CsvRow.new(headers,row.chomp.split(', ')) end end def each(\u0026amp;block) csv_rows.each(\u0026amp;block) end attr_accessor :csv_rows def initialize read end end\nclass CsvRow def initialize(headers, csv_contents) @headers = headers @csv_contents = csv_contents end\nattr_accessor :headers, :csv_contents def method_missing name, *args csv_contents.fetch(headers.find_index(name.to_s)) end end end\nここまでが実装したモジュール+クラス。 以下は実行例。id,name,sizeというheaderをもつCSVを使ってみた。 require \u0026lsquo;acts_as_csv_module_mod.rb\u0026rsquo; =\u0026gt; true class RubyCsv include ActsAsCsv acts_as_csv end =\u0026gt; RubyCsv csv = RubyCsv.new =\u0026gt; #\u0026lt;RubyCsv:0x103c4c530 @csv_rows=[#\u0026lt;ActsAsCsv::CsvRow:0x103c4c030 @csv_contents=[\u0026ldquo;1\u0026rdquo;, \u0026ldquo;RubyCsv.class\u0026rdquo;, \u0026ldquo;20\u0026rdquo;], @headers=[\u0026ldquo;id\u0026rdquo;, \u0026ldquo;name\u0026rdquo;, \u0026ldquo;size\u0026rdquo;]\u0026gt;, #\u0026lt;ActsAsCsv::CsvRow:0x103c4be78 @csv_contents=[\u0026ldquo;2\u0026rdquo;, \u0026ldquo;JRubyCsv.class\u0026rdquo;, \u0026ldquo;50\u0026rdquo;], @headers=[\u0026ldquo;id\u0026rdquo;, \u0026ldquo;name\u0026rdquo;, \u0026ldquo;size\u0026rdquo;]\u0026gt;]\u0026gt; csv.each {|row| puts row.name} RubyCsv.class JRubyCsv.class =\u0026gt; [#\u0026lt;ActsAsCsv::CsvRow:0x103c4c030 @csv_contents=[\u0026ldquo;1\u0026rdquo;, \u0026ldquo;RubyCsv.class\u0026rdquo;, \u0026ldquo;20\u0026rdquo;], @headers=[\u0026ldquo;id\u0026rdquo;, \u0026ldquo;name\u0026rdquo;, \u0026ldquo;size\u0026rdquo;]\u0026gt;, #\u0026lt;ActsAsCsv::CsvRow:0x103c4be78 @csv_contents=[\u0026ldquo;2\u0026rdquo;, \u0026ldquo;JRubyCsv.class\u0026rdquo;, \u0026ldquo;50\u0026rdquo;], @headers=[\u0026ldquo;id\u0026rdquo;, \u0026ldquo;name\u0026rdquo;, \u0026ldquo;size\u0026rdquo;]\u0026gt;] csv.each {|row| puts row.id} (irb):8: warning: Object#id will be deprecated; use Object#object_id 2179096600 (irb):8: warning: Object#id will be deprecated; use Object#object_id 2179096380 =\u0026gt; [#\u0026lt;ActsAsCsv::CsvRow:0x103c4c030 @csv_contents=[\u0026ldquo;1\u0026rdquo;, \u0026ldquo;RubyCsv.class\u0026rdquo;, \u0026ldquo;20\u0026rdquo;], @headers=[\u0026ldquo;id\u0026rdquo;, \u0026ldquo;name\u0026rdquo;, \u0026ldquo;size\u0026rdquo;]\u0026gt;, #\u0026lt;ActsAsCsv::CsvRow:0x103c4be78 @csv_contents=[\u0026ldquo;2\u0026rdquo;, \u0026ldquo;JRubyCsv.class\u0026rdquo;, \u0026ldquo;50\u0026rdquo;], @headers=[\u0026ldquo;id\u0026rdquo;, \u0026ldquo;name\u0026rdquo;, \u0026ldquo;size\u0026rdquo;]\u0026gt;]\n\u0026lt;span style=\u0026#34;color:#FF0000\u0026#34;\u0026gt;※idというcsvフィールド名にしたら、object_idとかぶっているようでwarningが出てしまった。\u0026lt;/span\u0026gt; CsvRowクラスの定義がモジュールの中に入っているが、この実装でも動くみたい。ただ、パッケージみたいな感じ7日までは調査してない。。。 ","date":1315992060,"dir":"post/2011/","id":"41b811063b9425de1934e77d89118022","lang":"ja","lastmod":1315992060,"permalink":"https://blog.johtani.info/blog/2011/09/14/7%E3%81%A4%E3%81%AE%E8%A8%80%E8%AA%9E-7%E3%81%A4%E3%81%AE%E4%B8%96%E7%95%8C-ruby-3%E6%97%A5%E7%9B%AE%E6%9C%80%E7%B5%82%E6%97%A5/","publishdate":"2011-09-14T18:21:00+09:00","summary":"ということで、Rubyの最終日の感想。 今回もセルフスタディの私の回答が最後の方に記載されてます。見たくない人は気をつけてください。 ツッコミ大","tags":["読書"],"title":"「7つの言語 7つの世界」 Ruby 3日目(最終日)(Jugemより移植)"},{"contents":"「第6回Solr勉強会」に参加しました。 なんだかんだと第6回で、今のところ皆勤賞です。\nということで、主に自分用ですが、メモなどとったので。\n概要\n日時 :2011/09/12 19:00 to 21:00 定員 :110 人 会場 :株式会社 ECナビ 1.「Lucene/Solr 3.2-3.4」 by ロンウイット 関口 宏司さん ※Solr2.9.4、3.1でデグレードし、Solr3.4で修正されたバグがあります。 インデックス中にPCがシャットダウンされた場合にインデックスが壊れてしまうものあり。 Solr3.1-3.3は使用しないようにとのこと。 ○index ・IndexWriter.addDocuments(docs) 複数ドキュメントの更新が可能になった。 ※検索で話をする親子関係のNestedQuery向けの登録にも利用する。 この登録では途中でフラッシュされないため、セグメントが分割されない特徴あり。 複数だけでなく、 ・TieredMergePolicy ※Lucene3.2/Solr3.3からデフォルトになった。 新しいインデックスのマージポリシー。(amebaの開発者ブログに説明があった。) インデックスの登録順が守られていたが、このマージ処理では保証がされなくなったので注意が必要。 ・update.chain update.processorがdeprecatedに。 update.chainというパラメータに変更 ○index(cont\u0026#39;d) ・TwoPhaseCommit ・UniqFieldsUpdateProcessor 重複した値を削除するための機能。 UIMAでの提案から取り込まれた ○search ・group=on 検索グルーピング機能を使えるパラメータ ・{!term} クエリパーサを通さないでTermQueryをかける機能。 ・structured explanation debug=onの算出根拠を XMLタグで構造化されたExplanationが取得可能に ・ReloadCacheRequestHandler 関口さん担当。ExternalFileField インデックス外(外部ファイル)を元にFunctionQueryの情報を利用可能にできるのだが、 このファイルのリロードが可能になる。 ・Carrot2 3.5.0 アップグレード。 デモあり。Carrot2のworkbenchとか ○search(cont\u0026#39;d) ・hl.phraseLimit parameter FastVectorHighlighterの高速化用パラメータ。 ・{!cache=false} キャッシュを利用しないためのローカルパラメータ。fqのローカルパラメータに利用可能。 検索セッション内でキャッシュへの処理(参照・登録)をしなくなる ・BlockJoinQuery NestedDocumentQueryの名前が変更された。 (Luceneで登録されたところまで。) ○schema ・KStemFilter PoterStemmerとは別のstemmer ・ReversePathHierarchyTokenizer パスの構造化インデックスの逆バージョン ・ommitPositions=\u0026#34;true\u0026#34; 指定が可能になった。 ・version 1.4 スキーマのバージョンが新しくなった。 ○admin/tools ・action=MERGEINDEXES\u0026amp;srcCore=coreName コア名指定可能。 ・action=UNLOAD\u0026amp;deleteIndex=true UNLOAD時にインデックス削除 ・action=CREATE\u0026amp;property.name ※ぎゃーーー。打ち込み失敗。 ○ぎゃーーーー失敗。 ○技術者大募集中!! Q\u0026amp;A Q:クラスタリングの日本語は大丈夫?入門には制限があると記載があったが。 A:analyzerが記載が簡単になってるかは不明 前処理をして別フィールドにメタデータ的にある程度単語で区切ったようなものを作成したほうがいい。 Q:グルーピングで、グルーピング後のファセット件数が取得可能か? A:3.4ではグループ数で表示可能。 パラメータ指定で可能。 2.「Solr@cookpad」 by @PENGUINANA_ さん ○COOKPADとは? ・レシピ投稿サイト ・105万のユーザのレシピ ・30代女性の1/2が利用 ○レシピ検索 ・PC:1307万UU、1億回強/月 ・モバイルで利用が多く、スーパの店頭などで利用? ・Androidもあるよ。 ○人気順検索(Solrですよ) ○自己紹介 ・@PNGUINANA_ ・情報可視化+検索が好き!! yats、など ○Solrはどのように利用 ・レシピ検索 ・もしかして ○Tritonnから移行 同じ検索結果になるようにして徐々に移行 ○なぜ? パフォーマンスが良い。 フィールド追加が簡単 レプリケーション-\u0026gt;ファイルベース プロトタイピングが楽 ○Solr4 nightly(on Oracle JVM) ・マルチコア利用 ・Ruby on Railsから ○簡単な構成+説明 ・バッチからSolrへの更新をしている。 ※Analyzerを利用せず、バッチ側で分かち書き、正規化、同義語展開を行っている。 Rubyで全部かけるほうが社内に展開しやすい。 ・バッチ終了後、可能ならoptimize ※検索速度がmax20%高速になる。 ・マスタ-\u0026gt;スレーブレプリケーションはschema.xmlもレプリケート 新規フィールド追加などはレプリケーションだけで実行できて楽。 ・アプリはMySQLとSolrのSlaveにアクセス。 Solrにはidのみ。本文はMySQLから取得 インデックスサイズを小さくできる=レプリケーション時間が短くなる オンメモリにできるため検索速度も向上 ○監視(munin) ・監視項目(コア別): クエリ:QTime/QPS キャッシュ:hit/eviction キャッシュから漏れている数をみてキャッシュサイズを定期的に変更して無駄をなくす インデックス:サイズ/docの数 運用してから重要。開始当初は気にしてるが、そのうち気にならなくなるため。 レプリケーション:所要時間 スレーブ間でのズレを検知するため。 ※コアごとに監視することで、問題点を把握しやすくしている。 ○監視(nagios) ・監視項目(コア別): サーバの基本的なヘルスチェック Solrが動いてるサーバのはなし。 レプリ:インデックスバージョンのチェック ズレが長いとメールが飛ぶ ○便利だった機能 ・DynamicField フィールドをあとから簡単に追加可能。 例:人気順のアルゴリズムの違うフィールド。検索用フィールド ・FacetQuery 絞り込み検索をクエリで記載可能。 現時点では社内向け検索機能で利用。 ※ファセットで簡単な解析もやってる。 例:鍋の季節ごとの登録件数。 ・HTTP経由で色々可能 検索の並列化 通常検索画面:3クエリを同時実行 あるプロトタイプ画面だと8クエリで実行したりしてる。 ・分散検索(Distributed Search) 簡単にsharding可能 思いクエリは4shardで投げる オーバヘッドが大きいので思いクエリにだけ利用しているらしい。 ○開発の流れ ・まずはステージングを更新 ・問題なければマスターも更新 例外: フィールド追加するだけだったら直接マスタへ 例:ファセット追加など。 ○パフォーマンスとか大丈夫? 本番で複数のバージョンを持っており、 バグっていても自動フォールバックするらしい。 価値があったらパフォーマンス向上+テスト追加 例:スニペット変更 ○気になっている機能 ・not to cache(SOLR-2429) ・SurroundQuery(Solr-2703) ・JOIN(SOLR-2272) SQLのJOINなイメージ ・BloomFilter(SOLR-1375) 単語が存在するかどうかのチェック ○Solr入門おすすめ ○おすすめ ・http://blog.sematext.com 月一で新機能が出てくる ・SolrのJIRA ・@otisg ○今後やりたいこと ・わかち書きの精度向上 ・検索セッションの分析 nDCG、クエリ分類、検索意図 ・デバイス対応 ・パーソナライズ Q\u0026amp;A Q:同義語は誰が集めている? A:外部辞書を利用。0件キーワードから解析して取得 単語登録も一緒。 Q:プチトマトとトマトの違いはどうやってる? A:上位、下位の概念で同義語を利用している。 本にあるよ。 Q:もしかしてはSolrの機能? A:Solrではない。訂正候補の単語をSolrに検索してからチェックして表示する。 Q:人気順はどういった計算をしてるんですか?計算してから登録?By 大谷 A:1フィールドに外から入れている。 Q:RubyからSolrの利用方法は?独自?ライブラリ?By 大谷 A:Rsolrを利用しており、コネクション管理にだけ利用している。 あとは、ラッパーを独自で作成。 Q:4.0を利用している理由は?なかなかチャレンジャー。By関口 A:グループクエリを利用したかったため。 実際には重くて使えていない。 今は必要ないかもと思っている。年始のバージョンを利用。いつでも入れ替え可能。 マスタスレーブ構成のsolrのバージョンアップはサービスアウトしてから入れ替える。 3. 「Solrを用いた検索システムの構築」 by データセクション株式会社 高井さん いろいろな試行錯誤について ○データセクションについて 言語処理を元にデータの解析(Twitterとかブログとか)している会社。 ・昔は自社で検索サーバを構築していた ・Luceneを利用して検索サーバを構築するように変更。 ○構成(過去?) ・Lucene+RMI 3.0から縮小で、4.0で廃止に ○SolrにするかLuceneにするか? ・いろいろ機能があるからSolr使ってみるかw ○Solr導入は1.4.1から スペック マスタ: メモリ:16G Disk:2Tx12 スレーブ: 256GのSSDを利用 JavaVMが32bit ○ひと月分を1shardにして登録 ○検証+手探り? メモリが足りない。 Solrのキャッシュを全Offに。 BOBO SolrPluginってのを利用 compressオプションも利用。 各スレーブにキューを用意して1つだけしか処理しない。(なんでだ??) ○結果 キャッシュはフィルタキャッシュのみ利用 ユーザが同じクエリを投げるのはほぼないので。 フィルタキャッシュのエントリのメモリ量の計算式(あとで資料が出てくるかなぁ。) ○問題点 ・レプリケーションでインデックスサイズの2倍の容量が必要になる。 ・レプリケーションの日時フォーマットのバグ(SOLR-1995)を踏んでしまった。 ・レプリケーション後にインデックスが消えない場合がある ○検討(1.4.1-\u0026gt;3.2) うれしい要素 レプリケーションバグがfix 省メモリや範囲検索の高速化など かなしい要素 compressが使えなく(しかも回答してからriindexしてくれる) ○検討 余計なインデックス消す nearinfinityが出しているlucene-compressionを利用 https://github.com/nearinfinity/lucene-compression ○残った問題 facet.rangeが使えないなど。 ○じゃあ集約サーバつくっちゃえ(すごいな。) facet書き換えコンポーネントなど。 ○シャードのインデックスサイズが下がった 130GiB-\u0026gt;90GiB これはlucene-compressionの効果 ○ここまでの変更はプラグインにて対応(この一覧いいかも) ○感想 コンポーネント化されてて、簡単に追加機能が実装可能 用途次第であまりスペック高くなくても使える。 Q\u0026amp;A Q:Twitterのデータのクロール方法は? A:HTMLをスクレイピングしている。publicなTLのみ。 Q:いきなりSolrに入れる?Solrの前処理は? A:SolrJを利用して前処理済みのデータを登録している。 4. 「Anuenueの紹介と最近の進捗」 by @takahi_i さん(mixi) ○自己紹介 ・NAIST出身 ・ファストサーチ ・今はmixi ○mixiとは? ○社内の緊急タスク ・内製検索エンジンをメンテナンスしやすいOSSにしたい! -\u0026gt;Solrを選択 Anuenueも実装 ○Anuenueの作成理由は? インデックス運用が面倒(検索(distributed search)はあるがインデックスは自前) クラスタ用のコマンドが提供されていない。 ○Anuenueが提供する機能 ・検索クラスタの簡単設定 ・クラスタ用コマンド ・もしかして機能 ○機能:Anuenueのクラスタ設定 Merger:クライアントからのクエリをMasterに分散 Master:インデックス作成側 Slave:検索用スレーブ。マスタからコピー ○クラスタの管理コマンド クラスタのコマンドを用意。 起動、コミット、登録など ○SolrCloud向けのAnuenueを検討中 branch-cloudにあります。 今後の予定 インスタンス追加削除を動的に実行できるようにしたい ○Hadoop Conferenceの宣伝w Oluolu:Hadoop上で動くクエリログマイニングツール Likelike:LSHをHadoopで実装(Hadoop Conference 2011 Fallで発表) 5. LT 5.1 「solrとRの連携について」 by @yutakashino さん(BakFoo) Python本、Zope本を書いてます。 ○NHKの実証実験で利用? ○TwitterストリームをSolrにストア facet.date ○Rでキーワード頻度グラフ Node.js、Redis、R、Solrを使ってる。しかもPython ○デモ キーワード+日付でグラフが出てくる。 Rでプロット。 GoogleのチャートAPIを利用すると面白いことができる。 5.2 「 Apache ManifoldCF」 by 阿部さん(ロンウィット) ○Apache Incubator ○Manifold Connector Framework Solr <- MCF <- web+non-web repositories すぐに利用可能。 ○概要 出力はSolr。 接続先はWeb、DB、CMS、などなどいろいろRepositoryConnectorというのがあります。 ○Crawler Agent クロールに関するJobの管理 接続先、スケジュールなど ○Windowsサーバのクロールもできる 社内のナレッジ共有などに使える。権限周りも簡単に対応可能。 JCIFS.jarによりWindowsの権限情報を取得 ○クロール設定画面もある デモ ○導入が簡単なのがおすすめ。 ○ManifoldCFの資料関連 http://www.manning.com/wright 懇親会についてはあとで記載します!! ということで追記です。 懇親会でも色々と面白い話を聞けました。 @PENGUINANA_さんにはCOOKPADのCI関連の話を聞けました。 1日に数度リリースするという話もあるようでした。\nあとは、Rについても@yutakashinoさんから概要が聞けたのが良かったです。\nちょっとだけ追記。まだ成形する予定ですが、とりあえず。\n追記:スライドが公開され始めたので。\n関口さんのスライドはこちら 阿部さんのスライドはこちら @PENGUINANA_さんのスライドはこちら。 @takahi_iさんのスライドはこちらからPDFダウンロード可能。\nその他に関連するブログも見つけましたので。 「Solr@Cookpad」- Solr勉強会で発表してきました Ars longa, vita brevis: 第6回 Solr 勉強会に行ってきた\n勉強会で出てきた各製品などのリンク: 色々とURLが出てきていたので、リンクをまとめておきます。\nlucene-compression Anuenue Apache Solr のラッパー Likelike LSH (Localtiy Sensitive Hashing)の実装 OluOlu 検索ログマイニングツール @takahi_iさんのLuceneRevolution2011のスライド Kuromoji 形態素解析器 lucene-gosen 形態素解析器(Senの後継) Apache ManifoldCF ","date":1315810980,"dir":"post/2011/","id":"37b622eaad1f79e759a722aacebf48ec","lang":"ja","lastmod":1315810980,"permalink":"https://blog.johtani.info/blog/2011/09/12/%E7%AC%AC6%E5%9B%9Esolr%E5%8B%89%E5%BC%B7%E4%BC%9A%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-09-12T16:03:00+09:00","summary":"「第6回Solr勉強会」に参加しました。 なんだかんだと第6回で、今のところ皆勤賞です。 ということで、主に自分用ですが、メモなどとったので。 概","tags":["勉強会"],"title":"第6回Solr勉強会に参加しました。(Jugemより移植)"},{"contents":"ということで、Ruby2日目の感想(2日目だけで2日間かかったのは内緒。。。) 今回もセルフスタディの私の回答が最後の方に記載されてます。見たくない人は気をつけてください。 ツッコミ大募集です。コメント欄にどしどしコメントください。そこは違うだろ?こっちのほうがいいのでは?という感じで。\n感想: ◎関数の定義:ありゃ、利用するのはダメなんだ、これじゃ。\u0026ndash;\u0026gt;単なるタイプミスでした。お恥ずかしい。。。 \u0026gt;\u0026gt; def tell_the_truth \u0026gt;\u0026gt; true \u0026gt;\u0026gt; end =\u0026gt; nil \u0026gt;\u0026gt; tell_the_trueth() NoMethodError: undefined method `tell_the_trueth\u0026#39; for main:Object from (irb):4 ◎配列:そしてシンタックスシュガー puts animalsで内容が出力されるのはうれしい。JavaだとHashCodeが出てくるから。出力メソッド書かないといけなくなる。 animals[-1]で最後の要素とかかなり便利。 animals[0..1]はRangeクラスを利用する形。Rangeはやはり便利。substringなどもできそう。 カラ配列の定義は必要。a = [] 1.9と1.8でinclude?の書き方が異なるので注意! 配列(Array)クラスは中はObjectが入る。 多次元配列もOK。popやpushでキューとしても利用可能。\n◎ハッシュ: Mapのようなもの。任意のキーが利用可能。:付きの文字列はシンボルと呼ばれる定数値を簡単に定義する方法。 object_idという属性?関数によりObjectのハッシュコードが取れるらしい。 ブレース=「{}」のカッコのこと。do~endでも代用可能\n◎コードブロックとyeild コードブロック=名前なし関数。習慣では複数行の場合、do/endで、1行は{}みたい。Javaと混同しそう。 コードブロックは引数も指定可能。 「yield」予約語?を利用してコードブロック自体をメソッド内部などで呼び出し可能。 ということで、コードブロックは引数にも指定できると。コードブロック=関数もObjectとして扱われてる感じか? 実行遅延、分岐、共通関数とか?Javaだとabstractメソッドを利用して処理するようなイメージか?ちょっと違うなぁ。 なれると、yieldはコードを読みやすくできそう。また、シンタックスハイライトしてくれるツールがあれば、更に便利。\n◎ファイルの実行 ruby ファイル名 vi、Emacs、TextMateなどがあるよ。\n◎クラスの定義 ※数字で始まる変数は利用できない!Javaと一緒 Tree.rbとログを参考にすること。 \u0026amp;使うとブロックに名前が付けられる。yieldじゃなくてもいい? クラス名はキャメルケース。 変数とメソッド名は「_」アンダーバーつなぎ インスタンス変数の頭は@ クラス変数は@@ 定数は大文字 ※メソッド名、変数名には違和感が。なんでこんな規則?? 判定用関数とメソッドには「?」(if test?)をつける!!Javaでいう「is」か。\n◎Mixin(多重継承?モジュールと呼ばれるものを利用) 多重継承のような類似の振る舞いを伝搬する仕組み。 Javaではインタフェースでやること。 Rubyではモジュールといい、関数と定数の集まり。 クラスに機能を盛り込む場合はincludeする ※複数includeして、includeしたものの中に同じメソッドとかあったらどーなる? \u0026ndash;\u0026gt;Overrideされた=includeがあとにあるもので上書きされる Abstractにできないものをモジュール化できるの楽。 javaだとstaticメソッドだらけのUtilクラスを別途起こすイメージだけど、内部で呼ばれるメソッド(コードブロック)が同じインタフェースじゃないと行けないから、インタフェースの記述もしないと行けない。 ただし、同一名のメソッドを持ってるとややこしそう。 ※モジュールからモジュールは呼べる?\n◎モジュール、Enumerable、セット EnumerableとComparable(JavaのCollectionまわりかな。) 宇宙船演算子(\u0026lt;=\u0026gt;)Javaのequalsに似てる any?とかCollectionUtils??に似たのあったな。 ※今利用しているクラスが何をincludeしてるかってのは分かる仕組みあるのかな? ※そういえば、メソッドごとに戻り値があるが、全部newされてインスタンス化されてGCの対象になってるのか?irbだけ? injectはすんなり使うイメージが出にくそう。また、ソースをぱっと見て理解出来ない。なれだろうけど。 ※injectしながらinjectとかあるんだろうな。\n(探してみよう:) ○コードブロックを使った場合と使わない場合の両方について、ファイルにアクセスするコードを書く。コードブロックの利点は? ※コードブロックあり。 ``` File.open(\u0026ldquo;tree.rb\u0026rdquo;, \u0026lsquo;r\u0026rsquo;) {|f| f.each {|line| puts \u0026ldquo;#{f.lineno} : #{line}\u0026rdquo;}}\n※コードブロックなし f = File.open(\u0026ldquo;tree.rb\u0026rdquo;, \u0026lsquo;r\u0026rsquo;) while line = f.gets puts \u0026ldquo;#{f.lineno} : #{line}\u0026rdquo; end\nコードブロックの利点: 見通しの良さ。行数が少なくてすむ。繰り返し処理が簡単に記述できる。 ※うーん、まだきちんと理解できてないか? \u0026lt;/dd\u0026gt; \u0026lt;dt\u0026gt;○ハッシュを配列に変換するにはどうすればよいか?また、逆に配列をハッシュに変換する方法は?\u0026lt;/dt\u0026gt; \u0026lt;dd\u0026gt; ※間違えた。。。 h = [:key1 =\u0026gt; \u0026ldquo;hoge\u0026rdquo;, :key2 =\u0026gt; \u0026ldquo;boke\u0026rdquo;, :key3 =\u0026gt; \u0026ldquo;fuga\u0026rdquo;] h.each {|key, value| puts \u0026ldquo;#{key} is #{value}\u0026rdquo;} =\u0026gt;key1hogekey2bokekey3fuga is\nハッシュ-\u0026amp;gt;配列変換 h.to_a\n配列-\u0026amp;gt;ハッシュ変換 a = [\u0026ldquo;value1\u0026rdquo;, \u0026ldquo;valu2\u0026rdquo;, \u0026ldquo;value3\u0026rdquo;] h = {} a.each {|i| h.store(a.index(i),i) }\n※また間違い?なんでそうなる? a.inject(h2) {|hoge, i| hoge[a.index(i).to_s] = i}\nこっちならいいみたい。まだinjectがわかってない。 a.inject(h2) {|hoge, i| hoge[a.index(i).to_s] = i;puts \u0026ldquo;#{i}\u0026rdquo;; hoge}\n\u0026lt;/dd\u0026gt; \u0026lt;dt\u0026gt;○ハッシュの各要素について繰り返すにはどうすればよいか?\u0026lt;/dt\u0026gt; \u0026lt;dd\u0026gt; h.each {|key, value| puts \u0026ldquo;#{key} is #{value}\u0026rdquo;}\n\u0026lt;/dd\u0026gt; \u0026lt;dt\u0026gt;○Rubyの配列はスタックとしても使える。スタック以外に配列で実現可能なよくあるデータ構造体を挙げよ。\u0026lt;/dt\u0026gt; \u0026lt;dd\u0026gt;キュー。 他にある?Treeとか?Treeはハッシュじゃないか?Set?順番が関係ないけど。\u0026lt;/dd\u0026gt; \u0026lt;/dl\u0026gt; ### **(試してみよう:)** \u0026lt;dl\u0026gt; \u0026lt;dt\u0026gt;○最初に、eachだけを用いて、16個の数値と4個の数値の配列の中身を同時に出力せよ。次に、同じ事をEnumerableのeach_sliceを用いて実行せよ。\u0026lt;/dt\u0026gt; \u0026lt;dd\u0026gt; \u0026lt;span style=\u0026#34;color:#FF0000\u0026#34;\u0026gt;\u0026lt;em\u0026gt;※これ日本語がわからないんだが、4個ずつ出せってことか??\u0026lt;/em\u0026gt;\u0026lt;/span\u0026gt;ということで、「16個の数字の配列の中身を4個ずつ同時に出力せよ。」と解釈して実装してみた ※each利用版 a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] s = [] a.each do |b| unless s.length \u0026lt; 4 puts s.inspect s.clear end s \u0026laquo; b end\n※each_slice a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] a.each_slice(4) {|b| puts b.inspect}\nまた、えらい違いだな。 \u0026lt;/dd\u0026gt; \u0026lt;dt\u0026gt;○Treeクラスは面白いクラスだったが、きれいなインタフェースを用いて新しいツリーを指定することは出来なかった。そこで、initializerにハッシュと配列が入れ子になった構造体を指定できるようにせよ。具体的には、次のようなツリーを指定できるようにしたい。{\u0026#39;grandpa\u0026#39; =\u0026amp;gt; { \u0026#39;dad\u0026#39; =\u0026amp;gt; {\u0026#39;child 1\u0026#39; =\u0026amp;gt; [], \u0026#39;child 2\u0026#39; =\u0026amp;gt; [] }, \u0026#39;uncle\u0026#39; =\u0026amp;gt; {\u0026#39;child 3\u0026#39; =\u0026amp;gt; [], \u0026#39;child 4\u0026#39; =\u0026lt; [] } } }\u0026lt;/dt\u0026gt; \u0026lt;dd\u0026gt;\u0026lt;span style=\u0026#34;color:#FF0000\u0026#34;\u0026gt;※root(ここではgrandpaレベル)が複数あると破綻しないのか?\u0026lt;/span\u0026gt; class Tree attr_accessor :children, :node_name\ndef initialize(name, children=[]) @children = children @node_name = name end\ndef initialize(hash) hash.each do |key, value| @node_name = key @children = value.inject([]) do |array, (child_key, child_val)| puts \u0026ldquo;inject! #{key}\u0026rdquo; [Tree.new({child_key =\u0026gt; child_val})] + array end end end\ndef visit_all(\u0026amp;block) visit \u0026amp;block children.each {|c| c.visit_all \u0026amp;block} end\ndef visit(\u0026amp;block) block.call self end end\n残念ながらちょっとカンニングしてしまいました。。。 \u0026lt;/dd\u0026gt; \u0026lt;dt\u0026gt; ○ファイル内で、あるフレーズを含む全ての行を出力する簡単なgrepをかけ。簡単な正規表現でマッチングを行い、ファイルから行を読み出す必要がある(この処理はRubyでは驚くほど簡単にかける)。必要なら行番号も出力してみると良い。\u0026lt;/dt\u0026gt; \u0026lt;dd\u0026gt;※メソッドだけでいいな。\u0026lt;span style=\u0026#34;color:#0000FF\u0026#34;\u0026gt;ファイルクローズはこの記述の場合はコーディングブロックのendのタイミングでクローズされるのか?\u0026lt;/span\u0026gt; class RegGrep def grep(filename, regexp) File.open(filename, \u0026lsquo;r\u0026rsquo;) do |f| f.each do |line| puts \u0026ldquo;#{f.lineno} : #{line}\u0026rdquo; if line.match(regexp) end end end end\n\u0026lt;/dd\u0026gt; \u0026lt;/dl\u0026gt; ということで、2日目終了。 恥ずかしいコードだらけだけど、ぜひツッコミ入れてもらえると助かります。 数年前までは、恥ずかしいからとか見せられるレベルじゃないからと、ほとんどアウトプットしなかったのですが、 最近はそれではものすごく損をしていると思っています。 ホントは発表するとか議論するとかする場もあればいいのですが。 アウトプットすることで、フィードバックが貰えて、いろんなかたの考えが参考になり、糧となり成長していけるのかと。 (これじゃ成長できないレベルだよという話でなければいいのだが。。。) 一度、Rubyのプロフェッショナル各位に見てもらいたいなぁw ","date":1315588260,"dir":"post/2011/","id":"73262345214f9b7794f2cc4a612b15e8","lang":"ja","lastmod":1315588260,"permalink":"https://blog.johtani.info/blog/2011/09/10/7%E3%81%A4%E3%81%AE%E8%A8%80%E8%AA%9E-7%E3%81%A4%E3%81%AE%E4%B8%96%E7%95%8C-ruby-2%E6%97%A5%E7%9B%AE/","publishdate":"2011-09-10T02:11:00+09:00","summary":"ということで、Ruby2日目の感想(2日目だけで2日間かかったのは内緒。。。) 今回もセルフスタディの私の回答が最後の方に記載されてます。見た","tags":["読書"],"title":"「7つの言語 7つの世界」 Ruby 2日目(Jugemより移植)"},{"contents":"実に3年ぶりくらいにゆっくりできる日々が訪れたので、積読状態の本を消化しようと「7つの言語 7つの世界」を読み始めました。\nせっかくブログも始めたので、備忘録も兼ねて感想などを書いていこうかと。\nこの本ですが、以下の7つの言語についてエッセンスがまとめられています。\nRuby Io Prolog Scala Erlang Clojure Haskell まずはRubyからです。 ここ2年ほどRuby(Rails)に関連する仕事をしていたのですが、Ruby周りはプロフェッショナルな方たちがいたので、きちんと勉強していないことがこの本を読み始めてわかりました。\nということで、前置きはそれなりな記述ですが、感想は適当になりますので、あしからず。\n感想: irbが便利。簡単に動作確認ができるのが便利。Javaだとコンパイルが必要。 変数を定義する必要がない気軽さはある。 必ず戻り値が帰ってくる「puts \u0026lsquo;hello, world\u0026rsquo;」でも。=\u0026gt;nil putsは楽かな。まぁ、Eclipse使ってると一緒か。 「4」もオブジェクトとなっている。ここもJavaと異なる。 (x \u0026lt;= 4).classという記述でTrueClassというクラスだとわかる。 unlessが結構便利。ただし、記述方法が多数あるので、可読性は落ちる?場合によってはわかりやすいか? あと、括弧()がないのも慣れない。(まぁ、これは慣れの問題。ただし、カッコありでもOK) {}のかわりがif~endなのはわかりやすいかも。 if not はわかりやすくていい。!はだいたい間違えるから。。。 whileも1行形式で書けるのか。「x = x + 1 while x \u0026lt; 10」慣れないと厳しい。個人的には混在すると読めないなぁ。 nilとfalse以外がすべてtrueに評価されるのは厳しいのでは?型のチェックがないので、booleanが入ってると想定してない場合に挙動を読めないかも。実行時に動作が変だなーと思うことが出てきそう。 and、orの記述が使えるのは読みやすい。ただし、混在するとやっかい。 判定結果が明らかになった時点で実行が中止されるのは普通。\u0026amp;、|の挙動はJava同様。\nやりながら疑問点:\nNetBeansとかIDEでフォーマッタやcheckstyleみたいなのはあるのか? コーディング規約はあるのか?(2日目に「習慣」があるらしいとの記載があった。) 必ず戻り値が戻ってくるのは、必ずGC対象になりうるオブジェクトが生成されるってことか? ここまでが感想と疑問点。で、この本の面白いところは最後に調査、コーディングを行う練習問題的なものがある部分です。 一応、私なりの答えを書いておこうかと。(一覧などで見えないようにはしますが、ネタバレがあるので注意してください。)\nということで、セルフスタディの回答。\n(探してみよう) ○Ruby API http://ruby-doc.org/core/ ○Programming Ruby: The Pragmatic Programmer's Guideのオンライン版 http://www.ruby-doc.org/docs/ProgrammingRuby/参考資料:http://www.swlab.it.okayama-u.ac.jp/man/ruby/uguide/uguide00.html ○文字列の一部を置換するメソッド \"hello\".gsub(/[aeiou]/, '*') ○Rubyの正規表現に関する情報 日本語:http://www.namaraii.com/rubytips/?%A5%D1%A5%BF%A1%BC%A5%F3%A5%DE%A5%C3%A5%C1 英語の試せるサイト(irbが動けば必要ないかもね):http://rubular.com/ ○Rubyの範囲に関する情報 日本語:http://doc.okkez.net/static/192/class/Range.html 英語:RDocのRangeクラスに相当するのかな。 (試してみよう) ○文字列\"Hello, world\"を出力する。 ``` ○文字列\"Hello, Ruby\"の中の\"Ruby\"という単語のインデックスを検索する。 ``` s = \u0026lsquo;Hello, Ruby\u0026rsquo; s.index(\u0026lsquo;Ruby\u0026rsquo;) //indexofで間違えた\n\u0026lt;dt\u0026gt;○自分の名前を10回出力する。\u0026lt;/dt\u0026gt; \u0026lt;dd\u0026gt;``` ※まずは、正統派。 i = 0 while i \u0026lt; 10 puts \u0026#34;johtani\u0026#34; i = i + 1 end ※Rangeを利用 (1..10).each {|n| puts \u0026#34;johtani #{n}\u0026#34;} ※forもあるよね for i in 1..10 puts \u0026#34;johtani\u0026#34; end ※timesってのもある。(0始まり) 10.times {|n| puts \u0026#34;johtani #{n}\u0026#34;} ※uptoなんてのもあるのか。 1.upto(10) {|n| puts \u0026#34;johtani #{n}\u0026#34;} ※downtoも 10.downto(1) {puts \u0026#34;johtani\u0026#34;} ※stepもある。 10.step(1, -1) {puts \u0026#34;johtani\u0026#34;}//step(上限,ステップ) ```\u0026lt;/dd\u0026gt; \u0026lt;dt\u0026gt;○文字列\u0026#34;This is sentence number 1\u0026#34;の1を10までカウントアップしながら10回出力する。\u0026lt;/dt\u0026gt; \u0026lt;dd\u0026gt;``` 1.upto(10) {|n| puts \u0026#34;This is sentence number #{n}\u0026#34;} ※あとは上記と一緒 ```\u0026lt;/dd\u0026gt; \u0026lt;dt\u0026gt;○ファイルに格納されているRubyプログラムを実行する。\u0026lt;/dt\u0026gt; \u0026lt;dd\u0026gt;``` vi hoge.rb ※#上記処理をどれか記述 $ ruby hoge.rb ○ボーナス問題:少し物足りない人は、乱数を選択するプログラムを書いてみてほしい。プレーヤーに数字を選択してもらい、その数字が生成された乱数よりも大きいか小さいかを返す。 ``` -- coding: utf-8 -- range = (1..100) while true puts \u0026ldquo;#{range.min}から#{range.max}の数字を入力してください\u0026rdquo; n = gets n = n.to_i if range.include?(n) break; else puts \u0026ldquo;範囲外の入力値です。もう一度入力してください\u0026rdquo; end end i = rand(range.max) if i \u0026lt; n puts \u0026ldquo;入力「#{n}」は乱数「#{i}」より大きいです\u0026rdquo; elsif i == n puts \u0026ldquo;入力「#{n}」は乱数「#{i}」と等しいです\u0026rdquo; else puts \u0026ldquo;入力「#{n}」は乱数「#{i}」より小さいです\u0026rdquo; end\n\u0026lt;/dl\u0026gt; とまぁ、こんな感じ。こんな方法もあるよ、ここおかしくない?などあれば、コメント欄まで。 リアクション大募集です。 はやく、シンタックスライター導入せねば。 ","date":1315545120,"dir":"post/2011/","id":"9baedcd033169611a42c3cfd58b3ae03","lang":"ja","lastmod":1315545120,"permalink":"https://blog.johtani.info/blog/2011/09/09/7%E3%81%A4%E3%81%AE%E8%A8%80%E8%AA%9E-7%E3%81%A4%E3%81%AE%E4%B8%96%E7%95%8C-ruby-1%E6%97%A5%E7%9B%AE/","publishdate":"2011-09-09T14:12:00+09:00","summary":"実に3年ぶりくらいにゆっくりできる日々が訪れたので、積読状態の本を消化しようと「7つの言語 7つの世界」を読み始めました。 せっかくブログも始め","tags":["読書"],"title":"「7つの言語 7つの世界」 Ruby 1日目(Jugemより移植)"},{"contents":"現在の出先でMBAを使えないので、なかなか進んでいないMBAのセットアップです。。。\nとりあえず、Eclipse、homebrewをインストールしたので、lucene-gosenの開発やビルドには支障がない程度になってきました。(肝心のSolrがまだ動く状況になかった。。。)\nあとは、Windowsで使用頻度の高いソフトを列挙して、対応するMacのアプリを探そうかと。 まずは、Windowsでよく利用するソフトのリストアップ\nEclipse Cygwin TeraTerm WinSCP meadow サクラエディタ WinMerge PDF-XChange Viewer Evernote FreeMind VMWare こんなところかな。 a.~e.についてはMacOS特に問題なし。Eclipseは入れたし、その他は標準で入ってるものでまかなえると。 f.についてもEmacsで当面対応する予定。ただ、OmmWriter やCotEditorがおすすめらしいと聞いてます。 g.についてはFileMergeなるものがあるらしいので、試してみようかと。 h.は現状Adobe Readerです。ほかにいいのあるのかしら。PDF-XChange Viewerはちなみに、Solr入門を書くときに編集の方から教えてもらったPDFのビューワです。コメントとかハイライトできるのが便利でした。 i.はMacOS版をインストールして、すでに活用中。 j.については一時期活用していたのですが、最近利用していないです。なので、保留 k.についてはVirtualBoxをインストールしてみました。フリーだったので。WindowsではVMWareだったのですが。。。\nほんとにこれくらいで大丈夫かどうかはもう少し使ってみてからかなぁと。 その他におすすめ、これがあるとかなり便利などあれば、教えてもらえると助かります。 まだ、MacOSに触り始めたところなので、細かな部分のカスタマイズなどができていないので、その辺りもオイオイ考えていこうかと。\n※余談ですが、現在「7つの言語 7つの世界」を読み始めました。いろいろな言語の特徴について学べる本のようでかなり楽しく感じています。どうしてもJavaで仕事優先だとコーディングする速度優先でJavaばかり使ってしまうので。 いい頭の体操にもなりそうなのでオススメです。(といってもまだ、最初の言語Rubyなのですが。。。)\n","date":1315329480,"dir":"post/2011/","id":"f23ca2aa066b1ee0fa4df1f2f865be4c","lang":"ja","lastmod":1315329480,"permalink":"https://blog.johtani.info/blog/2011/09/07/mba%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97%E5%82%99%E5%BF%98%E9%8C%B2%E3%81%9D%E3%81%AE%EF%BC%93/","publishdate":"2011-09-07T02:18:00+09:00","summary":"現在の出先でMBAを使えないので、なかなか進んでいないMBAのセットアップです。。。 とりあえず、Eclipse、homebrewをインストー","tags":["備忘録"],"title":"MBAセットアップ備忘録その3(Jugemより移植)"},{"contents":"すぐにテストケース追加しますといいつつ、はや一週間。\nようやく仕事が落ち着いたので、テストケースを追記しました。まだパッチの段階です。 一応、異なる辞書の読み込みのテストケースなどを追加し、テストケース追加時点で いくつか気になったところもあったので、ついでに修正を加えました。 一応、辞書の分離+複数辞書対応については現時点ではこんなところかと。\nあと、もう1項目対応してからtrunkに取り込む予定です。 対応する項目とは以下の項目です。\nカスタム辞書ビルドの簡易化 以前の記事にも書いていますが、カスタム辞書のビルドが思いのほか手間がかかります。 辞書の外部化は対応したのですが、せっかく辞書が外部化できたのですから、コマンド(ant?)で一発で カスタム辞書を含んだビルドをしたくなるのが人情です。 辞書なしのjarファイルもあることなので、すぐに対応可能かと。 ということで、今週中には対応する予定です(宣言しないとまた先延ばしになりそう)\n忘れてそうだったらTwitterやコメントでツッコミを入れてもらえると助かります。\n","date":1315328188,"dir":"post/2011/","id":"3c2523e65ff953fd73579aaaf5d7ce36","lang":"ja","lastmod":1315328188,"permalink":"https://blog.johtani.info/blog/2011/09/07/%E8%BE%9E%E6%9B%B8%E5%88%86%E9%9B%A2%E3%81%AE%E3%83%86%E3%82%B9%E3%83%88%E3%82%B1%E3%83%BC%E3%82%B9%E8%BF%BD%E5%8A%A0%E3%81%A8%E6%AE%8B%E3%82%BF%E3%82%B9%E3%82%AF/","publishdate":"2011-09-07T01:56:28+09:00","summary":"すぐにテストケース追加しますといいつつ、はや一週間。 ようやく仕事が落ち着いたので、テストケースを追記しました。まだパッチの段階です。 一応、異","tags":["lucene-gosen"],"title":"辞書分離のテストケース追加と残タスク(Jugemより移植)"},{"contents":"先日、辞書のjarファイルからの分離についてパッチと記事を書きました。\nIssueにあげていたパッチをRobertさんが見ていたらしく、次のようなコメントをもらいました。\nMaybe if we change SenFactory.getInstance to use a ConcurrentHashMap then you can easily use multiple dictionaries at the same time? 「SenFactory.getInstanceメソッドでConcurrentHashMap使ったら複数辞書対応できるんじゃない?」(訳) たしかに。。。なんで思いつかなかったのだろう。。。\nということで、実装してみました。 パッチはこちら。\n使い方ですが、先日の記事と代わりはありません。 ただし、あった制限事項が次のようになります。\nマルチコアの設定でsharedLibにlucene-gosenのjarを含まない 同一コア内で異なるdictinaryDirの指定はできない ソースの変更点ですが、ものすごく単純です。 dictionaryDirに指定された文字列をキー、その辞書ディレクトリを利用したSenFactoryのインスタンスを値に持つmapをSenFactory内に保持します。あとは、SenFactoryのgetInstance(String dictionaryDir)メソッドで取得する際にmapに対応するインスタンスがあれば、そのインスタンスをなければ、dictionaryDirから辞書を読み込んでインスタンス生成してmapにキャッシュしつつ返すという実装に変えただけです。 ということで、次のようなIPADICとNAIST-JDIC for ChaSenを同時に使う設定も可能となります。\n\u0026lt;fieldType name=\u0026#34;text_ja_ipadic\u0026#34; class=\u0026#34;solr.TextField\u0026#34; positionIncrementGap=\u0026#34;100\u0026#34;\u0026amp;gt; \u0026lt;analyzer\u0026amp;gt; \u0026lt;tokenizer class=\u0026#34;solr.JapaneseTokenizerFactory\u0026#34; dictionaryDir=\u0026#34;/tmp/lucene-gosen/dictionary/ipadic\u0026#34;/\u0026amp;gt; \u0026lt;/analyzer\u0026amp;gt; \u0026lt;/fieldType\u0026amp;gt; \u0026lt;fieldType name=\u0026#34;text_ja_naist_chasen\u0026#34; class=\u0026#34;solr.TextField\u0026#34; positionIncrementGap=\u0026#34;100\u0026#34;\u0026amp;gt; \u0026lt;analyzer\u0026amp;gt; \u0026lt;tokenizer class=\u0026#34;solr.JapaneseTokenizerFactory\u0026#34; dictionaryDir=\u0026#34;/tmp/lucene-gosen/dictionary/naist-chasen\u0026#34;/\u0026amp;gt; \u0026lt;/analyzer\u0026amp;gt; \u0026lt;/fieldType\u0026amp;gt; あと、注意事項です。 普通に考えるとわかることですが、辞書を複数読み込めるようになったことで、読み込んだ複数の辞書をメモリに保持することになります。ですので、今までよりも多くのメモリを利用するので、Heapのサイズには注意が必要です。 例のごとく(ほんとよくない。。。)テストコードを書いていない状態のパッチをまずはアップしました。 テスト書かないと。。。次回はテストコードかきましたと言う報告をしたいな\nあと、Robertさんのコメントの前に@shinobu_aokiさんからJapaneseTokenizerFactoryの設定では辞書のディレクトリを$SOLR_HOME/confからの相対パスで記述できるというパッチもいただいています。 この部分については先日と使い方が異なります。 (すみません、まだきちんとソースを見れてないです。。。)\n","date":1314668040,"dir":"post/2011/","id":"88a8e608108be939da9aab5a9a8af7d1","lang":"ja","lastmod":1314668040,"permalink":"https://blog.johtani.info/blog/2011/08/30/%E8%A4%87%E6%95%B0%E8%BE%9E%E6%9B%B8%E3%81%AE%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%81%BF%E6%A9%9F%E8%83%BD%E8%BF%BD%E5%8A%A0%E4%BB%AE/","publishdate":"2011-08-30T10:34:00+09:00","summary":"先日、辞書のjarファイルからの分離についてパッチと記事を書きました。 IssueにあげていたパッチをRobertさんが見ていたらしく、次のよ","tags":["lucene-gosen"],"title":"複数辞書の読み込み機能追加(仮)(Jugemより移植)"},{"contents":"ひさびさに、lucene-gosenの話題です。\nlucene-gosenはjarファイルに辞書も同梱されており、jarファイルをクラスパスに取り込むだけで、 簡単に形態素解析器が利用できるといお手軽さがあり、便利です。\nですが、以前カスタム辞書の登録について記事を書いたように、カスタム辞書の登録は思いのほか手間がかかります。 lucene-gosenのソースをダウンロードし、lucene-gosenを一度コンパイルし、カスタム辞書のcsvファイルを作成し、カスタム辞書を取り込んだ辞書のバイナリを生成し、最後にjarファイルにするという作業です。(書くだけでいやになってきました。。。)さらに作成したjarファイルをSolrや各プログラムに再度配布するという具合です。\nそこで、辞書ファイルの外部化ができないかという話があがっていました。 すこし時間ができたので、山積みになっているissueを横目に軽く実装をしてpatchをissueにアップしました。\n機能としてはごく簡単で、JapaneseTokenizerのコンストラクタに辞書のディレクトリ(*.senファイルのあるディレクトリ)を指定可能にしただけです。 また、JapaneseTokenizerFactoryでもdictionaryDir属性で指定可能になっています。 まずは、コンパイルの方法から。 trunkをSVNでcheckoutし、issueにあるpatchをダウンロードして適用します。(svnのチェックアウトについてはこちらを参考にしてください。)\n$ cd lucene-gosen-trunk $ patch -p0 --dry-run \u0026lt; lucene-gosen-separate-dictionary.patch $ patch -p0 \u0026lt; lucene-gosen-separate-dictionary.patch 次に、antを実行し辞書なし版のjarファイルをビルドします。\n$ ant nodic-jar これで、dictディレクトリに「lucene-gosen-1.2-dev.jar」というjarファイルが出来上がります。 (※ただし、これだけでは動作しないので、別途辞書のコンパイルは必要です。)\n次に、指定の仕方です。JapaneseTokenizerのコンストラクタは第3引数に辞書のディレクトリ(フルパスor実行ディレクトリからの相対パス)を渡すだけです。\nTokenizer tokenizer = new JapaneseTokenizer(reader, compositeTokenFilter, dictionaryDir); 最後に、Solrのtokenizerタグでの指定方法です。\n\u0026lt;fieldType name=\u0026#34;text_ja\u0026#34; class=\u0026#34;solr.TextField\u0026#34; positionIncrementGap=\u0026#34;100\u0026#34;\u0026amp;gt; \u0026lt;analyzer\u0026amp;gt; \u0026lt;tokenizer class=\u0026#34;solr.JapaneseTokenizerFactory\u0026#34; dictionaryDir=\u0026#34;/hoge/dictionarydir\u0026#34;/\u0026amp;gt; \u0026lt;/analyzer\u0026amp;gt; \u0026lt;/fieldType\u0026amp;gt; 以上が、簡単な設定の仕方です。なお、辞書を内包したjarファイルでもdictionaryDirは利用可能です。優先度としては、dictionaryDirが指定されている場合はdictionaryDirを探索しファイルがなければRuntimeExceptionです。指定がnullもしくは空文字の場合はjarファイルの辞書の読み込みを行います。\n次に利用シーン、制限事項についてです。 利用シーンとしてはカスタム辞書を定期的にメンテナンス(追加更新)しながらSolrを運用するというのが想定されます。定期的に辞書の再読み込みをしたい場合です。 利用方法は次のようになります。\nSolrのマルチコア構成を利用する 各コアごとにlib/lucene-gosen-1.2-dev.jarを用意 辞書の更新が終わったらコアのRELOADを実施 コアをリロードすることで、lucene-gosenが辞書を再読み込みようになります。(現状でも再読み込みするが、jarファイルを再配置しないといけない。)あとは、定期的に辞書ファイルを更新、再構築しコアをリロードすれば、 リロード後に新しい辞書が利用できるという具合です。 (もちろん、辞書更新後に入った単語は辞書更新以前に作成したインデックスにはでてこないですが。。。) また、コアごとにdictinaryDirを別々に指定することも可能です。\n制限事項は次のようになります。\nマルチコアの設定でsharedLibにlucene-gosenのjarを含まない 同一コア内で異なるdictinaryDirの指定はできない 以上が、辞書の外部ファイル化のパッチについてでした。 少しテストケースを追加したら、trunkにコミットする予定です。興味があれば、パッチを利用してみてください。\nSyntaxHighlighterの導入をしないとソースコードが見にくいですね。。。導入を検討しないと。。。どこかにWebサーバ用意しないとダメかも\n","date":1314062760,"dir":"post/2011/","id":"2f1ec795216d5bafa33a810af3421942","lang":"ja","lastmod":1314062760,"permalink":"https://blog.johtani.info/blog/2011/08/23/%E8%BE%9E%E6%9B%B8%E3%81%AEjar%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%8B%E3%82%89%E3%81%AE%E5%88%86%E9%9B%A2/","publishdate":"2011-08-23T10:26:00+09:00","summary":"ひさびさに、lucene-gosenの話題です。 lucene-gosenはjarファイルに辞書も同梱されており、jarファイルをクラスパスに","tags":["lucene-gosen"],"title":"辞書のjarファイルからの分離(Jugemより移植)"},{"contents":"すみません、また、MBA関連の記事になってしまいました。 ということで、備忘録その2です。\n前回からいくつかインストールや環境の設定をしたので、リストアップ。\nVirtualBoxとWindowsのインストール homebrewのインストール KeyRemap4MacBookのインストール Growlのインストール Time Machine用HDDの購入と設定 VirtualBoxのインストールとWindowsXPのセットアップ。会社関連でどうしてもWindowsが必要なので、 とりあえず、VirtualBoxとWIndowsを入れました。これまでのWindows環境ではVMWareを利用してたのですが、 Macだと有償ということで、無償版が存在するVirtualBoxを選択。 MBAにはDVDのドライブがなく、また、ケチって購入しなかったので、ちょっと手間取りました。 自宅のデスクトップでXPのイメージをisoにして、MBAにコピーしてからインストールと。。。 ただ、MBAのSSDの効果なのか、XPの起動がすごく速くてびっくりです。\nhomebrewのインストールは、まだインストールしただけの状態。。。 MacPortsってのがあるというのは知っていたのですが、最近はこちらがいいとのこと。 ちなみに、MacPortsにはSolrがあるらしいです。デフォルトのため、lucene-gosenとか入れる必要がありますが。\nKeyRemap4MacBookのインストール。入れた方がいいですよと言われてたのだが、きちんと調査してなく、 キーの入れ替えができる程度だと思ってました。昨日、EmacsModeなるものが存在するというのをKeyRemap4MacBookのドキュメントを読んでいて発見し即インストール。 とりあえず、Ctrl-x,Ctrl-cでEvernoteが終了できて喜んでるところです。\nGrowlのインストール。KeyRemap4MacBookのCtrl-xを通知してくれます。ほかにも使い方があるかは調査が必要。\nあとは、昨日、ビックカメラでWDの2TBのHDDを購入してTimeMachineの設定をしてバックアップをとりました。 まだバックアップをとっただけで、差分を見たりはしていないです。帰ってからやってみようかと。\n最後に、ケースを買いました。封筒とかいろいろ考えたのですが、やはり機能重視ということで、以下のケースです。 できれば、ファスナーが2つついていて、両方からあけられるとよかったのですが。リュックとショルダーバッグを使い分けるので、横でも縦でも取り出しが楽なものがよかったので、このケースを買いました。 一応、がんばれば縦でも出せるので。あとは、PCだけもって移動することもあるため、取っ手があるのが便利かと。\nとまぁ、お盆なので、このエントリーで許してください。次回は技術的なことを書きますので。。。 CaseLogic 機能的なモバイルコンピュータケース(13~14.1インチPC対応)、MacBookやMacBook Proにも対応 ダークグレー UNS-114J-DG ","date":1313369460,"dir":"post/2011/","id":"ce0aea06d44878b4a373efe090a66a62","lang":"ja","lastmod":1313369460,"permalink":"https://blog.johtani.info/blog/2011/08/15/mba%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97%E5%82%99%E5%BF%98%E9%8C%B2%E3%81%9D%E3%81%AE%EF%BC%92/","publishdate":"2011-08-15T09:51:00+09:00","summary":"すみません、また、MBA関連の記事になってしまいました。 ということで、備忘録その2です。 前回からいくつかインストールや環境の設定をしたので、","tags":["備忘録"],"title":"MBAセットアップ備忘録その2(Jugemより移植)"},{"contents":"Mac Book Airのセットアップ関連の備忘録\n(今回は備忘録なので、文体も変かも)\nインストールしたもの(順不同)だいたい、このサイトを参考にした。\nEvernote Dropbox XCode Twitter YoruFukurou GNU Emacs For Mac OS X Java Office for mac 現状はこんなところ。\nまだ、キーボードの配列とショートカット、ウィンドウの切り替えなどがすぐにできないので、かなりおぼつかない状態。\nCtrl+aなどの操作は快適なのだが、ウインドウを閉じたりする場合のcommandキーの扱いがまだなれない。キー配置を切り替えたりした方がいいのか悩み中。 Windowsでは長年XKeymacsを使ってきたため、通常のOfficeなどもCtrl+x Ctrl+sなどで閉じていたので、command+qなどがすんなり出てこない。。。\nあとは、VirtualBoxにWindowsを入れて、Eclipseを入れればなんとか、WindowsPCからMBAへの切り替えができそう。\n残っている課題は以下の通り。\nTime Machine環境の整備USB接続のHDDの導入(ミラーリング対応にするか悩み中)※ちなみにうちで使ってるNASは古い+NFSマウントできない機種だった。。。 対応可能だったらScientific Linux+Netatalk環境などを用意するのも考えたんだが。 homebrewのインストール 日本語入力(GoogleIME?SKK?) ウォークマン、Xperia arcの運用方法まぁ、今まで使ってたPCで対応かな キーの配置Emacsのショートカットに変更できたりするか調査したい データの移行Windowsに入ってるデータのうち移行するものしないものの選別Macでは利用できないデータやファイルもあると思う。 解凍ツールの選別?いるのかな? ブラウザのインストールchrome、Firefoxはいれるかな。 メーラーのインストールWindwosではBecky!を使ってたのだが、どうするか。デフォルトメーラで様子見? ウイルス対策ソフトの導入Macってどんなソフトがあるかがわからない。。。 あと、1週間触っての感想\nまずは、良かった点。\nいろんなUIがよくできてるセットアップなどきれいな画面で説明が進むのが新鮮だった。あと、フォントのきれいさも新鮮。これは、今までのPCが古いからかもしれないが。 トラックパッドがいいまだなれてないけど、スイスイ動くのでストレスなく作業できる。スワイプとかも画面の移動が楽でいい。 静かで速いSSDのため、静かだし起動がすごく速い。会社で支給されてるPCもSSD(3年くらい前のもの)だけど、こんなに起動などがはやくない。 あとは、気になった点。\nAppStoreでページ間のスワイプができない。かなり使いづらい。Safariと同じイメージでいるので。 手首がいたい手前のエッジ部分が手首に当たってちょっといたい。 アプリインストール時にファンがうるさい動画などはまだ見てないが、Office、XCodeのインストール時にファンの排気音がうるさくなり、結構な熱を発していた ファーストインプレッションはこんな感じ。\nただ、前回も書いたようにうらやましかったのもあり、かなり満足している。 もっと触る時間が欲しいのだが、なかなかとれないのが歯がゆい。。。\n持ち歩くようになったらとりあえず、「7つの言語 7つの世界」を読み進め+写経をやる予定。\n","date":1312904760,"dir":"post/2011/","id":"c0e423f9ac41cc5b265c95a3e97e3fcb","lang":"ja","lastmod":1312904760,"permalink":"https://blog.johtani.info/blog/2011/08/10/mba%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97%E5%82%99%E5%BF%98%E9%8C%B2/","publishdate":"2011-08-10T00:46:00+09:00","summary":"Mac Book Airのセットアップ関連の備忘録 (今回は備忘録なので、文体も変かも) インストールしたもの(順不同)だいたい、このサイトを参考にした。 Evernote Dropbox","tags":["備忘録"],"title":"MBAセットアップ備忘録(Jugemより移植)"},{"contents":"個人用のPCを8年ぶりに新調しました。\n前回購入した家のデスクトップPCがもう8年ものになりつつあるということで、\nさすがに今年はPCを買おうと思い、年初からいろいろと調べていました。\n当初は次もデスクトップPCを購入する予定でした。ただ、次のような状況ということもあり\nデスクトップは見送ることにし、代わりにノートPCにすることに。\n通勤時間が1時間を超えること\n基本、客先に出向いての仕事\n家でPCに触る時間が少ない(家族サービスのため。)\nで、ここ数週間悩んでいたのですが、Mac Book Air 13インチを購入しました。(そのMBAから初投稿です。)\n実は、Apple製品はこれが初の購入となります。\n対抗馬としてあがっていたのはSonyのVAIO Type Zでした。\n元々ソニスト(ソニー大好き)であり、携帯(Xperia arc)、ウォークマン(Sony)、PSP go、ハンディカムなど、\nソニー製品に囲まれており、デザインもType Zのほうが好みなのですが、MBAを購入しました。\nこの理由なのですが、私が大学時代にさかのぼります。\n情報系の大学の出身で、はじめてきちんと触ったマシンがSunOS4.1(最後の数年はSolaris2.6)でした。\nその後、大学6年間は基本的にEmacsでメールをみて、Emacsで文章を書いていました。\nそのため、社会人になってからもEmacsのキーバインドから抜け出せない日々を送っていました。\n社会人ではやはりWindowsでしたが、XKeymacsというフリーソフトのおかげ(せい?)でEmacsの\nショートカットからは抜け出せないまま。(家のPCはXPで、XKeymacsがインストールされてます。)\n今までの流れだと、何も考えずにWindows7+XKeymacsの流れだったのですが。。。\n職場でWindows7のPCを使う機会があり、XKeymacsを入れてみたのですが、これまでとことなり、\nうまく機能しないことこの上なし(例:chromeのアドレスバーでCtrl+Kとかできないなど)。\nさらに、64bit版の場合、XKeymacsを32bit、64bitの2つインストールしないといけないことに。(32bit用アプリのために32bitを入れないといけない)\nで、数ヶ月使っているのですが、ちょっとずつストレスがたまっている始末。。。\n今までは、「Mac?今更恥ずかしくてかえない」「Mac?おしゃれすぎて無理」「Apple?MSにかわって独占してるの気に食わん」と公言していたのですが。。。\nやはりUnixベースであり、Ctrl+aやCtrl+kが意識せずに利用できるということでコーディングなどを行う場合のストレスよりも保守的な思考を変える方が今後のためにも良さそうだということで、心機一転MBAを購入しました。\nということで、ついにApple教へ入信です。\nまだ、1時間も触ってないですが、すでに洗脳されつつあります。。。\n新しいものに触れるのって楽しいですよね。当分は何をインストールするかなど楽しい悩みでいっぱいになれそうです。(次回はちゃんとした技術的な記事書きたいと、書けるかな、書くぞ、たぶん。。。)\nとまぁ、いろいろと理由を書いてみましたが、要は(オシャレさに)憧れてて、あまのじゃくになって思ってもないこと言ってたんです!\n理由が欲しかったんです!!\nMacかっこえーわーw\nMac miniとかiMacとかもほしーわー\n","date":1312389240,"dir":"post/2011/","id":"7ed1d2efa3e0f0ed6b77eb4eff3d86b3","lang":"ja","lastmod":1312389240,"permalink":"https://blog.johtani.info/blog/2011/08/04/apple%E6%95%99%E3%81%AB%E5%85%A5%E4%BF%A1%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-08-04T01:34:00+09:00","summary":"個人用のPCを8年ぶりに新調しました。 前回購入した家のデスクトップPCがもう8年ものになりつつあるということで、 さすがに今年はPCを買おうと","tags":["備忘録"],"title":"Apple教に入信しました(Jugemより移植)"},{"contents":"かなり遅くなりましたが、第1回 データ構造と情報検索と言語処理勉強会 #DSIRNLPに参加しました。\n帰ってから2日半ほど寝込んでしまい、更新が遅れました。。。\n初の土曜日開催の勉強会でしたが、家族を説得してなんとか参加しました。\nおかげで色々と面白そうなキーワードが拾えてよかったです。(拾っただけで理解するのはかなり時間がかかりそうですが。。。)\nということで、前回同様、個人的にメモを取ったので。誤記などあるかもしれませんが、その時はコメントいただければと。\n0.DSIRNLPについて\n※ボランティアで受付してたので聞けず。\n1.TRIEにトライ!~今日からはじめるTRIE入門~\n@echizen_tm さん\n資料:http://www.scribd.com/doc/58688141/Try-for-Trie\n1.TRIEの説明\n実装についてはあとでスライドをみればいいか。(※ボランティアで受付してたので前半聞けず)\n・パトリシア木\n・Double Array\n・LOUDS\n・XBW\n2.作ってみた\nその1 ベーシック\nQ.ノードのラベルどーする?\n・固定長(ラベル=1文字)\n定数時間でアクセス可能\n・可変長(ラベル=任意文字列)\nPatricia木に拡張可能\nA.拡張性を考えて可変長に!\n3.LOUDSとは?\n概要\nJacobsonが提案 Level-Order Unary Degree Sequenceの略(いつからLOUDSになったのか不明)\n構築済みTRIEからLOUDSを構築\n作業領域がO(NlogN)からO(N)に\n・ノードに幅優先で順番(Level-Order)をつける\n・子ノードの数を付ける。Unary符号で実装\n作ってみた\n・UnaryよりVerticalCodeのほうがよさそう\nhttp://d.hatena.ne.jp/echizen_tm/20100531/1275323074\n・dag_vectorを使ってもいいかもよ?\n4.QA\nQ.可変長を配列にすればいいんじゃね?\nA.単純にやると効率悪そう?\n※LOUDSをlucene-gosenに適用するとなんか嬉しいことあるかな?\n現状はDouble-Arrayだけど。\n2. ランキング学習ことはじめ(Solr系に利用できそうな予感。。。ごごご。。。むずかしい。。。)\n@sleepy_yoshi さん NTTのSuharaさん「話がうまい」\n数原 良彦\n自己紹介\n情報検索、ランキング学習をやってる。\n三浦半島在住\nねらい\nランキング学習の認知度を高める、ざっくり伝える。 ごめんなさい 「実装」についてをわすれてた。\n・ランキング学習とは?\nLearning to rank\npreference learningとは違う\n教師あり機械学習で検索ランキングに適用\n・歴史\n従来は単一ランキング\nクエリ・文書関連度(TF-IDF、BM25)\n文書の重要度(PageRank、HITS、SALSAなど)\n近代的なランキングの実装方法\n上記データを利用して関数を適用する。\n・何を正解とするのか?\n適合性評価の作成方法\n評価点数を多段階で点数化\nランキング評価方法\nランキングを正解データと比較\nNDCG(Normalized Discounted Cumulative Gain) ※分類問題におけるモデルの生成\nTraining Data+学習アルゴリズム=>モデル\nランキング学習の訓練データ\n素性や評価はクエリごとに変わってくるTraining data(ここが違う)\nここまでのまとめ\n正解データは適合度至上主義!\nランキング学習手法\n3つのアプローチ\n教師あり機械学習(識別学習)≒\nどのような目的関数/損失関数を\nどのように最適化するのか\nアプローチ\n1.Pointwise手法\n単一のデータに対して損失関数を設定\n2.Pairwise手法\n同一クエリのペアに対して損失関数を設定\n3.Listwise手法\n同一クエリのリストに対して損失関数を設定\nPointwise:あまりつかえない。\n例:二値分類(適合+1不適合-1)で学習\n補足:Perceptron\n例:PRank\nしきい値と重み両方修正する。\nPairwise:Pointwiseよりいいらしい\n文書ペアで損失を設定\nMQ2007、MQ2008データセットの結果\nPairwise手法とListwise手法を比較しても\nそんなに悪くないらしい\nIR-SVMってので偏りなどを排除できて、精度向上になるよ\nNLP2011でPARankっての発表したよ(手前味噌)\nQA\nQ.じゃんけんみたいに循環しない?(nokuno)\nA.半順序のデータだと起きるが、検索の場合は全順序なので大丈夫だよ\nListwise:Pairwiseよりいいらしい\nListNetってのあり。\nAdaRank\n検索評価指標を直接最適化するブースティング手法\n性能はいまいち?実装は簡単\nその他の話題\nClick-through logs\nQuery-dependent ranking\nFeature selection\nTransfer learning/Domain adaptation\nDiversity/Novelty\n公開Dataset\nLETOR3.0/4.0 Dataset\nMSLR-WEB Datasetなど\n実装\nRankingSVM\nStoch\u0026hellip;.\nLearning to Rank教科書\n英語の資料が今年複数出たみたい\nまとめ\n近代的な検索エンジンは多数のランキング素性を利用\n評価データを用いてランキング素性の最適な重み付けを求める方法\n。。。\n機械学習手法は論文≒実装\nなので、ソースコード見るほうが重要(論文にないノウハウがあるよ)\n3.snappy調べてみた\n@machy 町永圭吾(赤いポータルサイト)\nTopCoderなどで活躍中?\n・snappyは圧縮/伸張ライブラリ\nzlibよりサイズが大きいけど一桁はやいですぞ。\n・インストールなど\ngoogle-gflagsってのがないと動作しないよ。\n・比較してみた(zlib)\n一桁は言い過ぎだけど、はやかった。\n・比較してみた(lzo)\nHadoopで利用されているlzo\nはやかった。\n・仕組みは?\nzlib 辞書式符号化+ハフマン符号化=出力\nsnappy 辞書式符号化+リテラル=出力\n・辞書式符号化は?\n前に出てきたデータで同じ文字列の部分について端折る\n・ハフマン符号化\nよく出てくる記号を短い符号で置き換えることで圧縮する。\n・snappyの符号化\n基本バイト単位での処理にすることで、高速化してるみたい。\n・snappyの辞書参照元の探し方\nハッシュテーブル利用してマッチする位置を検索\n4byte窓でハッシュ値を計算してハッシュテーブルを更新\n・圧縮しにくいデータ(同じ単語が出てこないパターン)について\n圧縮をあきらめ始める(32回同じのが見つからないと窓の移動幅が1つずつ大きくなる)\n16KB(フラグメント内)での比較回数が1008回に抑えられる。\n・特徴\nハッシュがしょうと移したらあるはずのマッチが見つからないこともある。\nメモリ消費量を抑えるためのハッシュのサイズ?\n最悪ケースのサイズを予め確保してから処理するため、メモリの再確保が起きないのではやいぞ。\n4.類似文字列検索してますか?\n@overlast さん Yな会社\n1.曖昧な情報を処理する能力\n曖昧な情報を解決しようとする能力が高い。\n例:お笑い芸人の芸がサンプルw\n画像検索は曖昧クエリに答える例。。。\nスターバックス、スタバ、SUTABA\nスータバでも画像が出てきた。-\u0026gt;女子高生とかが「スータバ」で画像をアップしてたりするから。\n文字列を使った検索は現代のインフラになってるよね。\n例:iタウンページ\nタイトルとかに「スターバックスコーヒー」って書いてないとだめ。?\n「スタバ」800件くらい -\u0026gt; 正規化で「ー」消してるんじゃないの?\n「スータバックスコーヒー」0件 ちがうな。シノニム辞書登録してるな。\n曖昧なクエリ(キーワード)から検索できないかなぁ?\n曖昧情報の処理は文字列処理にこそ必要\nなんでヒットしたかがわかるのが正解 なんでヒットしたかわからないけど、ちゃんと出てきたから正解!\n2.ゼロ件ヒット問題(ゼロマッチ)\nピクシブ百科事典\n「ピングドラム」だと17件\n「ピンクドラム」だと0件 しかも真っ白!!\n使いにくいよね。けど、一般的な検索システムの問題だよね。\nGoogleだと出てくる「ピンクドラム」の結果の最初にはピングドラムが出てくる。\n-\u0026gt;リンクがはられているから出てきた?みんなの間違いで助けられてる\n食べログ\n「俺のハンバーグ」\n「俺はハンバーグ」で検索したら。。。「俺はハンバーグで連れは。。。」がヒット-\u0026gt;しらねーよw\nまとめ\nゼロ件ヒットは機会損失!!\n3.曖昧な文字列で正しい文字列を探す方法\n正しい文字列って?\n1.表記誤りがない\n2.心の底で求めている\n※異表記同義、同表記異義、異言語表記(日本語の情報を英語で検索)などもある\n正しさはユーザによって変わる。\n正しい文字列をさがす手法\nクエリ表記の正誤という軸\n誤の場合表記をヒントに似た文字列を検索してみる。\n探したい対象が正確か曖昧か\n表記意外がヒントで同じ対象に到達できる?\nどんな情報を手がかりにする?\n編集距離(レーベンシュタイン)\n検索ログ\n4.Apporoの紹介\nチョコ?いや、ロケット?いや、Approximate \u0026hellip;\nhttp://code.google.com/p/apporo/\n中小規模だと使えそう\nSimString\n今後\nよみかな、ローマ字表記に基づく類似文字列検索+高速化の予定\n技術概要\nSuffix Array\nN-gram Searchベースの近似文字列照合\nBit Parallel Matchingによる編集距離計算\n5.検索と言語と文化(仮)\n@mizuno_takaaki さん\n放送禁止のためメモなし。\n7.自然言語処理におけるargmax操作\n@hitoshi_ni さん\n※順番変更\n・近似解法\nその1 全探索\nいや、無理でしょ、計算が。\nその2 貪欲法\n最適解が出るかは不明。\nその3 ビームサーチ\n上位kこの仮説を保持しながら幅優先探索\n・動的計画法\nすでに最大値がわかっていて、ゴールから眺めてみる。\n逆からたどるとルートがわかるんじゃないか。\nマルコフ性につけ込むことで、わかるんじゃないか。\n計算量:品詞数の2乗\n(品詞数の2乗)*形態素数\nDPの実装\nViterbiかなぁ?\n・整数計画法(線形-\u0026gt;整数)\n自然言語処理としては整数計画法でだいたいOK。\nアルゴリズム\n・手元の解空間中から許容解を得る\n・分枝してそこから最大値を求める\n最大値>許容解ならそちらを探索。\nプログラム実装する?\nすごく大変じゃないけど簡単でもないね。\n問題の弱点がわかってるなら実装してもいいよね。\n整数計画法の場合lp_solveなどのフリーのソフトで解くのがいいよ。エクセルでも解けるよ\nILP(整数計画法?)\n問題の切り分けに使える。\nまとめ\nILPで解けたら、いろいろ自分で考えると面白いよ。\nその他のバズワード\n参考資料\n組み合わせ最適化=1万円超\nアリ本\n6.ソーシャルグラフ分析(導入編)\n@kimuras さん mixiの木村さん\n・グラフ探索部分はまた今度。\n・テキストマイニングや検索エンジンまわりやってる。\n・ノードが数1千万、エッジが数億のオーダー\n・分散技術の発展によるアルゴリズムの多様化\nこれまで\nRDBからDumpしたデータをKVSに入れて頑張ってた。\nDump部分でデータ構造を毎回構築\n問題点\n変更による再実装、メンテナンスコスト、\nこれから\ngraphDBに取組中。マイニングに最適な感じ\ngraphDBの実装\nOrientDB、Neo4jとか\nNeo4jって\nACIDトランザクション可能\nEmbeddedGraphDatabaseだとAGPLv3だから気をつけてね。\nluceneで全文検索インデックスつくってるみたい。\nGremlinってのがquery言語を汎化してるらし。\nとあるSNSのデータを使ってみたよ。\nメモリ64G、CPUは1コアしか使えなかったよ。\nノード:15million、枝:600million\nまとめ\nということで、色々と面白い話が聞けました。特にTRIEの話はかなり興味を持ちました。\n検索周りで嫌というほど出てくるので。まだまだきちんと理解できてないので復習しないと。。。\nlucene-gosenにも関係あるので、しっかり資料をみて復習する予定です。\n基本的に検索系の話に関連があることが多くて面白く聞くことができました。\n「類似文字列検索してますか?」や「ランキング学習ことはじめ」などは身近な話(だけど、なかなかきちんと学習できてない話)でした。\nまた、「自然言語処理におけるargmax操作」では大学でやっていた線形計画法などのわかりやすい説明で10年経ってようやく理解ができた次第です。。。(もっとちゃんと勉強しとけば。。。)\n懇親会にも参加し、研究に近い分野の方が多い中でいろいろな話が聞けたのはよかったと思います。\n次回もいろいろなキーワードを拾いたいのでぜひ参加したいです。\n","date":1311737580,"dir":"post/2011/","id":"3811b40721f7ca651887aac4eb17f9f0","lang":"ja","lastmod":1311737580,"permalink":"https://blog.johtani.info/blog/2011/07/27/%E7%AC%AC1%E5%9B%9E-%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0%E3%81%A8%E6%83%85%E5%A0%B1%E6%A4%9C%E7%B4%A2%E3%81%A8%E8%A8%80%E8%AA%9E%E5%87%A6%E7%90%86%E5%8B%89%E5%BC%B7%E4%BC%9A%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-07-27T12:33:00+09:00","summary":"かなり遅くなりましたが、第1回 データ構造と情報検索と言語処理勉強会 #DSIRNLPに参加しました。 帰ってから2日半ほど寝込んでしまい、更新が","tags":["勉強会"],"title":"第1回 データ構造と情報検索と言語処理勉強会に参加しました。(Jugemより移植)"},{"contents":"以前から春山さんのブログ(リンク)や勉強会で耳にはしていたのですがソースは読んでいませんでした。 先日、Luceneにcontributeされた(リンク)ので軽くソースを読んでみました。\n公式サイトはこちら\nまずはMeCabのページにある比較表(リンク)を基準に特徴を調べてみました。せっかくなので、lucene-gosenも隣に。\n\u0026nbsp; Kuromoji lucene-gosen 解析モデル なし(学習機能なし) なし(学習機能なし) コスト推定 なし(学習機能なし) なし(学習機能なし) 学習モデル なし(学習機能なし) なし(学習機能なし) 辞書引きアルゴリズム Double Array Trie Double Array Trie 解探索アルゴリズム Viterbi Viterbi 連接表の実装 2次元 Table 3次元 Table 品詞の階層 無制限多階層品詞?ipadic、unidic形式に対応 無制限多階層品詞 未知語処理 字種 (動作定義を変更可能)(おそらく。) 字種(変更不可能) 制約つき解析 たぶん、不可? たぶん、不可? N-best解 不可能 不可能 こうやって比較してみるとlucene-gosen(Sen)とあまりかわりはありませんが、lucene-gosenが少し古いのがわかりますね。。。\nKuromojiで利用出来る辞書は現時点ではMeCab IPADIC、UNIDICの2種類のようです。\nソースを読んでの感想ですが、やはりMeCabが偉大だということがよくわかりました。 Senよりも新しいMeCabの処理に似ている点が多いです。解探索アルゴリズムや連接コスト表が特に。 MeCab向けの辞書を利用しているためというのもあるかと思います。\nKuromojiが特徴的なのは「searchモード」と呼ばれるモードが用意されていることです。 公式サイトにある例ですと、「関西国際空港」が「関西」「国際」「空港」というTokenで出力されます。 ソースを見たところViterbiアルゴリズムで辞書を探索しているときに特定の条件でコストをカサ増しすることで、結果を変えるという処理を行っているようです。\n全て漢字の単語:3文字以上の場合に「(単語の長さ-3)*10000」をコストに加算 その他の単語:7文字以上の場合に「(単語の長さ-7)*10000」をコストに加算 このようにコストを変化させることで「空港」でも「関西国際空港」という文字を含む文章が検索できる仕組みになっています。 また、「拡張searchモード」と呼ばれるモードも存在し、こちらは、未知語をuni-gramで区切って出力を行うようです。\nソース上で確認しただけで、未確認ですが、GraphvizFormatterというクラスがあるので、Graphvizで読み込める形式で形態素解析の結果が出力されるかもしれません。(すみません、確認してなくて。)\n未知語の処理やsearchモードなど面白い機能があるので、試してみるのもいいかもしれません。lucene-gosenを考えていく上でも参考になりそうです。\n最後に余談ですが、FAQのページ(リンク)が面白いです。。。\n","date":1311132540,"dir":"post/2011/","id":"5a765f9668608a39333fa90cf462657e","lang":"ja","lastmod":1311132540,"permalink":"https://blog.johtani.info/blog/2011/07/20/kuromoji%E3%82%92%E8%AA%BF%E3%81%B9%E3%81%A6%E3%81%BF%E3%81%9F/","publishdate":"2011-07-20T12:29:00+09:00","summary":"以前から春山さんのブログ(リンク)や勉強会で耳にはしていたのですがソースは読んでいませんでした。 先日、Luceneにcontributeされ","tags":["形態素解析"],"title":"Kuromojiを調べてみた(Jugemより移植)"},{"contents":"忘れてしまうので、備忘録を残しておきます。 一応、ソースには少しずつコメントをいれてはいるのですが。 私は残念ながら、自然言語処理は初心者に毛が生えた程度(現在、鋭意勉強中)で、対応方法に問題があるかもしれません。気づいた方はコメントをいただけると助かります。\n辞書ファイルについて NAIST-JDic for MeCabの辞書ファイルは以下の構成になっています。\nファイル名 メモ char.def 文字種の設定 feature.def 辞書学習用の設定? left-id.def左文脈IDのマスタ(左文脈ID、品詞情報) matrix.def 連接コスト表(前件文脈ID,後件文脈ID,連接コスト) pos-id.def 品詞IDのマスタ(品詞情報、ID) rewrite.def rewrite情報(左右文脈に出現した場合のそれぞれの品詞情報のrewriteルール。辞書学習で主に利用) right-id.def 右文脈IDのマスタ(右文脈ID、品詞情報) unk.def 未知語の品詞情報(文字種ごとに未知語のコスト、左右文脈ID、品詞情報が記載されている) naist-jdic.csv 単語辞書(単語、左右文脈ID、単語コスト、品詞情報、読みなど記載) 現時点では、MeCabDicPreprocessorでは以下のファイルを利用しています。\nleft-id.def matrix.def right-id.def naist-jdic.csv 上記以外のファイルは現時点では利用しない実装になっています。 ただし、rewrite.def、unk.def、char.defについては利用したほうがよりMeCabに近い結果が得られるような気がしています。(特に文字種ごとのコストを利用することは有効と思われます。)\nPreprocessorでの処理について lucene-gosenはSenの後継であり、MeCabの昔のバージョンを移植したものがベースとなっています。 lucene-gosenとMeCabの現時点での実装の大きな違いとして、連接コスト表の違いがあります。 ここからは憶測になってしまいますので、注意してください。(論文を探せばどこかにこの実装の変化の過程が記載してあるかもしれないですが、まだ探していません、すみません。) 過去のMeCabではChaSen向けの辞書を利用していました。 ChaSenでは連接コスト表が3つの項(前の前、前、後)から構成されていました。(n項まで定義可能らしい) ですので、lucene-gosenのViterbiアルゴリズムの引数も3つのノードが引数となっています。 lucene-gosen向けの連接コスト辞書も同様の作りになっています。 一方、現在のMeCabは先ほど書いたとおり、matrix.defでは2項の連接コスト表(前、後)となっています。この違いを保管するために、Preprocessorでは、matrix.defを3項にするために一番左(前の前)については任意の品詞を採用できるように「,,,,,,*」のみを設定しています。\n現時点では、Preprocessorの出力である中間ファイルを共通の形式に出力することで、DictinaryBuilder以降の処理に変更を加えることなくNAIST-JDic for MeCabへの対応を行う形を取りました。まずは使えるようにするのが先かと思いまして。 ただ、MeCabの辞書の構成から考えると中間ファイルに落とし込む処理に無駄があると感じています。 matrix.defでせっかく、IDによる連接コスト表を構成しているのに、IDを品詞情報の文字列に戻したconnection.csvを生成していますので。\nということで、備忘録でした。 あとは、テストをどうするか(正解をどう考えるか)なども考える必要があります。現時点での悩みの種です。。。アイデア募集中です。\n","date":1310432760,"dir":"post/2011/","id":"c70b78fd0b5dffcd38322355e9c2471e","lang":"ja","lastmod":1310432760,"permalink":"https://blog.johtani.info/blog/2011/07/12/naist-jdic-for-mecab%E3%81%AEpreprocessor%E3%81%AE%E5%AE%9F%E8%A3%85%E3%81%AB%E9%96%A2%E3%81%99%E3%82%8B%E5%82%99%E5%BF%98%E9%8C%B2/","publishdate":"2011-07-12T10:06:00+09:00","summary":"忘れてしまうので、備忘録を残しておきます。 一応、ソースには少しずつコメントをいれてはいるのですが。 私は残念ながら、自然言語処理は初心者に毛が","tags":["lucene-gosen"],"title":"NAIST-JDic for MeCabのPreprocessorの実装に関する備忘録(Jugemより移植)"},{"contents":"lucene-gosen 1.1.1をリリースしました。\n先日お知らせしたバグ修正を取り込んだjarを用意いしました。\nダウンロードはこちらから\n","date":1309777240,"dir":"post/2011/","id":"229975f1e84b5088e819cd5f2dc43080","lang":"ja","lastmod":1309777240,"permalink":"https://blog.johtani.info/blog/2011/07/04/lucene-gosen-1-1-1%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9/","publishdate":"2011-07-04T20:00:40+09:00","summary":"lucene-gosen 1.1.1をリリースしました。 先日お知らせしたバグ修正を取り込んだjarを用意いしました。 ダウンロードはこちらから","tags":["lucene-gosen"],"title":"lucene-gosen 1.1.1リリース(Jugemより移植)"},{"contents":"Solr/Lucene 3.3がリリースされました。(速報)\n以下、各サイトへのリンクです。\nSolrリリースのお知らせ\nLuceneリリースのお知らせ\nリリースのタイミングがどんどん早くなってる。。。\n","date":1309501779,"dir":"post/2011/","id":"10eb1e7dc64d8ca3dad92641dadb5de7","lang":"ja","lastmod":1309501779,"permalink":"https://blog.johtani.info/blog/2011/07/01/lucene-solr-3-3%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E9%80%9F%E5%A0%B1/","publishdate":"2011-07-01T15:29:39+09:00","summary":"Solr/Lucene 3.3がリリースされました。(速報) 以下、各サイトへのリンクです。 Solrリリースのお知らせ Luceneリリースのお知らせ リリースのタイミ","tags":["solr"],"title":"Lucene/Solr 3.3リリース(速報)(Jugemより移植)"},{"contents":"「Hadoopを中心とした分散環境での開発方法論・モデリング・設計手法等についての座談会(第5回)」に参加しました。300名入るイベントルームでしたが、後ろの方まで人が埋まっていました。\nということで、主に自分用ですが、メモを取ったので。\n※二次会行きたかった。。。\n1.「鉄道システムへの誘い」\n@ayasehiro(本名無理w)\nHadoopの話はありません。\n○鉄道系基幹システムの開発\n実態:\n耐用年数:10年以上\n開発期間:数年~5年程度\n開発規模:~10Mステップ、10k人月~\nほとんどテスト、しかも異常系が主体。\n夜間に実際に鉄道を走らせて試験したり。\n開発サイクルが長い\n人材育成が難しい、ノウハウがたまらない。\n開発自体はほとんど時間がなく、設計・製造・試験など新規技術の採用が難しい。\n開発4年前の調査・検証自体が2年程度。\nHadoopも調査中。\n○鉄道システム3大システム\nマルス(予約オンラインシステム)(1960~)\nコムトラック(運行管理システム)(1972~)\nヤックス(ヤード自動化システム)(1968~1984)\n○鉄道輸送システムとは\n用語:\n運行を計画する=\u0026gt;輸送計画\n列車を運行する=\u0026gt;運行管理\n需要想定+営業施策+その他(お召し列車など)=列車ダイヤ作成\n基本計画(長期)+短期計画(数日~四半期程度)=列車ダイヤ(重ねあわせてできあがり)\nダイヤの計画(発車時刻など)と車両運用(車両自体の走る組み合わせ(仮の車両))の作成\n+乗務員運用(乗務員の運用計画)\n運行管理:\nなにも起きなければすることなし。(車両故障、天候、人身事故などによる整合性を取る作業)\n=事前に計画した輸送計画をすべて見直し\n遅延の検知は?\n昔:人による伝令\n今:システムによる検知(レールに電流流して検知)\n運転整理(実際に遅れた):\n部分運休、折り返し駅の変更などにより対応\n元の計画になるべく近づく形で修正していく。\n新幹線、山手線、京浜東北線などは速度信号という信号が表示される。\n線路上に信号はないらしい。\n○鉄道システムを取り巻く情勢\n少子高齢化・人口減少のため凋落産業となっている。\n社会インフラの責務=動くのが当たり前\n2007年問題(ベテランの引退)=スジ屋さんは最近いないらしい。\n高度な判断支援をするシステムが必要\n連続稼動=分散技術を適用できない?\n関係各所との情報共有\n計画立案のための情報支援=最適化技術を適用できない?\n○分散処理技術の適用\n個人的な感想\n可用性(連続稼動)のための仕組み\nバッチ処理\n○分散技術の適用\n・連続稼動\nactive-active構成がメイン\n主系の出力だけを行う。問題が出れば副系の出力。\n3系統の出力を比較器にて出力もある\nmagiシステム\n問題点:\nハードが高い(H社)\nソフトウェアの作り込みが複雑=テストが前パターンできない\n解決案:\n汎用的なハードが使いたい。\n作り込みも減らしたい\n・バッチ処理:\nAsakusa使えないかなーw\n○最適化技術の採用\nコンピュータ技術の発展\n2007年問題\n職人に言わせれば最適化はいらない、俺の言うことを聞けw\n・車両運用のモデリング\n車両数大=\u0026gt;組み合わせ大\n制約条件が多い\n車両運用の場合、走行累積キロの条件もある\n-\u0026gt;有向グラフにモデル化される。(ただし、グラフ化するまでが大変)\n・乗務員運用のモデリング\n車両と違い、乗務員は1回で2人とか運べる(運転士+移動する人とか)\n・車両割当のモデリング\nやはり、グラフ化が可能\n・乗務員交番のモデリング。。。など\n結構一般的なモデルに落とし込める。ただし、落し込みが大変。\n机上研究だったものが、コンピュータの発展により実証研究になりつつある。\n○まとめ\n鉄道システムはまだまだ未到の領域が残っている。\n開発サイクルが長いため、保守的な開発になる(35年前の設計思想からあまり変わってなかったりする)\nしかし業務要件やシステム利用者の意識は変化している\n興味を持たれた方は、ぜひ、我社に!(社名は2次会でw)\n○Q\u0026amp;A\nQ:鉄道システムのカルチャーってイケイケ?保守的?(@okachimachiorgさん)\nA:最新技術も知らないとだめじゃないかという人が出てきている。\nコア部分(安全第一なところ)+周辺領域(ある程度融通が効きそうな部分)と考えることができるんじゃないかって人も出てきている。\nJR九○=先進的\nJR四○、北○道=お金ない\nJR○海=超保守(企業的に超保守)\nJR東、西=うーむ?\n東京メト○(運行計画)、阪○=先進的\n京○急行=基本人間で進路制御w\n基本的には新しいものには興味をもつ人たちでは。\nQ:Su○caとかで分散処理は利用出来るんでは?\nA:匿名なので外側から見ていると分散処理はいろいろ使えるんでは?\nログデータからいろいろできるんじゃないの?活かすべきでないの?\n使いどころはいっぱいある。\nQ:鉄道システムでどうしようもなくなったことはあるか?\nA:保守体制が一番気になる。\nOSSとかならまだ調べられる。ミドルウェアなどの保守契約が必要。\n保守体制が確立されてればある程度の保守費用は飲み込む。\nどうしようもないことはないが、今すごく困ってることは\nExcelで帳票を出したいとかいわれること。(ちょっと前に作ったシステムでExcel2003。バージョンあげると速度が遅くなったりするw)\nilog社のものを使ってたが、IBMに買収されて保守費用があがってこまってるw\n保守が10年と長いため、サポートなどの折衝が必要。\nQ:最適化の適用範囲は?\nA:走行順序(どこで追い抜くか)の算出に活用。ほぼ完成でユーザ教育中。\n1列車の波及がかなり影響が出る。ダイヤだけ見ると列車だけだが、乗務員も関係しており、大変。\nある時点から終電までを最適化の対象としたりして割り切っている。\nまた、不足分について算出が出来れば、そこで打ち切ったりもする。\n2.「九州電力におけるHadoopの取り組みについて」\n株式会社キューデンインフォコム e-ビジネス部 @hisashi_yano\n概要:2年間関係したOSSをメインにしたシステムの話。\n○九州電力の概要\n現在風当たりが強い業界。\n東電の1/10くらい\n部門ごとに大手ベンダーが関わってる。\n○Hadoop採用の経緯\n部門ごとに個別最適なシステムを導入していてベンダーロックインされてる。\n・ホストのリプレース\n・両現用センター構成への対応\n・スマートグリッドへの対応\n問題点\n・コスト削減\n・技術革新への中の人の対応(内部でも問題を理解できるように)\n・商用パッケージのカスタマイズの限界\n・脱ベンダーロックイン(実は楽なんだけど。。。)\n○過去2年間の研究内容\n・H21年度の結果\nテーマ:クラウドの要素技術の研究\nKVM、Eucalyptus、wakame、hadoop 性能比較:VMWareとKVM-\u0026gt;ベンチマーク比較\n結論:性能的にあまり問題なし。\nMapReduceの耐障害性など\nダミーデータにより台数増加による影響を検証\n結論:台数大-\u0026gt;性能向上\nストリーミングは性能劣化する\nスループットはリニアに向上\n信頼性は?\n実行中にノードを抜いたりして検証。\n結論:問題なし。\nクラウド環境におけるシステム管理手法\n複数ハードで1アプリという構成になる。\n監視対象が膨大になる。\n障害発生時の切り離しや監視対象も膨大。\nデータセンター自体を監視する仕組みが必要では?というところで終了。\n・H22年度の結果\n分散に特化した研究\n前年度の課題\nサーバの仮想化・管理に関する課題\n分散処理に関する課題\n分散処理環境の運用監視に関する課題\n目的:\nHadoopを本番への適用(実際にはダミーデータ+本番の仕組み)\n柔軟なサーバ統合基盤(サーバを起動-\u0026gt;バッチを起動-\u0026gt;回す仕組み)=MonkeyMagic\nlibvirtを使ってる\n50台の仮想サーバの起動が10数分で完了。\n運用監視基盤(monkey magic)\n仮想、実サーバ混在の監視\n監視状況(サーバの状況)から判断して制御する仕組みを構築\nDSLにてルール(判断+制御)を指定\n・ジョブの監視\n・ジョブの実行管理\n・構成管理の省力化\nvolanteと連携が可能=AmazonWebServiceとも連携可能\n・サーバリソース+アプリケーションの一括監視が可能\n分散バッチ処理の概要\nRDBからKV形式にして抽出し、MRで回してRDBに戻すという研究\n対象:\n配電部門(電柱の設備情報の目視検査)のデータの月間バッチ処理\n現状:\n19時間程度かかってる。\nテスト環境:\n実サーバ2台(仮想10台)\nMySQL、Javaで実装\n処理内容\n電柱104万本\n巨大バッチを分割して実装\n結果\nMySQL1台では15日以上かかる処理(現行システムで19時間)\n処理が32分で終了!他でも効果でるよね。\nバッチ短縮の理由は?\n1.データアクセスが分散された\n2.処理の並列化(多重化出来る部分がうまくできた)\n分散処理を書くのに2名死亡。。。\n適用基準の策定、開発ガイドライン、フレームワーク整備などが必要。\n・H23年度は?\nAsakusaの適用など。\n・さらに今後は?\nスマートグリッドへの適用\n-\u0026gt;メーターの交換が必要だが、10年くらいかかる\n-\u0026gt;スパンが長い(10年)ので商用製品だときつい?\nデータ量も半端ない。\nテネシー州とClouderaでOpenPDCってのやってるらしい。\n電力と気温の関係は密接な関係あり。\nエアコンが割合を占めてるから。\n過去実績と予想気温データから分析するのにHadoop使える!\n・2年間やってきて思うこと\n将来目指すべき理想像を掲げるのが重要\n新技術導入は段階を踏むことが必要\nコミュニケーション大切!\n○Q\u0026amp;A\nQ:仮想化環境のオーバヘッドは?(I/O)\nA:台数を増やしたときにどうなるか?というのを検証したかった。\nアプリ配布も考えていたので、物理サーバに縛られたくなかった。\nQ:仮想化に関して気をつけたM/RのPGで気をつけたことありますか?\nA:まったくないです。\nQ:日本でスマートグリッドははやるの?\nA:電力会社的にはやりたくない。費用対効果があまりない。\nQ:今後のスケジュールは?\nA:文書管理システムの組織名変更などの処理時間が540時間とかでてくるらしい。\nこれをHadoopで対応してみようかと思ってる。\nQ:Asakusaをどう評価していくのか?\nA:開発効率性があがるか?は検証する予定。1/3くらい楽になるんじゃないかなぁ?byのぐちさん\nバッチの種類などにもよると思うが、標準化も指標にする予定。\n結果はまたこの場で報告する予定。\nQ:Asakusa+MonkeyMagicの連携はどんなこと考えてる?\nA:MonkeyMagicを運用基盤として行く予定。合意が取れればだけど。\n※MonkeyMagicもOSSにするよー\nまとめ\nHadoopから少しずつ離れつつありますが、やはり興味があるので、非常に楽しく話を聞けました。\nまた、今回はインフラ分野のシステムということで、システムに要求されるレベルや\n運用周りにも気を配っている話が聞けたのが収穫でした。保守期間が長いため、テストが長い=\n運用もしっかりと考慮を入れた設計、実装が必要になるというのは最もだと思います。\nただ、少しずつ修正が入るアジャイルなども同様かと。\nMonkeyMagicが出来上がってきた背景の話を聞いて、さらに興味が湧いてきたところです。\n今後もかかわりが少ないかもしれないですが、ウォッチしていきたいと思いました。\nただ、興味あるモノが多すぎるので、優先度をつけつつこなして行かないと。。。\n少しずつでも身につけていきたいと思う今日このごろです。\n※追記:Twitterでコメントを頂いたので、忘れないように追記。\nコメントを貰えるだけでもうれしい。やはり、アウトプットしたらフィードバック貰いたいし。\nありがとうございます!\nTwitter / @cocoatomo: あの質問をまとめるとこうなるのかぁ…… 最適化そのも \u0026hellip;\nTwitter / @cocoatomo: @johtani すみません, コメントはコメント欄 \u0026hellip;\nTwitter / @cocoatomo: @johtani そこらへんの理論って最後には計算量 \u0026hellip;\nTwitter / @cocoatomo: @johtani あの話し振りだとどうもまだ本格的に \u0026hellip;\nあと、まとめも出来ていたので、ついでに。\nTogetter - 「2011/06/29_Hadoopを中心とした分散環境での開発方法論・モデリング・設計手法等についての座談会(第5回) #hadoopmodeling」\n関連するブログも見つけたので。\n第5回Hadoop座談会の感想 - ひしだまの変更履歴\nHadoopモデリング座談会(第5回)へ行ってきました - 虎塚\n","date":1309356600,"dir":"post/2011/","id":"49ba23148db9effdc3979aa0fe5876ea","lang":"ja","lastmod":1309356600,"permalink":"https://blog.johtani.info/blog/2011/06/29/hadoop%E3%82%92%E4%B8%AD%E5%BF%83%E3%81%A8%E3%81%97%E3%81%9F%E5%88%86%E6%95%A3%E7%92%B0%E5%A2%83%E3%81%A7%E3%81%AE%E9%96%8B%E7%99%BA%E6%96%B9%E6%B3%95%E8%AB%96%E3%83%A2%E3%83%87%E3%83%AA%E3%83%B3%E3%82%B0%E8%A8%AD%E8%A8%88%E6%89%8B%E6%B3%95%E7%AD%89%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E3%81%AE%E5%BA%A7%E8%AB%87%E4%BC%9A-%E7%AC%AC5%E5%9B%9E%E3%81%AB%E5%8F%82%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F/","publishdate":"2011-06-29T23:10:00+09:00","summary":"「Hadoopを中心とした分散環境での開発方法論・モデリング・設計手法等についての座談会(第5回)」に参加しました。300名入るイベントルー","tags":["hadoop"],"title":"Hadoopを中心とした分散環境での開発方法論・モデリング・設計手法等についての座談会(第5回)に参加しました。(Jugemより移植)"},{"contents":"以前、こちらで話題に上がっていた「未知語」に関するcompositePOSのエラーの件を調査しました。(Twitterでも流れてました。) 次のような条件の場合にエラーが発生するようです。\ncompositePOSの設定に構成品詞として「未知語」が指定されたエントリが存在する。 未知語が連続して出現する文字列をanalyzeする。(例:ニンテンドーDSi) ということで、trunkに修正版をコミットしました。 Issueはこちら。\n※お茶をにごす感じの日記になってしまいました。次回はマシな記事を書く予定です。。。\n6/29追記:恥ずかしいバグをいれこんでしましました。。。 ということで、trunkに再度修正版をコミットしました。\n","date":1309232160,"dir":"post/2011/","id":"f6dff70097776e24c2a7c9c0f2514f79","lang":"ja","lastmod":1309232160,"permalink":"https://blog.johtani.info/blog/2011/06/28/compositeposcompositetokenfilter%E3%81%AE%E3%83%90%E3%82%B0%E4%BF%AE%E6%AD%A3/","publishdate":"2011-06-28T12:36:00+09:00","summary":"以前、こちらで話題に上がっていた「未知語」に関するcompositePOSのエラーの件を調査しました。(Twitterでも流れてました。) 次","tags":["lucene-gosen"],"title":"compositePOS(CompositeTokenFilter)のバグ修正(Jugemより移植)"},{"contents":"lucene-gosenのtrunkbranches/impl-mecab-dicにNAIST-JDic for MeCabの辞書を利用出来るPreprocessorをコミットしました。\nビルド方法は次のとおりです。\n$ cd lucene-gosen-trunk $ ant -Ddictype=naist-mecab 現在のstable版で利用できる辞書は「ipadic」「naist-chasen」の2種類でした。\n[以前の記事](http://johtani.jugem.jp/?eid=4)に書きましたが、naist-chasenの辞書でも2008年の更新となっています。\n今回コミットしたPreprocessorでは[NAIST-JDicのサイト](http://sourceforge.jp/projects/naist-jdic/)で公開されているMeCab向けの辞書である「mecab-naist-jdic-0.6.3-20100801」を利用出来るようになります。\nただし、lucene-gosenは昔のMeCabから派生したSenをもとにしていますので、最新のMeCabが持っている機能は\n利用できません。\nMeCab向けの辞書のうち一部のもの(matrix.def、naist-jdic.csvなど)を利用してlucene-gosen向けの辞書の中間ファイルを生成する仕組みになっています。\nまだ、仮実装版ということで、とりあえず動作するバージョンとなっています。\nまだテストが不十分ですが。。。\n利用してみて問題などあれば、lucene-gosenの[issue](http://code.google.com/p/lucene-gosen/issues/list)に登録していただくか、コメントを頂ければと思います。\n※更新が週1回に落ちてきてるので、もう少し頑張らねば。\n※2011/07/04追記 trunkにコミットしていましたが、branchに一旦移動しました。 仮実装として一旦コミットしたので、trunkとは別でテストする必要があるかと思った次第です。 ということで、試してみたい方は、[branches/impl-mecab-dic](http://code.google.com/p/lucene-gosen/source/browse/#svn%2Fbranches%2Fimpl-mecab-dic)にありますので、触ってみてください。 ","date":1308609480,"dir":"post/2011/","id":"991285e3967c3295b4ff2dcd835f7c61","lang":"ja","lastmod":1308609480,"permalink":"https://blog.johtani.info/blog/2011/06/21/naist-jdic-for-mecab%E5%AF%BE%E5%BF%9C%E7%89%88%E4%BB%AE%E5%AE%9F%E8%A3%85/","publishdate":"2011-06-21T07:38:00+09:00","summary":"lucene-gosenのtrunkbranches/impl-mecab-dicにNAIST-JDic for MeCabの辞書を利用出来るPre","tags":["lucene-gosen"],"title":"NAIST-JDic for MeCab対応版(仮実装)(Jugemより移植)"},{"contents":"前回、naist-chasenではアルファベットが別々の単語としてanalyzeされてしまうという話をしました。\nただ、これだと、英単語が含まれた文章を形態素解析すると、英単語がアルファベット単位に区切られてしまい、 単語の意味をなさなくなってしまいます。\nlucene-gosenでは、この問題に対応するための方法が提供されています。 CompositeTokenFilter(compositePOS)という機能です。\n文字通り「トークン」を「合成」するための機能になります。\n利用するためには以下の作業が必要です。(※Solrでのの利用方法を説明します。)\ncompositePOS設定ファイル(composite_pos_ja_naist-chasen.txt)の用意 schema.xmlのtokenizerにcompositePOS設定を追加 まずは、compositePOS設定ファイルの記述方法について説明します。 compositePOS設定ファイルには1行につき1つのcompositeの設定を記述していきます。 記述方法は次のようになります。品詞名を半角スペース区切りで記述します。\n連結品詞名 構成品詞名1 構成品詞名2 ... 構成品詞名n それぞれは次のような意味を持ちます。\n連結品詞名:合成したあとのトークンの品詞として出力する品詞名 構成品詞名:合成したい品詞名(スペース区切りで複数指定可能) TokenizerのcompositePOS機能は、構成品詞に定義されたトークンが連続して出力された場合に、 結合(合成)して1つのトークン(連結品詞名)として出力します。 また、以下のように構成品詞名が1種類で連続品詞名としても利用する場合は次のように省略した記述も可能です。\n以下にcompositePOSファイルの設定例を上げます。 ※なお、現時点では#によるコメント機能はありません。ので、記述した内容がそのまま利用されます。\n名詞-数 未知語 記号-アルファベット 1行目は連続した数字を1つのトークン(名詞-数)として出力する設定です。(連続品詞名=構成品詞名として省略して記述した例になります。) 2行目は連続したアルファベットを1つのトークン(未知語)として出力する設定です。\n次にSolrのschema.xmlにlucene-gosenのtokenizerを利用するフィールドタイプの設定を記述します。 $SOLR_HOME/conf/schema.xmlに以下を追加します。\u0026lt;types\u0026gt;~\u0026lt;/types\u0026gt;タグの間に記載します。\n... \u0026lt;types\u0026amp;gt; ... \u0026lt;fieldType name=\u0026amp;quot;text_ja\u0026amp;quot; class=\u0026amp;quot;solr.TextField\u0026amp;quot; positionIncrementGap=\u0026amp;quot;100\u0026amp;quot;\u0026amp;gt; \u0026lt;analyzer\u0026amp;gt; \u0026lt;tokenizer class=\u0026amp;quot;solr.JapaneseTokenizerFactory\u0026amp;quot; compositePOS=\u0026amp;quot;composite_pos_ja_naist-chasen.txt\u0026amp;quot;/\u0026amp;gt; \u0026lt;/analyzer\u0026amp;gt; \u0026lt;/fieldType\u0026amp;gt; \u0026lt;/types\u0026amp;gt; ... 重要なのはtokenizerタグのcompositePOS属性になります。ここに1.で記載したファイルを指定します。指定したファイルはschema.xmlと同じディレクトリに配置します。 以上が利用するための設定です。\n前回同様、「このComputerは、10回に1回の割合で起動中に青い画面が表示されます。」という文章をanalyze画面で解析した結果を示します。\nとまぁ、記事を書きましたが、すでにこちらで出ている話ですね。。。\nみなさん手が早くて困ってますw\nちなみに、上記の設定の場合、「100,000」や「3.14」といった文字列は「100」「,」「000」という形で出力されてしまいます。これらも数字とみなしたい場合は「名詞-数 名詞-数 記号-句点 記号-読点」という設定で1つのトークンとして出力されます。ただし、「。」も「記号-句点」なので注意が必要です。\n※なお、今回はlucene-gosen-1.1.0、Solr3.2を利用した例になっています。 ","date":1307977200,"dir":"post/2011/","id":"50f43b1726cf61066ef8656477b226be","lang":"ja","lastmod":1307977200,"permalink":"https://blog.johtani.info/blog/2011/06/14/compositepos%E3%81%AE%E5%88%A9%E7%94%A8%E4%BE%8Bnaist-chasen%E3%81%A7%E3%81%AE%E8%8B%B1%E5%8D%98%E8%AA%9E%E3%81%AE%E5%87%BA%E5%8A%9B%E6%96%B9%E6%B3%95%E4%BE%8B/","publishdate":"2011-06-14T00:00:00+09:00","summary":"前回、naist-chasenではアルファベットが別々の単語としてanalyzeされてしまうという話をしました。 ただ、これだと、英単語が含ま","tags":["lucene-gosen"],"title":"compositePOSの利用例(naist-chasenでの英単語の出力方法例)(Jugemより移植)"},{"contents":"lucene-gosenの1.1.0がリリースされました。\n大きな目玉はJapaneseTokenizerが出力する形態素に関するデータを遅延ロードすることで、パフォーマンスの改善を行ったことです。\n詳しくは関口さんのブログで実測されてます。さすが、早い。。。 あと、先日リリースされたLucene/Solr 3.2への対応も行われています。\nlucene-gosen-1.1.0のダウンロードはこちらから。\nうーん、中身がない記事だ。。。\n","date":1307934480,"dir":"post/2011/","id":"eeef60efe889349870426d10edc694be","lang":"ja","lastmod":1307934480,"permalink":"https://blog.johtani.info/blog/2011/06/13/lucene-gosen-1-1-0-%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9/","publishdate":"2011-06-13T12:08:00+09:00","summary":"lucene-gosenの1.1.0がリリースされました。 大きな目玉はJapaneseTokenizerが出力する形態素に関するデータを遅延","tags":["lucene-gosen"],"title":"lucene-gosen 1.1.0 リリース(Jugemより移植)"},{"contents":"lucene-gosenをSolr/Luceneで利用する場合、TokenFilterを利用してTokenizerが出力したToken対してさまざまな処理(Tokenに対する正規化や展開など)を追加することが可能です。\n今回は現在(ver. 1.0.1)用意されているTokenFilterについて説明します。 以下はTokenFilterの一覧です。 「フィルタ名」にはSolrのschema.xmlで記述するクラス名を書いてあります。\nフィルタ名(Factory名) 概要 solr.JapaneseWidthFilterFactory 全角のASCII文字を半角に、半角カタカナを全角にするフィルタ。例:「Computer」-\u0026gt;「Computer」 solr.JapanesePunctuationFilterFactory 区切り文字、記号などを除外するフィルタ。[※1](#token_filter_kome_1) solr.JapanesePartOfSpeechStopFilterFactory 設定ファイルに記載した品詞に該当するTokenを除外するフィルタ。ファイルは「tags=\"ファイル名\"」とfilterに記載。なお、ここで記述する品詞とはanalysis画面に表示される「partOfSpeech」の完全一致となります。 solr.JapanesePartOfSpeechKeepFilterFactory 設定ファイルに記載した品詞に該当するToken\"以外\"を除去フィルタ。ファイルは「tags=\"ファイル名\"」とfilterに記載。なお、ここで記述する品詞とはanalysis画面に表示される「partOfSpeech」の完全一致となります。 solr.JapaneseBasicFormFilterFactory Tokenを基本形に変換するフィルタ。例:「悲しき」-\u0026gt;「悲しい」 solr.JapaneseKatakanaStemFilterFactory カタカナの長音(ー)の正規化フィルタ。4文字以上のカタカナのみの文字列の最後の長音(ー)を除去した文字列に変換します。例:「コンピューター」-\u0026gt;「コンピュータ」、「コピー」-\u0026gt;「コピー」 上記のTokenFilterをJapanizeTokenizerを利用するフィールドタイプに設定することで 各フィルタによる機能が有効になります。 schema.xmlの記載に関する詳細についてはこちらを参考にしてください。\n※1 Characterクラスの以下の定数に相当する文字が。SPACE_SEPARATOR、LINE_SEPARATOR、PARAGRAPH_SEPARATOR、CONTROL、FORMAT、DASH_PUNCTUATION、START_PUNCTUATION、END_PUNCTUATION、CONNECTOR_PUNCTUATION、OTHER_PUNCTUATION、MATH_SYMBOL、CURRENCY_SYMBOL、MODIFIER_SYMBOL、OTHER_SYMBOL、INITIAL_QUOTE_PUNCTUATION、FINAL_QUOTE_PUNCTUATION\n","date":1307344980,"dir":"post/2011/","id":"4b046ac6a4796fb1338f0481dbd4003d","lang":"ja","lastmod":1307344980,"permalink":"https://blog.johtani.info/blog/2011/06/06/lucene-gosen%E3%81%AEtokenfilter%E3%81%9F%E3%81%A1/","publishdate":"2011-06-06T16:23:00+09:00","summary":"lucene-gosenをSolr/Luceneで利用する場合、TokenFilterを利用してTokenizerが出力したToken対して","tags":["lucene-gosen"],"title":"lucene-gosenのTokenFilterたち(Jugemより移植)"},{"contents":"辞書の特性について 現在lucene-gosenでは以下の2つの辞書が利用可能です。 簡単に違いについて説明します。\nIPAdicの辞書について\nバージョン:2.6.0(※IPAdicとして公開されている最新は2.7.0) 最終更新日:2003/06/19 登録単語数:約24万語 NAIST-Jdicができたためか、更新されていない NAIST-Jdic-for-ChaSenの辞書について\nバージョン:0.4.3(※NAISTとして公開されている最新はMeCab用の辞書0.6.3) 最終更新日:2008/07/07 登録単語数:約28万語 IPAdicの後継として整備。品詞の定義など大まかな仕様は共通。 IPAdicと異なり、アルファベットや数字が1文字ずつ単語として登録されている。 IPAdicとNAIST-Jdicで大きな違いはアルファベットと数字の扱いについてです。 次のような文章をそれぞれの辞書で解析した結果は次のようになります。(SolrのField Analysisの画面です。思いの外大きいのでサムネイルのみですが。) 「このComputerは、10回に1回の割合で起動中に青い画面が表示されます。」 ○IPAdicの場合 ○NAIST-Jdicの場合 「Computer」と「10」という単語の区切り方が異なることがわかります。 この違いは、辞書のエントリが異なるために発生します。 NAIST-Jdicでは、数字(例:「1」)やアルファベット(例:「a」)が個々のエントリで登録されているため、分割された単語として認識されます。\n※この問題への対応方法はまた後日。\nカスタム辞書について 実際のデータを形態素解析したい場合、辞書に存在しない単語を登録して、1単語として認識させたい場合があります。(固有名詞など) このような場合にカスタム辞書を利用することで、新しい単語を辞書に登録することが可能になります。 カスタム辞書を利用する手順としては次のようになります。\nカスタム辞書ファイルの作成 作成した辞書ファイルを利用したjarファイルの生成 まずは辞書ファイルの作成についてです。 以下では、naist-chasen(NAIST-Jdic)の辞書を例として説明します。(ディレクトリの違いだけで、IPAdicでも同じ方法でOKです。)\nlucene-gosenでは辞書のコンパイルに2つのフェーズが存在します。\ngosen用辞書を生成する前処理(中間csvファイルの生成) gosen用バイナリ辞書の生成 カスタム辞書は1の出力の形式(=中間csvファイル=dictionary.csv)にあわせたCSVファイルとして作成します。 CSVの各カラムは次のような意味を持っています。\n単語 単語の生起コスト 品詞 品詞細分類1 品詞細分類2 品詞細分類3 活用型 活用形 基本形 読み 発音 3カラム目以降は「素性(そせい?)」と呼ばれる項目です。ipadic、naist-jdicでは「品詞」「品詞細分類1」「品詞細分類2」「品詞細分類3」「活用型」「活用形」「基本形」「読み」「発音」となります。 ※「見出し語」「形態素生起コスト」「素性」と呼ばれる項目を表形式にする。 厳密な品詞の体系に関してはIPAdicやNAIST-Jdicのサイトをご覧ください(説明できるレベルにはまだまだなっていないので。。。) 今回は、固有名詞(人名、地名など)を追加するという例でカスタム辞書について説明します。 固有名詞として「達川」という人名を追加してみましょう。 まずは、次のようなエントリをもつ「custom-dic.csv」ファイルを作成します。ファイルはUTF-8で保存してください。 コストはすでにあるエントリで似たようなエントリのコストを真似します。(今回は固有名詞,人名で似ているものを採用)。ちなみに、コストは小さいほど単語として出てきやすくなります。 ※カスタム辞書にはSenで利用していたものが利用できます。 **\"達川\",2245,名詞,固有名詞,人名,名,*,*,\"達川\",\"タツカワ\",\"タツカワ\"** 上記ファイルを、先日紹介した$LUCENE-GOSEN/dictionary/ディレクトリにコピーします。 では、カスタム辞書を含んだlucene-gosenのjarを作成しましょう。 カスタム辞書のビルドは$LUCENE-GOSEN/dictionary/で行います。 また、カスタム辞書の指定はCSVファイル名をantの引数で指定します。次がコマンドの例になります。\n$ cd lucene-gosen-trunk $ cd dictionary $ ant -Ddictype=naist-chasen clean-sen $ ant -Ddictype=naist-chasen -Dcustom.dics=\u0026#34;../custom-dic.csv\u0026#34; compile $ cd .. $ ant -Ddictype=naist-chasen 上記コマンドの例で\u0026quot;clean-sen\u0026quot;というタスクを実行しています。これは、すでに出来上がっているgosen用のバイナリ辞書を削除するタスクになります。すでにgosen用の辞書が作成されている場合には辞書の再生成が行われないためです。 また、複数のファイルを利用したい場合は-Dcustom.dics=\u0026ldquo;custom-dic.csv custom-dic2.csv\u0026quot;という形でスペース区切りでファイル名を記述すればOKです。\nカスタム辞書を適用する前と適用後の違いは次のとおりです。 適用前 適用後 簡単ですが、以上がカスタマイズ辞書を利用する方法でした。 ちなみに、この記事を書く前にすでにカスタム辞書の件を書いているブログがありました。。。こちらも参考にしてください。 今回の例でいくつかSolrのanalysis画面を利用して説明してきました。Solrでのlucene-gosenの利用方法についてはまた後日記載したいと思います。 ※参考までに。Solrでの利用方法はこちらにも記載してあります。\nまた、IPAdicなどの辞書について記載のある書籍を見つけましたので、参考になれば。\nアプリケーションソフトの基礎 (講座ITと日本語研究) ","date":1307002560,"dir":"post/2011/","id":"b2621497b3313c97855ed951f0d9b291","lang":"ja","lastmod":1307002560,"permalink":"https://blog.johtani.info/blog/2011/06/02/%E8%BE%9E%E6%9B%B8%E3%81%A8%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0%E8%BE%9E%E6%9B%B8%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/","publishdate":"2011-06-02T17:16:00+09:00","summary":"辞書の特性について 現在lucene-gosenでは以下の2つの辞書が利用可能です。 簡単に違いについて説明します。 IPAdicの辞書について バ","tags":["lucene-gosen"],"title":"辞書とカスタム辞書について(Jugemより移植)"},{"contents":"今回はソースのダウンロードとビルドについてです。\n最新版のソースを利用したり、JavaDocを見たい場合はソースをダウンロードしてからビルドすることになります。 ソースのダウンロードからビルドまでの手順について説明します。\nまずはソースのダウンロードです。\n$ mkdir ~/work $ cd work $ svn co http://lucene-gosen.googlecode.com/svn/trunk/ lucene-gosen-trunk $ cd lucene-gosen-trunk ダウンロードしたソースは次のようなディレクトリ構成です。\n.classpathEclipse用ファイル .projectEclipse用ファイル .settingsEclipse用ファイル AUTHORS作者のリスト(Sen、GoSen) CHANGES.txtlucene-gosenにおける更新履歴 COPYING.LGPLライセンス README.txtReadme build.xmlAntのビルドファイル dictionary辞書コンパイル用ディレクトリ docsAPIドキュメント用ディレクトリ libライブラリ prettifyGoogle Code Prettify用ディレクトリ(APIドキュメントでの色づけ用) srcソースコード また、辞書やソースのコンパイルにはAntを利用します。 通常利用するAntのタスクには次のようなものがあります。\ncleanプロジェクトのクリーンアップ build-dic辞書のコンパイル(辞書のダウンロードも行う) jarjarファイル生成 dist配布パッケージの生成(2つのjarファイル生成) javadocJavaDocの生成 jarファイルの生成までの大まかな流れは「javaソースのコンパイル」~「辞書のダウンロード」~「辞書のプレコンパイル」~「辞書のコンパイル」~「jarファイルの生成」となります。 Antのタスク以外にjarファイルを生成する場合に利用するオプションは以下の通りです。\n-Dproxy.hostプロキシのホスト -Dproxy.portプロキシのポート -Ddictype辞書の指定(指定可能なものは次の通り。naist-chasen、ipadic) 以下はNaist-Jdicのjarファイルを生成するコマンドの実行例になります。プロキシサーバを利用する環境の場合は-Dproxy.hostと-Dproxy.portも指定してください。(※認証が必要なプロキシの場合はAntのビルドファイルを修正する必要が出てきます。)\n$ ant -Ddictype=naist-chasen jarファイルはdistディレクトリに生成されます。 これで、jarファイルが利用できるようになります。\n次回は、ipadicとNaist-chasenの辞書の違いとカスタム辞書を利用する方法について書こうと思います。\n","date":1306398840,"dir":"post/2011/","id":"ff1441a42144a7de9a3eaf9f5e7cfea9","lang":"ja","lastmod":1306398840,"permalink":"https://blog.johtani.info/blog/2011/05/26/%E3%82%BD%E3%83%BC%E3%82%B9%E3%81%8B%E3%82%89%E3%81%AE%E3%83%93%E3%83%AB%E3%83%89%E3%81%A8%E6%A7%8B%E6%88%90/","publishdate":"2011-05-26T17:34:00+09:00","summary":"今回はソースのダウンロードとビルドについてです。 最新版のソースを利用したり、JavaDocを見たい場合はソースをダウンロードしてからビルドす","tags":["lucene-gosen"],"title":"ソースからのビルドと構成(Jugemより移植)"},{"contents":"概要: Lucene/SolrのコミッターであるRobert Muirさんが始めたプロジェクト 歴史: MeCabのJava移植版としてスタートしたSenがベースになります。 その後、辞書の構築部分をPerlからJavaに置き換えたGoSenが登場しました。 が、どちらもメンテナンスされなくなってきたので、Robertさんが引き継いでメンテナンスとLucene/Solr対応をはじめました。そして、現在にいたります。 ライセンス: LGPLライセンス(ベースになったMeCabのライセンスにならって) 特徴: 以下のような特徴があります。 ・Lucene/Solrですぐに利用可能(3.1、4.0に対応済み) ・jarファイル1つで利用可能(辞書をjarファイルに内包) ・LuceneのAttributeをベースにしたTokenの解析 ・その他(パフォーマンス改善、テスト改善など) プロジェクトのサイト: http://code.google.com/p/lucene-gosen/ ダウンロード: http://code.google.com/p/lucene-gosen/downloads/list 現時点では2つの辞書を内包したjarファイルが用意されています。 Naist-jdic 0.4.3(for ChaSen) 参考サイト:http://sourceforge.jp/projects/naist-jdic/ IpaDic 2.6.0 参考サイト:http://sourceforge.jp/projects/ipadic/ ","date":1306130400,"dir":"post/2011/","id":"5988b62a0c0785a303b77c74608e8b55","lang":"ja","lastmod":1306130400,"permalink":"https://blog.johtani.info/blog/2011/05/23/lucene-gosen%E3%81%A8%E3%81%AF/","publishdate":"2011-05-23T15:00:00+09:00","summary":"概要: Lucene/SolrのコミッターであるRobert Muirさんが始めたプロジェクト 歴史: MeCabのJava移植版としてスタートした","tags":["lucene-gosen"],"title":"lucene-gosenとは(Jugemより移植)"},{"contents":"今さらですが、ブログをはじめてみようかと。今さらですが…\nはじめてみようと思った一番の理由は、自分で調べたことをメモがわりに残すためです。 あとは、自分を追い込むためもありますが。(こっちが一番の理由かも)最近勉強してないなぁと感じているので。 ということで、まずは、lucene-gosenやsolrについて書いていく予定です。\n","date":1305859440,"dir":"post/2011/","id":"94b85ba716dbb7c20b230e69248b8208","lang":"ja","lastmod":1305859440,"permalink":"https://blog.johtani.info/blog/2011/05/20/%E3%83%96%E3%83%AD%E3%82%B0%E3%81%AF%E3%81%98%E3%82%81%E3%81%BE%E3%81%99/","publishdate":"2011-05-20T11:44:00+09:00","summary":"今さらですが、ブログをはじめてみようかと。今さらですが… はじめてみようと思った一番の理由は、自分で調べたことをメモがわりに残すためです。 あと","tags":["misc"],"title":"ブログはじめます(Jugemより移植)"}]
\ No newline at end of file
+[{"contents":"今年も振り返りブログをリビングで書いています(ドミノ倒しすごいな)。 FMVのキーボードで書いているのでタイポがつらい。。。\n振り返り(2022年に書いた抱負から) まずは振り返りをと。\nフリーランス継続 今年も個人事業主として乗り越えられました。 ZOZOさんには今年も引き続きお世話になっている感じです。 そのほかにベクトル検索のお手伝いをしたり、OpenSearchを調べたりといった仕事を手伝っています。 今年も完全にリモートで作業していましたが、イベントに出かけたりできました。 来年はもう少し出かける感じになるかな? 今年はすこしのんびり仕事をしていたので、来年はもう少し仕事探さないとかな(営業しないとなあ)\nプログラミング 今年はプログラムを書いたほうかなと。 Goで個人用ですが、Slackのボットを書いてみたり(GoでSlackのボットを作った話 | @johtaniの日記 3rd | @johtani\u0026rsquo;s blog 3rd edition)、公開されているAmazonのプロダクトデータを使って検索アプリを書いてみたり。 プロダクト用のアプリを書いているわけではないですが、ちょっとずつコードを読んだり書いたりしています。\nベクトル検索まわりをさわる がっつりとまではいかないですが、Elasticsearchのベクトル検索の調査をやったりしました。 Amazonのプロダクトデータを使ってもうちょっとやろうと思いつつ、そこまでは手が回せてない感じですが。 速度という面でどうやって折り合いをつけつつ導入するのか? どういうシーンでつかうのがいいのか? どのモデル選ぶのか?とか気になることだらけ。 なんか、みなさんがどうしてるのか気になってしょうがないので、話をしてもいいよという方は連絡をもらえるとうれしいかもなぁ。 ベクトル検索とかLLMの周りの動きがはやすぎてついていけてるのかどうか。。。\n本を読む 今年は比較的読んだかも?\n単体テストの考え方/使い方 ユーザーの問題解決とプロダクトの成功を導く エンジニアのためのドキュメントライティング ザ・ダークパターン ユーザーの心や行動をあざむくデザイン これまでの仕事 これからの仕事 機械学習による検索ランキング改善ガイド ソフトウェア設計のトレードオフと誤り 初めてのGo言語 買って読んでない本ももっとあるんですが。。。\n振り返り(今年あったできごと) ここからは今年の出来事を。 今年もずっと自宅でしごとしてました。 あとは少し仕事が少なめだったのでゲームが多くなってしまったかも?(本読めばいいのに。。。)\nゲーム(ONI、ゼルダ、FactorioのSpace Exploration) Dev container導入 検索技術勉強会の再開 ゼルダの新作面白かったですね。年初はOxigen Not Includedをやっていたのに、ゼルダが出てからはご無沙汰中です。ゼルダが終わった後は、ゼルダロスになってPythonを書いたりしていたのですが、うっかりFactorioのSpace Explorationを始めてしまい大変なことに。。。 全然終わる気配がないw\nローカルでの開発環境などをDev containerにちょっとずつしています。 Slackのボット、検索の遊び場、このブログ環境など。Dockerが必要にはなりますが、VSCodeとDev containerで環境を隔離できるし、VSCodeの拡張もコンテナごとに入れるのもできたりと便利です。\n最後は、検索技術勉強会を再開したことです。再始動という感じで4年ぶり?に再開しました(12月に開催した時のページ)。残念ながら私は裏方をしてただけで、当日は参加できてないのですが、次回(たぶん4月くらい)は参加するつもりです。再開の声を上げてくれた@takuya_aさんありがとう。絶賛スピーカーを募集中です。\n来年の抱負 さて、来年の抱負です。\nフリーランス継続 プログラミング継続 ベクトル検索の使い方をいろいろ試す 本を読んだブログを書く 今年もなんとかフリーランスを継続できましたが、そろそろ営業をしないといけないのかも? ということで、外でしゃべったりもしていかないとなぁと。 あとは、検索ってどうやって導入すればいいのか?検索どうすれば改善できる?みたいなところのお手伝いをもっとしたいと思っています。 昨年出したこの本もあるので(『検索システム ― 実務者のための開発改善ガイドブック』 – 技術書出版と販売のラムダノート)、勉強会をやろうとしているところに顔を出したりしたいなあ。 外部の人を呼んで社内勉強会とかをできるというところがあれば参加したいので、声をかけてもらえればと。\nプログラミングはGo言語を触ったし、今年後半には検索の画面回りのプロダクトを触ってTypeScriptを勉強していこうかなという気になっています(なっているだけかもしれない?)。\nベクトル検索の使い方は、LLMだったりRAGだったりが世の中を席巻しているのもあり、いろんな記事が出てきて全然追いつけていません。だれか、少人数で勉強会とかやると興味ある人とかいるかなぁ? こんなブログ見つけたよ、こんな論文があったよ、こんな使い方したらよかったよとかの共有をやるとみんな楽になったりしないかなぁ?\n今年は時々出かけて移動するタイミングで書籍を読んでいました。 読んだだけになってるのもあるので、少しでもいいからブログか何かに残しとかないとな。\nさて、今年は少しゆっくりできたので、来年はもうちょっといろんなところに顔を出しつつ、新しい仕事もできるといいなぁ。 勉強会もスピーカー集めをがんばるぞと。\nということで、今年もあと少しというところで無事書き終わりました。 来年もよろしくお願いいたします。よいお年をー\n","date":1704008961,"dir":"post/2023/","id":"d869fb48cb9acba03dc639481524ee80","lang":"ja","lastmod":1704008961,"permalink":"https://blog.johtani.info/blog/2023/12/31/review-2023/","publishdate":"2023-12-31T07:49:21Z","summary":"今年も振り返りブログをリビングで書いています(ドミノ倒しすごいな)。 FMVのキーボードで書いているのでタイポがつらい。。。 振り返り(2022","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2023)"},{"contents":"この記事は、情報検索・検索技術 Advent Calendar 2023の15日目の記事です。\n昨年に続き2回目の情報検索のAdvent Calendar参戦です。\n今年は、夏にオンライン参加したBerlin Buzzwordsの「The Debate Returns (with more vectors) Which Search Engine?」というセッションでPhilippさんが話題に出したOrama searchという検索エンジンを紹介してみようと思います(Oramaが正式名称なのかな?)。\nOramaという検索エンジン 公式サイトのトップにも記載がありますが、エッジで動作する全文検索&ベクトル検索エンジンというもののようです。 なにそれ?という感じがしますが、オープンソース版のドキュメントを見るともう少しわかりやすい説明になっています。\nOrama is a fast, batteries-included, full-text and vector search engine entirely written in TypeScript, with zero dependencies.\nOramaはTypeScriptで書かれた、依存なしで利用できる検索エンジンということです(batteries-includedって初めて見たかも。「必要なものがそろってる」とかいう意味みたい(参考:英語のWikipedia))。\n以下は公式サイトにあるサンプルです。\ncreateでスキーマの定義をした検索エンジンのインスタンスを生成します。 insertで先ほど生成した検索エンジンにデータをインデックスします(後で紹介しますが、一括でインデックスするメソッドも用意されています)。 searchで検索し、検索した結果が返ってきます。 以上です。あとは、必要に応じてGUIを用意するだけです。\nimport { create, insert, search } from \u0026#39;@orama/orama\u0026#39; const db = await create({ schema: { title: \u0026#39;string\u0026#39;, director: \u0026#39;string\u0026#39;, isFavorite: \u0026#39;boolean\u0026#39;, year: \u0026#39;number\u0026#39; } }) await insert(db, { title: \u0026#39;The Prestige\u0026#39;, director: \u0026#39;Christopher Nolan\u0026#39;, isFavorite: true, year: 2006 }) const searchResults = await search(db, { term: \u0026#39;prestige\u0026#39;, where: { isFavorite: true, year: { between: [2000, 2008] } } }) サクッと動きそうですよね?依存関係がなくTypeScriptで書かれているということは静的なサイトなどでコンテンツを検索するのに使えるのでは?\nということで、自分のブログに組み込んでみました。 今回は組み込んだ時の流れと気になった点などを紹介します。 Hugoに組み込む際になるべく簡単にしたかったので、unpkg.comで公開されているJavaScriptだけを利用する形で検索ページを作ってみました。 JavaScriptやTypeScriptは不慣れなので効率がよくなかったり、間違っている点があればコメントなどをいただけると嬉しいです。\n構成 私のブログサイトはHugoで生成(参考:Hugo導入時の記事)して、GitHub Pagesとして公開しています。 現在のブログ検索にはAlgoliaを利用しているのですが、テスト目的としてOramaも使えるようにしてみました(右上のメニューでOramaをクリックすると以下で説明するOramaによる検索を試すことができます。\n今回実装してみたのは次のような流れです(日本語検索対応については後で説明します)。\nHugoでJSONのリストを生成(これまでと一緒) 1.で生成したリストをもとにNodeのスクリプトでOramaのインデックスファイルを作成 2.で作成したファイルを公開 画面で3.のファイルをダウンロードして検索 1. HugoでJSONのリストを生成(これまでと一緒) HugoでJSONのリストを生成します。Algoliaに記事を登録するのにも利用している仕組みです。 検索に利用する記事の情報を1記事を1つのオブジェクトとして出力します。1つの配列に記事ごとのオブジェクトが入っているJSONファイルになります。\n少しだけ特殊なことをしています。 ブログ記事にTagsというフィールドのありなしで処理を分岐しています。 Oramaが配列にNullを受け取った場合にうまく動かなかったので出力するJSON側で調整しています(あとで再確認してIssueあげておかないと)\n2. 1.で生成したリストをもとにNodeのスクリプトでOramaのインデックスファイルを作成 最初に紹介した公式のサンプルの場合、毎回Oramaのインスタンスを生成した後にインデックス登録の処理を行わなければいけません。 ただ、Hugoで生成したコンテンツは特に動的に更新があるわけでもないので、検索画面を表示するたびにインデックス登録するのも無駄が多い気がします。 Orama単体で最初に実装した時には、1.で作成した記事一覧のJSONをOramaで実装した検索ページのスクリプトが呼ばれたタイミングでフェッチし、insertMultiple(複数登録用のメソッド)を呼び出す実装にしていました。\nOramaでは、あらかじめ作成したOramaのデータベースを永続化・リストアするためのData Persistenceプラグインが提供されています。 インデックスに登録する処理コストはHugoでコンテンツを生成した直後に行い、検索画面では作成済みのインデックスファイルをフェッチしてリストアする形にすることにしました。インデックスと記事のJSONデータを含んだファイルになるので、元の記事一覧のJSONよりはファイルサイズが大きくなってしまいますが、処理時間も含めて考えると許容できるサイズではないかなと。\n次のスクリプトは1.で生成したJSONファイルを読み込んで、Oramaでインデックスした後にdpackというバイナリ形式でファイルに保存しています。 こののプラグインで選択できる形式は現時点ではjson、binary(デフォルト=msgpack)、dpackの3種類になります。 残念ながら今回試したところ、binaryではエラーが発生したので、dpackを使用しました。\n3. 2.で作成したファイルを公開 単にGitHub Pagesに公開しているだけです。 ブラウザが2.で作成したインデックスファイルをフェッチしてから利用するためです。\n4. 画面で3.のファイルをダウンロードして検索 あとは検索画面です(長すぎるので、styleの部分は省略しています)。\nまず、必要なライブラリなどを読み込みます(下のソースコードの1行目から14行目)。\nOramaだけであれば問題ないのですが、OramaのプラグインがOramaをモジュールとして参照しているため、importmapとして定義しています。 Oramaのプラグインがいくつか利用しているものがあったので、まとめてimportmapに定義してあります。\n次に、検索窓(search-searchbar)や検索結果(search-hits)などのHTMLタグを用意します。 ヒット件数と検索にかかった時間も取れるので、表示する場所としてstatsも用意してあります。\n22行目からが実際の処理になります。\n28行目で、手順2.で作成したインデックスのファイルをフェッチします。 32行目でフェッチしたファイルから取り出した文字列をリストアして、Oramaのインスタンスを生成します。 34行目のtokenizerに関しては日本語対応で説明します。\n48行目のquery関数がクエリの組み立て+検索の処理です。search-inputで入力されたテキストをtermとして渡して検索をしています(56行目)。 検索した結果のリストをもとに検索結果のHTMLタグを組み上げていきます。 検索結果には後述する@orama/highlightのモジュールを利用してスニペットを追加しています。\n日本語対応 残念ながらOramaは公式には日本語をサポートしていません(サポートしているスキーマに設定できるlanguageの一覧(=STEMMERSにあるものだけ指定可能)。一覧と実装分けたほうがいい気がするけど?)。 ただ、tokenize関数を変更できるようにしてくれています。これを利用して、少しトリッキーな形で日本語対応しました。\n先ほどの手順2.でOramaのcreate関数として、componentsに次のtokenizerを渡します。\nlanguageはenglishですが、日本語をtokenizeする処理に次のように書き換えました。 stemmingは今回は行わない(=用意されているstemmerを使えない)のでfalse、normalizationCacheは空のMapを用意しておかないとエラーが出るので、new Map()しています。 この設定を使ってcreateすることで、\ncomponents: { tokenizer: { language: \u0026#34;english\u0026#34;, stemming: false, normalizationCache: new Map(), tokenize: (raw) =\u0026gt; { return tokenize(raw) }, }, }, 少しわかりにくいですが、tokenizerのtokenize関数の中で呼び出しているreturn tokenize(raw)の部分はwakachigakiというライブラリのtokenize関数となっています。\nwakachigakiというライブラリ Elasticsearchなどのサーバー上で動作させる検索エンジンではkuromojiなどの辞書を内包した形態素解析器を利用するのが通常です。 ただ、今回はブラウザだけで完結した簡単な検索を行う仕組みをOramaを使って提供しようと考えました(kuromoji.jsというのもありますが、辞書のサイズがそこそこのサイズです)。 ですので、辞書ファイルのない軽量の形態素解析ライブラリとして、wakachigakiというライブラリ(=6.2Kbの軽量日本語分かち書きライブラリ)を利用してみました。\n最初はTinySegmenterの利用をしていたのですが、wakachigakiのサイトにもあるように、TypeScriptやES Moduleでも利用できる形式となっていたのでこちらに切り替えました。\n辞書もっていないため、品詞でのフィルタリングや読みを利用した処理はできませんが、日本語の文章を分かち書きしてくれます。\ntokenize関数の設定 OramaのTokenizerインタフェースのtokenizeは入力の文字列をstring[]として返すことを期待しています。 wakachigakiのtokenizeも文字列を引数にとり、string[]を返すので、そのまま呼び出すだけにしてあります。\nただ、今回のブログ検索の実装では、検索窓に入力された文字列も特に何も処理せずにtokenizeに渡す形にしています。 クエリパーサーなどを考える場合は、検索窓に入力された文字列を前処理したりする必要がありますが今回はいったんこれで。。。\ndata-persistenceはcomponentsはpersistしない 手順2.で導入した、data-persistenceプラグインですが、現在の実装ではOramaが生成したデータベース(転置インデックス)だけを永続化しています。 独自に設定したtokenizerは残念ながら含まれていませんでした。 手順4.の検索画面のコードの34行目の部分(下記)で、フェッチしたインデックスデータからrestoreした後のOramaのインスタンスのtokenizerに手順2.と同じ設定のtokenizerを設定することで検索時にも同じトークナイズがされるようになります(今の仕組みだと修正した場合には、両方のソースコードを修正しないといけないのがちょっと面倒かも?)。\ndb.tokenizer = { language: \u0026#34;english\u0026#34;, stemming: false, normalizationCache: new Map(), tokenize: (raw) =\u0026gt; { return tokenize(raw) }, } tokenizerはOramaの検索エンジンのインスタンスに紐づく設定となっているので、フィールドごとに切り替えるといったことも現在では想定されていない気がします。\nハイライト ハイライトのために、インデックスデータに単語のポジションを保存するためのプラグインも提供されています。 このポジションは検索の単語がヒットしドキュメントのどの位置に出てくるのか?をあらかじめデータとして保存しておくことで、ハイライトのたびに単語の位置を毎回計算しなくてもよくするためのものと思われます。\nこれを利用してもよかったのですが、今回は@orama/highlightというモジュールを利用することにしました。 検索にヒットしたドキュメントの元の文章と検索のキーワードを入力すると検索キーワードの周りにハイライトのHTMLタグを埋め込んでくれるライブラリを利用しました。これは普通に他でも便利かも?\n余力があればプラグインを利用した時のインデックスのサイズの違いや検索時の速度の違いを調べてみるのもいいかもしれないです。\nそのほかの機能 今回は利用していませんが、Oramaにはそのほかの機能も用意されています(公式ドキュメントの検索の紹介のページ)。詳細は公式ドキュメントをご覧ください。\nTypo tolerance Facet/Filter Vector Search Geo Search Grouping Threshold Preflight Oramaで(まだ?)できないこと 今回触ってみて、現在のOramaの実装ではできなそうなことがいくつかあったので書き出しておきます。 あくまでも現時点のことです。今後実装される可能性もあります。\nデフォルトでは、searchのtermに渡した文字列をtokenizeし、出力されたトークン列(単語の配列)のそれぞれのトークン(単語)にヒットしたドキュメントが全て検索結果に含まれます。 検索結果のドキュメントはBM25でスコアリングされるので、多くのトークンが含まれるものが上位に来る可能性が高いです。\nただ、特定の単語を含まない検索、ANDやOR検索など凝ったクエリは現在は書けないようです(Issueがある)。\nfilterは別途用意されているので、例えばファセットで表示したカテゴリで絞り込んだ状態にするといったことはできそうです。\n残課題 とりあえず日本語をなんとなく検索できるようにすることはできました。 が、気になることもいっぱいありました。 時間を見つけてTypeScriptなどを勉強しながら探っていく感じでしょうか。\nインデックスを小さくする方法 今回はブログ記事のサマリー(Hugoで生成されるSummary)でインデックスを作ったので、インデックスのサイズはまだ小さくなっています(といっても1MB超えてるけど)。ブログ記事全体を検索できるようにする場合は、インデックスファイルが大きくなります。\nこれは、OramaがデフォルトではインデックスしたJSON自体もインデックス(ドキュメントストア)に保存しているためです。 ですので、Oramaに登録したJSONデータ+検索用のインデックスがインデックスファイルとなります。 ただ、検索だけができればよい場合は、出来上がったインデックスがあればドキュメントのIDは取得できます。\n公式ドキュメントでもそのことに触れているページがあります(参考:Remote document storing)。\nまだちゃんと実装を見ていませんが、ブログ記事本体の文字列はドキュメントストアに保存しないようにすれば検索はできるが、容量が大きくならないといった工夫ができそうです。\nただ、検索結果にハイライトを含んだスニペットを表示したい場合は、コンテンツ文字列が必要になってくるので、代わりに何かしらの仕組みを考える必要が出てきます(例えばサマリー部分の文字列だけ保存しておいて、ハイライトはそこだけを対象とするなど)。\nそのほか そのほかに思いつくのはこの辺でしょうか?\nオートコンプリート:Oramaというよりも、JavaScriptやTypeScriptでうまく実装できるのか?という話のような気がしますが。。。 ファセット対応:機能としては存在していますが、今回は実装が間に合いませんでした。 Vector Search:検索キーワードのベクトルをどうやって作るのか?という問題が残りそう。コンテンツのベクトルだけで関連ページの表示みたいなことはできるかも?(動的にやる必要がないので、事前計算して各ページに埋め込むほうがよさそうだけど) Geo Search:緯度経度があるデータを探し出してこないと? relevanceの処理の変更:BM25以外に切り替えることができるかどうか(Oramaのソースとにらめっこしないといけなそう) tokenizeの改良:辞書を利用する形態素解析ライブラリやAPIを利用してみたり、「てにをは」といった1文字のひらがなを削ることで、無駄な検索ヒットを減らしてみたり。大文字小文字の正規化も必要。 検索ログの解析:検索ログを保存する仕組みなどはないので、Google AnalyticsやほかのAPIなどを用意する? まとめ ということで、Oramaという検索エンジン?ライブラリ?を利用して日本語のブログ検索を実装してみました。 まだ、機能が少ない部分もありますが、少数のデータをブラウザだけで簡単に検索できる仕組みをGitHub Pagesだけで提供することができそうです。 今回は静的なファイルだけで完結する形にしましたが、TypeScriptで利用できる簡単な検索エンジンライブラリとして使ってみるとまた別の面白さもあるかもしれないです。 まだ触っていない機能は思いついたこと(=残課題に書いたこと)もあるので、ちょっと試行錯誤してみようかなぁ。\n","date":1702566000,"dir":"post/2023/","id":"476e17b6f854414033d5cec1470774ee","lang":"ja","lastmod":1702566000,"permalink":"https://blog.johtani.info/blog/2023/12/15/introduce-orama-to-blog/","publishdate":"2023-12-15T00:00:00+09:00","summary":"この記事は、情報検索・検索技術 Advent Calendar 2023の15日目の記事です。 昨年に続き2回目の情報検索のAdvent Calendar参戦です。 今年は、夏","tags":["orama","search"],"title":"Oramaという検索エンジンでブログ検索を作ってみた"},{"contents":"PySpaアドベントカレンダーの12/08のエントリーです。昨日は渋川さんのアンラーニングで失敗した話でした。\n私は、今年は昨年の続きっぽい話を。\n音楽の再生とか停止とか 今年もリモートで仕事を継続しています。 昨年、OwnToneという音楽サーバーを導入しましたが、ミーティング開始時や終了後に音楽の停止や再生をするのに、ブラウザで操作するのはちょっと面倒です。 加えて、ミーティングする際には実際には\n音楽を止める 電気をつける といったことをっやります。 音楽再生についても\n音楽を再生する アンプの音は音楽再生用の音量にする といった複数のことを行います。\n基本的にPCの前にいるし、Slackを常に開いているからSlackのBotを作ると便利になるのでは? ということで、自分専用のSlack Botを作ってみました。\nGitHubリポジトリ 全く誰の役にも立たないけど、公開しています。\nhttps://github.com/johtani/smarthome Goで実装 知り合いに勧められたということもあり、Goをあまり触ったことがなかったので、Goでやってみました。時々新しい言語を触ってみたくなるので。。。\nコマンドパターンのような作りで、コマンド(操作)を増やしていく感じで実装してはみたのですが、この書き方がいいのかはまだよくわかっていないです。\nActionという単体の操作(例:OwnToneの一時停止)を、操作したい機器の操作ごとに作成しています。 インターフェースとしてはRunだけを定義しています。\ntype Action interface { Run() (string, error) } それらの操作(Action)をひとまとめにしたものをSubcommandという形で定義して、SlackのBotにはSubcommandの名前を送って処理を実行する形にしています。\ntype Subcommand struct { Definition actions []action.Action ignoreError bool } やりたいことを追加するタイミングで時々リファクタしたりもしていますが、基本はこんな感じです。 細かな実装はさておき、今回ボットを作るときの観点をいくつか。\n宅内ネットワーク 音楽サーバーのOwnToneもですが、YAMAHAのアンプのAPIも見つけたのでこれらの操作をボットから行っています。どちらも自宅のネットワークにあるので、今回作成したボットも同じネットワークで動作します。\n外部に公開されたHTTPのエンドポイントがあればよいのですが、今回は用意していません。 SlackのAPIではこれに対応したアプリを作るときのためにSocket Modeを用意してくれています。\nドキュメントがしっかりしているのもあり、チュートリアルなどを見つつ特に迷うことなく構築できました。\n基本的には「特定のチャンネルでボットがメンションされたら動作する」という挙動だけしか実装していないので、特に今回はこれで困ることもありませんでした(世の中の人たちはもっとすごいSlackの使い方をしていそうだけど。。。)。\n対象となるものたち ボットから操作しているのは今のところ3種類です。\nSwitchBot OwnTone YAMAHAのアンプ SwitchBot SwitchBotについては、go-siwtchbotを利用しています。 電気、エアコン、空気清浄機、サーキュレーターのオンオフをSwitchBot経由でやっています。\n室内灯の明るさのために、SwitchBot側でシーンを設定している(一番暗い明るさで電気をつける)ので、そこが少しと特殊でしょうか?\nあとは、SwitchBotの温湿度計を3つ(室内2つ、室外1つ)おいてあるので、これらの温度を表示するコマンドも用意しました。\nそれぞれの機器の電池残量(電池の絵文字の右側)を表示してます(書斎が2つあるように見えますが、温湿度計の名前なので、同じ部屋においてあります。。。温度が高いほうがデスクトップPCの近くにある)。 防水の温湿度計があるので、外の気温もわかるのは便利です。\nOwnTone JSONのAPIが用意されていますが、特にクライアントライブラリなどは用意されていません。 今回は、用意されているAPIのごく一部だけを利用するので、net/httpのClientでJSONを投げています。 必要になったらowntone/clientにメソッドを追加していく感じです。\nhttps://github.com/johtani/smarthome/blob/master/subcommand/action/owntone/client.go#L45 再生、一時停止、プレイリストの取得、音量指定あたりを実装しています。 音の出力先はAirPlay(次に出てくるYamahaのアンプ)になっています。\nあと、JSON APIのサンプルをChatGPTに渡して、「このJSONをレスポンスに受け取る処理をGoで書いてください」と聞いて処理を書いたりしました(細かいのはどう聞いたか覚えてないけど)。\nYAMAHAのアンプ ググって探してきましたが、利用しているYAMAHAのアンプにYXC(Yamaha Extented Control)と呼ばれるAPIが用意されていました。 PDFでAPIの仕様が公開されていたので、この資料とにらめっこしながら、必要そうなAPIを実行するクライアントを実装しました。 こちらは、OwnToneのAPIの処理をすでに書いた後だったので、それをもとに必要な実装を追加しただけです。\nちなみに、アンプの電源をONにするAPIは実装していません。\nOwnToneで音楽を再生する(AirPlayで信号が送られるみたい) シーン選択(Nintendo SwitchやPS5のシーンを用意している)のAPIを呼び出す という処理をすると自動で電源がONになりました。スタンバイしている状態でもAPIはリクエストを受け付ける状態になっているようです。 また、PS5のシーンを呼び出したら、PS5自体も起動するのが便利だったりします。HDMI経由で信号が飛んでるのかな? 「ミーティング開始」や「音楽停止」コマンドではアンプの電源をオフするAPIを呼び出すようにしています。\nタイポ対応 「入力間違いしちゃうんです、人間だもの。。。」\nということで、10月にタイポ対応の処理を入れてみました。 タイポ対応前の実装では、入力された文字列がコマンドの文字列と完全一致した場合にだけ、コマンドが実行される形になっていました。 結構タイポしちゃうので、完全一致で見つからない場合の処理として、入力された文字列とコマンド名のレーベンシュタイン距離が2以下のものを探し、その中で距離が一番小さな値のコマンドを実行する形にしてみました。 コマンド数はたかが知れているのでコマンドのリストを全部チェックする形にしています。 タイポするとこんな感じ。\nレーベンシュタイン距離の計算にはGo-edlibを利用しています。OSS便利ですね。\nやってよかったこと ミーティング開始時などのいくつかの手順が簡素化できたので満足しています。 SwitchBotの操作もスマホをわざわざ操作しなくてもいいですし(仕事してるとキーボードとSlackは常に使ってるし)。 また、副次的な効果として、部屋の外から電源を切り忘れていたり、エアコンの切り忘れなどの場合に、スマホから遠隔でまとめた処理ができるのが便利です。\n今後やってみたいこと こういうのがあるともうちょっと便利かもなぁ?というのもあるので今後も気が向いたらコマンドなどを追加していく予定です。 今のところこんなことやりたいなというのがいくつかあります。\nキーワードに関連する曲の再生 OwnTone自体に検索の仕組みがついているので、キーワードを受け付けてそれに関する曲を流す Flexispotの操作 ミーティングの時は立ち上がっているので、机をスタンディングの状態にしたい 電子工作しないとだめかも? Webカメラ用ライトの点灯 ミーティング時に明かりが必要なのですが、物理スイッチのOn/Off これも電子工作かな? 定期的に温度をBotに表示させるとと面白いかも? まとめ ということで、新しいプログラミング言語にも触れたし、作業環境も便利になって一石二鳥でした。 新しいプログラミング言語触るのはやっぱたのしいですね。\n","date":1701961200,"dir":"post/2023/","id":"516a7aa07f8faa6b7aa38beb5010cf8c","lang":"ja","lastmod":1701961200,"permalink":"https://blog.johtani.info/blog/2023/12/08/smarthome-bot/","publishdate":"2023-12-08T00:00:00+09:00","summary":"PySpaアドベントカレンダーの12/08のエントリーです。昨日は渋川さんのアンラーニングで失敗した話でした。 私は、今年は昨年の続きっぽい話","tags":["misc","music","bot"],"title":"GoでSlackのボットを作った話"},{"contents":"「機械学習による検索ランキング改善ガイド」を読みました。\n著者の鈴木さんより献本いただいたのを読み終わったのでレビューと、あとおまけです。\n紹介とレビュー どんな本なのか?は打田さんが書かれたブログ、「ブックレビュー:『機械学習による検索ランキング改善ガイド』 - Tomoko Uchida - Medium」に詳しく書かれているので、そちらも参考にしてもらうほうがわかりやすいと思います(丸投げ)。\n読みながらいくつかツイートしていたので、そちらも参考のために貼っておきいます。\nオライリーの検索ランキング本、負荷テストのことも書いてある、すごいhttps://t.co/YPnB6kxFY2\n\u0026mdash; Jun Ohtani (@johtani) August 28, 2023 私のレビュー わかりやすく検索の基本を紹介しつつ、本書のメインであるランキング改善について全体の流れが書かれています。 ランキング改善のやり方といっても、手法の話だけではなく、プロジェクトとしてどの様に進めていくべきなのか?また、関係するものはどんなものがあり(システムだけではなくチームについても書かれていたり)、どういう判断をもちながら運用していくのか?、負荷テストにまで言及されています。\n読んでいて特に私が気に入ったのは以下のような話でした\nランキング改善を進める前にきちんと解ける問題なのか?それ以前にやることはないのかを考えましょう マッチング改善についても少しだけ触れられているが、メインはランキングについてだと明記されている 実際に体験されたのであろう落とし穴の話 負荷テストについて1章設けてある! ハンズオンのパートでもレイテンシの話がされている 付録としてベクトル検索についても触れてある 日本語でまとまって読める本があるのは本当に幸せですよね。\nおまけ 書籍ではハンズオンで、Elasticsearchとランキング学習のプラグインであるelasticsearch-learning-to-rankを利用しています(GitHubにサンプルが公開されています)。 書籍ではElasticsearchが7.13.4、プラグインが1.5.7-es7.13.4というバージョンになっていました。\nブログを書いている時点でのElasticsearchは8.x系になっています。せっかくなので、書籍を読みながら現時点で最新のものに置き換えてみるというのをやってみました。\nElasticsearchは8.10.2が最新なのですが、ランキング学習のプラグインはサードパティ製で、1.5.8-es8.8.2が最新版となっています。 ハンズオンのサンプルコードをフォークして、以下の構成にして動くようにしてみました。\nElasticsearch : 8.8.2 learning-to-rankプラグイン : 1.5.8-es8.8.2 Kibana : 8.8.2 Python : 3.10 Elasticsearch、プラグイン、Kibanaのアップグレード Elastic社が提供しているDockerイメージが利用されているので、バージョン番号を書き換えました。 あとは、learning-to-rankプラグインのバージョンを書き換えるついでに、elasticsearch-pluginコマンドで直接ダウンロードさせる形に書き換えました。\nhttps://github.com/johtani/building-search-app-w-ml/blob/es8/part2/app/search-engine/Dockerfile\nPython3.10にアップグレード 本当は必要なかったのですが、Pythonのイメージもついでに3.10にしました。 ただ、このおかげでインストールされるXGBoostのバージョンも1系から2系に上がってしまい、XGBoostを利用してモデル生成をする処理でエラーが出るようになってしまいました。。。\n2系へのアップグレードは手間がかかりそうだということで、pipコマンドでのインストールでのバージョンを\u0026lt;2として、1系をインストールすることで回避しました。\nhttps://github.com/johtani/building-search-app-w-ml/blob/es8/part2/app/workspace/Dockerfile\nelasticsearch-pyのアップグレード Elasticsearchを8系にしたので、クライアントライブラリ側も8系に書き換えました(元は7.17以下に固定されていた)。 pipで7系に固定されていたものを外して最新のもの(8系)をインストールするようにしました。 これだけでも特に問題なく動いたのですが、「DeprecationWarning」が出ている部分が1か所だけあります(サンプルではDeprecationWarningが出力されない形になっていましたが、出力するように変更しました)。\nElastic公式のドキュメントにMigrate to 8.0というページが公開されています。Pythonクライアントのアップグレードを行う際はこちらを参考にすると指針が記載されています。\n今回のサンプルコードではsearchの時の引数としてbodyを渡していたのですが、8系のクライアントライブラリからこちらが廃止になり、queryやrescoreなど個別の引数を渡す形に変更されています(search APIのリファレンス)。 ですので、bodyを**bodyでアンパックして渡すようにしただけです。サンプルコードがわかりやすく書かれているので変更も少しで済みました。\nhttps://github.com/johtani/building-search-app-w-ml/blob/es8/part2/app/workspace/collect_responses.py#L59\n一応、これでエラーが出ないで動きました。 すべて適用した、フォークして修正したブランチはhttps://github.com/johtani/building-search-app-w-ml/tree/es8で公開しています。\nまとめ すごくわかりやすいうえに、手を動かしながらどんなデータを使ってどんなことをやるのかが体験できる良い本でした。 理論的な話だけでなく、システムとしてどういうものが必要で、どういうことをやらないといけないのか?というのがわかるのがイメージできるのは重要だと思います。\n最後は広告ですが、ランキング改善以外の検索システムについて学べる本を検索システム ― 実務者のための開発改善ガイドブック – 技術書出版と販売のラムダノート出していますので、こちらも参考書として読んでいただけるとうれしいです。\n","date":1695612744,"dir":"post/2023/","id":"7f78b02c531f09602ba4e140132d26a2","lang":"ja","lastmod":1695612744,"permalink":"https://blog.johtani.info/blog/2023/09/25/read-search-raking-guide/","publishdate":"2023-09-25T03:32:24Z","summary":"「機械学習による検索ランキング改善ガイド」を読みました。 著者の鈴木さんより献本いただいたのを読み終わったのでレビューと、あとおまけです。 紹介","tags":["読書","elasticsearch"],"title":"機械学習による検索ランキング改善ガイドを読みました"},{"contents":"趣味?(検索エンジンに関する趣味プロジェクト)でPythonのプログラムを書いています。 ベクトル検索などの確認なども含めて、Jupyter Notebookで簡単なAPIの呼び出しを書いていましたが、検索はやはり画面があるほうがにぎやかでいいですよね。 ということで、画面周りで調べものをしていた時のことを後日の自分のためのメモとして残しておきます。\nSearch UIとSearchkit ということで、それほど手がかからないで検索の画面をサクッと作る方法がないか?ということでちょっとだけ探してみました。 最初にElasticsearchを利用していることもあり、すぐに検索の画面を作れるライブラリ・フレームワーク・コンポーネントがないかな?ということで思いついたのが次の2つでした。\nElastic Search UI Searchkit どちらも直接Elasticsearchに接続して検索をすることができるコンポーネントです。 Elasticsearchだけで完結していればそれでおしまいだったのですが、今回はバックエンド経由でElasticsearchに検索を書ける必要があります(ベクトル検索の仕組みもデモをしたいため、クエリの文字列をLLMなどでベクトルにしてからknn検索をすることになります)。\nSearch UIの構成 もともとSearch UIはElasticのApp SearchのGUI構築向けのコンポーネントとして作られました。 最近になって、直接Elasticsearchに接続できるコネクターを提供しています(ベータだけど)。 このコネクターを利用した場合は、ざっくりですが、このような流れになります。\nまた、Search UIはCustom Connectorの仕組みも用意しており(ConnectorのAPIが宣言されているのでそのAPIで独自実装が可能)、これを利用することで、ブラウザではなくバックエンド(Node)でElasticsearch Connectorを利用するような構成も取れるようになっています。\n改めて要件をまとめると ということで、やりたいことは\n簡単にUIが作れる バックエンドはPythonを経由して検索したい となります。 Searchkitも調べようかと思いましたが、いったんはSearch UIのCustom ConnectorでPythonでFastAPIでバックエンドのAPIを実装して、Search UIの想定しているリクエスト・レスポンスに変換すればいいかな?ということにしました。\nとりあえずSearch UI+Custom Connectorからのリクエスト・レスポンス(フロントからバックエンドへの出入りの部分)を記録し、 Search UI+Elasticsearch Connectorのときのリクエスト・レスポンス(バックエンドからEsへのの出入りの部分)も記録して、 参考にしながらバックエンドを実装しようと試みました。 Search UIのCustom Connectorのサンプルとなっていた、Node上でElasticsearch Connectorを動かしている部分をPythonで簡単に再実装しようという試みです(まったく同じ実装にする必要はなく、必要最低限の機能(検索窓、ファセット、ページング)が動作するところを目指します)。\nElasticsearch API connectorの調査 方針が決まったので、Search UIがElasticsearch API Connectorに渡しているリクエストをブラウザのデバッグ機能を使って追いかけてみると。。。 内部でSearchkitを読んでいる??ことがわかりました。\nElasticsearch API Connectorがリクエストを変換しているのかと思っていたのですが、実は内部にもう一段変換が行われていました。\n方針を決めたつもりが、Searchkitが出てきてしまったので、Searchkitも調べてみることに。。。 なお、Search UIにElasticsearch API Connectorを導入したのがどうやら、Searchkitの作者で、現在はElasticのエンジニアになられているようです。\nSearchkitとは? Search UIが利用しているSearchkitは、3.0ですが、Searchkit本家のリポジトリを見ると4.x.0となっています。\nどうして新しいものをSearch UIで使っていないのかな?と思いつつ調べてみたところ、Searchkit V4のブログを発見しました。\nSearchkit V4 integrates with Algolia’s Instantsearch library, which is a Search UI library built by Algolia. Instantsearch is an amazing library, and it’s been used by many companies and supports many frameworks like React, Vue and Angular. ブログより引用\nどうやら、V4ではコンセプトをガラッと変更されたようで、Algoliaがオープンソースとして開発しているInstantSearchのコネクター(アダプター)としてSearchkit V4を開発しているようです。 これは最近出てきている検索エンジンのTypesenseやMeilisearchの戦略にもなっています。\nなお、SearchkitのGitHubリポジトリやSearch UIのリポジトリを見ていると、Search UIの開発(およびSearchkitの3系)は現在は活発に行われていないように見えました。 Searchkit V4はちょっとずつ開発が進んでいるようです。\nまとめ? 一応Searchkit V4の現状やInstantSearchもすこしだけ見てみたのですが、今回の私のプロジェクトでは検索画面はまだそこまで重要度は高くないので、いったん調べていたSearch UI+Pythonのバックエンドの構成で動作する最小限を実装したところで終わりにしました。 なので、Searchkit V4+InstantSearchの構成はまた今度という感じです。\nなお、Search UIの方は5月からコミットがされていないようです。どうも開発しているチームが別件で忙しそうだなというのを感じました。\n","date":1692768764,"dir":"post/2023/","id":"8f58cbe5f2ce85c22569af765de3f8d3","lang":"ja","lastmod":1692768764,"permalink":"https://blog.johtani.info/blog/2023/08/23/search-ui-and-searchkit/","publishdate":"2023-08-23T05:32:44Z","summary":"趣味?(検索エンジンに関する趣味プロジェクト)でPythonのプログラムを書いています。 ベクトル検索などの確認なども含めて、Jupyter N","tags":["searchkit","search-ui","画面"],"title":"search-UIとSearchkitと検索画面"},{"contents":"いくつかある環境をDev Containerで動くように変えていますが、最初に導入した時に疑問点だった「コンテナ名」について解消したのでメモを残しておきます。\nコンテナ名の指定 最初のDev Container導入の記事で、起動したコンテナの名前が自動で付与されて、ランダムに変わるという疑問点を書いていました。\ndocker-compose.yml対応の記事ではdocker-compose.ymlを利用すると、コンテナ名はファイル内で定義されたサービス名で起動されて見やすくなると気づきました。\nやはり、Dev Containerでイメージを指定している場合もわかりやすいコンテナ名がいいなと思ったところで、「runArgs」を思い出しました。 Dev Containerからコンテナを起動するときに渡す引数が書けるじゃないですか。そういえば、むかしdockerコマンドを使う時に名前を指定した記憶があったなと。ということで、Google検索です。「docker command args container name」で検索しましたw\n--nameというオプションで起動時のコンテナの名前の指定ができます。ということで、このブログを生成するためのdevcontainer.jsonに\u0026quot;runArgs\u0026quot;でコンテナ名を指定してコンテナ起動ができるようになりました(「ブログ記述環境としてのDev Container」という記事のdevcontainer.jsonにrunArgsの行を追加しただけ)。\n{ \u0026#34;name\u0026#34;: \u0026#34;Hugo - blog generator\u0026#34;, \u0026#34;image\u0026#34;: \u0026#34;mcr.microsoft.com/devcontainers/javascript-node:16\u0026#34;, \u0026#34;runArgs\u0026#34;: [\u0026#34;--name\u0026#34;, \u0026#34;blog_generator\u0026#34;], \u0026#34;postCreateCommand\u0026#34;: \u0026#34;/bin/sh ./.devcontainer/postCreateCommand.sh\u0026#34;, ... ","date":1690420969,"dir":"post/2023/","id":"f9e847ee886bdb9ab5583eeb6eabbd51","lang":"ja","lastmod":1690420969,"permalink":"https://blog.johtani.info/blog/2023/07/27/container-name-in-devcontainer/","publishdate":"2023-07-27T01:22:49Z","summary":"いくつかある環境をDev Containerで動くように変えていますが、最初に導入した時に疑問点だった「コンテナ名」について解消したのでメモを","tags":["dev container"],"title":"VS CodeとDev Container(コンテナ名の指定)"},{"contents":"このブログの生成には、Hugoを利用しています。 ブログ移行日記(その1)に書いてありますが、当時はbrewでインストールしていました。 また、Windowsに移行したタイミングで、WSL2のUbuntuにaptでhugoをインストールして利用していました。 WSL2の環境が壊れなければこのままでもいいのですが、最近Dev Containerを触っていたので、このブログを書く環境(おもにHugo)もDev Containerにできるのでは?と気づきました。\nということで、Hugo+αの環境をDev Container化したので、そのメモです。\n必要なもの ブログを書いて、記事を構築して、公開するところまでに利用するのは次のようなものです。\ngit Hugo node atomic-algolia GitHubのプライベートリポジトリでHugoのプロジェクトを管理しています。 また、GitHub Pagesで公開しており、生成したHTMLもgitコマンドを利用してGitHubにpushしています。 このため、gitコマンドが必要です。\nコンテンツの生成はHugoコマンドを利用します(テーマの適用とかいろいろ)。\nあと、Algoliaでブログを検索できるようにしており(ブログ移行日記(その4)参照)、Algoliaへドキュメントのデータをアップロードするために、atomic-algoliaを利用しています。こちらは、nodeのモジュールであるので、nodeの環境も必要です。\nベースにするイメージ Dev Container Templatesというリポジトリが公開されています。 こちらを探すと、元となるdevcontainer.jsonが見つかることがあります。 Hugoのものがあるか探してみましたが、残念ながら見つかったのはJekyllのテンプレートでした。 今回は、nodeの環境が必要なのでjavascript-nodeを元に編集していきます。\n手元のUbuntuのnodeのバージョンが16だったので、バージョン16のイメージを指定します(devcontainer.jsonは後述)。\nHugoの追加 Hugoのテンプレートはなかったのですが、Dev Container FeaturesにHugoのfeatureが用意されていました。 featuresに1行追加するだけでコンテナにHugoをインストールしてくれる便利ものです。\nMarkdownの環境 Dev Container Templatesを探索していて見つけたMarkdownのテンプレートも参考にしてみました。 VS CodeのMarkdown向けの拡張機能がいくつかリストアップされていたので、ついでに追加です。 markdown-all-in-oneやmarkdownlintはこれまでも利用していたので、他のものも便利だろうということで。 他の物はどんなものかを後で調べてみる予定です。\n作った.devcontainerの設定はこちら ということで、出来上がった設定は以下の通りです。\ndevcontainer.json { \u0026#34;name\u0026#34;: \u0026#34;Hugo - blog generator\u0026#34;, \u0026#34;image\u0026#34;: \u0026#34;mcr.microsoft.com/devcontainers/javascript-node:16\u0026#34;, \u0026#34;postCreateCommand\u0026#34;: \u0026#34;/bin/sh ./.devcontainer/postCreateCommand.sh\u0026#34;, \u0026#34;features\u0026#34;: { \u0026#34;ghcr.io/devcontainers/features/hugo:1\u0026#34;: {} }, \u0026#34;customizations\u0026#34;: { \u0026#34;vscode\u0026#34;: { \u0026#34;extensions\u0026#34;: [ \u0026#34;yzhang.markdown-all-in-one\u0026#34;, \u0026#34;streetsidesoftware.code-spell-checker\u0026#34;, \u0026#34;DavidAnson.vscode-markdownlint\u0026#34;, \u0026#34;shd101wyy.markdown-preview-enhanced\u0026#34;, \u0026#34;bierner.github-markdown-preview\u0026#34; ] } } } postCreateCommand.shでは、npm installで、必要なモジュールのインストールをコンテナビルド後に実行できるようにしました。 (apt updateはなくてもいいな)\npostCreateCommand.sh #!/bin/sh # postCreateCommand.sh echo \u0026#34;START Install\u0026#34; sudo apt update sudo chown -R vscode:vscode . npm install echo \u0026#34;FINISH Install\u0026#34; まとめ ということで、ここ最近Dev Containerについて色々調べていたのでサクッとDev Container化ができました。 まぁ、HugoのFeatureが用意されていて、他に大したことをやっていないというのが大きいのですが。 このブログは今回構築したDev Containerで生成して公開した記事になります。\n","date":1690189832,"dir":"post/2023/","id":"7884b62c561b999b9358d52779a18218","lang":"ja","lastmod":1690189832,"permalink":"https://blog.johtani.info/blog/2023/07/24/introduce-dev-container-to-hugo-env/","publishdate":"2023-07-24T09:10:32Z","summary":"このブログの生成には、Hugoを利用しています。 ブログ移行日記(その1)に書いてありますが、当時はbrewでインストールしていました。 また、","tags":["hugo","dev container"],"title":"ブログ記述環境としてのDev Container"},{"contents":"WSL2にUbuntuを入れて、開発とかはこちらを利用しています。 また、Docker DesktopもWSL2のバックエンドエンジンを利用しています。\n知り合いとの話で、Ubuntuの外付けのSSDをマウントしたという話が出てきて、それだと遅くない?Ubuntu自体を移動できるんじゃないかな?という 流れになりました。 知り合いは、特に移動とかは考えてなかったのですが、自分のディスクの容量が今どのくらい使われているのかが気になり、調べてみると、 Cドライブの使用率が90%を超えてるじゃないですか。\nWizTreeというソフトを前回入れていたのを思い出して、再度調べてみたところUbuntuらしきvhdxファイルのサイズが171GB、Docker Desktopのデータ領域のvhdxファイルのサイズが81GBと、結構な割合です。\n前回は、Hyper-V管理ツールで仮想ディスクの圧縮処理を行ったのですが、Dドライブに移行したほうが安心できそうな気がしたので、移動の方法を調べました。\nWSLコマンドのドキュメントが公式で公開されています。こちらのコマンドを元に作業をしました。 また、ググって出てきた記事も参考にさせていただきました。ありがとうございます。\nwsl をDドライブに入れ直してディスク拡張する | blog.ojisan.io WSL2環境をコピー(複製)する方法 - Qiita まずは確認と停止 WSL2で使っているディストリビューションを確認します。コマンドは以下の通り。 実行した結果も含まれています。コマンドの実行にはコマンドプロンプトを使用しました。公式ドキュメントのドキュメントではスニペットはPower Shellと書かれてますが、コマンドプロンプトでも大丈夫そうでした。\nD:\\\u0026gt;wsl -l -v NAME STATE VERSION * Ubuntu Running 2 docker-desktop Running 2 docker-desktop-data Running 2 残念ながら、wslのコマンドでは実体がどこにあるのかを調べることができなかったですが、WizTreeでディレクトリ名などを見ていたのでなんとなう予測ができました。 (これ、他に知る方法あるのかなぁ?)\nディストリビューションの移動は次のような手順になります。\nwslのshutdown エクスポート(ディストリビューションのコピー) 今あるディストリビューションを削除 インポート(今ある名前で2.のファイルをインポート) まずは停止です。これをやらないとエクスポートができないので。\nD:\\\u0026gt;wsl --shutdown エクスポート 次にエクスポートです。 今回は以下の2種類の仮想環境をエクスポートします。\nUbuntu docker-desktop-data エクスポートでは、元のディストリビューションのファイル(Cドライブにあるファイル)が消えることはありません。 また、エクスポートの形式として、tarとvhdxの2種類が指定できます。 エクスポートのコマンドのデフォルトはtar形式ですが、エクスポート元のファイルがvhdxなので、vhdxでエクスポートしたほうがCPUにやさしかったです。 ちなみに、docker-desktop-dataはtar形式でエクスポートしてインポートしました。tar形式の場合は、ディスクのサイズが小さくなる可能性があるみたいです(不要なデータがvhdxの中に残っていたりする影響かと)。\nコマンドは以下の通りです(詳細は公式ドキュメントを参照してください)。出力ディレクトリはあらかじめ作っておきました(作ってない場合の挙動は未確認です。)\nD:\\\u0026gt;wsl --export Ubuntu .\\wsl\\Ubuntu\\ext4.vhdx --vhd docker-desktop-dataはtar形式です。\nD:\\\u0026gt;wsl --export docker-desktop-data .\\Docker\\ docker-desktop-data.tar ディストリビューションの削除(こわい?) 今ついているディストリビューション名を利用したいので、いったん、Cドライブ上にあるディストリビューションを削除する必要があります。 コマンドは公式ドキュメントにある--unregisterオプションを利用します。 以下のコマンドはUbuntuですが、docker-desktop-dataもやりました。\nD:\\\u0026gt;wsl --unregister Ubuntu ちなみに、このコマンドを実行すると、Cドライブの容量がいきなり空きました。 コマンドいっぱつでなくなりました。きちんとエクスポートしてから実行しましょう。 (なんなら、一度、別名でインポートして動作確認するのもいいかもしれないです。私はしましたw)\nインポート インポートするオプションも2種類あります。vhdxファイルの場合は、インプレースでのインポート(vhdxファイルをそのまま利用する形式)が可能です。 Ubuntuについてはこちらを利用しました。この場合、vhdxファイルがそのまま利用されるため、バックアップとしては利用できなくなります。今回は170GBもあるので、これでいいかと。\nD:\\\u0026gt;wsl --import-in-place Ubuntu .\\wsl\\Ubuntu\\ext4.vhdx tarファイル(docker-desktop-data)の場合は、通常のインポートを行いました。\nwsl --import docker-desktop-data D:\\Docker\\docker-desktop-data\\ D:\\Docker\\docker-desktop-data.tar この場合、tarファイルは残ったままで、新たにD:\\Docker\\docker-desktop-data\\ディレクトリにext4.vhdxファイルが作られました。 バックアップも取りつつ移行したい場合は--importがいいかもしれません。 また、WSLはバージョン1とバージョン2があり、インポートの際にこの部分も気にする必要があるようです。 今回はすべてバージョン2で、かつ、wslのデフォルトのバージョンを2にしてあったので特に意識していません。\nUbuntu起動ユーザーの指定と注意点 公式ドキュメントに、既存のユーザーを変更するコマンドの記載があります。 インポートしたディストリビューションは、デフォルトユーザーがrootになっていることがあるようなので、Ubuntuのユーザーを次のようなコマンドで変更しました。\nubuntu config --default-user johtani 公式ドキュメントの警告にもありますが、実行可能ランチャーがない場合があります。 今回のubuntuは、WSL2でUbuntuをインストールした時に作成されたコマンドで、unregisterした後にimportしてもきちんと動いたので問題にはなりませんでした。これは、インポートするときに、既存のディストリビューション名を利用したためと思われます。\nエクスポートやインポートの検証するために、NewUbuntuという名前で別途インポートした時には、NewUbuntuという実行可能ランチャーは作成されず、上記のデフォルトユーザーの設定は別の方法が必要になります(罠だ)\ndocker-desktop-dataのほうは、特に変更してないけど動いてそうだからいいのかな? 前の設定の確認とかやっておくのがいいんだろうな、本当は。。。\nまとめ ということで、Cドライブに300GB近い空きができて、心の余裕もできました。 今回は、同じPC内で別のドライブへの移動でしたが、他のPCにもこれで移行ができそうですね。 たまにはバックアップをとっておくのもいいのかも?と思いました(やるかどうかはまた別の話)\n","date":1690180128,"dir":"post/2023/","id":"ed431877ce11fe403fee77f7d26ce637","lang":"ja","lastmod":1690180128,"permalink":"https://blog.johtani.info/blog/2023/07/24/move-distribution-to-another-disk/","publishdate":"2023-07-24T06:28:48Z","summary":"WSL2にUbuntuを入れて、開発とかはこちらを利用しています。 また、Docker DesktopもWSL2のバックエンドエンジンを利用して","tags":["wsl","windows"],"title":"WSL2のディストリビューションの環境移行"},{"contents":"前回の記事で、VS Code+Dev Containerを導入しました。 残課題として「マルチコンテナ化」があるという話もしました。今回はDev Containerのdocker-compose.yml対応をした話をメモとして残しておきます。 実際、VS Code + Dev Containerに移行した後に、Esを起動してアプリからつなげるというのがうまくいかないというのがあったので対応がんばりました。。。\nDev Containerのdocker compose設定 この記事ではすでにdocker-compose.ymlが存在している状態の話をします。 変更する前は、devcontainer.jsonでベースのコンテナイメージの指定、マウントの設定などを行っていましたが、docker-compose.ymlにいくつかを移動しないといけません。 対応した時の作業の流れは以下のような感じです。\nワークスペース用のDockerfileの作成 docker-compose.ymlにワークスペース用のサービスを追加 devcontainer.jsonをdokcer-compose.ymlを利用する形に書き換え アプリでの接続文字列をlocalhostからdocker-compose.ymlのサービス名に変更 参考:対応した時のコミットです。差分などはこちらをごらんください。\ndevcontainerのリポジトリにPython+PostgreSQLのサンプルが公開されており、こちらを参考にしながら作業をしました。\n1. Dockerfileの作成 docker-compose.ymlだけでも完結するのかもしれないですが、いろいろやりたいことも出てくるかもしれないので別のファイルに切り出しました。 といっても、コンテナのイメージはdevcontainer.jsonに記述していたものを使っています。\nARG VARIANT=3.11-bookworm FROM mcr.microsoft.com/devcontainers/python:${VARIANT} ENV PYTHONUNBUFFERED 1 ENV TZ Asia/Tokyo TZはdevcontainer.jsonで指定していたものを、こちらに移行した形になります。 PYTHONUNBUFFEREDは参考にしたDockerfileの記載です。標準出力・エラーをバッファリングしない指定になっています。\n2. dokcer-compose.ymlにサービス追加 backendという名前のサービスをdevcontainer(VS Code)から接続するコンテナのサービス名にしています。\nservices: backend: build: context: . dockerfile: .devcontainer/Dockerfile init: true environment: - TZ=Asia/Tokyo command: sleep infinity volumes: - .:/workspace/search-research:cached - venv-search-research-backend:/workspace/search-research/.venv ... volumes: venv-search-research-backend: 1.で作成したDockerfileを利用します。docker-compose.ymlファイル自体は、プロジェクトのルートディレクトリに配置していますが、Dockerfileは.devcontainerディレクトリに入れたため、contextとdockerfileはこのような指定になっています。\ninitは、devcontainer.jsonで指定していた\u0026quot;runArgs\u0026quot;: [\u0026quot;--init\u0026quot;],の設定になります。\ncommandの部分は、コンテナが起動したままにしておくための設定です。\nvolumesでは2つのボリュームに関しての指定があります。 1つ目の/workspace...は、VS Codeがコンテナにプロジェクトをマウントする場所の指定です。 devcontainer.jsonだけを利用していた場合は意識していませんでしたが、/workspace/プロジェクト名というディレクトリにプロジェクトがマウントされていました。 docker-compose.ymlを利用する場合は、明示的に指定が必要です。 2つ目のvenv-...は.venvのディレクトリをコンテナの中だけのものにする設定を移植したものになります。 前回の記事ではコンテナIDをボリューム名に含めていましたが、こちらのほうがわかりやすいかと思い、プロジェクトの名前とサービス名をつけるようにしてみました。 Dev Containerで起動した場合はsearch-research_venv-search-research-backendという名前がついています(最初の部分はDev Containerがつけてるのかな?)\n3. dovcontainer.jsonの変更 devcountainer.jsonから呼び出すものの準備ができたので、devcontainer.jsonを書き換えます。 公式のドキュメントとしてDocker Compose向けのプロパティが紹介されています。 変更したものは次のような形です。\n{ \u0026#34;name\u0026#34;: \u0026#34;search-research\u0026#34;, \u0026#34;dockerComposeFile\u0026#34;: \u0026#34;../docker-compose.yml\u0026#34;, \u0026#34;service\u0026#34;: \u0026#34;backend\u0026#34;, \u0026#34;workspaceFolder\u0026#34;: \u0026#34;/workspace/search-research\u0026#34;, \u0026#34;postCreateCommand\u0026#34;: \u0026#34;/bin/sh ./.devcontainer/postCreateCommand.sh\u0026#34;, \u0026#34;customizations\u0026#34;: { ... dockerComposeFile : 利用するdocker-compose.ymlのファイルパス service:VS Codeが利用するワークスペース用のサービス名 workspaceFoldeer:VS Codeがコンテナに接続したときに開くフォルダのパス を指定します。これで、VS Codeでこのプロジェクトを開いた時に、Dev Containerがdocker-compose.ymlを使ってコンテナの起動(ビルドとか)を行ってくれます。\n4. アプリの接続文字列の書き換え こちらはおまけです。 PythonのアプリからElasticsearchに接続するときの文字列として、Dev Container化の前は、http://localhost:9200と指定をしていました。 Elasticsearch用のサービス(es)で、ポートフォワードをしていたためです。\nアプリ側もコンテナ化したので、Docker Composeが名前の解決をしてくれるので、http://es:9200という接続文字列で接続ができるようになりました。\nということで、ここまでで、VS Codeでプロジェクトを開くと、2つのコンテナ(backendとes)が起動してVS Code上でPythonアプリからEsへの接続ができるようになりました。\n追加の変更 参考のプルリクでは、上記まででしたがさらにいくつかの変更をそのあとやっています。\n起動するサービスの指定(開発だけするときはEsを起動したくない) devcontainer.jsonでrunServicesを使って指定できます(公式ドキュメント) GPUをコンテナから利用できるように devcontainer.jsonでfeaturesのnvidia-cudaを指定し、docker-compose.ymlでnvidiaのドライバーなどを設定することで対応しました。 nvidiaが公開しているcuda対応のコンテナイメージでもよかったのですが、こちらのほうが楽そうだったという理由です。featuresとコンテナのビルド、postCreateCommandの順序などはもうちょっと勉強しないといけない気がしています。 これらの対応はこちらのコミットで対応しています。\nGPUの対応は、私個人の環境はこれでいいのですが、複数の人がこのリポジトリを使う場合はどうやって切り替えたりするんだろう?という疑問が残っています。。。 今回はrinna/japanese-clipのモデルを使って、テキストからベクトルを生成する部分の処理のためにGPUを使いたいというモチベーションがあり、コンテナでもGPUを使えるようにしています(CPUだと時間がすごくかかる。。。)。\nサービス起動の新たな問題点 runServicesで起動するサービス名を指定したのはよかったのですが、Elasticsearchのサービスを起動して、データ登録や検索の確認を行おうと思った時に、EsのコンテナをVS Codeだけで起動する方法がまだわかっていません。。。 一度コンテナをビルドした後なら、「Remote Explorer」でOther Containerというくくりで表示され、右クリックで起動や停止ができそうなのだけど、新規サービスをdocker-compose.ymlに追加した場合は、自分でターミナルなどでコンテナのビルドをしないといけないかもしれないです。もうちょっと調べてみないとなぁ。\n副次的な効果 Docker Compose対応をしたことで、前回の記事での疑問点のうち、「コンテナ名」「VolumeのID」については懸念点がなくなりました。\n「コンテナ名」は、docker-compose.ymlのサービス名がコンテナ起動時に名前として利用されるため、Docker Desktopで見た時などの探しにくさはなくなりました。 ただ、「イメージ名」については、いまだに2つできています。「-uid」がつかないものの代わりに、search-research-backendというイメージが作られています。 ただし、実際に利用されるのは前回の記事に書いたようなvsc-search-research-bf04371c017c8d2f1dd5ad2529841b02e9ea1d1aaa4354c19edf53cef3f0c13b-uidという名前のイメージです。\n「VolumeのID」については、docker-compose.ymlのファイルで自分で名前をつけるようにしたので、コンテナのIDが利用されなくなったという次第です。 代わりに、プロジェクト名である「search-research」という名前を直接記述しているので、変数などで置き換えたほうがいいのかも?という気がしています。\nまとめ ということで、複数のコンテナを利用するプロジェクトでVS Code+Dev Container対応ができそうだということがわかりました。 ついでに、GPU対応もできたのでこれで、やっと他の検索エンジン対応などができる気がしています。 (その前にpre-commitを保存時にチェックする形に変更かなぁ) やりたいことからちょっとずつ外れている気もするけれど、新しいことを調べるのは楽しいですね。\n","date":1689902010,"dir":"post/2023/","id":"086b4fd5f77021a0a2aa6b0e90061486","lang":"ja","lastmod":1689902010,"permalink":"https://blog.johtani.info/blog/2023/07/21/multi-containers-with-dev-container/","publishdate":"2023-07-21T10:13:30+09:00","summary":"前回の記事で、VS Code+Dev Containerを導入しました。 残課題として「マルチコンテナ化」があるという話もしました。今回はDev C","tags":["python","dev container"],"title":"VS CodeとDev Container(docker-compose.yml対応)"},{"contents":"前回の記事で、pre-commitとPyCharmとWindowsの組み合わせで困っていることを書きました。 これについて、知り合いとチャットで話をしていて、それほどPyCharmにこだわりもないよなぁということになり、 であれば、ISIDのブログ(Dev Containerを使ってステップバイステップで作るPythonアプリケーション開発環境 - ISID テックブログ)を試してみるとすっきりするかもしれないとなり、Dev Container対応をブログを参考に行ってみました。\n順を追ってブログで説明されているので、どういう仕組みなのか、どの設定が何を意味しているのか?がとてもよくわかりやすくすんなり対応することができました。\nブログの手順をなぞっているところでいくつか固有の手順や疑問点が出てきたのでブログに書き記しておきます。 結果は、コミットしてあるものを見てください。\nブログとは違う手順 まずはISIDのブログとは違う点をいくつか。\n.venvはいったん削除 ブログでは新規のプロジェクトを作成していく過程で、コンテナ化した環境を作った後に.venvをDockerコンテナのボリュームにして、最後に仮想環境のPythonを生成していました。 私の場合は、すでにホストOS(実際にはWSL2のUbuntuだけど)で.venvのディレクトリを作成してある状態だったので、いったん削除する必要がありました。 すでに存在する.venvがbindマウントされてしまっている状態になるため、Dockerのボリュームとの整合性が取れなくなるようです。\nこの作業を行う前か、途中でDev Containerを停止した状態で、.venvを削除することで問題なくDockerのボリュームに仮想環境のPythonが登録されるようになります。\npostCreateCommand.shの呼び出し方 ファイルに実行権限がないと、実行権限エラーが出ました。 実行権限を与えるか、次のような記述で動くようになりました。 今は、ファイルに実行権限をつけるのではなく、次のような記述にしていますが、何か問題あるかな?\n\u0026#34;postCreateCommand\u0026#34;: \u0026#34;/bin/sh ./.devcontainer/postCreateCommand.sh\u0026#34;, 実際に動作しているログを見ると\n/bin/sh -c /bin/sh ./.devcontainer/postCreateCommand.sh\nとなっているので、少し気持ち悪いのだけれども。。。\npostCreateCommand.shの追加処理 今回Dev Containerを適用したプロジェクトでは、sentencepieceを利用します。 この、sentencepieceをpoetryがインストールするタイミングで、cmakeを要求してきました。 今回利用しているDocker Imageにはcmakeは含まれていないため、以下の処理を追加しています。\nsudo apt update sudo apt-get install cmake -y また、rinna/japanese-clipも利用しているのですが、こちらは、poetryで追加してインストールでは依存するパッケージがインストールされないため、pipコマンドを利用するようにしています。\npip install git+https://github.com/rinnakk/japanese-clip.git コンテナイメージを作った後にやりたいことを、自由にスクリプトで書けるのは便利ですね。\npre-commitのスクリプトの再生成 こちらも、既存の環境が残っているとPythonへのパスの違いの問題が出たので、作り直しました。 .git/hooks/pre-commitのファイルを削除し、pre-commit installをやったものをリポジトリにコミットしてあります。\n疑問点 作業をしていて疑問点もいくつか出てきたのでメモを残しておきます。ちなみに、これらの疑問について実際に調べるまでには至っていません。 時間を見て解決できればなぁと(できるのか?)。\nImageが2つ Dev Containerの設定を書いた後に、コンテナをビルドすると、Docker DesktopのImagesにイメージが出来上がります。 この時、イメージが2つできあがっています(なぜ?)。\nREPOSITORY TAG IMAGE ID CREATED SIZE vsc-search-research-bf04371c017c8d2f1dd5ad2529841b02e9ea1d1aaa4354c19edf53cef3f0c13b-features-uid latest 25c7e23416ec 3 days ago 1.69GB vsc-search-research-bf04371c017c8d2f1dd5ad2529841b02e9ea1d1aaa4354c19edf53cef3f0c13b-features latest fcf9eaeb2187 3 days ago 1.69GB こんな感じで、最後に-uidがついているかいないかの違いです。 実際にコンテナ起動時に利用されるのは-uidがついているものになります。 なぜ2つになっているのか、1つにする設定などがあるのか?といったところが気になるところです。\nContainerの名前 devcontainer.jsonの設定を書き換えて、コンテナをリビルドすると起動したコンテナの名前が自動で割り振られているようです。 今は、fervent_hopperとなっています。ランダムにつけられているようなのですが、名前を付ける方法はないのかなぁ?と。\ndevcontainer.jsonにはnameというプロパティもあるのですが、この値がどこで使われているのかはよくわかっていません。 Remote Explorerでコンテナの一覧が見えますが、ここでは、リポジトリ名が利用されているようです。\nVolumeのIDはどこから? devcontainer.jsonで次のような記述で、.venvのディレクトリようにDockerにボリュームを作っています。\n\u0026#34;mounts\u0026#34;: [ \u0026#34;source=venv-${devcontainerId},target=${containerWorkspaceFolder}/.venv,type=volume\u0026#34; ], 実際にコンテナでマウントされている情報を見ると\n/workspaces/search-research/.venv /var/lib/docker/volumes/venv-04emir9hi2caivtjunfe3l17452hkbb3hdut1qflbrn8n924ho5c/_data となっています。 04emir9hi2caivtjunfe3l17452hkbb3hdut1qflbrn8n924ho5cがdevcontainerIdに相当するのだとは思うのですが、誰がつけたものかなどがまだよくわかっていません。 もうちょっとわかりやすいものが使えるほうが嬉しいかも?と思っていたりします。 (複数Dev Containerを使い始めると、Docker Desktopで見ると、どのボリュームがどのDev Containerに紐づいているかがぱっと見ではわからない)\n.vscodeディレクトリどうしよう? たぶん、VS Codeを触っている過程で、何かの設定をしてしまったのだとは思うのですが、 .vscode/settings.jsonというファイルができており、次のような内容になっています。\n{ \u0026#34;git.ignoreLimitWarning\u0026#34;: true } 何か意味があるかも?ということで、コミットしてリポジトリに入れたのですが、いらないのかもしれないなぁと。\n残作業 とりあえず、VS CodeでPython環境ができて、VS CodeのTerminalでPythonのプログラムが実行できるのはわかった段階です。 いくつか、今後調べながらやる必要があるものが残っているのでメモとして残しておきます。\nマルチコンテナ化 今回Dev Containerに対応したプロジェクトでは、検索エンジンもDockerのコンテナとして起動して、Pythonのプログラムから接続したいと思っています。 となると、docker composeでいろいろと起動するほうがネットワークなどの設定も楽になるのでは?と思っているところです。 Dev Containerのテンプレートがいくつか用意されており、その中に「Python 3 \u0026amp; PostgreSQL (postgres)」というのを見つけたので、このあたりが参考になるのでは?と考えているところです。\npre-commitではなく、保存時にフォーマット pre-commit+localのコマンドも動くようにはなったのですが、保存時にフォーマットなどをかける設定もISIDのブログで記載がありました。 コミットしようとして、怒られるよりも、保存時に怒られたりするほうがいいかも?という気分になってきています。 どこまでが切り替え可能なのか?なども見ながら対応してみようかなと。\nもう少し開発してみて改善点を探っていく とりあえず動いたという段階です。 PyCharmとの違いがあるはずで(たとえば、git周りのGUIの違いとか)、そのあたりでどんな違いがあり、どんなものがあると嬉しいのか?といったものを調べる必要もあるかなと考えています。 TerminalでCtrl+rがうまく使えなかったり(Auto Hot Keyで検索のショートカットに割り当ててしまっているから。。。)などもあるので、この辺も調べていきたいなと。 Windows Terminalを使えたりするのかなぁ?\nまとめ さて、とりあえず、VS CodeでPythonのDev Container環境を作って動くところまでは来ました。 PyCharmを使いこなしていなかったのもあり、それほど違和感なく移行できるような気がしています。 調べることはまだまだあるし、プログラム書くつもりが、環境を整える方向に話がずれている気もしますが、まぁ面白いのでよしとするかなぁ。 いろいろまだまだ知らないことだらけです。。。\n","date":1689254123,"dir":"post/2023/","id":"a12474027c91fad5a861aa9919817d72","lang":"ja","lastmod":1689254123,"permalink":"https://blog.johtani.info/blog/2023/07/13/introduce-vs-code-and-dev-container/","publishdate":"2023-07-13T22:15:23+09:00","summary":"前回の記事で、pre-commitとPyCharmとWindowsの組み合わせで困っていることを書きました。 これについて、知り合いとチャット","tags":["python","dev container"],"title":"VS CodeとDev Containerの導入(まだ途中)"},{"contents":"最近、趣味(検索エンジンに関する趣味プロジェクト)でPythonのプログラムを書き始めました。\nきちんとPythonのプログラムをプロジェクトとして書いたことがないので、 Pythonのプロジェクトのディレクトリ構成などを手探りで進めているところです。 コードのフォーマットとかもやらないとなぁ?と知り合いのいるSlackでつぶやいたところ、gitのpre-commitフェーズでblackなどのフォーマットやスタイルを修正してくれるツールを実行する方法を教えてもらいました(PRまで送ってもらえたのでありがたい)。\nで、pre-commit周りの設定などを変えている段階で遭遇した問題点についてログを残しておこうと重いブログを書いています。 残念ながら現時点では解決してないんですけどね。。。\n手元の環境 簡単に環境を書いておくとこんな感じです。\nWindows上のPyCharmを開発で使用 プロジェクトのディレクトリはWSL2のUbuntu上 Python、gitはUbuntuのものを利用 プロジェクトのルートディレクトリにある.venvにvenvでPythonの仮想環境を作成してある 問題点 遭遇したpre-commitの問題点は次の通りです。\npre-commitの設定でrepo:localでローカルのプロジェクトにインストールしたコマンドを利用するように変更 すると、PyCharmでコミットすると、blackなどのコマンドが見つからない ターミナルでコミットするときはきちんと動作する 色々調べて試行錯誤した結果、現在はrepo:localでのローカルコマンドを使用する方法はあきらめました。 移行は、作業記録みたいなものです。どういう流れでpre-commitを取り込み、ローカルに切り替え、切り戻したかという話です。\npre-commitとpre-commit 最初に少し戸惑ったのは、pre-commitというツールとgitのpre-commitフックです。 gitのpre-commitのフックのために作られたPython製のpre-commitというツールがあります。\nこのPython製のツールを利用することで、プロジェクトに.pre-commit-config.yamlという設定ファイルを置けば設定に記述されたツールをgit commitのタイミングで実行してくれます。 実際には、pre-commitというツールの初期設定のタイミングでpre-commit installというコマンドを実行して .git/hooks/pre-commitというスクリプトが生成されます。 gitコマンドはcommitされた時に(commit前のフェーズ)でこのスクリプトを実行し、そこで.pre-commit-config.yamlが参照されています。\n.pre-commit-config.yamlの記述は次のようなものになります(最初にもらったPRより)。\nrepos: - repo: https://github.com/psf/black rev: 23.3.0 hooks: - id: black args: [\u0026#34;--line-length\u0026#34;, \u0026#34;120\u0026#34;, \u0026#34;.\u0026#34;] - repo: https://github.com/pycqa/flake8 rev: 6.0.0 hooks: - id: flake8 - repo: https://github.com/pycqa/isort rev: 5.12.0 hooks: - id: isort args: [\u0026#34;--profile\u0026#34;, \u0026#34;black\u0026#34;, \u0026#34;--filter-files\u0026#34;, \u0026#34;--multi-line\u0026#34;, \u0026#34;3\u0026#34;] - repo: https://github.com/pre-commit/mirrors-mypy rev: v1.4.1 hooks: - id: mypy 実際に、PRを取り込んで動かしてみたところ、blackなどが動いて行末のスーペースの除去や未使用のimportについて指摘をしてくれました。 便利だなと思ったのですが、ここで疑問が。\n今回は対象とするプロジェクトはpoetryで依存パッケージの管理を行っています。 今回、上記を動かすためにpoetryに追加されたものはpre-commitだけでした。 「あれ?blackとかはどこにあって、どうやって動いてるんだ?」という疑問が出てきます。 コンフィグファイルにはパスなどの記載をせず、それぞれのgithubリポジトリの記載とバージョンがあるからです。\npre-commitが使用するツールのインストール先 調べてみたところ、どうやらホームディレクトリにある.cache/pre-commitにblackなどのコマンドが見つかりました。 pre-commitツールが設定ファイルを基に、必要なコマンドをgithubからダウンロードしてきて実行時に利用しているようです。 pre-commitは便利なのだけど、せっかくPythonのプロジェクトだしそれぞれのツールはpoetryでpyproject.tomlでバージョンや設定を管理したほうがすっきりするのではないか?ということで、少し調べてみました。\n同じようなことを考えている方がブログを残していてくれました(Pythonレポジトリ用のpre-commit環境を整える)。 設定をpyproject.tomlに移行し、そのあと、ローカルのpetryでblackなどのコマンド類をインストールして利用する設定に書き換えています。 先人の肩に乗っかって、手元で同じようにpre-commitの設定ファイルのrepoをlocalに書き換えていき(その時のコミット)、ターミナルでpoetry run pre-commit run -aで動作確認できました。\nPyCharmでコミットしたらエラー ですが、実際に変更した状態でPyCharmからコミットしたら、コマンドが見つかりませんというエラーが出ます。。。 WSL2のターミナルでgit commitした場合は問題ありません。 どうして?となりますよね。。。。\n.git/hooks/pre-commitはPyCharm、ターミナルのどちらからも実行されています。 ですが、PyCharmではblackなどが見つからないというエラーが出ました。\n.git/hooks/pre-commitを見てみると、python実行するためのpythonのパスはプロジェクトにある.venv/bin/pythonを指定しています。 デバッグのために、このスクリプトにecho $PATHを差し込んで、git commitをPyCharmとターミナルからそれぞれ実行してみたところ、大きな違いがあります。\nターミナルで実行した場合は、\u0026lt;プロジェクトのディレクトリ\u0026gt;/.venv/binもPATH環境変数に存在していました。このため、.venv/binにあるblackなどを実行できています。\nPyCharmはWindowsから起動しています。プロジェクトのインタプリタとしては、WSL2のUbuntuにある.venv/bin/pythonを指定しているためもあり(?)、出力されたパスは/mnt/c/などのWindowsのパスなども入っていたりしますが、\u0026lt;プロジェクトのディレクトリ\u0026gt;/.venv/binは見つかりません。\nここからはソースコードは読んでいないので憶測ですが、.git/hooks/pre-commitで呼び出されているpre-commitツール(Python製)は、設定ファイルで指定されたコマンド(blackなど)を、コマンドとして今の呼び出されたコンテキストで実行しているのではないかということです。 実際、ターミナル上でもsource .venv/bin/activateを実行していない状態だとコマンドが見つからないというエラーが出ました。\n対処方法は? ということで、今考えられる対処方法としては次の通りです。\n.git/hooks/pre-commitのスクリプトを修正して、\u0026lt;プロジェクトのディレクトリ\u0026gt;/.venv/binのパスを見えるようにする PyCharmで何かしらの設定を探す PyCharmではgit操作しない repo:localはあきらめて、.pre-commit-config.yamlでblackなどは管理して、pyproject.tomlからは除外する 1.ですが、.git/hooks/pre-commitはprecommit intallを実行すると自動で生成されるスクリプトです。自分の環境で書き換えたとしても他の人が同じ環境を作るときにパッチを当てるなどをしないといけなくなります。\n2.はそれらしい設定を見つけることができませんでした。\n3.はめんどくさいですよね。。。ターミナルでgitのコメントを日本語で書くためにいくつか他の設定を考えないといけないです。。。\nということで、今回は4.の対処をとりました。やりたいことは、ツールや環境をそろえるのではなく、プロジェクトでやりたいことをやることなので。。。\nまとめ 最終的には元に戻ってしまいました(pyproject.tomlに設定周りは移動した)。 Windows環境がちょっとややこしくしてるかもな?というのと、個人のプロジェクトなのでそこまで気にしなくてもいいのでは?というのもありそうです。 それにしても、世の中の皆さんはフォーマッターとかどのタイミングで動かしてるんだろう?とかどういう環境構築してるんだろう?とか気になってます。 最近だとこういうディレクトリ構造にする、こういうツールを使うと便利などあれば、コメントいただけると嬉しいです。\n教えてもらったISIDのブログ(Dev Containerを使ってステップバイステップで作るPythonアプリケーション開発環境 - ISID テックブログ)も参考にさせてもらおうと思ってるところです。Pythonの環境をコンテナに移動したいなぁというのもあるので。ただ、PyCharmだからこのブログの通りには行かないけど(VS Codeに移るのも検討したほうがいいのかなぁ)。\n参考サイト Git - Git フック pre-commit Pythonレポジトリ用のpre-commit環境を整える Dev Containerを使ってステップバイステップで作るPythonアプリケーション開発環境 - ISID テックブログ ","date":1688954148,"dir":"post/2023/","id":"698cf3cbd796161d82c9ac438ebab5d2","lang":"ja","lastmod":1688954148,"permalink":"https://blog.johtani.info/blog/2023/07/10/pre-commit-and-python/","publishdate":"2023-07-10T10:55:48+09:00","summary":"最近、趣味(検索エンジンに関する趣味プロジェクト)でPythonのプログラムを書き始めました。 きちんとPythonのプログラムをプロジェクト","tags":["python"],"title":"pre-commitとvenvとPyCharm(困ったな?)"},{"contents":"今年もこの季節がやってきました。 Berlin Buzzwordsにオンラインで出張してました。 今年もハイブリッド開催をしてくれたので、オンラインで参加できました。 現地ではブースが出たり、朝食なども用意されているようでした。今年は昨年と違いマスク必須でもなくなったようです。 MICESも去年同様、現地開催のみのようです(今見たら、昨年のビデオとスライドが公開されてるので、時間見つけてみてみよう)。\n今年はうれしいことに検索に絡むセッションが大多数でした。世の中的にChatGPTの盛り上がりやベクトル検索がいろんな検索エンジンで使えるようになってきたこともあり、 大規模言語モデルと検索エンジン、ベクトルデータベースに関する話がたくさんありました(昨年まではKafkaやストリーム処理の話も多かったんですが)。\nということで、今年もセッションを見ながら残したメモを公開しておきます。\n簡単にメモ What defines the “open” in “open AI”? セッションページ:What defines the “open” in “open AI”? 動画: Jennifer Ding - What defines the \u0026ldquo;open\u0026rdquo; in \u0026ldquo;open AI\u0026rdquo;? - YouTube \u0026ldquo;OpenAI\u0026quot;の話ではなく、オープンなAIとは?という話で、ライセンスの話であったり、コミュニティ(データセットの公開とかベンチマークの共有とか)に関する話であったり。 後半は気を抜いてしまって話をうまく聞き取れてないので、興味がある方はビデオで。。。\nVectorize Your Open Source Search Engine セッションページ:Vectorize Your Open Source Search Engine 動画: Atita Arora - Vectorize Your Open Source Search Engine - YouTube ベクトル検索が流行ってきてるけど、これまでの検索(エンジン)に対して、どうやってベクトル検索を取り入れる?という話です。 ベクトル検索ってどんなもので、どういうことの助けになりそうか?じゃあ、どうやって、これまでの検索が改善したかを見ていくのか? という、これからベクトル検索を取り入れようとしている時にどのようなアーキテクチャにして、 どのような考慮するポイント(モデルの選択とかスケーラビリティとか)にどんなものがあるのか?といった紹介でした。 ざっくりですが、ベクトル検索やるのにどんなことをやっていけばよいのか?という地図になるようなセッションでした。\nSupercharging your transformers with synthetic query generation and lexical search セッションページ: Supercharging your transformers with synthetic query generation and lexical search 動画: Milind Shyani - Supercharging your transformers with synthetic query generation and lexical search - YouTube AWSの人の話でした。こちらもトランスフォーマーが検索に使えると便利だよねという話なのですが。 LLMを使うと高コストでサイズがどんどん大きくなっていて、小さな学習済みのモデルだといまいちな精度でだし、 ファインチューニングしたい場合、ドメインに特化したデータはなかなかないよね。とくにデータ(検索したいもの)はあるけど、クエリがないということがよくあるよね。 そこで、LLMを使って、データからクエリを作って、正解データを作り、それでファインチューニングすればいいのでは? ということで、やってみました、どうでしたという話でした。\nブログなどもあるので参考にすると面白いかも\nThe Debate Returns (with more vectors) Which Search Engine? セッションページ:The Debate Returns (with more vectors) Which Search Engine? 動画:Charlie Hull - The Debate Returns (with more vectors) Which Search Engine? - YouTube 今年も検索エンジンの人を集めてパネルディスカッションです。今年は次の方たちが参加してディスカッションでした。\n参加者 Jo:Vespaの人。ランキングとかがよくできてるからVespa好き Alessandro:Apache Solrの人。SolrのPMCメンバー。なんでSolr?Pure OSSだし。スケーラブルだ Etienne:Weaviateの人。新しいAI nativeなベクトルデータベース Philipp:Elasticの人。 Kacper:Qdrantの人。 質問は次のようなものでした。\n最初の質問:スケールの話。スケールアウトかな? 2つ目の質問:どんなアプリケーションが適していないか? 3つ目の質問:どうやってAIをサポートできるの? 4つ目の質問:どうやってコミュニティにアプローチしてる? 5つ目の質問:自分の検索エンジンが使えない時に何を使う? 6つ目の質問:今後に何が面白そう? 最後の質問:あなたの検索エンジンが使われてるユースケースで一番好きなものは? 2つ目や5つ目の質問が面白いですよね。実際の内容はぜひビデオを見ていただくのがいいかと(メモも取ったけど、聞いてもらうほうが面白そうだし)。\nWhat\u0026rsquo;s coming next with Apache Lucene? セッションページ:What\u0026rsquo;s coming next with Apache Lucene? 動画:Uwe Schindler - What\u0026rsquo;s coming next with Apache Lucene? - YouTube 毎年恒例Uweさん。今年Luceneが25周年という話で、これまでの進化の話を駆け足でしてくれました。 あとは、後半は来週9.7が出るよということで、9.7で入ってくるベクトルの距離計算の最適化に関して説明してくれています。 次のバージョンのElasticsearchでもこの最適化が使えるようになるという話もされていましたので、ベクトル検索を使ってる方は、次のバージョンも楽しみですね。\nBuilding MLOps Infrastructure at Japan\u0026rsquo;s Largest C2C E-Commerce Site セッションページ:Building MLOps Infrastructure at Japan\u0026rsquo;s Largest C2C E-Commerce Site 動画:Berlin Buzzwords 2023: Building MLOps Infrastructure at Japan\u0026rsquo;s Largest C2C E-Commerce Site - YouTube メルカリの検索システムに関係しているMLOps周りがどうやって進化してきたのか?という話でした。 英語にいらすとやの絵があるスライドがドイツで使われているのがとても新鮮ですw\nHighly Available Search at Shopify セッションページ:Highly Available Search at Shopify 動画:Khosrow Ebrahimpour - Highly Available Search at Shopify - YouTube Shopifyの検索プラットフォームチームの人の、Shopifyの検索プラットフォームがどういったものか?(EsとKafka使ってる)どんな工夫をしているか?という話です。 Kubeconでも他の同僚の方が話をされている見たいで、そちらも参考になるとのことでした(動画)。 スキーマ変更時の話とかもあり、実践的でした。最後に将来的な話でやはりベクトル検索というキーワードが出てきていました。あとは、データ量が大きいのでスケーリングの挑戦もあるとのこと。\nUsing Dense Vector search at the EU Publications Office セッションページ:Using Dense Vector search at the EU Publications Office 動画:Martin Bayton - Using Dense Vector search at the EU Publications Office - YouTube EUのPublication Office(日本だと公文書館とかになるのかなぁ?)の検索サービスで、Googleみたいなこと(検索結果の上にスニペットが出たり、そこにハイライトされたり)をやってみたいよね?という話みたいでした。実際公開してるかはわからないですが、途中からはPureinsightsという会社のプラットフォームで似たようなことをやるデモになってました。\nGoogleでも12%のクエリが、質問の自然文になっているという話で、検索結果にナレッジグラフからの情報(スニペットとか、質問に対する答えとか、地図とか)が出るようになってきていますと。 それをPublication Officeのデータで再現したデモを行った後に、どんな感じのアーキテクチャなのか?という概略を説明されています。国会図書館とかの検索サービスやってる方が興味を持ったりするかもなーと思ったり、思わなかったり?\nLearning to hybrid search セッションページ:Learning to hybrid search 動画:Berlin Buzzwords 2023: Learning to hybrid search - YouTube これまたキーワード検索とセマンティック検索のハイブリッドの話です。 よくハイブリッド検索というのを聞きますが、データだったりベンチマークなどの話があまりないですよね?昨年AmazonがECSIというデータセットを公開したりしています(rejasupotaroさんが年末に書かれた記事にも出てきていました)。 これにLearn to Rankとかもテストできるようなデータ(レビューや評価、カテゴリーとか)を拡張したものを作って、それをもとにいろいろとハイブリッド検索で精度を測ってみたというお話でした。 Metarankというリランキングエンジンの会社の方たちで、Metarankを使ってハイブリッドな検索結果のリランキングで精度がどのように上げられるか?という話です。 今年のTRECのProduct Search Trackの話もされていました。 これが元ネタのブログかな?\nCatch the fraud — with observability and analytics セッションページ:Catch the fraud — with observability and analytics 動画:まだ? 最後は元同僚のセッションです。こちらは検索ではなく、ちょっと自虐的なネタをもとにしたオブザバビリティおよび分析のお話です。 コミュニティの人たちの貢献(ブログ書いたりプルリク送ったり、どこかで話をしたり)を計測して、年間の貢献者に対してプレゼントを上げるというのをやっているみたいです。 で、昨年の最も貢献した人にMac Bookをプレゼントするというすばらしい(暴挙)話で、チートしようとした人がいてそれを分析した話でしたw 締め切り直前に信じられない量の貢献したという登録がブラジルからあり、何かおかしいよね?ということで、Elastic Stackのオブザバビリティの機能などを元に分析してチートした人を除外していったよという話でした。 Kibanaが使いやすくなってるのがわかるセッションで面白かったです。\nまとめ 検索がまたすごく盛り上がってきたなーという時間があるカンファレンスでした。みんな似たような話(ベクトル検索、LLM、AIなど)だったりしますが、 知らないプロダクトで興味が出てくるものもあったし、Amazonのデータセットがあるからいろいろ試してみることもできそうだなぁと。\nすでにビデオが公開されはじめているので、気になったセッションのビデオも見てから後日またブログを書こうとおもいます (たぶん、一覧が作成されるので後日リンクを貼っておきます)。\n来年の予定(6月11日から開催)も公開されていましたし。来年も楽しみですね。 来年はプロダクションでベクトル検索やってみた話とかがさらに出てくるのかなぁ?\n","date":1687278645,"dir":"post/2023/","id":"9335522f4c8dbc7256a42a091e6e00bc","lang":"ja","lastmod":1687278645,"permalink":"https://blog.johtani.info/blog/2023/06/21/attend-berlin-buzzwords-2023/","publishdate":"2023-06-21T01:30:45+09:00","summary":"今年もこの季節がやってきました。 Berlin Buzzwordsにオンラインで出張してました。 今年もハイブリッド開催をしてくれたので、オンラインで参加で","tags":["conference","belin buzzwords"],"title":"今年もオンラインでBerlin Buzzwordsに参加した"},{"contents":"今年もなんとか振り返りブログを書いてます(時間大丈夫かな?w)。紅白をリアタイで見ながら。\n振り返り(2021年に書いた抱負から) まずは振り返りをと。\nフリーランス継続 ありがたいことに個人事業主として今年も1年乗り越えられました。 ZOZOさんには引き続きお世話になっている感じです。 10月からは今月末まで別のお客さんを手伝っていたりという感じでした(アップグレードの手伝いとか)。 相変わらず完全リモートで作業をさせていただいてます。\nただ、来年は今の所、余力がある感じになっているので、新しい仕事を見つけたいところだなあという感じです。 検索で何かお手伝いできることあれば、気軽にお声がけいただければと。\nプログラミング Linderaの大須賀さんのおかげで、レビューは定期的にやらせていただいてますw 業務がっつりというほどではないのですが、検証用のコードを書いたりはしています。\n個人用では、BGM環境のためにシェルを書いたり、文字化けしてるデータを解析したりするのにコードを書いてますが、もうちょっと量を増やしたいところです。 コードがっつり書く仕事をやらせてもらうのとかやらせてもらうのがいいかもなぁ。\n書くよりもどうしても読むほうが多くなってる気がします。\nブッチャー本ちゃんと読む 全部ではないですが、ZOZOさんで輪読をしたりしていました。 が、自分で全部読むといったところまではできてないです。\n読んだ本のブログを書く これはできてないですね。 読むのはちょとちゃってるんですが、ブログを書くところまではできてない。 メモとりながら読みたいですね。\n振り返り(今年あったできごと) ここからは今年の出来事を。 今年もずっと自宅で仕事した。来年は出張とかできるのかなあ?\n自宅環境 今年もDIY 検索ペンギン本が出版された 仕事場を模様替えしました。 今年もずっとWindows環境をメインで仕事をしていました。 年末まではM1 Macを借りて作業するという経験もできたのでよかったです。 今年仕事の環境は少し変わって、AVアンプ(譲り受けたもの)+Polk Audioのスピーカーで音が良くなりましたw あと、机の天板を大きくして、作業がやりやすくなりました。写真はそのうち。\n仕事場の模様替えにもなるのですが、今年のDIYはラブリコ+有孔ボードでケーブルやキーボードをすっきり片付けられる環境を作ってみました。 壁を有効活用できるのはよかったです。こちらについては、別途ブログを書こうと思います。\n今年最大のニュースは検索ペンギン本を出版したことです。 声をかけていただいた打田さんには感謝です。著者の皆さん検索システムを色々と手掛けられているので良い本になったと思います。\n『検索システム ― 実務者のための開発改善ガイドブック』 – 技術書出版と販売のラムダノート おー、届いたー pic.twitter.com/RbY5tOe9GB\n\u0026mdash; Jun Ohtani (@johtani) May 17, 2022 いろんなところで輪読も開催されているようで、顔を出してみたいなぁ。 輪読やってます!外部の人を呼んでもOKという方がいたら、参加してみたいのでTwitterでメンションしてもらえると嬉しいです。\n来年の抱負 ということで、来年の抱負です。\nフリーランス継続 プログラミング ベクトル検索まわりをさわる 本を読む 今年もありがたいことに仕事を継続していただけて、乗り越えられました。 来年も価値を提供できるように頑張っていきます。 もっといろんな会社の検索システムを見てみたいですし、検索エンジン入れてみたけどここからどうすればいい?という方も増えて来ているような気がするので、気軽に声をかけていただければと。\nプログラミングは、家の音楽ファイルの文字化けを直すプログラムをもう少しちゃんと書いてからブログを書きたいなと。まぁ、個人的なプログラムなので誰も嬉しくないかもですが(色々検討した結果Javaで書いてる)。 あとは、オライリーさんの初めてのGo言語を買ったのもあるので、前にRustで書いたElasticsearchへのBulk登録のツールをGoで書いてみようかなと考えているところです。みんなはデータ登録するときはどうしてるんだろう?\nNLPでBERTなどによる目まぐるしい進歩の影響もあり、ベクトル検索やセマンティック検索といった検索技術が各社から出て来ています。 ElasticsearchでもGAされたのもあり、今後ますます注目を浴びる技術になるのだろうなと。 ただ、これまでの検索とどう組み合わせるのがいいのか?どう言ったメリットデメリットがあるのか?向き不向きは?といったものもあるので、仕組みを調べながら色々と試行錯誤してみたいと思っています。\nさいごは、毎年書いてる気もしますが、本を読むのもやらんとなぁ。 あたらしいネタを仕入れては実践できる時間もとりつつ、他のことにも目を向けたいと思っています。\n今年は仕事の変化も少し出て来ているので、来年は新しいことをいくつかやってみたいところです。 あとは、外に出る機会が増やせるといいなぁ、少しずつ人から刺激をもらいたいと思っています。\nさて、今年は年内に無事描き終わりました。 来年もよろしくお願いいたします、良い年にしたいなー。\n","date":1672486684,"dir":"post/2022/","id":"df30d810068e4656498e5972c6de7e3d","lang":"ja","lastmod":1672486684,"permalink":"https://blog.johtani.info/blog/2022/12/31/review-2022/","publishdate":"2022-12-31T20:38:04+09:00","summary":"今年もなんとか振り返りブログを書いてます(時間大丈夫かな?w)。紅白をリアタイで見ながら。 振り返り(2021年に書いた抱負から) まずは振り返","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2022)"},{"contents":"PySpaアドベントカレンダーの12/15のエントリーです。昨日はtaichiさんでした。 今年はDIYではなく、PCにまつわる話を。\n仕事中はBGMが基本 フリーランスを始めて(2020年初頭)からすぐに、自宅で仕事をする情勢になりました。 打合せをしていないとき、カンファレンスの発表などの動画を見ていないときは基本的にBGMをかけて作業をしています。 音源としては、CDなどから音楽ファイルにしたり、AmazonやSonyのサイトで購入した音楽ファイルなどがNASにあります。\n今年10月までの環境 2020年の後半に次のような環境を構築して今年の10月まで使っていました。\nLibreELECをラズパイ4に入れて、Kodiのリモコンをスマホに入れたら快適になった\n\u0026mdash; Jun Ohtani (@johtani) October 20, 2020 KODIと呼ばれるマルチメディアセンター?のようなソフトで、それを動かす最小限のOSとして、LibreELECが公開されています。 これをラズパイ4に入れて、NASからファイルをSSDにコピーしてそれをラズパイに接続して音楽を聞いていました。 毎回ラズパイの画面を見に行くのも面倒なので、再生などの操作にはAndroid用のKodiのリモコンアプリを使っていました。\n場所も取らないのでよかったのですが、使っているといくつか問題点が。\n時々調子悪(音が出ない、リモコンからつながらない、無反応など)くなって、ラズパイ再起動 音楽ファイルを購入して増えた時に、外付けSSDを取り外してPCでコピーしたり スマホじゃないと再生できない(PCのクライアントもあったのかもだけど調べてなかった) Ubuntu on Mac mini 10月に模様替えをして、2012年製のMac Miniが宙ぶらりんになりました。 さすがに古いしメインマシンがWindowsになっているのもあり、macOSである必要も特にないので、Ubuntu 22.04を入れて何かに使えるのでは?と。 また、1TBのSSDに内臓ディスクを乗せ換えていたのもあり、音楽再生に使ってみようということに。 なので、Kodiの環境で困っていた点も考慮して、ほしい機能を元にちょっと探してみました。\n音楽再生 on Ubuntu 音楽再生でほしい要件としては次のようなものです。\nUbuntuで音楽再生できるソフト(あたりまえ) PCから操作したい(できればブラウザ) 音楽ファイルの更新(ローカルでもいいけどNASからもってきたり) 日本語の曲情報も表示 対象音楽ファイルが豊富(そんなに制限があるものはないだろうなぁ) 上記の要件をもとに適当にググって見つけてきたのがOwnToneというソフトでした。\nOwnTone OwnToneの説明は公式サイトを見ていただくとして、OwnToneにしてよかったなというのが以下の点です。\nインストールが簡単(apt-getでインストールできる) サポートフォーマットが豊富 Web UIがついてる(ブラウザで見えるし、スマホでもOK。どのブラウザから見ても今の状況も分かる) 簡単だけど検索できる プレイリスト対応(ファイルパスを入れるだけ) サムネイルとかも出てくる(どうやってんだろう?w) AirPlayで再生できる(AVアンプを利用しており、そこにAirPlayで再生できてる) OSS(まだソースは見たことないですがw) 再生画面例\nやっぱ検索も気になるよね?\n日本語も検索できるな。 pic.twitter.com/EF6WHkJKli\n\u0026mdash; Jun Ohtani (@johtani) October 19, 2022 とりあえず、インストールして画面もすぐに出て操作も簡単で、便利な世の中になったなーと感動しましたw\nただ、音がヘッドフォン端子に刺したアナログ出力先のスピーカーではなく、本体のスピーカーで最初はなってしまいましたww Linuxの音周りが全然わかってない問題が発覚。\n幸い、先週のPyspa Advent Calendarのエントリーを書いていたaodag先生に助言をいただき、alsamixerで音の設定を見たところ、ヘッドフォン端子がミュートされていたので、ミュートを外して無事再生できました。 インストール当初はYAMAHAのアクティブスピーカーにJust Mixer経由でヘッドフォン端子(アナログ)で出力して音楽再生をしていました。 今は(この記事を書いてる現時点で)、AVアンプのAirPlayにOwnToneから音を流している形で聞いています(便利なんだけど、当初の想定とは異なる、理由は後述)。\nファイルのコピーとか さて、上にも書きましたが、NASにバックアップもかねて音楽ファイルを保存してあります。 新しく買ったファイルもここに置くようになっています。 OwnToneのMac MiniからNASをネットワーク経由で見に行くのもいいのですが、できればローカルにあったほうがネットに影響も出ないなと。\nということで、定期的にNASをウォッチしてMac Miniにファイルをコピーするようなプログラム(Bashスクリプト)を書いてみました。 毎回購入後に手で実行もめんどくさいので毎日夜中にcron実行するような設定になっています。\nスクリプトの中身は次のような感じです。\nfindコマンドで特定の日時(最近コピーしたファイルの日付)以降(-newermtオプション)のファイルのリスト(音楽ファイルの拡張子に限定)を取得 取得したリストをもとに以下の操作 ファイルをコピー コピーしたファイルをコピーした日付のプレイリストを作って入れる(プレイリストはパスだけ書けばOK) mp4形式だと聞けない端末もあるので、soundconverterコマンドでmp3に変換してNASに戻す 最新のファイルの日付を保存(次回のfindコマンド) ファイルがあったら、OwnToneの再読み込みのエンドポイントをcurlでキック NASはSambaでマウントして、見えるようにしてあります。 やっぱり、自動化便利ですねぇ。 気に入った曲を買ってNASに入れとけば聞けるようになるのは本当に便利。\n他にもスマートプレイリストとかもあるので、活用しないとな。\n今後の課題 さて、すごく便利になったのですが、課題も残っています。\n音声出力問題 アナログ出力はaodag先生の助言ですぐに解決したのですが、takabowから譲り受けたAVアンプを導入してから実は音の出力がうまくいっていません。\nHDMI、光端子出力でAVアンプにつなごうとしたのですが、私のUbuntu力(Linux力?)が全然不足しているのでうまくいっていません。ググりつつ、HDMI、光出力でamixerというコマンドで音声ファイルを鳴らすところまでは行ったのですが、OwnToneに設定するとうまくいかない状況です。 結局、解決してないのですが、AVアンプのAirPlayのレシーバー経由で音楽再生ができてしまったので、とりあえずAirPlayで運用することにしました。時間を見つけてaodag先生の記事を読み直して再チャレンジしないとな(けど、鳴ってるしなぁ、音w)。\n文字化け問題 これは、OwnToneというよりはもともとあった問題です。 古い音楽ファイルだったり、Wav形式のファイルなど、様々な形式のファイルを持っています。 音楽サーバーとは別に、音楽ファイルの検索をできるようにしつつ、付加的な情報(Wikimediaなどのデータとか)を付与して、検索できるようにしてみようと思い、音楽ファイルからメタデータを抜き出して、ElasticのApp Searchにいれるデータを作るツールを書いたりしています。 この時にも文字化けに遭遇しました。\n様々な音楽ファイルにはメタデータを付与することができる仕様が決まっています(ID3タグ - Wikipediaなど)。 ただ、文字コードの情報が入っていなかったり、デフォルトとは違う文字コードでデータを付与したファイルがあったり、いろいろな原因で文字化けしているものがあります。 昨年Amazonで購入したmp3の中にも文字化けしているものもあったりします。Wavファイルに付与されたタグなどは、容赦なくShift-JISだったりしますが、読み込むソフトはUTF-8で読もうとしたり。。。\n検索サーバーにデータを抜き出して入れるツールを書いているときは、元のファイルを変更することなく、抜き出す時点でいくつかの文字化けに対応した処理を書いたのですが、今回のOwnToneで曲を流すと結局、元のファイルをきれいにしないとダメだということに気づきました(すぐわかるだろ。。。)\nということで、書いている途中のツールをもとに、根本的な文字化けのファイルのメタデータをきれいにするプログラムを書かないといけないなぁと。\nちなみに、メタデータの抜き出しにはJavaでプログラムを書いており、JAudiotaggerというライブラリを利用しています。 Pythonや他のJavaのライブラリを試そうとしたのですが、文字コードが決め打ちで抜かれているものが多く、ライブラリから読みだした時点ですでにどうしようもない状態のものが多いといった問題からこのライブラリにたどり着きました(まぁ、まだちゃんとしたものができていないんですけどね)。\n検索サーバー OwnToneのUIはブラウザでうごきます。 検索窓もついています。 が、先ほども書いたように、他にもデータを追加して、いろんな検索をしてみたいなぁと(ドラマに使われてたとか、CMにつかわれてたとかとか)。 検索が好きでいろいろとやってるので、その辺も遊んでみたいなぁと思っているところです(実際、ElasticのApp SearchにWikidataから生成した類義語を入れてみたりしている)。\nこうやってブログにしてしまったので、課題をつぶしていなかったら、Twitterなどでつついてくださいw\nまとめ 構成図とかは書かなかったですが、OwnToneを使うと簡単にWeb UIが入った音楽サーバーが使えるようになって、仕事がはかどりますよという記事でした。 他にもこれに関するネタを募集してますので、コメントもらえるとうれしいです(Twitterでメンションも大歓迎)。\n","date":1671030358,"dir":"post/2022/","id":"67c2ae6761e89be0fa66db9623b40d30","lang":"ja","lastmod":1671030358,"permalink":"https://blog.johtani.info/blog/2022/12/15/music-server-on-mac-mini/","publishdate":"2022-12-15T00:05:58+09:00","summary":"PySpaアドベントカレンダーの12/15のエントリーです。昨日はtaichiさんでした。 今年はDIYではなく、PCにまつわる話を。 仕事中は","tags":["misc","music"],"title":"仕事中のBGM環境"},{"contents":"本記事は情報検索・検索技術 Advent Calendar 2022の9日目の記事です。\nだいぶ間が空いてしまいましたが、日本語のオートコンプリートに関する記事の続きです。 という感じで、Suggesterのデータ構造とか仕組みを書こうと思っていたのですが、思ったよりも調べないといけないことが多くて挫折しました。。。 (これの続きは年末年始で調べて書くはず?)\nということで、代わりにElasticsearch/OpenSearchのアーキテクチャの変更に関してさらっとまとめてお茶を濁してみようと思います。\n発端はElasticON Tokyo? 先週の11月30日に、ElasticのオフラインイベントであるElasticON Tokyoが開催され参加しました。 参加しようと思ったのは、10月の頭にElasticのブログで公開された「Stateless — your new state of find with Elasticsearch」というアーキテクチャの変更がきっかけです。\n(図はElasticのブログから引用)\nElasticsearchはLuceneのインデックスを分散したシステムとしてスケールアウトできるようにするという目的でリリースされました。 インデックスをシャードという単位で複数のElasticsearchのノードにデータを保存し、レプリカを作ることで分散する仕組みを実装していました。 Elasticsearchでは、インデックスのレプリカは、作成したインデックスを定期的にコピーするのではなく、登録するデータがElasticsearchのクラスターにやってきた時に、 データ自体をコピー先にも配り、プライマリーやレプリカとなるシャードがあるノード上でそれぞれインデックスに登録する処理を行うという処理の流れです(古いけど、わかりやすい説明はこちら)。 この場合、インデックスにデータを登録する処理(転置インデックスのデータ構造に変換する処理など)は、レプリカの数だけ同じ処理がクラスター上で発生します。\nこの基本的なアーキテクチャをもとに、保持するデータの鮮度(新しいデータのほうが検索頻度が高い、インデックス登録する時はマシンは多く、古くなったデータが入ったインデックスはコストが低いマシンになど)などを元に、クラスター内のノードの特性を異なるものが混在するような複雑な仕組みを作ってきました。 いろいろなデータの持ち方などで多くのデータなどを保持できるようにしてきたのですが、クラスター全体としては、検索の負荷のピークをさばけるような構成を基本的に保持しておくというかんがえです。\nただ、昨今は必要に応じてスケールアウト(リクエストが増えたりデータ量が増えた時)、スケールイン(夜中は利用者が少ないからクラスターを小さくしたい時)できるような仕組みのほうが求められています。 そこで、発表されたのが上記のブログであり、上図の新しいアーキテクチャです。 計算処理(データを登録、検索する処理)とストレージを分離し、さらに登録する処理と検索する処理も分離した構成です。 このようなアーキテクチャにすることで、登録処理の演算コストがレプリカごとに必要ではなくなり、検索の部分だけだったり、登録の部分だけをスケールアウト・インできるような自由度が手に入ります。 また、ストレージ部分でレプリカを担保(S3とかのオブジェクトストレージで冗長性を担保)できれば、レプリカのストレージコストも必要なくなります。\nというブログが発表されたのですが、詳細などはまだよくわからなかったのでElasticON Tokyoに参加して詳しい話が聞けるのかなぁと期待していました。\n参加当日の朝のびっくりするニュース 11月30日の朝に起きて、出かけようかと思っていたところに、AWSのre:Inventで発表されたニュースが舞い込んできました。\nほー(まだタイトルしか読んでない)https://t.co/KK22duaBNH\n\u0026mdash; Jun Ohtani (@johtani) November 29, 2022 Amazon OpenSearchがServerlessオプションを発表というニュースです。 (Amazon OpenSearchとは、AWSがElasticsearchをフォークして始めた検索エンジンで、Amazon OpenSearch Serviceというのは、AWSがそれをSaaSとして提供しているものです)\nまぁ、気になりますよね、「Serverless」ってキーワードに。 ElasticON Tokyoに向かう電車でブログを読んだり、どんな仕組みかを調べたので、それを簡単にまとめておきます。\nプレビュー段階(Tokyoリージョンではもう試せる) これまでのAmazon OpenSearch Serviceとは別(オンザフライで移行はできない?) 「コレクション」という単位でクラスターを管理(スケールインとかアウトとか) コレクションにはタイプがあり、タイムシリーズ(ログとか)か検索のユースケースなのかで使い分ける(公式ドキュメント) インデックス処理と検索処理で計算ユニット(OCU)が別々にスケールできる(下図) 作成されたインデックスはAmazon S3に保存され、そこで冗長性は担保される。(下図) 検索処理のユニットはS3のデータをローカルに持ってきて処理をできる データ登録とかのAPIは基本的にServerlessかどうかで違いはなさそう(これまで通りのクライアントでアクセスとかで競う) 設定した範囲でいいかんじにスケールアウトインしてくれそう(ほんとかな?) もちろん、いくつか制限がある(サポートしてないプラグインとか操作もある) (図はAWSのドキュメントより引用)\n発表時のブログでは詳しくはわからないのですが、公式ドキュメントではさらに詳しく説明がありました。 こちらを読むほうが仕組みがわかると思います。 今後もどんどんドキュメントは充実していくんだろうなと。今ならまだサクッと読める量ですw\nただ、「サーバーレス」という定義が私はよくわかりませんでした。 公式ドキュメントを読むとコレクションを作ると少なくとも4つのOCUが起動しているみたいで課金されると記載があります。\nまぁ、Elasticの発表と同様に、これまでは最大負荷の時を元にクラスターを維持せずとも、より柔軟に検索だけ、登録処理だけを一時的にスケールできるとコストを下げられそうですね。 すぐに誰かが使ってみたブログなどを出してくれると思うので、細かな使用感などはそのうちわかってくるかと。\n今後は? ElasticもAWSも考え方の基本となっているのは、Berlin BuzzwordsでAmazonのMikeさん(Luceneのコミッター)が2019年に発表されたものだと思っています。 アーキテクチャの変更がどんな影響が出るかはわからないですが、少なくとも検索のユースケースでよりスケールアウトしやすくなるだろうなと。 どちらもSaaSとしての仕組みとして提供するので、検索エンジンそのものの機能として公開されるかはわからないです。 ですが、そのほかの検索エンジンも出てきていますし、今後も検索エンジンから目をはなせないです。 今回は残念ながら触っていませんが、時間を見つけて使ってみたいです(Elasticも早く出してくれないかなー)\nということで、当初の予定とは違うブログになってしまいました。。。 技術的な深い話はまたどこかで。。。\n参考文献 Stateless — your new state of find with Elasticsearch | Elastic Blog Preview: Amazon OpenSearch Serverless – Run Search and Analytics Workloads without Managing Clusters | AWS News Blog Berlin Buzzwords 2019: Michael Sokolov \u0026amp; Mike McCandless–E-Commerce search at scale on Apache Lucene - YouTube ","date":1670516125,"dir":"post/2022/","id":"9693a1e77dee5785b1dc61ccffd2e906","lang":"ja","lastmod":1670516125,"permalink":"https://blog.johtani.info/blog/2022/12/09/open-search-serverless/","publishdate":"2022-12-09T01:15:25+09:00","summary":"本記事は情報検索・検索技術 Advent Calendar 2022の9日目の記事です。 だいぶ間が空いてしまいましたが、日本語のオートコンプリートに関する記事の続きです。","tags":["elasticsearch","opensearch"],"title":"ElasticsearchのアーキテクチャとStateless / Serverless"},{"contents":"前回は日本語用オートコンプリートのためのAnalyzerとして、どうやって使うのかを簡単に紹介しました。\n今回はもう少し、いろんなパターンを試してみたいと思います。\nローマ字入力のゆれ 前回のサンプルでも「吾輩\u0026hellip;」のデータをサジェストするためのサンプルとして、「wagah」という「わがはい」をローマ字にしたものを利用しました。\nちなみにローマ字というとどんなものを思い起こしますか? 普通は学校で習ったヘボン式あたりだと思います。 Kuromojiの読みでローマ字出力するには通常、kuromoji_readingformでuse_romajiをtrueにします。 以下、「吾輩」のサンプルです。\nGET _analyze { \u0026#34;text\u0026#34;: [\u0026#34;吾輩\u0026#34;], \u0026#34;tokenizer\u0026#34;: \u0026#34;kuromoji_tokenizer\u0026#34;, \u0026#34;filter\u0026#34;: [ { \u0026#34;type\u0026#34;: \u0026#34;kuromoji_readingform\u0026#34;, \u0026#34;use_romaji\u0026#34;: true } ] } レスポンス { \u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;wagahai\u0026#34;, \u0026#34;start_offset\u0026#34;: 0, \u0026#34;end_offset\u0026#34;: 2, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 0 } ] } 「吾輩」の場合は特に問題ないのですが、ローマ字による日本語入力の場合、次のような単語を入力するときに、ゆれが生じます。\nシャボン=「shabon」 新橋=「shimbashi」 括弧内はkuromoji_readingformで出力したもの(=ヘボン式のローマ字)です。 ですが、ローマ字入力の場合は「syabon」や「shabon」と入力したり、「sinbasi」や「sinnbasi」と入力すると思います。 JapaneseCompletionAnalyzerを利用したCompletion Suggesterの場合、これらのゆれも考慮してサジェストしてくれるようになっています。 前回のサンプルデータを用いると次のような感じです。\nGET aozora_index/_search { \u0026#34;explain\u0026#34;: true, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: { \u0026#34;prefix\u0026#34;: \u0026#34;sha\u0026#34;, \u0026#34;completion\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;suggest_ja\u0026#34; } } } } GET aozora_index/_search { \u0026#34;explain\u0026#34;: true, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: { \u0026#34;prefix\u0026#34;: \u0026#34;sya\u0026#34;, \u0026#34;completion\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;suggest_ja\u0026#34; } } } } これらのリクエストは、「しゃ」について2パターンになっていますが、結果はどちらも次のものが返ってきます(このレスはsyaのレスになります)。\n{ \u0026#34;took\u0026#34;: 1, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;sya\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 3, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;シャドウ・ワーク\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;000739\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;シャドウ・ワーク\u0026#34;, \u0026#34;朝倉 克彦\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;シャボン玉\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;045054\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;シャボン玉\u0026#34;, \u0026#34;豊島 与志雄\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;上海\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;050899\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;上海\u0026#34;, \u0026#34;横光 利一\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;斜坑\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;002095\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;斜坑\u0026#34;, \u0026#34;夢野 久作\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;社会事情と科学的精神\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;053864\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;社会事情と科学的精神\u0026#34;, \u0026#34;石原 純\u0026#34; ] } } ] } ] } } 「sinnba」や「shinba」も試してみました。\nGET aozora_index/_search { \u0026#34;explain\u0026#34;: true, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: { \u0026#34;prefix\u0026#34;: \u0026#34;sinnba\u0026#34;, \u0026#34;completion\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;suggest_ja\u0026#34; } } }, \u0026#34;_source\u0026#34;: [\u0026#34;suggest_ja\u0026#34;] } GET aozora_index/_search { \u0026#34;explain\u0026#34;: true, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: { \u0026#34;prefix\u0026#34;: \u0026#34;shinba\u0026#34;, \u0026#34;completion\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;suggest_ja\u0026#34; } } }, \u0026#34;_source\u0026#34;: [\u0026#34;suggest_ja\u0026#34;] } これらも同じ結果です。\n{ \u0026#34;took\u0026#34;: 0, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;shinba\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 6, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;しんばい\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;044942\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;しんばい\u0026#34;, \u0026#34;村山 籌子\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;新橋\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;002409\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;新橋\u0026#34;, \u0026#34;北原 白秋\u0026#34; ] } } ] } ] } } 入力されるパターンを想定した実装がされているので対応できている形です。 使い方が楽なだけでなく、より使いやすくなってるのは便利ですね。\nうまくいかないパターン 万事OKかというと残念ながらそうでもありません。 うまくいかないパターンもあります(これが本当にうまくいかないかは難しい話な気がしますが)。 「日本」という漢字ですが、「にほん」「にっぽん」どちらとも読めますよね? これらを試してみると次のようになります(リクエストは省略します)。\nまず「にほん」\n{ \u0026#34;took\u0026#34;: 0, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;にほん\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 3, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;日本橋\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;004565\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本橋\u0026#34;, \u0026#34;泉 鏡花\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本橋\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;045357\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本橋\u0026#34;, \u0026#34;牧野 信一\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本橋あたり\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;047648\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本橋あたり\u0026#34;, \u0026#34;長谷川 時雨\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本橋附近\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;055666\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本橋附近\u0026#34;, \u0026#34;田山 花袋\u0026#34; ] } } ] } ] } } 次に「にっぽん」\n{ \u0026#34;took\u0026#34;: 1, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;にっぽん\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 4, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;日本アルプスの五仙境\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;056269\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本アルプスの五仙境\u0026#34;, \u0026#34;木暮 理太郎\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本出版協会論\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;049436\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本出版協会論\u0026#34;, \u0026#34;嶋中 雄作\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本文化と科学的思想\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;055750\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本文化と科学的思想\u0026#34;, \u0026#34;石原 純\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本文化のために\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;003183\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本文化のために\u0026#34;, \u0026#34;宮本 百合子\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本文化の特殊性\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;055290\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本文化の特殊性\u0026#34;, \u0026#34;戸坂 潤\u0026#34; ] } } ] } ] } } 最後に「日本」\n{ \u0026#34;took\u0026#34;: 1, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;日本\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 2, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;日本アルプスの五仙境\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;056269\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本アルプスの五仙境\u0026#34;, \u0026#34;木暮 理太郎\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本出版協会論\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;049436\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本出版協会論\u0026#34;, \u0026#34;嶋中 雄作\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本文化とは何ぞや(其二)\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;002940\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本文化とは何ぞや(其二)\u0026#34;, \u0026#34;内藤 湖南\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本文化と科学的思想\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;055750\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本文化と科学的思想\u0026#34;, \u0026#34;石原 純\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;日本文化のために\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;003183\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;日本文化のために\u0026#34;, \u0026#34;宮本 百合子\u0026#34; ] } } ] } ] } } 最初の「にほん」は「日本橋」がヒットしているようです。返ってきたoptionsの数は4件しかなく、どうやらこれがすべてのようです(取得件数はデフォルト5件)。 2番目の「にっぽん」は「日本」という単語から始まるものがヒットしていますが、「日本橋」はなさそうでした。 最後に「日本」という漢字を入力にした場合は2つの合計が帰ってきているようです(今回のレスポンス例にはありませんが、サイズを大きくすると「日本橋」が帰ってきていました)。\nどうしてそうなるの? JapaneseCompletionAnalyzerの基本的な動作としては、\nKuromojiが単語に区切る 区切られた単語ごとに読みを持っている 元の単語と読みをローマ字にしたものが最終的に出てくる というような動きです。 この時、単語には「1つ」の読みが対応しています。 読みから単語を探そうとすると、読みの違い(ゆれ)を吸収することはできないためです。 JapaneseCompletionAanlyzerは3点目のローマ字のゆれに対応していますが、入力となる読みのゆれまでは対応できないです。 対応しているといいかどうかというのも難しい判断になる気もします。。。\nそのほかの例としては次のようなものもあります。 これは、今回のオートコンプリートの話とは少しずれてるかもしれませんが、1番目の処理の結果が変わってくる例です。 「南方熊楠」という名前の間にスペースがあるかないかで、出力される読みが変わってくる例です。\nGET _analyze { \u0026#34;text\u0026#34;: [\u0026#34;南方 熊楠\u0026#34;], \u0026#34;tokenizer\u0026#34;: \u0026#34;kuromoji_tokenizer\u0026#34;, \u0026#34;filter\u0026#34;: [\u0026#34;kuromoji_readingform\u0026#34;] } GET _analyze { \u0026#34;text\u0026#34;: [\u0026#34;南方熊楠\u0026#34;], \u0026#34;tokenizer\u0026#34;: \u0026#34;kuromoji_tokenizer\u0026#34;, \u0026#34;filter\u0026#34;: [\u0026#34;kuromoji_readingform\u0026#34;] } # GET _analyze { \u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;ナンポウ\u0026#34;, \u0026#34;start_offset\u0026#34;: 0, \u0026#34;end_offset\u0026#34;: 2, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 0 }, { \u0026#34;token\u0026#34;: \u0026#34;クマグス\u0026#34;, \u0026#34;start_offset\u0026#34;: 3, \u0026#34;end_offset\u0026#34;: 5, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 1 } ] } # GET _analyze { \u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;ミナカタ\u0026#34;, \u0026#34;start_offset\u0026#34;: 0, \u0026#34;end_offset\u0026#34;: 2, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 0 }, { \u0026#34;token\u0026#34;: \u0026#34;クマグス\u0026#34;, \u0026#34;start_offset\u0026#34;: 2, \u0026#34;end_offset\u0026#34;: 4, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 1 } ] } 人名や地名は1つの漢字に対して多くの読みが存在しているので大変です。。。 どうしてこれは出てこないんだろう?と不思議に思った場合は、_analyze APIを使ってどういう動きなのかを見てみるのがいいかと。\nまとめ ということで、少しだけですが、こんなことができるよ、できないよというのを書いてみました。 挙動をしっていれば、なんでこうなってるんだっけ?といったことを調べる役に立つかと思います。 入力された文字をもとにどれをサジェストするかなどについてはもう少し違う動きなので、中の仕組みをそろそろ書かないとなぁ。\n参考 同形異音語 - Wikipedia ","date":1660099802,"dir":"post/2022/","id":"73279888a8fe482c836fb19ca23318dc","lang":"ja","lastmod":1660099802,"permalink":"https://blog.johtani.info/blog/2022/08/10/jp-auto-completion-2/","publishdate":"2022-08-10T11:50:02+09:00","summary":"前回は日本語用オートコンプリートのためのAnalyzerとして、どうやって使うのかを簡単に紹介しました。 今回はもう少し、いろんなパターンを試","tags":["elasticsearch","lucene"],"title":"ローマ字入力のゆれと読み(JapaneseCompletionAnalyzerその2)"},{"contents":"風のうわさで、日本語用のオートコンプリートのためのTokenFilterとAnalyzerがLuceneに取り込まれたと聞きました(LUCENE-10102)。 Elasticsearchでも使えるかなぁ?ということで調べたところ(調べた?聞いた?)、どうやら8.1から利用できるようになっている(GitHub Issue #81858)みたいです(まだ、公式ドキュメントには記載がないのですが)。\n8/17追記\n作者の打田さんがブログ書いてたの見落としてた(もしくは見たけど忘れてた)ので貼っておきます。マルチテナンシー下での Query Auto Completion 設計・運用戦略 - LegalForce Engineering Blog\nということで、こんな感じで使えるよというのを試してみました。\nどういうもの? 日本語入力方法を考慮したオートコンプリート用のトークンを生成してくれるTokenFilterと、 それをLuceneのSuggesterで動くようにしたAnalyzerが用意されています。 Elasticsearchでは、Kuromojiプラグインにそれらを使えるようになっています(バージョン8.1.0以降)。 KuromojiTokenizerと一緒に利用する前提の仕組みとなります。\nオートコンプリートとは? 検索窓などでキー入力をしていると、入力した文字で始まる単語の一覧が現れることがあると思います。 あの機能がオートコンプリートと呼ばれるものです。search-as-you-typeとも呼ばれることもあります。 (検索ペンギン本にも書いてあるので興味のある方はぜひ!(ステマ)) 入力された文字列を含むパターンもありますが、今回紹介するものは入力された文字で始まる単語を見つけてくる機能になります。\n何がなんで追加されたの? 日本語の入力方法は、かな入力の人もいればローマ字入力の人もいます。 ですので、オートコンプリートでの入力として、「しゃ」という入力が来る場合もあれば、「sha」というローマ字入力途中のものが来る場合もあります。 これらを考慮したトークンの扱いができるように、 JapaneseCompletionFilterというクラスが追加されています。 内部的にはKuromojiTokenizerでトークンに分割された後に、もともとのトークンと同じポジションで読みをローマ字にしたものを出力します。 JapaneseCompletionAnalyzerは上記Filterをすぐに使えるようにしたAnalyzerです。\n動かし方 百聞は一見に如かずということで、Elasticsearchでの使い方を見たほうが分かりやすいので、簡単に動かしてみることにします。\nインストールとインデックスの用意 Elasticsearch(8.1以上)とKuromojiのプラグインをインストールします(今回試したのは8.3.1)。\nサンプルデータ なにかいいデータはないものか?と思っていたところ夏休みだというのを思い出しました。 夏休みといえば読書感想文だ、ということで、書籍のタイトルがいいかもなと。 青空文庫の著者名と書籍のタイトルの一覧を見つけたのでそちらのデータを使って試してみました。\nCSV to JSON CSVファイルは最後の参考にある青空文庫のページから、「公開中 作家別作品一覧:全て(CSV形式、zip圧縮)」をダウンロードしたものを利用しました。 CSVファイルだったので、jqコマンドで必要な部分だけをNDJSONの形でとりあえずファイルに出力します。\ncat list_person_all_utf8.csv | tr -d \u0026#39;\u0026#34;\u0026#39; | jq -c -R \u0026#39;split(\u0026#34;,\u0026#34;) | {\u0026#34;auth_id\u0026#34;: .[0] | tonumber, \u0026#34;author\u0026#34;: .[1], \u0026#34;id\u0026#34;: .[2] , \u0026#34;title\u0026#34;: .[3], \u0026#34;suggest_ja\u0026#34;: [.[3], .[1]]}\u0026#39; 次のようなJSONが1行ずつ出力されます。\n{\u0026#34;auth_id\u0026#34;:1257,\u0026#34;author\u0026#34;:\u0026#34;アーヴィング ワシントン\u0026#34;,\u0026#34;id\u0026#34;:\u0026#34;056078\u0026#34;,\u0026#34;title\u0026#34;:\u0026#34;駅伝馬車\u0026#34;,\u0026#34;suggest_ja\u0026#34;:[\u0026#34;駅伝馬車\u0026#34;,\u0026#34;アーヴィング ワシントン\u0026#34;]} suggest_jaがオートコンプリートの対象となるデータになります。今回は著作と著者にしてみました。 あとは次に紹介するスキーマでインデックスを作成して、適当なプログラムを使ってBulkでElasticsearchに登録しましょう(私は個人作のツールで入れました)。\nインデックス オートコンプリート用のSuggesterを利用するための特殊なフィールド(completion)を利用したフィールドを用意します。 ちなみに、今回はLUCENE-10102に記載があった設定をそのまま使わせていただきました。 そのほかのフィールドは今回は特に必要はないのでおまけです。\nPUT aozora_index { \u0026#34;mappings\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;completion\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;japanese_completion_index\u0026#34;, \u0026#34;search_analyzer\u0026#34;: \u0026#34;japanese_completion_query\u0026#34;, \u0026#34;preserve_separators\u0026#34;: false, \u0026#34;preserve_position_increments\u0026#34;: true, \u0026#34;max_input_length\u0026#34;: 50 }, \u0026#34;auth_id\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;author\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;fields\u0026#34;: { \u0026#34;keyword\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;keyword\u0026#34;, \u0026#34;ignore_above\u0026#34;: 256 } }, \u0026#34;analyzer\u0026#34;: \u0026#34;kuromoji\u0026#34; }, \u0026#34;author_id\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34; }, \u0026#34;id\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34; }, \u0026#34;title\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;fields\u0026#34;: { \u0026#34;keyword\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;keyword\u0026#34;, \u0026#34;ignore_above\u0026#34;: 256 } }, \u0026#34;analyzer\u0026#34;: \u0026#34;kuromoji\u0026#34; } } }, \u0026#34;settings\u0026#34;: { \u0026#34;index\u0026#34;: { \u0026#34;number_of_shards\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;analysis\u0026#34;: { \u0026#34;analyzer\u0026#34;: { \u0026#34;japanese_completion_index\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;index\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;kuromoji_completion\u0026#34; }, \u0026#34;japanese_completion_query\u0026#34;: { \u0026#34;mode\u0026#34;: \u0026#34;query\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;kuromoji_completion\u0026#34; } } } } } } 動作確認 ここまでで、インデックスとデータの用意ができました。 オートコンプリートを実現するためにはElasticsearchのSuggesterという機能の、Completion Suggesterを利用します。検索の仕方が通常のものとは少し異なります。 ちなみに、速度重視のためにインメモリで動いているとの記載がドキュメントにあります。\nCompletion Suggesterのクエリ Suggester用のクエリがあるのでこちらを使います。 例えば、「wagah」という入力がある時に、サジェストする内容を取得するには次のようなリクエストになります。\nGET aozora_index/_search { \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: { \u0026#34;prefix\u0026#34;: \u0026#34;wagah\u0026#34;, \u0026#34;completion\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;suggest_ja\u0026#34; } } }, \u0026#34;_source\u0026#34;: [\u0026#34;title\u0026#34;, \u0026#34;author\u0026#34;] } 最初の「suggest」がsuggest用のパラメータを意味しています。 次の「title-suggest」は好きな名前をつけられます。レスポンスにこの名前がついた配列がサジェストの結果になります(同時に3. 複数suggestを呼び出せるので、対応した結果が分かるように名前が付けられます)。 「prefix」に入力の文字列を渡します。 「completion」がsuggesterのタイプの指定です。今回はCompletion Suggesterなので「completion」を指定します。その中に「field」でcompletionに利用するフィールド名を指定します。先ほどのスキーマでcompletionタイプを指定したフィールドです。今回は「suggest_ja」になります。 「_source」は結果を見やすくするために、ヒットしたデータの一部だけ取得するオプションです。 すると、次のような結果が返ってきます。\n{ \u0026#34;took\u0026#34;: 1, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;wagah\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 5, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;『吾輩は猫である』中篇自序\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;002671\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;『吾輩は猫である』中篇自序\u0026#34;, \u0026#34;夏目 漱石\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;わが俳諧修業\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;003771\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;わが俳諧修業\u0026#34;, \u0026#34;芥川 竜之介\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;わが母をおもう\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;003997\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;わが母をおもう\u0026#34;, \u0026#34;宮本 百合子\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;わが母を語る\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;049723\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;わが母を語る\u0026#34;, \u0026#34;上村 松園\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;吾輩は猫である\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;000789\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;吾輩は猫である\u0026#34;, \u0026#34;夏目 漱石\u0026#34; ] } } ] } ] } } 「suggest」の「title-suggest」がCompletion Suggesterのレスポンスになります。 最初の「text」は入力の「prefix」の値です。「offset」、「length」もこの文字に関する情報なので特に気にしなくてもいいかと。 「options」がサジェストされた内容になります。それぞれの「text」がサジェストされた文字列になります。「suggest_ja」には著作と著者名を入れましたが、今回は著作が「text」に帰ってきていることがわかります。 次に著者名でもやってみましょう。 「太宰」という入力が来たものとしてリクエストを投げます。\nGET aozora_index/_search { \u0026#34;explain\u0026#34;: true, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: { \u0026#34;prefix\u0026#34;: \u0026#34;太宰\u0026#34;, \u0026#34;completion\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;suggest_ja\u0026#34; } } } } レスポンスは次のようになります。\n{ \u0026#34;took\u0026#34;: 1, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;太宰\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 2, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;太宰 治\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;000236\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;ア、秋\u0026#34;, \u0026#34;太宰 治\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;太宰 治\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;001572\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;I can speak\u0026#34;, \u0026#34;太宰 治\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;太宰 治\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;001578\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;愛と美について\u0026#34;, \u0026#34;太宰 治\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;太宰 治\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;046597\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;青森\u0026#34;, \u0026#34;太宰 治\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;太宰 治\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;004357\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;青森\u0026#34;, \u0026#34;太宰 治\u0026#34; ] } } ] } ] } } 先ほどとは異なり、「options」の中の個々の「text」はすべて「太宰 治」になってしまいました。 登録したデータは著作の一覧ですが、「suggest_ja」には著作と著者名を入れたためです。 これでは、実際に検索窓に実装したときに同じものが並んでしまいます。 こんな時のためのオプション「skip_duplicates」が用意されています。 先ほどのリクエストに「\u0026ldquo;skip_duplicates\u0026rdquo;: true」を追加します。\nGET aozora_index/_search { \u0026#34;explain\u0026#34;: true, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: { \u0026#34;prefix\u0026#34;: \u0026#34;太宰\u0026#34;, \u0026#34;completion\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;suggest_ja\u0026#34;, \u0026#34;skip_duplicates\u0026#34;: true } } }, \u0026#34;_source\u0026#34;: [\u0026#34;suggest_ja\u0026#34;] } するとレスポンスは次のように変化します。\n{ \u0026#34;took\u0026#34;: 1, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;skipped\u0026#34;: 0, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: { \u0026#34;value\u0026#34;: 0, \u0026#34;relation\u0026#34;: \u0026#34;eq\u0026#34; }, \u0026#34;max_score\u0026#34;: null, \u0026#34;hits\u0026#34;: [] }, \u0026#34;suggest\u0026#34;: { \u0026#34;title-suggest\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;太宰\u0026#34;, \u0026#34;offset\u0026#34;: 0, \u0026#34;length\u0026#34;: 2, \u0026#34;options\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;太宰 治\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;000236\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;ア、秋\u0026#34;, \u0026#34;太宰 治\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;太宰治との一日\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;042582\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;太宰治との一日\u0026#34;, \u0026#34;豊島 与志雄\u0026#34; ] } }, { \u0026#34;text\u0026#34;: \u0026#34;太宰治情死考\u0026#34;, \u0026#34;_index\u0026#34;: \u0026#34;aozora_index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;043137\u0026#34;, \u0026#34;_score\u0026#34;: 1, \u0026#34;_source\u0026#34;: { \u0026#34;suggest_ja\u0026#34;: [ \u0026#34;太宰治情死考\u0026#34;, \u0026#34;坂口 安吾\u0026#34; ] } } ] } ] } } 「options」は3つに減り、重複していないことがわかります。 「text」が同じ場合は最初に出てきたものを返すようです(注意:結果から観測しているだけで、実装はまだ見ていません)。 (なお、今回は説明を省きますが、入力データでスコアを指定することも可能になっています)。 そのほかにもCompletion Suggesterにはいくつか仕組みが用意されているのですが、それはまた今度にでも。\nまとめ ということで、Luceneコミッターの打田さんに感謝です。 便利な仕組みが簡単に使えるようになるのはとてもありがたいですね。\nまずは簡単にどういうものかとどうやって使うのかを記事にしてみました。 中の動きや、注意点、これまでとの違いなどは次の記事にしようと思います。 そういえば、公式ドキュメントにはまだ出てきてないな、それを書こうと思ってついでに動かしてみたんだけど、追加するのはまた後日かな。。。\n参考資料 青空文庫 - 公開中 作家リスト:全て [LUCENE-10102] Add JapaneseCompletionFilter for Input Method-aware auto-completion - ASF JIRA Expose Japanese completion filter to kuromoji analysis plugin by mocobeta · Pull Request #81858 · elastic/elasticsearch Suggesters | Elasticsearch Guide [8.3] | Elastic ","date":1660028402,"dir":"post/2022/","id":"6639ec6f88c4976f8ca20fa840f169e3","lang":"ja","lastmod":1660028402,"permalink":"https://blog.johtani.info/blog/2022/08/09/japanese-auto-completion/","publishdate":"2022-08-09T16:00:02+09:00","summary":"風のうわさで、日本語用のオートコンプリートのためのTokenFilterとAnalyzerがLuceneに取り込まれたと聞きました(LUCE","tags":["lucene","elasticsearch"],"title":"日本語用オートコンプリートのためのAnalyzer"},{"contents":"Hugoを0.84から0.92にアップデートをする際に、これまでのブログ記事やレイアウトファイルを修正したので個人的にメモを残しておきます。\nなんでアップデート? うっかり魔がさして、メインのWSL2のUbuntuを20.04から22.04にアップグレードしました。。。 新規に22.04を落としてきて移行ではなく。 皆さんはまねしないほうがいいですよ! アップデートした後にGitの環境がおかしくなったりと大変でした。 WSL2のUbuntuではHugoでブログのビルド、いろんな確認のためのElasticsearchの起動、個人的なプログラムとかを書く環境として利用しています。\nで、Ubuntuを上げたところ無事(?)Hugoもアップデートされたわけです。 最初はGitでfetchが出来なくなって修正していましたが、そのほかの動作確認を行なう段階でHugoでブログがビルドできなくなっていることが判明しました。\nバージョンアップに伴う修正 hugoコマンドを実行すると、いくつかのERRORとWARNが出力されました。 次のようなものです。\nhugo v0.92.2+extended linux/amd64 BuildDate=2022-02-23T16:47:50Z VendorInfo=ubuntu:0.92.2-1 ERROR 2022/08/05 13:22:32 Page.URL is deprecated and will be removed in Hugo 0.93.0. Use .Permalink or .RelPermalink. If what you want is the front matter URL value, use .Params.url WARN 2022/08/05 13:22:32 The \u0026#34;tweet\u0026#34; shortcode will soon require two named parameters: user and id. See \u0026#34;/home/johtani/blog_generator/content/post/2020/2020-12-04-build_corne_choc.md:46:1\u0026#34; ... ERROR 2022/08/05 13:22:33 Failed to get JSON resource \u0026#34;https://publish.twitter.com/oembed?dnt=fa... If you feel that this should not be logged as an ERROR, you can ignore it by adding this to your site config: ignoreErrors = [\u0026#34;error-remote-getjson\u0026#34;] ERROR 2022/08/05 18:44:11 Page.UniqueID is deprecated and will be removed in Hugo 0.93.0. Use .File.UniqueID ERROR 2022/08/05 18:44:11 Page.Dir is deprecated and will be removed in Hugo 0.93.0. Use .File.Dir Page.URLなどがdeprecatedに 最初と最後2行のERRORがこちらになります。 どうやら、Pageオブジェクトの変数に変更があったようです(まだdeprecatedであり、存在はしていそう?)。 レイアウト(テンプレート)ファイルで「Previous Post」や「Next Post」といったリンクを作ったり、 Algoliaに登録するためのJSONファイルを生成するところでURL文字列を取得するために参照していました。\nログ出力でどのように変更すればよいのか?という記載があるので便利ですね。 ただ、どのファイルにこの記述があるのかはログに出てなかったので少しだけ苦労しました。\n実際には「UniqueID」という文字列でディレクトリ内を検索してあたりを付けた感じです。 利用させていただいているテーマ(Clean White)がすでにアップデートに対応されていたのでそちらが参考になりました。\nいくつか、テーマをもとに修正したテンプレートがlayoutsディレクトリにあったので、それらを修正した形です(参考のリンクはテーマのファイルになります)。\n.URLを.Permalinkに変更(参考:single.html) .UniqueIDを.File.UniqueIDに変更(参考:list.algolia.json) tweetのshortcodeの引数が増えた これまでは以下のようにIDだけで良かったのですが、userとidという2つの引数が必須になるという変更が入ったようです。\n変更前:\n{{ \u0026lt;tweet 1449214872143609860\u0026gt; }} 変更後:\n{{ \u0026lt;tweet user=\u0026#34;johtani\u0026#34; id=\u0026#34;1449214872143609860\u0026#34;\u0026gt; }} WARNにはファイル名、行番号が出力されていたので、1つずつ修正していきました。 結構な量があったので、地味に大変でした、 公開しているブログを見ながら、該当するツイートを見つけてはuserを指定していく部分が特に。 自分のツイート以外もブログに貼っていたので画一的には対処できなくて。。。\nなにかプログラムで機械的に対応ができたかもなぁ。\n鍵付きツイートによるエラー tweetのshortcode対応を行なった後でもビルドがエラーになっており、次のようなエラーが消えないままでした(エラーの一部は省略しています)。 (幸いにも)1つのツイートだけ、ブログ記事を書いた後で鍵付きになってしまった方のツイートがあったようで、ツイート用のJSONが取得できなくてエラーになっていました。\nERROR 2022/08/05 13:22:33 Failed to get JSON resource \u0026#34;https://publish.twitter.com/oembed?dnt=fa... If you feel that this should not be logged as an ERROR, you can ignore it by adding this to your site config: ignoreErrors = [\u0026#34;error-remote-getjson\u0026#34;] こちらもログに対処方法が出ています。 config.tomlにignoreErrors = [\u0026quot;error-remote-getjson\u0026quot;]を追加すれば、エラーが出力されなくなりビルドも成功するようになります。 ただ、tweet以外でもエラーが出る可能性がありそうで、その場合に、ブログに書いたつもりが一部が出力されないまま公開されそうな気がします。 なので、今回はconfig.tomlに該当の設定を追加するのではなく、ブログ記事から該当のツイートを消す対応をしました。 幸いにも、ツイートを消してもブログ記事自体には影響がありませんでした。\n.hugo_build.lockファイルが生成される これは、エラーではないのですがgit addしようとした際に、ファイルが増えていたのでどういったファイルなのかを調べました。 0.89.0から追加されたロックファイルのようです(参考:0.89.0のリリースノート)。 こちらは特に保管する必要もなさそうなので.gitignoreに追加して対処しました。\nまとめ ということで、気軽にUbuntuをアップグレードしないほうがいいですね。。。 期せずしてHugoのアップグレードができたのは良かったかもなw\n参考 【WSL2】Ubuntu 20.04.4 LTS を 22.04 LTS へアップグレードした ","date":1659689954,"dir":"post/2022/","id":"167a7c9d579ce6f2cebf64a6f6329ecb","lang":"ja","lastmod":1659689954,"permalink":"https://blog.johtani.info/blog/2022/08/05/upgrade-hugo-accidentally/","publishdate":"2022-08-05T17:59:14+09:00","summary":"Hugoを0.84から0.92にアップデートをする際に、これまでのブログ記事やレイアウトファイルを修正したので個人的にメモを残しておきます。","tags":["hugo"],"title":"Hugoをアップデートした"},{"contents":"今回はQuerqyのElasticsearchのプラグインがどんなつくりになっているか?をちょっとだけ調べてみました。 SolrでもElasticsearchでも使えるという形なので、どんなつくりになっているのかな?と思ったのが発端です。\nGitHubのリポジトリ GitHubにリポジトリが公開されています。 2つのリポジトリに分かれています。\nEs向けのプラグイン コアのライブラリ どちらもJavaのライブラリで、ビルドシステムとしてはMavenを利用しています。 コアのライブラリのリポジトリにはさらに、以下の2つが存在しています。\nlucene向けライブラリ(Solr向けのモジュールもこちらに含まれる) コアライブラリ pom.xmlを読んだところ、次のような依存関係になっています(それ以外にも使ってるライブラリはあるけど)。\nEsプラグイン -\u0026gt; Lucene向けライブラリ -\u0026gt; コアライブラリ Esプラグイン Es向けのエンドポイントの実装、Esのクエリの組み立てを行なっています。 Rewriterの実装については、Lucene向けライブラリ、コアライブラリを利用する形になります。\nquerqy用のQueryBuilderを実装しており、EsがクエリをパースするタイミングでRewriterなどを呼び出してクエリの書き換えを行う仕組みです。 なお、Es向けのクエリの組み立てと書きましたが、ほとんどLuceneのクエリの組み立てになっています(そりゃそうだ)。 実際にquerqyのクエリ組み立て処理を行っているのは、Lucene向けライブラリのQueryParsingControllerになります。 いくつかのRewriterは、生のEsクエリをルールなどとして登録することができるようになっています。 これらのクエリのパースをEs側にやらせる処理の部分もこちらで定義されている感じです。\nそのほかに、ドキュメントには記載がないエンドポイントが2つ用意されていました。 インデックスに登録してあるRewriterの設定を各ノードでキャッシュする仕組みがあって、そのキャッシュの操作(クリア、リロード)用みたいです。 これらは、Rewriterの追加、削除のアクションの内部で呼び出されているので、ユーザー側で呼び出す必要はなさそうです。\nLucene向けライブラリ Luceneに関連する処理がまとめられています。 Es内部ではLuceneを使って検索処理が行なわれるため、Luceneのクエリを組み立てる必要があります。 querqyとしてLuceneのクエリを組み立てるときに必要なクラスがこのライブラリに含まれています。\nまた、Word Break Rewriterの実装はコアライブラリではなくこちらのライブラリに実装されています。 これは、Luceneのタームディクショナリを活用したRewriterになっているため、Lucene必須となっているからのようです。 (まだちゃんと実装を見ていないので、どんな活用の仕方をしているのかまではわかっていませんが。。。)\nコアライブラリ Rewriterの設定のパース処理、クエリのリライト処理の実装がまとめられています。 querqyのクエリが、Rewriterの処理に基づいて、querqyとして定義されたクエリのモデルに一旦変換される作りになっています。 Lucene向けライブラリやEs向けプラグインはこの内部のクエリモデルになったものをもとに、Lucene向けのクエリに書き換えていくというながれになっています。\nまとめ ざっくりですが、どんな構成なのかを見てみました。 Esのプラグインとなっているのですが、プラグインではなく、外部に出すことってできるのかな?と思いつつ、なんとなくソースを読んでみました。 パターンとしては、Lucene向けのクエリからEs向けのクエリを組み立てるとかの無駄な努力が必要になる気もするけど。。。 Luceneを使っていない検索エンジンに対しては、コアライブラリをもとに、それぞれの検索エンジンむけのクエリを組み立てる仕組みを作る形になると思います。 その際、Rewriterの設定を保持する仕組み、querqyが置き換えたクエリのマッピングができるか?といった点を考える必要がありそうです。 デバッグとかするときに、EsのクエリDSLのJSONとして見れるといいなぁと思ってたけど、そんなことできるかなぁ?\n","date":1658300650,"dir":"post/2022/","id":"3384ea6bb47d70f8ca94b4510813f36a","lang":"ja","lastmod":1658300650,"permalink":"https://blog.johtani.info/blog/2022/07/20/querqy-architecture/","publishdate":"2022-07-20T16:04:10+09:00","summary":"今回はQuerqyのElasticsearchのプラグインがどんなつくりになっているか?をちょっとだけ調べてみました。 SolrでもElast","tags":["elasticsearch"],"title":"Querqyの調査(その2:アーキテクチャ)"},{"contents":"Querqyというクエリのリライト用のプラグインがあるのでどんなものかを調べてみました。とりあえずは概要をドキュメントから追いかけてみた感じです。対応しているのはSolrとElasticsearch(以降、Es)になります。手元にはEsの環境があるのでそちらで試してみました。\nなにもの? EsやSolrのプラグインで、ルールやパラメータを利用して、クエリの書き換えをEsやSolr側で行えるプラグインです。 なお、本記事ではEsのプラグインを説明します。 今回はドキュメントを読みながらメモを取った感じなので、詳細については公式ドキュメントを見ていただくのが良いかと。 手元では動作させてみましたが、今回の記事ではざっとメモを取っただけになります。\nインストール Esのpluginコマンドでインストール可能ですが、Mavenにアップロードされているバージョンは限定的なので、必要に応じて自分でビルドする必要があります。 対応しているかは、公式ドキュメントのInstallationのプルダウンが参考になります。\nどうやって使うの? Query DSLにquerqyというクエリが追加されるので、あとはドキュメントをもとにクエリを組み立てるクエリを書いていきます。 すると、プラグインが指定されたルールに従い、EsのQueryに書き換え、実際の検索が実行して結果が返ってきます。 普通にmatchなどの既存のQueryと同レベルのものになるので、既存のEsのクエリと組み合わせた使い方もできるようです。\nサンプルとして紹介されている短めのクエリ(このクエリではルールによるクエリの書き換えはない)。\nGET ecommerce/_search { \u0026#34;query\u0026#34;: { \u0026#34;querqy\u0026#34;: { \u0026#34;matching_query\u0026#34;: { \u0026#34;query\u0026#34;: \u0026#34;notebook\u0026#34; }, \u0026#34;query_fields\u0026#34;: [ \u0026#34;title^3.0\u0026#34;, \u0026#34;brand^2.1\u0026#34;, \u0026#34;short_description\u0026#34;] } } } また、書き換え(Rewriter)の設定をElasticsearchに対して保存できるエンドポイント_querqy/rewriterが用意されています。\nSynonymの書き換えを行なうサンプル(後述するCommon Rules Rewriterの設定)。\nPUT /_querqy/rewriter/common_rules { \u0026#34;class\u0026#34;: \u0026#34;querqy.elasticsearch.rewriter.SimpleCommonRulesRewriterFactory\u0026#34;, \u0026#34;config\u0026#34;: { \u0026#34;rules\u0026#34; : \u0026#34;notebook =\u0026gt;\\nSYNONYM: laptop\u0026#34; } } どんな書き換えができるの? 用意されているRewriterは2022年7月時点では次のようなものになります(がんばれば、Javaで実装すれば自作もできそう)。\nCommon Rules Rewriter Replace Rewriter Number Unit Rewriter Word Break Rewriter また、複数のRewriterをチェインして使うこともできる。記述した順番で適用されます。 それぞれのRewriterについて簡単にメモを。\nCommon Rules Rewriter シノニム、結果のブースト、フィルター、結果に対して追加情報を付与したりできます。\nrulesにルールを記載していきます。 以下のようなフォーマットになっています。 クエリが入力に合致したら、ルールが適用される形です。プロパティは後述しますが、ルールの適用する順序などをハンドリングするために使用します。\n入力 =\u0026gt; ルール ルール @プロパティ @プロパティ 入力部分に関する書式 ルールの左辺に該当する部分で、クエリに入力された文字列がマッチするかどうかで、右辺のルールを適用するかがきまります。\n入力の一致の条件は次のような感じです。 完全一致、前方一致、後方一致の使い分けが可能。ダブルクォート\u0026quot;で制御 デフォルトでは、大文字小文字の区別なし(後述するオプションで変更可能) 単語の末尾にワイルドカード*で1文字以上にマッチ。入力の最後にだけ利用可能 書き換えの命令(ルール) 右辺に利用できる命令で、次のようなものがあります。\nSYNONYM 同義語展開するための命令です。Synonym Token Filterとの違いは、複数のルールを同時に適用できます。 フィールドに依存しない設定なのでメンテナンスが楽になるとのこと。 ただし、双方向の設定はないため、例えば\u0026quot;personal computer\u0026quot;と\u0026quot;pc\u0026quot;の場合、2つの設定を個別に定義する必要があります。 また、ステミングなどには未対応なので、\u0026ldquo;personal computers\u0026quot;も対応する場合はこれも追加する必要があります。 類義語ごとに重みを変えることが可能になっています。同列ではなく、同義語のスコアを下げるなどで、リコールを増加させつつ、入力語のスコアを上位にすると行ったことが可能です。\nUP/DOWN 入力文字列がマッチした場合に、追加のクエリを正か負のブーストをしつつ追加できます。 例えば、「iphone」と検索された場合に、「apple」もクエリとして追加しつつスコアをブーストし、「case」のクエリをスコアを下げるように追加できます。 これにより、アクセサリーではなく本体が検索結果の上位に出てくるような仕組みを提供できます。\nFILTER UP/DOWNではクエリとして追加されていたが、こちらはフィルターとして追加されます(=スコアで調整ではなく、結果から除外される)。\nDELETE クエリからキーワードを削除できます。 単語自体をそのまま削除することも、入力された単語に合わせて他の単語を削除することもできます。\nDECORATE 2022年7月時点でEsでは利用不可で、Solrのみで利用可能です(なので読み飛ばしました)。\nプロパティ 各ルールの設定にタグをつけられるような機能です。 このプロパティを利用して、ルールのソートやフィルタリングなどが可能になります。 複数のルールにクエリがマッチした場合に、優先度が最高のものだけを適用したり、プロパティに特定の値を持っているものだけを採用したりできます。 なお、プロパティは命令のあとに記述する必要があります(パーサーの関係かな?)。\nReplace Rewriter クエリタームの置き換え用のRewriterです。クエリの正規化処理として、他のRewriterの前処理に利用したりできます。 サンプルではタイポの修正などに利用したり、不要な語の除去などがあげてありました。\nWord Break Rewriter クエリトークンを分解・結合します。 たとえばドイツ語は、複合語と呼ばれる個別の意味の単語を結合した1つの単語を持っているため、個別の意味に分解して検索すると便利なことがあります。 そういった単語を辞書を基にして分割できるようにする機能です。 辞書とは実際のインデックスのタームディクショナリのことと思われます(要調査。どのインデックスのフィールドを指し示すのかなど、設定とドキュメントではよくわからない)。 なお、利用可能な形態素解析を基にした実装はドイツ語のみとなっており、また、分解の時には形態素解析を考慮しますが結合時には考慮しません。\nNumber-Unit Rewriter クエリの数値と単位を判別し、対象となるフィールドにマッチさせます。範囲での一致や完全一致やブーストが可能です。 単位をもとにして、特定のフィールドに対する数値のクエリに書き換えることができます。\nShingle Rewriter Solrのみで利用可能なので読み飛ばしました。\nルールはどこに保存されるの? .querqyというインデックスが内部で作成され、そこに保存されます(公式ドキュメントより)。 (ちなみに、Mappingはこんな感じみたいです)。 現状、プラグインでは設定したRewriterの取得ができないようなので、自分で登録した設定がどんなものかは、このインデックスを検索する必要がありそうです。\n気になった点・改善点? 気になった点があったので。\nRewriterのエンドポイントは、登録・更新・削除のみ対応しており、登録したものの確認は直接インデックスを見に行くしかなさそうです(Issueは作られてた)。 [要検証]書き換えられたクエリがどんなものか?は残念ながら確認できなそうで、_validate/queryで最終的なLuceneレベルのクエリで確認するしかなさそう? スキーマ側で定義したものと、Querqyで定義したものの兼ね合いがどういう形になるのか?などを気にする必要があるのが注意点かも。組み合わせたときの副作用などがどんなことになりそうか?が予測がつきにくそう。 Rewriterの定義自体のテストはどうしたものか? まとめ とりあえず、ざっとドキュメントを見ながらメモを取った感じです。 設定などの記述が独自のものなので、そこに慣れていく必要がありそうです(特にルールの改行の部分とか)。 次は実際にどんな感じで使えそうか、既存の仕組みとの違いは?みたいなところをもう少し見ていきたいとおもいます。\n参考文献 querqy/querqy: Query preprocessor for Java-based search engines (Querqy Core and Solr implementation) Getting started with Querqy — querqy.org documentation ","date":1658285563,"dir":"post/2022/","id":"779e444b4bc720a9eed97f19c41e8773","lang":"ja","lastmod":1658285563,"permalink":"https://blog.johtani.info/blog/2022/07/20/intro-querqy/","publishdate":"2022-07-20T11:52:43+09:00","summary":"Querqyというクエリのリライト用のプラグインがあるのでどんなものかを調べてみました。とりあえずは概要をドキュメントから追いかけてみた感じ","tags":["elasticsearch"],"title":"Querqyの調査(その1)"},{"contents":"今年もBerlin Buzzwordsにオンライン出張してました。 今年はハイブリッドな開催だったようで、現地で再開している人もいるようでした。 ブースもあったみたいです。ちなみに、現地で参加する人はマスク必須のようでした(Health \u0026amp; Safetyというページが用意されていました)。 昨年オンラインだったMICESは現地のみでの開催みたいで見ることはできなかったです(録画公開されないかなぁ)。\nさて、いくつか見たセッションで面白かったものがあったので簡単にメモを。 すでにセッションのビデオがYouTubeで公開されているので、興味のある方は見てみてください。\n面白かったセッション The future of Lucene\u0026rsquo;s MMapDirectory: Why use it and what\u0026rsquo;s coming with Java 19 and later? セッションページ: The future of Lucene\u0026rsquo;s MMapDirectory: Why use it and what\u0026rsquo;s coming with Java 19 and later? :: Berlin Buzzwords 2022 動画:Uwe Schindler – The future of Lucene\u0026rsquo;s MMapDirectory: Why use it \u0026amp; what\u0026rsquo;s coming with Java19 \u0026amp; later - YouTube 毎年恒例になってる気も? 前半は昨年も話をした内容で、後半はJava 19がリリースされたら、Previewという形でフラグを立てて使えるようになるようです。 使えるようにするから、テストしてみて!という感じで終わっていますw\nScaling an online search engine to thousands of physical stores セッションページ:Scaling an online search engine to thousands of physical stores :: Berlin Buzzwords 2022 :: pretalx 動画:Aline Paponaud – Scaling an online search engine to thousands of physical stores - YouTube 数千の実店舗の商品をオンラインで検索できるようにしつつ、オンラインのマーケットプレイスのような検索も一緒にできるようにしたというお話でした。 インデックスの構成をどう工夫したのか?とかどういうクラスター構成にして、どんなことをモニタリングしてるよ?というお話です。 実際の店舗がどんなものかなどは出てこなかったので、少しイメージは沸きにくかったのですが、どんなことを考えながらインデックスの構成とか考慮したよという話はおもしろかったです。 実際に検索したときに、実店舗のデータがどんな感じで結果として表示されたりするのか?といった点はわからなかったので、そのあたりの話をもうちょっと聞いてみたかったなぁ。\nOffline Ranking Validation - Predicting A/B Test Results セッションページ:Offline Ranking Validation - Predicting A/B Test Results :: Berlin Buzzwords 2022 :: pretalx 動画:Andrea Schütt \u0026amp; Yunus Lutz – Offline Ranking Validation - Predicting A/B Test Results - YouTube otto.deというECサイトでのランキングをどうやって改善していくか?という話。 現在はマニュアルなチューニングをコンテキストごとにやっているけど、リクエスト量とかデータとかが増えてきてて、このままマニュアルで改善していくのも大変なので、 モデルベースのランキングを開発できないか?というのをはじめていますよと。 そのために、これまでのデータから、A/Bテストの結果を予測できるモデルが作れないか?というのをやっていますという話。 いくつかわからない単語も出てきたので、誰か詳しい人教えて!\nAI-powered Semantic Search; A story of broken promises? セッションページ:AI-powered Semantic Search; A story of broken promises? :: Berlin Buzzwords 2022 :: pretalx 動画:Jo Kristian Bergum – AI-powered Semantic Search; A story of broken promises? - YouTube Vespaの開発にかかわってる方の、Semantic Searchに関する話。 Semantic Searchが流行り始めていて、どうやればできるのか?という話が出てきています。 けど、どういうものでどういう点に気を付けたほうがいい?という話でした。 LtRってこんなもの、そのあとに出てきたLLM(Large Language Model)でどうやって検索の改善に使えるの?というのが分かりやすく説明されていました。 それらの説明の後、BEIRという論文を紹介しつつ、LLMを使うときの注意点の話がありました。\nBERTとかをちょっと勉強してたのもあり、なんとなくそうだよなぁと思っていた結論と同じ結論が出てきたので面白いと感じました。 BEIRの論文は時間を見つけて読んでみないとな。\nHybrid search \u0026gt; sum of its parts? セッションページ: Hybrid search \u0026gt; sum of its parts? :: Berlin Buzzwords 2022 :: pretalx 動画:Lester Solbakken – Hybrid search: Greater than the sum of its parts? - YouTube こちらもVespaの人の話。 先ほどのSemantic Searchの話では、Semantic Searchがどんなものか?という話でした。 が、それだけで検索ができるわけでもないので、キーワードサーチとSemantic Searchの両方をうまく活用するには?というのがこのセッションでした。 最終的にはVespaを使うとうまくハイブリッドできるよという話ですが、考え方は参考になるかなと。 Vespaも触ってみたいなぁ。\nThe life of a search engine administrator セッションページ:The life of a search engine administrator :: Berlin Buzzwords 2022 :: pretalx 動画:Lucian Precup \u0026amp; Vincent Bréhin – The life of a search engine administrator - YouTube 検索システムの管理者ってどんなことやるの?それにはどんなことができるツールがあるといいの?という話です。 まぁ、ツールについてはこの会社の人たちのツールの宣伝なのですが、検索システムを作って育てていくのにどんなことを考えたりするのか?という参考になるかなぁと。\nShould we stop using distance in our location-based data recommendation models? セッションページ:Should we stop using distance in our location-based data recommendation models? :: Berlin Buzzwords 2022 :: pretalx 動画:Charlie Davies – Should we stop using distance in our location-based data recommendation models? - YouTube TravelTimeという会社を立ち上げた人の話。 位置に関する情報って重要だし、検索するときに利用しますよね?例えば、ホテル決めたりとか、仕事探したりするときに。 ということで、位置情報を検索エンジンで利用する方法(Bounding Box、ポリゴン、距離)をまず紹介して、どんなユースケースで使えるかという話があります。 また、それとは別に検索速度(いかに検索を速く返すか)も重要だという話があります(ウォルマートはページロード時間を1秒早くしてコンバージョンが2%あがったとか)。 で、実際に検索結果に距離とかでるけど、実際に知りたいのはどのくらいの時間で行けるのか?という話だったりしませんか?と。 公共交通機関を使ったりする場合に、実際に45分で移動できる距離というのは半径5マイルとかできまるものではないのに、単純に位置情報を利用した距離だけでソートしていいの?という問いかけから、 その辺を考慮した検索ができるAPIを開発しているよ、検索速度もはやいよというお話でした。 残念ながら具体的にどうやって作っているのか?というのはなかったですが、観点がおもしろかったです。\nWord2Vec model to generate synonyms on the fly in Apache Lucene セッションページ:Word2Vec model to generate synonyms on the fly in Apache Lucene :: Berlin Buzzwords 2022 :: pretalx 動画:Daniele Antuzi \u0026amp; Ilaria Petreti – Word2Vec model to generate synonyms on the fly in Apache Lucene - YouTube Word2Vecのモデルを使った、Apache LuceneのSynonym Filterを開発中だよという話 DeepLearning4Jを使ってみたが、遅くて使えなかったんだけど、最近Luceneに入ったkNNを使うことでそれなりの速度で使えそうなものができるかもよ?って感じでした。 モデル学習用のツールも作ってて、イタリア語のWikipediaで学習したものでちょっと動かしたらそれっぽい感じになってるという話でした。 まだ途中でいくつかやりたいことがあるという話で、実用はまだ先のようでした。例えば、1単語のSynonymにしか対応してないとか、モデルをインメモリでしか動かせないとか。\nQAでも出たのですが、Word2Vecだと対義語も類似していると判定されてしまうと思うので、その辺がどうなっているのかなぁ?という疑問があります。 ルールベースの類義語ではないので、調整するのはどうやるのかなぁ、学習用のコーパスをいい感じにするとかなのかな?とか、気になるところです。\nNrtSearch: Yelp’s fast, scalable, and cost-effective open source search engine セッションページ:NrtSearch: Yelp’s fast, scalable, and cost-effective open source search engine :: Berlin Buzzwords 2022 :: pretalx 動画:Umesh Dangat – NrtSearch: Yelp’s fast, scalable, and cost-effective open source search engine - YouTube YelpがLuceneベースで開発をしているNrtSearchというOSSの話です。 Elasticsearchを使っていたんだけど、どういった点が問題点になってどういうモチベーションでNrtSearchを開発したのか?を説明しています。 アーキテクチャがどんなもので、実際に動かしてみてどんな利点があって、どんな点が問題として出てきているか、将来どんなことをやろうとしているかがわかります。 QAでもいろんな質問が出ていて面白いです。\nまとめ ということで、簡単でしたがセッションの感想でした。 Neural/Semantic Searchというのがセッションのタイトルなどに入っているのが多くなってるなぁという感想です(ちょっとやってみたい気はしてるんだよなぁ)。 すでにYouTubeに動画が公開されているので興味があるセッションを見つけてみてください。 Berlin Buzzwordsの次の日に開催されたMICESも観てみたかったですが、オンラインでも参加できる形式で海外のカンファレンスが開催されるのはとても助かりますね(ヨーロッパだと時差もそれほど大変じゃないし)。 けど、落ち着いたらまたオフラインで参加してみたいなぁ。\n","date":1655283615,"dir":"post/2022/","id":"f56c19442484b3e4f47875b58b3f72b2","lang":"ja","lastmod":1655283615,"permalink":"https://blog.johtani.info/blog/2022/06/15/ttend-berlin-buzzwords-online/","publishdate":"2022-06-15T18:00:15+09:00","summary":"今年もBerlin Buzzwordsにオンライン出張してました。 今年はハイブリッドな開催だったようで、現地で再開している人もいるようでした。","tags":["conference","berlin buzzwords"],"title":"今年もオンラインでBerlin Buzzwordsに参加した"},{"contents":"7.16で正式リリースされましたが、Elasticsearchの新しいJavaのクライアントが出ています。 使ってみたので、ちょっとだけ紹介でもしてみようかな。\nこのクライアントが出るまでは、ElasticsearchのJavaクライアント(REST版)はElasticsearch本体の一部として実装・管理されていました(Elasticsearchのリポジトリにあるclientディレクトリ)。\nHTTP経由でElasticsearchにアクセスするクライアントだったのですが、Elasticsearch本体のリポジトリで管理されていることもあり、Elasticsearch本体で利用されているクラスを使用していました。 このため、クライアントライブラリなのですが、Elasticsearch本体のJarが必要になりサイズが大きくなっていました。 また、JavaのObjectへの詰め替えなどの機能も備えておらず、すこし古臭い感じでもあります。 この辺りを刷新する目的もあり新しいクライアントが公開されたようです。 3月くらいに触った時はまだ、ドキュメントが揃ってなかったのですが利用方法などが増えているので移行も楽になってきているようです。 根本的に作り直されたため、これまでのREST Clientとは使い方が違います。ですので、jarだけの差し替えでこれまで動いていたプログラムを移行ができるわけではないので注意が必要です。\nどの辺が便利? 順次移行が可能 これまでのRESTクライアントとはパッケージ名もjarも別モノになっています。 ですので、少しずつ新しいJava Clientに切り替えていくことが可能になっています。 根本的に使い方が変わっているので、大きなシステムのクライアントを全部切り替えるのは結構大変かと思います。 ですので、Indexをしている部分だけとか、検索部分だけなどといった部分的な置き換えをしつつ新しいクライアントに慣れていくことができます。\nラムダっぽく書ける 検索のクエリのサンプルを見るとわかりますが、こんな感じでクエリが書けます(公式ドキュメントより抜粋)。\nSearchResponse\u0026lt;Product\u0026gt; response = esClient.search(s -\u0026gt; s .index(\u0026#34;products\u0026#34;) .query(q -\u0026gt; q .match(t -\u0026gt; t .field(\u0026#34;name\u0026#34;) .query(searchText) ) ), Product.class ); また、最後で渡しているProduct.classは、検索結果をどのクラスのインスタンスにして返すかの指定です。 Elasticsearchのレスポンス(JSON)から値をコピーして返してくれるようになっています。 ですので、値を入れ替える処理を書く必要がなくなっています。\nJSON文字列をそのまま使える 触り始めてからリリース(7.17.2より後なら使える)された、JSON文字列からリクエストを作る機能もあります。\nこれまでのREST Clientだと、Elasticsearchへのリクエストを必ずJavaのメソッドで構築する必要がありました。 今回のこの機能を利用すると、JSON文字列(やファイル)からリクエストオブジェクトを作るためのメソッド.withJson()が提供されています。 例えば、スキーマや設定変更用のリクエストのJSONなどは、Kibanaやcurlから試験的に投げたリクエスト(JSON)と同じものを使いたいことが多いです。また、ElasticsearchのAPIは数が多く、ドキュメントを見ながら利用方法を調べてJSONでまず試行錯誤することが多いです。 このwithJsonメソッドを利用することで、動作確認などをしたJSONがそのままソースにも利用できるので、リクエスト変更時の確認なども容易になると思います。\n使ってみて困ったのは? 便利な面も多いのですが、使っていて少し困ったこともあったのでそれもメモを残しておきます。\nどんなリクエストを投げているかが不明 先ほども書きましたが、Elasticsearchのリクエストを試行錯誤するときは公式ドキュメントを見ながら、Kibanaなどを利用して試すことが多いです。 ですので、自分がやりたいことのJSONは手元にあることが多いです。 ただ、プログラムでクエリを組み立てる必要も出てきます。この時、実際にRESTリクエストとしてどんなJSONを投げているのかを知りたいことがあります(実際、検索クエリ作っててメソッドの使い方がうまくいかなくて四苦八苦してました)。 4月時点では簡単にリクエストで投げているJSONを文字列としてログに出すメソッドなどは用意されていないようでした。 デバッグ用に次のようなメソッドを書いてみました。 Elasticsearchへ投げるRequestのクラス(例:CreateTemplateRequestとか)を引数に渡すことで、JSON文字列に変換できるようになっています(StringWriterに書き出されてる)。 ここのLoggerはサンプルです。writer.toString()で取り出せる文字列がJSON文字列になっているので、ログに出してみるなり、ファイルに落とすなりしてデバッグのお供にしてください。\nimport java.io.StringWriter; import co.elastic.clients.elasticsearch._types.RequestBase; import co.elastic.clients.json.SimpleJsonpMapper; import jakarta.json.stream.JsonGenerator; ... private void printRequestBodyJsonForDebug(RequestBase request) { //for debug Logger.log(\u0026#34;** Debug print start **\u0026#34;); StringWriter writer = new StringWriter(); SimpleJsonpMapper mapper = new SimpleJsonpMapper(); JsonGenerator generator = mapper.jsonProvider().createGenerator(writer); mapper.serialize(request, generator); generator.close(); Logger.log(writer.toString()); Logger.log(\u0026#34;** Debug print finish **\u0026#34;); } プラグインなどで提供されるクエリが書けない LtRプラグインなどは、Elasticsearchの検索クエリを拡張しています。 残念ながら、現時点(2022/06/13)ではカスタムクエリを新しいJavaクライアントで利用しようとした場合、エラーが発生してしまいます(知らないJSONだと判断されてしまいます)。\nGitHubのIssueとして「[roadmap] Add support for plugin-defined custom components · Issue #252 · elastic/elasticsearch-java」があります。 これに対応されたら、拡張されたクエリも利用できるようになるでしょう。 プラグインなどで拡張されているものを使いたい場合は、残念ながら既存のRESTクライアントを当面は使うことになりそうです。\nまとめ 新しいElasticsearchのJavaクライアントを簡単ですが触ってみて、気になった点を記事にしました。 JavaのObjectに詰め替えてくれる機能など便利になっているので使ってみてください。 ドキュメントもちょっとずつ増えているようで、使い方も分かりやすくなっていました(触った時はレスポンスの扱い方などがJavaDocしか用意されてなかったんです)。 説明が欲しいなぁと思うことがあれば、GitHubにIssueを上げてみるといいかもです。\n参考 公式ドキュメント Java Clientチームの人がカンファレンスで利用したスライド ","date":1655119446,"dir":"post/2022/","id":"5eebdf85fd1726db301194bfeeee4377","lang":"ja","lastmod":1655119446,"permalink":"https://blog.johtani.info/blog/2022/06/13/new-elasticsearch-java-client/","publishdate":"2022-06-13T20:24:06+09:00","summary":"7.16で正式リリースされましたが、Elasticsearchの新しいJavaのクライアントが出ています。 使ってみたので、ちょっとだけ紹介で","tags":["elasticsearch","java"],"title":"Elasticsearchの新しいJavaクライアント"},{"contents":"Azure Cognitive Searchで2月に新しい機能が公開されました。 「Index Alias」(インデックスの別名)です。まだ、パブリックプレビューの段階ですが、ドキュメントなどが公開されていたのでどんな機能かを調べてみました。なお、本ブログの内容は2022/05/18時点での内容となります、ご注意ください。\n公式ドキュメント まずは公式ドキュメントです。1つ目の「インデックスの別名を作成する」の冒頭で別名(エイリアス)がどんなものかを説明しています。\nインデックスの別名を作成する - Azure Cognitive Search | Microsoft Docs エイリアスの作成または更新 (2021-04-30-Preview) - Azure Cognitive Search | Microsoft Docs Alias Operations (2021-04-30-Preview) - Azure Cognitive Search | Microsoft Docs REST APIのドキュメント(2022/05/18現在、日本語のページだと左のメニューが壊れているため、どんなAPIがあるかがわかりにくいため、Alias Operationsのページは英語のリンクになっています)\nインデックスエイリアスってどんなもの? 文字通り、インデックスにエイリアス(別名)をつけることができるようになります。 Azure Cognitive Searchでは残念ながらインデックスを作成するタイミング以外ではインデックスの名前を変更できません。 このため、インデックスのスキーマ(Analyzerの設定変更など)を変更したい場合、新しいインデックスを作成します。 新しいインデックスの名前はこれまでのものとは別の名前になってしまうため、アプリケーションで指定しているインデックス名も書き換える必要が出てきます。 利用しているアプリが複数ある場合は、すべて変更が必要です。\n今回出てきたエイリアスを利用することで、アプリケーションではエイリアスを指定することで、アプリケーション側の変更なくインデックスを入れ替えることができるようになります。\nエイリアスの操作方法 公式ドキュメントにAPIの一覧や利用方法の記載があるので詳細はそちらをご覧ください。 本ブログでは、いくつか利用するときに気になった点を書き残しておきます。\n作成 aliasesというエンドポイントにエイリアスの名前とインデックス名をPOSTすることで作成できます。 以下のサンプルは公式ドキュメントの例です。\nPOST /aliases?api-version=2021-04-30-preview { \u0026#34;name\u0026#34;: \u0026#34;my-alias\u0026#34;, \u0026#34;indexes\u0026#34;: [\u0026#34;hotel-samples-index\u0026#34;] } ちなみに、インデックスの指定がindexesで配列になっていますが、公式ドキュメントに以下の記述があり、複数の指定はできないです(エラーが返ってきます)。\nindexes 配列に指定できるインデックスの名前は 1 つだけです。\nまた、1つのインデックスに対して複数のエイリアスをつけることは問題ありません。\n確認 エイリアスのリストも取得できます。\nGET /aliases?api-version=2021-04-30-preview 現在どんなエイリアスが、どのインデックスに対して付与されているかがリストで取得できます。 きちんと作成されたかどうかなどの確認にも使えるかと思います(もちろんエイリアス名を指定したGETも可能です)\n検索での利用 検索のREST APIでインデックス名を指定していた部分をエイリアス名に置き換えるだけです。\nPOST /indexes/my-alias/docs/search?api-version=2021-04-30-preview { \u0026#34;search\u0026#34;: \u0026#34;pool spa +airport\u0026#34;, \u0026#34;searchMode\u0026#34;: any, \u0026#34;queryType\u0026#34;: \u0026#34;simple\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;HotelId, HotelName, Category, Description\u0026#34;, \u0026#34;count\u0026#34;: true } 更新 エイリアスの更新(インデックスの入れ替え)は作成と同じリクエストです。 更新が成功すれば204のステータスコードが返ってきます(エイリアス初回作成時は201) なお、ドキュメントには以下のような記述があります。入れ替え時の注意点になるかと(入れ替えのタイミングをきちんと制御したい場合は、少しだけアプリケーションを停止するなどが必要かと思います)。\n別名に対する更新がシステムに反映されるまでに最大 10 秒かかります。以前その別名が対応付けられていたインデックスを削除するのは、10 秒以上待ってからにしてください。\n削除 もちろん削除もできます。\nDELETE /aliases/my-alias エイリアスを利用する場合の注意点 便利なエイリアスですが、エイリアスが使用できない場合もあるので注意が必要です。\nデータ登録のAPIと検索のAPIでのみエイリアス名を利用可能 インデックスの設定変更やAnalyze Text APIではこれまで通りインデックス名を指定します。 また、エイリアス名はインデクサー機能でtargetIndexNameにも指定できません。 エイリアス名がついているインデックスは削除不可 エイリアスがついているインデックスを削除しようとした場合はエラーが出るようになっています。 まずはエイリアスを削除してからインデックスを削除するという手順になります。 まとめ 簡単ですが、インデックスのエイリアスに関しての紹介でした。まだパブリックプレビューなので正式リリース時点では利用方法が変わっている可能性もあります。こちらは注意してください。\n正式公開されればですが、今後Azure Cognitive Searchを使ったアプリを開発する場合はインデックスエイリアスを利用することを基本にするのがいいかもなと思います (ちなみに、Elasticsearchにもインデックスエイリアスの機能がありますが、異なる点が多いので同じものとは思わないほうがよさそうです)。\n","date":1652856857,"dir":"post/2022/","id":"7cc21814165879f72529e91682ece5c6","lang":"ja","lastmod":1652856857,"permalink":"https://blog.johtani.info/blog/2022/05/18/index-alias-in-azure-cognitive-search/","publishdate":"2022-05-18T15:54:17+09:00","summary":"Azure Cognitive Searchで2月に新しい機能が公開されました。 「Index Alias」(インデックスの別名)です。まだ、パブリックプレビューの段階です","tags":["azure search"],"title":"インデックスエイリアス - Azure Cognitive Searchの新機能"},{"contents":"年末までに知り合いと次の論文を読んだので軽くまとめておきます。\nExtreme Multi-label Learning for Semantic Matching in Product Search なんで読んだの? 前回読んだ理由と一緒ですが、Semantic Searchに絡んだ検索の論文であり、Amazonの製品検索での話も関係していたので読みました。\nどんな論文? Amazonの製品検索でセマンティックマッチングを利用する方法、レイテンシを低くしつつ再現率を改善できるような仕組みを検討して評価した論文です。 実際には商品検索のマッチングを大規模なマルチラベル問題(Extreme Multi-label Classification:以下ではXMC問題とする)として定義して、その問題を効率よく解く方法について検討評価しています。\n検索には大きく2つのフェーズがあります。マッチング(クエリにヒットした文書の集合を求める)とランキング(マッチングのデータを関連性の高い順序で並べる)です。 前回のMSの論文では、マッチング後のランキングのフェーズで言語モデルを利用した並び替えを行う話でした。 今回の論文ではマッチングに関してセマンティックサーチを有効活用できないか?という論文になります。 転置インデックスベースの(語彙による)検索では、スペルミスや類義語などを検索することが難しいです。 語彙以外のデータ(クリックや購入といったユーザーの行動や製品の意味的表現など)を学習できる埋め込みベースのニューラルモデルを活用して、マッチングを補完する方法を検討しています。 下図のようにあくまで転置インデックスベースの検索の補完として利用するみたいです(論文に掲載されていたアーキテクチャ)。\nXMC問題とは? セマンティックサーチを行なう場合、埋め込みベースのニューラルモデル(例えばBERTとか)を利用することが多いですが、 クエリトークンを埋め込み空間にベクトル化する部分が推論のボトルネック(レイテンシが高くなる)になることが多いです。 これは、ニューラルネットワークの複雑さに依存します。 低レイテンシになるように、複雑ではないエンコーダーを用いることもありますが今度は性能(精度)が良くなくなります。\nそこで、この論文ではセマンティックマッチングをXMC問題として定義し、これを効率よく解くための手法を提案しています。 ここで、XMCの問題とは、入力(今回はクエリ)に対して、最も関連性の高い複数のラベル(今回は製品)を出力することとなります。 Amazonでの製品なのでほんとに大規模(ラベル=製品=1億件)です。\n従来のXMC問題を解くための手法として、疎な線形モデルの手法、パーティションベースの手法、グラフベースの手法などが列挙されています。 疎な線形モデルの手法では、ナイーブなOVR(one-versus-rest)だと出力となるラベルの数に対して線形に推論時間も大きくなるため、今回の用途には適しません。 この論文ではパーティションベースの手法として、推論時間を短くできるツリーベースで疎な線形モデルの手法を評価しています。\nどういう仕組み? ツリーベースのモデルは次のような感じです。 PECOSのXR-Linearモデルを利用しています。 モデルに関する詳細についてはこちらの論文に詳しく載っているようです(まだ読んでいないです、、、)。\n一番上に入力として与えられるxがクエリ(ベクトル)で一番下の四角が製品にあたるラベル(Y={1,...,l,...L})です。 これらが与えられたときに最も関連性の高い上位k件のラベル(製品)を出力するモデルを生成します。 モデルのパラメータは、学習データとして(x, y)(ここで、y∈{0, 1}^𝐿、すなわちクエリに製品がマッチするかしないかの二値)を使って調整します。\nこれは、ツリーのそれぞれの階層のノードで、その下の層に関連するデータがあるかどうか?という分類を学習すればよいことになります。 学習データとしては、入力と最下層のラベルにマッチするかどうかというデータです。 これをもとに、ツリーの最下層のデータをもとにひとつ上の層の分類器の学習をすればよいことになります。\n推論は出来上がったツリーベースのモデルに対して、ビームサーチで行ないます。 この時、それぞれの層のノードの分類器では推論の効率化のために枝刈りの閾値を設定しています。 本論文で閾値の違いによる精度とレイテンシの比較も行われています。 また、ビームサーチのビームサイズを変化させた場合の性能についても実験しています。\nどうやって検証した? 次のようなデータを用いてAWS上にモデル構築、推論のシステムを用意し実験しています。\n10億件以上のポジティブなクエリ-商品ペアのデータセット クエリ:2億4千万、商品:1億 ポジティブなペアとは、クリック数や購入数の集計値が閾値以上。ただし、データセットとしては集計値は利用していない。 トレーニングセット:12か月分の検索ログ 評価用テストセット:1か月分の検索ログ(12%の製品はトレーニングセットには出てこない) というデーセットをもとに上記のモデルを学習しています。 特徴量はクエリテキストと製品のタイトルをもとにTF-IDFをいくつかのパターンで導出したものが使われています。 詳しくは論文の結果に関する表などを見ていただくとして。。。\n結果として、1億件の商品カタログで60.9%のRecall@100を1.25ミリ秒/リクエストという低レイテンシで達成したとなっています。\n気になる点は? 知り合いと3人で読んでいて次のような気になる点が出てきました。\nツリーの構築をするときに、製品のラベルの並び順(製品のクラスタリング?に他製品が似た場所に来る感じ)が推論の効率の良し悪しに影響するんじゃないの?=Amazonではないところではうまくいかない? PECOSの論文読まないといけない? 製品が増えたときにモデルの組み換えとかどうするの? コールドスタート問題という形で今後の課題として書かれていたので、今後に期待 転置インデックスでのマッチングの補完として利用しているということだったけど、ランキングはどうしてるんだろう? 別のランキング用の指標があるのかな?上位k件とした場合にどうやって、決めているのか? モデル更新のタイミングはどのくらいのスパンなんだろう? まとめ&感想 セマンティック検索の処理を分類問題に置き換えてその手法を用いて行い、実際のシステムに適用できそうな速度と精度を出しているのが面白かったです。 セマンティック検索にもいろんな手法があるのだなと(そして、いろいろ勉強しないといけないんだなと。。。)。\n気になる点にも書きましたが、ツリーの作り方になにかコツがあるのか?他の検索結果と組み合わせるときに、どのような基準で上位を選択しているのか?など疑問点も残っています。 個人的には特にどのように既存のシステムにくっつけていくのかというところが気になっています。 論文の続編でその辺の話が出てくるのかなぁ?\nツリーの作り方に関するPECOSの論文を誰か解説してくれると嬉しいかもなぁと思いつつ、とりあえずブログに書き残してみました。参考になるかなぁ。。。\n参考文献 Extreme Multi-label Learning for Semantic Matching in Product Search - ACM Extreme multi-label learning for semantic matching in product search - Amazon Science PECOS: Prediction for Enormous and Correlated Output Spaces 数えきれないほどの分類を行うExtreme Classification - Technical Hedgehog ","date":1641980462,"dir":"post/2022/","id":"0645bdb1cdf88ec74288d503eb71839c","lang":"ja","lastmod":1641980462,"permalink":"https://blog.johtani.info/blog/2022/01/12/reading-xmc-for-semantic-search-in-prod/","publishdate":"2022-01-12T18:41:02+09:00","summary":"年末までに知り合いと次の論文を読んだので軽くまとめておきます。 Extreme Multi-label Learning for Semantic Matching in Product Search なんで読んだの? 前回読んだ理由と一緒ですが、Semantic","tags":["search","paper"],"title":"Extreme Multi-label Learning for Semantic Matching in Product Searchという論文を読んだ"},{"contents":"今年も振り返りブログです。録画した紅白をオッかけ再生して気になるアーティストだけ見ながら書ています。\n振り返り(2020年に書いた抱負から) まずは去年の抱負を元に書きます。今年もコロナウィルスの影響が年末まで続き、ほとんどで書けなかったです。\nフリーランス継続? ありがたいことに個人事業主として無事1年を終えられました。 夏頃は5社ほどお手伝いをさせていただき、年末時点では3社をお手伝いさせていただいています。\n昨年の振り返りで書いた2社はありがたいことに継続していただいています。\n今年も完全リモートで仕事が終わりました。オミクロン株が来ているし、来年春くらいにはミーティングに出かけられるかなぁ。 相変わらず検索のお手伝いをしています。手伝いをしつつ勉強させていただいている感じです。 ありがたし。\nプログラミング ちょっとペースダウンしています。。。\nextract-kana-java 新しく書いたのはこれくらいかな。 SudachiやNeologdのkuromojiでフリガナを出力して違いを見るというコマンドツールです。 ちょっと比較してみたくなったので書いて公開しました。\nあとは、Sudachiをいろいろと触り始めています。 来年はそのへんをもうちょっと何かできるかなぁ。 コーディングしないとよくないなぁと思っているので、強制的になんかやらないとだ。\n検索の勉強 仕事でやってます。ブッチャー本は昨年買って手を付けてませんが。。。 来年は少しずつやる予定です。 あとは、Azure Cognitive SearchのSemantic Searchを触った関係でSemantic Searchに関する論文を探してちょっとずつ読んでいます。 知り合いと読んでいたAmazonの論文をブログにまとめるのは来年早々に。。。\n検索のポッドキャスト? これはできませんでした。重い腰が上がらない。 公開しないまでも雑談したいなぁ。\n振り返り(今年あったできごと) ここからは今年の出来事を。\n自宅環境 キーボード以外もDIY 検索Slack爆誕 車買い替えた WindowsノートPC買った 今年もずっと自宅で仕事でした。 昨年だいぶそろえていたのでそれほど変更はないですが。\n2月バージョン 切り替えてからずっとWindowsです。Macもブラウズ用に使ってはいますが。 ただ、Windowsといっても、プログラムなどに関する環境はほぼWSL2になっています。コマンドプロンプトは触ってないなぁ。 今年最後に更新された自宅環境は椅子になります。 詳しくは昨日のブログをご覧ください。\nキーボードもDIYしましたが、今年はほかにも少しDIYしました。\n今年のDIYキーボードとコントローラーラック このブログにも書きましたが、来年はキーマップやファーム関連を触っていきたいなと。あとロータリーエンコーダー。。。 BLE化は快適で、3台のPCの切り替えがとっても便利です。\ntakuya_aさんの鶴の一声で検索のSlackが爆誕しました。 検索に関連する情報交換ができる場として楽しませてもらってます。 年末には検索100本ノックの話が立ち上がってきています。 来年も面白い話が聞けそうでワクワクしています。\nあとは、車を買い替えました。初のハイブリッドです。 まだまだ慣れないですが、燃費とかがとても楽しみです。\n結局まだ出かけていませんが、出かけられるようにFMV Zeroを購入しました。 このブログもリビングでFMV Zeroで書いています(まだちゃんとセットアップしていないので、実際にはリモートデスクトップでデスクトップにつないでそこのVSCodeで書いちゃってますが。。。)。 ブログ書いたりコード書ける程度の環境は作らないとな。\n来年の抱負 ということで、来年の抱負です。\nフリーランス継続 プログラミング ブッチャー本ちゃんと読む 読んだ本のブログを書く 今年もありがたいことに仕事を継続していただけて、乗り越えられました。 来年も価値を提供できるように頑張っていきます。\nプログラミングは失速気味のでなにかテーマを見つけないとなあ。\nブッチャー本は読み始めます。必ずw\nブログのペースが落ちていたり、本を読むペースが落ちているので、 本を読んで自分のためにもブログを書こうと思います。 書いてないって思ったら叱咤してください。。。\n今年も出かけられませんでしたが、仕事も安定してあり、無事乗り切れました。 人と話をする機会は減っているので雑談したいな、オンラインなどで。 相手をしてやってもいいぞという方はぜひ連絡ください。\nさて、来年(もう年あけちゃったけど)は出かけられるかなぁ。 何はともあれ、今年もよろしくお願いします!\n","date":1640957359,"dir":"post/2021/","id":"104b8ee17a8bf1f7043d236659680493","lang":"ja","lastmod":1640957359,"permalink":"https://blog.johtani.info/blog/2021/12/31/looking-back-2021/","publishdate":"2021-12-31T22:29:19+09:00","summary":"今年も振り返りブログです。録画した紅白をオッかけ再生して気になるアーティストだけ見ながら書ています。 振り返り(2020年に書いた抱負から) ま","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2021)"},{"contents":"2021年もあと少しですが、今年買って良かったものをリストアップしておこうかと思います。 今年買ったといいながら、昨年このネタを書くといいつつ書いてないので、昨年の分も入っているかも? Amazonのアフィリンクを貼っていますが、急いでないものはAliExpressで購入したりもしています。\n象印のポット Amazon | 象印 電気ケトル 1.0L コーヒードリップ用機能付き ホワイト CK-AX10-WA | 象印マホービン(ZOJIRUSHI) いわゆる電気ケトルというやつです。これが来るまでは鍋で湯を沸かしていました。 水を入れてボタンを押し、湯を沸かしている間に他のことができるのはやはり便利です。 また、コーヒーを入れるためのコーヒードリップモードがあるので、ドリップするためにわざわざ湯を他のものに入れたり、 専用のヤカンを使わなくても簡単にドリップができるのがさらに便利で重宝しています。\nウォータードリップコーヒーサーバー Amazon | iwaki(イワキ) コーヒーサーバー SNOWTOP ウォータードリップ ここ数年、冬以外は水出しコーヒーを飲んでいます。 麦茶のポットのような水出しコーヒー用ポットを使っていたのですが、滴下式のほうがえぐみが少ないというのを見かけてウォータードリップのサーバーに変えてみました。 このひとつ前に水のタンクの部分がプラスチックのものを利用していたのですが、ドリップする部分を壊してしまったので、部品を購入することができるこちらに切り替えました。 朝、仕事をする前に豆を挽いて仕込んでおくと、昼にはコーヒーが落ちています。 夏は入れ終わったポットごと冷蔵庫に入れておくと氷を入れなくてもアイスコーヒーが飲めるので気に入っています。\neufyの掃除機 Amazon | Anker Eufy HomeVac H11(ハンディクリーナー) USB充電 仕事に使っている机でプラモデルを作ったり、DIYキーボードの工作をしたりと細かなごみが出る作業を行ないます。 ちょっとごみを吸いたいだけなのに、掃除機を毎回取りに行くのも面倒なので充電式のクリーナーを買ってみました。 仕組みも簡単だし、USBで充電できるのでおすすめです。アタッチメントを利用してキーボードの掃除なんかもしています。\n電動精密ドライバー Amazon | Wowstick 1F\u0026#43; 69in1 電動精密ドライバー ビット56種セット ケース USB充電式 LEDライト付き [並行輸入品] キースイッチを付け替えたり、工作したりでねじの開け閉めを頻繁に行います。 思ったよりも頻度が高くなってきたので、電動の精密ドライバーを試しに使ってみたらすごく楽ができました。 電池の入れ替えなどでもねじの開け閉めは行なうので、すごく役に立っています。 ビットが56種類もついていますが、プラスとマイナス以外はまだ使ってないかも。。。\n磁石のUSBケーブル Amazon | SUNTAIHO マグネット充電ケーブル DIYキーボード、エネループの充電器、上記のドライバーや掃除機など、USBで充電したり、接続するものが結構あります。 毎回ケーブルを差し替えるのも大変なのですが、@ymotongpooに教えてもらった磁石のUSBケーブルがお気に入りです。 先端部分(USB-C、micro)とケーブル部分が別々になっており、また、ケーブルと先端は磁石でくっつく構造なので、充電したい機器に先端部分を刺しておきます。 充電や接続したいときにケーブルを近づけると磁石でくっついてくれるのでケーブルの抜き差しが必要なくなります。 先端部分だけを個別に購入できたので、色々な機器にあらかじめつけてあります。\nMaker hart Just Mixer 5 Amazon | Maker hart Just Mixer 5 ステレオ5入力音声ミキサー/Bluetoothオーディオ入力対応 3台のPC+音楽サーバーとしてラズパイを主に利用しており、通知音などを1つのスピーカーから聞きたいので、ミキサーを導入しました。 5つの入力個別に音量調節できるので打ち合わせの時だけ他の音源を小さくしたりなど重宝しています。 ただ、入力が増えるとノイズが乗っている気もしますが。。。\nリストレスト(アームレスト) Amazon | エレコム リストレスト アームレスト 肘起き 扇形 左右で使える2個セット ブラック MOH-EL01BK 扇形のものを分割キーボードの手間においてリストレストとして使っています。 使用例の写真を見ると肘を置いていますが、手のひらをおくのにちょうどいいです。 これまでいくつかパームレストを試してみましたが、凹凸もなく適度な硬さで気に入っています。\nコンテッサセコンダ Amazon | オカムラ オフィスチェア コンテッサ セコンダ 10月に注文してクリスマスに届きました。部品が不足しているようで年内に届かないかもといわれていたのですが。 2003年くらいからアーロンチェアを使っていたのですが、さすがに買い替えるかということで奮発しました。 アーロンチェアは座面がメッシュなのですが、ももが疲れるのもあり、クッション座面のものにしてみました。 冬寒くないのがいいですねwまだ届いたばかりなので調整しないと。\nKindle paperwhite Amazon | Kindle Paperwhite - 大きくなった6.8インチディスプレイ 防水機能搭載 wifi 8GB 電子書籍リーダー 車の点検などでちょっとした待ち時間があるようなときに新書や小説が読めるようにセールで安くなったタイミングで購入しました。 健康診断で読書がはかどりました。もっと本を読まないとなぁ。\nということで、ここ数年で買って便利なものをまとめてみました。 他にもある気がするけど、とりあえずこの辺で。\n","date":1640784504,"dir":"post/2021/","id":"218e2c36d5945ece02fdc55d6cbcbc38","lang":"ja","lastmod":1640784504,"permalink":"https://blog.johtani.info/blog/2021/12/29/best-buy-2021/","publishdate":"2021-12-29T22:28:24+09:00","summary":"2021年もあと少しですが、今年買って良かったものをリストアップしておこうかと思います。 今年買ったといいながら、昨年このネタを書くといいつつ","tags":["misc"],"title":"2021年かって良かったもの"},{"contents":"Azure Cognitive Searchのスキーマの確認をするときに、Azureのポータルでは次のようにフィールドの一覧として見ることができます。\nただ、実際のインデックス定義はJSON形式でやり取りする形になっています(JSONの例:Create Index | Microsoft Docs)。 上記のスクリーンショットのようにフィールド数が少ない場合はそれほど気にならないのですが、フィールド数が大きくなると一覧で見たくなることがあります。 また、ポータルを自分で確認できない場合にJSONファイルを受け取って確認することもあります。 こういう時は、Excel(CSV)って便利ですよね?\nということで、サクッと確認するときには、次のようなjqコマンドをWSL2上で利用して、CSVに変換して確認しています。\necho \u0026#34;Name\u0026#34;, \u0026#34;Type\u0026#34;, \u0026#34;Searchable\u0026#34;, \u0026#34;Facetable\u0026#34;, \u0026#34;Filterable\u0026#34;, \u0026#34;Retrievable\u0026#34;, \u0026#34;Sortable\u0026#34;, \u0026#34;Analyzer\u0026#34;, \u0026#34;IndexAnalyzer\u0026#34;, \u0026#34;SearchAnalyzer\u0026#34; \u0026gt; index_schema.csv cat index_schema.json | jq -r \u0026#39;.fields[]|[.name, .type, .searchable, .facetable, .filterable, .retrievable, .sortable, .analyzer, .indexAnalyzer, .searchAnalyzer]|@csv\u0026#39; \u0026gt;\u0026gt; index_schema.csv 例えばこんな感じになります(上記のポータルのスクショとは別のスキーマですが。。。)。\nどんなフィールドオプションが利用されているか?などをExcelで開いてフィルターなどを活用してチェックするのには便利かなと。 jqコマンドをもっとうまく使うと、ヘッダ行ももっとスマートに出せるかもしれないんですが。。。\nちなみに、上記のコマンドでは残念ながらEdm.ComplexType(参考: 複合データ型をモデル化する方法 - Azure Cognitive Search | Microsoft Docs)には対応していません。 必要になった時に考えるかな。。。\n","date":1640141671,"dir":"post/2021/","id":"f0fdc140e18514362a4e52376a6fecba","lang":"ja","lastmod":1640141671,"permalink":"https://blog.johtani.info/blog/2021/12/22/azure-search-schema-json2csv/","publishdate":"2021-12-22T11:54:31+09:00","summary":"Azure Cognitive Searchのスキーマの確認をするときに、Azureのポータルでは次のようにフィールドの一覧として見ることができます。 ただ、実際のインデ","tags":["azure search","misc"],"title":"Azure Cognitive SearchのIndex Schema JSONをCSVで見たくなる"},{"contents":"今年もアドベントカレンダーの季節になってしまいました。 今年で2回目となる、pyspa Advent Calendar 2021の投稿です。 昨年に引き続きDIYがらみの投稿です。\nコントローラーラック 3つのコントローラーがあるのですが、結構場所を取ります。 また、それぞれ充電しないといけません。\n充電しつつ、邪魔にならない置き方はできないものか?と思っていたところ次のようなコントローラーラックを見つけました。\nAmazon | 山崎実業(Yamazaki) ゲームコントローラー収納ラック これそのものは場所を取るので購入は見送りましたが、エレクターの棚にワイヤーネットをつけると似たようなものができるのでは?ということで、DIYしてみることにしました。\n材料 材料は以下の通りです。 書いていない材料としてあとは、結束バンドがあります。\nワイヤーネット44×29.5cm オフホワイトB28 | 【公式】DAISO(ダイソー)ネットストア スリム型ネットフック50mm 2本入り | 【公式】DAISO(ダイソー)ネットストア クロームメッキワイヤーフック(2連、U字、2個) | 【公式】DAISO(ダイソー)ネットストア Amazon | マグネット 充電ケーブル SUNTAIHO USBケーブル LEDインジケーター付き Amazon | Anker PowerPort Atom III Slim (PD 充電器 65W 4ポート USB-C) 設置 まずは、2連のワイヤーフックでワイヤーネットをエレクターの棚にぶら下げました。\nそのままでは固定されないので、下のエレクターの棚とワイヤーネットを結束バンドで固定。 これで、コントローラーを置いたり取ったりしてもぐらぐらしません。\n固定したワイヤーネットの表(コントローラーを配置する側)に、ネットフック50mmをコントローラーの数だけ配置しました(上の写真でフックとコントローラーの関係がわかります)。\n前から見るとこのような形です。 裏側に、2連フックを使って、Ankerの充電器を固定し、USBのケーブルをコントローラーの上に来るように配置します(写真ではPS4とPS5のコントローラーの上の部分にぶら下がる形です)。\nコントローラーには磁石の端子をコントローラーに差し込んでおきます。\n磁石のUSBケーブルを利用していることで、コントローラーを取り出すときは少し力を入れて引っ張るだけ、収めるときは、ケーブルに近づけて充電できる状態にした後にフックに載せるだけとなりました。 ケーブルの抜き差しをしなくてもよいのでとても便利。 全体像は次の写真のようになっています。一番上のコントローラーはエネループを利用しているのでケーブルは不要になっています。\n磁石のUSBケーブルをpyspaでとんぷーに教えてもらって思いついたアイデアです。 磁石の端子は色々と使い勝手が良いので、DIYキーボードやテンキー、MX Ergo、Kindleなど色々なところに使っています。\n今年のDIYキーボード キーボードを作ったのは2つですが、改造を色々やってました。 ブログに記載したものはリンクだけにしておきます。\nケーブル自作 自作ケーブルキット – 遊舎工房 ケーブルも自作できるみたいなので作ってみました。 現在はテンキーの配置の問題もあって、メインでは利用はしていませんが工作としては面白かったです。 熱収縮チューブを処理するための道具を持っていなかったので、チューブの固定が甘いのが失敗でした。ドライヤーくらいの熱では足りないので作ろうと思っている方は要注意かと。\nCorne Light v2のBLE+LPME-IO対応 詳細はブログ記事を。Corneはこれ以外に、キースイッチの付け替えも行ないました。ルブしたGateronクリアをハンダでつけなおしました。\nCorne Light v2のBLE+LPME-IO対応 #DIYキーボード Sofle keyboard v2のBLE+LPME-IO対応 詳細はブログ記事を。このブログはSofleで書いています。現在メインに利用しているキーボードです。\nSofle v2を組み立てて、BLE+LPME-IO化してみた #DIYキーボード 10月には電池モジュールを次のものに付け替えました。家で主に使用するのもあり、充電池のほうが使い勝手がよさそうだという判断です。スイッチのON/OFFもしやすくなって満足しています。\n単4電池昇圧モジュール - のぎけす屋 - BOOTH Sofleの電池モジュールをボタン電池から単4電池用に差し替えた。 pic.twitter.com/TUizwr2qmw\n\u0026mdash; Jun Ohtani (@johtani) October 16, 2021 Lunakey Miniの組み立てとBLE+LPME-IO対応 詳細はブログ記事を。Sofleと時々入れ替えて使っています。小指のあたりのずれの大きさ、親指のキーの多さが使い勝手のよいキーボードです。コンパクトなのもあり、こちらは持ち運びにも利用できるかなと考えています。\nLunakey Miniを組み立てて、BLE+LPME-IO化してみた #DIYキーボード Soyuzの組み立て(Numpadキット) Soyuz (黒基板) – 遊舎工房 自宅の作業環境(2021/02)の写真にもありますが、分割したキーボードとは別にテンキーを利用しています。 WindowsのログインでPinコードを入力したり、色々な場面で数字の入力をすることがあるためです。 Soyuzを組み立てる前は素 - Shiro – 遊舎工房を利用していたのですが、これでは「⁺」や「Enter」など、電卓のような利用方法の場合にはキーが足りません。 かゆいところに手が届かないので、きちんとしたNumpadをということでSoyuzを組み立てました。\nShiroよりもだいぶ存在感があります。\nGK21S(Numpad) USB Type C充電器付きの滑らかな交換用キーボードキット (Gk21s/k21),スイッチ,デュアルモードPCB|Keyboards| - AliExpress 最後は独身の日のセールで見つけたNumpadキットです。キットといってもこちらは、基盤からケースまで組み立てが終わっているキットで、キースイッチを差し込んで、キーキャップを付けるだけというものになります。 現在はこれをメインに利用しています。通常のNumpadの上に1列キーが多く、Backspaceなどを割り当てられるのが便利です。 ドライバーソフトも用意されており、キーマップのカスタマイズも可能です(まだそこまでやってないけど)。\nお気に入りキースイッチ Kailh Box Silent ピンク軸 5個 | Kochi Keyboard Input Club Hako スイッチ(10個入り) – 遊舎工房 最後はキースイッチの紹介です。 現時点ではこの2種類を組み合わせるのが私の好みに合っているようです(今のところ)。 Box Silentのピンクをアルファベットのキーに、Input Club HakoのVioletをCtrlやShift、Enterなどのキーに割り当てて使っています(下の写真の左側で、キーキャップをつけている部分がHako Violetになっています)。\nまとめ ということで、pyspa Advent Calendar 2021の8日目の記事でした。 それほど作ったりしてないなと思っていたのですが、記事にしてみると今年も色々とDIYしてたみたいです。 キースイッチやキーキャップも自分の好みが固まってきたので、来年はファームウェアやキーマップ周りをいじっていきたいと思っています。\n","date":1638889200,"dir":"post/2021/","id":"26e44dfd16a2963d4c18e99806c26fd7","lang":"ja","lastmod":1638889200,"permalink":"https://blog.johtani.info/blog/2021/12/08/controller-rack/","publishdate":"2021-12-08T00:00:00+09:00","summary":"今年もアドベントカレンダーの季節になってしまいました。 今年で2回目となる、pyspa Advent Calendar 2021の投稿です。 昨年に引き続きDIYがらみの投稿","tags":["DIYキーボード","misc"],"title":"今年のDIYキーボードとコントローラーラック"},{"contents":"Domain-Specific Pretraining for Vertical Search: Case Study on Biomedical Literatureという論文を読んだので軽くメモを残しておきます。論文自体はリンクから参照してください。\n読んだ理由 Azure Cognitive SearchでSemantic Searchが利用可能になったこともあり、「Semantic Search」に関するMSのリサーチチームが発表している論文をたまたま見つけたためです。 Elasticsearchとニューラルモデルを利用したランカーでのリランクする仕組みがSemantic Searchと似ていたので読んでみました。\nざっくりメモ どんなもの? クリックログなどで関連度を改善できないような場合に、ドメイン固有の言語モデルを利用して検索結果の改善をする方法が提案されているので、バイオメディカル検索で実際に評価してみたという論文です。 特定分野の大量の文書から検索をするときに、ドメイン固有の事前学習した言語モデルを用意して、さらにファインチューニングする方法を評価しています。 言語モデルの生成に利用されたのはBERTになります。\n技術や手法のキモはどこ? 医療分野のデータを利用して評価していますが、ほかのドメインにも一般化できる可能性があることや、実際のシステムを提示している部分が肝になりそうです。\n論文から引用した言語モデルを用いてランキングを行う仕組みを構築する部分の構成です。\n左半分が、ドメイン固有の事前学習についてです。Wikipediaなどを利用したBERTのモデルが公開されたりしていますが、大量のドメイン固有データが用意できるのであれば、ドメイン固有のデータで事前学習することが有効であるという主張です(参考文献。これもMS Researchでした。同じチームなのかな?)。 この論文ではBERTの学習データとして、ドメイン固有のテキストを用いています。 実際にはPubMedBERTを利用しています。\n右半分がドメイン固有のデータで生成された言語モデルを利用して、ドメイン固有のニューラルランカー(検索結果のランキングを行なう仕組み)をファインチューニングする処理です。 MS MARCOと呼ばれるMSが公開している機械学習向けのデータセットのうち、ドメイン固有のサブセットを取り出して利用しているようです。\nこの論文では、L1検索(第1段階の検索)にBM25を利用して、L2検索にここで作成したニューラルランカーを利用し、検索結果を返す仕組みとなっています。 これは、Azure Cognitive SearchのSemantic Searchのシステムに似ています。\nこの論文では、BM25で検索した結果の上位60件の結果がL2のランカーの入力となっています。\n以下の2つが主な論文の成果となっています。\nドメイン固有の事前学習を利用することで、高度な学習コンポーネントなどの追加することなく高い精度が出た。 既存のBM25の検索エンジンと組み合わせてニューラルランカーを使うことで、計算コストを下げつつより良い上位の検索結果を返す仕組みを構築した。 どうやって有効だと検証した? TREC-COVIDデータセットを用いて評価して、TREC-COVIDに参加しているシステムと論文で提案している構成のシステムとの比較をしています。 また、ドメイン固有の事前学習が、一般ドメインなどの事前学習と比較して影響があるかどうかの評価もしています。\n実際にAzure上で構築した仕組みをMicrosoft Biomedical Searchとして公開しているようです。 上記のシステム構成のように、Elasticsearchで検索して、ニューラルランカーはKubernetes上に展開されたGPUで計算をしています。 論文には使用しているマシンの構成や台数なども記載があります。\n実際に構築したシステムをユーザーに利用して体験したもらった結果としては、 複雑な意図を持った長いクエリに対してはPubMedなどの他の検索ツールとしても良い結果が返ってきたことが確認されたとなっています。 ただし、一般的な短いクエリの場合は十分な結果にならない場合があったとのことです。\n議論はある? 実際にほかのドメイン(金融、法律、小売りなど)で適用してもうまくいくかは今後の研究に期待だと思います。 また、ファインチューニングするときに利用できるデータが今回の論文にあるようにMS MARCOのサブセットとして抽出できればよさそうです。\n他に読むべき論文は? TREC-COVIDに参加しているほかのシステムがどのような学習や仕組みが必要なのかを見ることで、どのくらいの手間・コストが軽減しているのかがわかるはずです。\n感想 ということで、読んでみました。 細かなほかの手法については調べていませんが、システム構成としてはAzure Cognitive SearchのSemantic Searchの仕組みと同じだと思われます。 違いは、ドメイン固有の事前学習のモデルではないことでしょうか。 ある程度のドメイン固有のモデルを利用できる仕組みができると、さらにSemantic Searchがうまく使えるようになるのかもしれません(前回書いたブログではWikipediaのデータを利用してみましたが、思ったほど良い感じはしなかったです。。。ファインチューニングの仕組みもないしなぁ)。 また、短いクエリでは芳しくない結果もあったというのは、おそらくニューラルランカーで評価するための情報が少なくなってしまうのだと思います。Semantic Searchに向いているクエリの作り方とかが出てくるのかな?\n","date":1636522396,"dir":"post/2021/","id":"35200cbf0b5b45d7f5f0b343cb18868b","lang":"ja","lastmod":1636522396,"permalink":"https://blog.johtani.info/blog/2021/11/10/reading-ms-biomedical-search-paper/","publishdate":"2021-11-10T14:33:16+09:00","summary":"Domain-Specific Pretraining for Vertical Search: Case Study on Biomedical Literatureという論文を読んだので軽くメモを残しておきます。論文自体はリンクから参照してください。 読んだ理由 Azure Cognitive S","tags":["search","paper"],"title":"Domain-Specific Pretraining for Vertical Search: Case Study on Biomedical Literatureという論文を読んだ"},{"contents":"今年もMICESにも参加してました。 昨年はBerlin Buzzwordsと共同開催でしたが、今年は別開催(別日程)でした。\nMICESは2017年から始まったe-commerceの検索にフォーカスしたカンファレンスです。 ECに関連する話に特化されていますが、話題は多岐にわたっています。色々やることありますねぇ、ECも。\n参加したセッション 参加したセッションの個人メモを今回も残しておきます。 セッション個別のリンクは用意されていないみたいですが、公式サイトにタイムテーブルがあり、セッションのタイトル、概要に加えて、スライドのPDFもリンクがあります。動画が公開されているものもあります。\nDreaming Search ビデオが公開されています。スライドがざっくりしたものなので最初に聞いた時にはしっくりこなかったので、聞き直してのメモです。 GDPRのような話で、個人の情報を自分たちで管理しようと流れがあります。 それぞれのECサイトなどでのユーザーのイベント(何を検索して、何をクリックした)情報はそれぞれのサイトで閉じた情報になっています。このため、自分の興味のある情報が断片化された情報でそれぞれのサイトで管理されてしまい、パーソナライゼーションされるもの(ランキングだったりレコメンドだったり)がいまいちな場合があります。 この個人の情報(ユーザーのイベント)をユーザー自身がハンドリングして、どの情報までをどこまで公開できるようにするというように管理できる仕組みができないか?という話のようでした。実際にそのための仕組み(もっと大きな話の仕様)を検討しているプロジェクトがあり、それに関連して検索という観点で夢を語っているセッションです。\nざっくり私が理解したのをまとめましたが、empathy.coという会社としてはいくつかPoCなども実施されているようでした。 個人の情報の扱い方に関する話は新鮮で面白かったです。 仕組みが出来上がり、各サイトが対応するとより個人が欲しい情報が集まりやすくなるのかなぁ?\nForget Facets, welcome Refinements (TM) Berlin BuzzwordsでいくつかLTをやられていた方によるファセットとその応用(彼らはRefinementsと名前をつけたみたい)についての話でした(ビデオとスライドが公開済み。)。 検索エンジンとファセットの関係の歴史から始まって、Kibanaでの使い方、モバイルや音声検索・チャットボットでのファセットは難しいよね?という話につながります。 ということで、Refinementsとして、ファセットを提示してユーザーに選んでもらうだけでなく状況に応じて、提案するための情報としてファセットを使うといいのでは?という話でした。例えば、チャットボットや音声検索での結果の場合、検索結果数が多くなるとユーザーが望んだものが返せるとは限らないです。その時に、ファセットの情報をもとに絞り込み条件を聞き返すネタに使うのはどうか?というような話でした。オートサジェスト(検索があいまいな時に、追加のキーワードを提案するもの)のような形でブランド名だったり、カテゴリーなどを表示する仕組みです。 実際の実装の話は、彼らが過去にBerlin Buzzwordsなどで話をしているのでそちらが参考になるとのことでした(参考:berlin buzzwords 2019 / Heystack 2019)\nReinforcement learning in search 検索における強化学習の話みたいです。ビデオとスライドが公開されています。ビジネス的に検索のランキングが重要だが、そのランキングをどうやって良くしていくのか?という話です。 ランキングでデフォルトのBM25から始まり、LtRを導入し、A/Bテストなどをしつつ、モデルの変化がどのようにビジネスに影響するかをはかるのが難しくなります。 LtRに対するオンライン機械学習のアプローチについて実際に直面した課題の話などがされている(はず?)です(どうも、実際にCTRなどを用いたところまでは行ってなさそう)。\n多腕バンディットなどの強化学習の話が続いたあたりでギブアップしてしまいました。。。\nBetter Search through Query Understanding - Panel Query Understandingに関するパネルとして3社の人がそれぞれどういった取り組みをしてるか?という話をしたあと質問などに答えていく形式でした。残念ながらビデオはまだ公開されていませんが、スライドが公開されています。QA部分も結構な時間だったのでビデオの公開がされるといいなぁ。\nUnderstanding queries by analysing user interaction / Andrea Schütt (OTTO) OTTOというECサイトでのQuery Understandingの紹介と、LtR導入にまつわる話。 データサイエンスとして最初はQuery Understandingやってたけど、スケールしないのでLtR導入して色々と試行錯誤しているところのようだった。\nQuery Understanding AI search eBayの方の発表。Query Understanding = ユーザーの興味をクエリから類推するという定義から、クエリを分類する、同定するためにどうしているか?という話でっした。 単語の表面的な文字としての近さだけでは、語順が変わると意味が変わるものや、ステミングのせいで同じになってしまうものといった例を紹介しつつ、クエリをベクトルにして表現(コンバージョン、クリックなどの情報を元にプロダクトのベクトルにしてみたり)し似ているかどうか?を判断している話です。\nCase study : Autocomplete Search Suggestions Digitec Galaxusというサイトでのオートコンプリートをもっと使いやすくするためにどんなデータを集めて、どうやって表示しているか?という話でした。 とりあえず入力されたものにヒットしたものを出すような実装だった場合に、サジェストされる量が多く、ノイズも多いので使いにくかったものをどうやって改善して行ったかという処理の流れなどの説明もありました。\nThe need for an open web search in Europe - The approach of the Open Search Foundation and its implications for E-Commerce-Companies Speaker: Alexander Decker / OPEN SEARCH FOUNDATION\nもっとオープンな検索システムを作っていこうという団体の話でした。 AWSが最近1.0をリリースしたやつとは別物です。 Googleでみんな検索しているけど、ブラックボックスなのでバイアスがかかっている。 もっとバイアスフリーなインデックスを提供できると、使いやすくなるよね?みんなでそういうインデックスを作っていかないか?という話でした。 ECとの直接の関係はセッションからは読み取れませんでした。 どうやって、集めるデータの基準(入れるべき、入れるべきではないなど)を作るんだろう?という疑問が残っています。公共的なものやオープンデータについてはあるとよさそうかもなぁ。\n101 hints to improving the customer satisfaction on search engines in the retail industry Speaker: Marion Hemery (Carrefour France) \u0026amp; Lucian Precup (a// \u0026amp; Adelean)\nカルフールのECサイトでの検索に関する顧客満足度の改善についての話です。 どんなものをどうやって図るのか、フィードバックを取るための仕組みは? そこからわかったものをどうやってシステムに優先度をつけながら取り込んでいくのか? というのをどんなものを使っているかという説明を交えながらのセッションです。 スライドが結構細かく書かれているのでスライドを見るだけでもわかりやすいかな。\n“An ounce of prevention is worth a pound of cure”: establishing a gold standard-based evaluation in customer projects Speaker: Bertram Sändig \u0026amp; Cornelia Werk / NEOFONIE\n検索の性能指標(速度ではないほうの性能)をきちんと評価する仕組みが重要だよというセッションです。 検索の仕組みを変更(例ではステミングを導入するはなしをしてました)した場合に、現行システムにどういう影響が出るのか?それをどうやって図るのか、どうやってテストしていくのか?という話です。 ステミングを導入したら、検索にヒットしやすくなったものも出てきたけどその弊害として今までよかった検索の結果にノイズが増え多という話をもとに、検索結果としてこうあってほしいというゴールデンスタンダードをきちんと作って育てていくべきですよという話でした。完ぺきなものなどないので少しずつやっていきましょうと。\nということで、見ていないもの(LTや最後のワークショップ)もありますが、見たものに関してメモを残してみました。\n","date":1626160103,"dir":"post/2021/","id":"10a7f69bd03d2632722300194f01e93d","lang":"ja","lastmod":1626160103,"permalink":"https://blog.johtani.info/blog/2021/07/13/attend-mices-2021/","publishdate":"2021-07-13T16:08:23+09:00","summary":"今年もMICESにも参加してました。 昨年はBerlin Buzzwordsと共同開催でしたが、今年は別開催(別日程)でした。 MICESは201","tags":["conference","berlin buzzwords","MICES"],"title":"今年もMICESにオンライン出張してた"},{"contents":"今年もBerlin Buzzwordsにオンライン出張してました。 今年の開催は6月14日から17日まででした。 どんなカンファレンスなのかは昨年のブログ記事をごらんください。\n今年はHAYSTACKは共同開催で、MICESは別開催でした。 MICESにも参加していたので、また後日にブログ記事を公開する予定です。\n参加したセッション 参加したセッションの個人用のメモを取ってあるので、簡単にまとめておきます。 セッションページに動画やスライドも追加されつつあります。興味のある方はそちらをご覧いただければと。 (今のところYouTubeに上がっているビデオは69本あります。再生リストはこちら) 気になっていたセッションもあるので、ビデオを見てまたメモを公開すると思いますが、まずは第1弾を。 ちなみに、検索をメインに見ています。Berlin Buzzwords自体はオブザバビリティやOSSコミュニティ、データのストリーミングの話などの話題もあるので、この辺りも興味があれば探してみても面白いかもです。\nHow to measure Diversity of Search Results セッションページ: How to measure Diversity of Search Results | Berlin Buzzwords 2021 従来の検索では、クエリに対して精度の高い検索結果を1件または数件返すのはどうするか?というものだったが、最近、あるユースケース(ほかの物の発見を促したいケース)では 検索結果の多様性を高めつつ、精度もある程度確保したいという場合があります。\nざっくりした検索クエリ(例えば自転車)の場合に、自転車だけが1ページ目にある場合よりも自転車とは別に自転車グッズも表示された場合のほうがクリック率やGMV(Gross Merchandice Value?)が上がったという話が紹介されていました。 この時どのくらい混ぜればいいのか?というのを、シャノンのエントロピーを使って、検索結果の多様性を保つための具体的なヒントについて話をされています。 実際にこういう計算をしてやれますねという紹介がされています。\nFrom text search and recommendation to ads and online dating; approximate nearest neighbors in real world applications セッションページ: From text search and recommendation to ads and online dating; approximate nearest neighbors in real world applications | Berlin Buzzwords 2021 Vespa.ai(OSS)の紹介でANNの話でした。通常、ANNを用いた検索の場合に他の検索条件(地理情報、日付など)をANNの結果に対して適用すると、望んでいる数がとれないです。その場合に、Vespaは内部でいい感じの動きをしますよという紹介でした。\n\u0026ldquo;Are You Sure?\u0026quot;: blending product comparisons and recommendations with A.I. セッションページ: \u0026ldquo;Are You Sure?\u0026quot;: blending product comparisons and recommendations with A.I. | Berlin Buzzwords 2021 Amazonの製品ページにある、類似商品との比較一覧のような一覧をどうやって実現するか?という話でした。比較一覧に掲載する商品を選出するパイプラインをこうやれますよね?という話でした。ログ(クリックやカートに入れたかどうかなど)を元にkNNで似ているデータを洗い出し、どの商品、どの項目を比較一覧として選ぶかという流れでした(セッションではもっと詳しい話がされています)。オフライン実験の話までがセッションでされています。\nThe future of Lucene\u0026rsquo;s MMapDirectory: Why use it and what\u0026rsquo;s coming with Java 16 and later? セッションページ: The future of Lucene\u0026rsquo;s MMapDirectory: Why use it and what\u0026rsquo;s coming with Java 16 and later? | Berlin Buzzwords 2021 Apache Lucene PMCのUweさんによるLuceneのMMapDirectoryの話です。 ファイルシステムとJavaに関する歴史と、なぜMMapなのか、現在のMMapの実装の問題点とJDK 16でどうなっているか(どんな感触か)、さらにその先(JDK17)は?という話です。 Luceneでの利用方法からJDKへのフィードバックが行われている話や、そのフィードバックをもとに今後どのようにしていくのか?という話がされています。\nSearch and Sushi; Freshness Counts セッションページ: Search and Sushi; Freshness Counts | Berlin Buzzwords 2021 こちらもVespa.aiの紹介です(今年はスポンサーしてるから多いのかも?)。Yahoo!とVerizon Mediaで利用している話をしたあと、Vespaでのリアルタイムインデキシングに関するアーキテクチャの紹介でした。内部で転置インデックスやそれ以外のデータをどのように保持しているのか?どういったことができるのか?というのをアーキテクチャ、ストレージの観点から紹介しています。\nEncores? - Going beyond matching and ranking of search results セッションページ(動画がまだない): Encores? - Going beyond matching and ranking of search results | Berlin Buzzwords 2021 検索のマッチングやランキング以外のいくつかの機能についての紹介をワークショップ形式で行うセッションです。ファセット、クエリオートコンプリート、スペル訂正、クエリリラクゼーションについて、データとSolrのクエリを基準に説明をしてくれます。\nThe Invasion of Transformers - Boosting Search with Latest NLP セッションページ: The Invasion of Transformers - Boosting Search with Latest NLP | Berlin Buzzwords 2021 deepsetという会社のCTOの方で、自社で作っているOSSのhaystackという製品の紹介です。 最近のGoogleの検索結果にはいろんなもの(問いかけに関する答えそのもの、またそのプレビューやサマリー)が出てきているという話から、Transformersを使って検索ができないかということで自社のOSSの仕組みを紹介しています。\n参考 Google: BERT now used on almost every English query deepset-ai/haystack: End-to-end Python framework for building natural language search interfaces to data. Leverages Transformers and the State-of-the-Art of NLP. Supports DPR, Elasticsearch, Hugging Face’s Hub, and much more! Learning to Judge セッションページ: Learning to Judge | Berlin Buzzwords 2021 otto.deというECサイトでLtRを導入し、そのLtRにどんな特徴を利用しどうやって実験したかというセッションでした。Apache Solrで検索ができていて、これまでは検索の管理を人手で行っていたがスケールしない(扱う商品などは増えているのに)のでLtRを導入し始めたという感じでした。LtRの導入の過程でどういう仮定を置いて、どうモデルを決め、それをどうやってテストしてどう分析したか?という流れでした。\nText categorization with Apache Lucene セッションページ: Text categorization with Apache Lucene | Berlin Buzzwords 2021 LTなので短めです。BBCのデータセットをインデックスに登録し、そのデータをもとにLucene(デモではKibana+Esを利用していた)でテキスト分類を行なう方法について紹介しています。BBCのデータセットは記事(テキスト)とカテゴリ(タグ)というデータです。 このデータが登録されているインデックスに対して、More Like Thisクエリに分類したい文章を与え、ヒットしたデータをもとにAggregationでカテゴリを取得し、上位のカテゴリが分類された結果になるというデモでした。 テキストフィールドにはEdge N-Gramを利用していること、Aggregationのソートの条件はMore Like Thisクエリでのスコアの平均を利用していることというのがこの方法がうまくいくことのようでした(なるほど!)。ただ、日本語でもこれが使えるかな?というのはやってみないとわからないかなぁと(やってないです)。\nとりあえず、メモしておいたのはこの辺でした。 他にもセッション一覧を眺めながら面白そうな話をピックアップしてメモを取っていこうかなぁ?気になるセッション、メモがおかしいなどあればコメントいただければと。\n","date":1625815493,"dir":"post/2021/","id":"59b7b60e6bbf4858d72643d22ad90451","lang":"ja","lastmod":1625815493,"permalink":"https://blog.johtani.info/blog/2021/07/09/berlin-buzzwords-2021-1/","publishdate":"2021-07-09T16:24:53+09:00","summary":"今年もBerlin Buzzwordsにオンライン出張してました。 今年の開催は6月14日から17日まででした。 どんなカンファレンスなのかは昨年","tags":["conference","berlin buzzwords"],"title":"今年もBerlin Buzzwordsにオンライン出張してた"},{"contents":"Azure Cognitive Searchで新機能「Semantic Search(セマンティック検索)」という機能の日本語対応が発表されました。 実際にはPublic Previewという状態ではありますが、どんな機能か気になったので調べてみました。 なお、本ブログは2021年6月時点での内容となります。\n公式ドキュメント 公式ドキュメントでいろいろと説明されています。まずは公式ドキュメントを見ていただくのが良いかなと。最初のドキュメントには10分ちょっとの紹介ビデオもあります。ピックアップしたのは概要、クエリ、レスポンスの構造、紹介ブログになります。ブログ以外は日本語(たぶん機械翻訳?)になっています(新機能の紹介の日本語ページにはまだ記載がありません)。\nSemantic search - Azure Cognitive Search | Microsoft Docs Create a semantic query - Azure Cognitive Search | Microsoft Docs Structure a semantic response - Azure Cognitive Search | Microsoft Docs The science behind semantic search: How AI from Bing is powering Azure Cognitive Search - Microsoft Research 簡単にですがデータを入れて試してみたので、どんな仕組みなのかどういう挙動なのかを紹介します。\nSemantic Searchとは? 言語理解、セマンティック関連性などを提供する機能です。BingとMSリサーチにより開発されて、Azure Cognitive Searchに導入されました。 クエリの書き方を少し変更する必要がありますが、再インデックスや設定変更などは必要ないという仕組みになっています。\n検索クエリからコンテキストを読み取って、検索し、リランクするアルゴリズム(Semantic Ranker) 関連する一節を強調表示(Semantic Caption) クエリに対するセマンティック回答(Semantic Answer) スペルチェック機能 言語によって利用できる機能が異なります。\nSemantic Searchの利点は先ほどの紹介にも書きましたが、インデキシング時に特殊処理をする必要がないことかなと。 すでに登録してあるデータ(制限がありますが)でもすぐに試すことができます。\n仕組み https://docs.microsoft.com/ja-jp/azure/search/media/semantic-search-overview/semantic-query-architecture.png\nスペル修正機能 クエリパース スコアリング 上位50件に対してSemantic Rankerにより再評価(検索ヒットが50件以上の場合でも上位50件のみがリランクの対象) 言語表現モデルを利用 結果の要約として最適な部分をキャプションとして抽出。 クエリが質問形式の場合は一番よさそうな場所を回答として選択 1および4番目の処理が今回新しく使えるSemantic Searchの機能になります。スペルチェックは日本語がまだ対象外なので、4番目の機能について紹介します。\n利用できる環境と制限 冒頭でも書きましたが、Public Previewの段階です。実際に利用するにはリクエストページから申し込みが必要になっています。\n利用リクエスト時に利用するAzure Cognitive Searchのサービス名が必要になるので、あらかじめ起動しておかなければいけません。 また、利用できるリージョンが限定されているのでサービス起動時のリージョンには気を付けてください。\n利用できるリージョン 米国中北部、米国西部、米国西部 2、米国東部 2、北ヨーロッパ、西ヨーロッパ 利用できるTier セマンティック検索はStandardレベル スペルチェックはレベル制限なし 価格(セマンティック検索のみ) 7月初旬までは25万クエリで500ドル Analyzerの制限 Azure Cognitive Searchが提供する言語アナライザーが対象(Custom Analyzerでは利用不可) サービス起動後にプレビュープログラムを申請すると、利用できるようになるとメールが届きます。そこから利用ができるようになります。\n今回は日本語のWikipediaのデータをいれてどんな機能なのかを確認してみました。\nWikipediaのデータを入れて試してみた 日本語のWikipedia(あとで英語も入れました)を一部(10万件程度)登録してSemantic Search(主にRanker)の動きを確認してみました。\nデータの登録には自作ツールを利用。\nJSONデータ生成ツール:https://github.com/johtani/wiki-extractor-rs JSONデータ登録ツール:https://github.com/johtani/wiki-json-loader 日本語Wikipediaの2020年6月のデータ、英語Wikipediaの2021年6月のデータを利用。上記ツールで生成したもののうち約10万件をAzure Cognitive Searchに登録して動作確認をしました(英語のデータでJSONデータ生成ツールでバグがあるのですが修正していません。。。)。 また、クエリの実行にはVisual Studio CodeのREST Client拡張(どんなものかは以前のブログをご覧ください)を使いました。簡単にREST APIを呼び出せるのはすばらしい。\n日本語のWikipedia 日本語のWikipediaのデータを「96,344件」登録し実験しました。 スキーマは次のような形です(説明に必要なものだけ抽出してあります)。自然分が入っているtitle、contents、headingsの3つのフィールドを今回はSemantic Searchの対象にしてみるので、AnalyzerをLuceneベースの日本語Analyzerであるja.luceneを設定しました。\nフィールド名 : タイプ / Analyzer id : Edm.String / keyword categories : Collection(Edm.String) / keyword title : Edm.String / ja.lucene contents : Edm.String / ja.lucene headings : Edm.String / ja.lucene Analyzerに言語Analyzerを設定するくらいで、他の設定は特に必要ありません。\nクエリとデータの確認 デモの動画や説明のサンプルを見たところ英語で「Where was Alan Turing born?」や「What\u0026rsquo;s the capital of France?」のような自然文のクエリが出てきたので、次のようなクエリで試してみました。\nフランスの首都はどこですか? 実際にパリのページがインデックスに存在していることは以下のクエリで確認しました。\nパリ:3047件 POST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;パリ\u0026#34;, \u0026#34;top\u0026#34;: 10, \u0026#34;searchFields\u0026#34;: \u0026#34;title, categories, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id, contents\u0026#34; } ※ここで{{host}}などはREST Client拡張で変数として定義したものです。\nhost : Azure Cognitive Searchのサービス名 index-name : インデックス名 api-key : 接続のためのAPIキー URLパラメータのapi-version=2020-06-30-PreviewがPreview機能を呼び出すための指定になっています。\n3047件の1件目が「パリ」のページで以下のようなWikipediaの文章をセクションごとに文字列としてページ全体を配列に入れてcontentsに登録してあります。\n\u0026#34;パリ(、巴里)は、フランス北部、イル=ド=フランス地域圏にある都市。フランスの首都であり、イル=ド=フランス地域圏の首府である。\\nフランス最大の都市であり、同国の政治、経済、文化などの中心である。ロンドンと共に欧州を代表する世界都市。行政上では、1コミューン単独で県を構成する特別市であり、ルーヴル美術館を含む1区を中心に、時計回りに20の行政区が並ぶ(エスカルゴと形容される)。\u0026#34;, このインデックスに対して「フランスの首都はどこですか?」というクエリを、セマンティック検索のクエリと通常のクエリの2パターンで検索をしてみました。\nこれまでのクエリ(セマンティックではない検索) まずは通常のクエリです。 searchがクエリ文字列、searchFieldsが検索対象フィールドになります。\nPOST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;top\u0026#34;: 100, \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;フランスの首都はどこですか?\u0026#34;, \u0026#34;searchFields\u0026#34;: \u0026#34;title, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id\u0026#34; } クエリを実行するとヒット件数が'13996\u0026rsquo;件で、トップ5件のデータは次のようになりました。\n\u0026#34;@odata.count\u0026#34;: 13996, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 17.059355, \u0026#34;id\u0026#34;: \u0026#34;462\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;首都\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 16.086372, \u0026#34;id\u0026#34;: \u0026#34;21053\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;首都圏\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 15.059893, \u0026#34;id\u0026#34;: \u0026#34;71414\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;どこでもドア\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 14.086605, \u0026#34;id\u0026#34;: \u0026#34;51972\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;首都機能移転\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.996841, \u0026#34;id\u0026#34;: \u0026#34;3877\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;首都の一覧\u0026#34; }, 見るとわかりますが、「首都」「どこ」といった単語を含むデータが上位に入っています。「フランス」を含むデータは8件目と10件目に「フランス植民地帝国」、「ラ・フランス」といったデータが出てきます。\n{ \u0026#34;@search.score\u0026#34;: 12.705561, \u0026#34;id\u0026#34;: \u0026#34;129279\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;フランス植民地帝国\u0026#34; }, ... { \u0026#34;@search.score\u0026#34;: 12.036648, \u0026#34;id\u0026#34;: \u0026#34;3173\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ラ・フランス\u0026#34; }, 残念ながら望んでいる結果にはほど遠いかと。\nどんな検索になっているのでしょうか?まずは、クエリの解釈から。 デフォルトで、Azure Cognitive Searchはデフォルトでは、入力された文字列をtype=simple、mode=anyで検索します(クエリパラメータ参照)。 対象となるフィールドはsearchFieldsで今回は指定してあるので、これらのフィールドに対して、入力された文字列を渡してAnalyzerで単語分割し(今回はsimpleクエリ用の特殊文字が入っていないため文字列として扱われる)、 出てきた単語で(mode=anyだから)OR検索します。 ja.luceneのAnalyzerが出力する単語列がどんなものかは以下のリクエストを実行するとわかります。\nPOST https://{{host}}/indexes/{{index-name}}/analyze?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;analyzer\u0026#34;:\u0026#34;ja.lucene\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;フランスの首都はどこですか?\u0026#34; } 結果は以下の通りです。\n\u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;フランス\u0026#34;, \u0026#34;startOffset\u0026#34;: 0, \u0026#34;endOffset\u0026#34;: 4, \u0026#34;position\u0026#34;: 0 }, { \u0026#34;token\u0026#34;: \u0026#34;首都\u0026#34;, \u0026#34;startOffset\u0026#34;: 5, \u0026#34;endOffset\u0026#34;: 7, \u0026#34;position\u0026#34;: 2 }, { \u0026#34;token\u0026#34;: \u0026#34;どこ\u0026#34;, \u0026#34;startOffset\u0026#34;: 8, \u0026#34;endOffset\u0026#34;: 10, \u0026#34;position\u0026#34;: 4 } ] これで、どのような単語が出てきているかがわかりました。 それぞれのフィールドでどのようなスコアになっているかまではわからないですが、検索結果には上記3つの単語のいずれかがsearchFieldsにヒットすれば出てきます。おそらく、ヒットした単語数が多い、短い文字列のフィールドがより高いスコアになるというような動きになっていると思われます(BM25になってるはず)。\nセマンティック検索 では、セマンティック検索のクエリに変更してみましょう。\nPOST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;top\u0026#34;: 100, \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;フランスの首都はどこですか?\u0026#34;, \u0026#34;searchFields\u0026#34;: \u0026#34;title, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id\u0026#34;, \u0026#34;queryType\u0026#34;: \u0026#34;semantic\u0026#34;, \u0026#34;queryLanguage\u0026#34;: \u0026#34;ja-jp\u0026#34; } queryType、queryLanguageがセマンティック検索のクエリを実行するためのパラメータになります(公式ガイド参照)。 今回は日本語のデータであるため、日本語のモデルを利用するようにqueryLanguageを指定します(許可されていない文字列を渡すとエラーになる)。 この2つを追加するだけです。簡単ですね。\n結果は次のようになります(上位5件抜粋)。\n\u0026#34;@odata.count\u0026#34;: 13996, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 12.036648, \u0026#34;@search.rerankerScore\u0026#34;: 2.3456064984202385, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;ラ・フランス\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;ラ・フランス\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;3173\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ラ・フランス\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 11.144733, \u0026#34;@search.rerankerScore\u0026#34;: 2.3173404783010483, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;ラン (フランス)\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;ラン\u0026lt;/em\u0026gt; (\u0026lt;em\u0026gt;フランス)\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;108094\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ラン (フランス)\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 11.144793, \u0026#34;@search.rerankerScore\u0026#34;: 2.1937477812170982, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;ブレスト (フランス)\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;ブレスト\u0026lt;/em\u0026gt; (\u0026lt;em\u0026gt;フランス)\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;116154\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ブレスト (フランス)\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 10.199907, \u0026#34;@search.rerankerScore\u0026#34;: 2.1590753793716431, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;フランス・ハルス\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;フランス・ハルス\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;81566\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;フランス・ハルス\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 11.273148, \u0026#34;@search.rerankerScore\u0026#34;: 2.1434053033590317, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;バカロレア (フランス)\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;バカロレア\u0026lt;/em\u0026gt; (\u0026lt;em\u0026gt;フランス\u0026lt;/em\u0026gt;)\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;54514\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;バカロレア (フランス)\u0026#34; }, 検索結果数を見ると、通常のクエリと同じ値です。 これは、公式ドキュメントのセマンティック検索に説明があるように、 セマンティック検索が通常のクエリで実行した後の検索結果に対して、上位50件のデータだけに対してsemantic rankerによってスコアを再計算するという仕様のためです(ドキュメントからの推測)。\n実際に検索結果の50件目、51件目は次のようになっていました。50件目までのデータには@search.rerankerScoreというスコア(と@search.captions)が追加されています。 51件目のデータについては、前の通常のクエリの51件目のデータと同じデータでした。\n{ \u0026#34;@search.score\u0026#34;: 10.909212, \u0026#34;@search.rerankerScore\u0026#34;: 0.07321979058906436, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;首都高速埼玉大宮線\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;67667\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;首都高速埼玉大宮線\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 10.049902, \u0026#34;id\u0026#34;: \u0026#34;68569\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;スタッド・ド・フランス\u0026#34; }, 上位5件のデータに戻ります。 これらは、通常のクエリとは異なる結果となりました。 見ると@search.captionsというところにハイライトされた項目が表示されています。 検索クエリをもとにそれっぽい部分がキャプションという形で返ってくる仕組みです。\n結果を見るとわかりますが、残念ながら「パリ」のページは返ってきませんでした。 もともと通常のクエリを実行したときの「326」番目の結果として返ってきているため、セマンティック検索の対象とはならなかったためです。 ただ、「首都」「どこ」といった単語よりも「フランス」に関するドキュメントが通常の検索よりも上位に来ています。 クエリに存在する単語で「フランス」がより重要であると判断されているようです。\nSemantic Rankerに処理させてみる ちなみに、今回登録したデータにはWikipediaのカテゴリも登録してあります。 「ヨーロッパの首都」というカテゴリで絞り込んでから検索してみるとどうなるかもやってみました。 filterのパラメータが絞り込み条件です。\nPOST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;top\u0026#34;: 100, \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;フランスの首都はどこですか?\u0026#34;, \u0026#34;searchFields\u0026#34;: \u0026#34;title, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id\u0026#34;, \u0026#34;queryType\u0026#34;: \u0026#34;semantic\u0026#34;, \u0026#34;queryLanguage\u0026#34;: \u0026#34;ja-jp\u0026#34;, \u0026#34;filter\u0026#34;: \u0026#34;search.ismatch(\u0026#39;ヨーロッパの首都\u0026#39;, \u0026#39;categories\u0026#39;)\u0026#34; } 結果は次の通りです。カテゴリで絞り込みをしているので検索結果数は39件となります。このため、すべてのデータがSemantic Rankerの対象です。 ですが、「パリ」のページは11件目に出てきました。\n\u0026#34;@odata.count\u0026#34;: 39, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 3.8405614, \u0026#34;@search.rerankerScore\u0026#34;: 2.0472740978002548, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;ウィーン\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;9465\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ウィーン\u0026#34; }, ... { \u0026#34;@search.score\u0026#34;: 4.8915977, \u0026#34;@search.rerankerScore\u0026#34;: 1.8480307757854462, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;レイキャヴィーク\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;レイキャヴィーク\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;112253\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;レイキャヴィーク\u0026#34; }, ... { \u0026#34;@search.score\u0026#34;: 7.277628, \u0026#34;@search.rerankerScore\u0026#34;: 1.7982495501637459, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;パリ\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;パリ\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;31\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;パリ\u0026#34; }, キャプションは入力された単語だけではなく、クエリが持っている単語をもとにした何かしらの基準(おそらく言語モデルで近い単語?)で選択されていると思われます。首都というカテゴリーで絞り込んでしまったので、ヒットした文章が似たようなものが多くなったせいか、残念ながらそこまでSemantic Rankerが意図を汲み取るところまでは行きませんでした。\nフランスの歴史 視点を変えてみましょう。質問そのものの答えではなく、クエリの意図に近いものが出てくるかを見てみましょう。 ここまでのクエリでフランスに関するクエリを投げていました。今回のインデックスに「フランスの歴史」で検索すると「30820」件のドキュメントがヒットし、上位にはフランスには関係ない「歴史」のページや「フランス」の文学、都市など「フランスの歴史」とは少し離れた意味のものが上位に来ています。\n\u0026#34;@odata.count\u0026#34;: 30820, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 12.888079, \u0026#34;id\u0026#34;: \u0026#34;17875\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;スコットランドの歴史\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.718105, \u0026#34;id\u0026#34;: \u0026#34;10665\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;世界の歴史\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.701981, \u0026#34;id\u0026#34;: \u0026#34;31397\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ベトナムの歴史\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.579847, \u0026#34;id\u0026#34;: \u0026#34;22433\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;フランス文学\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.524254, \u0026#34;id\u0026#34;: \u0026#34;34667\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;フランスの国旗\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.52136, \u0026#34;id\u0026#34;: \u0026#34;108094\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ラン (フランス)\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.41088, \u0026#34;id\u0026#34;: \u0026#34;20717\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;歴史小説\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.388911, \u0026#34;id\u0026#34;: \u0026#34;56229\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;演劇の歴史\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.343941, \u0026#34;id\u0026#34;: \u0026#34;39669\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;イギリスの歴史\u0026#34; }, このクエリをセマンティッククエリで検索すると次のようになりました。\n\u0026#34;@odata.count\u0026#34;: 30820, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 12.274498, \u0026#34;@search.rerankerScore\u0026#34;: 1.482184374704957, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;自由フランス\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;自由フランス\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;96475\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;自由フランス\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 11.446766, \u0026#34;@search.rerankerScore\u0026#34;: 1.3535655084997416, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;フランスの地域圏\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;フランスの地域圏\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;51845\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;フランスの地域圏\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 10.926437, \u0026#34;@search.rerankerScore\u0026#34;: 1.3261859538033605, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;フランス第一帝政\u0026#34;, \u0026#34;highlights\u0026#34;: \u0026#34;\u0026lt;em\u0026gt;フランス第一帝政\u0026lt;/em\u0026gt;\u0026#34; } ], \u0026#34;id\u0026#34;: \u0026#34;57573\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;フランス第一帝政\u0026#34; }, 上位には「フランスの歴史」に関連しそうなタイトルが上がってきています。 また、先ほど「歴史」という単語でヒットして上位に来ていた「スコットランドの歴史」は@search.rerankerScoreの値が低くなっていました(31件目に出現)。\n{ \u0026#34;@search.score\u0026#34;: 12.888079, \u0026#34;@search.rerankerScore\u0026#34;: 0.42768346797674894, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;スコットランドの歴史\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;17875\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;スコットランドの歴史\u0026#34; }, 考察 日本語のWikipediaを約10万件入れたインデックスでセマンティック検索を試してみました。 デモや説明などでクエリが自然文の質問だったこともあり、質問の回答になりそうなページが上に来るかと期待しましたが、期待しすぎました。\nこれは、Azure Cognitive Searchのセマンティック検索の仕組みを考えると納得のいくものです。 説明を読んだ時にも感じたのですが、入力された文字列でまず検索をし、上位50件をセマンティック検索の対象としています。\nですので、そもそもクエリの文章に出てくる単語が含まれたデータだけが対象となります。 このため、クエリに出てこない単語のみで構成されているものは残念ながら対象とできません。 また、上位50件だけがSemantic Rankerの対象となっているため、検索にヒットしたとしても上位に食い込まなければ言語モデルによるランキングの対象にもなりません。 セマンティック検索といっても、残念ながらドキュメントに出てこない単語(似た単語、質問に対するそのものの回答)まで読み取る機能はありません。\nただ、「フランスの歴史」の検索で見たようにそれぞれの単語だけで検索をしていた場合とは異なり、 クエリの意味に沿ったスコアづけにより、通常の検索よりも意図したものに近いデータが出ていることが確認できました。 複数の単語で構成されるクエリの場合に、単語だけでスコアを計算した場合よりもよさそうな結果が上位に出てくることがわかりました。\nただし、重要なのは「上位50件」までしかSemantic Rankerの対象にはならない点です。\n英語のWikipedia セマンティックは英語対応が一番最初にリリースされているので、英語のWikipediaについてもデータを登録してみました。\n英語のWikipediaのデータを「111,649件」登録しました。 スキーマは以下の通り(今回の調査に利用していないものは省略)です。日本語と異なる点はAnalyzerがen.luceneになっていることぐらいです。\nフィールド名 : タイプ / Analyzer id : Edm.String / keyword categories : Collection(Edm.String) / keyword title : Edm.String / en.lucene contents : Edm.String / en.lucene headings : Edm.String / en.lucene クエリとデータの確認 日本語同様に首都に関する質問形式にしてみました。\nWhat\u0026rsquo;s the capital of Italy? 実際にRomeのページがインデックスに存在していることは以下のクエリで確認済みです。\nRome:2302件\nPOST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;Rome\u0026#34;, \u0026#34;top\u0026#34;: 10, \u0026#34;searchFields\u0026#34;: \u0026#34;title, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id, contents\u0026#34; } 以下のようなWikipediaの文章をセクションごとに文字列としてページ全体を配列に入れてcontentsに登録してあります(これも日本語と同じです)。\n\u0026#34;\u0026#34;\\n\\nRome (Italian and Latin: Roma ) is the capital city and a special comune of Italy (named Comune di Roma Capitale), as well as the capital of the Lazio region. The city has been a major human settlement for almost three millennia. With 2,860,009 residents in , it is also the country\u0026#39;s most populated comune...\u0026#34;, このデータ群に対して「What\u0026rsquo;s the capital of Italy?」というクエリを、Semantic Searchのクエリと通常のクエリの2パターンで検索をしてみる。\nこれまでのクエリ(セマンティックではない検索) まずは、Semantic Searchではないクエリです。\nPOST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;top\u0026#34;: 100, \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;What\u0026#39;s the capital of Italy?\u0026#34;, \u0026#34;searchFields\u0026#34;: \u0026#34;title, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id\u0026#34; } ヒット件数は18049件で、トップ5件は次のような形です。\n\u0026#34;@odata.count\u0026#34;: 18049, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 17.870815, \u0026#34;id\u0026#34;: \u0026#34;14532\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Italy\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 16.596167, \u0026#34;id\u0026#34;: \u0026#34;14702\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Economy of Italy\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 16.180624, \u0026#34;id\u0026#34;: \u0026#34;183878\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Louis II of Italy\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 15.917025, \u0026#34;id\u0026#34;: \u0026#34;29665\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;State capitalism\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 15.88901, \u0026#34;id\u0026#34;: \u0026#34;215741\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Capitalization\u0026#34; }, 日本語の場合よりもItalyに関連するものが上位に多く含まれます。 ただ、Rome自体のページは上位50件には出てきていませんでした。 また、capitalとは意味の異なるcapitalizationやcapitalismが上位に来ています。 日本語の場合と同様にクエリがどのように解釈されているのか?も見てみます。\nPOST https://{{host}}/indexes/{{index-name}}/analyze?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;analyzer\u0026#34;:\u0026#34;en.lucene\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;What\u0026#39;s the capital of Italy?\u0026#34; } 結果は以下の通りです。\n\u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;what\u0026#34;, \u0026#34;startOffset\u0026#34;: 0, \u0026#34;endOffset\u0026#34;: 6, \u0026#34;position\u0026#34;: 0 }, { \u0026#34;token\u0026#34;: \u0026#34;capit\u0026#34;, \u0026#34;startOffset\u0026#34;: 11, \u0026#34;endOffset\u0026#34;: 18, \u0026#34;position\u0026#34;: 2 }, { \u0026#34;token\u0026#34;: \u0026#34;itali\u0026#34;, \u0026#34;startOffset\u0026#34;: 22, \u0026#34;endOffset\u0026#34;: 27, \u0026#34;position\u0026#34;: 4 } ] 日本語とあまり変わってはいません。ただ、単語が入力されたものとは少し変わっています。 これは、en.luceneの処理で、stemmingが行われているためだと思われます。たとえば、「capital」の場合、Stemmingにより「capital」「capitalize」などの単語が元になりますが、動詞、名詞などの違いなく検索できるようにするためにこのようなStemmingの処理が行われます。 ということで、これらの単語を含むドキュメントがヒットしています。Italyが一番上に来ているのはItalyという単語が多く含まれるからのようです。\nSemantic Searchクエリ では、Semantic Searchのクエリに変更してみましょう。\nPOST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;top\u0026#34;: 100, \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;What\u0026#39;s the capital of Italy?\u0026#34;, \u0026#34;searchFields\u0026#34;: \u0026#34;title, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id\u0026#34;, \u0026#34;queryType\u0026#34;: \u0026#34;semantic\u0026#34;, \u0026#34;queryLanguage\u0026#34;: \u0026#34;en_us\u0026#34; } queryType、queryLanguageがsemantic searchのクエリを実行するためのパラメータになります(公式ガイド参照)。 今回は英語のデータであるため、英語のモデルを利用するようにqueryLanguageを指定します(許可されていない文字列を渡すとエラーになる)。\n結果は次のようになります(上位5件抜粋)。\n\u0026#34;@odata.count\u0026#34;: 18049, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 17.870815, \u0026#34;@search.rerankerScore\u0026#34;: 1.9688458815217018, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Italy\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;14532\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Italy\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 14.239678, \u0026#34;@search.rerankerScore\u0026#34;: 1.9419755563139915, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Capital city\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;181337\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Capital city\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 10.181764, \u0026#34;@search.rerankerScore\u0026#34;: 1.8902588561177254, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Lepontii\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;325133\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Lepontii\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 10.865718, \u0026#34;@search.rerankerScore\u0026#34;: 1.875102698802948, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;ItalY\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;14482\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;ItalY\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 11.689348, \u0026#34;@search.rerankerScore\u0026#34;: 1.8201303631067276, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Savoy\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;27885\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Savoy\u0026#34; }, 日本語で見てきたように、検索結果数を見ると、通常のクエリと同じ値で、残念ながら50件までにRomeは入っていないため、Semantic Rankerによるブーストもかかりませんでした。 ただし、「Capitalization」や「State capitalism」といった別の意味(地理に関するものではない単語)のものが上位に出てこなくなっています。 これは、capitalという単語が地理に関する意味を持っていると判断された結果のように見えます。 Capitalizationの@search.rerankerScoreは上位のスコアに比べて小さいものとなっています。\n{ \u0026#34;@search.score\u0026#34;: 15.88901, \u0026#34;@search.rerankerScore\u0026#34;: 0.93921028636395931, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Capitalization\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;215741\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Capitalization\u0026#34; }, What\u0026rsquo;s the capital of Finland? 上位50件以内(20件目)に「Helsinki」のページが出てくるクエリでセマンティック検索をしてみました。\nPOST https://{{host}}/indexes/{{index-name}}/docs/search?api-version=2020-06-30-Preview Content-Type: application/json api-key: {{api-key}} { \u0026#34;top\u0026#34;: 100, \u0026#34;count\u0026#34;: true, \u0026#34;search\u0026#34;: \u0026#34;What\u0026#39;s the captial of Finland?\u0026#34;, \u0026#34;searchFields\u0026#34;: \u0026#34;title, contents\u0026#34;, \u0026#34;select\u0026#34;: \u0026#34;title, id\u0026#34;, \u0026#34;queryType\u0026#34;: \u0026#34;semantic\u0026#34;, \u0026#34;queryLanguage\u0026#34;: \u0026#34;en-us\u0026#34; } 結果としては、2件目にHelsinkiが返ってきていたので、Semantic Rankerがによる並び替えがうまくいきました。 (下記の結果は上位3件を抜粋したものです)。\n\u0026#34;@odata.count\u0026#34;: 16673, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.score\u0026#34;: 14.026371, \u0026#34;@search.rerankerScore\u0026#34;: 2.42378556355834, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Vanaja (Finland)\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;7132102\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Vanaja (Finland)\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 12.434971, \u0026#34;@search.rerankerScore\u0026#34;: 2.383675143122673, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Helsinki\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;13696\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Helsinki\u0026#34; }, { \u0026#34;@search.score\u0026#34;: 13.380153, \u0026#34;@search.rerankerScore\u0026#34;: 2.2026549801230431, \u0026#34;@search.captions\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;Rauma, Finland\u0026#34;, \u0026#34;highlights\u0026#34;: null } ], \u0026#34;id\u0026#34;: \u0026#34;178635\u0026#34;, \u0026#34;title\u0026#34;: \u0026#34;Rauma, Finland\u0026#34; }, 考察 今回の英語のクエリではSemantic Rankerがある程度の役割をはたしていそうだということはわかりました。 Capitalがいくつもの意味を持っていることもあり、文章をもとにより意味の近いドキュメントが上位に来たということです。 ただ、英語の場合も基本的には上位50件以内のデータに対して処理が行われるので上位50件以内にデータが入らなければうまくいかないようです。\nまとめ Azure Cognitive Searchの新機能であるセマンティック検索について調べてみました。 まだPublic Previewですが、簡単に使えるような仕組み(データの再登録なし、クエリでパラメータを追加するだけ)が用意されているのは便利でした。 ただ、最初に想像していたもの(私の早とちりもありますが)ほどのセマンティック検索とは行きませんでした。 似たような言葉の意味を持ったものを探してくれたり、答えそのもののページのスコアがすごく高くなるといったものではありませんでした。\n仕組み上、クエリに含まれる単語で検索し、上位50件以内のデータだけが対象になる(残念ながら現時点ではこの件数の変更はできません。)ため、これまでの検索とは劇的に変化するものではないことはわかりました(銀の弾丸はないんですけどね)。\nある程度の挙動をわかっていれば、Wikipediaのようなデータでもそれなりの結果は取得できそうだということはわかりました。\n「言語モデル」でクエリとヒットしたデータをもとにスコア計算をし直しているようですが、この部分がどのようなデータ・クエリだと有効活用できるのか?というのをもう少しいろいろな角度で試してみる必要がある気がします(適材適所が何なのか?)。 あとは、上位50件までが対象なので、それ以上の件数のデータの並びに関してはこれまでと同様の結果となる点は注意しないといけません。 また、今回試していないほかの機能(スペルチェック、Semantic Answerなど)にメリットがあるのかもしれません。\nざっくりですがセマンティック検索について調べてみました。 こんなデータだとどうなの?ここの考え方が間違ってるのでは?などの指摘がありましたら、コメント欄またはTwitter(@johtani)でコメントを頂けたらと。\n","date":1625130583,"dir":"post/2021/","id":"43caef5d41c4e74826e4a8d82088739d","lang":"ja","lastmod":1625130583,"permalink":"https://blog.johtani.info/blog/2021/07/01/semantic-search-in-azure-cognitive-search/","publishdate":"2021-07-01T18:09:43+09:00","summary":"Azure Cognitive Searchで新機能「Semantic Search(セマンティック検索)」という機能の日本語対応が発表されました。 実際にはPublic P","tags":["azure search"],"title":"Azure Cognitive Searchの新機能、Semantic Searchを試してみた"},{"contents":"Sofle v2を長らく使っていましたが、コンパクトなのもやっぱりいいよなぁというときにKochi KeyboardからLunakey Miniが発売していました。 小指のあたりの傾斜が使いやすいかも?ということで、組み立ててみました。\nもちろん購入はKochi Keyboardさんからです(購入はこちらから)。\nLunakey Miniビルドガイド 作者のYoichiroさんが公開しているビルドガイドが詳細まで書かれています。 こちらをまずは参照してください。\nLunakey Mini ビルドガイド (Rev.4以降) ビルドログ(主にツイート) 私の組み立てについては、Twitterでツイートしていたものがありますので、そちらを貼っておきます。 ちなみに、ツイートしていて躓いているときに、作者のYoichiroさんからたびたびコメントをいただきました。 ありがとうございました!!\n間にいくつかコメントを差し込んでいます。\n結局両方のダイオードつけてしまいました。今日はここまで pic.twitter.com/3qLI6EpfXB\n\u0026mdash; Jun Ohtani (@johtani) April 12, 2021 ハンダはつけた pic.twitter.com/ySE9SA3gZn\n\u0026mdash; Jun Ohtani (@johtani) April 13, 2021 コンスルー問題 左手じゃん、T。Tのダイオード浮いてた。右手も一回全部見直すか\n\u0026mdash; Jun Ohtani (@johtani) April 13, 2021 ここで問題が発覚。右手(ツイートではぼけていて、左手と書いています)についてはダイオードが1か所浮いていただけなので、はんだ付けですぐ直りました。 左手側が大問題です。そもそも右手につけたProMicroへの書き込みができませんでした。 キーボードによっては、ダイオードなどを付ける前からまず、リセットボタンを付けて、ProMicroを指して書き込みをする場合もあります。 ただ、その書き込みができない。 (ちなみにこのタイミングでテスターをつけっぱなしにしていたのが発覚し、9V電池切れのため翌日に持ち越した。。。)\nさて、デバッグのお時間です pic.twitter.com/CaEOv4E5Bg\n\u0026mdash; Jun Ohtani (@johtani) April 14, 2021 ただ、ProMicro刺した状態で、リセットボタン、リセットボタンの足をショートさせても書き込みはできず、ProMicroのGndとResetの足のショートでは書き込みができる。\n\u0026mdash; Jun Ohtani (@johtani) April 14, 2021 テスターで調べてみたところ、リセットボタンとProMicroがうまく通電していません。\nだいぶ進んだけど、Eの列がおかしいなぁ。さて、どこの接触だ? pic.twitter.com/5tci12Vk05\n\u0026mdash; Jun Ohtani (@johtani) April 14, 2021 どうも、左手の基盤のProMicroの足の穴がコンスルーとの接触が悪いみたいでした。 コンスルーの足を無理やりまげて(3個のコンスルーの足を折りました。。。)、通電できるようにして解決(結局あとでいくつかの足についてははんだ付けしました)。\n終わった。LEDの予備はんだまでやってからおしまいにしよ\n\u0026mdash; Jun Ohtani (@johtani) April 16, 2021 LED実装 鬼門の表面実装ですが、LEDを1個破損するだけで乗り切りました。ちょっと色はおかしかったですが、これはおそらくProMicroの足のせい。\n一個逆につけてしまい、お亡くなりになりましたが、まぁ、良いかな。まずは右手 pic.twitter.com/zldu6fRsXR\n\u0026mdash; Jun Ohtani (@johtani) April 18, 2021 ソケットの実装x2 ロープロファイル(Kailh choc v1)のキースイッチも試してみたいので、MXと両方のソケットをはんだ付けしました。 両方利用できるのは便利ですね。はんだ付けも楽しいし。\nソケットを片手だけ(両方のソケットつけるのでまだ、1/4) pic.twitter.com/7XFRDx0D0I\n\u0026mdash; Jun Ohtani (@johtani) April 18, 2021 キースイッチ設置 親指以外にはKailh Box Silentのピンク軸(Kochi Keyboardから)、親指にはKailh Input Club Hako Violet(AliExpressで購入したもの。リンクは遊舎工房のもの)をつけました。 どちらもそれほどぶれもないものです。Silent ピンクはリニアで静かでそれほど力がいらないスイッチになっています。 親指はタクタイルで小気味のいい音が気に入っています。Sofleもこのキースイッチになってます。\n残りのソケットつけて、キースイッチも設置して、動確してボトムプレートも装着。残りはキーキャップ。 pic.twitter.com/hGc1TtI6fu\n\u0026mdash; Jun Ohtani (@johtani) April 25, 2021 キーキャップ+キーマップ お試しにXDAのキーキャップをはめてみたのですが、キーの境目がわかりにくく、タイプミスが多かったです。 その後のツイートにあるようにOEMに切り替えています。\nキーマップについては、Lunakey Miniの作者のYoichiroさんが作ったRemapというブラウザベースでキーマップの書き換えができるツールで楽々変更ができました。JISキーまで対応しているのでJISベースでキーマップを作成している私にはうってつけでした。 Remapの利用方法についてはサリチル酸さんのブログが詳しく書いてあります(本当に頭が下がります)。\nRemap使ってキーマップいじったら、すごく楽だった。\n\u0026mdash; Jun Ohtani (@johtani) April 26, 2021 BLE + LPME-IO化 ここまでで、USB接続で動作はしていたのですが、Sofle同様に3台をBluetoothで切り替えながら使いたかったので、 Corne Light v2につけていたBLE+LPME-IO(Corneの実装などは前のブログを参照)を抜き取って、Lunakey Miniに移植してみました。\nBLE ProMicro化は作者の方のブログで行われていたので、LPME-IO対応も何とかなるだろうと。\nBLE+LPMEに変えた。後でブログ書こう pic.twitter.com/mGePN52v6k\n\u0026mdash; Jun Ohtani (@johtani) April 29, 2021 LPME-IOへの対応はCorneとSofleの時に行なったこともあり、なんとなくあたりがついていました。 流れとしては、以下の通りです。\nBLE Micro Pro用の設定ファイルを作成 BLE Micro Proのサイトの「キーボードの設定ファイルを編集する」のコマンドでコンフィグファイルを生成 LPME-IOのジャンパをはんだでブリッジ 1.で生成したコンフィグから、Corne Lightと同じ個所のジャンプをすれば良いとわかったので今回はスキップ TRRSのI2C対応 Corne LightのLPME-IO対応の時と同様にSDAとSCLをTRRSの足にショートカット ただ、今回右手側は、下記ツイートのようにOLEDの足からTRRSの足にショートカットしました。Corneの基盤を見ていた時にこれでも行けそうだな?と思っていたので、試してみた次第です。ちなみに、左手はCorneの時と同じPro Microから長い銅線を引っ張っています(電池基盤があったので、外すのがめんどくさかったため)。 BLE Micro Proにファームウェア書き込み BLE Micro Proのサイトの手順に従います。 設定ファイルには1.で出力されているLPME用のファイルを使用。 といった感じです。キーマップが設定されていないので、Remapで設定しなおしました。 Remapは、キーマップをPDFで出力する機能までついていて、すごくいいですね。サイコー\nあと、足。 pic.twitter.com/W0Wpf5k5SE\n\u0026mdash; Jun Ohtani (@johtani) April 29, 2021 傾斜がつくように奥側に高さを出すためのゴム足を貼り付けました。 あとは、3台のPCにBluetoothで接続すれば終了です。 (AD_WO_Lのキーを利用して追加していくのを毎回忘れる。。。)\n疑問点 ちょっとだけ疑問点がありますが、時間があればそのうち調べるかな。\nRemapはクラウドに設定ファイルをセーブできるけど、json形式で手元にダウンロードしたりはできないのかなぁ? LEDは有線じゃないと点かないみたいだけど、音はどうなんだろう? 音が出せそうなら、Bluetoothの接続切り替えするときに音の出方を変えるとかをやってみたいなぁ。 まとめ ということで、Lunakey Miniを組み立てて、BLE+LPME-IO対応してみました。 はんだ付けはだいぶ慣れてきましたし、今回もトラブルがあったおかげでテスターを利用して、どのあたりがおかしいかという調査をするのも慣れてきました。 あとは、キーの配置の違いを体感して、どれが自分に合ってるかなぁ?というのを試したり仕様と思います。 ロープロファイルも試してみようかな。\nあ。もちろん、このブログは組み立ててBluetoothで接続したLunakey Mini Rev5、Kailh Box Silentピンク軸+Input Club Hako Violetで書きました!!久々に数字列がないので記号入力とかがちょっとバタバタしましたw\n","date":1619709972,"dir":"post/2021/","id":"f4baa43cc7ca712d83b99a794c4e2dbd","lang":"ja","lastmod":1619709972,"permalink":"https://blog.johtani.info/blog/2021/04/30/build-lunakey-mini-ble/","publishdate":"2021-04-30T00:26:12+09:00","summary":"Sofle v2を長らく使っていましたが、コンパクトなのもやっぱりいいよなぁというときにKochi KeyboardからLunakey Miniが発売して","tags":["DIYキーボード","misc"],"title":"Lunakey Miniを組み立てて、BLE+LPME-IO化してみた #DIYキーボード"},{"contents":"みなさんは、スライドの作成には何を使っていますか? Keynote?Powerpoint?Google Slides?\n私は、Macでスライドを作るときは前職ではテンプレートもあったのでKeynoteでしたが、ちょっとしたものはMarkdownベースのDecksetを利用していました(買い切りタイプの有料ソフト)。\nフリーランスになってもこちらを利用していたのですが、Windows環境に切り替えたので使えなくなってしまいました。 一度はGoogle Slidesで作ったのですが(第39回Es勉強会スライド)、既存の資産を流用したくなりどうしたものかと悩んでい(ツイートし)たら。\nMacの頃はDecksetってアプリでMarkdownで書いてたんだけど、Winに移動したのでこのタイミングでGoogle Slidesにでもしようかなと考えてるところ。Markdownでスライド作るのほかになんかあるか探すほうがいいかなぁ?\n\u0026mdash; Jun Ohtani (@johtani) March 18, 2021 僕はこれ使ってますhttps://t.co/sFaAmKZY6V\n\u0026mdash; miyake | ZEN (@kazuyukimiyake) March 18, 2021 ということで、利用してみようかなとなりました。\nMarpとは? Markdownでプレゼンテーションのスライドを作ることができるOSS?になります。\nMarp公式サイト といっても、これ自体を使わなくても、VS Code上でプレビューしたりHTML形式で動作するスライドを吐き出すことが可能です。 なので、VS Code用のプラグインを利用しています。\nサンプル この間利用したスライドはこんな感じのMarkdownになってます。 ---でページを区切りつつ、記述していく形です。\n--- marp: true theme: poster --- \u0026lt;!-- _class: big-center --\u0026gt; # 本当にその検索は\u0026lt;br/\u0026gt;自分が想像している検索に\u0026lt;br/\u0026gt;なってますか? \u0026lt;br/\u0026gt; \u0026lt;br/\u0026gt; \u0026gt; 2021/03 \u0026gt; Jun Ohtani / @johtani --- ![bg right:40% 40%](johtani_face.jpg) # 自己紹介 - フリーランスエンジニア - 検索技術勉強会主催者 - Apache Solr入門(第2版まで)や データ分析基盤構築入門の著者の一人 --- プレビューで見るとこんな感じです。\nプラグイン Marp for VS Code プラグインをインストールするのも簡単ですよね。 マーケットプレイスからインストールすれば完了です。\n機能については上記のページにあるように、プレビューとスライドの出力です。 プレビューでは、Markdownのプレビューみたいな形で、スライドが表示できます。\n先日この機能を利用して作成して、HTMLで出力して利用しました。 PDFとかPPTX出も出せるようなので、今後試してみようかなと。\nDecksetのスライドとの違い ページの区切りなども同じだったので、大筋ではそれほど違いはありませんでした。 ただ、画像周りとスタイルの設定は細かく修正をしました。\n変更した点としては、以下のようなものがあります。\nヘッダ部分の変更 上のサンプルにありますが、marp: trueを含む部分がMarp独自の記述です。 ページごとのちょっとした変更 ページごとにスタイルの変更ができるみたいで(Decksetではできなかったはず?)、タイトルページのスタイルを変えてあります。 画像の指定 画像の読み込み自体は違いはないのですが、画像の配置についての指定方法は カスタムテーマ用CSSの作成 デフォルトではなく、Decksetで用意されているような感じのスタイルに変更してみてます。 カスタムテーマはCSSで設定できるので、CSSファイルを用意して、VS Codeの拡張機能の設定からファイルパスを指定する形です。\nということで、当面はMarpでスライドを作っていくことになるかと思います。 まぁ、ただ、スライドを作るいこと自体が減ってきてはいるのですが。 ほかの配色を試したり、ヘッダフッタとかも試してみるのもいいかもな。\n気が向いたら、CSSをどこかにアップロードするかもです。\n※今回のブログはGateronサイレントクリア軸をルブしてみた、Corne Light v2で最後の数行を書いてみました。 キースイッチだけだとこすれる音が減った気がしてましたが、キーキャップを付けたら少しこすれる音が気になる感じです。\n","date":1617615911,"dir":"post/2021/","id":"f41d4fde94cbd7bbd28808dc080a2019","lang":"ja","lastmod":1617615911,"permalink":"https://blog.johtani.info/blog/2021/04/05/intro-marp/","publishdate":"2021-04-05T18:45:11+09:00","summary":"みなさんは、スライドの作成には何を使っていますか? Keynote?Powerpoint?Google Slides? 私は、Macでスライドを作","tags":["勉強会"],"title":"スライド作成の環境をMarpにしてみた"},{"contents":"新型コロナウィルスの影響もあり、オフラインで集まって勉強会も開催できなくなっています。 検索技術勉強会も、もう1年以上開催できていないです。\nスピーカーの人にオンラインでしゃべってもらうのもありだとは思うのですが、 懇親会とセットでその価値があったかもなぁと思うところもあり、オンラインでの開催に乗り気になれないまま時間がたってしまいました。 (配信周りを調べるのがめんどくさいなぁというのもあったかも(反省))\nそんな中、takuya-aさんと話をしていて、エンジニア同士のゆるいつながりができる場所が欲しいですねぇということに。\nはー、検索技術勉強会、オフラインでできないまま1年以上たってしまったのか。オンライン勉強会とかはスピーカーの人の負担とかもあるし、Discordみたいなオープンな場だけ用意してみるのありかなぁ?ただ、活発に話がされるのかどうかわからんし、ROMな人ばかりだとアレなんだけどなぁ。\n\u0026mdash; Jun Ohtani (@johtani) March 30, 2021 そこからの、このツイートです。 ちらほらと興味のありそうな人が出てきたねという話をしていたら、Slackのワークスペースが出来上がってましたw\n検索技術に関する情報交換を目的とした Slack を立ち上げました!こちらの招待リンクからご参加ください。 https://t.co/Tca70vuMff\n\u0026mdash; takuya-a (@takuya_b) March 31, 2021 ありがとう、takuya-aさん!\nということで、検索周りでわいわいできる場になればいいなぁと。 盛り上がってくれば、オンラインでの勉強会とかもありかもしれないですね! 興味のある方は、上記ツイート内のリンクからご参加下さい!!\n","date":1617200894,"dir":"post/2021/","id":"ce426b7f3190c8a4a47d45ac799e91a4","lang":"ja","lastmod":1617200894,"permalink":"https://blog.johtani.info/blog/2021/03/31/search-tech-jp-slack/","publishdate":"2021-03-31T23:28:14+09:00","summary":"新型コロナウィルスの影響もあり、オフラインで集まって勉強会も開催できなくなっています。 検索技術勉強会も、もう1年以上開催できていないです。 ス","tags":["勉強会"],"title":"検索技術に関する情報交換を目的としたSlackができました!"},{"contents":"Azure Cognitive SearchにはOData式という書式で条件が書ける仕組みがあります。 ODataは検索条件($filter)やソート条件($orderby)、取得する項目名の指定($select)です。\n私は、Luceneの構文に慣れているので、普通のsearchパラメータを利用しようとします。 が、OData式として特殊な書き方がいくつかあるようなのでこちらの利用方法も調べてみました。 その時、N-Gram(よくやるのはN=2)で陥る問題の話もあるのでこちらについても言及します。\nOData式で検索 次のような3件のドキュメント(フィールド名はbodyとします)をN-Gramで登録していたとします。\nミルクティを飲みたいです。 マティーニはカクテルですが、ミルクセーキは? 風呂上がりのミルクは最高です。 この時、OData式でミルクティという単語で検索してみましょう。\n検索条件は$filterで指定します。 フルテキスト検索用に関数が用意されており、こちらに単語を指定します。\n$filter=search.ismatchscoring(\u0026#39;ミルクティ\u0026#39;) こんな感じ。フィールドの指定がない場合、対象のフィールドは検索可能なフィールドすべてが検索対象になります(公式ガイドのクエリパラメータのqueryTypeに説明あり)。\nでは、実行してみましょう。で返ってくるのは?1だけかな?と思う人が多いかもしれません。 が、結果は3件とも帰ってきます。\n問題点は? では問題点はどこでしょう? ismatchscoringのオプションなどを見る前に、転置インデックスを用いた検索エンジンの挙動をおさらいしましょう。 転置インデックスの仕組みを理解することで、なぜそんな挙動になるのか?というのがわかりやすくなります。 おさらいにはElasticsearchをベースに話をしますが、Azure Cognitive Searchでも同じような挙動になります。\n転置インデックスとトークナイザー(アナライザー)の関係(おさらい) 昨年、オンラインで開催されたOSC広島で発表した資料(録画あり)でもざっくりと説明しています。\nView 本当にその検索は自分が想像している検索になってますか? on Notist.\nざっくりですが、おさらいです。\n検索エンジンでは、入力された文章を、ある規則(アナライザー)で単語に分割し、その単語ごとにどのドキュメントに出現したのか?というリストが作られます。 このリストが転置インデックスです。書籍の後ろにある索引を想像するとどんなものかがわかりやすいです。 単語に対してその単語が出てくるページ番号がわかるという仕組みです(下図は本の索引の一例)。\n書籍の索引は著者や編集の方により厳選された単語のみが採用されています。 が、検索エンジンでは文章を単語に区切る機能が存在します。 この「ある規則」で単語を区切る仕組みが「アナライザー(トークナイザー)」と呼ばれる機能です。 例えば英語用のアナライザーに英語の文章が入力されたとき、文章はこのように単語に区切られたもの(単語列)を出力します(下図)。\n今回はNGramの話なので、NGramのAnalyzerを利用してみるとこんな感じになります。\n実際に出来上がる転置インデックスは次のような形になります。 検索の仕組み(おさらい) 出来上がっている転置インデックスに対して検索をする場合、入力文字列(検索条件)に対して、転置インデックス作成時と同様にAnalyzerが動作します。 処理としては、\nクエリのパース フィールドのAnalyzerで処理 転置インデックスを検索 という形です。 例えばこんな感じ。\n同じAnalyzerの処理が入ることで、転置インデックスに採用されているのと同じ単語が出てくるため、検索がきちんとできるということになります。\n英語と日本語(NGram)の違い 英語と日本語の違いは、スペースの意味になります。 英語の場合は、スペースが単語の区切りになりますが、日本語の場合スペースでは区切られていません。\nですので、検索窓に入力された文字列は、英語の場合、クエリのパースの時点で単語に区切られます。そのあとにAnalyzerになるので、基本的には単語単位でAnalyzerの処理が動きます。そのあと、転置インデックスへの検索となります。なので、多くの場合はAnalyzerの出力は1単語です(類義語などを利用していたりする場合は異なりますが)。\n日本語の場合、スペースでは区切られていないので、クエリのパースの時点で入力された文字列がそのままAnalyzerにわたります。 今回はAnalyzer(NGram)が単語に分割し、それをもとに検索処理が実行されます。\nismatchscoringの問題点は?(やっと帰ってきました) さて、回り道をし、簡単ですが転置インデックスやAnalyzerについて説明しました。 では本題です。\n$filter=search.ismatchscoring(\u0026#39;ミルクティ\u0026#39;) このismatchscoring関数ですが、そのほかにも引数の指定が可能で、省略した場合にデフォルトで採用される値がいくつかあります。 公式のドキュメントにパラメータの意味が掲載されています。\n今回は、第4引数のsearchModeの値が問題点です。デフォルトでは、anyが指定されます。 この、anyは検索語(今回はミルクティ)の任意の検索語句が一致する必要があることになります。 「検索語句」?なんでしょう?これが、ここまで回り道をして説明してきた、Analyzerの出力した単語になります。 「ミルクティ」はNGram(N=2)のAnalyzerを通すと、\n「ミル」「ルク」「クテ」「ティ」\nという4つの単語が出力されます。 これが、「検索語句」です。「任意の」とあるので、上記4つの2文字のどれか?が出現すれば検索条件にヒットしたこととなります。\nですので、以下のように(一部のみ色を変えてます)3つの文章にはそれぞれの文字が含まれているため、先ほどの条件では3件の結果が返ってくることになります。\nミルクティを飲みたいです。 マティーニはカクテルですが、ミルクセーキは? 風呂上がりのミルクは最高です。 NGramで一部分の単語だけで一致したものがヒットしてしまうと違和感があるので、allに変更します。\n$filter=search.ismatchscoring(\u0026#39;ミルクティ\u0026#39;, \u0026#39;body\u0026#39;, \u0026#39;simple\u0026#39;, \u0026#39;all\u0026#39;) 今度はどうなるでしょう?\nミルクティを飲みたいです。 マティーニはカクテルですが、ミルクセーキは? 先ほどよりもマシになりました。 3がヒットしなくなっています。3の文章には「ティ」などが出てこないためです。 ただ、感覚的に2番目がヒットするのは少し違和感がありますよね? 確かに4つの単語がすべて出てきていますが、「ミルクティ」とは少し遠いです。\nさらに「ミルクティ」にヒットさせるにはフレーズ検索にする必要があります。 Elastic社のブログの日本語の検索に関する記事でも出てきますが、フレーズで検索することで「ミルクティ」だけにヒットさせることができます。\n「フレーズ検索=語順を保証する検索」となります。 ですので、\n「ミル」「ルク」「クテ」「ティ」\nこの順序で出てきた場合のみ、検索にヒットしたことになります。 OData式でフレーズ検索する場合は、単語をダブルクォート\u0026quot;でくくる必要があります(公式ドキュメントの例に記載あり)。\n$filter=search.ismatchscoring(\u0026#39;\u0026#34;ミルクティ\u0026#34;\u0026#39;, \u0026#39;body\u0026#39;, \u0026#39;simple\u0026#39;, \u0026#39;all\u0026#39;) これで結果は以下の1件だけとなります。\nミルクティを飲みたいです。 これでNGramで部分一致のような挙動で日本語の検索ができるようになりました。\nちなみに、フレーズにした場合は第4引数はanyに変更しても1件だけの検索結果となります。 フレーズ検索には「すべての語が含まれる」、「すべての語が順番に現れる」という2つの条件が含まれるためです。\n$filter=search.ismatchscoring(\u0026#39;\u0026#34;ミルクティ\u0026#34;\u0026#39;, \u0026#39;body\u0026#39;, \u0026#39;simple\u0026#39;, \u0026#39;any\u0026#39;) この例の引数をミルクティを\u0026quot;ミルク\u0026quot; \u0026quot;最高\u0026quot;のような検索条件に変えた場合、「\u0026ldquo;ミルク\u0026rdquo;」「\u0026ldquo;最高\u0026rdquo;」の2つの条件をanyで扱うため、 「\u0026ldquo;ミルク\u0026rdquo;」「\u0026ldquo;最高\u0026rdquo;」のどちらかが出てくれば良い結果となり、3件の結果が返ってきます。 第4引数をallに変更すると、「\u0026ldquo;ミルク\u0026rdquo;」「\u0026ldquo;最高\u0026rdquo;」の両方が出てこなければならないため、3件目のデータのみが返ってきます。\n$filter=search.ismatchscoring(\u0026#39;\u0026#34;ミルクティ\u0026#34; \u0026#34;最高\u0026#34;\u0026#39;, \u0026#39;body\u0026#39;, \u0026#39;simple\u0026#39;, \u0026#39;all\u0026#39;) これは、\n$filter=search.ismatchscoring(\u0026#39;\u0026#34;ミルクティ\u0026#34;\u0026#39;, \u0026#39;body\u0026#39;, \u0026#39;simple\u0026#39;, \u0026#39;any\u0026#39;) and search.ismatchscoring(\u0026#39;\u0026#34;最高\u0026#34;\u0026#39;, \u0026#39;body\u0026#39;, \u0026#39;simple\u0026#39;, \u0026#39;any\u0026#39;) と同じ意味となります。 少し長くはなりますが、後者の書き方をプログラムで書くと思います、私の場合は。 検索窓に入力された単語に必ず\u0026quot;を追加する処理を書くために、画面入力の文字列を一旦パースをすることになるからです。\nまとめ 簡単?にですが、OData式でのフルテキスト検索と、NGramでのフレーズ検索について説明しました。 英語の場合、もともとスペースで区切られているので、フレーズといわれてピンときますが、日本語の場合はAnalyzerの挙動をわかっていないと「?」となるかと思います。 なぜフレーズ検索が必要なのか?というのが少しでもわかっていただければと。 ちなみに、NGramのTokenizerには別の落とし穴もありますが、その話はまた後日にでも。\n参考として日本語関連の検索に関する記事のリンクを残しておきます。\n参考 Elasticsearch日本語でフレーズ検索が必要なわけ NGramも含め、Elasticsearchでの日本語の検索の設定やクエリについては、Elastic社のブログで日本語で書かれた記事が詳しいのでこちらをご覧いただくのがいいです。 ","date":1614756213,"dir":"post/2021/","id":"eced95e5f301a8340e83d81d3c0d5c0d","lang":"ja","lastmod":1614756213,"permalink":"https://blog.johtani.info/blog/2021/03/03/phrase-query-in-japanese/","publishdate":"2021-03-03T16:23:33+09:00","summary":"Azure Cognitive SearchにはOData式という書式で条件が書ける仕組みがあります。 ODataは検索条件($filter)やソート条件($orderb","tags":["azure search","elasticsearch"],"title":"OData式と日本語の検索(NGram)とフレーズ検索"},{"contents":"自宅の環境がいろいろと変わったのですが、書いていなかったので更新版です。 前回のブログ(2020/09)、前々回のブログ(2020/03)はそれぞれリンクをたどってください。\n現状のデスクトップはこんな感じ\nPC 別のブログにまとめましたが、Windowsメインに切り替えました。 ハードの話以外に、Windows OSに切り替えたときにいくつか入れたものもあります。 それは、移行のブログに少しだけ書いてあります。\nひさびさにWindowsに戻ってきていますが、だいぶ慣れました。 まぁ、それほど大したことをやってないというのもあるかもですが。。。\nメインPC以外にこれまでのmacをブラウジング用にサブディスプレイにつなぎ、マウスをLogicool Flowで行き来できるようにし、 キーボードはKVMスイッチで切り替えてやりくりしていました(最新環境はキーボードのところを参照してください)。\nAmazon | サンワダイレクト USB切替器 キーボード・マウス用 KVMスイッチ キーボード いくつかDIYしましたが、今はメインでSofle Keyboard v2を利用しています(Kochi Keyboardさんで購入できます)\nSofle keyboard v2を有線で使っていましたが、最近Bluetooth対応して無線化しました(その時のブログはこちら)。 ですので、PCとの接続の切り替えはキーボード上で特定のキーの組み合わせを押すことで、切り替えられるようになっています。 KVMとは異なり、Bluetoothの接続が切り替わるのにタイムラグがある+どこにつながっているのか?というのがわからないので、想定していないところでキーが入力されていることがあります。 これは、何とかしたいかもなぁと考えてはいるところ。\nマイク&オーディオインターフェース 基本的に自宅でリモート作業をしています(ありがとうございます)。 なので、ミーティングもオンラインです。 となるとやはり、音がいいほうがお客さんにも喜ばれるかなぁと。 2020年3月時点ではSAMSONのGoMicを利用していました。 これもいい音なのですが、大きいマイクでもいいかなと。 あとは、ほかの使い道もあるかも?ということで、オーディオテクニカのマイク(+ポップガード)とフォーカスライトのオーディオインターフェースに変えてみました。 自分は実感ないですが、きっと役に立っていると思いますw\nAmazon | audio-technica サイドアドレス コンデンサーマイクロホン AT2050 | コンデンサ | 楽器 Amazon | AUDIO-TECHNICA AT-PF2 ポップフィルター | マイクアクセサリ | 楽器 Amazon | Focusrite フォーカスライト オーディオインターフェイス 2イン/2アウト 24bit/192kHz Scarlett Solo (3rd Gen) ステッカー付きセット 【国内正規品】 | 楽器・音響機器 | 楽器 ディスプレイ 以前は、MacBookProの16インチで、メインディスプレイの下に2枚目のディスプレイも兼ねて開いて利用していました(前回のブログ参照)。 自作PCに切り替えたので、ディスプレイがなくなってしまうので、同じような大きさのモバイルモニターを利用しています。 今のところは据え置きになっていますが、持ち運べるので、ほかの部屋や外出時にも使えるんではないかなと。 ディスプレイの足などはないので、邪魔にもならず便利ですね。\nAmazon | モバイルモニター モバイルディスプレイ 4K 15.6インチ cocoparスイッチ用モニター 非光沢IPSパネル 薄い 軽量HDRモード/FreeSync対応/ブルーライト機能 3840x2160 UHD/USB Type-C/標準HDMI/mini DP/カバー付3年保証付 | cocopar | ディスプレイ 通販 音楽再生環境 サブディスプレイにサンダーボルトディスプレイを使用していたので、Mac Miniを接続していましたがサンダーボルトディスプレイには退役してもらいました。 それに伴って、Mac Miniも別の場所に移動しました。音楽再生環境にラズパイ4を復活させました。 以前購入したセットについていたケースではファンの音が気になっていたので、ヒートシンク型に変えました。 結構重いですが、冷えてそうです。\nAmazon | Geekworm Raspberry Pi(ラズベリーパイ) 4 B 用アーマー金属ケース パッシブ冷却/シェル熱放散 ラズベリーパイ4 コンピュ ータモデルB適用 (アーマーケース(ファン無し)) | Geekworm | 冷却パーツ・ファン 通販 Webカメラ カメラ自体に変更はないですが、付属品をいくつか。 Webカメラではないカメラもつけてみたいなと思い、モニターアームにカメラを付けられるものを付けてみました。 ただ、おっさんの顔をきれいに映してもなぁという結論に至ったので、Webカメラが乗っかっています。。。 あとは、デスクトップPCになり、カメラのケーブルだけではPCまで届かなくなってしまったのでUSB Type-Cの延長コードを買ってみました。実はこれ2本目ですが。。。 スタンディングデスクの昇降でケーブルに負荷がかかってしまったことがなんどかあり、1本目の延長コードは接触が悪くなってしまいました。。。時々外したりしていて、ケーブルの配置がおかしいときがあるので、気を付けるようにしています。\nAmazon | 長尾製作所 モニターアーム用 VESA カメラ&マイクマウント NB-MV001MH | 長尾製作所 | モニタアーム\u0026amp;スタンド 通販 Amazon | iVANKY USB Type C 延長ケーブル USB 3.1 Gen 2(4K@60Hz/1.0m/オス-メス)10Gbps高速データ転送 3A急速充電 usb-c 変換 Huawei MateBook13, iPad Pro11, Nintendo Switch, MacBook等対応 | IVANKY | USBケーブル 通販 照明 裸の蛍光管だったのですが、リモコンで点灯したり、照度を変えられるようにしたかったので、 パナソニックの照明に変えました。\nAmazon | パナソニック LEDシーリングライト 調光・調色タイプ リモコン付 6畳 3, 699lm HH-CD0620AZ 【Amazon.co.jp限定】 | パナソニック(Panasonic) | ホーム&キッチン 変えたのはよかったのですが、部屋が長細い+Webカメラの位置(自分から見て左にカメラを置いて、部屋の奥への画角?になっている)のせいで、右半分の顔が暗くなる場合がありました。 幸い、右にはスチールラックが組んであるので、そこにつけられる照明を購入して女優ライトみたいな感じで使っています(頻繁ではないですが)\nAmazon|ルミナス メタルラック用 LEDライト 磁石で簡単設置 連結可能 幅60cm 昼白色 LED60R-N|メタルラックパーツ オンライン通販 フットレスト 昨年3月くらいに配置して、座っているときに足を置くのに便利に使っていました。 が、1台だと幅が足りないので最近2つ目を購入して並べて使っています。 片足ずつ載せられるのは便利ですね(基本ガニ股なので。。。)。\nAmazon | サンワダイレクト フットレスト スチール製 角度10° 幅40×奥行30cm 足置き台 100-FR011 | フットレスト | 文房具・オフィス用品 ということで、最近はこんな環境で仕事をしています。 当分これで更新しないんじゃないかなぁ。 (サブディスプレイが左に寄っているので、局面ディスプレイが気になっているところですが。。。)\n","date":1614246182,"dir":"post/2021/","id":"fcb0105fa6b5777a133f247784b9d930","lang":"ja","lastmod":1614246182,"permalink":"https://blog.johtani.info/blog/2021/02/25/update-working-facility/","publishdate":"2021-02-25T18:43:02+09:00","summary":"自宅の環境がいろいろと変わったのですが、書いていなかったので更新版です。 前回のブログ(2020/09)、前々回のブログ(2020/03)はそ","tags":["misc"],"title":"自宅の作業環境(2021/02)"},{"contents":"Azure Cognitive SearchにSuggestやAutocompleteの機能があるのを見つけたので、どんな挙動なのかを調べてログとして残しておきます。\n公式ドキュメント 日本語で公式ドキュメントが公開されています。使い方や流れについてはこちらをまずは見れば使えると思います。\n本ブログでは、ざっくりとした機能の紹介と内部がどんな挙動をしていそうか?、日本語だとどういう感じになるのか?という点を紹介しようと思います。\nどんな機能? 検索窓でよく、キーワードを入力しているときに検索キーワードの候補が表示されることがあります。 このキーワードの候補を表示するための機能が今回紹介するSuggesterと呼ばれる機能です(日本語の公式ドキュメントでは「先行入力エクスペリエンス」)。 Suggesterには、以下の2つの機能が用意されています。\nAutocomplete:キー入力しているときに、入力されている文字列で始まる単語で、検索できるもの(転置インデックスに登録されている単語)をリストで返す機能 Suggestion:入力した文字列で始まるキーワードを含む、元のデータを返す機能 利用方法 Suggesterの機能を利用するにはインデックスに設定を追加する必要があります(新規、既存どちらでも可)。 ただ、既存のインデックスに設定を追加した場合、内部にすでに存在するドキュメント(データ)については、このSuggesterのデータは作られません。 ですので、既存データを再度登録しなおすといった作業が必要となるので注意が必要です。\n本ブログでは、いくつかAzure Cognitive Searchのサンプルのリクエストが出てきます。Visual Studio CodeのREST Client Extensionの書式となります。拡張機能の簡単な紹介は昨年のブログをご覧ください。\n設定編 Suggesterの設定では、主に以下の2つを設定する必要があります。\nname: suggesterの名称。クエリ時に指定します。 sourceFields: 入力データのもととなるフィールド名。 String型のみ指定可能。また、Azureで用意されたアナライザーだけが利用可能です。自分で用意するカスタムアナライザーは利用できないので注意が必要です(制限についてはこちら)。 今回使用するサンプルのインデックス設定は次の通りです。\nインデックス作成のリクエスト(@host、@api-keyはご自身のものに置き換えてください。)\n## 設定 @host = 名前.search.windows.netと記載 @api-key = APIキーを入力 ### Create index with suggester POST https://{{host}}/indexes/?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;name\u0026#34;:\u0026#34;suggester-test\u0026#34;, \u0026#34;fields\u0026#34;:[ { \u0026#34;name\u0026#34;:\u0026#34;id\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;Edm.String\u0026#34;, \u0026#34;key\u0026#34;:true, \u0026#34;searchable\u0026#34;:false }, { \u0026#34;name\u0026#34;:\u0026#34;name\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;Edm.String\u0026#34;, \u0026#34;searchable\u0026#34;:true, \u0026#34;analyzer\u0026#34;:\u0026#34;ngram_analyzer\u0026#34; }, { \u0026#34;name\u0026#34;:\u0026#34;category\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;Edm.String\u0026#34;, \u0026#34;filterable\u0026#34;:true, \u0026#34;facetable\u0026#34;: true } ], \u0026#34;suggesters\u0026#34;: [ { \u0026#34;name\u0026#34;: \u0026#34;name_suggester\u0026#34;, \u0026#34;searchMode\u0026#34;: \u0026#34;analyzingInfixMatching\u0026#34;, \u0026#34;sourceFields\u0026#34;: [ \u0026#34;name\u0026#34; ] } ] } 公式ドキュメントのサンプルでは日本語がないので、日本語のデータも入力しています。\nデータ登録リクエスト\n### Index data POST https://{{host}}/indexes/suggester-test/docs/index?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;value\u0026#34;: [ { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Microsoft Office\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;microsoft\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;2\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Microsoft Azure\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;microsoft\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;3\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;GitHub Enterprise\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;github\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;4\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;GitHub dot com\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;github\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;5\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Bluetooth Mic\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;hardware\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;6\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;東京スカイツリー\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;japanese\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;7\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;東京タワー\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;japanese\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;8\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;東京特許許可局\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;japanese\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;9\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;グランメゾン東京\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;japanese\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;10\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;東京都庁\u0026#34;, \u0026#34;category\u0026#34;: \u0026#34;japanese\u0026#34; } ] } 以上が事前準備です。データ登録時に内部でSuggester用のデータを内部で生成しているようです(公式ドキュメント)。\nクエリ編 最初に説明しましたが、Suggesterの中ではAutocompleteとSuggestionという2種類の機能が用意されています。それぞれについて例をもとに説明していきます。\nAutocomplete API 検索窓に入力された文字を元に、前方一致でどのような単語で検索できるか?という候補を表示するための機能です(2単語も対応していますが今回は省略。APIの仕様はこちら)。\nたとえば、micという文字が入力されているところでAutocomplete APIを呼び出す時は、次のようなリクエストです。searchというパラメータに入力値を与えます。suggesterNameはインデックス作成時につけた名前になります。\nPOST https://{{host}}/indexes/suggester-test/docs/autocomplete?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#34;mic\u0026#34;, \u0026#34;suggesterName\u0026#34;: \u0026#34;name_suggester\u0026#34; } レスポンスとして、次のようなJSONが返ってきます。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;value\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;microsoft\u0026#34;, \u0026#34;queryPlusText\u0026#34;: \u0026#34;microsoft\u0026#34; }, { \u0026#34;text\u0026#34;: \u0026#34;mic\u0026#34;, \u0026#34;queryPlusText\u0026#34;: \u0026#34;mic\u0026#34; } ] } サンプルデータとして登録したデータにcategoryというフィールドを入れていました。 Autocompleteは条件を絞り込んで結果を返すこともできます。 filterにODataの書式で条件を書けます。 categoryフィールドにmicrosoftが設定されているデータだけを取得するということができます。\n### Autocomplete with filter POST https://{{host}}/indexes/suggester-test/docs/autocomplete?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#34;mic\u0026#34;, \u0026#34;suggesterName\u0026#34;: \u0026#34;name_suggester\u0026#34;, \u0026#34;filter\u0026#34;: \u0026#34;category eq \u0026#39;microsoft\u0026#39;\u0026#34; } レスポンスはこちら。先ほどとは違い、micというデータは返ってきていません。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;value\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;microsoft\u0026#34;, \u0026#34;queryPlusText\u0026#34;: \u0026#34;microsoft\u0026#34; } ] } 英語の場合、「単語」の単位は字面の通りです。スペースで単語が区切られているのでわかりやすいです。 日本語の場合は普通の人には少し想像しにくいです。 東京という文字を入力してみます。\n### Autocomplete in Japanese POST https://{{host}}/indexes/suggester-test/docs/autocomplete?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#34;東京\u0026#34;, \u0026#34;suggesterName\u0026#34;: \u0026#34;name_suggester\u0026#34; } すると返ってくるのは以下の通り「東京」だけになります。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;value\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;東京\u0026#34;, \u0026#34;queryPlusText\u0026#34;: \u0026#34;東京\u0026#34; } ] } 入っているデータは「東京スカイツリー」、「東京タワー」などです。 普通に考えると、これらがそのまま返ってくると思うかもしれませんが、違います。\nこれは、Suggesterの元となるフィールドのAnalyzerの挙動によります。 今回のインデックスのnameフィールドのanalyzerにはja.luceneです。これは、日本語用のアナライザー(Kuromoji)になります。いわゆる形態素解析器で日本語の文字列を「単語」に分割します。 英語についてはスペース区切りで分割しますが、日本語についてはKuromojiが内部の辞書とアルゴリズムに基づいて単語に分割してくれます。 Azure Cognitive Searchでは、Analyzerの挙動を確認するためのAPIも用意してあるので実行しみると、\n### Autocomplete in Japanese POST https://{{host}}/indexes/suggester-test/analyze?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;text\u0026#34;: \u0026#34;東京スカイツリー\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;ja.lucene\u0026#34; } このような結果が返ってきます。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;東京\u0026#34;, \u0026#34;startOffset\u0026#34;: 0, \u0026#34;endOffset\u0026#34;: 2, \u0026#34;position\u0026#34;: 0 }, { \u0026#34;token\u0026#34;: \u0026#34;スカイ\u0026#34;, \u0026#34;startOffset\u0026#34;: 2, \u0026#34;endOffset\u0026#34;: 5, \u0026#34;position\u0026#34;: 1 }, { \u0026#34;token\u0026#34;: \u0026#34;ツリー\u0026#34;, \u0026#34;startOffset\u0026#34;: 5, \u0026#34;endOffset\u0026#34;: 8, \u0026#34;position\u0026#34;: 2 } ] } ja.luceneのAnalyzerによって、3つの単語に分割されているのがわかります。 Autocomplete APIの実行結果も、このAnalyzerによって分割された単語をもとに、候補となる単語を前方一致で検索して結果を返しているのです。 ですので、「東」と入れても「東京」が返ってくるのがわかります。 一方で、「東京ス」と入力した場合は次のような結果となります。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;value\u0026#34;: [ { \u0026#34;text\u0026#34;: \u0026#34;スカイ\u0026#34;, \u0026#34;queryPlusText\u0026#34;: \u0026#34;東京スカイ\u0026#34; } ] } これは、autocompleteModeと呼ばれるパラメータの挙動となります。 デフォルトでは、oneTermという設定で、最後の単語(例の「東京ス」の場合は「東京」「ス」と区切られるので「ス」という文字を単語とみなす)にマッチする単語(例では「スカイ」)が返ってきます。 queryPlusTextについては、入力された文字にtextで返ってきた単語をくっつけたものが取得できます。\n英語であれば、スペースで区切られており、単語が切れているのが簡単にイメージできますが、日本語の場合は少し違和感が出るかと。\nこのように、入力された文字が含まれる「単語」を基本的に返す動作をするのがAutocomplete APIです。\nSuggest API では、もうひとつのSuggest APIはどういったものでしょうか? autocomplete APIに似ていますが、返ってくるデータが登録されたデータそのものになります。\nたとえば、micという文字列を入力とした場合、\nPOST https://{{host}}/indexes/suggester-test/docs/suggest?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#34;mic\u0026#34;, \u0026#34;suggesterName\u0026#34;: \u0026#34;name_suggester\u0026#34; } 次のような結果が返ってきます。Autocompleteの時は単語でしたが、こちらは入力データがそのまま返ってきています。 入力データの中にmicで始まる単語が含まれたものが候補となっています。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.text\u0026#34;: \u0026#34;Bluetooth Mic\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;5\u0026#34; }, { \u0026#34;@search.text\u0026#34;: \u0026#34;Microsoft Office\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;1\u0026#34; }, { \u0026#34;@search.text\u0026#34;: \u0026#34;Microsoft Azure\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;2\u0026#34; } ] } 日本語の場合、Autocompleteとは異なり、その単語を含むものがサジェストされるので、「東京」をsearchに指定すると「東京」を含むデータが出てきます。\n### Suggest in Japanese POST https://{{host}}/indexes/suggester-test/docs/suggest?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#34;東京\u0026#34;, \u0026#34;suggesterName\u0026#34;: \u0026#34;name_suggester\u0026#34; } レスポンスはこちら。単語を含む元の文字列が返ってきます。ここまでは違和感はありません。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.text\u0026#34;: \u0026#34;東京タワー\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;7\u0026#34; }, { \u0026#34;@search.text\u0026#34;: \u0026#34;グランメゾン東京\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;9\u0026#34; }, { \u0026#34;@search.text\u0026#34;: \u0026#34;東京都庁\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;10\u0026#34; }, { \u0026#34;@search.text\u0026#34;: \u0026#34;東京スカイツリー\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;6\u0026#34; }, { \u0026#34;@search.text\u0026#34;: \u0026#34;東京特許許可局\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;8\u0026#34; } ] } では、「東京」「特許」という2つの単語をスペースで区切ったものが入力されたとするとどうでしょう?\n### Suggest in Japanese POST https://{{host}}/indexes/suggester-test/docs/suggest?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#34;東京 特許\u0026#34;, \u0026#34;suggesterName\u0026#34;: \u0026#34;name_suggester\u0026#34; } スペースがありますが、内部処理では形態素解析器が分割した後でこの単語の順番で出てくるものを探しているので、出てくることになります。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;...\u0026#34;, \u0026#34;value\u0026#34;: [ { \u0026#34;@search.text\u0026#34;: \u0026#34;東京特許許可局\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;8\u0026#34; } ] } なお、このSuggestのAPIは、単語の語順を気を付ける必要があります。 「特許」「東京」と順序を入れ替えたスペース区切りの場合は、\n### Suggest in Japanese POST https://{{host}}/indexes/suggester-test/docs/suggest?api-version=2020-06-30 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#34;特許 東京\u0026#34;, \u0026#34;suggesterName\u0026#34;: \u0026#34;name_suggester\u0026#34; } 結果は返ってこないです。おそらく内部では、フレーズクエリで、最後の単語だけを前方一致で検索するような仕組みが動いているのだと思われます。 スペースで区切られてはいるが、順序があるので少し違和感を感じるかもしれません。英語だとフレーズの部分のイメージは沸きやすいのですが。\n短い文章のデータ(例:本のタイトルやランドマーク名など)では、このSuggestAPIを利用するとデータそのものが返却されるので、便利かもしれません。\nまとめ ということで、Azure Cognitive SearchのSuggesterの簡単な紹介でした。APIのページにはそのほかのパラメータについても説明があるので、使ってみようと思う方は目を通していただくのがよいかと。\n今回のブログは裏の仕組みがどんな感じなのか?を想像しながらAPIについて調べた形になります。日本語の場合に、少し違和感を覚える人もいそうだろうなということでブログを書いてみました。 今回は書いていませんが日本語でAutocompleteをやりたい場合は、読み仮名でも漢字が表示されるほうがよいという場合もあると思います。 その場合は、用意されている機能では難しいので、独自実装するといった方法になりそうです。 英語や、読みを利用しない場合は、挙動を理解していれば役に立つ場面もありそうです。\n","date":1612515120,"dir":"post/2021/","id":"931b2ebd9bfaeb5dcf1973e724a1f8d0","lang":"ja","lastmod":1612515120,"permalink":"https://blog.johtani.info/blog/2021/02/05/autocomplete-and-suggest-on-azure-search/","publishdate":"2021-02-05T17:52:00+09:00","summary":"Azure Cognitive SearchにSuggestやAutocompleteの機能があるのを見つけたので、どんな挙動なのかを調べてログとして残しておきます。 公","tags":["azure search"],"title":"Azure Cognitive Searchでオートコンプリートやサジェストをしてみる"},{"contents":"オライリー・ジャパンから出ている「コンピュータシステムの理論と実装」を読み始めたのでメモを取ることに。\n原著はオライリーじゃないのかというのが、まず最初の気づきでした。\nNANDからテトリス コンピュータのハードウェアからOS、さらにその上で動くアプリケーションまでを動作させるというのを少しずつやっていくという書籍みたいです。 イントロと1章を読みましたが、1章では論理回路の話でした。\n実際に物理的に作るわけではなく、シミュレーターなどのソフトウェアが用意されており、 そのソフトウェア上で動くものを作っていくことになります。 ソフトウェアのために専用のサイトが用意されて、ダウンロードもできるようになっているので、実際に手を動かしながら理解を進める感じになるのかと。\n目次を見ていただくとわかりますが、すごく幅が広いです。 1年で読み終われるかなぁ?まぁ、のんびりやっていこうかなと。\n用意されているソフトウェアなどで便利だなと思ったのは、どの章からでも興味のある部分から始められるようになっているようです(まだ始めてなくて。。。) 内部ではすべてのパーツがそろえてあるけど、章ごとのプロジェクトでは、個別に自分で実装したものがあればそちらが動くという挙動のようです。\nということで、ちょっとずつやっていこうかなと。 ほんとにテトリス動くのかなぁ?\n","date":1612424444,"dir":"post/2021/","id":"aa61b4543e8a7c67fccabee27a6e99cd","lang":"ja","lastmod":1612424444,"permalink":"https://blog.johtani.info/blog/2021/02/04/reading-elements-of-computing-systems/","publishdate":"2021-02-04T16:40:44+09:00","summary":"オライリー・ジャパンから出ている「コンピュータシステムの理論と実装」を読み始めたのでメモを取ることに。 原著はオライリーじゃないのかというのが","tags":["輪読","Nand2Tetris"],"title":"「コンピュータシステムの理論と実装」を読み始めた #Nand2Tetris"},{"contents":"Corne使ってましたが、数字キーがあるとどうなのかな?というのがやはり気になって。 そこに、Kochi KeyboardさんからSofle Keyboard v2というのが発売されたので組み立ててみました(去年末に)。また、先日Corne Light v2のBLE化に成功したので、Sofle keyboard v2のBLE Pro Micro + LPME-IO化にもチャレンジしてみました。\nSofle keyboard v2 ビルドログ 自分で書くよりもすごくよくできたビルドログがKochi Keyboardさんで公開されているので、そちらを参考にしてください。\nSofle Keyboard v2ビルドガイド すごく詳しく書いてあります。なので、こちらを見ていただければ問題ないかなと。 ただ、自分ではいくつか失敗したので自戒を込めてログを残しておきます。\nOLED用のジャンパをはんだ付けし忘れ 単にビルドログを流し読みしたツケが。。。 Sofleは同じ基盤を左右で利用します。なので、右手と左手で、同じ基盤の表と裏を利用します。 OLED用のジャンパする部分は両面に用意されていますが、はんだでジャンプするのはPro Microが実装される面となります。\n両面にジャンプ用のランドがあるとは気づかないで、左手の裏面をジャンプしてすべて実装し終わってから、OLEDが表示されないことに気づいてしまいました(ビルドログ用にと思って撮った写真に証拠が残ってますねw)。。。\nということで、またはんダッシュ太郎くんのお世話になりました(Pro Microを外してジャンプしました)。本当に有能ですよ彼は。。。\nAmazon | サンハヤト はんだシュッ太郎NEO 45Wタイプ HSK-300 | ハンダゴテパーツ ソケットのはんだ付け甘すぎ あとは、慣れてきたなぁと思っていたところに天罰が。 キースイッチのソケットを付けるの慣れてきたなーと思って、サクサクとつけていたのですが、 いざキースイッチをはめるときにボロボロとはがれていきましたw 半分くらいは外れたんじゃないかな?ちゃんとはんだ付けした後にピンセットなどで軽くいじってみるべきですね。。。\n滑り止め 利用しているキーキャップがOEMプロファイルということもあり、数字キー側を少し高くしたほうが入力しやすいです。そのために、少し大きめのソフトクッションを購入しました。\nAmazon | WAKI ソフトクッションCN-020 クリアータイプ: 産業・研究開発用品 上の左右の角に貼り付けると、がたつきがあったので少しずらして貼り付けて安定させています。 OLEDのプレートの部分を押すと手前が浮き上がってしまいますが、そこにはキーはないので問題ないかと。\nということで、毎回気づきがあって面白いですね。。。\nSofle keyboardのBLE化 Corne LightのBLE化がうまくいったので、もうひとセットのぎけす屋さんから購入しました。 BLE Micro ProやLPME-IO、電池基盤などについては前回のCorneのBLE化の記事を参照してください。\nハードウェア編 Sofle keyboard v2は残念ながらせきごんさんの公式ページの対応キーボード一覧には掲載されていません。 が、Sofle KeyboardのGitHubのページには次のような記載があります。\nSofle is 6×4+5 keys column-staggered split keyboard with encoder support. Based on Lily58, Corne and Helix keyboards.\n基盤の写真のPro Micro周りもCorneに似ています。 ということで、おそらくBLE + LPME-IO化が行けるのでは?と予測して作業に取り掛かりました。\nPCBの確認 Sofle Keyboardの基盤の設計図はGitHub上に公開されています。 この設計図を見る方法をまずは探しました。\n自作キーボードについて探すにはまずはサリチル酸さんのブログ「自作キーボード温泉街の歩き方」です。 回路図なので、設計ノウハウあたりのカテゴリーにあるだろうと探したところ見つかりました。\n(設計者向け)オートルーターを使って睡眠時間を確保しよう 配線のテクニックというブログですが、回路図を書くためのツールKiCadについて記載があります。 このブログにある以下の記事をもとに、KiCadのインストールや使い方をちょっとだけ勉強しました。\nfoostanさんのMeishi Keyboardの開発者向けガイド(JP) KiCadことはじめ KiCadの中の回路図エディタ「Eeschema」でSofle keyboardのPCBのフォルダを開くと回路図が開きます。 実際の基盤になる前に、Pro Microのどの足と何がつながっているのか?などが見て取れます。 前回のCorneのBLE化でLPME-IO対応したときに、学習しましたが、 TRRSの足とPro MicroのSDAとSCLをつなぐことで、LPME-IOを使うことができるようになるというのがわかっています。 それをもとに回路図を見たところ、以下のような記述がありました。\nどうも、JP9とJP10というはんだでジャンプする場所を用意してくれていそうです。 先を見越した設計本当にありがたいですね。\nJP9とJP10のはんだ付け 今ついているPro Microを外し(またはんダッシュ太郎が活躍)、基板を確認したところ対象の個所がありました。下の写真は左手の裏側です。\nこれらをはんだでジャンプします。\n右手は表側にあるので、Pro Microを外した後にジャンプしました。 左手は裏側です。 Corne Lightでは、Pro Microの足から導線を使ってTRRSの足につなぎましたが、今回はすっきり実装できました。 ジャンプした後はBLE Micro Proをはんだ付けします(はんだ付けせずに動作確認しようとしましたが、うまく通電しなくてちゃんと動かなかったです)。\nLPME-IOのジャンパ LPME-IOのGitHubページにあるように、利用するキーボードによって、いくつかはんだでジャンプする必要があります。 これは、BLE Micro Pro用のConfigファイルを見て、対象を決める必要があります。 が、Sofleは事前に用意されたものがありません。\nConfigファイルの生成 用意されていないConfigファイルが、QMKの設定ファイルから生成することができるようななっています(本当に感謝しかないですね)。 手順はBLE Micro Proのドキュメントにありました。\n新しいキーボード用の設定を作成する - QMK用の設定から変換する この変換スクリプトで3種類のconfig(右手用、左手用、LPME-IO用)が生成されます。 私の場合はLPMEを利用するので、lpmeという名前の入ったconfigを利用します。 中を見るとcol以下の記載が以下の通りだったので、8からDをジャンプします。\n\u0026#34;col_pins\u0026#34;:[18, 17, 16, 15, 14, 13, 18, 17, 16, 15, 14, 13], ここまででハードウェア側が終了です。\nファームウェア・設定編 ハードウェアの実装が終わったので、ファームウェアおよびアプリの設定です。\nファームウェアのセットアップ キーボードをUSBで接続し、BLE Micro Pro Web Configuratorのページにアクセスすると、 セットアップ初期画面が出てきます。\n公式ページの「キーボードを選ぶ」を参考にファームウェア、アプリのアップデートを行います。 「設定ファイルの書き込み」のタイミングでupload your ownを選択すると、ファイル選択画面が出てくるので、変換スクリプトで生成したJSONファイルを選択します。 このとき、Mas Storage Classとしてキーボードが認識されている状態だとうまく書き込めなかったので、キーボードのドライブを「取り出し」してからファイルをアップロードしました。\nキーマップの設定 BLE Micro Proのアプリが設定をきちんと認識すれば、あとはWeb Configuratorでキーマップの設定が可能になります。 これまた、残念なことに、BLE化する前のキーマップをJSONファイルで保存してなかったので(泣きそうw)、QMKのkeymap.cのファイルをもとに、ブラウザ上でがんばって設定しましたw また、新しい設定ではBLE関連のキーをマッピングとして追加しています。\nBluetooth接続 あとは、接続確認です。 MacとWin2台と接続するのですが、Win→Mac→Winの順番でBluetoothの接続をやっていたら、なぜか3つ目のWindowsで接続候補に出てくるけど、接続しようとするとタイムアウトをするという現象に遭遇しました。 MacのBluetoothの設定を一旦削除してから、Win→Win→Macの順番でペアリングしたところ問題なく接続できました。ただ、これが本当の対処なのかどうかは不明です。3番目だと接続できなかったWindowsマシンは再起動もしてみたのですがダメでした。この辺よくわかってないなぁ。\nまとめ ということで、Corne Lightに引き続き、Sofle Keyboard v2もBLE+LPME化に成功しました。 導線なども使わずにLPME対応ができたので見た目もすっきりしています。 これで、KVMスイッチだと2台までしか切り替えできなかったのが、3台をひとつのキーボードで操ることができるようになりました。 だいぶ楽になりそうな予感がしています。\nまだ、完ぺきではないので、次のような対応をやっていく予定です。\nロータリーエンコーダー対応:BLE以前はQMKのkeymap.cの中でロータリーエンコーダーの動作を記述していたので、BLE Micro Proでどうやるのかを調べたい。encorder.jsonというファイルがあったのでその辺ではないかな? OLED対応:Corne Lightの時と同様に、OLEDが点かなくなったのでこの辺りを調べたい。 ということで、とりあえずキー入力するのには困らない程度にはできたので、より便利にする方法を時間を見つけて模索する感じになりそうです。 あと、KiCadも面白そうなのでこっちもちょっと触ってみたくなってきたかも?\n","date":1612106122,"dir":"post/2021/","id":"d95522c691013bfe66dd46ded85a98ed","lang":"ja","lastmod":1612106122,"permalink":"https://blog.johtani.info/blog/2021/02/01/apply-ble-to-sofle/","publishdate":"2021-02-01T00:15:22+09:00","summary":"Corne使ってましたが、数字キーがあるとどうなのかな?というのがやはり気になって。 そこに、Kochi KeyboardさんからSofle Keyboard v","tags":["DIYキーボード","misc"],"title":"Sofle v2を組み立てて、BLE+LPME-IO化してみた #DIYキーボード"},{"contents":"メインマシンとMacは下記のサンワサプライのUSB接続のKVMスイッチを使っていますが、もう一台ノートPCがありここに接続しているCorne(初めてのDIYキーボード)が長いUSBケーブルでつながっています。\nAmazon | サンワダイレクト USB切替器 キーボード・マウス用 KVMスイッチ 時々必要になって、デスクにキーボードだけ引っ張ってきて利用するのですが、ケーブルの取り回しがまぁ邪魔で。。。 BLE対応(BLE Micro Pro)をしてみようかなということに。\nBLE + LPME-IO対応 分割キーボードをBLE対応(それぞれにBLE Micro Proを実装)すると、キーボード間のつながりがいまいちになることもあるというのをちらほら見ていたので、BLE Micro Pro + LPME-IOという構成で、 Corneのキーボード同士はTRRSケーブルで接続し、PCとCorne間をBluetoothで接続する構成にしてみました。\nBLE Micro Proについては、公式ドキュメントにいろいろと記載があります。\n材料 ということで、材料は以下の通り。セット販売は売り切れていたので、個別に購入しました。 コンスルーと電池以外は1つずつです。\nBLE Micro Pro(のぎけす屋) x 1 LPME-IO(のぎけす屋) x 1 BLE Micro Pro用電池基盤(遊舎工房) x 1 コンスルー(Kochi Keyboard) x 4 CR1632ボタン電池(近所のスーパー) x 2 実装 まずは、それぞれ組み立てです。\n電池基盤 以下の記事を参考にはんだ付けしました。\nQiita: 自作キーボードビルドログ:その2「ErgoDash」無線化対応 ハードウェア編 - 電池基盤の組み立て・半田付け yfuku docs - Claw44 / 無線接続について 注意点は以下の通りです。\n基盤が軽いので固定が必要(マスキングテープでマットに貼り付けたらましになった) 電池ホルダーが変形しやすい(設置して、足を折るために上から押さえつけたら、本体が曲がってしまった。。。) 部品が細かいので大変(老眼だから?) BLE Micro Proとの接続は参考にしたyfuku docsにある方法(余っていたピンヘッダを1本ずつ使ってはんだ付け)を採用しました。 (パッと見大丈夫そうだったので電池基盤の裏に絶縁テープは貼ってないです貼ってないです)\nBLE Micro Pro(もげ対策) BLE Micro Pro自体はコンスルーをはんだ付けするだけですが、今回はもげ対策として、ダイソーで買ってきたグルーガンで ちょっとだけ補強してみました。 初グルーガンだったので不細工だけど。これ難しいな。\n効き目あればいいけど?\nLPME-IO対応 いくつかのジャンパをはんだでブリッジ まずは、LPME-IOのREADMEのページの導入手順を読み、いくつかのピンをジャンプしました。 せきごんさんのBLE-Micro-Proのリポジトリに、CorneのLPME用コンフィグファイルを見ると、ジャンプするのは20, 19, 18, 17, 16, 15に対応している、F,E,D,C,B,Aの6つです(写真撮り忘れた。。。)。\nTRRSのI2C対応(って言い方であってるのかなぁ?) ジャンプだけでいけないかなぁ?と思いましたがダメでした(USBでつないでみたけど、左手(BLE-Micro-Proがついている側)だけ入力可能です。\nBLE Micro Proの公式サイトにLPME-IOについても記載があります。 実績のあるキーボード一覧にCorne Lightの記載もあったので、試してみようと思ったのが発端です。\nただ、LPME-IOの欄に注意書きが。\n*LPME-IOを使うには改造が必要\nまた、一覧の最初にも記載があります。\nLPME-IOを使うにはキーボードの左右の有線通信がI2Cである必要があります。とくにOLEDに対応しているキーボード等の場合は、I2C用のピンをTRRSジャックに接続する改造を施すことでI2C化できる場合があります。\nまだ、自作キーボードの仕組みをがっつり理解しているわけではない初心者なので、まぁ、ちょっとわからないかなと。。。 BLE Micro Proのはじめにのページを見ると、 Self Made keyboard in JapanのDiscordに専用チャネルがあるようで、過去ログを検索してみました。 検索したところ、Corneの場合Micro ProのSDA(写真の青い線)とSCL(写真の黄色い線)(参考:Corneの基盤の図)をそれぞれ、TRRSの2つのピンに接続する必要がありそうだというコメントがありました。\nCorne Cherry v2の場合は、接続するためのショートカットが用意されていましたが、Corne Light v2だと見当たりませんでした。 ということで、線を使って物理ショートカットしました。ちなみに、ショートカットは両手ともに必要なようです。\nUSB-Cで接続テスト 上記対応が終わって、基板に設置してUSB-Cケーブルで接続したところ、外部ドライブとして見えるようになりました。\nキーマップの書き換えとか 公式ドキュメントのBLE Micro Pro Web Configuratorを使うの手順通りに書き込みを行っていくと、特に問題なく接続できました。 便利すぎですね。キーマップの変更は、これまでのCorneのキーマップJSONファイルからコピペして書き込んだだけです。 (この後、BLE用のキーマップを書き足すためにもう一度変更しますが)\nLPME-IO対応なので、Micro Proは片側しかないので、書き換えも楽々でした。\nBLEで接続テスト 今回の目的だったWindowsにBluetoothで接続できるようにしてみました。 最初はサリチル酸さんの記事を見ていたのですが、キーコードがちょっと変わっているようでした。\nで、よくよく見ると、BLE Micro Pro Web ConfiguratorにBLE関連のキーも用意されているじゃないですか。。。\nBLE関連のキーを割り当てた後は、USBをオフにして、Bluetoothをオン、BTNEWで新しくペアリングするようにすれば接続完了でした。\n課題 これまでと違い、すんなり実装ができましたがまだいくつか気になる点が。\n複数の機器とペアリングして切り替え Macともペアリングしてみようとしたのですが、切り替えがうまくいかないようで。。。 OLEDつけるにはどうするんだろう? 左手側は電池が乗っているのですが、右手側はLPME-IOだけなので、上にOLEDを載せる余裕があります。 なので載せてみましたが点かないですね。ファームウェアを何かしないといけないんじゃないかな?調べないとなぁ。 という感じです。 まだちゃんと長時間使っていないので、他の問題点も出てくるかもしれませんが、まぁとりあえず使ってみてからかな。 うまくいくようなら、メインマシンにBluetoothモジュール追加してみるのもありかと考えているところです。\n調べながら、自分なりに対応してみましたが他にもいい方法とかあれば教えてもらえると助かります。\n","date":1610332951,"dir":"post/2021/","id":"4ad8239a37f641bcd17abeb96106314e","lang":"ja","lastmod":1610332951,"permalink":"https://blog.johtani.info/blog/2021/01/11/apply-ble-and-lpme-to-corne/","publishdate":"2021-01-11T11:42:31+09:00","summary":"メインマシンとMacは下記のサンワサプライのUSB接続のKVMスイッチを使っていますが、もう一台ノートPCがありここに接続しているCorne","tags":["DIYキーボード","misc"],"title":"Corne Light v2のBLE+LPME-IO対応 #DIYキーボード"},{"contents":"振り返りブログにも書きましたが、デスクトップPCを自作(DIY)しました。 組み立てたに使ったパーツのアフィリンクを貼っておきます。\n10月くらいにPC組もうと思って、組み上がったのは11月半ばでした。 最初はもうちょっと小さいPCにしようと思ってたのに気づいたらATXになってました。 パーツの選定の基準は以下のツイートです。影響されやすいなぁ。\nタワーってほど大きくなくていいと思いますが、NZXT H510 ぐらいの大きさは欲しいですね。https://t.co/s1c1fOnPyI\n単純に、スペースがないと組みにくいのと冷えにくい、買ってきたものがやっぱりこれだと入らない、というリスクがかなり減るので。\n\u0026mdash; さぼてん(さぼ福)🌵 (@cactusman) October 9, 2020 今年3台作りました。ノートPC使えない体になります。 pic.twitter.com/8zDmeRwNkS\n\u0026mdash; miyake | ZEN (@kazuyukimiyake) October 9, 2020 白いケースいいなぁという感じで、ケースとCPUクーラーが決まったんで、ググってこちらのHAKKAさんのYouTube見ながら妄想してました。 パーツがなかなか揃わなくて。 そして、PCが光るのどうなの?と思ってたのに、気づいたら光ってました(なぜ?)。\nグラボがない状態(CPU内蔵GPU)で12月頭までは動作してました。\n購入自体はTSUKUMO、ビックカメラオンライン、パソコンSHOPアーク、イートレンドオンラインショップでオンラインで購入しました。\nPCケース Amazon | NZXT H510i White CA-H510I-W1 CS7946 | NZXT | PCバッグ・ケース・スリーブ 電源 Amazon | NZXT E850 デジタル電源ユニット 80 Plus Gold 認証 [ 定格 850W 出力 ] NP-1PM-E850A-JP NP-1PM-E850A-JP SP947 | NZXT | パソコン・周辺機器 通販 マザーボード Amazon | ASRock AMD Ryzen 3000シリーズ CPU(Soket AM4)対応 X570チップセット搭載 ATX マザーボード X570 Steel Legend | ASROCK CPU AMD Ryzen 4750G\nCPUクーラー Amazon | NZXT KRAKEN Z63 簡易水冷CPUクーラー 液晶モニタ搭載 RGB対応 280mm RL-KRZ63-01 FN1441 | NZXT | CPUファン 通販 メモリ Amazon | G.SKILL 128GB(4 x 32GB)Trident Z NeoシリーズDDR4 SDRAM 3200MHz PC4-25600デスクトップメモリモデルF4-3200C16Q-128GTZN | G.Skill | メモリ 通販 SSD Amazon | Seagate FireCuda 520 M.2 1TB PCIe Gen4x4 内蔵SSD M.2 2280 3D TLC ZP1000GM3A002 | SEAGATE グラボ Amazon | GIGABYTE NVIDIA GeForce RTX3080搭載 グラフィックボード GDDR6X 10GB ホワイトモデル【国内正規代理店品】GV-N3080VISION OC-10GD | 日本ギガバイト 拡張カード Amazon | ASRock 拡張インターフェースボード Thunderbolt 3 AIC R2.0 | ASROCK | インターフェースカード 通販 拡張カードは実は差し込んだら最初うまく動かなくてサポートに連絡しました。同じ構成の検証機を用意して解決方法を見つけてもらいました。しかも数日で。サイコーのエクスペリエンスでした!\n日本語でサポートしてもらえてしかも数日で解決してもらった。ASRockのサポートすばらしかったです! https://t.co/8FasCInIqt\n\u0026mdash; Jun Ohtani (@johtani) December 8, 2020 その他 ケースのフロントパネルのUSB-Cポートを使えるようにするために。\nAmazon | Cablecc USB 3.1フロントパネルソケットType-E-マザーボード用USB 3.0 20ピンヘッダーオス拡張アダプター | cablecc | PCアクセサリ・サプライ 通販 最近のPCパーツはUSBでモニタリングできるみたいで、マザボのUSBポートが足りなかったので拡張しました。\nAmazon | マザーボードのUSB 9ピン 増設 内部用4ポートUSB2.0 HUB | ノーブランド品 | USBハブ 通販 白いケースだし、「映え」のために白いケーブルを。\nAmazon | Novonest 電源専用延長スリーブ 補助電源モジュラーケーブル 長さ300mm 6本1セット スリーブガイド24点セット付き 【SC304】 | novonest | 電源ユニット 通販 組み立て中 手元にあったCPUでBiosアップデート(Ryzen 5000シリーズにしたかったから。まだできてないけど)。\n応急処置でBiosアップデートしてる pic.twitter.com/mXf2B5kwqB\n\u0026mdash; Jun Ohtani (@johtani) November 8, 2020 さーて、頑張るぞー pic.twitter.com/HmlGqREjmP\n\u0026mdash; Jun Ohtani (@johtani) November 13, 2020 さて、仮起動実験ですよと pic.twitter.com/5HP3cbs6SH\n\u0026mdash; Jun Ohtani (@johtani) November 13, 2020 きたきたー pic.twitter.com/4sL3ymecEo\n\u0026mdash; Jun Ohtani (@johtani) November 13, 2020 コネクター刺しまくらないと pic.twitter.com/Soye3lS4M9\n\u0026mdash; Jun Ohtani (@johtani) November 13, 2020 完成はこんなかんじ 初期構成\n組み上がったよー pic.twitter.com/sBwpvLsZh3\n\u0026mdash; Jun Ohtani (@johtani) November 14, 2020 グラボデプロイ\n設置完了してこんな感じ。なんかベンチマーク走らせるかなぁ。何がいいだろ pic.twitter.com/aZufAE9fJA\n\u0026mdash; Jun Ohtani (@johtani) December 4, 2020 グラボのおまけも付けてみた。\nまぁ、せっかくついてきたので取り付けてみました(グラボ下の光ってるパネル)。 pic.twitter.com/068IxaV1ps\n\u0026mdash; Jun Ohtani (@johtani) December 4, 2020 とまぁ、こんな感じでした。 メモリは多分使い切れないだろうなぁと思いながら、やってみたかったという感じです。。。\n","date":1609422526,"dir":"post/2020/","id":"64a421c2367372c3199c66a6420faf89","lang":"ja","lastmod":1609422526,"permalink":"https://blog.johtani.info/blog/2020/12/31/diy-pc/","publishdate":"2020-12-31T22:48:46+09:00","summary":"振り返りブログにも書きましたが、デスクトップPCを自作(DIY)しました。 組み立てたに使ったパーツのアフィリンクを貼っておきます。 10月くら","tags":["misc"],"title":"PCもDIYしました"},{"contents":"今年も振り返りブログ書いてます。カタンの航海者版を購入して家族とやってましたが、負けてしまいました。\n振り返り(2019年に書いた抱負から) まずは去年の抱負を元に書きますが、3月以降はコロナウィルスの影響でいろいろと生活が変わってしまいましたね。\n職につく 厳密には達成してないことになるのかな?\n1月末にフリーランスはじめました(仮)という記事を書きましたが、 そのまま、現時点では個人事業主でフリーランスとして4社ほどお手伝いさせていただいています。\nお手伝いしてるお客さんの事例が出てた。直接的に類似画像検索の部分を手伝ってるわけではないんですが、Azure Cognitive Searchの調査とかやってます。 / 「ハッカソン」で社外の知見を積極的に活用! 富士フイルムソフトウエアが実践するサービス開発の理想形 - https://t.co/yDIwYmYDBM\n\u0026mdash; Jun Ohtani (@johtani) June 19, 2020 名前出てた。ZOZOさんの手伝いさせていただいております。 / ZOZOTOWNにおける検索速度改善までの道のり - ZOZO Technologies TECH BLOG - https://t.co/OqaFMYe0TY\n\u0026mdash; Jun Ohtani (@johtani) August 20, 2020 こんな感じです。 コロナウィルスの影響もあり、完全リモートで仕事をさせていただいています。 感謝しかないです。\nブログプラットフォームの移行 昨年の振り返りの時点で目を付けていたHugoへの乗り換えを行いました。 乗り換えについてもまとめてあります。\nOctopressからHugoへ移行中(まだ途中) ブログ移行日記(その1) - Hugoとテーマ ブログ移行日記(その2) - Markdownファイルの変換 ブログ移行日記(その3) - Hugoの設定と微調整(テーマに合わせた) ブログ移行日記(その4) - 検索機能(Algolia)の導入 ブログ移行日記(その5) - Jugemのブログを移行 無事移行できて、特に困ってない感じです。\nプログラミング 昨年よりは書いた気がしています。 まぁ、書きなぐって放置してるのもありますが。。。\n細々としたツールがいくつか。\nfrom-octopress-to-hugo bulk2es-rs azure-search-analyze-client wiki-extractor-rs kuromoji-graphviz-output kuromoji-cli あとは、Linderaという形態素解析も手伝ってみました。 ちょっと後半は忙しくなり、コーディングが減ってるんで、また復活させないと。\nRust再入門 Tantivyは結局触れてないけど、Linderaを手伝えました。あとは、ちょっとしたツール(bulk2es-rs)なども作りました。 知り合いとやっていたRust the bookを読むのも一通り終わりました。 Linderaまわりのリファクタとかを年明けにやろうかな?\n検索の勉強 仕事になりました。というか、しました。 ブッチャー本も買ったんですが、手を付けられてないので、年明けから心機一転、よみ始めようと思います。\n検索技術勉強会の継続 残念ながらだめでした。 年初にスピーカーの方に連絡は入れて履いたのですが、コロナウイルスの影響で 今年はオフラインの勉強会は無理だろうとい事で延期したままです。 オンラインの勉強会もいくつか開催されていましたが、検索技術勉強会は残念ながらモチベーションもわかずのまま今年も終わってしまいました。 単に話を聴くセミナーのようなものよりは、Podcastのような形を取るのがいいのかもなぁとは思っているのですが。。。 だれか、サクッと話したい人いたらやってみませんか?\n振り返り(今年あったできごと) さて、ここからは今年の出来事を。\n自宅環境の改善 Windowsへの移行 キーボードDIY フリーランス ブログ書いたなぁ 3月以降はずーっと自宅で仕事してました。 ということで、自宅の環境がどんどんアップデートされていった1年でした。 最終バージョンは年内に間に合わなくて、年明けに書きますが。。。 途中経過はこんな感じでした。今は更に変わっていますが。\n3月バージョン 9月バージョン 12月バージョンでも書きますが、ずっと自宅で作業だったのもあり、自作PCをやりたくなったので、久々にWindowsに帰ってきました。Ubuntuもチョット検討しましたが、Windowsに今は落ち着いています。自作PCはこんな感じ。 自作PCブログも後で書きますね。\n設置完了してこんな感じ。なんかベンチマーク走らせるかなぁ。何がいいだろ pic.twitter.com/aZufAE9fJA\n\u0026mdash; Jun Ohtani (@johtani) December 4, 2020 Windowsをお試し中 Windowsへの移行(その1) AutoHotKeyで色々と弄っているので、素のWindowsは触れる気がしないけど。。。\n自作つながりで、キーボードもDIYしました。\nDozen0を作成した Corne Light v2を作成した Corne Chocolateを組み立てた Sofle Keyboardも組み立てた(けど、ビルドブログはまだ) 分離キーボードには昨年から興味があったのですが、手を付けていませんでした。 今年は自宅でずっと作業でしたから、これを機会に作ってみました。 既製品(Moonlander)も気になってはいたのですが、DIYキーボードはプラモデル感覚で作れそうだし面白そうだなと。 今年一番ハマったものかもしれないです。 知り合いが始めたKochi Keyboardで最初に発売されたのがCorne Light v2だったので、これが初めての分割キーボードです。 40%キーボードからいきなり入ったので最初はかなり大変でしたが、なれると入力が早くなる気がします。ホームポジションからほぼ動かないのはいいですね。最初は数字列がないのでアホか???と思っていましたが。 今は、Sofle(60%キーボード)がメインになっています。40%から60%に移行すると 数字のキーが遠いなと思ってしまいますねw\nどうなるものかと思いつつ、フリーランスを続けています。 最初に仕事をいただいた富士フイルムソフトウェアさんには非常にお世話になっています(今もお手伝いさせてもらっています、ありがたい)。来年も精進していきます!\n今年はブログを書きました、最後はちょっと息切れしてる感じになってるけど。。。 もっとカジュアルに書くようにしないとなぁ。 年明けにまだ書いてないブログを書いていかないと。「自作PCブログ」「Sofleのビルドブログ」「2020年買ってよかったブログ」とか。\n来年の抱負 ということで、来年の抱負です。\nフリーランス継続? プログラミング 検索の勉強 検索のポッドキャスト? とりあえず今年は乗り切れました。来年も食べていくためにもフリーランスを継続できるように、お手伝いさせて頂いてる各社に 継続してもらえるように精進していきます。色々と勉強させて頂いてるのでほんとうにありがたいです。\nプログラミングは今年の後半はスローダウンしてしまったのでがんばらないと。 検証用のコードやちょっとしたツールを書くほうが多いので、もう少し継続してメンテナンスするようなものも書きたいなぁと。\n検索の勉強はまずはブッチャー本を買ってしまったので、ここからでしょうか。 値段も厚みもすごいので、コツコツ元を取れるようにがんばります。。。\n来年もまだまだ自宅で仕事が続きそうなので、勉強会というよりもポッドキャストみたいなものをやるのがいいのかもなと。 2020年初にやらせていただいた、「検索システム探訪」をポッドキャスト風にやるのもありなのかもなぁ。 興味ある人いたら連絡ください。公開しない雑談とかもありだと思ってるので。\n今年は色々ありましたが、無事に乗り切れました。 気軽にランチなどで遊びに行けない状況ですが、雑談相手になっていいなと思う方、連絡お待ちしています。\nさて、来年はどんなキーボード作るのかなぁ(え?また作るの??)。 今後もよろしくおねがいしまーす!\n","date":1609406004,"dir":"post/2020/","id":"a5b2ee641e10d3e4db8f888217ab9ecc","lang":"ja","lastmod":1609406004,"permalink":"https://blog.johtani.info/blog/2020/12/31/looking-back-2020/","publishdate":"2020-12-31T18:13:24+09:00","summary":"今年も振り返りブログ書いてます。カタンの航海者版を購入して家族とやってましたが、負けてしまいました。 振り返り(2019年に書いた抱負から) ま","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2020)"},{"contents":"Elastic stack (Elasticsearch) Advent Calendar 2020の18日目の記事になります。\n本日の勉強会でLTをしましたが、しゃべり足りなかったんで。 Elasticsearch 7.8でこっそりとリリースされたIndex Template V2について調べたのでどんなものかをまとめてみます。 リリースブログには出てきてない(7.8のEsのページのWhat\u0026rsquo;s newには出てた)ので気づいてない人も多いのではないでしょうか?\nIndex Templateとは? まずはIndex Templateがどんなものかを説明しましょう。\nIndexの設定やマッピングはデフォルト値以外を設定したい場合に、毎回\u0026quot;mappings\u0026quot;や\u0026quot;settings\u0026quot;の設定を指定してIndexを作成するのは手間がかかります。 そこで便利な機能として提供されているのがIndex Templateです。このIndex TemplateはCluster Stateに保管されます。\nIndex Templateを利用するときの流れは以下の通りです。\nIndex Templateの作成 Indexの作成 例えば、3ノード構成のクラスターでインデックスを作成するときに常に\u0026quot;number_of_shards: 3\u0026quot;を設定したいとします。 Index Templateは次のような感じになります。\nPUT _template/blog_num_shards { \u0026#34;index_patterns\u0026#34;: \u0026#34;blog_*\u0026#34;, \u0026#34;settings\u0026#34;: { \u0026#34;index\u0026#34;: { \u0026#34;number_of_shards\u0026#34;: 3 } } } または日本語のシンプルな形態素解析のアナライザーの設定を\u0026quot;jp_\u0026ldquo;という名前でるようできるようにしたい場合には次のような感じになります。\nPUT _template/jp_simple_kuromoji { \u0026#34;index_patterns\u0026#34;: \u0026#34;jp_\u0026#34;, \u0026#34;settings\u0026#34;: { \u0026#34;index\u0026#34;: { \u0026#34;analysis\u0026#34;: { \u0026#34;simple_jp\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;custom\u0026#34;, \u0026#34;tokenizer\u0026#34;: \u0026#34;kuromoji\u0026#34; } } } } } インデックステンプレートの登録が終われば、インデックスを作成するタイミングでIndex Templateが適用されます。 例えば、blog_2020というインデックスを作成すると、number_of_shards: 3のインデックスが作成されます(デフォルトは1)。 jp_blog_2020というインデックスを作成すると、simple_jpというAnalyzerが設定されています。 このように、インデックス名を意識するだけで設定が適用されていくのが利点です。\nちなみに、Index TemplateはIndex作成時に適用されるだけなので、Index Templateを変更してもこれまでのインデックスへは影響はありません。\nこれまでのIndex Templateの問題点 と、Index Templateが便利なのはわかりましたが、ではなぜ今回V2がリリースされたのでしょうか? 先ほどの例を見るとわかりますが、これまでのIndex Templateは部品化が難しいのが問題でした。 Index Templateはそれぞれがインデックスの作成時に適用されます。 が、Index TemplateにIndex Templateを組み込むことはできません。 例えば、先ほどサンプルとして作成したjp_simple_kuromojiのIndex Templateはjp_で始まるインデックスにしか適用できません。\nでは、blog_で始まるインデックスにもkuromojiのシンプルなアナライザーを使いたくなった場合はどうなるでしょう? 残念ながら、jp_simple_kuromojiと同じ設定をblog_num_shardsのテンプレートに追加するか、jp_simple_kuromojiのindex_patternsの部分だけを書き換えた新しいテンプレートを用意するか、jp_simple_kuromojiのindex_patternsにjp_を追加する方法です。 いずれにしてもIndex Templateの継承(複数のテンプレートを1つのインデックスに紐づける)が必要となります。 この時、複数のIndex Templateが適用されるため、適用する順番が出てきます。 この順番をIndex Templateのorderパラメータで指定できます。\nただ、これも問題のもととなっていました。 複数あるIndex Templateのどれがどの順番で適用されるのか?それはインデックスを作成時にようやくわかります。 使いたい側(インデックス)が、使いたいもの(テンプレート)を指定するのではなく、その逆(使いたいものに使いたい側の情報を設定しなくてはならない(index_patternsやorder))になっているのでわかりにくくなっていました。\nということで解決策としてリリースされたのがIndex Template V2です(ちなみに名前にV2とは言ってるわけではなく、現在のIndex Templateの機能がlegacy index templateという名前になり、Deprecatedになっています(まだログには出ない))。\nIndex Template V2 7.8のWhat\u0026rsquo;s newドキュメントではComposable Index Templateと紹介されています。 大きく3つのエンドポイントが提供されます。\nComponent Template 用API テンプレートのコンポーネントという単位で管理するためのAPI。 登録更新、削除、取得が可能 Index Template 用API Index Templateを管理するためのAPI 登録更新、削除、取得が可能 Simulate index template API(Experimental) Index Template Legacy Index Templateとの大きな違いは、\nテンプレートをコンポーネントにできる 1つのインデックスに適用されれるテンプレートは1つだけ という点です。これまでとは挙動が異なるので注意が必要です。\n新しいIndex Templateを利用する際の流れは次のようになります。\nComponent Templateの作成 Index Templateの作成 作成したIndex Templateの挙動を確認 実際にIndex名を指定してIndex Templateの挙動を確認 という形です。では、それぞれの機能を見ていきましょう。\nCoponent Template API テンプレートコンポーネントを管理するためのAPIです。 具体的なAPIごとに説明していきます。\nPUT _component_template コンポーネントを登録、変更するためのAPIです。公式ドキュメントはこちらです。 先ほどのkuromojiのAnalzyerをコンポーネントとして登録してみましょう。\nPUT _component_template/jp_simple_kuromoji { \u0026#34;template\u0026#34;: { \u0026#34;settings\u0026#34;: { \u0026#34;index\u0026#34;: { \u0026#34;analysis\u0026#34;: { \u0026#34;analyzer\u0026#34;: { \u0026#34;simple_jp\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;custom\u0026#34;, \u0026#34;tokenizer\u0026#34;: \u0026#34;kuromoji_tokenizer\u0026#34; } } } } } }, \u0026#34;version\u0026#34;: 1, \u0026#34;_meta\u0026#34;: { \u0026#34;description\u0026#34;: \u0026#34;simpleなKuromoji analyzer\u0026#34; } } 先ほどと特に違いはありません。templateという階層が1段増え、index_patternsがなくなりました。 template部分はIndexに設定するsettings、mappings、aliasesが指定可能です。 ちなみに、\u0026ldquo;template\u0026quot;の中身をそのままIndex作成時に使用した場合にエラーにならない設定である必要があります。 ここは注意が必要です。例えば、component Aでkuromojiのアナライザーの設定をし、component Bでそのアナライザーを使用するフィールドのmappingだけを記述した場合、component Bでエラーが発生します。上記のようなシチュエーションでは、Index Templateで利用するフィールドを定義し、component Aを利用する宣言をすれば問題ありません。\nそのほかに使えるパラメータで便利なものを紹介しておきます。\nクエリパラメータ\ncreate: URLに指定するパラメータ。trueを指定することで、既に存在する場合にエラーを返してくれる。更新も同じAPIなので間違わないようにするために利用すると便利。デフォルトはfalse リクエストボディ\n_meta: テンプレートにメタ情報を付与できる。_metaの中は自由に記述可能。コメントなどを書いておくとあとでわかりやすい GET _component_template コンポーネントを取得するためのAPIです。公式ドキュメントはこちらです。 一覧での取得とリストでの取得が可能です。\n一覧取得サンプル\nGET /_component_template GET /_component_template/* これ以外に、IDを指定して取得することも可能です。\nGET _component_template/jp_simple_kuromoji *を利用して複数取得も可能です。\nGET _component_template/jp* GET _component_template/j*_* DELETE _component_template コンポーネントを削除するためのAPIです。公式ドキュメントはこちらです。 IDを指定してコンポーネントを削除できます。\nDELETE /_component_template/jp_simple_kuromoji ID指定以外に*を利用することも可能ですが気を付けて使用しましょう。\nDELETE /_component_template/jp_* DELETE /_component_template/* ちなみにIndex Templateで利用されているコンポーネントを削除しようとした場合はエラー(ステータスコード400)が返ってきます。 *などを使用して削除しようとした場合は、ひとつでも利用されているものが含まれている場合は削除は実行されずにエラーだけが返ってくるようになっています。\nIndex Template API Index Templateを管理するためのAPIです。 Component Template APIで定義したコンポーネントを利用してテンプレートを作成できます。コンポーネントを利用しないで単体で完結したテンプレートも作成可能です。 具体的なAPIごとに説明していきます。\nPUT _index_template Index Templateを登録・更新するためのAPIです。公式ドキュメントはこちらです。\nこれまでのLegacy Index TemplateのAPIのエンドポイント(_template)ではなく、(_index_template)というエンドポイントになっていることにまず注意してください。 先ほど作成したjp_simple_kuromojiコンポーネントと、追加で作成した3_shardsというコンポーネントを利用して blog_で始まるインデックスに適用できるIndex Templateを作成してみましょう。\nPUT _index_template/blog_template { \u0026#34;index_patterns\u0026#34;: [\u0026#34;blog_*\u0026#34;], \u0026#34;template\u0026#34;: { \u0026#34;mappings\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;hoge\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;simple_jp\u0026#34; } } } }, \u0026#34;priority\u0026#34;: 100, \u0026#34;composed_of\u0026#34;: [\u0026#34;jp_simple_kuromoji\u0026#34;, \u0026#34;3_shards\u0026#34;] } composed_ofというパラメータに利用したいコンポーネントを配列で記述していきます。 Index Templateが適用される時に、ここに記述されている順番でコンポーネントが適用されていきます。 ですので、最後に書いてあるテンプレートが一番強いことになります。 これは例えば、同じ設定値number_of_shardsを2つのコンポーネントが設定している場合に、最後に設定した値がインデックスに採用されるという意味です (公式ドキュメントにサンプルが掲載されています)。 なお、存在しないコンポーネントをcomposed_ofに指定した場合は400エラーが返ってきます。同じコンポーネントを複数重複して指定した場合は特にエラーにはなりませんでした。 composed_ofを指定しなければ、単体で完結したテンプレートを定義可能です。\n次に重要な設定はpriorityです。これまでのテンプレート機能と異なる点で説明しましたが、\n1つのインデックスに適用されれるテンプレートは1つだけ となっています。 この1つを決めるための値がpriorityになります。 インデックス名によってはindex_patternの定義によって、複数のIndex Templateにマッチします。例えばblog_*と*_2020のIndex Templateがあった場合にblog_2020というインデックスを作った場合です。 この時、Elasticsearchはpriorityの大きい値を持ったIndex Templateだけを適用します。 blog_*のIndex Templateのpropertyが10、*_2020のIndex Templateのpropertyが100だった場合、*_2020のテンプレートが適用されます。Legacy Index Templateではorderという似たパラメータがありましたが、こちらは適用する順序を決定するためのものでした。挙動が違うので注意しましょう。\nちなみに、blog_*と*_2020のpropertyがどちらも10というIndex TemplateをPUTしようとした場合、2番目にIndex TemplateをPUTするタイミングでエラーが返ってきます。\nそのほかに使えるパラメータで便利なものはPUT _component_templateと同様にcreateと_metaです。\nGET _index_template Index Templateを取得するためのAPIです。公式ドキュメントはこちらです。 一覧での取得とリストでの取得が可能です。\n一覧取得サンプル\nGET /_index_template GET /_index_template/* これ以外に、IDを指定して取得することも可能です。\nGET _index_template/blog_template *を利用して複数取得も可能です。\nGET _index_template/blog_* GET _index_template/b*_* DELETE _index_template Index Templateを削除するためのAPIです。公式ドキュメントはこちらです。\nIDを指定してコンポーネントを削除できます。\nDELETE /_component_template/jp_simple_kuromoji ID指定以外に*を利用することも可能ですが気を付けて使用しましょう。\nDELETE /_component_template/jp_* DELETE /_component_template/* 最後のサンプルを実行すると、Elasticのツールなどが登録したIndex Template以外はすべて削除されてしまうので本当に気を付けましょう。\nSimulalte API さて、コンポーネントとテンプレートを作成したので確認をしましょう。 Legacy Index Templateでは確認するためには実際にインデックスを作成するしかありませんでしたが、V2ではSimulate APIが用意されています。 このSimulate APIには2つのAPIがあります。\nPOST /_index_template/_simulate/\u0026lt;テンプレート名\u0026gt; POST /_index_template/_simulate_index/\u0026lt;インデックス名\u0026gt; Index Templateの確認のためのAPIとインデックス名を指定したときに出来上がるIndexの設定を確認するためのAPIです。 Indexを実際に作成しなくても確認できるのは便利ですね。\n例えば先ほど作成したblog_templateを試してみましょう。\n_index_template/_simulate API POST _index_template/_simulate/blog_template レスポンスはこんな感じです。\n{ \u0026#34;template\u0026#34; : { \u0026#34;settings\u0026#34; : { \u0026#34;index\u0026#34; : { \u0026#34;analysis\u0026#34; : { \u0026#34;analyzer\u0026#34; : { \u0026#34;simple_jp\u0026#34; : { \u0026#34;filter\u0026#34; : [ \u0026#34;kuromoji_readingform\u0026#34; ], \u0026#34;type\u0026#34; : \u0026#34;custom\u0026#34;, \u0026#34;tokenizer\u0026#34; : \u0026#34;kuromoji_tokenizer\u0026#34; } } }, \u0026#34;number_of_shards\u0026#34; : \u0026#34;3\u0026#34; } }, \u0026#34;mappings\u0026#34; : { \u0026#34;properties\u0026#34; : { \u0026#34;hoge\u0026#34; : { \u0026#34;type\u0026#34; : \u0026#34;text\u0026#34;, \u0026#34;analyzer\u0026#34; : \u0026#34;simple_jp\u0026#34; } } }, \u0026#34;aliases\u0026#34; : { } }, \u0026#34;overlapping\u0026#34; : [ { \u0026#34;name\u0026#34; : \u0026#34;blog_template2\u0026#34;, \u0026#34;index_patterns\u0026#34; : [ \u0026#34;blog_*\u0026#34; ] } ] } templateにコンポーネントがマージされた結果が出力されます。 overlappingはindex_patternsがかぶる可能性があるIndex Templateの情報が出力されます。 サンプル用にblog_template2という、同じindex_patternsでpriorityが低いものを登録してあるためです。 index_patternsが完全に同じではなくとも、重複する可能性があるものはここに出力されます。 例えば、index_patternsがb*という別のIndex Templateを作成してからSimulate APIを実行すると、overlappingにそのIndex Templateも出力されます。\nSimulate Index Template APIのもう一つの機能は登録前のIndex Templateの確認です。 リクエストのURLのテンプレート名をなくし、PUT _index_templateと同じJSONをリクエストボディとして送信した場合、コンポーネントをマージしたテンプレートがどんなものかを確認できます。\nPOST _index_template/_simulate { \u0026#34;index_patterns\u0026#34;: [\u0026#34;blog_*\u0026#34;], \u0026#34;template\u0026#34;: { \u0026#34;mappings\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;hoge\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;text\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;simple_jp\u0026#34; } } } }, \u0026#34;priority\u0026#34;: 10, \u0026#34;composed_of\u0026#34;: [\u0026#34;jp_simple_kuromoji\u0026#34;] } このリクエストを送信すると、コンポーネントがマージされた結果が返ってきます。index_patternsがかぶるものがある場合はoverlappingも一緒に返却されます。\n_index_template/_simulate_index API 今度はインデックス名を指定するSimulate APIを試してみましょう。\nPOST _index_template/_simulate_index/blog_2021 これだけです。\n{ \u0026#34;template\u0026#34; : { \u0026#34;settings\u0026#34; : { \u0026#34;index\u0026#34; : { \u0026#34;analysis\u0026#34; : { \u0026#34;analyzer\u0026#34; : { \u0026#34;simple_jp\u0026#34; : { \u0026#34;filter\u0026#34; : [ \u0026#34;kuromoji_readingform\u0026#34; ], \u0026#34;type\u0026#34; : \u0026#34;custom\u0026#34;, \u0026#34;tokenizer\u0026#34; : \u0026#34;kuromoji_tokenizer\u0026#34; } } }, \u0026#34;number_of_shards\u0026#34; : \u0026#34;3\u0026#34; } }, \u0026#34;mappings\u0026#34; : { \u0026#34;properties\u0026#34; : { \u0026#34;hoge\u0026#34; : { \u0026#34;type\u0026#34; : \u0026#34;text\u0026#34;, \u0026#34;analyzer\u0026#34; : \u0026#34;simple_jp\u0026#34; } } }, \u0026#34;aliases\u0026#34; : { } }, \u0026#34;overlapping\u0026#34; : [ { \u0026#34;name\u0026#34; : \u0026#34;fuga\u0026#34;, \u0026#34;index_patterns\u0026#34; : [ \u0026#34;b*\u0026#34; ] }, { \u0026#34;name\u0026#34; : \u0026#34;2021\u0026#34;, \u0026#34;index_patterns\u0026#34; : [ \u0026#34;*_2021\u0026#34; ] } ] } 例で作成したblog_templateが適用されていますが、それ以外にindex_patternsに合致したがpriorityが低くて適用されなかったものがoverlappingに出力されています。 実際に適用されたテンプレートの名前も別途出力してくれるとわかりやすいかもしれないですね。 (*_2021というインデックスパターンのテンプレートを試しに作ってみたのですが、これはバグがありそうです。2021に合致するインデックス名をSimulateしたらoverlappingに合致しないものがたくさん出てきました。バグ報告しとくか)。\nKibana対応 ここまで、Index Template V2のAPIの説明でしたが、Kibanaでの対応についても調べてみました。\nIndex Management(Stack Management機能。Elasticライセンスが必要だが無償の機能) 7.9からKibanaのIndex管理画面でComposable Templateが利用できるようになっています(GitHub Issue)。 画面のスクショを一通り貼っておきます。残念ながら、それぞれのJSONの編集部分では補完などはサポートされていないようでした。 頑張って自分でsettingsやmappingsのJSONを記述していく感じになります。JSONとして正しいかどうかはチェックしてくれます。 Index Templateのウィザードでは、ボタンでコンポーネントを追加したり削除したり、順序を入れ替えたりといった作業が可能になっています。 また、プレビュー表示が可能なので、composed_ofで選択したものが今どのように適用されているか?といったのも確認できるようになっていました。 結構便利に管理できそうです。ちなみにスクショは7.10の画面になります。\nComponent Template周り 一覧表示とウィザード Index Template周り 一覧表示とウィザード Console(Dev Tools。OSSで利用可能) リクエストを実行は可能ですが、自動補完機能は一部のみ対応しているようです(GitHub Issue)。\n対応済みの機能\nDELETE _component_template (ただし、ここまで。存在するコンポーネント名は補完されない) 上記以外はまだ未対応のようです。 プルリクエストチャンスかも?\n参考 Composable Templates · Issue #53101 · elastic/elasticsearch What’s new in 7.8 | Elasticsearch Reference [7.8] | Elastic Index management | Elasticsearch Reference [7.10] | Elastic [Composable template] Create / Edit wizard by sebelga · Pull Request #70220 · elastic/kibana [Console] Support suggesting index templates v2 · Issue #75967 · elastic/kibana まとめ ちょっと長くなってしまいましたが、新しいIndex Templateについての紹介でした。 これまでと違い、複数のテンプレートが適用されない点があるのでそこは注意が必要そうです。 コンポーネントをうまく使えば、管理が簡易化はされそうですね。\n","date":1608216955,"dir":"post/2020/","id":"c6fc88bd57a0e57ddf22e2eb1bef892c","lang":"ja","lastmod":1608216955,"permalink":"https://blog.johtani.info/blog/2020/12/17/index_template_v2/","publishdate":"2020-12-17T23:55:55+09:00","summary":"Elastic stack (Elasticsearch) Advent Calendar 2020の18日目の記事になります。 本日の勉強会でLTをしましたが、しゃべり足りなかったんで。 Elasticsearch 7.8でこっそりとリリースされたI","tags":["elasticsearch"],"title":"Index Template V2"},{"contents":"はじめまして、pyspa。 ということで、pyspa Advent Calendar 2020の4日目(大谷コンビの2号)の投稿になります。 コンビそろってキーボード記事ですね。\n今年はDIYキーボードにはまった(はめられた?)年でした。 もともと分割キーボードには興味があり、自宅で作業するのが基本となったのもあり手を出した次第です。 まだまだ使いこなすところまでは来てないかもしれないですが、組み立てたり、問題点のキリ分けしたり、試行錯誤するのは楽しいなと。\n今回はCorne Chocolateというキーボードを組み立てたのでそちらのビルドログ(かつ今後のための教訓)になります。 LEDを使ったキーボードがどんなものなのか+薄いキーボードも気になるなということで取り組んでみました。 今回もいくつか失敗をしつつ、リカバリーして動くものができました。\nパーツ(材料) 基本のパーツは今回もKochi Keyboardさんから購入しました。\nキット : Corne Chocolate(ベースキット) キースイッチ : Kailh Choc v1 Blue (25gf リニア) 5個 キーキャップ : Kailhロープロ刻印キーキャップ ケーブル類は家に転がっていたケーブルを利用しました。 キースイッチセットもあるのですが、軽いキータッチが好みなので、一番軽いKailh ChocのBlueを試してみたくキースイッチを個別に選択しました。 キーキャップはShiroを作るときに調達していたものを利用した形です。\n今回も公式のビルドガイドにざっと目を通してから着手しました。\n準備 ビルドログにもあるようにPCBがリバーシルブなので、作業中に迷子にならないようにこんな感じで表にマスキングテープで目印をつけておきました。\n今回から耐熱ワーキングマットで作業をすることにしました。机の天板に傷つくの嫌だし。 気兼ねなくはんだできるのでおすすめです。\nhttps://t.co/0qntPD8qIa\n2ヶ月ぐらいにここで買いました!\n\u0026mdash; 西田和史(k.bigwheel) 開発基盤EM (@k_bigwheel) November 11, 2020 ダイオード、OLEDソケット、コンスルー、TRRSソケット、 こちらは前回のCorneとほぼ同様だったのでビルドガイド通りに進めます(写真撮り損ねました。。。) 前回との違いはダイオードの形です。 表面実装するタイプのダイオードなので向きに気を付けつつ、つけていきます。\nビルドガイドに向きやダイオードのつけ方が紹介されています。 拡大鏡とピンセット必須ですね。 前回同様に、ここまででいったんqmk_toolsでファームウェアをインストールして、ピンセットを使いながらキーの認識とOLEDの動作確認を行いました。 今使っているファームウェアがあるのでそれを入れて問題ないかを確認しました。\nLED実装 今回のメインイベントです(そして苦杯をなめたイベントでもあります)。 ビルドガイドにも記載がありますが、信号が流れる順番があるようなので1番から取り付けていきます。 また、ビルドガイドにLEDに関する注意事項もいくつか掲載されています。必ず読みましょう。\nこの1~6までのLEDがすごく大変でした。。。\n表面実装のLED(Underglow LED)で四苦八苦 いくつかのブログを参考にしながら作業を進めました。\nコルネキーボードを作りました ~LED取り付けに四苦八苦記~ | キオクノロンダリング SK6812miniの仕様などについて書いてあります。デバッグするのにすごく役に立ちました。 Corne Chocolateビルドログ - nokの雑記 手書きでどんな感じでやればいいのかを解説してくれています。最終的にはこの方法が一番だったのかも? 自作キーボードキット「Corne Cherry」のレビュー - 自作キーボード温泉街の歩き方 あとで出てきますが、リカバリ方法の参考になりました。 皆さん苦労されてますね、そして私も苦労しました。。。\n試してみた方法、考察は次の通りです。\nLEDチェック用のファームウェアをインストールして1つつけては動作確認 HelixのLEDテスト用ファームウェアをインストールしました。 白光 1C型こて先 失敗した後にリカバリするために購入しました。 LEDのランドなどが2Cよりも面積が小さいので、そのサイズに合わせたこて先のほうがよかったようです。 はんだの温度(温調できるはんだごて必須) 最初は250℃でやっていましたが、なかなかはんだが溶けません。そのせいで焦りも出てきます。 最終的には270度で作業しましたが、温度のせいでLEDが壊れたのはなかった気がします。1Cのこて先だったので無事だったのかもしれません。 フラックスなし あると楽だったのかも?残念ながら試してないです。 予備はんだ手法(だめっぽかった) 基盤のランド4か所に予備はんだをし、はんだを温めつつLEDを乗せる方法 LEDの裏にも予備はんだ どちらも試してみましたが、温めている個所以外のはんだと高さの違いが出てしまい、LEDが浮いてしまいます。4か所を同時に温めることはできないので、すこしずつ調整しているうちにLEDを物理的に壊してしまうことがありました。。。 ちょっとコツが分かったかも? pic.twitter.com/ruwrmEWCAe\n\u0026mdash; Jun Ohtani (@johtani) November 19, 2020 わかった気になっていますが結局失敗しました。。。\n結局最後までこれというコツはわかってない気がします。結局3つか4つのLEDがお亡くなりになりました。 うまくいかなかった原因は、予備はんだで傾きなどができ、それを修正していくうちに基盤やLEDにダメージを与えてしまったのだと思います。\nよく見ると基盤が一部剥がれかけてるのがわかるかなぁと。\nリカバリー 右手側の表面実装の4番と5番が失敗しました。\n4番目(以下のツイート右側画像の上) こちらは、1度付けたLEDをはがすときにはんだを取り除くのが不十分な状態でLEDをはがしたために、基板のランドごとはがれてしまいました。 なのでここはLEDはつかないです。。。 5番目(以下のツイート右側画像の真ん中あたりの黄色い線がつながっているLED) LED自体はつけてありますが、青色しか発光しなくなっています。 4番目が完全に死んでしまったので、無事な3番目のLEDのDINに流れている信号を 5番目のLEDのDINにも流れるようにするために10芯コードでショートカットさせました。 (リカバリ方法は先ほど紹介したブログが非常に参考になりました、先人の知恵ありがたし)。 黒い線も売っていたのですが、自戒も込めて目立つ色にしてみました。\n勉強させていただきました、、、 pic.twitter.com/Zp16fJKziM\n\u0026mdash; Jun Ohtani (@johtani) November 22, 2020 ちなみに、左側のショートカットのコードはつけた後に1か所LEDの向きが違うことに気づき必要なくなっています (上記の基盤が傷ついている画像をよく見ると上下が逆になってるのがわかる人にはわかるかも)。\n片方は導線なくて良くなった。表から見たら向きが違うのに気がついたわ、、、 pic.twitter.com/7TSDMPPxlX\n\u0026mdash; Jun Ohtani (@johtani) November 22, 2020 最終的に2か所おかしいLEDにはなりましたが、幸いにもアンダーグローです。 Kochi Keyboardさんで購入したキットのボトムプレートはFR4なのでほぼ見えません!(負け惜しみ)\nソケット さて、気を取り直してソケットをつけていきます。 Dozen0にて経験済みなのでそれほど手間はかかりませんでした。 LEDの失敗の時に1Cのこて先を購入していたため、ソケットの横の隙間からこて先が差し込めたのが便利でした(LEDでダメージを受けていたのもあり写真撮り忘れ)。\n完成 ということで完成です。デフォルトで赤く光ってます。キーキャップがLEDを透過してくれるタイプだったのがこれまたよかったですね。 作る前は光らなくてもなんて思ってたのに。\nキーマップ(v2) Corne Lightで作業を数週間ほどして、いくつか入力しにくい部分があったのでマッピングを少しだけ変えました。 相変わらず日本語キーボードベースですが、数字のレイヤーにいくつかの記号を使えるように割り当てました。 コーディングをするときに、ライブラリのバージョン(例:7.10.0とか)やIPアドレスを入力していてレイヤー切り替えのためのキーを押したり話したりするのは効率が悪すぎたためです。 数字との組み合わせでよく使いそうな以下のキーを数字のレイヤーに移動しました。\nセミコロン(JP_SCLN) コロン(KC_QUOT) アンダースコア(JP_UNDS) コンマ(KC_COMM) ピリオド(KC_DOT) スラッシュ(KC_SLSH) #include \u0026#34;keymap_jp.h\u0026#34; const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [0] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, JP_MINS, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, JP_SCLN, KC_QUOT, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, MO(1), KC_SPC, KC_ENT, MO(2), KC_RALT //`--------------------------\u0026#39; `--------------------------\u0026#39; ), [1] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LCTL, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_LEFT, KC_DOWN, KC_UP,KC_RIGHT, JP_SCLN, KC_QUOT, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LSFT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, JP_UNDS, XXXXXXX, KC_COMM, KC_DOT, KC_SLSH, XXXXXXX, //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, _______, KC_SPC, KC_ENT, MO(3), KC_RALT\\ //`--------------------------\u0026#39; `--------------------------\u0026#39; ), [2] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. KC_TAB, JP_EXLM, JP_DQUO, JP_HASH, JP_DLR, JP_PERC, JP_AMPR, JP_QUOT, JP_LPRN, JP_RPRN, JP_CIRC, KC_BSPC, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LCTL, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, JP_MINS, JP_EQL, JP_LBRC, JP_RBRC, JP_YEN, JP_AT, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LSFT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, JP_UNDS, JP_PLUS, JP_LCBR, JP_RCBR, JP_PIPE, JP_TILD, //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, MO(3), KC_SPC, KC_ENT, _______, KC_RALT //`--------------------------\u0026#39; `--------------------------\u0026#39; ), [3] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. RESET, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,\\ //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| RGB_TOG, RGB_HUI, RGB_SAI, RGB_VAI, RGB_SPI, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,\\ //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| RGB_MOD, RGB_HUD, RGB_SAD, RGB_VAD, RGB_SPD, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,\\ //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, _______, KC_SPC, KC_ENT, _______, KC_RALT\\ //`--------------------------\u0026#39; `--------------------------\u0026#39; ) }; LEDの色が変えられる!(気づくの遅い) あと、キーマップを変更しているときに4つ目のレイヤーにRGBなどのボタンがあるのに気付いて押してみたら、LEDのパターンや色を変えることができるのに気付きました。 (遅すぎでは。。。)\nキーキャップが白いのもありこんな感じの色にしてみています。\nユニコーンガンダムっぽくなった pic.twitter.com/vHxZkMrYyP\n\u0026mdash; Jun Ohtani (@johtani) November 28, 2020 まとめ ということで、失敗も多々ありましたがキーボードとしてはちゃんと動くできたものができたので安心しました。 今後、状況が落ち着いてきて自宅以外で仕事をするときにはCorne ChocolateをPCと一緒に持ち歩くと思います。 薄くて邪魔にならなくてよさそうです。\n今回もはんだっしゅ太郎大活躍でした。本当に買ってよかった。 LEDがつかないときはちょっと落ち込みましたが、これのおかげで立ち直れたのもありますし。 あとは、試行錯誤しつつLEDとかの理解ができたのも楽しかったです。 キーマップの変更時にLEDの変更などができるのに気づいたのはちょっと遅すぎたので、qmkの仕組みや割り当てられるキーにどんなものがあるのかをもう少し研究したいなと思います。\nさて、次はどんなことを試すかなぁ。\n","date":1607004824,"dir":"post/2020/","id":"a46c601d03a3a26bc418d0096fe83a42","lang":"ja","lastmod":1607004824,"permalink":"https://blog.johtani.info/blog/2020/12/03/build_corne_choc/","publishdate":"2020-12-03T23:13:44+09:00","summary":"はじめまして、pyspa。 ということで、pyspa Advent Calendar 2020の4日目(大谷コンビの2号)の投稿になります。 コンビそろってキーボード記事です","tags":["DIYキーボード","misc"],"title":"Corne Chocolateを組み立てた #DIYキーボード"},{"contents":"前回のブログのまとめに書いたように、セパレートタイプのキーボードであるCorne Light v2を作成したのでそのビルドログです。DIYキーボードとしては2つ目になります。\nまとめで書いていたお店が開店したので、購入してみました。 購入したのはこちらのKOCHI KEYBOARDさんです。 ついこの間オープンしたばっかりのお店です!\nなんで作ったの? スプリット型(セパレートタイプ?どっちが正しいんだろう?)のキーボードに興味があって、KOCHI KEYBOARDさんで買えたのがこれだったというのが大きな理由です。こういうのってタイミングだと思うので。 あとは、組み立てていくのがプラモデルみたいで面白いというのもあります。 基本的にここのところ自宅で仕事をしているので、ノートPCのキーボードにこだわる必要もないなというのも理由ですね。今後も当面は自宅で仕事になると思いますので。\nCorne Light v2 foostanさんが設計された(って言い方であってるのかな?)、3x6のサイズに親指の3キーが配置された分離型のキーボードの一種です。 シリーズ?の名前としてはCorne Keyboardと呼ばれています。 (そういえば、由来は何だろう?自作キーボードがどうやって設計されていくのかという流れがまとめられた作者の方のブログがおもしろいです。) また、基板の設計などがGitHub上でMITライセンスで公開されています。 オープンソースなハードウェアというのも面白いです。\nビルドログ 作者の方がビルドガイドを公開してくれています。ですので、こちらに沿って作業をしていきます。 ちなみに、私は今回Gateronのクリア軸を選択してみました。さらさらと入力できるのが好きなので。 サイレント軸にも興味はあるのですが、今回は実際にスプリット型のキーボードを早く触ってみたいというのが勝ちました。キーキャップについては後述します。 ツイートに都度、写真をアップしていたので組み立ては画像でお楽しみください(時々取り忘れてるけどw)。\nうむ pic.twitter.com/svW9WdzaZv\n\u0026mdash; Jun Ohtani (@johtani) October 21, 2020 刺して曲げる pic.twitter.com/M0jfQJg2k8\n\u0026mdash; Jun Ohtani (@johtani) October 22, 2020 両方できたと。ハンダまでやって今日はおしまいにすっか pic.twitter.com/HgsSrxqpcg\n\u0026mdash; Jun Ohtani (@johtani) October 22, 2020 写真取り忘れたけど、ProMicroつけた pic.twitter.com/RS4z0lqsUZ\n\u0026mdash; Jun Ohtani (@johtani) October 22, 2020 OLEDもついたと。今日はここまで pic.twitter.com/p6Z8MMP0Xz\n\u0026mdash; Jun Ohtani (@johtani) October 22, 2020 ここまでは順調です。\nOLEDがつかない? ビルドガイドに従って、この後キースイッチをつけちゃうと問題の切り分けが難しくなるということで、 ここまでの段階でQMK Toolboxを使ってProMicroにファームウェアを書き込んで、それぞれのキーのソケットの取り付け部をピンセットでショートさせつつ、キーが入力されるかどうかを見ていきます。 QMK Toolboxについてはサリチル酸さんのブログがわかりやすいので参考にさせていただきました(わかりやすい記事をありがとうございます)。 で、ビルドガイドにあるように動いてるかを確認しようとしたのですが。。。\nさて、ファームウェア書き込んだけど、OLEDがつかないな。どっかつながってないのか?\n\u0026mdash; Jun Ohtani (@johtani) October 24, 2020 ビルドガイドのようにはいかず。。。 USBでPCとつないだ状態で、QMK Configuratorをサイトで開いて、キーボード入力テストを開くと、ショートさせたキーがPC側で認識されているかのテストができます。 これで、一通りキーは認識できていそうだというのはピンセットでショートさせながら確認しました。 ただ、OLEDには何も表示されないんです。。。\n前回Dozen0を組み立てた時に、ソケットのはんだ付けが甘かったというのもあったので、 OLEDやソケットのはんだを温めなおしたりしてみて、何度か確認してみたものの特に進展がなしです。 (ちなみにうまくいかないのもあって、ぼけたツイートしたりもしてます。)\nまぁ、OLEDはビルドガイドを見てもオプション扱いなので、それよりも触ってみたい衝動に駆られて、 キースイッチをはんだ付けしていきます。\nちなみに昨晩、OLEDはとりあえず置いといてって感じでキースイッチつけてた。キーキャップはまだない pic.twitter.com/SzLmzNg60Y\n\u0026mdash; Jun Ohtani (@johtani) October 26, 2020 それも終わって、問題点の切り分けに何かできないかな?と思ってやったのがOLED単体でArduinoと接続してみて動くかどうかです。 Qiitaにちょうどいい感じの記事を見つけたのでこれまた参考にさせていただきました(4本のジャンパー線を一人で持ちながら確認するの大変だったw)。\nはんだでの修正にしっぱい で、自分の中での結論として、「OLEDソケットのはんだ付けが怪しい」となりました。 そこで、まずは外してみようかと思ったのが間違いでした。 はんだごてとはんだ吸い取り線で何とか外せるだろうと思っちゃったんですよ。 OLEDピンソケットは足が4本あって、とりあえずとれるところまではんだ吸い取り線で吸い取ってみましたが、 さすがに基盤の穴に流れ込んだはんだまでは吸い取れず、頑張って温めながらソケットを抜こうとがんばって、 ラジオペンチでピンソケットを引っ張りながら引き抜きました。かろうじて引き抜きはできたのですが、ソケットは足が折れてしまいました。\n作者登場(OLED問題の解決) そんなところにCorneの作者の方がツイートを拾ってくれたみたいで以下のような返信を頂きました。\nOLEDが点かないのはファームのせいかもしれません(最近以前のファームで動かない新しいタイプのOLEDモジュールが出回るようになりました)。お手数ですが、https://t.co/vfSBfIeeJX のブランチのものを試して頂けますか?(ただいまPRレビュー中でまだマージされていない状態です)\n\u0026mdash; c7s (@foostan) October 25, 2020 暗闇に光明とはこのことです。 教えていただいたブランチを手元でビルドしてファームウェアを書き込むと、\nすごい、出ました!右側のディスプレイにロゴが。ありがとうございます(左側のOLEDはソケットのはんだ付け直し失敗したのでもうちょっと先になりますが)!\n\u0026mdash; Jun Ohtani (@johtani) October 26, 2020 なんと、ファームウェア書き込んだ瞬間にOLEDが点くじゃないですか。 感謝感激ってやつです。お礼を言うのに便乗してOLEDの問題の切り分けの方法についても聞いてしまいました。\nOLEDリベンジ 片側は無事だったのですが、もう一方は修復が困難になったので救世主を発注します。 自作キーボードの作成に便利なものリストとして、いくつかのブログに上がっていたのですが、必要ないだろうと見送っていたツールです。\nAmazon | サンハヤト はんだシュッ太郎NEO 45Wタイプ HSK-300 | ハンダゴテパーツ 本当にすごく使いやすかったです。 OLEDのピンソケットが修復不可能だったのですが、ProMicro用に付属して余っているピンヘッダがちょうどいい長さでした。 なので、これを4本分切り取り、OLEDモジュールにつけてしまったOLEDヘッダピンを抜き取って、代わりに切り取ったピンヘッダをつかって、OLEDと基盤を直接はんだ付けすれば修復できそうだと判断しました。\nはんだシュッ太郎君を使ってOLEDについてるヘッダピンをまずは除去。 そのあとはこんな感じで繋げました。\n見にくいかもだけど pic.twitter.com/YAHoxjgppN\n\u0026mdash; Jun Ohtani (@johtani) November 5, 2020 取り外しにくくはなったけど、無事両方のOLEDが点くのも確認できました。やったー。\nヤッター、両方のOLEDがついたよー pic.twitter.com/6KLDWvnaEC\n\u0026mdash; Jun Ohtani (@johtani) October 28, 2020 キースイッチがご機嫌斜め キーキャップは別途、AliExpressで発注をかけたのですが、ここまで来たら待ちきれないですよね? ということで、手元にあった上海問屋のキーボードのキーキャップが同じMXキースイッチ用のものだったので移植しました。キーキャップ付けてみないとわかならいものですね、1つだけキースイッチがうまくはまっておらず、斜めについているのがこの時点で判明しました(ボトムプレート付けた後だったので、プレート外してから、はんだで修正)。\nちなみにキーキャップはめてる途中で、一箇所キースイッチが斜めにはんだ付けされちゃってるのを発見して慌てて直しました。 pic.twitter.com/qofHp3o4Pc\n\u0026mdash; Jun Ohtani (@johtani) October 30, 2020 無事使えるようになりました。\nアンスコが打てない&Escどこ? キーキャップ付けたので仮運用ということで、まずはデフォルトのキーマップをもとにどんな感じで入力できるのかを試してみました。 ここにも罠がw ブラウザでQMK Configuratorを開いてデフォルトのキーマップを確認しながら試し打ちをしていたのですが、どうも思ったのと違う動きをしているキーが。\nまずBASEレイヤー(レイヤー0)の右側のシフトと、LOWERレイヤーやRAISEレイヤーのEscです。 入力しているとどうも、右のシフトがEscで、レイヤーを切り替えてもTabのままだなと。 しょうがないので、OLEDが出なくてもいいのでQMK Toolboxでダウンロードしてきたものを利用したら想定通りなのにと。 きちんとqmk_firmwareの構成を理解しないままやってたつけでしたね。 結論としては、OLED用に教えてもらったブランチではキーマップが書き換わっていたようでした。 make crkbd:defautでビルドした時に利用されるkeymap.cがキーマップの定義が書いてあるファイルです。 qmk/qmk_firmwareのリポジトリにあるkeymap.cとfoostanさんにもらったブランチでは差分があったみたいでした。\nおかげで、qmk_firmwareのkeymap.cの仕組みがわかったし結果オーライです。 問題があって調べるとどんな作りになってるかとかちゃんと確認できますしね。 手順通りにやってるだけで問題が起きないと、どんな仕組みになってるのかがわからないので人に聞きまくるしかできなくなっちゃいますしね。\nこれでEsc問題は解決したのですが、アンスコがどうしても入力できません。 自作キーボード以外はすべて日本語配列のキーボードを使用しているのもあり、 日本語配列のキーボードだとどうもキーのマッピングが異なるようだと。\nググって参考にしたのはこの辺でした。\n【QMK】JPキーコードでキーマップを定義する - 天高工房 自作キーボードキット「Corne Cherry」のレビュー - 自作キーボード温泉街の歩き方 そのほかにもVIAのファームなども試したのですが、どれもうまくいかず。 色々ググってみて最終的な解決策はkeymap.cでkeymap_jp.hというファイルが読み込まれていないので、日本語用の設定とかを読み込んでみたつもりがうまく反映されていないという感じでした。\nJISにする場合、keymap_jp.hっていうヘッダファイル読み込んだほうがいいです\n\u0026mdash; Yoshi Yamaguchi (@ymotongpoo) November 3, 2020 今の時点ではこんなキーマップにしてあります。 今後も日本語配列のキーボードをベースに考えていくつもりです。\n#include QMK_KEYBOARD_H #include \u0026#34;keymap_jp.h\u0026#34; const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [0] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, JP_MINS, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, JP_SCLN, KC_QUOT, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, MO(1), KC_SPC, KC_ENT, MO(2), KC_RALT //`--------------------------\u0026#39; `--------------------------\u0026#39; ), [1] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LCTL, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_LEFT, KC_DOWN, KC_UP,KC_RIGHT, XXXXXXX, XXXXXXX, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LSFT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, _______, KC_SPC, KC_ENT, MO(3), KC_RALT\\ //`--------------------------\u0026#39; `--------------------------\u0026#39; ), [2] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. KC_TAB, JP_EXLM, JP_DQUO, JP_HASH, JP_DLR, JP_PERC, JP_AMPR, JP_QUOT, JP_LPRN, JP_RPRN, JP_CIRC, KC_BSPC, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LCTL, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, JP_MINS, JP_EQL, JP_LBRC, JP_RBRC, JP_YEN, JP_AT, //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| KC_LSFT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, JP_UNDS, JP_PLUS, JP_LCBR, JP_RCBR, JP_PIPE, JP_TILD, //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, MO(3), KC_SPC, KC_ENT, _______, KC_RALT //`--------------------------\u0026#39; `--------------------------\u0026#39; ), [3] = LAYOUT_split_3x6_3( \\ //,-----------------------------------------------------. ,-----------------------------------------------------. RESET, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,\\ //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| RGB_TOG, RGB_HUI, RGB_SAI, RGB_VAI, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,\\ //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------| RGB_MOD, RGB_HUD, RGB_SAD, RGB_VAD, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,\\ //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------| KC_LGUI, _______, KC_SPC, KC_ENT, _______, KC_RALT\\ //`--------------------------\u0026#39; `--------------------------\u0026#39; ) }; キーキャップが待ちきれなくて この右下のトンガリがちょっと気になる pic.twitter.com/W0A0z67cns\n\u0026mdash; Jun Ohtani (@johtani) October 30, 2020 キーキャップが待ちきれなくて上海問屋のキーキャップを付けてみて、いろいろ試行錯誤してみました。\nあー。上下関係ないのか。だからみんなこんな感じにしてるのか? pic.twitter.com/KTBlPLespr\n\u0026mdash; Jun Ohtani (@johtani) October 30, 2020 どのくらい離すのが良いか実験中 pic.twitter.com/ozK4WyBXY8\n\u0026mdash; Jun Ohtani (@johtani) November 2, 2020 キーキャップもいろいろあるのね 届いた。 pic.twitter.com/jccNW1ZcEM\n\u0026mdash; Jun Ohtani (@johtani) November 2, 2020 もう一個 pic.twitter.com/9y6qat4JiN\n\u0026mdash; Jun Ohtani (@johtani) November 2, 2020 とりあえずセミコロンの位置につけてみた。 pic.twitter.com/TDk5213IHi\n\u0026mdash; Jun Ohtani (@johtani) November 3, 2020 今はこのDSAプロファイルの青いグラデーションのキーキャップを使っています(Dukeはここにはいないですw)。 キーキャップのプロファイルはこれまた、サリチル酸さんのブログがわかりやすく書かれています(ほんとすごいなぁ。)。\n高さ調節 そのまま使っていたのですが、やはりもうちょっと奥側に高さがほしいなと。 ダイソーなどで打っているケーブルクリップがお試しには良さそうだったのでこんな感じで内側がちょっとだけ高くなるような感じにして使っています。\nこうなった。とりあえず仮運用 pic.twitter.com/VkhjawdhLM\n\u0026mdash; Jun Ohtani (@johtani) November 4, 2020 まとめ ということで、駆け足ですがCorne Light v2のビルドログでした。 いきなりフルキーボードから40%キーボードかつ異なる並びにしたので、 混乱しっぱなしですが、いい頭の運動になっているし、なにより作って動かすまでの間に いろいろと調べたり試行錯誤できたのがすごく楽しかったです。\nあとは、スプリット型+Column Staggeredになったので「c」や「b」を間違えまくっていますが、 いい気付きでした。まだまだ記号とかの入力に慣れていないですが、ちょっとずつ身に着けていけたらなと。\nただ、もう次のキーボードをDIYしたい気持ちも出てきているので困っているところです。\n書ききれてないこともあるかと思うので、ここはどうしてるの?これはどうやったの?などあれば、Tweetなりコメントなりを頂けたらなと思います。いやぁ、DIYキーボード楽しいわ。\n","date":1604503527,"dir":"post/2020/","id":"b16bddd1a6d3e5f4136446bebe7ffbc7","lang":"ja","lastmod":1604503527,"permalink":"https://blog.johtani.info/blog/2020/11/05/build-corne-light-v2/","publishdate":"2020-11-05T00:25:27+09:00","summary":"前回のブログのまとめに書いたように、セパレートタイプのキーボードであるCorne Light v2を作成したのでそのビルドログです。DIYキーボードとし","tags":["DIYキーボード","misc"],"title":"Corne Light v2を作成した #DIYキーボード"},{"contents":"ヒゲが不評だったのでいつも通りの長さに切りました。\n前回「Windowsをお試し中」と書きましたが、いくつかソフトをインストールしたりしたので現状を忘れないようにブログに残しておきます(また同じ作業する予定なので)\nインストールしたものたち 今のところインストールしたのはこの辺。 特にコメントしたいものについてこのあと明記します。\nドライバインストール from CD MX Ergoのソフトインストール。接続はコネクター Windowsアップデート Chrome Visual Studio ビルドツール(Lindera用) JetBrains Toolbox IntelliJ CLion Rider Visual Studio Code Slack Teams Google Drive共有 Gitter Divvy for Windows Zoom DeepL Sophos Twitter for Windows Office 365 AutoHotKey WSL2 - Ubuntu Windows Terminal Rustup Git for Windows wsl-ssh-agent PeaZip Speccy Hugo (WSL2のUbuntuにapt-get install hugoした) PowerToys AutoHotKey 前回のブログに書いたように、カーソル系のEmacsショートカットが体に染みついて離れないのです。 そこで、ググって見つけた記事はこちら。 AutoHotKeyというツールが Windowsに常駐して、特定のキー入力の時に、別の操作を実行してくれるツールです。\n見つけた記事にあった、https://github.com/lintaro-jp/gtk-emacs-theme-like.ahkのキーマップをもとに、いくつか変更したものを使用させていただいています。\n書き換えたのは、以下の通りです。\nCtrl+\\でIMEの切り替え(Wnn風) Ctrl+kをEmacsと同じ挙動に(もとにしたキーマップでは、カーソルから行末までが削除されてしまう) Win+sでもファイル保存(Ctrl+sと同じ挙動に。デフォルトではCortanaが起動して邪魔くさいので) すごく快適です。そのうち、もう少し自分が使いやすいようにキーマップを追加していったりするかもしれません。 特に、Macのショートカットがしみついているものについてなどです(仮想デスクトップ切り替えとか?)\nPowerToys Divvyをインストールしたのですが、グローバルショートカットがうまく動かなくていまいちでした(なんでだろ?) そこでググって見つけたのが@ITのPowerToysの記事でした。 PowerToysはMS製のOSSツールで、GitHub上で公開されています。 中には「ColorPicker」、「FancyZones」、「File Explowrer Add-ons」など、複数のツールが入っています。 「FancyZones」です。\nWindowsでは、デフォルトで、アプリにフォーカスしているときにWin+カーソルでウィンドウの配置場所をいくつか(左右どちらかに半分、4分の1(右上、左上など))に配置してくれるAero Snapというものが動いています。が、上半分などデフォルトにない柔軟な配置を設定することができません。 MacではDivvyというツールをいれて、それを実施していたのですが、先ほど書いたようにWindows版はあるものの、なぜかグローバルショートカットが動かず、システムタスクトレイのアイコンをクリックしなければいけませんでした。\nそれを解消してくれるのがFancyZonesです。 FancyZonesの設定項目で、自分で画面上にどのような割り当て領域を作るかを設定できます。さらに、マルチディスプレイ、仮想デスクトップを使っている場合、それぞれのディスプレイかつ仮想デスクトップで個別にレイアウトが設定できるようになります。 レイアウトを設定した後は、Shiftキーを押しながらウィンドウを移動すると、設定した領域が出てきて、あとは、割り当てたい領域にウィンドウを移動するだけでその領域いっぱいにウィンドウをリサイズしてくれます。 また、設定を変えることで、Shiftキーを押さなくてもウィンドウ移動するだけで領域にリサイズすることも可能です。また、Aero Snapの機能をオーバーライドしてWin+カーソルで動作させることも可能になります。\nWSL2 + Windows Terminal 三宅さんからコメントを頂いたので。\nもう少し幅広い感じですかね。あわせて Windows Terminal 使うとわりと快適です。\n\u0026mdash; miyake | ZEN (@kazuyukimiyake) October 15, 2020 なんとなく噂は聞いていましたがということで、MSのドキュメントを見ながらインストールしました。クイックスタートに則って作業するだけで特に問題なくUbuntuまで無事インストールできました。 Windows Terminalも同様です(クイックスタートで入れることになる)。\nGit for Windows + wsl-ssh-agent 少してこずったのがこちらです。 チュートリアルに記述はあったのですが、どちらで作業するのか?などが少しわかりにくかったので。ググって出てきた記事をもとに作用しました。\nRustのプロジェクトファイルをMacから丸ごとコピーしていたのですが、Git for Windowsを入れるまでは、CLion+Rust pluginの環境では、.gitファイルをきちんと認識してくれませんでした(この時WSL2と少し混同してた)。\n無事環境は用意できました。 作業の手順は以下のような感じです。 Macで使用していた.sshのディレクトリを持ってきて作業しました。\nWindows側での作業 Macから.sshディレクトリをc:\\\\Users\\johta\\にコピー Git for Windowsのインストール OpenSSHクライアントの設定 管理者権限でコマンドプロンプトを起動して sc config ssh-agent start=auto sc start ssh-agent [wsl-ssh-agent(https://github.com/rupor-github/wsl-ssh-agent)のインストール ダウンロードして.7zファイルを展開 wsl-ssh-agent-gui.exeとnpiperelay.exeをc:\\\\Users\\johta\\binに移動 c:\\\\Users\\johta\\bin\\wsl-ssh-agent-gui.exeのショートカットをスタートアップに作成 作成したスタートアップのリンク先に -setenv -envname=WSL_AUTH_SOCKを追加 Git BashでOpenSSHを利用するように設定 setx GIT_SSH C:\\\\Windows\\system32\\OpenSSH\\ssh.exe ssh-addで秘密鍵を登録 ssh-add .ssh/id_rsa WSL2のUbuntuでの作業 Ubuntuはgitがすでに入っていたのでインストールはスキップ git config --global user.name \u0026quot;Jun Ohtani\u0026quot; git config --global user.email \u0026quot;メールアドレス\u0026quot; mkdir .ssh .bashrcの最後行にwsl-ssh-agentのWSL2 compatibilityにあるexportからfiまでをコピー。この時、パスを自分のパスに変更すること(私の場合$HOME/winhome/.wslの部分を/mnt/c/Users/johta/binに書き換えました) これで、WSL2側では.sshのファイルを管理しなくても、Windows側のOpenSSHに接続してssh周りの処理をしてくれるようになりました。\nPeaZip wsl-ssh-agentが.7z形式で圧縮されていたので、ダウンロードしました。 とりあえずこれを入れてみたのですが、ほかにお勧めがあれば教えてほしいです。\nSpeccy CPUの温度やスレッドごとのCPU使用率などを見てみたいので入れてみました。 これもとりあえず入れてみた感じなので、ほかにお勧めのソフトがあれば教えてもらえればと。 リソースマネージャーでもスレッドごとのCPU使用率は見れたのですが、温度が見れなかったので。\nHugo + WSL2にあるUbuntuにsudo apt-get install hugoしてインストールしました。\nそこで、VS Code の Remote Extension です。WSL2 から ‘code’ で起動できます😎\n\u0026mdash; Daiyu Hatakeyama@Microsoft, Hack in ChatGPT (@dahatake) October 17, 2020 あとは、畠山さんに教えてもらったVSCodeのRemote - WSLを入れて、 WLSに接続した状態でVSCodeを起動して記事のMarkdownを書くと、VSCodeのターミナルを開くとWSL2に接続してくれて、hugoコマンドが実行できます。\nまとめ とりあえず、ブログが書ける環境ができました。 Mac上にあった各種プロジェクトのディレクトリをコピーして、Rustの開発もできるようになりました。\n今後も環境構築は続いていきます。Javaとか入ってないし。 SDKMan使ってたけど、切り替えどうしよう?とか。\nそういえばSDKMAN!をJDK切替に使ってたけど、結局windows側のパスは通らんので自力インストールになった。scoopがよさげ\n\u0026mdash; きしだൠ(K1S) (@kis) October 17, 2020 IDE系から呼び出すターミナルはWSL2がいいなぁとか。\nhttps://t.co/X4Jj4tih1I\n\u0026mdash; そーだい@初代ALF (@soudai1025) October 17, 2020 ほかにもおすすめなどがあれば教えてください!\n","date":1603029710,"dir":"post/2020/","id":"188c1ee5132a6752dfce5a0235354070","lang":"ja","lastmod":1603029710,"permalink":"https://blog.johtani.info/blog/2020/10/18/restart-windows-no1/","publishdate":"2020-10-18T23:01:50+09:00","summary":"ヒゲが不評だったのでいつも通りの長さに切りました。 前回「Windowsをお試し中」と書きましたが、いくつかソフトをインストールしたりしたので","tags":["misc","windows"],"title":"Windowsへの移行(その1)"},{"contents":"ヒゲが伸びてきて(試しに伸ばしてる)不評を買っている今日このごろです。\n自宅で作業することが多くなってきたので、自作PCでもと思っていますが、OSをどうしようか悩み中。 とりあえず、試しにWindowsにしてみるかということで、10年ぶりくらいにWindowsに帰ってきました (この文章はMacで入力してますが)。\nむかしむかし もともとはWindowsを使っていたのですが、Win7くらいに32bitと64bit混在の時期に、 Xkeymacsを利用するときに少し手間がかかるなぁと思ったのもあり、Macに移行しました。 Macだと自分がよく使うEmacsっぽいショートカットがデフォルトいろんなアプリで使用できる利点があったからです。\nただ、最近、TL上で光るPCとかを見てしまったのもあり、 自作PC(どちらかというとDIYかな?)熱が復活しました。 まだ、OSをWindows、Ubuntuのどちらをメインにしようかな?と悩んでいるところではありますが、まずはWndowsをちょっと試してみるかなと。\nまずは、やりたいことをちょっとリストアップしておこうかなと思います(きっと、先人の知見が集まってくるはず!)。\nどうしてもほしい機能 大学の頃にSunOSやSolarisを使用し、Emacsでメールを読んだしていたせいで、Emacsのショートカット操作が体から抜けない状態です(抜こうとしてないという話もあるが)。 ですので、社会人になってからWindowsを利用していたときはXkeymacsというソフトのお世話になっていました(神アプリでした。まだあるのかな?)。\nショートカット操作とか カーソル移動(必須) 上下左右:Ctrl+n、p、f、b 行頭、行末:Ctrl+a、e 編集 デリートキー:Ctrl+d Ctrl+hがバックスペースだけど使わないな、そういえば カーソルから行末までをカット:Ctrl+k 必須! カーソル移動がホームポジションから移動しなくてもいいのもあって、多用してしまっています。 これ、WindowsとかUbuntuでいい感じにできるのあるのかな? できれば、IMEやブラウザのURLのサジェストなどもこのカーソル移動で移動できると嬉しいです。 (昔はM-%とかで置換などもやってたけど最近はやらないな。)\nデスクトップ操作系 仮想デスクトップ やることごとにデスクトップを切り替えて使うので ウィンドウのリサイズ? DivvyというアプリをmacOSで利用中 自分で登録したサイズ(例:画面右半分)にウィンドウサイズを変更などがショートカットで可能 仮想デスクトップはあると思うけど、ウィンドウのリサイズの便利なツールあるかなぁ?\n利用するアプリ SNS、オンラインミーティング Twitter macOSではTweetDeckと夜フクロウを使用 Slack ネイティブアプリ Gitter ネイティブアプリ Chatwork ブラウザ Teams ネイティブアプリ Zoom ネイティブアプリ Google Meet ブラウザ Discord ネイティブアプリ(最近使ってないな) 色々使ってますが、最悪ブラウザで使う感じかな?\nオンラインストレージ Google Drive 同期アプリ使ってる Dropbox あんまり使ってない 開発系 JetBrainsのIDE Toolbox App IntelliJ CLion + Rust plugin Rider zsh macOSで標準になったから コマンド系 git SDKman ant gradle JDK Rust Hugo Jasper GitHubのIssueとかを見るネイティブアプリ 自分が関連しているIssueとかが楽に見える(メールだと埋もれてしまう) エディタ Visual Studio Code 開発系では?と思われるかもだけど、Markdownエディタとして使ってる Emacs by Homebrew 最近は起動してない その他 カレンダー macOSのカレンダーで複数のGoogleカレンダーを取り込んでる ScanSnap Ubuntuで使えるやつあるのかな? Mac miniにつないであるので、画面共有とかで入れればそれでOK 画面共有 winやubuntuからMac miniとか見えるかな? キーボード共有 macも使うので、KVMスイッチとかかな? マウス共有 MX ErgoのFlowを使うと行き来が簡単にできたので良さそう。 ただし、Ubuntuだとどうなるのか? システム監視系 CPUの温度とかCPU、メモリの使用率とか まとめ とりあえずこんなところです。カーソル移動系が一番重要なので、そのへんから色々とちょっとずつ試していく予定。 ぜひオススメアプリとかあれば教えていただければと。\n","date":1602727442,"dir":"post/2020/","id":"de37d9fae011687eb1eb5a127fcb89e3","lang":"ja","lastmod":1602727442,"permalink":"https://blog.johtani.info/blog/2020/10/15/restart-windows/","publishdate":"2020-10-15T11:04:02+09:00","summary":"ヒゲが伸びてきて(試しに伸ばしてる)不評を買っている今日このごろです。 自宅で作業することが多くなってきたので、自作PCでもと思っていますが、","tags":["misc","windows"],"title":"Windowsをお試し中"},{"contents":"今年の春くらいから、セパレートタイプのキーボードが気になっています。 また、なんか知らないですが、Twitterのタイムラインが自作キーボード(DIYキーボード)で盛り上がってる気がします。 (たぶん、気になってるから余計目についてる)。 これとか。このスライドから、自分がやってるのは「まだ」DIYキーボードだなということで、タイトルに使ってみました。\n#toruby \u0026quot;DIYキーボードは実質Ruby\u0026quot; 本日のスライドです! とちぎでこの話をできてよかった!!!q: https://t.co/RJot71Ngu9\n\u0026mdash; Kakutani Shintaro (@kakutani) September 12, 2020 セパレートタイプのキーボード 今年の夏まではMac Book Pro 16インチのキーボードを利用していました(参考:自宅の作業環境(2020))。 これまで、自宅で作業することよりも、外で仕事をすることが多く、また、外といっても様々な場所(サムライズムだったり、オフィスだったり、カフェだったり)で作業をすることが多かったので、ノートPCのキーボードにしていました。流石にキーボードを持って歩くほどは気にしていなかったので。\nただ、コロナウイルスの影響もあり、ほぼ自宅で作業することとなりました。 となると、前から気になっていたセパレートタイプのキーボードが俄然気になり始めます。 (といいつつ、寄り道してたりしますが)\n気になっていたのはこのあたりなのですが、\nErgodox EZ Moonlander Mark I 流石にいきなり行くにはちょっと気が引けるなぁと(なかなかいいお値段)。 また、自分が日本語キーボードを利用しているというのもちょっとあります。\nキースイッチの感触を知りたくて ただ、日々、楽しそうな自作キーボードの記事や画像が流れてきます。 で、思い出したのが自分の趣味。プラモデルです。色を塗ったりはしないですが、組み立てるのは楽しいなと。 じゃあ、趣味と実益を兼ねればいいのでは?(ほんとか?)となり、作る気になってきました。\nただ、全く知らない世界だし、どんなものなんだろう?と。 市販のキーボードでも、キーの押し具合が色々合ったり、形もまちまちです。 また、このご時世ですので、自宅からあまり出ていないので遊舎工房さんなどに遊びにも行けず。\nそんなところに流れてきたのがキースイッチのテスターでした(世の中誘惑だらけ)。\nスイッチテスター人気スイッチ詰め合わせ 18個セット 「なるほど、これでどんな感触かわかるじゃないか!」と、気づけばポチッと押していました。。。 届いて、「ふむふむ、これがこういう感触なのか。なるほど」ポチポチ押しながら、さらに自作キーボードについて調べていきます。\nいろんな感触なんだなぁ pic.twitter.com/PaGDMIRJiv\n\u0026mdash; Jun Ohtani (@johtani) September 22, 2020 キースイッチのストロークの深さを知りたくて まぁ、当たり前なのですが、先程のキースイッチテスターどこにもつながっていません。 キーボード触ってるとわかりますが、ストロークが違いがあるんですよ。 ただ、これだとわからない。けど知りたい。\nで、ググっているとArduinoを使ってLチカやってる人とか、キー入力させている人がいるじゃないですか。 これでは?そういえば、Arduinoもどきうちにもあるぞ?と。 で、準備をしていたときに見かけてしまったのがこのツイートでした。。。\nhttps://t.co/ALl7OcRVRa 高機能テスターとしてもおすすめ\n\u0026mdash; Kakutani Shintaro (@kakutani) October 4, 2020 やられてしまいました。。。\ndozen0作りました ということで、前置き長かったですが、Dozen0というキーボード(マクロパッド?)を遊舎工房さんから購入して作ってみました。 手順はビルドガイドという形でまとまっています。\n基本的にはこれに沿って作成しました。\nパーツと手順の確認 さてと。 pic.twitter.com/GTBJ7zDleN\n\u0026mdash; Jun Ohtani (@johtani) October 10, 2020 まずは入っているパーツがきちんとあるか確認します。 また、ビルドガイドでどんな作業があるのかをざっと眺めておきます。 まぁ、プラモデルといっしょですよね。\nキットにはキースイッチとキーキャップは含まれていません。これはご注意ください。 私は、キースイッチテスターとして入手していたキースイッチとキーキャップがどんな押し具合なのかを確認したかったので特に問題ありません。\nハンダづけ Amazon | 白光 ダイヤル式温度制御はんだこて FX600 | ハンダゴテ Amazon | 白光 こて先 2C型 T18-C2 | ハンダゴテパーツ Amazon | 白光(HAKKO) セラミックヒーターはんだこて専用こて台 クリーニングスポンジ付き FH300-81 | ハンダゴテパーツ Amazon | goot(グット) 高密度集積基板用 鉛入りはんだ Φ0.6mm スズ60%/鉛40% ヤニ入り SD-60 | ハンダゴテ はんだ付け用に揃えた道具です。「自作キーボード ハンダゴテ」とかでググると出てきたものがこれだったので。 デフォルトのコテ先ではなく、2Cのコテ先に付け替えてから作業を開始しました。\n私の持っていたソケットはCherry MX系なのですが、気が向いたらKailh Chocも試したくなるかも?ということで、 すべてはんだ付けしました。本格的にはんだ付けしたのは大学以来だからもう20年近く経ってますね。 ソケットの足をプリント基板にはんだ付けするのですが、2Cのコテ先が大きくなかなか手こずりました(これがこのあと問題を引き起こしました)。\nソケット、リセットスイッチ、ProMicroをはんだ付けすればはんだの作業は終了です。\npic.twitter.com/jjUo162n54\n\u0026mdash; Jun Ohtani (@johtani) October 10, 2020 pic.twitter.com/p5atvtHfFN\n\u0026mdash; Jun Ohtani (@johtani) October 10, 2020 スイッチの取付と組みたて 試したいキースイッチを選んでトッププレートにつけていきます。\nキーテスターからスイッチとキーキャップ持ってきて完成。動作確認はまだなのでまた、最初に戻るかもだけど、、、 pic.twitter.com/ZmBd3bgOKI\n\u0026mdash; Jun Ohtani (@johtani) October 10, 2020 組み立ても終わり次は実際の動作確認です(ツイートしていますが、予想通りの展開でした)。\nファームウェアの書き込み USBで接続して、ファームウェアの書き込みです。 書き込み手順はビルドガイドにありますが、QMK Toolboxの使い方やQMK Configuratorの使い方は以下のサリチル酸さんのブログがわかりやすかったです。\n(初心者編)自作キーボードにファームウェアを書き込む (初心者編)QMK Configuratorを使ってキーマップを書き換えよう 実際に書き込んで動かしてみると。。。。\nうーん、上半分が死んでる気がするなぁ。\nデフォルトキーマップの書き込みはできたけど、カーソルの上とかバックスペースが入らないw\n\u0026mdash; Jun Ohtani (@johtani) October 10, 2020 とりあえず、もう一回確認してみた。デフォルトのキーマップで、「Cut」「Paste」が強く押さないと入力されない。UpとDeleteは動くようになってた。CopyとBkSpがうんともすんとも言わない。下段のキーは全部動く。https://t.co/zEyINdAK6t\n\u0026mdash; Jun Ohtani (@johtani) October 10, 2020 といった具合に上半分が動作があやしいです。\n再度、はんだ付け ということで、ネジを外して上の段のソケットをはんだで温めてみると、片側だけ温めるとはずれるじゃないですか。 どうやら、うまくソケットの足が基盤にはんだ付けできていなかったようです。 この時、最初に作業したときに2C型のコテ先が大きくて、ソケットの足に入らなかったのを思い出したので、 最初にはんだごてについていたコテ先に戻してから作業をしました。 これだとソケットの足の隙間に入るんです。ということで、挙動のおかしい上段のソケットをすべてつけ直したところ無事動作しました。\n上の段、全体的にソケットがうまくはんだ付けできてなかったみたいだった。今回はMX系のスイッチしかないので、Kailh Chocのソケットの導通は未確認。ざっとブログにまとめるか。\n\u0026mdash; Jun Ohtani (@johtani) October 10, 2020 現在のキーマップ これが今のキーマップです。仕事中のBGMをラズパイ4の音楽プレーヤーで流していますが、 部屋から出るときや、打ち合わせがあるときに音楽の停止、開始などを画面共有経由でやっています。 が、わざわざマウス移動するのもめんどくさいなと。これに使えそうだというのもあったので、Dozen0を購入したというのがあります。 残念ながら、Prev Trackとかがうまく動かないので、ショートカットを調べてキーマップ書き換える予定ですが、非常に便利になりました。\nまとめ ということで、Dozen0を作ってみましたが、楽しかったです。すんなりと行かなかったのがまた良かったです。 試行錯誤して動いたときの喜びが何倍もありました。また、キースイッチの感触も知ることができました。 たぶんGateron Silentクリア軸もしくは赤軸くらいが良さそうだなぁと(こうやって沼へ。。。)。 キーマップの仕組みを調べたり、もっと面白い使い方できないかな?と探りつつ、次のステップに進もうかなと。\n次は本格的なセパレートタイプのキーボードを作る予定です。が、お店のオープンを待ってからということになってます。はやくオープンしないかなぁ!!\nがんばって!!\n\u0026mdash; Jun Ohtani (@johtani) September 29, 2020 ","date":1602428006,"dir":"post/2020/","id":"c377351433a941a927aab543931f6026","lang":"ja","lastmod":1602428006,"permalink":"https://blog.johtani.info/blog/2020/10/11/build-dozen0/","publishdate":"2020-10-11T23:53:26+09:00","summary":"今年の春くらいから、セパレートタイプのキーボードが気になっています。 また、なんか知らないですが、Twitterのタイムラインが自作キーボード","tags":["DIYキーボード","misc"],"title":"Dozen0を作成した #DIYキーボード"},{"contents":" 2020/10/06 11:00くらいにマージされました。\n@minoru_osuka さんが開発を引き継いだLinderaというKuromojiのRustクローンがあります(リポジトリ) 。 最近趣味でRustを勉強しているので、こちらを少し手伝っています。\nRustの勉強仲間である@takuya_bさんや@ikawahaさんと話をしているときに、FST部分をDouble Array Trieに置き換えると速度が向上するのでは?という話が出まして、@takuya_bさんがDouble Array Trieを作るらしいという話になったので、下準備などをしつつ、作ってもらったライブラリyadaを組み込んでみたという話です。\nベンチマークの追加 下準備として、今のLindera(FST実装)がどのくらいの性能なのか?というのを計っておく必要があります。 幸いにも、Linderaのオリジナルの開発者の方が、criterion.rsというライブラリを使ったベンチマークプログラムを作成してくれていました。\nただ、1種類だけだと少し心もとないなというのと、長い文章やパターンを増やしたほうが良さそうだなということで、 ベンチマーク自体をいくつか追加しました(追加したときのPR)。\n種類としては、5種類のベンチマークです。\nシステム辞書のみのTokenizerのコンストラクタ呼び出し カスタム辞書ありのTokenizerのコンストラクタ呼び出し システム辞書のみのTokenizerのtokenize処理の呼び出し カスタム辞書ありのTokenizerのtokenize処理の呼び出し 青空文庫の坊っちゃんのテキストをシステム辞書のみのTokenizerでtokenize 1,2はコンストラクタ部分だけの処理をベンチマークテストする目的で作成しました。 LinderaはTokenizerがtokenize処理するのに利用するデータをいくつか内部で保持しています。 これらはファイルにシリアライズされており、Tokenizerのオブジェクト生成時に読み込みやデシリアライズ処理が発生します。 この部分だけも速度を計測したい目的でコンストラクタだけを切り出しました。\n3,4はTokenizerのメインの処理です。コンストラクタはベンチマークの対象外にしました。 純粋にtokenizeの処理だけを切り出して計測するためです。 カスタム辞書がある場合、ない場合は念の為切り出した形になっています。\n5は長い文章(文章が多いのでバリエーションも増える)を扱いたいために別にしました。\nこれで、一応下準備が完了です。 ちなみに、Criterionは賢くて、前のベンチマークの結果と最新の結果を比較してくれる機能があります。 どんな感じで出てくるかはベンチマーク結果をご覧ください。\nyadaの組み込み ベンチマークの準備をしていたところyadaがリリースされたので、Linderaへの組み込みを検討し始めました。\nというわけで、またダブル配列を書いてしまったので crate として公開しました。フィードバックお待ちしております! https://t.co/As7h0tfmjf\n\u0026mdash; takuya-a (@takuya_b) September 20, 2020 中身の理解 lindera-fstを利用して、prefix searchしている処理があるので、そこで利用しているFSTをyadaに置き換えれば良さそうだと判断して、 処理を読んでいきます。\nTokenizerは、PrefixDictという構造体でlindera-fstを利用している prefixメソッドが入力文字列を元に、FSTを前方一致検索して、ヒットした単語の情報をIteratorとして取り出せる(単語の情報は「入力文字列の先頭からの文字数」と「ヒットした単語のWordEntry構造体」) PrefixDictのfstは辞書(例:ipadic)ごとにlindera-\u0026lt;辞書名\u0026gt;-builderで生成される システム辞書としては、デフォルトではlindera-ipadic-builderでfstを構築している 構築処理はこの辺 という感じです。 また、辞書周りのファイルがそれぞれどんな役割なのか、どんなデータの持ち方をしているのか?といった点を、変更点の調査のついでに書き出してみました。lindera-dictionary/FILES.md。TODOになっている部分も追記が終わっています(PR)\n変更点 実際に変更したプログラムの詳細についてはのPRを見ていただくとして、簡単には以下の点になります。\nRustのバージョンを1.46.0に(おもにREADME.md) yadaが利用している機能に1.46.0で導入された機能があるため lindera-fstをyadaに変更(lindera-core/Cargo.toml, lindera-ipadic-builder/Cargo.toml) 合わせて、dict.fstというファイル名をdict.daに変更 dict.daに関して構築部分と検索部分を変更 FSTではFSTから返ってくる値(入力文字列に出てきた単語に関連する値)はu64だったが、yadaのDoubleArrayがu32しか扱えないため、u32に変更。テストの記述はしていないが、扱うデータ的にu32で問題なさそうだったので。 検索部分:PrefixDict構造体のprefixメソッドでDoubleArrayのprefix_common_searchを使用 DoubleArray自体がprefix_common_searchのメソッドを持っていたので、処理が簡単に置き換え可能だった。FSTはprefixメソッド内で独自で前方一致検索を実装していた。 構築部分:lindera-ipadic-builder/src/lib.rsのbuild_dictとbuild_user_dictのdict.da構築処理 ipadicのCSVファイルを読み込んで、見出し語をキーに、辞書にある単語情報のベクタを値とするBTreeMapを生成し、このBTreeMapに基づいてFSTを構築していた部分をDoubleArray構築処理に置き換えた。 シフト演算などで、実際の値(dict.vals)へのポインタを作っていたのだが、ここの処理を読み解くためにFILES.mdを書き出した。 という感じです。そもそもデータ構造がどうなっているのか?から読み解いて、変更部分を洗い出して変更していった形になります。 取り込み作業中にいくつかyadaに要望(このへん)を上げて、変更を取り込んでもらい、最終的にyadaのバージョン0.3.2で問題なく動きそうだという形になりました。@takuya_bさん、対応ありがとうございました。\nエッジケースバグの発見 作っててよかった、テストケースでした(実際にはベンチマークテストですが)。 取り込み作業中に、Lindera本体のcargo testはすべてOKになるが、ベンチマークを取ろうとしたときに、坊っちゃんの文字列を入力にしたベンチマークが失敗するという事象が発生しました(PRのコメント参照)。 切り分けのために、入力の文章のどこでおかしくなるのか?DoubleArrayのbuildメソッドに渡している値がおかしくないか?などをすこしずつ調べていくと次のバグが判明したという感じです。\n特定のデータ(ipadicの見出し語一覧)をDoubleArrayに入れて、特定の文字列(「は相」)をcommon_prefix_searchにいれたら、 返ってくる情報(0から何バイト目の文字が一覧に存在した)が、不正な値が返ってくるというバグでした。 @takuya_bさんに見てもらいつつ(DoubleArrayの中身わからん。。。)、修正してもらいました。素早い対応ありがとうございます。\nyada 0.3.1 をリリースしています。特定の条件で不正な遷移を許すダブル配列が構築されてしまうバグを修正しています。このエッジケースは @johtani さんが見つけてくださいました。ありがとうございました! https://t.co/CiftZi5GDn\n\u0026mdash; takuya-a (@takuya_b) September 30, 2020 やはり、いろんな文字列入れてテストしてみるの重要ですね。 ということで、ベンチマークだけでなく、テストケースとしても坊っちゃんのファイルを読み込んでトークナイズするようにPRでテストケースを追加しています。\nベンチマーク結果 yadaを利用した変更が終わったので、再度cargo benchを実行して計測です。 計測としては、masterブランチでまずcargo benchを実行し、yadaの実装をしたブランチに切り替えてからcargo benchを実行します。 すると、Criterion? cargo benchが、最終的な結果に前回との差分でどのくらい性能が改善、改悪したかも合わせて出力してくれます。 実行環境と結果は以下のとおりです。\nMacBook Pro 16インチ CPU:Core i7 6コア 2.6GHz メモリ:32GB コンストラクタのベンチマークについては10%ほど性能が悪くなっています。 これは、FSTよりもDoubleArrayTrieのほうがデータが大きくなってしまうためだと思われます。 実際にファイルのサイズは次のようになりました。yada(DoubleArrayTrie)のほうが2倍以上大きいことがわかります。 また、このファイル以外にもLinderaが利用しているデータはありますが、それらは今回変更の対象にはなっていません。 なので、単純にこのファイルの読み込みの処理に時間がかかっているのだと想像できます。\n2147765 / FST / dict.fst 5425152 / yada / dict.da tokenizeのベンチマークについては、11%〜28%の改善が見られました。 文章から、内部に保持している辞書に存在する単語を見つけ出す処理に利用されるのがFST、DoubleArrayTrieです。 今回の変更では、この処理に利用しているデータ構造だけを変更しました。 実際には\nDoubleArrayTrieを用いた単語の検索処理 見つかった単語の持つ値(data.valsのオフセット情報)を元にシフト演算 といった処理が実行されます。シフト演算はu64だったものがu32に変更されたくらいなので、大した処理量ではないかと。 大部分はDoubleArrayTrieを利用したルックアップ処理が速度向上に寄与していると思います。\nまとめ 最近Linderaに加えた変更、作ったPRについて少しブログにまとめてみました。 ちなみに、まだPRの段階でレビュー\u0026amp;リリース待ちという感じです。\n実際には作ってもらったライブラリを組み込んでみたというだけなのですが、速度が向上した結果が見れたのは面白いです。 また、基本的なデータ構造とかアルゴリズムの勉強にもなりました(2次元配列を1次元配列に押し込むとか)。このへんも今後も勉強していきたいです。\n組み込む際に色々と協力していただいた@takuya_bさん、@ikawahaさん、巻き込んでくれた@minoru_osukaさんに改めて感謝いたします。\nRustや形態素解析のプログラムの勉強を兼ねて、今後もなにか改善できる部分がないかなどを見ていこうと思っています。 Rustで形態素解析をしたいという人がどのくらいいるかはわかりませんが、おかしなところや疑問点などあればコメントください。\n","date":1601865378,"dir":"post/2020/","id":"15932a656f7acfac897d27766eadc9e2","lang":"ja","lastmod":1601865378,"permalink":"https://blog.johtani.info/blog/2020/10/05/switch-fst-2-da/","publishdate":"2020-10-05T11:36:18+09:00","summary":"2020/10/06 11:00くらいにマージされました。 @minoru_osuka さんが開発を引き継いだLinderaというKuromojiのRustクローンがあります(リポジトリ)","tags":["Rust","Lindera"],"title":"LinderaのFSTをDoubleArrayTrieに変更した話"},{"contents":"先日は「検索システムを構成するパーツ」ということで検索システムを構成しているパーツについて書いてみました。\n大体、検索がうまくヒットしないといった場合に、問題になるのがコンテンツ自体のデータもしくは、転置インデックスのキーワードだったりします。 そこで今回は、前回のパーツの「データソース・コンテンツ」周りについて少し書いてみようと思います。言葉の定義、それぞれがどんなことをやるのか、とりあえず導入したあとにコンテンツ周りでどんな改善ができるかなどを書いてみます。\n言葉の定義 コンテンツ 実際に検索させたいデータになります。 コンテンツにはWebページ、データベースのレコード(CMSで登録されたデータなど)、ファイルサーバーにある文書(PDF、Word、Excelなど)などになります。\nデータソース コンテンツのマスタデータが保存されている先です。 よくあるデータソースとしては以下のものが考えられます。\nWebサイト - 自社もしくはインターネットに存在しているWebサイトです。 ファイルサーバー - ローカルネットワーク上のファイルサーバーもありますが、最近ではGoogle DriveやDropboxといった外部のWebサービスもあります。 RDB - CMSや自社システムでのデータの保存先です。 クローラー コンテンツをデータソースから収集してくるプログラムのことです。 Webサイトやファイルサーバーからコンテンツを収集して検索エンジンに登録するところまでを担当します。 RDBにあるデータを検索エンジンに登録する場合はクローラーがデータを登録するというよりは、RDBにデータを登録するシステムが検索エンジンに登録する機能を持っていることが多いです。\nデータの収集と登録 収集 クローラーを使用した収集の場合は、サービスの特性とデータソースによって、どの程度の頻度でクロールするのか、クロール対象はどこまでか?といったものを決める必要が出てきます。 これらが決まれば収集ができるかと(他に権限とかもありますが。)。 収集コンテンツは、そのままでは利用しにくかったり、利用できないことがあるので、次はデータの変換を行います。\nデータ変換 コンテンツはそのままの形では検索エンジンには扱いにくいデータ形式である場合があります。\nWebページの場合 Webページの場合、コンテンツにはHTMLタグが入っていたり、JavaScriptなど検索対象にはしたくないデータなどが入っています。これらを除去して、検索させたいものを取り出す必要があります。 また、Titleタグなど、いくつかメタデータとして扱えるものがHTMLで規定されているので、これらを別の項目として取り出して個別に検索できるようにすると便利です。 HTMLをパースしてデータを抜き出す処理ができるライブラリなどがあるので活用します。\nファイル PDFファイルなど、ファイルの場合もメタデータと呼ばれるファイル自体が持っている情報が存在します。作成者、更新日時、ファイル名、パスなどです。 これらも検索時に有効な情報になります。 また、ファイルから文字列を抜き出す処理も必要になります。 それぞれデータフォーマットが異なりますので、そのフォーマットに合わせて文章データを抜き出す処理が必要です。OSSや製品がありますので、それらを利用して、ファイルから文章を抜き出します。\nRDB RDBのデータの場合、データが正規化されています。 検索エンジンでは、非正規化のデータを登録して検索することが基本となるため、まずは非正規化して取り出す必要が出てきます。\n例えば、ジャンルやカテゴリ、各種IDなどが実際のコンテンツのレコードに入っていると思いますが、これらをユーザーが入力したキーワードで検索したい場合などは、IDではなく表示名を取り出して、検索エンジンに登録する必要が出てきます。\nその他 データごとの変換処理について説明しました。 その他に、データのクリーニング処理などと言ったことも必要になってきます。例えば、HTMLのタイトルに必ずサイト名が入っているが、除去したいといった場合や、検索エンジン固有のデータの前処理などもあります。\n登録 最後は検索エンジンへの登録です。 最近の検索エンジンはJSON形式でデータを受け取る場合が多いので、JSONに変換することが多いです。 基本的には各種プログラミング言語のライブラリが用意されているのでこれらを利用するのが基本となります。\n検索したい項目、検索させたい方法などを洗い出し、必要なデータを作成して検索エンジンに登録します。 登録と書いていますが、更新、削除などもここでの対象となります。\nここまでの流れで、データソースからコンテンツを取得し、変換して、検索エンジンへの登録が終わりました。\n検索の改善 検索のログから分析して改善していくのが良いですが、ユーザーからの質問や意見などからも改善すべき点が見えてくると思います。 検索ログでは、次のようなものを元に、検索がうまく行かないものを見つけ出します。\n0件ヒット 0件クリック ヒットしていない検索ワードがある場合、コンテンツに問題がある場合があります。まずはこのあたりをとってみるのが良いかと。 そもそも、入力されたキーワードにマッチするコンテンツを扱っていないこともわかりますし、入力されたキーワードに似た単語を持ったコンテンツなども存在するはずです。 類義語の辞書を用意して、検索にヒットできるようにするといった分析と改善にも利用できます。\nあとは、検索エンジン側の話ですが、形態素解析器などを利用している場合に、意図した区切りになっていないために、うまくキーワードがヒットしないと言ったこともあります。\nコンテンツの理解 実はこれが一番だったりします。 どんなコンテンツを自分たちが扱っているのか?どんなデータがどういった項目でコンテンツに入っているのか?といったところから、 コンテンツのデータを元に検索にヒットさせる方法が改善できます。\nCMSなど人が入力したデータをコンテンツとして扱う場合、入力画面を改良することで、望んでいるデータを入れてもらえたり、不要なデータが入らなくなる可能性があります。 例えば、ECサイトなどで商品の説明文やタイトルにいろいろなキーワードが入っている場合などがあります。むりやりどんなキーワードでもヒットさせたいという入力者の意図もあるのですが、検索しているユーザーにはノイズになることも多いです。適切にカテゴリやジャンル、属性といった項目に分けることでおかしな入力データを減らすことも可能です。\nWebサイトなどをクローリングしたものの場合は、サイトごとに文章の特徴があったり、重複している部分などが合ったりする場合があります。 これらもコンテンツをよく調べることで、不要な情報を除去したりといったことが可能になります。\nまとめ 簡単ですが、検索のデータソースやコンテンツにまつわる話を紹介しました。 もちろんここでは紹介しきれていない項目がいっぱいあります。 また、具体例ではなく概略をざっくりと書いているのでわかりにくい場合もあるかもしれません。 すこしユースケースを絞り込んで書いたほうがわかりやすくなるのかも?\n次はUIとか書くかも?\n不明点とか疑問点、指摘事項などあればコメントしていただければと。 要望などもお待ちしております。\n","date":1600136614,"dir":"post/2020/","id":"b2c4cf0fb96d02d37f03668caaecbc57","lang":"ja","lastmod":1600136614,"permalink":"https://blog.johtani.info/blog/2020/09/15/improve-search-no3/","publishdate":"2020-09-15T11:23:34+09:00","summary":"先日は「検索システムを構成するパーツ」ということで検索システムを構成しているパーツについて書いてみました。 大体、検索がうまくヒットしないとい","tags":["検索"],"title":"検索対象のデータとデータソース(検索システムに関する妄想その3)"},{"contents":"自宅環境に少しアップデートがあったので更新版です。 お客さんのおかげで相変わらず自宅で作業させてもらってるのもあり、昨今のコロナウイルスの影響で出かけることもないので、自室の作業環境が更新されている感じです。 前回のブログはこちらです。 前回のまとめで触れていた2点について更新されています。\nまずは、現状のデスクの上の写真です。\n基本的には前回紹介したものと大きくは変わっていません(?)。 変わったものについて紹介していきます。\nデスク 先程の写真ではちょっとわかりにくいですが、スタンディングデスクになりました。\nタイマーついてるの便利 pic.twitter.com/E9engTIMnM\n\u0026mdash; Jun Ohtani (@johtani) April 30, 2020 Flexispotの天板と足の組み合わせにしました。 前のElectaの天板が明るめの色だったのもあって、メープルの天板です。 組み立てはちょっと大変でした。 足が重たいのと、天板にはネジ穴がなく電動ドライバーもないので、ネジ締めと机を起こすのがちょっと大変です。子供に手伝ってもらいながら組み立て設置をしました。 オンラインミーティングなどのときには基本、立って作業しています。 あとは、デフォルトのタイマー設定のままですが、45分ごとに立ったり座ったりを数回繰り返す感じです。\nAmazon | FLEXISPOT オフィスデスク用天板 スタンディングデスク120×60cm Amazon | FLEXISPOT スタンディングデスク 電動式 昇降デスク メモリー機能付き ブラック EN1B(天板別売り) スタンディングデスクマット フローリングに45分立ちっぱなしだと結構、足の裏がつかれるんですよ。なので、クッション性が高いフロアマットを立ってるときは利用しています。ちょっとめんどくさいのですが、椅子のときは壁に立て掛けて、立つときにマットを敷くようにして使っています。\nちなみに、ウレタン素材なので開封直後はすごい匂いでした。。。 数日は陰干しみたいなのが必要です、ご注意を。 ただ、これを利用してから膝やかかとが痛いことはなくなっています。\nAmazon | 疲労軽減マット スタンディングデスクマット 滑り止め加工 立ち仕事 耐水 耐油 耐菌 (ブラック, 75cm*50cm*2cm) ケーブルトレー スタンディングデスクだとケーブルをぶら下げた状態だと危なそうだなということで、ケーブルトレーも机の下に追加してあります。電源タップを配置して、ディスプレイなどの電源はこちらから取るようにして、ケーブルトレーからは電源タップとスタンディングデスクの電源コードを垂らすという感じです。実際にはLANケーブルも伸びてたりはしますが。。。 また、後で出てくるラズパイ+SSDも最近こちらに移設しました。 最初にチャコールグレーを発注したのですが、配送日が未定になったので、Lサイズのシルバーを発注するという慌てようでした。 結局、今は両方使っています。テーブルタップにラズパイと、結構乗せるものがあるんですよね。見えない場所だし、色が揃ってないのは気にならないかなと。\nAmazon | プラス Garage ワイヤーケーブルトレー Lサイズ 幅63.7cm シルバー Amazon | プラス Garage 配線ケーブルトレー 幅40cm チャコールグレー キーボード+パームレスト 10数年ぶりに外付けキーボードじゃないかな? 少なくともMacに移行してからは、ずっとMac bookのキーボードを使ってました(極稀にMac mini起動後とかにMagic Keyboard使うくらい)。 外出して仕事をすることが多かったのもあり、体をキーボードに合わせる感じでした。\nが、ずっと在宅で仕事をしていますし、ふるさと納税でRealforce(リンクは楽天)がということで、申し込んでみました。2週間ちょっとで到着。 箱が厳重でびっくりしました。\nAmazon | 東プレ REALFORCE SA for Mac ホワイト R2SA-JP3M-WH | Realforce まだ深いキーに慣れつつあると言った感じです。 付属の2mmのキースペーサーでAPCを2.2mmの設定で使用しています。最初は3mm+APC 1.5mmでやっていたのですが、流石にキーが敏感すぎてちょっとキーボードに手をおいたまま考え事をしているだけで「lllllllllll」のようになってしまったので現在の組み合わせに落ち着いています。\nあと、特殊な設定としてはスペースの横のeng/kanaキーを設定でキーロックして使えなくしました。どうも、ご入力の原因になっているようだったので。 日本語の入力切替は、昨日まではCtrl+Spaceを使用していましたが、このブログを書き始めてからCtrl+\\に変更しています。 むかーし、使っていたIME切り替えのショートカットです(知っている人は知っているやつ)。\nマウスは使用しておらず、キーボードの手前にトラックパッドをおいて使っています。パームレストの部分は、サムライズムさんのトラックパッドがきれいに入るmagicTrayPalmです。 Mac book Proと同じような感じでトラックパッドが使えるのがいいですね。 興味がある方は、侍割のリンクをたどってもらうと、初めてサムライズムさんで買い物をする方に限り割引がつくようになってるみたいです(なんと、私もなんか割引になる!)。\nディスプレイアーム 外付けキーボードになったのですが、Mac Book Proの画面も活用したく、さらに上下での配置がやはり目線の移動距離が少ないので気に入っていました。ただ、前回のブログで紹介したアームでは少し高さが足りず。。。 思案しながらAmazonを回遊していたら、同じ会社の新しいアームがあり、調べると高さが取れそうだということで付け替えました。 アーム2本ありますが、今のところ1本だけを使っています。 2本目のアームにカメラを乗せるのもあり?と思いながらまだ試していませんが。玉突き式に前に使っていたアームがサンダーボルトディスプレイ(縦置き)のアームになっています。前にサンダーボルトにつけていたアームは重量オーバーで悲鳴を上げていたので。。。\nAmazon | HUANUO 2画面 アーム デュアル ガススプリング式 スマホ充電器 寝室で利用していた斜めに立てかけるタイプのワイヤレス充電器を作業デスクに持ってきました。 実は部屋に時計がなく、Pixel 3 XLを使っているので、スマホの画面に常に表示されている時計を置き時計の代わりに使えそうだなと (スマホで写真を撮っているので上の画像ではスマホがありませんが)。 結構便利です。ちょっと時間を確認したいときに、メニューバーの時計では流石に小さすぎるのでw\nAmazon | Anker PowerWave 7.5 Stand, Qi ワイヤレス充電器 ミキサー 音声のミキサーです。Yamahaのスピーカーは入力が2系統あるのですが、入力したい音声は3系統あります(ラズパイ4、Mac mini、メインディスプレイ)。2入力を1系統にまとめるプラグを試しに買ってみて、Mac miniとラズパイをまとめてみたのですが、残念ながら切り替わるときに数分無音状態が続くという問題が発生しました。 USB給電できるタイプを購入しました。スライダーとかいらないなと思っていたのですが、電話やミーティング時にBGMの音を下げたりするのに地味に便利だったりします。 ただ、スライダーを動かそうとすると本体も動いてしまっていたので、本体裏に滑り止めを貼ってあります。\nAmazon | Maker hart Just Mixer ステレオ3入力音声ミキサー/電池とUSB電源可能 Webカメラ おっさんの顔がきれいに写っても仕方ないんですが、下からのアングルよりはいいかなぁということと、今後の勉強会で使えそうかな?ということで、購入してみました。 縦でも横でも使える便利なカメラです。また、あんまりないのですが、部屋の中などを写すときにカメラを持ち回せるの便利ですね。 ディスプレイの上に置いてしまうと高さがありすぎるということで、スピーカーの上に乗っけています。仮置きなのですが、このままになるんじゃないかな? 打ち合わせ中は画面共有してることが多いのでオンライン飲み会などで主に活躍してる気も。。。\nAmazon | ロジクール ウェブカメラ フルHD 1080P 60FPS StreamCam C980OW オフホワイト USB-C接続 Mac miniのSSD化 見えないところですが、Mac miniのHDDをSSDに差し替えました。 性能検証用のマシンとしてMac miniを利用し始めたのですが、 計測するたびに速度の差がありすぎるのでおかしいな?と。 よくよく考えてみると、このMac miniはFusion Driveだったんです。。。 開発などで使う分には大容量だし便利だったのですが、負荷計測に利用する場合は挙動をハンドリングできないので、弊害でしかないです。。。 ということで、頑張って差し替えました。想像以上の大手術でした。 「Mac mini HDD 交換」などでググると換装している方たちがいらっしゃいます。興味ある方はググってみてください。\nさて、復路 pic.twitter.com/SwndXPoKqn\n\u0026mdash; Jun Ohtani (@johtani) July 25, 2020 Amazon | シリコンパワー SSD 1TB SATA3 6Gb/s 2.5インチ ラズパイ4 Mac miniの負荷検証マシン化のため+Linuxを触りたかったというのもあり、ラズパイ4を追加しました。 Mac miniは主な使用用途が音楽再生だったのでラズパイ4で肩代わりできるだろう+その他の検証にもラズパイ4が使えそうだと。 現在はUbuntuをインストールして、画面共有で操作しています。\nAmazon | LABISTS Raspberry Pi 4 4B MicroSDHCカード64G まとめ かなり快適になりました。キーボードもうるさくないですし、熱くもありません。マイクのポップガードは意味がなさそうなので外しました。\nまだいくつか気になってるものもあるので、また更新するかもしれません。\n分離式キーボード - 胸を広げた状態でキーを打ったほうがいいのでは?という気がしています。ただ、最近はずっと日本語キーボードを使っているので選択肢が少ないんですよね。。。\nサンダーボルト?USB-C?ドック - MacBook Proのポートがすべて埋まっているし、もう少しケーブルを減らせると幸せになれそうなきが。。。\nモバイルディスプレイ - MacBook Proのディスプレイを使っているのですが、キーボードの上にかぶってるんですよね、結構。。。クラムシェルにしてiPadもしくはモバイルディスプレイに置き換えたほうがスッキリはしそうかなと。ただ、Touch IDが使えなくなったり、クラムシェル状態でMacBook Proの電源を入れられないというはなしなので、あまり意味がなさそうだなというのもあります。\n","date":1599531445,"dir":"post/2020/","id":"d08a3fdc040bbbdd81c9927ce296318c","lang":"ja","lastmod":1599531445,"permalink":"https://blog.johtani.info/blog/2020/09/08/update-working-facility/","publishdate":"2020-09-08T11:17:25+09:00","summary":"自宅環境に少しアップデートがあったので更新版です。 お客さんのおかげで相変わらず自宅で作業させてもらってるのもあり、昨今のコロナウイルスの影響","tags":["misc"],"title":"自宅の作業環境(2020/09)"},{"contents":"Rustで便利なクレートを見つけたので、紹介がてら、自分のメモのためにブログに残しておきます。\nそもそもの問題 Rustで処理を書いていて、なんかちょっと遅いな?どこの処理で時間がかかってるんだろう? ということがありませんか?ありますよね?\nというのを調べるために、最初に思いつくのは自分で計測する方法です。 流石にそれはなぁ、と思ったのでググって出てきた方法を最初は使っていました。\nRustで実行時間計測 3年前の記事ですが、とりあえず計測する分には問題なかったのでこちらの方が書いていたマクロを拝借していました。 が、ちょっと面倒なのが戻り値がある処理などのときに、このマクロを挟むのが結構めんどくさいなと。 また、処理の時間を測りたいのは基本的にはメソッドや関数単位であることが多いです。\nで、さらにググっていて見つけたのが、meteredでした。\nどんなもの? 計測したい部分に#[metric]のようなアノテーションを追加することで計測対象としてくれます。 あとは、計測したものを保存するレジストリという場所を指定するだけです。 処理が終わったタイミングなどで、そのレジストリの内容を出力することで、次の情報を計測することができます。\nHitCount : 実行された回数 ErrorCount : エラーを返した数(Resultを戻り値にしているメソッドが対象) InFlight : 処理中の回数かな? ResponseTime : レスポンスタイム(処理に何秒かかったか) Throughput : スループット(1秒あたり何回呼ばれたか) とりあえず試してみたのは、ResponseTimeとThroughputです。他のメトリクスはまた後日(機会があれば)。 また、metered::metric::Metricトレイトというものが用意されているようで、これを実装した独自のメトリクスも扱うことができるようです。\n使い方 使い方としては次のようになります。\n計測対象となるメソッドがある構造体に、メトリクスを保持するためのレジストリを用意 計測対象にしたい構造体のメソッドに#[measure]を追加(このとき、計測したいものも指定する。) あとは、実行したあとに構造体をダンプするとメトリクスが出力されます。\nレジストリの用意 #[derive(Default, Debug, Serialize)] pub struct NekoParser { metric_reg: NekoParserMetricRegistry, } NekoParserMetricRegistryという型はこのあとのimplのアノテーションで指定する名前になります。 実際にはこの型の構造体を自分で定義する必要はありません。 構造体のderiveでDefaultを指定します。構造体のインスタンス化のときにdefault()メソッドを呼び出して初期化したいためです(おそらくレジストリの初期化をやってくれるのだと思う(要確認))。 レジストリの用意はこれだけです。\nレジストリの指定と計測対象の指定 計測対象側です。少し長いですが、NekoParserのメソッドすべてを掲載しました。 まずは、1行目でレジストリの名前の指定(registry = NekoParserMetricRegistry)、レジストリのフィールド名(registry_expr = self.metric_reg)、レジストリの可視性(visibility = pub(self))を定義します。 2行目では、implブロック全体で計測したいメトリクスを指定しています。今回は、スループットとレスポンスタイムを計測したかったので #measure([ResponseTime, Throughput])]と2種類を指定しています。 メトリクスが2種類のため配列で指定していますが、1種類だけの場合は[]の記号は必要ありません。\nあとは、計測したい各メソッドに#[measure]をつけるだけです。 なお、メソッドごとに#[measure(ErrorCount)]といったかたちで個別にメトリクスを指定することも可能です。 今回はお試しということもあり、すべて#[measure]だけになっています。 アノテーションを付けただけで、メソッド自体を変更はしていません。\n#[metered(registry = NekoParserMetricRegistry, registry_expr = self.metric_reg, visibility = pub(self))] #[measure([ResponseTime, Throughput])] impl NekoParser { #[measure] pub fn load_and_parse_neko(\u0026amp;self) { let file_path = \u0026#34;./data/chap04/neko.txt\u0026#34;; let file = File::open(file_path).unwrap(); let buf = BufReader::new(file); let mut out = File::create(\u0026#34;./data/chap04/neko.txt.lindera.json\u0026#34;).unwrap(); buf.lines().filter_map(|item| item.ok()).for_each(|line| { let tokens = self.tokenize(line.as_str()); self.output_tokens(\u0026amp;tokens, \u0026amp;mut out); }); } #[measure] pub fn output_tokens(\u0026amp;self, tokens: \u0026amp;Vec\u0026lt;Token\u0026gt;, buf: \u0026amp;mut File) { writeln!(buf, \u0026#34;{}\u0026#34;, serde_json::to_string(tokens).unwrap()) .expect(\u0026#34;Error during output json\u0026#34;); } #[measure] pub fn tokenize(\u0026amp;self, line: \u0026amp;str) -\u0026gt; Vec\u0026lt;Token\u0026gt; { let mut tokenizer = lindera::tokenizer::Tokenizer::new(\u0026#34;normal\u0026#34;, \u0026#34;\u0026#34;); let lindera_tokens = tokenizer.tokenize(line); let tokens = lindera_tokens .iter() .map(|lindera_token| { let surface = lindera_token.text.to_string(); let pos = lindera_token.detail[0].to_string(); let pos1 = if pos != \u0026#34;UNK\u0026#34; { lindera_token.detail[1].to_string() } else { String::new() }; let base = if pos != \u0026#34;UNK\u0026#34; { lindera_token.detail[6].to_string() } else { String::new() }; Token { surface, base, pos, pos1, } }) .collect(); return tokens; } } 計測結果の出力 最後は計測結果の出力です。 今回はテストメソッドで実行して結果を出力する処理を書きました。\nlet parser = NekoParser::default();で構造体をインスタンス化します。 あとは、処理をそのまま実行します。\n最後に出力結果をJSON形式の文字列にしてから出力しました。 let serialized ... println!(\u0026quot;{}\u0026quot;, serialized);という形です。 簡単ですね!\n#[cfg(test)] mod tests { use crate::chapter04::answer::NekoParser; use std::path::Path; #[test] fn success_output_tokenlists() { let parser = NekoParser::default(); parser.load_and_parse_neko(); let serialized = serde_json::to_string(\u0026amp;parser).unwrap(); println!(\u0026#34;{}\u0026#34;, serialized); assert!(Path::new(\u0026#34;./data/chap04/neko.txt.lindera.json\u0026#34;).exists()); } } 出力結果 ここまで紹介したものの実行結果は次のような形でした。 レスポンスタイム、スループットともに、最小、最大、99パーセンタイルなどを出力してくれます。 出力はメソッド名ごとにくくられているのでとても便利です。\n{ \u0026#34;metric_reg\u0026#34;: { \u0026#34;load_and_parse_neko\u0026#34;: { \u0026#34;response_time\u0026#34;: { \u0026#34;samples\u0026#34;: 1, \u0026#34;min\u0026#34;: 176128, \u0026#34;max\u0026#34;: 177151, \u0026#34;mean\u0026#34;: 176640.0, \u0026#34;stdev\u0026#34;: 0.0, \u0026#34;90%ile\u0026#34;: 177151, \u0026#34;95%ile\u0026#34;: 177151, \u0026#34;99%ile\u0026#34;: 177151, \u0026#34;99.9%ile\u0026#34;: 177151, \u0026#34;99.99%ile\u0026#34;: 177151 }, \u0026#34;throughput\u0026#34;: { \u0026#34;samples\u0026#34;: 0, \u0026#34;min\u0026#34;: 0, \u0026#34;max\u0026#34;: 0, \u0026#34;mean\u0026#34;: 0.0, \u0026#34;stdev\u0026#34;: 0.0, \u0026#34;90%ile\u0026#34;: 0, \u0026#34;95%ile\u0026#34;: 0, \u0026#34;99%ile\u0026#34;: 0, \u0026#34;99.9%ile\u0026#34;: 0, \u0026#34;99.99%ile\u0026#34;: 0 } }, \u0026#34;output_tokens\u0026#34;: { \u0026#34;response_time\u0026#34;: { \u0026#34;samples\u0026#34;: 9964, \u0026#34;min\u0026#34;: 0, \u0026#34;max\u0026#34;: 143, \u0026#34;mean\u0026#34;: 0.03592934564431955, \u0026#34;stdev\u0026#34;: 1.5152489085107463, \u0026#34;90%ile\u0026#34;: 0, \u0026#34;95%ile\u0026#34;: 0, \u0026#34;99%ile\u0026#34;: 0, \u0026#34;99.9%ile\u0026#34;: 6, \u0026#34;99.99%ile\u0026#34;: 143 }, \u0026#34;throughput\u0026#34;: { \u0026#34;samples\u0026#34;: 174, \u0026#34;min\u0026#34;: 39, \u0026#34;max\u0026#34;: 71, \u0026#34;mean\u0026#34;: 57.103448275862064, \u0026#34;stdev\u0026#34;: 3.8417981983375835, \u0026#34;90%ile\u0026#34;: 60, \u0026#34;95%ile\u0026#34;: 61, \u0026#34;99%ile\u0026#34;: 64, \u0026#34;99.9%ile\u0026#34;: 71, \u0026#34;99.99%ile\u0026#34;: 71 } }, \u0026#34;tokenize\u0026#34;: { \u0026#34;response_time\u0026#34;: { \u0026#34;samples\u0026#34;: 9964, \u0026#34;min\u0026#34;: 12, \u0026#34;max\u0026#34;: 79, \u0026#34;mean\u0026#34;: 16.897230028101177, \u0026#34;stdev\u0026#34;: 2.331145559054724, \u0026#34;90%ile\u0026#34;: 19, \u0026#34;95%ile\u0026#34;: 20, \u0026#34;99%ile\u0026#34;: 24, \u0026#34;99.9%ile\u0026#34;: 46, \u0026#34;99.99%ile\u0026#34;: 79 }, \u0026#34;throughput\u0026#34;: { \u0026#34;samples\u0026#34;: 174, \u0026#34;min\u0026#34;: 39, \u0026#34;max\u0026#34;: 71, \u0026#34;mean\u0026#34;: 57.103448275862064, \u0026#34;stdev\u0026#34;: 3.819293076427424, \u0026#34;90%ile\u0026#34;: 60, \u0026#34;95%ile\u0026#34;: 61, \u0026#34;99%ile\u0026#34;: 64, \u0026#34;99.9%ile\u0026#34;: 71, \u0026#34;99.99%ile\u0026#34;: 71 } } } } 出力内容で気になったのはoutput_tokensとtokenizeのthroughputが全く同じ結果が出ていることです。 なにかバグを踏んでいる気がします。。。(時間を見つけてソースコード読んでみるか。)\n気をつけること meteredの導入時にわかりにくいコンパイルエラーが出たので備忘録として残しておきます。 (下からコンパイルエラーを読んでしまうくせがあったのが問題なのですが。。。) エラーメッセージは次のとおりです。\nerror[E0412]: cannot find type `ResponseTime` in this scope --\u0026gt; src/chapter04/answer.rs:13:12 | 13 | #[measure([ResponseTime, Throughput])] | ^^^^^^^^^^^^ not found in this scope | help: consider importing one of these items | 1 | use metered::ResponseTime; | 1 | use metered::common::ResponseTime; | error[E0283]: type annotations needed --\u0026gt; src/chapter04/answer.rs:12:1 | 12 | #[metered(registry = NekoParserMetricRegistry, /* default = self.metrics */ registry_expr = self.metric_reg)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type | = note: cannot satisfy `_: std::default::Default` = note: required by `std::default::Default::default` = note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info) 最初のメッセージにはわかりやすく出ていますが、ResponseTimeをuseせずに利用しようとした場合に以下のようなエラーが出ていました。 ターミナル画面が狭かったのでE0283のエラーが目に入り、何を言ってるんだろう?という状態になってしまいました。 スクロールアップしたら、答えが載っているのに。。。\nコード全体 元ネタはNLP100本ノックの第4章です。 コードの全体はGitHubのソースをご覧ください。\nまとめ meteredを簡単ですが紹介してみました。 導入自体も簡単で、想像していたような使い方ができたので満足しています。 ほかにもプロファイラなどはあるのかもしれませんが、まずはこれを使っていこうかと思っています。\nバグらしきものがありそうだったりするので、そのへんは今後調査してみようかと。 まだ、ちょっと試してみただけなので、metered自体のオーバーヘッドや、独自のメトリクスの実装方法、メソッドではなく関数に対して利用する場合にはどうするのか?などいくつか疑問点があるので、今後試してみてまたブログに残しておこうと思います。\n","date":1599487900,"dir":"post/2020/","id":"827de2d7a9d231f6bcb44caf35896c1f","lang":"ja","lastmod":1599487900,"permalink":"https://blog.johtani.info/blog/2020/09/07/intro-metered-rs/","publishdate":"2020-09-07T23:11:40+09:00","summary":"Rustで便利なクレートを見つけたので、紹介がてら、自分のメモのためにブログに残しておきます。 そもそもの問題 Rustで処理を書いていて、なん","tags":["Rust"],"title":"meteredクレートの紹介"},{"contents":"Rustで言語処理100本ノックの第4章です。\n前回はこちら。\n今回は早めに続きをやりました。 「形態素解析」ですしね。\n第4章の概要 吾輩は猫であるの文章が用意されていて、MaCabで形態素解析した結果をファイルに保存したところからが開始となります。\nが、せっかくRustでやっているのでKuromojiのRust版であるLinderaを利用して形態素解析した結果を保存する部分から作成しました。 3章に引き続き、大きな流れのところの説明だけにしておきます。\n形態素解析 もとのneko.txtが文章が1行ごとになっているので、そのまま1行ずつ読みならが、形態素解析していきます。読み込みの部分は3章とあまり変わらないので割愛します。 以下は、形態素解析の処理と形態素解析結果用の構造体です。\n#[derive(Clone, Debug, Serialize, Deserialize)] struct Token { surface: String, base: String, pos: String, pos1: String, } まずは構造体です。今回の問題では、必要な情報は4種類だったのでそれを構造体にしました。\n表層形(surface) 基本形(base) 品詞(pos) 品詞細分類1(pos1) deriveでSerialize、Deserializeを付与しているのは、形態素解析の結果をJSON文字列として保存し、あとのそれぞれの課題で読み出すためにserde_jsonを利用するためです。\nfn tokenize(line: \u0026amp;str) -\u0026gt; Vec\u0026lt;Token\u0026gt; { let mut tokenizer = lindera::tokenizer::Tokenizer::new(\u0026#34;normal\u0026#34;, \u0026#34;\u0026#34;); let lindera_tokens = tokenizer.tokenize(line); let tokens = lindera_tokens .iter() .map(|lindera_token| { let surface = lindera_token.text.to_string(); let pos = lindera_token.detail[0].to_string(); let pos1 = if pos != \u0026#34;UNK\u0026#34; { lindera_token.detail[1].to_string() } else { String::new() }; let base = if pos != \u0026#34;UNK\u0026#34; { lindera_token.detail[6].to_string() } else { String::new() }; Token { surface, base, pos, pos1, } }) .collect(); return tokens; } 次が形態素解析の処理です。 入力に1行分の文章を受け取り、出力として、さきほどの構造体をベクタに入れたものVec\u0026lt;Token\u0026gt;を返します。 内部ではLinderaのTokenizerをnormalモードでインスタンス化してそのtokenizer()メソッドを叩いているだけです。 インスタンス化のときの第2引数は辞書のディレクトリですが、今回はデフォルト辞書(IPADIC)を利用しています。 戻り値はLinderaが用意したToken構造体なので、これを今回作成したToken構造体に詰め替えているだけです。\n注意点としてLinderaはMeCabとは異なり、未知語(辞書に出てこない単語)の処理が実装されていないので、品詞が\u0026quot;UNK\u0026quot;の場合にはその他の情報が取得できないので、空文字を構造体に設定するようにしました。\n結果の保存 形態素解析の結果はJSONで保存しました。 もとのファイルが1文が1行になっていたので、 1行を読み込み、形態素解析し、それをVecで取り出して、1行1配列JSONの形で保存するようにしてあります。\nfn output_tokens(tokens: \u0026amp;Vec\u0026lt;Token\u0026gt;, buf: \u0026amp;mut File) { writeln!(buf, \u0026#34;{}\u0026#34;, serde_json::to_string(tokens).unwrap()).expect(\u0026#34;Error during output json\u0026#34;); } serde_json::to_stringにVec\u0026lt;Token\u0026gt;を渡しているだけですが、構造体にderiveをつけているのでよしなにやってくれます(便利ー)。\nJSONの読み込み処理 1行1JSONの読み込み処理です。 今回も3章のように読み込みながら、各文章ごとの形態素解析結果に対して処理を実施するために、処理を実行するためのtraitをCommandとして用意し、それぞれの問題で形態素解析結果に対して処理を書くような実装にしました。また、設問37で「猫」と共起している単語を処理するという課題があるので、文章に「猫」が入っているものだけを処理できるようにするためのFilterも用意し、これをJSONの読み込み処理のイテレータのfilterにわたすようにしています。 特にフィルタリングが必要ない場合ように、NonFilterを予め実装済みです。\ntrait Command { fn execute(\u0026amp;mut self, tokens: \u0026amp;Vec\u0026lt;Token\u0026gt;); } trait Filter { fn is_target(\u0026amp;self, line: \u0026amp;str) -\u0026gt; bool; } struct NonFilter {} impl Filter for NonFilter { fn is_target(\u0026amp;self, line: \u0026amp;str) -\u0026gt; bool { true } } // ch04-30. 形態素解析結果の読み込み fn load_json\u0026lt;T: Command\u0026gt;(cmd: \u0026amp;mut T) { load_json_with_filter(cmd, \u0026amp;NonFilter {}); } fn load_json_with_filter\u0026lt;T: Command, U: Filter\u0026gt;(cmd: \u0026amp;mut T, filter: \u0026amp;U) { let file = File::open(\u0026#34;./data/chap04/neko.txt.lindera.json\u0026#34;).unwrap(); let buf = BufReader::new(file); buf.lines() .filter_map(|item| item.ok()) .filter(|line| filter.is_target(line)) .for_each(|line| { let tokens = parse_line_json(line.as_str()); cmd.execute(\u0026amp;tokens); }); } output_tokensではserde_json::to_stringを呼び出してましたが、読み込みでは、serde_json::from_strを使うと構造体にしてくれます。\nfn parse_line_json(line: \u0026amp;str) -\u0026gt; Vec\u0026lt;Token\u0026gt; { return serde_json::from_str(line).unwrap(); } あとは、設問ごとにCommandトレイトを実装していく形です。 たとえば、32.の動詞の原形を出力する場合は次のようになります。\nstruct ExtractVerbBase { out: File, } impl Command for ExtractVerbBase { fn execute(\u0026amp;mut self, tokens: \u0026amp;Vec\u0026lt;Token\u0026gt;) { tokens .iter() .filter(|token| token.pos == \u0026#34;動詞\u0026#34;) .for_each(|token| { writeln!(self.out, \u0026#34;{}\u0026#34;, token.base).expect(\u0026#34;Error during writeln\u0026#34;); println!(\u0026#34;{}\u0026#34;, token.base); }) } } 標準出力とは別にファイルにも出力できるようにExtractVerbBaseにoutでファイルを保持しています。\n34. 名詞の連接 「名詞の連接(連続して出現する名詞)を最長一致で抽出せよ.」という課題だったのですが、最初は読み間違えて、名詞の連接の最も長いものだけを出力するようにしてました。。。 やっぱり、出力結果とかのサンプルは用意しといてほしいなぁ。。。\nimpl Command for ExtractMaxConjunctionNoun { fn execute(\u0026amp;mut self, tokens: \u0026amp;Vec\u0026lt;Token\u0026gt;) { let mut nouns = vec![]; // TODO 参照保持でどうにかしたいけどなぁ。 tokens.iter().map(|token| token.clone()).for_each(|token| { if token.pos == \u0026#34;名詞\u0026#34; { nouns.push(token); } else { if nouns.len() \u0026gt; 1 { self.buffer.push(nouns.clone()); } nouns = vec![] } }); } } 名詞の場合に、nounsにバッファリングしつつ、違う品詞が来たら出力するという処理になっています。 cloneを呼び出していますが、これを参照を引き回す感じにできるといいのかもなぁ(結構めんどくさい)。\n36. 頻度上位10語 頻度を数えるのにはBTreeMapを利用しています。 数えながら、Top10を保持する方法がいい気がしたのですが、いい入れ物を見つけられなかったので、数え上げたあとにBTreeMapのIteratorを回しながら、キーバリューのVecをまず生成します。 その生成したVecに値でソートし、その後Iteratorから最初の10件を取得して表示する方法にしました。\nソートして取り出すという処理がついでにかかっています。。。 BinaryHeapがなにか使えそうな気もしたのですが、いい方法が思いつきませんでした。\nfn print_top10(\u0026amp;mut self) { let mut key_values: Vec\u0026lt;(\u0026amp;String, \u0026amp;u32)\u0026gt; = self.terms_count.iter().collect::\u0026lt;Vec\u0026lt;(\u0026amp;String, \u0026amp;u32)\u0026gt;\u0026gt;(); key_values.sort_by(|x, y| y.1.cmp(\u0026amp;x.1)); key_values.iter().take(10).for_each(|(key, value)| { writeln!(\u0026amp;self.out, \u0026#34;{}, {}\u0026#34;, key, value).expect(\u0026#34;Error during writeln\u0026#34;); println!(\u0026#34;{}, {}\u0026#34;, key, value); }); } まとめ 形態素解析結果をちゃんと眺めてはいないですが、処理としてはこんなところかなと。 グラフはめんどくさいのでスキップしてしまいました。。。 Kibana/Esに食わせて見てみるのもありかなぁ?\n次は係り受け解析です。Rustで使えるライブラリとかあるかなぁ?\n","date":1599445027,"dir":"post/2020/","id":"3c5d4d351e0fb9e33e0e8b6d1d43c0f2","lang":"ja","lastmod":1599445027,"permalink":"https://blog.johtani.info/blog/2020/09/07/reboot-nlp100-ch04/","publishdate":"2020-09-07T11:17:07+09:00","summary":"Rustで言語処理100本ノックの第4章です。 前回はこちら。 今回は早めに続きをやりました。 「形態素解析」ですしね。 第4章の概要 吾輩は猫である","tags":["Rust","nlp100"],"title":"第4章終了(言語処理100本ノック2020)"},{"contents":"Rustで言語処理100本ノックの第3章です。\n前回はこちら。\n少し間が空きましたが、再開しました。 間が空いた理由は。。。「正規表現」ですかね。。。 苦手なんです、正規表現。 なので、28はちょっとギブアップしてしまいました。\n第3章の概要 個別に説明はせずに大きな流れのところだけ。 それぞれの問題の解についてはリポジトリを御覧ください(興味ある人いるのかなぁ?)\n第3章はNDJSON(new line delimited JSON)という、 1行に1JSONという形式のデータを格納したファイルがgzipで圧縮された状態で提供されます。 まずは、このJSONファイルからJSONを読み込むのが主な処理になります。\n読み込んだデータに「イギリス」のWikipediaの記事が入っているので、そこから正規表現で必要なデータを抽出します。\n最後の問題が少し特殊で、抜き出した情報の「国旗」のファイル名を元に、MediaWikiのREST APIを叩いて、結果を取得し、その一部の情報を抜き出すというものです。\nJSONの読み込み処理 gzipファイルを読み込んでから、1行ずつ抜き出してVecに入れる処理が次のようになります。 今回のgzipファイルは大した量が入っていないので、全部先に抜き出す処理としてまとめました。 もっと巨大なファイルの場合は個別のJSONに対する処理を buf.lines().map()のmapのなかで実行する形にすると思います。 gzipのファイルを開くのにflate2というクレート(ライブラリ)を利用しました。便利なのは、BufReaderにlines()というメソッドがあるところですかね。\n// https://docs.rs/flate2/1.0.14/flate2/read/struct.GzDecoder.html pub fn extract_ndjson_from_gzip(input_file_name: \u0026amp;str) -\u0026gt; Vec\u0026lt;String\u0026gt; { let f = File::open(input_file_name).expect(\u0026#34;file not found?\u0026#34;); let gz = GzDecoder::new(f); let buf = BufReader::new(gz); let lines: Vec\u0026lt;String\u0026gt; = buf.lines().map(|l| l.unwrap()).collect(); return lines; } こちらは、上記のメソッドで抜き出したVecを元に、記事の情報を抜き出す処理をしています。 JSONをパースして構造体Articleにデシリアライズするために、serdeというライブラリを使用しています。 serde自体は様々なデータ形式(JSON、YAMLなど)をパースするためのフレームワークです。今回はJSONなので、serde_jsonの実装を利用しています。 また、JSON文字列から構造体にデシリアライズするのを簡単にできるように構造体に#[derive(Deserialize)]をつけています。 あとは、let article: Article = serde_json::from_str(json.as_str())という処理を実行すればserde_jsonがJSONをパースして構造体に変換してくれます。形式がわかっているJSONの扱いはこれが楽ですね。変数に型を明記してあるので、型の推論もしてくれてるようです。\n#[derive(Deserialize)] pub struct Article { title: String, text: String, } // ch03-20. JSONデータの読み込み // https://serde.rs/ pub fn load_json(input_file_name: \u0026amp;str, target_title: \u0026amp;str) -\u0026gt; Vec\u0026lt;Article\u0026gt; { let mut results = vec![]; let ndjson = extract_ndjson_from_gzip(input_file_name); for json in ndjson { let article: Article = serde_json::from_str(json.as_str()).expect(\u0026#34;json parse error\u0026#34;); if article.title == target_title { results.push(article); } } return results; } 後続の処理ではパースしたArticleから記事情報を取得して色々と処理をしています。\n正規表現 正規表現用のクレートregexがRustに用意されています。Regex::new(正規表現)で、正規表現をコンパイルし、あとは、この構造体のメソッドを利用して文字列を処理していきます。 問題では、マッチするかどうか、マッチした一部の文字列を抜き出す、不要なタグを削除するといった処理を正規表現で行いました(Rust書くよりも正規表現の書き方とかを調べるのに大半の時間をもっていかれてます。。。)。\npub fn extract_category_lines(article: \u0026amp;Article) -\u0026gt; Vec\u0026lt;String\u0026gt; { let re = Regex::new(r\u0026#34;\\[\\[Category:(.*)\\]\\]\u0026#34;).expect(\u0026#34;syntax error in regex\u0026#34;); let mut lines = vec![]; article.lines_from_text().iter().for_each(|line| { if re.is_match(line) { lines.push(line.to_string()); } }); return lines; } MediaWiki APIリクエスト処理 最後の問題で国旗のファイル名を元にMediaWiki APIを叩いて、URLの文字列を取得しましょうという問題がありました。 ファイル名をREST APIの引数に渡してHTTP経由でリクエストを送信し、返ってくるJSONレスポンスからURLを抜き出すという処理です。\nHTTPのリクエストの送受信にreqwestというクレートを利用しました。 ちょっと長いけど、APIコールしている箇所はこんな形です。\nこの関数にはasyncとついています。非同期処理の関数です。内部で2回ほど(リクエスト送信の結果待ちとレスポンスのパース待ち).awaitがあります。\nclientに.get(URL)やquery(\u0026amp;[])といったメソッドが用意されているので、URLやクエリパラメータを用意してsend()でリクエスト送信します。\nasync fn call_api(file_name: \u0026amp;str) -\u0026gt; Result\u0026lt;String, String\u0026gt; { let client = reqwest::Client::new(); let file_name2 = format!(\u0026#34;File:{}\u0026#34;, file_name); //let mut file_name2 = file_name.to_string().replace(\u0026#34; \u0026#34;, \u0026#34;_\u0026#34;); let query = [ (\u0026#34;action\u0026#34;, \u0026#34;query\u0026#34;), (\u0026#34;format\u0026#34;, \u0026#34;json\u0026#34;), (\u0026#34;prop\u0026#34;, \u0026#34;imageinfo\u0026#34;), (\u0026#34;iiprop\u0026#34;, \u0026#34;url\u0026#34;), (\u0026#34;titles\u0026#34;, file_name2.as_str()), ]; let result = client .get(\u0026#34;https://en.wikipedia.org/w/api.php\u0026#34;) .query(\u0026amp;query) .send() .await; match result { Ok(response) =\u0026gt; match response.status() { StatusCode::OK =\u0026gt; { let body = response.json::\u0026lt;MediaWikiResponse\u0026gt;().await; match body { Ok(obj) =\u0026gt; match obj.get_url() { Some(url) =\u0026gt; Ok(url), None =\u0026gt; Err(String::from(\u0026#34;Cannot get url...\u0026#34;)), }, Err(error) =\u0026gt; Err(error.to_string()), } } _ =\u0026gt; Err(String::from(format!( \u0026#34;Status code is {}.\u0026#34;, response.status() ))), }, Err(error) =\u0026gt; { let error_msg = format!(\u0026#34;Error occurred... {:?}\u0026#34;, error); println!(\u0026#34;{}\u0026#34;, error_msg.as_str()); Err(error_msg) } } } あとは、呼び出し元で非同期の処理を実行するために、tokioというクレートを利用しています。 block_on()でcall_api()の実行をして、結果が返ってくるのを待ち受けています。結果が返ってきて、問題なければ、call_apiの戻り値Result\u0026lt;String, String\u0026gt;の左側のStringの値が取り出され、get_image_urlの戻り値となります。\nfn get_image_url(file_name: \u0026amp;str) -\u0026gt; String { let mut _rt = tokio::runtime::Runtime::new().expect(\u0026#34;Fail initializing runtime\u0026#34;); let task = call_api(file_name); _rt.block_on(task).expect(\u0026#34;Something wrong...\u0026#34;) } 一応、非同期に関して説明してみましたが、合っているのかどうか。。。 クレートの関係などはまだちょっと自身がないです。。。 あとは、エラーの処理の仕方とかももうちょっと勉強したいかな。\nまとめ 一応、3章を終わらせました。だいぶ強引かつ1つスキップしましたが。。。 次は第4章の形態素解析です。\n","date":1599230785,"dir":"post/2020/","id":"eb2a5824e03996c1966bee38866ce349","lang":"ja","lastmod":1599230785,"permalink":"https://blog.johtani.info/blog/2020/09/04/reboot-nlp100-ch03/","publishdate":"2020-09-04T23:46:25+09:00","summary":"Rustで言語処理100本ノックの第3章です。 前回はこちら。 少し間が空きましたが、再開しました。 間が空いた理由は。。。「正規表現」ですかね。","tags":["Rust","nlp100"],"title":"第3章終了(言語処理100本ノック2020)"},{"contents":"負荷を計測するために、数回、Azure Cognitive Searchのクラスターを起動したり、停止したりしてました。 これは、Terraformでやると楽できるのでは?と思ったので、やってみました。 1パーティションのクラスターなので、全然大したことはないのですが、メモを残しておくためにブログに書いておきます。\n基本的にはTerraformの公式ドキュメントにあったものを自分用に変数を抽出しただけです。\nファイルたち 単にクラスターを起動するためだけなので、2種類のファイルだけ作成しました(1個でもいいかも)。\nvariables.tf - 変数用のファイル。いくつかの設定を変数として定義しました。 terraform.tf - Terraform本体のファイル。 variables.tf まずはvariables.tfです(ファイル内の並びは異なりますが。。。)。terraform.tfで利用する5つの変数です。\nresource_group - リソースグループ名。既存とは異なるリソースグループ名にしました(変に壊してもいいので)。 machine_type - 価格レベル(SKU)。公式ドキュメントに設定できる値の一覧があります。今回はWikipediaのデータを登録していたのでそれが入るサイズにしています。 region - 場所(リージョン)。リージョンの一覧はどこにあるんだろう?これを参考にしましたが。 partition_size - パーティションのサイズ(=Elasticsearchでのシャードかな?)です。今回は1つでの性能を計測したかったので1にしてあります。 search_cluster_name - Azure Cognitive Searchのサービス名。search.windows.net名前空間で一意である必要があったので、他の人が使わなそうな名前をつけています。 variable \u0026#34;machine_type\u0026#34; { default = \u0026#34;standard\u0026#34; } variable \u0026#34;region\u0026#34; { default = \u0026#34;East Asia\u0026#34; } variable \u0026#34;resource_group\u0026#34; { default = \u0026#34;johtani-wiki-test\u0026#34; } variable \u0026#34;search_cluster_name\u0026#34; { default = \u0026#34;johtani-wikipedia\u0026#34; } variable \u0026#34;partition_size\u0026#34; { default = 1 } terraform.tf terraform.tfは以下の通り。Terraformの公式ドキュメントにある例にproviderを追加しただけのものになります。\nprovider - プロバイダーの設定。Azureを利用するという宣言です。features {}がないとエラーになります。空でも必ず指定が必要です。認証周りについては、azure-cli経由で認証する方式を採用しました。azure-cliはHomebrewでインストールしています。 azurerm_resource_group - リソースグループの設定。variables.tfのresource_groupとregionを利用しています。必須項目はこの2種類だけです。 azurerm_search_service - Azure Cognitive Searchの設定。partition_count以外は必須項目です。variables.tfとazurerm_resource_groupの設定を利用しています。今回は利用していませんが、レプリカ数なども指定できるようになっています。 # Azureのproviderを指定。 provider \u0026#34;azurerm\u0026#34; { features {} } # リソースグループの設定 resource \u0026#34;azurerm_resource_group\u0026#34; \u0026#34;wiki-test\u0026#34; { name = var.resource_group location = var.region } # Azure Cognitive Searchの設定 resource \u0026#34;azurerm_search_service\u0026#34; \u0026#34;search_service\u0026#34; { name = var.search_cluster_name resource_group_name = azurerm_resource_group.wiki-test.name location = azurerm_resource_group.wiki-test.location sku = var.machine_type partition_count = var.partition_size } 以上がファイルです。ほぼ公式ドキュメントのサンプル通りですねw\nデプロイとか ファイルの準備ができたら実際にデプロイします。 Azureの環境への認証にはAzure CLIを利用して、事前にログインした状態にします。 実際にデプロイするまでの手順は次のようになります。\naz login - Azureの認証。ブラウザが起動してログイン画面が表示されます。無事認証がOKなら、azコマンドでAzure Cloudの情報が取得できます。 terraform init - 初回だけです。Terraformのワーキングディレクトリの初期化処理を実行します。 terraform plan - Terraform \u0026lt; 0.12の場合は実行。最新版だともういらないみたいだ。 terraform apply - 実際にAzure上にクラスターを起動します。Terraformが隠蔽してくれているので、実際にどんなことをやっているかはわかってないですが。 以上で、Azure Cognitive Searchのクラスターが起動します。 すごく簡単です。Webコンソールでチェックすれば、起動していることも確認できます。\nこの状態では、クラスターが起動しただけなので、あとは必要に応じてデータをロードしたり、アプリから検索したりと行ったことが可能になります。 そのへんの話はまた機会があれば。\nDestroy 今回は負荷テスト用にクラスターを起動していましたので、必要なくなれば、クラスターを削除します。Terraformを導入したもう一つの理由がこの簡略化です。 terraform destroyを実行するだけで、Azure Cognitive Searchのクラスターおよび、リソースグループが削除されます。\nまとめ ということで、ほぼ公式ドキュメントのままですが、TerraformでAzure Cognitive Searchのクラスターを起動する方法の紹介でした。 ブログを書いていて、1点気になったのは、ロケーション(リージョン)の一覧はどこにあるんだろう?という点です。azコマンドとかで出てくるのかなぁ?\n","date":1597742807,"dir":"post/2020/","id":"f5effd616a3f8db6193b482caec37912","lang":"ja","lastmod":1597742807,"permalink":"https://blog.johtani.info/blog/2020/08/18/azure-search-with-terraform/","publishdate":"2020-08-18T18:26:47+09:00","summary":"負荷を計測するために、数回、Azure Cognitive Searchのクラスターを起動したり、停止したりしてました。 これは、Terraformでやると楽でき","tags":["azure search"],"title":"TerraformでAzure Cognitive Searchのクラスターを起動"},{"contents":"先日は「システムの特徴と検索機能について」という感じでふんわり書きました。 まぁ、頭の中でぼんやり考えてることを文章にしてみた感じです。 他にもぼんやりしてるものはいくつかあるので今日も書いてみることに。 検索システム?みたいなツイートも見かけたので、検索システムってこんなイメージですというブログを書いてみました。\n検索システム(機能)を構成するパーツ 今回はシステムに組み込まれる検索機能を構成するパーツについて書き出してみようかなと思います。 パーツといってもユーザー、UI、コンテンツなども入れています。\nユーザー 検索UI 検索窓 オートコンプリート 検索結果画面 ファセット ソート ハイライト 詳細画面 レコメンド 検索エンジン コンテンツ 検索ログ クリックログとかも サービス提供者 ざっくり書くとこんな感じです。 システム構成だったり、機能だったり、アクターだったりといろいろなものが混ざってしまっていますが、登場するものはこんなものです。\nざっくりした繋がりの図はこんな感じです。\nそれぞれの役割について見ていきましょう。\nユーザー サイト、システムのユーザーです。 検索UIを経由して望んだコンテンツを探します。 探す目的は、サイトによって異なります。 「何かを購入(ECサイトやオークション)する」だったり、「情報(レシピや社内文書)を見つける」だったりします。 図では「キーワード」と記載しましたが、最近では自然文(文章)を受け付ける検索もあります。\n検索UI サイト、システムが提供するUIです。ユーザーはこのUIにキーワード(質問)を入力し、検索結果を取得します。 UIにはいくつものパーツがさらに存在します。簡単に例を上げると以下のようなものです。\n検索窓 - キーワードを入れるための入力ボックスです。 オートコンプリート(自動補完) - サイトによっては、検索窓に何かを入力すると、キーワードを保管したりサジェストしたりしてくれます。 検索結果画面 - 質問にマッチしたコンテンツの一覧を表示する画面です。一覧以外にもいくつか情報が表示されます。 検索結果一覧 - コンテンツの一覧です。何かしらの基準(日付順や人気順など)によってソートされたものが表示されます。 ファセット - 検索結果が持っている属性(価格帯、カテゴリ、メーカー名など)の一覧で、絞り込み検索のヒントです。 ハイライト - 入力したキーワードがどこにマッチしたかがわかるように、強調表示されたスニペット(情報の一部)が出ます。 検索APIとUIに分かれている場合が多いでしょうか? 処理の流れとしては、検索窓に入力されたキーワードを検索エンジンに問い合わせができるクエリに書き換えてからリクエストを投げます。 あとは、検索エンジンからのレスポンスにある検索結果を表示できる形に変換して表示するのが役割です。 また、検索ログの出力もこの部分で担当することが多いです(もしくは、検索エンジン自体がログ出力の機能を持っている場合もあります)。\n検索エンジン 検索に特化したデータ構造を内部に持っているサーバーもしくはサービスです。 ElasticsearchやApache Solr、Azure Cognitive Searchなどは転置インデックスと呼ばれるデータ構造になっています。 検索エンジンの検索処理に対しての主な役割は次の2つです。\nクエリにマッチするコンテンツの集合を決定する マッチしたコンテンツを特定の条件で並び替える(ランキング) クエリを受け取り、検索結果のリストを返すのが処理の大きな流れです。 その他に、ファセット、ハイライトといった付加的な処理を実行することがあります。\nまた、データ登録(インデキシング/インデクシング)の処理もあります。\n登録するコンテンツを検索に特化したデータ構造にして格納する 転置インデックスの場合は、入力されたデータ(文章)から単語列を作り出して、単語からコンテンツのIDが判別できる形にする処理になります。\nAlgoliaやElastic App SearchのようなSaaSであったり、RDBの機能を利用するといった選択肢もあります。\nデータソース・コンテンツ 実際に提供したいコンテンツになります。 コンテンツが保存されている場所は、サイトによって異なります。\nWebの検索サイト - インターネット上のホームページ ECサイト - データベースに格納されているアイテムのデータ 社内文書検索 - ファイルサーバーやWikiなどのファイル、文書 といった感じです。 実際には、データソースからコンテンツを検索エンジンに登録する場合は、いくつかの処理(いわゆる前処理)が必要になります。 社内文書検索やWebの検索サイトの場合は、データを収集するためのクローラーが必要ですし、 収集したデータから、検索エンジンに登録するデータを加工したり(HTMLタグを除去したり、メタデータ(URL、収集日、タイトル)を付与したり)もします(ETL処理とか言われる)。\n検索ログ 検索を提供するだけであれば、必要ありません。 が、実際に検索がどのような使われ方をしているか?を知るために必要な機能になります。 この検索ログがユーザーのニーズを読み解くための情報になります。 検索ログには次のような情報が入ります。\n検索窓に入力された文字列 入力された文字列でヒットした件数 検索結果を出したタイミングでのログです。他にも実際にヒットしたコンテンツのIDなどをログに残したり、他のユーザーと区別をつけるために、ユーザーのセッションごとにIDを発行してログに残したりもします。\nまた、検索に満足してもらえているかを見るために、実際に検索結果のどのコンテンツに興味をもったのか?という情報も検索ログとして残すことがあります。クリックログなどとも呼ばれます。検索結果のどのドキュメントが実際にクリックされたか(詳細画面に遷移したか)という情報です。1回の検索結果に対してクリックされるごとにログが残ります。 もちろん、結果に満足しない場合は、クリックされずに、キーワードを変えたり、絞り込み条件がクリックされたりします。\nECサイトなどの場合は更に、実際に購入されたかどうかといった情報もユーザーのニーズを読み解くための情報となります。 詳細画面へのクリックログや購入ログについては、検索以外からの流れ(広告やDMだったり、レコメンドだったり)なども考えられます。 これらのログを元に、検索を改善していくことになります。\nサービス提供者 サイト・システムの提供者です。 コンテンツの準備、検索UIにはどんな物が必要なのか、サイト・システムにとって良い検索とはなにか?、検索ログからユーザーのニーズを分析して何を改善していくのか?といったことを考えます。 例としては次のようなことです。\n検索結果に表示するコンテンツとはなにか? コンテンツの持っている項目・属性の何を検索対象とするか? 検索結果の並び順(ランキング)がどんなものがよいのか? 検索UIにはどんなものを表示するのか? 検索機能を作るときの流れ 検索機能を構成するパーツにどんなものがあるかを紹介しました。 実際にシステムに検索機能を追加する場合は、最低限、次のものが必要になります。\n検索UI 検索エンジン(RDB?SaaS?ミドルウェア?) データソース・コンテンツ とりあえずこれらがあれば、検索機能を作ることはできるかと。 ただ、作っただけでは、いいか悪いかの判断がつかないので、どういった使われ方をしているかを知るために検索ログをとったりして、 改善をしていく必要が出てきます。\nまとめ わかってるよそんなことはと言われそうな感じになったかもしれないですが、 検索の機能を構成するパーツについて紹介してみました。 細かなはなしは色々とありますが、大まかにはこのような役割のパーツがあります。\n実際にはこれらのパーツを用意すればよいわけではなく、それぞれで検索を良くしていくためにどんなことを考えていくのか?などが出てきます。そのあたりの話はまた、別のブログで書いていく感じでしょうか。こんな感じで書いてくと、終わらない気がしてきたけど。。。 次はどんなはなしを書くかなぁ。\n","date":1595907282,"dir":"post/2020/","id":"11a61827e80739a6065960eb188d5758","lang":"ja","lastmod":1595907282,"permalink":"https://blog.johtani.info/blog/2020/07/28/improve-search-no2/","publishdate":"2020-07-28T12:34:42+09:00","summary":"先日は「システムの特徴と検索機能について」という感じでふんわり書きました。 まぁ、頭の中でぼんやり考えてることを文章にしてみた感じです。 他にも","tags":["検索"],"title":"検索システムを構成するパーツ(検索システムに関する妄想その2)"},{"contents":"今年の頭からシステムの検索周りを手伝う仕事をフリーランスとしてやっています。 検索の仕組みを知れば知るほど面白くなってきたからという理由になるのかな? LuceneやSolr、Elasticsearchなどを長く触っているというのもあるかと思います。\nということで、検索についていつも考えています。 頭の中でまとまっていない状況ですが、システムにおける検索機能についていくつか頭の中にあることを書き出して、 いろんな方にダメ出しやコメントをもらいたいなと思ったので、色々と書いてみようかと。 思いつきのままに書いているので、はなしがあちこち飛ぶ可能性もありますが、あしからず。\n検索って難しい 「「検索」とは、データの集合から目的のデータを探し出すこと」By Wikipedia\n一言で「検索」といっても、使う人、ユースケースによっていろいろな「検索」があります。 例えば、新しいスマホを買ったときに、スクリーンロックの時間を設定する機能を「検索」したりします。 また、PCで仕事をしているときに、ファイルの中身をある文字列で「検索」したりもします。 TSUTAYAに行って、欲しかった本がおいてあるかどうか店内の端末で「検索」もします。 Rustを書いていて、こんなことをやるライブラリありそうだよな?と思ってGoogleでウェブの検索をしたりもします。\n私が特にそうだと思いますが、なにかあったらまず検索をするという生活をしています。 ただ、このとき、「検索」といっても望んでいる挙動が違ったりするものです。 以下は自分が「検索」しているときに想定していることになります。\nファイル内の検索をしているときはgrep的な検索を想定していることが多い。 書籍の検索をしているときは、特定の項目(著者など)に対してgrep的な検索を想定しているが、名前の読みなどでも検索されることを想定している(漢字覚えてなかったりする。。。)。 Rustを書いているときに機能をGoogleで検索するときは、いい感じに検索してくれることを望んでいる(入力するキーワードが曖昧なことが多々ある。例えば、そのものズバリの名前をしらないときとか) あくまでも私が想像している挙動です。他の人とは違う可能性もあります。 なので、「検索」といってもさまざまな要素があるし、想定しているシーンも異なるので「難しい」なと思っています。 また、そんな「検索」ですが、世の中的にはあって当たり前だと思われていたり、お金や時間がかかるものと思われてなかったりもします。ま、けどそういったことも含めてやればやるほど面白いなと感じている今日このごろです。\n前置きはこのくらいにして、今回はシステムの特徴と検索機能について感じていることを書いてみようと思います。\nシステムの特徴と検索機能 先ほども書きましたが、検索は今やシステムに欠かせない機能となっています。 が、あればいいというものでもないのではないかなと。とりあえず検索できるべきだということで 検索機能を追加しても使いにくいものや、想定している動きをしない場合は使われないものになってしまいます。\nシステムでの検索機能は特に、「情報検索」(Wikipediaはこちら)と呼ばれたりもします。Wikipediaによるとこんな説明です。\n情報検索(じょうほうけんさく)とは、コンピュータを用いて大量のデータ群から目的に合致したものを取り出すこと。検索の対象となるデータには文書や画像、音声、映像、その他さまざまなメディアやその組み合わせとして記録されたデータなどが含まれる。\n「目的」と呼ばれるものは「ユーザーのニーズ」と呼ばれたりもします。 「合致したもの」というのがシステムが返す「検索結果」になります。検索結果は大体の場合、何かしらの順序でソートされていることが多いです。 ざっくり話をすると、「ユーザーのニーズ」を元に「(何かしらの順序でソートされている)検索結果」を返すという処理です。\nただ、この「ユーザーのニーズ」や「何かしらの順序でソートされている検索結果」はシステムの特性、特徴によってぜんぜん違うものになります。検索エンジンを入れただけで解決するものではありません。\nまた、システムは提供する側のニーズもあります。 ECサイトであればより多くのユーザーに購買してもらったり、 コミュニティサイトの場合は利用ユーザーを増やしてコンテンツや広告の収入を増やしたりといったニーズがあります。\nこれらの両方のニーズが検索機能に影響を与えたりもします。\nいくつか例を上げてみましょう。\n書籍の検索の場合 ユーザーのニーズは、「ある本を探す」ことです。そのためにユーザーがクエリを入力します。 クエリは、例にも出しましたがタイトルや著者名の読みだったりします。 検索窓が1つしかないというよりは、著者やタイトル、出版社などそれぞれの項目ごとに検索できるほうが便利だったりしますよね。 検索結果については、完全一致したものが一番最初に出てきてほしいこともあれば、出版年月日の降順で並べたいことなど、 その時々でやりたいことが変わったりもします。\n場合によっては、説明文などでも検索できると嬉しいこともあります。また、システムからは離れますが、図書館や書店で時々、「〇〇について書かれている本ありますか?」といった聞き方をしたりもします。\nまた、書店としては、探している本を見つけてもらうために検索端末などを用意しますが、そ れ以外の本も買ってもらえるといいですよね。 オンラインの書店などでは、検索結果や書籍詳細の画面に関連書籍が出ていることもあります。\n検索とは少し異なり、探索(なにか面白い本とかないかな?というようなニーズ)をしに、書店に行くこともあります。 書店で平積みされた本やポップなどを見て新しい本に興味を持つこともあります。\nオークションサイトやECサイトでの検索の場合 ユーザーのニーズは、「欲しい物を探す」ことです。 ユーザーが入力するクエリは、幅広いものになると思います。製品の型番を入力する人もいれば、 メーカー名や製品名だったり、ジャンルで絞り込んで検索することもあります。\n探されるもの(コンテンツ、アイテム)も多数に渡ります。 検索窓は1つかもしれませんが、検索結果には、絞り込み条件(ファセット)がいくつか並んで、絞り込んでいける仕組みが用意されていることが多いです。\n検索結果のソートは、価格順だったり人気順だったりします。 ただ、オークションサイトの場合は新しいもの順や、終了日時の早い物順だったりします。\nサイト提供者のニーズとしては、より多くのアイテムを購入してもらうこと(売上)です。 また、オークションサイトの場合は、アイテムを提供している人のニーズも影響してくるでしょう。 売りたい人はより多くの人の目に止まってほしいと思うはずなので、 様々な情報を付与していかに目にとまるか?といったことを考えてくると思います。\nまた、様々な商品を扱うECサイトの場合は、さらに色々と大変になってきます。たとえば、「iPhone」で検索されたときに、 iPhoneそのものが上位に来るべきなのか、ケースなどの周辺商品なのかだったりといった問題が出てきます。 商品の提供者が多数に渡る場合は、同一商品でもさまざまなお店から提供されてしまうために、検索結果一覧に多数同じ商品が並んだりもしますよね。\nレシピサイトでの検索の場合 ユーザーのニーズは「レシピを探す」です。が、探し方はユーザーによって様々です。 冷蔵庫にある材料を入力して検索することもあれば、食べたいものが決まっていてそのレシピを検索することもあります。 このとき、重要なのは類義語だったりするでしょう。食材やレシピは同じものでも様々な名前(例:パクチー、コリアンダー、シャンツァイ(香菜)など)を持っていたりします。また、部位や形によっても名前が変わったりもします。\n検索結果は人気順で並ぶことが多いでしょうか? ただ、レシピの提供がユーザーによるものなのか、サイト運営者が提供しているものかによっても変わってくるでしょう。\nサイト提供者のニーズとしては、レシピコミュニティサイトの場合は、ユーザー数の増加や広告の売上などがあるでしょう。 調味料などのメーカーがレシピサイトをやっている場合は、調味料の売上だったりします。この場合は、検索がどの程度売上に寄与しているのか?などを測ることが難しかったりしそうです。\n社内文書検索の場合 ユーザーのニーズは「文書を探す」です。探し方はファイル名であったり、ファイルのなかに出てくる単語だったりします。 社内用語・略語のような特殊な単語で検索されることもあるでしょう。ユーザーによっては、ぼんやりとした「こんな資料を探している」といったふんわりとした検索をしたくなることもあります。\n検索結果の表示順は「それっぽいもの」が上位に出てくることが望まれそうです。 ただ、古い文書が出てきても役に立たないこともあります。新しい文書のほうが役に立つことが多いので、最近作られたものというのも重要な情報になります。ただし、権限によっては見ることができなかったり、そもそも探すこともNGだったりもします。\n社内文書検索の提供者は、素早く検索できるものを提供することで仕事の効率を上げてもらったり、無駄を省くことができることを期待しているでしょう。\n昔からですが、社内の文書は様々な場所に散らばっていることが多いです。顧客管理システム、ファイルサーバー、Wiki、ウェブサイトなどこれらをまとめて検索できるシステムなどが望まれていることも多いです(使われるかはまた別ですが。。。)。\nスマートスピーカーの場合 ちょっと特殊な面白い例かなと思ってます。 音声で検索(というかお願い?)します。 システムとしては、ユーザーのニーズを理解するのに2段階あるのかなと。\n音声認識 認識した文章・キーワードで検索(場合によってはコマンド発行) これだけでも難易度が増します。\nさらに、画面のないスピーカーの場合は、結果は1件だけになります。これって結構難しいことだと思うんです。 画面があれば、検索結果を上位10件などのリストで表示して、あとはユーザーに選んでもらうことができますが、 音声の場合は1件だけしか返せません。 また、レスポンスタイムもシビアなものだと想定されます。ずっとスピーカーに黙っていられると困りますよね? きっと大変なんだろうなぁ(妄想)。\nこのように、検索と言っても、システムごとに要求・想定されるものは変わってきます。\nまとめ 例をいくつか上げましたが、ざっくりしすぎて発散してますかね。。。 想像している部分もあるので、この通りではないと思います。 ただ、システムによって、「検索」といってもシステムの特性上、 さまざまな物事、思惑が絡んでくるというのは想像してもらえたと思います?(思いたい)。\nシステムに検索機能を追加すると言っても、探したいものが何なのか?、探してもらうものはどういったものなのか?、 検索機能を追加することで何を達成したいのか?など考えることは色々あります。 どうやって、検索機能を実装するのか、その検索機能を実装するためにはどんな情報が必要なのか?などの検索機能のコアな部分を考えるだけでなく、提供しているシステム、コンテンツがどんなものかなど、システム全体を考えながら検索機能を考えていく事が検索をより良いものとして行くことだと思います。\nまた、検索されるものも検索する人もシステムが成長するのに合わせて変化していきいます。システム同様、一度作ればおしまいというものではないので、やることはいっぱいあるのかなと。\n次は、検索のパーツについてなにか書こうかなぁ。\nボヤキ もう少しまとめてから書いたほうがいいのかもなぁ。 もしくは、出てくる要素を整理するとか。 ユーザー、コンテンツ、コンテンツ提供者とかで。 ふんわりとしたブログになってしまった。 個別のシステムごとにもっと書けることもありそう。\n","date":1595842134,"dir":"post/2020/","id":"9da845cd31310b8952efd1be1881e651","lang":"ja","lastmod":1595842134,"permalink":"https://blog.johtani.info/blog/2020/07/27/improve-search-no1/","publishdate":"2020-07-27T18:28:54+09:00","summary":"今年の頭からシステムの検索周りを手伝う仕事をフリーランスとしてやっています。 検索の仕組みを知れば知るほど面白くなってきたからという理由になる","tags":["検索"],"title":"システムの特徴と検索機能について(検索システムに関する妄想その1)"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章 Rust the book - 第9章 Rust the book - 第10章 Rust the book - 第13章 14章は飛ばして、15章です(Cargoはまた別途調べればいいかな?と思って)。\n第15章 スマートポインタ たぶん、これを理解すれば、参照とベクタや構造体とかの組み合わせがもう少し効率よく使えるようになるのかなぁ?\nポインタの強い版? 参照カウント方式のスマートポインタ型 - Luceneとかで実装されてた気がするなぁ 複数の所有者!? DerefとDropトレイトを実装している構造体 ヒープのデータを指すBoxを使用する これはコンパイルエラー。let yのタイミングで借用してるので、書き換えでエラーになる。\nfn main() { let mut x = 5; let y = \u0026amp;x; assert_eq!(5, x); assert_eq!(5, *y); x = 6; assert_eq!(6, x); assert_eq!(6, *y); } こっちはOK。\nfn main() { let mut x = 5; // in stack let y = Box::new(x); // in heap assert_eq!(5, x); assert_eq!(5, *y); x = 6; assert_eq!(6, x); assert_eq!(6, *y); } 余談:コンパイラが変なワーニングを出してくれた。\nuse std::ops::Deref; impl\u0026lt;T, Z\u0026gt; Deref for MyBox\u0026lt;T, Z\u0026gt; { type Target = T; fn deref(\u0026amp;self) -\u0026gt; \u0026amp;T { \u0026amp;self.0 } } struct MyBox\u0026lt;T, Z\u0026gt;(T, Z); impl\u0026lt;T, Z\u0026gt; MyBox\u0026lt;T, Z\u0026gt; { fn new(x: T, y: Z) -\u0026gt; MyBox\u0026lt;T, Z\u0026gt; { MyBox(x, y) } } fn main() { let x = 5; let z = \u0026#34;10\u0026#34;; let y = MyBox::new(x, z); assert_eq!(5, x); assert_eq!(5, *y); } Derefトレイトでスマートポインタを普通の参照のように扱う 参照外し型強制 : 日本語ムズカシイネ Derefを自分で実装しないといけない場面がちょっと想像できてない。たぶん、Boxとかの説明に必要なので出てきたって感じなんだろうけど。 Dropトレイトで片付け時にコードを走らせる こっちは、リソース開放とかでいい感じにできそうだってのはわかった。 Dropはどんなときに実装するんだろう?Tantivyだとオブジェクトプールとかで使ってた。 Rcは、参照カウント方式のスマートポインタ これ、ここで作ったConsのリストを追っかけるためのサンプルも書いてほしい。 #[derive(Debug)] enum List { Cons(i32, Rc\u0026lt;List\u0026gt;), Nil, } fn print_typename\u0026lt;T\u0026gt;(_: T) { println!(\u0026#34;{}\u0026#34;, std::any::type_name::\u0026lt;T\u0026gt;()); } use List::{Cons, Nil}; use std::rc::Rc; use std::borrow::Borrow; fn main() { let z = Cons(5, Rc::new(Cons(10, Rc::new(Nil)))); let a = Rc::new(z); let _b = Cons(3, Rc::clone(\u0026amp;a)); let _c = Cons(4, Rc::clone(\u0026amp;a)); match \u0026amp;(*a) { Cons(v1, v2) =\u0026gt; { print_typename(v2); println!(\u0026#34;{}, {:?}\u0026#34;, v1, v2); }, Nil =\u0026gt; println!(\u0026#34;Nil!!\u0026#34;) }; } RefCellと内部可変性パターン 循環参照は、メモリをリークすることもある ","date":1594288778,"dir":"post/2020/","id":"208a8c072ea521c813b86ca7730eb880","lang":"ja","lastmod":1594288778,"permalink":"https://blog.johtani.info/blog/2020/07/09/hap15-rust-the-book/","publishdate":"2020-07-09T18:59:38+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第15章"},{"contents":"6月7日の週に開催されたBerlin Buzzwordsにオンライン出張してました。\nBerlin Buzzwordsとは? ベルリンで開催されている、Big Data、Scarability、Storage and Searchabilityに関するカンファレンスです。 今年はコロナウイルスの影響で、オンラインで開催されました。 また、同時期に検索に関する他のカンファレンス(以下の2つ)もベルリンで毎年開催されているのですが、今年はこれら3つのカンファレンスが1つのチケットで参加できる形で開催されました。\nMICES - MIX-CAMP E-COMMERCE SEARCH HAYSTACK - The Search Relevance Conference! sponsored by OpenSource Connections MICES、HAYSTACKは初参加ですが、検索に関するいくつかのトピックが聞けたので楽しかったです。\n6/7から6/12まで(がんばって)参加したので、その感想などをブログにとどめておきます。\nオンラインってどんな感じで開催されてた? まずは、オンライン開催がどのような感じだったのかをメモしておきます。\n有料のオンラインカンファレンス(事前にチケット購入が必要) 参加者用Slack カンファレンス数日前まではここで連絡とか質問が可能だった(もちろん、メールも来ましたけど)。 基本的なプラットフォームはBrellaのバーチャルイベントプラットフォーム 参加者同士のSNS機能 - 参加者同士の興味によって参加登録時に似たような人ですよとマッチングしたり。ビデオチャット機能もあり。 カンファレンスのスケジュール確認 - セッションのスケジュールの他に、参加者同士でのチャットのスケジュールも可能。一番便利だったのは自分のタイムゾーンも表示してくれること。 ストリームチャネル - セッションが行われている場所への誘導 スピーカー・スポンサーのリスト - スピーカーやスポンサーを探せる機能。スポンサー企業からは参加者も見ることができる セッションはYouTubeライブ ストリーム中だったらちょっと戻ったり、ポーズもできるので、便利だった セッション後の質疑応答にはJitsiというオープンソース!?のビデオカンファレンスの部屋が用意されてた(GitHubで公開されてるのか。https://github.com/jitsi)。 2日目、3日目はLTとかが終わったあとに、オンライン飲み会やってたっぽい(不参加) 主催者側も初めてだとは思うのですが、目立ったトラブルはなかったです。 ちょっとだけ遅れたりしてましたが、それほど影響はなかったです。 オンラインでの開催の一番のネックは、日本だと時差が辛いということです。 ベルリンが開催地なのですが、スピーカーや参加者はアメリカからの方が結構います。 そのため、開始時間が日本の23時といった具合になりました。\n面白かった\u0026amp;気になったセッション いくつか面白かった\u0026amp;もう一度見ないとなと思ったセッションと感想を。\nNatural Language queries at Salesforce scale セッションのページはこちら(2020年7月現在) Salesforceでどのような自然言語のようなクエリに対して書き換え、サジェストのようなことをやっているか?という話です。 Salesforceはテナント(企業)ごとに、データ構造などがカスタマイズ可能なため、 それぞれ個別に入力クエリ(例: new leads in sf)に対して、どういったパーツ(時間?場所?状態?)なのか?、どのフィールドへの条件なのか?といったものをNERのディープラーニングモデルとして捉えて解析しているという話でした。 企業毎にパーソナライズもされていると。実際にはパイプラインの一部でこの処理をやっており、それ以外にも処理はされているという話もありました。評価の話もされています。\nAMA - AI-Powered Search セッションのページはこちら(2020年7月現在) ManningでMEAP(絶賛書いているところ)のAI-Powered Searchの著者2名がAMA形式でいろんな質問に答えていく感じのやつです。 最初は近況報告(Treyさんがカンファレンス直前に転職してた)と、書籍がどんなものかを簡単に紹介したあと、質問に答えていく形式で2時間あります。ディープラーニングのモデルに関する話なども出てきています。 もう一度見たいと思ってたやつなので見ないとな。。。 (パネルっぽいセッションは、ヒントがなにもないので結構辛い)\nAsk Me Anything: Lucene 9 セッションのページはこちら(2020年7月現在) LuceneのPMCメンバーのUweさんが今後のLucene/Solrのいくつかの質問に答える感じのAMAです。 出てきた話(質問の前の)としては、Lucene 8の現状(Bloc-Max WANDとか)や、Java 11対応になるよとかです。 QAでは、SIMDの話、Approximate Nearest Neighborがどんな感じか?などの話でした。\nFrom commercial search to owned search セッションのページはこちら(2020年7月現在) カルフールスペインがECの検索をどのように導入したかという概要レベルの話でした。 モノリシックなものをマイクロサービスでk8s上に載せ替えたという大きなアーキテクチャ以降の話です。 Empathy.coが提供しているものを最終的には使用したみたいだけど、 どんな検索がされているのかといったニーズの調査ができるようになり、検索に絡んだKPIが改善した話でした。 COVID-19に絡んだクエリの変化についてもちょっと話が出てました。\nNeural Search in Practice セッションのページはこちら(2020年7月現在) Zalandoの検索の一部でNIR(Neural IRモデル)を利用してクエリの改善をやって、それをどうやってトレーニングして、テストしたかなどの話。 NIRを利用することで、複数の言語に対して改善が見られたという話だった。 今までは、クエリをいくつかの処理を元に翻訳して、入力された単語がカテゴリーに対するものなのか、スタイルに関するものなのか?などを判別して、クエリの補強?を行っている手法だった。 これに対して、ディープラーニングでクエリに対するクリックデータを元にトレーニングして、どういうクエリに対してどんなアイテムを出すのか?というモデルで検索を改善していた。 ヒット件数が0件だったり少ないものを対象にして上記の処理を入れているらしい。 (ということで、ディープラーニングをしっかり勉強しないといけないみたいなので、どうにかしたい。。。)\nTop 10 Lessons learned in search projects the past 10 years セッションのページはこちら(2020年7月現在) 10年検索プロジェクトをやってきた10個の気づきという感じのセッション。 ごく当たり前のことなんだけど、検索の導入・改善に関して、こういう事あって、何も考えないとこうなっちゃうよね。 だから、こんなことをやるべきだよね?という話です。 たとえば、検索窓はあるけど分析すらしていない状況(レッスン1)だとまずはこういうのやらないとね。とか、 検索クエリの分析・改善ばかりして、コンテンツの分析・改善を怠っていないか?という当たり前の話です。 当たり前なんだけどまとめてくれてるのは、やはりいいなぁと。\nClick logs and insights: Putting the search experts in your audience to work セッションのページはこちら(2020年7月現在) 検索ログとクリックログがあったときに、どういったことに使えるのかを料理のレシピに見立ててデモをするセッションで説明が面白かったです。 「こんなログがあったときに、ログのこの項目とこの項目を材料にすると、こんなのができますね」というのを、Elasticsearchにログを取り込んで、JupyterNotebookでデモをしていました。やはり動くものがあるとわかりやすいですねぇ。\nMixing and Matching: Diversifying Search Results セッションのページはこちら(2020年7月現在) これまたパネルセッションです。 検索結果の多様性に関するディスカッションでした。 これは、ECだからこその課題でもあるのかなと。検索自体は「何かを見つける」ための手段です。 普通に考えた場合は、ピンポイントで探していたものが見つかるのが嬉しいです。 が、例えば、ユーザーが検索した単語そのものが入っているだけのものが見つかるよりも、似たような商品も一緒に出てきてほしいことありますよね?また、ECサイトだと、回遊してほしいというのもあります。ということで、それぞれの方がどんな観点で多様性を考えているのかという話をするディスカッションになっていました。\nThought Vectors, Knowledge Graphs, and Curious Death(?) of Keyword Search セッションのページはこちら(2020年7月現在) AI-Powered Searchの著者の一人、Treyさんのセッション。ベクトルを検索にどうやって使うのか、 ベクトルで表現できるものはどんなものがあるのか?どんな検索エンジンで使えるのか?という話でした。 歴史的な話も交えつつ、検索だとこのへんで使えるんじゃないか?というような話でした。\n録画は? 気になったセッションをいくつか書き出してみました。 ちなみに、全セッションのビデオが公開されています。興味がある方は、ご覧いただければと。\nThe recordings from this year\u0026#39;s Berlin Buzzwords / MICES / Haystack joint event are now online. You can watch them all on our YouTube channel. Thank you once again to all of our wonderful speakers. https://t.co/hTRDmKNdpd\n\u0026mdash; @berlinbuzzwords@floss.social (@berlinbuzzwords) July 6, 2020 感想そして来年は? 楽しかったです。検索に関する話が色々聞けるのはやっぱ楽しいですね。サイトの特性(ECなのか、Wikipediaなのかなど)によっても「良い検索」の定義も変わるので、サービスなどがどんなものか、そしてそれを良くするためには検索はどんなことができるのか?といった話や、技術的な濃い話までいろいろな話を聞けました。 ただ、パネルは英語の聞き取りが辛いですね。。。あと、時差が。日本にいながらにして時差ボケは辛い。。。 オンライン飲み会には流石に参加できませんでした(4時とか5時から始まるし)。\n来年もオンラインで開催されたら間違いなく参加します。 オフラインのみだった場合はどうなるかなぁ。。。\n","date":1594005164,"dir":"post/2020/","id":"e5cb2e5d501d3db2db5d8f14984a66d4","lang":"ja","lastmod":1594005164,"permalink":"https://blog.johtani.info/blog/2020/07/06/attend-berlin-buzzwords/","publishdate":"2020-07-06T12:12:44+09:00","summary":"6月7日の週に開催されたBerlin Buzzwordsにオンライン出張してました。 Berlin Buzzwordsとは? ベルリンで開催されている、Big","tags":["conference","berlin buzzwords"],"title":"Berlin Buzzwordsにオンライン出張してた"},{"contents":"luceneutil - マニアックなツールのセットアップの続きです。 今回も誰得?なブログなので興味ない場合は飛ばしましょう。\n一応、luceneutilのREADMEにあるlocalrun.pyを動かせるところまでいったんですが、そこで一旦本題を思い返してみました。\nKuromojiの性能が落ちてるらしいし、Analyzer系のベンチマーク測ってるグラフに載せたほうがいいよね。\nこれが、そもそも動かしてみようと思った本題です。 READMEに書いてある手順で動いたんですが、よくよく調べてみると、Analyzer系の性能テストをやってるのは、別物っぽいぞと。 なんとなく、「ソフトウェア考古学」っぽくなってきましたね。\nAnalyzerの性能テストやってるのは? Analyzerのパフォーマンステストのグラフに出てきたTokenizerの名前を元にluceneutilのリポジトリを検索してみました。 EgdeNGrams当たりで検索するとヒットしたのが以下のファイルです。\nsrc/main/perf/TestAnalyzerPerf.java src/main/perf/TestAnalyzerPerf4x.java src/python/sumAnalyzerPerf.py 本命はsrc/main/perf/TestAnalyzerPerf.javaっぽいですね。 これを動かしている人はどれかな?ということで、今度はこのファイル名で検索します。\nsrc/python/runAnalyzerPerf.py どうやら、このPythonのファイルが先程のJavaファイルを実行して、性能を計測しているみたいです。 最初に出てきた、sumAnalyzerPerf.pyはrunAnalyzerPerf.pyの実行結果をAnalyzerの計測結果のグラフに追加する処理をしているようだということまでがわかりました。\nKuromojiをTestAnalyzerPerfに追加してみる 動かす対象がわかったので、あとは、やることを追加しましょうと。\nKuromojiの実行をTestAnalyzerPerfに追加 引数を追加して日本語版のWikipediaのファイルも読み込むようにする runAnalyzerPerf.pyに引数の追加とクラスパスの追加 JapaneseAnalyzerはlucene/analysis/kuromojiにビルドされるのでクラスパスを追加 引数に日本語版のWikipediaのファイルを追加 日本語版のWikipediaのデータの用意 こんなものかな?と。\n1と2はそれほど大変ではないので、3をまずはというところから始めてみました。\nWikipediaのXMLから1行1データのTSVファイルに まずは、どんなファイルを想定して動いているのかな?ということで、英語版のファイルがどんなものかを探してみることに。\nTestAnalyzerPerf.javaでは入力ファイルから1行ずつ文字列を読み込んでAnalyzerに処理させているだけというのがわかっています。なので、とりあえず、1行ずつ読めるような形式だと。 次に、runAnalyzerPerf.pyの55行目でenwiki-20130102-lines.txtというものを読み込んでいます。 が、これがよくわからないw\n前回とりあえず動いたときに、src/python/constants.pyにいろんなファイルへのパスとかが記載されていたのを覚えていたので、その当たりから調べてみます。 52行目に約665万件のドキュメントだというような記載があります。 前回のlocalrun.pyのファイルと似たような構造(1行に1記事が埋め込まれたTSVファイル)だろうと判断して、それを作りそうなプログラムを探してみました。 Wikiとかで検索して見つけたのがこのソースたちでした。\nsrc/python/wikiXMLToText.py - それっぽい名前ですよね? 中身を見ると、第1引数のファイル(XML)からpageタグごとにデータを抜き出し、処理をしてからタブ区切りで第2引数のファイルに書き出してます。 src/python/WikipediaExtractor.py - これもそれっぽいですね。 WikipediaExtractory.pyは界隈では有名なhttps://github.com/attardi/wikiextractorみたいです。こっちはなんとなく使い方はわかっています。 src/python/combineWikiFiles.py - これまたそれっぽい。 中身を見ると、1番目のコードで出力したデータに、2番めのコードで出力されたデータを元になにかしら処理をして、引数で与えられたファイルに出力する感じになってます。 ということで、完全に憶測ですが、日本語のWikipediaのXMLファイルを元に次のような流れでファイル作ってみればいいのかな?と。\njawiki-20200620-pages-articles.xml.bz2をwikimediaからダウンロードして、unbzip2で展開 python src/python/wikiXMLToText.py jawiki-20200620-pages-articles.xml jawiki-lines.txtで、1行ごとのデータを作る ちなみに、このプログラムは2箇所ほど修正しました。usernameタグが存在しないpageが出力されなさそうなので、デフォルトでusername: \u0026quot;\u0026quot;みたいなデータをattrってディクショナリに設定しました。 cat jawiki-20200620-pages-articles.xml | python -u src/python/WikipediaExtractor.py -b102400m -o extractedで別途XMLからデータを抽出 python src/python/combineWikiFiles.py jawiki-lines.txt extracted/AA/wiki_00 jawiki-20200620-lines.txtで2と3の出力をかけ合わせる で、まぁ、一応ファイルはできたんですが。。。 前回のブログ記事でセットアップしたときにダウンロードされたファイルはtitle、日付、本文の3つのカラムしかないんですが、上記の手順で作り出したファイルにはいろんなカラムが存在するんですよね(2が出力する項目が結構ある)。。。\n性能テスト用プログラムの書き換え 入力ファイルは出来上がったので、あとは、性能テストを走らせる部分の修正です。 修正部分はプルリク見たほうが明確なので省略で。\n実行してみた で、実行してみました。 せっかくなので、ブランチをbranch_8_5とmasterを対象にしてやってみました。 実際にはsrc/python/runAnalyzerPerf.pyにディレクトリ名やブランチ名が直書きされてたので書き換えつつ実施した結果はこちら。\n他の英語系のAnalyzerと同じグラフに載せてみたのですが、遅いので、下の方に表示されてます。 で、下に凹んだ部分(23 Juneのところ)がbranch_8_5で実行したときの性能値でした。 実際に遅くなってますね。ただ、他のAnalyzerの振れ幅も大きいので、別のグラフにしたほうがわかりやすくなるのかもなぁと思った次第です。\nということで、一応動いたんでプルリク出してみました。 採用されるかなぁ?\n一応誰得ブログはこれでおしまい。 Noriとかもこの感じで対応できるんじゃないかな?\n","date":1593050518,"dir":"post/2020/","id":"bbd2824ff0d5b801bb6f5da3a2a1a888","lang":"ja","lastmod":1593050518,"permalink":"https://blog.johtani.info/blog/2020/06/25/analyzer-perf-test-with-luceneutil/","publishdate":"2020-06-25T11:01:58+09:00","summary":"luceneutil - マニアックなツールのセットアップの続きです。 今回も誰得?なブログなので興味ない場合は飛ばしましょう。 一応、luceneutilのREAD","tags":["lucene"],"title":"luceneutil - Analyzer性能テストへのkuromojiの追加"},{"contents":"LuceneのFSTの修正に関連して、Kuromojiのパフォーマンス問題が出ているようです。 この問題自体はLucene 8.6.0以降で直る予定のようなのです(Elasticsearchへの影響範囲についてはこれが参考になるかな?)。 で、これに関連して、ベンチマーク計らないとねという話が出ていて、 昔から、LuceneのMikeさんがやっているベンチマークのグラフに載せるのがいいよねという話になっていました。 どうも、これについては、Luceneの中にあるbenchmarkというプロジェクトではなく、MikeさんのGitHubリポジトリにあるプログラムで計測しているようです。\nじゃあ、手元でこれどうやって動かすんだろう?ということでやってみたブログになります。 おそらく、99.99%の人は興味ないと思うのでスルーしていただくのがいいと思います。備忘録のために書いてます。\nとりあえずgit clone 公開されているリポジトリはこちらです。\n手順通りに? とりあえず、READMEにセットアップなどのやり方があったんで追っていくことに。 とりあえず動くまでの手順は以下のとおりです。\nディレクトリを決める $LUCENE_BENCH_HOMEが起点になります。名前は何でもいいみたいです。 cd $LUCENE_BENCH_HOME リポジトリをクローン - git clone https://github.com/mikemccand/luceneutil.git utilです。 コレ自体は問題なし。 cd util セットアップスクリプトを実行 - python src/python/setup.py -download ここがすごく時間かかります。6GBのファイルをゆっくりダウンロードしてきますので、一晩置いておきましょう(起きたら終わってた) $LUCENE_BENCH_HOME/dataにenwiki-20120502-lines-1k.txt.lzmaとwikimedium500.tasksいうファイルがダウンロードされている。 ダウンロードした圧縮ファイルを展開 - unlzma enwiki-20120502-lines-1k.txt.lzma macOSにlzmaのコマンド入ってるんですね。知らなかった。 終わったらcd ../で$LUCENE_BENCH_HOMEに戻っておく ベンチマーク対象となるLuceneを用意 - git clone https://github.com/apache/lucene-solr.git READMEにはlucene_candidateとlucene_baselineって名前でって書いてあったのですが、これだと、この後の実行フェーズでエラーになりました。 trunkとpatchというディレクトリにそれぞれ変更しました。localrun.pyを実行したらこのディレクトリ名だったので(相変わらず、自分、行きあたりばったりな対応してるなぁ。。。) とりあえず動くかどうかを確認したかったので、trunkとpatchはどちらもリポジトリをcloneしたものになってます。動いたのを確認したら、タグを指定して比較したいブランチをチェックアウトする予定。 trunkとpatchをビルド - ant jar * localrun.pyを実行 - cd utilそして。。。 5.で記述したディレクトリ以外に1箇所Pythonのコードを書き換えた。 src/python/benchUtil.py内部にhppc-0.8.1.jarのファイルの存在チェックをしているのだが、2020/06/23時点でのLuceneのリポジトリの依存関係だとhppc-0.8.2.jarになっており、ファイルが見つからないエラーが出たため、0.8.2に書き換えた。970行目付近。 改めて実行したら成功した。 まだ途中 とりあえず、実行するところまではできましたが、結果の見方とかちゃんと調べないとなぁ。 いくつかローカルで対応したものについてはあとでGitHubにIssue立てとくべきだな。\nと、動くのを確認したので、日本語周りの準備をしてみてるところです。\n終わったこと\n日本語のWikipediaのデータjawiki-20200620-pages-articles.xml.bz2をダウンロードして展開 試している途中\nWikipediaExtractorでXMLからデータを抽出 - cat ~/tmp/wiki/jawiki-20200620-pages-articles.xml | python -u src/python/WikipediaExtractor.py -b102400m -o extracted これは手順が違うかも???? python src/python/wikiXMLToText.py ~/tmp/wiki/20200620-pages-articles.xml ./hoge.txt これで、title、日付、本文が抜き出せそう? この後にcombineWikiFiles.pyの実行かな? って感じです。 誰得だろうこれ???\n","date":1592917109,"dir":"post/2020/","id":"8a1ea5d5cf843bc5955a94cfcc321e92","lang":"ja","lastmod":1592917109,"permalink":"https://blog.johtani.info/blog/2020/06/23/how-to-use-luceneutil/","publishdate":"2020-06-23T21:58:29+09:00","summary":"LuceneのFSTの修正に関連して、Kuromojiのパフォーマンス問題が出ているようです。 この問題自体はLucene 8.6.0以降で直る","tags":["lucene"],"title":"luceneutil - マニアックなツールのセットアップ"},{"contents":"Azure Cognitive Searchで日本語を扱うときに、形態素解析器を使いたい場合、2種類のAnalyzerが用意されています。今回はこれらの違いがどんなものかを見ていくことにします。\nAnalyzerとは? まずは、その前にAnalyzerとは何者か?というのを少しだけ。 Azure Cognitive Searchは転置インデックスを内部で作成して、検索を行っています。 この、転置インデックスは、「単語」がどのドキュメントに入っているか?を素早く見つけることができるデータ構造となっています。\nAzure Cognitive Searchは、この「単語」を入力された文章から生成するときに、Analyzerというものを利用します。 Analyzerは入力された文章をある規則に則って単語に分割する機能です。 この「ある規則」が、各種言語や用途によって様々に用意されています。 今回はこの中のja.luceneとja.microsoftという2種類のAnalyzerについて違いを見ていきます。\n2種類のAnalyzerの違いはどんなもの? このAnalyzerの挙動を見るためのエンドポイントとしてanalyzeというAPIがあります(詳細は昔のブログを参照)。\nこのAPIを利用して、Wikipediaのいくつかの文章を単語に区切って見て、 ja.microsoftがどんな動きをしているのか想像してみます(残念ながらja.microsoftの仕様?や挙動についてはページが見つからないため)。\nもとの文章と解析結果(一部抜粋) 文章は、手元のElasticsearchに登録したjawikiのデータからランダムに抽出しています。また、自前のツールで生成したWikipediaのデータなので、まだ一部、見苦しい文字列になっています(そっちもなおさないと)。\n1. 砂川(熊本県) thumb|250px|right|上砂川橋より上流方砂川(すながわ)は、熊本県宇城市・八代郡氷川町を流れる二級河川。\nこの文字列から抽出された単語で特徴的なものを一部抜粋しました。\nja.microsoft ja.lucene 250px 250 px 上砂 上, 上砂川 川橋 砂川 橋 宇城 宇 市 城市 二級 二 ^ 級 まず、最初の250pxですが、ja.microsoftでは、pxが単位であると判定しているのか、数値と合わせた単語として抽出されています。この場合、250で検索しても、この文字列はヒットしない形になるので、ノイズが減ることが考えられるかと。\n上砂川橋という文字は、分割の仕方が別れました。 ja.luceneでは、上砂川という単語が地名として辞書に存在するために、このような分割になっています。ja.microsoftのデータは品詞の情報が取れないのですが、上砂、川橋ともに、名詞として辞書に存在しているのではないかなと。ja.luceneには川橋という単語は存在していないようでした。\n宇城市(うきし)については、2005年に合併でできた市のようで、ja.luceneが利用している辞書には存在しない可能性があり、宇城という文字が抽出できてないと思われます。\n最後は二級です。ja.luceneでは、数字と助数詞として分割されています。こちらも何かしらのロジックにより、二級という1単語でヒットできるように数字と単位?が合わせた単語で出てくる仕組みがja.microsoftなのかなと。\n2. UEFA U-18女子選手権2000 UEFA U-18女子選手権2000は第3回目のUEFA U-18女子選手権である。決勝トーナメントは2000年7月27日から8月4日までフランスで行われ、ドイツが初優勝を果たした。\nこの文字列から抽出された単語で特徴的なものを一部抜粋しました。\nja.microsoft ja.lucene u-18, u u 18, nn18 18 第3回目 第 3 回 目 トーナメント, トナメント トーナメント 2000年 2000 年 7月 7 月 27日 27 日 数字を含む単語第3回目や2000年、7月などは、ja.microsoftは先程と同様、数字と単位の組み合わせを1単語として出力しています。\nまた、トーナメントという単語をトナメントという形で、長音を除去した形で出力しています。 今回の文字列ではないですが、この他に、センターをセンターとセンタの2パターンの単語で出力するといったことを行っています。 ja.luceneの場合、単語の最後に長音がある場合だけセンタとして、長音を除去した単語が出力されます。 これは、長音の表記ゆれに対応するためではないかなと。たとえば、インターフェースとインタフェース、インターフェイスのように、人や文章によって、間にでてくる長音を使ったり使わなかったりという表記ゆれに対応するためだと思われます。 その他にも、イプロゥヴェトをイプロゥベトに、ネクストをネキストに、バラエティをバラエチにも変換するなどといった処理をしてくれるようです。カタカナの表記ゆれには強そうですね(これどうやってるんだろう?)。\nja.microsoftでは、nn18というちょっと変わった単語も出てきていました。純粋な数字の場合はnnと入力してくれるようで、数字だけで検索したい場合に利用できるのかな?これはドキュメントに書いておいてほしいかも?\n共通点 ja.lucene、ja.microsoftともに、共通している動作として、「てにをは」といった単語は除去されていました。違いがあるものとしては、「より」(助詞-格助詞-一般)、「されている」(動詞-自立、動詞-接尾、助詞-接続助詞、動詞-非自立)、「ある」(助動詞)といったものはja.microsoftでは除去されずに出てきていました。 ストップワード的に「てにをは」あたりを除去をしている感じでしょうか?\nアルファベットで構成されている単語についても、基本はそのまま出力される挙動のようでした。\nじゃあどっちがいいの? 残念ながらどちらがいいかは、一長一短かなぁと。 ja.luceneに関しては、Luceneの仕組みを利用しているので、Elasticsearchなどを使えば、個別の単語についてより詳細の情報を取得することが可能です(品詞、読みなど)。ja.microsoftについては、残念ながら手の入れようがないので、そういう動きのものだという割り切った使い方になるでしょうか? ただ、長音の除去による表記ゆれなどについては、便利な機能なので、そのあたりの問題に対応したい場合は、ja.microsoftを活用するのも良いかと思います。\n個人的には、より細かい単語としてインデックスに登録できるもののほうが、柔軟な検索には対応できるのではないかなぁと考えています(Kuromojiの辞書をUniDicにするとか?も考えますが、これはAzure Searchではできないですが)。\nまとめ Wikipediaのデータをいくつか使って、ja.microsoftとja.luceneの違いについて、考察してみました。何かの役に立てばと。 他に、これはどんな感じになるの?などありましたら、コメントいただければと。\n","date":1591692240,"dir":"post/2020/","id":"82a115ab8d617e4e96813587fe3a6049","lang":"ja","lastmod":1591692240,"permalink":"https://blog.johtani.info/blog/2020/06/09/difference-analyzers-in-azure-search/","publishdate":"2020-06-09T17:44:00+09:00","summary":"Azure Cognitive Searchで日本語を扱うときに、形態素解析器を使いたい場合、2種類のAnalyzerが用意されています。今回はこれらの違いがどんなもの","tags":["azure search","kuromoji"],"title":"Azure Cognitive Searchでの日本語向けAnalyzerの違い"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章 Rust the book - 第9章 Rust the book - 第10章 11章、12章はちょっと飛ばして、13章です。\n第13章 イテレータ、クロージャです。 12章の話もちょっと出てくるのか。\nクロージャ 基本的に、「変数には値が束縛されている」という固定観念がずっと頭にこびりついたままなので、クロージャに慣れないんだろうなぁ。そろそろこの固定概念をどうにかしないと。\n匿名関数で、変数に保存したり引数に渡せる ちょっと面白い話(ワークアウト)で実際に考えられる手法の説明がいくつか行われる 関数でリファクタリング これが自分がよくやるパターンかなぁ。クロージャになれてないので。。。 クロージャーを変数に束縛 呼び出しは関数みたいな感じ(ここで少し混乱) これだと、結局呼び出されたタイミングが複数回あるよね? -\u0026gt; あはりそうだった ここで、閑話休題で、クロージャの型推論とか注釈の話。 クロージャは狭い文脈だし、外に公開しているものでもないので、戻り値なども定義してなくてもいいよねとのこと。書くことも可能?なので、書いてわかりやすくするのもありなんだろうな。\n推論についてはこれまで通りで、2回異なる型の変数で呼び出すと、2回目で怒られていた。\n遅延評価(クロージャを保持する構造体!?) Fnトレイト トレイトとMatchの組み合わせだからこのへんで説明する形になるのか。 これを真似すれば、いくつか処理を簡素化できるかもしれないなぁ、たしかに。 なければ実行するみたいな処理を書きたいことがよくあるし。Javaだとnullで定義しといて、nullだったらみたいなのがあるから。 Cacherはサンプルだからこの名前でいいけど、自分だと、どんな名前にするかなぁ?\n振る舞いは難しくなるのか。Cacher実装の限界を読むと。\n関数にするとスコープが変わるのでアクセスできなくなると。。。コンパイラが教えてくれるのは便利だな。\n環境から値をキャプチャする3つの方法\n多分この話が一番クロージャに意味がある話なんだと思う。 イテレータ 回しましょう。\n便利。ただ、こういう書き方に自分が慣れてないので、そっちを補正しないとなぁ。 どれがイテレータ?っていうのを判別するのがちょっとむずかしい(慣れの問題かなぁ) イテレータアダプタ便利。どんなのがあるのか?とかがやっとわかってきた。 パフォーマンスに関しては、うーん、どうなんだろう?という感想だった。 ","date":1591259849,"dir":"post/2020/","id":"e74d071363645a588f858b35231128c4","lang":"ja","lastmod":1591259849,"permalink":"https://blog.johtani.info/blog/2020/06/04/chap13-rust-the-book/","publishdate":"2020-06-04T17:37:29+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第13章"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章 Rust the book - 第9章 第10章 ジェネリック、トレイト、ライフタイムです。 手強そう。\nいきなり関数の切り出し方みたいな話が始まって面食らいました。\nジェネリックなデータ型 ジェネリックはJavaにもあるので、それほど理解に苦しむことはなかったです。 また、OptionやResultですでに経験済みでしたし。\nただ、impl\u0026lt;T\u0026gt; Point\u0026lt;T\u0026gt;{、このメソッド定義は少し最初は戸惑いました。 言われてみれば、なるほどなんですけど。\nコンパイル時にコンパイラが単相化を行うことにより、必要最低限なコードを生成してくるというのは理にかなっているなぁと。\nトレイト: 共通の振る舞いを定義する 出だしにもありますが、「インターフェイス」という機能に類似していると考えると割とすんなりと理解が進みました。 ただ、Javaだと、インターフェースはクラスとセットなため、トレイとの実装に関する記述方法は少し戸惑いが。\nデフォルト実装との組み合わせはAbstractに似た処理になるなと考えながら読みすすめました。\n「トレイト境界」という日本語には少し違和感を覚えましたが、線引をして、制限をかけるという理解でいいのかな?\n実際には#[derive()]などで、トレイトを自分で実装する必要がないなどの、便利機能も用意されており、このあたりのコードの追い方がまだ少し慣れていないかもなぁと。便利なんですけど。。。\n少しだけ気になったので、動作確認したのは次の実装です。\nトレイトで宣言されている関数と構造体が独自に実装する関数の名前がかぶるとどうなるのかという実験です。 構造体独自のメソッドが優先される感じになりそう。\npub struct Tweet { pub username: String, pub content: String, pub reply: bool, pub retweet: bool, } pub trait Summary { fn summarize_author(\u0026amp;self) -\u0026gt; String; fn summarize(\u0026amp;self) -\u0026gt; String { // {}さんからもっと読む format!(\u0026#34;(Read more from {}...)\u0026#34;, self.summarize_author()) } } impl Tweet { fn summarize_author(\u0026amp;self) -\u0026gt; String { format!(\u0026#34;hoge {}\u0026#34;, self.username) } fn to_string(\u0026amp;self) -\u0026gt; String { format!(\u0026#34;fuga\u0026#34;) } } impl Summary for Tweet { fn summarize_author(\u0026amp;self) -\u0026gt; String { format!(\u0026#34;@{}\u0026#34;, self.username) } } pub fn summary\u0026lt;T: Summary\u0026gt;(hoge: \u0026amp;T) { println!(\u0026#34;{}\u0026#34;, hoge.summarize_author()); } pub fn main() { let tweet = Tweet { username: String::from(\u0026#34;horse_ebooks\u0026#34;), content: String::from(\u0026#34;of course, as you probably already know, people\u0026#34;), reply: false, retweet: false, }; println!(\u0026#34;{}\u0026#34;, tweet.summarize_author()); summary(\u0026amp;tweet); println!(\u0026#34;{}\u0026#34;, Summary::summarize_author(\u0026amp;tweet)); } ライフタイムで参照を有効化する 言われてみればそうですが、プログラマが色々考えないとまぁ、行けないんですねという感想。\nただ、借用チェッカーが賢くやってくれるおかげで、全てにライフタイム注釈をつけなくて良くなっているというのがわかりました。 逆に言うと、なんとなくRustを書き始めてしまったので、それを知らずに書いたせいで、コンパイラに怒られてても「?」となっていたのかと。。。\n疑問点がいくつかあって、\n通常はどんなライフタイム注釈をみんな書いてるんだろう?'aとかざっくりしすぎてる? 1つのメソッド、関数にライフタイム注釈が大量に出てくるような書き方をした場合は設計がおかしいのでは?って考えたほうがいいのかも? ジェネリックな型とライフタイム引数の順序を入れ替えてみても動くだろ?とおもって入れ替えてみたら怒られた。 あとは、構造体+ジェネリックが絡んできたら少しこんがらがってきそうっという感じです。 まぁ、これから先は実際に書いてみないことにはわからないんだろうなと。\nまとめ 読みました。 実際にはプログラムを書きながら慣れていく感じだろうなぁと。 まだまだ、あれ?ジェネリックってどう書くんだっけ?とか、ライフタイム注釈どうやって付けて、使うときはどうすんだ?みたいになりながら、 出てくるサンプルを少し変えてみてはどうやって動くんだろうこの場合?みたいなことをやってました。 次は、11章、12章を少しだけ自習しつつ、13章に入る予定です(知り合いと一緒に読みすすめてる)。\n","date":1590656815,"dir":"post/2020/","id":"163beeae9620c1a6a46a38aa7ebd9663","lang":"ja","lastmod":1590656815,"permalink":"https://blog.johtani.info/blog/2020/05/28/chap10-rust-the-book/","publishdate":"2020-05-28T18:06:55+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第10章"},{"contents":"今回はAzure Cognitive SearchのSDKを利用したアプリケーションが、実際にAzure Cognitive Searchに対して送信しているリクエストのパラメータとボディをログに保存する方法について紹介します。\n動機 アプリケーションでリクエストを組み立てて、SDK経由で送信していると、最終的にAzure Cognitive Searchに対して送信されているリクエストのパラメータや検索条件などをひと目で見たいことがあります。 アプリケーションでは、ソート条件や、クエリ文字列の組み立てなどの処理は異なる場所で行われたりしますので。\nまた、公式リファレンスでは、機能の説明はRest APIの使い方と組み合わせで説明されることが多いです。\nということで、SDKを利用しているアプリからAzure Searchへ送信されているリクエストをログに保存する方法を調べてみました。\n方法 調べてみるといくつかの手段を取ることができそうだとわかりました。実際に調べて実装する方法を4種類ほど試してみたのでブログに残しておきます。なお、2020年4月時点でのSDKとAzureの仕組みに基づいたブログになります。最新版ではお手軽な方法があるかもしれません。\nDelegatingHandlerを利用する ServiceClientTracingの機能を利用する Azure Application Insightsを活用する Azure Cognitive Searchのコンソールにある診断情報の機能を利用する 1、2はAzure Cognitive SearchのSDKのリファレンスから当たりを付けて見つけた方法です。 3はApplication Insights、4はAzure Cognitive Searchの機能になります。 これらの方法について個別に説明していきます。\n1. DelegatingHandleを利用する まずは、SDKでロギングの機能がないかを調べて見つけた機能がこちらです。 SDKのSearchServiceClientのコンストラクタの引数にDelegatingHandlerというものが渡せることを発見しました。\nこれは、.NET FrameworkのHttpのAPIに存在するクラスで、HTTPのクライアントがHTTPの送受信時に、処理を挟むことができる機能です。フレームワーク側で、LoggingHttpMessaggeHandlerというクラスを用意してくれていましたが、残念ながらこちらは、リクエストとレスポンスのヘッダのみをロギングするクラスでした。 ということで、リクエストボディをログに出力したい場合は独自に拡張してやる必要があります。なお、ロギングにはMicrosoft.Extensions.LoggingのILoggerを使用します。\nまた、Azure Cognitive SearchのSDK側に違う問題点もありました。チュートリアルにあるように、検索するときには、SDKは次のような使い方を想定しています。\n// Create a service and index client. _serviceClient = new SearchServiceClient(searchServiceName, new SearchCredentials(queryApiKey)); _indexClient = _serviceClient.Indexes.GetClient(\u0026#34;hotels\u0026#34;); インデックス用のクライアントを取得するために、GetClient(インデックス名)というメソッドを使用します。このGetClientメソッドのバリエーションとして、DelegatingHandlerを受け取るメソッドがないのです。。。\nということで、DelegationHandlerを活用する方法としては、以下の2つを実装する必要があります。\nCustomなLoggingHttpMessageHandlerクラスを実装 GetClientと同等の処理をDelegatingHandlerを引数にしたものを実装する 以上の2つを実装し、アプリケーション側から2で作成したGetClientを呼び出すことで、リクエストをボディも含めてログ出力することが可能になります。以下は実装例です。\nCustomHttpMessageHandlerクラス。\nusing System; using System.Collections.Generic; using System.Diagnostics; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; namespace AzureSearchSample { public class CustomLoggingHttpMessageHandler : DelegatingHandler { private readonly ILogger _logger; private readonly bool _logContent = false; public CustomLoggingHttpMessageHandler(ILogger logger, bool logContent) { if (logger == null) { throw new ArgumentNullException(nameof(logger)); } this._logger = logger; this._logContent = logContent; } protected override async Task\u0026lt;HttpResponseMessage\u0026gt; SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { if (request == null) { throw new ArgumentNullException(nameof(request)); } await Log.RequestStart(this._logger, request, this._logContent); var stopwatch = new Stopwatch(); HttpResponseMessage response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false); stopwatch.Stop(); await Log.RequestEnd(this._logger, response, stopwatch.Elapsed); return response; } private static class Log { private static class EventIds { public static readonly EventId RequestStart = new EventId(100, \u0026#34;RequestStart\u0026#34;); public static readonly EventId RequestEnd = new EventId(101, \u0026#34;RequestEnd\u0026#34;); } public static async Task RequestStart(ILogger logger, HttpRequestMessage request, bool logContent) { StringBuilder message = new StringBuilder(); message.AppendLine($\u0026#34;Sending HTTP request {request.Method} {request.RequestUri}\u0026#34;); if (logger.IsEnabled(LogLevel.Trace)) { LogHttpHeaders(message, request.Headers); await LogHttpContent(message, request.Content, logContent); logger.Log( LogLevel.Trace, EventIds.RequestStart, message, null, (state, ex) =\u0026gt; state.ToString()); } } public static async Task RequestEnd(ILogger logger, HttpResponseMessage response, TimeSpan duration) { StringBuilder message = new StringBuilder(); message.AppendLine( $\u0026#34;Recieving HTTP response after {duration.TotalMilliseconds}ms - {response.StatusCode}\u0026#34;); if (logger.IsEnabled(LogLevel.Trace)) { LogHttpHeaders(message, response.Headers); await LogHttpContent(message, response.Content, false); logger.Log( LogLevel.Trace, EventIds.RequestEnd, message, null, (state, ex) =\u0026gt; state.ToString() ); } } private static void LogHttpHeaders(StringBuilder message, HttpHeaders headers) { if (headers == null) throw new ArgumentNullException(nameof(headers)); foreach (KeyValuePair\u0026lt;string, IEnumerable\u0026lt;string\u0026gt;\u0026gt; header in headers) { foreach (string value in header.Value) { message.AppendLine($\u0026#34;{header.Key}: {value}\u0026#34;); } } } private static async Task LogHttpContent(StringBuilder message, HttpContent content, bool logContent) { if (content != null) { foreach (KeyValuePair\u0026lt;string,IEnumerable\u0026lt;string\u0026gt;\u0026gt; header in content.Headers) { foreach (string value in header.Value) { message.AppendLine($\u0026#34;{header.Key}: {value}\u0026#34;); } } if (logContent) { string contentBody = await content.ReadAsStringAsync(); message.AppendLine(contentBody); } } } } } } GetClientの実装\nprivate ISearchIndexClient GetClient(string indexName, params DelegatingHandler[] handlers) { var rootHandler = _searchServiceClient.HttpMessageHandlers.OfType\u0026lt;HttpClientHandler\u0026gt;().SingleOrDefault(); var indexClient = new SearchIndexClient(_searchServiceClient.SearchServiceName, indexName, _searchServiceClient.SearchCredentials, rootHandler, handlers) { SearchDnsSuffix = _searchServiceClient.SearchDnsSuffix }; indexClient.HttpClient.Timeout = _searchServiceClient.HttpClient.Timeout; return indexClient; } 出力されるログ例\n2020/04/14 19:17:53.591|TRACE|Sending HTTP request POST https://サービス名.search.windows.net/indexes(\u0026#39;インデックス名\u0026#39;)/docs/search.post.search?api-version=2019-05-06 client-request-id: be02140f-3a07-48cc-b018-d8aa5e819bc3 Accept-Language: en-US Accept: application/json; odata.metadata=none api-key: APIキー User-Agent: FxVersion/4.700.20.11803 User-Agent: OSName/MacOs User-Agent: OSVersion/Darwin.19.4.0.Darwin.Kernel.Version.19.4.0.Wed.Mar.4.22.28.40.PST.2020.root.xnu.6153.101.6.15RELEASE.X86.64 User-Agent: Microsoft.Azure.Search.SearchIndexClient/10.100.19.52907 Content-Type: application/json; charset=utf-8 { \u0026#34;count\u0026#34;: false, \u0026#34;facets\u0026#34;: [], \u0026#34;queryType\u0026#34;: \u0026#34;simple\u0026#34;, \u0026#34;scoringParameters\u0026#34;: [], \u0026#34;search\u0026#34;: \u0026#34;azure\u0026#34;, \u0026#34;searchMode\u0026#34;: \u0026#34;any\u0026#34; } |AzureSearchSample.SearchService|EventId_Id=100, EventId_Name=RequestStart, EventId=RequestStart メリット、デメリット Azure Cognitive Searchの検索の処理だけを対象にリクエストのログを出力することが可能です。また、影響範囲はアプリケーションだけに閉じていますので、デバッグ目的などでログ出力したい場合に、自分だけの手元でログの確認が可能になります。\nデメリットとしては、独自に実装しなければいけない範囲が広いことです。\n2. ServiceClientTracingの機能を利用する Microsoft.Rest.ClientRuntimeというライブラリをAzure Cognitive Searchは利用しています。 このライブラリにServiceClientTracingというクラスが存在します。 なにやら、クライアントの処理のトレースができそうです。\nAzure Cognitive SearchのSDKの実装がGitHubに公開されており、検索リクエストの処理を投げる直前に、このトレースの仕組がONになっていると、ServiceClientTracing.SendRequestメソッドを呼び出していました。\n実際にSendRequestメソッドに送られたものに対して何かしらの処理を行うのは、IServiceClientTracingIntercepterインターフェースを実装したクラスになります。 このインターフェースの実装がLog4Netに存在します。Log4Netを利用している場合は、これを活用すれば楽ができます。\n実際にServiceClientTracingを有効にするには、以下の2行を呼び出すだけです。\nServiceClientTracing.IsEnabled = true; ServiceClientTracing.AddTracingInterceptor(new Log4NetTracingInterceptor()); あとは、Rest.ClientRuntimeがよしなにやってくれます。 1とは異なり、トレースログなので、リクエストのボディについても出力してくれます。\n2020-05-26 19:09:04,058 [1] DEBUG Microsoft.Rest.Tracing.Log4Net.Log4NetTracingInterceptor [(null)] - invocationId: 1 instance: Microsoft.Azure.Search.DocumentsProxyOperations method: SearchPost parameters: {searchRequest=Microsoft.Azure.Search.Models.SearchRequest,clientRequestId=,cancellationToken=System.Threading.CancellationToken} 2020-05-26 19:09:04,164 [1] DEBUG Microsoft.Rest.Tracing.Log4Net.Log4NetTracingInterceptor [(null)] - invocationId: 1 request: Method: POST, RequestUri: \u0026#39;https://サービス名.search.windows.net/indexes(\u0026#39;インデックス名\u0026#39;)/docs/search.post.search?api-version=2019-05-06\u0026#39;, Version: 2.0, Content: System.Net.Http.StringContent, Headers: { client-request-id: 591cb14f-e5c2-4a85-977d-01d1f6431ddc Accept-Language: en-US Accept: application/json; odata.metadata=none api-key: APIキー Content-Type: application/json; charset=utf-8 } Body: { { \u0026#34;count\u0026#34;: false, \u0026#34;facets\u0026#34;: [], \u0026#34;queryType\u0026#34;: \u0026#34;simple\u0026#34;, \u0026#34;scoringParameters\u0026#34;: [], \u0026#34;search\u0026#34;: \u0026#34;azure\u0026#34;, \u0026#34;searchMode\u0026#34;: \u0026#34;any\u0026#34; } } 2020-05-26 19:09:04,459 [Thread Pool Worker] DEBUG Microsoft.Rest.Tracing.Log4Net.Log4NetTracingInterceptor [(null)] - invocationId: 1 response: StatusCode: 200, ReasonPhrase: \u0026#39;OK\u0026#39;, Version: 1.1, Content: System.Net.Http.StreamContent, Headers: { Cache-Control: no-cache Pragma: no-cache request-id: 591cb14f-e5c2-4a85-977d-01d1f6431ddc elapsed-time: 72 OData-Version: 4.0 Preference-Applied: odata.include-annotations=\u0026#34;*\u0026#34; Strict-Transport-Security: max-age=15724800; includeSubDomains Date: Tue, 26 May 2020 10:09:04 GMT Content-Type: application/json; odata.metadata=none Expires: -1 Content-Length: 376 } メリット、デメリット Log4Netを利用しているアプリの場合、2行だけを追加することで実装が完了するのがお手軽な点です。\n難点としては、Rest Client全てにたいしてトレース処理が入ってしまうので、Azure Cognitive Search以外にもRestクライアントを利用しているものが存在した場合、ログの量が増えてしまいます。また、検索以外の処理でもトレースされてしまうのもデメリットになります。\nLog4Net以外のログ機構を使用している場合は、自分でIServiceClientTracingInterceptorを実装する必要も出てきます(参考:StackOverflow)。\n3. Azure Application Insightsを活用する ここから紹介する3と4については、ログの出力先がAzure上になります。\nAzureのApplication Insightsを利用する方法です。 Azure?.NET?のアプリケーションパフォーマンスモニタリングのサービスです。\nApplication Insightsを自分のアプリケーションに設定することで、アプリケーションのパフォーマンス監視に関する情報がAzure上のApplication Insightsリソースに送信されるようになります。\nただ、Application Insightsのデフォルトの機能では、URL程度の情報だけが送信されます(参考:しばやんさんのブログ)\nこちらも拡張機能が用意されており、ITelemetryInitializerのインターフェースを実装したクラスを用意することで、独自の情報をApplication Insightsに出力することが可能となります。詳細についてはしばやんさんのブログを参考にしてもらうのが良いかと。\nHttpリクエストを出力する実装例は次のとおりです。ただ、ちょっとうまく行かないパターンがあったので、コメントアウトとして残してあったりします(なんでだろう?)\nusing System.Collections.Generic; using System.Net.Http; using System.Net.Http.Headers; using Microsoft.ApplicationInsights.Channel; using Microsoft.ApplicationInsights.DataContracts; using Microsoft.ApplicationInsights.Extensibility; namespace AzureSearchWebSample.ApplicationInsights { public class HttpRequestInitializer : ITelemetryInitializer { public void Initialize(ITelemetry telemetry) { if (!(telemetry is DependencyTelemetry dependency)) { return; } HttpRequestMessage requestMessage = null; HttpRequestHeaders requestHeaders; if (dependency.TryGetOperationDetail(\u0026#34;HttpRequest\u0026#34;, out var details) \u0026amp;\u0026amp; details is HttpRequestMessage request) { requestMessage = request; requestHeaders = request.Headers; if (requestMessage.Method == HttpMethod.Post) { string contentBody = requestMessage.Content.ReadAsStringAsync().GetAwaiter().GetResult(); dependency.Properties.Add(\u0026#34;RequestBody\u0026#34;,contentBody); } } else if (dependency.TryGetOperationDetail(\u0026#34;HttpRequestHeaders\u0026#34;, out details) \u0026amp;\u0026amp; details is HttpRequestHeaders headers) { requestHeaders = headers; } else { return; } foreach (KeyValuePair\u0026lt;string,IEnumerable\u0026lt;string\u0026gt;\u0026gt; header in requestHeaders) { foreach (string value in header.Value) { dependency.Properties.Add(header.Key, value); } } //この実装の場合は出力されなかった。なぜ? // if (requestMessage != null \u0026amp;\u0026amp; requestMessage.Method == HttpMethod.Post) // { // string contentBody = requestMessage.Content.ReadAsStringAsync().GetAwaiter().GetResult(); // dependency.Properties.Add(\u0026#34;RequestBody\u0026#34;,contentBody); // } } } } メリット、デメリット すでにApplication Insightsを利用している場合はついでに情報が出力されるので便利です。かつ、常にリクエストログを見れるようにしておく場合はとても便利だと思います。\nApplication Insightsを利用していない場合は、そこから導入しなければならなくなるので、手間が増えるかもしれないです。\n4. Azure Cognitive Searchのコンソールにある診断情報の機能を利用する。 最後はAzure Cognitive Searchの診断ログを有効にする方法です。 ここまで説明してきた方法の中で、一番お手軽な方法です。。。\nこれまでは、リクエストボディを出力する方法を考えていましたが、Azure Cognitive Search側の診断ログを有効にすると、リクエストボディで送信したものが、Azure Cognitive Search側で、クエリパラーメータとして、診断ログに出力されます(診断ログのQuery_s)。\nあとは、Azureのコンソールで当該時間のログを見ればよいだけです。以下は出力されたログの一部です。Description_sにはURLのパスが記載されています。\n診断ログ例(一部)\nDescription_s POST /indexes(\u0026#39;multi-field-test\u0026#39;)/docs/search.post.search Query_s ?api-version=2019-05-06\u0026amp;searchMode=Any\u0026amp;search=azure\u0026amp;queryType=Simple\u0026amp;$count=false メリット、デメリット アプリケーション側に手を入れる必要がなのでお手軽です。 一度設定しておけばコンソール側でログをいつでも見れるので便利です。\nリクエスト量が多くなってしまうと、ログの量も多くなり、費用がかさむ恐れがあります。また、複数の人が触る環境の場合は自分で送信したリクエストがどれだったのか?といった状況に陥る可能性はあります。\nその他は? Azureに対してではないですが、昔似たようなことをやるときにやっていた方法として、ローカルにプロキシサーバーを起動し、そのプロキシサーバー経由でアプリケーションから、Azureに接続することで、リクエストを保存する方法もあります。 ざんねんながら、未調査ですがアプリなどにはそれほど手を入れる必要はないかと思います。\nまとめ ちょっと送信リクエストの内容が見てみたいという話でしたが、いろいろな手段が存在しました。 自分の状況、環境に合わせて手段を選択肢てみるのがいいかと思います。 まずは、簡単な診断ログあたりからでしょうか?\n","date":1590481367,"dir":"post/2020/","id":"36dd94159e3e60076c0c6098086e255f","lang":"ja","lastmod":1590481367,"permalink":"https://blog.johtani.info/blog/2020/05/26/logging-azure-search-request/","publishdate":"2020-05-26T17:22:47+09:00","summary":"今回はAzure Cognitive SearchのSDKを利用したアプリケーションが、実際にAzure Cognitive Searchに対して送信しているリクエストのパラメータ","tags":["azure search",".net"],"title":"Azure Cognitive Searchのリクエストのロギング"},{"contents":"Mircosoft Buildというイベントが今週ありました(MSの方やお客さんに教えてもらった)。\nそこで、Azure Cognitive Searchのセッション(MyBuild - Cognitive Search: The pocket-knife for knowledge mining)があったので、見てみました。 内容がどんなものかをメモっておきます。 最初はCognitive Searchがどんなものよという説明でした。\nビルトインスキルの拡充の話 データソースからデータを取り出し、エンリッチし、検索エンジンに保存するという、パイプラインが組めるようになっています。\nこのパイプラインで利用できる処理のことがスキルと呼ばれています。ここで利用できるビルトインスキルが拡充されますよという話でした。ちょっとだけ抜き出すと以下のとおりです。\nAzure Machine Learning Text translation Brand detection Object detection スキルのリファレンスには載ってるものと載ってないものがあるので、今後追加されてくのかな? Brand detectionがどんなものなんだろう?ってのがちょっと気になりました。どっかにデモとかあるかなぁ?\nスキルセットのための新機能 : Debug Sessionのデモ 上記のスキルを組み合わせてパイプラインを組んで、データソースから取り出したデータをエンリッチしてから、検索エンジンに入れる処理をかけるのですが、その処理のデバッグ用に新しいGUIの機能が追加されてますよという紹介とデモでした。\nTutorial: Use Debug sessions to diagnose, fix, and commit changes to your skillset - Azure Cognitive Search | Microsoft Docs Manage Identityの話 Azure Cognitive Searchにデータを登録するパイプランの最初の段階で、各種データソースにアクセスが必要です。 このアクセス時にコネクションの設定にアカウントキーなども含めてましたが、これをコネクション設定ではなく、専用の管理機能が用意されましたよという話でした。\nSet up a connection to a data source using a managed identity (preview) - Azure Cognitive Search | Microsoft Docs QA Similarityとかの話 BM25になってるよとか SDKの話とか ほかにRelevancyの話 Analyzerをデフォルトのままじゃなくてちゃんと考えて使いましょう(例:各言語用のAnalyzerがいっぱいあるよとか) こんな感じでした。\n","date":1590117041,"dir":"post/2020/","id":"21982f43bc435f22efef22b309a48c66","lang":"ja","lastmod":1590117041,"permalink":"https://blog.johtani.info/blog/2020/05/22/watching-azure-cognirive-search-session-at-ms-build/","publishdate":"2020-05-22T12:10:41+09:00","summary":"Mircosoft Buildというイベントが今週ありました(MSの方やお客さんに教えてもらった)。 そこで、Azure Cognitive Searchのセッション(MyBuil","tags":["azure search"],"title":"Microsoft Build(2020)のAzure Cognirive Searchのセッションを見たのでメモ"},{"contents":"ElasticのWorkplace Searchを触ってみています(その1、その2)が、Elastic Stackの7.7.0がリリースされてしまいました。\n簡単ですが、リリースブログを見ながら気になった点をメモしとこうかと。\n本家のリリースブログ いっぱいあるんですよ、これが。まぁ、内容かぶってるのもあるんですが。\nElastic Stack Elastic Stack 7.7.0をリリース Elasticsearch 7.7.0 released Kibana 7.7.0 released Logstash 7.7.0 released Enterprise Search系 Elastic Enterprise Search 7.7 released, featuring Workplace Search GA | Elastic Blog Elastic App Search updates: Scale your way with new configuration options | Elastic Blog Elastic Workplace Search: 新しい、統合された働き方へ Observability系 Elastic Observability 7.7 released | Elastic Blog\nElastic APM 7.7.0 released with service maps, async profiler, and more | Elastic Blog\nElastic Logs 7.7.0 released with PCF support, MQTT support, and more | Elastic Blog\nElastic Metrics 7.7.0 released with enhanced Prometheus integration and PCF support, | Elastic Blog\nElastic Uptime Monitoring 7.7.0 released with alerting, anomaly detection and more | Elastic Blog\nNew alerting framework released for Observability, Security and the Elastic Stack | Elastic Blog\nIntroducing Elastic Security 7.7.0 | Elastic Blog\n個人的に気になったもの で、全部読んだわけではないのですが、個人的に気になった機能についてメモを残しておきます。 多分に検索によっている可能性がありますが、お気になさらず。 また、ブログとドキュメントを元に気になるところをピックアップしてます。 実際の実装とか動作に関してはまだ未調査の段階です。\nAsync Search - Elasticsearch ElasticsearchのAPIとして非同期に検索できるAPIが実装されました (公式リファレンス)。 大量データを検索が終了してから検索結果を返すのではなく、クエリは実行しつつわかったところまでは都度取得したいという要望だったり、Coldインデックスのように遅いストレージ上にあるデータへの検索でも少しずつ取得できるようにという具合だと思います。ログとか大量に扱う場合にまぁ、ほしいですよね。今回はEsのリリースがメインで、今後はKibanaなどとの連携だったり色々改善していくよという話みたいです(Kibanaの一部の機能は利用しているみたい)。\nライセンスとサブスクリプションのレベル Elastic License Basic 気になるところ(と、予想とか) 仕組みがどうなっているか? Search APIと同等のリクエストパラメータが使える。が、いくつか制約はありそう おそらくTask Manageerで検索してる処理が管理され、レスポンスにはIDが発行されて、そのIDで処理の進み具合を取得する感じ。 Shard単位?Segment単位? 内部的にはShard単位で検索処理を扱ってるので、Shard単位がとりあえず楽そう? Aggsとかも? 対象の模様 Sortは? 有効。ソートのフィールドがインデックス対象だった場合は、そのデータの統計値を使ってShardをソートするっぽい(公式リファレンスのNOTE参照) 関連しそうなGitHubのIssuesとか まだ読んでない\nAsync search · Issue #49091 · elastic/elasticsearch Add a listener to track the progress of a search request locally by jimczi · Pull Request #49471 · elastic/elasticsearch Pre-sort shards based on the max/min value of the primary sort field by jimczi · Pull Request #49092 · elastic/elasticsearch Async search: store intermediate results · Issue #55464 · elastic/elasticsearch Reduced consumption of heap - Elasticsearch ヒープの使用量が7.7で減ってるよというブログも別途ありました。\n元になっているLuceneの実装に関するIssueが「[LUCENE-8635] Lazy loading Lucene FST offheap using mmap - ASF JIRA」です。ヒープ上に展開していたデータをmmapで扱えるようにすることで、ヒープのメモリを削減してる。\nで関連して、これがLuceneで操作できるようになって(「Use reader attributes to control term dict memory useage by s1monw · Pull Request #42838 · elastic/elasticsearch」)、そこからEsに取り込まれたと。\n_idをoff-heapにする話は[ここ](Move the terms index of _id off-heap. by jpountz · Pull Request #52405 · elastic/elasticsearch)にあった。\nこれに関連して、ヒープサイズの推奨について再考が必要かも?というIssue(Reconsider our recommendations for heap size? · Issue #52561 · elastic/elasticsearch)も上がってる。\nPainless Lab - Kibana ほんとにPainless?と言う話はさておき、_script APIでexecuteはできていましたが、やはりもう少し楽に実行したいですよね?ということで画面ができたみたいです。\nシンタックスハイライトとかもできるので、より簡単に使えるようになってますね。 まだ、ベータなので足りないContextとかもあるっぽいけど。\nライセンスとサブスクリプションのレベル Elastic License Basic? まだベータだからか、サブスクリプションのページにはなかった。 公式ドキュメントとGitHubのリポジトリから、Elastic Licenseであることは判明。\n気になるところ(と、予想とか?) 制限事項がどんなものか? 使えるContextがまだ少ない?まだGAではない サジェストがどのくらい効くのか? シンタックスハイライトはあるけど。まだかなぁ? その他Elasticsearch関連 7.7リリースのハイライトが別途用意されています。\n7.7.0 release highlights | Elasticsearch Reference [7.7] | Elastic こっちで気になるのは、ClassificationとかTransformsあたりかなぁ。ML関連の機能で。\nWorkplace Search GA これは別のブログに書くかな。\n気になるところ Betaと何が変わったのか? APIとかどういう形で提供されるのか?そもそも提供されるのか? どんな機能?みたいなのも書く予定です。\nData VisualizerでFilebeatのConfigをサジェスト - Kibana and Filebeat Kibanaの画面からデータをちょっと?(100MB)だけアップロードして、Elasticsearchにサクッとデータ登録できる機能が実はあります。この機能の拡張として、Filebeatの設定だとこんな感じに作れるよ?というのを提示してくれるようになったみたいです。 手元にあるファイルを定期的に読み込むときに、設定を書く下地ができるのは便利じゃないかな?\nライセンスとサブスクリプションのレベル Elastic License Basic Data Visualizerってどんなもの?というのはここにブログがあります。残念ながらKibanaとかの公式リファレンスには使い方のページがないんだよなぁ。\nAPMのサービスマップ - APM and Kibana アプリケーションアーキテクチャのどこでAPMが動作しているか、どこと通信しているかという、APMのエージェントが入っているアプリ間のつながりをKibana上で可視化できる機能っぽいです。まだ、ベータみたいですが、面白そう。Azure Application Insightのアプリケーションマップに似てる気がします。\nライセンスとサブスクリプションのレベル Elastic License Platinum 気になるところ どうやって作ってる(つながりをどうやて判断してる)のか? 分散トレーシングのデータを元に誰がどこと通信してるってのは取れるんじゃなかろうか? Log categorization and contextual examples - Kibana and Elasticsearch 7.6から入ってたっぽいですが、ログの分類をMLの機能を使ってできるものが、LogsのUIとかでさらに使いやすくなった模様。\nライセンスとサブスクリプションのレベル Elastic License Platinum 気になるところ 7.6の機能から追いかけないとなぁ。。。 似たようなログをカテゴリーごとに分析できるようになるので、プラスMLの仕組みでこれまでとは異なる種類のログが出始めたみたいなことが分析できそう。 まとめ 眺めるだけで時間かかりましたが、まぁ、相変わらずいっぱいありますね。 興味のあるところの濃淡が出た感じになりましたが、気になる点をピックアップしてみました。 おかしなところとか、ここはどういう意味?などあればツッコミお願いします。\n","date":1589509037,"dir":"post/2020/","id":"306cecb32320ead508346ad8fed3394d","lang":"ja","lastmod":1589509037,"permalink":"https://blog.johtani.info/blog/2020/05/15/elastic-stack-7_7/","publishdate":"2020-05-15T11:17:17+09:00","summary":"ElasticのWorkplace Searchを触ってみています(その1、その2)が、Elastic Stackの7.7.0がリリースされてし","tags":["elastic stack"],"title":"Elastic Stack 7.7がリリースされた"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章 第9章 エラー処理です。 NLP100とか、いくつかのプログラムを書いていて、なんとなくは扱っていますが、きちんと勉強しないと。\nとりあえず、「Rustには例外は存在しません。」が一番知っておくことかな。\npanic!で回復不能なエラー panic!マクロでスタックを巻き戻して掃除をして終了。 異常終了(panic = 'abort')にもできる。 「RUST_BACKTRACEを0以外の変数にセットして実行」 * Resultで回復可能なエラー expect()は気持ち悪い名前じゃないかなぁ? ここでio::Errorではないものもエラーが発生する場合には panic!すべきかするまいか まとめ 「Rustには例外は存在しない」ので、回復不能か可能かを考えつつ処理を書こうと。\n","date":1589449406,"dir":"post/2020/","id":"1e220a934e16fd941bd804ca03865b60","lang":"ja","lastmod":1589449406,"permalink":"https://blog.johtani.info/blog/2020/05/14/chap9-rust-the-book/","publishdate":"2020-05-14T18:43:26+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 Rust the book - 第8章","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第9章"},{"contents":"Rustで言語処理100本ノックの第2章の残りです。\n前回はこちら。\nちなみに、標準入力から受け取る処理は書いてないです。 出力に関してはファイル分割、保存と支持があるもの以外は文字列として取り出すところで終わっています。\n12. 1列目をcol1.txtに,2列目をcol2.txtに保存 pub fn extract_column(input_file_name: \u0026amp;str, num: usize, output_file_name: \u0026amp;str) { let input_f = File::open(input_file_name).expect(\u0026#34;file not found\u0026#34;); let read_buf = BufReader::new(input_f); let mut output_f = OpenOptions::new() .write(true) .create(true) .open(output_file_name) .expect(format!(\u0026#34;can\u0026#39;t open file[{}] with write option\u0026#34;, output_file_name).as_str()); read_buf.lines().for_each(|line| match line { Ok(line) =\u0026gt; { let columns: Vec\u0026lt;_\u0026gt; = line.split(\u0026#39;\\t\u0026#39;).collect(); writeln!(output_f, \u0026#34;{}\u0026#34;, columns[num]); output_f.flush().expect(\u0026#34;Error during flush\u0026#34;); } Err(_) =\u0026gt; panic!(\u0026#34;parse error \u0026#34;), }); } 13で出力結果を利用するので入力として出力ファイル名も受け取るようにしました。 問題としては、1列目と2列目を別々に出力すればいいので、1回の処理で書いても良かったのですが、1回1ファイルの出力という形で実装しました(効率は悪い)。\n改行コードあたりを考えるのがめんどくさかったのでwriteln!マクロでファイルに書き出しています。が、普通にwriteメソッドで改行コードを追加しても良かったのかなと。\nあとは、出力先ファイルが存在しない場合だけopenするようにOpenOptionsを利用してみています。\nflushを呼び出すべきなのかどうか?を調べないとな。。。\n13. col1.txtとcol2.txtをマージ pub fn merge_files(col1_file: \u0026amp;str, col2_file: \u0026amp;str, output_file_name: \u0026amp;str) { let col1_buf = BufReader::new(File::open(col1_file).expect(\u0026#34;file not found\u0026#34;)); let col2_buf = BufReader::new(File::open(col2_file).expect(\u0026#34;file not found\u0026#34;)); let mut output_f = OpenOptions::new() .write(true) .create(true) .open(output_file_name) .expect(format!(\u0026#34;can\u0026#39;t open file[{}] with write option\u0026#34;, output_file_name).as_str()); col1_buf .lines() .zip(col2_buf.lines()) .for_each(|(col1, col2)| { let col1 = col1.expect(\u0026#34;parse error col1\u0026#34;); let col2 = col2.expect(\u0026#34;parse error col2\u0026#34;); writeln!(output_f, \u0026#34;{}\\t{}\u0026#34;, col1, col2); output_f.flush().expect(\u0026#34;Error during flush\u0026#34;); }); } 2つのファイル名を入力として受け取り、タブでくっつけて出力します。 zipを利用することで、2つのイテレーターを同時に回しています。\n14. 先頭からN行を出力 pub fn head(input_file_name: \u0026amp;str, lines: usize) -\u0026gt; String { let buf = BufReader::new(File::open(input_file_name).expect(\u0026#34;file not found\u0026#34;)); let mut head = String::new(); buf.lines().take(lines).for_each(|line| { head.push_str(format!(\u0026#34;{}\\n\u0026#34;, line.expect(\u0026#34;parse error\u0026#34;)).as_str()); }); return head; } イテレーターのメソッドにtakeがあります。 これを利用することで、引数に指定した数のエレメントが取得できるので、これでheadが実現できます。\n15. 末尾のN行を出力 pub fn tail(input_file_name: \u0026amp;str, lines: usize) -\u0026gt; String { let buf = BufReader::new(File::open(input_file_name).expect(\u0026#34;file not found\u0026#34;)); let mut tail = String::new(); let line_count = word_count(input_file_name); buf.lines().skip(line_count - lines).for_each(|line| { tail.push_str(format!(\u0026#34;{}\\n\u0026#34;, line.expect(\u0026#34;parse error\u0026#34;)).as_str()); }); return tail; } tailの場合は少し複雑で、11で作成した行数をカウントするメソッドで総行数を取り出し、そこから引数で指定された行数を引き算した数(=出力しない行数)を、イテレーターのskipメソッドの引数に渡しています。これにより、指定された数のエレメントをスキップしたあとの処理がかけます。\n16. ファイルをN分割する pub fn split_files( input_file_name: \u0026amp;str, num: usize, output_file_prefix: \u0026amp;str, output_file_suffix: \u0026amp;str, ) { let total = word_count(input_file_name) as f64; let lines_in_file = total / num as f64; let lines_in_file = lines_in_file.ceil() as usize; // let buf = BufReader::new(File::open(input_file_name).expect(\u0026#34;file not found\u0026#34;)); let output_files: Vec\u0026lt;File\u0026gt; = create_file_vec(output_file_prefix, num, output_file_suffix); println!(\u0026#34;split file each {} lines.\u0026#34;, lines_in_file); let mut lines = buf.lines(); for mut output_f in output_files { let mut current = 1; while current \u0026lt; lines_in_file + 1 { let line = lines.next(); if let Some(line_rs) = line { if let Ok(line_str) = line_rs { writeln!(output_f, \u0026#34;{}\u0026#34;, line_str); } } current = current + 1; } output_f.flush().expect(\u0026#34;error during flush\u0026#34;); } } fn create_file_vec(output_file_prefix: \u0026amp;str, num: usize, output_file_suffix: \u0026amp;str) -\u0026gt; Vec\u0026lt;File\u0026gt; { let mut files = Vec::with_capacity(num); for i in 0..num { let output_file_name = format!(\u0026#34;{}{}{}\u0026#34;, output_file_prefix, i + 1, output_file_suffix); let output_f = OpenOptions::new() .write(true) .create(true) .open(output_file_name.as_str()) .expect(format!(\u0026#34;can\u0026#39;t open file[{}] with write option\u0026#34;, output_file_name).as_str()); files.push(output_f); } return files; } ちょっと長いですね。\n入力としては、分割するファイル数Nが指定されます。まずは、総行数/Nで各ファイルに保存されるべき行数を計算します。 次に、2つ目の関数をつかって、必要な数のファイルオブジェクトをベクトルとして生成します。\nファイルオブジェクトのベクトルの要素を元にしたfor文を回しつつ、それぞれのファイルに必要な行数を出力している処理になっています。\n総行数がNで割り切れない場合にceilで切り上げした行数にするというちょっとした処理を入れてあります。\n17. 1列目の文字列の異なり pub fn count_uniq_words(input_file_name: \u0026amp;str, col: usize) -\u0026gt; usize { let mut words = HashSet::new(); let buf = BufReader::new(File::open(input_file_name).expect(\u0026#34;file not found\u0026#34;)); buf.lines().for_each(|line| match line { Ok(line_str) =\u0026gt; { let columns: Vec\u0026lt;_\u0026gt; = line_str.split(\u0026#39;\\t\u0026#39;).collect(); words.insert(columns[col].to_string()); } Err(_) =\u0026gt; panic!(\u0026#34;parse error \u0026#34;), }); return words.len(); } HashSetを利用することでユニーク性を担保して、最後はHashSetの数を数え上げれば終了です。\n18. 各行を3コラム目の数値の降順にソート pub fn sort_on_col3(input_file_name: \u0026amp;str) -\u0026gt; String { let mut lines: BTreeSet\u0026lt;Line\u0026gt; = BTreeSet::new(); let buf = BufReader::new(File::open(input_file_name).expect(\u0026#34;file not found\u0026#34;)); buf.lines().for_each(|line| match line { Ok(line_str) =\u0026gt; { let columns: Vec\u0026lt;_\u0026gt; = line_str.split(\u0026#39;\\t\u0026#39;).collect(); let num: u32 = columns[2].parse().expect(\u0026#34;parse error\u0026#34;); let line = Line { line: line_str, num, }; lines.insert(line); } Err(_) =\u0026gt; panic!(\u0026#34;parse error\u0026#34;), }); let mut sorted = String::new(); lines.iter().for_each(|line| { sorted.push_str(format!(\u0026#34;{}\\n\u0026#34;, line.line).as_str()); }); return sorted; } #[derive(Eq)] struct Line { line: String, num: u32, } impl Ord for Line { fn cmp(\u0026amp;self, other: \u0026amp;Self) -\u0026gt; Ordering { let ord = other.num.cmp(\u0026amp;self.num); if let Ordering::Equal = ord { other.line.cmp(\u0026amp;self.line) } else { ord } } } impl PartialOrd for Line { fn partial_cmp(\u0026amp;self, other: \u0026amp;Self) -\u0026gt; Option\u0026lt;Ordering\u0026gt; { Some(self.cmp(other)) } } impl PartialEq for Line { fn eq(\u0026amp;self, other: \u0026amp;Self) -\u0026gt; bool { self.eq(other) } } Lineという、行の文章と第3カラム目の値をもった構造体を作成しました。そこにEq、Ord、PartialOrd、PartialEqを実装し、3カラム目での大小比較できるようにしました。 この構造体をBTeeSetに格納していき、イテレーターで回すことで、ソートされた状態にしてあります。 同一数値の場合は行の降順でソートできるようにOrdを実装してあります。\n19. 各行の1コラム目の文字列の出現頻度を求め,出現頻度の高い順に並べる pub fn sort_on_frequency(input_file_name: \u0026amp;str) -\u0026gt; String { let mut names: HashMap\u0026lt;String, u32\u0026gt; = HashMap::new(); let buf = BufReader::new(File::open(input_file_name).expect(\u0026#34;file not found\u0026#34;)); buf.lines().for_each(|line| match line { Ok(line_str) =\u0026gt; { let columns: Vec\u0026lt;_\u0026gt; = line_str.split(\u0026#39;\\t\u0026#39;).collect(); let name_str = columns[0].to_string(); let count = names.entry(name_str).or_insert(0); *count += 1; } Err(_) =\u0026gt; panic!(\u0026#34;parse error\u0026#34;), }); let mut sorted = String::new(); let mut sorted_names: Vec\u0026lt;(\u0026amp;String, \u0026amp;u32)\u0026gt; = names.iter().collect(); sorted_names.sort_by(|(aname, acount), (bname, bcount)| { let ord = bcount.cmp(acount); if let Ordering::Equal = ord { bname.cmp(aname) } else { ord } }); sorted_names.iter().for_each(|(name, count)| { sorted.push_str(format!(\u0026#34;{} {}\\n\u0026#34;, count, name).as_str()); }); return sorted; } もうすこしうまくできる気がしますが、いったんこれで。 数え上げのためにまずはHashMapに第1カラムの文字列, 個数という組み合わせでデータを入れていきます。 出来上がったHashMapをタプルのベクターに変換し、変換したベクターのsort_byメソッドに比較用の関数を渡すことで個数の降順に並べています。同一個数の場合は文字列の降順になっています。 で、最後に並びかわったベクターのイテレーターを使って出力しておしまいです。 内部的には最悪3回回る感じでしょうか? 最初からベクトルに入れつつソートできる仕組みにするようなのがいいのかなぁ?\nまとめ Unixコマンドの勉強になりましたw あとは、HashMapなどの勉強にもなりました。 最後の方は効率がいまいち良くない気もしてはいますが、とりあえず第3章に進もうかと思います。\n","date":1589253809,"dir":"post/2020/","id":"09155bf417a93847b538ad607f78cca2","lang":"ja","lastmod":1589253809,"permalink":"https://blog.johtani.info/blog/2020/05/12/reboot-nlp100-ch02-12to19/","publishdate":"2020-05-12T12:23:29+09:00","summary":"Rustで言語処理100本ノックの第2章の残りです。 前回はこちら。 ちなみに、標準入力から受け取る処理は書いてないです。 出力に関してはファイル","tags":["Rust","nlp100"],"title":"第2章の12から19まで(言語処理100本ノック2020)"},{"contents":"気づいたら1ヶ月サボってました、ごめんなさい。。。\nRustで言語処理100本ノックの第2章をはじめました。\n前回はこちら。\n確認用のUnixコマンド 確認用のファイルを先に生成して置きました。 これで、Rustでコードを書いて、作成済みの確認ファイルを元にassert_eq!でチェックするという方式を取ろうかと。\nで、コマンド群はこちらです。\nUnix/Linuxコマンド、昔から使っています。が、なにかちょっとした文字列処理やファイル処理をやるときは、Javaのプログラム(最近だとPython)を書くというのが基本になってるので、結構、使ったことの無いコマンドが今回ありました。使ったことがなかったのはこちらです。\nsed tr expand paste cut split sedとかは普通さわってるだろ?って思われそうですね。。。\nで、コマンドをmanで調べつつやりました、macOS上で。 これがまたいくつか罠があったので書き残しておきます(自分が知らないだけかもしれないので、おかしいところがあったらツッコミお願いします。)。\nsedコマンドでのタブの扱い ## sed command for macOS. If using Linux, use \u0026#34;\\t\u0026#34; for tab character cat $INPUT_FILE_NAME | sed -e \u0026#39;s/\t/ /g\u0026#39; \u0026gt; $OUTPUT_DIR/11_sed.txt \\tで行けると思ったのですが、うまく動きませんでした。\u0026lt;tab\u0026gt;みたいな書き方もあると思うのですが、これも駄目で、結局タブ文字をそのまま打ち込みました。。。 これ、めんどくさくないですか??? ちなみに、ターミナルで動作確認して、GitHubにあげてあるシェルファイルにコピペしてたのですが、CLionに貼り付けたらタブ文字がスペースに変換されてしまってて20分くらい悩みました。。。\nsplitコマンドに-nオプションがない LINES=`cat $OUTPUT_DIR/10.txt` SPLIT_LINES=`echo $LINES/$N | bc` split -a 1 -l $SPLIT_LINES $INPUT_FILE_NAME $OUTPUT_DIR/16_ splitコマンドについてググると、-nで指定した数のファイルに分割できるという記事がいくつも出てくるのですが、man splitをターミナル上でやるとそんなオプションがないと。。。 macOSがBSD系だからっぽいです。 ということで、行数を元に、指定した数(N)で行数を割ってから、指定行数ごとにファイルを分割する方式にしました。\nこれらのコマンドの違いはHomebrewとかでインストールするとなくなるのかなぁ?(めんどくさいので確認してないですが。。。)\nってことで、2章のそれぞれの課題の正解ファイルの生成はこれでできたはずです。\n10. 行数のカウント wc -lですね。\n// ch02-10 行数のカウント pub fn word_count(file_name: \u0026amp;str) -\u0026gt; usize { let f = File::open(file_name).expect(\u0026#34;file not found\u0026#34;); let buf = BufReader::new(f); return buf.lines().count(); } ファイルを読み込んで行数を数えます。 文字列として読み込んで改行コードの数を数えるというのもありかな?と思いましたが、RustのBufReaderにlines()という行のイテレータ?が取れることがわかったので、それでカウントを取りました。\n11. タブをスペースに置換 // ch02-11 タブをスペースに置換 pub fn tab_2_space(file_name: \u0026amp;str) -\u0026gt; String { let mut f = File::open(file_name).expect(\u0026#34;file not found\u0026#34;); let mut contents= String::new(); f.read_to_string(\u0026amp;mut contents).expect(\u0026#34;read error\u0026#34;); return contents.replace(\u0026#34;\\t\u0026#34;, \u0026#34; \u0026#34;); } こっちはファイル全体を文字列に読み込んでしまってから、文字列のreplaceで置換するという方式です。 ファイルが大きい場合にこれでいいのか?という問題がある気がしますが、まずはこの実装にしました。 やるとしたら、readメソッドとbufferを用意して、少しずつ読みながら、置換して吐き出す感じでしょうか? ちゃんとした文字コードの区切りで取れるかどうかを気にしないと行けないと思うので、思ったよりはめんどくさくなりそう。\nBufReaderをつかってread_lineのほうがましかも?\nまとめ ということで、サボっていたのを再開しました。 Rustのコードを書く前に、Unixコマンドの処理に結構悩みましたw\nRustのコードとしてはファイル処理なので、今後も役立つ気がしてます。 ということで、頑張っていくぞと。\n","date":1588948640,"dir":"post/2020/","id":"c098c6f0901979bd914ed7a345200f90","lang":"ja","lastmod":1588948640,"permalink":"https://blog.johtani.info/blog/2020/05/08/rebootnlp100-ch02-10to11/","publishdate":"2020-05-08T23:37:20+09:00","summary":"気づいたら1ヶ月サボってました、ごめんなさい。。。 Rustで言語処理100本ノックの第2章をはじめました。 前回はこちら。 確認用のUnixコマ","tags":["Rust","nlp100"],"title":"第2章の10から11まで(言語処理100本ノック2020)"},{"contents":"Rustで言語処理100本ノックのリファクタリングの続き。\n前回はこちら。\nとっくに終わってたのに、ブログ書いてなかった。。。\n08. 暗号文 pub fn cipher(text: \u0026amp;str) -\u0026gt; String { return String::from_iter(text.chars().map(|x| { if x.is_ascii_alphanumeric() \u0026amp;\u0026amp; x.is_lowercase() { let mut b = [0; 4]; x.encode_utf8(\u0026amp;mut b); b[0] = 219 - b[0]; char::from(b[0]) } else { x } })); } Rustの文字列はUTF-8でエンコードされたテキストを保持しているので、文字コード自体は意識していないです。 chars()でUnicodeスカラー値のイテレータが返ってくるので、1文字ずつ扱えるようになります。\nただ、1文字をバイトとして扱うのに手こずりました。 encode_utf8というメソッドを利用して1バイトだけ取り出して、計算するというのをやっています。 文字種の判別のメソッドが用意されているのは便利ですね。\nなんかもうちょっとスマートにできないのかな?と思いつつ動いたのでこれになってます。\n09. Typoglycemia pub fn typoglycemia(text: \u0026amp;str) -\u0026gt; String { return text .split_whitespace() .map(|word| { if word.len() \u0026lt;= 4 { word.to_string() } else { let original = word.chars().collect::\u0026lt;Vec\u0026lt;char\u0026gt;\u0026gt;(); let first = original.get(0).unwrap(); let last = original.last().unwrap(); let mut typo = original[1..original.len() - 1] .iter() .map(|x| x.clone()) .collect::\u0026lt;Vec\u0026lt;char\u0026gt;\u0026gt;(); let mut rng = thread_rng(); typo.shuffle(\u0026amp;mut rng); let mut typo = String::from_iter(typo.iter()); typo.insert(0, first.clone()); typo.push(last.clone()); typo } }) .collect::\u0026lt;Vec\u0026lt;String\u0026gt;\u0026gt;() .join(\u0026#34; \u0026#34;); } 一応、1行で記述できたかな? まずは、スペースで単語ごとに区切った後に、word(単語)の長さによって、処理を分岐し、単語が5文字以上の場合にランダムに並び替えを行うというのをやっています。 文字単位で処理を行うために、chars()で1文字ずつ取り出しています。 最初と最後の文字だけはそのままに、間の文字をランダムにシャッフルするというのをやるのに、もとのwordのスライスからコピーした文字列を作り出してから組み立て直すということをやっています。\nコピーしないでゴニョゴニョする方法ってあるのかなぁ? 思いつかなかったので、結構泥臭い感じの実装になってしまいました。\nまとめ めんどくさいので、コードをGitHubのソースコードからではなく、ブログにコードスニペットとしてコピペしました。Hugoでいい感じにGitHubのコードスニペット表示するのないかなぁ?\nということで、2年越しで1章が終了しました。 2章もやらないとなぁ。\n","date":1588923657,"dir":"post/2020/","id":"2c3270f8797ace2fb37402ea6a09d126","lang":"ja","lastmod":1588923657,"permalink":"https://blog.johtani.info/blog/2020/05/08/reboot-nlp100-finish-ch01/","publishdate":"2020-05-08T16:40:57+09:00","summary":"Rustで言語処理100本ノックのリファクタリングの続き。 前回はこちら。 とっくに終わってたのに、ブログ書いてなかった。。。 08. 暗号文 pub fn cipher(text: \u0026amp;str) -\u0026gt;","tags":["Rust","nlp100"],"title":"第1章の08から09まで(言語処理100本ノック2020)"},{"contents":"前回はWorkplace Searchの概要について書きましたが、今回はインストールと構成要素について説明します。なお、2020/5/7時点での情報を元に本記事は書いていますのでご注意ください。基本的にはインストールと起動方法についての手順を元に書いています。所々に考察を挟んだ形の記事になっていますので、気になるところだけ呼んでいただければと。\n記事一覧 ElasticのWorkplace Searchを触ってみる - その1 インストール インストール方法は公式リファレンスもしくはダウンロードページに記載があります。 現時点ではMacもしくはLinuxが対象でWindowsはまだサポート対象外となっています。\n必要なもの インストールに必要なものは以下になります。\nElasticsearch 7.6.x + Platinum license Elastic CloudのElasticsearch Service もしくは ダウンロードしてローカルで起動 enterprise-search-7.6.0.tar.gz ダウンロードページはこちら Java 8もしくは11 Long Term Supportの対象であるJavaです。2020/5/7時点では8か11 今回はローカルにElasticsearchの7.6.2をインストールしてから試してみます。30日間のトライアルライセンスが有効になっているので、Platinumの機能を試すことができます。\nJavaの8か11が必要になります。Elasticsearchには7.xからJDKが同梱されるようになりましたが、Workplace SearchがJettyを元に動作しているからです(enterprise-search-7.6.0.tar.gzにjettyというフォルダあり)。\nインストール手順 大まかには以下の3つです。\nJava 8もしくは11のインストール 14でも大丈夫でした(ローカルにはSDKMANでインストールした14.0.1が利用された)。 Elasticsearchのインストール(Elastic Cloudの場合はクラスタの起動) 今回はローカルにインストール Workplace Searchのインストール Javaはもともとインストールされていたので、今回は2と3をインストールしました。どちらもローカルで起動するので、2つをダウンロードしてtar.gzファイルを展開するだけになります。\n起動方法と設定 起動方法に起動前の設定の手順も記載があります。 設定しながら起動していきます。\nElasticsearchの起動 既存のElasticsearchのクラスターがあり、Platinumのライセンスが有効になっている場合はこの手順は必要ありません。\nElasticsearchの設定ファイルでSecurity機能をオンに 7.1から基本的なセキュリティ機能はベーシックの機能に含まれています。 Elasticsearchを起動 まずは起動(パスワードなどを設定するために必要) Elasticsearchのパスワードの設定 Elasticsearchでデフォルトで用意されているユーザーのパスワードを設定してします。手順では自動で生成させる方法ですが、独自に設定することも可能です。 Workplace Searchの起動 Elasticsearchが起動したらWorkplace Searchの設定をして起動します。\nEsへの接続設定をconfig/enterprise-search.ymlに指定 Esのパスワード設定時に生成されたelasticというユーザーのパスワードをここで指定。 yamlファイルに記載があるが、${ELASTICSEARCH_PASSWORD:changeme}という記述をした場合に環境変数を読み込める allow_es_settings_modification: trueをconfig/enterprise-search.yml ここに記載があるような変更をWorkplace SearchがEsのクラスターに対して実行する模様。Workplace Search以外でも使用しているElasticsearchクラスターの場合はallow_es_settings_modificationを有効にする代わりに、リンク先にあるような設定を自分で追加する。 secret_management.encryption_keysを複数設定 Encryption Keysのガイドに少し詳しい説明がある。 opensslコマンドとかで作ればいいかな?? 1.と同じような設定をしようとしたがうまくいかなかったので、ファイルにキーを設定する方式にしました(バグ?) 起動するときにデフォルトユーザーパスワードを指定 指定しなければ勝手に生成してコンソールに出力してくれるので、そちらの方がいいかと。 今回は手順通りに指定した。 起動確認のためhttp://localhost:3002にアクセス 起動するとログが流れ、問題がなければ次のようにデフォルトユーザーの情報が出力されます。\n######################################################### *** Default user credentials have been setup. These are only printed once, so please ensure they are recorded. *** username: enterprise_search password: pas...ple ######################################################### そして無事起動に成功したことも出力されます。\n######################################################### Success! Elastic Workplace Search is starting successfully. In a few moments, you\u0026#39;ll be able to login at the following address: * URL: http://localhost:3002 * If this is your first time starting Workplace Search, check the console output above for your user authentication credentials. * Visit the documentation: https://swiftype.com/documentation/enterprise-search Secret session key has been generated. Set the key in your config file to persist user sessions through process restarts: secret_session_key: c23...3 ######################################################### ブラウザで画面にアクセスすると、次のような画面が表示されました。\n起動時のエラー いくつかのパターンも試してどんなエラーが出るのかを見てみました。 おまけですね。\nElasticsearchが見つからないエラー Esを起動しないでWorkplace Searchを起動してみました。\n200秒間アクセスしようと試みて駄目だったらエラーで終了みたいです。\n[2020-05-07T03:48:33.645+00:00][13709][2002][app-server][INFO]: Failed to connect to Elasticsearch backend. Make sure it is running. ... [2020-05-07T03:51:54.038+00:00][13709][2002][app-server][INFO]: Could not connect to Elasticsearch backend after 200s. Terminating... [2020-05-07T03:51:54.039+00:00][13709][2002][app-server][ERROR]: -------------------------------------------------------------------------------- Error: Workplace Search is unable to connect to Elasticsearch. Ensure a healthy Elasticsearch cluster is running at http://127.0.0.1:9200 for user elastic. -------------------------------------------------------------------------------- ElasticsearchのSecurityがオフのときのエラー ちなみにSecurityをオフにしたままWorkplace Searchを起動した場合は以下のようなエラーが出ました。\n[2020-05-07T03:46:53.474+00:00][13567][2002][app-server][ERROR]: -------------------------------------------------------------------------------- Elastic Workplace Search requires Elasticsearch security features to be enabled. Please enable Elasticsearch security features as outlined here: https://www.elastic.co/guide/en/workplace-search/current/workplace-search-install.html -------------------------------------------------------------------------------- 構成要素 ここまでインストールして起動してきました。 では、Workplace Searchがどういったコンポーネントから構成されているかを予測してみましょう(あくまで外から見た予想となります。そのうちElastic社のウェビナーとかイベントで内部の発表とかあるかも?)。\nインストールページの記載から インストールページに最小ハードウェアという記載があり、そこで何が動く可能性があるかというのがわかります。\n起動するものはこんな感じみたいです。\nElasticsearch - 外部でもOK App Server - Workplace SearchのWeb機能 Worker - クローラーとかかな? Filebeat - Workplace Searchのログ収集用 その他プロセス - なんだろ? という具合です。\n設定などからの予想 次は設定項目や起動時のログなどからの予想です。\nWorklpace Search配下のセキュアなデータストア - アクセストークンなどの管理のため JRubyアプリケーション - App ServerはJRuby上で動いているRailsアプリ Filebeatも起動している - Workplace Searchのログ収集のため? Filebeatの接続設定はWorkplace Searchの設定値を利用 では構成要素は? ということで、現時点でわかった構成要素は以下のとおりです。\nElasticsearch Workplace Search App Server - Railsアプリ on JRuby Webアプリとは別に(内部?で)、いくつかのワーカーが存在する 管理画面と検索画面の2種類が存在 Filebeat - ログ収集 といった感じです。 まだ起動したばかりなのでこのくらいでしょうか。ログを見るともう少しわかりそうな気がします。\n基本的には、EsをバックエンドにしたRailsのミドルウェアになります。コネクターや検索画面はすべてWorkplace Searchのミドルウェア経由でアクセスする形になりますので、普通に検索で利用するユーザーにはElasticsearchの存在は見えない作りになっています。\n次は? Getting Startedを元に、どんなアクターがいて、どんな機能が提供されているのか、どんな利用方法なのか?というのを見ていこうと思います。\n","date":1588818770,"dir":"post/2020/","id":"44db1f1fefc97cd28d55d443f2bd2b63","lang":"ja","lastmod":1588818770,"permalink":"https://blog.johtani.info/blog/2020/05/07/install-workplace-search/","publishdate":"2020-05-07T11:32:50+09:00","summary":"前回はWorkplace Searchの概要について書きましたが、今回はインストールと構成要素について説明します。なお、2020/5/7時点で","tags":["elasticsearch","workplace search"],"title":"ElasticのWorkplace Searchを触ってみる - その2 - インストールと起動"},{"contents":"2月のElastic社のブログですが、Enterprise Searchとこれまで呼んでいた製品をWorkplace Searchという製品名に変更し、App Searchなどを含む製品群をEnterprise Searchという名前に変更しました(ちょっとややこしい)。 Workplace Search自体はまだβ版という位置づけですが、ダウンロードして試すことが可能です。\nきちんと触ったことがないので、ちょっと触って見ようかなと思い、何回かに分けてブログを書いてみます。まずは概要とかから。\nWorkplace Searchとは? Elasticsearchをバックエンドに利用するElastic社が提供するアプリケーション(ミドルウェア?)の1つです。\nもともとはSwiftypeという会社が作っていた、Site Search、App Searchと同じような系列で開発されている統合検索の検索エンジンミドルウェアという感じです。 製品ページを見るとわかりますが、様々なデータソースから、データをクロールしてElasticsearchに保存することで、統合された検索を提供することができるようになる製品です。 最近は会社のドキュメントがさまざまな場所(Google Drive、Saleseforce、GitHub、Dropboxなど)に保存されています。 それぞれで検索窓などはありますが、1箇所で検索することで横断的に検索でき、仕事の効率があがりますよね?ということで作られている製品です。\n提供(利用)方法は? 今後の提供方法としては、Elastic Cloudで利用できるSaaS形式のものと、独自に(クラウドのコンピューティングエンジンやオンプレのサーバーなどで)Workplace Searchのアプリを起動する方法(オンプレ版)があります。後者の場合は、Elasticsearchのクラスターを用意する必要があります。なお、後者の場合、Elasticsearchのサブスクリプションのプラチナライセンスが必要になるようです(ダウンロードページに記載あり)\nまだ、β版という位置づけなので、今後どのように変更されるかはわかりませんが、今回は2020年5月1日時点でのベータ版(7.6.0)を元にどんなものかを紹介します。現時点で利用できるのはβ版のオンプレ版で、MacやLinuxで利用可能です。\nダウンロードとインストール ダウンロードページにインストール方法などの記載があります。\nインストールして触って見るところはまた後日。\nライセンス、価格は? まだ不明です。SaaS版の提供はまだです。 オンプレ版については少なくとも、Elasticのサブスクリプションのプラチナが必要になります。こちらは、価格は公開されていません。Elastich社もしくはパートナー企業での問い合わせが必要になります。 (たぶん、ドキュメントレベルのセキュリティとかSSOとかの仕組みがプラチナで提供されているのでそのあたりを使っているのでは?と想像してます。)\n想定できそうな用途は? 社内の文書検索でしょうか。ただ、いわゆる昔ながらのエンタープライズサーチと呼ばれている、社内のファイルサーバーなどの文書検索ではなく、クラウドサービスを複数利用している会社が利用する想定になっています。\n例えば、開発者は社内Wiki(Confluence)で社内文書を書き、Issue管理にはJIRAやGitHubを活用しており、ただ、社内での説明にはGoogle Driveを利用しているといった場合です。こういう場合、あの機能についての説明や資料ってどこだっけ?というので、あちこち探し回ったりしないといけないです。また、営業部門やサポート、マーケティングなどが絡んでくると更に、SalesforceやZendeskといったデータソースも出てきます。 情報が散らばっていて、それらを探し出したりまとめるだけで時間を取られている場合などに便利かもしれません。\n次は? 実際にインストールしてから起動して、どんな感じで使えるのかといったところを見て、どんな機能が提供されているのかを見ていこうと思います。\n","date":1588318144,"dir":"post/2020/","id":"4d71d2a23c85fb7af20e8d1e8b3e0de8","lang":"ja","lastmod":1588318144,"permalink":"https://blog.johtani.info/blog/2020/05/01/intro-workplace-search/","publishdate":"2020-05-01T16:29:04+09:00","summary":"2月のElastic社のブログですが、Enterprise Searchとこれまで呼んでいた製品をWorkplace Searchという製品名に","tags":["elasticsearch","workplace search"],"title":"ElasticのWorkplace Searchを触ってみる - その1"},{"contents":"先日、Elasticsearchでのカスタム辞書の利用方法についてブログを書きました。\n辞書の設定方法について記載しましたが、今回は辞書の更新について書いていなかったので、書いてみようと思います。 ここで「辞書」としているのは、Kuromojiのユーザー辞書、Synonym Graph Token FilterのSynonym辞書(いわゆる類義語辞書)のことになります。サードパーティのAnalyzer等に関する話ではありません。\n辞書更新に関する制限事項 辞書の更新について、大原則と制限事項が存在します。\n大原則(辞書の更新=データも更新) ElasticsearchはAnalyzerが切り出した単語を元に転置インデックスを作成して、検索を行っています(この仕組みに関するスライドはこちらを参照のこと)。 Analyzerが辞書を持っている場合、その辞書を元に単語を切り出して転置インデックスに利用します。 また、検索クエリの単語に対してもこのAnalyzerの辞書が利用されます。\n辞書に新しい単語を追加するということは、その単語に関連するドキュメントも更新しないと行けないということになります。\n例えば、Kuromojiを利用していて、「グランベリーパーク」という単語「グランベリー」「パーク」という単語に分割できるような新しい単語として辞書に追加する場合を考えてみましょう。ユーザーが「グランベリー」で検索しても検索結果として出てきてほしいという場合です。\n辞書に「グランベリーパーク」を登録していない頃に登録されたドキュメントは「グランベリーパーク」という1単語として転置インデックスの見出し語を切り出します(Kuromojiはカタカナの連続している文字列については未知語として1単語にし、「名詞-一般」の品詞を付与)。\n更新前でのドキュメントのAnalyze結果\n「グランベリーパーク」「で」「ショッピング」 もし、辞書に「グランベリーパーク」を「グランベリー」「パーク」から構成される新規の単語として登録しそれを使用した場合、辞書を更新したあとから、「グランベリーパーク」という単語がAnalyzerからは出てこなくなります。\n更新後でのドキュメントのAnalyze結果\n「グランベリー」「パーク」「で」「ショッピング」 ということは、辞書更新以前のドキュメントは「グランベリーパーク」という見出し語に対して登録されているので、辞書更新以前に登録されているドキュメントは検索にヒットしなくなります。\nこのように転置インデックスを利用している検索エンジンでは、単語の区切りが変更されるような辞書の更新があった場合、最低でも影響があるドキュメントについては再登録が必要となるわけです。\nこれが大原則(辞書更新=データも更新)となります。 基本的には辞書の更新を行った場合は、ドキュメントの再インデックス(再登録)が必要となります。\nElasticsearchでの制限事項 Elasticsearchでは、辞書の更新に関して実装上の制限事項が存在しています。 内部的な実装として、ElasticsearchではAnalyzerのインスタンス(正確にはAnalyzerのFactoryのインスタンス)の生成がインデックスに関する内部のインスタンスが生成されたタイミングの1回のみとなっています。\nこのインスタンスの生成時に設定ファイル(辞書を含む)を読み込んでいます。\n言い換えると、辞書(ファイル、インデックス設定に関わらず)の読み込みは、インデックスが作られたタイミングのみということになります。 なおここで言う「インデックスが作られたタイミング」というのは、以下の2パターンです。\nインデックス新規作成時 インデックスオープン時 では、ここから辞書を更新してそれを既存のインデックスに適用する方法について説明しましょう。\n辞書の更新方法(ファイル編) 前回のブログで説明しましたが、Elasticsearch 7.4よりも古いバージョンでは、ファイルでKuromojiのユーザー辞書を設定していました。まずはこちらの方法について説明します。前提として、すでにユーザー辞書を設定したKuromoji Tokenizerがインデックスに設定されているものとします(ユーザー辞書の設定方法については公式リファレンスを御覧ください)。\n辞書ファイルに新規にエントリーを追加しただけでは、設定は読み込まれていません。新規辞書を反映させるためには以下の手順が必要となります。\n更新した辞書ファイルの配布 複数ノードでElasticsearchのクラスターを構成している場合はすべてのノードに更新した辞書ファイルを配布する必要があります。 インデックスのクローズ(公式リファレンス) 設定ファイルを再読込させるために一度インデックスをクローズします。 クローズするので、書き込み、検索などの処理を停止する必要があります。もし停止していない場合はクライアント側ではインデックスがクローズされているという旨のエラーを受け取ります(400で、index_closed_exception)。 インデックスのオープン(公式リファレンス) 設定ファイルを読み込みます。これで、新規追加された単語が読み込まれます。 再インデックス _update_by_queryを利用することで、対象のインデックスのデータを再インデックスすることができます。条件無しでAPIを呼び出すとすべてのデータが再度登録されます。 _sourceがfalseの場合は_update_by_queryは利用できません。元データをもう一度外部からElasticsearchに対して登録する必要があります。 Kibanaでの手順をGistにしてあります。手順はこちらをご覧ください。\n辞書の更新方法(インデックス設定編) ファイルの場合とは少し手順が異なります。 インデックスの設定としてユーザー辞書を登録しているため、ファイルをElasticsearchのクラスターにあるノードに配布する必要がありません。 また、辞書の設定はインデックスの設定に指定してありますが、こちらは動的に設定変更できる項目ではないため、インデックスを先にクローズする必要があります。\nインデックスのクローズ(公式リファレンス) 辞書の設定を更新するにはインデックスをクローズする必要があります。辞書の設定は動的に更新できる項目にはなっていないためです。 オープンしているインデックスで更新しようとした場合はillegal_argument_exceptionでCan't update non dynamic settings...というメッセージが返ってきます。 辞書の更新(公式リファレンス:インデックス設定の更新) user_dictionary_rulesに単語と追加します。 インデックスのオープン(公式リファレンス) 設定ファイルを読み込みます。これで、新規追加された単語が読み込まれます。 再インデックス _update_by_queryを利用することで、対象のインデックスのデータを再インデックスすることができます。条件無しでAPIを呼び出すとすべてのデータが再度登録されます。 _sourceがfalseの場合は_update_by_queryは利用できません。元データをもう一度外部からElasticsearchに対して登録する必要があります。 Kibanaでの手順をGistにしてあります。手順はこちらをご覧ください。\n第3の方法(新規インデックス作成) ここまで、インデックスのクローズ、オープンで既存のインデックスに対して辞書を更新する方法について説明しました。 ただ、残念なことにAmazon Elasticsearch ServiceではElasticsearchが提供しているすべてのAPIが利用できるわけではありません(Amazon ESの利用可能なAPIの一覧はこちら)。 (_closeは駄目だけど_openは呼べるのかな???)\nということで、新規にインデックスを作成して、新しい辞書の設定を反映したインデックスを用意し、そこにデータをコピーもしくは登録するという方法になります(Amazon ESのカスタム辞書のドキュメントに手順がありますね)。\n手順としては以下のとおりです。\n辞書の更新(用意) 新しい単語などを登録した辞書を用意します。 ファイル、インデックス設定どちらでもOKです。 ファイルの場合は、既存のファイル名とは異なるファイル名にしたほうが混乱がなくなります。 新規インデックス作成 1.で作成した辞書を元に新規インデックスを作成します。 新規インデックスにデータコピー _reindex APIを利用するとデータコピーが簡単です。sourceとdestを指定するだけです。 _sourceがfalseの場合は_update_by_queryは利用できません。元データをもう一度外部からElasticsearchに対して登録する必要があります。 アプリケーション側で新規インデックスを利用するように変更 _aliasを使用しておくと切り替えが簡単です(公式リファレンスはこのあたり)。 考慮すべき点としては、サービスを提供しながら行う場合は、3.の_reindexを実行し始めたタイミング以降の登録・更新データの扱いについてでしょうか。\nまとめ 辞書の更新に関する大原則、制限事項、手順などについて説明しました。 辞書の変更は検索に大きく影響がでます。そのあたりをきちんと考慮しながら更新しましょう。 ユーザー辞書、カスタム辞書を扱う際の参考にしていただければと。 他にもユーザー辞書で気をつけないといけないこともありますが、今日はこのあたりで。\n","date":1587951855,"dir":"post/2020/","id":"be2c49ea5816e7daa6d3b3ff45353291","lang":"ja","lastmod":1587951855,"permalink":"https://blog.johtani.info/blog/2020/04/27/note-updating-dictionary/","publishdate":"2020-04-27T10:44:15+09:00","summary":"先日、Elasticsearchでのカスタム辞書の利用方法についてブログを書きました。 辞書の設定方法について記載しましたが、今回は辞書の更新","tags":["elasticsearch"],"title":"辞書の更新についての注意点"},{"contents":"Elasticsearchで日本語を扱うときに、カスタム辞書を使いたいという要望がよくあります。 AWSのElasticsearch Serviceでカスタム辞書ファイルを読み込める機能が発表されたようです。\n実は、Elasticsearchの7.4からファイルを使用しなくても日本語のTokenizerでカスタム辞書を利用することができるようになっています。\nカスタム辞書をインデックスの設定で指定 やり方はドキュメントに記載があります。\nトークナイザーの設定をインデックスの設定に記述しますが、このときに user_dictionary_rulesという設定を利用することでカスタム辞書を指定できます。\nPUT custom_dic_sample { \u0026#34;settings\u0026#34;: { \u0026#34;index\u0026#34;: { \u0026#34;analysis\u0026#34;: { \u0026#34;tokenizer\u0026#34;: { \u0026#34;kuromoji_user_dict\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;kuromoji_tokenizer\u0026#34;, \u0026#34;mode\u0026#34;: \u0026#34;extended\u0026#34;, \u0026#34;user_dictionary_rules\u0026#34;: [ \u0026#34;グランベリーパーク,グランベリー パーク,グランベリー パーク,カスタム名詞\u0026#34;, \u0026#34;高輪ゲートウェイ,高輪 ゲートウェイ,タカナワ ゲートウェイ,カスタム名詞\u0026#34;] } }, \u0026#34;analyzer\u0026#34;: { \u0026#34;my_analyzer\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;custom\u0026#34;, \u0026#34;tokenizer\u0026#34;: \u0026#34;kuromoji_user_dict\u0026#34; } } } } } } 辞書の内部は\u0026quot;単語,出てきてほしい単語列(スペース区切り),読みの単語列(スペース区切り),品詞名\u0026quot;になります。配列で設定可能で、複数の単語を登録したい場合は、カンマ区切りで登録していきます(上記例では2つの単語を登録しています)。\n_analyzeを利用して設定の確認 実際に上記の設定がうまく動作するかは_analyzeのエンドポイントを利用します。\nGET custom_dic_sample/_analyze { \u0026#34;text\u0026#34;: \u0026#34;グランベリーパークがオープンしました。\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;my_analyzer\u0026#34; } 出力は以下のようになります。\n{ \u0026#34;tokens\u0026#34; : [ { \u0026#34;token\u0026#34; : \u0026#34;グランベリー\u0026#34;, \u0026#34;start_offset\u0026#34; : 0, \u0026#34;end_offset\u0026#34; : 6, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 0 }, { \u0026#34;token\u0026#34; : \u0026#34;パーク\u0026#34;, \u0026#34;start_offset\u0026#34; : 6, \u0026#34;end_offset\u0026#34; : 9, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 1 }, { \u0026#34;token\u0026#34; : \u0026#34;が\u0026#34;, \u0026#34;start_offset\u0026#34; : 9, \u0026#34;end_offset\u0026#34; : 10, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 2 }, { \u0026#34;token\u0026#34; : \u0026#34;オープン\u0026#34;, \u0026#34;start_offset\u0026#34; : 10, \u0026#34;end_offset\u0026#34; : 14, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 3 }, ...(省略) ] } ちなみに、デフォルトのkuromojiを利用した場合は、グランベリーパークが1単語として出力されます。\nGET _analyze { \u0026#34;text\u0026#34;: \u0026#34;グランベリーパークがオープンしました。\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;kuromoji\u0026#34; } ## レスポンス { \u0026#34;tokens\u0026#34; : [ { \u0026#34;token\u0026#34; : \u0026#34;グランベリーパーク\u0026#34;, \u0026#34;start_offset\u0026#34; : 0, \u0026#34;end_offset\u0026#34; : 9, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 0 }, { \u0026#34;token\u0026#34; : \u0026#34;オープン\u0026#34;, \u0026#34;start_offset\u0026#34; : 10, \u0026#34;end_offset\u0026#34; : 14, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 2 } ] } これで、カスタム辞書を使用することでグランベリーで検索された場合に、グランベリーパークもヒットするという仕組みです。\n_analyzeはexplainというパラメータも持っており、こちらを利用することで、単語の品詞情報なども取得できます。これを使うことで、実際に設定がきちんと動作しているかの確認に利用できます。\nGET custom_dic_sample/_analyze { \u0026#34;text\u0026#34;: \u0026#34;グランベリーパークがオープンしました。\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;my_analyzer\u0026#34;, \u0026#34;explain\u0026#34;: true } ## レスポンス(一部のみ) { \u0026#34;detail\u0026#34; : { \u0026#34;custom_analyzer\u0026#34; : true, \u0026#34;charfilters\u0026#34; : [ ], \u0026#34;tokenizer\u0026#34; : { \u0026#34;name\u0026#34; : \u0026#34;kuromoji_user_dict\u0026#34;, \u0026#34;tokens\u0026#34; : [ { \u0026#34;token\u0026#34; : \u0026#34;グランベリー\u0026#34;, \u0026#34;start_offset\u0026#34; : 0, \u0026#34;end_offset\u0026#34; : 6, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 0, \u0026#34;baseForm\u0026#34; : null, \u0026#34;bytes\u0026#34; : \u0026#34;[e3 82 b0 e3 83 a9 e3 83 b3 e3 83 99 e3 83 aa e3 83 bc]\u0026#34;, \u0026#34;inflectionForm\u0026#34; : null, \u0026#34;inflectionForm (en)\u0026#34; : null, \u0026#34;inflectionType\u0026#34; : null, \u0026#34;inflectionType (en)\u0026#34; : null, \u0026#34;partOfSpeech\u0026#34; : \u0026#34;カスタム名詞\u0026#34;, \u0026#34;partOfSpeech (en)\u0026#34; : null, \u0026#34;positionLength\u0026#34; : 1, \u0026#34;pronunciation\u0026#34; : null, \u0026#34;pronunciation (en)\u0026#34; : null, \u0026#34;reading\u0026#34; : \u0026#34;グランベリー\u0026#34;, \u0026#34;reading (en)\u0026#34; : \u0026#34;guramberi\u0026#34;, \u0026#34;termFrequency\u0026#34; : 1 }, { partOfSpeechにカスタム辞書で設定したカスタム名詞が出力されていますね。 _analyzeのAPIはこのように、アナライザーの挙動の確認に非常に便利なので是非活用してみてください。\nKibanaでこのAPIを使うためのプラグインも開発していますので、こちらも合わせて利用してみてください。\n注意点 ちなみに、user_dictionaryとuser_dictionary_rulesを両方指定した場合はエラーとなります。 ファイルをベースにしつつ、追加の設定をするという使い方はできないので、注意しましょう。\nインデックスの設定で書くことにより、バックアップ・リストアは楽になるかな。ただ、クラスターステートに取り込まれるから、あまりにも巨大なカスタム辞書だと心配かなぁ。ファイルの場合はクラスターステートには取り込まれないので、そこは圧迫しない。\n\u0026mdash; Jun Ohtani (@johtani) April 22, 2020 それ以外の注意点については、別途ブログを書きました。 「辞書の更新についての注意点」、こちらも合わせてご覧ください。\nまとめ カスタム辞書をファイルではなくインデックスの設定値として設定する方法を紹介しました。こちらは、Elasticsearch 7.4で導入された機能になります。7.4以降を利用している場合はこちらを利用することも検討してはいかがでしょうか? また、_analyze APIも便利なので合わせて活用してみてください。\n","date":1587519056,"dir":"post/2020/","id":"15357b6978e83daa2d97692c861dc177","lang":"ja","lastmod":1587519056,"permalink":"https://blog.johtani.info/blog/2020/04/22/custom-dictionary-after-7-4/","publishdate":"2020-04-22T10:30:56+09:00","summary":"Elasticsearchで日本語を扱うときに、カスタム辞書を使いたいという要望がよくあります。 AWSのElasticsearch Servi","tags":["elasticsearch"],"title":"Kuromojiのカスタム辞書をインデックスの設定で指定"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 第8章 7章はパッケージなので後回しにして、8章に入ります。 8章はコレクションです。\nベクタ型 ベクタは同じ型の値だけ保持可能。 ジェネリクスで型を指定可能 - Vec\u0026lt;i32\u0026gt;とか。 vec!マクロで初期値とか設定すると便利。 ベクタに値を追加するのはpush。もちろん値が変わるので元のベクタにはmutが必要 ベクタのスコープ(ライフサイクル)は要素に対する参照があるのとないので話が変わってくる メモリの確保などの影響で、ベクタ全体に対して借用の規則が矯正されると。 ベクタの値を読むのはいくつか方法あり getメソッドはOptionを返す \u0026amp;v[2]の添字記法の場合はパニックの可能性あり 走査(唐突に参照外しが出てきた) 単純に値を取り出す場合はfor - in \u0026amp;v Enumをベクタにいれることで、異なる型も保持可能(まぁ、Enumの型では固定されるけど)。 これだけのためにEnumを使うことってあるのかな? トレイとオブジェクトに関する文章はちょっとわかりにくい。。。 説明以外のメソッドなどについてはAPIドキュメント見ましょうと(リンクも張ってくれてると嬉しいなぁと思ったり。まぁ、バージョンとかの絡みがあるから難しいか)。\n文字列型 文字列はUTF-8でエンコードされた文字を扱うための型。\nstrは文字列データへの参照。\nString型は言語のコアではなく、標準ライブラリに入っている文字列型。\n他にもあるのか。。。OsStringとか。。。 文字リテラルはDisplayトレイトを実装していると。\n.to_string() = String::from\nStringはコレクションだから追加とかが可能なのか、なるほど。\npush_strとpush\n+演算子での参照。\n\u0026amp;Stringは\u0026amp;strに型強制(キャスト?)してくれる。してくれる場合としてくれない場合もあるのかな?s2の所有権は奪わない形で扱うのでs2はこのあとも使えていると。 ここでは、s1を変更したあとに所有権がs3に持っていかれてる? format!を使うとどの所有権も奪わないので、これを使うほうが考え方は簡単そう。ただし、効率がいいかはわからん。 添字記法でのアクセスをStringは許容していない\n文字の境界が必ずしも1バイトとは限らないから。 スライスも同様。 基本的には.chars()で文字としてアクセスするのが良い。\n逆にバイト表現を得る方法はどうするんだろう?\nNLP100本ノックではencode_utf8メソッド使ったけど。 ハッシュマップ いろんな呼び方あるよね。Rustではハッシュマップだよ。 ハッシュマップはuseしないと使えない キーは1つの型、値も1つの型 タプルのベクタからcollectで生成。なるほど。 タプルのベクタだと、タプルの中身は同じものであることが言える? -\u0026gt; 言える。エレメント数が異なるとコンパイルエラーになった 所有権周りの話。 これ、ベクタのときに話してほしい感じがした。 値を渡すか参照を渡すかによって話が変わってくる。詳しくは10章 このあたりが自分が混乱していた元だ。 entryとinsertの違い entryの戻り値はEntryというenumでor_insertというメソッドがありそれを使うと存在しない場合だけinsertが呼ばれる。 これ便利だ。毎回existあたりで存在チェックしてた気がする。 or_insertは可変参照\u0026amp;mut Vを返す。 これをlet countで束縛するときに、中身が可変かどうかをcountには指定しないのか。。。 まとめ 一応、大学などで習ってた(はず)ですが、 スタックとヒープを意識して考えないといけないなぁというのを何度か意識させられた感じです。\nあと、これはRustに限らずですが、それぞれがどんな関数を持っているか、どんなメソッドを持っているか、どんなマクロが存在するかなどを探すときにみんなどうしてるんだろう? 人に教えてもらっているのか、APIリファレンスを探すのか、そういったところをみんながどういう感じにプログラミング言語を勉強しているか、業務で書いているのかと言うのが気になりました。\n","date":1587028650,"dir":"post/2020/","id":"f488aa62d39194824861a134567cadb8","lang":"ja","lastmod":1587028650,"permalink":"https://blog.johtani.info/blog/2020/04/16/chap8-rust-the-book/","publishdate":"2020-04-16T18:17:30+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 Rust the book - 第6章 第8章 7章はパ","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第8章"},{"contents":"Rustで言語処理100本ノックのリファクタリングの続き。\n前回はこちら。\nコードも載せたほうが見やすいかなぁ?\n03. 円周率 2年前はこちら。 どちらかというとJavaっぽい書き方かな? 入れ物を用意して、入力を整形して、それからループを回す感じで書いてました。\n今回は1行で収めてみました。 Rustっぽく、returnを省略してみました。 あとは、Iteratorを組み合わせる感じでやってます。 アルファベットの文字数ということで、is_alphabetic()メソッドでfilterしてます。\n04. 元素記号 2年前はこちら。 エラー処理が多いのと、文字の扱いがちょっと\nここまで同様に極力イテレータを利用するという方針でリファクタリングしました。 あとは、エラー処理を除去してます。 正常系だけのテストなのでスッキリさせました。\nこういった、ストリーム系?の書き方の場合にエラー処理をどう入れるかってところはちょっと悩みどころになるんじゃないかなぁ?と思いつつ、イレギュラーなものは後回しで(あとにやるのかなぁ?)\n05. n-gram 2年前はこちら。 これまでと同じく、入れ物を作ってから処理をしてます。\n同じく、極力イテレータを利用する形で実装しました。 いくつか型の変換が必要なので、.map()を呼び出して詰め替えたりしています。\n06. 集合 2年前はこちら。 独自に実装しています。\nせっかく05で文字n-gramの配列を返す処理を実装しているので、 そちらを呼び出して、Setに入れるという処理に書き換えました。 その後の集合に対する処理については特にリファクタリングしてないです。\nまとめ 2年前にやってたところまでは追いつきました。 07は特にリファクタリングする必要がないので、次は08からの予定です。\nリファクタリングしているときになるのは、速度とかでしょうか。 実装の違いでなにか差が出るのかどうかはちょっと気になるところですが、 今回の目的ではないので、目をつぶって進める予定です。\n","date":1586423695,"dir":"post/2020/","id":"9a687babb0f44db51dc389b75bdaa19d","lang":"ja","lastmod":1586423695,"permalink":"https://blog.johtani.info/blog/2020/04/09/reboot-nlp100-ch01-03to05/","publishdate":"2020-04-09T18:14:55+09:00","summary":"Rustで言語処理100本ノックのリファクタリングの続き。 前回はこちら。 コードも載せたほうが見やすいかなぁ? 03. 円周率 2年前はこちら。 どちらか","tags":["Rust","nlp100"],"title":"第1章の03から06まで(言語処理100本ノック2020)"},{"contents":"今回もツイートから。\n言語処理100本ノックの2020年版を公開しました。最近の自然言語処理の研究動向を反映し、深層ニューラルネットワークに関する問題を追加しました。留学生も一緒に取り組めるように多言語化を進め、その第1弾として英訳を部分公開しています(40番以降は順次公開予定)。 https://t.co/52h362PIQQ\n\u0026mdash; Naoaki Okazaki (@chokkanorg) April 6, 2020 言語処理100本ノックが2020年版になったそうです。 そうです、2年前に初めて、準備運動で止まっていたんです!(衝撃的な続かなさ。。。)\nということで、Rust the bookも読んでいることだし、過去のプログラムをチェックしつつ再開しようかなと。 ということで、いくつかリファクタリングしてみました。\nソースはリポジトリを御覧ください。\n00. 文字列の逆順 2年前の実装では、chars()メソッドで取り出したあとに、collect()でVecにしていたのですが、RustのIteratorトレイトにrev()という便利なメソッドが存在していました。\nということで、これを取り出すと、最初の文字列の逆順で文字を取り出すIteratorが取得できます。 あとは、Stringが実装してくれているfrom_iterに渡せば文字列が出来上がります。\n01. 「パタトクカシーー」 ストリーム処理っぽい書き方に変更しました。 2年前はIteratorを取り出して、詰替していましたが、 enumerate()で添字と文字のタプルのイテレータに変換し、 filterで添字が偶数のときだけフィルタリングして、 mapで対象の文字をまとめたイテレータにします。 で、最後はそれを元に文字列を生成することにしました。 iterを使わないでそのままString::from_iterの引数に渡すことも可能ですね。\n02. 「パトカー」+「タクシー」=「パタトクカシーー」 2年前は2つのIteratorをloopで回して頑張って結合してました。 ではなく、zip()を使って、2つのイテレータを組み合わせる方法に替えてみました。 このとき、2つの文字列が違う文字数の場合の処理として、長い方から取り出した文字をあとに結合する処理を追加で記述しました。 ちょっとスマートな感じになりましたかね?\nzipしたあとに出てきたタプルの文字列を結合するのにformat!マクロを使いましたが、他にいい方法有るかなぁ?\nまとめ とりあえず最初の3つをリファクタリングしてみました。 残りもやりつつ、準備運動以降もがんばるぞと。\n","date":1586338425,"dir":"post/2020/","id":"dc9580308938069159c5afc55b2f3b96","lang":"ja","lastmod":1586338425,"permalink":"https://blog.johtani.info/blog/2020/04/08/reboot-nlp10-with-rust/","publishdate":"2020-04-08T18:33:45+09:00","summary":"今回もツイートから。 言語処理100本ノックの2020年版を公開しました。最近の自然言語処理の研究動向を反映し、深層ニューラルネットワークに関","tags":["Rust","nlp100"],"title":"言語処理100本ノック、再び"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 第6章 Enumです。match式に大活躍\nEnumを定義する 列挙型は取りうる値をすべて列挙できる。これが名前の由来 列挙型と列挙子 2連コロン(::)で列挙子を指定可能 列挙子にデータ(構造体も)が格納可能。 標準ライブラリに実装例あり。 疑問:Write(String)とかはタプルの表現になるのかな? と思ったが、タプルでは1つだけの変数を持つものは定義(正確には定義できるが、内部で普通の変数にもどされてるっぽい)できなかった。 メソッド定義も可能 関連関数もできる? -\u0026gt; できる Optionの紹介 Rustにnullはない。代わりにOptionがある Noneを指定する場合に型が必要。Someの場合はすでに値が入るから推測可能なため。 match制御フロー演算子 アーム -\u0026gt; matchしたときの処理のこと 短い場合は波括弧は不要 returnなしでmatchが書いてあるだけだと、慣れない場合に値を返していることに気づかないかも(実際気づけてないかも) Enumが値を持っているときに、値の束縛がmatch式で可能 すべての列挙子を網羅していないことをコンパイラが検知してくれるのはすごく助かる。 ただし、_を利用していなければだけど if letで簡潔な制御フロー enumで1つのパターンのときに処理をしたい場合に使えるmatchの糖衣構文 elseもかけるよ。 まとめ enumに慣れていないので、値や構造体を持つenumを利用するという想像ができないことがありそうだなぁと読みながら思いました。 それになれると、色々とプログラムがシンプルに書ける部分が多くなりそうかな。\n","date":1586255231,"dir":"post/2020/","id":"4fbdc9c57a37781dc5dd86f470c61d04","lang":"ja","lastmod":1586255231,"permalink":"https://blog.johtani.info/blog/2020/04/07/chap6-rust-the-book/","publishdate":"2020-04-07T19:27:11+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた Rust the book - 第4章 Rust the book - 第5章 第6章 Enumです。matc","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第6章"},{"contents":"Kuromoji-CLIの使い方などについては過去のブログを御覧ください。\nKuromojiのCLIコマンドとpicocliとGraalVM GitHubリポジトリ Issueだけ上げていたJSON出力対応をしました。 また、ラティス(後述)の出力対応もしました。\nJSON出力 LinderaがJSON出力に対応してるのでそれを真似しました。 -o jsonで指定していただくと、次のようなJSONが出力されます。\n% echo \u0026#34;春眠暁を覚えず\u0026#34; | build/graal/kuromoji -o json [ { \u0026#34;text\u0026#34;: \u0026#34;春眠\u0026#34;, \u0026#34;detail\u0026#34;: [ \u0026#34;名詞\u0026#34;, \u0026#34;一般\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;春眠\u0026#34;, \u0026#34;シュンミン\u0026#34;, \u0026#34;シュンミン\u0026#34; ] }, { \u0026#34;text\u0026#34;: \u0026#34;暁\u0026#34;, \u0026#34;detail\u0026#34;: [ \u0026#34;名詞\u0026#34;, \u0026#34;一般\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;暁\u0026#34;, \u0026#34;アカツキ\u0026#34;, \u0026#34;アカツキ\u0026#34; ] }, { \u0026#34;text\u0026#34;: \u0026#34;を\u0026#34;, \u0026#34;detail\u0026#34;: [ \u0026#34;助詞\u0026#34;, \u0026#34;格助詞\u0026#34;, \u0026#34;一般\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;を\u0026#34;, \u0026#34;ヲ\u0026#34;, \u0026#34;ヲ\u0026#34; ] }, { \u0026#34;text\u0026#34;: \u0026#34;覚え\u0026#34;, \u0026#34;detail\u0026#34;: [ \u0026#34;動詞\u0026#34;, \u0026#34;自立\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;一段\u0026#34;, \u0026#34;未然形\u0026#34;, \u0026#34;覚える\u0026#34;, \u0026#34;オボエ\u0026#34;, \u0026#34;オボエ\u0026#34; ] }, { \u0026#34;text\u0026#34;: \u0026#34;ず\u0026#34;, \u0026#34;detail\u0026#34;: [ \u0026#34;助動詞\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;*\u0026#34;, \u0026#34;特殊・ヌ\u0026#34;, \u0026#34;連用ニ接続\u0026#34;, \u0026#34;ぬ\u0026#34;, \u0026#34;ズ\u0026#34;, \u0026#34;ズ\u0026#34; ] } ] Viterbiラティス出力 Kuromojiが内部でトークンをどのように切り出すかを計算するためのViterbiのラティスです。これをGraphvizというツールのDOTフォーマットのファイルとして出力できるメソッドがデバッグ用ですが、Kuromojiに用意されています。 こちらを呼び出して出力するオプション-v(もしくは--viterbi)を追加しました。 注意点として、このオプションを指定すると、DOTファイルが標準出力に出力され、トークンの結果は標準エラーに出力されます。\necho \u0026#34;春眠暁を覚えず\u0026#34; | build/graal/kuromoji -v \u0026gt; viterbi.dot .dotファイル自体は画像ではないので、Graphvizのdotコマンドにて画像ファイルに変換する必要があります。\ndot -Tpng viterbi.dot -oviterbi.png これで、PNGファイルが出来上がります。出来上がったファイルはこんな感じです。\n画像を見ていただくと、緑色のパスがあるのがわかります。 こちらが、Kuromojiが実際に採用した形態素のリストです。それ以外のパスは不採用だったパスとなります。\nちなみに、macOSで1行で画像表示まで行うにはこんな感じで実行します。 openコマンドでpreviewアプリを指定することで画像が表示できます。 Windowsは。。。わかりません、すみません。\n% echo \u0026#34;春眠暁を覚えず\u0026#34; | build/graal/kuromoji -v -o json | dot -Tpng | open -f -a preview.app まとめ これ以前に複数辞書対応などもしていました。 今回は2つの出力形式を追加してみました。 特にViterbiラティス出力については、内部的にどのようなコスト計算で最終的な結果が出てきているかという理解に役立ちます。想定していない切れ方の場合は、そもそも想定している形態素になっていないか、コスト計算で不採用だったかなどを確認できますので、使ってみると面白いかもです。\n","date":1586143600,"dir":"post/2020/","id":"6fbf7c3d0f4f89e415e89cec28811a94","lang":"ja","lastmod":1586143600,"permalink":"https://blog.johtani.info/blog/2020/04/06/update-kuromoji-cli/","publishdate":"2020-04-06T12:26:40+09:00","summary":"Kuromoji-CLIの使い方などについては過去のブログを御覧ください。 KuromojiのCLIコマンドとpicocliとGraalVM G","tags":["misc"],"title":"KuromojiのCLIコマンドにJSON出力とラティス出力を追加"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた Rust the book - 第4章 第5章 構造体です。勝手知ったるなんとやら?オブジェクト指向的な部分は問題ないかなぁと。\n定義とインスタンス化 structで定義 インスタンスの生成は引数は順不同でOK 構造体のインスタンスを可変にするとフィールドの値も変更可能 特定のフィールドのみ可変にすることは不可能 インスタンス化する関数の最後でreturnなしでインスタンスの返却を暗黙にできる(return書いてほしいな。。。) インスタンス化時にフィールド初期化省略記法が可能(これはちょっと便利?) 構造体更新記法..user1のように、明示的に設定されていない他のフィールドをコピーしてくれる機能あり タプル構造体 タプル構造体!? struct Color(i32, i32, i32); いつ使うんだろう? ユニット様構造体 ユニット様構造体 = フィールドのない構造体。トレイトを実装したいけどインスタンスで持つ値はない場合に利用 ライフタイム 構造体が参照を持つときにライフタイムという話が出てくる。なるほど。 ライフタイム指定子が必要になる -\u0026gt; 10章での話 プログラム例 タプルを引数かぁ。タプルは慣れないので構造体作りそう Debugトレイトと{:?}という書き方 derive(Debug)でデバッグ用のトレイトを自動で実装=継承してくれる {:#?}だとpretty printになる(改行とか入る) この辺の便利なトレイとは付録Cにあるらしい。この辺はやりながら覚えるしかないか。\nメソッド記法 最初の引数は必ずself implは構造体とは別の場所に書く = Javaのクラスとは違う struct Rectangle { width: u32, height: u32, } impl Rectangle { fn area(\u0026amp;self) -\u0026gt; u32 { self.width * self.height } } 参照じゃないselfも使えるらしい。どういうときに使うんだろう? 関連関数 selfなしの関数をimplにかける。Javaのスタティックメソッドみたいな感じ その他 implブロックがあちこちにかける。これはつらいな。。。 2つにわかれたimplブロックに同じメソッドを書いてみたら、CLionのプラグインではエラーを検知してもらえなかった。 cargo buildではきちんとエラーが表示された。 複数のimplブロックが有用になるケースは第10章で見ますが、そこではジェネリック型と、トレイトについて議論します。\n人の構造体に自分のトレイトを適用したりもできる。 実験 スコープとかどうなりそう?って実験もしてみた。\nfn main() { trait Hoge { fn trim(\u0026amp;self); } impl Hoge for String { fn trim(\u0026amp;self) { println!(\u0026#34;hogehoge {}\u0026#34;, \u0026amp;self); } } let c = String::from(\u0026#34;hoge\u0026#34;); c.trim(); println!(\u0026#34;{}\u0026#34;, fuga(\u0026amp;c)); } fn fuga(d: \u0026amp;String) -\u0026gt; \u0026amp;str { d.trim() } 出力はこんな感じ\nhogehoge hoge hoge まとめ 気になったのは以下の点。そのうち分かるようになってくるのかな。\n構造体更新記法はどういったときに使うのを想定して作ったんだろう?とか 可変長引数はマクロじゃないとだめ ","date":1585807758,"dir":"post/2020/","id":"8d9c3760395e8e0eb40e335b22750b68","lang":"ja","lastmod":1585807758,"permalink":"https://blog.johtani.info/blog/2020/04/02/chap5-rust-the-book/","publishdate":"2020-04-02T15:09:18+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた Rust the book - 第4章 第5章 構造体です。勝手知ったるなんとやら?","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第5章"},{"contents":"すもけさんが在宅勤務環境をブログに書いてておもしろそうだな(あと、アフィリンク貼れるな)と思ったので自分の環境も書いてみようかなと。\n私自身は昨今の新型コロナウイルスの影響というのではなく、もう10年以上自宅でも作業ができる環境を整えています。 前前職の頃から家でも仕事をすることがよくあったので。今は、お客さんに恵まれていてリモートができる形で働かせていただいてます。\n机周りはこんな感じです。机はこれも15年以上前から使用しているエレクターの机です。椅子も15年以上前から使っているアーロンチェア(購入時は高いと思ったけど、これだけ使えているので大満足)です。\nメインのPCはMac Book Pro16インチを使っています。それとは別にMac miniがMac bookの後ろに隠れています。こっちはブラウジングや音楽を聞いたりするために使っています。\nまずはディスプレイ周りから。\nディスプレイ周り ディスプレイ Acerの31インチディスプレイです。昨年の夏に購入しました。28インチの4Kディスプレイを探していたのですが、セールか何かで2-3000円の違いでこのサイズが買えたので、このサイズになっちゃいました。Mac Book ProはDisplay port-USB-Cケーブルで接続し、PS4をHDMIで接続しています。 【Amazon.co.jp 限定】Acer モニター ディスプレイ ET322QKwmiipx 31.5インチ マイクの左側に写っているのはAppleのサンダーボルトディスプレイです。縦にしてブラウザやミュージックプレイヤーなどで音楽かけながら仕事をしています。 サブディスプレイって感じです。 Mac Book ProとMac miniの両方を操作するのですが、できれば同じキーボード+トラックパッドがいいなということで、Synergyというソフトを使って、Mac Book Proのキーボードとマウスでネットワーク越しにMac miniを操作しています。ただ、マシンの再起動後などにこのソフトが起動していない場合もあるので、Mac Book Proの右側にMac miniのためのトラックパッドがおいてあります。\nディスプレイアーム ディスプレイはそれぞれディスプレイアームを使っています。写真のようにMac Book Proを下に、外部ディスプレイを上にという上下で作業をしています。 16インチの画面だと普通のディスプレイの足だとメインディスプレイにかぶってしまうので、アームに切り替えました。 最初はグリーンハウスの激安を使っていたのですが、31インチのディスプレイだとアームの高さが足りなかったので、2つ目のガススプリング式のアームを追加で購入しました。ガススプリング式なのに5千円しないので、かなりお得感があります。ただ、ディスプレイは基本的に動かさないので、どちらかというとディスプレイの足の部分を効率良く使うことが目的です。\nAmazon | グリーンハウス 液晶ディスプレイアーム 4軸 クランプ式 Amazon | HUANUO PC モニター アーム 液晶ディスプレイ アーム ガススプリング式 サウンド関連 スピーカー 基本、音楽を聞きながら作業をするので、小型だけどしっかりと音がでるスピーカーを買いました。スタイルもいいし気に入ってます。 入力が2系統あるので、31インチディスプレイのヘッドフォン出力とMac miniのからの出力の2つをつないでいます。 仕事中はMac miniで音楽流しつつ、テレカンやゲームのときはメインディスプレイからの音が出る形です。 Amazon | ヤマハ パワードスピーカー NX-50 マイク 前職がDeveloper Advocateということで、インタビューなどに行くこともあるかも?ということで小さめのも運びができるコンデンサマイクを購入してました。結局それほど持ち運びはしてないのですが、値段の割には音がいいんじゃないかな?一応、無指向と単一指向の2種類を切り替えることが可能です。\nAmazon | SAMSON マイク ポータブル USB コンデンサ Go Mic | コンデンサ | 楽器 マイクスタンド マイクはあったのですが、クリップ式でした。PCのディスプレイにクリップしていると、打鍵音を拾ってしまうので、マイクスタンドを最近導入しました。やすかったです。 前まではヘッドフォンのケーブルに付いているマイクで喋っていたのですが、服によってはマイクに擦れてしまい、ノイズが載っていました。 マイクスタンド+スピーカーでもスピーカーの音をマイクが拾わないので、最近はヘッドフォンを使用しないで気楽に話ができるようになっています。 Amazon | Luling Arts マイクスタンド アーム その他 モニタスタンド Mac Book Proの後ろで見えにくいですが、Mac miniが下に入っていて、上にMac mini用のキーボード、スピーカー、Qiの充電パッドが載せてあります。 Mac miniのキーボードをじゃまにならないように置きたいという目的で購入しました。3次元で空間が利用できるので結構重宝してます。 Amazon | サンワサプライ 机上液晶モニタスタンド(D200・黒) MR-LC303BK 充電関連 スマホ充電用にスピーカーの横においてあります。ただ、スイートスポットを探すのがちょっと大変で、時々充電できてないことがあったりします。。。 Amazon | DesertWest Qi 急速充電ワイヤレス充電器 【Qi認証済み/PSEマーク付き】15W USBでの様々な充電用にはMercariさんのカンファレンスでいただいたAnkerの充電器をおいてあります。Mi Band 4、キーボードなどの充電向けです。 Amazon | Anker PowerPort 6(60W 6ポート USB急速充電器) まとめ 簡単ですが作業環境でした。だいたい満足しています。もうちょっと改善したいなと思っているのは次の点です。\nUSB-Cドック?ハブ?みたいなものがほしい 充電ケーブル、マイク、ディスプレイケーブル、有線LANの4つのケーブルがMac Book Proに刺さっており、ポートが全滅です。出先から帰ったときにつなぐのも少し面倒なので、1つか2つのポートでまとめられるといいなぁと思っています。が、ドック系はいい値段するのでまだ置き換わっていない感じです。 スタンディングデスクが気になる 自宅でずっと座っているのはやはり気になるもので。スタンディングデスクにして時々たって作業したいなぁと思うことがあります。ただ、使ったことがないので、どれがいいのかわからず手を出せない状況です。 ウェブカメラいる? Mac Book Proのカメラでオンラインミーティングなどしています。気にするほどのことではないとは思いますが、メインディスプレイを見ながらしゃべると下からカメラで撮影されている形になります。。。 今のところはこんな形です。なにかの参考になればと。 あと、なにかおすすめのもの(特にスタンディングデスク)があれば教えて下さい!\n","date":1585217511,"dir":"post/2020/","id":"3f431bf71ee866f626daf42bc915fa3f","lang":"ja","lastmod":1585217511,"permalink":"https://blog.johtani.info/blog/2020/03/26/working-facility/","publishdate":"2020-03-26T19:11:51+09:00","summary":"すもけさんが在宅勤務環境をブログに書いてておもしろそうだな(あと、アフィリンク貼れるな)と思ったので自分の環境も書いてみようかなと。 私自身は","tags":["misc"],"title":"自宅の作業環境(2020)"},{"contents":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。\nRust the Bookを読み始めた 第4章 第4章です。たぶん、これがいちばん大事な概念だと思います、Rustの。 そして、つまみ食いしながらRust書いてましたが、ここがきちんと理解できないまま書いてたってのもあります。。。\n所有権とは? drop関数ってのがあって、明示的に呼ぶことも可能。次のような感じで。2つ目のprintln!はエラーになる。sがもう無いのに借用しようとしてるから。 fn main() { let mut s = String::from(\u0026#34;hello\u0026#34;); s.push_str(\u0026#34;, world!\u0026#34;); println!(\u0026#34;{}\u0026#34;, s); drop(s); println!(\u0026#34;{}\u0026#34;, s); } ムーブ - shallow copyではない。以下の2行目がムーブ。 let s1 = String::from(\u0026#34;hello\u0026#34;); let s2 = s1; println!(\u0026#34;{}, world!\u0026#34;, s1); スタックとヒープの話が絡んでくる。あんまり意識すること無いよなぁ。 スタック = 固定長のデータを入れる場所。ポインタ、数値など ヒープ = 可変長のデータが入る場所。可変の文字列とか。\nクローン - ヒープのデータをコピーすること。 コピー - スタックに収まるデータの場合はクローンが必要なくコピーで事足りる。 CopyトレイととDropトレイとは同居できない。 タプルのコピーはややこしそう 所有権と関数でまた、スタックに入れられるような変数と可変のオブジェクトの違いが出てくる。 takes_ownership(s: String)が参照を受け取れば問題なく、このあとも使える。 戻り値でもムーブが発生 参照と借用 借用 - 関数の引数に参照を取ること 可変な参照\u0026amp;mutは1つ(不変な参照も含めて1つ)しか許さない データの競合を防ぐため。 不変な参照を複数用いるのはOK 実際に変更が実行されるタイミングでエラーと判定される場合もある。 let mut s = String::from(\u0026#34;hello\u0026#34;); { let r1 = \u0026amp;mut s; } // r1はここでスコープを抜けるので、問題なく新しい参照を作ることができる let r2 = \u0026amp;mut s; ダングリング参照はテスト書くときとかにやってるかも。。。 fn dangle() -\u0026gt; \u0026amp;String { // dangleはStringへの参照を返す let s = String::from(\u0026#34;hello\u0026#34;); // sは新しいString \u0026amp;s // String sへの参照を返す } // ここで、sはスコープを抜け、ドロップされる。そのメモリは消される。 // 危険だ スライス型 部分的な参照。開始位置+長さで構成されているっぽい \u0026amp;strの説明がよくわからなかった。 引数としての文字列スライスのテクニックは色々と使いまわせそう。\nまとめ 所有権、これまで特に難しいと思ってたのは、固定長の変数と、可変長の変数の違いを意識してなかったのが原因っぽい。 まぁ、Vecとかがどうなるのかとか、他にもいくつか気になるところはあるので、もうちょっとやらないといけないなと思いました。\n","date":1585210331,"dir":"post/2020/","id":"7fded0345c258eea966c0b5ee1b7c7aa","lang":"ja","lastmod":1585210331,"permalink":"https://blog.johtani.info/blog/2020/03/26/chap4-rust-the-book/","publishdate":"2020-03-26T17:12:11+09:00","summary":"前回の記事はこちら。自分用のメモなので、読みにくいかもです。 Rust the Bookを読み始めた 第4章 第4章です。たぶん、これがいちばん大事な概念だと思","tags":["rust","読書","rust-the-book"],"title":"Rust the book - 第4章"},{"contents":"先日、Visual Studio Codeのプラグインを作ってみた(Azure Search Analyze Client)というブログを書きました。 このプラグインを作ってたタイミングで、Elasticの河村さん経由で、Microsoft Open Tech Night #9 w/ ElasticでなにかLTしませんか?という打診がありました。\n仕組み的には似たようなものだし、Elasticsearch用の拡張機能も作れるし、発表のネタにもなるし一石二鳥では?ということで、LTを快諾し、昨日発表してきました。\n資料とか 発表資料やGitHubのリポジトリなどは、以下のとおりです。\n発表資料 : Analyze APIのVS Codeプラグインを作ってみた GitHub Repository : https://github.com/johtani/vs-code-es-analyze-client Visual Studio Code Marketplaceページ 機能 まだ、必要最低限の機能を実装した感じです。\nAnalyze APIのパラメータ入力用のエディタ起動(Elasticsearch Analyze Client: Create Elasticsearch Analyze Request) Esにリクエストを送信して結果の表示 インストールからリクエスト送信して結果が出てくるまでのデモです。\n1点LTのデモのときに話すのを忘れていましたが、.esanalyzeという拡張子のファイルであれば、このプラグインが入力値を見つけ出して、「Analyze text with analyzers」というコマンド送信用のリンクをエディタ画面に表示する機能があります。 ですので、パラメータ入力用のエディタを起動し、値を設定したあとにファイルをhoge.esanalyzeというような名前で保存してもらえれば、後日そのファイルを開くことでリクエストが再送できます。\nAzure Search版との機能の違い 先日のAzure Search向けのクライアントとの違いがいくつかあります。 ElasticsearchのAnalyze APIの方が多機能であるため、プラグインとしても違いがあったほうがいいかなと。\n入力がJSON形式 結果画面に詳細表示切り替えボタンを追加 現時点では対応していませんが、Analyze APIはカスタムのtokenizer、filter、char_filterの設定を入力として受け付けることが可能です。そのときに指定するのはJSON形式でtokenizerなどの設定を記述します。 今後、これらの対応をすることを考えると、入力全体をJSON形式で読み込めるほうがわかりやすいかなということで、入力はJSON形式で入力してもらうことを想定しました。\n結果画面に詳細表示切り替えボタンを追加したのは、2つの理由があります。1つはAzure SearchのAnalyze APIよりもTokenの情報としていくつか他の情報も存在するためです。複数のAnalyzerとの比較をする場合は、単語列だけを比較したいですが、Analyzer個別の詳細情報を見たい場合もあるので、切り替えができたほうがよいかなと。 2つ目の理由はまだ実装していませんが、explainパラメータの出力への対応のためです。 explainパラメータを指定すると、カスタムAnalyzerの場合に、Analyzerの設定にあるchar_filter、tokenizer、token_filterのそれぞれのステップでの単語列の出力が結果として返ってきます。この結果には標準の出力よりもさらに多くのtokenの情報(例えば、kuromojiだと品詞情報、読み、原型など)が追加されてきます。これらの表示を切り替えることができたほうがよいかと。\nこれらは、実はKibanaのプラグインとしてすでに実装済みになっています。 同等の機能は実装できるかなという目論見もあり、そちらに合わせた感じにしてあります。\n今後の対応 現時点では、Analyzer名の指定のみが可能となっています。Kibanaのプラグインと同程度の機能はGitHubのIssueとして登録してみました。\nexplainパラメータ対応 fieldパラメータ対応 custom analyzer対応 その他に、インデックス名やアナライザ名の自動補完みたいな機能があると便利かも?と妄想していたりします(実装が大変かもですが。。。)。Kibanaのプラグインの場合は、Mappingやインデックス名を調べるときに、KibanaのConsoleからチェックすればよかったのですが、このプラグイン単体だとそのあたりの情報の取得に他のツール(Kibanaだったり、REST API Clientだったり)を使わないといけないという問題点はあるかなぁと。\nあとは、結果画面がこのままで本当に見やすいかどうか?なども気になってはいます。\nまとめ まだまだ、作ってみたというレベルのプラグインです。 どのくらいの人に使ってもらえるかもわかりませんが、こんな機能あるといい?など要望があればリクエストいただければと。 Twitterで聞いていただいてもいいですし、GitHubのIssueとして登録していただいても構いません。 そもそもいらないなぁなんて意見でももちろん大歓迎です。フィードバックお待ちしてます!\n","date":1585102205,"dir":"post/2020/","id":"a7f0e85fcad4f5bc5ae5c18c10de4f9e","lang":"ja","lastmod":1585102205,"permalink":"https://blog.johtani.info/blog/2020/03/25/vsc-es-analzye-plugin/","publishdate":"2020-03-25T11:10:05+09:00","summary":"先日、Visual Studio Codeのプラグインを作ってみた(Azure Search Analyze Client)というブログを書きました。 このプラグインを作ってたタイミン","tags":["elasticsearch","visual studio code"],"title":"ElasticsearchのAnalyze APIのVisual Studio Codeのクライアントプラグイン"},{"contents":"自転車本を読み始めましたが、その前にRust the bookを読んだほうが良いかも?と知り合いと話をしていてなったので、先にRust the bookを読み始めてます。 コツコツ読むってのが苦手なので、知り合いと小規模オンライン読書会しながら読むことになりました(基本的になにか書きながら、使い方を調べるので、存在そのものを知らない記述や使用法などがあったりする)。\n日本語版Rust the book Rust the book 基本は日本語版を読んでいます。まずは1章から3章あたり。\n気になった点などを。自分用のメモなので、読みやすさとかは考えてないです(あとで自分が死ぬパターン?)。\n1章 rustfmt便利。\nCLionのRustプラグインでは、保存時にrustfmtするというオプションがある。デフォルトはオフ。\u0026ldquo;Run rustfmt on Save\u0026rdquo; cargoの--binオプション。意識してつけたことなかった=デフォルトだった。\nライブラリにするときは--lib 2章 「変数を値に束縛」という言い回しにまだ慣れない。 「代入」という言い方に慣れているから? ただ、エラーにはassignってあるな。\u0026ldquo;error[E0384]: cannot assign twice to immutable variable x\u0026rdquo; preludeというのがデフォルトで読み込まれる型が存在する場所。 .expect()により、Resultが評価済みになる マクロがまだ慣れない extern crate rand;が最新版だと要らなくなっている。 rand::Rngはgen_rangeのためにuseしている。CLionだとかってにuseを推測して追加してくれた。 matchはswitch文みたいな感じ。けど、defaultが必ず実行されるって感じではないな。 ただし、全て網羅しないと怒られるのが便利。 アームという呼び方が新鮮 単一の式のときは{}が省略できる ブロック{}のときは、終わりにカンマを入力するとrustfmtが除去する(最後の条件かどうかは関係ない)。 シャドーイングは面白い。 よく、hoge_strやhoge_intのような変数を書くので、ありがたい。 ただし、コードを読むときに少し混乱しそう? let ... matchで変数への束縛でmatchが使えるのは便利(これまで知らなかったので、変数宣言して条件つけて束縛する処理書いてた)。 シャドーイング? fn main() { let x = 5; let x = x + 1; let x = x * 2; println!(\u0026#34;The value of x is: {}\u0026#34;, x); } とか\nlet spaces = \u0026#34; \u0026#34;; let spaces = spaces.len(); みたいに、同一変数名を使い回せること。再代入ではない\n3章 constは型注釈が必須 100_000のような記述が便利(Javaもできるって言われてびっくりしたw) タプルの中身を一部だけ書き換え可能。(mutを指定すれば) tup.0 = 20;のような感じで。 配列は固定長でかつ、同一の型のものだけが入る 文末にセミコロンがない場合に四季になるというのはちょっと射にくいので辛いのでは。。。 自分は明示的にreturnを書きたくなる。が、returnだと動かない場合もある。。。 let ... ifのような記述もできる。 (1..4)はRange型 おまけ フィボナッチ数列計算してみろというのがまとめにあったので。こんな感じでいいのかな?\nfn calc_fibonacci(n: usize) -\u0026gt; usize { if n == 0 { return 0; } else if n==1 { return 1; } else { return calc_fibonacci(n-1) + calc_fibonacci(n-2); } } その他 知り合いと読みすすめると、人が不思議に思ったところが、自分が理解が曖昧だったことなどに気づけて便利です。\n","date":1584928642,"dir":"post/2020/","id":"48b5ab9805919736382ffea5a9554c02","lang":"ja","lastmod":1584928642,"permalink":"https://blog.johtani.info/blog/2020/03/23/start-reading-rust-the-book/","publishdate":"2020-03-23T10:57:22+09:00","summary":"自転車本を読み始めましたが、その前にRust the bookを読んだほうが良いかも?と知り合いと話をしていてなったので、先にRust the bookを読","tags":["rust","読書","rust-the-book"],"title":"Rust the Bookを読み始めた"},{"contents":"動機 Azure Cognitive Searchを検索エンジンに使っているお客さんを手伝っています。 そこで、検索の基本的な話をさせていただきました(もともとJJUGナイトセミナーでしゃべる予定だったスライドがベース)。\nで、Elasticsearchなどの転置インデックスを利用している検索エンジンで検索の基本的な動作がどうなっているかを理解するのに、 個人的には一番重要だと思っているのがAnalysis(Analyze)の機能です。 転置インデックスの単語の切り出し方がどうなっているかによって、望んだ単語でうまく検索できているかいないかなどがわかります。\nAzure Cognitive SearchもAnalyze TextというAPIを提供してくれています(内部的にはElasticsearchだし)。 APIはあるのですが、返ってくる結果はJSONです。また、他のAnalyzerの設定との違いなどをみたくなったりもします。 やはり、普段使っているツールなどで簡単にどういう単語が出てくるかがわかるとうれしんじゃないかなぁ?と。\nということで、最初はPythonでちょっとAPI呼び出して、カンマ区切りで出力するものを作ってみたのですが、GUIとかあると便利かなぁという話になりました。 最近、ブログ書いたりするのにVisual Studio Codeを使い始めているので、これなら使いやすいかなと。 ということで、Visual Studio Codeの拡張機能(プラグイン?)としてインストールできるツールを作ってみました。 Azure Cognitive Searchを使っている人向けなので、ニッチなツールですが。。。\n余談 Elastic Stack(Elasticsearch)向けにはKibanaのプラグインでAnalyze APIを可視化するツールを作ってます。 analyze-api-ui-pluginです。Elastic Stack、特にKibanaを必ず利用する方はこちらを使うと便利かもです。\n概要と機能 GitHub リポジトリ Visual Studio Marketplaceのページ Marketplaceに公開しているので、johtaniやAzure Search Analyze Clientなどで検索してもらえれば出てきてインストールができます。\n機能としては、以下の2つです。\nテンプレートから入力値設定用のドキュメントを作成(Untitled-1というドキュメントをエディタに新しく開く) Azure Cognitive SearchのAnalyze Text APIを呼び出して、結果をHTMLのテーブル形式で表示 入力値設定用のドキュメント作成 APIの呼び出しに必要な情報を記入してもらうのに、いくつか案を考えました。\nプラグインの設定に記入してもらう 環境変数とかを読み出す テキストとして保存したファイルを使う 設定や環境変数だと、異なる環境に接続したりするときに、わざわざ設定し直すのがめんどくさいかもと。 で、愛用していたREST API Clientを真似するのが良いかもという結論になり、.analyzeという拡張子のファイルから必要な項目を読み出して、APIを呼び出す形にしてあります。\nCommand Palette(左下の歯車マークもしくは、メニューのViewから開ける)からAzure Search Analyze Client: Create Azure Search Analyze Requestというコマンドを選びます。\nすると、以下のようなファイルがエディタに開きます。\nこれらの項目をまずは埋めていきます。 それぞれの値がどういったものかはGitHubのREADMEを御覧ください。\n入力値エラー(存在チェックしかしていない)がある場合は、ダイアログが表示されます。\n結果表示 値を入力したら、設定値と###の間に表示されているAnalyze text with analyzersというグレーの文字をクリックします。すると、APIにリクエストを送信し、結果が返ってきて、別のパネルとして表示されます。\n複数のAnalyzerを入力値に設定すると、それぞれがどのような区切り方をするかがわかります。 文字の下にある[0:2]は、その単語がもとの文章の何文字目から何文字目までに出現しているかというオフセットの表示になります。\nもし、Analyzer名の設定ミスなどで指定されたAnalyzerがない場合は、結果画面にエラーが表示されるようにしています。\n以上が簡単な機能の説明です。 簡単なと言いつつ、これだけしか機能がありませんが。\nVisual Studio Codeのプラグインの作り方 プラグイン自体の作り方に関してはVisual Studio CodeのGetting Startedがわかりやすかったです。 APIや機能が豊富なので、最初はちょっと戸惑いましたが、サンプルもGitHubで多数公開されています。\nあとは、REST API Clientを参考にさせていただきました。\nGetting Startedを一通り読むことで、なんとなくプラグインの作成からMarketplaceへのリリースまでが完了できました。 (TypeScriptに慣れていないのがあるので、プログラミング自体は手間取りましたが。。。)\n今後の対応? いまのところ、こんなところを考えていますが、こんな機能がほしい、バグが有るなどあれば、GitHubにIssueを上げていただければと(使う人すくないだろうけど)。\nいろいろなエラーに関する対応 Readmeに画像をアップ アイコン作成? 自動補完機能? まとめ Visual Studio Codeの拡張機能を作ってみました。 Yeomanによるプロジェクトテンプレートが用意されているので、とりあえず、Hello worldを作るのは簡単でした。 試行錯誤しつつTypeScriptを書いたので、TypeScriptっぽくないところなどもあるかもですが、誰かの役に立つツールになってくれれば良いなぁと。\n","date":1584582615,"dir":"post/2020/","id":"c9d257aba54475c20b3737ce7c779e55","lang":"ja","lastmod":1584582615,"permalink":"https://blog.johtani.info/blog/2020/03/19/azure-search-analyze-plugin/","publishdate":"2020-03-19T10:50:15+09:00","summary":"動機 Azure Cognitive Searchを検索エンジンに使っているお客さんを手伝っています。 そこで、検索の基本的な話をさせていただきました(もともとJJUGナイ","tags":["azure search","visual studio code"],"title":"Visual Studio Codeのプラグインを作ってみた(Azure Search Analyze Client)"},{"contents":"これまで\n実践Rust入門はじめました 実践Rust入門の3章を読んでるところ 3章終了 3章の終わりまで読み終えた。\nいきなり実践的なプログラムで少し面食らっていたが、ステップを追って所有権周りの話まで来たので、 なんとなくRustのいいところが理解できたような気がする。\nただ、最後のsplit_at_mutが実際には内部でどういう形に変換することによって、コンパイルエラーにならずに、 借用がうまく行っているのかあたりは、まだきちんと理解できていない。\nこれは、どの言語にも言えるんだけど、リファレンスをうまく読み解きながら、 自分がやりたい処理ができるかどうかを考えるのって結構むずかしいなぁと思う。\nbenchmark.rsはコピペして実行しただけなので、またあとで読み返してみるかな。\nということで、ここから先は、基本を勉強する感じで4章から読みつつ、なんかプログラムをまた書いてみるか。\n","date":1583140813,"dir":"post/2020/","id":"6f47cb314fd780c122adb8cc1f44f785","lang":"ja","lastmod":1583140813,"permalink":"https://blog.johtani.info/blog/2020/03/02/finish-bicycle-book-chap3/","publishdate":"2020-03-02T18:20:13+09:00","summary":"これまで 実践Rust入門はじめました 実践Rust入門の3章を読んでるところ 3章終了 3章の終わりまで読み終えた。 いきなり実践的なプログラムで少","tags":["rust","読書"],"title":"実践Rust入門の3章を読み終わった"},{"contents":"Kuromoji-CLI Rust初心者がRust製の日本語形態素解析器の開発を引き継いでみたという記事にありますが、LinderaというRust製の日本語形態素解析が出てきました。KuromojiのRustクローンみたいなものです。 で、作者の人とのチャットの中で、「MeCabみたいなKuromojiのCLIないですかね?誰か知りませんか?」という話になりました。\n自分は普段はKuromojiの確認をするのは、Elasticsearch関連もしくは、Azure Searchなどだったりするので、 当たり前のようにKibanaを立ち上げたり、REST APIを叩いてましたが、たしかにコマンドラインインタフェースあると便利かも? と思い、作ってみるかということに。\npicocli いま、JavaでかんたんなCLI作るとなったら何がおすすめ?\n\u0026mdash; Jun Ohtani (@johtani) February 26, 2020 で、いつものツイートです。で、picocliという返信がありました。 JavaでCLIのプログラムを書くのが簡単になりそうだと。 ドキュメントもしっかりしてます。サンプルも載ってるし。\nAnnotationで、コマンドの説明などパラメータ、オプションなどが記述でき、必須チェックなども可能です。\nまた、オプションの説明文に関しては、テンプレートを用いることで、取りうる値をEnumの値で出力してくれたりといった便利機能まで備わっていました。\nGraalVM また、GRAALVMとPICOCLIでJAVAのネイティブコマンドラインアプリを作ろうというスライドも教えてもらい、ネイティブコマンドまで作れるらしいと。 なんて便利なんでしょう!ってことで、こちらもチャレンジしてみました。 GraalVMがどんなものかはなんとなくは知ってたのですが、何者だろう?とツイートしたところ、これまた返信が。\nっ 資料はかなり古いので現行版と乖離はあるけど概念は変わってないので..https://t.co/KRQjhNdD9f\n\u0026mdash; たむたむ🏫 (@tamtam180) February 26, 2020 本当に、Twitter便利ですね。\nGraalVMがどんなものかもいただいた資料でサクッと理解できました。 ただ、picocliが実はものすごく良くできており、自分でインストールする必要も実はありませんでした。\ngradle-graalというGradleのプラグインと、 Picocli Code Generationを利用することで、 以下のコマンドを実行することで、ネイティブコマンドアプリが作成できました。\ngradle nativeImage build.gradleファイルに記述したのは、以下のような項目です。\npluginの利用 picocli-codegenをannotationProcessorとして呼び出し jarに関する記述(メインクラスと依存するJarを含める設定) ネイティブコマンドの名前とか(gradle-graalの設定) 辞書が読み込めなかった で、native imageを作って実行しましたが、Kuromojiが内包している辞書ファイルが読み込めませんでした。 どうやら、picocli-codegenの自動生成では対応できない、リソース関連設定が必要らしいと。\npicocli-godegenの設定を見ていて見つけたのが、other.resource.patternsというオプションでした。\nkuromoji-cliのbuild.gradleに、その設定を加えたら辞書が読み込めるようになりました。\nこの設定をどうやって書くのか?というのを探すのにちょっと時間がかかりました。Picocli作者のRemko Popmaさんのサンプルリポジトリに設定を利用したbuild.gradleがありました。サンプル本当にありがたいですね。\n完成 出来上がったのは、kuromoji-cliというリポジトリになります。 内部で利用しているのはAtilikaのKuromojiです。LuceneのKuromojiではないのでご注意を(LuceneのKuromojiで最初やってみたのですが、リフレクションなどが多用されてて、Single Imageにするのが手間がかかりそうだった)。 コマンドのポータビリティはそれほど無いと理解してる(あってる?)ので、利用してみたい方は、リポジトリをクローンしてからビルドしてみてください。\n参考資料 kuromoji Picocliドキュメント Getting Started GraalVM / GraalVM超入門 一体何モノなの? GraalVM入門編 / GraalVM for beginners まだ途中? ほかにもあると便利かも?という機能があればIssueやPRを上げてください。 とりあえず、頭にあるのは以下のとおりです。\nJSONの出力はまだ未対応 いろんな辞書をAtilikaのKuromojiはサポートしてるのでそのへんも対応してみる? ","date":1582858179,"dir":"post/2020/","id":"d710a073be2da219a388a150eb7b6b6a","lang":"ja","lastmod":1582858179,"permalink":"https://blog.johtani.info/blog/2020/02/28/kuromoji-cli/","publishdate":"2020-02-28T11:49:39+09:00","summary":"Kuromoji-CLI Rust初心者がRust製の日本語形態素解析器の開発を引き継いでみたという記事にありますが、LinderaというRust製の日本語形態素解","tags":["misc"],"title":"KuromojiのCLIコマンドとpicocliとGraalVM"},{"contents":"これまでのはこちら。読書メモなので、本と合わせて読んでいただくのが良いです。\n実践Rust入門はじめました 3章のクイックツアーを読んでます。 バイトニックソート自体の理解はちょっとおいておいて、読み進めています。 いくつか疑問に思ったことがあったので、またメモを。 まだ、3.5.7の手前ですが。\n疑問点 3.4.1のジェネリクス対応のテストケースの部分で、既存のu32用のテストケースの入力のデータ列にVec\u0026lt;u32\u0026gt;という型注釈をつけるのですが、 追加した文字列の入力データには注釈をここではつけないのはなんでなんだろう?ちなみに、なくても動いた。バージョンの違いとかあるのかしら?\n3.4.6のmatch文\nmatch文の引数?が*orderになっていたが、orderでも実行できた。引数にくるのが参照だから*が付いてるんだとも運だが、なくても動くのはコンパイラがよしなに解釈してくれてるからかな? 便利なツール Rust標準のツールの説明がいくつか3章で紹介されてて便利だったのでメモ。\nrustfmt フォーマッター。デフォルトでフォーマット機能が付いてるの便利ですね。言語として決まってると、プロジェクトごとに悩まなくていいってのがありますし。\nrustfmt ファイル名 という形で使えるみたい。 プロジェクトごとだとcargo fmtのほうが楽そうかな。\n標準ライブラリAPIドキュメントをブラウザで閲覧 rustup doc --std これでデフォルトブラウザでRustの公式ドキュメントが開きます。 しかもローカルファイルだからサクサク。検索バーもついてて便利です。\nエラーのドキュメントを閲覧 rustc --explain 308 コンパイル時にエラーが出たときに、error[E0308]のようにコンソールに出てきます。 ヒントも出てくるのですが、詳細が上記のコマンドで読めるみたいです。\n","date":1582443437,"dir":"post/2020/","id":"71cf83ae0f45e9ede3a3f979b9c74933","lang":"ja","lastmod":1582443437,"permalink":"https://blog.johtani.info/blog/2020/02/23/bicycle-book-chap3/","publishdate":"2020-02-23T16:37:17+09:00","summary":"これまでのはこちら。読書メモなので、本と合わせて読んでいただくのが良いです。 実践Rust入門はじめました 3章のクイックツアーを読んでます。 バ","tags":["rust","読書"],"title":"実践Rust入門の3章を読んでるところ"},{"contents":"もう2020年2月になってしまってますが、2019年に買って便利だったもの良かったものをいくつか記録に残しとこうかなと。\nBRAVIA KJ-55X9500G Amazon | ソニー SONY 49V型 液晶 テレビ ブラビア 4Kチューナー内蔵 テレビをやっと買い替えました。 前に使っていたのはプラズマディスプレイで、10年以上たったもので、パネルの一部が赤い残像が残ってたりしました。 もう流石にいいでしょうということで、買い替えたのがSonyのテレビです。 4Kのチューナーもついているし、アップコンバーターもついているので普通の地上波でもきれいです。 まぁ、10年前のテレビに比べればたくさんいいことがありますよねw\n新しいTV買って一番活躍してるのはYouTubeボタンだったりします。 最近はミュージックビデオがYouTubeにたくさんあるので、King Gnuなどの音楽流したりするのに便利です(テレビなのに)。 今は、プライムビデオボタンがより活用される感じになってきてます(テレビなのにw)。\nSodastream Amazon|スピリット ワンタッチ ホワイト スターターキット ここ数年、炭酸を普段飲んでます。甘いもの飲まないようにって意味でも。。。 で、これを買うまでは、サントリーの天然水スパークリングレモンとかを、箱買いしてました。 が、まぁ、ペットボトルのゴミが半端ないんですよ。場所も取るし。\nソーダストリームのことは知ってたのですが、自分で炭酸の量を考えながら、入れないといけないので避けていました。\nが、今回購入したものは、水の入ったボトルを指して、ボタン一つで3段階の炭酸を入れることができるんです!買って本当に重宝してます。うちでは1Lのボトルを1本追加して、2本で運用してます。 家族はなっちゃんのオレンジとかを炭酸割りしたり、カルピスソーダ作ったりして楽しんでます。 ワンタッチということで、簡単に入れられるので家族も重宝してます。\nNature Remo + Chromecast Amazon | Nature スマートリモコン Nature Remo mini Remo-2W1 Google Home miniがキャンペーンで手に入ったので、ベッドルームの照明やクーラーの操作もできそうなのでNature Remoを導入しました。 Chromecastは余っている液晶モニターにつないで、スマホからキャストできるようにしたり、音楽聞けるようにしてあります。\nNature Remoは温度計などもついているので、部屋の温度に合わせてエアコンのオンオフなども可能で、 暑い夏にとても便利でした。寝る時間にはクーラーが入っているのですんなり寝れたりと。 スマホから電源オンオフできるのも便利ですね。 Chromecastはモニターにつなぎましたが、今は、Google Music Playのプレーヤーになってます。 (最近、家にあるCDを読み込んでGoogle Play Musicにアップしてる)。\nただ、それ以上のことには使えてないので、もうちょっと面白いことしてみないとなぁ。\nモニターアーム Amazon | HUANUO PC モニター アーム 液晶ディスプレイ アーム ガススプリング式 Amazon | グリーンハウス 液晶ディスプレイアーム 4軸 クランプ式 ディスプレイがふるくなってたので、4Kディスプレイに買い替えた(27インチで4万切るとかで安い。。。)んですが、Mac Book Pro 15インチ(今は16インチ)を使っていて、Macの画面がディスプレイにかぶるので モニターアームを買いました。 1つ目がガススプリング式のアームです。なのに、5000円を切ってるんですよ。おそるべし。 2つ目はクランプ式です。アームにしたものの特に動かすことはなく、高さを出したいだけってことがあるので、クランプ式のも使ってます(家ではディスプレイ2枚使ってる)。 コスパ最高です。\nAnker PowerCore 10000 PD Amazon | Anker PowerCore 10000 PD(10000mAh PD対応最小最軽量 大容量 モバイルバッテリー) Pixel 3にしてから、電池の持ちはよくはなってるんですが、もしもの時のためにモバイルバッテリーは話せないですよね。 PD対応なので、Pixel 3に急速充電ができるし、サイズもそれほどじゃまにならないサイズなので便利です。USB-Aもついているので、このあと紹介するイヤホンの充電ケーブルなんかも差し込めて大活躍です。\nサウンドピーツのイヤホン Amazon | SOUNDPEATS(サウンドピーツ) Q35HD ワイヤレス イヤホン 高音質・低遅延 IPX8防水 私が持ってるのはこの前のバージョンで、micro-USBで充電充電するタイプですが、こちらもコスパ最高です。 冬は防寒も兼ねてヘッドフォンをしているのですが、春から秋にかけてはこれまで、優先のイヤホンを使ってました。もしくは、Bluetoothのレシーバーに優先のイヤホンつけてました。電池切れたら、イヤホンさして使う感じで。 が、Pixel 3はイヤホンジャックがありません。ということで、ワイヤレスイヤホンに移行するかということで選んだのがこちらです。 世の中的には、完全ワイヤレスイヤホンが流行っていますが、片方無くなってしまうイメージしかわかなくて。。。 これが壊れても、完全ワイヤレスではなくつながったワイヤレスイヤホンを使うと思います。\nヘッドルーペ Amazon | Tumao ヘッドルーペ ルーペ メガネ LED付拡大鏡 眼鏡の上装着 メガネゴムバンド両用 5レンズ交換調節 プラモデルをちょいちょい作るんですが、もう年ですね。。。細かいところが見にくくて。 ガンダムのRG系のプラモデルだと、1/144なんですよ。小さいんですよ。見えないんですよ。。。\n完成しましたー! pic.twitter.com/S9QTS4kJDI\n\u0026mdash; Jun Ohtani (@johtani) February 16, 2020 ということで、ヘッドルーペ導入してみました。 最初は、卓上に置けるルーペにしてみたんですが、自分がルーペがあるところに動かないといけないの結構つらくて。 これのおかげで、プラモデル作成に問題はなくなりました。老眼とは関係なく、ちょっと猫背になっちゃうのが今は悩みの種ですが。。。こたつで作ってるからなぁ。\nまとめ ということで、いくつかよかったものを紹介してみました。 今年はちゃんと年末に書こう。。。\n","date":1582272302,"dir":"post/2020/","id":"daa3fe935b0be9f31b6b362ad9e0d2d6","lang":"ja","lastmod":1582272302,"permalink":"https://blog.johtani.info/blog/2020/02/21/best-buy-2019/","publishdate":"2020-02-21T17:05:02+09:00","summary":"もう2020年2月になってしまってますが、2019年に買って便利だったもの良かったものをいくつか記録に残しとこうかなと。 BRAVIA KJ-55X9500G Amazon | ソニー SONY 49","tags":["買い物"],"title":"2019年に買ってよかったもの"},{"contents":"ブログ移行日記(その5)です。前回まではこちら\nブログ移行日記(その1) ブログ移行日記(その2) ブログ移行日記(その3) ブログ移行日記(その4) 今回はこれまでとは異なる特殊な話です。\n最初にブログを書き始めたときに利用していたのがJugemのブログでした。 その後、Octopressに移行して、今年、Hugoに移行したという流れです。\nで、よくよく考えると、Jugemのブログも移行できるんじゃないか?となりました。 じゃあ、やってみるかと。なので、今回のブログは自分の備忘録です(興味のない人が大多数じゃないかな)。 一応、Pythonで書いたプログラムはGitHubに上がっています。文字列置換と正規表現のオンパレードです。\nJugemからExport まずは、移行元のデータが取り出せるかどうかを調べたところ、text形式もしくはXML形式でエクスポートが可能でした。\n変換処理が必要なはずなので、XMLでダウンロードします。 独自のXMLですが、記事ごとにXMLのタグ(\u0026lt;entry\u0026gt;)でまとめられているので、処理が楽です。\nXMLをMarkdownに \u0026lt;entry\u0026gt;タグの下に次のような項目が入っているので、抜き出します。\nヘッダ部 title - 記事タイトル author - 著者 category - タグ date - 投稿日付 description : 本文(先頭部分) sequel : 本文(つづき) titleからdateまでをHugoのMarkdownのヘッダ部分として出力します。 日付は形式が違うので合わせるように変換し、 titleは(Jugemより移植)という文字列を追加しました。\nまた、Hugoの個別のコンテンツにするためにそれぞれをMarkdownのファイルに変換しています。 ファイル名は変換後のdateの先頭10文字(yyyy-MM-dd)に-を付け加えて、 タイトルを追加しました。ホントは英語のファイル名にしたかったんですが、ちょっと手抜き。ファイル名に使用できないような文字は-に置換しています。\n本文 本文部分はもう少し複雑です。 まずは、descriptionとsequelから抜き出した文字列を結合します。\nで、内部の文字列に次のようなものがあるので、それぞれMarkdownに変換したりという処理を書いてます。\nHTMLのheadingタグをMarkdown形式に br、hr、del、strongなどのタグもMarkdown形式に aタグの処理 Amazonのアフィリエイトタグの処理 ul、olタグの処理 などです。 アフィリエイトタグは、数行に渡るの複数のHTMLタグで記述されているので、 ASINと商品タイトルだけを抜き出しています。 Hugoでアフィリエイトのリンクを作るために、hugo-amazon-jpという公開されているshortcodeを元に、カスタマイズしたものを使っています。 これ用に、必要なASINとタイトルを別ファイルに出力したりしています。\nまた、いくつか画像を使っている記事があったのですが、これが曲者でした。 XMLに入っているimgタグに画像へのURLがあるのですが、アクセスしても存在しないURL担っています。。。 ブログで公開している画像のファイル名に似たものがXMLに入っていたので、URLを組み直して、ダウンロードするという処理も書いています。\nあとは、昔ちょっと凝った書き方(spanタグで章みたいなことやってた)をしていた部分の処理を加えて完成です。\nまとめ 元のXMLを見たり、抜き出したファイルを見ながら、トライアンドエラーでプログラムを書きました。 なんとなく変換できたなかっていうところで、取り込んで公開しました。 まだ、全部の記事をチェックしてないですが、なんとなく移植できたので一旦これでいいかなと。 昔の記事を見たときにおかしい場所があったら手で治すつもりでいます。\nなんか、もうちょっとうまくプログラムかけた気もしますが、書き捨てのプログラムだと思うのでこんなもんかな。\n1点気になっているところは、コメントの部分です。 ブログにコメントをいただいていたのですが、その部分は移植できてないです。\nOctopresに移植していこうは、Disqusのサービスでコメント部分を提供しています。ここに移植するのも変な話だなぁと思っているので、本文にコメントを取り込む感じかなぁ?\nもともとのJugemのサイトもそのまままだ残してあるので、そのうち気が向いたらで。\n","date":1582254240,"dir":"post/2020/","id":"ef8a399c9679ce4e9710c7c6ecf8bcc7","lang":"ja","lastmod":1582254240,"permalink":"https://blog.johtani.info/blog/2020/02/21/import-jugem-posts/","publishdate":"2020-02-21T12:04:00+09:00","summary":"ブログ移行日記(その5)です。前回まではこちら ブログ移行日記(その1) ブログ移行日記(その2) ブログ移行日記(その3) ブログ移行日記(その4","tags":["hugo","ブログ"],"title":"ブログ移行日記(その5) - Jugemのブログを移行"},{"contents":"お手伝いしているお客さんがAzure Cognitive Searchを利用してます。 検索周り=Azure Cognitive Searchに関する手伝いをする形で入っており、 いくつか触った感触をブログにまとめてみようかと(お客さんからはOKいただいてます)。\nAzure Cognitive Searchとは? 公式サイト 「AIを活用した」クラウド検索サービスと紹介されています。\n昔はAzure Searchと呼ばれていましたが、ここ最近はAzure Cognitive Searchと呼ばれているみたいです(Microsoft Igniteで発表された話がまとまっているページもあります)。 もともと、検索エンジンのSaaSサービス(キーワード検索、あいまい検索、オートサジェスト、スコアリングなどの機能)として作られていた部分に、データの登録パイプラインにCognitive Serviceの便利な機能を簡単に使えるようにしたものというイメージでしょうか。\nバックエンドはElasticsearchのはずです。変わってなければ。 昔、Elastic社主催のユーザーカンファレンスでMSの方が公演された資料が公開されていたりします。 ちなみに質問が多いのでしょうか、Azure Cognitive SearchとElasticsearchの違いはなんですか?というページがよくある質問のページに用意されていました。参考までに。\n今回はちょっとしたインデックスをつくって検索する部分を紹介してみようかと思います (Cognitiveなところは機会があればまた)。\n普通の使い方については、Azureのドキュメントなどを読んで頂く形にします。 ポータルと呼ばれるブラウザ上でAzureのサービスを触ることができる画面が用意されています。 ここで、簡単な操作(インデックス作成、フィールドの追加)\nAPIを使ってインデックス(特にAnalyzer)の設定をしたり、データをいれて、クエリしてみるというところをサクッと紹介しようと思います。\nインデックスの作り方 インデックス作成に関するドキュメントも用意されています。最初はポータル(GUI)でインデックスを作成する方法が紹介されています。 ですが、今回はn-gram(n=2)のAnalyzerを利用したかったので、GUIではなくAPIでインデックスを作成しました。 カスタムアナライザーを利用する場合、REST APIを利用しなければ行けないということになっています。 n-gramのAnalyzerを含むインデックス生成のREST APIは以下のとおりです。こちらを実行することで、インデックスが作成されます(JSONの記述ミスなどがある場合はエラーが返ってきます)。\n@host = \u0026lt;サーチのサービス名\u0026gt;.search.windows.net @api-key = \u0026lt;APIキー\u0026gt; ### POST https://{{host}}/indexes/?api-version=2019-05-06 Content-Type: application/json api-key: {{api-key}} { \u0026#34;name\u0026#34;:\u0026#34;ngram-test\u0026#34;, \u0026#34;fields\u0026#34;:[ { \u0026#34;name\u0026#34;:\u0026#34;id\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;Edm.String\u0026#34;, \u0026#34;key\u0026#34;:true, \u0026#34;searchable\u0026#34;:false }, { \u0026#34;name\u0026#34;:\u0026#34;ngram\u0026#34;, \u0026#34;type\u0026#34;:\u0026#34;Edm.String\u0026#34;, \u0026#34;searchable\u0026#34;:true, \u0026#34;analyzer\u0026#34;:\u0026#34;bi_gram_analyzer\u0026#34; } ], \u0026#34;analyzers\u0026#34;:[ { \u0026#34;name\u0026#34;:\u0026#34;bi_gram_analyzer\u0026#34;, \u0026#34;@odata.type\u0026#34;:\u0026#34;#Microsoft.Azure.Search.CustomAnalyzer\u0026#34;, \u0026#34;tokenizer\u0026#34;:\u0026#34;bi_gram_tokenizer\u0026#34;, \u0026#34;tokenFilters\u0026#34;:[ \u0026#34;lowercase\u0026#34; ] } ], \u0026#34;tokenizers\u0026#34;:[ { \u0026#34;name\u0026#34;:\u0026#34;bi_gram_tokenizer\u0026#34;, \u0026#34;@odata.type\u0026#34;:\u0026#34;#Microsoft.Azure.Search.NGramTokenizer\u0026#34;, \u0026#34;minGram\u0026#34;:2, \u0026#34;maxGram\u0026#34;:2 } ] } なんだかどこかで見たことのある記述のようなそうでないような。。。 Analyzerは、charFilters(0以上複数可)、tokenizer(1つ必須)、tokenFilters(0以上複数可)から構成されます。 フィールドで指定するのはAnalyzerなので、まずanalyzersにCustomAnalyzerの設定を行います。 名前はbi_gram_analyzerにしました(好きに付けてください)。 tokenizerにはこのあと設定するtokenizerの名前を設定します。ここでは、bi_gram_tokenizerという名前にしています。 また、大文字小文字を気にせずに検索したいため、tokenFiltersにlowercaseを指定しています。こちらはすでに定義済みのため、定義済みの名前で呼び出すだけで使用できます。\n次が、bi_gram_tokenizerの設定です。 n=2としたいので、tokenizers配下にTokenizerの設定をします。 @odata.type\u0026quot;:\u0026quot;#Microsoft.Azure.Search.NGramTokenizerがTokenizerの名前です(ちょっと独特な名前ですね)。 Tokenizerごとにオプションがあり、NGramTokenizerの場合は、minGram、maxGramがオプションに相当します。 今回は2文字ごとにトークンを出力したいので、minとmaxをそれぞれ2としています。\nこれで、あとは、フィールドでanalyzerという設定にbi_gram_analyzerを指定すればそのフィールドはbi_gram_analyzerを使用してアナライズされるようになります(このへんはElasticsearchといっしょですね)。 フィールドは文字列を扱うので、Edm.Stringというタイプにしてあります。データ型については、フィールドコレクションとフィールド属性というドキュメントを参考に設定しましょう。\n閑話休題 - REST Client Exstension for Visual Studio Code なお、今回のサンプルはREST Clinet Extention for Visual Studio Codeを利用する想定の記述になっています。\nVisual Studio Codeで.restもしくは.httpというファイルに以下のAPIを記述すると、Send RequestというリンクがURLの上部に出てくるような拡張機能です。REST APIにリクエストするときに便利なツールになっています。 変数も使えるので、APIのキーやURLの一部をこのように共通化して、他の環境でも使いやすくできるのは素晴らしいなと。\nアナライザーの挙動の確認 設定したAnalyzerがきちんと機能しているかというのを確認する必要があります。 入力した文字列がきちんと想定している単語として切り出されて、転置インデックスの見出し語に使われるかというのが重要になるからです。\nAzure Cognitive Searchでもアナライザーのテスト用APIが用意されています。 使い方はこちら。 APIの仕様のページもありました。 「アナライザーの挙動はどんな感じ?」という文字列が、作成したインデックスの定義したアナライザーbi_gram_analyzerにより、 どのように分割されるかを確認するAPIの呼び出しは以下のとおりです。\n### POST https://{{host}}/indexes/ngram-test/analyze?api-version=2019-05-06 Content-Type: application/json api-key: {{api-key}} { \u0026#34;analyzer\u0026#34;:\u0026#34;bi_gram_analyzer\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;アナライザーの挙動はどんな感じ?\u0026#34; } レスポンスはこんな形です。ヘッダ部分は省略してあります。\n{ \u0026#34;@odata.context\u0026#34;: \u0026#34;https://{{host}}.search.windows.net/$metadata#Microsoft.Azure.Search.V2019_05_06.AnalyzeResult\u0026#34;, \u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;アナ\u0026#34;, \u0026#34;startOffset\u0026#34;: 0, \u0026#34;endOffset\u0026#34;: 2, \u0026#34;position\u0026#34;: 0 }, { \u0026#34;token\u0026#34;: \u0026#34;ナラ\u0026#34;, \u0026#34;startOffset\u0026#34;: 1, \u0026#34;endOffset\u0026#34;: 3, \u0026#34;position\u0026#34;: 1 }, { \u0026#34;token\u0026#34;: \u0026#34;ライ\u0026#34;, \u0026#34;startOffset\u0026#34;: 2, \u0026#34;endOffset\u0026#34;: 4, \u0026#34;position\u0026#34;: 2 }, { \u0026#34;token\u0026#34;: \u0026#34;イザ\u0026#34;, \u0026#34;startOffset\u0026#34;: 3, \u0026#34;endOffset\u0026#34;: 5, \u0026#34;position\u0026#34;: 3 }, { \u0026#34;token\u0026#34;: \u0026#34;ザー\u0026#34;, \u0026#34;startOffset\u0026#34;: 4, \u0026#34;endOffset\u0026#34;: 6, \u0026#34;position\u0026#34;: 4 }, { \u0026#34;token\u0026#34;: \u0026#34;ーの\u0026#34;, \u0026#34;startOffset\u0026#34;: 5, \u0026#34;endOffset\u0026#34;: 7, \u0026#34;position\u0026#34;: 5 }, { \u0026#34;token\u0026#34;: \u0026#34;の挙\u0026#34;, \u0026#34;startOffset\u0026#34;: 6, \u0026#34;endOffset\u0026#34;: 8, \u0026#34;position\u0026#34;: 6 }, { \u0026#34;token\u0026#34;: \u0026#34;挙動\u0026#34;, \u0026#34;startOffset\u0026#34;: 7, \u0026#34;endOffset\u0026#34;: 9, \u0026#34;position\u0026#34;: 7 }, { \u0026#34;token\u0026#34;: \u0026#34;動は\u0026#34;, \u0026#34;startOffset\u0026#34;: 8, \u0026#34;endOffset\u0026#34;: 10, \u0026#34;position\u0026#34;: 8 }, { \u0026#34;token\u0026#34;: \u0026#34;はど\u0026#34;, \u0026#34;startOffset\u0026#34;: 9, \u0026#34;endOffset\u0026#34;: 11, \u0026#34;position\u0026#34;: 9 }, { \u0026#34;token\u0026#34;: \u0026#34;どん\u0026#34;, \u0026#34;startOffset\u0026#34;: 10, \u0026#34;endOffset\u0026#34;: 12, \u0026#34;position\u0026#34;: 10 }, { \u0026#34;token\u0026#34;: \u0026#34;んな\u0026#34;, \u0026#34;startOffset\u0026#34;: 11, \u0026#34;endOffset\u0026#34;: 13, \u0026#34;position\u0026#34;: 11 }, { \u0026#34;token\u0026#34;: \u0026#34;な感\u0026#34;, \u0026#34;startOffset\u0026#34;: 12, \u0026#34;endOffset\u0026#34;: 14, \u0026#34;position\u0026#34;: 12 }, { \u0026#34;token\u0026#34;: \u0026#34;感じ\u0026#34;, \u0026#34;startOffset\u0026#34;: 13, \u0026#34;endOffset\u0026#34;: 15, \u0026#34;position\u0026#34;: 13 }, { \u0026#34;token\u0026#34;: \u0026#34;じ?\u0026#34;, \u0026#34;startOffset\u0026#34;: 14, \u0026#34;endOffset\u0026#34;: 16, \u0026#34;position\u0026#34;: 14 } ] } このAzure SearchのAnalyze API、使用できるオプションはすくないですが、ElasticsearchのAnalyze APIと似ています。\nデータの登録の仕方 データ登録もAPIからできます(あたりまえですね)。 APIは1件ずつではなく、バルクで登録できる形で提供されています。\nサンプルとしては、以下のような形です。 @search.actionの部分(searchがあるとわかりにくい気がするけど。。。)が、ドキュメントの登録、更新、削除の命令を書き込むところになります。 今回は単純に登録するだけなので、uploadを指定しました。 ほかにもいくつかアクションが用意されています。用途に合わせて指定する感じになります。 id、ngramはそれぞれフィールド名です。ドキュメントに登録したい値を記述します。\nPOST https://{{host}}/indexes/ngram-test/docs/index?api-version=2019-05-06 Content-Type: application/json api-key: {{api-key}} { \u0026#34;value\u0026#34;: [ { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;ngram\u0026#34;: \u0026#34;新しいAzure Searchの使い方\u0026#34; }, { \u0026#34;@search.action\u0026#34;: \u0026#34;upload\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;2\u0026#34;, \u0026#34;ngram\u0026#34;: \u0026#34;Elasticsearchの紹介\u0026#34; } ] } 検索クエリ 最後は検索クエリです。 検索クエリはいくつかのオプションがあります。 ざっくりだと、queryTypeがsimpleとfullという2種類が用意されており、ちょっとした検索を作る場合はsimpleで事足りそうという感じです。 入力された単語(スペース区切りで複数扱い)をフィールド(複数可)に対していずれかの単語を含むもしくは、すべての単語を含むという検索に行くというパターンですね。 このときの、「いずれか」か「すべて」の設定がsearchModeというパラメータになります。 anyの場合、Googleの検索と同様に、どれかの単語が入っているドキュメントが対象に、allの場合すべての単語が含まれるドキュメントだけがたいしょうになるといった形です。\nqueryType=fullの場合はLuceneの構文でクエリがかけます。ElasticsearchのQuery String Queryみたいな形です。\n簡単なサンプルは次のような感じです。このサンプル\nPOST https://{{host}}/indexes/multi-field-test/docs/search?api-version=2019-05-06 Content-Type: application/json api-key: {{api-key}} { \u0026#34;search\u0026#34;: \u0026#39;ngram:\u0026#34;使い方\u0026#34; ngram:\u0026#34;紹介\u0026#34;\u0026#39;, \u0026#34;queryType\u0026#34;: \u0026#34;full\u0026#34;, \u0026#34;searchMode\u0026#34;: \u0026#34;any\u0026#34; } すこしだけクエリの補足を。 searchに入力された単語をダブルクォートで囲んでいます。これは、「使い方」という文字がbi_gram_analyzerにより「使い」「い方」に 分割されるのですが、必ずこの順序で出現したものだけを検索対象にしたい(フレーズ検索)という意味になります(*bi_*gramなので、「紹介」に関してはダブルクォートは厳密には必要ないです)。\nあと、レスポンスは今回記載していませんが、@search.scoreという項目で、スコアが返ってきます。 デフォルトのスコア計算には何を使ってるんだろう?ドキュメントにはTF-IDFとの記述があるのですが。。。カスタマイズもできそうです。\n少しオモシロイと思ったのは、スキーマ(インデックスの設定)に定義されているが、ドキュメントとしては登録していない項目についても、 Azure Cognitive Searchはドキュメントのフィールドがnullという形で返ってくるようでした。 そもそもフィールドが存在しないドキュメントとフィールドの値がnullのものの違いは無いようです。\n簡単ですが、インデックスの設定、ドキュメントの登録、検索の方法の紹介でした。\nちょっと触った感想 一番売りである、Cognitiveの部分はまだ触っていないです、すみません(こっちが売りな気もするんですが)。 検索エンジンの部分としては、Elasticsearchを知っていると、「あー、そんな感じね」という気持ちになれるサービスです。 個々のAPIやデータの形式は異なるので、きちんとAPIのリファレンスなどを確認しつつという形になりますが、なんとなくこういうAPIなどがありそうだな?と予測しつつ使えるかなと。 内部的にはElasticsearchだと思いますが、独自のAPIでラップされているおかげで、バージョンの違いなどを意識せずに使えるのではないかと思います。\nまた、今回は紹介していませんが、マイクロソフト独自の各言語のアナライザー(日本語も含む)があります。 Luceneのアナライザーとマイクロソフトのアナライザーのどちらも利用できますので、ここの違いを見てみるのも面白そうだなと思いました。 緯度経度を利用した検索、フィルター検索(スコア計算対象にならない)、ファセット、スコア調整の機能なども備えているようです。\nなんにせよ、利用する場合やドキュメントを読む場合に、全文検索の仕組みをなんとなく知っておいたほうが読みやすいんじゃないかなというのが感想です。\nここ数年はElasticsearchがメインでほかはほぼ触っていない状況だったので新しい製品に触れるのは面白いですね。 時間があったら、アナライザーの違いなども調べてみたいなと思います。\n","date":1582080481,"dir":"post/2020/","id":"c3053579ae25e2fb9b967076a06373af","lang":"ja","lastmod":1582080481,"permalink":"https://blog.johtani.info/blog/2020/02/19/research-azure-cognitive-search/","publishdate":"2020-02-19T11:48:01+09:00","summary":"お手伝いしているお客さんがAzure Cognitive Searchを利用してます。 検索周り=Azure Cognitive Searchに関する手伝いをする形で入っており、 いく","tags":["azure search"],"title":"Azure Cognitive Searchでインデックスを作って検索"},{"contents":"また、ツイートから始まるお話です。 まだまだ、検索システムってどんなものかを勉強したいしということで、こんなのをツイートしてました。\n「検索システム探訪」みたいな名前がいいかな? https://t.co/sG7BDdGI9h\n\u0026mdash; Jun Ohtani (@johtani) February 6, 2020 検索について知り合いとお茶をしながら話をしていて、こういう話を聞くの面白いなぁと思ったので。 どんなことを個人的には聞きたいかな?というのをまとめといたほうがいいかと思いブログを書いています。 こんなことも面白そうだよね?\nどんなこと聞きたいかな? いまのところ思いついた内容はこんな感じかな? こんなのも聞くと面白そうだよね?などありましたら、コメント欄に書いてもらえればと。\n利用しているシステム・サービスは? 構成やどこのサービスなのか? 検索ユーザーはどんな人? ユーザーの種類 ユーザーの検索ニーズ 検索対象データはどんなもの? データ件数はどのくらい? 属性、項目がどのくらいあるか? 検索結果として出したいものは? ソートはどんなものがあるの? ランキングで重要なものは? UI/UXはどんな感じ? ハイライト、ソート、ファセット(Aggs) キーワードサジェスト、オートコンプリート 検索システムの監視(オブザバビリティ??) ビジネス的な指標 クエリログ、クリック(ユーザーに関する情報) システムメトリクス 困っていることは? ランキング クエリ 検索システム分析 第1回やりました。 ちなみに、最初のツイートに対して、すぐに返事をくれた方がいました。\nうちでよければご説明します!\n\u0026mdash; Kizashi (令和もRailsエンジニア募集中) (@kizashi1122) February 6, 2020 Twitter本当にありがとうございますという感じです。\nで、早速話を聞かせていただきました。大阪の方だったので、テレカンでやらせていただきました。 移動時間とか気にせずにできるので、テレカン形式いいですよね。\n内容は、非常に面白かったです。 使ってるシステムについて、どんなところで、どのようなように検索エンジンをつかっているのか、 どんなことで困っているのかなどをお聞きすることができました。\n2020/02/13 追記 対応していただいたIngageの永田さんから、内容を公開しても良いという承諾をいただいたので、メモを公開します。\nサービス : Re:lation 問い合わせメールなどのチームで対応する対応 利用している検索エンジン Elasticsearch (AWS Es) ノード数 8 - 3 master + 5 data データ データ数 : 約1億5千万 親子関係 : チケット - メール(=1ドキュメント) - コメント 画面としてはチケットの一覧=aggsでチケットIDの一覧を生成してリスト表示 インデックス数 : 5 = テナントごとに振り分けしてる。 8シャード - スケールアウトした場合も対応できるので。 PostgreSQLにマスターは保存 データの単位はメール。コメントはtextの配列でメールに保存されている。 EsはIDの一覧を返す。ただし、チケットのIDの一覧 機能 ハイライト Esではなく独自実装。 クエリ n-gramでやってる = kuromoji使ってない min=1, max=2 悩み事 EBS上だったものをローカルにしたので速くなった。 期間が長いと、検索結果一覧の表示が遅い aggsが遅いのかな? 検索結果一覧はチケットが持っているメールの日付の降順。結果一覧はチケットの一覧。 詳細検索はDB、左のステータスもファセットも現在はDBから生成 Es使ったほうが早いかも? マルチテナントのつらさ 検索ログ 独自ログはとっていない = アプリのログから判別 今後 アドレス帳検索 お誘いお待ちしております! 今後もこれやっていきたいなぁ。話してもいいよ!という方がいらっしゃいましたら、@johtaniまでDMもしくはメンションをください。お待ちしております!\n","date":1581344427,"dir":"post/2020/","id":"7b080dc43fce482af14de61c6ab819a5","lang":"ja","lastmod":1581344427,"permalink":"https://blog.johtani.info/blog/2020/02/10/explore-search-system/","publishdate":"2020-02-10T23:20:27+09:00","summary":"また、ツイートから始まるお話です。 まだまだ、検索システムってどんなものかを勉強したいしということで、こんなのをツイートしてました。 「検索シス","tags":["検索システム探訪"],"title":"「検索システム探訪」したいな=\u003eやりました"},{"contents":"年末、何種類かのボードゲームを家族で楽しみました。 家族の感想を交えて簡単に紹介しようかと思います。 家族や知人でボードゲームを購入するときの参考に参考にしてもらえたらと。 それぞれのゲームの詳細については、それぞれWikipediaなどのリンクを張っておくので、参考にしていただけたらと。 結構有名なボードゲームが多いのかな?\nカタン Amazon | カタン スタンダード版 | ボードゲーム | おもちゃ 簡単な紹介 プレーヤー数 : 3-4名 (拡張版を追加すると5-6名でもプレイできるみたい) 対象年齢 : 10歳以上 種類 : 対戦型 紹介 : 大航海時代に発見された無人島を複数の入植者たちが開拓していき、もっとも繁栄したプレイヤーが勝利するという内容のボードゲーム(Wikipediaより)。 特徴 : 5種類の資源を元に、道を作ったり、開拓地や都市を作ったり、サイコロを使った運も必要ですが、プレーヤー同士で手持ちの資源を交渉することも可能なゲームです。 感想 最初の配置が重要な気がします。資源の組み合わせによってできることが変わってくるので、何をやりたいかというのを元に考えて配置するのが重要そうです(私はまだうまくできてませんがw)。 プレーヤー同士の交渉も1つの手段なので、会話しながら、自然と交渉術も身についてきそうです。 戦略だけじゃなくサイコロを使った運もあるので、子供と大人が混ざっていても偏った結果にはならないです。 自分の道や町が発展していくのも楽しみの1つです。 お化け屋敷の宝石ハンター Amazon | お化け屋敷の宝石ハンター FBH20 | おもちゃ | おもちゃ 簡単な紹介 プレーヤー数 : 2-4名 対象年齢 : 8歳以上 種類 : 協力型 紹介 : お化け屋敷がおばけでいっぱいになる前に、みんなで協力して8つの宝石をみつけて、屋敷から脱出しよう!(メーカーホームページより)。 特徴 : 対戦ではなくプレーヤーみんなで協力してやるボードゲーム。おばけのフィギュアも可愛いです。サイコロを利用した運もありますが、みんなでどういった戦略で宝石を取り出すかなど会話も進むゲームです。上級編という難しめのルールも用意されているので、ハラハラ・ドキドキしながらプレイできます。 感想 負けて悔しくなったり機嫌が悪くなることがないのがいいですね。 普通のルールだと少し物足りない感じですが、上級編のルールはより、みんなで協力する必要が出てきます。 また、上級編のルールは絶妙な難易度で、もう一度やりたいと思わせるのが良い仕組みです。 ラビリンス Amazon | ラビリンス (Labyrinth) ボードゲーム | ボードゲーム | おもちゃ 簡単な紹介 プレーヤー数 : 1-4名 対象年齢 : 8歳以上 種類 : 対戦型 紹介 : 動く迷路で宝探し!通路が動く不思議な迷路の中に、「宝物」や「奇妙な生き物」が隠されています。プレイヤーはこれらを集めてこなければなりませんが、そのためには、巧みに迷路を動かさなければなりません。(メーカーホームページより)。 特徴 : サイコロがないボードゲームです。先を予測しながら人のじゃまをしつつ、自分に有利に進めていくゲームです。プレーヤー個別に難易度を変えられる仕組みがあります(子供だけに有利なルール設定が可能)。 感想 子供ルールがあるので、1度のゲームで別々の難易度が設定できるのがいいです。左右盲の人には子供ルールとかもありです。 ラビリンスが得意な人は地図を読むのが得意な人だと思います。 頭も使うけど、自分が望んだ道ができた時の快感があります。 モノポリー Amazon | ハズブロ ボードゲーム モノポリー クラシック C1009 正規品 | ボードゲーム | おもちゃ 簡単な紹介 プレーヤー数 : 2-6名 対象年齢 : 8歳以上 種類 : 対戦型 紹介 : プレイヤーは双六の要領で盤上を周回しながら他プレイヤーと盤上の不動産を取引することにより同一グループを揃え、家やホテルを建設することで他のプレイヤーから高額なレンタル料を徴収して自らの資産を増やし、最終的に他のプレイヤーを全て破産させることを目的とする。モノポリーとは英語で「独占」を意味する。(Wikipediaより)。 特徴 : 資本主義とは?みたいなのを体験できるゲーム。すごろく型ですが、ゴールがあるわけではなく、決着がつくまでぐるぐる回る感じです。 感想 資本主義を象徴しているゲーム展開。真剣勝負間違いなしです。 負けると途中退場ってのがちょっとつらいです。。。 カタンとは違った感じの交渉術になります。 コマが色んな種類があってかわいいです。 パンデミック Amazon | パンデミック:新たなる試練 (Pandemic) 日本語版 ボードゲーム | ボードゲーム | おもちゃ 簡単な紹介 プレーヤー数 : 2-4名 対象年齢 : 8歳以上 種類 : 協力型 紹介 : 『パンデミック』(Pandemic)は、プレイヤーが新型ウイルス対策チームの一員となり、協力しあい感染症の世界的流行(パンデミック)に立ち向かうというボードゲームである。(Wikipediaより)。 特徴 : プレーヤーが個別のロール(役割)を持っており、よりみんなで協力をしないとウイルスに打ち勝てない感じです。 感想 ルールが結構複雑で、理解しながらだと少し時間かかりました。 8歳以上になっていますが、少しむずかしい印象でした。 戦略、戦術が問われる形のゲームなのでしっかり理解すると楽しそう。 世界地図上で、ウイルスと戦っていく感じは臨場感があって面白いです。 ナインタイル Amazon | ナインタイル | カードゲーム・トランプ | おもちゃ 簡単な紹介 プレーヤー数 : 2-4名 対象年齢 : 6歳以上 種類 : スピード対戦型 紹介 : 「ナインタイル」の基本ルールは、それぞれの手元にある、9枚のタイルを自由に動かしたりひっくり返したりして、誰よりも早くお題どおりに並べるだけ。(公式サイトより)。 特徴 : ボードゲームというか、カードゲーム。ルールは簡単ですが、記憶力と素早さが重要です。 感想 脳トレに良さそう(子供に勝てませんでした。。。)。 瞬発力+記憶力が重要。 デザインがきれい じゃあ、家族の人気は? ラビリンス、カタン、モノポリーあたりが人気です。 ゲーム性もありますが、デザインとしてもきれいなものが多かったです。\nテレビゲームも面白いですが、ワイワイ喋りながらボードゲームをやるのも楽しかったです。 今回紹介したボードゲームはどれもある程度ルールを理解するところから始めないといけないですが、理解力や説明力なども必要になってくるので色んな楽しみがあるかなと思います。\n","date":1580558694,"dir":"post/2020/","id":"90f9355781403b92e844de8568863ae8","lang":"ja","lastmod":1580558694,"permalink":"https://blog.johtani.info/blog/2020/02/01/intro-board-game/","publishdate":"2020-02-01T21:04:54+09:00","summary":"年末、何種類かのボードゲームを家族で楽しみました。 家族の感想を交えて簡単に紹介しようかと思います。 家族や知人でボードゲームを購入するときの参","tags":["ゲーム"],"title":"ボードゲーム紹介"},{"contents":"実践Rust入門という本を買っていた(去年の7月だ。。。)のですが、積んであったので、時間を作って読み始めようかと。\n実践Rust入門[言語仕様から開発手法まで] | κeen, 河野 達也, 小松 礼人 |本 | 通販 | Amazon 経緯 もともとは、言語処理100本ノックはじめました(Rust)という感じで、触っていたのですが、場当たり的にやってても時間を持っていかれるだけだなということに気づいたのが最初です。\n今年の目標は、覚えられなので、ちょっとずつでもアウトプットしていこうってのもあり、 読書記録をつけつつ、読んでいこうかなぁと。\nどこまで読んだ? 2章の2-2-5までです。 前回、Rustの環境はセットアップしていたのですが、新PCに切り替わったので、rustupからはじめました。\nrustup rustupではデフォルト設定のままではなく、PATH変数の書き換えだけはしない形でインストールを行いました。\nPATH変数は.zshrcファイルで変更したかったためです(rustupコマンドに変更して貰う場合は.profileなどのファイルが変更されそうだったため)。\nインストールが終わったあとに.zshrcに以下の行を追加しました。\n### For Rust env source $HOME/.cargo/env 疑問点 ここまで読んだ疑問点です。\ncargo new helloしたあとにmain.rsに以下のmain()関数が出来上がっている!? fn main() { println!(\u0026#34;Hello, world!\u0026#34;); } 驚きましたが、cargo new hogeってやっても、おなじmain.rsができてました。デフォルトで出来上がるんですね。どんな超能力!?と思ってしまいましたw\ncargo new helloして出来上がったCargo.tomlに著者名が入力されていた。 authors = [\u0026#34;Jun Ohtani \u0026lt;メアド\u0026gt;\u0026#34;] なんで?と思いました。まだ解明してないです。 本を読んでいけばわかるかな?\n予想:gitの設定(~/.gitconfig)に氏名とメアドが設定されているので、これを利用しているのかな? ","date":1580475492,"dir":"post/2020/","id":"7fcfaa8dd34dbd508f19e8ca0fcfda0f","lang":"ja","lastmod":1580475492,"permalink":"https://blog.johtani.info/blog/2020/01/31/start-reading-bicycle-book/","publishdate":"2020-01-31T21:58:12+09:00","summary":"実践Rust入門という本を買っていた(去年の7月だ。。。)のですが、積んであったので、時間を作って読み始めようかと。 実践Rust入門[言語仕","tags":["rust","読書"],"title":"実践Rust入門はじめました"},{"contents":"12月に退職しますブログを書きましたが、その後どうなったのか?という話をしてないなと思ったので、一応現在の状況を書き留めておこううかと。\n結論 実際にはフリーランスとして働き始めてます。検索周りをお手伝いするお仕事を。読解いとこあれば所属するつもりでもいるし。\n\u0026mdash; Jun Ohtani (@johtani) January 27, 2020 フリーランスとして最初の仕事はElasticsearchではなく、Azure Cognitive Searchの支援だったりします。Esで困ってる方の手伝いもしますので、興味ある方はDMください。\n\u0026mdash; Jun Ohtani (@johtani) January 31, 2020 2020年1月24日が、正式なElasticの退職日でした(有給休暇消化してた)。 で、現在のステータスはこのツイートです。\n現在の心境 どこかに就職してガッツリ検索もやりたいし、いろんな会社の検索やElastic Stackに関するお手伝いをするのにも興味があるし、どちらにも興味がある状況です。まぁ、検索に興味が尽きないというのだけは決まってますかね。\n悩んでいるところに、幸いにもAzure Search周りで手伝ってほしいという話が舞い込んできたので、フリーランスとしてお手伝いをさせていただいてます(現時点で、半稼働で、が3月末まで)。\nElastic Stackなどの知見もあるのでのお手伝いをするというのもありかなぁと。お仕事発注してもいいな?という方があれば、TwitterのDMなど、連絡をいただければと。\n現在の状況でした。\n副業ができる会社に就職するのがどっちもできていいのかも?\n","date":1580470659,"dir":"post/2020/","id":"c61a5bda3f1667498626ae52ad0362e0","lang":"ja","lastmod":1580470659,"permalink":"https://blog.johtani.info/blog/2020/01/31/start-freelance/","publishdate":"2020-01-31T20:37:39+09:00","summary":"12月に退職しますブログを書きましたが、その後どうなったのか?という話をしてないなと思ったので、一応現在の状況を書き留めておこううかと。 結論","tags":["転職"],"title":"フリーランスはじめました(仮)"},{"contents":"ブログ移行日記(その4)です。その他の記事はこちら。\nブログ移行日記(その1) ブログ移行日記(その2) ブログ移行日記(その3) ブログ移行日記(その5) 前回までで、なんとなく移行は終わってます。 今回はテーマで使えるようになっているブログの検索機能の導入の話です。\n検索サービスはAlgoliaを利用します。 OctopressのころはElastic社のサービスであるElastic Site Searchの機能を利用して、クローリングしてから検索できるようにしていましたが、Hugoで導入できるモジュール?があったので、今回からこちらに移行しました。\n参考記事 Clean White ThemeのREADME(Algoliaの設定方法) 参考ブログ:hugoで作ったblogにalgoliaで全文検索機能を追加する Algoliaとは? 検索のas-a-serviceをやっている会社です。Wikipediaによると本社はサンフランシスコにあるみたいですね(フランスの会社のイメージでした。起業された方がフランス出身だからかなぁ?)。 クラウドで検索インデックスを保持でき、API経由で検索したり登録したりできる感じのサービスです。内部で使われているのはOSSではない独自の検索エンジンです。\nクラウドで提供されているサービスなのでサクッと検索を使い始めることができるのがいい点ですね。 また、小さな非商用のプロジェクトにフリーで利用できるプランも提供されているようです(2020年1月現在)。\nAlgoliaのサービス登録からインデックス作成 私が利用しているテーマで設定する方法の記載があったので手順の通りにやってみました。 大きく2つの作業(Algolia側とHugo側)が必要です。まずは、Algoliaで必要な作業から。作業の流れだけ記載しておきます。詳細は「Static site search with Hugo + Algolia」の3)を確認してください。\nAlgoliaのサインアップ(すでにアカウントがあれば不要) New Applicationの作成(名前とプランの指定) リージョンの指定 インデックス名の指定 APIキーを確認 です。これで、Algolia側の準備は完了です。\n今回は関係ないですが、Algoliaの管理画面で、利用状況(データ登録などの操作回数、クエリの回数、インデックスに保存されているレコード数)の確認が可能です。 ほかにも有料プランを利用するとAnalyticsなどもできるようです。\nHugo側で必要な設定 今度はHugo側です。Hugoのサイトのディレクトリに移動してからの作業です。\n仕組みとしては、\nHugoのoutput機能でAlgolia向けのJSONファイルを生成する Node.jsのライブラリを使用してAlgoliaに1.で生成したJSONを登録、更新する 検索画面の作成 という流れになります。 ですので、作業としては以下のとおりです。\nOutput出力の設定(すでにテーマ側で設定されているので、特に作業は必要なし) npm環境の構築(Hugoのconfig.tomlと同じディレクトリ階層) Node.jsのインストール(必要であれば) npm環境の初期化 npmでatomic-algoliaのインストール atomic-algolia向けの設定(登録のためのAPI関連の設定) Algolia向けJSONの出力設定 検索関連の設定 content/search/placeholder.mdの作成 検索用のAPIキーなどを設定 npm関連の作業 以下、npm関連の作業です。\nNode.jsのインストール(必要であれば) 割愛します。環境に合わせてインストールしてください。私はnvm経由でインストールしています。 npm環境の初期化 Hugoのディレクトリでnvm initを実行 npmでatomic-algoliaのインストール Hugoのディレクトリでnpm install atomic-algolia --save atomic-algolia向けの設定(登録のためのAPI関連の設定) Hugoのディレクトリに.envファイルを作成し、以下を設定します。 Algolia向けJSONの出力設定 特に変更なし(config.tomlに少し設定があります)。 ALGOLIA_APP_ID=AlgoliaのApplication ID ALGOLIA_ADMIN_KEY=AlgoliaのAdmin API Key ALGOLIA_INDEX_NAME=先程作ったインデックス名 ALGOLIA_INDEX_FILE=public/algolia.json 最後のALGOLIA_INDEX_FILEは固定文字列でいいと思います。 hugoコマンドを実行するとpublicディレクトリ配下にalgolia.jsonというファイルが生成され、Algolia登録用のJSONが出力されています。\n余談 : algolia.jsonの出力の設定は、config.tomlに記載があります。また、JSONファイルのテンプレート自体はthemes/hugo-theme-cleanwhite/layouts/_default/list.algolia.jsonにあります。Algoliaに登録するデータの構造など変更をする場合はこのテンプレートをカスタマイズすれば良さそうです。\n検索関連の設定 実際に検索の画面を表示するために、検索用の画面と、検索用のAPIの設定が必要です。\ncontent/search/placeholder.mdの作成 /search/が検索用のページになります。空のファイルです。実際にはJavaScriptが検索用の窓を表示したりしてくれます(これが必要な理由がまだ不明だなぁ)。 検索用のAPIキーなどを設定 検索のためのAPIキーなどの設定が必要となります。テーマ作者の方のサンプルのconfig.tomlにパラメータは用意されています。 以下の値を設定します。\nalgolia_search = true algolia_appId = \u0026#34;AlgoliaのApplication ID\u0026#34; algolia_indexName = \u0026#34;作成したインデックス名\u0026#34; algolia_apiKey = \u0026#34;AlgoliaのSearch-Only API Key\u0026#34; 以上でAlgolia関連の設定などの作業が終了です。\nAlgoliaへのデータ登録方法 最後に、実際にデータを登録する必要があります。 手順は、以下のとおりです。\nhugoコマンドの実行(htmlと一緒に登録データのalgolia.jsonを生成) npm run algoliaコマンドの実行(atomic-algoliaを利用してAlgoliaにデータを登録) 設定などが問題なければ、Algoliaの管理画面で登録ができているはずです。 実際にブログのデプロイにはdeploy.shというファイルをこちらを元に作成して使っています。このなかで、hugoコマンド実行後にnpm run algoliaを実行するようにしいます。\n今後の課題 Hugoで生成された記事はそれぞれのブログポスト以外に、タグごとのページも生成されています。 こちらも実はAlgoliaのインデックスに登録されていて、タグを入力すると、タグ名のリンクが出てきます。\nこちらはelasticsearchで検索したときの検索結果です。1件目はタグページです。\nこれらのページはAlgoliaに登録しないようにするのが良さそうかな?と考えているところです(考えてるだけ)。\n2020/01/29更新\nlist.algolia.jsonを編集して、記事だけをインデックスするように修正しました。 テーマに存在するlayouts/_default/list.algolia.jsonを、自分のところにコピーし、次のように変更しました。if文を1行追加して、postという種類のものだけを出力するようにしました。\n{{/* Generates a valid Algolia search index */}} {{- $.Scratch.Add \u0026#34;index\u0026#34; slice -}} {{- $section := $.Site.GetPage \u0026#34;section\u0026#34; .Section }} {{- range .Site.AllPages -}} {{- if or (and (.IsDescendant $section) (and (not .Draft) (not .Params.private))) $section.IsHome -}} {{- if (and (eq .Section \u0026#34;post\u0026#34;) (ne .URL \u0026#34;/post/\u0026#34;)) -}} {{- $.Scratch.Add \u0026#34;index\u0026#34; (dict \u0026#34;objectID\u0026#34; .UniqueID \u0026#34;date\u0026#34; .Date.UTC.Unix \u0026#34;description\u0026#34; .Description \u0026#34;dir\u0026#34; .Dir \u0026#34;expirydate\u0026#34; .ExpiryDate.UTC.Unix \u0026#34;fuzzywordcount\u0026#34; .FuzzyWordCount \u0026#34;keywords\u0026#34; .Keywords \u0026#34;kind\u0026#34; .Kind \u0026#34;lang\u0026#34; .Lang \u0026#34;lastmod\u0026#34; .Lastmod.UTC.Unix \u0026#34;permalink\u0026#34; .Permalink \u0026#34;publishdate\u0026#34; .PublishDate \u0026#34;readingtime\u0026#34; .ReadingTime \u0026#34;relpermalink\u0026#34; .RelPermalink \u0026#34;html\u0026#34; .Params.Description \u0026#34;title\u0026#34; .Title \u0026#34;type\u0026#34; .Type \u0026#34;url\u0026#34; .URL \u0026#34;weight\u0026#34; .Weight \u0026#34;wordcount\u0026#34; .WordCount \u0026#34;section\u0026#34; .Section \u0026#34;tags\u0026#34; .Params.Tags \u0026#34;categories\u0026#34; .Params.Categories \u0026#34;author\u0026#34; .Params.authors \u0026#34;content\u0026#34; .Params.Description \u0026#34;excerpt_html\u0026#34; .Params.Description \u0026#34;excerpt_text\u0026#34; .Params.Description \u0026#34;summary\u0026#34; .Summary)}} {{- end -}} {{- end -}} {{- end -}} {{- $.Scratch.Get \u0026#34;index\u0026#34; | jsonify -}} まとめ これで、ブログ内記事検索ができるようになります。 Algoliaは個人の非商用利用の場合、フリープランが用意されているのがありがたいですね。 まだ、Hugoと連携しただけで、Algolia自体でどんな機能があって、どんなことができそうかといったところは調べていませんが、簡単に利用できるのはとても助かります。\nまぁ、個人ブログの検索機能ってそんなに使う人はいないんですが、自分としては便利かなぁと。\n","date":1580186404,"dir":"post/2020/","id":"d9018f459d3c94a91e92b459e152f7e7","lang":"ja","lastmod":1580283604,"permalink":"https://blog.johtani.info/blog/2020/01/28/introduce-algolia/","publishdate":"2020-01-28T13:40:04+09:00","summary":"ブログ移行日記(その4)です。その他の記事はこちら。 ブログ移行日記(その1) ブログ移行日記(その2) ブログ移行日記(その3) ブログ移行日記(","tags":["ブログ"],"title":"ブログ移行日記(その4) - 検索機能(Algolia)の導入"},{"contents":"ブログ移行日記(その3)です。その他の記事はこちら。\nブログ移行日記(その1) ブログ移行日記(その2) ブログ移行日記(その4) ブログ移行日記(その5) 今回は、Hugoの設定とテーマの一部変更した点について記載します。\n設定ファイル(config.toml) Hugoの設定ファイルはconfig.tomlになります。hogo new siteコマンドで生成したディレクトリの中にデフォルトで含まれていますが、こちらではなく、テーマの作者が用意してくれたconfig.tomlを元に変更を加えました。\nちなみにテーマの作者の方が設定とコンテンツを含めたサンプルも公開してくれています。設定やディレクトリの構成はこちらを参考にしました。\n設定ファイルで変更した項目は以下のとおりです。\nサイトのタイトルや説明など 特記することはありません。好きなように変えました。\nbaseurl title SEOTitle description keyword slogan sidebar_about_descrption 画像関連(ヘッダーや著者近影) 画像の置き場はstatic/images/ディレクトリですが、設定ファイルには images/から設定します。\nheader_image : ブログのヘッダー背景 sidebar_avatar : 著者近影 言語周り(特に多言語対応する予定は無いのですが) languageCode = \u0026ldquo;ja\u0026rdquo; defaultContentLanguage = \u0026ldquo;ja\u0026rdquo; オフにした機能、削除した項目 freands = false bookmarks = false 上記の設定変更以外に、[[params.bookmark_link]]や[[params.friend_link]]も削除。\n中国のサービスや、特化した設定など。\nBaidu Analytics関連 Disqus proxy関連 Reward(wechat pay \u0026amp; alipay関連) params.social関連 rss = true twitter linkedin github ほかはすべてコメントアウト。\n外部サービス関連 disqusShortname : Disqusのショートネーム googleAnalytics : Gooogle AnalyticsのトラッキングID algolia関連 : 別のブログ記事として、設定方法などを書きます。 追加した設定(昨日のブログで説明済み) Octopressと同じ形のパーマリンク [permalinks] post = \u0026#34;/blog/:year/:month/:day/:slug\u0026#34; Markdownファイル中のHTMLタグ表示 [markup.goldmark.renderer] unsafe = true 以上が設定ファイル関連です。\nテーマの変更点 テーマそのままでは問題があったり、独自に変更したいという点があったので、いくつか変更をしています。\nフォントの変更 そのままテーマを適用するだけでうまく行けばよかったのですが、フォントの問題が発生しました。テーマの作者の方が中国の方だから?かどうかはわかりませんが、デフォルトのままだと中華フォントになってしまいました。\nあー、中華フォントだな。 pic.twitter.com/OvHpY4LSp1\n\u0026mdash; Jun Ohtani (@johtani) January 16, 2020 config.tomlにcustom_cssという設定があり、こちらで指定したCSSのファイルがテーマのlayouts/partials/head.htmlから読み込まれる仕組みがあるようなので、フォントに関するCSSをこの機能を使用して指定するようにしました。\nconfig.tomlの設定は次のとおりです(リスト)になっているので、複数のファイルに分割して、読み込ませることも可能なのかな?。\ncustom_css = [\u0026#34;css/custom-font.css\u0026#34;] cssファイルについては、static/css/custom-font.cssというファイルを作成し、次のような記載になっています。 フォントの指定と右側サイドバーの自己紹介の部分の文字色を変更するためのものです。\nbody, h1, h2, h3, h4, h5, h6, .navbar-custom { font-family: Helvetica,\u0026#34;Sawarabi Gothic\u0026#34;,Meiryo,\u0026#34;メイリオ\u0026#34;,\u0026#34;Hiragino Kaku Gothic ProN\u0026#34;, \u0026#34;ヒラギノ角ゴ ProN\u0026#34;,YuGothic,\u0026#34;游ゴシック\u0026#34;,Arial,sans-serif; } .sidebar-container { color: #404040; font-size: 14px; } faviconの変更 テーマにfavicon.icoが含まれていたのですが、せっかくなので独自のものに変えてみようかと。 ただ、残念ながら、こちらはパスおよびファイル名がlayouts/partials/head.htmlに直書きされていました。\n画像はimages配下にと思っていたのですが、このパスだけを変更するためにhead.htmlを自分の配下にコピーしてカスタマイズするのもどうかと思った(テーマに変更やバグ修正が入るたびに手動でコピーするのはなぁと思った)ので、static/img/favicon.icoファイルを作成しました。\nテーマよりもHugoのプロジェクトにあるファイルを優先するようなので、ファイルだけをプロジェクトに作成しました。\n記事一覧のテンプレート 記事の一覧で表示される、作成者と作成日時が英語表記でかつ、冗長な感じがしたので、スッキリさせるために、layouts/partials/post_list.htmlをテーマからコピーして、次のように変更しました。\n元の形式は : Posted by author Monday, January 2, 2006 現在の形式 : 2006-01-02 by author 記事のテンプレート 今回採用したテーマでは、記事の先頭に記事のセクションを元に目次を生成してくれるものでした。\n目次をコンテンツから自動で作ってくれるの便利だな。 pic.twitter.com/9bU3sLnUrm\n\u0026mdash; Jun Ohtani (@johtani) January 16, 2020 とても便利です。ただ、表示が「TOC」なんです。 英語でしかも「ToC」という表記ならまだ気にならなかったかもですが、大文字だと流石に気になったので、プロジェクトのlayouts/_default/single.htmlにコピーして「目次」という日本語に書き換えました。 このHTMLにテーマで修正が入った場合はどうしようかなぁ。。。というのが目下の悩みです。。。\nArchetypeテンプレートの追加 最後は新規記事を書くときに生成されるMarkdownのメタデータの追加です。 HugoにはArchetypesというのが存在します。\nHugoではhugo new 記事としたときに、記事の種類(content/ディレクトリ名=記事のタイプ)によって、作成するmarkdownファイルをテンプレートから生成する機能があります。この生成時に使われるのがarchetypesというディレクトリにあるファイルです。\n私のブログサイトでは、今のところcontent/postというブログの記事だけを書く予定ですので、archetypes/post.mdというファイルを作って以下のようなメタデータをhugo newしたときに自動で生成するようにしました(テーマにあったpost.mdファイルの代わり)。\n--- layout: post title: \u0026#34;{{ replace .Name \u0026#34;-\u0026#34; \u0026#34; \u0026#34; | title }}\u0026#34; slug: \u0026#34;{{ substr .Name 11 }}\u0026#34; author: johtani date: {{ .Date }} comments: true tags: [] draft: true --- タイトルはファイル名のハイフンを空白に変換したもの(実際にはファイル名は英語にしているので、使いませんが。。。) slugはファイル名の先頭からYYYY-MM-DD-という11文字を除いたもの。これは、OctopressのURLに合わせるために使用するURLの一部の文字列です。 author: johtani : 著者は私だけだから固定文字列 comments: true : ブログ記事にはDisqusのコメント機能を利用 tags: [] : 各内容によってタグを付けるが、生成時には空 draft: true : 明示的にこの行を消すまではドラフト記事としたいため という感じです。ほかにどのよなメタデータがあるのかまではまだ調べていないので、今後また適宜変更していくと思います。\nまとめ Hugoの設定や、テーマそのままではなく独自の変更を加えた部分を思い出して書き出してみました。\nこれで、Algoliaに関する部分以外はだいたい思い出して書いたと思います。 次は、Algoliaの使い方と設定について書き残す予定です。\n","date":1579853081,"dir":"post/2020/","id":"99c9c80a6532e4ea3b535c5a92d07a25","lang":"ja","lastmod":1579853081,"permalink":"https://blog.johtani.info/blog/2020/01/24/setting-hugo/","publishdate":"2020-01-24T17:04:41+09:00","summary":"ブログ移行日記(その3)です。その他の記事はこちら。 ブログ移行日記(その1) ブログ移行日記(その2) ブログ移行日記(その4) ブログ移行日記(","tags":["ブログ"],"title":"ブログ移行日記(その3) - Hugoの設定と微調整(テーマに合わせた)"},{"contents":"その他の記事はこちら\nブログ移行日記(その1) ブログ移行日記(その3) ブログ移行日記(その4) ブログ移行日記(その5) ブログ移行日記(その2)です。前回はHugoとは?というのと、自分が選んだテーマについて記載しました。 本家の手順などを参考にすると、Hugoにテーマを適用し、でHTMLを生成して、表示するところまでできるはずです。\n今回は、OctopressのmarkdownファイルをHugo用に変換する方法について紹介します。お手製ですが、Pythonスクリプトを作ったので、そちらも合わせて簡単に紹介する予定です。\n参考ブログ 「Octopress Hugo 移行」でググるといくつか出てきます。先人の知恵ありがたいですね。 ということで、私はこちらの2つのブログを参考にさせていただきました。ありがとうございます。\nOctopress から Hugo へ移行した - iriya-ufo\u0026rsquo;s blog OctopressからHugoへ移行する方法 | gam0022.net 画像のコピー 画像はそのまま上記参考ブログを元にsource/imagesからstatic/imagesにコピーしました。特にディレクトリ構造の変更とかもしませんでした。\nコンテンツのコピー こちらは、コピーのタイミングでいくつか変換などの処理を行いました。 ファイルの変換にはPythonのスクリプトを書きました。 自分向けの移行ツールなんで、ディレクトリ名とか引数にすらしてないです。。。\n参考ブログと同様の変換\nメタデータの日付変換 categoriesをtagsに変換 画像タグの変換 タイトル、画像のサイズなどに合わせていくつか分岐があります。 参考ブログとは異なる変換、変更\nコードブロックは無変換 0.60.0からCode Fencesに対応したみたいなので不要でした。 ディレクトリ構造の変更 ファイルを年ごとのディレクトリに格納(これまでは、全てのファイルが同一ディレクトリにあった) 拡張子の変更 (.markdown -\u0026gt; .md) メタデータにauthorの追加(自分しか書かないんですけどね) URLをOctopressに合わせる Google検索からの流入もあり、これまでのURLに変更はかけたくないなと。 こちらも参考ブログに記載があるので、そのまま参考にさせていただきました。\nslugについては、移行ツールでファイル名を元に追加する処理を書きました。\nHTMLを含んだMarkdownの対応 TweetやAmazonのアフィリエイトのリンクがHTMLタグでいくつかの記事に含まれており、デフォルトの設定だと表示されません。 config.tomlファイルに以下の設定を追記することで、出力されるようになりました。\n[markup.goldmark.renderer] unsafe = true 名前がunsafeなので、ちょっと気になりますが。。。 すべての記事を表示してチェックしてみたわけではないので、おかしな記事を見つけた方は連絡をいただけると助かります。\nまとめ OctopressのファイルをHugo用にコピーや変換した方法を思い出しながら書いてみました。基本的には参考ブログに上げた2つのブログを真似したものになります。\n次は、利用したテーマのサンプル設定を元に、自分用に変更した点などについて書き残しておこうかな?\n","date":1579775514,"dir":"post/2020/","id":"018b365b00dd3a6ad17c813d21590549","lang":"ja","lastmod":1579775514,"permalink":"https://blog.johtani.info/blog/2020/01/23/convert-md-from-octopress-to-hugo/","publishdate":"2020-01-23T19:31:54+09:00","summary":"その他の記事はこちら ブログ移行日記(その1) ブログ移行日記(その3) ブログ移行日記(その4) ブログ移行日記(その5) ブログ移行日記(その2)","tags":["ブログ"],"title":"ブログ移行日記(その2) - Markdownファイルの変換"},{"contents":"その他の記事はこちら\nブログ移行日記(その2) ブログ移行日記(その3) ブログ移行日記(その4) ブログ移行日記(その5) 起因 いつものツイートから始まる私の行動です。\n(もしかしたら前に一度おすすめしたかもですが) Goのtemplate構文に拒絶反応がなければHugo割と良いですよ〜。\n\u0026mdash; Nobuyuki Kubota (@nobu_k) October 10, 2019 ってことで、Hugo勧められたし、テーマが豊富だしということで、乗り換えた次第です。\n(元)同僚に教えてもらった記事を見てる。Gatsbyも気になるんだけど、デザインセンスないし、テーマが豊富なのがいいなぁ。/ Comparison of Gatsby vs Jekyll vs Hugo | GatsbyJS - https://t.co/yUbKiBmtMS\n\u0026mdash; Jun Ohtani (@johtani) January 9, 2020 一応Gatsbyのサイトにあった比較も見たのですが、テーマの豊富さが勝ちました。デザインを自分でやれるほどではないので。\n理由 乗り換えるに至ったのは主に2つの理由です。\nOctopressが更新されていない ページが増えてきてサイトの生成に時間がかかる 前に使っていたOctopressもJekyllというものがベースになっていました。 Jekyllは今でも更新があるのですが、Octopressが更新されなくなってしまったのと、Rubyがベースになっているため?なのかはわかりませんが、 ブログのページ数が増えてきて、サイトのビルドに時間がかかってくるようになりました。\n結果 まだ、改良点があるかもですが、とりあえず公開できる感じになったと思ったんで切り替えました。\n前のブログはこんな感じで、\n移行後はこんな感じです。\nHugoとは? 公式サイト こちらにあるように、Go言語で実装されているウェブサイト構築フレームワークです。 Go言語で実装されているのもあり、インストールが簡単でした。 Macを使っていますが、Homebrewでインストールができてしまいます。 他の方法もあるようでしたが、Emacsをインストールするのにbrewを入れているので、brewでインストールしました。\n使い方は色んな人が書いてるし、公式ドキュメントを見ていただけばいいかな。\nテーマとは? Hugoのサイトにテーマの一覧があります。 一応、個人のブログなので、それなりにデザインを入れつつ、他の人と違う感じにしたいなと。 テーマ一覧をざっと眺めて良さそうなのをピックアップしたら、最終的にこちらのテーマになりました。\nClean White それなりに更新されてますし、DisqusとSearch(Algolia)が使えるのでこのテーマに決めました。 テーマのインストール方法などはGitHubのREADMEの「Quick Start」に記載があります。\n私は、Hugo自体の設定などをGitHubで管理したかったので、git submoduleを利用して、次のような構成になりました。\nhugo - main repository ├── archetypes ├── content ├── data ├── layouts ├── public - github.com/johtani/johtani.github.io ├── resources ├── static └── themes └── hugo-theme-cleanwhite - github.com/zhaohuabing/hugo-theme-cleanwhite.git hugo : hugo new siteコマンドで作成されたディレクトリです。このディレクトリでまずgit initしました(このリポジトリはプライベートで管理してます)。 themes/hugo-theme-cleanwhite : テーマのQuick Startにあるgit submodule addコマンドでサブモジュールとしてテーマをインストールしました。 public : hugoが生成するHTMLのトップのディレクトリがこちらです。私はGitHub pagesを利用してブログを公開しているので、git submodule addでjohtani.github.ioをサブモジュールにしました。 Hugoで生成したHTMLなどをGitHub pagesで公開するときの手順などはHugoのドキュメントに記載がありました。\nまとめ Hugoに移行した理由や、Hugoとテーマの簡単な紹介でした。 テーマが豊富なのはデザイン力(りょく)がない身としてはありがたいですよね。 次はOctopressのmarkdownファイルをHugo用に変換したり、それに関する設定周りの話を書く予定です。\n","date":1579659814,"dir":"post/2020/","id":"a65bd31d4c3dab0a41712823a5d6002b","lang":"ja","lastmod":1579659814,"permalink":"https://blog.johtani.info/blog/2020/01/22/intro-hugo-and-theme/","publishdate":"2020-01-22T11:23:34+09:00","summary":"その他の記事はこちら ブログ移行日記(その2) ブログ移行日記(その3) ブログ移行日記(その4) ブログ移行日記(その5) 起因 いつものツイートから","tags":["ブログ"],"title":"ブログ移行日記(その1) - Hugoとテーマ"},{"contents":"5年くらい、Octopressを使用していましたが、更新されなくなっているのと、コンテンツの生成に時間がかかることもあり、 ほかのプラットフォームを使用するように変更しました。\nとりあえず、今回の移行で参考にした記事とかURLをリストアップしてみました。 詳細についてはまた明日以降で。\n参考記事 移行関連 : https://iriya-ufo.net/blog/2018/12/27/octopress-to-hugo/#github-pages- 移行関連 : https://gam0022.net/blog/2016/09/25/migrated-from-octopress-to-hugo/ Hugo自体の日本語紹介記事 : https://knowledge.sakura.ad.jp/22908/ Hugo概要 https://gohugo.io/ テーマ 一覧 : https://themes.gohugo.io/ 利用したテーマ : https://github.com/zhaohuabing/hugo-theme-cleanwhite データ移行 作ったスクリプト : https://github.com/johtani/from-octopress-to-hugo favicon 作ったサイト : http://emblemmatic.org/markmaker/#/ Algoliaセッティング 参考 : https://blog.uni-3.app/2019/01/02/hugo-algolia-search/ GitHub Pagesでの運用 https://gohugo.io/hosting-and-deployment/hosting-on-github/#types-of-github-pages 残タスク Amazonのアフィリンクをきれいに表示するlayoutか何かを用意する? ","date":1579166617,"dir":"post/2020/","id":"3c299a4d77be8b4f886ce9fcd23a2561","lang":"ja","lastmod":1579166617,"permalink":"https://blog.johtani.info/blog/2020/01/16/moving-to-hugo/","publishdate":"2020-01-16T18:23:37+09:00","summary":"5年くらい、Octopressを使用していましたが、更新されなくなっているのと、コンテンツの生成に時間がかかることもあり、 ほかのプラットフォ","tags":["hugo","ブログ","octopress"],"title":"OctopressからHugoへ移行中(まだ途中)"},{"contents":"今年も振り返りブログ書いてます。Sasukeがついてる。\n振り返り(2018年に書いた抱負から) まずは去年の抱負を元に。\nTOEIC 受けました。\nお。TOEICの点上がってた(まだまだだけど。。。)\n\u0026mdash; Jun Ohtani (@johtani) October 21, 2019 無事、上がってました。テストの点数を上げるのが目的ではなく、今の実力が どんな感じかというのを確認するために受けました。 前回までが低かったのもあるんですが。 また、数年後に受けてみるのかな?\nCfP見つけて応募 \u0026amp; いろんな場所に顔を出す 色んな所には顔を出しました。 CfPはそれほど出せていなく、とちぎRubyとDevRelJPで喋った程度かと。 12月に最終出社日を迎えたので、今後は顔を出したりCfP見つけて応募も、 一旦休憩に入る予定です。\nもっとブログ! 12月に入ってから、一気に増えてますねw Elasticでは結局それほどかけなかったなぁ。\nRustの継続 こっちは、書籍も買ったのに手がついてないです。 来年に書籍を読みながら再入門する予定です。\n開発の継続 一応ほそぼそと続けてますが、メンテナンスですね。 Analyzer向けのKibanaのプラグインのバージョンアップにだけ対応していたり。 年初にReact化には着手しました。 あとは、Luceneにちょっとしたパッチ(Lukeの画面とKuromojiのUniDic対応)を送った感じかな。もっとLucene周りやりたいかな。\n日本でエンジニア獲得! トレーナーやエンジニアが入社してくれました! が、私が退職してしまいますが。。。 私自体が次のステップに移らないとなぁと。 Elasticに興味がある人いたら、中の人を紹介できるので声をかけてください!\n振り返り(今年あったできごと) さて、ここからは今年の出来事を。\n検索技術勉強会発足 勉強会運営座談会 初フロリダ 初カナダ\u0026amp;初ナイアガラの滝 退職(予定) 検索技術勉強会ってのをはじめました(はじめましたブログはこちら)。 やっぱり検索の話を聞いたり考えたりするのが好きなので、もっといろんな話を聞く機会がほしいなぁと。ツイートすると何人かの知り合いが手を上げてくれたので、初めて見たのが2月でした。 所属会社もあったので、自分が全面に出ない形で運営に協力するという形式でやっています。なんだかんだでもう4回も開催できています。スピーカーへの声掛けなど、複数人で運営するとそのあたりが多様性が出るし、楽になるのですごくいいなぁと。 来年も2月か3月にやりたいねと話をしているところです。興味のある方は、ぜひスピーカーを!\nで、その流れで、他の勉強会の運営ってみんなどうしてるんだろう? という疑問も出てきたので、勉強会運営座談会なるものもやってみました。少人数で集まって、勉強会の運営ってどんなやり方してます?どんなことに困ってます?みたいなのを共有してみました。 自分自身がそれほど、ほかの勉強会の運営に顔を出してたわけでもなく、やり方をみんなはどうやって共有してるのかなぁ?というのが気になったので。 思った以上に属人化してるのかもなぁというのが感想でした。 ドタバタしてたので、あれからやってませんが、共有する勉強会みたいなのも面白いのかも?\n今年も2回ほどElasticの社内イベントで海外に行かせてもらいました。 5月にフロリダと11月にトロントでした。 フロリダでは、NASAにも行けたし、トロントでは足を伸ばしてナイアガラの滝を見に行くなどもしてみました。こういう機会が定期的にあるのは、いいですよねぇ。\n最後は、退職イベントですね。5年5ヶ月勤めたElasticでの仕事が、12/6で最終出社日でした。実際の退職日は1/24となっています(現在有給休暇消化中)。長かったような、短かったような。日本で1人目で入社してさまざまなことをやらせてもらい、本当に色んな経験ができました。英語も上達したし。 ただ、外にいることでできることがありそうだなと感じたこともあってのこの決断でした。\n最終出社日以降、色んな人とランチさせてもらったりしています。 次に何をやろうかな?ってのんびり考えながら休んでいるところなので。 やっぱり、検索周りのことをやりたいなぁというのが念頭にあるので、そのあたりで模索中という感じです。 が、せっかくの機会なので、少しのんびりしようかなとも思ってます。 なので、プラモデルの作成や配達業(デス・ストランディング)をやってみたり、16インチMacbookのセットアップしながらブログ書いたりしています。 年明けに入ったら、プログラミングもちょっとやりたいな。\nあとこの場を借りて、ブログの欲しい物リストのものを送っていただいた皆様に感謝を述べさせていただきます。本当にありがとうございました!この感謝はまた何かの機会にでも!\n来年の抱負 ということで、来年の抱負です。\n職につく ブログプラットフォームの移行 プログラミング Rust再入門 検索の勉強 検索技術勉強会の継続 まぁ、まずは職につかないとですね。どこかに在籍しつつ、副業で検索周りのこととかやるのもありかもなぁと考えたりしています(プラモデルつくりながらw)。\nブログのプラットフォームをOctopressからHugoあたりに移行しようかなと思ってます。Octopress自体がもう開発がされてないようですし。Hugoだとテンプレート?テーマ?がそれなりにありそうなので良さそうかなぁと。移行プログラムも書かないとかな。新しいものを調べるのって楽しいですよね。\nプログラミングも復活させたいなと。どうしてもこれまでは、しゃべるのをメインにしていたので、後回しにしてしまっていたのもあります。まぁ、向いてないのかもと思ったりもしますが、下手の横好きなりに少しずつでも何かを改善したり作ったりしたいなと。 勉強会の運営周りですこし楽をするためのプログラム書いたりもしているので、この辺もブログに書こうかな?\nRustはTantivyというプロダクトも出てきているし、勉強しようと思って、自転車本を買いつつ、Kindleの肥やしにしているので、手を動かそうとおもいます。 ブログ書いてサボった場合の可視化しないとなw\n検索の勉強もやりたいなと。これまではElasticsearchに注力していましたが、ほかのプロダクトやサービスも調べてみたいなと。教えを請いに皆さんのところにお邪魔するかもしれないので、そのときは優しくしてください。\n今年始めた検索技術勉強会を今後も継続できるようにしたいなと。 で、運営周りを楽にできるような仕組みをもう少し導入できればなぁと考えていきたいなと思います。\nさて、嵐の曲も始まったし終わりです。\n今年も様々な方々に助けていただきました。また、最終出社日以降にランチを一緒にさせていただいたり、遊びに行かせていただいたりとありがとうございました。年明けもひましてるので、ぜひランチしましょうw\n来年はなにやってるんだろうなぁ? 今後も皆さんよろしくおねがいします!!\n","date":1577764743,"dir":"post/2019/","id":"35aa9e09db936aee7ec407c431816573","lang":"ja","lastmod":1577764743,"permalink":"https://blog.johtani.info/blog/2019/12/31/looking-back-2019/","publishdate":"2019-12-31T12:59:03+09:00","summary":"今年も振り返りブログ書いてます。Sasukeがついてる。 振り返り(2018年に書いた抱負から) まずは去年の抱負を元に。 TOEIC 受けました。 お。TO","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2019)"},{"contents":"このブログ書こうと思って、これまでMacのセットアップしてたんだった。。。\n普段、macOSの標準ターミナルを使ってます。 で、ターミナルを使うシーンは次のような感じです。\nブログのデプロイ(参考:Octopress環境のDockerイメージ化) ElasticsearchとKibanaの動作確認 Elasticsearchの起動用ターミナル Kibanaの起動用ターミナル プラグインの開発(elasticsearch-ingest-csv と analyze_api_ui) elasticsearchのリポジトリ kibanaのリポジトリ ingest-csvのリポジトリ analyze_api_uiのリポジトリ 上記のように1.以外については複数のターミナルをそれぞれのディレクトリで起動して使っています。 これらの3つのパターンのときに、毎回ターミナル(シーンによっては複数のウィンドウ)を開いて、ディレクトリに移動って大変だなと。\nウィンドウグループって? そこで、ターミナルに便利な機能がないのかな?と思い、メニューを見ていたところ「ウィンドウグループ」というのがあったので調べて、現在の使い方に至っています。\nウィンドウグループの使い方の説明はこちらです。\n使い方にあるようにウィンドウの場所、設定、タブなどを保存できます。 そして、「ウィンドウグループを開く」というメニューから保存しておいたグループを開くと、簡単に作業環境が再現可能になります。\n開くときのメニューはこんな感じです。\n作り方 ウィンドウグループの使い方に載ってます。 まずは、保存したいターミナルを開いて、開いたときに移動していたいディレクトリに移動します。 複数のタブやウィンドウを開いた状態にしたい場合は、複数ターミナルを起動して、それぞれ移動したいディレクトリに移動しておきます。\nグループとしてまとめたいウィンドウが起動できたら、あとは、「ウィンドウ」メニューの「ウィンドウをグループとして保存」を選択します。\nこれだけです。あとは、使いたくなったときに開くだけです。 簡単ですよね?\n作るときの注意点としては、複数のウィンドウグループを作りたいときは、 それぞれグループごとに作成しては、個別にやる必要があります。 現在開いているターミナルのうち、あれとこれをウィンドウにしたいというやり方はできないので、そこだけ注意点です。 環境ごとにプロファイル(バックグラウンドの色やテーマ)を覚えさせることができるので、1.のシーンだとIceberg、2.のシーンではBasic、3.のシーンではHomevrewで設定していたりします。 (ただ、Preztoのテーマをagnosterにしてしまったので、Basicだとプロンプトが見にくくてしょうがないのですが。。。)\n設定はどんな感じ?? ウィンドウグループの管理については、ターミナルの「環境設定」に管理用の画面があります。\nこの画面でいらないグループを削除したり、設定のエクスポート/インポートも可能です。\n私の使い方 3つの利用シーンは説明しました。 すべてのウィンドウグループを変更するたびにインポート/エクスポートしてます。 上記1.と3.のユースケースはほぼ変更がないので、エクスポートしたものを移植用に管理していますが、2.のユースケースについては、頻繁に更新しています(ElasticsearchとKibanaのバージョンをアップしないといけないので)。\nこのとき、MacのGUIで毎回設定をしているわけではありません。 エクスポートしたファイルは、.terminalという名のXMLファイルになっています。\nその中に、次のようなパスが記述されています。このバージョン番号の部分をアップデートのたびにemacsなどで変更し、ターミナルの管理画面で、削除してからインポートし直すだけで、バージョンアップに対応している感じです。\n\u0026lt;key\u0026gt;Tab Working Directory URL\u0026lt;/key\u0026gt; \u0026lt;string\u0026gt;file://johtani-mac-15.local/Users/johtani/tmp/elastic_stack/v7.5/elasticsearch-7.5.1/\u0026lt;/string\u0026gt; \u0026lt;key\u0026gt;Tab Working Directory URL String\u0026lt;/key\u0026gt; \u0026lt;string\u0026gt;file://johtani-mac-15.local/Users/johtani/tmp/elastic_stack/v7.5/elasticsearch-7.5.1\u0026lt;/string\u0026gt; まとめ ということで、標準ターミナルのウィンドウグループを使うと、よく開くディレクトリやウィンドウ、タブを覚えて置かせることができるので、それぞれの環境向けのターミナルを、好きなときに開くことができるようになります。 私は、ウィンドウは1つで複数のタブをウィンドウグループという形で覚えさせておくことで、各シーンの切り替え、もしくは併用を閉じたり開いたりを簡単にできるようにしています。\n他のターミナルソフトを使うと似たようなことが簡単にできたりするのかな? みなさんがどうやってこのような作業やってるのかな?ってのはちょっと気になるところです。\n余談(いつものようにツイートとその反応) ちなみに、みんなどんなターミナル環境なんだろう?と思いツイートしてみた結果はこちらです。 (コメントRTってうまいことひろえないのかなぁ?)\nMac標準のターミナル使ってる人ってどのくらいいるんだろ?iTermとか入れてるのかな?tmuxとか?\n\u0026mdash; Jun Ohtani (@johtani) December 11, 2019 Iterm2使ってtmux使って今はIterm2だなー\ncommand2回押すだけでターミナル出すくせが抜けん https://t.co/P8o4M1HSoj\n\u0026mdash; GO☆ | TAFDATA (@_gogoponz) December 11, 2019 Alacritty + tmux やなー。標準はもう使ってない。 https://t.co/HI7hPCg3uo\n\u0026mdash; Ryo HIGASHIGAWA (@biwakonbu) December 11, 2019 標準です https://t.co/W27e2pcq3j\n\u0026mdash; shin higuchi @Acroquest (@shin0higuchi) December 11, 2019 Macを買って以来、ずっと結局標準ターミナル以外使っていない感じ。珍しかったのか。。 https://t.co/Zjz32SgjC6\n\u0026mdash; Kazuhiro Hara™ (@kara_d) December 11, 2019 ","date":1577063679,"dir":"post/2019/","id":"1a1a8cc0040b356d06eacd22e0526476","lang":"ja","lastmod":1577063679,"permalink":"https://blog.johtani.info/blog/2019/12/23/whats-window-group-of-terminal/","publishdate":"2019-12-23T10:14:39+09:00","summary":"このブログ書こうと思って、これまでMacのセットアップしてたんだった。。。 普段、macOSの標準ターミナルを使ってます。 で、ターミナルを使う","tags":["misc"],"title":"macOS標準のターミナルのウィンドウグループが便利"},{"contents":"ドットファイル系(.emacsとか)をこれまでは、PCを引っ越すたびにコピーしてたんですが、いいかげん、GitHubとかで管理したいなと。\nで、ツイートしたところ(こればっかりだなw)、homeshick(homesick)が便利だよとの情報を得たので使ってみました。\nhomesick、正確にいうとhomeshickを使ってます。悪くないです\n\u0026mdash; 🤓k.bigwheel🤓 (@k_bigwheel) December 10, 2019 使い方とか 実物はGitHubで公開されていました。\nhttps://github.com/andsens/homeshick\n何者かというと、ホームディレクトリにあるドットファイル(.zshrcなど)をgitコマンドで管理するのを楽にしてくれるシェルの関数群みたいです。 インストールは至ってかんたんで、git cloneで持ってくるだけです。homeshickのリポジトリのREADMEに記載があります。\n使い方はTutorialsにあります。\nhomeshick generate ほげほげで管理する単位(castle)を作ります。ほげほげが名称です。今回私はdotfilesにしました。 homeshick track ほげほげ .zshrcで管理したいファイルを指定します。すると、homeshickが対象のファイル(ここでは.zshrc)をcastleの保存先ディレクトリにコピーしてから、シンボリックリンクをホームディレクトリ上に作ってくれます。 homeshick cd ほげほげで、castleの実際のディレクトリに移動します。実態は.homeshick/repos/ほげほげです。 git remoteコマンドでcastleとGitHubの関連をつけて、あとは、普通にgitコマンドでコミットしたりすればOKです。 すごく簡単に導入できました。あとは、実際にtrackしたいファイルを追加していく感じです。 現状は、.zshrc、.gitconfigあたりを管理しています。 ついでに、homebrewでインストールしたものもbrew bundle dumpで出力して、homeshickで管理することで、brewでインストールしたものの管理もできそう(参考)。\nってことで、至極かんたんでした。すばらしい。\n参考 homeshick Tutorials Qiita : homeshickを使ったdotfilesの管理 ","date":1576624266,"dir":"post/2019/","id":"80c8fca02ebfecc7a931dad1ec38466e","lang":"ja","lastmod":1576624266,"permalink":"https://blog.johtani.info/blog/2019/12/18/introduce-homeshick/","publishdate":"2019-12-18T08:11:06+09:00","summary":"ドットファイル系(.emacsとか)をこれまでは、PCを引っ越すたびにコピーしてたんですが、いいかげん、GitHubとかで管理したいなと。 で","tags":["misc"],"title":"homeshick導入"},{"contents":"Macbook Proが新しくなり、OSがCatalinaになっちゃいました。 これまで使ってた、.bash_profileをコピーしてターミナルを立ち上げたところ、 なんか色々と設定が動いてないな?と思ったら、zshがデフォルトに切り替わってました。\nということで、デフォルト変わったし、時間あるしzshってどんな感じなのか調べてみようと。\n準備前(ツイート) で、ツイートをしたところ、海外の方?より返信が来ました。\nI have a series of posts explaining the transition: https://t.co/dz8QNjxxGf\n\u0026mdash; Scripting OS X (@scriptingosx) December 10, 2019 おもしろそうなので、ざっくりと読んでみました。zshを利用されているTwitterの知り合いの何人かからはzsh + oh-my-zshがいいよとコメント頂いてたんですが、\nMoving to zsh Catalinaからzshがデフォルトになるからと、手元の環境を変更するための話をブログにまとめてくれてます。\nMoving to zsh\nサラッと読んだので、いくつか抜粋すると\nbashでいくつか今設定しているものがあるのでその説明 alias - ファイルをそれぞれの拡張子ごとにアプリを切り替えてる(openコマンドの利用例があって参考になりました)。 functions - manコマンドのときに新しいWindowひらいたりとか shell settings - 大文字小文字関係なくファイル名をTabで候補を表示したり、historyをターミナル個別ではなく共有できるような設定にしたり prompt - 現在のディレクトリがどこかとか表示したり zshの設定ファイル群の説明 shellオプションの抜粋 といった感じでした(途中で読むのやめましたが。。。)\n面白かったのは、Suffix Aliasesです。 ファイル名だけをターミナルで指定すると、拡張子に応じて起動するコマンドを切り替えたりできると(結局まだ採用はしてないですがw)\n結局? 結局、上記ブログを読んでいろんなオプションあるんだなぁ。と思ったのですが、手っ取り早く試すためにPreztoをインストールしました。 以下のような構成になってます。\nなるほど、これがzsh + prezto + powerline fontか。前までgit-promptを拾ってきてbashに組み込んでたけど、ブランチ表示されるし便利だな。 pic.twitter.com/Z2ArBgRZey\n\u0026mdash; Jun Ohtani (@johtani) December 12, 2019 Mac標準ターミナル Iceberg プロファイル Powerline font Prezto agnoster theme - prompt agnoster or ~/.zpreztorc の変更 .zshrcにいくつかaliasなどを追加。参考:gist Preztoのデフォルトでlessなどからエディタを立ち上げるとnanoが起動したので、vimに変更 Preztoが作る設定と自分の設定を混ぜたくなかったので、.zshrcでinit.zshを呼び出し になりました。フォントサイズだけはちょっと大きくしました(老眼ェ。。。) ターミナルの参考にさせていただいたブログは「preztoでzsh構築した時のメモ 」です。\nターミナルソフト(余談?) terminalも人によっては、色んなものを使ってたなと思いツイートしました。 結構みなさん標準のterminalを使ってるみたいでした。ただ、私が聞いたこともないターミナルソフトもちらほらあったので、色々あるんだなぁと。\nMac標準のターミナル使ってる人ってどのくらいいるんだろ?iTermとか入れてるのかな?tmuxとか?\n\u0026mdash; Jun Ohtani (@johtani) December 11, 2019 ","date":1576542903,"dir":"post/2019/","id":"f3ef819656f68b87a91c53afbd441fec","lang":"ja","lastmod":1576542903,"permalink":"https://blog.johtani.info/blog/2019/12/17/move-to-zsh/","publishdate":"2019-12-17T09:35:03+09:00","summary":"Macbook Proが新しくなり、OSがCatalinaになっちゃいました。 これまで使ってた、.bash_profileをコピーしてターミナルを立ち上げ","tags":["misc"],"title":"zshへの移行"},{"contents":"最近使っていたPCが手元からなくなったので、16インチ Macbook Proをセットアップしているところです。 で、時間もあるのでこれまでほったらかしてきた、このブログの環境をちょっと変更しようかなと。\nまずは、変更するにしても、Octopressのブログの環境自体は必要です。 実際に、移行する前のこの記事自体も書いているわけですし。\nただ、今後なくなる環境をローカル環境にセットアップするのもどうかと思い、Docker環境にしてみました。\n参考 \u0026ldquo;Octopress Docker image\u0026quot;でググって出てきたサイトを参考にしました。\n参考ブログ:Octopress in a Docker Container\nセットアップからDockerイメージのビルドまで Docker for Mac自体もインストールしていなかったので、インストールしておきます。 参考ブログの方がGitHubのリポジトリにDockerfileをアップしてくれているので、手順に従い、cloneします。 cloneしたDockerfileの3行目にENV LC_ALL C.UTF-8を追加します(UTF-8でブログを書いており、previewした場合にエラーが出たため) 参考ブログにある「Build the docker image」の手順に従い、Gemfile、.gitconfigをコピーしてイメージをビルドします。 参考ブログの「Rakefile」にあるように、自分のoctopress/RakefileのProcess.spawn(...)にアドレスを追加します(Dockerコンテナの外からアクセスできるように) 自分のoctopressにあるGemfile.lockを削除しました(ビルドしたイメージにはいるGemと一部バージョンが異なる記載のものがあったため) ここまでで、\nDocker run 実際にコンテナを実行するためのスクリプトを書きました(書いたと言っても参考ブログにある起動コマンドを叩いてるだけですが。。。)\nlaunch-octopress-docker.shというファイル名で以下のコマンドを実行してるだけです。\n!/bin/sh docker run -p 4000:4000 --rm --volume /Users/johtani/projects/blog/octopress:/octopress --volume /Users/johtani/.ssh:/home/blogger/.ssh -ti blog/octopress /bin/bash このシェルを起動すると、Dockerコンテナにbashで接続し、/octopressディレクトリにログインしています。 あとは、いつものようにrake new_post[\u0026quot;....\u0026quot;]で新規記事のテンプレートを作成したりすればOKです。\nrake generate; rake previewと実行してからローカルのブラウザでhttp://localhost:4000に接続すればプレビューも可能。\nということで、このDockerファイルとかを持っておけば、他の環境でもかんたんにOctopressの環境が再現できそうです。 先人の知恵有り難し。 これで、クリーンなまま他のブログ環境に移行できそう。\n追記(2019/12/17) Docker環境でいくつか問題があったので、追記しておきます。\nDocker for Macが再起動しない Docker for MacがCatalina環境だと問題があるみたいでした。 CPUの数やメモリの数を変更してDockerを再起動したところ、ずっとStartingのまま。\n解決方法としては、launchctlの設定に$PATHを追加するみたい。これで、問題なく起動するようになった気がする\nsshの設定ファイルの問題 .ssh/configにMacのKeyChainを利用する設定を記載してるんですが、Ubuntu上だとこの設定のせいで、エラーが出てしまいます。 IgnoreUnknownという設定で、知らないオプションがあったら無視するという設定になる模様。ということで、Dockerコンテナ上でrake deployのときにエラーが出てたのが解消できました。\n","date":1576458061,"dir":"post/2019/","id":"1abc586d67f0b6c05fd5e60f25492340","lang":"ja","lastmod":1576458061,"permalink":"https://blog.johtani.info/blog/2019/12/16/dockernize-octopress/","publishdate":"2019-12-16T10:01:01+09:00","summary":"最近使っていたPCが手元からなくなったので、16インチ Macbook Proをセットアップしているところです。 で、時間もあるのでこれまでほったらかしてきた","tags":["octopress"],"title":"Octopress環境のDockerイメージ化"},{"contents":"本日、Elasticでの最終出社日でした。実際の退職日はまだ先ですが、有休消化という感じです。\n思い返せばもう5年と5ヶ月も前ですが、Elastic(当時はElasticsearchって社名だった)に参加しました。\n社名も変わりましたし、プロダクトの数も増えたし、IPOもしました。 初の外資+スタートアップということもあり、ものすごくエキサイティングな5年半でした。 Elasticを離れはしますが、検索自体にはまだまだ興味があるので、LuceneやElasticsearchになにかしら関わる感じのことをする予定です。 検索技術勉強会も今後もやっていきますし。\nただ、激動の5年半だったので、退職日までちょっとゆっくりしようと思っています。 次にどんなことをするのかはまた、別の機会にでも。\nおまけ ということで、まぁお約束です。\nほしい物リストはこちら\n","date":1575615090,"dir":"post/2019/","id":"1bbf2ef67f096960e13d8578fa544536","lang":"ja","lastmod":1575615090,"permalink":"https://blog.johtani.info/blog/2019/12/06/leaving-elastic/","publishdate":"2019-12-06T15:51:30+09:00","summary":"本日、Elasticでの最終出社日でした。実際の退職日はまだ先ですが、有休消化という感じです。 思い返せばもう5年と5ヶ月も前ですが、Elas","tags":["転職"],"title":"退職します"},{"contents":"これは、情報検索・検索エンジン Advent Calendar 2019 の 4 日目の記事です。\n1日目から、質の高いエントリーが続いていましたが、一旦休憩して頂く感じの記事になってます。気軽に読んでくださいw。Advent Calendarつくらないの?と煽ったのもあり、穴を埋めようかなと。 発端 ちょっと先ですがこういうのやります。実装寄りの話やOSS開発に興味がある方,きてください~ / Lucene 版 #Kuromoji のコードを読む会(辞書ビルダー編) https://t.co/NgEmUohoPo #kuromoji\n\u0026mdash; Tomoko Uchida (@moco_beta) September 6, 2019 「Lucene 版 #Kuromoji のコードを読む会(辞書ビルダー編)」という勉強会があり、参加したところ、UniDicの辞書のビルドがコケるという話を聞いたんで、ちょっとやってみるかと。\nちなみに、Kuromojiとは、Apache Luceneに入っている、日本語向けの形態素解析ライブラリです。IPAdicの辞書を内包しており、SolrやElasticsearchといった、Apache Luceneを利用している検索エンジンで手軽に使える形態素解析ライブラリになっています。が、対応している辞書がデフォルトだとIPAdicなのです。\n問題点 LUCENE-4056というIssueが上がっています。\nbuild.xmlには記載はないけど、辞書のビルダーは対応していそうな雰囲気を醸し出しているので、試してみたというのが発端?かと。で、実際に動かしてみると動かない点がありましたと。\nまた、Issueの会話で出ていたUniDicの辞書のライセンスの話もありました。 ただ、UniDicがライセンスを変更したので、このあたりはクリアできそうかなと。\nパッチ ということで、動かしてみていくつか修正してパッチを作りました。\nhttps://github.com/apache/lucene-solr/pull/935\n最近のLuceneはGitHubでプルリク遅れるのが便利ですね。 そんなに大したことはやってないです。以下の点が問題だったので直しています。\nIPAdicとUniDicで語彙定義ファイルのCSVの形式(カラムの数)が異なる unk.defのカラム数も異なる あとは、辞書のダウンロードの部分やbuild.xmlでの処理を追加した形です。 このプルリクを適用したlucene-solrのソースディレクトリを持ってきて、手元でjarをビルドすれば普通はIPAdicの辞書を内包したkuromojiのjarファイルが出来上がります。\nlucene/analysis/kuromoji/build.xmlファイルを、このGistにあるように変更して、ant build-dictとやれば辞書のビルドが可能です。 また、cd lucene/;ant jarとすれば、UniDicの辞書を内包したjarファイルもビルドできます(lucene/build/analysis/kuromojiの下にjarファイルができあがります)。\n確認? 一応、パッチは動くのですが、パッチ自体はUniDicの辞書をビルドする仕組みはオフのままです。なので、テストをどうやろう?というところでやなんで止まっています。。。\nただ、実際に作ったパッチできちんとIPAdicとUniDicがそれぞれビルドできているかの確認はしないとなと。\nということで、2つのjarファイルを読み込んで、それぞれトークナイズして、その出力を表示するツールを作ってみました。\n上記パッチを適用したlucene-solrのソースを持ってきて、IPAdicの辞書を内包したkuromojiのjarファイルと、UniDicの辞書を内包したjarファイルを用意し、ツールの支持に従って、ファイルをディレクトリに配置して、実行すれば以下のような出力がされるようになっています(とりあえず作ったものなので、Javaファイルにトークナイズしたいテキストを書かないといけないのですが)。\nたとえば、「自転車と自動車の違いはなんでしょう?」という文字列を入力すると、以下のような出力になりました。\n+++ ipadic ++++++++++++++ token[0] is [自転車] token[1] is [と] token[2] is [自動車] token[3] is [の] token[4] is [違い] token[5] is [は] token[6] is [なん] token[7] is [でしょ] token[8] is [う] +++ unidic ++++++++++++++ token[0] is [自転] token[1] is [車] token[2] is [と] token[3] is [自動] token[4] is [車] token[5] is [の] token[6] is [違い] token[7] is [は] token[8] is [なん] token[9] is [でしょう] UniDicは[短単位]で語彙が扱われるため、「自転車」や「自動車」がそれぞれ「自転」「車」、「自動」「車」という形でトークナイズされていることがわかります。\nどちらがより便利なのか?というのは用途によっても変わってくるかと思いますが、検索の転置インデックスとしては、より短い単語で区切られている方が、より多くの文書にヒットする可能性が高くなるので、便利な可能性が高いです。\nまとめ ということで、パッチを作ってみたものの、まだ取り込まれていない状況です。 着地点をどうするかって話かなと思っています。興味があれば遊んでみていただければと。\n将来的には、辞書をjarから切り離して別のディレクトリやjarとして使えるようにしようというIssueも作られています。こちらがすすめば、UniDicだけでなく、その他の辞書を切り替えながら使えるようになる日が来るのではないでしょうか?\n","date":1575385200,"dir":"post/2019/","id":"c2d39f2f7fe6cb69fc8efb6c5495c932","lang":"ja","lastmod":1575385200,"permalink":"https://blog.johtani.info/blog/2019/12/04/about-lucene-4056/","publishdate":"2019-12-04T00:00:00+09:00","summary":"これは、情報検索・検索エンジン Advent Calendar 2019 の 4 日目の記事です。 1日目から、質の高いエントリーが続いていましたが、一旦休憩して頂く感じの記事になって","tags":["Lucene"],"title":"Apache LuceneのKuromojiのUniDicビルド対応パッチについて"},{"contents":"Elastic stack (Elasticsearch) Advent Calendar 2019の1日目の記事になります。\nまだ、1ヶ月を残してますが、簡単に今年起こったことを振り返ってみようと思います。毎年恒例ですね、ここ数年。\nElastic Stack 6.6.0リリース(1月) リリース記事はこちら\nElastic APMが6.6のリリースと同時にElastic CloudでAPM Serverが無料で利用できるようになったのが地味に便利でした。APMのデモをやるために、それまでは手元にAPM Serverの起動が必要だったので。。。\nユーザーの方たちにはIndex Lifecycle Management(インデックスライフサイクル管理:ILM)がリリースされたのが便利だったと思います。 まだ、ベータでしたが、インデックスの世代管理を格段に便利にしてくれるツールになり、現在では必須アイテムとなっています。 もう一つ、地味に便利なのは、KibanaからElasticsearchへの接続を複数指定できるようになった点かと思います。\nElatic Common Schemaのベータリリース(2月) リリース記事はこちら\nElastic Stackではメトリック、APM、ログなど、様々なデータを一元的に可視化することができるという利点があります。ただ、一元的にデータを可視化、検索するためには異なるデータセットに統一されたフィールド名が欠かせません。そのための手段としてElasticが公開したのがElastic Common Schemaです。 各種データの項目名、型などを共通化する仕様をGitHub上で公開しています。最近のBeatsのモジュールはこのElastic Common Schemaに則ってデータが定義されるようになってきています。これにより、ログからメトリックへ、APMからログデータへというシームレスな移動ができるようになっています。\nElastic Stack 6.7.0リリース(3月) リリース記事はこちら\nElastic MapsやUptimeといった、これまでの可視化とは異なる便利なアプリが増え始めました。Mapsでは地図の表現が格段にアップしたので、コレまで以上に地理情報と合わせた可視化が楽しくなりました。\nもちろん、基本的に必要な技術が着実にGAされていくのもElastic Stackの素晴らしい点です。\nIndex Lifecycle Management(ILM)がGA Cross Cluster Replication(CCR)がGA CanvasがGA Logs \u0026amp; Infra UIがGA Elastic Stack 7.0.0リリース(4月) リリース記事はこちら\nメジャーバージョンのリリースです。 KibanaのUIが刷新されたり、Elasticsearchのクラスター管理の機能が新規に構築されたり、様々な改善がこのリリースでも入っています。また、メジャーバージョンのリリースのタイミングが、さまざまな大きな仕様の変更や改善が入るタイミングでもあります。これまで以上にパフォーマンスが改善(Top-Nクエリ高速化など)されたり、新しい機能の追加(ナノ秒のサポート)されたりしました。\nElasticsearchのセキュリティの主要な機能が無料に(5月) リリース記事はこちら\n6.8.0および7.1.0のリリースはこの機能の無償提供となりました。 結構衝撃的な話だったのではないかなぁと。これ以前は有償の機能だったセキュリティの以下の機能をElastic License配下で無料で提供する形に変わりました。まだ、ご存知でない方は、データの安全のためにもセキュリティ機能を利用することをおすすめします。\nTLSによる通信暗号化 ユーザー作成と管理にファイルおよびネイティブのレルム認証を使用可能 クラスターAPIとインデックスに対するユーザーアクセスの管理にロールベースのアクセス制御を使用可能、またSpaces機能でKibanaのマルチテナンシーの安全性を向上 Elastic{ON}19開催(5月) 今年も東京で開催しました。ビデオなどはこちらで公開されています。 https://www.elastic.co/elasticon/tour/2019/tokyo\n今回も偉そうにElatic Stackの新しくなった点を紹介するなどしてました。。。\nElastic Stack 7.2.0リリース(6月) リリース記事はこちら\nElastic SIEMがベータリリースされたのがこのタイミングです。 2月の発表したElastic Common Schemaをフルに活用していると言ってもいいのがこの機能になります。まだ今後もどんどん改善が入るであろうきのうになります。\nまた、Elasticsearchをバックエンドにした検索ミドルウェアとして利用いただけるElastic App Searchのセルフマネージド版もこのタイミングでリリースされています。\nさらに、このリリースの直前にはElastic Cloud on Kuberunetes(ECK)というものベータリリースされました。少しわかりにくいかもですが、ElasticsearchやKibanaをKubernetesのOperatorとして利用できるようになっています。こちらもElastic Licenseでリリースされているのでk8s上でKibanaやEsを管理しようとしている方は触ってみると面白いかもです。\nElastic Cloud Elasticsearch ServiceがGCP日本で利用可能に(7月) リリース記事はこちら\nElastic Cloudもプラットフォームが拡大した年でした。 Google Cloud Platformの東京リージョンを選択できるようになりました。さらなる統合(支払いをGCP経由にまとめたり、GCPのコンソールから利用できたりなど)も進んでいます。\nElastic Stack 7.3.0リリース(8月) リリース記事はこちら\nデータフレームと呼ばれるデータ取り込み時のピボット機能が導入されました。また、MapsのGAリリース、Elastic APMの.NETエージェント正式リリースなど、細かいですが様々なものがリリースされています。\nElastic Cloud Elasticsearch ServiceがAzureで利用可能に(9月) リリース記事はこちら\nMicrosoft Azureへのデプロイも可能になりました。残念ながらまだ日本リージョンには来ていないですが、今後出てくるはずです!さまざまなクラウドベンダーのサポートにより、より多くの人に使っていただけるようになるのかと。\nElastic Stack 7.4.0リリース(10月) リリース記事はこちら\nもう7.4.2まで出ていますが、いい感じの間隔で7.0、7.2、7.3と来ていますね。 7.4では、スナップショットリストアがKibanaから簡単に行えるようになりました。これまではKibanaのConsoleでJSONを見ながら管理されていたかもですが、GUIにより今どんなスナップショットがあるのか、どれをリストアするのかといった操作が簡単にできるようになっています。\nKibanaについてはPKI認証のサポートなども始まり、様々な認証方式でより便利にKibanaが使えるようになっています。\n12月? 12月ですし、Elasticsearch勉強会では「LT&忘年会」ということで、懇親会がメインの勉強会として12/6に開催します。悪路クエストの緑川さん、吉岡さんに主体となっていただき、マイクロソフトさんを会場に借りて開催予定です。興味のある方はぜひご参加ください。 LTもおまちしています!\nまとめ 駆け足でしたが今年を振り返ってみました。 今年も色々ありました。残すところあと1ヶ月です!\nさて、Elastic Stack Advent Calendar 2019は今日から25日まで続きます。今年はその2もできています!こらからの記事を楽しみにしています! 本日はその2で[kaibadash@github]さんが「5分でできるElastic stack環境構築」というのを書いてくれてるはずです!\nということで、次はKunihikoKidoさんの「 Elastic Cloud を使うようになって設計方針やら変わったことについて書きます。」になります。お楽しみに!\n","date":1575126000,"dir":"post/2019/","id":"78da47d61c91c82809a3c97a791d26d2","lang":"ja","lastmod":1575126000,"permalink":"https://blog.johtani.info/blog/2019/12/01/whats-happen-at-elastic-in-2019/","publishdate":"2019-12-01T00:00:00+09:00","summary":"Elastic stack (Elasticsearch) Advent Calendar 2019の1日目の記事になります。 まだ、1ヶ月を残してますが、簡単に今年起こったことを振り返ってみようと思います。毎年恒例ですね、","tags":["elasticsearch"],"title":"2019年のElastic StackとElastic"},{"contents":"Bonfire Data \u0026amp; Science #1にブログ枠で参加してきました。 ということで、メモです。\n日時 : 2019/10/25 19:00 - 21:30 場所 : Yahoo! Japan サイト : https://yj-meetup.connpass.com/event/148121/ ハッシュタグ: #yjbonfire 概要 Data \u0026amp; Scienceとは? データとサイエンスに関わる人達の情報共有のための勉強会/交流会\nサイトから引用です。\n第1回のテーマは「画像検索」です! 最近EC系のサイトで類似画像検索が出来るようになったけどどうやってるの? 画像検索のモデルってどうしてるの? 画像検索のインフラはどうしてるの? 私たちの会社でも画像検索を用いたサービスを構築できるだろうか? こういった疑問に答えたり、いま抱えている悩みを解決するヒントを得る場になればと思っています。 今回は、画像検索を行なっているヤフー, メルカリ, ZOZOテクノロジーズの3社に事例と基盤技術について登壇いただきます。 QAはこちら。https://app.sli.do/event/w3wayjmv/live/questions\nMercari画像検索について(仮) 発表者:荒瀬晃介(株式会社メルカリ / AIエンジニアリングチーム)\nAIエンジニアチーム\n写真検索プロジェクトのTech Lead\niOSのみで提供の写真検索\nシステムオーバービュー\nMobileNet v2で特徴抽出 ANNのインデックスを使ってDBに入れる 論文も発表済み(3本)\n今日の発表はこの内の2本を元に話をします。 C2Cでの問題点 商品は床やテーブル上で撮影 クエリは着用(着ている)画像が使われやすい。 人が写ってる写真が結果に多いと業者が出展しているように見えてしまう。 提案手法 人が写ってるものから人の代表ベクトルを抜き取る (クエリ時にのみ処理を実施しているので変更が容易) 特徴変換ベクトル トップスなど、分類ごとに学習させてからベクトルを構成 なんでMobileNet v2? エッジデバイスでの処理を見据えて選択 インフラ Docker + k8s\nCRDを使ってる?\ntraining\nコンテナベースパイプライン いくつかのバッチ処理を工程ごとにパイプライン化 バッチ実行情報をカスタムリソースとしている=再実行が簡単(復旧作業が容易) 画像を扱う=ダウンロードが時間がかかる -\u0026gt; 復旧しやすいようにPVにある程度キャッシュさせている Serving\u0026hellip;\nGCP側 なぜ2つに別れてるんだろう?実際のサービスも2つに分かれてたりするんだろうか?\n将来の展望 Realtime Image Search カメラでものを写している状態でそれが何かを検索できる。 物体検出+特徴抽出をエッジで行うためできる エッジの性能により違いが出てきたりするっぽい QA Q: 業者が想定されると、購入意欲を下げるというのは実験した結果?それとも想像? A: 実験はしていないが、e-commerceにおいての研究がある Q: どういう理由でマルチクラウドにしたんでしょう? A: 画像のマスターがAWS。メルカリのマイクロサービスはGKEなので、サービング環境がGCP Q: 画像の内、服のエリアが大部分で体の面積が少ない場合と、メガネや帽子のように、アイテムの方の面積が少ない場合で、トレーニングに必要なデータ数は変わりましたか? A: カテゴリによる性質の違うはある。ので、改善は必要。 ZOZO画像検索について(仮) 発表者:平田拓也(株式会社ZOZO / AIエンジニアリングチーム)\n(聞き逃した。。。)\nWEAR\nマルチサイズ\nチーム構成 研究所+ML Opsチーム 使用しているアルゴリズム 物体検出アルゴリズム 特徴量抽出アルゴリズム 近似最近傍探索(approximate nearest neighbor, ANN) インフラ GCPを採用。 BigQuery上にデータ基盤がある Managed GPUが必要 なんでk8s? コンテナ Cloud Runがなかった アーキテクチャ マイクロサービス化されている Google Cloud Next 2019 Tokyoでsonotsさんの発表があるよ 監視項目 CPUなどは見ていない レスポンスタイムとステータス監視 リクエスト数 APM 使ってるものStackdriver + Datadog + Sentry Warningが30分で続けたら通知などができるのがStackdriver 画像検索の改善のためにやっていること 課題 レイテンシーが大きい 推論が大変? 急激なトラフィックの増加に対応できない GPUのスケールアウトが問題 -\u0026gt; 先行投資が必要 流れ キャッシュありなし 物体検出 (GPU) 特徴量抽出 (GPU) 近似最近傍探索 DBから取得 2と3が問題\n2と3を特徴量DBという形でデータが登録された時点で特徴量などを計算してしまうことでGPUへの依存をなくした。 Apache AirFlowが便利? Cloud ComposerとApache AirFlow Cloud Composerに関するいくつかのTipsがありました。\nQA Q: 推論をCPUでやったらどれぐらい遅いんだろう A: GPUインスタンス代金 \u0026lt; それと同等の速度を出すためのCPUインスタンス代金 Q: k8sスケールアウト時のリソース割当を最適化する為、resource limit / request標準化 or 時系列分析などから自動調整するなどはされていますか? A: \u0026hellip;聞き逃した Q: (TCOを考慮したクラスタ構成) Cloud Composerの値段が高いようなパプリッククラウド利用の課題対策としてプライベートクラウドとのハイブリッド構成にされているのでしょうか?もしハイブリッド構成でしたら、パブリック or クラウドを切り分ける基準はございますか。 A: GKEオンリー Q: cloud composerでairflowを使う辛い点は? A: 不安定さ。。。 Yahoo!ショッピングにおける画像検索(仮) 発表者:佐藤 純一(ヤフー株式会社) 商品検索APIの開発とか検索エンジンの保守とか 類似画像検索システムの開発が直近の仕事 類似画像検索 ヤフーショッピング 3億の商品 ファッション系はビジュアルが重要=言語による表現が難しい iOSとAndroid Androidだとカメラで撮影してから検索みたいなことも可能 システム概要 物体検出 ノイズ除去 特徴抽出 インデックス(NGT) -\u0026gt; https://github.com/yahoojapan/NGT 1000万件を超える 検索 アプリの画像をAPIに投げてベクトルから、近いものn件を取得 ベクトル化/インデックス更新 GPUマシン Kafka使ってる クラウドストレージに日次?バックアップみたいに保存 差分更新の仕組みがある メンズとレディースは分けている 絞り込み検索のために分離(インデックスのメタデータとしてタグがある) システム構成 Python Kafka TensolflowServing 可視化?監視?はGrafana+Prometheus 開発を通しての学び 自動デプロイとかテスト 検索精度の確認ツールを作る コレ重要だよね。何が変更してるかとか、何が正しいかってのが必要だし。。。 復旧可能、早期復旧の仕組みを容易 今後の方針 対象商品の拡大 物体検出特徴抽出モデルの性能改善 NGTの検索システムをValdに移行 Vald k8s上で動作、分散検索、分散インデキシングなどの機能を提供予定 QA Q: iOS(既存の画像)とAndroid(カメラで撮る)で画像検索の方式が違うのはなぜ? A: アプリの違い Q: 1枚の写真に沢山写っている中で、対象の商品をどう識別しているんでしょう。靴もトップスもボトムスも写っていたら、かなり難しそう A: Yahooブラウザの場合は1番大きな領域のものを選択。Yahoo shoppingだと選択可能 NGTについて(仮) 発表者:岩崎 雅二郎(ヤフー株式会社) 類似画像検索を20年くらいやってる 近傍検索ライブラリ https://github.com/yahoojapan/NGT\n高次元ベクトルの近傍検索 ツリーとグラフによるインデックス 近傍検索とは?\n距離空間上でのクエリの近傍のオブジェクトを取得 k最近傍検索(通常はこっち) 範囲検索(あんまり使われない) NGTの特徴\n世界トップレベルの高速高精度な近似近傍検索 OSS 追加削除が可能(削除がとくに難しいらしい) 多様な利用形態(Python、C++、C、Go、コマンドライン) サーバ版NGT(ngtd、vald)を提供 共有メモリ版でメモリサイズ以上のデータ登録可能 量子化版NGT(NGTQ)により。。。 ANNベンチマークによりテスト\n実行環境が決められているらしい。誰が実行しても比較可能 グラフベースの検索の仕組みのほうが性能がいいというのがベンチマーク結果からわかる なんではやいの? インデックス生成 ツリー(グラフの探索起点の取得に利用する。DVP-tree) グラフ(ANNG) ノードを逐次追加しつつ、近傍ノードを検索してから接続するというのを繰り返している 検索 ツリーから絞り込みつつ、グラフを検索する ANNGに課題があるのでONNG(Optimized Nearest Neighbors Graph)に ノード単位の次数(入出)を最適化 データセットによって有効な次数が違う。。。 NGTを利用した深層学習で。。。 Yahoo!ラボ FavNavi 特徴量の構成(低次特徴量(300次元)、カテゴリ特徴量(128次元)、領域アスペクト比(1次元)) 個別の特徴量だけだとイマイチな結果になるが、組み合わせるといい感じになる モデル性西洋学習データ スライドがあればいいなぁ(表書くの大変だし。。。)\nQA Q: 実際のお客さまの利用を考えると、近似近隣の密度が異なるので、近いものばかりの検索結果や遠いものも含んでしまった検索結果が出ると思うのですが、遠いものが含まれてしまうと、閾値でフィルタしたりするのでしょうか? A: NGTは近いものしかないので、外れ値ってなんでしょう。。。 検索のフィルタリングをある程度している(カテゴリとか)。 まとめ 慣れない分野の話を聞きながらざっとメモを取ったものなので役に立つかはわかりませんが。。。\nアルゴリズムとかまでは得意ではないんですが、画像「検索」ということで参加してみました。 実際に画像検索の仕組みがどんな感じでできているのか、どんな技術がつかわれているのか?ってのがわかったのは 面白かったです。確かに検索のためのキーワードって出てこないことあるしなぁと。 あー、こんなかばんほしいとか、これなんだろ?みたいなのあるからなぁ。\n","date":1572000002,"dir":"post/2019/","id":"11b3a28b536f34d3606427f835bd3ddf","lang":"ja","lastmod":1572000002,"permalink":"https://blog.johtani.info/blog/2019/10/25/bonefire-01/","publishdate":"2019-10-25T19:40:02+09:00","summary":"Bonfire Data \u0026amp; Science #1にブログ枠で参加してきました。 ということで、メモです。 日時 : 2019/10/25 19:00 - 21:30 場所 : Yahoo! Japan サイト : https://yj-meetup.connpass.com/event/148121/ ハッシュタグ: #yjbonfire 概要 Data \u0026amp; Scienceと","tags":["勉強会"],"title":"Bonfire Data \u0026 Science #1に参加しました"},{"contents":"この間のElasticsearch勉強会でAcroquest Technologyの人たちが技術書展7で販売されていた書籍を頂いてしまいました。なので、軽く読んでの感想と宣伝です(これ、電子版とかで買えないのかな?)。\nElasticのパートナーとしても活躍していただいてますが、こういう感じでさまざまなところでElastic Stackを広めていただいていて感謝しかありません。\n章立てとしては以下の通りです。\nElasticsearchでエンタープライズサーチを実現する 同僚が作成、メンテナンスしているFSCrawlerを使った例も書かれています。ローカルのファイル(PDFやJSONとか)をサクッとElasticsearchにインストールしたりするのには便利です。 Kibana Canvasによる柔軟な可視化 Canvasについてどんなものなのか?というのとelasticcofeeというサンプルを元に、その変更の仕方などが説明されています。 Elastic APMによるアプリケーションパフォーマンス監視 Go AgentとAPM自体の使い方の説明です。最近強化されている他の機能との連携(AlertingやMachine Learning)についても触れてくれています。 Kubernetesクラスタのメトリクス・ログ・性能情報の可視化 Azure上でAzure Kubernetes Serviceの上で動いているアプリなどをBeats、APMでデータを取りつつ、他のAzure上にAzure Marketplaceのテンプレートを用いて起動したElasticsearchとKibanaの環境を用いて可視化する方法が説明されています。 ということで、薄い本ですが、手順をおって説明されていたり、7.3と新しいバージョンで書かれているのですばらしいなぁと。 前作の「Elasticsearch NEXT STEP」に引き続きインプレスさんから出たりするのかなぁ?\nちなみに、Elastic APMのRubyに関して興味がある方は、私が前に発表したときの資料がありますので、こちらを参考にしてみてください。\n","date":1570690589,"dir":"post/2019/","id":"d8041ae308961666b15aa1e57b0f9f35","lang":"ja","lastmod":1570690589,"permalink":"https://blog.johtani.info/blog/2019/10/10/review-es-next-step-2/","publishdate":"2019-10-10T15:56:29+09:00","summary":"この間のElasticsearch勉強会でAcroquest Technologyの人たちが技術書展7で販売されていた書籍を頂いてしまいました","tags":["書籍"],"title":"Elasticsearch NEXT STEP 2を頂きました"},{"contents":"Twitterで「Meetup.comに切り替えたらー」みたいな話があったので、 受付用アプリとかなくてという話になったので、普段Elasticsearch勉強会で使用している QRコード生成の仕組みを紹介してみようかと。\nHTMLだけで済むようにQRコードを生成するjquery.qrcode.min.jsってのを使用してます。\nHTMLコードはこちら。\n仕組み 1枚だけのHTMLを生成 MeetupのOAuth2の仕組みを利用(consumer keyを発行する必要あり。) Meetup APIを利用してユーザー情報取得 取得したユーザー情報をGoogle Formに埋め込んだ形で表示するURLを組み立てる 組み立てたURLをQRコードにしてHTMLに表示 受付で、QRコードリーダーを使って、QRコードを読み込むとGoogle Formが開くので、「送信」ボタンを押す 1. HTMLの作成 QRコードを表示するためのHTMLを作成します。Gistに貼り付けてあるので、参考にしてもらえれば。 いくつか埋め込まないといけないものがあるので、個別にそれは説明します。\n2. Google Formの準備 Elasticsearch勉強会では、出席者の情報として、IDと氏名をリストとして保存しています。 目的としては、何人実際に参加したかを計測するのが目的です。 ですので、参加者リストのGoogle Formを作成します。 で、作成した後に、プレビューを表示する。こんな感じ。\nこの時のプレビューのURLをQRコードのURLとして使いたいので、このURLをQRコード表示のHTMLに埋め込みます。\nfunction createGoogleFormURL(data) { var obj = { \u0026#34;entry.1744035444\u0026#34; : data.id, \u0026#34;entry.2031666715\u0026#34; : data.name }; return \u0026#34;https://docs.google.com/forms/d/e/\u0026lt;GOOGLE_FORM_ID\u0026gt;/viewform?\u0026#34; + $.param(obj); } ここら辺です。 returnに書いてあるhttpsで始まる文字列をまず、先ほどのURLで置き換えます。 次に、プレビューのHTMLの中から\u0026lt;input\u0026gt;タグを探して、nameの値を抜き出します。 それをobjのキーに利用します。entry.で始まる文字列が該当します。\nこれで、このURLをQRコードにすれば、値(ここだとIDと氏名)が埋め込まれた形のGoogle Formがスマホのブラウザで起動します。\n3. Meetup APIの準備 MeetupのAPIを利用できるようにします。Meetup.comにログインするとみれるAPIのページがあります。 https://secure.meetup.com/meetup_api\nまず、OAuthを利用するためのConsumer Keyを発行します。\nメニューのOAuth Consumersをクリックして、\n\u0026ldquo;Create New Consumer\u0026quot;をクリックします。 すると、次のような画面が開きます。\nConsumer nameとRedirect URIが重要です。\nConsumer nameはユーザーがMeetup経由で認証するときに、その認証画面で表示される名前になります。 わかりやすい名前を表示してあげると良いかと。\nRedirect URIが一番重要です。実際にOAuthで認証が通った後に表示するHTMLを提供しているURLを指定します。 Elasticsearch勉強会の場合は、私のドメインにwwwをつけた\u0026quot;https://www.johtani.info\u0026quot;を指定しています。 実際にQRコード表示用のHTMLを配置するHTTPサーバーのトップのURLを指定します。 (ちなみに、私のウェブサーバーはS3で運用してます。ですので、HTMLをS3のバケットにアップロードしてあるだけです)\n必須項目を入力したあと、最下部にあるRegister Consumerボタンを押せばキーが生成されます。 生成されたキーがOAuth2のURLのパラメータに必要になります。\nこれで、リダイレクトの準備が整いました。\nOAuth2のURLには、Implicit Flowを利用します。 これで、リダイレクト先のHTMLにトークンがわたるので、Meetup APIにこのトークンが使えるようになります。\n認証用のURLはこちらです。このURLを参加者宛のメールに入れて毎回送信しています。\nhttps://secure.meetup.com/ja-JP/oauth2/authorize?response_type=token\u0026amp;redirect_uri=\u0026lt;QRコード表示HTMLのURL\u0026gt;\u0026amp;client_id=\u0026lt;コンシューマーキー\u0026gt; 参加者はこのリンクをクリックすることで、次のような画面が出てきます。 ログインしていない場合はLog in画面が表示され、まずはログインを促されます。\nで、Allowをクリックすれば、redirect_uriに指定されているページが表示されるわけです。\nQRコード表示用のHTMLでは、次のAPIを使用して、ログインしているユーザーの情報を取得してきています。\nfunction getMemberId() { $.getJSON(\u0026#39;https://api.meetup.com/2/member/self/?only=id,name\u0026amp;access_token=\u0026#39;+ getToken(), displayQRCode); } ここで取れた値が、先ほどの「2. Google Formの準備」で説明したコードのdataの部分に渡ってくるわけです。\nfunction createGoogleFormURL(data) { var obj = { \u0026#34;entry.1744035444\u0026#34; : data.id, \u0026#34;entry.2031666715\u0026#34; : data.name }; return \u0026#34;https://docs.google.com/forms/d/e/\u0026lt;GOOGLE_FORM_ID\u0026gt;/viewform?\u0026#34; + $.param(obj); } 4. QRコードの表示 あとは、jquery.qrcode.min.jsを使用してURLを表示するだけです。\nfunction displayQRCode(data) { $(\u0026#39;#qrcode\u0026#39;).qrcode({width: 128,height: 128, text:createGoogleFormURL(data)}); } サイズとURLを指定するだけですね。\nまとめ あとは、受付で、参加者の方が表示してくれたQRコードをスマホのQRコードリーダーやカメラで読み込めばGoogle Formが開いて必要な情報は入っているので、「送信ボタン」を押せば参加者リストが出来上がっていくという形になります。\n毎回勉強会の前日に、前回のGoogle Formを「コピー」してから、各回の勉強会の登録者フォームを作成しています。 コピーすることにより、Google Formの\u0026lt;input\u0026gt;タグに使用されるnameもそのままコピーされるので、 QRコード生成用のHTMLを書き換える部分の手間が減る形になっています(気づくまで数回かかったw)。\nですので、QRコードのHTMLの中身としては、「勉強会のページへのリンク」、「Google Formへのリンク」の2つを書き換えてから毎回アップロードしているだけとなっています。\nこのやり方が、スマートかどうかはわからないですが、受付アプリがない中、Meetup.comから取得した参加者リストのExcelやプリントアウトしたリストを元に参加者をチェックするよりは、手間が省けてるんじゃないかなぁと。\n残念ながら、QRコードの存在を知らないでそのまま勉強会にくる人がいるので、受付で最低一人はMeetup.comの参加者リストから、 名前を検索してチェックするという作業もやってもらってます。 QRコードを持ってきた方がすんなり受付を通過できるようになってますので、ぜひQRコードを持って勉強会にきてもらえればと。\n","date":1560939044,"dir":"post/2019/","id":"d96f80f23543850a2ee9fff8cd2cc53f","lang":"ja","lastmod":1560939044,"permalink":"https://blog.johtani.info/blog/2019/06/19/qr-code-with-meetup-dot-com/","publishdate":"2019-06-19T19:10:44+09:00","summary":"Twitterで「Meetup.comに切り替えたらー」みたいな話があったので、 受付用アプリとかなくてという話になったので、普段Elasti","tags":["勉強会"],"title":"勉強会の受付自作?アプリ?HTMLについて"},{"contents":"Elasticsearch勉強会や検索技術勉強会やってるんだけど、独学で勉強会やってるなーと思い、みんなはどうやってるんだろうとツイートしてみたところ。\nあー、勉強会運営座談会したい。\n\u0026mdash; Jun Ohtani (@johtani) 2019年4月2日 面白そう\n\u0026mdash; 機械の体を手に入れるのよ鉄郎 (@tetsuroito) 2019年4月2日 やってみるか。\n\u0026mdash; Jun Ohtani (@johtani) 2019年4月2日 やりましょう\n\u0026mdash; 機械の体を手に入れるのよ鉄郎 (@tetsuroito) 2019年4月2日 ってことで、何人か釣れたので、勉強会運営座談会をやってみました。 会場提供していただいた、Classiさんありがとうございました!\n参加してくれた人たちはまぁ、勉強会のサイトを見ていただければなんとなくわかるかなと。 自己紹介とどんな勉強会、読書会運営してますってとこから始めて、次のようなトピックについてピザ食いながら3時間くらい話しました。\nスピーカーの募集方法 運営側から声かけてる?それとも公募してる? 登壇時間とかどうしてる? スピーカーになってもらうためになんかやってる? スケジュール管理 会場探し、スピーカー探し、イベントページ作るタイミングは? 複数拠点開催したことある? ハンズオンとかはどうしてる? 土日開催?平日開催? アンケートとってますか? 使用してるイベントサイトは? ドタキャン対応どうしてる?出欠とったりしてる?懇親会の規模とかどうやって見積もってる? 運営費用関連はどうしてる? グッズとか、ツールとか、スピーカーへの謝礼とか 運営って複数でやってる? その時のツールは? 運営メンバーにはどうやってなってもらう? 録画配信とかまで手が回る? 会場探すの大変じゃない? 会場の部屋の使い方はどうしてる? 行動規範とかどうしてる? 読書会の場合に人が減ってったりしない? まぁ、こんな感じです。色々話してメモしてたんですが、まぁトピックくらいで。\nそもそもは、勉強会の運営って本業ではない(はずな)ので、いかに楽をしつつうまく運営できるかってのを知りたいのと、 他の人どうやってるかってのからアイデアもらえるといいなーと思ったんでやってみました。 他のツールがどんなものかとか知れたし、あー、そういうやり方すればいいのねーみたいなのも知れたので、次回以降の勉強会に活かせればなーと。 自分がやってるやり方とかもブログ書くといいのかなぁ?\n残念です!次回もやるかもしれないので、 @johtani さんに期待してください!\n\u0026mdash; 機械の体を手に入れるのよ鉄郎 (@tetsuroito) 2019年4月25日 次回やるのかなぁ?興味ある人いるのかなぁ?\n","date":1556204526,"dir":"post/2019/","id":"538e38fbc3f78cd61e1841d8141ddcc1","lang":"ja","lastmod":1556204526,"permalink":"https://blog.johtani.info/blog/2019/04/26/meetup-organizer-drinkup/","publishdate":"2019-04-26T00:02:06+09:00","summary":"Elasticsearch勉強会や検索技術勉強会やってるんだけど、独学で勉強会やってるなーと思い、みんなはどうやってるんだろうとツイートして","tags":["勉強会"],"title":"勉強会運営座談会ってのをやってみた"},{"contents":"どーも、johtaniです。\nSearch Engineering Tech Talkという勉強会に運営として参加して、第1回の勉強会を開始しました。 本日(2/26)は第1回目だったので、ブログを残しておこうかと。\n勉強会自体の資料については第1回の勉強会のページにあるし、勉強会の感想とかブログはツイートやみんながブログを書いてくれると思うので、勉強会開催の経緯などについてブログを残しておこうかと。\nなんで始めたの? 私自身が古くはFAST Searchに始まり、何か縁があって、 検索のシステムに長く携わってきたこと(Apache Solrの本書いたり、Elasticsearch勉強会始めたり)もあり、 検索が面白いなと日々思ってます(思ってるだけかもしれないが)。\nで、これまでElasticsearch勉強会をやっているのですが、検索エンジン固有の話ではない、 いわゆる検索の共通の課題というのがあるなぁと。 そういう課題やノウハウって、製品に限らず共有できれば面白いことがもっとできるんじゃないだろうか? と感じることが多々ありまして。 オープンソースのコミュニティをソースコードをベースではなく、共通の課題・話題を中心としたコミュニティが あってもいいんじゃないかなぁと。\nまぁ、要は、私がみんなの検索で困ってることとか、どうやって検索システム考えてるのかが聞きたかったわけですよ。\nということで、一人でやっても面白くないので、興味ありそうな人を募ってやってみようということを始めたのが2018年12月くらいです。\n運営とかどうしてるの? まずは、共同主催者(コアメンバー)を募集してみようということで、Googleフォーム作って、 興味ありそうな人がいる場所に投稿してみました。(TwitterとかFBとか) で集まったのが今回紹介したメンバー(スライド参照)です。 ユーザー企業の人もいれば、私みたいな検索エンジンの人もいるので面白い感じにできたかなぁと。 で、スピーカーを運営や知り合いに声をかけて第1回をやってみたという感じです。\n今後どうするの? 残念ながら次回はまだ未定です。 2ヶ月に1回くらいのペースで開催できればなーと思ってますが、スピーカーが集まるかなどによるかなぁと。 ということで、勉強会のグループのページにスピーカー応募フォームのリンクがありますので、スピーカーに興味がある方は入力していただければと。\nもちろん第2回はやりたいので、勉強会のページからの連絡をお待ちください!!\n","date":1551191880,"dir":"post/2019/","id":"b27bdabd8e1a6b7dc06886867331ceb3","lang":"ja","lastmod":1551191880,"permalink":"https://blog.johtani.info/blog/2019/02/26/start-search-engineering-tech-talk/","publishdate":"2019-02-26T23:38:00+09:00","summary":"どーも、johtaniです。 Search Engineering Tech Talkという勉強会に運営として参加して、第1回の勉強会を開始しました。 本日(2/26)は第1回目だったの","tags":["勉強会","検索"],"title":"Search Engineering Tech Talk(検索技術勉強会)の運営として参加して始めてみました。"},{"contents":"今年も振り返りブログをかけてます。よかったw\n振り返り(2017年に書いた抱負から) まずは去年の抱負を元に。\nもっと英語の継続&TOEIC まぁ、継続してます。英会話も続けてますし、海外TVドラマや映画見てます。 ただ、昨年書いたTOEICはイベントが被りまくってて受けれてないです。。。 来年は受けれればいいが。 ちなみに見たドラマはこの辺。あんまり見てないなぁ。 「はじまりのうた」は飛行機の中で見たんですが、よかったです。 最近は音楽系の映画が好きなのかなぁ。グレーテストマンショー(ミュージカル風)とかもハマったし。\nGame of Thrones はじまりのうた BEGIN AGAIN (映画) 24 シーズン4まで 今は、ボキャブラリのなさに苦しんでる感じです。キクタンとかするべきなのかもなぁ。 基本勉強が下手だからなー。\n継続的にイベントに登壇 & CfPもっと出すぞ! OSCには出てました。あとは、いくつかに呼ばれて出たりでしょうか。 CfPはJJUGしか出せてない気がするんで、もっと出さないとですね。。。 春のJJUGでは20分で短すぎた「オープンソースとビジネスモデル」の話(同僚のネタ)が 今年面白かった内容かなぁと。 もっと話を作るのをうまくしないとだろうなぁ。 ユースケースが増えてるんで、もっといろんなところに出ていかないとなぁと。 ブースの出し方とかもちょっと考えないといけないかもなーと思ってたり。 マンネリになってきてる気がするんで、なんか取り入れないとなぁ。\nもっとブログ! 出だしはよかったんですが、途中でRustネタのブログも止まってしまいましたね。。。 業務が忙しくなったのを言い訳にして時間が取れなくなってるんで、 もっと習慣つけないとなぁ。\n雑誌やWeb系雑誌で記事を。 できてないです。。。どうすっかなぁ。 重い腰上げないのが問題なんですけどね。。。 自社のウェビナーとかはそこそこやってましたが。\nコミュニティを別の方法で盛り上げ フォーラムは皆さんのおかげで盛り上がってきてる気がしてます。 別の方法ではなく、勉強会を9月から毎月開催にして、ユースケースごとに切り替えてみました。 あとは、スピーカー登録用のフォームの用意とかして、継続的に楽にスピーカーの人たちが見つけられるようにと。 私は「全然」関わってないんですが、技術書典でいろんな方に書籍を書いていただきました。 また、Elasticloverという毎週いろんな記事をまとめていただけ助かりました。 少しでも感謝をということで、コミュニティランチというイベントで、フォーラムで回答していただいてる方や、書籍を出していただいた方を招いてCEOのShayとランチするというイベントもやってみました。 少しは盛り上げられたかなぁ。 次は、ハッカソンみたいなのとかやってみるのもありなのかなぁ?(サポートしきれない気がするんだよなぁ)\nElasticsearchなど検索系の開発にも参加 開発。。。 Analyzer向けのKibanaのプラグインの開発は継続してますが、あんまり開発してないですねぇ(GitHubの草をみながら)。 ちょっとしたPRはやったりしてますが、もっとやりたい。。。 とりあえず、来年しょっぱなは、検索系じゃないですが、KibanaのプラグインのReact化をやらないとなぁと。\n振り返り(今年あったできごと) さて、反省が多かったですが、ここからは今年の出来事を。\n初スノーシュー in US オフィス引越し パリで料理w K8sとde:code QNAPとか IPO! 初のオンライン登壇 初アイルランド! Pixel3 XL 今年も初モノがちらほら。\nアメリカでスノーシューやりました。昨年は釣りでしたが、今年はスノーシューでした。 スノーシューはすごくよかったんですが、サンフランシスコから社内ミーティングのある場所までの 移動に10時間バスに缶詰という変な初モノもありました。。。 スノーリゾートのある山の上にバスで移動だったんですが、前日までの天候の生でチェーン規制が出てしまい、登りかけた山を降りて、違う経路で登り直すという長旅でした。。。 途中からずっとゲームオブスローンズみてました。。。\nオフィスが引っ越しました。人数が増えてきたのもあり、銀座のWeWorkに引っ越しました(私はあんまり行かなかったりしますがw)。 ただ、すでに手狭になってきて、来年はまた引っ越してるかもなぁ。 今年の終わりで日本のメンバーが22名に増えました!すごい!4年半前の22倍!\nパリで料理もしましたwセールスのキックオフミーティングがパリで開催され、なぜか参加してきました。 そこで、DevRelチームのミーティング&ディナーがあったんですが、ディナーがアクティビティ付きで、チームのみんなとパリで料理やカクテル作ってきました。 まさか、パリで手巻き寿司作るとは思わなかった(怖くて食べてないですw)\n今年はイベントが連続することが多かったです。パリから帰ってすぐにde:codeでMSの川崎さんと登壇したりしました。Kubernetesを触る機会ができたんでよかったですが、時差ボケは辛かったw今年は他にもカンファレンス直後にトレーニングだったりと、夏に喉やられちゃいました。喉に負担をかけない話し方の練習すべきなんだろうなぁ。\n自宅の環境もちょっと整えました。10年前から使ってた、TeraStationをQNAPに刷新。快適に検索できるわ、クラウドにバックアップとれるわで、すごく快適です。 あとは、自室のディスプレイをディスプレイアームにつけたり、壊れたモニタースピーカーをYamahaのパワードスピーカーに買い替えたりと。 ちょこちょこ自宅で作業したりするんで、快適です。\n今年はめでたいことに会社がIPOしました。ニューヨーク証券取引所で株式公開しました。 転職して4年、初体験なんで何がどうってのはいまいち実感わかないんですが、順調にきてるのは嬉しい限りです。今後も頑張りますよ!\n自社のウェビナーでは、オンライン登壇してたんですが、インフラ勉強会でオンライン登壇させていただきました。 Elastic Stackの入門的な話をさせていただいたので、興味があればみていただければと。 こういうのにはマイクが非常に重要だなというのが結論です。ウェビナーで使ってるShureのマイクで話したので聞き取りやすかったです。 来年はもっと手軽にちょっとしたウェビナーとかポッドキャストやろうかな、ということで、持ち運び用にSAM SONGo Micを購入してみたのでどっかで試してみたいなー。\nアイルランド(ダブリン)にも行きました。これまた、社内のミーティングなんですけどね。半年に1度エンジニアが集まる社内イベントがあるので、いろんなところに旅をさせてもらっていて、すごく楽しいです。 みんなにも会えるし。ただ、アイルランドの英語はきつかった。。。\n最後はPixel3です。SonyのXperiaをここ数年は使ってたんですが、電池の持ちなどが悪くなったんで、気になってたPixel3に変えました。すごくいい。いらないものが入ってないのもいい。あとカメラがすごくいい。他の機能をまだちゃんと調べてないんで、誰か便利機能知ってたら教えてくださいw\nとまぁ、こんな感じでした。\n来年の抱負 最後は来年の抱負を。\nTOEIC CfP見つけて応募 \u0026amp; いろんな場所に顔を出す もっとブログ! Rustの継続 開発の継続 日本でエンジニア獲得! まぁ、英語ですね。これは地道にやるしかないんだろうなと思いつつ、コツコツが苦手でw とりあえず、今年はどこかでTOEIC受けないとな。\nいつも行かないけど、弊社プロダクトに関係のあるカンファレンスのCfPを見つけ出して、 応募しまくって、少しでもしゃべらないとなぁ。喋れなくても、Elasticsearchがらみで登壇していただいてる方がいるカンファレンスには顔を出していきたいなぁと。 登壇される方いたら、ぜひ連絡ください!あとは、CfPのサイトを探す仕組みを作らないとなぁ。 検索サイト作るかなぁ。 あとは、カンファレンスではなく、いろんな会社に遊びにいきたいと思ってます。 入門的な話をしてほしいような方、こんな使い方してますっていう話をしていただける方、大募集です。 これもGoogle Formでも作ってみるか。\nブログなぁ。小さな習慣を読んだのに、習慣化できてないので、なんとかしないとという意味で。。。が、頑張ります。。。\nRustの継続&開発の継続もですね。Java歴が長いので、他の言語を勉強しようと思ってRustやってますがなかなか身についてないというか、時間を取れてない。これもコツコツやらないとなー 検索関連の開発もちょっとずつやりたいなと思ってるんで、LukeへContributeしようかな。\n切実なんですが、日本に弊社のエンジニアを増やしたいなと。特に人前で喋ってもらえる人が増えると助かるんです。弊社最近、ユースケースが増えてきてて、追いつかなくてwダレカタスケテーw\nさーて、そろそろ紅白のサザンが始まるんで終わりです。\n今年も様々な方々に様々な面で助けていただきました。本当にお世話になりました。 この場を借りてお礼申し上げます。\n来年ももちろん、助けてもらうんで、よろしくお願いいたします! あと、話聞きたい方、声かけてくださーい。\n","date":1546240485,"dir":"post/2018/","id":"6c226ee1519fbf910197cc1d5c5a5756","lang":"ja","lastmod":1546240485,"permalink":"https://blog.johtani.info/blog/2018/12/31/looking-back-2018/","publishdate":"2018-12-31T16:14:45+09:00","summary":"今年も振り返りブログをかけてます。よかったw 振り返り(2017年に書いた抱負から) まずは去年の抱負を元に。 もっと英語の継続&TOEIC まぁ、","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2018)"},{"contents":"Elastic stack (Elasticsearch) Advent Calendar 2018の25日目の記事になります。 今年最後のAdvent Calendarです!来年も忘れてなければやるはず!\n今日は、すでにalpha2までリリースされた7系でどんな変更が入るのかをちょっとだけ紹介します。 ほんとにちょっとだけですよ。\nKibanaのk7 design (kibana) Kibanaの新デザインです。K7って呼ぶのかな?\nまだ、メニューと一部が実装されているだけですが、7.0.0でガラッと変わりそうです。 そのほかの画面のIssueはこちらです。 \u0026ldquo;k7\u0026quot;で検索しただけですが。メタIssueが見つからなかったんで。例えば、こんな感じでアプリとかのスイッチとかがこんな感じになるよというデザイン案が観れたりします。\nZen2 (elasticsearch) Elasticsearchの新しいクラスター管理機構アルゴリズムになります。 Zenと呼ばれる独自実装のものを6系までは使っていましたが、7系向けに変更がかかりました。 実際には、Nodeを探す仕組み、Masterの選出アルゴリズム、クラスター状態の管理などを行います。 上記のリンクにあるようにドキュメントも詳しくなりました。 信頼性をさらに向上し、設定ミスを起こしにくくして、より使いやすくという目的で様々な変更が加えられています。 これが、メタIssueかな? アルゴリズムの変更や、クラスターの状態の管理の方法などの変更に関するIssueやPRにリンクが貼ってあります。\n新しいデータタイプ (elasticsearch) Feature/Feature vector datatype ドキュメントはこちらとこちら\nfeature queryと合わせて使用するためのフィールドで、しかもクエリのスコア計算「のみ」に使用するフィールドになります。 検索条件やソート、Aggregationの対象ではなく、クエリのスコアに影響させたい値を入れておくためのフィールドです。 6から追加された機能の「track_total_hits」をfalseにした時と合わせると、function_scoreなどで計算をしていた場合よりも、検索性能が上がるという利点まであります。 ちなみに、「track_total_hits」は検索ヒット数を計算しないで、上位のデータを取得する時にクエリを早くするといったことができる機能になります。 Index Sortingと組み合わせることで威力が発揮できる仕組みになるはずです。\nFilebeat supports NetFlow (beats) NetFlowが入力として追加されます。 Filebeatと言いつつ、File以外の入力が徐々に増えてきてますね(UDPやTCPにも対応しましたし)。 ネットワーク機器などの監視を行う方などにはさらに便利になってくるのではないでしょうか? (私はこの辺りは不得手なので、誰か使ってみてもらえればと!)\nまとめ まだ、序の口って感じですが、今年はこの辺で。7系ではここであげた以外にも様々な機能が追加されています(もしくは予定です)。 Elasticのドキュメントの良いところは、masterブランチのドキュメントも公開されていることです。 ドキュメントのバージョンを7.0.0-alpha2にすれば、masterブランチで追加されたページが見れるので、 興味のある方は眺めてみていただければと。物によって、リリースノートが書かれていなかったりするので注意は必要ですが。\n今年もあと数日になりましたが、Advent Calendarへの参加ありがとうございました! 来年ももちろんやりますので、年始からネタを考えてくださいね。\n来年一発目は、第28回Elasticsearch勉強会 - 6.5機能紹介 -になります。ウェビナーでも紹介しましたが、6.5で入った様々な新機能をデモありで紹介する予定です。 興味のある方はぜひご参加ください。\nでは、来年もよろしくお願いいたします。\n","date":1545663601,"dir":"post/2018/","id":"ee62cb0b9a97f990df1ed0266a7027e2","lang":"ja","lastmod":1545663601,"permalink":"https://blog.johtani.info/blog/2018/12/25/whats-new-in-elastic-stack-7/","publishdate":"2018-12-25T00:00:01+09:00","summary":"Elastic stack (Elasticsearch) Advent Calendar 2018の25日目の記事になります。 今年最後のAdvent Calendarです!来年も忘れてなければやるはず! 今日は、すでにalp","tags":["elasticsearch"],"title":"Elastic Stack 7.0で入ってくる新機能をちょっと紹介"},{"contents":"Elastic stack (Elasticsearch) Advent Calendar 2018の1日目の記事になります。\nちょっと遅れちゃいました。。。 まだ、1ヶ月を残してますが、簡単に今年起こったことを振り返ってみようと思います。毎年恒例ですね、ここ数年。\nElastic Stack 6.2.0リリース(2月) リリース記事はこちら\nAPMがGAリリースされ、Beats monitoring UIも追加されました。Stackとしての統一度がちょっとずつ上がってきた感じですね。 Kibanaのホーム画面(左メニューのKibanaアイコンをクリックした時)にデータ登録のチュートリアル的な画面が追加されています。 特にBeatsを利用する時の流れが簡単にわかるのがいい感じです。Metricsなどはローカルでちょっと試すのにも簡単な流れですので、ぜひ一度やってみてもらいたいなと。 個人的にはtermsを使ったパイチャートで、その他の数値がどのくらいあるかといった表示ができるようになって、やっと帰ってきた!(Kibana 3の頃にはあった機能)という印象でした。\nElastic{ON}18開催(2月) 第4回目のユーザーカンファレンスがSFで開催されました。 今年のキーノートが今年最大のニュースですね。 X-Packのコードの公開が発表されたのがこの時でした。 個人的に今後もオープンソースに携わっていきたいと思いながら日々働いていますが、 Elasticのオープンソースへのこだわりと、シンプルな考え方を再確認して素晴らしい会社で働けてるなーと。 商用のソースコードを公開してユーザーや顧客の皆さんとより良いものを作っていきたいという形ですので、今後もよろしくお願いします! キーノートの動画はこちらからご覧いただけます。\nそのほかにも次のような発表が行われました。\nSQL for elasticsearch Canvas Elastic App Search(旧Swiftype) Elastic Stack 6.3.0リリース(6月) リリース記事はこちら\n2月末のElastic{ON}で発表されたX-Packのコードの公開にはやはり時間がかかりました。 有償コードのリポジトリとの統合やライセンスの変更、テスト環境などなど、色々大変だったみたいです。 ようやく公開され、ベーシックのライセンスの扱いなども変わり、より使いやすくなったのがこのタイミングです。\nX-Packをプラグインとしてのインストールが不要に ベーシックライセンスがデフォルトでONに。6.3から登録などが不要に。 Apache 2.0ライセンスの部分のみのディストリビューションも別途ダウンロードできるようになどなど 日本でもリリースウェビナーをやりました。ご覧いただけましたかね?\nElastic Cloud Elasticsearch Serviceがより使いやすく(8月) リリース記事はこちら\nこれまでは、メモリとストレージの比率だけしか指定できなかったのですが、 このリリースで様々なユースケースに応じた組み合わせが可能になりました。 CPUやメモリリソースよりもストレージを大きくしたりなどです。 専用マスターノードを追加できたり、待望の機械学習(Machine Learning)が提供されたりと色々と変更があり使いやすくなったかと。 昔からよく聞かれる、Kuromojiなどのカスタム辞書を登録する機能もあるので、Elastic Cloud便利です。 ご存知ない方は、14日間のトライアルもありますので試していただければと!\nElastic Stack 6.4.0リリース(8月) リリース記事はこちら\nフィールドエイリアスや韓国語のアナライザーがElasticsearchに追加されました。 Kibanaはデザインがここからさらに少しずつ変更が入ってたりします。 Elastic UIフレームワークと呼ばれるデザイン用のライブラリが、ElasticのプロダクトのUIに取り込まれていってる感じです。統一感が取れてきてますよね。私が開発しているAnalyze UIのプラグインにも取り込みました。 あとは、マイクロソフトのde:codeで話をさせていただいた、Logstash向けのAzure Moduleがリリースされたのもこのバージョンでした。AzureのEvent Hubからデータを取り込んで、SQLデータベースのモニタリングや、ユーザーの認証などをとってKibanaで可視化するものです。\nもっとも気に入っているのはサンプルデータの登録が簡単になったことです。これまでは、KibanaとElasticsearchを用意した後に、データを入れるためにFilebeatなどを使ってから、ようやくKibanaで遊べるという形でした。 6.4からは、ElasticsearchとKibanaを立ち上げて、Kibanaのホーム画面の「Sample Data」のリンクを押した後に、「Sample flght data」の「Add」ボタンを押せばKibanaからデータが登録されます(サンプルデータについてはこちら)。とりあえず触ってみたいという方への敷居がさらに下がったのではないかなぁと。\nElastic認定エンジニア第1号(8月) ブログ記事はこちら\n認定制度も始まりました。Elasticsearchの知識、経験を問われるテストを受けていただき、合格すると認定されるというやつです。 なんと、社外で世界初の認定エンジニアがアクロクエストの吉岡さんでした(上記ブログ参照)。 私もトレーナーやってるのもあり、慌てて認定をとったりしましたw。 認定テストは筆記ではなく、実際に作業をするテストなので実践的です。 トレーニングの受講が必須ではないのも面白いなぁと思いました。 トレーニングや認定エンジニアに興味がある方は、Elasticのトレーニングのサイトをご覧ください。 1月末にはまた、日本語でElasticsearchのトレーニングも開催されます!\nElastic Cloud Enterprise 2.0リリース(9月) リリース記事はこちら\nElastic Cloud Enterpriseをご存知ない方もいらっしゃるかもしれません。 Elastic Cloudの裏側で利用しているクラスターの起動などの仕組みを製品として提供しているのがこちらになります。 Elastic Cloudで機械学習や様々な構成ができるようになったものがリリースされたのがこの2.0です。 複数のElasticsearchクラスターを管理したい場合には、こちらが便利なツールになってるんじゃないかなぁと。 部署ごとにクラスターを提供するといったことが可能になるので、乱立する前に利用するのも便利かなーと。\nニューヨーク証券取引所で株式を公開(10月) ブログ記事\n日本語でブログ(10月) Elasticsearchの運用に関する典型的な4つの誤解というブログを書きました。4年も働いてるのに、会社のブログに翻訳以外で書いたことなかったので。。。 Twitterや勉強会、ブログ記事などで見かけるよくある誤解に関する記事を書いてみました。 Elasticは英語のブログも活発に書かれているのですが、今後もこのような形で日本語でのブログも頑張りますので、 読んでみたいものなどあればコメントいただければと。\nまぁ、弊社の大輪は色々書いてるんで、私がもっと頑張れって話ですかね。。。\nElastic Stack 6.5.0リリース(11月) リリース記事はこちら\n昨日(11/30)のウェビナーでも話をさせていただきましたが、Elastic Stack 6.5は「本当にマイナーリリース???」と思うほど盛りだくさんの機能がリリースされました。\nインフラUI、ログUI Elastic APMの分散トレーシング対応 Java \u0026amp; Go APM Agent GAリリース Cross Cluster Replication ODBCドライバー Kibana Canvas Kibana Spaces Data Visualizer for files Functionbeat LogstashのApp Search output リストアップしただけでもこれです。45分のウェビナーでは伝えきれてないなぁとも思ってますので、何か検討しようと思います!\nElasticsearch勉強会(3月から12月) Elasticsearch勉強会ページ\n今年は、6回の勉強会を開催(1つは12月19日開催)しました。 9月からは、ユースケースなど、もっと参加者の皆さんの興味があることにフォーカスしながら開催をしてみ始めました。 参加しやすくなってればいいのですが。。。 そろそろまたアンケートをとったりして、参加しやすいか、どんな改善がしてほしいかなどを聞きたいなと思っています。\n12月はもっと皆さんと喋りたいなということで、スピーカーなしの「LT\u0026amp;忘年会」にしてみました。 私やElasticのものも参加するので、ぜひ色々聞いたり、他のコミュニティの方達の使い方を聞き出して、 新しい発見をしていただければなーと思います。LTでスピーカーの練習をするってものありですよ!(まだ誰も応募してくれてない。。。) 発表することで、フィードバックがもらえて、自分の使い方に自信が持てたり、その他の視点を得ることができると思いますので、 ぜひ発表してみていただければと。\n12月のjohtani出没イベント 12月は以下のイベントにブースを出してます。イベントに参加される方ははぜひブースにお立ち寄りください!!\n12/4-5 : Japan Container Days - 東京 12/8 : OSC福岡 - 福岡 12/15 : JJUG CCC 2018 Fall - 東京 12/19 : 第27回Elasticsearch勉強会 - 東京 なんか、忙しそうだな。。。\nまとめ 駆け足でしたが今年を振り返ってみました。 今年も色々ありましたが、今後もよろしくお願いいたします。\nさて、Elastic Stack Advent Calendar 2018は今日から25日まで続きます。こらからの記事を楽しみにしています!\nということで、次はkaibadash@githubさんの「ぼくの考えた最強のElasticsearch index設定を最強にわかりやすく書くぞ!!!」になります。お楽しみに!\n","date":1543628918,"dir":"post/2018/","id":"ba45ddd3042dad59a12e5937644f7246","lang":"ja","lastmod":1543628918,"permalink":"https://blog.johtani.info/blog/2018/12/01/whats-happen-at-elastic-in-2018/","publishdate":"2018-12-01T10:48:38+09:00","summary":"Elastic stack (Elasticsearch) Advent Calendar 2018の1日目の記事になります。 ちょっと遅れちゃいました。。。 まだ、1ヶ月を残してますが、簡単に今年起こったことを振り返ってみよ","tags":["elasticsearch"],"title":"2018年のElastic StackとElastic"},{"contents":"(転職する少し前までパスポートすら持ってなかったのに)今の会社に転職してから、半年に1度の割合で海外への出張が発生する生活を送っています。 4年目になりますが、今回いくつか新しいガジェット?アイテム?を出張用に導入したので感想を書いておこうかなと。\nとりあえず、以下の4つです。\nFelimoa ネック ピロー これまでは、無印で購入した「フィットするネックピロー」を使ってました。 特に使ってる間は問題ないのですが、どうしてもかさばります。。。 そんな時、FBで見かけたのがこちら。\n厚みがないので、持ち運びが便利でした(商品紹介の中にありますが、リュックにつけると邪魔にならない)。 飛行機の中で使うので、それほど暑くない場所なので、ムレる感じでもなく。 ただ、ヘッドフォン+真横にフレームがくる形になるとヘッドフォンに干渉するので、 私はフレームを顎の下の方に寄せた形で使ってました。 軽さと場所を取らないのがよかったです。\nノイズキャンセリングヘッドフォン これまでは、SONYのNW-A847という ノイズキャンセリング機能付きのウォークマン+アクセサリーで外部入力を取り込む形で、飛行機で映画を見ていました。 これ自体が8年前の製品ですね。。。 これとは別に、冬の寒い時期は防寒も兼ねてヘッドフォンを使用しています。 MDR-10Rを使ってたんですが、昨年こんな感じになりまして。。。\n応急処置 pic.twitter.com/uDErZWpPVC\n\u0026mdash; Jun Ohtani (@johtani) 2017年11月10日 で、ヘッドフォンの買い替えを検討してたんです。 そこへ飛び込んできたのがSonyの新しいノイズキャンセリングヘッドフォンでしたと。\nせっかく買い換えるし、今度はいいものを長くということでフライト前日に購入してしまいました。 結論としては高いけど買ってよかったと。よかった点はこんな感じです。\n軽い イヤーパッドが耳を抑えることがないので長時間でも気にならない 人の声だけノイズキャンセリングをオフにする(騒音などはキャンセルしてくれる) バッテリーが長時間 ヘッドフォンを外さないでも案内を聞くことができる「クイックアテンションモード」 などなど。行きのフライトで5時間も遅れが出ましたが、空港、飛行機内で非常に快適に過ごせました。 大事に使おう。。。\ncw-x 知り合いがFBにアップしてて、立ちっぱなしの仕事だったり、長時間のフライトでも足が疲れないという噂を聞いて購入しました。\n長時間のフライトの後に、ホテルで1泊しても足の疲れって結構残ってるんです。 今回、12時間のフライトでズボンの下に履いて行きましたが、足の疲れがほぼありませんでした。 デブになりつつあり、足太くなって来てるので、履くのはちょっと苦労しますが。。。もともときつめに作ってるんじゃないかなぁ(希望的観測)。 帰りも使用しましたが、帰りはフライト前に1万歩ほどダブリンの街中を歩き回ってたので、流石に疲れが出てます。。。 今度は、カンファレンスのブースなどで立つことが多いシーンでも使ってみて、疲れがどうなるかを試してみようと思います。\n携帯ウォシュレット 初めて購入しました。海外のホテルで1週間とか連泊するんですが、トイレットペーパーがやはり硬めなのが気になって。。。\n世界に誇る日本の技術の一つだと確信してますw ドイツに長期出張してた友人が便利だよと言ってたので、思い切って購入して持って行きました。 硬めのトイレットペーパーも気にならなくなるのでとても幸せな気分ですw\nまとめ とりあえず、今回はこんな感じです。 総じて導入してよかったなという感じでした。 他にもおすすめ出張グッズとかあればコメントいただけると嬉しいです。\n普段使ってるものとか、どういうものを持っていってるとか興味ある人いるかなぁ? ではでは。\n","date":1539794095,"dir":"post/2018/","id":"3fd9052870778e14ab4a5acbc8c24af4","lang":"ja","lastmod":1539794095,"permalink":"https://blog.johtani.info/blog/2018/10/18/items-for-long-businesstrip/","publishdate":"2018-10-18T01:34:55+09:00","summary":"(転職する少し前までパスポートすら持ってなかったのに)今の会社に転職してから、半年に1度の割合で海外への出張が発生する生活を送っています。 4","tags":["misc"],"title":"新規導入した長期出張用のアイテムをいくつか紹介"},{"contents":"毎月開催の2回目になります。 今回は日経さんの会場をお借りしての開催となりました。\n前回から、スピーカーの募集をhttp://bit.ly/SpeakerElasticTokyoMeetup で行なっております。 ぜひ皆さんのノウハウを共有していただけると助かります。 また、次回もすでにスケジュール済みです。次回は「ログ/メトリック分析」回になります。\n以下は、個人的なメモになります。\nメディアコンテンツ向け記事検索DBとして使うElasticsearch / Future Architect 株式会社 村田 靖拓さん (twitter: @famipapamart) メディア記事コンテンツ検索 全ての情報が1indexに入っているようにすること。 typeは少し悩んだ。 範囲検索にはならない場合がある。(文字列で登録してWildcard検索できるようにした) kuromojiで基本対応 異体字についてはchar filterでマッピング 細かな設定とかもスライドにて公開予定。 基本的なプラグインだけで対応した Dynamic Field mappingを有効にしたまま対応 パフォーマンス検証 初回のインデックスのロードはこの辺かなぁ?。 自力でQueryのoffset-limitを構築するのかぁ。 ソート条件が固定らしいのでできる方法 minne での検索運用(仮) / @_shiro16 さん ハンドメイドなものをマーケットプレイスがminne SolrからElasticsearchに切り替えた話 2016/02以降はEs 昔は、DBからSolrへ同期 Es版ではDBからの同期ではなく、Workerに対してリクエストを入れる 現状は独自にEC2で運用中 ユーザーが求めているものがきちんとでているかを計測している 行動ログはどんな感じ? TDにログを入れて、CTRとかを計算してre:dashで可視化 A/Bテストも実施 指標はキャンペーンなどが実施されている場合にブレる場合もある トレンドをログから知ることができる Function Scoreでスコアを変更してる 季節的な単語でスコアを変更したりする ドリンクの対応などをして聴けてないところが。。。 query_stringのはなし / 加藤遼さん (日本経済新聞社) 電池が切れそう+ピザとかの手配をしていたらメモが取れず。\n苦労が滲み出る感じのセッションでした。 query_string queryが実際にどんなクエリになっているかの説明を交えて説明してもらえたのはすごくよかったんじゃないかと。 まとめ 検索は話してくれる人が多いし話題に事欠かないなぁという印象でした。 今回も、スピーカーの皆さん、会場提供をしていただいた日経さんありがとうございました。\n他のユースケースのスピーカーも募集してます。ぜひMeetup.comの概要に記載してあるリンクからスピーカーの応募をお願いします!\n","date":1539765230,"dir":"post/2018/","id":"d3fa23c9066f943f10e8883de9340dea","lang":"ja","lastmod":1539765230,"permalink":"https://blog.johtani.info/blog/2018/10/17/26th-elasticsearch-tokyo-meetup/","publishdate":"2018-10-17T17:33:50+09:00","summary":"毎月開催の2回目になります。 今回は日経さんの会場をお借りしての開催となりました。 前回から、スピーカーの募集をhttp://bit.ly/Sp","tags":["elasticsearch","勉強会"],"title":"第25回Elasticsearch勉強会を開催しました。"},{"contents":"7/25にJJUGナイトセミナーでElastic Stackの紹介とAPMのJava Agentの紹介をしたので、補足のブログです。 (久々に書くな。。。)\nスライドとサンプルアプリのリポジトリはこちら。\nスライド:https://speakerdeck.com/johtani/intro-elastic-stack-and-elastic-apm-java リポジトリ:https://github.com/johtani/apm-beats-kubernetes-demo/tree/master サンプルアプリ 勉強会の頭でサンプルアプリへのアクセス用QRコードを用意して質問してもらう感じにしました。\nアプリ自体が質問の受付と、そこにある質問に対して聞きたいかどうかのVoteができる仕組みになっています。 セッション最後にこの画面をみながら答えました。 手を挙げていただくよりも、匿名(名前入れるようになってますが、実名である必要はない)で登録できるし、 みんなが聞きたいかどうかもわかるので便利だなぁと。\n元は、Elastic{ON} 2018であった「Docker \u0026amp; Kubernetes Log Collection and Monitoring with Beats and Elasticsearch」のサンプルアプリです。 これをSpring Bootに移植して、ちょっとだけサンプルコードを追加したものになります。\n構成とかの補足 スライド、GitHubのリポジトリのREADMEにある図は、k8s上のサンプルアプリケーションの構成だけでした。 ElasticsearchとKibanaを含めた図はこんな感じです。\nk8s上の各種Beats、APM Serverは一旦Elastic CLoud Elasticsearch Service(AWS Tokyoリージョンにデプロイ)に対してデータを投げます。 で、KibanaはGKE(k8s on GCP)で動かして、実際に勉強会ではkubectl proxyで接続してから表示していました。 この構成にしている理由は次の理由です。\nElastic CloudのElasticsearchクラスターにデータを投げている理由 クラスターの起動が簡単。 データを永続化したい。k8sのアプリは必要がなくなったらデータを削除したいから。 k8sのdeploymentを書く手間を省く 普段使ってるので。。。 KibanaをGKEで動かした理由 Elastic Cloudでは*「現時点(7/29現在)」*で、KibanaでAPM専用のUIを起動できない ローカルである必要はない といったところです。 Elastic Cloudのインスタンスを起動したままにしておけば、デモをしなくても、このタイミングのログ、メトリクスを 再利用して話をすることも可能です。\nまとめ ということで、簡単ですが、構成の補足でした。 勉強会では告知したのですが、今後の勉強会はトピックスごとでやりたいなと。ということで、どんなトピックスに興味があるのか、スピーカーの応募にはどんなツールが話しやすいかなどといったことのアンケートを集めております。ぜひご協力ください! また、アンケート、このブログに関する質問がある場合は、@johtani、もしくはブログへのコメントでお願い致します。\n今後の勉強会のやり方などについてアンケートを実施中です。https://t.co/XU15CHro0n 皆さん是非ご協力ください。ここにない項目については返信をお願いします。 #elasticsearchjp\n\u0026mdash; Jun Ohtani (@johtani) 2018年7月23日 ","date":1532843130,"dir":"post/2018/","id":"10ae016e19fff6ae9cfaeb8534fa47f9","lang":"ja","lastmod":1532843130,"permalink":"https://blog.johtani.info/blog/2018/07/29/apm-java-at-jjug/","publishdate":"2018-07-29T14:45:30+09:00","summary":"7/25にJJUGナイトセミナーでElastic Stackの紹介とAPMのJava Agentの紹介をしたので、補足のブログです。 (久々に書く","tags":["勉強会"],"title":"JJUGナイトセミナーで話しました"},{"contents":"第2回から少し間が空いてしまいましたが、templateで作成したプラグインのディレクトリ構成とどういう流れでデータがやり取りされるかについてみていきます。 (2018/02月時点で作成したディレクトリ構成にしたがって説明します) ちなみに、JavaScriptの優れた開発者ではないので、誤解している点や、効率の悪い書き方などがあるかもしれません。見つけた場合は、連絡をいただければと思います。\nでは、まずは作成したディレクトリ構成についてみていきましょう。\nディレクトリ構成 simple-sample-kibana-pluginがプラグインのプロジェクトのトップディレクトリになります。このディレクトリに次のような構成でサブディレクトリが存在します(なお、画像はIntelliJに取り込んだ後のディレクトリになっているので、.imlなど、不要なファイル/ディレクトリが存在しています)。\n主要なディレクトリ、ファイルについて簡単に一覧で説明します(順不同)。\nファイル/ディレクトリ名 説明 index.js プラグインの本体。Kibanaはこのファイルのオブジェクトを読み込みプラグインを起動。設定などの読み込みもこちら。 package.json npm/yarnのパッケージに関する情報を定義するファイル README.md README。プラグインの説明などを記載する。インストール方法なども記載すると便利 public ブラウザ側に配布されるプログラムや画像一式 public/less/main.less LESS用のファイル。アプリ固有のスタイルなどを記載 public/app.js ブラウザ側で読み込まれるプラグインのモジュールなど。 public/template/index.html HTMLのテンプレート。ブラウザ上での描画に利用 server/routes Kibanaサーバー側で動作するプラグイン。hapi.jsを利用してREST APIを実装する 重要なファイルについて少しだけ説明します。\npackage.json npmやyarnでビルドなどをするときに使用するパッケージ情報を記載するためのファイルです。 プラグインの名前、バージョン、説明などを記載します。 Kibanaのバージョンについてもこちらで管理します。この情報を また、ライブラリなどの依存関係についてもこちらで記載しています。 以下、抜粋。\n{ \u0026#34;name\u0026#34;: \u0026#34;simple-sample-kibana-plugin\u0026#34;, \u0026#34;version\u0026#34;: \u0026#34;0.0.0\u0026#34;, \u0026#34;description\u0026#34;: \u0026#34;Sample plugin for explaining how to make kibana app\u0026#34;, \u0026#34;main\u0026#34;: \u0026#34;index.js\u0026#34;, \u0026#34;kibana\u0026#34;: { \u0026#34;version\u0026#34;: \u0026#34;6.2.1\u0026#34;, \u0026#34;templateVersion\u0026#34;: \u0026#34;7.2.4\u0026#34; }, \u0026#34;scripts\u0026#34;: { \u0026#34;lint\u0026#34;: \u0026#34;eslint **/*.js\u0026#34;, ... }, \u0026#34;devDependencies\u0026#34;: { \u0026#34;@elastic/eslint-config-kibana\u0026#34;: \u0026#34;^0.14.0\u0026#34;, \u0026#34;@elastic/eslint-import-resolver-kibana\u0026#34;: \u0026#34;^0.9.0\u0026#34;, \u0026#34;@elastic/plugin-helpers\u0026#34;: \u0026#34;^7.1.3\u0026#34;, ... \u0026#34;expect.js\u0026#34;: \u0026#34;^0.3.1\u0026#34; } } ちなみに私は、versionなどをリリースするたびに変更しています。\nindex.js 最初にKibanaに読み込まれるオブジェクトになります。 Kibanaのアプリの名前や、必要なモジュールなどを記載します。\nまた、kibana.ymlから設定など読み込む処理なども書くことができます。\n2行目のexampleRouteはサーバー側のAPIとして利用するhapi.js用のファイルのパスになります。\nuiExportsはこのアプリの画面に関する設定などの記載になります。 appの部分が実際にアプリの情報で、 mainがあとで説明するこのプラグインのUIのためのJavaScriptファイル(public/app.js)になります。mainですので、最初に読み込まれる処理が記載されているものを指定します。app.jsというファイル名を変更する場合は、こちらのappの部分を変更したファイルに合わせましょう。\nconfig(Joi)の関数が設定ファイルの読み込みなどの処理を記載する場所です。\ninit(server, options)の関数が初期化処理を記載する場所になります。 このサンプルアプリでは、2行目のimportで読み込んだhapi.js用のファイルの関数を呼び出しています。引数で渡しているserverがhapi.jsのserverオブジェクトになります。 routeメソッドを使用して作成しているプラグイン用のREST APIを追加しています。\nimport { resolve } from \u0026#39;path\u0026#39;; import exampleRoute from \u0026#39;./server/routes/example\u0026#39;; export default function (kibana) { return new kibana.Plugin({ require: [\u0026#39;elasticsearch\u0026#39;], name: \u0026#39;simple-sample-kibana-plugin\u0026#39;, uiExports: { app: { title: \u0026#39;Simple Sample Kibana Plugin\u0026#39;, description: \u0026#39;Sample plugin for explaining how to make kibana app\u0026#39;, main: \u0026#39;plugins/simple-sample-kibana-plugin/app\u0026#39; }, ... }, config(Joi) { return Joi.object({ enabled: Joi.boolean().default(true), }).default(); }, init(server, options) { // Add server routes and initialize the plugin here exampleRoute(server); } }); }; public/app.js 画面用のモジュールです。 uiRoutesという機能を使用して、アプリの呼び出しURLを定義します。テンプレートで作成したばかりの場合は、/というURLが追加されるのみです。\n実際に画面を表示する際に動くコントローラーの部分はその下の uiModules.controllerに指定してあるfunctionが画面描画の 処理を書く部分になります。 templateで作成したプラグインでは、\u0026ldquo;title\u0026quot;など表示に必要なデータを$scopeというオブジェクトに詰め込んでいます。 これはAngularJS(1系)でのモデルオブジェクトになります。\nimport moment from \u0026#39;moment\u0026#39;; import { uiModules } from \u0026#39;ui/modules\u0026#39;; import uiRoutes from \u0026#39;ui/routes\u0026#39;; import \u0026#39;ui/autoload/styles\u0026#39;; import \u0026#39;./less/main.less\u0026#39;; import template from \u0026#39;./templates/index.html\u0026#39;; uiRoutes.enable(); uiRoutes .when(\u0026#39;/\u0026#39;, { template, resolve: { ... } }); uiModules .get(\u0026#39;app/simple-sample-kibana-plugin\u0026#39;, []) .controller(\u0026#39;simpleSampleKibanaPluginHelloWorld\u0026#39;, function ($scope, $route, $interval) { $scope.title = \u0026#39;Simple Sample Kibana Plugin\u0026#39;; $scope.description = \u0026#39;Sample plugin for explaining how to make kibana app\u0026#39;; ... $scope.$watch(\u0026#39;$destroy\u0026#39;, unsubscribe); }); server/routes/example.js hapi.jsというNode.jsのためのサーバーフレームワークです。 このフレームワークをKibanaは使っており、Kibanaのサーバーとブラウザとのやり取りに使用するREST APIを記述するために使用しています。 例えば、Elasticsearchとのやり取りを実際に行うAPIなどをこのREST API内部で記述します。\nexport default function (server) { server.route({ path: \u0026#39;/api/simple-sample-kibana-plugin/example\u0026#39;, method: \u0026#39;GET\u0026#39;, handler(req, reply) { reply({ time: (new Date()).toISOString() }); } }); } pathの部分がブラウザ側からアクセスするURLになります。 実際にElasticsearchとやり取りする処理の書き方については、次回の記事で説明します。\nアーキテクチャ(簡易版) ざっくりですが、ファイルやディレクトリについて説明しました。 簡単なデータのやり取りについての流れを説明します。\nKibana自体はNode.jsで実装されサーバーとして動作していますが、ブラウザでアクセスすることで画面を描画しています。 簡単なコンポーネントを並べるとデータのやり取りはこのような形です。\nすごく簡易で大雑把な絵ですが。。。\n実際のプラグインとしては大きく、2つの処理があります。\nブラウザ上の処理 クリックなどのイベント処理 HTMLなどのレンダリング処理 Kibanaサーバー上の処理(Elasticsearchなどとの通信が必要な場合) 外部との通信処理 ブラウザ上では重い処理 絵に記載しましたが、ブラウザ上の処理についてはAngularJSが主なフレームワークで、サーバー上の処理についてはhapi.jsがフレームワークとなっています。\nまとめ ということで、今回はディレクトリ構造とファイルの説明、どういったフレームワークが使われ、データのやり取りがどのように行われているか説明しました。\n次回からは、実際に私が作成したAnalyze UIを元にElasticsearchとのデータのやり取りなどについて紹介していきます。\n","date":1524205801,"dir":"post/2018/","id":"04d818cbaac08b2915db15e0bffdcb5b","lang":"ja","lastmod":1524205801,"permalink":"https://blog.johtani.info/blog/2018/04/20/directory-layout-and-architecture/","publishdate":"2018-04-20T15:30:01+09:00","summary":"第2回から少し間が空いてしまいましたが、templateで作成したプラグインのディレクトリ構成とどういう流れでデータがやり取りされるかについ","tags":["Kibana","plugin"],"title":"Analyze UIとKibanaのプラグインの作成方法(第3回)"},{"contents":"#MANABIYA のブースでセッション時間の合間はお客さん少ないので、ブログを書いてみたり。 ここ数年、スポンサーとして色々なカンファレンスに参加してるんですが、それについてちょっと気なることがあったので。\nスポンサー情報ってどうやって探してます? 職業柄、カンファレンスにCfP出してセッションしてみたり(落ちること多いけど)、スポンサーとしてブースを出したりしています。\nで、疑問があるんですが、みなさんどうやってカンファレンスの情報をゲットしてます?\n数年やって来て、検索したりして見つけてスポンサーした結果、 これまでスポンサーしていたので、情報が流れてくるという感じになりました。 それ以外だと、@yusuke さんに教えてもらったりと言うのがあったんですが。。。\n自分が知らない、自分のTwitterで流れてこないという情報をどうやったら集められるかな?と言うのが今の課題になってます。 と言うことで、ブログを書いてみました。\nカンファレンスを検索できるサイトとか便利? で、私の会社は検索エンジンの会社なんで、検索できると便利では?と考えるんです。\nCfPの応募期間で絞り込みできたり、場所で検索できたり、スポンサー情報を取得する方法が載ってたりすると便利なのではないかなと。 便利に思うのが自分だけでは?と言うのがあるんですが。。。\nあると嬉しい人、データを掲載したいなと言う人いますでしょうか? Google Formなどで入力してもらえるようにして何か作るのもありかなぁと考えているところです。 それとも、スポンサーを募っているカンファレンスのスタッフや企業の人は、こういう情報は特定の人にだけ知ってもらったりしたいでしょうか?\n自分だけではわからないことが多いので、懸念事項や、それダメでしょ? あると便利!などのフィードバックをいただけると助かります。\nそれ以外に、カンファレンス自体の場所、開催日程、サイトへのURLなどが検索できると便利だったりするかも?というのもあります。\nとりあえず、自分が知ってるものだけ、個人的に検索できるようにしたりするのがいいかなぁ。。。 コメントお待ちしてます!\n","date":1521867012,"dir":"post/2018/","id":"8cc6b19cd410e638f4beaf1642f4f52a","lang":"ja","lastmod":1521867012,"permalink":"https://blog.johtani.info/blog/2018/03/24/how-to-find-conferences/","publishdate":"2018-03-24T13:50:12+09:00","summary":"#MANABIYA のブースでセッション時間の合間はお客さん少ないので、ブログを書いてみたり。 ここ数年、スポンサーとして色々なカンファレンスに参加してるんです","tags":["カンファレンス","スポンサー"],"title":"カンファレンス情報の探し方(CfP、スポンサー応募、開催期間など)?"},{"contents":"Rustで言語処理100本ノックの続きで、05と06です。\n05. n-gram 問題はこちら。\nみんな大好きn-gramです。単語と文字があるので、それぞれ別関数として実装しました。問題はbi-gramとn=2だったのですが、一応、nを引数に取る形にして実装しました。\nまずは、単語です。\n前に実装した時は、自分で頑張って、先頭から数えたりしてたんですが、Rustにはwindows(n)という便利なメソッドがsliceにあり、これを利用したらこんな簡単になりました。 sliceは特定のシーケンス(配列)に対してある特定のサイズのViewを作ってくれます(説明あってる?)。 ということで、文字列から、単語の配列(スペース区切りで単語にしている)を作り出して、windows(n)メソッドを通すと、 nで指定した数字の個数だけの単語の配列を先頭から、1単語ずつずらして作ってくれます。まさに、n-gram! 戻り値は配列の配列です。 1点だけ疑問点があるのは、「空白で区切ったものが単語」という考え方で良いかどうか?という点です。特に問題文にはそれが明示されていなかったので、このような前提を置いてあります。\ninvalid_n(text, n)はnの値や入力された文字列をチェックする関数です。入力チェックですね。nが1よりも小さい場合、入力文字列が空文字の場合は、warningでメッセージを出して、空の配列を返す仕組みになっています。\n次は、文字です。\n単語とほぼ一緒ですが、入力文字列を、1文字ずつの配列にしているところが異なります。 また、windowsメソッドで取り出された、1文字ずつのn個の配列を文字列に修正してから、結果の配列に入れています。 ここでも疑問は空白をどう扱うか?になります。 現時点では、空白も1文字とカウントして扱うことにしてあります。 どっちがいいのかなぁ?\n06. 集合 問題はこちら。\nまずは、文字n-gramで出てきた文字列をSetに入れる関数から。\nn-gramの問題で実装した文字n-gramの関数の戻り値を配列ではなく、BTreeSetに変えたものになります。比較などがしやすいように?と思い、BTreeSetを利用していますが、実装としてはHashSetでも問題ないかと。 この関数の集合(Set)を元に、和集合、積集合、差集合を求める関数を実装しました。\nSetのメソッドとして、それぞれ、union=和集合、intersection=積集合、difference=差集合のメソッドが用意されているので、特に困ることはなかったです。 差集合については、1-2と2-1で結果が異なるはずなので、それぞれをテストケース、main.rsで出力するようにしてあります。\n所感 今回は、Rustがすでに実装してくれているメソッドがあったので楽ができました。 やりたいことに相当するメソッドがあるかどうかを調べるためにリファレンスを探さないといけないのがちょっと苦労しましたが。。。 ということで、今日はこの辺りまで。\n","date":1521549285,"dir":"post/2018/","id":"d791eaca9375ca1b36a987af22ee71dd","lang":"ja","lastmod":1521549285,"permalink":"https://blog.johtani.info/blog/2018/03/20/nlp100-ch01-05to06/","publishdate":"2018-03-20T21:34:45+09:00","summary":"Rustで言語処理100本ノックの続きで、05と06です。 05. n-gram 問題はこちら。 みんな大好きn-gramです。単語と文字があるので、それぞれ別関","tags":["Rust","nlp100"],"title":"第1章の05から06までやってみた(言語処理100本ノック)"},{"contents":"Rustで言語処理100本ノックの続きで、03と04です。\n03. 円周率 問題はこちら。\n入力文字列を.split_whitespace()で分割しておいて、単語ごとのベクタを作り出し、そこに対して文字を数えました。「アルファベットの」という注意書きがあるので\u0026quot;,\u0026ldquo;や\u0026rdquo;.\u0026ldquo;は含めずに数えるのかなということで、 charの.is_alphabetic()でA-zまでの判定をしつつ、文字のベクタを作ってから、そのベクタの長さを詰め込むという感じでやりました。\nこれ、ひょっとして、collectでベクタにしなくても、i32とかの変数でカウントするとベクタ作らなくてもいいなじゃにか?というのに書きながら気づいた。。。 必要じゃないオブジェクトを作ってるよなぁ。\n.filter().mapとかかな?この辺りの操作がイマイチ苦手。Javaでもまだ馴染めてないところなんだよなぁ。頭固すぎ。\n04. 元素記号 問題はこちら。\n大作ですね。何だろう、大作。。。 最終的に連想配列(辞書型もしくはマップ型)」ということだったので、BTreeMapに詰め込んでます。 HashMapでもいいんですが、文字列で出力した時にキーが並んで見やすいからという理由で、BTreeMap使いました。それ以上の理由はないです。普通にやるなら、HashMapかな?\n入力として、1文字だけの出力をする場所(インデックス番号)の配列を受け取ってます。1点だけ、チェックしていない、けど入力値の想定をしていて、idx_one_symbolsがソートされていて、小さいものから順番に出てくるものとしてます。関数作って、チェックすべきかな?\nで、指定された場所の最後のものが入力文字列よりも大きいかどうかというチェックもしています。(あー、テストケース書いてないな)この辺りのせいでちょっと長めになってます。\n単語の配列を作るのは03の時と同じやり方です。 回しかたがちょっと違って、.iter().enumerate()で回して、添字と値をタプル?でとりだしてます。添字を見ながら1文字取り出すのか、2文字取り出すのかの判断が必要だからです。あとは一緒ですね。1文字取り出すときは、.first()を使って見ました。 実は、2文字取り出す時と、1文字の時と同じロジック使った方が共通化できて、短くなった???\nということで、こんな感じでした。いつものようにツッコミお待ちしてます。\n所感 問題それぞれについてではなく、 やってて思ったのですが、問題に対して想定される結果が記載されていると嬉しいなと思いました。 ロジックについては、各自実装者に寄ったり、言語によって違いが出たりするし、議論するベースになっていいかなと思うんですが、 問題で想定されている結果(出力)があると、自分の実装にケアが足りないところがないのか?とか、ケアしなくていい点とかがわかるのかもなぁと。 ユニットテスト相当のものがあると楽かなぁと。\nこのケースどうするんだろ?みたいなのが、ところどころコメントに残ったりしてます。 出題の意図としては、その部分も議論の対象ということなのかな?\n","date":1519032848,"dir":"post/2018/","id":"e6684944c37dbdd4c08d978af9e47bed","lang":"ja","lastmod":1519032848,"permalink":"https://blog.johtani.info/blog/2018/02/19/nlp100-ch01-03to04/","publishdate":"2018-02-19T18:34:08+09:00","summary":"Rustで言語処理100本ノックの続きで、03と04です。 03. 円周率 問題はこちら。 入力文字列を.split_whitespace()で分割して","tags":["Rust","nlp100"],"title":"第1章の03から04までやってみた(言語処理100本ノック)"},{"contents":"「鉄は熱いうちに打て」ということで、言語処理100本ノックの第1章の00から02を実装してみました。\nさて、これが効率がいいのかどうかはさておき。\n00. 文字列の逆順 問題はこちら。\n最初、Vecのreverse()で逆順にして0からlen()まで回してたんですが、pop()がいい感じに後ろから取れることがわかったんで、切り替えました。 シンプルかな?\n01. 「パタトクカシーー」 問題はこちら。\n1文字ずつ取り出して、インデックスの番号が2で割ってあまりが0なら文字列に追加していくってのでやってみました。 (ブログ書いてるところで、i in 0..char_array.len()じゃなくて、(i, x) in char_array.iter().enumerate()に切り替えました。) matchとか使って綺麗に書けたりするのかなぁ?\n02. 「パトカー」+「タクシー」=「パタトクカシーー」 問題はこちら。\nだいぶ思考錯誤してる感じがソースに現れてます。 とりあえず、両方の文字列をcharsの配列にして個々のイテレータを回しながら、next()の戻り値があれば追加していく感じにして、 終了条件が両方Noneを通ったらにしてるけど、、、 なんか、もっと綺麗にできないのかなぁ。。。 next()のタプル返す関数作って、とかでなんかできたりするかなぁ?\ngist-it 関係ないですが、GitHubのコードを貼り付けるのに便利なサービスがあるみたいです。\nhttp://gist-it.appspot.com\nこれほんと便利だな。行数指定もできるし。 説明するのが簡単だ。\nとりあえず、今日はこの辺まで。なんか、いい知恵あれば教えてください!\n","date":1518699541,"dir":"post/2018/","id":"bbe1deec11d459bdb348051b970abdaf","lang":"ja","lastmod":1518699541,"permalink":"https://blog.johtani.info/blog/2018/02/15/nlp100-ch01-00to02/","publishdate":"2018-02-15T21:59:01+09:00","summary":"「鉄は熱いうちに打て」ということで、言語処理100本ノックの第1章の00から02を実装してみました。 さて、これが効率がいいのかどうかはさてお","tags":["Rust","nlp100"],"title":"第1章の00から02までやってみた(言語処理100本ノック)"},{"contents":"ども。新しいもの始めないと頭が退化する。。。ということで、こちら( happy new year and new language - katsyoshiのめもみたいなもの)のブログに触発されて、言語処理100本ノックをはじめてみました。\n言語処理100本ノックとは、自然言語処理になるのかな、東北大学の研究室の先生が公開している言語処理に関する実践的な課題をベースにプログラミングなどのスキルを学んでいくための問題集です。 元々はPythonを対象とされているようですが、Rustでやってみようかと。 まぁ、先ほどあげたブログの二番煎じです。。。 ちなみに、インスパイアされた元のブログの方はRust book 2nd editionを読み終えたらしいですが、私はかじった程度です(ダメかも?)。\nNLPもRustもかじった程度なので、苦戦しそうですが、ちょっとずつやっていこうかなと。 ということで、準備運動の第1章から始めようかと。 GitHubにちょっとずつあげていく予定です。 https://github.com/johtani/nlp100-rust\nまぁ、まずは宣言のブログを書いてみただけです。 続いてなかったら、叱咤激励してください。叱咤だけかも?\n","date":1518605551,"dir":"post/2018/","id":"a673b3829e62477e01abc75465416b86","lang":"ja","lastmod":1518605551,"permalink":"https://blog.johtani.info/blog/2018/02/14/start-nlp100-with-rust/","publishdate":"2018-02-14T19:52:31+09:00","summary":"ども。新しいもの始めないと頭が退化する。。。ということで、こちら( happy new year and new language - katsyoshiのめもみたいなもの)のブログに触発されて、","tags":["Rust","nlp100"],"title":"言語処理100本ノックはじめました(Rust)"},{"contents":"第1回では、Analyze UIというプラグインの紹介をしました、ごく簡単にですが。\n第2回では、Kibanaのプラグインの作成方法を順を追って見ていこうと思います。今回は、プラグインのプロジェクトの作り方を説明します。 どんなファイルがあるのかなどについては第3回で説明します(2018/02月現在の方法になります。残念ながら、Kibanaのプラグイン作成自体はまだExperimentalな話になっていますので、変更がある可能性があります)。\n実はそれほど難しいというわけではありません。Kibanaのプラグインを作成するためのテンプレートが用意されています。template-kiban-pluginです。 テンプレートのリポジトリのREADMEに作業手順の記載があります。\nKibanaのリポジトリをClone、Checkout Node.jsの環境を用意する Kibanaを起動できるようにする SAOのインストール テンプレートによるプロジェクトファイルの生成 順を追って説明します。 PLUGIN_DEV_DIRというディレクトリ配下で作業をしている想定になります。\n1. KibanaのリポジトリをClone、Checkout 開発環境として、Kibanaが必要です。Kibanaのプラグインを作るので。 手順などはKibanaのCONTRIBUTING.mdに記載があります。 ということで、まずはKibanaのリポジトリをCloneします。\ncd PLUGIN_DEV_DIR git clone git@github.com:elastic/kibana.git このままだと、masterブランチなので、開発したい対象のKibanaのバージョンのブランチもしくはタグをcloneします。今回は6.2.1向けということで、次のようになります。\ngit checkout v6.2.1 これで、ソースが6.2.1向けになりました。\n2. Node.jsの環境を用意する Node.jsをインストールします。 Kibanaのリポジトリに.node-versionというファイルがあります。 こちらにNode.jsのバージョンが記載されています。 Kibanaが使用しているNode.jsを利用できるようにします。ローカルではnvm利用してインストールしました。後から、切り替えが可能だからです。 nvm自体のインストールについてはnvmのサイトをご覧ください。 nvmがインストールできたら、次のコマンドで、Kibanaが使用しているバージョンをインストールします。\ncd kibana nvm install \u0026#34;$(cat .node-version)\u0026#34; すでにnvmを利用している場合などは、Kibana起動時にKibanaのバージョンに合わせたNode.jsに切り替えるようにしてください。\n3. Kibanaを起動できるようにする Kibanaではyarnというjavascript向けのパッケージマネージャーを利用して起動やビルドなどを行います。まずはyarnをインストールします。最近npmからyarnに切り替えたようです。 私はMacだったので、brewでインストールしました。 インストールできたら、次のコマンドを実行します。\nyarn これにより、package.jsonから必要なライブラリなどをダウンロードして来てくれます。 問題なければ「✨ Done in 439.30s.」というような表示がされます(結構時間かかりますね)。 では、Kibanaを起動できるか確認してみましょう。 さらに、Elasticsearchも起動してみます。 Kibanaのpackage.jsonの中にはElasticsearchを起動するためのスクリプトも用意されています。実際にはgruntを利用してタスクを実行しているようです。Elasticsearchの起動にはJavaが必要になります。 今回は6.2.1なので、JDK 8以降がインストールされている必要があります。 こちらはインストールされているものとします。\nyarn elasticsearch で起動できます。\n\u0026gt;\u0026gt; Started 1 Elasticsearch nodes. という表示が出てればOKです。 次にKibanaです。別のTerminalを起動して、以下のコマンドで起動できます。\nyarn start これだけです。\nserver log [06:58:56.930] [info][listening] Server running at http://localhost:5603 この辺りが出てればKibanaのServerは起動済みです。また、Elasticsearchに接続できていれば、次のログが出ているはずです。\nserver log [07:02:18.010] [info][status][plugin:elasticsearch@6.2.1] Status changed from red to green - Ready Elasticsearch接続用のKibanaのプラグインの状態になります。 これで、Kibanaの環境が整ったことが確認できました。 もちろん、Elasticsearchに関しては、yarnで起動せずに、tar.gzなどでダウンロードして来たElasticsearchを起動しておき、アクセスするといったことも可能です。プラグインなどをElasticsearchにもいれてテストしたい場合などはそちらの方が便利かもしれません。\n4. SAOのインストール では、一度、ElasticsearchとKibanaを停止しましょう。フォワグラウンドで起動しているので、それぞれのTerminalでCtrl+Cで停止できます。 Kibanaのプラグイン作成むけに、テンプレートが作られています。sao.jsというGitHubのリポジトリやnpmのパッケージをテンプレートとして使うことができるツールを利用してプラグインのプロジェクト(リポジトリ)を作成します。 実際にテンプレートとなるリポジトリはtemplate-kibana-pluginになります。 まずはSaoのインストールです。\nnpm install -g sao プラグインのテンプレートのページには上記のようにnpmを利用したインストール方法になっていますが、次のようにyarnでも可能です。\nyarn global add sao これで、saoがインストールできました。\n5. テンプレートによるプロジェクトファイルの生成 あとは、テンプレートを元にプロジェクトを作成します。 PLUGIN_DEV_DIRディレクトリ配下に、kibanaと同じ階層で作成するプラグイン用のディレクトリを作成します。\nmkdir simple-sample-kibana-plugin 以下のような構成になります。\nkibana simple-sample-kibana-plugin 次にテンプレートを適用していきます。\ncd simple-sample-kibana-plugin sao kibana-plugin@7.2.4 2行目がsaoを利用してプロジェクトを作成しているコマンドになります。 すると、次のような質問が出て来ます。 これらに答えるとプロジェクトに必要なファイル(package.jsonやREADME.mdなど)に入力した情報を適用したものを作ってくれます。\n? Name of your plugin? ? Provide a short description ? What Kibana version are you targeting? ? Should an app component be generated? ? Should translation files be generated? ? Should an hack component be generated? ? Should a server API be generated? 実際に答えた内容はこちら。\n? Name of your plugin? simple-sample-kibana-plugin ? Provide a short description Sample plugin for explaining how to make kibana app ? What Kibana version are you targeting? 6.2.1 ? Should an app component be generated? Yes ? Should translation files be generated? Yes ? Should an hack component be generated? Yes ? Should a server API be generated? Yes プラグインの名前などは、ディレクトリ名と同じものを入力補完してくれているので、そのままEnterでもOKです。 Descriptionについてはわかりやすいものを入力しましょう。 バージョンは、先ほどのKibanaのリポジトリに合わせて、6.2.1にしてあります。 あとは、作るプラグインの種類に応じて、必要なコンポーネントを作るかどうかの質問にYes/Noで答えます。 今回はサンプルの説明ということもあるので、全てYesで答えました。 ちなみに、私が実際に作成したanalyze-api-ui-pluginでは、appとtranslationとserverの3つを作成しました。 ただし、translationについては現在はテンプレートで作成したままのファイルが入っており、実際には利用してないです。\n完了したら、プラグインのサンプル入りのプロジェクトが完成です。 もう一度、Elasticsearchを立ち上げて、プラグインのプロジェクトからKibanaを起動してアクセスしてみます。まずは、PLUGIN_DEV_DIR/kibanaディレクトリの下で、Elasticsearchを起動します。\nyarn elasticsearch 次に、PLUGIN_DEV_DIR/simple-sample-kibana-pluginディレクトリの下で、以下のコマンドを実行し、プラグインが入った状態のKibanaを起動します。\nyarn start 問題なく起動すれば、ブラウザでアクセスすると次のような画面が表示されるはずです。\n左側にメニューが1つ増えています。 クリックすると、上記画像のような画面が表示されるはずです。\nこれで、カスタムプラグインの開発ができる環境ができました! 次回は、プロジェクトのディレクトリ構成や、どんなツールが内部で使用されてデータのやり取りが行われているかについて説明します。お楽しみに。\n","date":1518167857,"dir":"post/2018/","id":"7b6cb59a177abe9767fd22da5a03b1e6","lang":"ja","lastmod":1518167857,"permalink":"https://blog.johtani.info/blog/2018/02/09/getting-started-template-kibana-plugin/","publishdate":"2018-02-09T18:17:37+09:00","summary":"第1回では、Analyze UIというプラグインの紹介をしました、ごく簡単にですが。 第2回では、Kibanaのプラグインの作成方法を順を追って","tags":["Kibana","plugin"],"title":"Analyze UIとKibanaのプラグインの作成方法(第2回)"},{"contents":"あけましておめでとうございます。今年はサボりがちだったブログをちょっとずつ復活させようかと。 ということで、第1弾として、昨年少し作っていたKibanaのプラグインを何度かに分けて紹介したいと思います。\n今回はAnalyze UIというプラグインの紹介です。\n今回はインストール方法と簡単な機能紹介です。 細かな紹介は個別にやりたいと思います。\nAnalyze UI pluginとは? Elasticsearchの_analyzeというAPI\u0002(個人的に好きなAPIです)をご存知でしょうか?\nElasticsearchは全文検索エンジンで、データの検索には転置インデックスというものを使用します。 Elasticsearchにデータを登録する際に、text型のデータの場合、この転置インデックスのキーとなる単語を決める処理のことをAnalysisと呼びます(Analysisの詳細については割愛します。後日説明するかも?)。 このAnalysisの処理が、入力されたデータの文字列に対してどのように行われて、結果としてどんな単語がキーとして用いられているかを確認できる機能が_analyze APIです。検索で単語がうまくヒットしないな?とか、なんで、こんなので検索結果に出てくるんだ?といった場合、このAPIを利用すると、どのような単語で転置インデックスが作られているかがわかるので、検索にヒットしない/する理由を見つけることができます。\nElasticsearchの便利な点はRESTfulなAPI+JSONでやりとりができる点なのですが、_analyze APIの結果をJSONで受け取っても、見るのにちょっと苦労します。。。こんな感じ。\nリクエスト:\nPOST _analyze { \u0026#34;analyzer\u0026#34;: \u0026#34;kuromoji\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;今年はブログをいっぱい書きますよ!\u0026#34; } レスポンス:\n{ \u0026#34;tokens\u0026#34;: [ { \u0026#34;token\u0026#34;: \u0026#34;今年\u0026#34;, \u0026#34;start_offset\u0026#34;: 0, \u0026#34;end_offset\u0026#34;: 2, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 0 }, { \u0026#34;token\u0026#34;: \u0026#34;ブログ\u0026#34;, \u0026#34;start_offset\u0026#34;: 3, \u0026#34;end_offset\u0026#34;: 6, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 2 }, { \u0026#34;token\u0026#34;: \u0026#34;いっぱい\u0026#34;, \u0026#34;start_offset\u0026#34;: 7, \u0026#34;end_offset\u0026#34;: 11, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 4 }, { \u0026#34;token\u0026#34;: \u0026#34;書く\u0026#34;, \u0026#34;start_offset\u0026#34;: 11, \u0026#34;end_offset\u0026#34;: 13, \u0026#34;type\u0026#34;: \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34;: 5 } ] } このくらいの量であればまだなんとかなりますが、文章が長くなると辛いですよね。\nということで、GUIがあると便利だろうなぁと。で、作ってみましたというのが今日紹介するKibana用のAnalyze UIプラグインです。 こんな感じで、Kibanaのアプリの一部として動作しブラウザ上で、入力テキストの文字列がどのようにanalyzeされて、単語になるかがわかります。\n(先ほどのAPIのサンプルと同じものを画面で入力した結果になります)。\nインストール方法 現時点の最新版Kibana(6.1.2)に対応しています。 Kibanaのディレクトリでkibana-pluginコマンドを利用してインストールします。\n./bin/kibana-plugin install https://github.com/johtani/analyze-api-ui-plugin/releases/download/6.1.2/analyze-api-ui-plugin-6.1.2.zip これだけです。 で、Kibanaを起動していただくと、左のメニューに「Analyze UI」という項目が増えています。\nクリックすると、Analyze UIが表示されます。\n初期画面は入力された文字を特定のAnalyzerで処理した場合の結果を見るための画面です。綱目の説明は画像をご覧ください。\n先ほどのJSONよりは見やすくなったかと思います。 そのほかにもいくつか画面や機能があるのですが、今日はこの辺りで。 「_analyze API便利なんだけど、JSONは。。。」とか「検索うまくできないなぁなんでだろう?」と思っている方は、ぜひ試して見ていただければと。 問題点などありましたら、GitHubのIssueを登録してください。\n","date":1516343806,"dir":"post/2018/","id":"4afcb20d4d95bcd1bde3aa6b7f552660","lang":"ja","lastmod":1516343806,"permalink":"https://blog.johtani.info/blog/2018/01/19/how-to-make-kibana-plugin-example-analysis-ui/","publishdate":"2018-01-19T15:36:46+09:00","summary":"あけましておめでとうございます。今年はサボりがちだったブログをちょっとずつ復活させようかと。 ということで、第1弾として、昨年少し作っていたK","tags":["Kibana","plugin"],"title":"Analyze UIとKibanaのプラグインの作成方法(第1回)"},{"contents":"今年は紅白を見ながら書いてます。 今年はいろんなところに出張に行ったなぁ。\n振り返り(2016年に書いた抱負から) まずは去年の抱負を元に。\nもちろん英語の継続 もちろん継続してます。英会話しながら海外TVドラマや映画を見てます。 ちょっとずつ英語字幕でも見ようとしてますが、まだまだだなぁ。 あと、TOEICを受けてないんで、それは受けないと。 見たドラマはこの辺です。\nER ウォーキング・デッド Agent of Shield SUITS Mr.Robot(いまいち話の展開についていけなかった) 継続的にイベントに登壇 OSCに今年もブース出してセッション持ってました。 勉強会ももちろんやりました。 あと、外部のカンファレンス(FOSS4G、BigData Analytics、db tech showcaseなど)や 勉強会(monitoring勉強会やCA.ioなど)にも登壇させていただきました。 もっと外部から読んでいただいたり、CfPに応募して通過できるようにしないとなぁ。\nもっと開発&ブログ ブログはすみません。。。来年頑張ります。。。 ブログの代わりに書籍を出せました。データ分析基盤系の書籍になるので、興味のある方はのぞいて見ていただければ。\n開発はちょっとやってます。今年後半はKibanaのプラグインとかをちょっと書いてました。 Ingest-CSVもちょこちょこバージョンアップに追従してたりします。\nサポートエンジニア獲得! 獲得しました!(自分の成果かどうかはわかりませんが。。。) 今は3名体制でサポートしてもらってます。おかげさまでだいぶサポートする機会が減ってきました。 開発は世界各地どこでも募集中だったりしますので、ぜひ連絡いただければと。\n個人的な検索勉強会の再開 再開しました。検索エンジン自作入門を知人と隔週くらいで読んでます。読んでるだけではあれなんで、実装もしてたり。全然違う言語でトライして見ようと思ったのでRustで書き始めてます。まずは、単純なところからと思ったんですが、 Rustの書き方の違いにだいぶ戸惑ってます。。。\n振り返り(今年あったできごと) ここからは今年の出来事を。\n初アメリカで釣り Nintendo Switch! 初Japanチームオフサイト チーム変更 初Berlin Buzzword! 母校(大学)訪問 Kibanaプラグイン開発 今年も初モノがちらほらとありますね。 今年もカレンダー振り返ってたら「え?これ今年だったの?」ってのがちらほらありました。。。\nアメリカで釣りやりました。自社のカンファレンスElastic{ON}のあとに、エンジニアが集まるミーティングがあるんですが、そこで1日Fun Dayがあって、そこで釣りをやりました。 魚群探知機とかで魚探すんですね、最近のは。2、3匹釣ったので非常に楽しかったです。 来年はスノーシューにチャレンジする予定。\nNintendo Switch買って、ゼルダやりました。今はイカやってます。 イカ欲はちょっと減ってるかもなぁ、1に比べると。 あとは、子供に買ったマリオやったりしてるかな。\nここ10年くらい行きたいと思っていたカンファレンス、Berlin Buzzwordに行ってきました! これが今年一番嬉しかった出来事です。Luceneコミッターの方々にも会えたし。特にPoliceman JenkinsのUweさんに会えたのが本当に感激でした。。。 来年も行けるといいなぁ。。。\n今年も出張が多めだったのであちこち飛び回ってたなぁ。 そんな飛び回っている中で、故郷である広島(出身地?)に出張で行ったので、母校に顔を出してきました。 変わってなかった。。。自分が一期生なので、自分が入学した時はまだクレーンとか立ってるような新校舎だったんだけど、それが20年くらい経て、だいぶ古くなってました。。。 広島市内は港近くに高速道路とか出ててだいぶ様変わりしてました。 ただ、小学校も高校も変わってなかったなぁ。久々に高校の同級生にも会えたし。 また、機会があればぜひ行きたいなと。帰省する場所ではなくなったので、行く機会がないんですよね。。。\n開発もちょっとやってます。Kibanaのプラグインに挑戦して見てます。 いまだにJavaScriptは苦手なんですが。。。 ちょっとずつ改良して、ひょっとすると本体とかに取り込めるかな? あとは、今年始めたRustをちょっとずつ継続して行きたいなと。\n来年の抱負 最後は来年の抱負を。\nもっと英語の継続&TOEIC 継続的にイベントに登壇 CfPもっと出すぞ! もっとブログ! 雑誌やWeb系雑誌で記事を。 コミュニティを別の方法で盛り上げ Elasticsearchなど検索系の開発にも参加 英語はもちろんですね。今年は12月の自社イベントに合わせて多くのAPJチームの人が来て、 チームで会話できたし、もっと英語やらないとなぁと。前よりもちょっとは喋れるようになった気がしてます(気がしてるだけで、喋れてるかどうかは不明)。あとは、TOEIC受けて、実力チェックしてみないとなぁ。\nイベント登壇はまぁ、DevRelですから、一応。 来年もとりあえず、3月までは毎月どこかでブース出してます。 Ask Me Anything的なブースの出し方を今年はしてみようかなと思ってるので、 ちょっと使い始めたけど、この辺よくわからないと思ってる方、ぜひ質問しに来てください。 ブース出すだけじゃなくて、スピーカーとしていろんな場所で喋れるようにしないとなぁと。 もっと幅広く知ってもらえるように雑誌とかで連載できるようにしたいなぁと思ってます。 また、日本語の入り口の情報を増やすためにブログも書かないとなぁ。\n勉強会も継続しますが、別の方法でも盛り上げて行きたいなぁと。 勉強会はどうしても聞く人が多くて、ユーザーの間での交流や情報交換とまでは行ってない気がするし、discuss.elastic.coというフォーラムで質問は増えて来てるけど、もう少し交流しやすい場があると使ってもらえるかなぁ?と思っていたり。 何かおすすめとかあれば、連絡ください。 meetup.comの勉強会のページにも掲示板はついてるんだけど交流しにくそうだし。\n来年は自分が最も興味のある検索系の開発にも参加したいなぁと。 Elasticsearchをちょっとずつ時間見つけてやってたりはしますが、もう少し首を突っ込んで行きたいなぁと。Swiftypeもジョインしたし。もっと検索やって行きたい気持ちが強いので。\nさて、ということで、今年もあと1時間なくなりました。 今年も様々な面で色々な方々に助けていただけました。本当にお世話になりました。 この場を借りてお礼申し上げます。\n来年ももちろん、色々な方に助けてもらうと思いますが、よろしくお願いいたします!\n","date":1514723443,"dir":"post/2017/","id":"7c21b70f9e9c782c1f5153268e0cc1c1","lang":"ja","lastmod":1514723443,"permalink":"https://blog.johtani.info/blog/2017/12/31/looking-back-2017/","publishdate":"2017-12-31T21:30:43+09:00","summary":"今年は紅白を見ながら書いてます。 今年はいろんなところに出張に行ったなぁ。 振り返り(2016年に書いた抱負から) まずは去年の抱負を元に。 もちろ","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2017)"},{"contents":"Merry Christmas! Elastic Stack Advent Calendar 2017の24日目の記事になります。\nちょっとですが、2018年のElasticについて書いてみようかと思います。\nイベント いくつか出展が決まっているイベントがあるのでまずは宣伝を。\nOSC Osaka 2018 まずは、1月25日、26日にOSC Osaka 2018に出展し、話をします。参加者がいそうであれば、25日や26日の夜に勉強会もありかなぁと思っています。 セッションでは入門的な話をする予定です。ブースにいますので、色々質問がある関西の方はぜひご参加ください。\nDeveloper Summit 2018 2月15日、16日はDeveloper Summit 2018に出展します。 こちらでもブースにいますので、AMA(Ask Me Anything)的に使っていただくのもいいかなと。 デブサミに参加される方はぜひお立ち寄りください。\nManabiya 3月23日、24日はManabiyaに出展します。 こちらでもAMAのつもりでブースを出す予定です。質問がある方はぜひお立ち寄りください。 こちらのイベントは初めての開催になるようなので、どんなイベントになるか楽しみにしています。\nイベント回りはこの辺りで。 また、1月末に勉強会を予定しています。決まり次第またMeetup.comの方々にメールを出す予定です。\nElastic Stackの2018年は? Canvas! 昨年のElastic{ON}でみなさんをCanvasがリリースされるかなぁと。 現在、みなさんにテストしてもらえるようにcanvas.elastic.coというサイトを公開中で、実際にインストールして試すことができるようになっています。 ぜひ、触って、全く新しいUIを体験して見てください。\nSQL? こちらも昨年のElastic{ON}でみなさんから反響があったものです。 もう直ぐでてくるのではないかなぁと。\nその他は? いくつか面白そうで、取り込み済みのものをピックアップしておきます。\nAdd ranking evaluation API 検索クエリなどに対して検索結果のランクのクオリティを評価するためのAPIの追加(7.0予定) JDK9サポート? 6.2でサポートされそうです。が、LTSのJDK8が推奨のままの予定です。 High-level REST ClientでいくつかAPIが追加 https://github.com/elastic/elasticsearch/pull/27574、https://github.com/elastic/elasticsearch/pull/27351 APM正式リリース? ベータ版がリリースされているので、秒読み段階? ということで より詳しく知りたい方は、サンフランシスコで開催されるElastic{ON} 2018に参加するのが一番です!(ステマ) 私も参加予定ですので、ぜひ、現地でお会いし、色々な情報をゲットしましょう。\n明日で、今年のAdvent Calendarも最後です。micci184さんの記事を楽しみにしましょう!\n","date":1514124616,"dir":"post/2017/","id":"f3a9b931b7f552a4f9dfa61ce4f39f0e","lang":"ja","lastmod":1514124616,"permalink":"https://blog.johtani.info/blog/2017/12/24/elastic-2018/","publishdate":"2017-12-24T23:10:16+09:00","summary":"Merry Christmas! Elastic Stack Advent Calendar 2017の24日目の記事になります。 ちょっとですが、2018年のElasticについて書いてみようかと思います。 イベント いくつか","tags":["elasticsearch"],"title":"2018年のElasticは?"},{"contents":"Elastic stack (Elasticsearch) Advent Calendar 2017の1日目の記事になります。\nまだ、1ヶ月を残していますが、簡単に今年起こったことを振り返ってみようかと思います。思った以上に色々ありましたね。。。\nElastic Stack 5.2.0リリース (1月) リリース記事はこちら\nHeatmapがKibanaで追加されたり、Heartbeatがベータですが追加されました。 個人的には、Terms aggregationのFiltering Valuesによるパーティションが便利になったと思います。Terms Aggsでページングに似たことができるようになりました。\nElastic{ON}17開催 (3月) 第3回目のユーザカンファレンスが開催されました。 バレーダンサーの踊りから始まったキーノート、様々なユーザ企業によるユースケース発表などいろいろありました。 セッションはこちらのサイトからから録画を見ることができます。 SQL for ElasticsearchやAwardが目を引いたと思います。SQL対応まだ出てきていないですが、もうすぐじゃないかと!\nElastic Stack 5.3.0リリース (3月) リリース記事はこちら\nFilebeat moduleが導入され、ログファイルを取り込んでKibanaで可視化するまでの手順がより簡単になりました。Elasticの目指しているものの一つに、シンプルな使い方、簡単にはじめられることといったものがあります。KibanaのTimepickerもより便利になったのも、このバージョンからです。\nShayがCEOに (5月) 2月にすでに発表されていましたが、Elasticsearchの生みの親のShay BanonがCEOに正式に就任しました。CEOになってさらに、精力的に様々なことをやっていて、本当にすごいなと思います。\nElastic Stack 5.4.0、6.0.0-alpha1リリース (5月) 5.4.0リリース記事はこちら、6.0.0-alpha1リリース記事はこちら\n5.4.0は節目になるリリースでした。Machine Learningがベータリリースとして、X-Packに追加されましたし、ElasticsearchではCross Cluster Searchの改善が進みました。LogstashではPersistent QueueがGAになりましたし、KibanaにはTime Series Visual BuilderやEvent Contextなどが追加されますます使いやすくなりました。\nまた、6.0.0のalpha版も同時にリリースされ、様々な方からのフィードバックが集まり始めました。\nElastic Cloud Enterprise GAリリース (5月) Elastic Cloudのバックエンドの技術を製品に採用したものになります。 多くのElasticsearchクラスタを管理しないといけない方には朗報でした。\nOpbeatがJoin (6月) Opbeatチームがジョインしたのが6月です。Elastic StackがAPM\u0002(Application Performance Monitoring)でも活躍することになりそうです。APMの仕組みとしては、APM Agentをアプリ側に配置し、APM Serverへデータを送信し、Elasticsearchに保存、Kibanaで可視化するという流れになります。\nElastic Stack 5.5.0リリース (7月) リリース記事はこちら\nMachime LearningがGAリリースになったのが5.5.0です。色々な方から質問を受けました。それ以外にも、ElasticsearchのWindows MSI InstallerやKibanaのFilter editorなどが追加されました。Filter editorはこれまで検索条件を記述するのが難しいと感じていたKibanaユーザにとても喜んでもらえたものじゃないかなと。 GrokDebuggerが導入されたのもこのタイミングです。\nElastic Stack 5.6.0リリース (9月) リリース記事はこちら\n5系最後のマイナーリリースであり、6へのアップグレードが楽になる様々な仕組みが用意されたのがこのバージョンです。ElasticsearchのJava High level REST clientが導入されたのもこのバージョンです。本当に様々な機能が次のメジャーバージョンとの互換性のために組み込まれています。。。\nElastic Cloud on GCP (9月) リリース記事はこちら\nこれまで、AWS上のみで展開していたElastic CloudがGCP上でも展開されることになりました。残念ながら、日本リージョンはまだありませんが、問い合わせなどが増えれば今後サポートされる可能性が高くなると思います!\nElastic APM alpha (9月) リリース記事はこちら\nOpbeatチームによりElastic StackのAPMがAlphaですがリリースされました。APMがOpen Sourceで利用できるんです!Agentがもっと増えてくると色々なことに使えるようになると思います。ぜひAgentを作成してみてください!\nElastic Stack 6.0.0リリース (11月) リリース記事はこちら\n待ちに待った6.0.0のリリースです。新機能については本日(12/1)の昼に行われるウェビナーをご覧ください!\nSwiftypeがJoin (11月) ニュースリリースはこちら\nSwiftypeと呼ばれる検索のSaaSを提供している会社がジョインしました。 個人的には今年一番嬉しいニュースです。やはり、検索が好きなので。 簡単にSite Searchを構築できる仕組みは非常に面白いものです。 興味のある方は、ぜひ触ってみてください。日本語固有の機能などはまだないので、今後関わっていければなーと。\nElastic{ON} Tour Tokyo開催 (12月) まだ開催前ですが、今年も東京で1dayイベントを開催します。 残念ながら、もうSold outなので、キャンセル待ちになってしまっているみたいですが。私もスピーカーとして喋りますし、AMAブースにも立っています。 参加される方はぜひ声をかけていただければと思います。\nOSC 2017.Enterprise (12月) オープンソースカンファレンスで今年も様々な都市に出張しました。 今年の締めくくりということで、12/8に渋谷で開催されるカンファレンスに出展します。時間のある方は、ぜひブースに遊びに来てください。入門者向けのセッションもあるので、こちらもお待ちしております。\nまとめ 超駆け足ですが、今年を振り返ってみました。 今年もいろんなことがありました。書くのが大変だったw。 OSCなどイベントで声をかけていただいた皆様、ありがとうございました。\nさて、Elastic Stack Advent Calendar 2017は始まったばかりです。これからの記事を楽しみにしています!\nということで、 次はaeroastroさんの「Elasticsearchのインデックスを本当の意味で無停止再構築する方法」(Advent Calendarのページはこちら)になります、お楽しみに!\n","date":1512054000,"dir":"post/2017/","id":"fa0486610d8a02cea245c13c85b6de27","lang":"ja","lastmod":1512054000,"permalink":"https://blog.johtani.info/blog/2017/12/01/whats-happen-at-elastic-in-2017/","publishdate":"2017-12-01T00:00:00+09:00","summary":"Elastic stack (Elasticsearch) Advent Calendar 2017の1日目の記事になります。 まだ、1ヶ月を残していますが、簡単に今年起こったことを振り返ってみようかと思います。思った以上に","tags":["elasticsearch"],"title":"2017年のElastic StackとElastic"},{"contents":"Swiftypeでサイト内検索? プレスリリース:Elasticがサイト内検索サービス最大手のSwiftypeを買収が出ましたが、SwiftypeチームがElasticにジョインしました!\n自分のブログ検索に導入してみる? SwiftypeはSite Searchをサービスとして提供しています。 実際に指定したサイトのデータをクロールして、インデキシングし、検索できるようになります。 ものは試しということで、自分のブログを登録してみました。検索窓はつけてないですが。 14日間のFree trialがあるのでそちらで試してみましょう。 検索窓はデモとか作れたらかな。\nということで、Free trialへ まずはユーザ登録です。Googleのアカウントと連携するか、Swiftypeにメルアドを登録するかが選択できます。 登録できたら、次にどちらのプロダクトを使うかという選択画面が出てきます。 今回はサイト検索して見たいので、「Site Search」の「START FREE TRIAL」をクリックします。\nEngineの指定 Web Crawlerを利用するか、独自にSwiftypeのAPIを利用してデータを登録するかを選択します。\n今回は、お手軽な方のCrawlerを選択します。 すると次に、クロールしたいURLの指定画面が出てきます。\n今回は自分のブログなので、\u0026lsquo;http://blog.johtani.info\u0026rsquo;を指定します。\nで少し待つと、URLのチェック(存在チェックとか、接続チェックとか)が終わり、今回作成するEngineに名前をつける画面が出てきます。 「My Blog search」という名前にしてみました。\nsitemapがあるかどうかをCrawlerがチェックしています。 私のBlogはOctopressでできていて、sitemap.xmlも作ってくれているので、これを元にCrawlerはクロールをしてくれます。そのほかにもRSSやAtomサポートもあるみたいですね。 「COMPLETE SETUP」を押すと、Engineの管理画面が出てきます。\n「CRAWLING」という表示が出ています。クロールしている最中です。これが終われば、「PREVIEW」に代わり、検索できる準備ができたことになります。 実際にPREVIEWして見ると、次のような検索ができるようになります。\nそのほかにはWeightの調整画面などもありますね。フィールド毎に重み付けを変えて見たりもできます。\n日本語独自のAnalyzerなどはまだないので、そのあたりができてくるともっと便利になりそうです。 とりあえず、気になる方は触って見てはいかがでしょうか? 個人的は検索に関するサービスが出てきたのですごく楽しみにしています!\n","date":1510280089,"dir":"post/2017/","id":"c20d71627e66a044b21780f56f2f9504","lang":"ja","lastmod":1510280089,"permalink":"https://blog.johtani.info/blog/2017/11/10/welcome-swiftype/","publishdate":"2017-11-10T11:14:49+09:00","summary":"Swiftypeでサイト内検索? プレスリリース:Elasticがサイト内検索サービス最大手のSwiftypeを買収が出ましたが、Swifty","title":"Swiftypeがジョインしたので触ってみました"},{"contents":"久々に執筆しました。といっても、以前の書籍の更新版です。 まぁ、更新版といっても、私以外の方々は結構な量を書き直しor新規書き起こしされてますが。。。\nということで、みなさん「買って」から感想をいただけるとうれしいです!\u0002(以下の画像でAmazonにジャンプできます!Kindle版も発売中です。)\n今回もElasticsearchの章を担当しました。 5.4ベースで書きましたが、ちょっとずつ6でどう変わるかなども記載してあります。 また、付録ではLogstashやBeatsにもちょっと触れています。 また、自分が一番好きなKibanaの機能であるDev ToolsのConsoleについても記載してあります。こちらも合わせて目を通していただければと。\nみなさんのフィードバック(ツイート、ブログ、Amazonのコメントなどなど)をお待ちしております!\n","date":1505955750,"dir":"post/2017/","id":"4f88f3eebe44285ded812939553ef94c","lang":"ja","lastmod":1505955750,"permalink":"https://blog.johtani.info/blog/2017/09/21/release-intro-logging-analysis-system/","publishdate":"2017-09-21T10:02:30+09:00","summary":"久々に執筆しました。といっても、以前の書籍の更新版です。 まぁ、更新版といっても、私以外の方々は結構な量を書き直しor新規書き起こしされてます","tags":["elasticsearch","kibana","本"],"title":"データ分析基盤構築入門 を一部執筆しました。"},{"contents":"久々のブログ。 Elasticsearch勉強会を主催してますが、 プロダクトを超えて、検索で共通してある課題とか、悩みとか、あるかなぁと。 その辺りを話す場所を考えてみるのいいかもと思い、検索座談会ってのを5人でやってみた。\nとりあえず、初めてなので、5名ほどで。プロダクトはかぶってない感じでした。\n話した議題はこの辺り。 形態素解析の辞書は何を使ってる?有償のもの? そもそも形態素解析? 辞書の更新とかは? シノニムってどうしてる? サジェストとかのデータはどう作ってる?どうしてる? 検索ログとかから作ってる? 検索結果のランキングって検索結果だけで決めるの? 検索漏れとかキーワードのミスマッチとかどうしてる? 今後話したい内容はこの辺かな? 緯度経度系の検索 画像検索、音声検索 検索のキーワードの調査とかしてる人とかいるかな? どんな機能が欲しい? 前処理としてはどんなことをしてる? このあとどうしていくかはまだ考え中。知り合いを捕まえて、どんなことしてるかを聞きにいくのもいいし、議題みたいなことを決めて、それを話してくれそうな人にコンタクトして議論するのもありかなぁ。 普通の勉強会みたいなのにするかもしれないし。 とりあえず、どのくらい興味を持ってる人がいるのかがわからないので。。。\nもちろん、Elasticsearch勉強会は別でやっていきますよ。\n","date":1495639453,"dir":"post/2017/","id":"29b4c2b5adcd80ced1612128b3ca95a9","lang":"ja","lastmod":1495639453,"permalink":"https://blog.johtani.info/blog/2017/05/25/search-meetup/","publishdate":"2017-05-25T00:24:13+09:00","summary":"久々のブログ。 Elasticsearch勉強会を主催してますが、 プロダクトを超えて、検索で共通してある課題とか、悩みとか、あるかなぁと。 その","tags":["勉強会"],"title":"検索座談会ってのをやってみた"},{"contents":"今年はRioのプレイバック\u000e見ながら書いてます。 今年はなんか長い一年だった気が。\n振り返り(2015年に書いた抱負から) まずは去年の抱負を元に。\n英語の継続 継続してます。まぁ当たり前ですが。もう少し話す機会増やさないとだなぁと思いつつ。英会話しながら、海外TVドラマ見ながら。 見たドラマはこの辺かな?\nER SUITS メンタリスト Numb3rs エレメンタリー Agent of Shield あと、映画も見てます。とりあえず、耳を慣らすために字幕ありで見てるので、 英語だけでとは行きませんが。。。 そろそろ同じ映画を英語字幕で見るとかしたほうがいいのかもなぁ。\nもっとElasticsearchの開発に参加 一応参加してます。ちょっとずつですが。 イベントが重なるとできなくなるので、小さなPRとかを細々とって感じですが。。。\n人員の倍増? 倍増したかな?現時点で日本は8名になりました。そのうち1人は完全リモートです。 来年も倍増とは行かないだろうなぁ。取り急ぎ、サポートエンジニアが足りてないのでそこを埋めないと。。。\n日本語情報発信 これはちょっと足踏みしてるかも。ブログの翻訳とかはやってるんですが、もう少しなんとかしないとなぁ。ブログも書かないと。。。\nSplatoon S+? なりました!とりあえずS+とSを行ったり来たりしてる感じです。 メインはノヴァネオですが、Sに落ちたら違う武器でS+に上がるまでチャレンジするってのをやってます。わかば、バケスロソーダ、プライム、ワサビくらいはやったかな? そろそろまた違う武器かなぁ。S+99は無理そうなんで。。。\n振り返り(今年あったできごと) その他の今年の出来事。\n初香港 初プラハ OSCなど、東京以外でのカンファレンス参加 厄年 東京オフィス! BBLとかトレーニング lucene-gosenをちょっとメンテ Podcastデビュー? 初モノ今年も多いかな。 今年は、昨年よりは長く感じた一年でした。 月1くらいで出張してたのもあるのかなぁ? 香港、プラハはもちろん会社のイベントです。 香港はジャッキーチェンの映画を彷彿とさせるところがちょくちょくあって面白かったです。 ビルとかの補修の足場が竹竿とか。 プラハも面白かったです。やっぱりヨーロッパの古い町は歴史のある建物が多くて楽しいです。\nOSCなどのイベントも色々行きました。福岡、名古屋、大阪、京都、札幌と回りました。 それとは別に大阪、福岡も行ったかな。 来年は沖縄と広島に行きたいなぁ。。。 出張のついで?じゃないですが、御朱印集めし始めました。神社仏閣もいいですよねぇ。\n厄年はきつかった。。。たまたまだとは思うけど、お祓いに行ったのが効いたのかなぁ。後半は特に問題なかったかな。腕時計無くしたと思ったら見つかったりしたし。\n弊社東京オフィスができました。(あんまり行ってないけど) ときどきアクロクエストさんがセミナーを開いたりしてます。 昨年のTour Tokyo後のMeetupでもイベントスペースを使って、Drinkup(勉強会の懇親会だけバージョン)もやりました。 今後もちょこちょことイベントをやってみようかな?\nBBLも始めました。あまりきちんと宣伝してないからそれほど依頼は来てないですが。 あとは、今年も2回日本語でトレーニングしました。 前回はほぼ満席にまでなりました。 来年も頑張りたいかな。ショートカットするためにもいいと思うんで、トレーニングを受けて欲しいんです。。。\nlucene-gosenのメンテもしました。 といってもプログラムではなく、ビルドシステムをAntからGradleに変更したんですが。 来年もちょっとずつ触りたいな。機能面で拡充するかはわからないですが。。。\nPodcastにもデビューさせていただきました。 wyukawaさんのPodcastです。「johtaniさんとElasticsearchについて話しました」楽しかったです。 また出たいなぁというか、喋るの面白かった!\n来年の抱負 もちろん英語の継続 継続的にイベントに登壇 もっと開発&ブログ サポートエンジニア獲得! 個人的な検索勉強会の再開 英語はまぁ、当たり前ですね。会社の人つかまえてもっと喋る時間増やさないとだな。\n来年もいろんなカンファレンスなどに出てブース出したり、セッション持ったりして もっともっと広めていかないとなぁ。 あとは、勉強会とMeetupもやっていかないと。入門編と上級編みたいに分けてみるのもありかなぁと考えて見たり。 スピーカー、ご意見募集しております。\n開発に時間をさくための時間の活用をしていかないとなぁと。 どうも時間の使い方がまだ上手くないので。ブログも一緒ですね。。。 月1くらいのペースではかきたいな。。。 ブログもそうだけど書籍もかな???? あと、外資系の他の会社の人ともまた飲みたいなー。\n開発の時間を確保という面ではサポートエンジニアも募集中です。 最近、クライアントが増えて来てチケットが増えて来てるんで、サポートしたりもしてるんです。。。 自分の時間を増やすためにもサポートエンジニアを確保しないと。誰かいい人いないかなぁ。\n個人的にやってた勉強会を忙しいって言って中断してるので、再開しないと。。。\nということで、今年もあと數十分になってしまいました。 今年も色々な方に助けていただけました。お世話になりました。 この場を借りてお礼申し上げます。\n来年もいろんな方々に助けてもらうと思いますが、よろしくお願いいたします。\n","date":1483190534,"dir":"post/2016/","id":"16f1046144ad9ee7bb96214ba7ae7516","lang":"ja","lastmod":1483190534,"permalink":"https://blog.johtani.info/blog/2016/12/31/looking-back-2016/","publishdate":"2016-12-31T22:22:14+09:00","summary":"今年はRioのプレイバック\u000e見ながら書いてます。 今年はなんか長い一年だった気が。 振り返り(2015年に書いた抱負から) まずは去年の抱負を元に","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2016)"},{"contents":"Merry Christmas! Elastic stack Advent Calendar 2016 最終日の記事になります。\n簡単に今年の変遷を振り返ってみます。\nElasticsearch 2.2 (2月) Elasticsearch 2.2.0、2.1.2、1.7.5リリース クエリプロファイラやGeo系の性能改善などが取り込まれました。 また、同時期にリリースされたKibana 4.4ではColor pickerやShare用のURLの短縮化機能なども追加されました。\n第2回目のユーザカンファレンス、Elastic{ON}開催(2月) サンフランシスコで、弊社第2回目のカンファレンスが開催されました。 2015年の会場よりも大きくなり、多数の方に参加いただきました。 ここで、以下の発表がありました。\nElastic StackとX-Packの紹介 これまで、ELK stackと呼ばれて意味明日が、Beatsチームの参加により、ELKだけではなくなったこともあり、Elastic Stackと呼び名を変える事になりました。 また、Marvel、Shield、Watcherなどの商用の拡張機能についても、 単体の名称ではなく、X(Extension)-Packと1つの名前になる事に。 詳細については公式のブログをご覧ください。\nElastic CloudとElastic Cloud Enterpriseの発表 2015年にElasticにジョインし、 これまでFound.no(Found)と呼ばれていた弊社のElasticsearch as a ServiceがElastic Cloudと名称変更しました。 また、Elastic Cloudで培っているノウハウを詰め込んだElastic Cloud Enterpriseも発表しました。実際に利用可能になるまでには まだもう少しかかってしまいますが、アルファ版が公開されていますので、興味のある方は触ってみてください。\nElastic{ON}2016で撮影された、「Elasticsearchがないあなたの人生はどうなりますか?」 といった面白い動画も公開されています。\nElasticsearch 2.3リリース(3月) Elasticsearch 2.3.0および2.2.2をリリース Reindex APIが登場し、Mappingの変更やShard数の変更など、色々とデータの更新などがやりやすくなりました。 また、Task Managementの機能も追加され、長時間かかる処理を間違った場合などの対処が楽になりました。 個人的には、Deprecation Loggingの機能が導入されたことが嬉しいこととなります。次期メジャーバージョンで廃止される機能についてログに出力されるようになりました。 実際に運用されているアプリで利用している機能が今後なくなるかどうかをログを見るとわかるという仕組みです。\nRally登場(4月) Rally登場:Elasticsearchのベンチマークツール Elasticsearchのベンチマークツールがリリースされました。 定期的にElasticsearchの性能を計測することは問題点を見つける事に役に立ちます。そういった手助けをしてくれるツールが公開されることは非常に便利なことかと。\nElastic Stack 5 alpha1 リリース(4月) Elastic Stack 5.0.0 alpha 1 リリース Ingest NodeやLucene 6、新しいKibanaのUIなど多くのものが詰まっていました。ここから多くのユーザにテストしてもらい、5.0の正式リリースを迎えることができました。\nElasticsearch 2.4.0リリース(8月) 2.xの最後のマイナーバージョンリリースです。 Reportingなどの追加とドットつきフィールド名の復活がありました。\nElastic Stack 5.0.0 beta1 リリース(9月) Elastic Stack Release - 5.0.0-beta1 ついにベータです。Painlessがスクリプトのデフォルトになったり、TimelionがKibanaに取り込まれるなど、正式リリースまであと少し!\nPrelertチームジョイン(9月) Welcome Prelert to the Elastic Team Machine Learningエンジンを開発し、Elasticsearch,Kibanaとの組み合わせの製品をリリースしていたPrelertという会社がジョインしました。 Elasticsearchに保存された多くのデータをより活用していただくことができるかと思います。 Elastic{ON} Tour 2016 Tokyoで弊社SAの大輪の発表も人気があるものでした。まだベータ段階ですが、利用して見ることも可能です。 ビデオなどが公開されたらまたツイートしようと思います。\nElastic{ON} Tour Tokyo 2016開催(12月) 今年で2回目のTokyoローカルの1日イベントでした。 ブログは「まだ」書いてませんが、、、今回も盛りだくさんのイベントになりました。 早朝のトレーニング(ハンズオンではない)にも80名近くの方に参加していただけましたし、私はKibanaのキーノート+デモという大役をもらいましたし、ちょっと大変でした。 今年もAMA(Ask Me Anything)ブースが大盛況でした。 色々な方から、弊社のサポート、開発者が色々な質問を受け、それに答えるという形です。楽しんでいただけたかと思います。 来年もぜひ開催したいなと思っています。\nまた、Elastic{ON}17のセッションもいくつか発表されています。 ぜひ、サンフランシスコで行われる本場のカンファレンスにもご参加ください!\n来年は? 1月後半か2月にElasticsearch勉強会を検討しようと思っています。スピーカーに興味のある方は連絡いただければと。\n会社としては、Elastic{ON}2017が3月にまた開催されます。これで3回目となります。もちろん私も参加予定なので、参加される方は、現地で会いましょう!\nそのほかにもBIG DATA ANALYTICS TOKYOやオープンソースカンファレンス(大阪)、デブサミといったカンファレンスに参加(登壇・ブースなど)予定です。 参加される方は、ぜひブースまでお越しください。\nでは、また来年のAdvent Calendarでお会いしましょう!\n","date":1482591830,"dir":"post/2016/","id":"002d980d74d19b43ff4e2446665e2fe5","lang":"ja","lastmod":1482591830,"permalink":"https://blog.johtani.info/blog/2016/12/25/elasticsearch-6-features/","publishdate":"2016-12-25T00:03:50+09:00","summary":"Merry Christmas! Elastic stack Advent Calendar 2016 最終日の記事になります。 簡単に今年の変遷を振り返ってみます。 Elasticsearch 2.2 (2月) Elasticsearch 2.2.0、2.1.2、1.7.5リリース クエリプロ","tags":["elasticsearch"],"title":"2016年のElastic Stack"},{"contents":"Elastic stack Advent Calendar 1日目の記事になります。\nElasticsearch 5.0が10月末にリリースされました。 リリースのブログでいくつか紹介されているのですが、そこでは紹介されていない機能について2、3紹介しようと思います。\nその前に、5.0、あれ?その前は2.xじゃなかったっけ??と困惑されている方もいるかと思うので、簡単に5となった経緯の紹介をしようかと。\nバージョン番号 なぜ2から5に飛んだのかという話ですが、このスライドがその紹介になっています。\nhttps://speakerdeck.com/johtani/elastic-stack-5-dot-0-alpha1-alpha5?slide=5\nElastic{ON} 2016のキーノートでも紹介がありましたが、KibanaやLogstashとElasticsearchを組み合わせて使うときにバージョンのミスマッチで動かないというユーザの声が上がっていました。 2.xのリリースから、同じ日にKibana、Logstash、Beatsもリリースするようになったのですが、 やはり、バージョン番号が異なるため、ミスマッチで動かないというユーザが時々いました。\nElastic Stackという名称にもなったため、バージョン番号をそろえようという事になり、 Elasticsearch、Kibana、Logstash、Beats全てが5.0.0としてリリースされ、 今後は同じバージョン番号になります。\nちなみに、「5」になった理由はKibanaのメジャーバージョンが「4」だったためです。\nさて、では、いくつか機能の紹介を。\nReindex from remote cluster Reindexが2.3から導入されました。データの再登録ができるようになり、マッピングの変更や Shardの数の変更などが柔軟に行えるようになりました。 便利でしたが、あくまでも同一のクラスタでデータを登録し直す形でした。\n5.0からはこの機能に加えて、異なるクラスタからデータを取得してReindexを行うことができるようになりました。 こんな形になります。\nPOST _reindex { \u0026#34;source\u0026#34;: { \u0026#34;remote\u0026#34;: { \u0026#34;host\u0026#34;: \u0026#34;http://otherhost:9200\u0026#34;, \u0026#34;username\u0026#34;: \u0026#34;user\u0026#34;, \u0026#34;password\u0026#34;: \u0026#34;pass\u0026#34; }, \u0026#34;index\u0026#34;: \u0026#34;source\u0026#34;, \u0026#34;query\u0026#34;: { \u0026#34;match\u0026#34;: { \u0026#34;test\u0026#34;: \u0026#34;data\u0026#34; } } }, \u0026#34;dest\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;dest\u0026#34; } } usernameとpasswordはリモートのクラスタに認証の気候が存在する場合に利用できるオプションです。 また、ReindexのAPIはクエリを使用して、必要なデータだけを取得することが可能です。 この機能により、1.xや2.xのクラスタからデータを移行することが可能になります。\nCustom analyzer test using Analyze API もう一つ、ちょっとだけ便利な機能を紹介します。 独自にAnalyzerを定義(TokenizerとToken Filterなどを個別に設定)して、その挙動を確認するとき、2.xまでは、インデックスを作成してそのインデックスに対して_analyze APIを呼び出す必要がありました。\n5.xからは_analyze APIの読み出しのパラメータで指定できるようになりました。 こんな感じです。ここでは、lowercaseフィルタのあとに、{...}でstopフィルタを パラメータの中で、指定しています。\ncurl -XGET \u0026#39;localhost:9200/_analyze\u0026#39; -d \u0026#39; { \u0026#34;tokenizer\u0026#34; : \u0026#34;whitespace\u0026#34;, \u0026#34;filter\u0026#34; : [\u0026#34;lowercase\u0026#34;, {\u0026#34;type\u0026#34;: \u0026#34;stop\u0026#34;, \u0026#34;stopwords\u0026#34;: [\u0026#34;a\u0026#34;, \u0026#34;is\u0026#34;, \u0026#34;this\u0026#34;]}], \u0026#34;text\u0026#34; : \u0026#34;this is a test\u0026#34; }\u0026#39; ちょっとだけですが、Analyzerなどを試すのが楽になるのではないでしょうか?\nということで、以上が1日目の記事でした。 Logstashなど、他の5.0.0に関する記事もAdvent Calendarに空きがあるようなので、個別にかこうかなと思います。お楽しみに!\n","date":1480581270,"dir":"post/2016/","id":"550becdd08d00fb1e7fd00c2adc3d3d6","lang":"ja","lastmod":1480581270,"permalink":"https://blog.johtani.info/blog/2016/12/01/elasticsearch-5-dot-0-highlight/","publishdate":"2016-12-01T17:34:30+09:00","summary":"Elastic stack Advent Calendar 1日目の記事になります。 Elasticsearch 5.0が10月末にリリースされました。 リリースのブログでいくつか紹介されているのですが、そこでは紹介されて","tags":["elasticsearch"],"title":"Elasticsearch 5.0の便利機能紹介?"},{"contents":"久しぶりに、技術的なブログ書いてます。\nIngest Processorのプラグインを作ってみたくなったので、書いてみました。 ただ書いてみるんじゃ3番煎じになりそうなので、cookiecutterを使ってみました。\nと言っても、同僚のAlexがcookiecutter-elasticsearch-ingest-processorと言うテンプレートを作ってくれているのを使っただけですが。(https://discuss.elastic.co に投稿された記事で、使い方がアニメgifで説明されててわかりやすいです)\ncookiecutterとは、コマンドラインで質問に答えると、テンプレートからプロジェクトが生成できるツールです。 Elasticでは、カスタムBeatを作る時に利用する例がいつかの日本語ブログや発表資料で話題になっていました。 これのIngest Processorのプラグインバージョンです。\n今回は、NEologdも使ってみたかったので、Lucene Kuromoji for NEologdを利用して 指定した品詞の単語だけを抽出するProcessorを作ってみました。\nGitHubのプロジェクト:https://github.com/johtani/elasticsearch-ingest-kuromoji-pos-extract\nCookiecutterの使い方 Cookiecutterのインストールはサイトをご覧ください。\ncookiecutter gh:spinscale/cookiecutter-elasticsearch-ingest-processor あとは、出てくる以下の項目を指定するだけです。\nprocessor_type : Ingest Processorのタイプ名です。kuromoji_part_of_speech_extractとしました。(Alexのだと_を使うとちょっと問題があるので後述) description : readme.mdに利用されます。 developer_name : 名前を記載。Javaのファイルのヘッダに利用 elasticsearch_version : デフォルトで5.0.0-alpha4が指定されているので、特に指定せず 以上の質問に答えたら、プロジェクトのディレクトリ構造が出来上がってます。 プロジェクトのビルドなどにはGradleを利用します。\nプロジェクトのIntelliJ IDEA用のファイルを生成 build.gradleファイルでGradleのideaプラグインがapplyされているので、以下のコマンドを叩けばIntelliJ IDEAのプロジェクトファイル(?)が生成され、IntelliJで開けばすぐに開発ができる状態にできます。\ngradle idea コーディング あとは、必要処理をコーディングします。 実際にコーディングするクラスはorg.elasticsearch.plugin.ingest.kuromoji_part_of_speech_extractのパッケージにある以下の2つです。(パッケージ名にはprocessor_typeの名前が指定されている)\nIngestKuromojiPartOfSpeechExtractPlugin KuromojiPartOfSpeechExtractProcessor IngestKuromojiPartOfSpeechExtractPlugin Pluginというクラスは、プラグインをNodeのModuleとして登録する処理を書くクラスとなります。 生成してすぐは、次のような形になっています。(※importやクラス定義の部分は省略しています。)\n... public static final Setting\u0026lt;String\u0026gt; YOUR_SETTING = new Setting\u0026lt;\u0026gt;(\u0026#34;ingest.kuromoji_part_of_speech_extract.setting\u0026#34;, \u0026#34;foo\u0026#34;, (value) -\u0026gt; value, Setting.Property.NodeScope); @Override public List\u0026lt;Setting\u0026lt;?\u0026gt;\u0026gt; getSettings() { return Arrays.asList(YOUR_SETTING); } public void onModule(NodeModule nodeModule) throws IOException { nodeModule.registerProcessor(KuromojiPartOfSpeechExtractProcessor.TYPE, (registry) -\u0026gt; new KuromojiPartOfSpeechExtractProcessor.Factory()); } ... YOUR_SETTINGプロパティとgetSettings()メソッドはelasticsearch.ymlで指定したい設定を記述する場合の例になります。今回は特に必要ないので両方削除しました。 最終系はGitHubのコードをご覧ください。\nKuromojiPartOfSpeechExtractProcessor Processorは実際にIngest Nodeで行う処理を書くところです。\npublic static final String TYPE = \u0026#34;kuromoji_part_of_speech_extract\u0026#34;; private final String field; private final String targetField; public KuromojiPartOfSpeechExtractProcessor(String tag, String field, String targetField) throws IOException { super(tag); this.field = field; this.targetField = targetField; } @Override public void execute(IngestDocument ingestDocument) throws Exception { String content = ingestDocument.getFieldValue(field, String.class); // TODO implement me! ingestDocument.setFieldValue(targetField, content); } @Override public String getType() { return TYPE; } public static final class Factory extends AbstractProcessorFactory\u0026lt;KuromojiPartOfSpeechExtractProcessor\u0026gt; { @Override public KuromojiPartOfSpeechExtractProcessor doCreate(String processorTag, Map\u0026lt;String, Object\u0026gt; config) throws Exception { String field = readStringProperty(TYPE, processorTag, config, \u0026#34;field\u0026#34;); String targetField = readStringProperty(TYPE, processorTag, config, \u0026#34;target_field\u0026#34;, \u0026#34;default_field_name\u0026#34;); return new KuromojiPartOfSpeechExtractProcessor(processorTag, field, targetField); } } TYPEがIngest APIのPipelineでProcessorを指定するときに使う名前になります。ここは、cookiecutterの時にprocessor_typeに入力した文字列になっています。 kuromoji_part_of_speech_extractだと長いので、kuromoji_pos_extractに変えました。\nexecute()メソッドに// TODO implement me!とあります。 この部分に実際の処理を記述していきます。\nあとは、FactoryクラスでIngest APIで指定された設定項目を読み込みます。 今回作成したelasticsearch-ingest-kuromoji-pos-extractでは品詞を指定する必要があるので、pos_tagsを指定できるように処理を追加しました。\n私が実装したものの説明をするとちょっと長くなりそうなので、GitHubのコードをご覧ください。\nテストのコーディング テストのクラスもテンプレートで生成されています。\nKuromojiPartOfSpeechExtractProcessorTests KuromojiPartOfSpeechExtractRestIT KuromojiPartOfSpeechExtractProcessorTests Processorクラスのテストになります。生成直後は次のような感じです。\npublic void testThatProcessorWorks() throws Exception { Map\u0026lt;String, Object\u0026gt; document = new HashMap\u0026lt;\u0026gt;(); document.put(\u0026#34;source_field\u0026#34;, \u0026#34;fancy source field content\u0026#34;); IngestDocument ingestDocument = RandomDocumentPicks.randomIngestDocument(random(), document); KuromojiPartOfSpeechExtractProcessor processor = new KuromojiPartOfSpeechExtractProcessor(randomAsciiOfLength(10), \u0026#34;source_field\u0026#34;, \u0026#34;target_field\u0026#34;); processor.execute(ingestDocument); Map\u0026lt;String, Object\u0026gt; data = ingestDocument.getSourceAndMetadata(); assertThat(data, hasKey(\u0026#34;target_field\u0026#34;)); assertThat(data.get(\u0026#34;target_field\u0026#34;), is(\u0026#34;fancy source field content\u0026#34;)); // TODO add fancy assertions here } テストメソッドも実装されていますが、パラメータの追加の設定処理やアサーションが書かれてません。 実装に合わせて、アサーションや設定処理を追加しましょう。\nKuromojiPartOfSpeechExtractRestIT こちらはIntegration Testになります。 実際にElasticsearchに対して外部からAPIを叩くような感じです。 APIを叩くときに利用するJSONの設定やアサーションはsrc/test/resourcesにyamlファイルがあります。\n10_basic.yaml 20_kuromoji_part_of_speech_extract_processor.yaml 10_basic.yamlはプラグインがインストールされているかの確認のテストです。特に変更する必要はないです。\n20_kuromoji_part_of_speech_extract_processor.yamlは実際にコーディングしたProcessorが動くかどうかのテストです。\nテストの内容については、GitHubのコードをご覧ください。\nテストの実行とZipの生成 テストの実行とZipの生成は次のコマンドを実行すればOKです。\ngradle check テストに問題があった場合は、コケますし、問題なければSUCCESSと表示が出ます。 成功した場合はbuild/distributions/というディレクトリにzipファイルができています。 これをElasticsearchのpluginコマンドでインストールすれば動きます。\nbin/plugin install file:///path/to/elasticsearch-ingest-kuromoji-pos-extract/build/distribution/ingest-kuromoji_part_of_speech_extract-0.0.1-SNAPSHOT.zip kuromoji_pos_extractの利用方法 Ingest APIには便利なSimulate Pipeline APIがあります。\nということで、mecab-ipadic-NEologdにあったサンプルの文章を使って、使い方の説明です。\nPOST _ingest/pipeline/_simulate { \u0026#34;pipeline\u0026#34; : { \u0026#34;description\u0026#34; : \u0026#34;kuromoji neologd extract test\u0026#34;, \u0026#34;processors\u0026#34; : [ { \u0026#34;kuromoji_pos_extract\u0026#34; : { \u0026#34;field\u0026#34; : \u0026#34;body\u0026#34;, \u0026#34;target_field\u0026#34; : \u0026#34;noun_field\u0026#34;, \u0026#34;pos_tags\u0026#34; : [ \u0026#34;名詞-固有名詞-組織\u0026#34;, \u0026#34;名詞-固有名詞-一般\u0026#34;, \u0026#34;名詞-固有名詞-人名-一般\u0026#34;, \u0026#34;名詞-固有名詞-地域-一般\u0026#34;, \u0026#34;名詞-固有名詞-地域-国\u0026#34; ] } } ] }, \u0026#34;docs\u0026#34; : [ { \u0026#34;_index\u0026#34;: \u0026#34;index\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;type\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;id\u0026#34;, \u0026#34;_source\u0026#34;: { \u0026#34;body\u0026#34; : \u0026#34;10日放送の「中居正広のミになる図書館」(テレビ朝日系)で、SMAPの中居正広が、篠原信一の過去の勘違いを明かす一幕があった。\u0026#34; } } ] } 結果はこちら。\n{ \u0026#34;docs\u0026#34;: [ { \u0026#34;doc\u0026#34;: { \u0026#34;_index\u0026#34;: \u0026#34;index\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;id\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;type\u0026#34;, \u0026#34;_source\u0026#34;: { \u0026#34;noun_field\u0026#34;: [ \u0026#34;10日\u0026#34;, \u0026#34;中居正広のミになる図書館\u0026#34;, \u0026#34;テレビ朝日\u0026#34;, \u0026#34;SMAP\u0026#34;, \u0026#34;中居正広\u0026#34;, \u0026#34;篠原信一\u0026#34; ], \u0026#34;body\u0026#34;: \u0026#34;10日放送の「中居正広のミになる図書館」(テレビ朝日系)で、SMAPの中居正広が、篠原信一の過去の勘違いを明かす一幕があった。\u0026#34; }, \u0026#34;_ingest\u0026#34;: { \u0026#34;timestamp\u0026#34;: \u0026#34;2016-07-22T06:18:49.007+0000\u0026#34; } } } ] } noun_fieldに固有名詞の単語が抜き出せているのがわかるかと思います。\nAlexのテンプレートで困った点 テンプレートは便利だったのですが、processor_typeに_を使用したタイプ名を指定すると次のような問題(?)が発生しました。\nクラス名がKuromoji_part_of_speech_extractProcessorとなってしまう 深刻な問題ではないのですが、JavaだとCamel Caseが普通なのでちょっと気になって。 ということで、プルリク作って出してみました。まだ取り込まれてないかな。\n取り込み前に使いたい方は以下のコマンドを実行してください。 processor_class_nameという項目が増えています。 デフォルトだとprocessor_typeの_の部分を取り除きつつCamel Caseにしたものが入ります。\ncookiecutter gh:johtani/cookiecutter-elasticsearch-ingest-processor まとめ ということで、とりあえず作ってみましたというものになります。 特徴的な単語(固有名詞だけ)を抜き出して、別のフィールドにできるので、タグみたいなものをこれを使って前処理で作れるようになるかなぁと。\n参考ブログ(元ネタ?) インスパイア元となったブログです。\nUser Agentを解析するIngest Pluginを書いてみた Elasticsearch 5.0.0のIngest Node用プラグインを書いた話 ","date":1469161616,"dir":"post/2016/","id":"a62186ea292d6db03a087bd5dfcc3f1e","lang":"ja","lastmod":1469161616,"permalink":"https://blog.johtani.info/blog/2016/07/22/making-ingest-processor-plugin-with-cookiecutter/","publishdate":"2016-07-22T13:26:56+09:00","summary":"久しぶりに、技術的なブログ書いてます。 Ingest Processorのプラグインを作ってみたくなったので、書いてみました。 ただ書いてみるんじゃ3番煎じ","tags":["elasticsearch","plugin"],"title":"Lucene Kuromoji for NEologdで指定した品詞の単語を抜き出すIngest Pluginを書いてみた #elasticsearchjp"},{"contents":"なんか、今年はよく物が壊れる、厄年だからかなぁ?\nということで、記念に何が壊れたかをブログに残しておこうかと。\n腕時計(壊れてないかな) 電波腕時計を使ってたんだけど、電池がへたってたのでオーバーホールしてもらった。 Moto 360(壊れたというか。。。) 何度かバージョンアップしてるんだけど、数ヶ月前から、ちょっと触っただけで電源が落ちる現象が。ファームウェアのせいかAndroid Wearのバージョンアップのせいかわからないけど。。。挙げ句の果てに、電源を入れるために充電器にセットしないといけないと言う酷い仕様。。。 自転車前輪 自転車で車道を横切る側溝の蓋の間に前輪がはまってすっ転んでしまい、タイヤのスポークがちょっと曲がってしまう ジーンズその1 自転車で転んだ時に、膝とかこすって破れる ジーンズその2 福岡出張中に雨で滑って派手に転んで、膝に大きな穴が。。。 リュック あー、怪しいなと思ってたんだけど、やっぱりこわれた、、、 pic.twitter.com/CD2Y7t6AOD\n\u0026mdash; Jun Ohtani (@johtani) 2016年6月16日 怪しいとは思ってたんだけど。。。 ということで、リュックを新調しつつ修理に出してるところ。 5. Xperia Z3 * 先週金曜日にカメラのレンズが結露してるなぁと思ったら、電源が入らなくなった。補償サービスに入ってたんで、新しいZ3を次の日に送付してもらい復旧。いろいろなアプリがログインしないといけないのでかなり大変だった。。。\nまだ、半年残ってるので他にも壊れるのかなぁ。。。 お祓いしてもらったので、何もなければいいんだけど。\nということで、なんとなく欲しいものリストを貼っておきますね。\n","date":1467251858,"dir":"post/2016/","id":"167e2a6833d49ce198cb3b88f521991e","lang":"ja","lastmod":1467251858,"permalink":"https://blog.johtani.info/blog/2016/06/30/broken-something-in-this-year/","publishdate":"2016-06-30T10:57:38+09:00","summary":"なんか、今年はよく物が壊れる、厄年だからかなぁ? ということで、記念に何が壊れたかをブログに残しておこうかと。 腕時計(壊れてないかな) 電波腕時","tags":["misc"],"title":"よく物が壊れる年"},{"contents":"第16回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 今回は、司会だけに注力してみました()。\nチェックイン数など チェックインした人:141名 キャンセルしなかった人:67名 でした。\n今回は、参加希望者が多くて、当日にも100名近いキャンセル待ちの方がいたので、 240名まで、参加者枠を増枠(会場キャパ190名程度)して対応しました。 まぁ、読み通り、1/3の方はキャンセルしない形でした。 天気も良く電車の遅延などもなさそうだったので、ちょっとドキドキしてたのですが。\n以下は簡単なメモです。\n「LogstashとElasticsearchで作るEnterprise Search Platform」/ Elastic Kosho Owa スライド:https://speakerdeck.com/kosho/enabling-enterprise-search-platform-with-elastic-stack\n使ってるLogstashの設定ファイルを elastic-japan at elastic dot co に送るとTシャツがもらえるらしい。 Logstashのfilter-rubyはここで、evalしてcallしてるから、特にforkとかしてないかと。 「企業・業界情報プラットフォームSPEEDAにおけるElasticsearchの活用」 / 株式会社ユーザベース 北内 啓さん スライド:http://www.slideshare.net/tau3000/speedaelasticsearch-63510388\nアルゴリズム関連の開発担当 企業データをいろんな軸で検索したい データ数が約70億レコードになりそう(通貨 x MySQL) 300万企業データ+Nestedとかで持ってる。 11万フィールド??? 10台の物理サーバに24仮想マシン 企業名の検索 recall重視 NewsPicksの検索機能 「日本 化粧品 売上高」業界のデータとかも観れるのかな?有料会員向け機能 登録済みキーワードかどうかをRDB+Esに検索して、ID化するっぽい ID(Analyze必要ない)検索だから、termクエリだった、サンプルが。 ノードの役割分担 更新はMasterNode経由でDataNodeへ。 検索はClientNode経由でDataNodeへ。 1.xかぁ。。。 「Elasticsearchベースの全文検索システムFess」 / 株式会社エヌツーエスエム 菅谷信介さん スライド:http://www.slideshare.net/shinsuke/elasticsearchfess\n10.xからSolrをやめてElasticsearchへ。 日本語検索 bigram+形態素(1文字検索とかに対応するため) NeologDに対応したkuromojiを利用 DBFluteをESFluteとしてEs対応 KOPFを組み込んで使ってる configをREST API経由で更新できるプラグインあり LT 「ElasticsearchとGCPのネットワークでハマった話」 株式会社サイバーエージェント 平田大地 さん @daichild スライド:https://speakerdeck.com/daic_h/gcpfalsenetutowakudehamatutahua\nhhkb2 2刀流! networkのKeep-alive周りで困ったよというお話。 後で聞いたけど、GCE Cloud Pluginは使ってるそうです。 06/28 17:00追記\nPingを定期的に実行させることで回避も出来るようです。 transport.ping_scheduleに時間を指定します。通常のNode(Transport以外)は\u0026rsquo;-1\u0026rsquo;が指定してあり、動作してません。 「スクリプトフィールドで作るランキングみたいな何か」iwag さん スライド:https://speakerdeck.com/iwag/elasticsearch-dezuo-rurankingu\n1.xかぁ。。。 あとは、function_scoreとかも面白いですよ! その他、感想などのブログ 第16回elasticsearch勉強会に参加してきた 第16回Elasticsearch勉強会に参加してきた まとめ+宣伝? 1.xがまだまだいますねぇ、早く2.xにアップしましょう!(5.0ももう直ぐだし)。懇親会でも色々と話しましたが、https://discuss.elastic.co というフォーラムあるので、ぜひ活用してください。\n次回は8月末か9月頭かでしょうか。 7月末にOSC京都に出没するので、京都で勉強会やりたいと思ってます! 会場とかスピーカーとか興味ある人連絡ください。\n東京の勉強会のスピーカーも随時募集中ですので、連絡ください。\n","date":1467089755,"dir":"post/2016/","id":"993e58f132740b464ecf06ee289dc7b2","lang":"ja","lastmod":1467089755,"permalink":"https://blog.johtani.info/blog/2016/06/28/16th-elasticsearch-meetup/","publishdate":"2016-06-28T13:55:55+09:00","summary":"第16回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズ","tags":["elasticsearch","勉強会"],"title":"第16回Elasticsearch勉強会を開催しました。 #elasticsearchjp"},{"contents":"第15回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 今回は、Elastic{on} 2016開催直後ということで、大半はElastic{on}に関する話でした。\nチェックイン数など チェックインした人:114名 キャンセルしなかった人:62名 でした。 今回は、少しおそめで1時間前にキャンセル待ちがいない状態にしました。 まぁ、いつもの感じでしょうか。数値も安定してきた感じですかね。\n\u0026ldquo;Elasticsearchと機械学習を実際に連携させる\u0026rdquo; / Preferred Networks America, Inc. CTO 久保田展行(Kubota Nobuyuki) さん スライド:Elasticsearchと機械学習を実際に連携させる\n前回の続きの話で、今回が本題でした。\n勉強会直前に発表されたSensorBeeをElasticsearchと一緒に使うとどんなことができるかというお話です。 まぁ、前処理重要ですよねというのが、いつものことですが、印象的でした。 いつものようにわかりやすい説明だったので、使ってブログを書いて欲しいなと。\n発表の中で、説明に出てきたデモとか。\nCES2016でロボットカーのデモを展示してきました \u0026ldquo;Elastic{ON} 2016レポート\u0026rdquo; / Elastic Jun Ohtani スライド:elastic{on} 2016 レポート\n写真多めで、キーノートをメインに話をしました。\n簡単なまとめとしては\nプロダクトロゴができました。ロゴ画像などはこちら 次のメインバージョンは全て5.0。(5.0に関する通知が欲しい人はこちらで登録できます) elastic{on} 2016のビデオなどはこちら BBL始めます。連絡ください \u0026ldquo;Elastic{ON}の過ごし方\u0026rdquo; / クラスメソッド株式会社 藤本 真司 さん スライド:Elastic{ON}の過ごし方\n印象に残ったのは\n「自他共に認めるブログの会社」 4/12にSAPさんに会場を借りてElastic&クラスメソッドでイベントやります。 やっぱりご飯が美味しいんですねぇ。 早速ブログが書かれてました。\n\u0026ldquo;Elastic{ON} 2016 見るべきセッション資料 7選\u0026rdquo; / Acroquest Technology株式会社 谷本 心 さん スライド:Elastic{ON} 2016 見るべきセッション資料 7選 #elasticsearchjp\n印象に残ったのは\n東京でハンズオンやる会場提供者募集中! Ingest Node(参考:Ingest Nodeのドキュメントは公開中。) Reindex API(参考:Backport reindex to 2.x ) その他、感想などのブログ 第15回elasticsearch勉強会にLTで登壇しました #elasticsearch #elasticsearchjp 第15回elasticsearch勉強会に参加してきました #elasticsearch #elasticsearchjp まとめ+宣伝 来年のElastic{ON}に参加したいと思っていただけたらよかったなと。\n4/12にクラスメソッドさんとイベントを行います。また、ツイートすると思います。\n次回はいつも通りだと5月中旬になるかと思います(大丈夫かな?OSC 2016 Nagoyaでしゃべったり、ブース出したりとかするけど)。 5末に名古屋に出没します。名古屋で勉強会できればやりたいと思ってます。会場とかスピーカーとか興味がある方は連絡ください。\n","date":1458186180,"dir":"post/2016/","id":"c56a76ef8f604a8d87be2a32b1f81fac","lang":"ja","lastmod":1458186180,"permalink":"https://blog.johtani.info/blog/2016/03/17/15th-elasticsearch-jp/","publishdate":"2016-03-17T12:43:00+09:00","summary":"第15回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズ","tags":["elasticsearch","勉強会"],"title":"第15回Elasticsearch勉強会を開催しました。 #elasticsearchjp"},{"contents":"久々のポスト。。。\n久々に、技術書読んでます。「自然言語処理の基本と技術」という本です。\n監修の方のツイートを見て気になったので、買ってみました。 書籍のサイトの説明はこんな感じでした。\n本書は、この未来に不可欠となるに違いない自然言語処理の、技術的、ビジネス的基礎知識をくまなくコンパクトに図解した一冊です。 著者陣もそれぞれの分野の第一線で活躍するエキスパート揃い!\n確かに著者陣がすごいです。\nまだ、「はじめに」と自分に関係のある「情報検索」の章を流し読みしただけなんですが、次のような特徴がある本です。\n平易な単語で説明してある(難しい専門用語が少ない) 数式が出てこない(多分。少なくとも読んだ部分では見てない) 説明には例と図解がある 情報検索の章で言うと、全文検索でよく使われる転置インデックス(索引という単語が使われてる)がなぜ必要なのか、どういう感じで作られるのか、 転置インデックスに利用する索引の単語をどうやって作るのか(文字N-Gramや形態素解析)、単語の正規化(ステミングやストップワード)などの説明が 本当にわかりやすく書かれています。 スコアリングについても触れられています。\nElasticsearchも転置インデックスを用いた検索を行っており、 MappingでAnalyzerの指定をしている理由などの理解に役に立つと思います。\n全文検索システムがどのように検索を処理しているかをざっくり理解するのにはもってこいじゃないかと。 1点残念だなと思ったのは、書籍に「索引」がありませんでした(本の索引を思い浮かべてくださいっていう説明あったんだけど)。。。 Kindle版を購入すれば「検索」できるのかな?\nということで、まだ、流し読みしただけなんですが、「すごく」オススメです。 購入はこちらから!\n","date":1457962452,"dir":"post/2016/","id":"3fc7462a83fa55885067fee629287e8a","lang":"ja","lastmod":1457962452,"permalink":"https://blog.johtani.info/blog/2016/03/14/review-basics-and-tech-of-nlp/","publishdate":"2016-03-14T22:34:12+09:00","summary":"久々のポスト。。。 久々に、技術書読んでます。「自然言語処理の基本と技術」という本です。 監修の方のツイートを見て気になったので、買ってみました","tags":["本"],"title":"「自然言語処理の基本と技術」を読んでる"},{"contents":"あけましておめでとうございます、johtaniです。\n第14回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 今年もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\nチェックイン数など チェックインした人:122名 キャンセルしなかった人:58名 でした。 今回も当日の昼の時点でキャンセル待ちがない状態にしていました。 いくつか電車が止まっていたという話を聞いていたので、開始を5分遅らせ、 受付は45分くらいまで開けておくという対応をしてもらいました。\n\u0026ldquo;ココが辛いよelasticsearch\u0026rdquo; / 株式会社リクルートテクノロジー @tatakaba さん スライド:ココが辛いよelasticsearch\n実際にいくつかのサービスで運用されている内容とどういった機能を利用しているか、 どういったものを独自に作っているかという話をしていただきました。\n独自PluginでA/Bテストしてる Snapshotの活用 Index作成は環境に合わせて行っている。 バージョンは混在 PusnaRSのバージョンアップの話。 2つのバージョンのクラスタを用意してリアルタイムに切り替え。 Elasticsearchの活用 QueryのRewrite: SolrのリクエストをEsで受け付けたり。 辛い話。 バージョンアップが辛い Riverなくなるのつらい データずれるのつらい 補足:\nバージョンアップについて 1.x系から2.x系にアップされるのであれば、こちらを必ず試してください。\nhttps://github.com/elastic/elasticsearch-migration\n「.」が使えなくなるという話は、Solrとの大きな違いになるのかもなぁと。 ネスト構造のデータの表記を「.」で行うというのを厳密に行えるように、 「.」を使えなくしたというのがあるかと。\nRiverについて Riverがなくなった理由については、https://www.elastic.co/blog/deprecating-rivers で記載があります。 便利なのですが、負荷が偏ったり、スケールしないとかいう問題点があるかなと。\n良いサンプルとしては、JDBC Riverなどは、Javaのプログラムとして起動できるように変更されていたりします。\nhttps://github.com/jprante/elasticsearch-jdbc/wiki/jdbc-plugin-feeder-mode-as-an-alternative-to-the-deprecated-elasticsearch-river-api\n(個人的 には、SolrのDIHもRiverもあんまり好きではなかったです。データの変換処理と、ロード処理は別々にしたい人だったので。)\nデータのズレなど 耐障害性とか信頼性に関しては、どういった問題点があるのか、どういった対応をしているのかというのがまとめられたページが用意されています。\nhttps://www.elastic.co/guide/en/elasticsearch/resiliency/current/index.html\n「機械学習を利用したちょっとリッチな検索」 / Preferred Networks America, Inc. CTO 久保田展行(Kubota Nobuyuki) さん スライド:機械学習を利用したちょっとリッチな検索\n来日していただき、機械学習と検索の話をしてもらいました。 本編は次回の発表かもw\n機械学習を元に、検索対象の情報を元の情報から増やしてあげる。 増えた情報を検索できるようにする 今日のゴール: 機械学習とはどういうものか? データの集め方とか、アノテーションとか 学習の方法(ツールやライブラリに依存) Esでの活用方法 オフラインで学習させて、情報を付与した後に、Elasticsearchに入れる Jubatus+fluentdで ChainerサポートのOSSのツールを公開予定 「ここからが本当の地獄だ。。。」ってのが聴きたいw\n「Lucene Query 再考 - Domain Specific Query 実装 -」 / Supership株式会社 インフラ事業開発本部検索グループ 大川真吾 さん スライド:Lucene Query 再考 - Domain Specific Query 実装 -\nLuceneのクエリに関する話と、クエリパーサーに関する話でした。 こういった濃い話も勉強会でしてもらえると、色々な参加者に楽しんでいただけるかなぁと。 次回も続きを話してもらう予定です。\n補足:\n参考までにですが、Elasticsearchに入門したての人向けに、 Analyzerとか転置インデックスとかの話をした時のスライドになります。 https://speakerdeck.com/johtani/lucenetori-ben-yu-falsejian-suo\nLT: Fluentd meets Beats / @repeatedly さん スライド:http://www.slideshare.net/repeatedly/fluentpluginbeats-at-elasticsearch-meetup-14\n参考Qiita:http://qiita.com/repeatedly/items/77af41788f0b3ccdefd2\nBeatsの説明をTDの人からしてもらうなどw FluentdにBeatsからのデータを流し込めるようにしたプラグインが出たという話でした。\nfilebeatの性能の件は社内で聞いてみようかと。\nElasticsearchインデクシングのパフォーマンスを測ってみた / 日本IBM 黒澤亮二さん スライド:Elasticsearchインデクシングのパフォーマンスを測ってみた\n参考Qiita:http://qiita.com/rjkuro/items/e79eec7ffb0511b7c678\n細かな性能測定の結果を駆け足で話してもらいました。 皆さんもこの指標をもとに、手元の環境を計測してみたりしてみてもらえればと。\nあとは、2.x系になってるので、同じ方法で計測してもらってまた 発表してもらえると嬉しいなー(棒)\nその他、感想などのブログ Elasticsearch勉強会 第14回フィードバック まとめ+宣伝 久々に(初めてかな?)、ゲストがいないのに自分が喋りませんでした。 次回は3月中旬を予定してます。 次回は、Elastic{ON}16の報告をする予定です。いろいろと発表あるだろうし。\nあと、今月末の1/29にオープンソースカンファレンス 2016.enterprise@Osakaにブース出展します。 セミナー枠でも弊社OSSプロダクトの概要を話しする予定です。 関西の方は、ぜひ参加していただければと。ブースでお待ちしております。\nまた、スピーカーや場所が用意できたら、出張勉強会もまたやりたいなと思っています。 興味ある方は、連絡ください!\n","date":1452220496,"dir":"post/2016/","id":"4b0a768585da8f9f8f8db1ca409e7ebd","lang":"ja","lastmod":1452220496,"permalink":"https://blog.johtani.info/blog/2016/01/08/14th-elasticcsearch-jp/","publishdate":"2016-01-08T11:34:56+09:00","summary":"あけましておめでとうございます、johtaniです。 第14回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆","tags":["elasticsearch","勉強会"],"title":"第14回Elasticsearch勉強会を開催しました。 #elasticsearchjp"},{"contents":"今年は紅白見ながら書いてます。 早い一年だったなぁ。\n振り返り(2014年に書いた抱負から) まずは去年の抱負を元に振り返りをば。\n英語の継続 海外のイベントへの参加 多岐にわたるイベントでのスピーカー 日本の人員の倍増!? Elasticsearchに関する日本語の情報発信 Elasticsearch座談会みたいなものの開催 英語はまぁ、継続してます。亀の歩みですが。。。\n海外のイベントへの参加は、自社のイベントだけでした。来年のElastic{ON}ももちろん参加です。来年こそBerlin Buzzwords行きたいな。。。\n多岐にわたるイベントとまではいってないですかね。。。来年はOSC(大阪や東京)に出没予定です。参加される方は、声をかけていただければと。\n人員は倍増しました!営業の方が参画されたのがかなり助かってます。 今現在で4名です!来年も倍増できるかなぁ?\n日本語の情報発信はリリースブログの翻訳が多めでした。来年は独自コンテンツも増やさないとなぁ。 あとやっぱ書籍かなぁ。。。座談会は来年の課題に。。。\n振り返り(今年あったできごと) その他の今年の出来事。\n初渡米 初バルセロナ 東京以外で勉強会 初自社イベント(日本で) 初トレーナー 不惑 今年も初モノ多いですね。今年も楽しい一年でした。 自社イベントでアメリカやバルセロナなどに行きました。40年近く、海外に行ったことないせいか、海外に行って経験することが面白いです。\n東京以外での勉強会もやりました。名古屋、大阪、京都、北海道と。 来年もOSCで訪れた場所で勉強会を開催したいなぁと。\n自社のイベント(Elastic{ON} Tour Tokyo)も東京でやりました。 どうなることかと思っていましたが、朝から大勢の方に来ていただけてホッとしました。 自分のトークがどうだったのかという反応も気になりますが。。。 せっかくShayたちが来ていたので、もっとブースに話しに来てもらえるともっと嬉しかったかもなぁと。\nTour Tokyoを挟んで自社の公式トレーニングのトレーナーもやりました。 日本で3回目にして、初の日本語でのトレーニングでした。前の2回は逐次通訳だったんですが。 トレーニングって大変だなぁと思ったのと、やはり日本語でトレーニングを受けられるとだいぶ違うだろうなという実感がありました。 来年もできればいいなと。トレーニング自体があったことを知らない人もいたのかなぁ?\n来年の抱負 英語の継続 もっとElasticsearchの開発に参加 人員の倍増? 日本語情報発信 Splatoon S+? 英語あいかわらず出来てないので、頑張らないと。 もっと喋ったりしないとなんだろうなぁ。\n来年は開発をもっとやりたいなと。 来年1月にはセールスのエンジニアが加入するので、開発にもっと時間を割きたいなと。\n人員は倍増できるように頑張りたいです。少なくとも、2人が1月に入ることは決まってるんで、後二人!\nブログももっと書かないとですね。新機能とかこんな使い方できるよとか。 どんな記事が欲しいかとかコメントもらえると楽なので、突っ込みくださいw\n最後は、完全に私用ですね。Splatoonにはまってますw SとA+を行ったり来たりで。。。\nということで、今年はあと、数時間ですが、色々とお世話になりました。 この場を借りてお礼申し上げます。\n来年も、いろんな方に絡んでいくとは思いますが、よろしくお願いいたします。\n","date":1451565182,"dir":"post/2015/","id":"c54909ecf4fb3e9afeea36200fe95dce","lang":"ja","lastmod":1451565182,"permalink":"https://blog.johtani.info/blog/2015/12/31/looking-back-2015/","publishdate":"2015-12-31T21:33:02+09:00","summary":"今年は紅白見ながら書いてます。 早い一年だったなぁ。 振り返り(2014年に書いた抱負から) まずは去年の抱負を元に振り返りをば。 英語の継続 海外の","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2015)"},{"contents":"今年最後のAdvent Calendarとなります。\nこの記事はElasticsearch Advent Calendar 2015の最終日のエントリです。\n簡単に今年の変遷を、Elasticsearchをベースに振り返ってみようかと思います。\nKibana 4リリース(2月) Kibana 4(日本語訳) いきなり、Elasticsearchではない話題ですが。 AggregationベースのKibanaがリリースされました。 画面が黒くないというので、話題になりましたw 12月末時点では、4.3.1になっています。 Sub Aggregationによる強力なグラフ表示や異なるインデックスに対するグラフを 一つのダッシュボードに表示できるといったことができるようになりました。\nセキュリティ向けプラグインShieldのリリース(2月) セキュリティ向けプラグインShieldのリリース(日本語訳) 商用向けのプラグインの第2弾です。 セキュリティ強化のためのプラグインで、いろいろなところで引き合いがあったりします。\n初のユーザカンファレンス、Elastic{ON}開催(3月) #elasticon に参加中 サンフランシスコで、弊社初のカンファレンスが開催されました。(来年(2016年)もサンフランシスコで開催されます。) また、ここで、以下の2点の発表がありました。\nロゴ及びドメイン名などの変更 Foundのジョイン 約1300名が参加する大イベントでした。 初の渡米で楽しんできましたが、ドメインの切り替えなどは大変でした。。。 まだ、ロゴを変えて1年経ってないということが実感できてないです。\nFoundのジョインはまだまだ、日本で知名度が出てないかもなぁと。 もっと広めないと。 利点としては以下の通りです。\n新バージョンがすぐに利用可能に。また、バージョンアップも画面で指定可能 公式プラグイン+その他いくつかのプラグインが利用可能 Elasticsearch 1.5 リリース(4月) Elasticsearch 1.5.0リリース(日本語訳) 主に、resiliencyに関する改良になります。 毎リリースで信頼性向上につながる改良が含まれる形になっています。 このリリースの近くで初の東京の外での勉強会を名古屋で開催したりもしました。\ndiscuss.elastic.coをオープン(5月) https://discuss.elastic.co これまでは、Google Groupsを使っていましたが、Elasticが提供しているプロダクトが 別々のグループであったために、プロダクトにまたがった質問がやりにくかったり、検索がしにくかったりという問題点がありました。 今では、過去のGoogle Groupsのデータも移行されているので、是非参加して、質問・回答してみてください。 日本語でやりとりできるカテゴリもあるので、どんどん、やりとりしていただければ。\nElasticsearch 1.6 リリース(6月) Elasticsearch 1.6.0リリース(日本語訳) 2.0に向けたUpgrade APIが含まれるなど、次期リリースに向けた準備が整いつつあるリリースでした。 他にもsynced flushの取り込みやレスポンスのJSONのフィルタリングなど細かな改善も取り込まれています。\nFound PremiumとStandardリリース(7月) さらに進化したFound(日本語訳) Foundに弊社のサポートチームがサポートできるプレミアムが追加されました。 これにより、商用プラグインとして提供しているShieldが(現在はWatcherも)利用できるなど、 より便利になりました。また、Kibana 4も無料で提供されていたりします。\n小さなサイズのものですと、無料で試していただけるものもあるので、試してみてもらえればと。\nElasticsearch 1.7 リリース(7月) Elasticsearch 1.7.0 および 1.6.1リリース(日本語訳) 1.x系、最後のリリースでした。 小さい改善ですが、セキュリティフィックス、クラスタの安定化に寄与する機能改善が含まれています。\nこのリリース直前に大阪、京都で勉強会も開催してみました。\nElasticsearch 2.0.0-beta1 リリース(8月) Elasticsearch 2.0.0-beta1リリース(日本語訳) 待ちに待った、Lucene 5ベースのElasticsearchの登場でした。 doc_valuesがデフォルトになったり、エラーが構造化されて見やすくなったり、 Pipeline Aggregationが導入されたりしています。 また、問題点の洗い出しも兼ねて、ベータリリースとして、本リリースまでに多くのIssueをあげていただきました。\nElasticsearch 2.0.0 リリース(10月) 2.0の本リリースです。リリースまでに、beta1、2及び、rc1がリリースされました。\n追加された機能や目玉の改善については「Elasticsearch 2.0の紹介」のスライドを参考にしていただければと。\nまた、Elasticsearch 2.0のリリースに合わせて、商用プラグインやLogstash、Kibanaの新しいバージョンがリリースされました。 Kibanaなどは、プラットフォームとしての機能を備え、SenseやTimelionと言ったプラグインアプリもリリースされています。\nLogstash 2.0.0リリース(日本語訳) Kibana 4.2.0リリース(日本語訳) Senseの歴史 - Sense 2.0.0-beta1の紹介(日本語訳) Shield、Watcher、Marvel 2.0.0 GAリリース(日本語訳) Elasticsearch 2.1.0 リリース(11月) Elasticsearch 2.1.0 and 2.0.1 released Beats 1.0.0のリリース(11月) The Beats 1.0.0 Go言語で書かれた軽量データシッパーになります。 パケットをキャプチャしてElasticsearchに送るPacketbeat、 topコマンドで取れるデータなどをTopbeat、 ログファイルなどを取り込み配送するFilebeatがリリースされました。\nlibbeatと呼ばれる、 ベースとなるライブラリを元にしたプロダクトで、Logstashのエージェントのような使い方もできるようになっています。\nGo言語に興味のある方などは、調べてみてはいかがでしょう?\n来年は? 日本では、1/7に第14回Elasticsearch勉強会を開催します。 すでに、38名のキャンセル待ちとなっていますが、おそらく、年明けにキャンセルがそこそこ出ると思うので、まだ間に合うんじゃないかなぁと。\n会社としては、Elastic{ON}16が控えています。参加される方は、ぜひ現地で声をかけてください!!\nその他にもイベント、オープンソースカンファレンス(まずは、大阪、東京)などに出没する予定ですので、こちらも参加していただければと。\nでは、また来年のAdvent Calendarでお会いしましょう!\n","date":1451017794,"dir":"post/2015/","id":"d819cea5197e9b8673d6c0b16659a5ea","lang":"ja","lastmod":1451017794,"permalink":"https://blog.johtani.info/blog/2015/12/25/about-elasticsearch-in-2015/","publishdate":"2015-12-25T13:29:54+09:00","summary":"今年最後のAdvent Calendarとなります。 この記事はElasticsearch Advent Calendar 2015の最終日のエントリです。 簡単に今年の変遷を","tags":["elasticsearch"],"title":"2015年のElasticsearch"},{"contents":"こんにちは、@johtaniです。\n早いもので、師走です。今年もあと少しとなりました(今月が一番忙しかったりしますが。。。)。 ということで、Advent Calendarの季節が始まりました。\nこの記事はElasticsearch Advent Calendar 2015の1日目のエントリです。\n今日は、最近公開されたTimelionの紹介をしたいと思います。\nTimelion? 11/12に公開されたばかりのアプリになります。(公式のブログはこちら。ブログでは動画による説明もあり)\nKibanaにプラグインとしてインストールすることで使用することができるようになるアプリです。 Timelionと書いて「Timeline」と読むようです。 Kibanaとは異なるグラフ描画のプラグインになっています。\nKibana 4.2からプラットフォーム化 Kibana 4.2から、Kibanaにプラグイン機構が導入されました。 Kibanaとしての機能以外にも、プラグインとして、アプリを追加できるようになっています。 Timelionもその一つです。\nインストール Timelionを試してみるには、ElasticsearchとKibanaが必要になります。(こちらは、すでにインストールされているとして。。。)\nKibanaのコマンドを利用して、プラグインをインストールします。\nbin/kibana plugin -i kibana/timelion インストールしたら、Kibanaにアクセスして、Timelionを呼び出します。\nTimelionへアクセス ブラウザでlocalhost:5601にアクセスすると、Kibanaが出てきます。 Kibanaのプラグイン選択のアイコンをクリックし、Timelionのアイコンをクリックします。\nすると、初期画面はこんな感じです。 直近15分のElasticsearchに入っているデータがが全部出てきます。 チュートリアルも出てきてます(初回起動時に出たはず)\nKibanaでの検索窓の部分に関数を指定していくことで、グラフが描画できるツールになっています。\nサンプル:気温データを可視化 百聞は一見に如かずということで、 気象庁のデータを使って、 ちょっとしたグラフを書いてみました。 1年間の気温の推移と日照時間になります。\n上のグラフが那覇、下グラフが札幌の気温のグラフになります。\n赤いライン:最高気温 青いライン:最低気温 黄色い棒グラフ:日照時間 最低気温と日照時間はグラフは次のような式で描画しています。\n青いラインの最低気温 気温のグラフになります。\n.es(index=\u0026#39;tenki2\u0026#39;, q=\u0026#39;city:naha\u0026#39;, metric=\u0026#39;avg:temperature_min\u0026#39;).label(\u0026#39;min\u0026#39;), .es()がelasticsearchに対するデータ取得の関数です。 引数は次のような意味になります。\nindex:対象とするインデックス名 q:検索クエリ。ここでは、cityというフィールドにnahaで検索。 metric:描画対象となっているデータの入ったフィールド。temperature_minというフィールドの1日毎の平均値を取得 最低気温と最高気温は別々のフィールドに格納してあります。最高気温の場合は(temperature_max)を指定します。\n.label(min)で、グラフの凡例の指定です。 残念ながら、日本語の指定は現時点(2015年12月01日時点)ではうまくいかなかったです。(https://github.com/elastic/timelion/issues/17)\nデフォルトでは、線グラフが選択されているので、グラフの種類は特に指定はしていません。 明確に指定する場合はlines()を指定します。\n黄色い棒グラフの日照時間 .es(index=\u0026#39;tenki2\u0026#39;, q=\u0026#39;city:naha\u0026#39;, metric=\u0026#39;avg:sunlight\u0026#39;).label(sunlight).bars() .es()に関しては最低気温のグラフとほぼ一緒です。異なるのは、metricの取得対象のフィールド名です。\n.label()で凡例を指定しています。先程と同様です。\n最後に、棒グラフにしたいため、.bars()を指定しています。\nその他に用意されている関数について知りたい場合は、Timelionのヘルプを表示すると説明が出てきます。 cusum()のような値を累積して表示するような関数も用意されています。\nまとめ Kibanaとは少し違うアプローチで時系列データを描画するためのツールとなっています。 線グラフと棒グラフを一つのグラフに描画したりもできますし、 累積のグラフなんかも描画できるようになっています。\n実験的なプロジェクトである、Timelionの紹介でした。 ここでのノウハウがkibanaにフィードバックされると色々と面白いことになるんじゃないかなと。\nということで、 明日は、zoetroさんの「Kibanaのプラグインの話」になります。 お楽しみに!\n","date":1448936891,"dir":"post/2015/","id":"1b56132638912a1ca54fcf7cd38b8e23","lang":"ja","lastmod":1448936891,"permalink":"https://blog.johtani.info/blog/2015/12/01/introduction-timelion/","publishdate":"2015-12-01T11:28:11+09:00","summary":"こんにちは、@johtaniです。 早いもので、師走です。今年もあと少しとなりました(今月が一番忙しかったりしますが。。。)。 ということで、A","tags":["kibana","timelion"],"title":"Timelionの紹介 - Elasticsearch Advent Calendar 2015 1日目"},{"contents":"第13回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 来年もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\n7月同様、サムライズムの@yusukeさんに テキスト翻訳していただき、大変助かりました。\nチェックイン数など チェックインした人:100名 キャンセルしなかった人:36名 でした。 今回は当日の時点でキャンセル待ちがない状態にしていました。 雨もあって、これなかった人もいるのでしょうか。\n\u0026ldquo;Beyond the basics with Elasticsearch\u0026rdquo; / Honza Král / Elastic スライド:https://speakerdeck.com/elasticsearch/beyond-the-basics-with-elasticsearch\n参考ビデオ(別のカンファレンスで話した時のビデオ):https://www.youtube.com/watch?v=yIixWzjTNog\nPycon HKでアジアに来ていたHonzaに、ついでに日本で話をしてもらうという企画で、 前回から1カ月足らずでの開催となりました。 Elasticsearchの基本的な検索機能とは別の機能に関して少し話をしてもらった感じです。 PercolatorとAggregationの話でした。\n詳しくはビデオやスライドを見てもらうのがいいかなと。\n\u0026ldquo;How did we use Found.no for our services?\u0026rdquo; / 株式会社アイリッジ Takuya Noguchi さん @tn961ir スライド:未定\nFoundユーザー。1.7までの話。 社内で独自にクラスタを構築していたが、managed serviceを利用したいと思っていた。 Found用のACLがShieldに マルチバイトのインデックス名とかも使いたいが、Nginxとの連携でちょっと。。。 セキュリティ関連の話も。Securityに関する報告はこういうものも用意されてるので、こちらに相談してもらうのがいいかも。https://www.elastic.co/community/security 要望がいくつか。 \u0026ldquo;ログ収集の仕組みを再考しよう! あとマウンテンビューに行ってきました。\u0026rdquo; / Acroquest Technology株式会社 谷本 心さん @cero_t スライド:http://www.slideshare.net/shintanimoto/lets-reconsider-about-collecting-logs-plus-visiting-elasticmoutain-view\nログの小話から始まり、ログに関する考え方とかを披露してもらいました。 さらに踏み込んだログの活用の方法の話になるかと思いきや、 思いっきり話が飛んで、マウンテンビューのElasticオフィスに遊びに行った写真が出てきましたw\n写真の後は、弊社のTanya(来月のElastic{ON} Tour Tokyoで来日予定)から 聞いた弊社製品に関する話をしていただきました。 きっと、Beatsに関して次は話してくれるんだろうなぁ(棒)。 流れ的には、来年の2月にサンフランシスコで開催されるElastic{ON}16につながりそうだったので、ここで宣伝しときますね。 今年3月に開催されたイベントには残念ながら日本の方はいなかったので、次回は日本の方がいると嬉しいなぁと。\nLT \u0026ldquo;「Elasticsearch を使った単語共起頻度の計算」\u0026rdquo; / 株式会社はてな id:takuya-a さん スライド:未定\n一風変わったElasticsearchの使い方的な話でした。 検索用にデータを登録してあるElasticsearchから単語の頻度情報を抜き出して、 別のインデックスに登録するという感じでしょうか。 こういうのが、実は、Elasticsearchに機能としてあると便利だったりするのかもなぁと思ってみたり。\nLTよりはちょっと長かったですかねw\nその他、感想などのブログ elasticsearch勉強会 まとめ+宣伝 今回も@yusukeさんのテキスト翻訳に助けていただきました。ほんとありがとうございます。 今年の勉強会はこれがラストになります。 来月は、トレーニングとElastic{ON} Tour Tokyoがあるので忙しくなりそうですが、 参加予定の方は楽しみにしていてください!\nOperations : http://training.elastic.co/class/Operations/Japan/Dec Developer : http://training.elastic.co/class/Developer/Japan/Dec ","date":1447143778,"dir":"post/2015/","id":"2ea86ae5093670df1d4502ea82efa1ac","lang":"ja","lastmod":1447143778,"permalink":"https://blog.johtani.info/blog/2015/11/10/13th-elasticsearch-jp/","publishdate":"2015-11-10T17:22:58+09:00","summary":"第13回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズ","tags":["elasticsearch","勉強会"],"title":"第13回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:The Story of Sense - Announcing Sense 2.0.0-beta1\n誕生 よくある良いプロジェクト同様、Senseもビールを飲みながら考えつきました。 Amstelでの手漕ぎボートのセッションの後で。 友人のJasperと私はJasperの会社で毎年行われる ハッカソンについて話をしていました。 このハッカソンはどのようなアイデアでどんなチームで行うかを聞き取りされる、厳密なハッカソンです。 その時、私とJasperはChromeブラウザに別のヒストリーを表示するという作業をやるとAnne Velingに話をしていました。\nJasperと私はElasticsearchのユーザでしたが、リッチなREST APIにリクエストを送信するための 便利なツールがないと知っていました。 恥ずべきことに、cURLコマンドを利用するターミナルがその時の一番良いツールでした。 皆さん、ターミナルでボディつきのリクエストをサブミットするのがどのくらい不便かというのをわかるために、 5秒ほどターミナルで実行してみてください。 タイプミスのような単純なことでさえ、すべてのコマンドを再タイプしなければならなかったり、 複数行サポートのターミナルと戦ったりです。 ウェブベースのJSONエディタを見つけ出して、それをベースにすることが必要でした。\n終わりなきウィークエンド リサーチをして、Anneに電話しました。 私は彼に、History Pageのプロジェクトにもコミットするが、 Elasticsearchユーザなので、便利なコンソールを開発する時間も欲しいという話をしました。 私たちは、Aceオンラインエディタを利用して、 自動でAPIを認識するナレッジベースを構築し、 コンテキストに沿ったサジェストを大なうようにしました。 Anneはすぐに、それが素晴らしいと同意してくれました。 しかし、彼は、ハッカソンの基本的なルール(週末にそれが終わる必要がある)に違反しているので、 そのアイデアを却下するしかありませんでした。 確かに、私たちが提案していたものは行えませんでした。 最後に、私たちは、ChromeのHistory Pageの素晴らしい置き換えについて実装しました。\nそれでも、私はチャレンジし、それが終わるであろうことを終わるであろうことを証明しなければなりませんでした。 次の週末(といくつかの終業後 :))に、私はそれを作りました。 Senseの誕生です。 それは、まだバグだらけでしたが、動きました。 これを見せるとみんな興奮しました。\n初期 Knowledge Baseの拡張とバグのフィックスで数日を過ごしました。 Senseは広まり始め、ずっと古いバグのあるバージョンを利用しないといけないのかと私は恐れました。 SenseをChromeのExtentionとしてリリースすることを決め、リリースすると自動的に更新されるようにしました。 History Panelのような機能を一つづつ追加するようにしました。\nElasticにジョインしてから、会社の人たちがSenseを使用しているということを聞き、とても幸せでした。 特に、Clintと話をしたときのことを覚えています。 彼は、\u0026ldquo;You know what Sense should do? It should use this format and allow you to have multiple requests in the editor\u0026rdquo; 「Senseになにをすべきかわかる?フォーマットを使うべきだし、エディタで複数のリクエストを持つようにするべきだ」 と言いました。 もちろん、その他のチャレンジも行いました。これは、簡単なものではなく、Aceの詳細を知る必要がありました。 それは新しいAceモード(Aceによって利用されているハイライティングロジック)です。 これは、Senseのサジェストエンジンに密に統合されました。\n次のものが古いSenseのスクリーンショットです。\n画像あり。Figure 1. Sense 0.7 ※画像に関しては原文をご覧ください。\nAPIのURLを入力すると、JSONのボディが入力されます。 うまく切り離すことができ、AceのスタンダードJSONモードを使っていました。 しかし、ここで、次のようなフォーマットをどうやってサポートするか考える必要がありました。\nGET _cluster/health POST index/_settings { \u0026#34;index\u0026#34;: { \u0026#34;number_of_replicas\u0026#34;: 3 } } これは、Aceが3つの異なるものをどうやってパースするかを知る必要があるということです。 HTTPメソッドとURLとJSONボディです。 また、困ったことに、前に説明した前に説明した通り、明らかに別々にはならないものでした。 JSONボディが完全であることを知る唯一の方法はかっこを数えることです。 それは、いくつかの作業とAceのカスタマイズが必要でしたが、それらを切り離すことができました。 そして、Senseのシンタックスが生まれたのです(Thanks Clint!)\nMarvel時代 就業時間中、私の優先すべき仕事はMarvelの開発になりました。 これは、Elasticsearchのための管理と監視のためのソリューションです。 (side note: Marvelは生まれ変わっています。(\u0026quot;Shield, Watcher, and Marvel 2.0.0 GA Released\u0026quot;)) Marvelは開発環境ではフリーなので、MarvelにSenseを組み込むことにしました。 これにより、Senseの開発が日中も行えるようになり、多くのユーザに利用され始めました。 また、Senseは実際に真のJavaScript開発者によって開発されました。 彼は、コードをクリーンにし、ブラウザにおける最新の技術を私に教えてくれました。\nこの期間のSenseは数回書き換えられています。 最も顕著なものは、個別のURLとJSONのサジェストエンジンを書き換えて、 1つのサジェストエンジンにしこれらのコンテキストで動作するようにし、さらに3つ目のコンテキスト(URLパラメータ)を追加したことです。\n新しいエンジンはまた、複数のサジェストコンテキストをメンテナンスするのが簡単になりました。 例えば、_search APIのソートパラメータを考えます。\nGET _search { \u0026#34;sort\u0026#34;: [ \u0026#34;timestamp\u0026#34;: \u0026#34;desc\u0026#34;, \u0026#34;price\u0026#34;: { \u0026#34;order\u0026#34;: \u0026#34;desc\u0026#34;. \u0026#34;missing\u0026#34;: \u0026#34;last\u0026#34; }, \u0026#34;nested_filter\u0026#34;: { \u0026#34;term\u0026#34;: { ... }}, \u0026#34;_score\u0026#34; ] } ユーザがどこにいるかによって、Senseは単純な値(_scoreのような)か、 複雑な構造(orderとmissingのような)やフィルタ(nested_filterのような)も サジェストする必要があります。 これらのサジェストのパスが一度に処理され、無関係なものは除外されます。\nSense 2.0の紹介! Marvel 1.xはKibana 3.0をベースにしていました。 これは、データの探索やダッシュボードツールとして素晴らしいものでした。 しかし、Kibanaチームはさらに素晴らしいものを出しました。 Kibana 4.xはElasticsearchをバックエンドとするUIアプリを簡単に構築することができる プラットフォームとして設計されています。 実際に、Marvel 2.0はKibanaの プラットフォームで利用できる最初のアプリです。\nSenseの話に戻します。 ElasticsearchのAPIとやりとりする一般的なコンソールです。 これをKibanaのアプリぴったりだと気付きました。 ということで、Sense 2.0をKibanaアプリとしてオープンソースで公開しました。 開発及び本番環境で利用してください。\nFigure 2. Screenshot Sense 2.0 ※画像に関しては原文をご覧ください。\nリリースのハイライト Sense 2.0の新しい機能をここで簡単に紹介します。 (すべての変更点についてはこちらをご覧ください。)\nElasticsearch 2.0 SenseのナレッジベースをElasticsearch 2.0サポートに更新しました。 新しいPipeline aggregationにも対応しています。\n複数リクエストの実行 テストやいくつかの一連のコマンドを繰り返し実行したい時があるでしょう。 その時に、それら全てをSenseに記述し、 実行したいリクエストを選択状態にしてElasticsearchにリクエストできます。\nFigure 3. Submit multiple requests ※画像に関しては原文をご覧ください。\nSenseは、Elasticsearchにリクエストを一つずつ送信し、それぞれの出力結果を右のパネルに表示します。 これは、問題のデバッグや複数のシナリオでのクエリの組み合わせの実行に非常に便利です。\n複数リクエストのコピーペースト 複数リクストを選択し、フォーマットしたり、cURLのコマンドとしてコピーすることも可能です。\nFigure 4. Copy multiple requests as cURL ※画像に関しては原文をご覧ください。\n# Delete all data in the `website` index curl -XDELETE \u0026#34;http://localhost:9200/website\u0026#34; # Create a document with ID 123 curl -XPUT \u0026#34;http://localhost:9200/website/blog/123\u0026#34; -d\u0026#39; { \u0026#34;title\u0026#34;: \u0026#34;My first blog entry\u0026#34;, \u0026#34;text\u0026#34;: \u0026#34;Just trying this out...\u0026#34;, \u0026#34;date\u0026#34;: \u0026#34;2014/01/01\u0026#34; }\u0026#39; もちろん、複数のcURLコマンドをコピーしてSenseにペースとすると、Senseはそれらをパースしてくれます。\nまとめ Sense 2.0.0のベータリリースです。 実際に多くの作業が終わった認識です。すぐにGAが出るでしょう。\nSense 2.0を知り、試していただくために、新しいドキュメントを参考にしてください。 バグやリクエストがある場合は、フォーラムやGitHubのIssueに登録をお願いします。\n","date":1446195306,"dir":"post/2015/","id":"5912529cfd6ce14c5ede5c6c83dae7e8","lang":"ja","lastmod":1446195306,"permalink":"https://blog.johtani.info/blog/2015/10/30/sense-2-0-0-beta1-ja/","publishdate":"2015-10-30T17:55:06+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:The Story of Sense - Announcing Sense 2.0.0-beta1 誕生 よくある良いプロジェクト同様、Senseもビールを飲みながら考","tags":["elasticsearch","sense"],"title":"Senseの歴史 - Sense 2.0.0-beta1の紹介(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Shield, Watcher, and Marvel 2.0.0 GA Released\n本日(10/28)Shield、WatcherおよびMarvel 2.0をリリースしました。 これが、Elasticsearch 2.0に対応したこれらのプラグインの最初のリリースです。\nElasticsearch 2.0対応のほかに、ShieldとWatcher 2.0は、 セキュリティとアラートを拡張するいくつかの新しい素敵な機能も備えています。\nShield 拡張可能なレルム - Sheild 1.xはユーザ認証のコア的なものを定義するのにフォーカスし 3つの認証メカニズム(esusers、LDAP/AD、PKI)を提供しました。 これらを提供することで、多くのユーザおよびユースケースをカバー出来ましたが、 追加の認証メカニズムを統合する必要があることもわかっていました。 ということで、Shieldのレルムベースの認証システムをユーザが利用、拡張できるようにオープンにし、 ユーザ認証を扱うためのレルム実装をプラグインとして拡張できるようにしました。 特定もしくはプロプライエタリな認証メカニズムが必要なユーザもShieldの強力な セキュリティ機能(ロールベースの認証、セキュアな通信など)をフルに活用できるようになりました。 カスタムレルムの詳細については、こちらをご覧ください。\nフィールドとドキュメントのACL - Shield 2.0はフィールドとドキュメントレベルのアクセス制御機能を提供します。 これは、ロールごとにアクセス可能なフィールドやドキュメントを定義できます。 この新しい機能は、設定の変更するよりも便利です。 このアクセス制御はElasticsearchのLuceneインデックスという最も低レベルで実装されています。 その結果として、このメンテナンスがより簡単であるだけでなく、より良くなっています。 詳細についてはこちらをご覧ください。\nユーザなりすまし - Shield 2.0で、ユーザなりすましの機能が実装されました。 これは、ユーザ(適切なパーミッションを持った)が、他のユーザになることができ、 それらのユーザのためにリクエストを実行できます。 これは、Elasticsearch上に構築されたアプリケーションがすでにユーザ認証を行いますが、 認可はElasticsearchサイドで行う必要があるような場合に有用です。 このシナリオで、アプリケーションの\u0026quot;main\u0026quot;ユーザを設定でき、正しくなりすましを割り当て、 ElasticsearchにアプリケーションユーザとしてリクエストをElasticsearchに実行させることができます。 詳細については、こちらをご覧ください。\nWatcher SlackとHipChatインテグレーション - SlackとHipChatはチーム/グループコラボレーションツールです。 これらは、急速に主流になり、組織の主な内部コミュニケーションハブとなっています。 Watcher 2.0はチャンネル/ルームやユーザにこれらのコミュニケーションチャネル経由で、Watchの通知を行うことができるアクションを 実装しました。 slackやhipchatアクションについてはドキュメントをご覧ください。\nArray Compare Condition - 新しいconditionはタイムシリーズのデータのスパイクを検知するのを簡単にします。 compare conditionは1.xで導入されましたが、このコンディションはElasticsearchのダイナミックスクリプト機能を有効にする必要がアンク使えます。 詳細についてはarray_compare conditionをご覧ください。\nWatchの有効・無効化 - ユーザからの多かったリクエストとして、Watchの無効化がありました。 1.xには、登録済みのWatchを無効にする機能がありませんでした。 これは、Watchを消すか、Watchのトリガーを変更することで回避していました。 これは、全体としてはWatchを管理するのを難しくする回避方法でしかありません。 2.0では、APIを呼び出すだけで、Watchの変更をすることなく、簡単にWatchの有効化・無効化が可能になりました。 これは1.0からあるべき基本的な機能でしたが、ついにこの問題を解決しました。 詳細はこちらをご覧ください。\nMarvel Marvel 2.0を紹介するのに興奮しています。 Kibana 4をベースとした、再設計されたUIを持っています。 Marvel 1.xで学んだ多くのことを導入し、より使いやすく監視しやすいUIになっています。 ShieldとWatcherと同様に、最初のMarvelのリリースは将来的な成長の基盤となり Elasticsearch2.0を効率的に管理するための主要なメトリックにフォーカスしています。\n画像あり。 ※画像に関しては原文をご覧ください。\n再設計により、インタフェースを6ページに減らしています。\nCluster list 画像あり。 ※画像に関しては原文をご覧ください。\nユーザやカスタマーの多くは複数のクラスタを利用しています。 新しいMarvelはそれらを集中的にモニタリングする一つのクラスタからそれらを簡単に監視できます。 各クラスタのデータ送信先をこのモニタリングクラスタにするだけです。\nCluster Overview 画像あり。 ※画像に関しては原文をご覧ください。\nクラスタオーバービューはある一つのクラスタの主要な性能メトリックを見ることができ、 素早くスパイクを発見できます。 このページはまた、アクティブなシャードのリカバリやリロケーションも見ることができます。\nIndices List 画像あり。 ※画像に関しては原文をご覧ください。\nインデックスのリストにはクラスタにあるすべてのインデックスとその属性が表示されます。 テーブルはライブでアップデートされ、フィルタリングやソートも可能です。 一番大きなインデックスは?といったことも調べられます。\nIndex Detail 画像あり。 ※画像に関しては原文をご覧ください。\nインデックス詳細ページはインデックスの主な性能メトリックを見ることができ、シャードの配置についても表示します。\nNodes List 画像あり。 ※画像に関しては原文をご覧ください。\nノードリストはクラスタにあるノードとその主な性能メトリックを見ることができます。 テーブルはライブでアップデートされ、フィルタリングも可能です。 高いCPU利用率やディスクの残り容量なども簡単にわかるようになっています。\nNode Detail 画像あり。 ※画像に関しては原文をご覧ください。\nノード詳細ページは個別のノードに関する主な性能メトリックを見ることができ、ノードにあるシャードのリストも見ることができます。\n新しいMarvelはKibana 4の上に構築されたので、管理方法が変わっています。 Marvelのインストールは2つのステップがあります。 marvel-agentとmarvel user interfaceです。\nMarvel Agent marvel-agentはElasticsearchクラスタにプラグインとしてインストールします。 主なパフォーマンス情報を取得し、ローカルもしくは分離されたモニタリングクラスタにデータを保存・送信します。\nMarvel User Interface Marvel UIはKibanaのプラグインとしてインストールします。 これは、Kibana 4.2の新しいプラグインインフラを利用し、 Marvel Appとして、Kibanaのインタフェースとは個別に提供されます。 Kibanaのアプリの切り替えは次の画像の通りです。\n画像あり。 ※画像に関しては原文をご覧ください。\n2.0リリースは私たちのプロダクトの大きな一歩です。またユーザの意見を常にお待ちしています。 ぜひ、Webフォーラム(https://discuss.elastic.co)やメール(info@elastic.co)でご意見を。\n","date":1446189691,"dir":"post/2015/","id":"15700442e957951307bbcec5fff8643d","lang":"ja","lastmod":1446189691,"permalink":"https://blog.johtani.info/blog/2015/10/30/shield-watcher-and-marvel-2-0-ga-released-ja/","publishdate":"2015-10-30T16:21:31+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Shield, Watcher, and Marvel 2.0.0 GA Released 本日(10/28)Shield、WatcherおよびMarv","tags":["elasticsearch","shield","watcher","marvel"],"title":"Shield、Watcher、Marvel 2.0.0 GAリリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 2.0.0 GA released\nElasticsearch 1.0.0のリリース以降、 477のコミッター2,799のpull requestがあった、 **Elasticsearch 2.0.0 GA(Lucene 5.2.1ベース)**をリリースしました。\nそれだけでなく、Shield(セキュリティプラグイン)とWatcher(アラーティングプラグイン)、 新しくなったMarvel(モニタリングプラグイン)(プロダクション環境でフリー!)、 また、新しくオープンソースとなったSense editorの2.0.0もリリースしました。\nElasticsearch 2.0.0のダウンロードはこちらから。 また、2.0.0での重要な変更点についてはこちらをご覧ください。 全ての変更点については、次をご覧ください。\nChanges list for Elasticsearch 2.0.0 Changes list for Elasticsearch 2.0.0-rc1 Changes list for Elasticsearch 2.0.0-beta2 Changes list for Elasticsearch 2.0.0-beta1 商用プラグインについてはこちらです。\nShield 2.0.0 change logs Watcher 2.0.0 change logs Elasticsearchの新機能 Elasticsearch 2.0.0には素晴らしい新機能があります。\nPipeline Aggregations Aggregationsで導関数や移動平均のような他のAggregationの結果に対する計算が可能となります。 この機能はクライアントサイドで実装しなければなりませんでしたが、 Elasticsearchに計算させることで、より強力な解析のクエリを簡単に組み立て、クライアントのコードを簡略化できます。 これは、予測解析や予測解析や例外検知といった可能性をもたらします。 Pipeline Aggregationについては次をご覧ください。\nOut of this world aggregations. Staying in Control with Moving Averages - Part 1. Staying in Control with Moving Averages - Part 2. Query/Filter merging フィルタはもうありません。 全てのフィルタ条件はクエリとなりました。 クエリコンテキストで使用した場合、関連度のスコアに影響し、フィルタコンテキストで使用した場合、 これまでのフィルタのように、ヒットしなかったドキュメントを除外するだけとなります。 この変更はクエリの実行時に自動的に最も効率的な順序で実行するように最適化されることを意味します。 例えば、遅いクエリ(フレーズやgeo)の最初の実行は速い近似フェーズで実行され、 それから、遅い正確なフェーズで結果を修正します。 フィルタコンテキストでは、直近でよく使われた条件が自動的にキャッシュされます。 詳細については、\u0026quot;Better query execution coming to Elasticsearch 2.0\u0026ldquo;をご覧ください。\n設定可能な圧縮率 _sourceのようなStored fieldsは高速なLZ4(デフォルト)で圧縮するか、インデックスサイズを小さくできるDEFLATE で圧縮できます。 これは、特にロギングのケースで便利です。 古いインデックスをオプティマイズする前にbest_compressionに変更することができます。 詳細については\u0026rdquo;Store compression in Lucene and Elasticsearch\u0026ldquo;をご覧ください。\n堅牢に 新しいElasticsearchはJava Security Managerの元で実行されます。 これは、セキュリティの観点で大きな前進です。 Seciruty ManagerはElastcsearchにより制限をかけ、ハッカーによりシステムに対して何でもできるようなものを制限します。 Elasticsearchはまた、インデキシングの観点でも堅牢になっています。\nドキュメントはインデキシングリクエストに答える前に、耐久性のためにディスクにfsyncされます。 すべてのファイルはチェックサムにより、早期に障害を検知します。 すべてのファイルはどんなファイルへの書き込みもアトミックです 最後に、システム管理者から要請の多かった変更として、 設定されて居ないノードがパブリックなネットワークから参加しないようになりました。 Elasticsearchはデフォルトではローカルホストのみにバインドします。マルチキャストは無くなりました。(プラグインとして残っています。)\nパフォーマンスと信頼性 上記以外にも細かな修正がElasticsearchとLuceneにはあります。 より安定し、信頼性をあげ、簡単に設定できるようにするものです。例えば、次のようなものです。\nヒープの使用率の低減(doc valuesがデフォルト、マージ時のメモリ使用率の削減、 roaring bitsetsによるフィルタキャッシュ) 構造化され読みやすくなった例外 設定の代わりに、フィードバックループを使用した自動調整 安全で明確で信頼性のあるタイプマッピングの大きな修正 クラスタ状態の差分変更による伝搬の高速化および、大きなクラスタでのより安定的に normsの圧縮の改善。これまではヒープスペースを大きく利用していた。 マージの自動的な調整(不可解な設定の微調整が必要ない) より詳細なLuceneのメモリリポート 最適化されたクエリ実行を活用するためにParent/childを書き換え コアプラグイン 公式にサポートされたコアプラグインはElasticsearchと同じバージョン番号で同じタイミングでリリースされます。 インストールするプラグインとElasticsearchの複雑なバージョンの対応表に悩まされる必要はもうありません。 コアプラグインのインストールは次のように簡略化されています。\nbin/plugin install analysis-icu ShieldとWatcherの新機能 商用プラグインも新しい機能をリリースしました。\nShield フィールドおよびドキュメントレベルのアクセス制御 ユーザのなりすまし カスタム拡張可能な認証レルム Watcher 個別のWatchを有効/無効に SlackやHipChatへの通知 これらの詳細については“Shield, Watcher, and Marvel 2.0.0 GA Released”をご覧ください。\nコアプラグイン同様、商用プラグインもElasticsearchのバージョンと同じものが同時にリリースされます。 インストールは次の通りです。\nbin/plugin install license bin/plugin install shield bin/plugin install watcher Marvel 2.0.0はプロダクションでの利用もフリーに Marvelモニタリングプラグインはカスタマに非常に価値のあるもので、 ユーザの発展とともに問題を診断したり見つけたりするのに役に立ってきました。 私たちは、何を改善でき、Mαrvelを一から書き直すことで、いろいろとわかったことがあります。\nMarvel UIを新しいKibanaプラットフォーム上に構築 ダッシュボードにはより簡単に問題を発見するために、最も重要なメトリックを可視化 1つのインストールで、複数のクラスタのモニタリングをサポート(商用サポート対象) 一番良い点はMarvelがすべてのElasticsearchユーザに対してプロダクション環境でフリーになったことです! ライセンスが必要ですが、課金の必要はありません。 もし、マルチクラスタモニタリングサポートが必要な場合、それは商用サポート対象となります。\n詳細に関しては“Shield, Watcher, and Marvel 2.0.0 GA Released”をご覧ください。\nSense editorがオープンソースに Sense(ブラウザベースのElasticsearchリクエストとDSL向けのエディタ)を Kibanaプラットフォームのアプリとして、オープンソースにしました。 また、このリリースで新しい機能が追加されています。\n複数のcURLリクエストをペースとすると、Sense表記に変更 複数のSenseリクエストをcURL表記にしてコピー 複数のリクエストを一度に実行可能 Elasticsearch 2.0サポートとなった自動補完機能 SenseはKibanaのアプリとして次のようにインストールします。\n./bin/kibana plugin --install elastic/sense Senseの詳細については、\u0026quot;The Story of Sense - Announcing Sense 2.0.0-beta1\u0026ldquo;をご覧ください。\nElasticsearch Migration Plugin Elasticsearch Migration PluginはElasticsearch 1.xから2.0にアップグレードする時の良い出発点となります。 1.xのElasticsearchクラスタにサイトプラグインとしてインストールすると、 アップグレードする前に解決すべき問題があるかどうかを検知してくれます。 (例えば、Lucene 3のような古いインデックスや、2.0.0にした場合に動作しない問題のある マッピング(The Great Mapping Refactoring)のような問題)\nプラグインに関してElasticsearch Migration repositoryをご覧ください。\nまとめ ぜひ、Elasticsearch 2.0.0をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)やWebフォーラムなどで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1446103243,"dir":"post/2015/","id":"018e32a8010960eb17e368a6fdd5a51b","lang":"ja","lastmod":1446103243,"permalink":"https://blog.johtani.info/blog/2015/10/29/elasticsearch-2-0-0-released-ja/","publishdate":"2015-10-29T16:20:43+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 2.0.0 GA released Elasticsearch 1.0.0のリリース以降、 477のコミッター2,79","tags":["elasticsearch"],"title":"Elasticsearch 2.0.0リリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Kibana 4.2.0 released\nElasticsearch 2.0 + Kibana 4.2 = 💚 Elasticsearch 2.0サポートのKibanaの最初のリリースです。 これが何を意味するでしょう? 速さ、安定さ、新しい機能。 試してみたい方は、いますぐダウンロードしてください。 そうでない方は、Kibana 4.2の楽しい機能について読んでみてください。\n暗黒面は怖い? そんなことありません。 私たちは常にチャートチャートとダッシュボードを組み立てている組み立てている間は明るいバックグラウンドを使うことを推奨してきましたが、 時々、巨大なスクリーンで暗い部屋で誰も明るい画面から目を背けないようにしたいでしょう。 その影響を小さくするためにダークモードを導入しました。 あなたは、NOCや天文台、その他の暗い場所でKibanaのダッシュボードを楽しむことができます。\n画像あり。 ※画像に関しては原文をご覧ください。\n地図のカスタマイズ Kibanaの地図は素晴らしいですが、もっと多くのオプションが望まれていると聞きました。 もし地図に関して知識があるなら、Kibana 4.2のWMSバックグラウンド地図サポートを試してみてください。 WMSは非常に強力で、US Geological Surveyを含む多くの無料サービスがあります。 http://viewer.nationalmap.gov/example/services/serviceList.html\n画像あり。 ※画像に関しては原文をご覧ください。\nシナリオは? 何かおかしい時、何が起こっているかを正しく知ってもらいたいので、Kibanaがそのタイミングで注目したいコンポーネントがあるなら、 どのように動いているかという概要を知るためのサーバステータスページを作りました。 もちろん、全てがOKであるというのを知りたいだけの場合でも、settingメニューのStatusタブからいつでも呼び出せます。\n画像あり。 ※画像に関しては原文をご覧ください。\n全てにおいて速く ブラウザリフレッシュはKibana 4.2の新しいコードビルディングシステムのおかげで、さらに早くなりました。 また、メモリを覚えてます?Pepperidge FarmKibanaが覚えています。 Kibana 4.2は小さな小さな小さなメモリフットプリントを管理している間、長い長い長い時間実行されているダッシュボードを見ることができるような 大きなメモリのクリーンアップも含んでいます。\nもっとありますが。。。 小さな微調整がいくつもあります。また、今後紹介する本当に刺激的なものの基礎を気づき上げてきました。 これからもElasticのブログ、Twitter、KibanaのGitHubリポジトリに注目し、モンスタートラックアナリティクスの瞬間に立ち会ってください。\n","date":1446103219,"dir":"post/2015/","id":"e159a35d1b9a46e03072a3d54780edcb","lang":"ja","lastmod":1446103219,"permalink":"https://blog.johtani.info/blog/2015/10/29/kibana-4-2-0-ja/","publishdate":"2015-10-29T16:20:19+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Kibana 4.2.0 released Elasticsearch 2.0 + Kibana 4.2 = 💚 Elasticsearch 2.0サポートのKibanaの最初のリリースです。 これ","tags":["elastic","kibana"],"title":"Kibana 4.2.0リリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Logstash 2.0.0 released\nLogstash 2.0.0が本日(10/28)リリースされました。 このリリースは いくつかの設定に関する重要な変更があります。 詳細については、changelogまたは、新しいbreaking changesドキュメントをご覧下さい。\nこれまでの2.0.0直前のリリースに関する変更点はこちらをご覧ください。\nbeta1 beta2 beta3 RC ここでは、2.0の主な変更点の概要を説明します。\nElasticsearch 2.0との互換性 多くの機能および改善を含んだElasticsearch 2.0がリリースされました。 Logstash 2.0はこのリリースに対応しています。 Logstashのこれまでのリリースでは、デフォルトで、Javaの node clientをElasticsearchとの通信として 使用してきました。 2.0では、HTTPクライアントがデフォルトになります。 これにより、シームレスにユーザのデータを取り込み、付加価値をつけ、Elasticsearchに保存して解析することができます。\nHTTPは他のプロトコル(nodeやtransport)同等の機能を持っていますが、 単一のクライアントに接続する時に、少しだけ遅いですが、管理や動作がより簡単です。 HTTPプロトコルを使うことで、Elasticsearchのバージョンのアップグレードが、Logstashのアップグレードすることなく 行うことができます。 デフォルトをHTTPに変更したさらに詳しい情報についてはbeta1のブログをご覧ください。\n他のプロトコル(nodeとtransport)もサポートしますが、これらを利用する場合には、 プラグインを別途インストールする必要があります。\nbin/plugin install --version 2.0.0 logstash-output-elasticsearch_java 互換性のマトリックス LogstashとElasticsearchのバージョンの互換性は次のようになります。\n画像あり。 ※画像に関しては原文をご覧ください。 #Image https://www.elastic.co/assets/bltde5b69e2164aa82f%2Fcompat_matrix.png\nShield 2.0との互換性 このリリースはShield 2.0リリースにも対応しています。 HTTPプロトコルで、追加のプラグインは必要ありません。 こちらのドキュメントをご覧ください。 transportプロトコルでは、Shield 2.0対応のプラグインを個別にインストールする必要があります。\nbin/plugin install --version 2.0.0 logstash-output-elasticsearch_java_shield パフォーマンスの改善 このリリースはまた、多くの部分のパフォーマンスの改善を含んでおり、Logstashを利用してデータをより早く処理することができます。 いくつかをここで説明します。\nUserAgentとGeoIPフィルタ:これらのフィルタで、LRUキャッシュを追加して改善しています。 これにより、IPとユーザエージェントがまとまって現れるというWebリクエストの特性を用いています。 ユーザエージェントフィルタのケースでは、サンプルデータセットにおいて3.7倍ほど早くなりました。 GeoIPでは、1.69倍早くなっています。\nJSONプロセシング:LogstashでJSONのsiriaraizu/でシリアライズに利用しているJrJacksonを新しいバージョンにしました。 これにより、JSONの処理が改善されています。\nフィルタワーカーのより良い値をデフォルトに:以前のリリースでは、filter_workersの設定は1がデフォルトでした。 これは、フィルタの処理を行うワーカーが1つであるという意味です。 filter_workersの設定のデフォルト値はCPUコア数の半分の値を設定します。フィルタ実行の並列性が上がります。 ですので、複雑なgrokパターンやuseragentフィルタの処理がにとっては重要です。\nFilebeat Support Filebeatのベータバージョンを先日リリースしました。 これは、Logstash Forwarderの次期バージョンです。 Filebeatはファイルベースのログをさらに処理するためにLogstashに送るためのエージェントです。 2.0.0はlogstash-input-beatsプラグインを使えばFilebeat 1.0.0-beta4とすぐに動作します。\nシャットダウン操作 これまでのLogstashでは、シャットダウンが開始した時に、例外の機構でシャットダウンが開始したことを プラグインに通知していました。 この処理はサードパーティのコードを使ったプラグインで問題を起こしていました。 Logstashはどの例外を処理するか知らないため、予期しない動作をしていました。 これを修正するためにAPI呼び出し(例えばstop)を各プラグインにシャットダウンのイベントを通知し、 プラグイン自身がきちんと停止するようにしました。 これは、200以上のプラグインに新しいAPIを利用するように修正しないといけないことを意味しました。 しかし、Logstashの停止についてはまだ完全にはフィックスしていません。 とちゅうでおわっているoutputがシャットダウンを遅らせる可能性があるからです。 2.0でAPIの破壊的な変更は適切なリリースでの変更を繰り返すことができる出発点です。\nプラグインの開発者へ:もし、Logstash 1.5のプラグインを開発しているなら、 シャットダウンに関する新しいAPIのリストに関するbreaking changesのドキュメントに助言をください。 また、example inputリポジトリにて、新しいシャットダウンメカニズムの使い方のサンプルコードを提供しています。\nドキュメント 2.0に更新されたドキュメントはこちらです。設定の変更についてもこちらをご覧ください。\n2.0へのアップデート 2.0へアップデートする前に、アップデートガイドもご覧ください。\nフィードバック 2.0のリリースできたことに、多くのコントリビューター、ユーザに感謝しています。 このリリースに含まれている多くのパッチと全てのプレリリースのテストにも感謝しています。 将来の修正やリリースなどについてはロードマップをご覧ください。 2.0は今日リリースされました。 ご意見ご感想はWebフォーラムで!\n","date":1446103197,"dir":"post/2015/","id":"cc64c2fcdecdb505b3797e1aaaa59adc","lang":"ja","lastmod":1446103197,"permalink":"https://blog.johtani.info/blog/2015/10/29/logstash-2-0-0-released-ja/","publishdate":"2015-10-29T16:19:57+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Logstash 2.0.0 released Logstash 2.0.0が本日(10/28)リリースされました。 このリリースは","tags":["elastic","logstash"],"title":"Logstash 2.0.0リリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Relase, we have ※画像に関しては原文をご覧ください。\nElasticにとって大きな1日(社内では「release bonanza」と呼んでいる)です。 多くの主要なプロダクトを新たにリリースしました。 そして、本日、それらを一緒に利用する時にそれらを一緒に利用する時にユーザの体験についてまとめてみました。\n次の通りです。\nElasticsearch 2.0リリース。 大きなマイルストーン、チームによる改善、そして、コミュニティからの素晴らしい貢献。 Pipeline Aggsと呼ばれる新しいタイプのaggregations、 クエリとフィルタのコンセプトを統合することにより簡素化されたクエリDSL、 better compressionオプション、 JavaのSecurity Managerを有効にすることによる強化されたセキュリティ、 FSの挙動に関する強化(fsync、checksum、atmicなリネーム)、 パフォーマンス、マッピングの挙動の一貫性などなどです。 また、我々のチームによる改善も含まれているLucene 5ベースにアップグレードしています。\nKibana 4.2リリース。 Elasticsearch 2.0対応、ダークテーマ、カスタマイズ可能な地図、多くの改善。 Kibana 4.2の多くに作業については外部プラグインサポートといった、内蔵に関するものでした。 この後の説明に続きます。\nMarvel 2.0リリース。 Elasticsearch 2.0対応、合理化されたメトリックス、簡素化されたUI、 多くはKibanaプラグイン(Kibanaプラットフォーム上に構築)としての書き換えです。 このKibana拡張の最初の努力は、Kibanaのプラグインをどうやって書くか、 Kibanaユーザに公式に何をする必要があるかといったものを特定するのに役立ちました。 おっと、忘れるところでした、Marvelを全てのユーザにフリーで使えるようにしました。 マルチクラスタサポートについては有償となります。\nSense 2.0リリース。 2つ目のKibanaプラグインがこれです。 SenseをKibanaプラグインとして書き換えました。 Elasticsearch 2.0サポート、複数リクエストの実行、 curlへのコピーなどです。 おっと、忘れるところでした。オープンソースとすることにしました!\nShield + Watcher 2.0リリース。ElasticsearchのためのセキュリティプラグインであるShieldと、アラート管理のためのプラグインであるWatcherにも 多くの結果が入っています。 最も要求のあった機能である、フィールドお呼びドキュメントレベルでのセキュリティについて、Luceneに落とし込んで実装しました。 また、セキュリティの操作についてプラガブルに実装できるように変更しました。 Watcherは監視の無効化、SlackやHipChatへの通知(bot ops向け)が可能です。\nLogstash 2.0リリース。 Elasticsearch 2.0のサポート、クリーンな停止、全面的なパフォーマンス改善、Beatsサポート。\nご覧の通り、すべてのプロダクトに関する大きな結果です。 チーム間およびFoundの開発者との間での密な連携に感謝します。 これらが私たちが公式にElasticsearch / KibanaをホストしているFoundで 利用可能です。\nひゅう、息切れしました。 チームがしてきたことは、感動的で、謙虚で、刺激的です! Elasticが会社として、全てのユーザ、コントリビュータがどのように私たちの大きなミッションに対する結果をもたらしたかという素晴らしい良い例です。 ユーザに愛され、楽しまれ、成功に導き、革新させる製品を是非ご利用ください。ありがとうございます。\n\u0026ldquo;A Lion, in Africa?\u0026rdquo; - まだまだ終わりではありません。この文言で終わりにしますが、すぐに(本当にすぐに)戻ってきます。;)\n","date":1446095939,"dir":"post/2015/","id":"4cc08ca51ecf0f963035f039de6194c5","lang":"ja","lastmod":1446095939,"permalink":"https://blog.johtani.info/blog/2015/10/29/release-we-have-ja/","publishdate":"2015-10-29T14:18:59+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Relase, we have ※画像に関しては原文をご覧ください。 Elasticにとって大きな1日","tags":["elasticsearch","kibana","logstash"],"title":"Release, we have(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 2.0.0-beta2 released\n本日(9/17)、Lucene 5.2.1ベースのElasticsearch 2.0.0-beta2をリリースしました。 本リリースが2.0.0のRCの前の最後のベータリリースになります。\n注意事項 本リリースはベータリリースであり、テストを目的としたものとなります。 Elasticsearch 2.0.0-beta2はElasticsearch 2.0.0-beta1と互換がありません。 また、Elasticsearch 2.0.0 GAと互換性があるかどうかの保証はありません。\n本番環境には利用しないでください。\nElasticsearch 2.0.0-beta2のダウンロードおよび、すべての変更についてはリンクをごらんください。\n2.0.0-beta1をテストし、問題点を報告していただいた皆様、ありがとうございます。 2.0.0-beta1のあとのElasticsearchのコアの部分の修正のほとんどはバグフィックスになりますが、 geo_shapeフィールドのpoints_only最適化のようなちょっとした改善も含んでいます。\nまた、本リリースでは、商用プラグインの重要な新機能もあります。 こちらについてはShield and Watcher 2.0.0-beta2 releasedをごらんください。 簡単な紹介は次の通りです。\nShieldの新機能 ドキュメントおよびフィールドレベルのセキュリティ Shieldは、クエリを利用したインデックスにあるドキュメントへのアクセスを制御するためのロールを定義できるようになりました。 また、ドキュメントにある特定のフィールドに関するアクセス制限も可能です。 フィルタされたエイリアスのような形ではなく、ドキュメントを検索したり、IDで取得したりする場合にこれらの制限が利用できます。 詳細はField- and Document-level Securityをごらんください\nユーザなりすまし 特定のユーザーに他のユーザーに扮して、彼らのためにリクエストを実行する能力を与えることが、現在できます。 これは、認証がアプリケーションによって実行される場合に便利です。 そして、それは、ユーザの許可レベルを考慮するようにElasticsearchにリクエストします。 詳細はSubmitting Requests for Other Usersをごらんください。\nプラガブルな認証レルム このリリースで、サードパーティの拡張のための認証レルムのインフラを公開しました。 もし、特定の認証要求があり、Shieldがサポートしていない(が、内部の認証管理システムを使いたいような)場合、 これらの要求に見合う新しい認証レルムを利用するプラグインを作成可能です。 詳細はCustom Realmsをごらんください。\nWatcherの新機能 監視の一時 新しく、active / inactive の状態がwatchに追加されました。 これらは、Watchを中断したり、要求に応じて再開させたりできます。 詳しくは、Active Stateをごらんください。\nチャットのための新しいアクション slackとhipchatアクションが追加されました。 これは、Watcherが通知を、SlackやHipchatのユーザに直接送ったり、 チームのチャットルームに送ったりすることが出来るようにします。 詳細については、Slack actionおよび、Hipchat actionをごらんください。\n2.0に関するこれまでのブログ記事 これまでのリリースについての情報はこれらのブログ記事をごらんください。\n\u0008* Elasticsearch 2.0.0.beta1 released\nElasticsearch 2.0.0.beta1 coming soon! The Great Mapping Refactoring Store compression in Lucene and Elasticsearch Better query execution coming to Elasticsearch 2.0 Out of this world aggregations Staying in Control with Moving Averages - Part 1 Staying in Control with Moving Averages - Part 2 The Delete by Query API Is now a plugin Elasticsearch unplugged - Networking changes in 2.0 また、Elasticsearch 2.0.0-beta2のドキュメントや2.0のbreaking changesのリストもごらんください。\nElsticsearch Migration Plugin Elasticsearch Migration Pluginは、既存のインデックスをアップグレードする 必要があるか、他に必要な行動がないかについて、Elasticsearch 2.0.0-beta2を試す前に確認する助けとなります。 Lucene 3のような古いインデックスや、2.0.0にした場合に動作しない問題のある マッピングのような問題を発見できます。\nプラグインの動作に関しては[Elasticsearch Migration repository](Elasticsearch Migration repository)をごらんください。\nテストしましょう! Elasticsearch 2.0.0 GAをすぐにリリースできるようにより多くのベータテスターをお待ちしています。\nぜひ、Elasticsearch 2.0.0-beta2をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)やWebフォーラムなどで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1442565101,"dir":"post/2015/","id":"4b227d61f33182579cd3edd0ac6c7c44","lang":"ja","lastmod":1442565101,"permalink":"https://blog.johtani.info/blog/2015/09/18/elasticsearch-2-0-0-beta2-released-ja/","publishdate":"2015-09-18T17:31:41+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 2.0.0-beta2 released 本日(9/17)、Lucene 5.2.1ベースのElas","tags":["elasticsearch"],"title":"Elasticsearch 2.0.0-beta2リリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch unplugged - Networking changes in 2.0\nElasticsearchをローカルのマシンで起動します。 そして、昨日試したデータを削除するためにDELETE *を実行します。 すると、悲しそうな叫びを同僚が発していることに気づき、なぜそんなことになっているのか不思議に思うでしょう。。。\nElasticsearchはいつも、親しみやすいものでした。 複数ノードのクラスタがどのように機能するのかをテストするには、 ローカルのマシンでいくつかのElasticsearchのインスタンスを起動するだけでした。 起動したインスタンスはマルチキャストを利用して自動的にお互いを見つけて、1つのクラスタになり、負荷を共有し始めます。 しかし、これは親しみやすすぎました。 カンファレンスなどで、ローカルのマシンでElasticsearchを起動してみてください。 すると100ノードのクラスタに参加しているのがすぐにわかるでしょう。\nもうすぐリリースされる、2.0.0-beta1では、Elasticsearchが通信先を選択するネットワークの機能に関する変更があります。 ただし、これまで通り、簡単に開発者が経験できる機能も残っています。\nlocalhostへのバインド 以前、Elasticsearchはデフォルトで、利用可能なネットワークインタフェース全てにバインドしていました。 そこから、一番適したインタフェースをpublish_hostとして選択しようとします。 このアドレスはElasticsearchがクラスタの他のノードとやりとりするためのアドレスです。\nElasticsearch 2.0では、デフォルトでは、localhostにのみバインドします。 127.0.0.1(IPv4)と[::1](IPv6)の両方にバインドしようとします。 また、どちらかのみの環境でも動作します。 この変更は、特に指定がない限り、Elasticsearchがネットワーク上の他のノードと接続しません。 本番環境に移行する場合は、network.hostパラメータを使って設定しましょう。 設定は、elasticsearch.ymlに記述するか、コマンドラインで指定します。\nbin/elasticsearch --network.host 192.168.1.5 bin/elasticsearch --network.host _non_loopback_ network.hostの全てのオプションについては、network settingsのドキュメントをごらんください。\nマルチキャストは廃止 Elasticsearch 1.xはネットワークの他のノードに接続・探索するためにマルチキャストを使用しました。 マルチキャストは魔法のような挙動です。。。 残念ながら、マルチキャストのサポートは良くも悪くもあります。 Linuxはローカルホストでマルチキャストの待ち受けをしていません。 OS/Xは構成されたアドレスの全てのインタフェースにマルチキャストで配信できます。 また、ネットワークによってはマルチキャストはデフォルトでは使用できなくなっています。\nElasticsearch 2.0は異なるアプローチを採用しました。 マルチキャストを廃止します(ただし、新たにプラグインとして提供します)。 代わりに、ローカルホストでは、Elasticsearchはtransport.tcp.portで指定されている範囲(デフォルトは9300-9400)の最初の5ポートに対してユニキャストを使用できるようにします。\nこれは、開発者のための、設定することなく自動的にクラスタを組むという機能を残しています。 しかし、本番に移行するときは、unicast hostsで次のようにリストを指定する必要があります。\ndiscovery.zen.ping.unicast.hosts: [ 192.168.1.2, 192.168.1.3 ] unicast hostsとしてクラスタにあるノードの全てのリストを指定する必要はありません。 少なくとも、マスタノードとして選出されるべきものを指定します。 巨大なクラスタでは、3つの専用のマスタノードを持っており、この3つをunicast hostsとして設定することを推奨しています。\nこれにより、開発の知識・経験が、私たちの推奨する本番でのネットワーク設定に、より近いものとなります。\nノード情報の変更 最後に、inet[/127.0.0.1:9200]といったシンタックスを廃止します。 これは、Elasticsearchがnodes-info APIなどで、使用していたIPアドレスのためのシンタックスです。 今は、RFCに準拠した形で表示します。 127.0.0.1:9200(IPv4)や[::1]:9200(IPv6)のようにです。\n質問がある場合は、ElasticsearchのWebフォーラムで質問してください。ベータはもうすぐです!(翻訳した時点で、すでにベータリリースされています。)\n","date":1440730890,"dir":"post/2015/","id":"0de0edbf2a506143c1739b12e94c0ef9","lang":"ja","lastmod":1440730890,"permalink":"https://blog.johtani.info/blog/2015/08/28/elasticsearch-unplugged-ja/","publishdate":"2015-08-28T12:01:30+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch unplugged - Networking changes in 2.0 Elasticsearchをローカルのマシンで起","tags":["elasticsearch"],"title":"Elasticsearch unplugged - 2.0におけるネットワークの変更(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 2.0.0-beta1 released\n本日(8/26)、Lucene 5.2.1ベースのElasticsearch 2.0.0-beta1をリリースしました。 本リリースは469名のコミッターからの2,500以上ものpull requestを含んでいます。 pull requestのうち、約850が2.0のための新規のものとなります。\n注意事項 本リリースはベータリリースであり、テストを目的としたものとなります。 Elasticsearch 2.0.0-beta1は Elasticsearch 2.0.0 GAと互換性があるかどうかの保証はありません。\n本番環境には利用しないでください。\nElasticsearch 2.0.0-beta1のダウンロードおよび、すべての変更についてはリンクをごらんください。\nElasticsearch 2.0.0-beta1には次の新しい変更が含まれています。\nPipeline Aggregations:これは、他のaggregationsの結果に対するAggregationを実行できます(導関数、移動平均、Holt Winter予測アルゴリズムなども含む) ディスクやファイルシステムキャッシュにより適したより良いデータの圧縮 doc-valuesがデフォルトになったこと、マージ実行時のメモリ使用量の低減、フィルターキャッシュのためのroaring bitsetsなどにより、ヒープの使用率がより効率的に。 構造化された例外 最適化されたクエリ実行順序、フィルタの自動キャッシュ、より高速なクエリに書き換えられたparent-child 設定の代わりに、フィードバックループを使用した自動調整 トランザクションログへの書き込みがデフォルトで、アトミックでかつ冗長に 安全で明確で信頼性のあるタイプマッピング デフォルトでローカルホストでのみクラスタを構成 クラスタ状態の差分によりより高速に変更を伝搬 上記の変更以外にも、多くのElasticsearchおよびLuceneに対する継続的な変更が含まれています。 これらは、Elasticsearch 2.0をより安全に、より簡単に、より良いものにしています。 本リリースに関するより詳しい情報が次のブログにあるので、参考にしてください。\nElasticsearch 2.0.0.beta1 coming soon! The Great Mapping Refactoring Store compression in Lucene and Elasticsearch Better query execution coming to Elasticsearch 2.0 Out of this world aggregations Staying in Control with Moving Averages - Part 1 Staying in Control with Moving Averages - Part 2 The Delete by Query API Is now a plugin Elasticsearch unplugged - Networking changes in 2.0 また、Elasticsearch 2.0.0-beta1のドキュメントも参考になります。 特に、2.0での重大な変更点については必ずごらんください。\nCore plugins コアプラグインの開発の方法を変更しました。 公式にサポートしているプラグインは、現在elasticsearchのリポジトリに含まれています。 これにより、コアと一緒にテストされ、Elasticsearchと同じタイミングでリリースされます。 コアプラグインはElasticsearchと同じバージョン番号隣ます。 インストールは次のようになります。\nsudo bin/plugin install analysis-icu プラグインの新しいドキュメントは私たちのWebサイトのGuideにあります。\nCommercial plugins 私たちの商用プラグインもElasticsearchと同じバージョン番号となり、Elasticsearchと一緒にリリースされます。 ShieldやWatcherはすでに2.0.0-beta1が利用可能です。 インストールのコマンドはは次のようになります。\nsudo bin/plugin install license sudo bin/plugin install shield sudo bin/plugin install watcher MarvelおよびSenseに関する新しい情報もありますが、もう少しお待ちください。\n2.0.0-beta1の商用プラグインに関するドキュメントは次のリンクからごらんください。\nShield 2.0.0-beta1 Watcher 2.0.0-beta1 Elasticsearch Migration plugin Elasticsearch 2.0.0-beta1を試す前に、 既存のインデックスのアップグレードするためになにか行う必要があるかどうかを確認するためのElasticsearch Migration Pluginもリリースしました。 2.0.0では機能しない、問題のあるマッピングなどを見つけるために便利なプラグインです。\nこのプラグインの利用方法についてはElasticsearch Migration repositoryをごらんください。\n既知の問題 同じインデックスの異なるタイプに、同じ名前のipタイプのフィールドを追加した時に、問題があることがわかっています。 この問題は次のリリースでフィックスされます。詳細は#13112をごらんください。\nテストしましょう! Elasticsearch 2.0.0 GAをすぐにリリースできるようにより多くのベータテスターをお待ちしています。\nぜひ、Elasticsearch 2.0.0-beta1をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)やWebフォーラムなどで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1440638952,"dir":"post/2015/","id":"744554499cb7880086fbd9b1f080e7e1","lang":"ja","lastmod":1440638952,"permalink":"https://blog.johtani.info/blog/2015/08/27/elasticsearch-2-0-0-beta1-released-ja/","publishdate":"2015-08-27T10:29:12+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 2.0.0-beta1 released 本日(8/26)、Lucene 5.2.1ベースのElas","tags":["elasticsearch"],"title":"Elasticsearch 2.0.0-beta1リリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:The Delete by Query API Is now a plugin\nElasticsearchの2.0.0-beta1では、これまであった Delete by Query APIが削除され、 新しく Delete by Query pluginに置き換えられています。\nもし、Delete by Query を利用する場合、2.0にアップグレードしたあとは、プラグインをインストールし、ドキュメントに従ってください。\nbin/plugin install delete-by-query なぜプラグインに? ElasticsearchのコアなAPIの品質を保つためであり、以前のDelete by Queryの実装は簡単にはフィックスできない大きな問題がありました。\n各リクエストのあとに、refreshを実行します。これは、削除されたデータが想定外に検索に出てこないようにするためです。\nまた、セグメントが大量にでき、マージが大量に発生し、ヒープが大量に消費されてインデキシングが劇的にスローダウンし、クラスタの複数のノードがクラッシュしてしまう状況も引き起こしました。 このクエリは、プライマリ、レプリカの両方で実行されるため、ことなるドキュメントを削除し、矛盾したレプリカ(データの破損)を引き起こしました。 アップグレードが不安定になります。これは、Delete by Queryリクエストがトランザクションログの中にクエリとして残るためです。そのため、アップグレードのあとに正確にパースされなかったり正確に実行されないかもしれません。例えば、インデックスエイリアスに対するリクエストで、それが削除された後の場合にこのようなバグが発生します。 対照的に、新しいプラグインは、安全な実装です。 scanとscrollリクエストでクエリにマッチしたIDを見つけ、そのIDを使って、bulk indexing APIで削除します。\nこの実装は、遅い必要があります。特に、クエリが多くのドキュメントを削除する場合です。 もし、多くのドキュメントをこのAPIを利用して削除する場合、アプリケーションをテストしてください。 そして、代わりにインデックス全体を消すようなアプローチに切り替えることができないか検討してください。\nDelete by Query pluginのドキュメントに、新しい実装についての違いなどのより詳しい説明があります。\nElasticsearch coreを最小限に プラグインに切り替えることは、簡単な決断ではありませんでした。 多くのユーザは問題なく、Delete by Queryを利用していました。 しかし、危険が常にそこにあり、些細とは言い切れない数のユーザが上記のような深刻な問題に遭遇していました。\nさらに、Elsticsearchのコアは信頼できるものでなければなりません。 他のコアAPIを利用して実装できる機能は、コアに含みません。特に、それがバグを含んでいる場合。 コアのすべての機能は強固であるべきで、Delete by Queryは人気があり、高性能ですが、そうではありませんでした。\n必要に応じて、このような難しいトレードオフの末、信頼性と品質を選びます。\nマッピングの削除の廃止 タイプのマッピングを削除する機能も2.0で廃止されます。 これは、同じフィールド名を、異なるフィールドのタイプで再利用した場合に、インデックスの破損を引き起こす可能性があるためです。\nしかし、Match All Queryで、Delete by Queryプラグインに対してタイプを指定することで、タイプのすべてのドキュメントを削除することはできます。 または、1つのインデックスに異なるタイプを複数含める代わりに、個別のインデックスに分割するようなアプローチに変更することを検討してください。\n","date":1440044644,"dir":"post/2015/","id":"5a9e950f4ac186925e5de978c5f72062","lang":"ja","lastmod":1440044644,"permalink":"https://blog.johtani.info/blog/2015/08/20/core-delete-by-query-is-a-plugin-ja/","publishdate":"2015-08-20T13:24:04+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:The Delete by Query API Is now a plugin Elasticsearchの2.0.0-beta1では、これまで","tags":["elasticsearch"],"title":"Delete by Query APIはプラグインへ(日本語訳)"},{"contents":"第11回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズさん、そして、Shayありがとうございました! 次回もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\n今回は、CTOのShayが来日していたので、英語でいろいろと喋ってもらいました。 4月同様、サムライズムの@yusukeさんに テキスト翻訳していただき、大変助かりました。 今回はQAベースのトークだったのでちょっときつかったですね、申し訳ない。。。\nチェックイン数など チェックインした人:141名 キャンセルしなかった人:51名 でした。 今回はあらかじめ220名(全員が来たらキャパオーバー)としていたので、キャンセル待ちの人は 当日の午後にはいなくなっていた状態です。まぁ、こんなもんかな。結構入りましたね。ありがたいです。\nLT 今回は、少し趣向を変えて、4社の方達にLTをしていただきました。 Shayが来日しているのもあり、事前に英語でスライドを作っていただけると助かりますとお願いさせていただきました。 英語でスライドを作っていただいていたので、伝わりやすくて助かりました、スピーカーの方々ありがとうございました!\n(海外のユーザにもリンクを紹介しやすいので、英語でスライド作ってもらえるといろいろと知ってもらえるのかも。)\nElasticsearch and Recruit Technologies Co., Ltd. / 株式会社リクルートテクノロジーズ 守谷 純之介さん スライド:未定\nN-Gramと形態素のハイブリッドの話などをしていただきました。 @ITで連載もされてますね。ありがとうございます。\nリクルート全社検索基盤のアーキテクチャ、採用技術、開発体制はどうなっているのか (1/2) ElasticsearchとKuromojiを使った形態素解析とN-Gramによる検索の適合率と再現率の向上 (1/3) Shayからは、elasticsearch-hadoopがあるから検討してねと質問(お願い?)がありましたw。\nElasticsearch as a DMP / 株式会社インティメート・マージャー 松田和樹さん @mats116 スライド:Elasticsearch as a DMP\nいくつかのデータソースからAEROSPIKE経由でelasticsearchにデータを登録しているようです。 Data Management Platformのエンジンの一部として、elasticsearchを利用しているようです。\nShayからの質問:「どの機能を使って関心のある単語を抽出していますか?」\n回答:「Significant Term Aggregation」です。\nShay:「おぉ、チェックしてみますw」。\nReal-time social big data analytics using elasticsearch / 株式会社ホットリンク宮田洋毅さん @kakka_jp スライド:未定\nソーシャルメディアのデータを解析するのにelasticsearchにデータを入れて解析。 時間軸での解析やテキストマイニングなんかをしているみたいでした。 いろいろと独自のプラグインを作ってるようです。(興味あるなぁ)\nShayからの質問:「ノード数は?」「30ノードで30シャード」\nElasticsearch in Hatena Bookmark / 株式会社はてな id:skozawa スライド:Elasticsearch in Hatena Bookmark\nはてなブックマークの検索の歴史(MySQL -\u0026gt; Sedue -\u0026gt; Solr -\u0026gt; Elasticsearch) はてなブックマークの検索(ユーザが利用)と社内利用と、ログ解析で利用してる Shayからの質問:「昨年会いましたよね?今はクラスタのサイズはどのくらいのサイズですか?」「メインクラスタは9データノード」\nOpen QA with Shay 思い出せるものだけ。。。(あとで追記します)\nElasticsearch 2.0の話 Pipeline Aggregationとか。 Spark Streaming対応してる? まだ検討中 elasticsearch-hadoopってどんなもの?HDFSにインデックス作ったりするの? いえ、Hadoopの入出力先としてelasticsearchが使える感じ 個人的にAWSのCloudSearchとAWSでElasticsearchはどっちがいい? 時系列データはCloudSearchだと難しいだろうし、AWS上ならfound.noがあるよ! PostgreSQLみたいに信頼性の高いデータストアを目指してる(まだ、プライマリデータストアには使わないで) その他、感想などのブログ Elasticsearch勉強会でLTしてきました | Intimate Merger Engineer Blog 『第11回elasticsearch勉強会』のまとめ #elasticsearchjp \u0008* [Elasticsearch] 第11回 Elasticsearch 勉強会へ参加してきた - 雑文発散(2015-07-28) 第11回 Elasticsearch 勉強会に参加したら英語力に危機感を覚えて最高だった まとめ 今回はShayが来日したので特別バージョンでした。 もっと英語を翻訳するサポートしないとですね、反省してます。。。ぜんぜん流暢じゃないしw\n次回は9月に開催予定ですが、12月にまたShayが再度来日する予定です。 丸1日のイベントを検討中で、Shay以外にも開発者が来日すると思います。 どんな話が聞きたい、どんな人と話をしたいなどあれば、コメントいただければ(対応できるかは。。。)\n勉強会のスピーカーは随時募集中ですので、コメント、メール、ツイートなど、コンタクトしていただければと思います。 よろしくお願いいたします。\n","date":1438321313,"dir":"post/2015/","id":"73b8194ad8fce0cabb01cd21d5e18500","lang":"ja","lastmod":1438321313,"permalink":"https://blog.johtani.info/blog/2015/07/31/11th-elasticsearch-jp/","publishdate":"2015-07-31T14:41:53+09:00","summary":"第11回Elasticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、会場提供していただいたリクルートテクノロジーズ","tags":["elasticsearch","勉強会"],"title":"第11回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 1.7.1 and 1.6.2 released\n本日(7/29)、Lucene 4.10.4ベースのElasticsearch 1.7.1およびElasticsearch 1.6.2 のバグフィックス版をリリースしました。 これらのリリースは稀ですが、データの欠損が発生する重要なバグのフィックスを含んでいます。 すべてのユーザにアップグレードを推奨します。\nダウンロードおよびすべての変更については次のリンクをごらんください。\n最新安定版:Elasticsearch 1.7.1 1.6系バグフィックス:Elasticsearch 1.6.2 問題のバグ(#12487)は、 同時に複数のノードが故障またはリスタートをした場合の非常にまれな状況で、 シャードのすべてのコピーがクラスタから削除されてしまう状況を発生させます。 このバグは1.5.0から含まれています。\nこのリリースはまた、IPv4アドレスのCIDRマスクのバグのフィックス、 Shieldユーザがmore-like-this APIを利用できないバグのフィックスなど、 いくつかの変更も含んでいます(詳細は更新リストをごらんください)。\nぜひ、Elasticsearch 1.7.1をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1438173353,"dir":"post/2015/","id":"100c0a69bea7f02a0f4540ecaa37d0e3","lang":"ja","lastmod":1438173353,"permalink":"https://blog.johtani.info/blog/2015/07/29/elasticsearch-1-7-1-and-1-6-2-released-ja/","publishdate":"2015-07-29T21:35:53+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 1.7.1 and 1.6.2 released 本日(7/29)、Lucene 4.10.4ベースのE","tags":["elasticsearch"],"title":"Elasticsearch 1.7.1 および 1.6.2リリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 1.7.0 and 1.6.1 released\n本日(7/16)、Lucene 4.10.4ベースのElasticsearch 1.7.0およびElasticsearch 1.6.1 のバグフィックス版をリリースしました。 これらのリリースはセキュリティフィックスを含んでおり、すべてのユーザにアップグレードを推奨します。\nダウンロードおよびすべての変更については次のリンクをごらんください。\n最新安定版:Elasticsearch 1.7.0 1.6系バグフィックス:Elasticsearch 1.6.1 1.7.0が1.x系の最後のリリースとなります。 今後の新機能については、Elasticsearch 2.0以降で取り込まれる予定です。\nElasticsearch 1.7.0は小さなリリースですが、2つの重要なセキュリティフィックスと クラスタの安定化とリカバリに関する2つの重要な機能を含んでいます。\nセキュリティフィックス シャードアロケーションを遅らせる インデックスリカバリの優先度 セキュリティフィックス Elasticsearch 1.6.1 と 1.7.0 は次の2つのセキュリティフィックスを含んでいます。\nリモートコード実行の脆弱性 Elasticsearch 1.6.1より前のバージョンには、transport protocol(ノードとJavaクライアント間での通信に利用)により、 リモートでコードが実行される脆弱性があります。 これは、CVE-2015-3253でのGroovyに関係しています。\nGroovyのダイナミックスクリプティングがオフでも脆弱性があります。 アップグレードをしないユーザは、transport protocol のポート(デフォルトで9300)信頼したエージェントからのみの アクセスに限定することで、脆弱性から保護できます。\nこの問題をCVE-2015-5377としました。\nディレクトリ探索の脆弱性 Elasticsearch 1.0.0から1.6.0までのバージョンで、ElasticsearchのJVMプロセスによって読み込みが可能なファイルを 取得することができるディレクトリ探索攻撃の脆弱性があります。 アップグレードをしないユーザは、信頼できない場所からのSnapshot-Restore APIの呼び出しを防ぐためにファイアウォール、リバースプロキシやShieldを使用することができます。\nこの問題をCVE-2015-5531としました。\nシャードアロケーションを遅らせる Elasticsearch 1.6.0でSynced Flushingが導入されました。 これは、ノードのリスタート時に、更新が止まっているシャードのリカバリを劇的にスピードアップします。 しかし、この変更は、シャードの配置を無効にしている環境でのみうまく実行されます。 ノードが一時的にクラスタから外れている場合や予期せぬリブートの場合には役に立ちません。\nこのシナリオとは次のようなものです。\nノードの想定外のシャットダウン マスタがたのノードにシャードを再配置 各シャードが新しい場所にネットワーク越しにコピー その間に、外れていたノードが再度クラスタにジョイン マスタは新しいノードにシャードを再配置。新しいノードに存在する既存のシャードが全く再利用されない可能性がある ノードレベルとクラスタレベルの両方の並列的なリカバリを抑制しても、 この\u0026quot;シャードシャッフル\u0026quot;がクラスタに対して負荷をかける可能性があります。 これは、外れたノードが再度ジョインするのを単に待つことにより防げるかもしれません。\n待ちましょう! Elasticsearch 1.7.0はindex.unassigned.node_left.delayed_timeout設定を追加しました。デフォルトでは1分です。 これは、ノードがクラスタから外れたとき、ほかのノードにこれらのノードを再配置するまでマスタが1分待つということです。 ノードがこの1分の間に復帰した場合、マスタはローカルにあるシャードを再度配置します。\nなぜ1分? ノードがシャットダウンし、リスタートし、復帰するために十分な時間が1分だからです。 しかし、ノードが復帰しない場合にはまだ再配置が発生することを意味します。 デフォルト値を決定するのは難しいです。 この設定をどのくらいに減らすか、増やすかを決める必要があるかもしれません。\nこのデフォルト値は、config/elasticsearch.ymlファイルに設定できますが、インデックス設定の更新APIを使って設定することも可能です。\nこのデフォルトに関する知見をぜひフィードバックしてください。\nインデックスリカバリの優先度 1.7.0の2つ目の重要な機構はフルクラスタリスタートのような後に、 どの順番でインデックスをリカバリするかという優先度をつけることができるという機能です。\n電源故障による、ロギング用のクラスタのダウンを想像してください。 クラスタが普及した場合、500個のインデックスをリカバリするような場合、499個のインデックスのデータは古く、 500番目のインデックスが重要です。 もっとも最近作成されたインデックスがリカバリされるまで、インデキシングを待つというようなことはできません。\nこれまでは、インデックスはランダムな順序でリカバリされ、重要なインデックスがリカバリされるまで待つしかありませんでした。 1.7.0では、インデックスは優先度の順番でリカバリされます。 この優先度は次のプロパティで指定できます。\nindex.priority設定(大きな値が優先度が高い) インデックス作成日(新しいものが優先度が高い) インデックス名 既存のクラスタについて特に変更せずとも、最も最近作成されたインデックスが古いものよりも復旧されます。 古いインデックスの優先度を上げるためには、index.priority設定に0よりも大きな値を設定します。\nPUT important_index/_settings { \u0026#34;index.priority\u0026#34;: 5 } この設定は、存在するインデックスに対して更新できます。リカバリ中にもです。\nまとめ ぜひ、Elasticsearch 1.7.0をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1437546817,"dir":"post/2015/","id":"809925e891b0456231c374b09cbe4a90","lang":"ja","lastmod":1437546817,"permalink":"https://blog.johtani.info/blog/2015/07/22/elasticsearch-1-7-0-and-1-6-1-released-ja/","publishdate":"2015-07-22T15:33:37+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 1.7.0 and 1.6.1 released 本日(7/16)、Lucene 4.10.4ベースのE","tags":["elasticsearch"],"title":"Elasticsearch 1.7.0 および 1.6.1リリース(日本語訳)"},{"contents":"東京以外での勉強会の第2弾として、関西で勉強会を開催してきました。\nElasticsearch勉強会 in 大阪 Elasticsearch勉強会 in 京都 会場提供をしていただいた、Yahoo!大阪、はてなのみなさん、ご協力ありがとうございました!\nここからはいつものメモです。 ちなみに、大阪の勉強会に、@takuya_aさんと@5kozawaさんの両名にお越しいただき話をしていただきました。 なので、勉強会の内容はほぼ同一になります。\nIntroduction Elastic @johtani スライド:Introduction Elasticsearch\n初めての関西での勉強会ということで、ElasticsearchのOSSおよび商用プラグインの紹介をしてきました。 もちろん、Kibanaのデモもちょっとだけ。スプラトゥーンに関するデータをKibanaでちょっとだけ。 突貫でデータをかき集めたのでもう少し改良しないとですが。\nElasticsearch での類似文書検索と More Like This API 詳解 / 株式会社はてな id:takuya-a スライド:Elasticsearch での類似文書検索と More Like This Query API 詳解\nElasticsearchのMore Like Thisのソースコードリーディングみたいな感じで、 内部でどうやって処理されているかの説明を詳しくしてもらいました。\n前のはてなエンジニアセミナーで話をされていた検索精度の件に絡んだ内容になっているかと。 (大阪で発表してもらった時より京都での発表が分かりやすくなってました。1日で改善されたのすごい!) MoreLikeThisだとチューニングつらいので、自分で作るためにTermVectorAPIでやってみたという流れかと。\n以下は発表後に出てきた質問のいくつかです。\nQ:MoreLikeThisに対してTermVectorで柔軟にできる? A:TermVectorのAPIで統計情報が取れるので、それを使うことでさらなるデータの更新ができる。\nQ:TFとかの統計情報が必要なら、すべてインデックスをしたあとじゃないとちゃんとした値はとれないのでは? A:TermVectorで取得したものをどうやって使うか\nQ:TermVectorAPi\u0026hellip;聞こえなかった A:。。。\nElasticsearchを用いたはてなブックマークのトピック生成 / 株式会社はてな id:skozawa スライド:Elasticsearchを用いたはてなブックマークのトピック生成\nSignificant Terms Aggregationを活用してる話。 トピックページの生成のために、Significant Terms Aggregationをどうやって利用しているかなどのお話でした。\nトピックの集合の重複だったり、精度の判定方法とかいろいろ詳しく説明していただきました。\nQ:2011年と12年で11年の方が多いのは? A:ブックマークの件数に比例\nQ:Significant terms aggsのsizeはいくつをつかってますか? A:20を指定してます。\nQ:Yahooとかニュースをストップワードとしてますが、Yahoo自体のニュースに関してはどーしてるんですか? A:本文とタイトルから別々に作っていて、タイトルからは弾かれますが、本文から作った時に出てきます。\nはてなブックマークにおける Elasticsearch の運用まわりの話 / 株式会社はてな id:hagihala スライド:未定(おそらく公開される)\n体調が回復しきっていない中の発表ありがとうございました。 大幅に修正された資料が出てくるかなと。(ツイートできない数値がちらほらあったので)\nElasticsearchのクラスタの構成、どういった点で困ってたのでどういう調べ方をしたのか、どういった対処をしたのか。 どのあたりが次の課題かなどの話もありました。\n感想・反省点など 大阪、京都ともに30名弱の方の参加をしていただきました。ありがとうございました。 反省点としては、ハッシュタグを告知し忘れてました。。。\n勉強会はやはり、東京が異常に活発で、大阪や京都はまだそれほどでもないのかなぁとも。 大阪はエンジニアの人や会社も多い気がするんですが。私の告知の仕方もあるかもなぁと。 次回があれば、大阪での事例も聞きたいので、スピーカーをもっと探さないとなと。\n関連ブログなど 見つけたら、リンク追加していきます。\nElasticsearch勉強会 in 大阪/京都で発表しました \u0008* 「Elasticsearch での類似文書検索と More Like This Query API 詳解」というタイトルで発表しました その他(余談) 大阪のYahoo!さんは立地条件(梅田のすぐそば)がよく、\n夜景も綺麗でした。大阪城とかも見えてました。(夜景じゃないけど。。。)\n京都は祇園祭の真っ最中。\n水曜日はお休みをいただいて、観光してました。ちょっと日焼けが。。。 おかげで、リフレッシュできました。三十三間堂とか良かった:)\nあまり、関西に縁がない(大阪15年ぶり、京都10年ぶり)ので、 もっとユーザが増えて勉強会の機運が高まると嬉しいなと。:)\n","date":1437010857,"dir":"post/2015/","id":"dd6c32a722dc815273cd9ed8cd6c671b","lang":"ja","lastmod":1437010857,"permalink":"https://blog.johtani.info/blog/2015/07/16/kansai-1st-elasticsearch-jp/","publishdate":"2015-07-16T10:40:57+09:00","summary":"東京以外での勉強会の第2弾として、関西で勉強会を開催してきました。 Elasticsearch勉強会 in 大阪 Elasticsearch勉強会 in 京","tags":["勉強会","elasticsearch"],"title":"大阪と京都でElasticsearch勉強会を開催しました。 #elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:The Great Mapping Refactoring\nElasticsearchのユーザの悩みの最も大きなものの一つは、 タイプとフィールドのマッピングに関する多義性です。 この多義性は、インデックス時の例外やクエリ時の例外、 正しくない結果、リクエストからリクエストへ変化する結果、 また、インデックスの故障やデータのロスを結果として引き起こします。\nElasticsearchをより強固で予測可能な振る舞いをするようにする作業において、 フィールドやタイプのマッピングをより厳格でより信頼性を高くするかといったことに 多くの変更を費やしました。 多くのケースで、Elasticsearch v2.0で新しいインデックスを作るときにのみ、 新しいルールを強制し、これまでのインデックスに関しては後方互換性を保つようにします。\nしかし、幾つかのケースでは、先ほど説明したようなフィールドマッピングの コンフリクトなどが存在するため、それらを利用できないです。\nコンフリクトしたフィールドのマッピングをもつインデックスはElasticsearch v2.0にはアップグレードできません。\nもし、これらのインデックスのデータが必要ない場合は、インデックスを消せばいいです。 そうでない場合はマッピングを正しくして再度インデックスする必要があるでしょう。\nマッピングを正しく変更することは、私たちが簡単に決めることではありません。 ここからは、現在ある問題点と、私たちがどのように実装して解決したかについて説明します。\nフィールドマッピングのコンフリクト あいまいなフィールドのルックアップ タイプのメタフィールド アナライザ設定 index_nameとpath 同期的なマッピングの更新 マッピングの削除 2.0のための準備 フィールドマッピングのコンフリクト これまで、わたしたちはドキュメントのタイプは「データベースのテーブルのようなもの」と説明していました。 タイプの目的を説明する簡単な方法だったからです。 しかし、残念なことにこれは、真実ではありません。 「同じ」インデックスの「異なるタイプ」にある同じ名前のフィールドは、 内部的に、Luceneのフィールド名が同じものになります。\nもしerrorフィールドとして、ドキュメントタイプがapacheのものには数値(integer)を、 ドキュメントタイプがnginxのものには文字列(string)を割り当てた場合、 Elasticsearchは同じLuceneのフィールドに数値と文字列のデータをもつことになります。 このフィールドに対して、検索やaggregationを行う場合、おかしな結果を受け取るか、例外が帰ってくるか、 インデックスが破損することになります。\nこの問題を解決するために、まず、ドキュメントタイプの名前をフィールドの名前の前に追加することを考えました。 各フィールドは完全に別のものとなります。 このアプローチの利点はドキュメントタイプが実際のテーブルのようになることです。\nしかし、この方法には多くの欠点があります。\nフィールドは常に、他のタイプとは異なるものであると区別するためもしくは、複数のタイプに同じフィールドのクエリのためにワイルドカードをつけた場合、 ドキュメントタイプを前につける必要があります。 複数のドキュメントタイプに対して同じフィールド名で検索する場合、クエリを個別に発行しなければならなく遅くなります。 多くの検索で、既存の多くのクエリを壊してしまうために、単純なmatchやtermクエリの代わりに、multi-fieldクエリを使う必要があります。 圧縮の効率の悪さから、ヒープ利用量、ディスク使用量、I/Oなどが、増加します。 複数のドキュメントタイプに対するaggregationは、global ordinalの利点を利用できなくなるために、遅くなり、メモリの使用量も増えます。 解決方法 最終的に、同じインデックスの同じ名前を持つ全てのフィールドは、同じマッピングを持つ必要があるというルールを採用することに決めました。 ただ、copy_toやenabledのようなパラメータはタイプごとに指定することができるようになっています。 これにより、データの破損、クエリ時の例外そして、おかしな結果が発生する問題を防ぎます。 クエリとaggregationは現在でも高速なままで、圧縮率を最大化し、ヒープ使用量やディスク使用率の低減させます。\nこの解決方法の欠点は、個別のテーブルとしてタイプを扱いたいユーザが彼らの考え方を変える必要があるということです。 これは、思ったよりも問題ではありません。 実際には、多くのフィールド名はデータの明確なタイプを表現しています。 created_dateは常に、日付ですし、number_of_hitsフィールドはいつも数値です。 フィールドマッピングがコンフリクトしているユーザはデータを失ったり、おかしなデータを受け取ったり、データを欠損させています。 ベストプラクティスにユーザが従っているかどうかによらず、インデックス時に正しい振る舞いを強制することが現在の違いです。\nユーザの多くがコンフリクトしていないフィールドマッピングをもっていれば、 コンフリクトが起きた場合、技術がこれらのシチュエーションを扱うことが可能になると思いませんか? そこにはいくつかの解決方法があります。\nタイプの代わりにインデックスを別々に 最も簡単な解決方法です。インデックスを別々のインデックスとし、実際のデータベーステーブルのようにします。 インデックスをまたいだ検索はタイプをまたいだ検索のように動作しますし、 ソートやaggregationも同じデータタイプへのクエリのように動作します。これまでと同じ制限です。\nコンフリクトしたフィールドの名前の変更 コンフリクトがごくわずかな場合、(Logstashやアプリケーションで使っているものも一緒に)よりわかりやすいフィールド名に変更することで解決できます。 例えば、2つのerrorフィールドがあった場合に、error_codeとerror_messageに変更します。\ncopy_toもしくはmulti-fieldsを利用 異なるドキュメントタイプのフィールドは別々のcopy_toを設定できます。 元のerrorフィールドはindexの設定にnoが設定してあり、全てのドキュメントタイプで無効化されていますが、 特定のタイプだけ、errorフィールドの値を数値のerror_codeフィールドにコピーすることができます。\nPUT my_index/_mapping/mapping_one { \u0026#34;properties\u0026#34;: { \u0026#34;error\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;no\u0026#34;, \u0026#34;copy_to\u0026#34;: \u0026#34;error_code\u0026#34; }, \u0026#34;error_code\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34; } } } 他のタイプでは文字列のerror_messageにコピーします。\nPUT my_index/_mapping/mapping_two { \u0026#34;properties\u0026#34;: { \u0026#34;error\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;no\u0026#34;, \u0026#34;copy_to\u0026#34;: \u0026#34;error_message\u0026#34; }, \u0026#34;error_message\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } } 同様の解決方法としてmulti-fieldも使えます。\n各データタイプに対してネストしたフィールドに ときどき、Elasticsearchに送ったドキュメントやドキュメントがもっているフィールドを制御できない場合があります。 部分的なコンフリクトに加え、闇雲に、ユーザが送ってきたフィールドを受け入れると、マッピングが肥大化します。 タイムスタンプやIPアドレスをフィールド名に使うようなドキュメントがあると考えてください。\nnested フィールドにすることで、str_val、int_val、date_valというような各データタイプを利用できます。\nこのアプローチによって、次のドキュメントは\n{ \u0026#34;message\u0026#34;: \u0026#34;some string\u0026#34;, \u0026#34;count\u0026#34;: 1, \u0026#34;date\u0026#34;: \u0026#34;2015-06-01\u0026#34; } アプリケーションによって、次のようにフォーマットしなおす必要があります。\n{ \u0026#34;data\u0026#34;: [ {\u0026#34;key\u0026#34;: \u0026#34;message\u0026#34;, \u0026#34;str_val\u0026#34;: \u0026#34;some_string\u0026#34; }, {\u0026#34;key\u0026#34;: \u0026#34;count\u0026#34;, \u0026#34;int_val\u0026#34;: 1 }, {\u0026#34;key\u0026#34;: \u0026#34;date\u0026#34;, \u0026#34;date_val\u0026#34;: \u0026#34;2015-06-01\u0026#34; } ] } この解決方法は、アプリケーションサイドでより多くの作業が必要ですが、コンフリクトの問題とマッピングの肥大化の問題を同時に解決します。\nあいまいなフィールドのルックアップ 現在、フィールドの指定には\u0026quot;short name\u0026quot;、フルパス、ドキュメントタイプを前につけたフルパスが利用できます。 これらのオプションがあいまいさをもたらしています。 サンプルとして次のマッピングをご覧ください。\n{ \u0026#34;mappings\u0026#34;: { \u0026#34;user\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;title\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, \u0026#34;blog\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;title\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;user\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;fields\u0026#34;: { \u0026#34;title\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } } } } } } titleはuser.title、blog.title、blog.user.titleのどれでしょう? user.titleはuser.titleまたはblog.user.titleのどちらでしょう? 答えは「場合によります。」です。Elasticsearchが最初に見つけたものになります。 フィールドはリクエストごとに変わるため、各ノードでマッピングがどのようにシリアライズされたかに依存します。\n2.0では、フィールドを指定する時に、ドキュメントタイプを除いたフルパス名を使用するべきでしょう。\nuser.titleは、blogタイプのuser.titleを意味します。 titleは、userとblogタイプのtitleフィールドを意味します。 *titleはuser.titleとtitleフィールドの両方にマッチします。 userタイプのtitleフィールドとblogタイプのtitleの違いはどのように指定するのでしょう?\n指定できません。フィールドマッピングのコンフリクトで説明した変更により、 titleフィールドは両方のタイプで同じフィールドになります。 本質的にtitleと呼ばれる1つのフィールドになります。\nuser.やblog.のようなタイプのプレフィックスはタイプを指定することによるフィルタリングで効果があります。 クエリのblog.titleフィールドはblogタイプのドキュメントだけを検索し、userタイプのドキュメントを検索しません。 このシンタックスは誤解を招きやすいです。なぜなら、いつでも動作するわけではないからです。 aggregationやsuggestionはすべてのタイプに関する結果を含みます。 この利用のため、上記の例のあいまいさがあるので、タイプのプレフィックスはサポートしません。\n重要 short nameやタイププレフィックスを利用したpercolatorは更新する必要があります。\nタイプのメタフィールド すべてのタイプはメタフィールドを持っています。_id、_index、_routing、_parent、_timestampなどです。 これらのほとんどはindex、store、pathのような幾つかの設定をサポートしています。 これらの設定について次のようにシンプルにしました。\n_idと_typeは変更不可 _indexは、ドキュメントのもつインデックスを保存するためにenabled _routingはrequiredのみを指定 _sizeはenabledのみ _timestampはデフォルトで保存される _boostと_analyzerは廃止。古いインデックスのものは無視される ドキュメントのフィールドから_idと_routingと_timestampの値を抽出することができました。 この機能は廃止されます。これは、ドキュメントのパースとコンフリクトを起こすためです。 代わりに、これらの値はURLもしくはquery stringで指定可能です。\n_boostと_analyzerフィールドは例外で、すでにあるメタフィールドの設定は古いインデックスのものが採用されます。\nアナライザ設定 これまで、indexとsearchのアナライザがインデックス、タイプ、フィールド、ドキュメント(_analyzerフィールドで)の それぞれのレベルで指定可能でした。 同じフィールドに対して異なるanalysis chainの組み合わせができることにより、おかしな関連度を引き起こしていました。 フィールドマッピングのコンフリクトを解消することに加え、アナライザの設定も簡略化します。\nAnalyzedな文字列フィールドは、analyzer設定とsearch_analyzer設定(analyzer設定の値をデフォルトとする)を指定できます。index_analyzer設定はanalyzerとなります。 複数のタイプで同じ名前のフィールドがある場合、フィールドはすべて、同じアナライザの設定を持たなければなりません。 タイプレベルのデフォルト設定のanalyzer、index_analyzer、search_analyzer設定は廃止されます。 デフォルトアナライザはインデックスごとにインデックスのanalysis設定で設定します。これらはdefaultもしくはdefault_searchという名前で設定します。 ドキュメントごとの_analyzerフィールドはサポートしません。既存のインデックスのものは無視されます。 index_nameとpath index_nameとpath設定は(Elasticsearch v1.0.0から利用できる)copy_toによって置き換わりました。 既存のインデックスについてはこれらは機能しますが、新しいインデックスでは指定できません。\n同期的なマッピングの更新 現在、これまで存在していないフィールドを含むドキュメントをインデキシングするとき、 フィールドはローカルのマッピングに追加され、それから、マスターに変更(新しいマッピングをすべてのシャードに適用する更新)が送信されていました。 同時に2つのシャードに同じフィールドを追加することができます。 また、そのとき、異なる2つのマッピングがある可能性があります。 1つはdoubleでもう1つはlongだったり、stringとdateだったりと。\nこのような場合、マスターに最初に届いたマッピングが採用されます。 しかし、「負けた」マッピングをもつシャードでは、すでに異なるデータのタイプを利用しているため、 これを利用し続けます。 そのご、ノードをリスタートしたときに、シャードが別のノードに移動し、マスターにあるマッピングを適用します。 このとき、インデックスが破損したりデータを失ったりします。\nこれを防ぐために、シャードはインデキシングを続ける前に、新しいマッピングがマスターによって採用されるかどうかを待つようになりました。 これはすべてのマッピングが安全に更新されます。 新しいフィールドをもっているドキュメントをインデキシングすると、前よりも処理が遅くなるでしょう。 受け入れられることを待つ必要があるためです。 しかし、クラスタの状態の更新処理のスピードが次の2つの新しい機能によって大きく改善されています。\nクラスタ状態の差分:可能であれば、クラスタの状態の変更はクラスタ状態全体の変更ではなく、部分的なものとする。 シャードへのリクエストの非同期化:シャードアロケーション処理中に、マスタノードは、 割り当てられていないシャードのコピーの日付が最新のものを持っているかを見つけるために、リクエストをデータノードに対して送信します。 ここで、クラスタ状態を変更する呼び出しがブロッキングで行われていました。v1.6.0から、このリクエストはバックグラウンドで非同期で実行されます。 これにより、マッピング更新のようなペンディングタスクをより早く処理できるようになります。 マッピングの削除 (そのタイプのドキュメントがある場合)タイプマッピングを削除できないようにします。 マッピングを削除した後に、削除されたフィールドの情報は、Luceneレベルでは存在し続け、 もし、後から同じ名前のフィールドが追加されたときにインデックスの破損を引き起こします。 そのようなマッピングは残しておくか、新しいインデックスに再インデックスすることができます。\n2.0のための準備 マッピングがコンフリクトしているかどうかを決めることは、手動で行うには慎重に行う必要があります。 私たちは、Elasticsearch Migration Pluginを提供します。 これは、2.0で非推奨になったり廃止された機能を利用しているかどうかを見つけるために役に立つでしょう。\nもし、コンフリクトしたマッピングを持っている場合、 正しいマッピングを持つ新しいインデックスにデータを再インデックスするか、 必要ないなら削除します。 これらのコンフリクトを解決しない限り2.0にはアップグレードできないでしょう。\n","date":1436346691,"dir":"post/2015/","id":"ee4ff9e4e8a1948795e26af2f3f8a30f","lang":"ja","lastmod":1436346691,"permalink":"https://blog.johtani.info/blog/2015/07/08/great-mapping-refactoring-ja/","publishdate":"2015-07-08T18:11:31+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:The Great Mapping Refactoring Elasticsearchのユーザの悩みの最も大きなものの一つは、 タイプと","tags":["elasticsearch"],"title":"Mappingのすばらしいリファクタリング(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 2.0.0.beta1 coming soon!\nElasticsearch 2.0.0.beta1のリリースの準備をしています。 これは、Lucene 5.2.1に含まれる多くの改善が利用できるようになります。 このリリースに関するいくつかの機能は次のようなものです。\nPipeline Aggregations 差分や移動平均、他のAggregationsの結果に対する series arithmeticのようなaggregationが利用可能になります。 この機能は、これまでは、クライアントサイドで実行する必要がありました。 しかし、この計算をより強力な解析クエリを構築してElasticsearchで 実行することができるようになります。 クライアントのコードをより簡潔にすることができます。 これにより、予測解析や異常検知のようなことができるようになります。\nQuery/Filter merging Filterはなくなります。全てのフィルタは、クエリになります。 クエリコンテキストで利用されると、効率的に関連度スコアを計算し、 フィルタコンテキストで利用されると、単に、 マッチしていないドキュメントを除外する(今のフィルタのようなもの)だけです この変更は、クエリ実行が自動的に、より効率的な順番で実行されるように 最適化されることを意味します。 例えば、フレーズやgeoクエリのような遅いクエリは まず、近似フェーズを実行し、それから、より遅い実際のフェーズが 結果に対して行われます。 フィルタコンテキストにおいて、頻繁に利用される条件は自動的にキャッシュされます。\nConfigurable store compression index.codec設定により、高速化のためのLZ4圧縮(default)か インデックスサイズを小さくするためのDEFLATE(best_compression)を 選択できます。これは、ロギングでとくに役に立ちます。 これにより、古いインデックスオプティマイズする前にbest_compressionに 変更できます。\nこれらに関するブログ記事がすぐに公開されるでしょう。\nPerformance and resilience 以降では、新しいメジャーリリースに関して簡単に紹介します。 2.0の変更の多くは内部の機能に関するものであり、 直接ユーザに関連するわけではないからです。\n新しいメジャーバージョンのテーマは、パフォーマンス、安定性、 堅牢性、予測可能性、そして使い勝手の良さです。\n物事が予測した通りに動作する 何か問題があった場合に、Elasticsearchから役立つフィードバックがある ローレベルの設定を扱う必要はなく、Elasticsearchが良い設定を決定する これらに加え、データがより安全に これらの目標は完全ではありません。 まだ、多くの改善があります。しかし、2.xブランチで、 すでに500コミットを超える大きな改善が実施されています。\non-diskの doc valuesをデフォルトで利用(これまではfielddata)。 ヒープ使用量を減らして、スケーラビリティを向上 セグメントマージ処理中のメモリ使用量の削減 normsの圧縮率の改善。ヒープスペースを利用している大きな処理のひとつだったため。 全てのリクエストの後に、transaction logをfsyncすることで、デフォルトで耐久性を向上 全てのファイル変更をアトミックに(部分的なファイルの書き出しはなし) マージを自動で制限 フレーズクエリやスパンクエリを高速化 フィルタキャッシュをより効率化するための圧縮されたビットセット クラスタ状態の差分更新 構造化されたJSON形式の例外 よりきめ細かいLuceneのメモリレポート デフォルトではlocalhostにのみバインド。開発のノードが他のクラスタにジョインするのを防ぐ parent/childのクエリ実行最適化のためにリライト Java Security Managerで必要最小限なパーミッションで実行 全てのコアなプラグインをelasticsearchリポジトリに移行し、Elasticsearchのバージョンに同期してリリースされる予定 アップグレード前に メジャーバージョンのアップグレードは問題のあるものを一掃する機会を与えてくれます。 できる限り、これらの変更をアップグレードするために、簡単な方法を提供しようとしています。 しかし、Elasticsearch 2.0にアップグレードする前に、必要な処理が2つあります。\n1つ目は、フィールドとタイプマッピングに関することです。 mapping APIは、現在、それほど厳密ではありません。 内蔵された保護機構を提供する代わりに、ユーザがベストプラクティスを知っていると信頼していました。 2.0では、mappingはより厳密で安全ですが、いくつかの変更では、後方互換性を保っていません。 詳細についてはThe Great Mapping Recatoringをごらんください。\n2つ目はElasticsearch 0.20以前のユーザに関する変更です。 これは、Lucene 3.xを使っています。 Elasticsearch 2.xはLucene 5をベースにしています。 Lucene 5はLucene 4.xによって作成されたインデックスの読み込みはサポートしていますが、 Lucene 3.xに関してはサポートしていません。\nElasticsearch 0.20以前のバージョンによって生成されたインデックスを持っている場合、 Elasticsearch 2.xのクラスタをスタートすることはできません。 これらの古いインデックスを削除するか、Elaticsearch 1.6.0以上に含まれている upgrade APIを使用してアップグレードする必要があります。\nupgrade APIの実行は2つのジョブを実行します。\n古いLuceneフォーマットのセグメントを最新のフォーマットで書き換えます Elasticsearch 2.xによって読み込めるようという印をインデックスに追加します 全てのセグメントを最新バージョンにアップグレードするのも良い案ですが、 アップグレード前に必要な処理を最小限に抑えることも可能です。 (Lucene 3.xのセグメントだけをアップグレード) その場合は、only_ancient_segmentsパラメータを指定します。\nElasticsearch Migration Plugin Elasticsearch 2.0 に移行する前に、インデックスがアップグレードが必要なのか、 ほかになにかするべきことがあるのかをチェックする助けになる Elasticsearch Migration Pluginをリリースしました。\nまず、プラグインをインストールします\n./bin/plugin -i elastic/elasticsearch-migration プラグインのインストール後はノードのリスタートは必要ありません。\n以下のリンクをブラウザで開きます。\nhttp://localhost:9200/_plugin/migration\n(localhost:9200はインストールしたホスト名に変更してください。)\nMigration pluginに関してバグやご意見がある場合は、GitHubのIssueにお願いします。\n","date":1436250300,"dir":"post/2015/","id":"f887e1aabf801e351bfb39698f208af1","lang":"ja","lastmod":1436250300,"permalink":"https://blog.johtani.info/blog/2015/07/07/elasticsearch-2-dot-0-0-dot-beta1-coming-soon-ja/","publishdate":"2015-07-07T15:25:00+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 2.0.0.beta1 coming soon! Elasticsearch 2.0.0.beta1のリリースの準備をしています。","tags":["elasticsearch"],"title":"Elasticsearch 2.0.0.beta1リリース間近(日本語訳)"},{"contents":"4ヶ月前に、Found joined our team at Elasticをアナウンスしました。 Foundの素晴らしいチームと一緒に仕事をしていますが、彼らによって、より素晴らしい hosted Elasticsearchを提供することになりました。\n私たちがともに密接に働くことにより、本日(2015/7/1)、 新しい2つのFoundを提供することになりました。 Found StandardはこれまでのFoundの機能に加え、さらに低価格を提供します。 Found Premiumは、SLAサポートと、ShieldやWatcherを将来Found上で提供します。\nFound Standard Foundは素晴らしいです。専用のElasticsearchクラスタ、簡単なスケール、 ビルトインのセキュリティそして、時間単位での課金などを持っています。 私たちは、hosted Elasticsearchを探している方に、 Foundが適したソリューションであると思っていますし、 すべての方に利用できて手頃な価格であるということを確信したいと思っています。\n本日(2015/07/01)からFoundの価格をかなり低価格にし、 月額50ドル以下でhosted Elasticsearchを簡単に試してもらえるようにしました。\n価格を下げることは正しい重要なステップですが、 Foundを利用している全ての人に、より良い経験を持っていただきたいと考えています。 低価格化と一緒に、free backupsとbuilt in SSDもFoundで提供を始めることになります。\nFoundの重要な特徴の一つが、高可用性のために、クラスタをいくつのデータセンターに持つかを 選択できることです。 データは重要です。これが正しい選択でユーザの助けになると考えています。 これにより、私たちの価格は、複数のデータセンターにより安価に配置することができます。\nまた、KibanaもElasticsearchのデータを可視化する素晴らしい方法だと考えています。 Kibana 4が最新バージョンですが、 これは、サーバサイドコンポーネントを持っています。 これは、サービスとしてこれを提供するために、追加の料金がかかることを意味します。 Foundチームが築いた素晴らしい基盤とKibanaチームの努力により、 hosted Elasticsearchクラスタで無料のKibana 4を7月15日より提供することになりました。\nFound Premium また、私たちは、オープンソースプロダクトに関してサブスクリプションを提供していますが、 Found Standardに対しても提供することになりました。 これが、Found Premiumです。\nフォーラムベースのサポートよりもSLAベースのサポートを望んでいる場合、 プロダクトを開発しているチームからのサポートを受けることができるオプションを 提供し始めました。 クリティカルなイベントを持っていたり、私たちのプロダクトに関する 問題を予測するためのベストなヘルプやガイダンス、アドバイスを探しているような場合にサポートします。\nさらに近い将来、サブスクリプションの一部として、Shield(Elasticasearchのセキュリティプラグイン)やWatcher(アラーティングプラグイン)が利用できるようになります。\n私たちのチームがともに働き、多くのことを可能にし、すばらしい仕事をユーザに提供したかを 将来も楽しみです。 私は非常に誇りに思っていますし、気に入っていただけたらと思っています。 ぜひ、7/15のWebnarに参加してくわしい話を聞いていただき、疑問を解消してください。\n","date":1436250000,"dir":"post/2015/","id":"9cc2a0b6c8be1405cddcdeb4487c59fe","lang":"ja","lastmod":1436250000,"permalink":"https://blog.johtani.info/blog/2015/07/07/we-just-made-found-more-awesome-ja/","publishdate":"2015-07-07T15:20:00+09:00","summary":"4ヶ月前に、Found joined our team at Elasticをアナウンスしました。 Foundの素晴らしいチームと一緒に仕事をしていますが、彼らによって、より","tags":["elasticsearch","found.no"],"title":"さらに進化したFound(日本語訳)"},{"contents":"JustTechTalk#02 形態素解析のあれやこれや@ジャストシステム\nに参加してきました。 ジャストシステムさんの形態素解析器JMATの話とKagome、Janome、Kuromoji.js、ssslaの開発者の パネルディスカッションでした。\nということで、いつものメモです。\nジャストシステムの形態素解析その2(機械学習編) JMATの話\n前回は辞書の話 今回は学習の話 教師あり/教師なし\nJMATは教師あり 教師なしは研究段階 ラティス構造を辞書ベースで構築して、コストの総和が最小の経路を求める\n連接、単語生成とか。 学習は3フェーズ\nベース、能動、部分アノテーション ベース 300万文のコーパスから1万文のみを利用(なぜ?今から説明) 64GBマシン買ってみたけど、複数実験するには追いつかない オンライン学習がメジャーでない時代に作り始めたので、つかってない CRF学習器を改善 結果として50万文くらいで精度が良くなる 辞書チームからNGがでて、方向転換 方向転換した結果が3つのフェーズらしい ピタジョブに採用? 疑問 \u0008* JMATって、Webの検索の前処理とか分類とかに主に利用するのかな?\nATOKでもこのノウハウって利用してるんかな? 辞書もあるらしいけど、辞書更新されると学習器のデータとかどーなるんだろ? 形態素解析器の実装言語Talkについて kuromoji.jsの@takuya_aさん\nTyped Arrayサポートが高速にできてる理由でもあるらしい Kagomeの@ikawahaさん\nGoはいろいろないらしい Janomeの@moco_betaさん\nsssla(茶筌のRuby clone)\nなんで作ったの?\n形態素解析のライブラリ「解析部分」はNLPのHelloWorldだから なんで、その言語?\nPython 3系は文字列とバイト配列の扱いがすごく楽! その言語で困った点は?\nGoだと、辞書を内包するのが大変 JSは苦労したところしかない(1hくらいしゃべれるぞ!)。基本的なデータ構造とかもない Pythonはパフォーマンスを考えないと Ruby(1.6だったので)もパフォーマンスが その言語を開発するときに必須のものは?\nGoはとくにない。エディタはどれでもOK browserifyが便利 \u0008* ほかの人たちの言語をdisってください * JSは論外。Pythonのコードフォーマッターが揺れるのが。。。Rubyはバージョンが。。。 * Goはブラウザで動かない。Pythonもブラウザで動かない。Rubyも(ry * ほかのは触ったことないので。。。 * Pythonは2.xか3.xか決めてくれ!\nなんで、Kuromojiベースなの? Java読みやすいから。 MeCabとKuromojiの違いは? 未知語の処理が結構違う 感想 きれいなロビーで良かったのですが、マイクがあると嬉しかったかもしれません。 前回の辞書の話も聞いてみたかったかも。\n","date":1436147341,"dir":"post/2015/","id":"18b7998a871950ebc36c415a53630477","lang":"ja","lastmod":1436147341,"permalink":"https://blog.johtani.info/blog/2015/07/06/attend-justsystem-techtalk-no2/","publishdate":"2015-07-06T10:49:01+09:00","summary":"JustTechTalk#02 形態素解析のあれやこれや@ジャストシステム に参加してきました。 ジャストシステムさんの形態素解析器JMATの話とKagome、Janome、","tags":["勉強会"],"title":"JustTechTalk#02 形態素解析のあれやこれや@ジャストシステムに参加しました。"},{"contents":"ひさびさに、勉強会メモ。 Hatena Engineer Seminar #5 @ Tokyoに当選したので行ってきました。\nいつもは近寄らないオシャレな街をドキドキしながら行ってきました。\nということで、簡単なメモです。\nはてなブックマーク全文検索の精度改善 id:takuya-a 問題:検索精度がよくない 京都で検索 → 「ポーランドの京都」「京都大学のまるまる教授」のようなもんがヒット 京都っぽいエントリが出て欲しい。 京都っぽい??? 問題点をブレイクダウン 課題 クエリ考えるの大変だよね 順序が新着順なのが辛い 適合率と再現率の両立 そして(ドラムロール)、できました!(さすが)\nアイデア:はてブのタグを利用する。 関連キーワードを抽出して、クエリ拡張する。\n関連キーワードとは? タグ検索する 検索にヒットしたTerm Vectorsを取得 特徴語をTop25件取得 もっともスコアが高いタームを特徴語とする 英語のストップワードとかが問題点となってたり。 →Dynamic stop word listというのを利用して排除(IDF、RIDF、Gain) 今後の課題 再現率の向上 解析用のフィールド・辞書を追加(精度向上や解析ミスなど) トークに出てきた機能など トークに出てきたElasticsearchの機能については、こんなツイートをしてたので、参考にしてもらえれば。\nこれのkuromoji_stemmerを使ってるっぽい? #hatenatech / elastic/elasticsearch-analysis-kuromoji - https://t.co/3F2sBYXLPH\n\u0026mdash; Jun Ohtani (@johtani) 2015, 6月 16 #hatenatech Term Vectors APIのドキュメントはこちら - https://t.co/HhBmTDr46i\n\u0026mdash; Jun Ohtani (@johtani) 2015, 6月 16 #hatenatech min_score - https://t.co/Sc0exzJRC1\n\u0026mdash; Jun Ohtani (@johtani) 2015, 6月 16 個人的な疑問 Q:クエリにヒットするタグがそもそもなかったら?\nはてなブックマークに基づく関連記事レコメンドエンジンの開発 id:skozawa 課題:一部のエントリに対して関連記事が出ない タグがない記事について関連エントリが出ない=既存はタグを利用している 例:レシピで考える\n現行システム ユーザがつけたタグ情報を利用してMoreLikeThisで計算 新規システム 類似記事検索 特徴語の抽出 特徴語を分類 関連記事検索 関連記事をスコアリング 個人的な疑問 Q:毎回計算してるのかな?記事登録とかされたタイミングでやってるのかな? Q:Termの精度などどうなんだろ?\n『BrandSafe はてな』のアドベリフィケーションのしくみ id:tarao BrandSafeはてな:とか。 広告の配信先をフィルタリング\n複数の素朴なフィルタの組み合わせ→AdaBoost\n個人的な疑問 Q:海外とかもいけるのかな?\nまとめと感想 ということで、簡単なメモでした。ピザごちそうさまでした! 聞いてて少し思ったのは、データ量があるサイトだからうまくいく手法だというのもあるんだろうなというところでした。 あとは、クエリを暗に改善するのとは別に、サジェスト的に表示するのにも使えたりするかも?と思ってみたり。 できるかどうかはわからないですが。。。\nElasticsearchをいろいろと活用してもらってるのがわかって、楽しい勉強会でした。 もっともっといろんなところで宣伝してくださいw\n今日の勉強会を聞いて、俄然、京都・大阪でElasticsearch勉強会を開催したい気になってきました。 特に大阪に知り合いがいないので、だれか紹介してもらえると嬉しいです。 お待ちしてます。\n","date":1434468093,"dir":"post/2015/","id":"ddab6357ff522c0c956ebd7669e83454","lang":"ja","lastmod":1434468093,"permalink":"https://blog.johtani.info/blog/2015/06/17/attend-hatena-engineer-seminar-5/","publishdate":"2015-06-17T00:21:33+09:00","summary":"ひさびさに、勉強会メモ。 Hatena Engineer Seminar #5 @ Tokyoに当選したので行ってきました。 いつもは近寄らないオシャレな街をドキドキしながら行ってきました。 と","tags":["勉強会"],"title":"Hatena Engineer Seminar #5 @ Tokyoに参加しました。 #hatenatech"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 1.6.0 released\n本日(6/9)、Lucene 4.10.4ベースのElasticsearch 1.6.0をリリースしました。 このリリースはElasticsearchの最新の安定バージョンとなります。 また、素晴らしい新機能がいくつか追加されています。\nsynced flushによるリスタートの高速化 \u0008* シャード配置は保留中のタスクをブロックしない レスポンスボディのJSONのフィルタリング 共有ファイルシステムリポジトリに対するセキュリティフィックス 古いインデックスのためのUpgrade API Kibanaユーザのためのハイライトの強化 Windowsユーザのためのmlockall より詳細なスクリプト設定 すべての変更リストとダウンロードはこちらをごらんください。\nsynced flushによるリスタートの高速化 1.6.0より前のバージョンでは、メンテナンスやローリングアップグレード時の ノードの再起動で、必要であるかどうかに関わらず、多くの場合、 ノードのすべてのシャードのすべてのデータを再度コピーする必要がありました。 この新しいsynced flush機能により、 sync-flushされたインデックスに対して、既存のデータを再利用し、 より早くクラスタを正常な状態にすることができるようにします。\nここで、この変更以前にどのように動いていたかを説明します。 すでにあるレプリカシャードは、ノードがリスタートした後に、 プライマリから復元するときに、 最初のステップはプライマリにあるセグメントとレプリカにあるセグメントを 比較することです。そして、セグメントに違いがあった場合にコピーされます。 問題は、セグメントプライマリのセグメントのマージと レプリカのセグメントのマージが別々に起こっており、 各シャードのセグメントが完全に異なるが、 それらが同じデータを持っているという点です。\n新しいsynced-flush機能では、sync_idがプライマリと レプリカシャードに、シャードのコンテンツが同一であるという判別するために、 書き込まれます。これは、リカバリがセグメントの比較のステップを スキップできることを意味します。 リカバリのスピードを高速にします。\nsynced flushはアイドル状態のインデックスで自動的に実行されます。 直前の5分間でデータが登録、更新削除されていないインデックスに対してです。 これは、ロギングのユースケースで特に役に立ちます。 機能のインデックスはインデキシングがストップしたあとの5分で自動的に syncされるでしょう。\nノードのリスタートやクラスタのリスタートが必要で、 自動的に発生するsyncを待てない場合は次のようなことが可能です。\nインデキシングを停止(実行中のリクエストが停止するのも待つ) シャードのアロケーションを停止 synced-flushリクエストの発行 ノードのリスタート シャードのアロケーションの再開 クラスタの状態がグリーンになるまで待つ インデキシングの再開 NOTE: \u0026ldquo;シャードのアロケーションを停止\u0026quot;のステップが必要です。 これがない場合、Elasticsearchはノードの再起動が始まると、 異なるノードにシャードの再配置を始めます。 これは、新しいノードにシャードデータの全てをコピーする必要があります。\nドキュメントのインデキシング、更新、削除のあとに最初のフラッシュが 発生したときに、 シャードのsync_idが自動的に無効化されます。 詳細については#11336と#11179をごらんください。\nシャード配置は保留中のタスクをブロックしない 多数のノードやインデックスを持っているユーザは クラスタ全体のリスタートのあとのシャードのリカバリで、 長い間、リカバリが止まって見えることに気づいたかもしれません。 これらのリカバリが止まって見える間は、クラスタ設定の更新のような軽微なアクションでさえ、 例外が発生したり、その設定が反映されるまでに長時間かかるといったことが起きていました。 この問題の兆候は保留中のタスクのキューが大きくなることです。\nこれらの遅延の原因はシャードの配置のプロセスにあります。 配置されるべきシャードのコピーを 持っているのがどのノードかを全てのデータノードに聞きます。 多くのシャードや遅いディスクを持ったデータノードは 反応するのに時間がかかります。 特に、シャードのリカバリがすでにI/Oを利用しているような時です。 このバージョン以前のものは、シャード情報のためのリクエストを 同期的に処理していました。 クラスタ状態の更新はアロケーションプロセスを続けるために 必要な情報を待っている間、ブロックされます。\n#11262での変更は この情報のためのリクエストを非同期にします。 クラスタ状態の更新はこのタスクによってブロックされません。 これは、保留中のタスクがより早く処理でき、 クラスタが変更に対してより早く反応できます。 処理中のshard infoリクエストの数は number_of_in_flight_fetchキーとしてcluster-health APIで取得できます。\nさらに、シャードがある理由で復旧に失敗すると、 クラスタは、シャードのリカバリが成功するまで、同じノードに対して シャードをアロケーションしないようにします。\nレスポンスボディのJSONのフィルタリング Elasticsearchは全ての情報を返します。 例えば、検索リクエストは_index、_type、_id、 _score、_sourceを返します。 しかし、全ての情報が必要でない場合があります。 また、これらのデータを遅いネットワークで転送することは 遅延の原因となります。\nユーザはこの検索メタデータを無効にするための特殊な設定を 行ったり、他のAPIのレスポンスのフォーマットを コントロールするための設定があります。 #10980の変更で、任意のレスポンスボディのJSONに対して、 必要な要素だけを取得する機能が追加されました。 filter_pathパラメータを使用します。\n例えば、検索リクエストからはtotal数と、各要素のhitsの配列を欲しい場合、 次のように指定します。\nGET _search?filter_path=hits.total,hits.hits nodes-info APIから各ノードのhttp_addressだけを取得したい場合は、 ノード名の部分にワイルドカード(*)を使用します。\nGET _nodes?filter_path=nodes.*.http_address 単一の*がJSON階層の1つの階層に対しての ワイルドカードとして機能します。 2つの**は複数階層に対してとなります。 複数のフィルタはカンマ区切りで指定可能です。 詳細についてResponse filteringをごらんください。\n共有ファイルシステムリポジトリに対するセキュリティフィックス 本リリースはsnapshot-restoreで使われる 共有ファイルシステムリポジトリに関するセキュリティ強化の変更が含まれます。 現在、Elasticsearchのユーザは、Elasticsearchプロセスによって書き込み可能 任意のディレクトリに.snapshotファイルを書き込むことができます。 #11284の変更で、リポジトリのために使用できるディレクトリを 強制的に指定できるようになりました。 適切なディレクトリがconfig/elasticsearch.yml設定ファイルの path.repoに指定される必要があります。\n次のように設定されたElasticsearchインスタンスはこのセキュリティ問題に対して影響を受けにくいです。\nrootではなくelasticsearchユーザとしてElasticsearchを実行 elasticsearchユーザがdataディレクトリに対してのみ 書き込み権限を持っていて、共有ファイルシステムリポジトリに対しても利用できる ファイアウォールやプロキシ、Shieldを使って、snapshot APIの実行を任意のユーザから実行されるのを防いでいる この問題をCVE-2015-4165としています。\n古いインデックスのためのUpgrade API Elasticsearch 2.0以降では、 Lucene 5ベースとなり、Lucene 3 (Elasticsearchのバージョンでは0.90以前) によって書き出されたセグメントを含んだインデックスを読み込むことが できなくなります。 これらの「古いインデックス」はLucene 4にアップグレードする必要があり、 2.0-compatibleとして印をつける必要があります。 そうしなければ、Elasticsearch 2.0に以降できないでしょう。\nupgrade APIは 、最新のLuceneフォーマットにインデックスにある全てのセグメントを アップグレードするためにすでに利用できます。 また、最新のフォーマットは性能向上やバグフィックスといった利点もあります。 さらに、2.0-compatibleとして古いインデックスをマークする設定も 書き込むことができます。 さらに、upgrade_only_ancient_segmentsオプションが Lucene 3のセグメントだけをアップグレードするために利用でき、 移行前の必要な処理を減らすことができます。\nKibanaユーザのためのハイライトの強化 KibanaユーザはElasticsearchのハイライトについて2つの点で問題を見つけていました。\nワイルドカードでフィールド名を指定した場合に、ハイライトに適さないフィールドも帰ってくる(日付や数値のフィールドなど) 古いインデックスが非常に大きなターム(\u0026gt; 32kB)を含んでいて、ハイライトが失敗する。 最近のバージョンでは、これらの大きなタームはインデックス時に除去される #11364の変更で これらの問題が修正されました。 ワイルドカードを利用したフィールド名では、stringフィールドのみを返し、非常に長いタームによる例外は無視するようになります。\nWindowsユーザのためのmlockall 速いGCはノードの安定性と性能について重要です。 小さなバイトのヒープでさえ、ディスクにスワップすることを許可してしまうと、GCに対して大きな影響が出てしまいます。 ですので、これらのコストは排除されるべきです。\nLinuxユーザはbootstrap.mloclall設定による恩恵を受けています。 これは、RAMにJVMのヒープを起動時にロックします。 #10887では、同様の機能をWindowsユーザにも提供します。\nより詳細なスクリプト設定 Scriptsはリクエストにインラインで指定できます。 .scriptsインデックスにインデックスもでき、config/ディレクトリ配下にファイルとして保存もできます。 これまでは、インラインかインデックスされたスクリプトの両方を同時に有効無効にすることが選択できましたが、 .scriptsインデックスをプロキシやShieldで保護することもできました。\n#10116で追加されたより詳細なスクリプトの設定で、インラインか、インデックスされたものか、ファイル化を個別に言語ごとに設定できるようになりました。 また、例えば、search APIではスクリプトを許可するが、update APIでは許可しないといったような設定も可能です。\n最後に ぜひ、Elasticsearch 1.6.0を試してみてください。 そして、感想をTwitter(@elastic)やWebフォーラムなどで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1433910662,"dir":"post/2015/","id":"55188a318c5998989255253e15ccc1f6","lang":"ja","lastmod":1433910662,"permalink":"https://blog.johtani.info/blog/2015/06/10/elasticsearch-1-6-0-released-ja/","publishdate":"2015-06-10T13:31:02+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 1.6.0 released 本日(6/9)、Lucene 4.10.4ベースのElas","tags":["elasticsearch"],"title":"Elasticsearch 1.6.0リリース(日本語訳)"},{"contents":"第10回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 次回もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\n今回も新規の方が結構いたような気がしました。 最終的に、124人がアプリでチェックインした形になりました。 直前にキャンセル待ちから繰り上がると来れない人がいますよねぇ。 多少キャパシティオーバーするくらいの人数で募集するのがいいのでしょうか。 あと、カードが2枚不明で。。。心あたりある人いないでしょうか?\nさて、いつもの通り簡単なメモです。\nElastic{ON}報告+有償プラグインの紹介 Elastic Jun Ohtani @johtani スライド:elastic{ON}報告と商用プラグインの紹介\n少し時間が経ってしまいましたが、弊社初のカンファレンスelastic{ON}の紹介をしました。 約1300名の方に参加していただいたカンファレンスで、非常に盛り上がりました。 Microsoft、GitHubなど、いろいろな会社の方が話をしたり、弊社のエンジニアが濃い話をしたりと。 今回は、日本の方はいなかったですが、次回は日本からも参加してもらえると嬉しいです!\nあとは、5月に弊社にも日本の営業の人が入社したので、有償プラグインについて簡単ですが説明をしました。 プラグインなどに興味があるかたがいらっしゃいましたら、Twitterなどで連絡いただければと。 もちろん、弊社サイトからの問い合わせでも大丈夫です。\nカンファレンスの資料やビデオが弊社サイトで公開されています。 ぜひ一度見ていただければと。\nAWSで実現するelasticsearchの大規模運用 株式会社インティメート・マージャー 松田和樹さん @mats116 スライド:第10回elasticsearch勉強会 公開用資料\nパブリックDMPのサービスの裏側でElasticsearchを利用しているというお話でした。 AWS Auto Scalingに詳しくないので、勉強しないといけないんですが、 リバランスがどのくらいの頻度で発生するのかはちょっと気になります。\nSSDを利用したり、doc valuesを利用したりと、性能を気にしながら利用されている点、負荷試験を行って検証されていたりと、 参考になる話でした。 今回はインフラ側の話に寄っていたので、今度はアプリ側でどんな使い方をしているかといった話を聞いてみたいですね!\nSpark in small or middle scale data processing with Elasticsearch 株式会社ビズリーチ 島本 多可子さん @chibochibo03 スライド:Spark in small or middle scale data processing with Elasticsearch\nScalaとSparkとElasticsearchで検索サービスを作っている話でした。 サービスのアーキテクチャの選別についての説明を順を追って説明していただきました。 失敗と言われていたアーキテクチャを見た時に、「あー、それは。。。」と思っていたら、 思った通りの改善案のアーキテクチャが出てきたので少しホッとしましたw\nJSONのクエリが辛いという話がありましたが、validate APIなどを利用してもらって、事前にチェックをしてもらうと 少しは改善できるかもなぁと。\nSparkをぼんやりとしかわかってないので、もう一度話を聴きたいなぁと思ったので、 押しかけて話を聴きたいと思います。\n話の中で出てきた自作のScalaのElasticsearchクライアントがHTTPのクライアントになった理由が知りたかったです。\nLT Elasticsearchのサジェスト機能を使った話 株式会社アイスタイル 渡邊 紘太朗さん @ktaro_w スライド:Elasticsearchのサジェスト機能を使った話\nぴったり5分でしたwまだ2年目なのにこんなにうまく話をしていただけるとは。。。\nGatling便利そうですね。サーバが1台しかないので、単一インデックスの方が性能が出るだろうなと。 Elasticsearchは1インデックスに対してデフォルトだと5シャードで、シャード単位でLuceneのインデックスが作成されます。 この話で行くと、18インデックスを作ると、かなりの数のファイルI/Oが発生するので、いろいろなインデックスに検索をすると キツいだろうなと。\nサジェストについての日本語の資料が少ないという事だったので、ブログを書いてもらえると嬉しいですw\nElasticsearchで作る形態素解析サーバ 株式会社エヌツーエスエム 菅谷信介さん スライド:Elasticsearchで作る形態素解析サーバ\nいつも発表ありがとうございます。私以外の最多発表者じゃないかという話でした。 今回はElasticsearchを形態素解析サーバにしてしまおうという話で、ちょっと面白い話でした。 Elasticsearch以外の場所で形態素解析したい場合には手軽に使えるかもしれないですし、Elasticsearchと同じ解析結果を別の場所で欲しい場合にも便利かも。\nextended analyze APIの紹介までしていただいて。。。\nちなみに、今は、extended analyze プラグインも指定したAttributeの情報だけ返せるようになってたり、 マルチバリューへの対応もしていたりします。 そのうち本家のanalyze APIに機能を取り込む予定です。(早くしないと)\n開発効率UP! Elasticsearch Client Tool 作ってみた ナレッジワークス株式会社 木戸国彦さん @9215 スライド:開発効率アップ!Elasticsearch Client Tool 作ってみた\nHello Elasticsearch!にはお世話になっている人が多いんじゃないかなと。 今回はSublime Textのプラグインのお話でした。(すみません、Sublime Text使ってなくて。。。) AtomとかIntellijのプラグインもあるとうれしいなー\n変わり種プラグインの作り方 日本IBM 黒澤亮二さん スライド:変わり種プラグインの作り方\nElasticsearchの拡張ポイントの話と、簡単なプラグインの作り方と少しElasticsearch内部の話をしていただきました。 Foundの資料が上がってました。さすが。あそこのブログは面白い話が多いんですよね。 社内で実際に使われてる話とかも聞いてみたい!\nその他、感想などのブログ 第10回 Elasticsearch 勉強会へ参加してきた昨日の話 第10回elasticsearch勉強会 #elasticsearch #elasticsearchjp 第10回elasticsearch勉強会に行ってきました elasticsearch勉強会に登壇してきました まとめ 懇親会で24Fに移動していただくということで、少し手間をかけてしまいました、すみませんでした。 今回も初参加の方がそこそこいたんじゃないかなと。 あとは、AWSサミットがあるために上京してて参加しましたという方もいらっしゃいました。 大きなカンファレンスの期間の前後に行うとこんなメリットもあるんですね、今後の参考にしたいと思います。 次回は7/27を予定しています。CTOのShayが来日予定です!\nあと、東京以外の勉強会も検討しつつあります。興味のある方はコメントやTwitterで反応をいただけると嬉しいです。\nスピーカーは随時募集中ですので、コメント、メール、ツイートなど、コンタクトしていただければと思います。 よろしくお願いいたします。\n","date":1433225196,"dir":"post/2015/","id":"75d9268739fe7787ac02d389ac605feb","lang":"ja","lastmod":1433225196,"permalink":"https://blog.johtani.info/blog/2015/06/02/10th-elasticsearch-jp/","publishdate":"2015-06-02T15:06:36+09:00","summary":"第10回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさ","tags":["elasticsearch","勉強会"],"title":"第10回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Reindex Elasticsearch With Logstash\nThanks David!\nマッピングを変更したり、インデックスの設定を変更したり、あるサーバから他のサーバや、 あるクラスタから他のクラスタ(例えば複数のデータセンターのような場合)にデータを再インデックスしたくなることがあるでしょう。\n後者のような場合はSnapshotやRestoreの機能を利用することもできますが、インデックスの設定を変更をしたい場合は その他の方法が必要になります。\nLogstash 1.5.0で、 elasticsearch inputとelasticsearch outputを使うことで、とても簡単に再インデックスができます。\nではやってみましょう。\n古いクラスタ elasticsearch 1.5.2 はすでにダウンロード済みとして、localhost:9200でoldという名前のクラスタを起動します。\nbin/elasticsearch --cluster.name=old クラスタにpersonという名前のインデックスが存在します。 これは、5シャードで、100万件のドキュメントを持っています。\n新しいクラスタ 次に新しいクラスタを起動します。 localhost:9201でnewという名前のクラスタを起動します。\nbin/elasticsearch --cluster.name=new こちらは、空です。\ncurl -XGET \u0026#34;http://localhost:9201/person\u0026#34; { \u0026#34;error\u0026#34;: \u0026#34;IndexMissingException[[person] missing]\u0026#34;, \u0026#34;status\u0026#34;: 404 } Logstashのインストール 次に、Logstash 1.5.0をダウンロードして、インストールします。\nwget http://download.elastic.co/logstash/logstash/logstash-1.5.0.tar.gz tar xzf logstash-1.5.0.tar.gz cd logstash-1.5.0 logstashの設定ファイルlogstash.confを次のように設定します。\ninput { # We read from the \u0026#34;old\u0026#34; cluster elasticsearch { hosts =\u0026gt; [ \u0026#34;localhost\u0026#34; ] port =\u0026gt; \u0026#34;9200\u0026#34; index =\u0026gt; \u0026#34;person\u0026#34; size =\u0026gt; 500 scroll =\u0026gt; \u0026#34;5m\u0026#34; docinfo =\u0026gt; true } } output { # We write to the \u0026#34;new\u0026#34; cluster elasticsearch { host =\u0026gt; \u0026#34;localhost\u0026#34; port =\u0026gt; \u0026#34;9201\u0026#34; protocol =\u0026gt; \u0026#34;http\u0026#34; index =\u0026gt; \u0026#34;%{[@metadata][_index]}\u0026#34; index_type =\u0026gt; \u0026#34;%{[@metadata][_type]}\u0026#34; document_id =\u0026gt; \u0026#34;%{[@metadata][_id]}\u0026#34; } # We print dots to see it in action stdout { codec =\u0026gt; \u0026#34;dots\u0026#34; } } 実行と修正 実行します。\nbin/logstash -f logstash.conf ドキュメントのチェックと修正 何が起きたでしょう?\ncurl -XGET \u0026#34;http://localhost:9200/person/person/AU1wqyQWZJKU8OibfxgH\u0026#34; { \u0026#34;_index\u0026#34;: \u0026#34;person\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;person\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;AU1wqyQWZJKU8OibfxgH\u0026#34;, \u0026#34;_version\u0026#34;: 1, \u0026#34;found\u0026#34;: true, \u0026#34;_source\u0026#34;: { \u0026#34;name\u0026#34;: \u0026#34;Tali Elyne\u0026#34;, \u0026#34;dateOfBirth\u0026#34;: \u0026#34;1955-05-03\u0026#34;, \u0026#34;gender\u0026#34;: \u0026#34;female\u0026#34;, \u0026#34;children\u0026#34;: 2, \u0026#34;marketing\u0026#34;: { \u0026#34;cars\u0026#34;: null, \u0026#34;shoes\u0026#34;: null, \u0026#34;toys\u0026#34;: null, \u0026#34;fashion\u0026#34;: null, \u0026#34;music\u0026#34;: null, \u0026#34;garden\u0026#34;: null, \u0026#34;electronic\u0026#34;: null, \u0026#34;hifi\u0026#34;: null, \u0026#34;food\u0026#34;: 846 }, \u0026#34;address\u0026#34;: { \u0026#34;country\u0026#34;: \u0026#34;Germany\u0026#34;, \u0026#34;zipcode\u0026#34;: \u0026#34;0099\u0026#34;, \u0026#34;city\u0026#34;: \u0026#34;Bonn\u0026#34;, \u0026#34;countrycode\u0026#34;: \u0026#34;DE\u0026#34;, \u0026#34;location\u0026#34;: [ 7.075943707068682, 50.72883500730124 ] } } } もう一方のクラスタと比較してみましょう。\ncurl -XGET \u0026#34;http://localhost:9201/person/person/AU1wqyQWZJKU8OibfxgH\u0026#34; { \u0026#34;_index\u0026#34;: \u0026#34;person\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;person\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;AU1wqyQWZJKU8OibfxgH\u0026#34;, \u0026#34;_version\u0026#34;: 1, \u0026#34;found\u0026#34;: true, \u0026#34;_source\u0026#34;: { \u0026#34;name\u0026#34;: \u0026#34;Tali Elyne\u0026#34;, \u0026#34;dateOfBirth\u0026#34;: \u0026#34;1955-05-03\u0026#34;, \u0026#34;gender\u0026#34;: \u0026#34;female\u0026#34;, \u0026#34;children\u0026#34;: 2, \u0026#34;marketing\u0026#34;: { \u0026#34;cars\u0026#34;: null, \u0026#34;shoes\u0026#34;: null, \u0026#34;toys\u0026#34;: null, \u0026#34;fashion\u0026#34;: null, \u0026#34;music\u0026#34;: null, \u0026#34;garden\u0026#34;: null, \u0026#34;electronic\u0026#34;: null, \u0026#34;hifi\u0026#34;: null, \u0026#34;food\u0026#34;: 846 }, \u0026#34;address\u0026#34;: { \u0026#34;country\u0026#34;: \u0026#34;Germany\u0026#34;, \u0026#34;zipcode\u0026#34;: \u0026#34;0099\u0026#34;, \u0026#34;city\u0026#34;: \u0026#34;Bonn\u0026#34;, \u0026#34;countrycode\u0026#34;: \u0026#34;DE\u0026#34;, \u0026#34;location\u0026#34;: [ 7.075943707068682, 50.72883500730124 ] }, \u0026#34;@version\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;@timestamp\u0026#34;: \u0026#34;2015-05-20T09:53:44.089Z\u0026#34; } } Logstashは@versionと@timestampフィールドを追加してしました。 これらを除去したいので、Mutate filter pluginのremove_fieldを使います。\nfilter { mutate { remove_field =\u0026gt; [ \u0026#34;@timestamp\u0026#34;, \u0026#34;@version\u0026#34; ] } } マッピングのチェックと修正 実際に、logstashは_sourceフィールドを既存のドキュメントから読み込み、 それらを新しいクラスタに直接投入しています。 しかし、logstashはマッピングについてはケアしていません。\n古いマッピングと新しいマッピングを比較するために、マッピングを取得してみましょう。\ncurl -XGET \u0026#34;http://localhost:9200/person/person/_mapping\u0026#34; { \u0026#34;person\u0026#34;: { \u0026#34;mappings\u0026#34;: { \u0026#34;person\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;address\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;city\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;country\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;countrycode\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;location\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;geo_point\u0026#34; }, \u0026#34;zipcode\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, \u0026#34;children\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;dateOfBirth\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;date\u0026#34;, \u0026#34;format\u0026#34;: \u0026#34;dateOptionalTime\u0026#34; }, \u0026#34;gender\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;marketing\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;cars\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;electronic\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;fashion\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;food\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;garden\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;hifi\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;music\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;shoes\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;toys\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; } } }, \u0026#34;name\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } } } } } curl -XGET \u0026#34;http://localhost:9201/person/person/_mapping\u0026#34; { \u0026#34;person\u0026#34;: { \u0026#34;mappings\u0026#34;: { \u0026#34;person\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;address\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;city\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;country\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;countrycode\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;location\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;double\u0026#34; }, \u0026#34;zipcode\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, \u0026#34;children\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;dateOfBirth\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;date\u0026#34;, \u0026#34;format\u0026#34;: \u0026#34;dateOptionalTime\u0026#34; }, \u0026#34;gender\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;marketing\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;cars\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;electronic\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;fashion\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;food\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;garden\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;hifi\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;music\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;shoes\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;toys\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; } } }, \u0026#34;name\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } } } } } これにより、いくつかの相違を発見できます。\n\u0026#34;location\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;geo_point\u0026#34; } \u0026#34;location\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;double\u0026#34; } データをインデックスする「前」に、実際に利用したいマッピングでインデックスを作成しておくことで、 この問題に対処できます。 この時点で、オリジナルのマッピングを望んだ形に変更することができます。例えば、アナライザを変更したりです。 また、インデックスの設定を新しく定義することもできます。 デフォルトでは、Elasticsearchは5つのシャードと各シャードに対して1つのレプリカを作成します。 しかし、この時点でもう一度変更することが可能です。\ncurl -XDELETE \u0026#34;http://localhost:9201/person\u0026#34; curl -XPUT \u0026#34;http://localhost:9201/person\u0026#34; -d\u0026#39; { \u0026#34;settings\u0026#34;: { \u0026#34;number_of_shards\u0026#34;: 1, \u0026#34;number_of_replicas\u0026#34;: 0 } }\u0026#39; curl -XPUT \u0026#34;http://localhost:9201/person/person/_mapping\u0026#34; -d\u0026#39; { \u0026#34;person\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;address\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;city\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;country\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;countrycode\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;location\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;geo_point\u0026#34; }, \u0026#34;zipcode\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, \u0026#34;children\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;dateOfBirth\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;date\u0026#34;, \u0026#34;format\u0026#34;: \u0026#34;dateOptionalTime\u0026#34; }, \u0026#34;gender\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34; }, \u0026#34;marketing\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;cars\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;electronic\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;fashion\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;food\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;garden\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;hifi\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;music\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;shoes\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;toys\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; } } }, \u0026#34;name\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } } }\u0026#39; さて、もう一度再インデックスしましょう!\nbin/logstash -f logstash.conf インデックスやタイプ名の変更 もちろん、インデックス名やタイプ名、IDを変更したい場合も変更が可能です!:)\nelasticsearch { host =\u0026gt; \u0026#34;localhost\u0026#34; port =\u0026gt; \u0026#34;9201\u0026#34; protocol =\u0026gt; \u0026#34;http\u0026#34; index =\u0026gt; \u0026#34;europe_people\u0026#34; index_type =\u0026gt; \u0026#34;someone\u0026#34; document_id =\u0026gt; \u0026#34;%{[@metadata][_id]}\u0026#34; } ","date":1432624090,"dir":"post/2015/","id":"23a22d1411afb787810d68210e6fad4f","lang":"ja","lastmod":1432624090,"permalink":"https://blog.johtani.info/blog/2015/05/26/reindex-elasticsearch-with-logstash-ja/","publishdate":"2015-05-26T16:08:10+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Reindex Elasticsearch With Logstash Thanks David! マッピングを変更したり、インデックスの設定を変更したり、あるサ","tags":["logstash","elasticsearch"],"title":"Logstashを使ったElasticsearchの再インデックス(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Join the Conversation: Discuss.Elastic.Co\n3つのOSSプロジェクトの開発をスケールアップし始め、 コミュニティサポートのために必要なやりとりに対してメーリングリストでは難しいということがわかってきました。 私たちは複数のメーリングリストを持っています。Elasticsearch、Logstash、そして英語以外の様々な言語のメーリングリストです。 このような状況では、あたらしい人たちはどこで質問をするのが良いのか混乱します。\nまた、メーリングリストの流量が増え、「参考になる話題」を見つけるのが難しくなってきました。 様々なユーザに採用してもらい、様々なユースケースが出てくることで、様々な質問が出てきています。 汎用的なメーリングリストではノイズの中から望んだ情報を見つけるのは難しいです。 また、ユーザ全てがメーリングリスト満足しているわけではありません。\nElasticは、ユーザの問題を解くことが大好きです。 コミュニティのメンバー皆さんに気に入っていただけるであろうソリューションを見つけ、フォーラムを https://discuss.elastic.co に移すことにしました。 ぜひ参加して、この新しいツールについてのご意見を聞かせてください。\nメーリングリストは好きだけど、ウェブフォーラムは苦手?問題ありません。 フォーラムにユーザプロファイル(GitHub、Facebook、Twitter、Google Appsのアカウントと連携するか、emailアドレスを利用すれば簡単に作れます)を作り、 email通知の設定をすればOKです。 これで、emailでのやりとりができるようになります。\n利用して、議論を楽しんでください。 もちろん、改善案などにかんするご意見もお待ちしています!\n","date":1432197903,"dir":"post/2015/","id":"615db1a24f36d19a8eaf18d4dceed6b2","lang":"ja","lastmod":1432197903,"permalink":"https://blog.johtani.info/blog/2015/05/21/join-the-conversation-ja/","publishdate":"2015-05-21T17:45:03+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Join the Conversation: Discuss.Elastic.Co 3つのOSSプロジェクトの開発をスケールアップし始め、 コミュニティサポー","title":"discuss.elastic.co にぜひ参加を"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 1.5.2 Released\n本日(4/27)、Lucene 4.10.4ベースのElasticsearch 1.5.1およびElasticsearch 1.4.5 をセキュリティバグフィックス版をリリースしました。 ダウンロードおよびすべての変更については次のリンクをごらんください。\n最新安定版:Elasticsearch 1.5.2 1.4系バグフィックス:Elasticsearch 1.4.5 本リリースはディレクトリトラバーサルの脆弱性のフィックスです。すべてのユーザにアップグレードを勧めます。\n過去のリリースに関するブログは以下のリンクを参照してください。\n1.5:1.4.1, 1.5.0 1.4:1.4.4,1.4.3, 1.4.2,1.4.1, 1.4.0, 1.4.0.Beta1 すべての1.5.2および1.4.5の変更についてはリンクをごらんください。以下では、セキュリティの問題について紹介します。\nディレクトリトラバーサル脆弱性の発見 1.5.2および1.4.5以前の全バージョンのElasticsearchで、ディレクトリトラバーサル攻撃に対する脆弱性がみつかりました。 攻撃者はElasticsearchを実行しているサーバからファイルを取得することができます。 この脆弱性はインストールしたばかりのElasticsearchには存在しません。 この脆弱性は\u0026quot;site plugin\u0026quot;がインストールされると露呈します。 ElasticのMarvelプラグインおよびコミュニティサポートの多くのプラグイン(例:Kopf、BigDesk、Head)がsite pluginです。 Elastic Shield、Licensing、Cloud-AWS、Cloud-GCE、Cloud-Azure、analysis pluginおよびriverプラグインはsite pluginではありません。\nこの問題をCVE-2015-3337としました。\nバージョン1.5.2と1.4.5はこの脆弱性に対して対策済みで、私たちはすべてのユーザにアップグレードを勧めています。\nアップグレードを望まないユーザはいくつかの方法でこの脆弱性に対して対応可能ですが、これらの方法はsite pluginを動作させなくします。\nsite pluginをインストールしているノードのelasticsearch.ymlのhttp.disable_sitesをtrueに設定し、Elasticsearchのノードを再起動 ファイアウォールもしくはプロキシを利用して、/_pluginへのHTTPリクエストをブロック すべてのsite pluginをすべてのElasticsearchノードからアンインストール この問題を報告していただいた、DocuSignのJohn Heasmanに感謝いたします。\n他の変更について インデックスされたスクリプトおよびテンプレートを上書きもしくは削除時に、キャッシュからも完全に削除する。 geo-shapeの多数のフィックス(distance_error_pctを利用した場合の、重要なprecisionに関するフィックスを含む) インデックステンプレートのデフォルトマッピングがバルクインデキシング中にも考慮するように修正 Shadowレプリカがファイルシステムの遅延に対する対障害性を向上し、プライマリシャードのよりスムーズなリロケーションをサポート geo-contextsをcompletion suggesterで使用した場合のマッピングのリフレッシュループを改善 いくつかの重要な変更がv1.4.5にバックポートされています。\n大きなシャードのリカバリを早くするためのシャードリカバリ中のマージを可能に \u0008* truncated translogsの操作をグレースフルに マージが遅くなる場合に、delete-by-queryを減速 ぜひ、Elasticsearch 1.5.2をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1430201648,"dir":"post/2015/","id":"8d7caf84b3a51cca27291c1f7cfc2d40","lang":"ja","lastmod":1430201648,"permalink":"https://blog.johtani.info/blog/2015/04/28/elasticsearch-1-5-2-and-1-4-5-released-ja/","publishdate":"2015-04-28T15:14:08+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 1.5.2 Released 本日(4/27)、Lucene 4.10.4ベースのEla","tags":["elasticsearch"],"title":"Elasticsearch 1.5.2 および 1.4.5リリース(日本語訳)"},{"contents":"第9回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 次回もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\n今回はトレーニングで来日していたIgorとNathanによる特別公演でした。 昨年同様、サムライズムの@yusukeさんに テキスト翻訳していただき、大変助かりました。ほんとうにすごかった。。。\nチェックイン数など 今回はチェックインした人:119名 キャンセルしなかった人:45名 でした。今回はキャンセル待ちのまま当日を迎えた人もいなかったので良かったかなと。 今回から懇親会ページを別にしてみました。本編の勉強会に参加登録していた方には何度かメールを出していたので、 見つけていなかった人は以内とは思うのですが、勉強会のページと間違える人がいたらしいという話を聞きました。 Doorkeeperで1イベントで複数のチケットにそれぞれの参加者数を設定できるようになると嬉しいかもなぁ。\nさて、いつもの通り簡単なメモです。 本当に簡単にですが。\nResiliency in Elasticsearch and Lucene / Igor Motov スライド:https://speakerdeck.com/elastic/resiliency-in-elasticsearch-and-lucene\n※上記スライドは少し古いバージョンです。公開されたら差し替える予定です。\nサンフランシスコで行われたElastic{ON}(弊社初のカンファレンス)で行われたセッションの 改良版といったところでしょうか。 話の中で登場した機能などのリンクをざっとアップしておきます。\nFielddata Doc Values Resiliency Status Kibana4: What\u0026rsquo;s New ? / Nathan Zamecnik スライド:未定\nKibana4の紹介をデモを交えてという感じでした。 こちらは、スライドよりもデモを見てもらうのが一番いいのですが。。。\nいくつかQAがあったので補足を。ちなみに、Issueのラベルに実装される予定のバージョンが付与されてたりします。\nQ:グラフをPDFでエクスポートとかできますか? A:4.3.0で実装される予定です。関連Issueはこちら。https://github.com/elastic/kibana/issues/509 Q:巨大な数値の場合にKB、MBなどといった表示は可能ですか? A:4.1.0で実装される予定です。関連Issueはこちら。https://github.com/elastic/kibana/issues/1543 Q:地図のズームを固定することはできますか? A:4.1.0で実装される予定です。関連Issueはこちら。https://github.com/elastic/kibana/issues/1442 その他、感想などのブログ [Elasticsearch] 第9回 Elasticsearch 勉強会へ参加してきた まとめ 今回は特別バージョンでした。かなり詳しい話だったので面白かったと思います。 Kibanaはデモを見ていただけましたし。また、海外から人を呼べるといいなぁ。\n次回は6月ごろをめどに計画しようかと。 スピーカーは随時募集中ですので、コメント、メール、ツイートなど、コンタクトしていただければと思います。 よろしくお願いいたします。\n","date":1429249314,"dir":"post/2015/","id":"7249710187cc2d983709e044dbc78d9d","lang":"ja","lastmod":1429249314,"permalink":"https://blog.johtani.info/blog/2015/04/17/9th-elasticsearch-jp/","publishdate":"2015-04-17T14:41:54+09:00","summary":"第9回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん","tags":["elasticsearch","勉強会"],"title":"第9回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 1.5.1 Released\n本日(4/9)、Lucene 4.10.4ベースのElasticsearch 1.5.1 をリリースしました。 このリリースはElasticsearchの最新の安定バージョンとなります。\nすべての変更についてはdownload Elasticsearch 1.5.1 hereをごらんください。\n本リリースはシャードを新しいノードに配置するスピードを改善するためのバグフィックスを含んでいます。 シャードのリカバリーの最初のフェーズで、コピー元のノードからコピー先のノードへすべてのセグメントをコピーします。 このフェーズ中には登録、更新削除のリクエストはトランザクションログに記録され、リカバリが終了したあとに コピー先のノードでトランザクションログが再生されます。 シャードが大きい場合、トランザクションログに多数のイベントがたまってしまいます。\n以前では、新しいセグメントのマージはリカバリ中のコピー先のノードでは、実行できませんでした。 大きなトランザクションログは結果として、小さな新しいセグメントを多く生成し、リカバリのスピードに非常に影響を与えます。 Issue #10463は リカバリ中のコピー先のシャードのマージを可能にする変更です。\nその他の注目すべきバグフィックスは次のものになります。\n多くの削除によりバージョンマップがいっぱいになった場合にrefreshを実行するように変更(#10312) 多数のスナップショットを含んだリポジトリの管理の改善(#10366) 実験的な機能であるinner hitsのバグフィックス(#10388, #10353, #10309, #10235) 最後に、Riverが非推奨となりました、まだ見ていない場合は記事をご覧ください。\nぜひ、Elasticsearch 1.5.1をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1428892471,"dir":"post/2015/","id":"563864a949924c505985a168191dcb84","lang":"ja","lastmod":1428892471,"permalink":"https://blog.johtani.info/blog/2015/04/13/elasticsearch-1-5-1-released-ja/","publishdate":"2015-04-13T11:34:31+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 1.5.1 Released 本日(4/9)、Lucene 4.10.4ベースのElas","tags":["elasticsearch"],"title":"Elasticsearch 1.5.1リリース(日本語訳)"},{"contents":"Elasticsearch勉強会 in 名古屋を開催しました。 初の東京以外での勉強会です。 企画、セッションなどお手伝いいただいた@smogamiさん、@mzpさんありがとうございました!\nElasticsearch/ELK stack紹介 @johtani スライド:Introduction Elasticsearch\n初回(次回があるかはわかりませんが。。。)ということもあり、Elasticsearchの説明を行いました。 あと、LogstashとKibanaも。 Kibanaについては、手元の環境でいつものアクセスログのデモやなどを行いました。 また、LTの後に時間があったので、前回の勉強会で利用したチェックリストの説明なども。\nスタンドファームにおけるElasticsearch導入事例 @mzp さん スライド:後日アップ?\n\u0008* 使ってるのはKibana3\nアクセスログが保存されてたけど、活用できてなかった。 Fluentd、Elasticsearch、Kibanaをいれて、可視化してみた。 普通にログ検索が簡単にできて嬉しい システムのレスポンスの性能値などを可視化できるようにして性能改善中 Kibanaでログ分析を1年続けてみたら業務システムの保守と運用が捗った(仮) @smogami さん スライド:「Kibanaでログ分析を1年続けてみたら業務システムの保守と運用が捗った」\n名古屋でJavaの勉強会を主催してみたり(最近できてないけど) 導入するのになかなか大変だった(ファイアウォールだったりが)。。。 Kibanaを使ってどんなことをしてるのか?\n既存システムなどの機能の実行回数やレスポンス時間の推移 曜日ごとにもチェック どの機能がよく使われるのか? 対象となっているシステムはJavaのシステム。 QA\nQ:ログの出力は新規に追加したのか? A : ログの出力自体はLog4Jの設定を変更しただけ。もともと、各メソッドの開始と終了にそれぞれ時間が出力される仕組みがある。\nログの読み込み自体は自作ツールを利用。 飛び込みLT @dabits さん スライド:未定\nKibanaの使い道\nKPIツール エゴサーチツール - Twitterや2chなどのデータを解析ソーシャル分析みたいな感じ? \u0008* ダッシュボードを用意してあげる場合もあるが、触っていろんな機能を試す人も。 感想・反省点など 30名弱の方に参加していただきました。ありがとうございました。 東京の勉強会でもそうですが、半分くらいが検索、半分くらいがログ解析関連に興味がある感じでした。 飛び込みLTもしていただけましたし。会場内限定の話もいくつか。\n場所 場所が少しわかりにくかったかなと。。。建物の入り口に看板がないので、1名に看板役として立っていただきました。 ただ、設備は充実していましたし、室内も綺麗でよかったです。\n懇親会 11名(+私)でした。美味しい手羽先などをいただきながら、Elasticsearch以外のことでも盛り上がりましたw。 また、名古屋の観光名所なども教えてもらったりと有意義な時間でしたw。\nということで、少しでもElasticsearch、Kibana、Logstashなどのユーザが増えてくれればうれしいかなと。 私抜きでも勉強会はできると思うので、今後も開いてもらえるとうれしいかぎりです。 初めての東京以外での勉強会でどんな感じの方が利用しているのか、興味があるのかといったことも知ることができました。\n関連ブログなど Kibana4活用事例を話しました その他(余談) コンパルという喫茶店のアイスコーヒー。ちょっと新鮮な体験でした。 あとは、日曜日に観光場所として教えてもらった、トヨタ産業技術記念館にも行ってみました。 一人だったけど、非常に楽しめました。実演とかあって、わかりやすいし。 トヨタが自動織機の会社が始まりだってのは知らなかった。\n","date":1428108439,"dir":"post/2015/","id":"24357fe145c869ec82fdfc8134a1a6d1","lang":"ja","lastmod":1428108439,"permalink":"https://blog.johtani.info/blog/2015/04/04/elasticsearch-study-session-at-nagoya/","publishdate":"2015-04-04T09:47:19+09:00","summary":"Elasticsearch勉強会 in 名古屋を開催しました。 初の東京以外での勉強会です。 企画、セッションなどお手伝いいただいた@smogamiさ","tags":["elasticsearch","勉強会"],"title":"Elasticsearch勉強会 in 名古屋を開催しました。#elasticsearch #elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:Elasticsearch 1.5.0 Released\n本日(3/23)、Lucene 4.10.4ベースのElasticsearch 1.5.0 をリリースしました。 このリリースはElasticsearchの最新の安定バージョンとなります。 多くのresiliency(復元性、弾力性) enhancementとバグフィックスを含んでおり、 すべてのユーザにアップグレードを推奨しています。\nすべての変更についてはdownload Elasticsearch 1.5.0 hereをごらんください。\n460PRという大量の変更を含む本リリースは、Elasticsearchをよりresilient(弾力のあるもの)にするために 費やされています。\nInner hits 本リリースで追加された、Elasticsearchに最もリクエストされたものの一つがinner hitsです。 これは、has_childもしくはnestedクエリにマッチした子のドキュメントを、各親ドキュメントと一緒に返すことができます。\n例えば、blogという親ドキュメントとcommentという子ドキュメントを持っているとします。 この時、\u0026ldquo;full text search\u0026quot;というコメントを持ったブログ記事を検索したいとします。\nGET /my_index/blog/_search { \u0026#34;query\u0026#34;: { \u0026#34;has_child\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;comment\u0026#34;, \u0026#34;score_mode\u0026#34;: \u0026#34;sum\u0026#34;, \u0026#34;query\u0026#34;: { \u0026#34;match\u0026#34;: { \u0026#34;body\u0026#34;: \u0026#34;full text search\u0026#34; } } } } } 上記のリクエストは、親のblogドキュメントを返します。 しかし、どのコメントが関係しているのかはわかりません。 関連しているコメントを検索して親ごとにグルーピングするために、 少し手間のかかる2回目のクエリを実行する必要があります。\nInner hitsがこれを変えてくれます。 inner_hitsパラメータを次のように、上記のクエリに追加するだけです!\nGET /my_index/blog/_search { \u0026#34;query\u0026#34;: { \u0026#34;has_child\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;comment\u0026#34;, \u0026#34;score_mode\u0026#34;: \u0026#34;sum\u0026#34;, \u0026#34;query\u0026#34;: { \u0026#34;match\u0026#34;: { \u0026#34;body\u0026#34;: \u0026#34;full text search\u0026#34; } }, \u0026#34;inner_hits\u0026#34;: {} } } } 検索結果の各blog記事に、inner_hitsという項目があり、そこに検索にヒットしたコメントの 上位3件(デフォルト値)が返ってきます。\n... \u0026#34;hits\u0026#34;: [ { \u0026#34;_index\u0026#34;: \u0026#34;my_index\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;blog\u0026#34;, \u0026#34;_id\u0026#34;: 1, \u0026#34;_score\u0026#34;: 3.68, \u0026#34;_source\u0026#34;: { ... }, \u0026#34;inner_hits\u0026#34;: { \u0026#34;comment\u0026#34;: { \u0026#34;total\u0026#34;: 16, \u0026#34;hits\u0026#34;: [ { \u0026#34;_type\u0026#34;: \u0026#34;comment\u0026#34;, \u0026#34;_id\u0026#34;: 5, \u0026#34;_score\u0026#34;: 2.79, \u0026#34;_source\u0026#34;: { \u0026#34;body\u0026#34;: \u0026#34;Full text search is the bomb\u0026#34; } }, { ... }, { ... } ] } } } ] ... inner_hits部分は、第2の検索リクエストに似ています。 sizeやfromパラメータを含めるくことで、挙動をカスタマイズできます。 また、検索から想像するであろう、ページネーション、ソート、ハイライト、_sourceフィルタリングなどといった機能もサポートします。\nInner hitsはparent-childおよび、nestedドキュメントをサポートします。 この機能は、現時点ではexperimentalラベルが付与されています。 このラベルは、この機能が将来変更されたり、削除されたりする可能性があるかもしれないことを意味します。 詳細については、Inner Hits documentationをごらんください。\nShadow replicas Elasticsearchはそれ自身の冗長性に常に気をつけています。 それは、レプリカシャード(各プライマリシャードの冗長なコピー)を持っています。 これは、プライマリシャードを失った時に、データをロスしないようにするためのものです。 レプリカシャードはまた、検索のスループットをスケールアウトするためにも利用できます。 多くのレプリカ(ノードを伴うことで。)はスループットを増加させます。\nしかし、ユーザによってはElsticsearchを分散ファイルシステム上でホスティングしており、すでに、 ファイルシステムがレプリケーションと冗長性を担当しています。 ファイルシステムが同じことしているので、各シャードのコピーを複数持つことはあまり意味がありません。\nShadowレプリカはノードを追加することによる検索スループットをスケールアウトすることが、 余分なストレージやインデキシングのコストを払うことなく、可能になります。 代わりに、各シャドーレプリカはプライマリシャードを持っている共有ファイルシステムにread-onlyでアクセスします。 Shadowレプリカは定期的にファイルシステムのビューをリフレッシュし、プライマリシャードのどんな変更も検知するでしょう。\nプライマリシャードが失敗したら、Shadowレプリカがプライマリに昇格し、 失敗したプライマリによって書き込まれたトランザクションログを読み込みリプレイできます。\nこの機能はexperimentalマークが付いています。詳細についてはShadow Replicas documentationをごらんください。\nResiliency improvements Elasticsearch 1.1 から 1.3では、インデックスのすべてのファイルのチェックサムを追加し、 それらのファイルが壊れているかどうかをチェックするために利用することにフォーカスしました。 1.4では、Zen discoveryと分散モデルについて大きな改良を加えました。\nこれらの変更にともなう、より詳細な統計情報やより詳細なロギングがElasticsearchやLuceneの以前のバージョンに存在した 未知の問題を明るみに出しました。 Elasticsearch 1.5.0では、これらの問題の多くに対処しています。\nElasticsearchとLuceneの以前のバージョンにあるバグがインデックスの故障を引き起こしていました。\nチェックサムコードのおかげで、これらを発見できました。現在は、Elasticsearchの起動時に自動的にLucene3.x\n(Elasticsearch 0.20.x以前)が作成したセグメントを検知して、シャードをオープンする前に、新しいフォーマットを使って、 新しいコミットポイントを書き出します。(#9899)\n1.3.xもしくは以前のバージョンからローリングアップグレードは、ローカルのシャードデータを再利用しようとせずに、\nシャード全体をコピーしようとします。1.3.2と以前のバージョンが実行されているノードからローリングアップグレードすることは 圧縮をオフにしない限りできなくなりました。(#9925)\n1.3.xやそれ以前のバージョンからアップグレードする場合、ローリングアップデートする代わりにクラスタの再起動を考えたほうがいいかもしれません。\n非同期環境は予測することが難しいです。時に、最も予測していないことが起きるからです。\nシャード配置、リカバリ、削除のコードの多くが単純化され、状態変更をよりアトミックで決定的にするための変更によりリファクタリングされました。\n(#8720, #9799, #9784, #9801, #9083, #8579, #8436, #8092, #9902, #6644, #8350, #9770, #9616, #9439, #8350, #8494)\n同様に、変更はクラスタ状態の更新が常に前進するということを確実にしました。更新の受け取り順序が順不同であったり、\nマスターだったノードからの更新を受け取った場合に混乱させていました。 (#9632, #9541, #9503)\nチェックサムとチェックサムのバリデーションの強化(#8723,\n#8599, #8587, #8407, #8010, #8018)\ndisk threshold allocation deciderを速く(#8803)、賢く(#7785)、自動化(#8270)\nauto-generated IDの利用時のインデキシングのスピードアップのためのに追加された最適化を除去。\nたまにドキュメントを重複して登録するため(#7729)\nDownload now ぜひ、Elasticsearch 1.5.0をダウンロードして、試してみてください。 そして、感想をTwitter(@elastic)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1427859496,"dir":"post/2015/","id":"19ecbaa5e12f7a9ebcff703c79534a52","lang":"ja","lastmod":1427859496,"permalink":"https://blog.johtani.info/blog/2015/04/01/elasticsearch-1-5-0-released-ja/","publishdate":"2015-04-01T12:38:16+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:Elasticsearch 1.5.0 Released 本日(3/23)、Lucene 4.10.4ベースのEla","tags":["elasticsearch"],"title":"Elasticsearch 1.5.0リリース(日本語訳)"},{"contents":"サンフランシスコからこんにちは。\n今、私は、弊社初のユーザカンファレンスelastic{ON}に 参加するために、初のアメリカ出張中です。 初のユーザカンファレンスですが、世界各国から約1300人!の登録がありました。\n本日が初日(Welcome Receptionが昨晩開催されましたが)です。 初日のキーノートで重要な発表が2つありました。\nブランド名の変更(Elastic: For - You Know, More Than Search) Found.noの加入(Welcome Found) です。\n昨日までは、elasticsearchでした。 本日からは、elasticになります。 ブランド名の変更と同時にサイト、ロゴなども変更されました。\nもう一つのビッグニュースがFoundの加入です。 found.noはElasticsearchをクラウドサービスとして提供している会社です。 彼らがジョインすることで、elasticsearchをより気軽に利用できるような環境ができてきます。\nKeynoteでの驚きのニュースこれらでした。 もちろん、このカンファレンスはそれだけには止まりません。\nNetflixやGitHub、Verison Mobile、WikimediaといったElasticsearch,ELKスタックのユーザの話や、 弊社の人たちによる今後のロードマップや私たちの考え方など多岐にわたる話を聞くことができます。\nこのような機会を今後も提供できるような会社になれるよう、頑張っていきたいなと思っています。\nちなみに、弊社のカンファレンスは私がこれまで経験したことのないカンファレンスになっています。 DJや各種ゲーム(ビリヤードとかパックマンとか)が楽しめるようなパーティが 懇親会として開催されたり、スポンサーブースでウェルカムレセプションが行われたりと、 面白い取り組みにあふれています。 次回開催されることがあれば、ぜひ日本の方達にも参加してもらえたらうれしいなと。\n","date":1426059991,"dir":"post/2015/","id":"ced9df0d8c8ed14de91c509b31b4c4ae","lang":"ja","lastmod":1426059991,"permalink":"https://blog.johtani.info/blog/2015/03/11/attend-elasticon/","publishdate":"2015-03-11T16:46:31+09:00","summary":"サンフランシスコからこんにちは。 今、私は、弊社初のユーザカンファレンスelastic{ON}に 参加するために、初のアメリカ出張中です。 初のユ","tags":["elastic","elasticon"],"title":"#elasticon に参加中"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:you know, for security: shield goes ga\n1/27にShield 1.0 をリリースしました。 Elasticsearch向けの私たちのセキュリティプラグインの最初のリリースです。 11月にShieldについてアナウンスしてから、Elsaticsearchのためのセキュリティの機能は、 一般的に望まれているものから始まり、具体的な考えと実行できる計画へと変遷し、それが、いま現実となりました。\n十分にセキュアな環境に、Elasticsearchクラスタをセキュアな状態でデプロイできるようにするため、 私たちは継続的にカスタマーやユーザーからのリクエストを受け取り、統合されたソリューションになるようにしてきました。\n私たちは、そのようなプロダクトがどうあるべきか調査することから始め、 カスタマーとユーザが必要とするセキュリティとはどんなものかを理解するために多くの時間を費やしました。 その結果がShieldです。 Shieldは、ElasticsearchクラスタをセキュアにするElasticsearchの有償プラグインです。 私たちは、ShieldをDev、Gold、Platinumサブスクリプションの一部として、追加料金なしで提供します。\n最初のリリースでは、基本的な機能と基盤にフォーカスしています。 Elasticsearch自身に対しても、セキュリティに対して準備してきました。 拡張性の側面だけでなく、Elasticsearchにあるデータフローについても再考してきました。 Elasticsearchクラスタをセキュアにする場合に、具体的な価値を即座に届けるだけでなく、素早く拡張できるようにも開発しました。\n機能 Shield 1.0は次の5つにフォーカスしています。\n認証(Authentication) 認可(Authorization) 暗号化通信とノードの認可(Encrypted Communication \u0026amp; Node Authentication) IPフィルタリング 監査証跡(Audit Trail) 認証(Authentication) セキュリティの大部分はアイデンティティについてです(例えば、だれがこのAPIを呼び出したのか?システムに何のサービスが接続するか?など) サービスのライフタイムのある時点で、サブジェクト(例えばユーザー)を現在実行中のサブプロセスなどに結びつけることです。 この関係性を持つためには、サブプロセスを実行する前にユーザの身元を確認するように命じます。 ユーザの身元の確認のプロセスをAuthenticationと呼び、ElasticsearchのすべてのAPIコールでそれが実行されます。\n認証の手法は多くの異なるものがあります。 それぞれの手法は、ユーザが認証されたという資格(Authentication Token)を、それぞれのタイプで提供するようにユーザに要求します。 Shield 1.0ではシンプルに、必要なauthentication tokenをユーザ/パスワードペアとしています。 (これは、Shieldの認証基盤が簡単に拡張でき、将来は異なるauthentication tokenもサポートできることを意味します。)\nユーザの資格を受け取ることだけでは不十分で、次に、それらをチェックする必要があります。 Shieldでは、これはレルムの責務です。 レルムは認証プロバイダ/サービスとしてみることができます。 妥当なユーザであると判断/解決されたか、 authentication tokenが適切な資格を持っていない/単に知らないユーザであるということで、拒否されたかです。 Shieldの認証メカニズムでは、複数のレルムを設定でき、さらに、あるレルムの戻り値を扱う他のレルム、というようなchainとすることもできます。 Shield 1.0は3つのレルムをサポートします。\nesusers - Elasticsearchによって管理されるファイルベースのレルムです。 これは、ファイルにユーザを定義することができます。(Apacheサーバのhtpasswdファイルのようなもの) このレルムは外部への依存はなく、Shieldをインストールすれば、デフォルトで使用できます。 このレルムは配置が簡単で、マルチテナントなElasticsearchクラスタに対して使用できます。 マルチテナントなElasticsearchクラスタとは、クラスタを複数のアプリでシェアすることをテナントと言います。 また、すべてのユーザがパスワードを忘れてしまうような\u0026quot;emergency\u0026quot;な代替レルムも対応可能です。 (誰もシステムに入れないような状況のことです) LDAP - 外部のLDAPサーバでユーザを認証するレルムです。 このレルムは組織のLDAPサーバで管理/保存されているユーザをすでに持っている組織を対象としています。 Active Directory - LDAPのタイプの1つで、Active Directoryに対する設定になります。 レルムはelasticsearch.yml設定ファイルで、次のように設定可能です。\nshield.authc realms:\nesuser: type: esusers order: 0 ldap: type: ldap order: 1 url: ldaps://url/to/ldap1/server ldap_fallback: type: ldap order: 2 url: ldaps://url/to/ldap2/server 上記のようにrealmsが一つのチェインとして参照されます。 レルムごとに、設定された順序で、それらは参照されます。\nNOTE : Shieldには、esusersファイルに保存されたユーザを管理するためのコマンドラインツールもあります。\n認可(authorization) 認可(Authorization)は保護されたリソースにアクセスするユーザを許可するか拒否するかということです。 モダンなシステムは、ユーザのパーミッションのために、ロールベースのアクセスコントロール(RBAC)モデルを利用します。 このモデルでは、各ユーザはロールの集合に関連していて、それぞれのロールには、パーミッションの集合が定義されています。 これは、洗練された設定で、パーミッションを機能的なグループで共有させることができます。 例えば、次のようなロールを定義したとします。\nemployee - すべての従業員は部門をまたいだ会社のデータへアクセスできます(例えば、コンタクトやディレクトリ情報など) sales - すべての営業職は営業データにアクセスできる(例えば、流通ルート、ルート、顧客) finace - すべての財務の従業員は財務データにアクセスできる(例えば、予算、経費、伝票) 財務部門のAnnは従業員と財務のロールを持っており、会社のディレクトリと財務データにアクセスでできます。\n認可プロセスはユーザがリクエストに関連したユーザが必要で、このプロセスのために、認証フェーズの後に直接実行されます。\nShieldは2つのタイプのリソースを定義します。クラスタとインデックスです。 これらは、すべてのAPIコールで保護されます。 さらに、それらに関連したパーミッションとロールも定義できます。 一度定義をすると、ロールはユーザもしくはLDAP/ADのグループに関係します。 ロールはroles.yml設定ファイルで定義されます。 設定のサンプルは次のようになります。\nadmin: cluster: all indices: \u0026#39;*\u0026#39; : all monitor: cluster: monitor indices: \u0026#39;*\u0026#39;: monitor employee: indices: \u0026#39;company_directory\u0026#39; : read sales: indices: \u0026#39;opportunities\u0026#39; : read, write \u0026#39;accounts\u0026#39; : read, write finance: indices: \u0026#39;expenses\u0026#39; : read, write \u0026#39;purchases\u0026#39; : read, write 上記のサンプルで、次の5つのロールを定義しています。\nadmin - 管理者のロールで、すべてのクラスターレベルの操作とすべてのインデックスに対してすべてのインデックスレベルの操作を実行可能です。 (¥*インデックスはすべてのインデックスにマッチするワイルドカード) monitor - システム/クラスタのモニタリングのためのロール。このロールのユーザはすべてのクラスタとインデックスレベルの情報の読み取りの APIにアクセス可能だが、インデックスのデータへの読み書きや設定の更新は不能 employee - compnay_directoryにあるすべてのデータへの読み取りアクセスを与えられたロール。このロールはクラスタレベルへのアクセスやデータの書き込みアクセスは持っていない (特にcompany。洗濯されたグループの人々はcompanyディレクトリの更新は可能だが、employeeは読み取りのみが可能) sales - opportunitiesとaccountsインデックスの読み書きができるロール finance - expensesとpurchasesの両方に読み書きができるロール 上記のサンプルで定義されているallとreadとwriteとして名前がつけられた権限です。 これらは、予約語で、Elasticsearchのローレベルのアクションを複数含んだ権限です。 (writeはindex, delete, delete_by_query, bulk, updateの操作を含んでいます。) 多くのケースで、これらのハイレベルの名前が付けられた権限で十分ですが、特定のロールに特定のアクションを明示的に指定することもできます。 次のようになります。\nhr: indices: \u0026#39;company_directory\u0026#39; : indices:data/write/index, indices:data/write/update ここまで説明した認可のレルムは、各ユーザに関連するロールを識別するためのものです。 内部のesuserレルムでは、提供されるesuserコマンドラインツールを使ってロールはユーザに割り当てたり変更したりもできます。 LDAPやActive Directoryでは、LDAP/ADグループにShieldのロールを割り当てることができます。\n認証と認可の両方を用いることで、ユーザリクエストに対して、ユーザごとに許可/不許可をすることができます。\n暗号化通信 認可はElasticsearchのデータを機能的な観点(許可されたユーザだけが操作を可能にする)で保護しますが、 クライアントからElasticsearchクラスタへ、もしくはクラスタのノード間では暗号化されていないデータを送るためまだ危険があります。 第三者が登頂したり、オンザフライでデータを書き換えたりといった可能性やクラスタを壊すことができます。\nShield 1.0はElasticsearchのすべての通信チャネルをセキュアにすることができます。 クラスタ内のノード間のチャネルやクライアントに公開されているチャネルです。 これは、SSL/TLS通信を導入して実現します。\nShieldで使えるSSLはElasticsearchのtransportサービスをSSL/TLSで通信できるものに置き換えます。 これは、ノード間通信チャネルと、HTTP transport(REST APIを提供するもの)のそれぞれに設定可能です。\nShieldのSSL/TLSは、スタンダードなJavaのものとkeystoreとtruststoreを基本にしたものが利用可能です。 SSL/TLSを設定すると、各ノードのキーストアに証明書をインポートする必要があります。 CAがサインした証明書を使うことも、CAが信頼したものとして許可許諾されたものを使うことが可能です。 これは、信頼されたすべてのCAとして知られているtrust storeが必要です。 新しいノードをクラスタに追加するときに、すべての必要な少なくとも一つの信頼されたCAから発行されてサインされたものが必要になります。 クラスタで個別のノードがすべてのkeystore/truststoreを更新する必要性なしに。??\n通信チャネルを安全にする方法やSSL/TLS設定をどのように行うかはShieldのドキュメントをご覧ください。\nノード間認証 強く推奨しますが、許可されたノードだけがクラスタに接続できるようにするために、ノードの認証をSSL transportに設定することができます。 これは、shield.transport.client.authにtrueを設定することで可能です。 設定した場合、ノード間でSSLハンドシェイクが行われ、接続されたノードが接続に来たノードのクライアント認証を要求しチェックします。 もし、チェックに失敗した場合は、SSLシェイクハンドが失敗し接続が拒否されます。\nSSLクライアント認証 transportレベルでノード認証が必要なようなら、次のような疑問がわくでしょう。 Elasticsearchはクラスタに接続するTransportクライアントを使うときはどのように振る舞うのか? Transportクライアントはクラスタの他のノードと同じチャネルを使うため、コネクションを確立するときに、ノードが他のノードと異なるかどうかを見極めることはできません。\nこの時、もっとも単純な解決は、Transportクライアントも同様に許可を与えることです。 それは、認証を解決するときに、他の問題(潜在的な悪意)を引き起こします。 Transportクライアントが他のクラスタのノードを偽装しようとすることです。これは望んでいません。\n幸いなことに、良い解決方法があります。 トランスポートプロファイルです。 Elasticsearch 1.4で導入されたトランスポートプロファイルは、トランスポートレイヤー(異なるホスト/ポートにバインドされる)のために複数のネットワークチャネルを設定することができます。 Shieldはこのサポートを、プロファイルごとに異なるSSL設定をできるように拡張します。 また、ノードのタイプとクライアントプロファイルタイプの間に明確な違いを設定することも可能です。 これを用いると、2つのプロファイルを設定できるようになります。 ひとつは、クライアントのためのもので、もうひとつはクラスタのノードのためのものです。 これにより、クライアントのための認証の問題が必要なくなり、Shieldはクライアントプロファイルをもった限定されたクライアントからのリクエストを保証します。\nIPフィルタリング これは、厳密には、認証カテゴリではありませんが関係しています。 Shieldはそれ自身がIPフィルタリングのメカニズムを持っています。 これは、許可/不許可のIPのリストを設定することができます。 これらのフィルタリングのルールは複数のレベルで設定可能です。 transportチャネル、transportプロファイルレベル、そして、HTTPチャネルです。 次の設定は、それらの設定のサンプルです。(設定ファイルはelasticsearch.ymlになります)\nshield: transport.filter: allow: - \u0026#39;127.0.0.1\u0026#39; - \u0026#39;2001:0db8:1234:0000:0000:8a2e:0370:73 deny: - \u0026#39;10.0.0.0/8\u0026#39; - \u0026#39;2001:0db8:1234::/48\u0026#39; - \u0026#39;*.google.com\u0026#39; http.filter: allow: [ \u0026#39;10.0.0.0/8\u0026#39; ] deny: [ \u0026#39;127.0.0.1\u0026#39; ] transport.profiles: client: shield.filter.deny: [ \u0026#39;_all\u0026#39; ] このように、IPv4とIPv6、CIDR、ホスト名、ワイルドカードが利用できます。 また、この機能はホストOSのIPテーブルに設定することで追加できるが、Shieldにそれを保持し、それらの設定を単純化し、 デプロイの全体から除去できることにも注意してください(詳細はドキュメントのIPフィルタリングをご覧ください)。\n監査証跡(Audit Trail) セキュアなシステムの必須機能の一つで、監査硝石により、Elasticsearchに発生した重要なイベントをトラッキングすることが可能です。 これらのイベントを保存することは、Elasticsearchクラスタの重要なアクティビティの証拠を提供でき、 不審な/悪意のある可能性のあるイベントを追跡するときの診断ツールにもなります。\nShield 1.0.0で、監査証跡は監査/アクセスlogを一般的なElasticsearchのログとは個別に保存します。 それらは、構造化されているため、読んだりパースするのが容易で、イベントのタイプも分類されています。 また、情報のレベルを設定することができ、各イベントをlogレベルの設定で書き出すことができます。 以下が、イベントのリストです。\nanonymous_access_denied - 認証トークンがないユーザからのリクエストがあった時のログ authentication_failed - リクエストされたユーザの認証に失敗した時のログ access_denied - 認証されたユーザが許可されていない操作を実行した時のログ access_granted - 認証されたユーザが許可された操作を実行した時のログ tampered_request - 不正に書き換えられたリクエストが到着したのを検知した時のログ connection_granted - ノードもしくはtransportクライアントがIPフィルタのルールにパスした時のログ connection_denied - ノードもしくはtransportクライアントがIPフィルタリングルールの制限により却下された時のログ Shieldの監査証跡についてより詳しく知りたい方は、ドキュメントをごらんください。\n次のバージョンでは? ここまで紹介したように、これはまだ始まりにすぎません。 Shieldに追加される多くの機能があり、しっかりとした基盤を構築したところです。 Shieldの次のバージョンでは、以下の機能の追加にフォーカスするでしょう。(これらだけに限ったわけではありません。)\nAPIによる設定、管理 より拡張され、柔軟なLDAP/Active Directoryサポート レルムタイプの追加(kerberos、anonymous、certificatesなどなど) セッションベースの認証 ShieldはElasticsearch社の2番目の(Marvelに続く)商用プロダクトです。 ダウンロードして開発環境で評価してください。 インストールは他のプラグインと同様の方法です(インストール方法についての詳細はこちら)。 一度インストールすると、30日の試用ライセンスが始まります。 もし、さらに時間が必要な場合は、sales@elasticsearch.comまで連絡してください。\n私たちのすべてのプロダクトについてフィードバックをお待ちしています。 Shieldの商用利用、機能、ロードマップ、その他のセキュリティに関するトピックなど、質問がありましたら、 サイトからご連絡ください。\n","date":1425030596,"dir":"post/2015/","id":"cb13b64d0127c13bb466c4d4677a7b8a","lang":"ja","lastmod":1425030596,"permalink":"https://blog.johtani.info/blog/2015/02/27/you-know-for-security-shield-goes-ga-ja/","publishdate":"2015-02-27T18:49:56+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:you know, for security: shield goes ga 1/27にShield 1.0 をリリースしました。 Elasticsearc","tags":["elasticsearch","shield"],"title":"セキュリティ向けプラグインShieldのリリース(日本語訳)"},{"contents":"4月13日から3日間、ElasticsearchのCoreトレーニングが東京で開催されます。 Early Birdということで、3/14までに申し込みすると割引があります。 興味のある方は、見ていただければと。\nまた、4/15にElasticsearch勉強会を開催します。 トレーニングに弊社のエンジニアが来日しますので、なにか話をしてもらう予定です。\n募集は後日、Elasticsearch勉強会のDoorkeeperで行います。 興味のある方は、登録しておいていただければと。\nトレーニングや勉強会でお待ちしております。\n","date":1425024629,"dir":"post/2015/","id":"f2cbe07bf2ff16d5a5860b4d6edbc5e8","lang":"ja","lastmod":1425024629,"permalink":"https://blog.johtani.info/blog/2015/02/27/2nd-tokyo-training/","publishdate":"2015-02-27T17:10:29+09:00","summary":"4月13日から3日間、ElasticsearchのCoreトレーニングが東京で開催されます。 Early Birdということで、3/14までに申し込みす","tags":["elasticsearch"],"title":"Elasticsearch Coreトレーニング開催"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:kibana 4. literally.\nKibana 4は現在、文字通り、抽象的に、概念的に、精神的に、そしてとても楽しく、プロダクションレディになりました。 1週間前に準備はできていましたが、満足できるものであるという確信を得たいと思っていました。 そして、Kibana 4.0.0 GAをリリースしました。 次のものはサンプルのスクリーンショットと前日譚です。 これらに興奮してしまった方のために、2ステップのプランを用意しました。\nダウンロードする:Kibana 4 downloadsページからダウンロードします。 理解する:Kibana 4 docsページを読んで理解します。 Tip : もし、まだ、あなたのクラスタがElasticsearch 1.4.4でない場合は、アップグレードする必要があります。\nTip2 : Kibana 4 RC1からアップグレードする場合は、configを移行する必要があります。こちらのgistを参照\n前日譚 - the back story Kibanaはすでに問題解決のためのツールになっています。 なぜ、毎晩2時に呼び出されるんでしょう? そのコードがプロダクションに入ったのはいつですか? その結果、何を壊しました? 私たちはそれらを解決しました。 世界的に、長い間、だれも夜中の2時に呼び出されませんでした。知ってます?。\n*しかし、ここには落とし穴があります。*答えが簡単になれば、問題が難しくなります。 楽な勝利は簡単でした。では、難しい問題(深さが3層の問題)を解きましょう。 複数の要素、複数のフィールドそして、複数のデータソースを分析する必要がある問題を解きましょう。 Kibana 4は少ない時間と労力で最も難しい問題を解決してくれます。\nKibana 3で学んだことをKibana 4に取り込みました。 なぜ10億のデータを持っているのに、地図には1000個しかプロットできないのでしょう? 1つのチャートに1つのフィールドなんでしょう? なぜ、1つのパネルに1つのチャートなんでしょう? なぜ、1つのダッシュボードに1つのインデックスなんでしょう? 5つのシナリオを用意し、2つのフィールドにまたがったデータを比較し、 1つのダッシュボードに3つのインデックスのデータを表示してみましょう。 さぁ、やりましょう。終わったらアイスクリーム(トッピング付きの)を取りに行きましょう。\nthe plot アイスクリームのように、問題には多くの種類があります。 そのために、Kibanaをナポリ風アイスクリーム(3色アイス)のように分割しました。 嫌いな種類は除いて。 もし、あなたがKibanaのユーザ歴が長い場合、最初のタブのDiscoverがホームであることが正しく感じるでしょう。 これにより、短時間で、検索し、レコードを見つけ、簡単な問題を解決できます。 簡単な問題とは、すべてを物語る1行のデータを見つけることによって解決する問題です。\n物事が簡単な検索で説明できるものよりも複雑になった時、チャートとグラフで魔法を作る時間です。 Visualizeタブを開き、Elasticsearchのaggregationの力を利用してデータを解析しましょう。 Visualizeは複数の次元の性質のデータを見せ、今まで尋ねたことがないような質問に対して素早く回答するチャートやテーブル、 地図を作成できます。 あなたが最初に尋ねる質問は「先週サイトが遅かったのはなぜ?」でした。 しかし、データによって明らかにされた質問は「なぜ、クリスマスに東京からの平均ファイルサイズリクエストがスパイクしたのか?」です。\n最後に、Dashboardでこれらを1つにします。\n大きなスクリーンに配置して、こう言います。 「あなたの答えはこのリンクにあります。また、Wikiに埋め込んで、データをCSVにエクスポートしてメールしました。 アイスクリームを食べた後に、自叙伝の第1章を書きました。もっとアイスを持ってきてください。かき混ぜますから。」\nそれぞれのタブで見てきた詳細については、Kibana 4 Beta 1 : Releasedをごらんください。\nto be continued\u0026hellip; 居眠りをする時間はあります?いいえ、Kibana 4.1についてすでに作業中で、将来の大きなプランを持っています。 多くの労力はKibana 4の土台の安定と実用性を構築することに使われました。 また、Elasticsearchアプリケーションの将来を構築するプラットフォームを作りました。 すべてのものは拡張できるように設計されています。 例えば、可視化はより良くなるように構築されています。 オープンソースは私たちのGitHubアカウント以上のものです。 それは、新しく素晴らしいものを誰もが作ることができる構造を作ることが私たちの約束です。\nKibanaでグラフなどを構築したり、Elasticsearchを利用したアプリケーションを作成するために、 私たち開発者のブログを参考にしてください。 ちょっと見てみたいですか? Elastic{ON}15のSpencer Algerのトークをチェックしてください。\nあなた方なしでは、私たちはここにはいないですし、あなた方の助けがなければ何もできません。 ぜひ、GitHubでのissueや提案、貢献をお待ちしています。 もしくは、IRCでFreenodeの#kibanaに参加してください。\nextra credit Kibana 4のすべての話に興味がありますか?私たちのKibana 4ベータに関する過去のブログをチェックしてください。\nKibana 4 Beta 1: Released Kibana 4 Beta 2: Get it now Kibana 4 Beta 3: Now more filtery Kibana 4 RC1: Freshly baked 最後に、Kibanaの利用に関する話をお持ちなら、ぜひ聞かせてください。 stories at elasticsearch dot comもしくは@elasticsearchに連絡をください。 あなたの話を世界にどのようにシェアしているかごらんください。\n","date":1424408752,"dir":"post/2015/","id":"eee039f49a5b570599cf459c55c649f3","lang":"ja","lastmod":1424408752,"permalink":"https://blog.johtani.info/blog/2015/02/20/kibana-4-literally-ja/","publishdate":"2015-02-20T14:05:52+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:kibana 4. literally. Kibana 4は現在、文字通り、抽象的に、概念的に、精神的に、そしてとても楽しく","tags":["elasticsearch","kibana4"],"title":"Kibana 4(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:elasticsearch 1.4.4 and 1.3.9 released\n本日(2/20)、Elasticsearch 1.4.4とElasticsearch 1.3.9をリリースしました。 これはバグフィックスリリースとなります。 主に、Lucene expression scriptsを使う場合のRPMとDEBパッケージの パッケージング問題のフィックスをしたものです。 1.4.4のダウンロードこちらのリンクからアクセスできます。\nfixes 1.4.3のRPMおよびDEBパッケージにはAntlrとASMの依存関係の不足がありました。 この依存はElasticsearchでLucene expression scriptsを利用する場合に必要になります。 Groovyに関する1.4.3の変更により、多くのユーザがLucene explression scriptsを利用することが予想されるため、すぐに、1.4.4をリリースしました。\nまた、このリリースには、クラスタの保留タスクに関するいくつかのバグフィックスも含まれています。 さらに、date histogramで負のインターバルの場合にOutOfMemoryErrorを引き起こすバグも 修正されています。\nすべての変更については1.4.4のリリースノートおよび1.3.9のリリースノートをごらんください。\nフィードバック 私たちはフィードバックをお待ちしています。 Twitter(@elasticsearch)もしくはGitHub issues pageで教えてください。\n","date":1424408734,"dir":"post/2015/","id":"ddd3e6f6e298d3884abc4d888a043664","lang":"ja","lastmod":1424408734,"permalink":"https://blog.johtani.info/blog/2015/02/20/elasticsearch-1-4-4-and-1-3-9-released-ja/","publishdate":"2015-02-20T14:05:34+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:elasticsearch 1.4.4 and 1.3.9 released 本日(2/20)、Elasticsearch 1.4.","tags":["elasticsearch"],"title":"Elasticsearch 1.4.4および1.3.9リリース(日本語訳)"},{"contents":"来る、4月4日の土曜日の午後に名古屋でElasticsearch勉強会を開催予定です。 「初」の東京以外の勉強会です。\nTwitterでこのようなツイートを見かけまして。\n名古屋でElasticsearchの勉強会やりたい機運(今のところ2人)。\n\u0026mdash; mogami (@smogami) 2015, 2月 4 これは!ということで、名古屋で勉強会をやろうかと思います。30名程度の場所を借りて実施予定です。 募集はいつもの、elasticsearch勉強会のDoorkeeperで行う予定です。 ページの準備まで少々待ちください。(おそらく、3月中旬くらい) 私自身はElasticsearchやELKについて話をしようと思っています。そのほかに、2,3名のスピーカーの方を予定しています。 LTなど興味がある人がいたら、連絡ください。\nこれを機に(?)他の場所でも勉強会を開催したいと考えています。 ニーズがどのくらいありそうなのかが、まだよくわかっていませんが、関西などでニーズがあるんじゃないかと期待していたり。\n興味のある方は、コメント欄、Twitterなどでコンタクトしてもらえればと。 (連絡来るとうれしいなぁ。)\n","date":1424240573,"dir":"post/2015/","id":"5b97ead91c0dd0bad57b4f43a89149a2","lang":"ja","lastmod":1424240573,"permalink":"https://blog.johtani.info/blog/2015/02/18/preparing-elasticsearch-meetup-in-nagoya/","publishdate":"2015-02-18T15:22:53+09:00","summary":"来る、4月4日の土曜日の午後に名古屋でElasticsearch勉強会を開催予定です。 「初」の東京以外の勉強会です。 Twitterでこのよう","tags":["elasticsearch","勉強会"],"title":"名古屋でElasticsearch勉強会を開催します"},{"contents":"第8回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 次回もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\n今回は出足が好調で、早々に180人の枠を超えるという嬉しい事態でしたが、 キャンセル待ちが残っているにもかからわらず、来られていない方が67名もいるということで、キャンセル待ちの方には申し訳なかったです。 もうすこし、キャンセルをしてもらえると嬉しいんですが。。。 今回はメールを当日に1度しか打ってないからかなぁ。\nさて、いつもの通り簡単なメモです。 本当に簡単にですが。\n「Elasticsearch導入チェックリスト?」 Elasticsearch株式会社 Jun Ohtani @johtani スライド:Elasticsearch導入チェックリスト?\nElasticsearchを開発環境や本番に導入する前に気にかけて欲しいことについて発表しました。 元ネタはelasticsearch pre-flight checklistです。 少々古いのですが、私が今回話した内容以外にもモニタリングなどについての話も盛り込まれています。 時間がある方は、見ていただければと。\n「Elasticsearch クエリとスキーマ定義のすごい細かい話」株式会社ドワンゴ 藤堂淳也 さん スライド:Elasticsearch クエリとスキーマ定義のすごい細かい話\nフィールドのチェックを別途インデキシングするアプリで行っている。利用できるものだけElasticsearchに投げる 実際に本番環境で利用しているマッピングに対してフィールドを追加する手順について 「これもドキュメントに書いてあるんですが」という感じでドキュメントに色々書いてあるので読みましょうというありがたい発表でした。 実際に試行錯誤したり検証するときに行ったことを喋ってもらえたので、どういった点を気にしながら運用、設計するかというのがわかりやすかったです。\n「ElasticsearchとKibanaで実現する、30億req/dayのリアルタイム分析」株式会社サイバーエージェント 山田直行さん @satully スライド:ElasticsearchとKibanaで実現する、30億req/dayのリアルタイム分析\n会場が21時までしか抑えられていないという失態で、ドタバタしてて前半は聞けてないです。。。\n前回の発表では30日分Elasticsearchに入れていたが、今は3日分のみ保存 レポートなどにはRedshift+Tableauを利用 Kibana3をメインに使っているが、Kibana4も検討予定? QA\nQ:なぜ、ELBを挟んでいるのか? A:特に考えておいているわけではない。 Q:インデックスの構成は? A:1日に2つのインデックス。Bitされたもの、入札されないもの Q:searchのnodeをやめたのは? A:前回発表した勉強会での懇親会で話を聞いたり、他の方と話を聞いて、不要と判断したため 「はてなのメディア面を支えるElasticsearch」株式会社はてな 山家雄介さん @yanbe スライド:未定。おそらく、開発者ブログに公開されるかと。\n\u0008* アドテク系にもやってるらしい。BrandSafeはてな\nはてなブックマークのデータを魅せ方を変える機能などで大活躍。B!KUMAとか その日の話題の見出し自動生成機能。Significant Terms Aggregationsを利用。 こちらの「自然言語処理技術を用いたはてなブックマークの新機能「トピック」をベータリリースしました」エントリに関係あるのかな? 記事の魅せ方を検索できる管理画面ではElasticsearchのクエリDSLを活用されているとのことでした。 検索専門の人でなくても検索式を簡単にくみたてられる画面を用意して、ElasticsearchのクエリDSLに変換するようにしていると。 確かに、クエリをそのまま組み立ててもらうよりも利用しやすい画面がある方がいいですよね。バックエンドはJSとPerlのライブラリとのことでした。\nその他、感想などのブログ 2015-02-13 第8回 elasticsearch 勉強会 @ 丸の内 リクルート 41Fアカデミーホール [Elasticsearch] 第8回 elasticsearch 勉強会へ参加してきた 第8回elasticsearch勉強会 #elasticsearch #elasticsearchjp 第8回 Elasticsearch 勉強会に行ってきた #elasticsearch #elasticsearchjp 勉強会メモ - 第8回elasticsearch勉強会 まとめ 今回も検索からログまでいろんな話になったので、面白かったかと。 参加された方は新しい方が多かったんじゃないかなぁと。(集計結果で見れないのかな、Doorkeeper)。\n今回は、みなさんに21時に41Fから33Fへ移動していただくという大失態があったので、大変申し訳なかったです。 次回(4月中旬)は、このようなことがないように気をつけますので、今後もよろしくお願いいたします。\nあと、東京以外の勉強会も検討しつつあります。興味のある方はコメントやTwitterで反応をいただけると嬉しいです。\nスピーカーは随時募集中ですので、コメント、メール、ツイートなど、コンタクトしていただければと思います。 よろしくお願いいたします。\n","date":1424066543,"dir":"post/2015/","id":"997acc135d01b54f7de77a432fb9133f","lang":"ja","lastmod":1424066543,"permalink":"https://blog.johtani.info/blog/2015/02/16/8th-elasticsearch-jp/","publishdate":"2015-02-16T15:02:23+09:00","summary":"第8回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん","tags":["elasticsearch","勉強会"],"title":"第8回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:running groovy scripts without dynamic scripting\nElasticsearch1.3.8と1.4.3のリリースにより、デフォルトで、リクエストに含まれるGroovyスクリプトや インデックスに保存されたスクリプトを動的に実行する機能をオフにしました。 しかし、Groovyはまだデフォルトのスクリプト言語です。 本ブログ記事では、少しだけダイナミックだが、サンドボックスではない言語のためのスクリプトを どのように使い続けるかを説明します。\n本ブログ記事は、それが何を意味し、さらに重要なのは、安全に重要なタスクを実行させるためにスクリプトを どのように使用し続けるかを理解する助けとなるはずです。\nダイナミックスクリプトとは? Elasticsearchに詳しくない方のために、Elasticsearchでは、 さまざまなリクエストの一部としてスクリプトを送信することができます。 search、aggregation、update、upsert、delete by queryなどです。 あなたのユースケースのために、通常の動作よりも拡張した動作をさせるためにスクリプトを追加できます。\n例えば、以下のリクエストは、ダイナミックスクリプトを含んでいます。 field1とfield2 + shiftが同じ値を持っている時だけドキュメントを返します。\nGET /_search { \u0026#34;query\u0026#34;:{ \u0026#34;filtered\u0026#34;:{ \u0026#34;filter\u0026#34;:{ \u0026#34;script\u0026#34;:{ \u0026#34;script\u0026#34;:\u0026#34;doc[\u0026#39;field1\u0026#39;].value == (doc[\u0026#39;field2\u0026#39;].value + shift)\u0026#34;, \u0026#34;lang\u0026#34;:\u0026#34;groovy\u0026#34;, \u0026#34;params\u0026#34;:{ \u0026#34;shift\u0026#34;:3 } } } } } } 言語を変えることもできます。 それは、当然、シンタックスが変わったり、制限が追加(例えば、Groovyスクリプトの代わりにLucene Expressionsに変更)されることもあります。 langパラメータによって言語を指定できます。\nなぜそれはダイナミック? 上記の例はダイナミックスクリプトです。 それは、実際のスクリプトの部分はサーバサイドで動的に解釈されコンパイルされる必要があるからです。 ダイナミックスクリプトはElasticsearchのAPIによってデータノードに送信されます。 これは、インデックスされたスクリプト(indexed script)も含みます。\n言い換えると、もし、スクリプトがデータノード全てに保存されていなければ、 それは、ダイナミックスクリプトとして扱われます。\ndynamic scriptingをオフにするとどうなるか? 最新のリリースでの変更により、Groovyのdynaic scriptingはデフォルトでオフになりました。 先ほどのスクリプトについても同様で、もし、先ほどのリクエストを実行すると、次のようなエラーが発生します。 (一部省略してあります。)\n{ \u0026#34;error\u0026#34;:\u0026#34;SearchPhaseExecutionException[Failed to execute phase [query], all shards failed; shardFailures {[8FJ02MofSnqVvOQ10BXxhQ][test][0]: SearchParseException[[test][0]: from[-1],size[-1]: Parse Failure [Failed to parse source [{...}]]]; nested: ScriptException[dynamic scripting for [groovy] disabled]...\u0026#34;, \u0026#34;status\u0026#34;:400 } エラーメッセージの重要な箇所は「ScriptException[dynamic scripting for [groovy] disabled]」です。\nスクリプティングを使い続けるには? Elasticsearchでスクリプトを実行するには3つの方法があります。 2つのダイナミックな方法は、リクエストごとのスクリプト(上述)かインデックスされた スクリプト(indexed script)を使う方法です。 インデックスされたスクリプトを使うことは、Elasticsearch自身にGroovyスクリプトを保管することで 利用で、それらを要求に応じて利用することです。 (これは、実際には十分機能しますが、これではまだ、信頼できないユーザに対して彼らのスクリプトを実行できます) RDBのように保存されたプロシージャとして同じ方法で実行させるものと同様です。 前もって、スクリプトを記述しておき、リクエストの一部として後から、名前で呼び出して実行可能です。\nGET /_search { \u0026#34;query\u0026#34;:{ \u0026#34;filtered\u0026#34;:{ \u0026#34;filter\u0026#34;:{ \u0026#34;script\u0026#34;:{ \u0026#34;script_id\u0026#34;:\u0026#34;your_custom_script\u0026#34;, \u0026#34;lang\u0026#34;:\u0026#34;groovy\u0026#34;, \u0026#34;params\u0026#34;:{ \u0026#34;shift\u0026#34;:3 } } } } } } あまり変わっていないことに気づくでしょう。 scriptの部分が、前もって記述されたスクリプトの名前script_idに変更されただけです。\nElasticsearchにスクリプトを提供するダイナミックではない方法はインデックスに保存する代わりに、 ディスクにファイルとしてスクリプトを保存することです。 そうすることで、各スクリプトを設定として保存します。 これは、どのようなスクリプト言語に対してもダイナミックスクリプティングをオフにしたまま、 サンドボックス化されないスクリプトを使い続けることができる方法です。\n最初のサンプルで、Groovyスクリプトはdoc['field1'].value == doc['field2'].value + shiftでした。 これを、.groovy拡張子を持ったファイルとして書き出すことができます。\ndoc[\u0026#39;field1\u0026#39;].value == (doc[\u0026#39;field2\u0026#39;].value + shift) もし、このファイルにyour_custom_script.groovyちう名前をつけて、 Elasticsearchのすべてのデータノードのconfig/scriptsディレクトリに保存すると、 Elasticsearchは60秒(elasticsearch.ymlのwatcher.intervalで変更可能)でこのスクリプトを認識し、今後のリクエストに利用できるようにプリコンパイルするでしょう。 そのファイルはElasticsearch実行ユーザによって読み込みができる必要があります。 これをディスクに書き込んだ後、あなたの設定ディレクトリは次のようになっています。\nconfig/ elasticsearch.yml logging.yml scripts/ your_custom_script.groovy これは、各リクエストやインデックスされたスクリプトをスクリプトとして動的に送信しませんが、 信頼された環境にスクリプトを追加することでダイナミックスクリプトとなることを許します。\nディスクに書かれたスクリプトを使用する スクリプトは、ロードされたスクリプトになるまでは、利用できません。 ログファイルに次のようなログが表示されるまではです。\n[2015-02-11 11:14:47,066][INFO ][script ] [Sergei Kravinoff] compiling script file [/path/to/elasticsearch-1.4.3/config/scripts/your_custom_script.groovy] すべてのElasticsearchのデータノードでスクリプトが読み込まれたら、 それを利用することができます。 利用するために、file(script_idではありません!)としてスクリプト名を指定します。\nGET /_search { \u0026#34;query\u0026#34;:{ \u0026#34;filtered\u0026#34;:{ \u0026#34;filter\u0026#34;:{ \u0026#34;script\u0026#34;:{ \u0026#34;file\u0026#34;:\u0026#34;your_custom_script\u0026#34;, \u0026#34;lang\u0026#34;:\u0026#34;groovy\u0026#34;, \u0026#34;params\u0026#34;:{ \u0026#34;shift\u0026#34;:3 } } } } } } Note:langは必須ではありません。Groovyがデフォルトの言語のためです。 もし、違うスクリプト言語を使いたい、もしくは、デフォルトの言語を(例えば、Lucene Expressionsへ) 変更したい場合、言語が正しいスクリプトを見つけるために提供されている必要があります。 一番良い方法は、アプリケーションがlangパラメータを含んでいることを勧めます。 これは、将来、デフォルトのスクリプト言語が変更されても、問題ないからです。\n質問? もし、質問があれば、遠慮なくTwitter(@elasticsearch)で教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1423721589,"dir":"post/2015/","id":"1fed22e99b0e11a50eb7b92cb1644e8a","lang":"ja","lastmod":1423721589,"permalink":"https://blog.johtani.info/blog/2015/02/12/running-groovy-scripts-without-dynamic-scripting-ja/","publishdate":"2015-02-12T15:13:09+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:running groovy scripts without dynamic scripting Elasticsearch1.3.8と1.4.3のリリースによ","tags":["elasticsearch"],"title":"Groovyスクリプトをダイナミックスクリプトなしで実行(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:elasticsearch 1.4.3 and 1.3.8 released\n本日、Lucene 4.10.3をベースにしたElasticsearch 1.4.3と、セキュリティとバグフィックスリリースである、Elasticsearch 1.3.8をリリースしました。 ダウンロードおよび変更リストはそれぞれ次のリンクからアクセスできます。\n最新ステーブルリリース:Elasticsearch 1.4.3 1.3.x系バグフィックス:Elasticsearch 1.3.8 過去のリリースに関するブログ(公式)はこちら。\n1.4:1.4.2, 1.4.1, 1.4.0, 1.4.0.Beta1 1.3:1.3.7, 1.3.6, 1.3.5, 1.3.4, 1.3.3, 1.3.2, 1.3.1, 1.3.0. すべての変更については1.4.3のリリースノートおよび1.3.8のリリースノートをごらんください。 以下では、セキュリティの問題について紹介します。\ngroovy scripting の脆弱性 Elasticsearchのバージョン1.3.0から1.3.7および1.4.0から1.4.2で、Groovyスクリプトエンジンに脆弱性が発見されました。 脆弱性は、攻撃者がGroovyスクリプトをサンドボックスを避けて構築でき、 ElasticsearchのJava VMを実行しているユーザとしてシェルコマンドを実行できます。\nこの問題をCVE-2015-1427として報告済みです。\nバージョン1.3.8と1.4.3では、デフォルトで、Groovyに対してのサンドボックスをオフにしました。 結果として、ダイナミックスクリプトの実行はGroovyに対してもオフとなります。\nもし、脆弱性のあるバージョンで実行している場合、v1.3.8かv1.4.3にアップグレードするか、ダイナミックなGroovyスクリプトをクラスタの すべてのノードに対して次の設定を追加することで、オフにします。\nscript.groovy.sandbox.enabled: false これは、Groovyのサンドボックスをオフにし、リクエストの一部としてインラインで受け付けるダイナミックなGroovyスクリプトや 特殊な.scriptsインデックスに保存されているスクリプトを実行しません。\nそれまでは、各データノードのconfig/scriptsディレクトリにファイルとして保存されたGroovyスクリプトは まだ、利用可能です。詳細の情報についてはRunning scripts without dynamic scriptingをごらんください。\nfuture scripting plans 安全なダイナミックスクリプティング言語としてGroovyを失うことは、Elasticsearchにとって痛手です。 update APIやsearch APIやaggregationsフレームワークの一部としてScriptを使います。 それらは、静的なAPIでは簡単に表現できない、カスタムなトリックをユーザに実行できるようにします。\n残念ながら、Groovyチームとこの問題を議論した後、Groovy言語もサンドボックスによってきちんと保護されている というにはあまりにもダイナミックであるという結論に達しました。 Groovyは、デフォルトでは利用できなくなります。 利用可能なダイナミックスクリプト言語としてはLucene Expressions言語のみとなります。 Expressionsははやいですが、それらは非常に限定されています。数値のフィールドでのみ実行可能で、ループをサポートしていません。\nより強力で(しかし安全な)ミニ言語になるようにExpressionsを拡張することを調査しています。 これは、Scriptユーザが現在持っている最も一般的なユースケースを少なくとも助けるでしょう。 この拡張は長期間のプロジェクトであり、進化には時間がかかるでしょう。\nぜひ、Elasticsearch 1.4.3をダウンロードして、試してみてください。 そして、感想をTwitter(@elasticsearch)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1423712393,"dir":"post/2015/","id":"5badf61ecb9cfadd7d6af58712fa5f6f","lang":"ja","lastmod":1423712393,"permalink":"https://blog.johtani.info/blog/2015/02/12/elasticsearch-1-4-3-and-1-3-8-released-ja/","publishdate":"2015-02-12T12:39:53+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:elasticsearch 1.4.3 and 1.3.8 released 本日、Lucene 4.10.3をベースにしたElas","tags":["elasticsearch"],"title":"Elasticsearch 1.4.3および1.3.8リリース(日本語訳)"},{"contents":"今年もCROSS参加しました。そして、話もしてきました。 今年は横浜の大さん橋でした。横浜はあんまりこないので、乗り換えでおたおたしてしまいましたが。。。\nなかなかいい景色でした。(寒いけど) 「おおさんばし」って読むんですね。「だいさんばし」だと思ってた。。。\n以下はいつもの、自分用メモです。\n俺はどうしてそのデータストアを選択したのか 〜銀河と小宇宙を語る会〜 http://2015.cross-party.com/program/c1\n遅れて入ったので、ちゃんと聴けてないです。\n最近注目しているデータストアは? Postgresql。JSON型が気になってる。 AiroSpike。データ型のあるデータストアが気になってる。 MongoDB。JSON使いたいなら、これじゃないの? AWSのAurora。インスタンスタイプを選ばなくていい(選ばないといけないらしい)とか、勝手にスケールしてくれるし、MySQL互換。 今こそ語るエンジニアの幸せな未来 http://2015.cross-party.com/program/x3\n「無職初日です。」 Web系の人?とか質問されて、自分が何系かいつもわからなくなるなぁ。 「働きがいは会社が提供するのか、個人が見つけるのか?」 個人かなぁ。会社がなにをやってるかにもよる気がするかなぁ。 「辞めると伝えると、やりたいようにやれって言われるw」 リモートできるかできないか。 「働きがい」というキーワードが出てると普通は怪しい会社w 今は、働きやすさを高くしないと人が雇えなくなってきている。 欧米のミドルウェアだと、35歳定年説はない。→日本でもそうじゃないですか? 漫然と進んでるとダメ。→そりゃそうだ。 全文検索エンジン群雄割拠〜あなたが使うべきはどれだ!〜 http://2015.cross-party.com/program/c4\nスライド:https://speakerdeck.com/johtani/elasticsearchfalseshao-jie-tote-zheng-cross-2015\n楽しんでいただけましたでしょうか? ちょっと話が長くなってしまい、あとの方の時間が少なかった気がしますが。。。\nKibanaのバックエンドとして認識されている人もいたので、検索エンジンですよというのをアピールするいい機会になったので良かったです。 もちろん、Kibanaとの組み合わせも面白いので、少しでも興味をもっていただき、触っていただけたらなぁと。\n話をする機会を用意していただいた、やまかつさん、その他のスピーカーのみなさん、ありがとうございました!。\nElasticsearchに関して何か興味質問などありましたら、気軽にコンタクトしてください。Twitterとかブログコメントなどで。\nプレモルタイム以降 プレモルの写真撮るの忘れてました。。。重要なのに。。。\n美味しくプレモルをいただきながら、何人かの方に声をかけていただき、話をすることができました。 こういう時間がとってあるのがいいですよね。 色々なところでElasticsearchを使っていただいているようで、うれしい限りです。 DMMの方とも話ができたし。\nまとめ 今年はプレモルを飲みに行くだけかなぁと思っていたのですが、話をする人になってました。(おかしいなぁ) 来年もあれば、きっと参加するかなぁと。ではまた来年!\n夜景きれいですね。(端っこに写ってる船は飛鳥IIでした。)\n","date":1422500368,"dir":"post/2015/","id":"fe6ba10cc6c9509b4b22e9d59e029775","lang":"ja","lastmod":1422500368,"permalink":"https://blog.johtani.info/blog/2015/01/29/talk-at-cross2015/","publishdate":"2015-01-29T11:59:28+09:00","summary":"今年もCROSS参加しました。そして、話もしてきました。 今年は横浜の大さん橋でした。横浜はあんまりこないので、乗り換えでおたおたしてしまいま","tags":["勉強会","elasticsearch"],"title":"CROSS 2015で話をしてきました #cross2015"},{"contents":"今年は大晦日になってしまいました。しかも、ちょっと飲んでたり。。。 第9流しながら書いてます。\n振り返り(2013年に書いた抱負から) まずは昨年書いた抱負からの振り返りです。\nElasticsearch勉強会の継続、Solr勉強会の継続+ミックスした検索勉強会の開催 IDEAのさらなる活用 もっと開発(プラグインとか) AWSをもう少し活用 海外のイベントに行ってみたい 読書と英語を継続 AWS活用できてないです、、、 ミックスした勉強会は、ドタバタしててできませんでした。\nIDEAはさらなる活用までいってるかは不明ですが、最近は隣にとても詳しい人が座っているので色々と教えてもらってます。 開発については、ちょっとずつですが、PR書いたりしてます。\n振り返り(今年あったできごと) 初海外(ベルリンとアムステルダム) Elasticsearchに転職 初献本? Elasticsearch勉強会の定期開催 ElasticSearch Serverの翻訳 サーバ/インフラエンジニア養成読本の執筆 勉強会以外でもスピーカー 英語の継続(切実) 初ものが多かったです。 初の海外の会社、初の海外旅行(仕事)、初の献本(著者の人から、多分、初)、初の翻訳本、初のムック本執筆などなど。\n初の海外でした。なのに、夏には海外の会社に転職してみてるとか、ちょっと自分でも信じられません。 ベルリンでは、海外の勉強会にも参加できて非常に有意義でした。 ヨーロッパの街並みは、日本では経験できない雰囲気で、向こうの方には普通の街並みも自分にはとても新鮮でした。\n転職自体は2回目ですが、海外の会社というのは初めてです。日々、英語\u0008の勉強になりますし、いろんな刺激を受けています。 英語の勉強自体も継続中です。英語力が不足しているのは自覚してるので、少しでも英語に触れるようにDLifeで海外ドラマを録画して、通勤時間帯にみるなどを試みてます。\n書籍には、昨年につづき関わることができました。来年も何かしらの書籍に関われることができればなと。 (\u0008気になる人は以下のリンクから。。。)\n分かりきったことですが、Elasticsearchな1年でした。 転職してあっという間の半年です。まだまだやりたいことがいっぱいあるので、来年もバランスよく頑張らないと。\n来年の抱負 英語の継続 海外のイベントへの参加 多岐にわたるイベントでのスピーカー 日本の人員の倍増!? Elasticsearchに関する日本語の情報発信 Elasticsearch座談会みたいなものの開催 英語の継続については書くまでもないですね。 海外のイベントへの参加もかなぁ。3月にサンフランシスコに行くとは思います。 そのほかには、今度こそBerlin Buzzwordsに行きたいです。\nElasticsearch勉強会以外のイベントでもElasticsearchを広めるべく色々なところでスピーカーをしたいなと思っています。 検索、ログ解析で少しは知名度が上がってきていますが、別の言語のコミュニティやイベントでは、まだまだ、elasticsearch自体を知らない人もいると思います。まずは知ってもらうところからかなと。\n日本の人員の倍増については、今年も達成してます(一人が二人になりましたw)。 来年も倍増できればうれしいなと。同じ母国語の同僚がいるのはやっぱりうれしいし、心強いですから。\n来年は(も)、日本語での情報をどんどん発信していきます。サイトやガイドなども 日本語にしたいなと。 あとは、これまで、勉強会でスピーカーをしていただいた人だけを集めた座談会のようなものも開催したいなと考えています。 私自身も色々と聞きたいことがありますし。 そのほかにも色々と要望をお待ちしています。Twitterやブログのコメント欄などで気軽にコンタクトしていただければと。\n最後は、いつものようにですが、来年も勉強会やいろんなイベントに参加する予定です。 ブログも週1程度で書く努力しないとなぁ。 こんな話を書いてくださいとかのリクエストもお待ちしています。\n今年はあと、数時間ですが、色々とお世話になりました。 この場を借りてお礼申し上げます。\n来年も、いろんな方に絡んでいくとは思いますが、よろしくお願いいたします。\n","date":1420026086,"dir":"post/2014/","id":"b36abffbe5d6a0de73a9968604a1a3f9","lang":"ja","lastmod":1420026086,"permalink":"https://blog.johtani.info/blog/2014/12/31/looking-back-2014/","publishdate":"2014-12-31T20:41:26+09:00","summary":"今年は大晦日になってしまいました。しかも、ちょっと飲んでたり。。。 第9流しながら書いてます。 振り返り(2013年に書いた抱負から) まずは昨年","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2014)"},{"contents":"この記事はElasticsearch Advent Calndar 2014の25日目のエントリです。\nあっという間に最終日です。来年につなげるという意味で、Elasticsearchの2系のIssueをいくつかピックアップして紹介してみます。\n現在、ElasticsearchのGitHubリポジトリは、大きく3つのブランチで作業しています。 master、1.x、1.4です。masterと1.xの大きな違いとしては、masterはLuceneの5.x系を採用している点です。\nなお、これから紹介するIssueは現在、確定していない項目も含んでいます。実際に2.0がリリースされるタイミングでは 採用されない場合もあります。\nUpgrade master to lucene 5.0 snapshot #8347 (closed) https://github.com/elasticsearch/elasticsearch/pull/8347\n先ほど書きましたが、Luceneの5に対応するためのPRです。 Lucene 5に関してはLuceneのコミッターのMikeさんのブログ記事も参考になります。\nLucene 5に変更することで、BitSetに関する改善が多く含まれることになります。 メモリの利用量、圧縮などの改善が多く含まれています。 もう1点大事な点としては、Lucene 5系ではLucene 3系のインデックスを読み込むことができなくなる点です。 Luceneの下位互換の範囲は1つ前のメジャーバージョン(5.x系の場合は4.xまでが対象)となっています。\nFilter cache: add a _cache: auto option and make it the default.(closed) https://github.com/elasticsearch/elasticsearch/pull/8573\nFilter cacheは、trueもしくはfalseの設定が利用できますが、filterの種類にも依存します。 その辺りの条件を加味しつつ、よしなにCacheをコントロールしてくれます。\nRemove and/or/not in favour of bool filter #8960(open / discuss) https://github.com/elasticsearch/elasticsearch/issues/8960\n似ているが少し異なるand、or、notフィルタとboolフィルタが存在しています。 これらをわかりやすくするために、boolフィルタに統一しましょうという話し合いをしています。\nInput validation #9059(open / discuss) https://github.com/elasticsearch/elasticsearch/issues/9059\n色々な入力に関するチェックを追加しようというIssueです。 たとえば、ディレクトリ名やファイル名、URLのパスやクエリストリング、フィールドのパスやスクリプトなどです。 Validationがあると、変な設定をして頭をかかえることもなくなるかなぁと。\nRefactor analysis framework #8961(open) https://github.com/elasticsearch/elasticsearch/issues/8961\n新しくAnalyzerを作った場合に、色々な場所に登録必要があったりします。インデックスレベルとノードレベルです。(Kuromojiプラグインなどが参考になります。) また、インデックスごとにカスタムのAnalyzerを設定するので、1つのノードに同じAnalyzerを何度も設定しないといけません。 よりシンプルにするために、Analyzerをノード単位で設定しようという提案です。\nRemove possibility for conflicting field definitions and ambiguous field resolution #8870(open) https://github.com/elasticsearch/elasticsearch/issues/8870\n同じインデックスに、異なるtypeで、同じフィールド名があった場合、いろいろと良くないことがあったりします。 たとえば、フィールドのタイプがintegerとstringと異なる場合に、インデックスレベルで検索を行うとうまく検索できなかったりと。 この問題を解消するために、より明確にしようというIssueです。 たとえば、フィールド名を指定するためには、フルパスで記述をするだとか、フィールドマッピングに関してはインデックスレベルで内部で保持をするなど。\nValidation of mappings request to reject unsupported fields #7205(closed) https://github.com/elasticsearch/elasticsearch/issues/7205\n1.xでも取り込まれますが、嬉しい機能なので紹介します。 これまでは、mappingsでスペルミスをした場合(たとえば、field設定で\u0026quot;indexx\u0026quot;といったミス)には、その項目は単に無視されるだけでした。 これが、v1.xでは、エラーに\nまとめ ということで、簡単ですが、v2.0.0に向けたIssueをピックアップして紹介してみました。 上記以外にも多くの改善、提案が2.0に向けて行われています。 興味のある方は、v2.0.0ラベルでIssueを検索してみてはいかがでしょうか?\n今年もあとわずかとなりました。 今年の2月にElasticsearchの1.0がリリースされ、あっという間に1.4なりました。まだまだ改善しています。\n来年もElasticsearchに興味をもっていただければ嬉しいです。 Elasticsearch初のユーザカンファレンスのサイトもオープンしました。 Elasticsearchに関するいろいろな話が聞ける機会だと思います。登録をお待ちしています。\n","date":1419490380,"dir":"post/2014/","id":"cb9649eca3dfbd356527ffc88f1dcb94","lang":"ja","lastmod":1419490380,"permalink":"https://blog.johtani.info/blog/2014/12/25/pickup-elasticsearch-2-0-0-labels/","publishdate":"2014-12-25T15:53:00+09:00","summary":"この記事はElasticsearch Advent Calndar 2014の25日目のエントリです。 あっという間に最終日です。来年につなげるという意味で、Elasti","tags":["elasticsearch"],"title":"Elasticsearch 2.0系のIssueの紹介"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:marvel 1.3.0 released\n12/17に、Elasticsearch Marvel 1.3.0をリリースしました。 Marvelの以前のリリースから、Elasticsearchでは様々なことがありました(Elasticsearch 1.4のリリースなど)。 このバージョンでは、モニタリングにクエリキャッシュや新しいcircuit breakerなどのような機能を追加してあります。 Senseのナレッジベースは最新のAPIを含むものに拡張されています。 また、Shieldのリリースに向けた準備として、HTTPsのサポートも追加しました。\nアップグレードのために、Elasticsearchの全てのノードに最新版のMarvelプラグインをインストールする必要があります。 また、他のJavaプラグインと同様に、Marvelの新バージョンを有効にするために、各ノードを(1台ずつ)リスタートする必要があるでしょう。 アップグレードプロセスについての詳細は、Marvelドキュメントをごらんください。\nまとめとして、ここに本リリースに関する改善点をいかにリストアップしておきます。\nagent 追加: httpsのサポート デフォルトのMarvelの設定(以前は常に9200)ではなく、ローカルノードのポートを自動的に検出 改善: marvelインデックステンプレートに関するエラーチェックと耐障害性(それに対するチェックと追加時のチェック) エラーログに関するくり返しの抑制 URLパラメータによるインデックス名を指定する_bulk exportコマンド。これは、rest.action.multi.allow_explicit_indexがfalseに設定されているときに有用 修正: ES 1.4.0のtribe nodeがMarvelのインストール時に初期化されない問題 削除: UIで表示されないoptional shard level statsを除去 monitoring ui 追加: ES 1.4.0で導入された新しいcircuit breakerを追加 circuit breakerのlimitをグラフにプロット QueryCacheのグラフを追加 index throttlingのグラフの追加 Index writerとバージョンのmapのメモリ使用量のグラフの追加 修正: Network Transport Bytes Receivedグラフに実際の送信量を表示 Node Statsダッシュボードでいくつかのスレッドプールの不足 sense 追加:\nmappingsをインデックスでオートコンプリートするしないの設定を可能に Cluster Reroute API Search APIのQuery Cacheパラメータ Analyze API Validate Query API Put Percolator API cluster.routing.allocation.*設定 Function Scoreクエリのweightパラメータ Flush API Terms Aggregationのshow_term_doc_count_errorパラメータ Update API _geo_distanceソートオプション Significant Terms aggregationを1.4.0にアップデート Mapping APIにメタデータフィールドを追加 Get Index API Scripted Metric Aggregation simple_query_stringクエリ More Like Thisクエリを1.4.0にアップデート has_childクエリ/フィルタのmin_childrenとmax_childrenオプション terms aggs/significant terms aggsのヒントオプション Mappings APIのtransform インデックスされたscriptとtemplate \u0008* Geo Bounds aggregation Top Hits aggregation Terms aggregationのcollect_modeオプション Percentiles Rank aggregation Disk Threshold Allocator設定 修正:\nURLオートコンプリートの挙動(プロトコルとホストのような組み合わせ) nested typeマッピングのinclude_in_parentとinclude_in_rootの不足 Rangeフィルタでのgt、gte、lt、lte Existsフィルタのオートコンプリート Snapshot、Restore APIのリポジトリ設定の時オートコンプリートの失敗 いつものように、Elasticsearch Marvelを改善するために、フィードバックをお待ちしています。 ElasticsearchユーザMLやTwitterに質問や意見お送りください。\n","date":1418890008,"dir":"post/2014/","id":"7dea465ad52758b10cbceb08c81d1760","lang":"ja","lastmod":1418890008,"permalink":"https://blog.johtani.info/blog/2014/12/18/marvel-1-3-0-released-ja/","publishdate":"2014-12-18T17:06:48+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:marvel 1.3.0 released 12/17に、Elasticsearch Marvel 1.3.0をリリースしました","tags":["elasticsearch","marvel"],"title":"Marvel 1.3.0リリース(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:elasticsearch 1.4.3 and 1.3.8 released\n本日、Lucene 4.10.3をベースにしたElasticsearch 1.4.3と、セキュリティフィックスとバグフィックスリリースである、Elasticsearch 1.3.8をリリースしました。 ダウンロードおよび変更リストはそれぞれ次のリンクからアクセスできます。\n最新ステーブルリリース:Elasticsearch 1.4.3 1.3.x系バグフィックス:Elasticsearch 1.3.8 過去のリリースに関するブログ(公式)はこちら。\n1.4:1.4.1, 1.4.0, 1.4.0.Beta1 1.3:1.3.6, 1.3.5, 1.3.4, 1.3.3, 1.3.2, 1.3.1, 1.3.0. すべての変更については1.4.2のリリースノートおよび1.3.7のリリースノートをごらんください。 以下では、重要な変更について紹介します。\nbug fixes Elasticsearchに対して広範囲にわたってランダムなテストを行っています。以下の問題を見つけ、修正するのに役立っています。\nプライマリシャードを持つnodeがレプリカシャードをプライマリから復旧している間に、リスタートした場合に、プライマリ上のトランザクションログが削除されデータをロスする(#8917) scriptインデックスが普及した場合に、ScriptService全体がデッドロック(#8901) Index Writerのロックを強制的に解放することによるシャードの破損(#8892) パフォーマンス改善 複雑な設定をもつ大きめのクラスタをもつユーザは、小さなスケールではわからない性能ボトルネックに直面します。 彼らの報告が次の改善をもたらす助けとなりました。\n使用可能なディスク空間に基づいてシャードの配置を決定する、disk allocation deciderの速度改善とクラスタリスタート後のリカバリ速度の改善(#8803) 以前よりも高速な共有ファイルシステムでのSnapshot生成(#8749) 不要なクラスタ状態変更の削減とそれによるネットワークトラフィックの削減およびリカバリの速度向上(#8933, #8413) index stats APIはシャードリカバリによるブロックしない(#8910) 試してみてください。 ぜひ、Elasticsearch 1.4.2をダウンロードして、試してみてください。 そして、感想をTwitter(@elasticsearch)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1418880374,"dir":"post/2014/","id":"bce2fa6458f39a75e2713f3d687271a1","lang":"ja","lastmod":1418880374,"permalink":"https://blog.johtani.info/blog/2014/12/18/elasticsearch-1-4-2-released-ja/","publishdate":"2014-12-18T14:26:14+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:elasticsearch 1.4.3 and 1.3.8 released 本日、Lucene 4.10.3をベースにしたElas","tags":["elasticsearch"],"title":"Elasticsearch 1.4.2および1.3.7リリース(日本語訳)"},{"contents":"「【東京】JJUG ナイト・セミナー「機械学習・自然言語処理特集!」12/17(水)開催」でLuceneの話をしてきました。 本当にごく簡単な入門です。 Luceneをさわるきっかけにしてもらえたら嬉しいです。\nそのほかにも面白い話が聞けましたので、簡単ですがメモを。\nJJUGの2014年振り返り だいたい、毎月ナイトセミナーかCCCを開催 イベント系に、のべ3100名が参加 Java でカジュアルにはじめる機械学習 小宮 篤史さん(スマートニュース株式会社) スライド:#JJUG - Java でカジュアルにはじめる機械学習\nブログ:#JJUG ナイトセミナー「機械学習・自然言語処理特集!」で Java でカジュアルに機械学習する話をしてきました\nガチの人は寝ててください。 機械学習でできること 分類・識別 予測・回帰 パターンマイニング・アソシエーションルール クラスタリング 上2つは教師あり学習/下2つは教師なし学習 データとしては、日構造では扱えないので、「特徴量」を抽出して「特徴ベクトル」を作って、処理をするのが機械学習 得られた結果の正しさの測定などなど\n機械学習の実装は辛いので、車輪の再発明をやめましょう! \u0008Javaで使える機械学習\nWeka:とりあえず使ってみるならこれ? MLlib:Sparkで使われてる Mahout:オワコン? SAMOA:Stormの上で利用できる Jubatus:Javaクライアントあり。 h2o:Deep learningをJavaでやるなら、これ。 ほかにもあったけど、スライド見ていただければ。 機械学習をはじめるのに使えるデータセット\nUCI Machine learning repository\nIris(アヤメデータ)は機械学習界のHello world Wekaを使ったサンプルコード\nSpark/MLlibではじめるスケーラブルな機械学習 猿田 浩輔さん(株式会社エヌ・ティ・ティ・データ) スライド:(後日、リンクがあれば更新予定)\n\u0008* Spark+MLlibを語る上で外せない話題\nHadoopとの違い?\nまずはHadoopの話\nHadoopによるK-meansのデモ\nHadoopの問題点に対するSparkの解決策\nSpark 1.0系からJava8で書ける\nQA:\nQ: データをキャッシュできるという話でしたが、キャッシュするということは、ジョブが途中で失敗した場合は最初からやり直しになるのでしょうか? A: キャッシュしたデータが残っている場合は、途中から再開出来ます。キャッシュしたデータを持ったマシンがこけたら、最初からやり直しです。\nLuceneと日本語の検索 自分 スライド:Luceneと日本語の検索 サンプルのリポジトリ:jjug-example\n自然言語処理にからめて何か話をしてくださいと話を受けていたのですが、自然言語処理については「形態素解析」くらいしか出てこなかったですけど。。。 Luceneがどんなものかを超概要で話をしてみました。少しでもLuceneがどんなものかをわかってもらえたら嬉しいです。\nもっと詳しく知りたい方は、スライドにある参考資料などを見ていただければと。\nJavaで書くのもいいんですが、もっと簡単に検索したい場合はElasticsearchを使うのが便利ですよ!で締めくくりたかったのですが、発表では失敗してしまいました。。。 Elasticsearchの起動からデータ登録、検索まではこちらのスライドを見ていただければ簡単さがわかると思います。\nまた、Kuromojiを利用した時に、Tokenizerなどが出力するTokenの品詞情報を見たい場合に便利なElasticsearch用プラグインも作っています。 こちらも、Elasticsearchと一緒に使ってみてください。\nまとめ 機械学習に関していろんなツールがあるのだなぁと。 懇親会でもちょっと話しましたが、アルゴリズムの選定とか、アルゴリズムに適したデータの作成など、前処理のノウハウとかが大変そうだなぁといつも思います。 機械学習はいつもぼやーっとしか理解してないので。。。\nJJUGさんはYouTubeの動画もあるようなので、過去の面白そうなセミナーも合わせてみてみると面白いと思います。\n毎度のことですが、なんでも良いので、発表した後のフィードバックをいただけるとうれしいです。 今後の励みや改善につながるので。\n","date":1418809314,"dir":"post/2014/","id":"e5390751969ab21df280b7591854b89f","lang":"ja","lastmod":1418809314,"permalink":"https://blog.johtani.info/blog/2014/12/17/jjug-night-seminar-dec-2014/","publishdate":"2014-12-17T18:41:54+09:00","summary":"「【東京】JJUG ナイト・セミナー「機械学習・自然言語処理特集!」12/17(水)開催」でLuceneの話をしてきました。 本当にごく簡単な入","tags":["elasticsearch","jjug"],"title":"JJUG ナイトセミナーでLuceneの簡単な紹介をしてきました。#JJUG"},{"contents":"たまには、他愛のないブログを。\n仕事しながら、コーヒーを飲んでます。\n最近は、サムライズムさんのオフィスに入り浸って仕事してます。 オフィスには、コーヒーミル付きのコーヒーメーカーがあるんです。\n↓こんな感じ(現物は違うけど)\nで、近所のコーヒー問屋で豆を買ってきてます。 そこのマスターに、いつもサジェストされるんです。\n「この豆は、日が経つにつれて、細かく挽いて飲んでください。」\n「この豆は、細かめに挽いて飲むのがオススメです。」\nなどなど。 オススメされるんですが、全自動のコーヒーメーカーは残念ながらここまでやってくれません。\nということで、手動のミルを買ってみました。家でも使えるし。\nちょっと考え事しながらとか、頭の切り替えに、ミルを回すのもいいかなと。 気持ち、美味しいコーヒーな気がします(気のせいかも)\n","date":1418698892,"dir":"post/2014/","id":"05330c3703d0e2c96cfe657ab33f130c","lang":"ja","lastmod":1418698892,"permalink":"https://blog.johtani.info/blog/2014/12/16/a-coffee-break/","publishdate":"2014-12-16T12:01:32+09:00","summary":"たまには、他愛のないブログを。 仕事しながら、コーヒーを飲んでます。 最近は、サムライズムさんのオフィスに入り浸って仕事してます。 オフィスには、","tags":["misc","coffee"],"title":"コーヒーブレイク"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:exciting logstash plugin ecosystem changes\nLogstash 1.5.0 Beta 1(お試しはこちら)のリリースで、 プラグインのインストール、管理、公開の方法を変更しています。 ユーザやコミュニティからフィードバックをもらいました。 その目的は、プラグインの利用や開発をより簡単にすることです。 このプロジェクトは始まったばかりです。プラグインのコミュニティを探し、 共有するためのワンストップソリューションを提供するこのアイデアを改善していく予定です。 このブログで、この決定を行った理由を説明し、新しいワークフローをと今後のロードマップを説明します。\nプラグインがあります! Logstashは、プラグイン(input、filter、output、codec)が豊富にあります。 これらは、Elasticsearchにより開発されたものと、コミュニティからコントリビュートされたものです。 Logstashの主な特長の1つは、これらのプラグインの有効性と動作を拡張するプラグインを追加するのが簡単なことです。 現在、165以上のプラグインがエコシステムにあり、これらは、2つのプロジェクトに分かれています。\nlogstash-coreは最もよく使われるプラグインで、Logstashにデフォルトで含まれます logstash-contribはコミュニティにより開発されたプラグインを含み、別途ダウンロードできます 新プラグインエコシステムの変更 1.5.0では、全てのプラグインは、Logstashコアから分離され、rubygemsを使って個別にパッケージングされます。 rubygemsを選択したのは、依存関係のあるライブラリの配布とパッケージングがパワフルで一般的なものだからです。 さらに、rubygems.orgプラットフォームは配布や探索に影響があります。 また、Logstashにプラグインをインストール、アップデート、削除するのが簡単な基盤も追加しました。 contribプロジェクトは徐々に終了します。全てのプラグインは個別のプロジェクトになります。\nプラグインエコシステム変更の理由 多数のプラグインをもっていると、配布と公開に関して難題が出てきます。 私たちが変更するに至った理由は次のようなものです。\n現在は、プラグインの更新に伴い、Logstashの新バージョンのリリースが必要 開発者は、Logstashのリリース間隔とは別に、新バージョンをリリースをしたい プラグイン開発者は、外部依存を記述できるようにしたい Logstashコアの配布パッケージのダウンロードサイズを小さくし、ユーザは必要なプラグインのみインストール logstash-contribを1つのリポジトリとして管理するのは難しい 詳細: ソースコードの場所 Logstashのソースコードは、今後も現在のGitHubのリポジトリのままです。 しかし、プラグインに関するコードやテストコードは含まなくなります。 この分離により、個別のプラグインの改善と同様にコアの改善に集中できます。 これにより、Logstashプロジェクトの全体の品質も向上します。\n全プラグインのソースコードは、新しいGitHub organization、logstash-pluginsにて管理します。 各プラグインは個別のリポジトリとして、ここに配置されます。 一見すると、これはメンテナンスが難しくなるように思えます。しかし、テスト、Issue、依存関係を明確にすることができます。 私たちの目的は、テスト、ドキュメント、gemの公開の自動化であり、これを簡単にするためのツールを追加します。\nしかし、プラグインの開発者はプラグインのソースコードソースコードをlogstash-pluginsに置く必要はありません。 ー コミュニティで利用可能にするために、rubygems.orgでそれを公開するだけで良いです。\nワークフロー ここで、新プラグインエコシステムのやりとり/ワークフローについて、いくつかの観点から説明します。\nlogstashユーザ: ユーザは、これまでのリリース同様にLogstashのバイナリをダウンロードします。 Logstash 1.5.0は、1.4.2でパッケージされていたプラグインと同等のものが含まれています。 新しいシステムに簡単に移行できるようにです。 そして、ユーザは、最初のデプロイの後に、Logstashプラグインのをインストール、アップグレードできるようになります。\n$LS_HOME/bin/pluginスクリプトがプラグイン操作に関連するコマンドになります。\nプラグインのインストール プラグインのほとんどはgemとしてrubygems.orgにアップロードされます。 例えば、もしユーザがApache Kafka outputプラグインをインストールする場合、次のコマンドを実行します。\nbin/plugin install logstash-output-kafka または、ファイルをダウンロード済みの場合は次のコマンドとなります。\nbin/plugin install /path/to/logstash-output-kafka-1.0.0.gem プラグインの削除 bin/plugin uninstall logstash-output-kafka 1つまた全プラグインのアップデート bin/plugin update bin/plugin update logstash-output-kafka プラグインのリストアップ bin/plugin list bin/plugin list elasticsearch ( List all plugins containing a name ) bin/plugin list --group output ( list all outputs ) ドキュメント プラグインが個別に管理されても、全プラグインのドキュメントは1カ所です。\nlogstash plugin開発者: プラグイン開発者と作者は、Logstashエコシステムのためにプラグインを公開することができます。 プラグインは、gemやJavaライブラリの依存関係を宣言できます。 より重要なのは、Logstashのリリース間隔に関係なく、プラグインの改善版をリリースできます。\nRubygemsテクノロジはパッケージングシステム、依存関係管理、ホスティングのために選択されてきました。 Rubyのgemを公開することに慣れている開発者は、Logstashプラグインを簡単に公開することができます。 Elasticsearchはこれらの機能に関して開発者を支援するために、ツールを提供、メンテナンスします。\n開発およびローカルでのテスト JRuby 1.7.16がプラグインを開発するための唯一の前提条件です。 プラグインにパッチを提供するのは以前と同様です。 例えば、logstash-output-kafkaにパッチを送るのは次のようになります。\ngit clone https://github.com/logstash-plugins/logstash-output-kafka.git 変更 プラグインをローカルでテスト bundle install bundle exec rspec Logstashの他のバージョンもしくはローカルでテストする場合、Gemfileを編集し、 次のように別のロケーションを加えます。gem \u0026quot;logstash\u0026quot;, :github =\u0026gt; \u0026quot;elasticsearch/logstash\u0026quot;, :ref =\u0026gt; \u0026quot;master\u0026quot; 新しいPull Requestをlogstash-output-kafkaに対して作成 コミュニティでコードレビューを受け、Elasticsearchがパッチを受け入れ バージョン バージョン情報は、それぞれのプラグインの.gemspecで管理します。 例えば、Apache Kafka outputのgemspecはこちらです。 バージョニングはsemantic versioningのルールに従い、 Logstashのバージョニングとは別に、プラグインの開発者によって管理されます。 Logstash 1.5.0がリリースされると、マイルストーン1のプラグインはバージョン1.0.0となり、マイルストーン2のプラグインはバージョン2.0.0となるでしょう。\n公開 開発者が変更を加えプラグインを公開したいと思った時、.gemspecのバージョン番号を変更します。 全テストが成功した時、Elasticsearchはrubygems.orgにプラグインを手動で公開します。 もし、テストが失敗した場合、プラグインは公開されません。 長期的には、プラグインの公開の自動化を行いたいと思っています。 この変更は新しいため、公開の自動化を提供する前に、自動化についてより理解し、プラグインのテスト基盤を改良したいと思っています。\nIssue Issueは、各プラグインのGitHubリポジトリに対してオープンなければなりません。 Logstashコアのリポジトリは、コアのパイプラインや共通的な機能に関連するIssueについて扱います。\nドキュメント プラグインのドキュメントはソースコード自体から生成されます。 それぞれのプラグインのドキュメントは、そのプラグインのリポジトリに含まれます。 Elasticsearchは elasticsearch.org/guideに全てのプラグインのドキュメントを集め生成できる基盤を提供します。\n移行 全ての新しいpull requestとissueはlogstash-plugin organisation配下にある各プラグインのリポジトリに対してオープンする必要があります。\nすでにあるPRはどうすれば良いですか? 気にしないでください。すでにあるpull requestは開発者によって移行する必要はありません。 LogstashチームがLogstashコアリポジトリに対してのPRを、個別の関連するプラグインのリポジトリに対してマージします。\ngit clone … # clone the specific plugin repo # now apply the patch curl -s https://github.com/elasticsearch/logstash/pull/XXXX | git am --3way git push Note:このプロセスはすでにあるPRに対してgit historyを管理します\nGitHub Issue 現在、LogstashリポジトリにオープンされているIssueは、それぞれのプラグインのリポジトリに移行します。 Logstashチームがgithub.com APIを利用してこの処理を自動的に行います。 安心してください。私たちが個別のプラグインに対する既存のIssueを移行します。\n今後のロードマップ これは、最初のステップであり、これらの変更は、ユーザや開発者に対してエコシステムをよりよくするために、 しっかりとした基盤を提供します。\n短期的には、開発者のためにpull requestのフィードバックでテスト自動化を提供する基盤を追加していきます。 プラグインリポジトリのブートストラップや管理のためのツールも提供していきます。\n長期的には、すべてのLogstashプラグインを探し、公開するためのコミュニティポータルを提供したいと思っています。 このアイデアは、Puppet ForgeやAWS marketplaceのようなものです。\nLogstash 1.5.0 Beta 1をリリースし、これは新しいエコシステムを提供します。 ぜひ、試していただき、これらの変更に関して感じたことを教えてください。 あなたのフィードバック(TwitterもしくはGitHub)はとても貴重です!\n","date":1418486440,"dir":"post/2014/","id":"4a3c42c9c5ac29db268010bbebf4f579","lang":"ja","lastmod":1418486440,"permalink":"https://blog.johtani.info/blog/2014/12/14/plugin-ecosystem-changes/","publishdate":"2014-12-14T01:00:40+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:exciting logstash plugin ecosystem changes Logstash 1.5.0 Beta 1(お試しはこちら)のリリースで、 プラグインのインストー","tags":["logstash"],"title":"Logstashプラグインのエコシステムの変更(日本語訳)"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:logstash 1.5.0.beta1 released\nLogstash 1.5.0 Beta1をリリースしました。こちらのページからダウンロードできます。\nNote: ベータリリースです。本番環境では使用しないでください。\n1.5.0の主な変更点は? 1.5.0の主なテーマはプラグイン管理、パフォーマンス改善、Apache Kafkaインテグレーションです。Logstashの主な特徴の1つは プラグインを利用できることであり、パイプラインの動作を拡張するためにプラグインを追加するのが簡単なことです。 このリリースで、プラグインの開発、管理、公開がより簡単になります。 また、Logstashの速度をより良くしたため、より多くのデータを短時間に処理することができます。 興味ありませんか?では、詳細を見ていきましょう。\nplugin ecosystemの変更 Logstashは165ものプラグイン(inputs、filters、outputs、codecs)を持っており、 これらはElasticsearchとコミュニティからのコントリビュートで開発されています。 多くのプラグインを管理することは、使いやすさと素早さの間のトレードオフがあります。 Logstashの全てのプラグインをまとめることは使いやすさがある一方、プラグインの更新を取り込むために Logstashの新しいリリースを待ってもらうことになります。 Logstashからプラグインを分離して個別に配布する場合、更新は簡単になりますが、使いやすさ(特に新しいユーザに)に影響が出ます。\n私たちは、プロジェクトを前進させるために、これらのバランスをとることを考えました。 これまで、全ての利用可能なプラグインは’core’と\u0026rsquo;contrib\u0026rsquo;の2つに分割していました。 \u0026lsquo;core\u0026rsquo;にあるよく使われるプラグインは、Logstashに含めていました。 コミュニティによりコントリビュートされたプラグインは\u0026rsquo;contrib\u0026rsquo;パッケージとして分離して配布していました。 1.5.0のリリースで、ユーザに対してより良いプラグイン管理をできるように変更しました。 全てのプラグインは、それ自身によるパッケージに移行しました。 パッケージングフレームワークとしてrubygemsを使い、rubygem.org経由でこれらのプラグインを配布、公開します。 また、Logstashにプラグインのインストール、更新、削除を簡単にするための構造も追加しました。\n例えば、S3 output pluginをインストールするには、以下のコマンドを実行します。\n$LS_HOME/bin/plugin install logstash-output-s3 それだけです!Logstashがgemと依存するgemをrubygems.orgからダウンロードし、インストールします。 あなたは、S3にデータを送ることができるようになります。\nダウンロード可能なLogstashリリースはプラグインをまだ多く含んでいますが、 いつでも、個別にプラグインをアップグレードし、インストールすることができます。 プラグインエコシステムの変更に関する詳細のブログ記事をお待ち下さい。\nパフォーマンス改善 Logstash 1.5.0はより高速になっています。パフォーマンスが改善された2カ所について説明します。\ngrok filter Grok filterはLogstashで、構造化データを抽出するためにパターンを記述するのに使われます。 本リリースで、人気のある幾つかのパターンのgrok filterのスループットを100%に改善しました。 言い換えると、grok filterを使うときに、Logstashを通してより多くのデータを処理することができます。\n私たちのベンチマークテストで、1.5.0と1.4.2のスループットの比較をしました。 利用したデータは690万件のApache Webアクセスlogで、COMBINEDAPACHELOGのgrok patternです。 1.5.0で、スループットは34,000 event per sec(eps)から50,000 epsに増加しました。 両方のテストを8コアのマシンでLogstashで8つのワーカーを実行しました。 これらのテストで、一つのgrok filterを実行し、 stdinとstdoutを使ったパイプラインでイベントのスループットを計測しました。 全体的なパフォーマンスは、様々なハードウェアやLogstashのコンフィグによって変化することに注意してください。\njson serialization / deserialization JSONのシリアライズ/でシリアライズをJrJacksonライブラリを利用して実装しました。 これにより、100%以上のスループットの改善がありました。 先ほど説明したパフォーマンステストにおいて、1.3KBのサイズの500,00 JSONイベントを送信し、 16,000 epsから30,000 epsにスループットが改善しました。 45,000サイズのイベントで、850 epsから3500 epsにスループットが増加しました。 すばらしいです。\napache kafka integration いまでは、Apache Kafkaが大規模スケールデータ処理システムでよく利用されます。 Logstashの配備のスケーリングにおいて、Kafkaもまた、shippingインスタンスとindexingインスタンス間の データを保存するための中間メッセージバッファとして使うことができます。\n1.5.0で、Logstash Kafkaのinputとoutputのプラグインのビルトインサポートを追加しました。 これは、Joseph Lawsonによって最初に開発されました。 私たちは、これらのプラグインにインテグレーションテストとドキュメントを追加することにより改良し、 新しいKafkaの機能を開発し続けます。 また、Apache Avro codecを追加することで、Kafkaに保存されたイベントを 簡単に取得でき、ELKスタックを使ってそれらを解析できるようにしました。\nKafka inputを追加するのは次のコマンドです。\n$LS_HOME/bin/plugin install logstash-input-kafka Kafka outputは次のコマンドです。\n$LS_HOME/bin/plugin install logstash-output-kafka セキュリティに関する改善 認証と経路暗号化のサポートを追加し、Elasticsearchのoutput、input、filterのセキュリティを改良しました。 例えば、HTTPプロトコルでSSL/TLSにより暗号化を有効にでき、 HTTPベーシック認証をユーザ名とパスワードをリクエストに与えることで設定できます。 これらの機能は、時期にリリースされるElasticsearch ShieldセキュリティプロダクトとLogstashを統合できます。\nドキュメント これまで、Logstashのドキュメントは[logstash.net])(http://logstash.net/)に置いてあり、 他のELKスタックと一緒に動かす時に、情報を探すのが厄介でした。 1.5.0および、今後のバージョンのドキュメントはelasticsearch.orgのLogstash Guideに移行します。 この移行でelasticsearch.org/guideにELKスタックを利用、 学習するためにドキュメントが1つになりました。 このベータリリースのイテレーションで、私たちはプレゼンテーションとドキュメントの品質を改善することに活発に取り組んでいきます。 (過去のLogstashのドキュメントの全てはいままでのlogstash.netで引き続き公開していく予定です。)\nバグフィックスと改善 ここまでの新しい機能に加えて、Logstash 1.5.0では、多くのバグフィックスと多くの機能改善があります。 ここで、これらのいくつかを紹介します。\n出力しない\u0026rsquo;metadata\u0026rsquo;をイベントに格納可能に。これは、例えば、date filterに使う中間フィールドのために必要。(#1834, #LOGSTASH-1798) HTTPを利用しているときのファイルデスクリプタリークの修正。Logstashがストールするのを防ぎ、OOMエラーからクラッシュするケースも防ぎます。(#1604) Twitter input:full_tweetオプションの追加、Twitter rate limitingエラーのハンドリング(#1471) イベントを生成するfilter(multiline、clone、split、metrics)により、 後続の条件文にこれらのイベントを正しく伝搬(#1431) Elasticsearch output:Logstashはデフォルトでmessage.rawフィールドを作成しない。messageフィールドはElasticsearch によりnot_analyzedでマルチフィールドとして追加される。マルチフィールドはディスクスペースが2倍必要だが、利点がない。 bin/logstashの複数のサブコマンドを除去(#1797) これらの機能、改善、バグフィックスについては、Logstash 1.5.0.Beta1 のchangelogをごらんください。\n試してみてください! ぜひ、Logstash 1.5.0 Beta 1をダウンロードして試してみてください。 そして、感想をTwitter(@elasticsearch)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1418372246,"dir":"post/2014/","id":"1bc36080b2493aab78c26e4f2152542c","lang":"ja","lastmod":1418372246,"permalink":"https://blog.johtani.info/blog/2014/12/12/logstash-1-5-0-beta1-released-ja/","publishdate":"2014-12-12T17:17:26+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:logstash 1.5.0.beta1 released Logstash 1.5.0 Beta1をリリースしました。こちらのページからダウンロードで","tags":["logstash"],"title":"Logstash 1.5.0 Beta1リリース(日本語訳)"},{"contents":"早いもので、師走です。今年もあと少しとなりました。ということで、Advent Calendarの季節が始まりました。\nこの記事はElasticsearch Advent Calndar 2014の1日目のエントリです。\n1日目ということで、簡単に今年の変遷を振り返りつつ、今年導入された新機能についてピックアップしてみようかと思います。\n1.0リリース(Lucene 4.6.0) 今年一番の目玉と思いますが、1月にRCが公開されて、1.0.0が2月にリリースされました。 (ElasticSearch Serverの翻訳が昨年末に終わってレビューをしていた段階での発表だったので個人的にはきついタイミングでした) 1.0の主な変更点はこちら。\nElasticsearch(Sが小文字に) 1.0からSが小文字になりました。(#4634) 0.90以前のバージョンについては、Sが大文字になっています。 ややこしいですが、今年の3月に出版された黒いElasticSearch Server日本語版は原著が0.20で日本語版にするタイミングで0.90に対応しました。 このため、こちらの書籍のタイトルはSが大文字となっています。 (なお、原著の2nd Editionは小文字になっています)\nSnapshot/Restoreの導入とGatewayの廃止 0.90以前のバージョンでは、gatewayというモジュールで、S3などにインデックスのメタデータなどを保存する機能がありました。 この機能は、0.20からlocal以外はdeprecatedとなりました。\nインデックスのバックアップ、リストアのために、1.0で実装されたのがSnapshot/Restoreです。 Snapshot/Restoreでは、インデックスごと、もしくはクラスタ全体をリモートにあるリポジトリにスナップショットを取ることが可能となりました。 初期リリースの段階では、共有ファイルシステムのみでしたが、現在は、S3やHDFSなどに保存が可能となっています。\nAggregation Facetをより強力にしたものです。Facetでは、指定したフィールドの集計のみでした。 データの解析などを行うには、独自で集計する必要がありました。 この機能をより柔軟に行えるように実装したのがAggregationです。\nたとえば、アクセスログを日毎に集計し、さらに日毎の集計に対して国別の集計やユーザエージェントごとの集計をさらに行うといった感じです。 Facetの場合は、日毎の検索結果に対して個別に集計するのみでしたが、Aggregationを使うことで、1週間の検索結果に対して、 日毎に国別の集計を行うといったことが可能になっっています。\ncat API \u0026ldquo;=^.^=\u0026ldquo;猫が出てくるAPIです。(違う)\nElasticsearchでは、クラスタの状態などが全てREST APIで取得でき、JSONで結果が帰ってきていました。 JSONはプログラムなどで処理を行う場合は便利ですが、コンソールで確認したり、管理系のツールでメールで通知する場合などは見にくいことがあります。 これを解消したのが_cat APIです。(公式の紹介ブログはこちら)\nCircuit Breaker OOMが発生しそうなfielddataの読み込みを検知して、事前に防ぐ機構になります。 初期段階ではFielddataに対してのものから実装されました。\n1.1リリース(Lucene 4.6.1) 3月にリリースされました。Elasticsearchはまだまだ発展しているため、リリースのサイクルが短いのが特徴です。\n1.x系では、Rolling Upgradeが導入されました。このため、クラスタ全体を停止することなく、クラスタのアップグレードが可能になりました。\nsearch templates 検索クエリをテンプレートとして登録することができるsearch templatesです。 JSONでクエリを記述できるのは便利ですが、毎回組み立てるのは大変かもしれません。 特に、固定のクエリをプログラムから利用するような場合などです。 テンプレートとして登録しておくことで、検索時に値を埋め込むだけで検索ができるようになりました。\nAggregationの強化 Aggregationの種類が増えました。\ncardinality:ユニークユーザ数の集計などが行えるaggregationです。HyperLogLog++アルゴリズムを利用した実装になっています。 significant_terms:単語の数による集計ではなく、コレクション全体に対する単語の頻度と、検索結果に対する単語の頻度を計算することで、重要度を計ることができます。 percentiles:パーセンタイル値を計算できます。 1.2リリース(Lucene 4.8系) Java 7必須 利用しているLuceneがJava 7必須となったためです。また、Java 6のEOLも切れてますし。\ndynamic scriptingがデフォルトオフ 採用していたMVELがサンドボックス化に対応していないため、危険を回避するためにオフとなりました。\nインデキシングとマージング インデキシングとマージ処理に関するさまざまな改善。\nflushのthreasholdを操作回数ではなく、サイズや時間によるものに変更 デフォルトをConcurrentMergeSchedulerに変更 1.3リリース(Lucene 4.9.0系) セキュリティ関連 JSONPのデフォルトオフ MVELの非推奨化(1.4で削除)+script.disable_dynamicのデフォルト値がsandbox aggregationの強化 top hits:Field Collapsing/combiningと呼ばれる機能です。たとえば、いくつかのサイトのHTMLを収集して検索機能を提供する場合に、ドメインごとに1件ずつ検索結果に出したい場合などに利用できる機能です。 その他にも以下のaggregationが追加されています。\npercentile ranks geo bounds mappingのtransform Mappingにtransform機能が追加されました。 mappingにドキュメントの値を元に、インデキシング時に変換処理を記述できます。 たとえば、特定のフィールドにある値がある場合にだけ、あるフィールドに値を入れるなどといったことが可能になります。\nディスク関連 disk based shard allocation deciderが導入されました。ノードのディスクの使用率を元に、シャードを配置しても良いかといった決定を行う機構です。 チェックサムによるファイルのチェック(Lucene4.9で導入されたコードへの切り替え) 1.4リリース(Lucene 4.10系) ベータ版が出されるほど、多くの改善が入っています。\nresiliency メモリ使用量の低下によるノードの安定性向上 DocValues、リクエストごとのcircuit breakerなど discoveryアルゴリズムの改善によるクラスタの安定性向上 チェックサムの導入による破損したデータの検知 セキュリティ関連 CORSをデフォルト無効 Groovyがデフォルトのスクリプト言語に。 Aggregationの強化 以下のaggregationが追加されています。\nfilter、children、scripted_metric Upgrade API インデックスを最新のバージョンのものにアップグレードするためのAPIです。 Luceneは下位互換を保ってくれているため、古いバージョンのインデックスも読み込むことが可能です。 ただ、最新バージョンで使える機能が制限されていたりということもあります。 クラスタにあるインデックスをアップグレードするのにかかる時間や必要かどうかといったことを取得できる仕組みも提供します。\nまた、Lucene自体は、1つ前のメジャーバージョン(4.x系だと3.x系まで)までの互換性は提供していますが、 2つ前のメジャーバージョンの互換性がなくなります。 Luceneも5.x系のブランチが作成されており、5系のリリースにより、3系との互換性がなくなります。 5系のリリースに対応する場合にも、こちらのAPIが助けになるかと。\n1.4.1 11\u0008/27に1.4.1がリリースされました。 シャードの配置やparent/child、nestedドキュメントの改善などが行われています。\nまとめ ということで、駆け足で、1月から11月までのElasticsearchの流れを追ってみました。 1.0で大きな機能追加、改善が行われ、その後も活発に開発が行われています。 要望などがあれば、MLで聞いてみたりやGitHubに登録するなどを行っていただければと。\nあと、今年から来年にかけての大きなイベントとして、 Elasticsearch初のユーザカンファレンスのサイトがオープンしました。 Elasticsearchに関するいろいろな話が聞ける機会だと思うので、興味のある方は見ていただければと。\nでは、また次のAdvent Calendarで!(最終日の予定ですが、空きがあるのでなにか書くかも)\n","date":1417424748,"dir":"post/2014/","id":"2de582c67fca31500621ecd6d3917a07","lang":"ja","lastmod":1417424748,"permalink":"https://blog.johtani.info/blog/2014/12/01/about-elasticsearch-in-2014/","publishdate":"2014-12-01T18:05:48+09:00","summary":"早いもので、師走です。今年もあと少しとなりました。ということで、Advent Calendarの季節が始まりました。 この記事はElastics","tags":["elasticsearch"],"title":"2014年のElasticsearch"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:elasticsearch 1.4.1 and 1.3.6 released\n本日、Lucene 4.10.2をベースにしたElasticsearch 1.4.1と、バグフィックスリリースである、Elasticsearch 1.3.6をリリースしました。 ダウンロードおよび変更リストはそれぞれ次のリンクからアクセスできます。\n最新ステーブルリリース:Elasticsearch 1.4.1 1.3.x系バグフィックス:Elasticsearch 1.3.6 過去のリリースに関するブログ(公式)はこちら。\n1.4:1.4.0, 1.4.0.Beta1 1.3:1.3.5, 1.3.4, 1.3.3, 1.3.2, 1.3.1, 1.3.0. すべての変更については1.4.1のリリースノートおよび1.3.6のリリースノートをごらんください。 以下では、重要な変更について紹介します。\nshard allocation Elasticsearch 1.3.0で、disk based shard allocationが デフォルトで有効になっています。 もし、ノードのディスクの使用量がlawで指定された値(85%)を超えた場合、ノードにはシャードが配置されません。 また、highで指定された値(90%)を超えた場合、シャードを他のノードへ移動します。\nElasticsearch 1.4.1では、disk based shard allocationに3つの改良が追加されました。\nディスク使用量のチェックはシャードがクラスタに配置されるタイミングでのみ実施していた。現在は60秒ごとに使用量をチェック。(#8270) ディスクフルメッセージはDEBUGレベルでログに出力されていました。なぜ、新しいシャードが配置されないのかを説明するのが困難でした。現在はWARNレベルで30秒ごとにログに出力されます。(#8382) 以前は、シャードをもう一つのノードへ動かすべきかどうか決めるとき、allocation deciderはノードにあるシャードのサイズを考慮するだけでした。現在は、動かされるシャードのサイズも考慮します。これにより、必要最小限のシャードの移動量となります。(#8569) parent/child and nested documents Elasticsearch 1.4.0で、parent/childとnestedドキュメントに対して(新しいセグメントを開くときに)固定長ビットセットフィルタを構築しキャッシュしました。クエリ、フィルタおよびAggregationを常に速くするためにです。 多くのnestedフィールドを持つユーザにとっては、以前のバージョンよりもヒープの使用量が大きくなってしまいました。\nnested aggregationによって処理されるドキュメントの順序を変更すること(#8454)によって、固定長ビットセットフィルタが子のドキュメントに対して必要でなくなりました。 現在は、親のドキュメント(つまり、nestedではないドキュメント)を表すフィルタのみをキャッシュしています。これにより必要なキャッシュ空間のサイズを減少しました。(#8414、#8440)\ndate ranges 2つの日付範囲に関する問題がこのリリースで修正されました。 1つ目は、日付を丸めるかというものです。例えば、timestampフィールドに1秒の解像度の値があるとします。 {\u0026quot;lt\u0026quot;: \u0026quot;2014/11/26||/d\u0026quot;}というrangeフィルタは2014/11/26 00:00:00未満のタイムスタンプのデータを結果として返しました。 しかし、ltをlteに変更した場合、2014/11/27 00:00:00以外の値も含めたいです。\n以前は、lteは2014/11/27 00:00:00のタイムスタンプも含めてしまっていました。現在は、想定通りの動作をします。(#8556)\n2つ目のバグは日付の範囲条件にnow()を利用したaliasとpercolatorフィルタです。 now()の値を、フィルタが作成したタイミングで決定していました。フィルタが実行されるたびに更新せずにです。 #8534で、now()はaliasとpercolatorで想定通りの動作をします。\n試してみてください。 ぜひ、Elasticsearch 1.4.1をダウンロードして、試してみてください。 そして、感想をTwitter(@elasticsearch)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1417056212,"dir":"post/2014/","id":"0a8183ced0e9e3e895b41286e54e8e4d","lang":"ja","lastmod":1417056212,"permalink":"https://blog.johtani.info/blog/2014/11/27/elasticsearch-1-4-1-released-ja/","publishdate":"2014-11-27T11:43:32+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:elasticsearch 1.4.1 and 1.3.6 released 本日、Lucene 4.10.2をベースにしたElas","tags":["elasticsearch"],"title":"Elasticsearch 1.4.1および1.3.6リリース(日本語訳)"},{"contents":"前回の「Logstashを利用したApacheアクセスログのインポート」の続きです。 前回の記事では、Logstashの設定ファイルについて説明しました。 今回は「Elasticsearchに設定するインデックステンプレート」について説明します。\nテンプレートの設定 Elasticsearchでは、登録するデータの特性に合わせてMappingを定義する方がデータを効率良く扱うことができる場合があります。 この場合、通常ですと、インデックス作成時にMappingを指定します。\nただ、今回は、インデックス名に「年」を含める形で指定してあります。 「年」はLogstashで処理したデータによって決まります。このため、あらかじめMappingを指定してインデックスを作成するのは難しいです。\nこのような場合に便利な機能として、「インデックステンプレート」があります。\nインデックステンプレートとは 実際のテンプレートの説明に入る前に、少しだけ説明を。 インデックステンプレートとは、インデックスが作成されるタイミングで自動的に適用される設定をテンプレートとして登録できる機能のことです。 実際にテンプレートが適用されるかどうかは、インデックス名で判断されます。\n例えば、大して重要でもなく、データ量も少ないインデックス用のテンプレートとして、シャード数が1、レプリカ数が0、\u0026quot;_source\u0026quot;を保存しない設定のテンプレートを登録する場合、 次のようになります。\ncurl -XPUT localhost:9200/_template/template_1 -d \u0026#39; { \u0026#34;template\u0026#34; : \u0026#34;te*\u0026#34;, \u0026#34;settings\u0026#34; : { \u0026#34;number_of_shards\u0026#34; : 1, \u0026#34;number_of_replicas\u0026#34; : 0 }, \u0026#34;mappings\u0026#34; : { \u0026#34;type1\u0026#34; : { \u0026#34;_source\u0026#34; : { \u0026#34;enabled\u0026#34; : false } } } } \u0026#39; _templateがインデックステンプレートを登録するためのエンドポイントです。 template_1がこのテンプレートのIDです。削除などについては、このIDを利用します。\nそして、重要なのは、\u0026quot;template\u0026ldquo;の設定です。 \u0026ldquo;template\u0026ldquo;には、このテンプレートが適用されるべきインデックス名を記載します。 上記サンプルではte*となっているため、teで始まる名前のインデックスを作成した場合にテンプレートにある設定が適用されます。\n今回利用するテンプレート 私がJJUG CCCや第7回Elasticsearch勉強会のKibana4のデモで利用したインデックスのテンプレートは次のものになります。 \u0026ldquo;template\u0026ldquo;には、前回の記事で紹介したoutput/elasticsearchの設定 に合致するnew_demo_access_log-*を指定しています。\ncurl -XPUT localhost:9200/_template/new_access_log_for_demo -d \u0026#39; { \u0026#34;template\u0026#34;: \u0026#34;new_demo_access_log-*\u0026#34;, \u0026#34;settings\u0026#34;: { \u0026#34;number_of_shards\u0026#34;: \u0026#34;2\u0026#34;, \u0026#34;number_of_replicas\u0026#34;: \u0026#34;0\u0026#34; }, \u0026#34;mappings\u0026#34;: { \u0026#34;_default_\u0026#34;: { \u0026#34;dynamic_templates\u0026#34;: [ { \u0026#34;string_template\u0026#34;: { \u0026#34;mapping\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;match_mapping_type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;match\u0026#34;: \u0026#34;*\u0026#34; } } ], \u0026#34;properties\u0026#34;: { \u0026#34;path\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;multi_field\u0026#34;, \u0026#34;fields\u0026#34;: { \u0026#34;no_analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, \u0026#34;referer\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;multi_field\u0026#34;, \u0026#34;fields\u0026#34;: { \u0026#34;no_analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, \u0026#34;agent\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;multi_field\u0026#34;, \u0026#34;fields\u0026#34;: { \u0026#34;no_analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, \u0026#34;geoip\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;location\u0026#34;: { \u0026#34;geohash\u0026#34;: true, \u0026#34;geohash_precision\u0026#34;: 10, \u0026#34;type\u0026#34;: \u0026#34;geo_point\u0026#34;, \u0026#34;lat_lon\u0026#34;: true, \u0026#34;geohash_prefix\u0026#34;: true } } }, \u0026#34;response\u0026#34;: { \u0026#34;copy_to\u0026#34;: \u0026#34;response_int\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;bytes\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;response_int\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34; } } } } } \u0026#39; settings設定 デモ用であり、手元で2台のノードを起動するということもあり、number_of_shardsに2を、number_of_replicasに0を指定してあります。\nmappings設定 インデックスのタイプ Mappingsの指定は通常、特定のタイプを指定します。 今回のデモでは、1種類しかないのですが、タイプ名を特に意識しないために、_default_を使用しました。 この場合、任意のタイプに適用されることとなります。 タイプを指定してMappingの設定を行う場合は_default_の部分に特定のタイプ名を記入します。\n\u0026#34;mappings\u0026#34;: { \u0026#34;_default_\u0026#34;: { ... ダイナミックテンプレート 次はダイナミックテンプレートです。 インデックステンプレートはインデックスの設定をテンプレート化しました。ダイナミックテンプレートはフィールドに対してテンプレートを設定できます。\n以下のダイナミックテンプレートでは、stringタイプのフィールドのデフォルト設定を変更しています。 通常、stringタイプのフィールドはanalyzedとなりますが、not_analyzedに変更してあります。 詳しく検索したいフィールドの方が少ないためです。\n... \u0026#34;dynamic_templates\u0026#34;: [ { \u0026#34;string_template\u0026#34;: { \u0026#34;mapping\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;match_mapping_type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;match\u0026#34;: \u0026#34;*\u0026#34; } } ], ... multi_field指定 検索もしたいし、Terms Aggregationでも利用したいフィールドについては、multi_fieldを利用して、 analyzedとnot_analyzedの2種類のフィールドを用意しています。 multi_field設定を用いることで、1つのJSONのデータから、異なる形のフィールドを用意することが可能です。\n今回のテンプレートでは、path、referer、agentにmulti_fieldを指定しました。\n... \u0026#34;path\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;multi_field\u0026#34;, \u0026#34;fields\u0026#34;: { \u0026#34;no_analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;analyzed\u0026#34;: { \u0026#34;index\u0026#34;: \u0026#34;analyzed\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; } } }, ... 例えば、上記の設定の場合、入力のJSONはpathというデータのみですが、インデックス上にはpath.no_analyzedと path.analyzedというフィールドができあがります。 実際に検索する場合は、path.analyzed:検索したい文字列という形で検索をすることで、いわゆる部分一致のような検索が可能です。 また、完全一致をしたい場合はpath.no_analyzed:検索したい文字列という指定になります。 用途を考えると、requestも指定したほうが良いかもしれません。\ngeoip Logstashでgeoipデータを付与していました。 このgeoipのデータをKibana4で利用するために、geoデータとして登録する必要があります。\n\u0026#34;geoip\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;object\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;location\u0026#34;: { \u0026#34;geohash\u0026#34;: true, \u0026#34;geohash_precision\u0026#34;: 10, \u0026#34;type\u0026#34;: \u0026#34;geo_point\u0026#34;, \u0026#34;lat_lon\u0026#34;: true, \u0026#34;geohash_prefix\u0026#34;: true } } }, 上記の設定がgeoデータの指定です。 typeにobjectが指定してありますが、これは、geoipのデータがネストしているためです。 geoipオブジェクトのうち、緯度経度のデータはlocationに入っているため、こちらに緯度経度関係の設定を指定します。\n\u0026quot;type\u0026quot;: \u0026quot;geo_point\u0026quot;:geo_pointタイプであることを指定 \u0026quot;geohash\u0026quot;: true:緯度経度のデータをもとに、geohashの値もインデックス \u0026quot;geohash_precision\u0026quot;: 10:geohashの精度の指定 \u0026quot;lat_lon\u0026quot;: true:緯度経度を個別の.lat、.lonというフィールドにもインデックス \u0026quot;geohash_prefix\u0026quot;: true:該当するgeohashのみでなく、その親にあたるgeohashについてもインデックスする response、response_int、bytes 最後は、response、response_int、bytesです。\nresponseには、HTTPステータスコードが入ります。 文字列としても扱いたいですが、integerとして、Renge Aggregationなどを行いたいので、 response_intというフィールドにも値を入れています。 multi_fieldでも可能ですが、ここでは、copy_toを利用しました。 copy_toを用いることで、異なるフィールドに値をコピーすることができます。\nbytesについては、longで扱いたいとういう理由だけです。\n\u0026#34;response\u0026#34;: { \u0026#34;copy_to\u0026#34;: \u0026#34;response_int\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34; }, \u0026#34;bytes\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;long\u0026#34; }, \u0026#34;response_int\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;integer\u0026#34; } まとめ 今回はデモに利用したインデックスてプレートについて説明しました。 前回の、Logstashの設定とこのインデックステンプレートを用いることで、Kibanaで解析するデータの準備ができます。 実際の操作などについては、また次回の記事で説明しようかと思います。\n不明な点、誤植などありましたら、コメント欄へお願いします。\n","date":1416900346,"dir":"post/2014/","id":"4d8f5e581eee602c7fd21da8eb68df9a","lang":"ja","lastmod":1416900346,"permalink":"https://blog.johtani.info/blog/2014/11/25/import-apache-accesslog-using-logstash-2/","publishdate":"2014-11-25T16:25:46+09:00","summary":"前回の「Logstashを利用したApacheアクセスログのインポート」の続きです。 前回の記事では、Logstashの設定ファイルについて説","tags":["logstash","kibana","elasticsearch"],"title":"インデックステンプレートとLogstash"},{"contents":"JJUG CCCや第7回Elasticsearch勉強会のKibana4のデモにアクセスログを利用しました。\nただ、セッションでは、どうやってElasticsearchに投入したのかという詳しい話をしていませんでした。 本記事では、データ取り込み時に利用したLogstashの設定ファイルについて説明します。\nLogstashの設定の説明に入る前に、全体の流れを。 「ApacheアクセスログをKibana4により可視化」です。\n材料の準備 「ApacheアクセスログをKibana4により可視化」に必要な材料は次の通りです。 (今回は起動するところまでいかないので、実際に必要なのは次回以降になります。)\nJava 7(u55以上を1つ) Logstash 1.4.2(1つ) Elasticsearch 1.4.0(1つ) Kibana4 Beta2(1つ) Apacheのアクセスログ(適量) Apacheのアクセスログ以外は、公式サイトからダウンロードできます。 それぞれをダウンロードして、起動できるようにしておきましょう。\n※1台のマシン上で行う場合は、アクセスログの量を少なめにするなどの対策をとりましょう。 ※今回は、1台のマシン(Mac)上で、VMなどを利用せず、それぞれ直接起動するものとします。\n可視化の手順と流れ 可視化の流れとしては、\nLogstashでファイルを読み込み、各種処理(パースしたり、情報を追加したり、切り出したり) Elasticsearchに保存 Kibanaでグラフを作ったり、検索してみたり です。\n今回は、1のLogstashでファイルを読み込んだりする設定ファイルの説明です。\nLogstashの設定 Logstashの基本 まずは、Logstashの設定ですが、簡単にLogstashの説明を。 Logstashは大きく3つのパーツに分かれています。\ninput:データの入力処理 filter:inputで読み込んだデータに対する操作など output:データの出力処理 inputでデータを読み込み(複数可)、filterでデータに対して各種処理を行い、outputでデータを指定されたところに出力(複数可)します。\nアクセスログの読み込み設定 アクセスログの読み込み処理は大まかに次のようなものとなります。\nアクセスログを読み込む(input/file) 読み取ったアクセスログを各フィールド(IPアドレス、ユーザエージェントなど)に分割(filter/grok) 日付のパース(filter/date) クライアントIPアドレスにgeoipの情報を付加(filter/geoip) リクエストのパスの第1階層の抽出(filter/grok) ユーザエージェントのパース(filter/useragent) Elasticsearchへの出力(output/elasticsearch) 設定ファイルは次のようなものになります。\ninput { file { path =\u0026gt; \u0026#34;/Users/johtani/demo_access_log/*/*.log\u0026#34; start_position =\u0026gt; \u0026#34;beginning\u0026#34; } } filter { grok { match =\u0026gt; { \u0026#34;message\u0026#34; =\u0026gt; \u0026#34;%{COMBINEDAPACHELOG}\u0026#34; } break_on_match =\u0026gt; false tag_on_failure =\u0026gt; [\u0026#34;_message_parse_failure\u0026#34;] } date { match =\u0026gt; [\u0026#34;timestamp\u0026#34;, \u0026#34;dd/MMM/YYYY:HH:mm:ss Z\u0026#34;] locale =\u0026gt; en } geoip { source =\u0026gt; [\u0026#34;clientip\u0026#34;] } grok { match =\u0026gt; { \u0026#34;request\u0026#34; =\u0026gt; \u0026#34;^/%{WORD:first_path}/%{GREEDYDATA}$\u0026#34; } tag_on_failure =\u0026gt; [\u0026#34;_request_parse_failure\u0026#34;] } useragent { source =\u0026gt; \u0026#34;agent\u0026#34; target =\u0026gt; \u0026#34;useragent\u0026#34; } } output { elasticsearch { host =\u0026gt; \u0026#34;localhost\u0026#34; index =\u0026gt; \u0026#34;new_demo_access_log-%{year}\u0026#34; cluster =\u0026gt; \u0026#34;demo_cluster\u0026#34; protocol =\u0026gt; \u0026#34;http\u0026#34; } } 1. アクセスログを読み込む(input/file) inputのfileモジュール(a)を使用してアクセスログのファイルを読み込みます。 pathでアクセスログのファイルのパスを指定します。 今回利用したアクセスログはdemo_access_log/2010/access20100201.logといった日毎のファイルに分割されていたため、 *を利用してファイルのパスを指定しました。 また、今回は既存のファイルの読み込みだけのため、start_positionにbeginningを指定してあります。 デフォルトではendが指定されるため、Logstashを起動後に追記されたログから対象になってしまうためです。 その他の設定については、公式ガイドをご覧ください。\ninput { file { # a path =\u0026gt; \u0026#34;/Users/johtani/demo_access_log/*/*.log\u0026#34; # b start_position =\u0026gt; \u0026#34;beginning\u0026#34; # c } } Logstashでは、ファイルをどこまで読み込んだかという情報を保持するために、sincedbを利用しています。 設定変更後に同じファイルを最初から読み込みたい場合などは、こちらのファイルを一旦削除するなどの対応が必要です。\nちなみに、読み込んだデータは次のようなJSONになっています。\n{ \u0026#34;message\u0026#34;: \u0026#34;読み込んだアクセスログ\u0026#34;, \u0026#34;@version\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;@timestamp\u0026#34;:\u0026#34;2014-11-21T06:16:21.644Z\u0026#34;, \u0026#34;host\u0026#34;:\u0026#34;jupiter.local\u0026#34;, \u0026#34;path\u0026#34;:\u0026#34;/Users/johtani/demo_access_log/2010/access20100201.log\u0026#34;} } 特に指定がない場合は、messageに読み込んだデータが入ってきます。 @timestampがLogstashが読み込んだ時刻、hostはLogstashが動作しているホスト名です。 pathはfileモジュールが読み込んだファイルのパスを設定しています。 この後の処理で、どこの項目に対して処理を行うかといったことが重要になるので、\n2. 読み取ったアクセスログを各フィールド(IPアドレス、ユーザエージェントなど)に分割(filter/grok) 2.〜6.の処理は、inputで読み込んだ1アクセスログに対する処理となります。\nここでは、grokフィルタを使用して Apacheのアクセスログを各フィールドに分割します。 Logastashでは、簡単に使えるようにいくつかのパターンが用意されています。 Apacheのログのために、COMBINEDAPACHELOGというのが用意されています。 今回はこちらを使用しています。その他にも日付などパターンが用意されているので、試してみてください。\nmessageにアクセスログが入っているので、こちらの項目に対してCOMBINEDAPACHELOGのパターンを matchで適用してフィールドに抜き出します。 tag_on_failureは、matchでパースに失敗した場合に、tagというフィールドに指定した文字列を出力する機能になります。 デフォルトだと_grokparsefailureが付与されますが、ここでは、どの処理で失敗したがを判別するために文字列を変更しています。\nfilter { grok { match =\u0026gt; { \u0026#34;message\u0026#34; =\u0026gt; \u0026#34;%{COMBINEDAPACHELOG}\u0026#34; } break_on_match =\u0026gt; false tag_on_failure =\u0026gt; [\u0026#34;_message_parse_failure\u0026#34;] } ... clientip、ident、auth、timestamp、verb、request、httpversion、response、bytes、referrer、agentがgrokフィルタにより抜き出された項目です。\n{ \u0026#34;message\u0026#34;:\u0026#34;アクセスログ\u0026#34;, \u0026#34;@version\u0026#34;:\u0026#34;1\u0026#34;, \u0026#34;@timestamp\u0026#34;:\u0026#34;2014-11-21T07:20:54.387Z\u0026#34;, \u0026#34;host\u0026#34;:\u0026#34;jupiter.local\u0026#34;, \u0026#34;path\u0026#34;:\u0026#34;/Users/johtani/demo_access_log/2010/access20100201.log\u0026#34;, \u0026#34;clientip\u0026#34;:\u0026#34;クライアントのIPアドレス\u0026#34;, \u0026#34;ident\u0026#34;:\u0026#34;-\u0026#34;, \u0026#34;auth\u0026#34;:\u0026#34;-\u0026#34;, \u0026#34;timestamp\u0026#34;:\u0026#34;01/Feb/2010:00:00:26 +0900\u0026#34;, \u0026#34;verb\u0026#34;:\u0026#34;GET\u0026#34;, \u0026#34;request\u0026#34;:\u0026#34;/images/favicon.ico\u0026#34;, \u0026#34;httpversion\u0026#34;:\u0026#34;1.1\u0026#34;, \u0026#34;response\u0026#34;:\u0026#34;200\u0026#34;, \u0026#34;bytes\u0026#34;:\u0026#34;318\u0026#34;, \u0026#34;referrer\u0026#34;:\u0026#34;\\\u0026#34;-\\\u0026#34;\u0026#34;, \u0026#34;agent\u0026#34;:\u0026#34;\\\u0026#34;Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)\\\u0026#34;\u0026#34; } 3. 日付のパース(filter/date) Logstashは特に指定がない場合、inputでデータを取り出した日付が@timestampとなります。 そして、このフィールドが特に指定がない場合は、Elasticsearchのデータの日付となり、Kibanaで利用する日付となります。\nリアルタイムにアクセスログを読み込む場合は、読み込んだ日時でもほぼ問題はありませんが、過去データの場合はそうもいきません。 そこで、dateフィルタを使用して、@timestampの値を書き換えます。\ndate { match =\u0026gt; [\u0026#34;timestamp\u0026#34;, \u0026#34;dd/MMM/YYYY:HH:mm:ss Z\u0026#34;] locale =\u0026gt; en } 上記では、timestampという項目に対してdd/MMM/YYYY:HH:mm:ss Zという日付パターンの場合に値を書き換える設定となります。 なお、日付の月の部分がFebとなっているため、localeにenを指定しています。Logstashが動作するマシンのlocaleがjaなどの場合にパースに失敗するためです。\n4. クライアントIPアドレスにgeoipの情報を付加(filter/geoip) どの国からのアクセスかなどを判別したいので、IPアドレスを元にgeoipを利用してより詳細な情報を付与します。 Logstashでもこの機能が用意されており、簡単に利用ができます。\ngeoip { source =\u0026gt; [\u0026#34;clientip\u0026#34;] } これだけです。対象とするIPアドレスのフィールドを指定しているだけです。 geoipというフィールドが追加され、次のような情報が付与されます。 国名、緯度経度、タイムゾーンなどです。\n{ ... \u0026#34;geoip\u0026#34;: { \u0026#34;ip\u0026#34;: \u0026#34;IPアドレス\u0026#34;, \u0026#34;country_code2\u0026#34;: \u0026#34;JP\u0026#34;, \u0026#34;country_code3\u0026#34;: \u0026#34;JPN\u0026#34;, \u0026#34;country_name\u0026#34;: \u0026#34;Japan\u0026#34;, \u0026#34;continent_code\u0026#34;: \u0026#34;AS\u0026#34;, \u0026#34;latitude\u0026#34;: 36, \u0026#34;longitude\u0026#34;: 138, \u0026#34;timezone\u0026#34;: \u0026#34;Asia/Tokyo\u0026#34;, \u0026#34;location\u0026#34;: [ 138, 36 ] } ... } 5. リクエストのパスの第1階層の抽出(filter/grok) リクエストされたURLはrequestフィールドにありますが、個別のURLだと、大まかな集計が大変です。 もちろん、クエリで処理することもできますが、Logstashで処理するついでに、第1階層のディレクトリ名を抽出しておくことで、 検索や集計を行いやすくしておきます。\ngrok { match =\u0026gt; { \u0026#34;request\u0026#34; =\u0026gt; \u0026#34;^/%{WORD:first_path}/%{GREEDYDATA}$\u0026#34; } tag_on_failure =\u0026gt; [\u0026#34;_request_parse_failure\u0026#34;] } また、grokフィルタの登場です。 今回は、WORD:first_pathという記述方法で、WORDパターンにマッチした文字列をfirst_pathというフィールドに展開する指定をしています。\n例えば、サイトのスクリプトなどがscriptsというディレクトリにある場合は、first_pathの値を利用して、 後続のフィルタでログデータを出力しないといった処理にも使えます。\n6. ユーザエージェントのパース(filter/useragent) Logstashではユーザエージェントの文字列から、いくつかの情報を付与するフィルタも用意されています。 useragentフィルタです。\nuseragent { source =\u0026gt; \u0026#34;agent\u0026#34; target =\u0026gt; \u0026#34;useragent\u0026#34; } agentというフィールドにユーザエージェントの文字列があるので、このフィールドに対してフィルタを適用します。 元の文字列も取っておきたいので、useragentという別のフィールドに出力するように指定してあります。\n\u0026#34;useragent\u0026#34;: { \u0026#34;name\u0026#34;: \u0026#34;Firefox\u0026#34;, \u0026#34;os\u0026#34;: \u0026#34;Windows XP\u0026#34;, \u0026#34;os_name\u0026#34;: \u0026#34;Windows XP\u0026#34;, \u0026#34;device\u0026#34;: \u0026#34;Other\u0026#34;, \u0026#34;major\u0026#34;: \u0026#34;17\u0026#34;, \u0026#34;minor\u0026#34;: \u0026#34;0\u0026#34; }, このように、OS名やバージョン名などが抽出できます。\n7. Elasticsearchへの出力(output/elasticsearch) 最後は、Elasticsearchへのデータの出力設定です。\nindexにて、出力するindex名を指定してあります。 また、年毎のインデックス名にするために%{year}を利用しています。 sprintf formatです。\nelasticsearch { host =\u0026gt; \u0026#34;localhost\u0026#34; index =\u0026gt; \u0026#34;new_demo_access_log-%{year}\u0026#34; cluster =\u0026gt; \u0026#34;demo_cluster\u0026#34; protocol =\u0026gt; \u0026#34;http\u0026#34; } まとめ ということで、今回はアクセスログをLogstashにて読み込む時の設定について説明してきました。 次回は、実際にLogstashを起動してElasticsearchにデータを登録するところまでを説明します。\nJJUG CCCや勉強会のデモに用いたデータは、 Elasticsearchにデータを登録する前にテンプレートも設定してありました。こちらについても、次回説明しようと思います。\n不明な点、誤植などありましたら、コメント欄へお願いします。\n","date":1416558639,"dir":"post/2014/","id":"937a597a8b399fd32caba88a3c1c7bc4","lang":"ja","lastmod":1416558639,"permalink":"https://blog.johtani.info/blog/2014/11/21/import-apache-accesslog-using-logstash/","publishdate":"2014-11-21T17:30:39+09:00","summary":"JJUG CCCや第7回Elasticsearch勉強会のKibana4のデモにアクセスログを利用しました。 ただ、セッションでは、どうやってElas","tags":["logstash","kibana","elasticsearch"],"title":"Logstashを利用したApacheアクセスログのインポート"},{"contents":"第7回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 次回もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\n昨日も紹介しましたが、Elasticsearch Advent Calendar 2014を用意してみました。まだ、空きがありますので、登録お待ちしております!\n今回は出足が好調で、早々に180人の枠を超えるという嬉しい事態でした。 最終的な参加人数は130名程度で、懇親会参加者が50名弱といったところです。\n「Kibana4」 Elasticsearch Inc. Jun Ohtani @johtani スライド:Kibana4\nということで、Kibana4の紹介と、Kibana4のBeta2を利用したデモを行いました。 デモの開始のところで少し環境がうまく動いてなくて手間取ってしまいましたが。。。\n発表で1点だけ修正があります。JRubyを選択しているのがElasticsearchのライブラリを使用するためという説明をしましたが、 こちらは、Logstashに関する話でした。Kibana4は現時点では、ElasticsearchへのProxyとしての動作が主なものとなります。Rubyでも動作可能です。 bin/kibanaについてはJavaを使った起動になります。 参考:https://github.com/elasticsearch/kibana/tree/master/src/server\n発表でも主張しましたが、ダウンロードして、Elasticsearchを用意すれば簡単に動作させることが可能です。 ぜひ、ローカルで試して見てもらえればと思います。 今回のデモのデータを入れるのに利用したLogstashの設定などについては、ブログで記事を書こうと思います。\nniconicoの検索を支えるElasticsearch 株式会社ドワンゴ 伊藤 祥 さん スライド:niconicoの検索を支えるElasticsearch\nリアルタイム検索の実現、新しい検索への対応 検索のアーキテクチャとか。 Capistranoでデプロイとかを管理 1.4.1が出たら、クラスタを更新予定 ということで、実際に導入した話から、現在の運用の仕方、クラスタのアップグレードなど多岐にわたる内容でおもしろかったです。 遭遇した問題点とかもあったので。 Marvel便利なのでぜひ導入を検討してもらえればw\nElasticsearch at CrowdWorks\u2028株式会社クラウドワークス 九岡 佑介 さん @mumoshu スライド:Elasticsearch at CrowdWorks\n会社の紹介 仕事が検索対象 検索時間が1桁減少! Graceful Degradationで失敗したら、InnoDB FTSで代替:Gracefully found.noのサービスを利用 elasticsearch-modelの拡張を作成してOSSとして公開:elasticsearch-model-extensions Gracefullyで切り替えとかは面白いなと思いました。 検索での利用の話でしたが、他のシーンでも使えそうですよね。 日本にFoundユーザがいるのも初めて知りました。 彼らの開発者ブログも質の良い情報が載っているので、参考になりますよね。\n次は、どんなMappingで運用しているのかとか、どういった工夫をしているかといった点を詳しく聞きたいなと思いました。 またお待ちしております。\n1分で作るElasticsearchプラグイン 株式会社エヌツーエスエム 菅谷 信介 さん スライド:Elasticsearchプラグインの作り方\n\u0008\u0008* プラグインの作り方とか。\n十数個のプラグインの紹介。プラグインはこちらで公開中。https://github.com/codelibs/ 実際に、業務で必要なものから作成 まだまだ作りたいものがある コミュニティ還元できるものはPR送ってもらえるとうれしいです。 前よりは体制も増えてるので、PRも目にとまるようになってるはずです。\nあとは、使ってみたいと思う方も多数いると思うので、ぜひ、OSSなので、貢献しましょう! フィードバックがあるだけで、OSS活動やってるものにとってはやる気につながると思いますし。\nLT:GISとして活用するElasticsearch\u2028船戸 隆さん スライド:GISとして活用するElasticsearch\u2028java-jaからIngressの青(Registance)の勧誘に来られた方w APIをハックして、情報を取得し、Kibanaで可視化 残念ながら、APIが変更されて見れなくなったらしい。 Ingress実際にやったことはないのですが、おもしろそうでした。 発表される方の会社の採用紹介ではなく、Ingressの勧誘をされるとは想定外でしたw\n興味のあるデータをKibanaで可視化するのも面白い例だと思うので、活用してもらえればと思います。\nその他、感想などのブログ 適当に見つけたブログを列挙してあります。これもあるよ!などあれば、教えてください。\n勉強会メモ - 第7回elasticsearch勉強会 第7回elasticsearch勉強会 #elasticsearch #elasticsearchjp まとめ JJUGの時とは違い、Elasticsearch勉強会ではさすがに、企業としてのElasticsearchの知名度が高かったのはありがたいことでした。 自分の発表のために始めた勉強会でもありますが、まだまだ、発表するときは緊張しますし、分かりにくいんじゃないかなぁと思うことも多々あります。 この辺がわかりにくかった、この辺をもっと知りたいなど、フィードバックをお待ちしております。\n冒頭にも書きましたが、Elasticsearch Advent Calendar 2014の登録をお待ちしております。どんなことでも歓迎なので、Elasticsearch、Kibana、Logstashなどについて書いてもらえるとうれしいです。\n次回ももちろん2ヶ月後くらいに行います。 スピーカー募集中ですので、コメント、メール、ツイートなど、コンタクトしていただければと思います。 よろしくお願いいたします。\n","date":1416363547,"dir":"post/2014/","id":"2a8412aa50d07330f1298f0243fa79d3","lang":"ja","lastmod":1416363547,"permalink":"https://blog.johtani.info/blog/2014/11/19/hold-on-7th-elasticsearch-jp/","publishdate":"2014-11-19T11:19:07+09:00","summary":"第7回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん","tags":["elasticsearch","勉強会"],"title":"第7回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:elasticsearch-1.4.0 and 1.3.5 released\n本日、Lucene 4.10.2をベースにしたElasticsearch 1.4.0と、バグフィックスリリースである、Elasticsearch 1.3.5をリリースしました。 ダウンロードおよび変更リストはそれぞれ次のリンクからアクセスできます。\n最新ステーブルリリース:Elasticsearch 1.4.0 1.3.x系バグフィックス:Elasticsearch 1.3.5 1.3ブランチに関する過去のリリースについてのブログは次のとおりです:1.3.4, 1.3.3, 1.3.2, 1.3.1, 1.3.0.\nBeta1リリースでも言及しましたが、1.4.0の主なテーマは*resiliency(復元性、弾力性)*です。 Elasticsearchをより安定し信頼性のあるものにし、メモリ管理を改善し、ディスカバリアルゴリズムを改善し、破損したデータの検知を改善しました。 Beta1リリースからのハイライトも含んでいます。\nDoc values (インデックス時にディスクに保存されるfielddata)がヒープ利用率を激減 Request circuit breaker: メモリを消費しすぎる検索リクエストの中断 Bloom filterのデフォルト無効、高速なインデキシングのためにもはや必要とされないため。 ノードディスカバリ、シャードリカバリの数多くのバグフィックス及び改善 データ破損の早期検知のためのチェックサムのさらなる利用 GroovyをMVELの代わりにデフォルトスクリプト言語に CORSをデフォルト無効に。XSS攻撃防止の為。 クエリキャッシュ、変更されていないシャードからすぐにaggregation結果を返す 新しいAggregation:filter(ドキュメント)、children(ドキュメント)、scripted_metric(ドキュメント) 新しいGET /indexAPI。インデックスのsettings、mappings、warmers、aliasesを1回のリクエストで返却(ドキュメント) 自動付与ドキュメントIDのためのFlake ID。プライマリキーの探索パフォーマンスの改善。 ドキュメントに変更のない更新によるドキュメントの再インデックスの防止 function_scoreクエリの関数でweightパラメータによる個別の改善を可能に。(ドキュメント) 詳細については1.4.0.Beta1のブログ(英語)(日本語訳)をご覧ください。\nBeta1以降の1.4.0の変更の全てについては、1.4.0 release notesでご覧いただけます。 以下では、2つの主な変更について紹介します。\nHTTP Pipelining HTTP pipeliningは複数のリクエストを1回のコネクションで、関連するレスポンスを待つことなく送信することができます。 そして、レスポンスは、受け取ったリクエストと同じ順序で返却されます。 HTTP/1.1の仕様で、pipeliningのサポートが必要です。ElasticsearchはHTTP/1.1であるとしてきましたが、pipeliningはサポートしていませんでした。この問題は.NETユーザで問題を引き起こしました。\n現在、HTTP pipeliningは公式にサポート済みで、デフォルトで利用できます。#8299をご覧ください。\nUpgrade API Luceneのすべてのリリースではバグフィックスや最適化が提供されます。しかし、多くのユーザは古いバージョンのLuceneで作成されたインデックスを持っており、より最新の改善による利点を利用できないことがあります。 新しいupgradeAPIは、あなたのインデックスすべてもしくは一部を最新のLuceneフォーマットに透過的にアップグレードできます。\nGET _upgradeリクエストは、インデックスのアップグレードが必要かどうかを提示し、アップグレードに必要なセグメントのサイズをリポートすることによって、どのくらいの時間が必要かの目安を提供します。 POST _upgradeコマンドはバックグラウンドでインデックスを最新のLuceneフォーマットに書き換えます。\nより詳しい情報はupgradeAPIドキュメントをご覧ください。\n試してみてください。 Beta1リリースを利用し、経験・体験を報告していただいたベータテスターの方々に感謝します。 1.4.0がこれまでの最高のリリースになると確信しています。 ぜひ、Elasticsearch 1.4.0をダウンロードして、試してみてください。 そして、感想をTwitter(@elasticsearch)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1415205033,"dir":"post/2014/","id":"d266a2023c67b7a20c3bd01055b223bc","lang":"ja","lastmod":1415205033,"permalink":"https://blog.johtani.info/blog/2014/11/06/elasticsearch-1-4-0-ja/","publishdate":"2014-11-06T01:30:33+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:elasticsearch-1.4.0 and 1.3.5 released 本日、Lucene 4.10.2をベースにし","tags":["elasticsearch"],"title":"Elasticsearch 1.4.0および1.3.5リリース(日本語訳)"},{"contents":"久しぶりに翻訳ではないブログを。書こうと思いながらかけてなかったので。。。\n今回はvalidate APIの紹介です。\n背景 ElasticsearchのクエリはQuery DSLというJSONで クエリを定義できるものを提供しています。 これは、様々なクエリ、フィルタを定義するために必要です。\n自分の望んでいる条件を記述するために、JSONのネストと格闘することも必要となります。。。 また、クエリ、フィルタには様々なパラメータが用意されています。 これらのパラメータをすべて覚えるのは無理でしょうし、タイプミスなどもありますよね。 タイプミスやカッコのミスマッチなどで格闘して1時間が経過してしまったなどもあると思います。\nそんな時に便利なAPIとして用意されているのがvalidate APIです。\n利用方法 APIが用意されています。\nhttp://ホスト名:ポート番号/インデックス名/タイプ名/_validate/query インデックス名やタイプ名は省略可能ですが、マッピングが異なると思うので、タイプ名まで指定するほうが良いと思います。 上記のAPIに対してクエリを送信するだけです。\nクエリの確認 たとえば、こちらのGistにあるようなマッピングのインデックスに対して 検索クエリを組み立てていて、エラーが出るとします。 ※このクエリはmatch_allのところをmatch_alと、lが1文字足りないクエリになっています。\n検索クエリのリクエスト(エラーあり)\nGET pref_aggs/_search { \u0026#34;query\u0026#34;: { \u0026#34;match_al\u0026#34;: {} } } 実行結果のレスポンス\n{ \u0026#34;error\u0026#34;: \u0026#34;SearchPhaseExecutionException[Failed to execute phase [query], all shards failed; shardFailures {[rwkb01chTZq2V7FD0Tlwrw][pref_aggs][0]: SearchParseException[[pref_aggs][0]: from[-1],size[-1]: Parse Failure [Failed to parse source [{\\n \\\u0026#34;query\\\u0026#34;: {\\n \\\u0026#34;match_al\\\u0026#34;: { }\\n }\\n}\\n]]]; nested: QueryParsingException[[pref_aggs] No query registered for [match_al]]; }{[rwkb01chTZq2V7FD0Tlwrw][pref_aggs][1]: SearchParseException[[pref_aggs][1]: from[-1],size[-1]: Parse Failure [Failed to parse source [{\\n \\\u0026#34;query\\\u0026#34;: {\\n \\\u0026#34;match_al\\\u0026#34;: { }\\n }\\n}\\n]]]; nested: QueryParsingException[[pref_aggs] No query registered for [match_al]]; }]\u0026#34;, \u0026#34;status\u0026#34;: 400 } とこんなかんじで、エラーが帰っては来るのですが、非常に読みづらいです。\nそこで、validate APIを利用します。 リクエスト先を/_searchから/_validate/queryに変更します。\nvalidate API\nGET pref_aggs/_validate/query { \u0026#34;query\u0026#34;: { \u0026#34;match_al\u0026#34;: {} } } validate APIのレスポンス\n{ \u0026#34;valid\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;failed\u0026#34;: 0 } } すると、非常にシンプルな結果が返ってきます。 \u0026quot;valid\u0026quot;: falseとなっているため、クエリに問題があることがわかります。\nエラーの詳細 問題がある事自体はわかりましたが、エラーの内容も知りたいですよね? その場合は、explainというパラメータを追加します。 (正しくはexplain=trueを追加しますが、=trueを省略可能です。)\nvalidate API(explainあり、クエリ自体は省略)\nGET pref_aggs/_validate/query?explain {...} validate APIのレスポンス\n{ \u0026#34;valid\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;explanations\u0026#34;: [ { \u0026#34;index\u0026#34;: \u0026#34;pref_aggs\u0026#34;, \u0026#34;valid\u0026#34;: false, \u0026#34;error\u0026#34;: \u0026#34;org.elasticsearch.index.query.QueryParsingException: [pref_aggs] No query registered for [match_al]\u0026#34; } ] } explanationsという項目が追加されました。 ここにerrorという項目として、エラーの詳細が返ってきます。_searchの時よりも見やすいですね。 今回のエラーは、match_allが正しいクエリですの、match_alというクエリは登録されていないというエラーでした。 では、クエリを修正して実行しましょう。\nvalidate API(エラー無し)\nGET pref_aggs/_validate/query?explain { \u0026#34;query\u0026#34;: { \u0026#34;match_all\u0026#34;: {} } } validate APIのレスポンス\n{ \u0026#34;valid\u0026#34;: true, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;explanations\u0026#34;: [ { \u0026#34;index\u0026#34;: \u0026#34;pref_aggs\u0026#34;, \u0026#34;valid\u0026#34;: true, \u0026#34;explanation\u0026#34;: \u0026#34;ConstantScore(*:*)\u0026#34; } ] } 今度はクエリに問題はありません。\u0026quot;valid\u0026quot;: trueです。 そして、explanationsの項目には、errorの代わりにexplanationという項目が返ってきました。 これが、実際にElasticsearch内部で実行されるクエリになります。\n実際のクエリに利用される単語の確認 この機能はこの他に、クエリの解析にも利用できます。 思ったとおりに検索にヒットしない場合があって、困ったことはないですか? フィールドに指定されたアナライザによっては、単語を変形したりするものが存在します。\nサンプルマッピング\nPUT /validate_sample { \u0026#34;mappings\u0026#34;: { \u0026#34;several_analyzer\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;title\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;}, \u0026#34;body_ja\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;kuromoji\u0026#34;}, \u0026#34;body_en\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;english\u0026#34;} } } } } 例えば、このようにkuromoji、english、デフォルト(standard)アナライザを利用したマッピングがあるとします。 このフィールドに対してpowerfulという単語で検索したとします。\nvalidate API\nGET /validate_sample/_validate/query?explain { \u0026#34;query\u0026#34;: { \u0026#34;multi_match\u0026#34;: { \u0026#34;fields\u0026#34;: [\u0026#34;body_en\u0026#34;,\u0026#34;body_ja\u0026#34;,\u0026#34;title\u0026#34;], \u0026#34;query\u0026#34;: \u0026#34;powerful\u0026#34; } } } この場合、レスポンスは次のとおりです。\nvalidate APIのレスポンス\n{ \u0026#34;valid\u0026#34;: true, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;explanations\u0026#34;: [ { \u0026#34;index\u0026#34;: \u0026#34;validate_sample\u0026#34;, \u0026#34;valid\u0026#34;: true, \u0026#34;explanation\u0026#34;: \u0026#34;(title:powerful | body_en:power | body_ja:powerful)\u0026#34; } ] } title、body_jaについては入力された単語がそのままクエリとして利用されています。 body_enについては、powerという単語に変換されて実行されています。 これは、englishアナライザがステミングを行った結果がクエリとして利用されるという意味です。 また、powerfulを秋葉原といった日本語に変更して実行すると次のようになります。 日本語はstandardアナライザなどでは、1文字ずつ区切られてしまうことがわかります。\nvalidate APIのレスポンス\n{ \u0026#34;valid\u0026#34;: true, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;successful\u0026#34;: 1, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;explanations\u0026#34;: [ { \u0026#34;index\u0026#34;: \u0026#34;validate_sample\u0026#34;, \u0026#34;valid\u0026#34;: true, \u0026#34;explanation\u0026#34;: \u0026#34;((title:秋 title:葉 title:原) | (body_en:秋 body_en:葉 body_en:原) | ((body_ja:秋葉 body_ja:秋葉原) body_ja:原))\u0026#34; } ] } このように、クエリの単語がどのような単語に変換されてクエリに利用されているかなども知ることが可能です。\nまた、クエリを組み立てて、ヒットするはずが、0件となってしまうという場合にも、どのようなクエリが組み立てられているかを確認するという点で、 validate APIが役立ちます。 検索がヒットするが、望んだクエリになっていないのでは?という場合は_search APIのexplainパラメータを 利用すれば、クエリの構成がわかるのですが、検索結果が0件の場合はクエリの構成は表示されません。\n解決できない問題は? 便利なvalidate APIですが、以下の問題に対しては残念ながら確認できません。\nquery以外の項目のvalidate不可 たとえば、_search APIのsizeなどの項目についてはチェックできないです。 存在しないフィールドの指定 上記validate_sampleのマッピングの例でクエリにbody_engという存在しないフィールドを指定してもエラーとはなりません。 まとめ 書いたクエリがうまく動かない、JSONのタグがおかしいといった場合は、 まずはこのvalidate APIで確認してみるのがオススメです。\n","date":1414402951,"dir":"post/2014/","id":"bc2709406a9bb19e8d83a78f81e36244","lang":"ja","lastmod":1414402951,"permalink":"https://blog.johtani.info/blog/2014/10/27/how-to-use-validate-api/","publishdate":"2014-10-27T18:42:31+09:00","summary":"久しぶりに翻訳ではないブログを。書こうと思いながらかけてなかったので。。。 今回はvalidate APIの紹介です。 背景 Elasticsear","tags":["elasticsearch"],"title":"validate APIの利用"},{"contents":"Elasticsearch 1.4.0.Beta1がリリースされました。\n個人でelasticsearch-extended-analyzeというプラグインを開発してます。 こちらも1.4.0.Beta1に対応するべく作業をしてて、少し戸惑ったことがあったので、メモをば。\nここ最近はプラグインのバージョン番号をElasticsearchのバージョン番号と同じものを利用していました。 (プラグインの機能追加をサボってる??) その時に、1.4.0.Beta1という番号を指定したのですが、意味不明なエラーに悩まされてしまいまして。\nプラグインのリリースでは、以下のコマンドを実行します。\n$ mvn release:prepare $ mvn release:perform 最初のコマンド(prepare)で、パッケージングを実施し、Githubにリリースタグを打ったバージョンがpushされます。 次のコマンド(perform)で、パッケージングされたzipファイルがsonatypeのサイトに公開するためにアップロードされます。\n1.4.0.Beta1というバージョン文字列を利用した場合、prepareは問題なく実行できたのですが、 performで以下の様なエラーが返ってきました。\nReturn code is: 401, ReasonPhrase: Unauthorized. バージョン番号が1.3.0では特に問題はなかったのですが、、、 結局、バージョン番号を1.4.0-beta1に変更すると問題なくリリースが完了しました。\nmike_neckさんと話をしていて、Semantic Versioningに関係しているのかなぁという話にはなったのですが、 詳しく調べていません。。。\nそのうち調べようかなぁ。。。。\n","date":1413354368,"dir":"post/2014/","id":"998eda745d07fd8608f251138384a0b9","lang":"ja","lastmod":1413354368,"permalink":"https://blog.johtani.info/blog/2014/10/15/versioning-of-sonatype/","publishdate":"2014-10-15T15:26:08+09:00","summary":"Elasticsearch 1.4.0.Beta1がリリースされました。 個人でelasticsearch-extended-analyzeというプラグインを開発してま","tags":["Elasticsearch","plugin","sonatype"],"title":"Sonatypeのバージョン番号で困ったので"},{"contents":"※この記事は次のブログを翻訳したものになります。\n原文:elasticsearch 1.4.0.beta1 released\n本日、Lucene 4.10.1をベースにした、Elasticsearch 1.4.0.Beta1をリリースしました。 Elasticsearch 1.4.0.Beta1からダウンロードできます。 また、すべての変更点に関してもこちらをご覧ください。\n1.4.0のテーマは*resiliency(復元性、弾力性)*です。 resiliencyとはElasticsearchをより安定し信頼性のあるものにすることを意味します。 すべての機能が正常に機能している場合は信頼することは簡単です。 予想外のことが発生した時に難しくなります:ノードでout of memoryの発生、スローGCや重いI/O、ネットワーク障害、不安定なデータの送信によるノードのパフォーマンス低下など。\n本ベータリリースは、resiliencyの主な3つの改善を含んでいます。\nメモリ使用量の低下によるノードの安定性向上 discoveryアルゴリズムの改善によるクラスタの安定性向上 チェックサムの導入による破損したデータの検知 分散システムは複雑です。 決して想像できないような状況をシミュレーションするために、ランダムなシナリオを作成する広範囲なテストスイートを持っています。 しかし、無数のエッジケース(特殊なケース)があることも認識しています。 1.4.0.Beta1はこれまで私たちが行ってきた改善のすべてを含んでいます。 これらの変更を実際にテストしていただき、何か問題があった場合は私たちに教えてください。\nメモリ管理 ヒープ空間は限られたリソースです。 上限を32GBとし、利用可能なRAMの50%をヒープの上限にすることを推奨します。 この上限を超えた場合、JVMは圧縮したポインタを使用することができず、GCが非常に遅くなります。 ノードの不安定性の主な原因は遅いGCです。それは、次のようなことから発生します。\nメモリプレッシャー スワップ(参照:memory settings) 非常に大きなヒープ 本リリースは、メモリ管理の改善し、(結果として)ノードの安定性を改善するいくつかの変更を含んでいます。\ndoc values メモリの利用の最も大きなものの1つはfielddataです aggregation、ソート、スクリプトがフィールドの値に素早くアクセスするために、フィールドの値をメモリにロードして保持します。 ヒープは貴重なため、1ビットも無駄にしないためにメモリ内のデータは高度な圧縮と最適化を行っています。 これは、ヒープスペース以上のデータをもつまでは、非常によく動作します。 これは、多くのノードを追加することによって常に解決できる問題です。 しかし、CPUやI/Oが限界に達してしまうずっと前に、ヒープ空間の容量に到達します。\n最近のリリースは、doc valuesによるサポートがあります。 基本的に、doc valuesはin-memory fielddataと同じ機能を提供します。 doc valuesの提供する利点は、それらが、非常に少量のヒープ空間しか使用しない点です。 doc valuesはメモリからではなく、ディスクから読み込まれます。 ディスクアクセスは遅いですが、doc valuesはカーネルのファイルシステムキャッシュの利点を得られます。 ファイルシステムキャッシュはJVMヒープとはことなり、32GBの制限による束縛がありません。 ヒープからファイルシステムキャッシュにfielddataを移行することによって、より小さなヒープを使うことができます。これは、GCがより早くなり、ノードが更に安定することを意味します。\n本リリースより前は、doc valuesはin-memory fielddataよりもかなり遅かったです。 本リリースに含まれる変更は、パフォーマンスをかなり向上させ、in-memory fielddataとほぼ同じくらいの速度になっています。\nin-memory fielddataの代わりにdoc valuesを利用するために必要なことは、次のように新しいフィールドをマッピングすることです。\nPUT /my_index { \u0026#34;mappings\u0026#34;: { \u0026#34;my_type\u0026#34;: { \u0026#34;properties\u0026#34;: { \u0026#34;timestamp\u0026#34;: { \u0026#34;type\u0026#34;: \u0026#34;date\u0026#34;, \u0026#34;doc_values\u0026#34;: true } } } } } このマッピングで、このフィールドに対するfielddataの利用は、メモリにフィールドをロードする代わりに、自動的にディスクからdoc valuesを利用します。 *注意:*現時点で、doc valuesはanalyzedなstringフィールドはサポートしていません。\nrequest circuit breaker fielddata circuit breakerはfielddataによって利用されるメモリの上限を制限するために追加され、OOMEの最も大きな原因の1つを防ぎました。 そして、リクエストレベルのcircuit-breakerを提供するために、コンセプトを拡張しました。 これは、単一のリクエストによって使用されるメモリの上限を制限します。\nbloom filters Bloom filters はインデキシング(前のバージョンのドキュメントが存在するかどうかのチェックのため)や、 IDによるドキュメントの検索(ドキュメントを含むセグメントがどれかを決定するため)に関する重要な性能最適化を提供しました。 しかし、もちろんそれらはコスト(メモリ)を必要とします。 現在の改善は、bloom filterの必要性を取り除きました。 現在では、Elasticsearchはまだ、インデックス時にそれらを構築します(実世界の経験がテストシナリオにそぐわない場合に備えて)。 しかし、デフォルトではメモリにはロードされません。 すべてが予定通りに運べば、将来のバージョンで完全にこれらは除去します。\nクラスタの安定性 クラスタの安定性向上のために私たちができる最も大きなことは、ノードの安定性の向上です。 もし、ノードが安定しておりタイミングよく反応すれば、クラスタが不安定になる可能性が大いに減少します。 私たちは不完全な世界に住んでいます。- 物事は予想外にうまく行きません。クラスタはデータを失うことなくこのような状況から回復できる必要があります。\n私たちは、improve_zenブランチ上で、Elasticsearchの障害からの復旧するための能力の向上に数ヶ月費やしてきました。 まず、複雑なネットワークレベルの障害を繰り返すためのテストを追加しました。 次に、各テストのための修正を追加しました。 そこには、より多くの行うことが存在します。しかし、私たちは、issue #2488(\u0026ldquo;分割が交差している場合、minimum_master_nodesはsplit-brainを防げない\u0026rdquo;)に含まれる、ユーザが経験してきた大部分の問題を私たちは解決しました。\n私たちはクラスタのresiliencyを非常に真剣に取り組んでいます。 私たちは、Elasticsearchが何ができるか、その上で何が弱点であるかを理解してほしいと思っています。 これを考慮して、私たちはResiliency Status Documentを作成しました。 このドキュメントは、私たち(または私たちユーザ)が遭遇したresiliencyの問題の、何が修正済みで、何が修正されないまま残っているかを記録します。 このドキュメントを慎重に読み、あなたのデータを保護するために適切な方法を選択してください。\nデータ破損の検知 ネットワークをまたいだシャードリカバリのチェックサムは、圧縮ライブラリのバグを発見する助けとなりました。 それは、バージョン1.3.2で修正済みです。 それ以来、私たちはElasticsearchのいたるところにチェックサムとチェックサムの確認を追加しました。\nマージ中に、あるセグメント内すべてのチェックサムの確認(#7360) インデックス再オープン時に、あるセグメント内の最も小さなファイルの完全な確認と、より大きなファイルの軽量な打ち切りチェック(LUCENE-5842) トランザクションログからイベントを再生するとき、各イベントはチェックサムを確認される(#6554) シャードのリカバリ中もしくは、スナップショットからのリストア中にElasticsearchはローカルファイルとリモートのコピーが同一であるか確認する必要がある。ファイルの長さとチェックサムのみを使うのは不十分であることが確認された。このため、現在はセグメントのすべてのファイルの同一性を確認(#7159) その他のハイライト Elasticsearch 1.4.0.Beta1のchangelogに本リリースの多くの機能、改善、バグフィックスについて読むことができます。 ここでは、特筆すべきいくつかの変更について述べます。\ngroovyによるmvelの置き換え Groovyは現在、デフォルトのscripting languageです。 以前のデフォルトはMVELで、古くなってきており、サンドボックス内で実行できないという事実は、セキュリティ問題でした。 Groovyはサンドボックスであり(それは、ボックスの外へは許可が必要)、メンテナンスされており、速いです! 詳しくはscriptingについてのブログ記事をご覧ください。\nデフォルトでcorsはオフ Elasticsearchのデフォルト設定はクロスサイトスクリプティングに対して脆弱でした。 私たちはデフォルトでCORSをオフにすることで修正しました。 Elasticsearchにインストールされたサイトプラグインはこれまで同様に機能します。 しかし、CORSを再度オンにすることがない限り、外部のウェブサイトがリモートのクラスタにアクセスすることはできません。 ウェブサイトがあなたのクラスタにアクセス可能に制御できるように、さらにCORS settingsを追加しました。 詳しくはsecurity pageをご覧ください。\nクエリキャッシュ 新しい試験的なshardレベルのクエリキャッシュは、静的なインデックスのアグリゲーションをほとんど即座に反応できます。 ウエブサイトのアクセスの日毎のページビュー数を見るダッシュボードを持っていると想像してみてください。 これらの数値は古いインデックスでは変更がありません。しかし、アグリゲーションはダッシュボードのリフレッシュのたびに再計算されます。 新しいクエリキャッシュを利用すると、シャードのデータが変更されない限り、アグリゲーションの結果はキャッシュから直接返却されます。 キャッシュから古い結果を決して取得することはありません。それは、常に、キャッシュされていないリクエストと同じ結果を返します。\n新しいaggregations 3つの新しいaggregationsがあります。\nfilters\nこれはfilter aggregationの拡張です。複数のバケットを定義し、バケット毎に異なるフィルタを利用できます。 children\nnestedアグリゲーションの親子版。children aggは親のドキュメントに属する子のドキュメントを集計できる scripted_metric\nこのaggregationは、データによって計算されたメトリックを完全にコントロールできます。これは、初期化フェーズ、ドキュメント収集フェーズ、shardレベル結合フェーズ、global reduceフェーズを提供します。 get /index api 以前、ある1つのインデックスのaliases、mappings、settings、warmersを取得出来ました。しかし、それらを個別にです。 get-index API はこれらのすべてもしくは一部を、複数もしくはひとつのインデックスに対して一緒に取得できます。 これは、既存のインデックスと同一もしくはほぼ同一であるインデックスを作成したいときに非常に役に立ちます。\n登録と更新 ドキュメントの登録と更新にいくつかの改善があります。\n現在、ドキュメントIDの自動生成のためにFlake IDを使用しています。これは、プライマリキー探索時に素晴らしい性能向上を提供します。 detect_noopにtrueを設定すると、ドキュメントに変更を与えない更新が軽量になります。この設定を有効にすると、_sourceフィールドのコンテンツを変更する更新リクエストだけ、ドキュメントの新しいバージョンを書き込みます。 更新はスクリプトから完全に操作できます。以前は、スクリプトはドキュメントがすでに存在しているときだけ実行可能で、それ以外は、upsertドキュメントで登録しました。script_upsertパラメータでスクリプトから直接ドキュメントの作成が操作できます。 function score すでに非常に便利なfunction_scoreクエリが、新しくweightパラメータをサポートします。 これは、それぞれの指定された関数の影響をチューニングするのに使われます。 これは、人気度よりも更新日時により重みをかけたり、地理情報よりも価格により重みをかけるといったことを可能にします。 また、random_score機能はセグメントマージによる影響を受けません。これにより、より一貫した順序が提供されます。\n試してみてください。 ぜひ、Elasticsearch 1.4.0.Beta1をダウンロードして、試してみてください。 そして、感想をTwitter(@elasticsearch)などで教えて下さい。 また、問題がありましたら、GitHub issues pageで報告をお願いします。\n","date":1412244840,"dir":"post/2014/","id":"853cac0f2d1f90b7c986e7d1dcdbbfde","lang":"ja","lastmod":1412244840,"permalink":"https://blog.johtani.info/blog/2014/10/02/elasticsearch-1-4-0-beta-released-ja/","publishdate":"2014-10-02T19:14:00+09:00","summary":"※この記事は次のブログを翻訳したものになります。 原文:elasticsearch 1.4.0.beta1 released 本日、Lucene 4.10.1をベースにした、Elast","tags":["Elasticsearch"],"title":"elasticsearch 1.4.0.Beta1のリリース"},{"contents":"第6回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 次回もよろしくお願いします!参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。 今回は、スタッフが私を含めて3,4名ということで、ドタバタしてしまってスミマセンでした。\n今回はキャンセルが多く、最終的には90人弱の参加となりましたが、今回も多数の方にお集まりいただきありがとうございました。 同じ日に他の勉強会もあった影響でしょうか?\n「Aggregationあれこれ」Elasticsearch Inc. Jun Ohtani @johtani スライド:Aggregationあれこれ\nちょっと長かったですかね。。。 Aggregationの概要、内部動作、種類などを簡単に紹介してみました。 個々のAggregationもいろいろなオプションなどがあるので、色々と試してみていただければと思います。 アニメーション入りのスライドになってましたが、UpしてあるスライドはPDF版になります。 「秒間3万の広告配信ログをElasticSearchでリアルタイム集計してきた戦いの記録」 株式会社サイバーエージェント 山田直行さん @satully スライド:秒間3万の広告配信ログをElasticSearchでリアルタイム集計してきた戦いの記録\nディスプレイ広告配信DSPの話 システム: Fluentd、S3、Elasticsearch、Redis、MySQL 7月に秒間3万〜4万のリクエストをさばいている。 なぜElasticsearchを選んだのか、今の構成など 実際に苦労された点なども交えて話していただき面白かったです。 7月時点のお話ということで、現時点ではまた違う構成っぽかったので、また話を聞きたいなぁ。 「Elasticsearch 日本語スキーマレス環境構築と、ついでに多言語対応」ナレッジワークス株式会社 木戸国彦さん @9215 スライド:Elasticsearch 日本語スキーマレス環境構築と、ついでに多言語対応\nDynamic TemplateやIndex Templateの説明 日本語や多言語化するときのMappingのサンプルになりそうなものがゴロゴロ紹介されてました。 いくつかの例があって、後で見直したいなと。 途中で出てきた、fielddata(インデックスに入っている単語区切りのデータ)を見るのに使ってたクエリはfield data fieldsだったかな。 「elasticsearchソースコードを読みはじめてみた」@furandon_pig さん スライド:elasticsearchソースコードを読みはじめてみた\nリクエストを受けて検索してる部分から読むといいって言われたらしいが、起動スクリプトから読み始めてみた。 時間かかりそうw ただ、人がどんな感じでソースを読んだり理解してるかがわかりやすかったので面白かったです。 定期的に続きを聞いてみたいです。 LT 「reroute APIを使用してシャード配置を制御する」 株式会社富士通ソフトウェアテクノロジーズ 滝田聖己さん @pisatoshi スライド:reroute APIを使用してシャード配置を制御する\nシャードの再配置が自動で行われるので、それをオフにしないと、せっかく移動しても無駄になることがというあるあるネタ Bonsaiロゴを作成するLT 実際にいくら掛かったのかが知りたかった。 「検索のダウンタイム0でバックアップからIndexをリストアする方法」株式会社ドワンゴモバイル 西田和史さん スライド:検索のダウンタイム0でバックアップからIndexをリストアする方法\n擬似無停止のやりかた。 aliasを活用して、かつ、Restoreで再構築するという方法。 aliasまで一緒にリストアされるので注意が必要っていうのは、実際にやってみたからわかることという感じですね。 その他、感想などのブログ 適当に見つけたブログを列挙してあります。これもあるよ!などあれば、教えてください。\n第6回elasticsearch勉強会に行ってきましたのでそのメモ elasticsearch 勉強会 第6回 まとめ 今回も、ためになる話がいっぱい聞けたかなと。 個人的な印象としては、いつものメンバーよりも新しい方が多かった印象です。 また、ほとんどの方が、Elasticsearchをご存知でした。 そこそこ知名度は上がってきているようで嬉しい限りです。(東京以外での知名度なども知りたいかなと。)\nあと、懇親会の部屋の案内が遅くなってしまってスミマセンでした。 さすがにスタッフ3名はきつかったです。。。\n19時半開始にしてみましたが、懇親会の時間がやはり短めになってしまうなぁという印象でした。\n次回ももちろん2ヶ月後くらいに行います。 スピーカー募集中ですので、コメント、メール、ツイートなど、コンタクトしていただければと思います。 よろしくお願いいたします。\n","date":1410927720,"dir":"post/2014/","id":"4616fbea6a6dbc1074bc3f1016bbc73b","lang":"ja","lastmod":1410927720,"permalink":"https://blog.johtani.info/blog/2014/09/17/hold-on-6th-elasticsearch-jp/","publishdate":"2014-09-17T13:22:00+09:00","summary":"第6回Elsticsearch勉強会を開催しました。 スタッフの皆さん、スピーカーの皆さん、開場提供していただいたリクルートテクノロジーズさん","tags":["elasticsearch","勉強会"],"title":"第6回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"先日2014年9月9日(火)に『サーバ/インフラエンジニア養成読本 ログ収集〜可視化編』 出版記念!執筆者が語る大講演会!で、 「elasticsearch.もうちょっと入門」というタイトルで発表してきました。 会場のGMOのみなさま、Treasure Data、技術評論社のみなさま、どうもありがとうございました。\n書籍に興味のある方は、右のリンクから購入してもらえるとうれしいです。Kindle版も用意されています。\n提供のTDの方に目をつぶってもらいながらLogstashについての発表となってしまいましたが、楽しんでいただけたかなぁと。 書籍では主にKibana3をメインにしたElasticsearchの使い方だったので、それ以外の機能ということで、Aggregationについて説明してみました。\nそのあとは、おそらく初めてですが、パネルディスカッションにも参加しました。 @naoya_itoさんをモデレーターに、rebuild.fm風に進めていただき、話しやすかったかなと。 (少なくとも私は楽しめました!) ただ、私だけバックグラウンドが少し異なることもあり、話をうまく繋げられなかったかもと気にしていたりもしますが。。。\nパネルディスカッションでもありましたが、エンジニアが「趣味」で入れて試してみるのにはもってこいのツール群だと思います。 ちょっと入れてみて、可視化をしてみるといろいろと発見があると思います。 何かを発見するためにもまず試してみるのが何事も重要かなと最近思ってるのもあるので、気軽に試してみてもらえればと。\n不明点などあれば、著者陣に気軽に聞いていただけると良いかと思います(いいですよね、みなさんw)。 Fluentd(もちろん、Logstashも)、Elasticsearch、Kibanaを利用して、データについて試行錯誤してもらって、 システムやビジネスに必要なものを探索して見てください。\n参考 他の方々のブログをメモとして。\nサービス改善とログデータ解析について発表してきました Kibanaではじめるダッシュボードについて発表してきました #gihyo_efk Fluentdのお勧めシステム構成パターンについて発表しました ","date":1410841260,"dir":"post/2014/","id":"f15702ae9e55bad42182cf18724d1863","lang":"ja","lastmod":1410841260,"permalink":"https://blog.johtani.info/blog/2014/09/16/book-publication-event/","publishdate":"2014-09-16T13:21:00+09:00","summary":"先日2014年9月9日(火)に『サーバ/インフラエンジニア養成読本 ログ収集〜可視化編』 出版記念!執筆者が語る大講演会!で、 「elastics","tags":["勉強会","本"],"title":"elasticsearch.もうちょっと入門という話をしてきました #gihyo_efk"},{"contents":"Elasticsearchのインデキシングに関するパフォーマンス検討\n原文:performance considerations for elasticsearch indexing\nElasticsearchユーザは様々な楽しいユースケースを持っています。小さなログを追加することから、Webスケールの大きなドキュメントの集合をインデキシングするようなことまでです。また、インデキシングのスループットを最大化することが重要で一般的な目標となります。 「典型的な」アプリケーションに対して良いデフォルト値を設定するようにしていますが、次のちょっとした簡単なベストプラクティスによってインデキシングのパフォーマンスをすぐに改善することができます。それらについて記述します。\n第一に、制御できないならば、巨大なJavaヒープを使用しない:必要なサイズ(マシンの持つRAMの半分以下)のheapだけを設定しましょう。Elasticsearchの利用方法のために必要な全体量を設定します。これは、OSにIOキャッシュを制御するためのRAMを残すことを意味します。OSがjavaプロセスをスワップアウトしていないことも確認しましょう。\n最新バージョン(現時点では1.3.2)のElasticsearchにアップグレードしましょう:多数のインデキシングに関連する問題点が最新リリースで修正されています。\n詳細に入る前に警告:ここで述べるすべての情報は現時点での最新(1.3.2)の情報です。しかし、Elasticsearchの更新は日々行われています。この情報をあなたが見た時点では最新ではなく、正確ではなくなっているかもしれません。自信がない場合はユーザメーリングリストで質問してください。\nクラスタのインデキシングスループットをチューニングする場合、Marvelは非常に有用なツールです:ここで述べている各設定を継続的に試し、変更の影響がクラスタの挙動をどのように変更されたかを簡単に可視化することが可能です。\nクライアントサイド bulk APIを常に使いましょう。1リクエストで複数のドキュメントをインデキシングでき、各バルクリクエストで送るのに良いドキュメント数を試しましょう。最適なサイズは多くの要因に依存しますが、最適サイズからずれるならば多すぎるよりも少なすぎる方が良いでしょう。クライアントサイドのスレッドで並列にbulkリクエストを使うか、個別の非同期リクエストを使ってください。\nインデキシングが遅いと結論付ける前に、クラスタのハードウェアの性能を引き出せているかを確認して下さい:すべてのノードでCPUやIOが溢れていないかを確認するためにiostatやtop、psといったツールを使いましょう。もし、溢れていなければ、より多くの並列なリクエストが必要です。しかし、javaクライアントからのEsRejectedExecutionExceptionや、RESTリクエストのHTTPレスポンスとしてTOO_MANY_REQUESTS (429)が返ってきた場合は並列リクエストを多く送りすぎています。もしMarvelを利用しているなら、Node Statistics DashboardのTHREAD POOLS - BULKにリジェクトされた数が表示されます。bulkスレッドプールサイズ(デフォルト値はコア数)を増やすのは得策ではありません。インデキシングスループットを減少させるでしょう。クライアントサイドの並列度を下げるか、ノードを増やすのが良い選択です。\nここでは、1シャードに対してインデキシングスループットを最大化する設定に注目します。1つのLuceneインデックスのドキュメントの容量を測定するために、単一ノード(単一シャード、レプリカなし)で最初にテストをして最適化し、クラスタ全体にスケールする前にチューニングを繰り返します。これはまた、インデキシングスループットの要件を見つけるために、クラスタ全体にどのくらいのノードが必要かをラフに見積もるためのベースラインを与えてくれます。\n単一シャードが十分機能したら、Elasticsearchのスケーラビリティの最大の利点や、クラスタでの複数ノードによるレプリカ数やシャード数の増加の利点が得られます。\n結論を導き出す前に、ある程度の時間(60分)くらいクラスタ全体の性能を計測しましょう。このテストは、巨大なマージ、GCサイクル、シャードの移動、OSのIOキャッシュ、予期しないスワップの可能性などのイベントのライフサイクルをカバーできます。\nストレージデバイス 当然ながらインデックスを保存するストレージデバイスはインデキシングの性能に多大な影響を及ぼします:\nSSDを利用する:これらは最も速いHDDよりも速いです。ランダムアクセスのための消費電力が低いだけでなく、シーケンシャルIOアクセスも高いです。また、同時に発生するインデキシング、マージや検索のための並列的なIOも高速です。 インデックスをリモートマウントされたファイルシステム(例:NFSやSMB/CIFS)上に配置しない:代わりにローカルストレージを使う 仮想化されたストレージ(AmazonのElastic Block Storageなど)に注意:仮想化されたストレージはElasticsearchで十分に動作します。また、十分早く簡単に用意できることから魅力的です。しかし、残念なことに、ローカルストレージと比較すると本質的に遅いです。最近の非公式なテストでは、最高の性能を持つプロビジョニングされたIOPSのSSDオプションのEBSでさえ、ローカルインスタンスにあるSSDよりも遅いです。ローカルインスタンスにあるSSDは物理マシン上のすべての仮想マシンから共有されてアクセスされます。もし他の仮想マシンが急にIOが集中した場合に不可解なスローダウンとなることがあることを覚えておいてください。 複数のSSDを複数のpath.dataディレクトリにインデックスをストライピング(RAID0のように):2つは同様で、ファイルブロックレベルでストライピングする代わりに、個別にインデックスファイルレベルでElasticsearchの\u0026quot;stripes\u0026quot;となります。これらのアプローチは、いづれかのSSDの故障によりインデックスが壊れるという、1シャードが故障する(IO性能を高速化することとトレードオフ)というリスクを増加させることに注意してください。これは、一般的に行うのに良いトレードオフです:単一シャードで最大のパフォーマンスを最適化し、異なるノード間でレプリカを追加すると、ノードの故障への冗長化ができます。また、snapshotやrestoreを使って保険のためにインデックスのバックアップを取ることもできます。 セグメントとマージ 新しくインデキシングされたドキュメントは最初にLuceneのIndexWriterによってRAMに保存されます。RAMバッファがいっぱいになった時もしくは、Elasticsearchがflushもしくはrefreshを実行した時など定期的にこれらのドキュメントはディスクに新しいセグメントとして書き込まれます。最後に、セグメントが多くなった時に、Merge PolicyとSuchedulerによってそれらがマージされます。このプロセスは連続的に生じます:マージされたセグメントはより大きなセグメントとなり、小さなマージが幾つか実行され、また、大きなセグメントにマージされます。これらがどのように動作するかをわかりやすく可視化したブログはこちらです。\nマージ、特に大きなマージは非常に時間がかかります。これは、通常は問題ありません。そのようなマージはレアで全体のインデックスのコストと比べればささいなものです。しかし、マージすることがインデキシングについていけない場合、インデックスに非常に多くのセグメントがあるような深刻な問題を防ぐために、Elasticsearchはやってくるインデキシングリクエストを単一スレッド(1.2以降)に制限します。\nもし、INFOレベルのログメッセージにnow throttling indexingと表示されていたり、Marvelでのセグメント数が増加しているを見た場合、マージが遅れているとわかります。MarvelはIndex Statistics dashboardのMANAGEMENT EXTENDEDの部分にセグメント数をプロットしており、それは、非常にゆっくりと指数対数的に増加しており、大きなマージが終了したところがのこぎりの歯のような形で見て取れます。\nセグメント数 なぜマージが遅れるのでしょう?デフォルトでElasticsearchはすべてのマージの書き込みのバイト数をわずか20MB/secに制限しています。スピニングディスク(HDD)に対して、これはマージによって典型的なドライブのIOキャパシティを飽和させず、並列に検索を十分に実行させることを保証します。しかし、もし、インデキシング中に検索をしない場合や、検索性能がインデキシングのスループットよりも重要でない場合、インデックスの保存にSSDを使用している場合などは、index.store.throttle.typeにnoneを設定して、マージの速度制限を無効化するべきです(詳細はこちらをご覧ください)。なおバージョン1.2以前には期待以上のマージIO制限の発生といったバグが存在します。アップグレードを!\nもし、不幸にもスピニングディスク(それはSSDと同等の並列なIOを扱えません)をまだ使っている場合、index.merge.scheduler.max_thread_countに1を設定しなければなりません。そうでない場合は、(SSDを支持する)デフォルト値が多くのマージを同時に実行させるでしょう。\n活発に更新が行われているインデックスでoptimizeを実行しないでください。それは、非常にコストの高い操作(すべてのセグメントをマージ)です。しかし、もし、インデックスにドキュメントを追加が終わった直後はオプティマイズのタイミングとしては良いタイミングです。それは、検索時のリソースを減らすからです。例えば、時間ベースのインデックスを持っており、新しいインデックスに日々のログを追加している場合、過去の日付のインデックスをオプティマイズするのは良い考えです。特に、ノードが多くの日付のインデックスを持っている場合です。\n更にチューニングするための設定:\n実際に必要のないフィールドをオフにする。例えば_allフィールドをオフ。また、保持したいフィールドでは、indexedかstoredかを検討する。 もし、_sourceフィールドをオフにしたくなるかもしれないが、インデキシングコストは小さい(保存するだけで、インデキシングしない)、また、それは、将来の更新や、前のインデックスを再インデキシングするために非常に価値があり、それはディスク使用率の懸念事項がない限り、オフにする価値はあまりない。それは、ディスクが比較的安価であるので価値がない。 もし、インデックスされたドキュメントの検索までの遅延を許容できるなら、index.refresh_intervalを30sに増やすか、-1を設定して、オフにする。これは、巨大なセグメントをフラッシュし、マージのプレッシャーを減らすことができる。 Elasticsearch 1.3.2(稀に、フラッシュ時に過度のRAMを使用するという問題を修正した)にアップグレードすることで、index.translog.flush_threshold_sizeをデフォルト(200mb)から1gbに増加し、インデックスファイルのfsyncの頻度を減らす。 MarvelにIndex Statistics dashboardのMANAGEMENTにフラッシュの頻度がプロットされている。 インデックスバッファサイズ 巨大なインデックスを構築中はレプリカ数を0にし、あとから、レプリカを有効にする。レプリカが0ということは、データを失った(ステータスがred)時に冗長性がないので、ノードの故障に注意すること。もし、optimize(ドキュメントの追加をすることがないので)を計画するなら、インデキシングが終わったあとで、レプリカを作成する前に実行するのが良いでしょう。レプリカはオプティマイズされたセグメントをコピーするだけになります。詳細はインデックス設定更新を参照。\nもし、ノードがヘビーなインデキシングを行っているだけなら、アクティブなシャードのインデキシングバッファに多くてい512MBをindices.memory.index_buffer_sizeに与えてください。(超えてもインデキシングのパフォーマンスは一般的には改善されません。)Elasticsearchはその設定(Javaヒープのパーセンテージもしくはバイト数)を受けて、min_index_buffer_sizeとmax_index_buffer_sizeの値を前提にノードのアクティブシャードに均等に割り当てます;大きな値はLuceneが最初のセグメントをより大きくし、将来的なマージのプレッシャーを減らすことを意味します。\nデフォルトは10%で、それで十分です;例えば、もし、5つのアクティブなシャードがノードにあり、ヒープが25GBの場合、各シャードは25GBの10%の1/5=512MB(すでに最大値)を持っています。ヘビーなインデキシングのあと、この設定をデフォルトに下げましょう。検索時のデータ構造のために十分なRAMを確保するために。この設定はまだ動的な設定変更はできません。Issueがここにあります。\nインデックスバッファによって現在利用されているバイト数は1.3.0のindices stats APIに追加されています。indices.segments.index_writer_memoryの値を見ることができます。これはMarvelではまだプロットされていませんが、将来のバージョンで追加される予定です。しかし、自分でグラフに追加することもできます。(Marvelはデータは収集しています)\n1.4.0では、indices.segments.index_writer_max_memoryとして、indices stats APIにアクティブシャードにどのくらいのRAMバッファが割り当てられているかも表示されます。これらの値はインデックスのシャード事の値として見ることができ、http://host:9200/\u0026lt;indexName\u0026gt;/_stats?level=shardsを使ってみることができます;これは、全シャードに対する合計と、各シャードごとのstatsを返すでしょう。\nオートIDの利用もしくは良いIDの利用 もし、ドキュメントのIDがなんでも良い場合、Elasticsearchで採番することができます:これは、(1.2以降)ドキュメントIDをバージョンを探さずに保存できるように最適化され、Elasticsearchの日毎のベンチマークで異なるパフォーマンスを見ることができます。(FastとFastUpdateのグラフを比較)\nもし、IDを自身が持っていて、自分の支配下でLuceneに対して素早く選ぼうとしているなら、1.3.2にアップグレードしましょう、IDのルックアップがさらにオプティマイズされています。JavaのUUID.randomUUID()はやめましょう。それは、セグメントに対してどのようにIDを割り当てるかという予測やパターン性がないため、最悪のケースでセグメントごとのシークが発生します。\nFlake IDsを利用した時のMarvelによるインデックス性能の違い:\nflakeIDsPerf ランダムUUIDを利用した場合:\nuuidsPerf 次の1.4.0では、ElasticsearchのID自動採番をUUIDからFlake IDに変更します。\nもし、Luceneのローレベル操作がインデックスに対してなにをやっているかについて興味があるなら、lucene.iwをTRACEログレベルで出力できるようにしてみましょう(1.2から利用可能)。これは、多くの出力がありますが、LuceneのIndexWriterレベルで何が起きているかを理解するのに非常に役に立ちます。出力は非常にローレベルです:Marvelがインデックスに何が起きているかをよりリアルタイムにグラフを描画してくれます。\nスケールアウト 我々は、単一シャード(Luceneインデックス)性能のチューニングに注目してきました。しかし、一旦それに満足できたならば、Elasticsearchはクラスタ全体にわたってインデキシングや検索を簡単にスケールアウトすることに長けています。シャード数(デフォルトでは5)を増やすのは可能です。それは、マシン全体に対して並列度、巨大なインデックスのサイズ、検索時のレイテンシの低下など得ることができます。また、レプリカを1位上にすることは、ハードウェア故障に対する冗長性を持つことを意味します。\n最後に、このドキュメントを見ても問題解決しない場合はコミュニティに参加しましょう。例えば、ElasticsearchのユーザMLに投稿するなど。おそらく、修正すべきエキサイティングなバグがあるでしょう。(パッチも常に歓迎です!)\n","date":1410250260,"dir":"post/2014/","id":"77d965afaebd7193badc746d52b4173f","lang":"ja","lastmod":1410250260,"permalink":"https://blog.johtani.info/blog/2014/09/09/performance-considerations-for-elasticsearch-indexing/","publishdate":"2014-09-09T17:11:00+09:00","summary":"Elasticsearchのインデキシングに関するパフォーマンス検討 原文:performance considerations for elasticsearch indexing Elasticsearchユーザは様","tags":["Elasticsearch"],"title":"Elasticsearchのインデキシングに関するパフォーマンス検討"},{"contents":"懲りずにまた、執筆してみました。みなさん「買って」から感想をいただけるとうれしいです!\n本書について 共著者の方々のブログが詳しいので、そちらを読んでもらいつつ。 実際にログを収集して解析されている方々と一緒に書かせていただくことで色々と勉強させていただいています。\n共著者の方々のブログ @suzu_vさん:サーバ/インフラエンジニア養成読本 ログ収集~可視化編 を書きました @yoshi_kenさん:ログ収集や可視化で話題のFluentd、Elasticsearch、Kibanaを徹底解説したムック本が発売となります @harukasanさん:書きました: サーバ/インフラエンジニア養成読本 ログ収集~可視化編 どの辺を書いたの? 「特集3:Elasticsearch入門」(なんか、入門ばっかりだなぁ)を書かせていただきました。 データストア入門ということで、ほんとうに簡単な他のデータストアを説明し、Elasticsearchってどんなものかを単語の説明をしつつ紹介してみました。\nElasticsearch自体は多くの機能を持っており、それ単体で分厚い書籍がかけるので、ログ検索に関係ありそうな部分をピックアップしてみました。 あとは、運用時に気をつける点や便利なツール(Curatorなど)の紹介をしています。\nまた、Hadoopと合わせて利用してみたい、すでにHadoopにあるデータも活用してみたいという話もありそうだということで、elasticsearch-hadoopについても簡単ですが紹介してあります。\nその他感想 個人的に、忙しい時期(参考記事)だったので、あんまり力になれてないので大変申し訳なく思っています。。。 ただ、素晴らしい出来(カラーでKibanaの解説が日本語で読めたり、Fluentdの逆引きのリストがあったり、ログを貯めて可視化する意義を説明してあったり)です。\nぜひ、読んだ感想をいただければと!\n","date":1407156840,"dir":"post/2014/","id":"bdea71d64cdfcc405e65e750fe8d9b86","lang":"ja","lastmod":1407156840,"permalink":"https://blog.johtani.info/blog/2014/08/04/release-magazine-book-of-log-aggs-and-viz/","publishdate":"2014-08-04T21:54:00+09:00","summary":"懲りずにまた、執筆してみました。みなさん「買って」から感想をいただけるとうれしいです! 本書について 共著者の方々のブログが詳しいので、そちらを","tags":["elasticsearch","kibana","本"],"title":"サーバ/インフラエンジニア養成読本 ログ収集~可視化編 を手伝いました"},{"contents":"Proxy環境で働いている方も結構いると思います。 Twitter上で、Elasticsearchのpluginコマンドでプラグインがインストールできなくて困っている方がいたので、 調べてみたのでメモしておきます。\nプラグインコマンド Elasticsearchでは、プラグインという形でいくつかの便利な機能が公開されています。 形態素解析ライブラリのKuromojiを使うためのプラグインや、クラスタの管理がGUIで可能なkopfプラグインなどがあります。 公式、サードパーティいろいろです。\nこれらのプラグインをElasticsearchにインストールする場合、以下のコマンドを実行すれば 自動的にダウンロードしてpluginsディレクトリにインストールしてくれます。\n./bin/plugin -i elasticsearch/elasticsearch-analysis-kuromoji/2.3.0 ここで、elasticsearch/elasticsearch-analysis-kuromoji/2.3.0がプラグインのパスになります(例では、提供元/プラグイン名/プラグインバージョンとなっています。)。\nこのpluginコマンドがダウンロード元にアクセスに行くのですが、プロキシ環境だとプロキシの設定が必要になります。\nプロキシの指定(Mac/LinuxとWindowsでの違い) Mac/Linux(shコマンド) 以前の記事でプロキシのポート番号などの指定方法を 以下のように説明していました。 (※昔の記事のため、kuromojiプラグインのバージョンが古いです)\nElasticsearchのpluginコマンドはJavaで実装されています。(org.elasticsearch.common.http.client.HttpDownloadHelper) プラグインのダウンロードには、java.net.URL.openConnection()から取得URLConnectionを使用しています。\nですので、pluginのインストールを行う際に、Proxy環境にある場合は以下のようにコマンドを実行します。\n./bin/plugin -DproxyPort=ポート番号 -DproxyHost=ホスト名 -i elasticsearch/elasticsearch-analysis-kuromoji/1.5.0 LinuxやMacの環境であれば、こちらのコマンドでプロキシの指定が可能です。 ただし、Windows環境ではうまくいきません。\nElasticsearchは、環境の違いにより、ダウンロードするファイルが異なります。 Windows環境の方は、zipファイルをダウンロードしてもらうようになっています。 elasticsearchコマンドおよびpluginコマンドがbat形式で提供されているのがzipファイルとなるからです。\nWindows(batコマンド) Windows環境では次のように指定します。\nset JAVA_OPTS=\u0026#34;-DproxyHost=ホスト名 -DproxyPort=ポート番号\u0026#34; bin\\plugin -i elasticsearch/elasticsearch-analysis-kuromoji/2.3.0 コマンドの実装方法が少し異なるために、このようになっています。\nまとめ プロキシ環境で利用される場合は、プラグインコマンドは上記のように実行していただければと。\n公式ガイドには、これらの情報を追記するPRを送る予定です。 また、WindowsのコマンドでもMac/Linuxと同様にできたほうがいい気がするので、Issueをあげようと思います。\n不明点などあれば、コメントいただければと。\n","date":1406874240,"dir":"post/2014/","id":"7cc605e721fdd1d2ccc16f5b6490e830","lang":"ja","lastmod":1406874240,"permalink":"https://blog.johtani.info/blog/2014/08/01/plugin-using-under-proxy-env/","publishdate":"2014-08-01T15:24:00+09:00","summary":"Proxy環境で働いている方も結構いると思います。 Twitter上で、Elasticsearchのpluginコマンドでプラグインがインスト","tags":["elasticsearch","plugin"],"title":"プロキシ環境でのpluginコマンドの実行"},{"contents":"原文:Elasticsearch 1.3.1 Releasedを日本語に翻訳したものです。\nバグフィックス版のElasticsearch 1.3.1をリリースしました。 ダウンロードおよび変更履歴はElasticsearch 1.3.1からお願いいたします。\nこのリリースはインデックスリカバリ時の後方互換性バグ(#7055)への対応です。 このバグはデータの欠損は起こりません。 Elasticsearch 1.3.1へアップグレードすることで問題を回避できます。 このバグは、以下のElasticsearchのバージョンで作成されたセグメントを含むインデックスを1.3.0へアップグレードしようとすると発生します。\nElasticsearch 0.90.7 Elasticsearch 0.90.2 Elasticsearch 0.90.0以前のバージョン このバグは、これらの古いインデックスをレプリカからリカバリできなくします。 これらのバージョンのセグメントを持つインデックスが、レプリカは可能ですが、 ステータスがYellowのままGreenに決してなりません。 ログには次のようなExceptionが発生します。\nIllegalArgumentException[No enum constant org.apache.lucene.util.Version.x.x.x]\nLuceneの特定のバージョンではLuceneのマイナーバージョンを含んでおらず、誤ったバージョン番号がセグメントに記録されました。 LUCENE-5850のチケットがこの問題に対処するためにオープンされています。 この問題は我々の後方互換テストで見つかるべき問題ですが、Luceneで不足しているため発見されませんでした。 テストスイートは今後の可能性のために改良されます。\nこのリリースはその他に、Aggregationのマイナーバグフィックスも含まれています。 詳細はリリースノートをご覧ください\nElasticsearch 1.3.1をダウンロードし、試してください。 もし問題を見つけた場合はGitHubのIssuesへご報告をお願いいたします。\n","date":1406604120,"dir":"post/2014/","id":"fb1da4a6ed74705ad98bb60ad4badaf2","lang":"ja","lastmod":1406604120,"permalink":"https://blog.johtani.info/blog/2014/07/29/elasticsearch-1-3-1-release/","publishdate":"2014-07-29T12:22:00+09:00","summary":"原文:Elasticsearch 1.3.1 Releasedを日本語に翻訳したものです。 バグフィックス版のElasticsearch 1.3.1をリリー","tags":["elasticsearch","release"],"title":"Elasticsearch 1.3.1 リリース(日本語訳)"},{"contents":"Curatorの1.2.0がリリースされました。\n前回のCuratorの記事が古くなってしまった(1.1.0からコマンドのI/Fが変更された)ので 1.1.0および1.2.0に関する記事を翻訳しておきます。\nちなみに、Curatorとは、Elasticsearchに時系列のインデックス(例:LogstashやFluentdでログを保存)を保存している場合にそれらのインデックスを管理(削除したり、クローズしたり)するための便利なツールです。 Curatorの概要については、GitHubリポジトリか前回の記事をご覧ください。\nCurator 1.1.0リリース (2014/06/13公開) 元記事:elasticsearch curator - version 1.1.0 released\nElasticsearch 1.0.0がリリースされ、新しい機能、Snapshot \u0026amp; Restoreが利用できるようになりました。 Snapshotはある時点でのインデックスの写真を撮るように、バックアップを作成することができます。 1.0.0が発表されてすぐに、この機能に関するリクエストが寄せられるようになりました。 「Curatorにスナップショットを追加して!」もしくは「いつCuratorでスナップショットが使えるようになる?」といった感じです。 これがあなたの要望なら、それはついに叶えられました。しかも他の追加機能も一緒にです。\n新機能 Curatorの新機能は以下のとおりです。\n新CLI構造 スナップショット(Snapshot) エイリアス(Aliases) パターンによる除外インデックス指定 配置ルーティング(Allocation Routing) インデックスとスナップショットの表示 リポジトリ管理(個別のスクリプトによる) ドキュメントWiki 新コマンドライン構造 注意:コマンドライン構造の変更とは、Curator 1.1.0以前のcron記述が動作しないことを意味します。Curator 1.1.0にアップグレードする場合はコマンドも修正が必要となるので注意してください。\nシンプルにするために、commandsという概念を追加しました。 また、ヘルプの出力もわかりやすくなっています。 前のバージョンと同じタスクをCuratorは実行できますが、異なるフォーマットを用いるようになりました。\n旧コマンド:\ncurator -d 30 新コマンド:\ncurator delete --older-than 30 コマンドは、フラグとは異なりハイフンを前に付けないことに注意してください。 また、似たような名前のフラグがあることに気をつけてください。 例えば、--older-thanフラグは多くのコマンドに利用できます。 指定される値は各ケースにおいて同一です。「指定された数よりも古いインデックス」となります。\n新しいコマンドのリストは次のとおりです。\nalias allocation bloom close delete optimize show snapshot コマンドのヘルプは次のコマンドで表示されます。\ncurator [COMMAND] --help コマンドに関係あるフラグがすべて表示されます。\nスナップショット(snapshots) snapshotコマンドで、存在しているリポジトリにインデックスのスナップショットを保存することができます。\nCuratorはインデックス毎に1つのスナップショットを作成し、インデックスから名前をつけます。 例えば、インデックスの名前がlogstash-2014.06.10の場合、スナップショットの名前はlogstash-2014.06.10となります。 指定した条件を元に、シーケンシャルに、1つずつインデックスのスナップショットを作成していきます。\ncurator snapshot --older-than 20 --repository REPOSITORY_NAME このコマンドは、20日以上古いインデックスすべてのスナップショットを作成し、REPOSITORY_NAMEで指定されたリポジトリに保存します。\nes_repo_mgrと呼ばれるリポジトリ作成を支援するスクリプトがCuratorには含まれています。 ファイルシステムおよびS3タイプのリポジトリ両方の作成を支援します。\nさらに、古いインデックスのスナップショットを取ることができることに加えて、Curatorは最新のインデックスをアップロードする方法も提供します。 これは、Elasticsearch Marvelのインデックスをアップロードするときに便利です。 トラブルシューティングを目的として、パフォーマンスデータを他の人に見せる場合などです。\ncurator snapshot --most-recent 3 --prefix .marvel- --repository REPOSITORY_NAME このコマンドでは、最新の3つのMarvelインデックスのスナップショットを指定されたリポジトリに保存できます。\nエイリアス(aliases) Curatorはすでに存在するエイリアスにインデックスを追加することも、削除することもできるようになりました。 ただし、エイリアスがすでに存在している必要があります。エイリアスの作成はできません。\nlast_weekという前の一週間のインデックスのエイリアスを保持していること想像してください。 この場合、次の2つのコマンドを利用することで、エイリアスを管理できます。\ncurator alias --alias-older-than 7 --alias last_week curator alias --unalias-older-than 14 --alias last_week 新しく作られたインデックスがインデックステンプレートによって 自動的にエイリアスの一部となるようにElasticsearchに設定しておくと、さらに便利です。 この場合、新しいインデックスが自動的にthis_weekというエイリアスの一部になるようにしてあれば、以下のコマンドのみとなります。\ncurator alias --unalias-older-than 7 --alias this_week this_weekとlast_weekのエイリアスのアップデートを保持できます。\nパターンによる除外(exclude pattern) 時には、指定したインデックスを操作から除外したくなる場合もあるでしょう。 ここまでは、プレフィックスや日付によって選択されたインデックスのみを対象にしてきました。 そこで、--exclude-patternオプションです。これは、指定したインデックスを除いて処理を行うことができます。\nlogstash-2014.06.11というインデックスを決して削除したくないとします。 この場合、次のコマンドのようになります。\ncurator delete --older-than 15 --exclude-pattern 2014.06.11 Curatorはデフォルトでlogstash-というプレフィックスにマッチしますが、2014.06.11というインデックスは対象外となります。\n配置ルーティング(allocation routing) Elasticsearchはノードにタグを付けることができます。 これらのタグはインデックスやシャードをクラスタのどこに配置するかをコントロールするために役立ちます。 一般的なユースケースだと、高性能なSSDドライブを持ったノードをインデキシングのために、ハードディスクを持った性能の低いマシンは検索頻度が低い古いインデックスを配置するといった場合です。 この場合、HDDノードには、elasticsearch.ymlにnode.tag: hdd、SSDノードにはnode.tag: ssdと設定されているべきです。 Curatorはこの時、インデックスをタグに基づいてオフピークの時間帯に再配置させることができます。\nコマンド:\ncurator allocation --older-than 2 --rule tag=hdd index.routing.allocation.require.tag=hddという設定が2日よりも古いインデックスに適用されます。 これは、インデックスのシャードがnode.tag: hddというノードに再配置される必要があると、Elasticsearchに伝えます。\nインデックスとスナップショットの表示(show indices and snapshots) これは、単にあなたの持っているインデックスやスナップショットがどんなものかを表示します。\ncurator show --show-indices これは、デフォルトプレフィックスのlogstash-にマッチするすべてのインデックスを表示します。\ncurator show --show-snapshots --repository REPOSITORY_NAME これは、指定されたリポジトリにある、デフォルトプレフィックスのlogstash-にマッチするすべてのスナップショットを表示します。\nリポジトリ管理(repository management) 前に説明したとおり、es_repo_mgrと呼ばれるヘルパースクリプトをCuratorは含んでいます。 現時点では、fsとs3タイプをサポートしています。 リポジトリを作る前に利用したいタイプのドキュメントを読むようにしてください。 例えば、fsタイプのリポジトリを各ノードで使う場合は、同じ共有ファイルシステムに、同じパスでアクセスできなければなりません。 パスの指定は--locationです。\nfsタイプリポジトリの作成\nes_repo_mgr create_fs --location \u0026#39;/tmp/REPOSITORY_LOCATION\u0026#39; --repository REPOSITORY_NAME 削除\nes_repo_mgr delete --repository REPOSITORY_NAME ドキュメントWiki Curatorのドキュメントが更新され、オンラインにWiki形式でだれでも更新できるようになっています。 コマンドやフラグのより詳細の情報はこちらで見つけることができます。また、もし、興味があれば、ドキュメントを追加することもできます。\nインストールと更新 Curator 1.1.0はPyPiリポジトリにあります。 インストールは以下のとおりです。\npip install elasticsearch-curator バージョン1.0.0からアップグレードする場合は以下のとおりです。\npip uninstall elasticsearch-curator pip install elasticsearch-curator バージョン1.0.0よりも古いバージョンからのアップグレードは以下のとおりです。\npip uninstall elasticsearch-curator pip uninstall elasticsearch pip install elasticsearch-curator pip uninstall elasticsearchで、古いパイションモジュールをを削除します。 適切なバージョンが依存関係により再インストールされます。\nまとめ Curatorの新機能は素晴らしいです!このリリースは大きな改善です。 もし、トラブルや足りないものを見つけた場合はGitHub Issueに報告してください。 また、Curatorが便利だと思ったら、私たちに伝えてください。#elasticsearchタグを付けてツイートしてください!\nCuratorはまだ、始まったばかりです。Curator 2.0のロードマップを作業中です。ここまで読んでいただきありがとうございます。 Happy Curating!\nCurator 1.2.0リリース(2014/07/24) 元記事:curator 1.2.0 released\nCurator v1.1.0のリリースから、数週間が経ちました。 私たちは、Curator 1.2.0をリリースしました。\n新機能(new features) ユーザ指定の日付パターン:長い間リクエストされていた機能 ウィークリーインデックスのサポート:これも長い間リクエストされていた機能 複数のログフォーマットオプション:Logstashフォーマットが利用可能 これらの変更はCuratorドキュメントにも記載されています。\n更新(updates) ログ出力の整理:デフォルトのログ出力を整理しました。デバッグログはすべて表示されます。 ドライランのログ出力の詳細化:テスト実行時に何が起きたかをわかりやすくしました。 日付パターンと--timestring(date patterns and \u0026ndash;timestring) 前のリリースで、セパレータ文字を利用して、インデックス名のエレメントを分離することで、日付を計算しました。 この設計の決定は、プログラムが管理するために設計されたLogstashのインデックスを使うのには簡単でした。 しかし、Curatorは時系列インデックス管理に成長しています。これは、異なる命名規則のインデックスを意味しています。\nまた、インターバルによって、日付の計算が必要になる場合もあります。 --time-unitオプションが残っており、weeksという単位を指定することもできます。 デフォルトの--timestringオプションは、以前のコマンドと同様の動作をしなければなりません。次のようになります。\nTime Unit Timestring days %Y.%m.%d hours %Y.%m.%d.%H weeks %Y.%W これが意味するものは、もし、単位にhoursをした場合、--timestringを指定しなかった場合は%Y.%m.%d.%Hとなります。 これは、Pythonのstrftimeフォーマットで\u0026quot;年.月.日.時\u0026quot;を意味します。 同様に、weeksを単位に指定した場合、Curatorはデフォルトの--timestringは%Y.%Wとなります。\nこの機能は、日付の間にセパレーター文字のないインデックスでも機能します。 例えば、production-20140724のような日時インデックスがある場合、2日よりも古いインデックスに対するブルームフィルタっキャッシュのオフのコマンドは次のようになります。\ncurator bloom --prefix production- --older-than 2 --timestring %Y%m%d この例で、デフォルトの単位はdaysであることに注意してください。hourly-2014072414のような時間インデックスの場合は次のようになります。\ncurator bloom --prefix hourly- --older-than 2 --time-unit hours --timestring %Y%m%d%H --separatorの置き換え もし、Curatorの前のバージョンでカスタムセパレータ文字を利用していた場合、次のように変更すべきです。 前のコマンドでcerberus-2014-07-24のようなインデックスがある場合、コマンドを--separator -の用に置き換える必要があります。 新しいコマンドは次のとおりです。\ncurator delete --prefix cerberus- --older-than 30 --timestring %Y-%m-%d 年(%Y)と月(%m)と日(\u0026rsquo;%d\u0026rsquo;)の間にセパレータ文字を置くだけです。\nこれは、また、Curatorで以前は不可能であったことをできるようにもします。 異なるセパレータ文字の混在です。 logs-2014.07.24-14というようなインデックスを処理するときに--timestringは%Y.%m.%d-%Hのようになります.\n--timestringの詳細はCuratorのドキュメントをご覧ください。\nフィードバック これらの新しい機能はユーザのコメントやリクエストから来ています。もし、機能のリクエストやバグを発見したら、こちらまで連絡してください。\nまた、Twitterでもお待ちしています。私たちのTwitter IDは@elasticsearchです。\nHappy Curating!\n","date":1406524740,"dir":"post/2014/","id":"0c1821d1069578551d0e3c7d9275f16b","lang":"ja","lastmod":1406524740,"permalink":"https://blog.johtani.info/blog/2014/07/28/curator-2-0-and-1-1/","publishdate":"2014-07-28T14:19:00+09:00","summary":"Curatorの1.2.0がリリースされました。 前回のCuratorの記事が古くなってしまった(1.1.0からコマンドのI/Fが変更された)","tags":["elasticsearch","curator"],"title":"Curator 1.2および1.1について"},{"contents":"第5回Elasticsearch勉強会を開催しました。 遅くなってしまいましたが、まとめてみました。\n今回は、Elasticsearchに入って初の勉強会でした。タイミングが良いことに、Honza、Igor、Shayの3名がトレーニングのために 来日していたため、特別回ということにして、話をしてもらいました。\nそして、サムライズムの@yusukeさんにテキスト翻訳してもらいました。 早くて正確なタイピング+翻訳、本当にありがとうございました。\n開場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 次回もよろしくお願いします! 参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\namazing turnout to the elasticsearch at Tokyo #elasticsearchjp pic.twitter.com/Aa88eVf5dF\n\u0026mdash; Shay Banon (@kimchy) 2014, 7月 14 動画があとで、アップされる予定です。お楽しみに。\nHonza\u0026rsquo;s talk djangoの開発者!であり、ElasticsearchのPythonクライアント、Curatorの開発者 Python Clientを利用しながら、ライブコーディングのような形で説明する方法が新鮮 Aggregationの便利さについての説明 Python Clientがクエリを組み立てるのにすごく便利そうだった Pythonユーザが結構いたので助かりましたw Igor\u0026rsquo;s talk スライド:elasticsearch data/\nSnapshot/Restoreの開発などを行っている開発者 Elasticsearchのデータ、ディレクトリ構造に関するお話 シャードの話から、ディレクトリ構造、メタデータに関する説明 transaction logの挙動の説明 検索のフェーズの説明 Igorは、実は私がElasticsearch社の人とコンタクトがとれた最初の人だと思います。 第1回Elasticsearch勉強会が開催する当日に帰国されるという不運だったのですが、1年越しでトークしてもらえました!\n@johtani I am so bummed! I am leaving Tokyo Thursday morning.\n\u0026mdash; Igor Motov (@imotov) 2013, 8月 27 QA ShayをメインにいくつかのQAをしてもらいました。 NetflixなどのMeetupの動画で見てたのですが、こんな形で日本でも実現できるとは。\nQ: なんで、ファイルデスクリプタの設定を大きくするの? A: Luceneのインデックスは複数のセグメントから構成されている。メモリに作られたあと、ファイルにfsyncされる。 Q: KibanaでAggregation使いたいんだけど? A: Kibana 4で対応するよ!異なるフィールドの値を1つのグラフにすることも出来るよ! Q: なんでElasticsearch作ったの? A: 暇だったからw奥さんのレシピ検索を作ってみようと思って作り始めて、Luceneを触って感動して。。。検索すげー、Compassってのを触ってこれもすごいと思いつつ、もっとLucene活用できるんじゃないかということでElasticsearch作ったんだ。奥さんのレシピ検索?まだ完成してないよw Q: 2000くらいスナップショット撮ったらパフォーマンスが悪くなっててなんで? A: 差分でスナップショットを作るんだけど、差分の計算に昔のスナップショットを見るので、定期的に新しくしたほうがいい。もし、気になることがあったらIssue上げたりMLに投げてくれるとうれしい。\n(あとでちょっと聞いたけど、古いスナップショットを消すのも有効っぽい。差分でスナップショットを作るけど、昔のを消した場合は、新しいスナップショットが利用しているファイルは残る仕組みになっているから。) Q: Relevancyのチューニングってどうすればいい?ドキュメントが少なくない? A: ドキュメンテーションは頑張ってるので、応援してねwあとは、definitive guideも参考になるよ。スコアはfunction_scoreクエリがすごいのでいろいろ使ってね。MVELをGroovyに帰る予定。性能もだけど、サンドボックス的な意味もあります。 Q: 次のVisionは?現時点は検索だけど。(最後の質問がとてもナイスで、助かりましたw私がしたほうがいい気がするww) A: 今後はアナリティクスのプラットフォームに向かってる。Aggregationとかね。メモリ効率よくしたりしてるよ。あとは、Field-collapsionも実装中だよ。あと、マシンラーニングとかもね。データを探索するための機能を色々作ってくよ。障害性にも。チェックサム機能をLuceneに入れて、ESにも入れていく予定。Zenの機能も改善している。 まとめ 今週は、トレーニングがあったり、いろいろな打ち合わせがあったりと、テンパってたので至らない点が多かったかもしれないですが。。。 楽しんでいただけと思います。 数日、Shay、Honza、Igorと行動を共にして、本当に情熱のあるチームでユーザのことを気にかけているなと感じることができました。 少しでもその片鱗を勉強会で感じてもらえたんじゃないかと。特に、QAでのShayによる情熱が伝わったんじゃないかと。\n懇親会でも数人の方から、日本語のサポートを望んでいるという声も頂きました。 興味のある方は私までコンタクトいただければと。\nあと、@yusukeさんのテキスト翻訳が素晴らしくて、参加してもらった方たちも絶賛してました。 次回も英語スピーカーの場合に助けてもらえると嬉しいです(私もそこまで出来るように頑張ります)\nその他のブログ ブログ記事ありがとうございます!\n第5回elasticsearch勉強会にいってきました - はやさがたりない。 感想戦:aggrigation から見える検索エンジンの次 - 第5回 Elasticsearch勉強会 - よしだのブログ 「第5回elasticsearch勉強会 #elasticsearch #elasticsearchjp」(2014年07月14日)の参加メモ - uchimanajet7のメモ ","date":1405774320,"dir":"post/2014/","id":"e3e146469ed4318eaa2ffbca3510c054","lang":"ja","lastmod":1405774320,"permalink":"https://blog.johtani.info/blog/2014/07/19/hold-on-5th-elasticsearch-jp/","publishdate":"2014-07-19T21:52:00+09:00","summary":"第5回Elasticsearch勉強会を開催しました。 遅くなってしまいましたが、まとめてみました。 今回は、Elasticsearchに入って","tags":["elasticsearch","勉強会"],"title":"第5回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"ということで、転職しました。 どーしてもやりたいことが出てきたので、無理を言って転職することにしてみました。\nサムライズムではなく、Elasticsearchにジョインします。(というか、しました。)\n初出社 #サムライズム\n\u0026mdash; Jun Ohtani (@johtani) 2014, 7月 1 冗談でツイートしたのですが、その前に英語アカウントのツイートがRTされてしまっていまいちでした。。。\nスキポール空港 先週、アムステルダムに行っていたのも退職前に休みをいただき、Elasticsearchの全社会議に参加していたためです。 とてもエキサイティングな経験(英語漬けとか)ができ、もっと精進しないとなという気持ちにもなり、ますます頑張らないとなと。\nということで、今後は日本中にElasticsearchやLogstash、Kibanaを広めるべく、いろいろな場所で話をしたいと思います。 興味のある方は、声をかけていただければと。\nあと、東京でElasticsearchのCoreトレーニングが行われます。 通常は2日間ですが、通訳の方が付く関係で3日間の開催となっています。 開発者2名がトレーナーとして来日します。開発者に質問をできる良い機会ですので、興味のある方は参加してみてはいかがでしょうか。 また、CTOのShay Banonも来日する予定です。\nトレーナー2名とShayは7/14の勉強会でも話をしてくれます。 こちらも興味のある方は参加してみてください。(参加登録はこの後、すぐに開始します。)\nまだまだ、勉強しなければいけないことだらけですが、ElasticsearchのいろいろなプロダクトやOSSについて広めていきたいと思いますので、よろしくお願いいたします。\nおまけ ということで、一度やってみたかったのでリンクを貼ってみます。\nほしい物リストはこちら\n","date":1404181800,"dir":"post/2014/","id":"21a8e6324e9330d4f8ebade604c62b6e","lang":"ja","lastmod":1404181800,"permalink":"https://blog.johtani.info/blog/2014/07/01/join-elasticsearch/","publishdate":"2014-07-01T11:30:00+09:00","summary":"ということで、転職しました。 どーしてもやりたいことが出てきたので、無理を言って転職することにしてみました。 サムライズムではなく、Elasti","tags":["転職"],"title":"転職しました"},{"contents":"退職しました。\n色々と書きたいんですが、時差ボケで頭痛いので、このくらいです。 余裕出たら書くかも。\nほしい物リストはこちら\n新天地についてはまた明日。\n","date":1404137940,"dir":"post/2014/","id":"40abea0a87a64bd832a1fad69458b293","lang":"ja","lastmod":1404137940,"permalink":"https://blog.johtani.info/blog/2014/06/30/resignation/","publishdate":"2014-06-30T23:19:00+09:00","summary":"退職しました。 色々と書きたいんですが、時差ボケで頭痛いので、このくらいです。 余裕出たら書くかも。 ほしい物リストはこちら 新天地についてはまた明","tags":["転職"],"title":"退職しました"},{"contents":"Elasticsearch server 2nd editionが発売されています。\n私が翻訳したのは前のバージョンですが。。。 まずは、目次を元にどのくらい変わってるかを見てみました。 (全部まだ読んでなくて。。。)\n1章 Getting Started with the Elasticsearch Cluster 冒頭に、全文検索とは、転置インデックスとはどんなものか、 Luceneの簡単なアーキテクチャの仕組みについて説明が追加されています。 検索の仕組みを知らない人が読んでもわかりやすくなっています。\nインストール方法なども少し追記されています。 バージョニングと簡単なデータ登録と検索方法についてもここで触れられています。 検索結果の構造の説明もちょっとあります。 まず簡単に触ってみるというところまでが1章でまとめられた感じです。\n2章 Indexing Your Data 新しく、切りだされた形です。 前のバージョンでは1章で説明されていた、Mapping周りが切りだされています。 シャードやレプリカの説明もこちらです。\nIPアドレスタイプ(IPv4のみ)とtoken_countタイプの説明も追加されてます。 similarityやpostingsフォーマットなどは新しく追記されています。 また、メタフィールドと呼ばれる_typeなどはこちらに移動しているようです。 マージ処理などの説明も追記されています。このあたりは、Mastering ElasticSearchに 記載されているものが移植された感じでしょうか。\n3章 Searching Your Data 前のバージョンでは2章だった章です。 クエリについては1.0で追加されたsimple_query_stringなどが追記されています。 constant_scoreやdismaxなどもです。\nまた、前のバージョンの3章で説明されていたハイライトや8章で触れられていたvalidate APIについても 移動しています。\n4章 Extending Your Index Structure 前のバージョンの3章で触れられていた、データの構造に関する部分がこの章になります。 親子や配列、ネスト等のデータのインデックスや検索の方法です。\n5章 Make Your Search Better スクリプティングや言語判定などの仕組みが記載されています。 また、ブーストについても同様です。Synonymについてもここです。 スパンクエリについては省略されたのかな?\n6章 Beyond Full-text Searching 1.0の目玉機能の一つであるAggregationの説明から始まります。 その後、ファセットやPercolatorについてです。メモリに関する注意点もありそうです。 また、Geoについての説明がこちらに移動されていました。 scroll APIについてもこちらで説明されています。\n7章 Elasticsearch Cluster in Detail 前の7章で記載されていたElasticsearchの分散の仕組み(Node Discovery)についての記載があります。 また、1.0で追加されたcircuit breakerやスレッドプール、インデックスのリフレッシュレートなど、Mastering ElasticSearchの 内容も追記されている気がします。\nインデックスやマッピングのテンプレート機能についてもここで説明があるみたいです。\n8章 Administrating Your Cluster 1.0で追加されたsnapshot/restoreの説明から始まります。 あとは、前のバージョンの7章で説明されていたクラスタ管理用のAPIについての説明です。 いくつか(例えばcat API)、1.0で追加されています。\nまた、シャードのリバランスの話も追加されているようです。 エイリアスやプラグインの話はこちらに移動してるみたいです。\n感想 ということで、とりあえず、駆け足で目次ベースで違いを見てみました。 Mastering ElasticSearchでの 知見がフィードバックされ、しかも1.0(すでに1.3が出そうな勢いですが。。。)にバージョンアップされた内容になっています。 冒頭がわかりやすくなっているので、検索をやったことのない方にもおすすめな書籍になった気がします。 英語が苦にならなければ、おすすめの一冊だと思います。\n来月から読み進めるつもりなので、また、面白い内容があったら感想を書いていこうと思います。 (また翻訳できるといいかもなー)\n","date":1402908420,"dir":"post/2014/","id":"916bda59bc7621d5c1790c040572a3c0","lang":"ja","lastmod":1402908420,"permalink":"https://blog.johtani.info/blog/2014/06/16/first-impression-elasticsearch-server-2nd-edition/","publishdate":"2014-06-16T17:47:00+09:00","summary":"Elasticsearch server 2nd editionが発売されています。 私が翻訳したのは前のバージョンですが。。。 まずは、目次を元にどのくらい変わってるかを見てみました。 (","tags":["elasticsearch","本"],"title":"Elasticsearch server 2nd editionのファーストインプレッション"},{"contents":"可視化ツール現状確認会に参加して、カジュアルウォーターじゃなくて可視化ツールの現状を確認してきました。\nということで、いつものメモです。\nMackerel と Graphite について (y_uuk1さん) Graphite 時系列 工夫すればスケーラブル SensuやCollectdと組み合わせたり GrafanaとGrapheneでGUI Mackerel素敵だよと。 架空のわかりやすいグラフが見れた Kibana \u0026amp; Grafana \u0026amp; Influga (hakoberaさん) Kibana\nかっこいい。 JVM大変。 Grafana\nGraphiteがカッコ悪いのでKibanaをフォーク なぜか、ESが必要。 InfluxDBに浮気しそう Influga\n@haoberaさん作 InfluxDB Queryサポート 迷ったら、Kibana入れとけ。\nDistinctがKibana出できないけど、それ以外はある程度行けるらしい。\naggregationがサポートされたら、できると思う。 Kibana以外は、バックエンドがタイムシリーズなので、縛りがある\n可視化ツール紹介(仮) (showyouさん) 誰がチャートを作るの? 誰が見るの? 一覧化されてて、あとで眺めたい IPython Notebookのデモ R shiny Serverのデモ Pentaho CE+Saikuのデモはネットワークがダメだったので割愛 分析側の視点を見せたかったので。 可視化とは何だったのか (harukasanさん) インフラ モニタリング、アナライズ、可視化どれ? 可視化は目的ではないよねと。 熱く、ユーザとサービスプロバイダ間の距離のお話。 ログ 生ファイルで残すのが重要 トータルで必要とか考えないといけないことがわかって面白かったw\nあなたの知らないrrdtool (shoichimasuharaさん) すげー! いろいろできるらしい(ノートPCの前にいなかったw) D3.jsとジオマッピング (Takaki_さん) 時空間推進課!すげー! ジオデータのおはなし。 TopoJSONとかGeoJSONとか Zipkinについて (synkさん) ものすごい数のJVMがThriftで殴りあってるらしい。 ZipkinはTwitterが作ったもの Brave、HTraceというのが、PureJava用のZipkinトレーシングプラグイン 見積もりする必要がないくらいでかいHBaseがあるので、そこにためてる。 まとめ LINEはエンジニアを大募集中 Graphiteについて (mickey19821 さん) ドリコムさんのGraphiteのおはなし Metricsの収集はCollectd Graphite-webがスケールできなくて困ってるらしい。 Graphiteで可視化ツラいw まとめ RRDTool最高\nあと、クックパッドの技術力がすごいという発表なんかもありました。\n","date":1401884100,"dir":"post/2014/","id":"5bb6f8322cdbda7a21e4aecbe04462b7","lang":"ja","lastmod":1401884100,"permalink":"https://blog.johtani.info/blog/2014/06/04/attending-visualize-study/","publishdate":"2014-06-04T21:15:00+09:00","summary":"可視化ツール現状確認会に参加して、カジュアルウォーターじゃなくて可視化ツールの現状を確認してきました。 ということで、いつものメモです。 Mackerel と Graphite","tags":["勉強会"],"title":"可視化ツール現状確認会に参加してきました。#可視化"},{"contents":"今月2回目の目黒で、初のドリコムさんです。 「最新インフラエンジニア技術勉強~Fluentd, Elasticsearch,Chefの実践実例~」に参加してきました。 もちろん、Elasticsearchってキーワードがあったからです。\nざっくりメモです。\nドリコムのInfrastructure as Code/ひらしーさん CM:jojoss、トレクル、など サーバ300台、クラウド○○台。月30〜50台の割合で増加中。 少人数でいかに回すか。 Chef Rubyが書ける人が多いから。 serverspec テストだよと。 すみません、色々と聞き逃しました。。。\nWinning the metrics battle/mickeyさん Graphiteとかを触っている。 1300台超えたら、色々大変だった。 失敗談 Cactiを利用して、色々と運用が大変だった。DCが別なのでProxyとか。 成功例?現行システム? 最大値、平均値、最小値などをプロット collectdを収集、送信に採用して、独自で開発? 受信して保存するのに、Graphite(carbon-relay、carbon-cache、DRBD、graphite-web)ってなってる。 1300台程度のサーバから、5分間隔で、問題ない。 Graphite良いツールだよ。 Q:過去データはどのくらい? A:5分間隔で1年分。\nQ:移動平均とかを使ったグラフとか時間かかりませんか?100台だと A:100台でもほとんど時間はかからない。\nFluentd プラグイン開発講座/外山 寛さん Fluentdプラグインを作ることができると威力倍増 Elasticsearchの勉強会の話までしてくれました! 勉強会スペース貸出しています。 未公開だけど、sedueのプラグインもあるらしい。 CHUNKとBUFFERとか覚えときましょう プラグインの作り方的なのがなかった気がしたので、今回の発表です。 gem作らなくてもディレクトリにおけば使えるよと。 td-agent使ってる人が大多数だよね。(fluentdを素で使ってる人は会場にはいなかった) エンジニア募集中 Q:エラー処理どうしてますか? A:今は、スルーしています\nQ:単体テストの書き方は? A:人によってバラバラみたいですね。\nMySQLと組み合わせて始める全文検索エンジン「elasticsearch」/yoshi_ken スライド:http://www.slideshare.net/y-ken/introduce-elasticsearch-mysql-importer\nElasticsearch歴は1年位です。\nMySQLを使っていて、モダンな検索がほしいですよね?ね?\nサジェスト、ファセット、位置情報、ネスト検索などなど。\nGoogleトレンドだとSolrに迫る勢いと。\n実データを用いて、手軽にElasticsearchと連携。\nBinaryLogではなく、SQLの結果を同意する方式。yamabiko\n今日は、新しいものを公開します。\nbulk import file generator as well as nested document from MySQL for elasticsearch bulk api 東京トレーニング\nElasticsearch本については、右にあるリンクをクリックしてくれるとうれしいなぁ。\n","date":1400840280,"dir":"post/2014/","id":"a578acf825a595ce95fe8f804b7208f0","lang":"ja","lastmod":1400840280,"permalink":"https://blog.johtani.info/blog/2014/05/23/attending-drecom-infra-study/","publishdate":"2014-05-23T19:18:00+09:00","summary":"今月2回目の目黒で、初のドリコムさんです。 「最新インフラエンジニア技術勉強~Fluentd, Elasticsearch,Chefの実践実例~","tags":["勉強会","elasticsearch"],"title":"最新インフラエンジニア技術勉強に参加しました。"},{"contents":"どうやら、中身がSolrベース?Luceneベース?になったらしいということで、 今日は「AWSプロダクトシリーズ|よくわかるAmazon CloudSearch」に行ってきました。\n※ElasticSearchではありません!\nということで、いつものメモ。\nCloudSearch Overview Amazon Web Services, Inc. Pravin Muthukumar(Product Manager) / Vivek Sriram (Business Development) Introduction to Search 検索の紹介。アイアンマンのDVD?のページにいろんな項目(フィールド)があるよねと。(もちろん、Amazonのページ) ファセット、Geo、テキスト処理(Analysis処理)、Postings listとか。とかとか ランキングも Amazon CloudSearch 独自実装orRDB拡張もある。 OSSもあるよね。 Legacy Enterprise SearchとしてFASTとかもある。 Building with CloudSearch 他のサービス同様、コンソールとかあるし、色々できるし、すぐ起動できるよと。 自動で、データが増えたら、パーティションが増えると。\n日本語の形態素解析があるらしい。何を使ってるのかな? ICUのノーマライズとかもやってくれるらしい。これかな?http://lucene.apache.org/core/4_8_0/analyzers-icu/index.html ユーザが辞書を指定できるのかな? 備えてる機能の説明\nファセット SimpleQuery Autocomplete Highlight などなど\nMulti-AZにも対応 QA Q:NGramありますか? A:今はないです。 Q:ユーザ辞書対応してますか? A:今はないです。 Q:lang-detectあるか? A:今はないので、自分で判定して、適切なフィールドに入れてね。 Expectation for CloudSearch Apache Solr contributor 大須賀 稔氏 Solr本の宣伝ありがとうございます!(右のアイコンから買ってもらえると更に嬉しいですw) Kinesisとかとの組み合わせとか、自然言語処理とか、いろいろとあるAWSのコンポーネントと組み合わせる例が欲しいと。 すばらしい、最後はManifoldCFがらみに持っていくとは。ACLがらみのクローリングとかあるといいじゃないでしょうかと。 Impression of using CloudSearch 吉田 匠氏 (@yoshi0309 http://blog.yoslab.com/) スライド:https://speakerdeck.com/yoshi0309/impression-of-using-cloudsearch\nお見かけしたことある気がするなぁ。 全部置き換えできる!わけではなさそう。。。 いいところ。 UIがいいし、セットアップが簡単 auto scaleがうれしい マルチドメイン、マルチスキーマがいい Luceneのdismaxサポートがいい。(edismaxじゃないのかな?) dismaxって書いてあるな。\nhttp://docs.aws.amazon.com/cloudsearch/latest/developerguide/search-api.html\nフィードの仕方に気をつけて!\nバッチサイズで課金されるので、1件ずつじゃなくて、複数件送ったほうがいい。 いきなりスケールアウトできるわけじゃない?\nウォームアップ機能がない。インスタンス上限がデフォルト50件\nVPC対応してほしい。\nインターネット経由になってしまう フィードのスピードが セキュリティグループ機能が使えない CloudSearch UseCase - SnapDish Vuzz Inc. 清田 史和氏 独自辞書をもって、Tokenizeは独自でやって、空白区切りでデータ登録している。 インデックス更新はSQSを使ってる。 古いAPIを使ってるらしい。 移行が結構大変らしい。 感想 使ったことないんですが、きめ細かい検索したい場合はちょっとテクニックが要るかもと思いました。 AWS初心者なんで、なんとも言えないんですが。。。\nといあえず、テキスト処理(アナライズ処理)で、単語がどうやって区切られるのかってのがわからないのはキツイんじゃなかろうかと。 ただ、簡単に起動できて、オートスケールできるのは素晴らしいと思います。\n","date":1400143800,"dir":"post/2014/","id":"706c033b4483b6d062b66d6e4ea0236a","lang":"ja","lastmod":1400143800,"permalink":"https://blog.johtani.info/blog/2014/05/15/amazon-cloud-seaarch-study-session/","publishdate":"2014-05-15T17:50:00+09:00","summary":"どうやら、中身がSolrベース?Luceneベース?になったらしいということで、 今日は「AWSプロダクトシリーズ|よくわかるAmazon Cl","tags":["勉強会","CloudSearch","AWS"],"title":"「よくわかるAmazon #CloudSearch 」に行ってきました!"},{"contents":"酔っ払ってなんとなく書きたくなったスピリチュアルなブログなので、流していただければと。\n最近、勉強会やTwitterで知り合いになって話をする人が増えたりで、 その方たちに色々と教えてもらうことが多いなぁと感じてます。 また、知り合いに恵まれてきたなぁとも。\nそもそも私が勉強会に参加し始めたきっかけはSolr勉強会(第1回から参加してて、気づいたら主催者になってた)で、 そのころは、Solr初心者で色々とやってる人、知ってる人がいて無料で話が聞けるのすごいと興奮したのを覚えてます。 (もちろん、ぼっちでしたが)\nSolr勉強会が定期的に開かれて、それに参加しているうちに少しずつ知り合いもできて、 面白そうな勉強会(Hadoopとか)が他にもあるんだ、参加してみようかって思うようになってと。\nそこにプラスで、関口さんと知りあえてSolr本を書く話が出てきて、本を書いてみたら、 今度は勉強会で話してみませんかとなって。\nスピーカーやると、顔を覚えてもらえるようで、また知り合いが増えてと。\n人のつながりって大事だし、自分が発信することで教えてもらえることもあるしと。 前にも書いた気がするけど、Solr勉強会(当時の主催の方)や関口さんやElasticsearch勉強会のスタッフの方や スピーカーやってくれた方、会場提供を心よくしてくれてるVOYAGE GROUP、リクルートテクノロジーズさん、という具合にどんどん頭が上がらなくなってきてるなぁと。\nということで、外の世界を知ると色々とつながりが出来て面白いですよという、個人的な感想でした。 ま、自分が思ってるだけで、違う意見もいっぱいあると思うけど。\nあー、なんか、酔って勢いで書いてしまった。。。 脈略のない文章なきがするけど、エイヤで公開しちゃおう。\n","date":1399999440,"dir":"post/2014/","id":"72df0bf7853e05560d94208817b83468","lang":"ja","lastmod":1399999440,"permalink":"https://blog.johtani.info/blog/2014/05/14/spiritual-entry1/","publishdate":"2014-05-14T01:44:00+09:00","summary":"酔っ払ってなんとなく書きたくなったスピリチュアルなブログなので、流していただければと。 最近、勉強会やTwitterで知り合いになって話をする","tags":["スピリチュアル"],"title":"外の世界を知るということ"},{"contents":"「アジャイルデータサイエンス」の見本をいただいてしまいました。\nなので、感想文でも書いてみようかと。\nどんな本? 想像以上に薄かったです、物理的に。 なのに、とても幅広い範囲をカバーしています。\nデータの分析にどんな人が関わっているのか、アジャイルにデータを分析する目的から始まり、 データから何かを見つけるための手順、考え方などをさらっとですが、 システムに取り込む流れから取り込んだあとに改良するという流れまで紹介してくれます。 流れはこんな感じ。\nイベント:ログとかのイベントの発生 コレクタ:イベントの収集 バルクストレージ:イベントの一時保存 バッチ処理:ストレージにあるデータに対して処理 分散ストア:処理結果をWebアプリなどで表示するために保存 Webアプリ:処理結果をユーザに提供 Webアプリでデータを見えるようにして、そこから更にフィードバックを受けることで、データの分析などを進めていくという流れです。\n私はデータサイエンス系の人ではないのでこの流れで作業をされているかはわからないのですが、 検索のシステムについてもこの流れに似ているなと感じました。\n検索システムでも、検索したいデータを収集して、加工(検索したい項目の洗い出しやファセットにする項目の選定とか)して、 インデックスを生成するといった処理が必要になるからです。\nこの本では、Python、Hadoop(Pig)、MongoDB、ElasticSearch(バージョンが0.90だから)、d3.jsなどが出てきます。 また、日本語版の付録では、Fluentd、Kibana+Elasticsearchといった組み合わせの紹介もあります。\nコードも書かれていますが、すみません、そこまでちゃんと読んでません。。。\n後半では、データを活用して行くためには順序があるという話が書かれています。\nレコード:レコード1件のアトミックな処理と表示 グラフ:レコードを元に集計したりグラフ作ったり レポート:関係性やトレンドを抽出し、インタラクティブに探求 予測:構造を利用して、推論やレコメンドとか 行動:上記の結果を元にユーザに行動を促す 前のステップがおろそかだと次のステップがうまくいかないという話です。 後半はこの流れに沿って、先ほどのシステムの流れを変更していく方法が展開されます。\n注意点 ちょっとだけ気になる点があったので。\nElasticsearch周りについては少し注意が必要かと。(Pigとかは詳しくないので不明です。) 紹介されているElasticsearchのバージョンが0.90と少し古いのと、 Hadoopとの統合(Pigで処理したデータをElasticsearchに出力)に利用されているWondordogというツールも最近更新がされていないみたいです。 おそらく、1.0系では動かないのではないかと。\n1.0系の場合は、Elasticsearchが提供しているelasticsearch-hadoopを利用するのが良いと思います。\n付録については1.0系で記載されているので問題ないかと。ただし、Elasticsearchは更新が早いので、公式サイトで最新情報を入手するのが良いと思います。\n感想 データを解析するシステムってどんなことやってるの?という全体像を 俯瞰するのに良い本なのではないかと思います。 また、データの解析を活かすために、必要な順序と疎かにできない点もあって面白かったです。\n紹介されているツール類については、OSSのトレンドや開発速度が早いので、参考程度にとどめておいて、 自分たちで使いやすいものを探してきて検討するのがいいと思います。\n付録がとても豪華です。FluentdやKibanaがわかりやすく解説されてます。\nあと、薄いのでさらっと読めます。w\n","date":1399563900,"dir":"post/2014/","id":"91fe03f994e8e85cede4e3bd62f4d6b7","lang":"ja","lastmod":1399563900,"permalink":"https://blog.johtani.info/blog/2014/05/09/reading-agile-data-science/","publishdate":"2014-05-09T00:45:00+09:00","summary":"「アジャイルデータサイエンス」の見本をいただいてしまいました。 なので、感想文でも書いてみようかと。 どんな本? 想像以上に薄かったです、物理的に","tags":["感想文","オライリー"],"title":"アジャイルデータサイエンスが届きました"},{"contents":"こんなツイートを見つけたので、Aggregationのサンプルでも書こうかなと。(前から書こうと思ってたんですが。。。)\n@elasticsearch Hi, Would you please tell me the way to do \u0026quot;Pivot Faceting\u0026quot; like Solr-4.0 in elasticsearch-1.1.1 or prior version? Thank you.\n\u0026mdash; Y.Kentaro (@yoshi_ken) 2014, 5月 2 ちなみに、Aggregationは1.0.0から導入された機能なので、ElasticSearch Server日本語版には掲載されていない機能になります。(ごめんなさい)\n公式ガイドのAggregationsのページはこちらになりますが、実例があったほうがいいかなと。\n@yoshi_ken さんから実例のサンプルの指定もいただいたので、ブログを書くのが非常に楽です。ありがとうございます。\n問題 元ネタ(gist)\n次のような不動産系のデータがあるとします。\nid 物件名 都道府県(東京、神奈川、\u0026hellip;..) 物件種別(賃貸、売買、\u0026hellip;..) この時、都道府県別に、物件種別ごとの件数を取得したいという趣旨です。\n東京 賃貸: xxx件 売買: yyy件 神奈川 賃貸: xxx件 売買: yyy件 \u0026hellip; これを、Elasticsearchでどうやって取得するかという問題です。\nインデックスとデータの登録 まずは、インデックスを作ります。 あくまでもサンプルなので、全部not_analyzedにしてますが、そのへんは適宜変更してください。\n# create index PUT /pref_aggs { \u0026#34;settings\u0026#34;: { \u0026#34;number_of_shards\u0026#34;: 2 }, \u0026#34;mappings\u0026#34;: { \u0026#34;japan\u0026#34; : { \u0026#34;_id\u0026#34; : { \u0026#34;path\u0026#34; : \u0026#34;id\u0026#34; }, \u0026#34;properties\u0026#34;: { \u0026#34;id\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;}, \u0026#34;name\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;}, \u0026#34;pref\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;}, \u0026#34;type\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;index\u0026#34;: \u0026#34;not_analyzed\u0026#34;} } } } } _idを使用して、データ登録時にidフィールドにある文字列をそのままIDとして登録できるように指定してあります。\n登録するデータは次のようなものを適当に100件程度作ってりました。\n{\u0026#34;id\u0026#34;: \u0026#34;id0\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;name0\u0026#34;, \u0026#34;pref\u0026#34;: \u0026#34;01_北海道\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;売買\u0026#34;} {\u0026#34;id\u0026#34;: \u0026#34;id1\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;name1\u0026#34;, \u0026#34;pref\u0026#34;: \u0026#34;09_栃木県\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;売買\u0026#34;} {\u0026#34;id\u0026#34;: \u0026#34;id2\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;name2\u0026#34;, \u0026#34;pref\u0026#34;: \u0026#34;38_愛媛県\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;賃貸\u0026#34;} {\u0026#34;id\u0026#34;: \u0026#34;id3\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;name3\u0026#34;, \u0026#34;pref\u0026#34;: \u0026#34;40_福岡県\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;賃貸\u0026#34;} {\u0026#34;id\u0026#34;: \u0026#34;id4\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;name4\u0026#34;, \u0026#34;pref\u0026#34;: \u0026#34;35_山口県\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;売買\u0026#34;} {\u0026#34;id\u0026#34;: \u0026#34;id5\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;name5\u0026#34;, \u0026#34;pref\u0026#34;: \u0026#34;12_千葉県\u0026#34;, \u0026#34;type\u0026#34;: \u0026#34;賃貸\u0026#34;} ... データの登録には、前に紹介した方法「stream2esと複数データの登録」を用いました。\nファセット このようなデータがある場合に、まず思いつくのはファセットによる取得です。 いささか強引ですが。。。\nGET /pref_aggs/japan/_search { \u0026#34;size\u0026#34;: 0, \u0026#34;query\u0026#34;: { \u0026#34;match_all\u0026#34;: {} }, \u0026#34;facets\u0026#34;: { \u0026#34;type_賃貸\u0026#34;: { \u0026#34;terms\u0026#34;: { \u0026#34;order\u0026#34;: \u0026#34;term\u0026#34;, \u0026#34;field\u0026#34;: \u0026#34;pref\u0026#34;, \u0026#34;size\u0026#34;: 50 }, \u0026#34;facet_filter\u0026#34;: {\u0026#34;term\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;賃貸\u0026#34; }} }, \u0026#34;type_売買\u0026#34;: { \u0026#34;terms\u0026#34;: { \u0026#34;order\u0026#34;: \u0026#34;term\u0026#34;, \u0026#34;field\u0026#34;: \u0026#34;pref\u0026#34;, \u0026#34;size\u0026#34;: 50 }, \u0026#34;facet_filter\u0026#34;: {\u0026#34;term\u0026#34;: {\u0026#34;type\u0026#34;: \u0026#34;売買\u0026#34; }} } } } facet_filterを使用して、typeフィールドによる個別の絞込を行っています。 あとは、prefフィールドのファセットを取得すれば、出力は次のようになります。\n{ \u0026#34;took\u0026#34;: 6, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 2, \u0026#34;successful\u0026#34;: 2, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 100, \u0026#34;max_score\u0026#34;: 0, \u0026#34;hits\u0026#34;: [] }, \u0026#34;facets\u0026#34;: { \u0026#34;type_賃貸\u0026#34;: { \u0026#34;_type\u0026#34;: \u0026#34;terms\u0026#34;, \u0026#34;missing\u0026#34;: 0, \u0026#34;total\u0026#34;: 52, \u0026#34;other\u0026#34;: 0, \u0026#34;terms\u0026#34;: [ { \u0026#34;term\u0026#34;: \u0026#34;00_北海道\u0026#34;, \u0026#34;count\u0026#34;: 1 }, { \u0026#34;term\u0026#34;: \u0026#34;01_青森県\u0026#34;, \u0026#34;count\u0026#34;: 2 }, { \u0026#34;term\u0026#34;: \u0026#34;03_宮城県\u0026#34;, \u0026#34;count\u0026#34;: 3 }, ... }, \u0026#34;type_売買\u0026#34;: { \u0026#34;_type\u0026#34;: \u0026#34;terms\u0026#34;, \u0026#34;missing\u0026#34;: 0, \u0026#34;total\u0026#34;: 48, \u0026#34;other\u0026#34;: 0, \u0026#34;terms\u0026#34;: [ { \u0026#34;term\u0026#34;: \u0026#34;00_北海道\u0026#34;, \u0026#34;count\u0026#34;: 2 }, { \u0026#34;term\u0026#34;: \u0026#34;02_岩手県\u0026#34;, \u0026#34;count\u0026#34;: 1 }, { \u0026#34;term\u0026#34;: \u0026#34;04_秋田県\u0026#34;, \u0026#34;count\u0026#34;: 1 }, ... } 望んでいた形式とは少し異なりますが、facet_filterする回数を少なくするため、 ファセットは都道府県のフィールドを指定したためです。 アプリで頑張って入れ替えてください。。。\nこの場合、\u0026rsquo;type\u0026rsquo;の個数がわかっているので、頑張ってこのような記述ができました。 ただ、typeが増えた時にアプリの修正とかが必要になりますよね。\nAggregations ということで、Aggregationsの出番です。 ファセットよりも柔軟に、検索結果に対していろいろな集計が行える機能になります。 一見に如かずということで、クエリを紹介します。\nGET /pref_aggs/japan/_search { \u0026#34;size\u0026#34;: 0, \u0026#34;query\u0026#34;: { \u0026#34;match_all\u0026#34;: {} }, \u0026#34;aggs\u0026#34;: { \u0026#34;pref\u0026#34;: { \u0026#34;terms\u0026#34;: { \u0026#34;order\u0026#34;: { \u0026#34;_term\u0026#34;: \u0026#34;asc\u0026#34; }, \u0026#34;field\u0026#34;: \u0026#34;pref\u0026#34;, \u0026#34;size\u0026#34;: 50 }, \u0026#34;aggs\u0026#34;: { \u0026#34;type\u0026#34;: { \u0026#34;terms\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;type\u0026#34;, \u0026#34;size\u0026#34;: 10 } } } } } } ファセットよりもシンプルですし、賃貸といったような値を指定していません。 aggsというのがaggregations機能を指定している部分になります。 検索結果は次のように出力されます。\n{ \u0026#34;took\u0026#34;: 4, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 2, \u0026#34;successful\u0026#34;: 2, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 100, \u0026#34;max_score\u0026#34;: 0, \u0026#34;hits\u0026#34;: [] }, \u0026#34;aggregations\u0026#34;: { \u0026#34;pref\u0026#34;: { \u0026#34;buckets\u0026#34;: [ { \u0026#34;key\u0026#34;: \u0026#34;00_北海道\u0026#34;, \u0026#34;doc_count\u0026#34;: 3, \u0026#34;type\u0026#34;: { \u0026#34;buckets\u0026#34;: [ { \u0026#34;key\u0026#34;: \u0026#34;売買\u0026#34;, \u0026#34;doc_count\u0026#34;: 2 }, { \u0026#34;key\u0026#34;: \u0026#34;賃貸\u0026#34;, \u0026#34;doc_count\u0026#34;: 1 } ] } }, { \u0026#34;key\u0026#34;: \u0026#34;01_青森県\u0026#34;, \u0026#34;doc_count\u0026#34;: 2, \u0026#34;type\u0026#34;: { \u0026#34;buckets\u0026#34;: [ { \u0026#34;key\u0026#34;: \u0026#34;賃貸\u0026#34;, \u0026#34;doc_count\u0026#34;: 2 } ] } }, ... Aggregationsの結果は、望んでいた通りの出力になっています。\nクエリの構成を見てみましょう。\n\u0026#34;aggs\u0026#34;: { \u0026#34;pref\u0026#34;: { #1 \u0026#34;terms\u0026#34;: { \u0026#34;order\u0026#34;: { \u0026#34;_term\u0026#34;: \u0026#34;asc\u0026#34; }, \u0026#34;field\u0026#34;: \u0026#34;pref\u0026#34;, \u0026#34;size\u0026#34;: 50 }, \u0026#34;aggs\u0026#34;: { #2 \u0026#34;type\u0026#34;: { \u0026#34;terms\u0026#34;: { \u0026#34;field\u0026#34;: \u0026#34;type\u0026#34;, \u0026#34;size\u0026#34;: 10 } } } } } 最初の#1のprefは出力を扱いやすくするためにつけているラベルになります。好きな名前をつけることが可能です。 次のtermsがAggregationのタイプ(どのような集計をして欲しいか)になります。 今回は、prefフィールドにある単語(term)毎に、集計をしたいので、termsを指定します。 その他にどんなタイプがあるかは、公式ガイドをご覧ください。\n次に、さらにtypeフィールドで集計したいので、#2の部分で後続のAggregationを指定しています。 都道府県同様、typeフィールドにある単語毎に集計するために、termsを指定します。\nこれで、先ほどのような結果が出力できます。 ちなみに、さらにtypeの中に他の種別で集計したいという場合は、さらにaggsを追加していけばOKです。\nAggregationは非常に柔軟な集計を可能にする機能です。ただし、検索結果に対して集計処理を行っているため、 メモリやCPUなどのリソースを消費するので注意が必要です。\nAggregationの説明については、こちらのFound.noのブログ(英語)がわかりやすかったので参考にしてみてください。\nまとめ 非常に簡単ですが、Aggregationsについて紹介しました。 その他にもAggregationsでできることがあるので、後日別のサンプルを用意して説明しようかと思います。\n100件のデータやここまでの操作については、gistにあるので、興味がある方はご覧いただければと。 stream2esの操作以外は、Marvelに付属のsenseを利用しています。\n","date":1399456620,"dir":"post/2014/","id":"ed4f5a398056eef1cf6caa90786b340a","lang":"ja","lastmod":1399456620,"permalink":"https://blog.johtani.info/blog/2014/05/07/aggregation-example/","publishdate":"2014-05-07T18:57:00+09:00","summary":"こんなツイートを見つけたので、Aggregationのサンプルでも書こうかなと。(前から書こうと思ってたんですが。。。) @elasticsearch Hi, Would you please tell me the way to","tags":["elasticsearch"],"title":"Aggregations - ファセットよりも柔軟な集計"},{"contents":"今日はelasticsearch-kopfのAnalysis画面の紹介です。\n(簡単なところから。。。その3)\nちょっとあいだが開いてしまいましたが、再開です。 メニューのaliasesを選択すると、次のような画面が表示されます。\nAliases画面 Elasticsearchのaliasを画面で確認できます。\nエイリアスは、インデックスに別名をつけることができるElasticsearchの機能です。 1エイリアス=1インデックスでも良いですが、1エイリアスに対して複数のエイリアスを付与することもできます。 この機能を利用することで、次のようなことが可能となります。\nインデックスの切り替えをアプリ側に意識させずに実施(アプリはエイリアス名に対して検索すればOKなので) 直近1週間のログを検索するためのエイリアスの作成(複数のインデックスを1つのエイリアスに割り当て可能) 特定のルーティングによる検索(特定のデータに対する検索だけに絞るためにfilterを指定する) エイリアスについて詳しく知りたい方は公式ガイドをご覧いただくのが良いかと。\n画面は非常にわかりやすい作りになっているので、特に説明必要ないんですよね。。。\n","date":1399132860,"dir":"post/2014/","id":"2824bef72110575c78aeb979170212b8","lang":"ja","lastmod":1399132860,"permalink":"https://blog.johtani.info/blog/2014/05/04/intro-elasticsearch-kopf-alias-percolator/","publishdate":"2014-05-04T01:01:00+09:00","summary":"今日はelasticsearch-kopfのAnalysis画面の紹介です。 (簡単なところから。。。その3) ちょっとあいだが開いてしまいまし","tags":["elasticsearch","plugin"],"title":"elasticsearch-kopfの紹介(aliases画面)"},{"contents":"kopfの記事の続きも書く必要があるんだけど、こんなツイートを見つけてしまったので。。。\nElasticsearchのBulk APIの仕様、JSONファイルをいい感じに加工して置かなければならないしハマりどころ多い。 http://t.co/hmfycqZlqk\n\u0026mdash; Kenta Suzuki (@suzu_v) 2014, 4月 24 前に思いついたけど、放ったらかしにしてた疑問が再浮上してきたので、せっかくだから調べてみようかなと。\n複数JSONデータがある場合にもっと楽にデータを入れる方法ないかなぁと思って、これかな?というのがあったのですが、 そのまま手を動かさずに放置してたので、一念発起してブログ書いてます。\nBulk APIって? ElasticsearchはURLにアクセスしてデータを登録できます。 基本的には次のように1件毎の登録になります。\n$ curl -XPUT http://localhost:9200/bookshop/books/1 -d \u0026#39; { \u0026#34;book_id\u0026#34; : 1, \u0026#34;title\u0026#34; : \u0026#34;ElasticSearch Server Japanese Edition\u0026#34;, \u0026#34;price\u0026#34; : 3024, \u0026#34;publisher\u0026#34; : \u0026#34;KADOKAWA\u0026#34; }\u0026#39; これでもいいのですが、大量のデータを登録するときは、Elasticsearch側での効率が悪いです。 そこで、Elasticsearchは大量データを登録するためにBulk APIというものを用意しています。\nこれは、次のような形式のJSONを作ってデータを登録します。\n{ \u0026#34;index\u0026#34; : { \u0026#34;_index\u0026#34; : \u0026#34;bookshop\u0026#34;, \u0026#34;_type\u0026#34; : \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34; : \u0026#34;1\u0026#34; } } { \u0026#34;book_id\u0026#34; : 1, \u0026#34;title\u0026#34; : \u0026#34;ElasticSearch Server Japanese Edition\u0026#34;, \u0026#34;price\u0026#34; : 3024, \u0026#34;publisher\u0026#34; : \u0026#34;KADOKAWA\u0026#34;} { \u0026#34;index\u0026#34; : { \u0026#34;_index\u0026#34; : \u0026#34;bookshop\u0026#34;, \u0026#34;_type\u0026#34; : \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34; : \u0026#34;2\u0026#34; } } { \u0026#34;book_id\u0026#34; : 2, \u0026#34;title\u0026#34; : \u0026#34;Introduction of Apache Solr\u0026#34;, \u0026#34;price\u0026#34; : 3888, \u0026#34;publisher\u0026#34; : \u0026#34;gihyo\u0026#34;} これは、次のような構成になっています。\nコマンド データ コマンド データ ... これで効率よくデータが登録できるのですが、このようなJSONデータを別途作って上げる必要が出てきます。 結局、複数のJSONがあるのに、特殊なJSONを生成しないといけないということでプログラム書いて実行することになります。 これだと、Elasticsearchへのアクセスをプログラムで書くのとあまり大差がないかもしれません。\nstream2es もっとお手軽に複数のJSONを登録できないかな?と目をつけていたのが、stream2esです。\nどんなもの? Clojureで作られた、Elasticsearchにデータを流し込むためのツールです。 Java 7がインストールされていれば、ダウンロードしてくれば動作せることができます。\nインストール 公式ページに載っている方法そのままです。\n$ curl -O download.elasticsearch.org/stream2es/stream2es; chmod +x stream2es 実行したディレクトリにコマンドがコピーされます。 あとは、コマンドを実行すればOKです。\n実行 データは次のような形式でsample.jsonに保存してあるとします。\n{ \u0026#34;book_id\u0026#34; : 1, \u0026#34;title\u0026#34; : \u0026#34;ElasticSearch Server Japanese Edition\u0026#34;, \u0026#34;price\u0026#34; : 3024, \u0026#34;publisher\u0026#34; : \u0026#34;KADOKAWA\u0026#34;} { \u0026#34;book_id\u0026#34; : 2, \u0026#34;title\u0026#34; : \u0026#34;Introduction of Apache Solr\u0026#34;, \u0026#34;price\u0026#34; : 3888, \u0026#34;publisher\u0026#34; : \u0026#34;gihyo\u0026#34;} 先ほどのBulk APIで利用したJSONよりも、スッキリしていますね。 1行1ドキュメント1JSONです。\nあとは、次のコマンドを実行するだけです。\n$ ./stream2es stdin --target http://localhost:9200/bookshop/books \u0026lt; sample.json ファイルをstream2esに流し込んで、stream2esが1行ずつパースして、Elasticsearchに投げ込んでくれます。\n登録されたデータは次のようになります。 IDは自動で付与されています。\n{ \u0026#34;_index\u0026#34;: \u0026#34;bookstore\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;0Hvy4IJCRkKrvGb4Dgam_w\u0026#34;, \u0026#34;_version\u0026#34;: 1, \u0026#34;found\u0026#34;: true, \u0026#34;_source\u0026#34;: { \u0026#34;book_id\u0026#34;: 1, \u0026#34;title\u0026#34;: \u0026#34;ElasticSearch Server Japanese Edition\u0026#34;, \u0026#34;price\u0026#34;: 3024, \u0026#34;publisher\u0026#34;: \u0026#34;KADOKAWA\u0026#34; } }, { \u0026#34;_index\u0026#34;: \u0026#34;bookstore\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;b9M6TooFQzGYyJeix_t_WA\u0026#34;, \u0026#34;_version\u0026#34;: 1, \u0026#34;found\u0026#34;: true, \u0026#34;_source\u0026#34;: { \u0026#34;book_id\u0026#34;: 2, \u0026#34;title\u0026#34;: \u0026#34;Introduction of Apache Solr\u0026#34;, \u0026#34;price\u0026#34;: 3888, \u0026#34;publisher\u0026#34;: \u0026#34;gihyo\u0026#34; } } せっかく、book_idがあるんだし、_idをインデックスの設定に指定します。\n$ curl -XDELETE http://localhost:9200/bookshop $ curl -XPUT http://localhost:9200/bookshop -d \u0026#39; { \u0026#34;mappings\u0026#34;: { \u0026#34;books\u0026#34; : { \u0026#34;_id\u0026#34; : { \u0026#34;path\u0026#34;: \u0026#34;book_id\u0026#34; } } } }\u0026#39; あとは、登録すればbook_idが_idに採用されます。\n{ \u0026#34;_index\u0026#34;: \u0026#34;bookshop\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;_version\u0026#34;: 1, \u0026#34;found\u0026#34;: true, \u0026#34;_source\u0026#34;: { \u0026#34;book_id\u0026#34;: 1, \u0026#34;title\u0026#34;: \u0026#34;ElasticSearch Server Japanese Edition\u0026#34;, \u0026#34;price\u0026#34;: 3024, \u0026#34;publisher\u0026#34;: \u0026#34;KADOKAWA\u0026#34; } }, { \u0026#34;_index\u0026#34;: \u0026#34;bookshop\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;2\u0026#34;, \u0026#34;_version\u0026#34;: 1, \u0026#34;found\u0026#34;: true, \u0026#34;_source\u0026#34;: { \u0026#34;book_id\u0026#34;: 2, \u0026#34;title\u0026#34;: \u0026#34;Introduction of Apache Solr\u0026#34;, \u0026#34;price\u0026#34;: 3888, \u0026#34;publisher\u0026#34;: \u0026#34;gihyo\u0026#34; } } 複数ファイル ディレクトリに複数のJSONファイルが有った場合は、次のようなコマンドでOK\n$ cat sample_data/*.json |./stream2es stdin --target http://localhost:9200/bookshop/books まぁ、catして流してるだけですが。。。\nダメだったケース JSONが複数行になっているようなデータだとエラーが出てしまいました。\n(jqコマンドで1行に整形したりできるかなぁ?)\nまた、1行に2つのJSONが書いてある場合は、1つ目のJSONをパースしたら、そこでおしまいみたいで、その後に記述されたデータは登録されませんでした。\nインデックスがない場合 stream2esで登録するインデックスがElasticsearchに存在しない場合、stream2esがインデックスを作成してくれるのですが、 この時、シャード数などはstream2es内部に記述があるので注意が必要です。 以下がその設定です。\nindex.number_of_shards : 2 index.number_of_replicas : 0 index.refresh_interval : 5s 課題? 内部的にはおそらく、Bulkでデータを登録していると思うのですが、まだよくわかっていません。 Clojureが読めないので、せっかくだから、Clojureの勉強も兼ねてちょっとソースを読んでみようかなと思います。 それほど量があるわけでもないので。\nあとは、その他にWikipediaのデータやTwitterのデータ登録、 ElasticsearchからデータをScrollで読み出しつつ、別のElasticsearchに流しこむといったこともできそうなので、そちらも試してみようかと。 他にもオプションがいくつかありそうです。\n今回は2件ほどでしたが、大量データを流し込んだ時にどうなるか(stream2esが悲鳴を上げるのか、Elasticsearchで詰まることがあったらどうなるか)なども 気になるので、なんか適当なデータで試してみるのもいいかなぁと。 (ということで、だれか、いろいろ試してみてもらえると楽できるなぁ。)\n","date":1398341460,"dir":"post/2014/","id":"e396cbf9274b590a1d94ee43d823a0bd","lang":"ja","lastmod":1398341460,"permalink":"https://blog.johtani.info/blog/2014/04/24/usage-stream2es/","publishdate":"2014-04-24T21:11:00+09:00","summary":"kopfの記事の続きも書く必要があるんだけど、こんなツイートを見つけてしまったので。。。 ElasticsearchのBulk APIの仕様、J","tags":["elasticsearch","stream2es"],"title":"stream2esと複数データの登録"},{"contents":"第4回Elsticsearch勉強会を開催しました。 今回から、遅刻厳禁にしてみました。 それほど困った人もいないと思うので、次回からも遅刻厳禁で。\nということで、今回も多数の方にお集まりいただきありがとうございました。\nスタッフの皆さん、スピーカーの皆さん、プレゼント用に書籍を用意してくれたKADOKAWAさん、開場提供していただいたリクルートテクノロジーズさん、ありがとうございました! 次回もよろしくお願いします! 参加していただき盛り上げていただいた参加者の皆さんもありがとうございました。\nさて、ブログですが司会業とかやってたので、あんまり書けてないけど。。。\n134番までチケットがはけていたので+スタッフで140〜150名くらいの参加者だったのではないかと思います。 懇親会まで残っていただいた方々も片付けなどありがとうございました。\nさて、感想とか補足です。\n「アナライズ処理の仕組みとクエリDSL」株式会社シーマーク 大谷 純 @johtani スライド:アナライズ処理の仕組みとクエリDSL※スライドはPDFです。\nプラグイン:elasticsearch-extended-analyze\nプラグインの紹介記事:http://blog.johtani.info/blog/2013/10/25/developing-es-extended-analyze-plugin/\nMarvel:http://www.elasticsearch.com/marvel/\n日本語版メーリングリスト:https://groups.google.com/forum/#!forum/elasticsearch-jp\nなんか、宣伝(本+プラグイン)ばっかりですみません。 「プラグインの紹介記事」に簡単な使い方が書いてあります。が、情報が古いので、Elasticsearchのバージョンに合わせたバージョンを使ってください。\nまだまだ発表に慣れてないので、頑張ろ。\nアンケート取ってみましたが、ログ検索と全文検索と半々くらいで興味がある人がいるみたいでした。 あと、有料トレーニングは人気ないっすね。。。\n「elasticsearch-hadoopを使ってごにょごにょしてみる」 株式会社マーズフラッグ R\u0026amp;D部 やまかつ さん @yamakatu スライド:elasticsearch-hadoopを使ってごにょごにょしてみる\nelasticsearch-hadoop:https://github.com/elasticsearch/elasticsearch-hadoop\nQAとして、Elasticsearchにプライマリデータを保存するのは的な話が出てました。 ESにのみデータを入れるのは個人的には考えたことないかなぁ。 どうしても、ElasticsearchのWriteが遅いんじゃないかという懸念事項を持ってる人がいるなぁと。(実際ツラいという話もちらほら)\nお腹痛い中の発表ありがとうございました。。。 次回はMapRの方に紹介してもらえそう(交渉中)なので楽しみです。やまかつさんの続きも聞きたいなぁ。\n「CouchbaseとElasticsearchが手を結んだら」株式会社アットウェア 佐竹雅央さん @madgaoh 河村康爾さん @ijokarumawak スライド:CouchbaseとElasticsearchが手を結んだら\nCouchbaseのElasticsearchに関するページ:http://docs.couchbase.com/couchbase-elastic-search/\nCouchbaseに入れたら、自動的にElasticsearchにもデータを入れてくれる。 デモがあるの、いいっすね。\n最新版はmasterを落としてきてビルドしないとダメらしい。確かに、上のページには0.90.5って書かれてる。 ここでも、やはり、Elasticsearchが詰まった時にどうするの?みたいな話が出てました。 CouchbaseのXDCRだと、後ろが詰まってる時によしなに?データを流すのを制御してくれるってのがあるみたいですが、 Elasticsearchだと悲鳴を上げているのがわかりにくいと。\nあと、Elasticsearchがインデキシングでキューを取りこぼしているのがログからわかりにくいってのも出てました。 (なにか、分かる方法があるかとかも調べてみようかなぁ。)\n自分の宿題:Transportプラグインって何かについて調べてブログに書くこと。\n「Elasticsearch at Wantedly」(タイトルあってるか不安) Wantedly, Inc 内田誠悟さん @spesnova スライド:Elasticsearch at Wantedly\n参考文献:Elasticsearchチュートリアル\n参考文献:Elasticsearch Workshop\n参考文献:elasticsearch-rails\nWantedlyでどうやって使ってるのか。 あと、オートコンプリートでも使ってます。(この話は次回聞けるといいなぁw)\nデータ数は少ないので、参考にまだならないかも。\n公式のサイト見難いですよねと。 ペンギン先生のブログが素晴らしかった! マッピングすごいw\n最後は、苦労して作ってもらったautocompleteの資料は放ったらかしにして、質疑応答してもらいました。 辞書とか、検索漏れとかの話は今後の課題っぽかったですね。\n「Elasticsearchのみに決めてました!」ってセリフがカッコ良かったw\nアクセスコントロール周りのノウハウもブログで共有してくれそうなので楽しみにしています!\nあと、「tireがretire」の話が出てましたが(この発表だっけ?)参考文献にあげてある、elasticsearch-railsが今は本流なんじゃないかなぁ?\nLT ###「ElasticsearchのScripting」株式会社富士通ソフトウェアテクノロジーズ 滝田聖己さん @pisatoshi\nスライド:ElasticsearchのScripting\n参考文献:elasticsearch-native-script-example\n色々とScriptがあるという話を説明してもらい感謝です。 もちろん、ElasticSearchServerにも書いてあるので、そちらも参考にしてください!\n「Elasticsearch 向け多言語解析プラグイン」ベイシス・テクノロジー株式会社 江口天さん スライド:Elasticsearch 向け多言語解析プラグイン\n参考文献:Elasticsearchで使えるRosette基本言語解析モジュール\n参考文献:Elasticsearch-inquisitorプラグインの紹介\nベイシステクノロジさんが提供しているRosetteをElasticsearchで活用できるモジュールみたいです。 いまなら、無料で体験できるみたいなので、どんなものか触ってみると面白いかもしれません。\nあと、デモで使用されていたプラグインについて、私が昔に書いた記事があるので、興味のある方は参考にしていただければと。 このプラグインはクエリがどのように内部でLuceneのクエリになっているか、どのフィールドでどうトークンが生成されるか? といったものが見ることができるプラグインになっています。\n関連ブログ 適当に見つけたブログを列挙してあります。これもあるよ!などあれば、教えてください。\n勉強会メモ - 第4回elasticsearch勉強会 2014/04/21\ntogetter 第4回elasticsearch勉強会 #elasticsearchjp\n参加レポート:第4回elasticsearch勉強会 #elasticsearchjp\n第4回elasticsearch勉強会に参加しました\nまとめ しつこいくらい宣伝してしまいましたが、「ElasticSearch Server日本語版」よろしくお願いします!\n今回も楽しい話が聞けました。メモがちょっと少ないんですが。。。\n次回は6末を目処に、MapRの方などと調整して開催しようと思います。 聞きたい話とか、発表したい方とかあれば、連絡くださいー!\n","date":1398077040,"dir":"post/2014/","id":"50562b09417cd8c4a2348a0a5aabe754","lang":"ja","lastmod":1398077040,"permalink":"https://blog.johtani.info/blog/2014/04/21/hold-on-4th-elasticsearch-jp/","publishdate":"2014-04-21T19:44:00+09:00","summary":"第4回Elsticsearch勉強会を開催しました。 今回から、遅刻厳禁にしてみました。 それほど困った人もいないと思うので、次回からも遅刻厳禁","tags":["elasticsearch","勉強会"],"title":"第4回Elasticsearch勉強会を開催しました。#elasticsearchjp"},{"contents":"今日はelasticsearch-kopfのAnalysis画面の紹介です。\n(簡単なところから。。。その2)\nメニューのanalysisを選択すると、次のような画面が表示されます。\nAnalysis画面 Elasticsearchの_analyze APIを画面で確認できます。 画面で動作の確認ができるのは嬉しいですよね。\n入力文字列:入力となるドキュメントに含まれる文字列や検索キーワードを入力 フィールドの指定:対象とするインデックス名、タイプ名、フィールド名を選択 analyze:ボタンを押す トークナイズされた結果:入力文字列がどのようなトークンに分割されるか start、end:入力文字列中の文字列の位置 pos:トークンの位置 という形でElasticsearchが指定されたフィールドで入力文字をどのようにトークナイズしたかを確認することができます。\nElasticsearchは内部でこのトークナイズされた単語を元に転置インデックスを作成し、検索に利用します。 ですので、特定のデータが検索に上手くヒットしないときに、この画面でデータの文字列をトークナイズしてみるといった用途に使えます。\nフィールドの設定がどのようにして入力文字列をトークンにしているかといった点については、今度のElasticsearch勉強会で話す予定です。\nフィールドの設定を利用する以外に、アナライザを指定してどのようにトークナイズされるかを見ることもできます。 「ANALYZE BYANALYZER」をクリックすると利用できます。\nANALYZE BY ANALYZER トークナイズしたい文字列を入力し、インデックス名と、インデックスに設定されているアナライザ名を選択してanalyzeボタンを押すと 結果が表示されます。 (例では、kuromojiアナライザを利用して出力になっています。また、出力結果のposの表示位置がFIELD TYPEの時と違うのが少し気になりました。)\nただ、残念ながら、インデックスのマッピングで指定したアナライザしか利用できないみたいなので、 どのアナライザがどんな挙動かを調べたい場合は、以前紹介したelasticsearch-inquisitorを 利用したほうが良さそうです。\nということで、今日はanalysis画面の説明でした。\n","date":1397011260,"dir":"post/2014/","id":"76a1fb7f21fda9eddb95426b65124517","lang":"ja","lastmod":1397011260,"permalink":"https://blog.johtani.info/blog/2014/04/09/intro-elasticsearch-kopf-analysis/","publishdate":"2014-04-09T11:41:00+09:00","summary":"今日はelasticsearch-kopfのAnalysis画面の紹介です。 (簡単なところから。。。その2) メニューのanalysisを選択","tags":["elasticsearch","plugin"],"title":"elasticsearch-kopfの紹介(analysis画面)"},{"contents":"JVM Operation Casual Talksに参加しました。 あんまり、運用とかやってないので、ついていけるか不安ですが、楽しそうだったので。 懇親会は予定されてないらしい。\n@stanaka\t15分でわかるJVMのメモリ管理 スライド:https://speakerdeck.com/stanaka/understanding-memory-management-of-javavm-in-15-minutes\nJVMの基礎知識\n某研究所で。。。\nElasticsearch、Solrの名前が!\nJVM困りどころ。ネットの情報が古いのが多いとか。\n使いこなすにはきちんと知識が必要。\nMemory Model 困ったらJava8に。。。\nHeapのチューニングが重要\nHeapの構成やGC処理の説明\nCMSでもすべて並列ではない\nOlgGenがフラグメントして確保が遅くなっていく G1GCの概念図。YoungやOld、Survivorの区別がない?\nリージョン? リファレンスリストすばらしい。\n@oranie\tCassandra運用で実施しているJVM監視について スライド:http://www.slideshare.net/oranie/jvm-operation-casual-talks-33218856\nCassandra(1.1)で運用中。 35TBとか エンジニアブログ読め。 Cassandraの監視って何すればいいの? GC頻度とかグラフで見れる VisualVM便利って教えてもらった。 VisualVMでどんな値があるか見ながら調べて、取りたい値を考える。 SNMPで頑張るの辛い=JMXかな?=Javaで叩くの?=Jolokia どんなことやってる? Nagios+Jenkins+。。。あとでスライド yohoushi+GrowthForecastも便利。 @waysaku\tSpray(Akka)運用でJVMをCPUスケールさせるために行った事 スライド:http://www.slideshare.net/waysaku/jvm-operation-casual-talks\nSpray Akkaアプリケーションの運用を任されちゃった人 カットオーバー直前の負荷試験でびっくりするくらいスループットでない。。。 いろんなActorが特定のActorに処理を投げた状態で待ってるという状況。。。 スレッドダンプ追っかけてる様子を追体験してる。 ログ出力がBLOCKしてた I/Oを伴う処理は非常にセンシティブ 以下、LT @oinume\t運用に効く!JVMオプション三選 スライド:http://www.slideshare.net/oinume/jvm-operationcasualtalks20140407\nサーバに入らなくても見れるのは VisualVM 最終形Java Mission Control Flight Recorder(商用だと有償) @y_uuki1\tなにもわからないところから始めるJVMモニタリング スライド:https://speakerdeck.com/yuukit/nanimowakaranaitokorokarashi-merujvmmonitaringu\nブログ:http://yuuki.hatenablog.com/entry/2014/04/08/074507\nなんでここにいるかわかりませんが。 色んな所記事とかのリンクがある。 Graphiteに放り込んでるらしい。 @tagomoris\tNorikraのJVMチューンで苦労している話 スライド:http://www.slideshare.net/tagomoris/norikrajvm\nNorikraで困ったので開催したらみんなしゃべりに来てくれてありがたい世の中ですね。 デフォルト設定で運用。mx4096mで4ヶ月は元気に動いてた 年末に崩壊 -\u0026gt; harukaさんのQiita見ながら設定してほったからした。 3月にまた崩壊OOM SoftRefが悪さしてるのか? nekopさんのブログにヒントが。 @shot6\tJVM的なナニカを話す、GC戦略をそえて スライド:http://www.slideshare.net/shot6/jvm-33248312\n某A社からきました。 CMSを中心が良い CPUコア少ないとCMS Incremental G1GCは6GB以上とかもっと大きい場合のほうが良さそう(雑感) 基本的に、ドキュメントに書いてあるけど、つらいので、まとめてみました。 後で見たいな、このスライドも。 @kazeburo\tWebアプリケーションとメモリ スライド:http://www.slideshare.net/kazeburo/jvm-casual\nJavaは1行も書いたことありません。 Java運用したけど、まぁ、ひどい目にあってます。 ということで、PerlとApacheの話? bumpyなんとかってのは頭良くプロセスの処理回数とかをなんとかしてくれる JVMとかどうなの? ということで、CA社の人が釣れたので良かったですね。 TBD\tJVMの運用について話す会(パネル) なんでJVM?\n全文検索だとJVMだなぁ。SolrとかElasticsearchとか 入社したらあった。 JVMこまったところは?\n突然Dioが出てくる JVMいいところは?\nうーん、あえて言うと。。。スレッド処理 型がある言語を調べるとJVM。というよりScala。 飛び入り参加。落ちないところ。人殺しは良くないw 簡単には殺せないところに使えるのは良いのでは。 チューンはどこまでやる?\n7,8割でやめたほうが良い? そんなに突き詰めなくてもいいのかな。 Cassandraだと、FullGCが走ってる時点で再起動しかない場合が多いです。 言語のランタイムについてチューンすることってJVMの他ある?\nRubyくらい? 自分たちで何とかできないものを相手にしている人たちは苦労してるんじゃないか\nCaなんとかさんとかHBなんとかさんは困ってる人が多い 最後に一言\nモニタリングツール参考にしたい 最後に 「やりたくなったら誰かやってください。」ということみたいです。\n基礎から監視まで結構幅広くキーワードが出てきたので楽しかったです。\nその他に話に出てきてた方のブログもリンクしとこうかな。\nnekopの日記\n","date":1396866240,"dir":"post/2014/","id":"299abcee56b05b312ed5700f686f79b8","lang":"ja","lastmod":1396866240,"permalink":"https://blog.johtani.info/blog/2014/04/07/attend-jvm-casual-1/","publishdate":"2014-04-07T19:24:00+09:00","summary":"JVM Operation Casual Talksに参加しました。 あんまり、運用とかやってないので、ついていけるか不安ですが、楽しそうだったので。 懇親会は予定されてないらしい","tags":["JVM","Java","勉強会"],"title":"JVM Operation Casual Talksに参加しました #jvmcasual"},{"contents":"今日はelasticsearch-kopfのREST画面の紹介です。\n(簡単なところから。。。)\nメニューのrestを選択すると、次のような画面が表示されます。\nElasticsearch自体が、さまざまな操作をRESTでできる仕組みになっています。 検索にも利用しますが、それ以外の設定などにつてもリクエストを送ればOKです。\nですので、リクエストや設定を自分で組み立てて送ることができる画面が用意されているととても便利です。 (もちろん、curlコマンドでもいいのですが、画面があると便利ですよね)\nREST画面 History 履歴表示画面です。 これまで、kopfのrest画面を利用して送信したリクエストが一覧で表示されます。\nHistoryという文字をクリックすることで、表示/非表示の切り替えが可能です。(最初は非表示) マウスオーバーすると、リクエストボディがポップアップで表示されます。\nHistory 履歴にあるURLはクリック可能で、クリックすると実行されます。 履歴はlocalStorageに保存されるみたいです。(ブラウザの仕様?あんまり詳しくないので。。。) たぶん、30件が上限かと(ソースで確認しただけ)\nURL rest画面でリクエストを送信する先のURLを指定します。 メソッドは右側のSELECTで選択可能です。\nリクエストパラメータも指定が可能です。\nリクエストボディ 検索や設定のJSONを記述するところです。 一応、JSON的にエラーがある場合は行数の左側にバツ印が出てきておかしなところもわかるようになっています。\nインデントなどは行ってくれますが、senseみたいな補完などはないので、少し辛いところです。\nレスポンス 送信したリクエストに対するレスポンスが返ってきます。 インデントされた状態で表示されるので読みやすいかと。 また、入れ子になっているJSONについては、閉じたり開いたりすることも可能です。 (開始のカッコの右側に-が表示されていて、クリックすると閉じることができます。閉じると+に変わります)\n簡単ですが、rest画面の説明でした。 KOPFを使っていて、ちょっとしたクエリを送ったりするのには便利だと思います。\n複雑な検索クエリなどについては、やはりsenseを使うのが良いかと思いますが。。。\n","date":1396837440,"dir":"post/2014/","id":"670744b945088de05866864f7d57bee7","lang":"ja","lastmod":1396837440,"permalink":"https://blog.johtani.info/blog/2014/04/07/intro-elasticsearch-kopf-rest/","publishdate":"2014-04-07T11:24:00+09:00","summary":"今日はelasticsearch-kopfのREST画面の紹介です。 (簡単なところから。。。) メニューのrestを選択すると、次のような画面","tags":["elasticsearch","plugin"],"title":"elasticsearch-kopfの紹介(rest画面)"},{"contents":"なんだか、ドタバタしてて久しぶりの更新です。 ベルリンの旅行記みたいなのも書きたいのですが、まずはこちらかと。\nelasticsearch-kopfプラグインの紹介です。\n今回は概要の説明だけになります。機能が結構多いので。\nelasticsearch-kopfとは? _siteプラグインの一つで、クラスタ管理用のプラグインになります。 headプラグインやHQプラグインと同様です。\nプラグインの画面 このようにシンプルな画面で、スッキリとしています。 緑を基調にした画面構成はElasticsearchの緑色を意識してるんでしょうか?\n上記の画像に簡単なコメントを入れてあります。\nメニュー KOPF:KOPF自体の設定(接続先とリフレッシュインターバルの変更) cluster:クラスタ管理、情報(デフォルト表示画面) rest:RESTリクエスト送信、結果表示画面 aliases:エイリアス管理 analysis:analysis API percolator:パーコレータ管理 warmup:ウォームアップクエリ管理 上記のようなメニューです。各メニューについては、今後のブログで少しずつ紹介しようかと。 このメニューの色が、クラスタの状態も表しています。ステータスがYELLOWなら黄色、REDなら赤色に変わります。\nインデックス インデックスは列として表示されます。先ほどの画像では、2つのインデックスが表示されている状態です。 インデックス毎に、シャードも表示されます。これは、各ノードがどのシャードを保持しているかという情報です。 色の濃いシャードがプライマリでしょう。 インデックス名やシャードの箱はクリックできるようになっていて、それぞれの情報がJSONで表示されます。 その他にもドキュメント数、サイズなども表示されます。 インデックスの各種操作(closeやdeleteなど)もここからメニューが表示されます。(これも次回詳しく)\nノード ノードの情報が行として表示されます。ノードが増えると下に追加されていきます。 node1というのが、ノード名です。(ヒーローの名前とかが出てくるやつです。)\nその他に、IPアドレス、ポート番号、負荷、ヒープサイズなども表示されています。 電源ボタンはノードのシャットダウンを行うためのボタンです。(確認用のダイアログが表示される)\nその他 その他に、クラスタの概要として、ノード数、インデックス数、シャード数、ドキュメント数なども表示されます。 インデックスの作成などは、アイコンから操作が可能です。 大規模なクラスタを管理している場合、検索ボックスを利用することで、インデックス名やノード名による絞込もできるようになっています。\n感想 シンプルな構成の画面で、個人的にはheadよりも好きな画面です。 HQよりもシャードの分散具合がわかりやすいので、今後はこのプラグインを利用していこうと考えています。\nまずは、簡単な紹介です。今後、各画面についてもう少し説明をブログに書いていこうかと考えています。 待てない方は、触ってみてもらうのが良いかと。 もちろん、続きを書いてもらってもいいですよ!!\n","date":1396707480,"dir":"post/2014/","id":"c1241374502f200cf9fc49c8d6fb5822","lang":"ja","lastmod":1396707480,"permalink":"https://blog.johtani.info/blog/2014/04/05/intro-elasticsearch-kopf-1/","publishdate":"2014-04-05T23:18:00+09:00","summary":"なんだか、ドタバタしてて久しぶりの更新です。 ベルリンの旅行記みたいなのも書きたいのですが、まずはこちらかと。 elasticsearch-ko","tags":["elasticsearch","plugin"],"title":"elasticsearch-kopfの紹介(概要)"},{"contents":"先日、「ElasticSearch Serverを翻訳しました」という記事を書きました。\nこの中で電子版も出ますよと書いていましたが、電子版も発売されたので、再告知も兼ねてブログを書いています。\nなお、最近よく「ElasticsearchのSは小文字」とツイートしていますが、本書は原著のタイトルが「ElasticSearch Server」となっているため、Sは大文字になっています。原著が出版された時期にはまだSが小文字に統一されていなかったためです。\n紙の書籍はすでに書店に並んでいたり、Amazonでも発送されているようです。\n私自身が電子書籍が場所を取らなくて好きというのもあり、電子版も出版していただけるようにお願いしていました。\n電子版についてはAmazonでKindle版、達人出版会からEPUBとPDFが購入可能です。\n達人出版会のElasitcSearch Serverのページ AmazonのKindle版ページ こちらのリンク(Amazonはアフィリンク)を参考にしていただければと。\n書籍の写真入りツイートしたら、原著者の方からレスを頂きました。\n@johtani Thanks for the great work out there :)\n\u0026mdash; Rafał Kuć (@kucrafal) 2014, 3月 23 また、原著者のサイトでも紹介してもらいました(結構うれしい)。 私が窓口をやっていた関係で、私の名前しか入っていませんが。。。 編集者と翻訳者の方々のお陰で良い本が出版できたと思っています。\nThanks for sharing! / ElasticSearch Server book in Japanese | ElasticSearch Server Book Blog http://t.co/fhCP1vVBd3\n\u0026mdash; Jun Ohtani (@johtani) 2014, 3月 24 ということで、Elasticsearchの導入の手助けになればと。 感想(賛否問わず)など、あればコメント、ツイート、ブログなど書いていただければうれしいです。 (その際に、連絡してもらえるとさらにうれしいです)\n","date":1395722580,"dir":"post/2014/","id":"d51032bef3e7117a94336fea18a3fad7","lang":"ja","lastmod":1395722580,"permalink":"https://blog.johtani.info/blog/2014/03/25/release-elasticsearch-server-ja-ebook/","publishdate":"2014-03-25T13:43:00+09:00","summary":"先日、「ElasticSearch Serverを翻訳しました」という記事を書きました。 この中で電子版も出ますよと書いていましたが、電子版も発","tags":["elasticsearch"],"title":"ElasticSearch Server日本語版(電子版も)が発売されました"},{"contents":"GOTO Night elasticsearchに参加しました。 初の海外の勉強会です(海外自体が初だし)。\nベルリンにあるWoogaという会社で開催された勉強会です。\nFull house at the #gotonight about @elasticsearch in the auditorium of @wooga pic.twitter.com/r2Vx2aMcEn\n\u0026mdash; GOTO Berlin (@GOTOber) 2014, 3月 18 会場はこんな感じで、とってもおしゃれです。(なんか、写ってますね、最前列にw) ベルリンの古い建物をリノベーションしたオフィスみたいで、そこにこういったひな壇を用意して発表するスペースにしているみたいです。\n内容としては、Elasticsearch1.0の新機能の話として、snapshot/restore、cat、aggregationなどの話題でした。簡単にどういったものかの説明です。\n一人目の発表が終わったら、ブレイクタイムとして上のフロアに用意されている軽食+ドリンクで軽く交流の時間が用意されていました。 ベーグルなどのサンドイッチとハイネケンやクラブマテ?と呼ばれるチープなレッドブルとかが飲めました。\nちょっと食べて談笑したあとに、次はLogstashとKibanaのお話でした。Logstashってどんなもの?という話がメインで、Kibanaは簡単な紹介という感じでしょうか。最後に、ライブデモがありました。 Kibanaを使ったライブデモはインパクトがあるなというのが感想です。 フィールド名の補完をしてくれたりと便利な機能が操作をしているところでわかるので。\nYoutubeなどでも見てても思っていた感想ですが、こちらの勉強会は質問が結構出てきます。 今日参加した勉強会も質疑応答が結構されてました。\nelasticsearchの方たちと少しだけ話しをできたので、かなり興奮気味でブログを書いています(ミーハー)。\nただ、やっぱり英語のヒアリングがまだまだだなぁとも実感出来ました。 場数踏むしかないと思うので少しずつ耳にしてなれるしかないかなぁと。 はぁ、ちゃんと高校とか大学の頃に単語を覚えとくんだったと軽く後悔。\nこんなツイートもしてもらって、興奮気味です。明日早起きしないといけないので寝ないといけないのにw\nMeeting @johtani finally in #berlin watching @spinscale talking about #elasticsearch\n\u0026mdash; Simon Willnauer (@s1m0nw) 2014, 3月 18 ","date":1395151860,"dir":"post/2014/","id":"65453a1ae403679bd2e47398a04205ca","lang":"ja","lastmod":1395151860,"permalink":"https://blog.johtani.info/blog/2014/03/18/attend-goto-night-elasticsearch/","publishdate":"2014-03-18T23:11:00+09:00","summary":"GOTO Night elasticsearchに参加しました。 初の海外の勉強会です(海外自体が初だし)。 ベルリンにあるWoogaという会社で開催された勉強会","tags":["elasticsearch","勉強会"],"title":"GOTO Night elasticsearchに参加しました"},{"contents":"Berlinからおはようございます。\nということで、人生で初めての海外に来ています。\n人生初の海外なのに、一人で乗り換えがあるようなBerlinに来ています。 今年はチャレンジの年になりそう。初めてづくしですが、楽しみたいなと。 会社に感謝です。ESのトレーニングを受けに来たのがメインなのです。 ついでに、Berlinでの勉強会にも参加してみようかなと。\n幸いにも時差ボケはなさそうなので、色々と見て回ろうと思います。 ただ、日曜日はお店が軒並みしまってそう。。。\n","date":1394916660,"dir":"post/2014/","id":"abc5ca9856a61831fd4ed06b402875d2","lang":"ja","lastmod":1394916660,"permalink":"https://blog.johtani.info/blog/2014/03/16/post-from-berlin/","publishdate":"2014-03-16T05:51:00+09:00","summary":"Berlinからおはようございます。 ということで、人生で初めての海外に来ています。 人生初の海外なのに、一人で乗り換えがあるようなBerlin","tags":["misc","travel"],"title":"Berlinからおはようございます"},{"contents":"elasticsearchに、このへん入れるときっと幸せになれるはず・たぶん。\u0026#10;elasticsearch/elasticsearch-analysis-kuromoji/1.6.0\u0026#10;oyrusso/elasticsearch-HQ\u0026#10;mobz/elasticsearch-head\n\u0026mdash; toshi_miura (@toshi_miura) 2014, 3月 5 こんなツイートを見かけたので、普段入れてるプラグインを簡単に紹介してみようかと。\nローカルの環境に普段入れているプラグインの紹介です。 ちゃんとクラスタを管理しているというよりは、最新版の動作などを確認するための環境になります。なので、ちょっと視点が異なるかもしれませんが参考になればと。\nelasticsearch-analysis-kuromoji URL : elasticsearch-analysis-kuromoji\nKuromojiという日本語形態素解析のTokenizerなどを使えるようにするためのプラグインです。 今度、発売される「ElasticSearch Server」日本語版には付録として、利用方法を執筆しました。参考にしていただければと。 READMEにもサンプルは掲載されてるので、こちらを参考にするのもありですが。\nelasticsearch-extended-analyze URL : elasticsearch-extended-analyze\n私が開発しているプラグインです。 ElasticsearchにはanalyzeというAPIが用意されています。 文章を渡すと指定したanalyzerなどでどのような単語に区切られるかがわかるAPIです。\nただ、analyzerの内部ではchar filter、tokenizer、token filterという個別のパーツがそれぞれ入力された文字列に対して処理を実施します。 この過程がanalyze APIではわかりません。 それをわかるようにしてみたのがelasticsearch-extended-analyzeプラグインになります。\n詳細については過去の記事を見ていただければと。 画面があると便利だよなぁと思いつつ、作ってない。。。\npolyfractal/elasticsearch-inquisitor URL : elasticsearch-inquisitor\nクエリのデバッグとかに便利なプラグイン。\nこちらも詳細は過去の記事を見ていただければと。\nmobz/elasticsearch-head URL : elasticsearch-head\nクラスタ管理に便利なプラグインです。クラスタに存在するノードに対してインデックスのデータ(シャード)がどこに配置されているかなどが一目瞭然になる便利なプラグインです。 プライマリシャードやレプリカなどもわかります。 インデックスの削除もできるし、クエリを投げることもできるし、全部入りな感じのプラグインです。\n私個人は、シャードの配置を見るのに主に利用しています。クエリを投げたりインデックスを消したりするのには殆ど使っていません。\nroyrusso/elasticsearch-HQ URL : elasticsearch-HQ\nこれも管理系のプラグインです。こっちのほうが個人的にスッキリしていて好きなプラグインです。 インデックスの管理やノードの停止などはこちらを主に使用しています。 あくまでもローカルの簡易クラスタを管理する目的というのもあります。\npolyfractal/elasticsearch-segmentspy URL : elasticsearch-segmentspy\nこちらはモニタリングでしょうか。 ElasticSearch Serverで紹介されていたのが主な理由で、入れてますがあんまり見てないかも。 インデックスのSegment単位の情報が見ることが可能です。 あと、ちょっと更新されてない感じがしますね。\nelasticsearch/marvel Elasticsearch社から提供されている、モニタリングなどに使えるプラグインです。 開発環境では無償提供という感じです。 渡しの場合、モニタリング目的ではなく、senseと呼ばれるクエリの補完をしてくれるツールの目的のために使用しています。 モニタリング部分を停止する方法とかないかなぁ。\n詳細については過去の記事を参考にしていただければと。\nまとめ? ということで、簡単にローカルに入っているプラグインの紹介でした。 他にもいっぱいあるので、おすすめがあれば、教えてもらえると助かります。\n","date":1394515380,"dir":"post/2014/","id":"386dc9d1b647a9f3965f1fbe29c7dfb9","lang":"ja","lastmod":1394515380,"permalink":"https://blog.johtani.info/blog/2014/03/11/es-plugin-installed-to-my-env/","publishdate":"2014-03-11T14:23:00+09:00","summary":"elasticsearchに、このへん入れるときっと幸せになれるはず・たぶん。\u0026#10;elasticsearch/elasticsearc","tags":["elasticsearch","plugin"],"title":"いつも入れているElasticsearchのプラグイン"},{"contents":"第3回Elasticsearch勉強会で、軽く触れていましたが、ElasticSearch Server日本語版が発売されます。 ツイートなどもちらほらとして頂いているみたいで嬉しい限りです。\n本書は、私自身、初の翻訳本となります。\nなお、ElasticSearchはAWSのサービスではなく、全文検索・解析サーバのOSSです\n内容、概要 PacktPublishingから発売されているElasticSearch Serverの日本語版となります。 以下の点が、原著とは異なる点になっています。\n0.90.xに対応(原著は0.20) Kibana、Kuromojiに関して追記 もちろん日本語 残念ながら、つい最近、Elasticsearchについては1.0がリリースされました。 1.0で追加された機能(SnapshotやRestore、Aggregatorなど)については触れていませんが、Elasticsearchの機能を網羅的にカバーした良書となっています。 どんな機能があるのか、どんなプラグインがあるのか、どういったことに使えるのかなど、幅広くまとめられた本になっていますので、 Elasticsearchに興味がある方はぜひ読んでいただければと思います。\nまた、現段階では予定ですが電子版の出版も予定されています。電子版が気になる方は、少しお待ちいただければと。\nElasticSearch?Elasticsearch? 1.0.0がリリースされた現在は、Elasticsearch(SearchのSは小文字)が正式な名称となっています。 ただ、原著が発売された当初(2013年2月時点)では、まだSは小文字と大文字が混在した状況でした(コミットログなどを見るとわかります。) このため、日本語版でもElasticSearchという表記に統一してあります。\n翻訳に関して 初の翻訳書ということもあり、大変でした。英語に精通しているわけではないので(むしろ苦手)。。。 他の翻訳者の方々には大変助けていただきましたし、勉強になりました。 また、監修社であるリクルートテクノロジーズにも色々とサポートしていただき、感謝の限りです。 (Elasticsearch勉強会の開場提供にも協力して頂いています。)\nわかりにくい日本語となっている部分などありましたら、ご指摘いただければ今後の参考にさせていただきます。 英語やElasticsearchについて、学ぶという目的もあって、本書の翻訳を買って出たのが本音です。\n翻訳作業について Githubのリポジトリを編集の方に用意してもらい、翻訳原稿を管理、校正していきました。 Github自体をあまり触っていなかったので、作業をしながらGithubも覚えられ一石二鳥でした。 Issueやプルリクエストによる校正、チェックも便利ですね。 他の原稿を書くようなことがあれば、またこの経験を活かしていきたいなと。 (翻訳の進め方や原稿のチェックなどについてはまた後日何か書こうかと。)\n原著について 原著のサイトが用意されています。 http://elasticsearchserverbook.com/elasticsearch-server-errata/\n原著を翻訳するにあたって見つけた、誤植などを報告し、掲載して頂いています。 原著をお持ちの場合はこちらも参考にしていただければと思います。\nご購入はこちらから ということで、簡単ですが書籍の紹介(というより宣伝!?)でした。 Elasticsearchに関する何かしらの助けになる書籍であれば嬉しい限りです。\n「ElasticSearch Server日本語版」をよろしくお願いします。 (もちろん、購入は下のリンクからですよね!)\n","date":1393836900,"dir":"post/2014/","id":"9ad72c2a5157f21741bd4581a562dfc7","lang":"ja","lastmod":1393836900,"permalink":"https://blog.johtani.info/blog/2014/03/03/release-elasticsearch-server-japanese-edition/","publishdate":"2014-03-03T17:55:00+09:00","summary":"第3回Elasticsearch勉強会で、軽く触れていましたが、ElasticSearch Server日本語版が発売されます。 ツイートなども","tags":["elasticsearch"],"title":"ElasticSearch Serverを翻訳しました"},{"contents":"今年初の「突撃!隣のElasticsearch」ということで、Wantedlyさんにおじゃましました。\n※写真を自分でも撮ったのですが、画像が壊れてたので、一緒に行ったペンギン先生の写真を拝借しました。\n第3回のElasticsearch勉強会を開催中にES使ってるってツイートを見つけたので、アタックかけて遊びに行きました。 交渉に快諾いただきありがとうございました!\nWantedlyさんがどのようにElasticsearchを使用されているかはきっと、ブログを書いてくれると思うので期待しておくとして、書いてくれました!! 「実践!Elasticsearch」 そこで、nestedでハイライトがなんかうまくいかないって話があったので、ちょっと調べてみました。 (※まだ、調査中です)\n前提条件 再現する手順はgistにあります。(Senseに貼り付ければ動作します。ただし、elasticsearch-analysis-kuromojiが必要です。)https://gist.github.com/johtani/9184287\nなお、このマッピングやデータはWantedlyさんとは全く関係ありません。\nnestedフィールド内部のデータに対して、検索しハイライトしようとするとうまく動作しないという状況です。 マッピングは以下のとおり。\n\u0026#34;books\u0026#34; : { \u0026#34;properties\u0026#34;: { \u0026#34;book\u0026#34; : { \u0026#34;type\u0026#34;: \u0026#34;nested\u0026#34;, \u0026#34;properties\u0026#34;: { \u0026#34;title\u0026#34; : { \u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;kuromoji\u0026#34;, \u0026#34;store\u0026#34;: \u0026#34;no\u0026#34;}, \u0026#34;contents\u0026#34; : {\u0026#34;type\u0026#34;: \u0026#34;string\u0026#34;, \u0026#34;analyzer\u0026#34;: \u0026#34;kuromoji\u0026#34;, \u0026#34;store\u0026#34;: \u0026#34;yes\u0026#34;} } } } } } このマッピングの特徴は以下のとおり。\n_sourceは保存される(デフォルト値) bookがnestedなオブジェクト titleはstore : no contentsはstore : yes 動作の挙動をわかりやすくするため、titleとcontentsのstore属性に違いを持たせてあります。\n問題点 nestedクエリを使って、検索した時にハイライトが返ってきません。 次のクエリを実行するとわかります。\nGET /bookstore/books/_search { \u0026#34;_source\u0026#34; : [\u0026#34;book.title\u0026#34;,\u0026#34;book.contents\u0026#34;], \u0026#34;fields\u0026#34;: [ \u0026#34;book.title\u0026#34;, \u0026#34;book.contents\u0026#34; ], \u0026#34;query\u0026#34;: { \u0026#34;nested\u0026#34;: { \u0026#34;path\u0026#34;: \u0026#34;book\u0026#34;, \u0026#34;query\u0026#34;: { \u0026#34;query_string\u0026#34; : { \u0026#34;query\u0026#34; : \u0026#34;Solr\u0026#34;, \u0026#34;fields\u0026#34; : [\u0026#34;book.title\u0026#34;, \u0026#34;book.contents\u0026#34;] } } } }, \u0026#34;highlight\u0026#34;: { \u0026#34;pre_tags\u0026#34;: [\u0026#34;\u0026lt;b\u0026gt;\u0026#34;], \u0026#34;post_tags\u0026#34;: [\u0026#34;\u0026lt;/b\u0026gt;\u0026#34;], \u0026#34;fields\u0026#34;: { \u0026#34;*\u0026#34;: {} } } } 結果はこちら。 ハイライトがありません。\n{ \u0026#34;took\u0026#34;: 3, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 5, \u0026#34;successful\u0026#34;: 5, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;max_score\u0026#34;: 0.5, \u0026#34;hits\u0026#34;: [ { \u0026#34;_index\u0026#34;: \u0026#34;bookstore\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;_score\u0026#34;: 0.5, \u0026#34;_source\u0026#34;: { \u0026#34;book\u0026#34;: { \u0026#34;title\u0026#34;: \u0026#34;Apache Solr入門\u0026#34;, \u0026#34;contents\u0026#34;: \u0026#34;Apache Solrについて日本語で書かれた唯一の書籍です。SolrはLuceneをコアにした検索サーバです。\u0026#34; } } } ] } } 次に、ハイライトが帰ってくるパターン。 nestedクエリではなく、_allを対象としたクエリを投げます。\n{ \u0026#34;_source\u0026#34; : [\u0026#34;book.title\u0026#34;,\u0026#34;book.contents\u0026#34;], \u0026#34;fields\u0026#34;: [ \u0026#34;book.title\u0026#34;, \u0026#34;book.contents\u0026#34; ], \u0026#34;query\u0026#34;: { \u0026#34;query_string\u0026#34; : { \u0026#34;query\u0026#34; : \u0026#34;Solr\u0026#34;, \u0026#34;fields\u0026#34;: [ \u0026#34;_all\u0026#34; ] } }, \u0026#34;highlight\u0026#34;: { \u0026#34;pre_tags\u0026#34;: [\u0026#34;\u0026lt;b\u0026gt;\u0026#34;], \u0026#34;post_tags\u0026#34;: [\u0026#34;\u0026lt;/b\u0026gt;\u0026#34;], \u0026#34;fields\u0026#34;: { \u0026#34;book.title\u0026#34; : {}, \u0026#34;book.contents\u0026#34;: {} } } } この場合の結果は次の通り。\n{ \u0026#34;took\u0026#34;: 2, \u0026#34;timed_out\u0026#34;: false, \u0026#34;_shards\u0026#34;: { \u0026#34;total\u0026#34;: 5, \u0026#34;successful\u0026#34;: 5, \u0026#34;failed\u0026#34;: 0 }, \u0026#34;hits\u0026#34;: { \u0026#34;total\u0026#34;: 1, \u0026#34;max_score\u0026#34;: 0.27063292, \u0026#34;hits\u0026#34;: [ { \u0026#34;_index\u0026#34;: \u0026#34;bookstore\u0026#34;, \u0026#34;_type\u0026#34;: \u0026#34;books\u0026#34;, \u0026#34;_id\u0026#34;: \u0026#34;1\u0026#34;, \u0026#34;_score\u0026#34;: 0.27063292, \u0026#34;_source\u0026#34;: { \u0026#34;book\u0026#34;: { \u0026#34;title\u0026#34;: \u0026#34;Apache Solr入門\u0026#34;, \u0026#34;contents\u0026#34;: \u0026#34;Apache Solrについて日本語で書かれた唯一の書籍です。SolrはLuceneをコアにした検索サーバです。\u0026#34; } }, \u0026#34;highlight\u0026#34;: { \u0026#34;book.title\u0026#34;: [ \u0026#34;Apache \u0026lt;b\u0026gt;Solr\u0026lt;/b\u0026gt;入門\u0026#34; ] } } ] } } ハイライトが返ってきています。\n考察(原因は未特定) 残念ながら、まだ調査してません。 まずは、現象が理解できたというだけです。 問題点が実は2つありそうです。\n問題点1:nestedクエリの場合に、ハイライトされない。 nestedクエリではハイライトが動作していないようです。 想像ですが、検索に利用されたクエリで指定されているフィールドをハイライタ(ハイライトを実行するモジュール)が認識できてないのではないかと。 なぜ認識できていないのかという点を調査する必要がありそうです。\n考察(試してみたパターン) nestedではないクエリで、ハイライトが動作しているのですが、 \u0026quot;book.title\u0026quot; : {\u0026quot;require_field_match\u0026quot; : true},にした場合は、ハイライトが返ってこないです。 このオプションは、検索対象のフィールドでマッチした文字列だけがハイライトされるオプションになります。 したがって、book.titleフィールドに対する検索でSolrという文字を検索していないことになります。 _allに対するクエリであるためです。 このため、例えば、titleだけを検索対象にしたのに、contentsにSolrという文字が入っていてもハイライトされてしまうという状況が発生します。\n問題点2 store : yesのデータがハイライトできない。 GithubにIssueをあげました。https://github.com/elasticsearch/elasticsearch/issues/5245 (2014/02/25追記)\nnestedオブジェクトにあるデータのうち、store : noのものだけがハイライト結果として返ってきました。\n考察 なぜ、store : yesのデータがハイライトされないかを調べるために、fieldsパラメータをリクエストに追加してみました。\n{ \u0026#34;_source\u0026#34; : [\u0026#34;book.title\u0026#34;,\u0026#34;book.contents\u0026#34;], \u0026#34;fields\u0026#34;: [ \u0026#34;book.title\u0026#34;, \u0026#34;book.contents\u0026#34; ], ... } すると、fieldsの戻り値は次のとおりです。\n... \u0026#34;fields\u0026#34;: { \u0026#34;book.title\u0026#34;: [ \u0026#34;Apache Solr入門\u0026#34; ] }, ... このことから、store : noのデータの場合、_sourceから値を取得して返却しているというのがわかります。 ハイライトがされない原因も、fieldsで値が取れていないのも同じ原因であると思われます。 なぜなら、ハイライトは、保存された文字列を内部で取り出し利用して、ハイライトタグを埋め込むという動作をするためです。\n参考? これらの問題点についてですが、次のIssueが関係あるかもしれません。\nReturn matching nested inner objects per hit #3022\n今後? 残念ながら、現時点では、問題点がどんなものかというのを理解しただけとなります。 デバッグしたりソースを追っかけたりして何が問題なのかを調べて行ってみようかなぁと。\nなにか、気づいたことなどあればコメントしてもらえると助かります。\n","date":1393231920,"dir":"post/2014/","id":"f55d33371dcff207fd7d201128df2ea3","lang":"ja","lastmod":1393231920,"permalink":"https://blog.johtani.info/blog/2014/02/24/strange-behavior-of-field-in-nested-obj/","publishdate":"2014-02-24T17:52:00+09:00","summary":"今年初の「突撃!隣のElasticsearch」ということで、Wantedlyさんにおじゃましました。 ※写真を自分でも撮ったのですが、画像が","tags":["elasticsearch"],"title":"Nested Objectのフィールドの奇妙な動作"},{"contents":"今回はたまたま日本にいたElasticsearchの人をスペシャルゲストに呼べたので、大満足ですw 英語の通訳とかちゃんと勉強しないとなぁ。。。\nとりあえず、てきとーなメモですが、残しておきます。 参加者数は130人+スタッフ+リクルートテクノロジーズ社内の人。という感じでした。アンケート集計はもう少々おまちを。\nスライドがそろったら、また、更新すると思いますが、第一報という感じで公開しておきます。 懇親会にも50名も参加していただけて、非常に楽しかったです。 話ができてない方が多数いるかもしれませんが、次回以降、声をかけていただければと。 (物覚え悪いんで、あれですが。。。) 盛り上がってきてて楽しいなぁ。 スタッフの人達の練度も上がってきてるので、すごく楽ができてます。\n至らない点とかあれば、こちらにコメントしてもらったりしていただければと。\nGeohashing with Elasticsearch Florian Schilling, Elasticsearch Inc, スライド:https://speakerdeck.com/chilling/tokyo-es-study-session-iii-geohashes\n自己紹介 Geoのスタッフ Elsticsearchの概要 転置イデックスやREST APIなどの説明 マイクの調子が良くなくて申し訳なかったっす。。。 平賀さん、通訳ありがとう! Solr本もよろしくお願いします!!\nAWSで構築するsharding 株式会社イプロス 外山 寛さん @toyama0919 スライド:http://toyama0919.bitbucket.org/elasticsearch.html\nAWS対応の話 ルーティングが重要だよ。(宣伝ありがとうございますw) type指定しないとルーティングできない。(内部でtypeも使ってハッシュ値取ってたかなぁ?) 苦労話とかいくつか。 tireはre-tire\u0026hellip; 実サービスでのElasticsearch設定・使用例(仮) 株式会社じげん 多田 雅斗さん @tady_jp スライド:https://speakerdeck.com/tadyjp/tesutoqu-dong-jian-suo-falsesusume-at-tady-jp\n検索とは的な話がわかりやすい。 全文検索のお話。ログ検索じゃないよと。 書籍ないですよねー(ふふふ) specで検索条件記述しといて、ってのいいですよね。絶対必要だと思う Mapping変更した時にテストやり直す方法とかどうしてますか? 特にフレームワークは使ってないです。\nMySQLユーザ視点での、小さく始めるElasticsearch 株式会社リブセンス 吉田 健太郎さん @yoshi_ken スライド:http://www.slideshare.net/y-ken/introducing-elasticsearch-for-mysql-users\nやっぱりkuromoji便利だよね MySQLとかと連携したい。 river-pluginもいまいち安定しない なので、Yamabiko作ってみました。 Geo検索とKuromojiの話をしてくれました。(作者とか開発者がいるってのを狙ってたのかすごいなぁ。) Mappingとかはちゃんと指定したほうがいろいろいいですよ。 nodeJS+DynamoDB+Elasticsearchで全社基盤を作った話 株式会社リクルートテクノロジーズ 相野谷 直樹さん @naokiainoya スライド:http://www.slideshare.net/recruitcojp/elasticsearchnodejsdynamodb-7\nちょっと変わった使い方のElasticsearchで面白いです。 Scroll/Scanについては、Solrでもない機能なので、そういう意味でもElasticsearchなのかもしれないですね。 参加していただいた方々のブログ 第3回elasticsearch勉強会 [2014/02/07(Fri.)]に参加してきました - ほわいとぼーど\nhttp://a3no.hatenablog.com/entry/2014/02/09/022405\n第 3 回 elasticsearch 勉強会に行ってきた - ようへいの日々精進\nhttp://inokara.hateblo.jp/entry/2014/02/07/233057\nhttp://www.smokeymonkey.net/2014/02/3elasticsearch.html\n第3回elasticsearch勉強会でトークしました #elasticsearchjp\nhttp://y-ken.hatenablog.com/entry/elasticsearch-meetup-vol3\n第3回elasticsearch勉強会にいってきました #elasticsearchjp\nhttp://blog.livedoor.jp/ashibuya0128/archives/52058766.html\n","date":1391787720,"dir":"post/2014/","id":"229b7fc784707b1d2c702fbeba080e86","lang":"ja","lastmod":1391787720,"permalink":"https://blog.johtani.info/blog/2014/02/08/hold-3rd-elasticsaerch-meetup-in-tokyo/","publishdate":"2014-02-08T00:42:00+09:00","summary":"今回はたまたま日本にいたElasticsearchの人をスペシャルゲストに呼べたので、大満足ですw 英語の通訳とかちゃんと勉強しないとなぁ。。","tags":["elasticsearch","勉強会"],"title":"第3回elasticsearch勉強会を開催しました! #elasticsearchjp"},{"contents":"すずけんさんがVagrant+puppet使って、VM起動してElasticsearchのクラスタを組んでる記事を書いているのを見て、試してみたくなりました。 ということで、VagrantとかPuppetなに?くらいの私ですが、クラスタを起動するところまで行ったので、その時のメモを残しておきます。\n元記事とか参考 Vagrant環境にpuppet moduleを利用してさくっとelasticsearchをインストールする Vagrant環境にpuppetを利用してさくっとelasticsearchのclusterを作成する puppet-elasticsearch なんとなくの理解 VagrantやPuppetについては、何度か勉強会で話を聞いてはいたのですが、 想像していたレベルだったので良い機会でした。 今のところの認識はこんな感じです。\nVagrant VMを起動したり、VM周りの設定をあれこれできるツール。 VMのネットワーク設定や、インスタンス名?などを指定できる。\nPuppet 起動後のVM(VMとは限らないか。)のゲストOS側の設定周りやアプリのインストールなどを 実行できるツール。\n詰まった箇所 すずけんさんのブログを元に作業をしましたが、自分がVagrantやPuppetに疎いため、以下の部分で躓いたので、備忘録のために残しておきました。\nその1:Puppetのファイルの場所 search01.vm.localのVMを設定(というか、elasticsearchのインストール?)するときに、manifests/search.appとroles/search/manifests/init.ppファイルが必要で作成します。\nこのファイルの配置場所は/vagrant配下に作成する必要がありました。 ssh search01.vm.localでVMにログインした場合は/home/vagrantにログインしており、この場所でファイルを作ってもPuppetがエラーを吐いたためです。\nと思ったのですが、あれ?これひょっとしてVagrantfileがあるところにディレクトリとファイル作ると勝手にVMにコピーしてくれるんですか?destroyして、upしたら、ファイルが勝手にコピーされてる。ひょっとして、/vagrantってディレクトリはVagrantfileがあるディレクトリを共有してたりするのかな?そのうち、Vagrantについても調べてみようかな。\nその2:ネットワーク周り curl http://192.168.10.114:9200/ をホストOSから実行してみましたがうまく行きませんでした。。。 ネットワーク周りの設定だと思うんですが。 少なくとも「sshによるログイン」「ping」コマンドの応答は返ってきてます。\nまた、VM内でcurlコマンドを実行したらレスポンスが返ってきました。\nなんで?ってツイートしたら各所から「iptables」という単語が飛んできて、 service止めたら大正解でした。まぁ、そうですよね。基本ですよね。。。\nということで、Puppetがよくわかっていませんが、ググって変更してみました。\nmanifests/search.appに以下を追加\ninclude iptables roles/iptables/manifests/init.pp\nclass iptables { service { \u0026#39;iptables\u0026#39;: enable =\u0026gt; false, ensure =\u0026gt; stopped, } } iptablesを停止するmanifests?です(良くないことなんですが、よくわかってない)。\nということで、ローカルで1個のVM起動して、elasticsearchにアクセスできることは確認できました。\nと、書いてるそばから、元記事が修正されてしまいましたw\nクラスタ編(変更点) クラスタを組むときに、追加でプラグインを入れたのでroles/search/manifests/init.ppは次のようにしました。\nclass search { class { \u0026#39;elasticsearch\u0026#39;: package_url =\u0026gt; \u0026#39;https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.0.0.RC2.noarch.rpm\u0026#39;, java_install =\u0026gt; true, config =\u0026gt; { \u0026#39;cluster\u0026#39; =\u0026gt; { \u0026#39;name\u0026#39; =\u0026gt; \u0026#39;test-es-cluster\u0026#39; }, \u0026#39;network.host\u0026#39; =\u0026gt; \u0026#39;_eth1:ipv4_\u0026#39;,, \u0026#39;marvel.agent.exporter.es.hosts\u0026#39; =\u0026gt; [\u0026#39;192.168.10.114:9200\u0026#39;,\u0026#39;192.168.10.115:9200\u0026#39;] } } elasticsearch::plugin{\u0026#39;elasticsearch/marvel/latest\u0026#39;: module_dir =\u0026gt; \u0026#39;marvel\u0026#39; } elasticsearch::plugin{\u0026#39;mobz/elasticsearch-head\u0026#39;: module_dir =\u0026gt; \u0026#39;head\u0026#39; } elasticsearch::plugin{\u0026#39;royrusso/elasticsearch-HQ\u0026#39;: module_dir =\u0026gt; \u0026#39;HQ\u0026#39; } elasticsearch::plugin{\u0026#39;elasticsearch/elasticsearch-analysis-kuromoji/2.0.0.RC1\u0026#39;: module_dir =\u0026gt; \u0026#39;analysis-kuromoji\u0026#39; } elasticsearch::plugin{\u0026#39;info.johtani/elasticsearch-extended-analyze/1.0.0.RC1\u0026#39;: module_dir =\u0026gt; \u0026#39;extended-analyze\u0026#39; } elasticsearch::plugin{\u0026#39;polyfractal/elasticsearch-inquisitor\u0026#39;: module_dir =\u0026gt; \u0026#39;inquisitor\u0026#39; } } とりあえず、今日はクラスタ組んでMarvelやプラグインの動作確認でおしまいです。\n疑問点 いくつか疑問点が。試してみてもないんでなんとも言えませんが。気が向いたら、調べて追記するかも。\n:private_networkはVirtualBox内で完結する(Macから外には影響しない)ネットワークが構築される?たぶん、VagrantというよりはVM、仮想化周りの知識なんだろうけど どこから再開可能?elasticsearch.ymlの設定を書き換えた場合に、最後のコマンドだけ実行するとちゃんとやりなしてくれたりするのかな? VMのディスク増やすのもVagrantでできるんかな?まぁ、できると思うけど。 :forwarded_portのauto_correctとかわかってない。 JVMをSunのJVMでかつ、7u25に変更したいのだがどうしたものか?(現時点での推奨バージョン) 感想 Vagrantって便利ですね。あれ?って思ったら、destroyして、やり直すのがすごく簡単です。 元記事があるので、なんとなくですが、構成とかどうすればいいかがわかるのは本当に助かりました。 これで、あれこれと検証する環境が簡単に構築できることがわかったので、色々と楽できるかも。ありがとうございます、すずけんさん!\n","date":1391695740,"dir":"post/2014/","id":"c98cbc333fb7d95c6c9fc4924b0526e1","lang":"ja","lastmod":1391695740,"permalink":"https://blog.johtani.info/blog/2014/02/06/es-cluster-start-using-vagrant-and-puppet/","publishdate":"2014-02-06T23:09:00+09:00","summary":"すずけんさんがVagrant+puppet使って、VM起動してElasticsearchのクラスタを組んでる記事を書いているのを見て、試して","tags":["elasticsearch","vagrant","puppet","marvel"],"title":"すずけんさんのメモを元にVagrantでElasticsearchクラスタを起動してみた"},{"contents":"改訂新版Solr入門出版記念ということで、第13回Solr勉強会 #SolrJP 新Solr本出版記念を開催しました。\n出版記念なので、技術評論社様より、プレゼント用にSolr本を用意していただきました!ありがとうございます!! 書籍をゲット出来た方は、ツイートしたりブログ書いたり書評書いたりして、宣伝してください!!!\n今回は、私は手を抜いて他の人に喋ってもらいました!\n今回は、著者陣(関口さんは特別ゲスト)でスピーカーを固めてみました。 以下は、いつもの簡単なメモです。 スライドが集まったらまた更新していきます。\n1. 「はじめての検索エンジン&Solr」 株式会社NTTデータCCS 鈴木 教嗣さん スライド:はじめての検索エンジン&Solr 第13回Solr勉強会\n鈴木さんの発表初めて聞きましたw。 趣味が多いなぁ。 ちょこちょこと、宣伝を入れてるのが流石ですw\n入門らしい概要 クエリの概要とかも。 スコア計算とか 導入するとうれしいところとか Solr盛り上げましょう! 2. 「Solr SearchComponent 再訪」 株式会社ロンウイット 関口 宏司さん スライド:公開待ち\nベン図で検索の評価指標の説明 理論的なお話 Solrのサーチコンポーネントを使って何ができるか。ベン図で。 サーチコンポーネント以外にも NGramTokenizerも SynonymFilterも パーソナライズ検索 いきなり話をふられたのでちょっとびっくりしましたw\n3. 「自動補完(Autocomplete)ともしかして?(Did You Mean?)」 株式会社 ロンウイット 大須賀 稔さん スライド:Solr AutoComplete and Did You Mean?\nデモ:https://github.com/mosuka/solr-suggester-demo-ui\n職歴が相変わらずおもしろい 編集距離のお話 素晴らしいCM! 候補のランキングを変更できる? SpellcheckComponentのパラメータで指定できるものなら楽ですが。。。\n4. 「Lucene Revolution 2013 Dublin振り返り」 楽天株式会社 平賀 一昭さん スライド:公開待ち\nダブリンどこ?(間違ってベルリンって言っちゃいましたw) スタジアムで開催。グランドにも入れるのかなぁ? まずはTwitter Luceneの改良版 ちょっと特殊。140文字とか 青いRさんのライバル。Careerbuilder 元FASTユーザ 企業向けに検索キーワードとかの解析画面を用意 検索精度の改良の話とか 転職で引っ越す意思があるかとか。 最後はLinkedIn Luceneのユーザ まとめ ということで、スピーカーの方々のスライドにもありましたが、 改訂新版Apache Solr入門は良い本なので、購入していただけると嬉しいです。\n感想、コメントなど、いつでもお待ちしています!\n","date":1390988760,"dir":"post/2014/","id":"c6107ff57e96a1373c019d252c00ad84","lang":"ja","lastmod":1390988760,"permalink":"https://blog.johtani.info/blog/2014/01/29/hold-to-japan-solr-meetup/","publishdate":"2014-01-29T18:46:00+09:00","summary":"改訂新版Solr入門出版記念ということで、第13回Solr勉強会 #SolrJP 新Solr本出版記念を開催しました。 出版記念なので、技術評論社様より、プレ","tags":["Solr","勉強会"],"title":"第13回Solr勉強会を開催しました"},{"contents":"昨晩、Elasticsearchから初のプロダクトとなるMarvelがリリースされました。ということで、さっそく触ってみて、簡単な紹介と感想を書いてみました。\nMarvelって? Elasticsearch社が初のプロダクトとしてリリースした、Elasticsearchクラスタモニタリングツールです。 次のような特徴があります。\nplugin形式で提供 GUIがKibana メトリックスはElasticsearchに保存 SenseがChrome以外でも使える プロダクション環境で利用する場合は有料ですが、開発用途では無料で利用できます。 現時点(2014/01/29)では、0.90.9以上のバージョン(1.0.0.RC1含む)で利用が可能です。\nなにができるの? Elasticsearchクラスタに関するメトリックスを保存、可視化できるプロダクトです。 ドキュメント数やJVMの状況、クラスタの状態など、いろいろなメトリックスが保存されます。\n保存先は、別のElasticsearchクラスタにすることも可能です。 お試しでインストールして見る場合は、同一クラスタにサービスに利用するインデックスとMarvel用のメトリックス保存先インデックスを入れても良いです。\nただ、プロダクション環境では、Marvel用インデックスはあくまでもモニタリングに使用するため、サービスのクラスタへの影響を最小にしたくなります。\nこのような場合、Marvelのプラグインの設定を変更することで、メトリックス送信用のエージェントとして動作させることができます。\n詳しくは、Marvelのドキュメントにあるinstalling a secondary monitoring clusterを御覧ください。\n1/29 16時時点で、上記ドキュメントのエージェントの送信先の設定に関する部分に誤記がありました。 おそらく、configuration optionsの記述が正だと思います。 もう、なおってました。(1/30朝時点)\nキャプチャいろいろ 日本語WikipediaのデータをRiverで登録しながら各画面の動作などを見てみました。\nMarvel Overview 日本語WikipediaをRiverで登録してる途中。Loadが高くなってることなどがわかります。\nOverview (クラスタの状態が変化) クラスタの状態が変化したところに、タグが付くみたいです。 ここでは、ノードの一つを停止、起動しました。\nインデックス終了後に、クラスタを再起動してしまい、クラスタ内のシャードの再配置が実行されてしまったため、クラスタの状態がYellowになってしまうとこんな感じ。ちょっとわかりにくいです。\nSense Chromeプラグインとしてリリースされていたクエリ実行コンソールがMarvelのサイトプラグインとして提供されています。これがあるだけで、Elasticsearchへのクエリの実行が格段に効率良くなります。\nIndex Statistics インデックスに関する情報のグラフが見れるページです。ドキュメント数の他に、容量やリクエスト数なども見れます。\nインデックス終了後のグラフはこんな感じ。\nインデックス終了後のOverviewはこんなかんじです。\nCluster Pulse クラスタで発生したイベントとイベントの詳細を見ることができるページです。各種インデックスがYELLOWからGREENに変わっていっているのがmessageで分かります。\nすべて再配置が終わったらGREENになりました。\nNode Statistics 各ノードに関する情報を見ることができる画面です。 ノードごとにグラフの色を分けることもできます。\nその他 Marvelプラグインにブラウザから接続できなくなるとこんなメッセージが出ました。\n参考までに、elasticsearch-headの画面も。こちらのほうが、シャードの再配置中であるのがひと目で分かります。\n感想 綺麗です。まぁ、Kibanaが綺麗ですから。 クラスタ内で発生したイベントが時系列で保存されるため、あとからどんなことが発生したのかといった原因の追求などには非常に役に立ちそうです。\nただ、インデックスの状態や状況(クラスタ再起動やノード追加時にshard再配置などが実行されている状況とか)はelasticsearch-headのほうがわかりやすかったです。 インデックス単位でのStatusがMarvelの画面ではわからないため、shard再配置が完了したかどうかなどのタイミングがわかりにくかったです。\nある程度、多くのノードを利用したクラスタを利用する場合に、モニタリングツールとして利用するのは便利なのではないでしょうか? 時系列でログやイベントが保存されるので、ノードが追加されたり外れたりといった状況があとからでも追跡可能なのが便利です。\n疑問点 インデックスの情報などは、5s毎にMarvelのインデックスに保存されているようです。ただ、GUI上では5分毎のデータしか表示されません。 どうやって変更するんだろう?\nまた、Marvelのクラスタへの接続が切れた時のデータはどうなるのか?という部分も気になります。Marvelのクラスタを更新している時や、ネットワークが遮断されてしまった場合のデータがどうなるのかという点です。\n疑問点への回答(2014/01/30追記) 疑問点に対して中の人から回答を頂いたので、追記です。\nQ:GUI上で5分毎のデータしか表示されないんですが? A:ブラウザの負荷を高くしないようにするために、1つのグラフに20のプロットしてるだけです。ズームしたりすると、もっと細かなデータが見れますよ。 Q:Marvelのクラスタへの接続が切れた時のデータはどうなるんだろう? A:接続が切れた場合は、ローカルに保存されるけどデータは無視されます。接続が戻ると、戻った後のデータは記録されていきます。将来的には改善するかも。 ちなみに、昨日試してた環境が、足元Linux環境(監視対象のクラスタ)+手元Mac環境(Marvelモニタリングデータ格納クラスタ)という環境でした。 確かに、出社してから、手元Mac環境を起動すると、データが流れてくるようになりました。 ただ、監視対象のクラスタでは、socket timeoutのログがずっと出てましたが。\n参考文献 リリースブログ プロダクトページ ドキュメント ","date":1390983240,"dir":"post/2014/","id":"f6debed350f20a2b3aa4d970e3227411","lang":"ja","lastmod":1390983240,"permalink":"https://blog.johtani.info/blog/2014/01/29/simple-introduction-and-first-impression-es-marvel/","publishdate":"2014-01-29T17:14:00+09:00","summary":"昨晩、Elasticsearchから初のプロダクトとなるMarvelがリリースされました。ということで、さっそく触ってみて、簡単な紹介と感想","tags":["elasticsearch","marvel"],"title":"Elasticsearch Marvelの紹介と第一印象"},{"contents":"Lucene/Solr 4.6.1がリリースされそう(バイナリ配布待ち)lucene-gosenの4.6.1対応版をリリースしました。\nライブラリのインタフェースなどは特に変更はないのですが、ライブラリのダウンロード先が変更になっているため、注意喚起です。\nGoogle Project Hostingの仕様変更により、Downloadsに新規ファイルがアップロードできなくなっています。(2014年から)\nこのため、プロジェクトの選択肢としては以下の3点となっています。\nGoogle Driveにファイルをアップロードしてダウンロードしてもらう 他のソースコード管理サイトなどを利用する。 他のダウンロードサイトを利用する 1.と3.は場所が違うだけで、方法は一緒です。 今回は、暫定的に1.を利用してダウンロードするように対応しました。\nダウンロード先はプロジェクトのページにリンクが有りますが、わかりにくいのでキャプチャを撮ってみました。\nダウンロード先 これまでのFeatured - Downloadsとは異なり、Links - External linksの下に Downloads lucene-gosen 4.6.1というリンクを用意してあります。\nフォルダとなっており、各種jarファイルがリストされていますので、こちらからダウンロードをお願いします。 今後は、この下にダウンロードリンクを追加していく予定です。\nただし、2.で述べたように「別のソースコード管理サイト」も検討中です。\n","date":1390880040,"dir":"post/2014/","id":"c4e7199a586a308352b7a881add7e356","lang":"ja","lastmod":1390880040,"permalink":"https://blog.johtani.info/blog/2014/01/28/release-lucene-gosen-4-dot-6-1/","publishdate":"2014-01-28T12:34:00+09:00","summary":"Lucene/Solr 4.6.1がリリースされそう(バイナリ配布待ち)lucene-gosenの4.6.1対応版をリリースしました。 ライブラリのインタフェースな","tags":["Solr","Lucene","lucene-gosen"],"title":"lucene-gosen 4.6.1のリリースに関する注意点"},{"contents":"Elasticsearchのcuratorのブログ記事を読んで、日本語でツイートしたところ、Aaron Mildensteinさんから日本語(ローマ字)で返信を頂きました。 せっかくなので、ブログ記事を翻訳してもいいかを尋ねたところ、快くOKを頂いたので、翻訳してみました。参考になればと。(誤訳など見つけたらコメントください。)\n@johtani Kore no hou ga ii. Nihongo de no Curator RT, arigatou gozaimasu! #elasticsearch #curator #logstash\n\u0026mdash; Aaron Mildenstein (@theuntergeek) 2014, 1月 22 curator: 時系列インデックスの管理 原文:curator: tending your time-series indices\n背景 数年前、Elasticsearch、Logstash、Kibana(ELK)を管理し、ここ30日よりも古いインデックスを自動的に削除する方法を必要としていました。 APIドキュメントを読み、#logstashや#elasticsearchのIRCチャネルのコミュニティの助けを借りて、簡単なスクリプトとcronを用意するのが簡単であることを知りました。\ncurl -XDELETE \u0026#39;localhost:9200/logstash-2014.01.01?pretty\u0026#39; もちろん、これも動作しますが、日付を生成するのがめんどくさいのでもっとエレガントな方法が欲しかったです。\n最初に pythonでスクリプトを書き始めました。特定の日数のインデックスを管理するだけのコマンドラインクリーナーを書いてコミュニティにシェアしました。他の人が、新しい機能を追加してくれました。私は、古いインデックスをoptimizeすることができる他のスクリプトも書きました。これは、シャードごとにnセグメント以上存在しないように各シャードのセグメントをマージすることです。これらのスクリプトで1つになるようにマージしたりエンハンスし、古いインデックスを管理する助けになるツールです。\ncuratorの紹介 Curatorで可能なインデックスオペレーション\n削除(日付もしくは、トータル容量による制限) インデックスのクローズ(Close) bloom filter cacheの無効化 Optimize(LuceneのforceMerge) curatorのインストール この記事を書いている時点で、Curator は0.5.1がリリースされ、0.90.10に対応しています。Curatorはまた、Elasticsearchの1.0(現在はRC1)へも対応しています。各リリースへの互換性の保証のためのテストも行っています。\n現時点では、gitリポジトリで配布しています。近い将来、pipによるインストール可能なパッケージにする予定です。利用することを恐れないでください。もし、pythonとpipがあなたのマシンにインストールされていれば、次のようにインストールは簡単です。\ngit clone https://github.com/elasticsearch/curator.git pip install -r requirements.txt インストール後の確認は次のコマンドです。\n$ ./curator.py -v curator.py 0.5.1 利用方法とサンプル サンプルを示す前に、オプションを見ておくとよいでしょう。このリストは長いですが(この記事の最後に含まれています)、どのようなことがコントロールできるかを説明しています。デフォルトがどうなっているかに注意してください。もし、デフォルト値で良い場合は、フラグを指定する必要はありません。\nでは、簡単なサンプルを見ながら、CuratorがELKスタックをどうやって管理するかを見て行きましょう。\n削除(delete) 90日以上のインデックスを保存したくないとしましょう。コマンドは次のようになります。\n$ curator.py --host my-elasticsearch -d 90 -dで日数を指定しているだけです。簡単でしょ?\n容量による削除(delete by space) これは、指定したギガバイト数を超えたインデックスを場合に(最も古いものから)削除を行う特殊なケースです。\n$ curator.py --host my-elasticsearch -C space -g 10024 -Cでspaceによるcurationであること、-gでギガバイト数(10024、10TB)であることを指定しているのがわかります。-gは1.5や0.5という数値を指定できます。\nその他のCuratorオプションはspaceによる削除と組み合わせて使用できないことに注意してください。\nクローズ(close) Open/Close Index APIにより、インデックスをクローズすることができます。\nopen/close index APIを利用すると、インデックスをクローズしたり、あとでオープンしたりすることができます。クローズされたインデックスはクラスタのオーバヘッドにほとんどならず(メタデータの管理を除く)、読み書き操作の妨げにもなりません。クローズされたインデックスは、リカバリプロセス時に、オープンされます。\nインデックスをクローズすることは、存在はするが検索できないという意味です。何が便利なのでしょう?\n90日のインデックスを保存する義務があるが、検索は過去30日のインデックスを対象にする以外は稀であるような場合を想像してください。このような状況で、価値のあるリソース(ヒープスペースなど)を節約するためにインデックスをクローズすることができます。これは、クラスタに検索やインデキシングのためのメモリを与えることができることを意味します。そして、もし、クローズしたインデックスのデータが必要になったら、APIを呼び出してインデックスをオープンすれば検索できます。\nこのような場合、今オープンしているインデックスが再び、クローズされないように、一時的にCuratorのスケジュール実行をオフにしておくのが懸命です。\n$ curator.py --host my-elasticsearch -c 30 -d 90 先ほど説明した例の実行方法です。これは、30日よりも古いインデックスはクローズし、90日より古いインデックスを削除します。本当に簡単でしょ?\nbloom filterの無効化 これは、0.90.9以降のバージョンで利用可能な機能です。(リンク先はIssue #4525)\n心配しないでください。このスクリプトは操作を行う前に、elasticsearchが利用可能なバージョンであるかをチェックします。\nbloom filterとは何でしょう?なぜ、無効化したくなるのでしょう?\nbloom filterはインデキシング操作を高速化するためにリソースを割り当てられます。時系列データで、インデキシングしている間もこれは有用です。インデックスは2日後には、日付が変わると新しいデータはおそらくインデックスされません。そのインデックスにはもはや必要のないリソースをbloom filterはまだ持っています。Curatorはこれらのリソースを開放することができます!\n$ curator.py --host my-elasticsearch -b 2 -c 30 -d 90 これで、bloom filterのリソースは少なくとも2日(1にもできます)よりも古いインデックスについては利用せず、30日より古いインデックスはクローズし、90より古いインデックスは削除します。\noptimizeというよりもforcemerge コマンドの説明をする前に、Elasticsearch APIのoptimizeを見ることは、生きているインデックスや\u0026quot;cold\u0026quot;インデックス(インデキシングがアクティブではないという意味)に実行する必要があるということを理解するために重要です。実際、optimizeはLuceneではforceMergeと名前が変えられ、インデックスを改善するためにoptimizeを呼び出す必要はなくなりました。Elasticsearchのセグメントをマージすることは利点がありますが、coldインデックス全てに対してoptimizeを開始する前に、コストを理解する必要があります。\nforceMerge操作はインデックスにある各シャードのセグメントの数を少なくします。各セグメントはオーバヘッドがあるため、セグメントが多いということは、より多くのリソースを使うという意味です。良さそうですね?リソースが少ない?\nそれは、可能ですが、merge操作を実行するには多くのディスクやネットワークI/Oが必要で、ディスクやクラスタの通常の書き込み操作に悪影響を及ぼします。もし、これが必要なら私のアドバイスを良く考えてください。(数%ほど)検索を速くし、リソースの使用量も減らすことができます。また、管理しているセグメント数が小さくなるということは、クラスタのリカバリを速くすることにもなります。1つのインデックスをoptimizeするためにはおそらく1時間以上の時間がかかります。「使用する前に目立たない場所で試してください」というクリーニングボトル(訳注:洗剤とか漂白剤かな?)の注意書きと同様に、ディスクI/Oが低い時にテストし、もし操作とリソースがあなたのクラスタのユースケースにあっているかを見てください。デフォルトでは、シャードごとに2つのセグメントにマージしますが、--max_num_segmentsフラグで変更可能です。\nここまでのサンプルは次のようなコマンドになります。\n$ curator.py --host my-elasticsearch -b 2 -o 2 -c 30 -d 90 これで、bloom filterは2日より古いインデックスでは向こうにし、2日より古いインデックスは\u0026quot;optimize\u0026quot;し、30日より古いインデックスはクローズし、90日より古いインデックスは削除されます。\n操作の順序 スクリプトは操作が衝突するのを防ぐために次の順序で実行されます。なぜ、クローズされたインデックスはoptimizeしないのでしょう?なぜ、削除予定のインデックスはクローズされないのでしょう?\nDelete (by space or time) Close Disable bloom filters Optimize 使用の検討 最後の例で、3つの操作を1つのコマンドで実行していますが、それらが連続ですべて実行されるのを望んでいないかもしれません。\n$ curator.py --host my-elasticsearch -b 2 -o 2 -c 30 -d 90 これは、次の操作と同様です。\n$ curator.py --host my-elasticsearch -d 90 $ curator.py --host my-elasticsearch -c 30 $ curator.py --host my-elasticsearch -b 2 $ curator.py --host my-elasticsearch -o 2 これらのコマンドを異なる時間に実行したり、異なるその他のオプション(特に、optimize実行で--timeout 3600を追加したり)を指定して実行するのは簡単です。\nまた、デフォルトのlogstash-とは異なるプレフィックスのインデックスを持っているかもしれません。\n$ curator.py --host my-elasticsearch --prefix logstash- -d 30 $ curator.py --host my-elasticsearch --prefix othername- -d 30 最後に Curatorは時系列インデックスの保存ポリシーを管理するのに役立ちます。豊富な設定オプションがインデックスを管理することを簡単にします。クラスタに存在するノードの数に関係なく。https://github.com/elasticsearch/curatorへのフィードバックやコントリビューションをお待ちしています!\n参考(全引数とオプション) $ curator.py -h usage: curator.py [-h] [-v] [--host HOST] [--port PORT] [-t TIMEOUT] [-p PREFIX] [-s SEPARATOR] [-C CURATION_STYLE] [-T TIME_UNIT] [-d DELETE_OLDER] [-c CLOSE_OLDER] [-b BLOOM_OLDER] [-g DISK_SPACE] [--max_num_segments MAX_NUM_SEGMENTS] [-o OPTIMIZE] [-n] [-D] [-l LOG_FILE] Curator for Elasticsearch indices. Can delete (by space or time), close, disable bloom filters and optimize (forceMerge) your indices. optional arguments: -h, --help show this help message and exit -v, --version show program version number and exit --host HOST Elasticsearch host. Default: localhost --port PORT Elasticsearch port. Default: 9200 -t TIMEOUT, --timeout TIMEOUT Elasticsearch timeout. Default: 30 -p PREFIX, --prefix PREFIX Prefix for the indices. Indices that do not have this prefix are skipped. Default: logstash- -s SEPARATOR, --separator SEPARATOR Time unit separator. Default: . -C CURATION_STYLE, --curation-style CURATION_STYLE Curate indices by [time, space] Default: time -T TIME_UNIT, --time-unit TIME_UNIT Unit of time to reckon by: [days, hours] Default: days -d DELETE_OLDER, --delete DELETE_OLDER Delete indices older than n TIME_UNITs. -c CLOSE_OLDER, --close CLOSE_OLDER Close indices older than n TIME_UNITs. -b BLOOM_OLDER, --bloom BLOOM_OLDER Disable bloom filter for indices older than n TIME_UNITs. -g DISK_SPACE, --disk-space DISK_SPACE Delete indices beyond n GIGABYTES. --max_num_segments MAX_NUM_SEGMENTS Maximum number of segments, post-optimize. Default: 2 -o OPTIMIZE, --optimize OPTIMIZE Optimize (Lucene forceMerge) indices older than n TIME_UNITs. Must increase timeout to stay connected throughout optimize operation, recommend no less than 3600. -n, --dry-run If true, does not perform any changes to the Elasticsearch indices. -D, --debug Debug mode -l LOG_FILE, --logfile LOG_FILE log file ","date":1390542480,"dir":"post/2014/","id":"15f501351d482ffd73985a50f5c89d1f","lang":"ja","lastmod":1390542480,"permalink":"https://blog.johtani.info/blog/2014/01/24/curator-tending-your-time-series-indices-in-japanese/","publishdate":"2014-01-24T14:48:00+09:00","summary":"Elasticsearchのcuratorのブログ記事を読んで、日本語でツイートしたところ、Aaron Mildensteinさんから日本語(","tags":["elasticsearch","curator"],"title":"Curator: 時系列インデックスの管理(日本語訳)"},{"contents":"あけましておめでとうございます。今年もSolrやElasticsearchについて色々と頑張っていく所存です。 とまぁ、お決まりの挨拶はおいておいてと。(もう、新年も22日ですが。。。)\nElasticsearchの1.0.0RC1がリリースされました。 ということで、私が作っているExtended-Analyzeプラグインも1.0.0RC1向けに修正してリリースしました。\n1.0.0RC1向けに修正したこと コミットログを見てもらえば、いいのですが、ロジック自体は変更しなくても良かったです。\nただ、正式に、Elasticsearchのつづりが決定したようで、クラス名が「ElasticSearchほげほげ」から、「Elasticsearchほげほげ」と、SearchのSが小文字になりっています。 この影響で、例外クラスなどの名称を幾つか変更しました。 また、バージョン番号を1.0.0RC1とし、0.x系をElasticsearchの0.90系向けのバージョンにしていく予定です。\n今後は、UIを追加したいと思っているので、Elasticsearchのバージョン番号とはずれてくるとは思いますが。。。\nElasticsearch 1.0.0RC1を利用してみて 1点だけですが。 これまでは、-fオプションを指定すると、デーモンではない動作で起動できていました。(デフォルトがデーモン起動)\nこれが、1.0.0から(0.90の最新もかな?詳しく見ていない)デフォルトの挙動が変更され、デーモン起動ではなくなりました。 代わりに、-dオプションを指定することで、デーモン起動ができるようになりました。\nこれで、手元でうっかりデーモン起動することがなくなって、ひと安心です。(他の人は困るかもしれないけど)\nということで 1.0.0RC1が出たので、少しずつ1.0系で追加されたAPIや機能について、ブログで紹介していけたらと思います。\nこんなこと調べてよ?、これわかんないんだけど?などありましたら、コメントいただければと。 気が向いたら記事を書くので。\nあと、Extended-Analyzeプラグインの感想などもお待ちしています!\n今年もよろしくお願いします!\n","date":1390317360,"dir":"post/2014/","id":"6425af51edead39c0e439073986043fb","lang":"ja","lastmod":1390317360,"permalink":"https://blog.johtani.info/blog/2014/01/22/release-extended-plugin-for-1-0-0rc1/","publishdate":"2014-01-22T00:16:00+09:00","summary":"あけましておめでとうございます。今年もSolrやElasticsearchについて色々と頑張っていく所存です。 とまぁ、お決まりの挨拶はおいて","tags":["elasticsearch"],"title":"Extended-Analyze 1.0.0RC1をリリースしました"},{"contents":"昨年は、大晦日に書いてました。 ちょっと進歩したかも。\n振り返り(2012年に書いた抱負から) ということで、まずは昨年書いた抱負からの振り返りです。\nIntelliJ IDEAをメインに使う JIRAを継続して活用 ブログの継続 elasticsearch Luceneのソースコードリーディング 何かOSSのソースを読む Macでもっと開発 読書と英語を継続 お。思ったよりもできてるかも。 IntelliJ IDEAについては、メインになりました。Eclipseを開くことはまずないです。 Macがメインの開発マシンにもなってきてるので。(開発してないんじゃないかという話も。。。)\nJIRAは一応、継続しているという感じです。\n唯一Luceneのソースコードリーディングができてないですね。。。 言い訳をすると、明示的にソースコードリーディングをしているわけではないですが、Luceneのソース自体は時々見ています。 SolrやElasticsearchを調べるとそのままLuceneにたどり着くことがあるので。\nポモドーロのタスク管理用に使っていますが、時々忘れていたり。あと、振り返りがまだちゃんとできてないので、そこをやらないとかなぁと。 読書と英語は今後も継続です。もっと習慣づけないと。\n振り返り(今年あった出来事など) CROSSでモデレータやりました Xperia Zに機種変 メニエール病 リクルートテクノロジーズさんのお手伝い Lucene In Action輪読やってる MIR輪読も継続 Solr勉強会を不定期開催 Elasticsearch勉強会を始めた Solr本の改訂版を執筆 AWSちょっと触った Elasticsearchプラグイン作ってみた Githubの活用 Octopressでブログ こんなかんじです。\nCROSSでは、モデレータをやらせていただきました。すこしは検索を面白いと思ってもらえたかなと思います。 来年のCROSS 2014ではスタッフとして盛り上げていく予定ですので、スタッフに興味ある方は声をかけてください! 面白い話がいっぱい聞けますし、おいしい物も飲み食いできるかも!?\nXperia Zは良い買い物でした。ただ、すでに2回電源部分が故障してますが。。。 それ以外は非常に快適です。\n2月末から3月は少し休んでました。難聴→めまい→メニエール病という流れで、ちょっとしんどかったです。 ほぼ回復しましたが、原因は不明みたいなので、長く付き合ってくのかなぁと。\n4月からリクルートテクノロジーズさんの仕事を手伝っています(Solr本の著者紹介にも書いてます)。 色々と面白いことをしているATLという部署で面白い人達と仕事させて頂いてます。 来年もよろしくお願いします!(もっと価値を出さないとなぁ。。。)\nその一環で、Lucene In Actionの輪読を社内でやっていたりも。バージョンが3.x系で書かれているので、 ちょっと大変ですが、4だとどう違うかなどの話を交えつつ少しずつ読んでいます。\n輪読会といえば、MIR(Modern Information Retirieval)の輪読も続いています。 私は深いところまでわからないのですが、色々と詳しい方たちとボチボチ読んでます。教えてもらってばかりですが、来年も頑張りますよと。\nSolr勉強会も、引き継いでぼちぼちやっています。来年は1/29に開催します。Solrの入門的な話をしてもらうので、 ぜひ、触ったことがない方や興味がある人に参加していただきたいと。\nElasticsearch勉強会も主催し始めました。興味ある人がいるだろうとは思ったのですが、想像以上でびっくりしてます。 自分が理解を深め、発表するためにも、2ヶ月程度のスパンで来年も開催する予定です。 スピーカーに興味のある方は、elasticsearch-jpのMLや私にコンタクトしてください。\nSolr入門のSolr4対応版も執筆しました。今回は全体のコーディネートもやらせていただきました。 Solr活用のお役に立てていただければと。まだ購入してない方はぜひ、以下のリンクから!(PDF版もあります。) 質問などあれば、ブログにコメントをいただくか、ツイートしていただくか、技術評論社のサポートページに問い合わせていただければと思います。\nAWSをちょっとだけ触りました。 S3にバックアップ取ってるだけですが。。。来年はもう少し。。。 JIRA(さくらVPSに立ててる)のバックアップなどをやってます。\nあとは、Elasticsearchの勉強会も始めたこともあり、Elasticsearchを色々と触っています。 elasticsearch-analysis-kuromojiプラグインのREADMEを記述してコントリビュートしてみたり、 elasticsearch-extended-analysisプラグインを作ってみたり。\n勉強会のスピーカー探しも兼ねて、いろんなところに、「突撃!隣のElasticsearch」と称してElasticsearchの話を聞きに行きたいと思っていますので、使ってるよ!とか使いたいんだけど、どうすればいい?みたいな話があれば、声をかけてください。Twitterでツイート見たら勝手に、アタックすることもあるかもですが、その時はよろしくお願いします。\n来年はSolrやElaticsearchにもっと貢献できればと。\nGithub(git)もようやくまともに触り始めました。 某データの管理やプラグインの開発などでやっと触り始めました。 まだ、チーム開発ってほどではないので、チームで開発するときのやり方なども少しずつ勉強していこうかと。 プルリクとかも少しずつやってみたりしてます。\nあとは、Octopressでブログ始めました。その前はjugemだったのですが、なんとなく。 Markdownに慣れるためというのもありOctopressにしてみました。 (Solr本の原稿もMarkdownで書いてました) 昔のブログもこっちにコピーするプログラムも書いてみようかな。\n来年の抱負 Elasticsearch勉強会、Solr勉強会の継続+ミックスした検索勉強会の開催 IDEAのさらなる活用 もっと開発(プラグインとか) AWSをもう少し活用 海外のイベントに行ってみたい 読書と英語を継続 勉強会の開催は今後も継続していく予定です。会場を毎回提供して頂いているVOYAGE GROUPさん、リクルートテクノロジーズさんには、 今後もお手数をお掛けしますが、よろしくお願い致します。勉強会の開催を通じて、色々な人のノウハウがうまく共有できて、 もっと本質的な作業(サービスの改善とか)に注力できる環境ができると面白いなぁと思ってるので。\nあと、Elasticsearch、Solrと別々の勉強会になっていますが、検索エンジン勉強会という形でそれぞれのメリット・デメリットを 共有できる勉強会も面白いかもと思っているので、春とかに開催したいなぁと考えてもいます。(まだ考えているだけで何もネタがないですが)\nIDEAは、年貢(13のサブスクリプション)を収めたので、もっと活用しないとという意味で。プラグインの開発、gitやsvnのクライアントとしては 活躍していますが、もっと開発に活用していかないとなぁと。まだ、10%くらいしか活用できてない気がするので。\nもっと開発しないとなと。毎年言ってますが。今年は書籍に注力したのもあり、ソースを読んだり英語を読んだりが多くなってました。 偉そうにしてるためか、開発する機会が減ってきているので、細かなことでもいいので、すこしずつコードを書いていこうかと。 (もっと自分で問題点を見出してそれを補完するようなコードなりプラグインなり書けばいいんだろうな。)\n開発と合わせて、AWSをもう少し触りたいなと。これも数年言っていますができてないです。。。 ネタ探すのが下手なのかなぁ。\n海外イベントにも行ってみたいです。まだ、海外行ったことないんですが。。。 Lucene Revolutionとか。その訓練も兼ねて英語でメール書いたり、プラグインのREADME書いたりしてみてます。\n最後は、毎年恒例ですが、読書と英語です。 Packtのキャンペーンで買ってしまった英語の本とか貯まっているので、読まないと。 nasneが便利で通勤時間にドラマ見てるからなぁ。ま、必要なときにボチボチと読んでいく予定です。\n最後は、いつものようにですが、来年も勉強会やいろんなイベントに参加する予定です。 ブログも週1程度で書く努力しないとなぁ。 こんな話を書いてくださいとかのリクエストもお待ちしています。\n今年もまだ、大晦日が残っていますが、色々とお世話になりました。 この場を借りてお礼申し上げます。\n来年も、いろんな方に絡んでいくとは思いますが、よろしくお願いいたします。\n","date":1388406000,"dir":"post/2013/","id":"10c715f70de25ccb493bbbb532b78ced","lang":"ja","lastmod":1388406000,"permalink":"https://blog.johtani.info/blog/2013/12/30/looking-back-2013/","publishdate":"2013-12-30T21:20:00+09:00","summary":"昨年は、大晦日に書いてました。 ちょっと進歩したかも。 振り返り(2012年に書いた抱負から) ということで、まずは昨年書いた抱負からの振り返りで","tags":["振り返り"],"title":"今年の振り返りと来年の抱負(2013)"},{"contents":"昨夜、Elasticsearchの0.90.8がリリースされました。\nリリースされた内容などについては、本家のブログ「0.90.8 released」をご覧いただくこととして。 1点注意したほうが良い点があります。\nelasticsearch-analysis-kuromojiを利用している場合は、0.90.8に対応したバージョンがリリースされるのを待つ必要があります。\nelasticsearch 0.90.8はLuceneのバージョンが4.6.0に変更されています。 Lucene 4.6.0では、TokenStreamというTokenizerのI/Fに変更があり、Tokenizerの実装を変更する必要があります。\n現時点(2013年12月19日現在)のelasticsearch-analysis-kuromojiの1.6.0にはlucene-analyzers-kuromoji-4.5.1.jarが含まれており、この部分でI/Fが異なるためエラーが発生してしまいます。 プラグインをインストールする時点ではエラーは発生せず、実際にKuromojiのTokenizerやAnalyzerを利用するタイミングでエラーが出ます。 以下、0.90.8にanalysis-kuromojiの1.6.0をインストールした状態で_analyzeを実行した時のエラー。\ncurl -XPOST \u0026#39;localhost:9200/_analyze?tokenizer=kuromoji_tokenizer\u0026amp;filters=kuromoji_baseform\u0026amp;pretty\u0026#39; -d \u0026#39;寿司が美味しかった\u0026#39; { \u0026#34;error\u0026#34; : \u0026#34;IllegalStateException[TokenStream contract violation: reset()/close() call missing, reset() called multiple times, or subclass does not call super.reset(). Please see Javadocs of TokenStream class for more information about the correct consuming workflow.]\u0026#34;, \u0026#34;status\u0026#34; : 500 } ということで、1.7.0がリリースされるのを待つか、自分でmvn packageしてビルドする必要があります。 他にも独自でTokenizerなどを造られている方は注意が必要かと。\nたぶん、すぐにリリースされるんじゃないかなぁと。\n2013/12/20追記\nとりあえず、masterブランチが0.90.8に変更されたみたいです。(と書いてるそばから、1.7.0がリリースされました) ということで、0.90.8では1.7.0を使うとエラーが出ないです。 (あと、踊り字対応のcharfilterも追加されたみたいです)\n","date":1387524240,"dir":"post/2013/","id":"c18b12fff24dc87e7f1039bd17c0c6aa","lang":"ja","lastmod":1387524240,"permalink":"https://blog.johtani.info/blog/2013/12/20/release-elasticsearch-0-90-8/","publishdate":"2013-12-20T16:24:00+09:00","summary":"昨夜、Elasticsearchの0.90.8がリリースされました。 リリースされた内容などについては、本家のブログ「0.90.8 releas","tags":["elasticsearch","kuromoji"],"title":"Elasticsearch 0.90.8がリリースされました&注意点(2013/12/20追記)"},{"contents":"Solr本が出てから、質問を受けてブログ書くと言いながら書いてなかったことを思い出しました。。。\nプラグインの配置方法についてこんな質問を受けてたので、それっぽいエントリを書いておきます。(想像と違ってたらツッコミ入れてください)\n@johtani 追加でプラグインの配置方法とかあると便利かなと思いました\n\u0026mdash; Tsubosaka (@tsubosaka) 2013, 12月 2 改定前のSolr本では、日本語の形態素解析器をjarファイルとして追加する方法が書かれていました。 ただ、改定後のSolr本では、KuromojiがLuceneで実装されているためサンプルとしてjarファイルを追加するような方法の記載が明確にはありません。\n19ページのcollection1の説明ですこしだけ、libディレクトリについて触れています。\n独自のTokenizer(lucene-gosenなど)はjar形式でSolrに追加し、schema.xmlなどに利用するFactoryを指定してから利用します。\nこのとき、追加のjarファイルを配置する先がlibディレクトリです。\nlibディレクトリは2つの種類のスコープのディレクトリが存在します。\nSolr全体で利用可能なlibディレクトリ コア単位で利用可能なlibディレクトリ Solr全体で利用するlibディレクトリ これは、起動しているSolrにある全てのコアで利用するようなjarファイルを配置するディレクトリになります。 場所は$SOLR_HOME/libです。ここにjarファイルを配置することで、この$SOLR_HOMEを利用するすべてのコアで同じjarファイルを利用することができるようになります。\nですので、例えば、lucene-gosenはすべてのコアで利用するという場合にはここに配置すれば、1つのjarファイルを配置するだけで済むことになります。\nコア単位で利用するlibディレクトリ これは、コアごとにlibディレクトリを用意する場合です。 19ページにも記載されていますが、$SOLR_HOME/コアディレクトリ名/libとなります。\n特定のコアのみで利用するライブラリについてはこちらに配置する形になります。 他のコアで利用してほしくないjarファイルなどを配置するのに利用すればよいかと。\n簡単ですが、補足記事でした。 UIMAやlangidの利用方法などもあるとうれしですかね? そのうち気が向けば書くかもしれません。(他の人に書いてもらうのもありかも。)\n","date":1387447740,"dir":"post/2013/","id":"cb5b6f7ab4d36e90d2619cb907ebb956","lang":"ja","lastmod":1387447740,"permalink":"https://blog.johtani.info/blog/2013/12/19/add-jar-file-to-solr/","publishdate":"2013-12-19T19:09:00+09:00","summary":"Solr本が出てから、質問を受けてブログ書くと言いながら書いてなかったことを思い出しました。。。 プラグインの配置方法についてこんな質問を受け","tags":["Solr"],"title":"Solrへのプラグインの配置方法について"},{"contents":"ども。 プラグインのインストールに長いURL入れるの辛いですよね?ね?\nということで、MavenでリリースしてMaven Repositoryからダウンロードできるようにしてみました。\n流れとしては\nSonatypeにリリースできるように申請する Sonatypeにリリースする SonatypeからMavenにSyncしてもらう という流れです。\nSonatypeにリリースするための方法はイケメンの人(@yusuke)がブログに簡単ですが残してくれてました。 あと、こちらの@vvakameさんのブログも参考にしながら作業しました。\n【最新版】Maven Central Repository へのライブラリ登録方法 #maven JsonPullParser が Maven Central Repository に入るようです pom.xmlについては、プラグインのpom.xmlを参考にしてもらえればと。 1.の作業が終わったら、リリースを実行します。\nこの時、\u0026lt;scm\u0026gt;タグにgithubの情報が記載されているため(?)、githubにタグを打つ作業もmavenコマンドがやってくれるみたいです。\nmvn release:prepare を実行すると、リリースするバージョンやタグ名などを聞いてくれます。 それらに答えると、pom.xmlにバージョンを指定してcommit\u0026amp;pushしてくれ、タグも打ってくれます。(なんて便利)\nその後、release:performにてSonatypeへのリリースが完了します。 あとは、Sonatypeの画面で作業したら、Mavenのリポジトリにそのうち同期してくれます。\nということで、次のコマンドを実行すればプラグインがインストールできるようになりました。0.6.0と0.7.0の違いは実装には差異はありません。リリース方法が変更されただけということになります。\nbin/plugin -i info.johtani/elasticsearch-extended-analyze/0.7.0 これで少しは活用してもらえるようになるかなぁ? (どのくらいの人が使ってくれてるのかは不明。。。)\n","date":1387249860,"dir":"post/2013/","id":"a0a00c23556fcc5dbfb7b7f43fbbb61d","lang":"ja","lastmod":1387249860,"permalink":"https://blog.johtani.info/blog/2013/12/17/release-es-extended-analyze-plugin-to-maven-and-sonatype/","publishdate":"2013-12-17T12:11:00+09:00","summary":"ども。 プラグインのインストールに長いURL入れるの辛いですよね?ね? ということで、MavenでリリースしてMaven Repositoryから","tags":["elasticsearch"],"title":"elasticsearch-extended-analyzeプラグインをMavenとSonatypeにリリース"},{"contents":"少し遅くなってしまいましたが、12/05に電子書籍も発売されました。\n技術評論社の電子書籍サイトから購入可能です。\n書籍のページへのリンク PDF版となっております。 購入の際は、技術評論社の電子書籍サイトに会員登録後購入可能となります。\n個人的には電子書籍が便利なので、こちらを普段活用しようと思っています。\nもちろん、紙の書籍も発売中です!購入の際は右の書影をクリックしていただければと!\n","date":1386554880,"dir":"post/2013/","id":"d9560caeb797b302191f667b4264da40","lang":"ja","lastmod":1386554880,"permalink":"https://blog.johtani.info/blog/2013/12/09/release-introduction-solr-ebook/","publishdate":"2013-12-09T11:08:00+09:00","summary":"少し遅くなってしまいましたが、12/05に電子書籍も発売されました。 技術評論社の電子書籍サイトから購入可能です。 書籍のページへのリンク PDF","tags":["Solr"],"title":"改訂版Solr入門のPDF版も発売"},{"contents":"勉強会で宣伝もしましたが、改めて。\nSolr入門の改訂版を執筆しました。 考えてみれば、もう3年も前なんですね、Solr入門は。 Solr勉強会などでも何度も新しいのは出ないのですか?と聞かれていましたが、やっと出ました。(お待たせしました。)\n時が立つのは早いものです。前回のSolr入門はバージョン1.4にて執筆していましたが、今回は4.4をベースにし、4.5.1への対応を行っています。\n月曜日には手元に見本が届き、今週金曜日に発売予定です!\nSolrCloud、SoftCommit、Spatial、Joinなど、多彩な機能についても記載してあります。 また、ManifoldCFというSolrにデータを登録するのに 利用できるコネクタフレームワークについても書いてあります。\nより多彩になったSolrの機能を活用するための一助となれればと思います。 (電子版も出る予定です。詳細についてはもう少々お待ちください)\nまた、出版を記念して少し時期が先になりますが、Solr勉強会を開催しようと思います。\n日時:2014年01月29日 第13回Solr勉強会 #SolrJP 新Solr本出版記念 今回はせっかくのSolr入門の書籍の出版記念ということで入門的な話をしてもらう予定です。 Solr初心者の方、Solrに興味のある方などに来ていただきたいと思っています。 (プレゼントも用意できるかも!?)\nということで、「改訂版Apache Solr入門」をよろしくお願いします。 (もちろん、購入は下のリンクからですよね!)\n","date":1385436420,"dir":"post/2013/","id":"a2012a3c9cdb1d6fd69afdbadc1e76b6","lang":"ja","lastmod":1385436420,"permalink":"https://blog.johtani.info/blog/2013/11/26/introduction-to-solr-new-edition/","publishdate":"2013-11-26T12:27:00+09:00","summary":"勉強会で宣伝もしましたが、改めて。 Solr入門の改訂版を執筆しました。 考えてみれば、もう3年も前なんですね、Solr入門は。 Solr勉強会な","tags":["Solr"],"title":"改訂版Solr入門を執筆しました"},{"contents":"どーも。以前の記事で開発中としていたプラグインですが、とりあえず、pluginコマンドでインストール出来る形にしてみました。\nインストールなどについては、READMEに記載したのでそちらを参照してもらうことにして、試行錯誤した話をメモとして残しておきます。\nプラグインの開発はしいてたのですが、やっぱりpluginコマンドでインストール出来ないと使ってもらえないよなということで、勉強会も終わったのでちょっと調べてました。\nプラグインコマンド コマンドが用意されてますが、実態はJavaで実装されてて、通常はこんなかんじでプラグインをインストールします。\n./bin/plugin -i elasticsearch/elasticsearch-analysis-kuromoji/1.6.0 この「elasticsearch/elasticsearch-analysis-kuromoji/1.6.0」という文字列ですが、「ユーザ名/リポジトリ名/バージョン」という意味になります。\nで、ダウンロードするURLは以下のものの中から選ばれます。\nelasticsearch.orgのダウンロード用サイト search.maven.org oss.sonatype.org Githubのarchive これらのサイトに先ほどのユーザ名、リポジトリ名、バージョンを利用したURLを組み立てて、ダウンロードしてくれるという仕組みになっています。\nelasticsearch.orgについては、本家の人しかアップロードできないと思うので、なし。\nmaven、sonatypeについては、Mavenのリポジトリにリリースする必要があるんじゃないかなと。 で、昔調べてググって途中で挫折したんですが、挫折してます。手順が結構手間で。。。 (参考記事:【最新版】Maven Central Repository へのライブラリ登録方法 #maven)\nということで、Githubにアップしたらなんとかなるんじゃん?ということで色々と調査して試してみました。(結果はイマイチなんですが。。。)\nその1:mvn release:prepare せっかくGithubだし、せっかくMavenなんだしなんか、pom.xmlに便利な設定したらコマンド一発でリリースできるんじゃない?という甘い気持ちで調査したググったらそれっぽい記事が見つかりました。 「MavenとGitHubの連携」って記事です。\nで、pom.xmlの設定にも他のプラグインを真似してコピペしたものに\u0026lt;scm\u0026gt;ってタグがあったなぁと。このコマンドでついでにGithubにアップロードできるんじゃないの?ということで、試してみました。\nmvn release:prepare このコマンドを叩くと、記事にあるとおりにいくつか質問をされます。 タグについては、プロジェクト名-バージョン番号という文字列がデフォルトだと指定されているので、v0.5と変更して実施してみると、Githubのreleaseにv0.5ってのができてるじゃないですか。\n※pluginコマンドはGithubを見に行く時に次のファイルをダウンロードしに行きます。\nhttps://github.com/ユーザ名/リポジトリ名/archive/vバージョン名.zip やった!と思い、早速pluginコマンドを実行してみましたが、エラーが出ました。。。\nTrying https://github.com/johtani/elasticsearch-extended-analyze/archive/v0.5.zip... Downloading ...DONE Installed johtani/elasticsearch-extended-analyze/0.5 into /Users/johtani/projects/tmp/ess_env/second_node/elasticsearch-0.90.7/plugins/extended-analyze Usage: -u, --url [plugin location] : Set exact URL to download the plugin from ...省略... Message: Error while installing plugin, reason: IllegalArgumentException: Plugin installation assumed to be site plugin, but contains source code, aborting installation. あらら、なんで?と。\nで、実際にgithubにアップされてたzipファイルをダウンロードしてみたら、githubのリポジトリにあるディレクトリ構成がそのまま入ってるじゃないですか。。。 そうですか、そうですよね。prepareだし、タグ打ってzipにかためてくれるだけなんですねと。。。\nおそらく、siteプラグインだけの場合はこの方法でpluginコマンド叩けばOKなんでしょうが、私がダウンロードしてもらいたいのは.jarファイルが入ったzipファイルなんです。\nということで、断念しました。(タグ消したりをgitコマンドで叩いて綺麗にし直すとか虚しい作業をしてました)\nその2:github.comのWebでリリース おとなしく、Sonatypeのサイトにアップロードする方向でがんばればいいんですが、とりあえず使えるようにするのが先だと思い、 github.comのページでアップロードしてしまおうと。\n「release」というタブをクリックすると、画面からアップロードできるようになります。\nzipファイルを作ってアップロードしました。(zipファイル自体はmvn packageコマンドを実行したらtarget/releaseというディレクトリに作成されてる)\nこれで行けるだろということで、またpluginコマンドを実行すると\nTrying https://github.com/johtani/elasticsearch-extended-analyze/archive/v0.5.zip... Downloading ...DONE Installed johtani/elasticsearch-extended-analyze/0.5 into /Users/johtani/projects/tmp/ess_env/second_node/elasticsearch-0.90.7/plugins/extended-analyze Usage: -u, --url [plugin location] : Set exact URL to download the plugin from ...省略... Message: Error while installing plugin, reason: IllegalArgumentException: Plugin installation assumed to be site plugin, but contains source code, aborting installation. あれ?同じエラー?なんで?jar入りのzipファイルアップロードしたのに???\nと。で、https://github.com/johtani/elasticsearch-extended-analyze/releasesにreleaseのページができてたので見てみると、あら。 アップロードしたファイルについては次のようなURLになってるじゃないですか。\nhttps://github.com/johtani/elasticsearch-extended-analyze/releases/download/v0.5/v0.5.zip で、よく見ると「Source code(zip)」というボタンもあるぞ?このリンクは?\nhttps://github.com/johtani/elasticsearch-extended-analyze/archive/v0.5.zip 。。。あぁ。そうですか。そういうことですか。理解してない私が悪いんですねと。\n結論? ということで、とりあえず、releaseにjar入りファイルはアップロードできた(手動で)ので -uオプションで直接URL指定すればインストールできるだろ!と諦めました。 いい勉強になりました。。。\nREADME見ていただくとインストール方法が分かりますが、長いです。。。\n時間をとって本腰入れてSonatypeにMavenコマンドでアップロードできるようにしようかな。。。\n","date":1384419300,"dir":"post/2013/","id":"13684d16fdd07d5f0584e29265a270e7","lang":"ja","lastmod":1384419300,"permalink":"https://blog.johtani.info/blog/2013/11/14/release-elasticsearch-extended-analyze-0-dot-5/","publishdate":"2013-11-14T17:55:00+09:00","summary":"どーも。以前の記事で開発中としていたプラグインですが、とりあえず、pluginコマンドでインストール出来る形にしてみました。 インストールなど","tags":["elasticsearch","plugin"],"title":"elasticsearch-extended-analyzeを公開?"},{"contents":"第2回を開催しました! すごい、140人くらいくらいの参加登録者(参加者は100人ちょっと!)がいて、びっくりです。 ステキな会場を提供していただいた、リクルートテクノロジーズさん、運営していただいた方々、スピーカーの皆さん、参加者の皆さん本当にありがとうございました。 今回も素敵な看板ありがとうございます。\n今回もしっかり楽しめたので、次回も頑張ります!\n今回は、elasticsearch-jpMLの紹介とかをできたのでよかったかなぁと。 ぜひ、活用してください!どんな質問でもいいので。\nあと、スライドに入ってた例の本もよろしくです。\nということで、懇親会も盛り上がったし楽しかったです。 今後も場の提供+自分の勉強のトリガーとして、開催していくので、ご協力お願いします! 聞きたい話など、MLや@ツイートしていただければと。\nelasticsearchのRouting機能:株式会社シーマーク 大谷 純 (@johtani) スライド:Routing機能※スライドはPDFです。\nド緊張で、大した発表ではなかったですが。。。 どちらかと言うとSolr本の紹介だったかもなぁ。スミマセン。\n※スライドが一部文字が消えてるので、作りなおすかも。\nElasticSearchを使ったBaaS基盤の開発(仮):株式会社富士通ソフトウェアテクノロジーズ 滝田聖己さん(@pisatoshi) スライド:https://speakerdeck.com/pisatoshi/elasticsearch-trial-and-error\n本日はお越しいただきありがとうございました!しかも静岡から!今後もよろしくお願い致します。\nEnchantMoonでシステム構成w\n0.17.0から利用されていると。(スゴイ)\nプライマリのデータストア!ただし、登録元データはMySQLにもある。\n階層も深く、大きめのドキュメント。\nレプリカ1、インデックスのバックアップも取ってないと。。。\nルーティングの機能\nDynamicMappingの問題点\nマッピング定義が肥大、型がコンフリクト。。。苦労しっぱなし\nデータ登録は1台にして、1台で一気に登録してから再配置\n実際に運用とかされてるので、いろんなノウハウがまだまだありそう!\nKibana入門:水戸祐介さん(@y_310) スライド:https://speakerdeck.com/y310/kibanaru-men\n(やっぱりru-menになってるw)\n実は、押しかけて話してもらうように説得したのでした。今後もよろしくです。\nCOOKPADの方によるKibanaのお話。 Kibanaの利点とかなんで?とか。 画面構成の説明から ダッシュボードは必ず保存して!リロードしたら悲しい思いをしてしまうので。 sparkline便利そうだなぁ。ほんとに、データサイエンティスト系のツールを目指してるのかな 一通り、ダッシュボードに配置できるパネルの説明してもらえたのですごく参考になりました! Tips周りが役に立ちそう。not_analyzedは重要ですよね。 LT 「データ集計用ダッシュボードブラウザとしても使えるElasticSearch+Kibana v3を利用する際の運用ノウハウ紹介」:株式会社リブセンス Y.Kentaro さん (@yoshi_ken) さん スライド:http://www.slideshare.net/y-ken/elasticsearch-kibnana-fluentd-management-tips\nKibanaの紹介とかFluentdの紹介。 Tips満載すばらしい。 JDBC riverは0.90.6ではうまく動かないので、気をつけてと。 「Fluentd as a Kibana」:@repeatedly さん スライド(gist)?:https://gist.github.com/repeatedly/7427856\nKibanaがfluentdの中で動くと!?\n「Authプラグインでアクセスコントロール」:株式会社エヌツーエスエム 菅谷信介さん (@shinsuke_sugaya) スライド:http://www.slideshare.net/shinsuke/es-auth-plugin\nAPI毎?インデックスごと?にアクセス制御ができるプラグイン\n","date":1384247760,"dir":"post/2013/","id":"66f43ab4b823d67f52735bbbe6ba65b0","lang":"ja","lastmod":1384247760,"permalink":"https://blog.johtani.info/blog/2013/11/12/elasticsearch-japan-user-meetup-no2/","publishdate":"2013-11-12T18:16:00+09:00","summary":"第2回を開催しました! すごい、140人くらいくらいの参加登録者(参加者は100人ちょっと!)がいて、びっくりです。 ステキな会場を提供していた","tags":["elasticsearch","kibana","fluentd","勉強会"],"title":"第2回elasticsearch勉強会を開催しました! #elasticsearchjp"},{"contents":"Cloudera World Tokyo 2013に参加してきました。\n午前中はあいにくの雨でしたが、それでも結構な人数が最初の基調講演から参加されてました。 私が参加したセッションは大盛況な感じでした。\nおみやげとしてカステラも頂いちゃいました!\nまた、色々なセッションに現れたこんなメッセージ画像も見つけました!\n昨日の写真データの整理をしていたら、こんなものが・・・ @shiumachi さんよ・・・ #cwt2013 pic.twitter.com/S0JsxSYXIx\n\u0026mdash; Kenichiro HAMANO (@hamaken) November 8, 2013 やっぱり、スーツの人が多いなという印象。\n名刺を毎回回収されるのはちょっとつらかったです。なにか、いい方法ないですかねぇ。\n以下はいつもの個人メモです。\n「ビッグデータプラットフォームとして進化するHadoop」 Cloudera株式会社 代表取締役 ジュセッペ小林氏 Costcoなどの写真を元にビッグデータを可視化 BigDataとHadoopの関係 検索、SQL、機会学習、数理処理、データ管理などにもHadoopの活用されつつある。 セキュリティ、データ管理、クラスタ上でのツールの実行なども増えてきてる。\n「今日ビッグデータは明日のスモールデータ」\nアーキテクチャとしてのビッグデータ 多種多様なデータを一箇所に集約し、生データを直接活用できる。 OSSとしての責任も。\nデータサイエンス Opsだけでないデータ解析にも活用\n「Clouderaのビッグデータプラットフォーム戦略」(仮) 講師:Cloudera, Inc. CTO Dr.Amr Awadallah レガシーな情報アーキテクチャ→スケールできない、可視化の限界、硬直したスキーマなどなど。\nエンタープライズデータハブとしてのHadoopとか。\nビッグデータの歴史と将来展望 講師:国立情報学研究所 アーキテクチャ科学研究系 教授 佐藤一郎氏 ビッグデータの歴史的経緯とか 最初の事例はアメリカの1880年国勢調査。\n「ビッグデータがコンピュータを生み出した」。コンピュータがビッグデータを生み出したんじゃない。\n少量データにもHadoopを\nバッチ処理のリアルタイム化とか(一晩から10分へ) 原点は検索データのインデクシング\nHadoopを使うのが目的じゃないんだから、構築には手を掛けないのがいいよね。\nプラットフォームと発展している\n分散システム研究者から見たHadoop 分散ししテムの難しさを、処理範囲を限定することで巧みに回避 データの近くで処理 研究レベルではリアルタイム化や逐次処理化が活発 全工程で逐次・リアルタイムが必要とは限らない 聞いてばかりじゃなくて、動かしてみましょう。 データサイエンス:超並列分散処理を活用した新たなビジネス価値の創出 講師:アクセンチュア株式会社 工藤卓哉氏 「日経BPのビッグデータ総覧2013」に記事書いてる。 多様化するデータ(社外のデータも)をどうやってうまく活用していくか。 データが教えてくれたこと→まず、データありき、まずデータためましょう。それから解析とかすればいいのでは?というはなし? 競合他社さんはNGだけど、ブースでデモ?実機?が見れますと。 Hadoopデータプラットフォーム Cloudera株式会社 嶋内 翔氏 まずは宣伝 Cloudera Implaraのフリーブックの日本語版 Hadoop Operationの書籍でるよ プラットフォームを構成するもの Flume Sqoop HBase Hive Impala データ登録してBIアナリストのお仕事にどうやって役立てる? 外部テーブル:Hiveからはテーブルのように見える仕組み。元ファイルは消えない SerDe(さーでぃー):データをHiveレコードに変換する仕組み 生データを少し加工しましょう 圧縮したりファイル結合したりはしときましょう。 Hadoop活用のポイント 富豪的プログラミング。リソースケチるな。 ローカルでできることはローカル。むりにHadoopでやんなくてもいいですよねと。バランス重要 スケジューリング実行などはOozie使うと便利。(日次集計とか) Cloudera Searchで元データにインデックス貼れるぞと。検索しながら分析ができる クラスタ管理とか Cloudera manager便利ですよ ストレージリソースの管理。 声掛け、管理者が容量チェック、Cloudera Managerのレポート 少数精鋭でHadoop使おう=手が回らなくなる。 みんなで使おう=Kerberos認証とか管理をちゃんと考えないと。けど、文化が根付けば強力。Sentry、Cloudera Navigatorとか。 Hadoopシステムの全体構成図。データの流れと各製品のつながり。 We are hiring!ということで、興味のある方は@shiumachiさんにコンタクトをとりましょうとのこと。 SQLで実現するバッチ処理とストリーム処理 LINE株式会社 田籠 聡氏 資料:Batch and Stream processing with SQL\nLINEのキャラがちらほら出てきた。\nSQL好きですか?\nログの量とか。2.1TB/Day\nバッチ処理とストリーム\n速い集計のためにHadoopが重要 エラー系のログとかはストリームで処理したい\nアーキテクチャ説明\nデータ解析する人って色々。\n管理者 プログラマ サービスディレクタ 経営陣 みんなが集計用処理を理解、編集ができるほうがいい。\n顔あげたらHiveアイコンだらけだったw\nShibとか。\nなんでHiveに限るの?\nHiveに着目したバージョンアップだけを考えれば良くなる。 スケジュールクエリが増えてきて、つらい。\nTimeWindowを固定して集計処理をすることで、回避できる。 Norikra!! スキーマレス\nOSS。Esperベース。\nインストールが楽\nクエリの動作のお話。\nhttp://norikra.github.io\nWe Are Hiring!\nHadoop コミュニティと YARN の現状 日本電信電話株式会社 小沢 健史氏 なんでHadoop? PostgreSQLでやってたけど、大きなデータにはHadoopを使おうという感じになってきた。 なんで使い分けるの? スキーマ後付け NTTDocomoのモバイル位置情報の統計処理とか? 技術的な話をするので、HiveTに着替えます!w YARNのなにが嬉しいの? ImpalaとMapReduceが同時に動くような環境の時に、リソースをうまく管理できないのがV1 そこでYARN Apache Mesosとだいたい一緒。 Apache MesosとYARNの比較 ","date":1383786660,"dir":"post/2013/","id":"a106d7c1b1b277538367f9c8140e3a75","lang":"ja","lastmod":1383786660,"permalink":"https://blog.johtani.info/blog/2013/11/07/cloudera-world-tokyo-2013/","publishdate":"2013-11-07T10:11:00+09:00","summary":"Cloudera World Tokyo 2013に参加してきました。 午前中はあいにくの雨でしたが、それでも結構な人数が最初の基調講演から参加されてました。 私が参加したセッショ","tags":["Cloudera","Hadoop","Norikra"],"title":"Cloudera World Tokyo 2013に参加しました! #cwt2013 "},{"contents":"またまた、Riak Meetup Tokyo #3に参加してきました。Riak2.0のYokozunaの話があると聞いたので。\nということで、いつものように個人メモです。\n今日は自重して、懇親会はアルコールなしにしました。思いがけずfluentd+elasticsearch+kibanaという組み合わせの話も聞けて大満足です。 Yokozunaのデモが見れなかったのがちょっと残念だったかなぁ。\n少しだけSolr本の宣伝もしてきちゃいました。\n古城さん@Mixi 「RiakCSとmixi プライベートクラウド環境」 プライベートクラウドとは? 計算リソースが安い(ストレージは微妙) 開発者が好きに使える環境+運用側のチケットに追われる毎日からの開放 Riak CSの概要 S3互換の分散ファイルストレージ 検証とか 検証時はRiak CS 1.3\n5ノードで2Mファイルを40万個\n削除は遅延で削除される\nPUT性能とか。\nRiak CSの死活監視にはRiakのstatsとか\n障害対応とか\nクラスタ クラスタは3つ。ログ、サービス(画像) 、バックアップ保存用 ログの収集にfluentd、解析にelasticsearchやkibanaを使っているらしい。 篠原@Basho 「Riak 2.0: 分散データ型、セキュリティ、そしてより容易な運用へ」 riak 2.0 pre5をリリース アプリ向け機能強化、運用の容易性 設計ポリシーとか、1.xとか 運用、高可用性、水平拡張性 Capabilityネゴシエーションとか 2.0の機能強化 バケットタイプ キーの名前空間としてバケットがあったけど、同種のバケットをまとめて管理とかしたくなった。 データ型の導入(CRDT) Setデータ型 セキュリティとか 強い整合性\u0026hellip; 鈴木@Basho 「Yokozuna: Riak 2.0の新しい全文検索機能」 YokozunaやSolrの概要 1ノードにRiakとSolrが1プロセスずつ SolrプロセスはRiakが管理してくれる SolrCloudは使ってません。 Riakのノードに届いたデータをSolrに裏で書き込んでくれる。 検索時にはRiakのノードが分散検索をしてくれる X-Riak-Metaもインデクシングしてくれる。jsonやxmlの各要素をSolrのフィールドとして認識してくれる。 Extractor Solrは4.4で、JVMは1.7をユーザが入れるらしい。\n","date":1383746460,"dir":"post/2013/","id":"9dca844d353efed03fbaddfc0fab7c76","lang":"ja","lastmod":1383746460,"permalink":"https://blog.johtani.info/blog/2013/11/06/riak-meetup-tokyo-no3/","publishdate":"2013-11-06T23:01:00+09:00","summary":"またまた、Riak Meetup Tokyo #3に参加してきました。Riak2.0のYokozunaの話があると聞いたので。 ということで、いつものように個人メモで","tags":["Riak","Yokozuna"],"title":"Riak Meetup #3 #riakjp に参加しました。"},{"contents":"開発中ですと書きました、elasticsearch-extended-analyzeですが、改良しました。\n改良と変更は以下のとおりです。\nソースのパッケージをorg.elasticsearchからinfo.johtaniに。MLで気になったので質問したら、変えたほうがいいよとのこと。ダウンロード化については、もう少々お待ちを。 出力形式を変更。可能な限りCharFilter、Tokenizer、TokenFilterそれぞれが出力する内容を返すようにしました。 ただし、既存のAnalyzer(JapaneseAnalyzerクラスとか)に関しては、現時点では出力しません。CharFilterなどを取得するI/Fが見えないためです。(改良できるかの調査は未着手) 現時点でできてないのは以下の項目\npluginコマンドでインストール 出力したいAttributeの指定 TokenizeChainで変更されたTokenの追跡(現状はどのTokenがStopFilterで消されたかなどが不明) 画面の用意(簡単に確認できる画面) ということで、README.mdに出力サンプルは貼り付けてるので、興味のある方は試してみてください。 不明点などあれば、コメントかIssueかツイートでも。\n","date":1383570720,"dir":"post/2013/","id":"b5c628b0c1dbf857a475c4be5de4690d","lang":"ja","lastmod":1383570720,"permalink":"https://blog.johtani.info/blog/2013/11/04/improve-output-extended-analyze/","publishdate":"2013-11-04T22:12:00+09:00","summary":"開発中ですと書きました、elasticsearch-extended-analyzeですが、改良しました。 改良と変更は以下のとおりです。 ソー","tags":["elasticsearch","plugin"],"title":"elasticsearch-extended-analyzeの改良"},{"contents":"お久しぶりです。 気づいたらまた、結構ブログを書いてなかったです。。。\n今回は、今開発しているElasticsearchのプラグインに関するお話です。\nいやぁ、名前決めるの難しいですね。これで英語的に合ってるか不安ですが、elasticsearch-extended-analyzeというプラグインを作っています。\nどんなもの? Solrの管理画面のanalysisに相当する機能が欲しくて作り始めました。\nElasticsearchにはanalyze APIというAPI(名前あってるのかなぁ?)が存在します。\nこれは、文字列を投げると、指定したアナライザやトークナイザでどのようなトークンに分割されるかを調べることができるAPIです。\n例えば、elasticsearch-analysis-kuromojiをインストールしたElasticsearchに対して、以下のcurlコマンドを実行します。\ncurl -XPOST \u0026#39;localhost:9200/_analyze?tokenizer=kuromoji_tokenizer\u0026amp;filters=kuromoji_baseform\u0026amp;pretty\u0026#39; -d \u0026#39;寿司が美味しい\u0026#39; すると、トークナイズされた結果が次のようなJSONで返ってきます。\n{ \u0026#34;tokens\u0026#34; : [ { \u0026#34;token\u0026#34; : \u0026#34;寿司\u0026#34;, \u0026#34;start_offset\u0026#34; : 0, \u0026#34;end_offset\u0026#34; : 2, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 1 }, { \u0026#34;token\u0026#34; : \u0026#34;が\u0026#34;, \u0026#34;start_offset\u0026#34; : 2, \u0026#34;end_offset\u0026#34; : 3, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 2 }, { \u0026#34;token\u0026#34; : \u0026#34;美味しい\u0026#34;, \u0026#34;start_offset\u0026#34; : 3, \u0026#34;end_offset\u0026#34; : 7, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 3 } ] } トークナイズの結果がわかるのは嬉しいのですが、どんな品詞なのかといったKuromoji固有のTokenの属性情報がなくなってしまいます。\nSolrでは、こんな画面が用意されていて、品詞情報とかが出力されます。あとは、各TokenFilterでどのトークンがなくなっているかなどもわかるようになっています。\nこれって結構役立つと思うんですよ。 ということで、Pluginも作ってみたかったので、いい機会だから作ってみようかと。\n出力サンプル まずは、その他のAttribute(品詞とか)を表示するところを実装してみました。\ncurl -XPOST \u0026#39;localhost:9200/_extended_analyze?tokenizer=kuromoji_tokenizer\u0026amp;filters=kuromoji_baseform\u0026amp;pretty\u0026#39; -d \u0026#39;寿司が美味しい\u0026#39; 先ほどとほぼ一緒のcurlコマンドを実行します。違う点は**「_analyze」が「_extended_analyze」**となっている点です。\nで、実行結果はこんな感じです。(長いですがそのまま載せてます。続きの文章がしたにあります。)\n{ \u0026#34;tokens\u0026#34; : [ { \u0026#34;token\u0026#34; : \u0026#34;寿司\u0026#34;, \u0026#34;start_offset\u0026#34; : 0, \u0026#34;end_offset\u0026#34; : 2, \u0026#34;type\u0026#34; : \u0026#34;word\u0026#34;, \u0026#34;position\u0026#34; : 1, \u0026#34;extended_attr