Java 開発 2.0: ElasticSearch によるスケーラブルな検索

Java エンタープライズ・アプリケーションのための分散検索

検索機能は、最近のアプリケーションにはなくてはならないものになっています。ElasticSearch は、難解な黒魔術をマスターすることなく、すぐに検索アルゴリズムを利用できるタイプの検索プラットフォームに分類されます。けれども大半の検索プラットフォームとは異なり、ElasticSearch は分散型となるように作られています。連載「Java 開発 2.0」の今回の記事では、セットアップから Snowball アルゴリズムまでを 1 時間足らずで学べる、手軽で楽しいチュートリアルに沿って ElasticSearch を紹介します。

Andrew Glover, Author and developer, App47

Andrew GloverAndrew Glover は、ビヘイビア駆動開発、継続的インテグレーション、アジャイル・ソフトウェア開発に情熱を持つ開発者であるとともに、著者、講演者、起業家でもあります。また、easyb BDD (Behavior-Driven Development) フレームワークの創始者、そして『継続的インテグレーション入門 開発プロセスを自動化する47の作法』、『Groovy in Action』、『Java Testing Patterns』の 3 冊の本の共著者でもあります。詳細は彼のブログにアクセスするか、Twitter で彼をフォローしてください。



2013年 1月 10日

私が高校生だった頃、英語で「グーゴゥ」と発音する単語は、非常に大きな数を意味する googol という名詞しかありませんでした。現在「グーゴゥ」と発音すると、それはオンラインでブラウズや検索をするのと同義の google という動詞であったり、Google という名前の企業を指していたりします。ほとんどどんな質問に対しても、その答えを得る方法として「Google 先生」を思い浮かべて「ググってみなよ!」と答えるのは一般的なことです。要するに、アプリケーション・ユーザーは、アプリケーションに保管されているデータ (ファイル、ログ、記事、画像など) を検索できることを期待しているわけです。これにより、ソフトウェア開発者にとっては、睡眠時間を削りすぎることも、お金をかけすぎることもなく、迅速かつ簡単に検索機能を有効にすることが課題となります。

この連載について

Java 技術が初めて登場してから現在に至るまでに、Java 開発の様相は劇的に変化しました。成熟したオープンソースのフレームワーク、そしてサービスとして提供される信頼性の高いデプロイメント・インフラストラクチャーを利用できる (借りられる) おかげで、今では Java アプリケーションを短時間かつ低コストでアセンブルし、テスト、実行、保守することが可能になっています。この連載では Andrew Glover が、この新たな Java 開発パラダイムを可能にする多種多様な技術とツールを詳しく探ります。

ユーザーのクエリーは次第に複雑で個人的なものになってきていますが、クエリーに対して適切な応答を提供するために必要なデータのほとんどは、元来構造化されていません。かつては SQL の LIKE 節で十分用が足りていたとしても、最近のクエリーには高度なアルゴリズムが必要になることがあります。幸い、プラガブル検索技術の必要性に応えるプラットフォームは、Lucene、Sphinx、Solr、Amazon CloudSearch、Xapian をはじめとし、オープンソースのものでも商用のものでも多数存在します。そのうち、連載「Java 開発 2.0」の今回の記事ではオープンソース検索プラットフォームの分野に比較的最近加わった ElasticSearch を紹介します。

記事ではまず、ElasticSearch をインストールして構成する方法を簡単に説明した後、検索インフラストラクチャーを定義する方法、検索可能なコンテンツを追加する方法、そして追加したコンテンツを検索する方法を順に説明します。記事に記載するサンプル・コードは、既存のアプリケーション (USA Today の Music Reviews フィードおよび API) をベースにしていますが、皆さんが構築するアプリケーションでも問題なく機能するはずです。この記事では、ElasticSearch と併せて、いくつかのオープンソース・ツールを使用します。そのうちの 1 つは、プラットフォームによらずに使えるコマンドライン・ツールとして、HTTP の URL を操作するためのツールである cURL です。もう 1 つは、ElasticSearch 用に作成された Java ライブラリーである Jest です。記事では Jest を使用して、サンプル・データの取得、保管、操作を行います。

ElasticSearch による分散検索

ElasticSearch は数あるオープンソース検索プラットフォームのうちの 1 つで、そのサービスとして、データベースと Web フロント・エンドを備えたアプリケーションにコンポーネント (検索可能リポジトリー) を追加します。ElasticSearch によって、検索アルゴリズムと関連インフラストラクチャーをアプリケーションに追加すれば、開発者はアプリケーション・データを ElasticSearch データストアにアップロードし、RESTful な URL を介してそのデータを操作するだけで済みます。データの操作は直接行うことも、cURL や Jest などのライブラリーを使用して間接的に行うこともできます。

ElasticSearch はダウンロード可能なアプリケーションです。一部のクラウド・ベースのプラットフォームでは、ElasticSearch をサービスとして提供し始めています。この記事では ElasticSearch を組み込みツールとして使用します。

ElasticSearch のアーキテクチャーは、これまでの検索プラットフォームとは明らかに異なります。その違いは、水平スケーリングを明確に念頭に置いて作成されている点です。他の大半の検索プラットフォームとは異なり、ElasticSearch は分散型となるように設計されています。この特徴は、クラウドやビッグ・データ技術の台頭に見事に適合します。ElasticSearch は安定したオープンソース検索エンジンである Lucene をベースに構築されていて、スキーマレスな JSON ドキュメント・データストアと同じように機能します。その唯一の目的は、テキスト・ベースの検索を可能にすることです。

ElasticSearch をアプリケーションにインストールして統合するのは簡単です。ユーザーは RESTful な API を使用して、任意の言語で ElasticSearch とやりとりすることができます。ElasticSearch には、活発に成長を続けるオープンソース・コミュニティーによって作成された多数の言語アダプターも付随しています。

賢人に尋ねてください

「パリの去年の今頃の気温は?」、「2008年の米国大統領選挙で投票した人の数は?」、「つま先の水ぶくれはつぶしたほうが良いのか?」などといった質問を、毎日世界中で何百万人ものユーザーが Web ブラウザーから投稿しています。そのため私たちは、事実に基づく情報を手元に (または、頭の中や本で) 揃えておく必要性をあまり感じることがない上に、遥かに広範かつ多彩な情報にアクセスできるのです (事実、正真正銘の膨大 (googol) な情報にアクセスできます)。このような社会の転換によって、私たちのアプリケーションおよび関連する検索技術には当然新しい要求が突きつけられます。

ElasticSearch をインストールして構成する

ElasticSearch は Lucene をベースに作成されているため、ElasticSearch に含まれるのは、詰まるところすべて Java コードです。ElasticSearch を使い始める上で必要な作業は、ElasticSearch の最新リリースをダウンロードして解凍し、ターゲット・プラットフォームの起動スクリプトを呼び出すことで、ElasticSearch を起動することだけです。ElasticSearch にはさまざまな構成が用意されていますが、この記事ではデフォルトで提供されている構成だけを使用します。このサンプル・アプリーションでは、ノードが互いをオート・ディスカバリーしてクラスターを作成する機能 (ちなみにこれは画期的な機能です) を有効にせずに、ドキュメントのデータベースとして機能する単一のノードを基本とします。


検索で自分の好みを探す

前述したように、ユーザーは、アプリケーションが保管し、操作するほぼあらゆる種類のデータを検索できることを期待します。したがって、この実際の例で最初に必要となるのは、何らかのデータです。つまらないサンプルにならないように、この記事では USA Today サイトの API から無料で入手できるデータを使用することにします。これから、USA Today の Music Reviews からミュージック・レビューのフィードを取得して、それを ElasticSearch にアップロードします。このプロセスは、一般に「インデクシング (索引付け)」として知られています。

現在、USA Today のミュージック・レビューは、特定のジャンルまたはアーティスト別のカテゴリーに分類されていますが、連想検索を行いたい場合、つまり、自分の好みのアーティストと似たようなアーティストについての好意的なレビューを検索したい場合には、このカテゴリー分けへの対処が課題となります。ここでは一例として Buddy Guy と似たようなサウンドのブルース・アーティストを検索する場合を取り上げます。

この記事の手順に従って USA Today からデータを取得するには、サイトに登録して無料の開発者キーを受け取る必要があります。登録が完了すると、RESTful な URL を使用して API にアクセスできるようになります。リスト 1 に、ミュージック・レビューを 1 件取得する場合の呼び出し例を記載します (皆さんのコードでは、ご自分の開発者キーを使用してください)。

リスト 1. USA Today のミュージック・レビュー・サービスに対する API 呼び出し
curl-XGET 'http://api.usatoday.com/open/reviews/music/recent?count=1&api_key=your_key'

リスト 2 に、上記の呼び出しに対する JSON レスポンスの例を記載します。

リスト 2. サービスからのレスポンス
{"APIParameters":
 {"Count":"1","MinimumRating":"","MaximumRating":"","Artist":"",
   "ArtistSearch":true,"Album":"",
   "AlbumSearch":true,"Year":""},
  "Found":1,"Albums":null,"Artists":null,
  "MusicReviews":[
      {"AlbumName":"Away From the World",
       "ArtistName":"Dave Matthews Band",
       "ReleaseDate":"",
       "Rating":"3",
       "DownloadSongs":"Mercy, Snow Outside, Drunken Soldier",
       "ConsiderSongs":"",
       "Reviewer":"Brian Mansfield",
       "ReviewDate":"9/11/2012 10:11:00 AM",
       "Brief":"...",
       "WebUrl":"..."
       }
  ]
}

この例では自分の好みに合った音楽を検索するので、レビューからは、少なくとも Brief (ミュージック・レビューの核心)、RatingWebUrl の 3 つの要素を取り込む必要があります。これにより、個人によるレビュー、数値による評価、そしてその音楽を自分で試聴してみるための URL を確認することができます。

ElasticSearch のインデックスをセットアップする

ElasticSearch では、RESTful な Web インターフェースを使用して操作を行います。これからコマンドライン・ツール cURL を使用して、このインターフェースにアクセスします。ドキュメントを ElasticSearch に挿入するには、その前にインデックス (索引) を作成しなければなりません。ElasticSearch のインデックスはデータベース・テーブルのようなもので、このインデックスの中に検索可能なドキュメント (この例ではミュージック・レビュー) を格納します。リスト 3 を見ると、cURL を使用すると簡単に ElasticSearch のインデックスを作成できることがわかります (デフォルトで ElasticSearch は指定されたすべてのドキュメントを取り込んで、そのそれぞれに対してインデックスを作成します)。

リスト 3. cURL を使用して ElasticSearch のインデックスを作成する
curl -XPUT 'http://localhost:9200/music_reviews/'

インデックスを作成した後は、ドキュメントの個々の属性に対するマッピングを指定することができます。これらの個々の属性は、自動的に推測されます。例えば、ドキュメントに name:‘test' のような値が含まれている場合、ElasticSearch は name 属性が String であると推測します。あるいは、ドキュメントに属性として score:1 が含まれているとしたら、ElasticSearch は当然のことながら、score が数値であると推測します。

時には、ElasticSearch の推測が誤っている場合もあります。String としてフォーマット設定された日付がその一例です。このような場合には、ElasticSearch に特定の値をマッピングする方法を指示することができます。リスト 4 は、ElasticSearch に対し、ミュージック・レビューの reviewDateString ではなく Date として扱うように指示する例です。

リスト 4. music_reviews インデックスでのマッピング
curl -XPUT 'http://localhost:9200/music_reviews/_mapping' -d 
  '{"review": { "properties": { 
     "reviewDate":
      {"type":"date", "format":"MM/dd/YY HH:mm:ss aaa", "store":"yes"} } } }'

リスト 4 から明らかなように、cURL では簡単に ElasticSearch の RESTful な API を扱うことができます。


データを POJO として取り込む

ここまでの手順で、ElasticSearch のインデックスを定義し、個々の属性をマッピングしました。次は、ミュージック・レビューを挿入します。この作業には、Jest と呼ばれる Java API を使用します。Jest は Java オブジェクトのシリアライズを極めて巧みに行います。Jest を使用することで、通常の Java オブジェクトを取得し、そのインデックスを ElasticSearch に作成することが可能になります。検索結果は、ElasticSearch の検索 API を使用して再び Java オブジェクトに変換することができます。また、自動的に POJO をシリアライズする機能は、ElasticSearch が必要とする JSON ドキュメント構造を扱う必要がないという点で重宝する可能性があります。

これからまず、ミュージック・レビューを表す単純な Java オブジェクトを作成し、続いて Jest を使ってこのオブジェクトのインデックスを作成します。最終的には、USA Today の API からミュージック・レビューの JSON 表現を受け取ることになるため、JSON ドキュメントを Java オブジェクトに変換するファクトリー・メソッドのコードを作成します。POJO のステップを完全に省略するのは難しいことではありませんが (これを省略して、USA Today からの JSON に対して直接インデックスを作成することもできます)、この後、検索結果を自動的に POJO に変換する方法を説明するため、ここでは POJO のステップを省略しないことにします。

リスト 5. ミュージック・レビューの結果を表す単純な POJO
import io.searchbox.annotations.JestId;
import net.sf.json.JSONObject;

public class MusicReview {
  private String albumName;
  private String artistName;
  private String rating;
  private String brief;
  private String reviewDate;
  private String url;

  @JestId
  private Long id;

  public static MusicReview fromJSON(JSONObject json) {
   return new MusicReview(
    json.getString("Id"),
    json.getString("AlbumName"),
    json.getString("ArtistName"),
    json.getString("Rating"),
    json.getString("Brief"),
    json.getString("ReviewDate"),
    json.getString("WebUrl"));
  }

  public MusicReview(String id, String albumName, String artistName, String rating, 
    String brief,
   String reviewDate, String url) {
    this.id = Long.valueOf(id);
    this.albumName = albumName;
    this.artistName = artistName;
    this.rating = rating;
    this.brief = brief;
    this.reviewDate = reviewDate;
    this.url = url;
  }

  //...setters and getters omitted

}

ElasticSearch では、インデックスが作成されたドキュメントごとに id が割り当てられることに注意してください。これは、主キーのようなもので、所定のドキュメントを取得するには、常にそのドキュメントの id を使用することができます。したがって Jest API で、@JestId アノテーションを使用して、ElasticSearch のドキュメント id をオブジェクトに関連付けます (リスト 5 を参照)。この例で使用している ID は、USA Today API から提供されたものです。

JestClient

続いて、Jest を使用して USA Today の API を呼び出すことでレビューのコレクションを取得し、これらの JSON ドキュメントを MusicReview オブジェクトに変換した後、ローカルで実行中のElasticSearch アプリケーション内に各オブジェクトのインデックスを作成します。

リスト 6 に記載する Jest の API 呼び出しに示されているように、ElasticSearch はクラスターで機能するように設計されています。この例の場合、接続先のサーバー・ノードは 1 つしかありませんが、接続でサーバー・アドレスのリストを取得できるという点は注目に値します。

リスト 6. Jest で ElasticSearch インスタンスへの接続を作成する
ClientConfig clientConfig = new ClientConfig();
Set<String> servers = new LinkedHashSet<String>();
servers.add("http://localhost:9200");
clientConfig.getServerProperties().put(ClientConstants.SERVER_LIST, servers);

ClientConfig オブジェクトを完全に初期化した後は、リスト 7 に示すような JestClient のインスタンスを作成することができます。

リスト 7. クライアント・オブジェクトを作成する
JestClientFactory factory = new JestClientFactory();
factory.setClientConfig(clientConfig);
JestClient client = factory.getObject();

接続にローカルで実行中の ElasticSearch インスタンスの場所を指定すれば、USA Today サービスから (例えば、300 件の) ミュージック・レビューを取得してインデックスを作成することができます。

リスト 8. ローカル ElasticSearch インスタンスにミュージック・レビューを取り込んでインデックスを作成する
URL url = 
  new URL("http://api.usatoday.com/open/reviews/music/recent?count=300&api_key=_key_");
String jsonTxt = IOUtils.toString(url.openConnection().getInputStream());
JSONObject json = (JSONObject) JSONSerializer.toJSON(jsonTxt);
JSONArray reviews = (JSONArray) json.getJSONArray("MusicReviews");
for (Object jsonReview : reviews) {
  MusicReview review = MusicReview.fromJSON((JSONObject) jsonReview);
  client.execute(new Index.Builder(review).index("music_reviews")
   .type("review").build());
}

リスト 8 の最後の for ループの行に注目してください。このコードは、MusicReview POJO を取り、そのインデックスを ElasticSearch 内に作成します。つまり、タイプを review として指定した music_reviews インデックス内に MusicReview POJO を配置します。これで、ElasticSearch がこのドキュメントを取り、ある種の本格的な魔法をかけることによって、このドキュメントに伴う各種の側面を検索できるようになります。


非構造化データを検索する

ElasticSearch の威力は、非構造化データの検索を可能にするところにあります。非構造化データの一例は、ミュージック・レビューの brief の部分です。ある特定の音楽を言い表すテキスト・パラグラフである brief には、多くのデータが含まれます。ただし、検索に必要となるのは、類似性を示せるキーワードです。つまり、検索エンジンがユーザーの求める結果だけを返せるようにするキーワードの関連付けが必要になります。この例では、私の好みの音楽に基づいて、聴いてみたいと思いそうな音楽を検索しているので、好みの音楽を言い表すために使用されているキーワードと同じキーワードが記述に含まれる音楽を検索します。

例えば、インデクシングされたコレクションの brief 属性で、「jazz」という単語を検索するとします (この検索では大/小文字が区別されることに注意してください)。Jest を使って検索を行うには、いくつかの準備作業が必要となります。まず、QueryBuilder タイプで用語クエリーを作成する必要があります。続いて、その作成したクエリーを、インデックスとタイプを指す Search に追加します。Jest は ElasticSearch からの JSON レスポンスを取り、それを MusicReview のコレクションに変換することにも注意してください。

リスト 9. Jest で検索を実行する
QueryBuilder queryBuilder = QueryBuilders.termQuery("brief", "jazz");
Search search = new Search(queryBuilder);
search.addIndex("music_reviews");
search.addType("review");
JestResult result = client.execute(search);

List<MusicReview> reviewList = result.getSourceAsObjectList(MusicReview.class);
for(MusicReview review: reviewList){
  System.out.println("search result is " + review);
}

Java 開発者にとって、リスト 10 の検索操作はお馴染みのことでしょう。Jest を使用して POJO を操作するのは簡単なプロセスです。その一方、ElasticSearch は完全にRESTful に制御されるため、cURL を使ったとしても、同じ検索を簡単に実行することができます。以下はその一例です。

リスト 10. cURL で検索を実行する
curl -XGET 'http://localhost:9200/music_reviews/_search?pretty=true' -d
 ' {"explain": true, "query" : { "term" : { "brief" : "jazz" } }}'

JSON は読みにくくなりがちなので、検索リクエストには常に pretty=true オプションを渡すようにして構いません。リスト 10 では ElasticSearch に対し、検索の実行方法に適用した実行計画 (explain plan) を返すようにも指定しています。これを指定するために、JSON ドキュメントを渡すときに、"explain":true 句をドキュメントに追加しました。

explain plan とは?

explain plan (実行計画) は単に、ドキュメントを見つけるために ElasticSearch が内部で行った操作を説明するだけに過ぎません。この情報は、クエリーを微調整する場合や、特定のインデックス・オプションを指定する場合に役立ちます。多くの RDBMS でもこの機能を提供しています。

リスト 9 とリスト 10 の検索は、10 件の結果を返しました (結果の件数は、インデックスを作成したドキュメントの数によって異なります)。したがってこの単純な検索では、私が興味を持ちそうなレビューとして、300 件のレビューをわずか 10 件の候補に絞り込んだことになります。ただし、評価の点数は 3.0 から 4.0 の範囲であることに注意してください。これよりも複雑なクエリーにより、試聴してみたい音楽のなかでもさらに評価の高いものに候補を絞り込むことができます。

範囲とフィルターを追加する

リスト 11 でインポートしているのは、複雑なクエリーの作成を多少楽にしてくれる便利な静的メソッドです。突きつめるところ、私がここで行っているのは、brief に jazz という単語が含まれていて、rating の値が 3.5 から 4.0 のドキュメントを検出するクエリーにするという作業です。このようにすることで、前の検索結果を絞り込んで、私のジャズの好みにぴったり合う音楽を見つけられる可能性が高くなります。

リスト 11. Jest で範囲とフィルターを指定して検索する
import static org.elasticsearch.index.query.FilterBuilders.rangeFilter;
import static org.elasticsearch.index.query.QueryBuilders.filteredQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;

//later in the code

QueryBuilder queryBuilder = filteredQuery(termQuery("brief", "jazz"), 
  rangeFilter("rating").from(3.5).to(4.0));

Search search = new Search(queryBuilder);
search.addIndex("music_reviews");
search.addType("review");
JestResult result = client.execute(search);

List<MusicReview> reviewList = result.getSourceAsObjectList(MusicReview.class);
for(MusicReview review: reviewList){
  System.out.println("search result is " + review);
}

上記とまったく同じ検索は、cURL を使用しても実行できることを忘れないでください。

リスト 12. cURL で範囲とフィルターを指定して検索する
curl -XGET 'http://192.168.1.11:9200/music_reviews/_search?pretty=true' -d
  '{"query": { "filtered" : { "filter" : {  "range" : { "rating" : 
     {"from": 3.5, "to":4.0} } },
     "query" : { "term" : { "brief" : "jazz" } } } }}'

この最新版の検索は結果をさらに絞り込み、有望ないくつかのアルバムを試聴候補として残しますが、これよりもさらに限定された結果が得られるようにしたい場合はどうすればよいのでしょう?前に、私がブルース・ギタリストの Buddy Guy のファンであるという話をしました。検索にワイルドカードを追加すると、どのような結果になるのか見てみましょう (リスト 13 を参照)。

リスト 13. ワイルドカードを使用して検索する
import static org.elasticsearch.index.query.QueryBuilders.wildcardQuery;
//later in the code
QueryBuilder queryBuilder = filteredQuery(wildcardQuery("brief", "buddy*"), 
  rangeFilter("rating").from(3.5).to(4.0));
//see listing 12 for the template search and response

リスト 13 で検索しているのは、rating の値が 3.5 から 4.0 の範囲で、brief に buddy という単語が含まれるレビューです。この検索では、Buddy Guy を参照する 1 つか 2 つのレビューが結果として返されます。この場合、これらの結果を試聴すると気に入ることは、ほぼ間違いありません。その一方、buddy という単語が含まれ、無作為に抽出されたドキュメントを受け取る可能性もあります。これが、一般的なワイルドカード検索の欠点です。

けれどもこの例では、ワイルドカードが功を奏しています。検索によって取得した 2 つのドキュメントのレビューは、私のお気に入りのギタリストの影響を受けた、ブルース・スタイルの音楽であることを示しています。一日分の仕事としては、まずまずの結果です。

トークン・アナライザーを扱う

この記事では、ElasticSearch の構成が複雑にならないように、クラスターを構成することも、デフォルトのインデクシング・ストラテジーに手を加えることもしませんでした。ElasticSearch では、記事で説明した機能より遥かに高度な機能を使用することができます。例えば、インデックス・マッピングを定義する際に、特定のフィールドに対するインデクシングの方法を構成することが可能です。さまざまなトークナイザー・ストラテジーにより、必要に応じて極めて強力で複雑な検索を作成することができます。USA Today の brief 要素を例にとると、Snowball アナライザーまたはキーワード・アナライザーを指定することができます。Snowball のトークン・アルゴリズムでは、英単語を基本形に変換することによって、検索結果の範囲を広げます (例えば、jazzy という単語を jazz にします)。アプリケーションの検索機能を微調整するには、各種のアナライザーを扱うのが最適な方法です。さらに、ElasticSearch のような検索プラットフォームを使用する場合、これらのオプションはすでに揃っているので、自分で作成する必要はありません。

まとめ

検索機能は、もはやオプションの機能ではありません。データを利用、生成、または保管するほとんどのアプリケーションに、当然用意されていると見込まれる機能です。しかし、最近の複雑な検索の基礎となっている高度なアルゴリズムの数々を考えると、誰もが検索技術のスペシャリストになりたいと思い立つことはないでしょう。既存のオープンソース検索プラットフォームを知っていれば、大幅に時間とお金を節約して、その分、ソフトウェアの主要な機能の微調整に時間をかけることができます。

この記事では、簡単に使い始めることができて、極めて拡張性の高い分散検索プラットフォームである ElasticSearch を紹介しました。ElasticSearch の精巧さと使いやすさは圧巻であり、データ要件にスケーラビリティーが含まれている場合には (近頃では、スケーラビリティーが要件とならない場合が果たしてあるでしょうか?)、水平スケーラビリティーをサポートする ElasticSearch が世界中で選ばれています。

参考文献

学ぶために

製品や技術を入手するために

議論するために

  • developerWorks コミュニティーに参加してください。ここでは他の developerWorks ユーザーとのつながりを持てる他、開発者によるブログ、フォーラム、グループ、Wiki を調べることができます。

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Java technology, Cloud computing
ArticleID=853346
ArticleTitle=Java 開発 2.0: ElasticSearch によるスケーラブルな検索
publish-date=01102013