OpenSearch SDK for Java V3.1 を使用して、OpenSearch 高性能検索版アプリケーションにドキュメントをプッシュします。この例では、単一のバッチでドキュメントの追加、更新、削除を行い、その後クエリを実行してプッシュ結果を検証します。
前提条件
開始する前に、以下をご確認ください。
テーブルが設定された OpenSearch 高性能検索版アプリケーション
必要な権限を持つ RAM ユーザー — 「AliyunServiceRoleForOpenSearch」および「アクセス承認ルール」をご参照ください。
認証情報の設定
AccessKey ID と AccessKey Secret を環境変数として保存します。認証情報をソースファイルにハードコーディングしないでください。
Alibaba Cloud アカウントの AccessKey ペアは、すべての API オペレーションにアクセスできます。代わりに RAM ユーザーの AccessKey ペアを使用し、アプリケーションが必要とする権限のみを付与してください。AccessKey ペアを作成するには、「AccessKey ペアの作成」をご参照ください。RAM ユーザーを作成するには、「RAM ユーザーの作成」をご参照ください。
Linux および macOS
<access_key_id> と <access_key_secret> を RAM ユーザーの認証情報に置き換えます。
export ALIBABA_CLOUD_ACCESS_KEY_ID=<access_key_id>
export ALIBABA_CLOUD_ACCESS_KEY_SECRET=<access_key_secret>Windows
環境変数ファイルを作成し、
ALIBABA_CLOUD_ACCESS_KEY_IDとALIBABA_CLOUD_ACCESS_KEY_SECRETを追加し、値としてご自身の AccessKey ID と AccessKey Secret を設定します。Windows を再起動して、環境変数を有効にします。
仕組み
Java SDK を使用したデータプッシュは、以下の 3 つのステップで行われます。
各ドキュメントを
Mapオブジェクトとして構築し、コマンド (ADDまたはDELETE) を割り当てます。すべてのドキュメントを
JSONArray文字列にシリアライズし、クライアントバッファーにロードします。documentClient.push()を呼び出して、バッチ全体を一度にアプリケーションに送信します。
各バッチには、単一テーブルのフィールドのみを含めることができます。クロステーブルプッシュはサポートされていません。
サポートされているコマンド
| コマンド | 動作 |
|---|---|
ADD | 新しいドキュメントを追加します。同じプライマリキーを持つドキュメントが既に存在する場合、そのドキュメントのフルアップデートを実行します。 |
DELETE | 指定されたプライマリキーを持つドキュメントを削除します。プライマリキーフィールドのみが必要です。 |
UPDATE | 部分的な更新を実行します。拡張アプリケーションでのみサポートされています。標準アプリケーションは ADD のみをサポートします。 |
データフォーマット
データセットは有効なフォーマットである必要があります。サンプルファイルをテンプレートとしてダウンロードするには、次の手順を実行します。
OpenSearch コンソールにログインします。
ご利用のアプリケーションの [操作] 列で、[その他] > [ファイルをアップロード] を選択します。
サンプルファイルをダウンロードします。
1 回のプッシュに含まれるドキュメント数が制限を超えると、プッシュは失敗し、エラーが返されます。
ドキュメントのプッシュとクエリ
以下の例では、2 つのドキュメント (doc1 と doc2) をプッシュし、doc3 を使用して doc2 を更新し、doc1 を削除した後、結果をクエリして検証します。すべての操作は documentClient.push() を使用してバッチを送信します。
package com.aliyun.opensearch;
import com.aliyun.opensearch.sdk.dependencies.com.google.common.collect.Lists;
import com.aliyun.opensearch.sdk.dependencies.com.google.common.collect.Maps;
import com.aliyun.opensearch.sdk.dependencies.org.json.JSONArray;
import com.aliyun.opensearch.sdk.dependencies.org.json.JSONObject;
import com.aliyun.opensearch.sdk.generated.OpenSearch;
import com.aliyun.opensearch.sdk.generated.commons.OpenSearchClientException;
import com.aliyun.opensearch.sdk.generated.commons.OpenSearchException;
import com.aliyun.opensearch.sdk.generated.commons.OpenSearchResult;
import com.aliyun.opensearch.sdk.generated.document.Command;
import com.aliyun.opensearch.sdk.generated.document.DocumentConstants;
import com.aliyun.opensearch.sdk.generated.search.*;
import com.aliyun.opensearch.sdk.generated.search.general.SearchResult;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.Random;
public class testPushSearch2 {
private String appName = "The name of the OpenSearch application to which you want to push data";
private String tableName = "The name of the table to which you want to push data";
private String host = "The endpoint of the OpenSearch API in your region";
public static void main(String[] args) {
// 環境変数から認証情報を読み取ります。
// このコードを実行する前に環境変数を設定してください。
// 手順については、「認証情報の設定」セクションをご参照ください。
String accesskey = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
String secret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
// デフォルトのエンコード形式を出力します。
System.out.println(String.format("file.encoding: %s", System.getProperty("file.encoding")));
System.out.println(String.format("defaultCharset: %s", Charset.defaultCharset().name()));
// プライマリキーとして使用するランダムな値を生成します。
Random rand = new Random();
int value1 = rand.nextInt(Integer.MAX_VALUE);
int value2 = rand.nextInt(Integer.MAX_VALUE);
// doc1 を構築します。
Map<String, Object> doc1 = Maps.newLinkedHashMap();
doc1.put("id", value1);
String title_string = "Add doc1 in push mode"; // UTF-8 エンコード
byte[] bytes;
try {
bytes = title_string.getBytes("utf-8");
String utf8_string = new String(bytes, "utf-8");
doc1.put("name", utf8_string);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
doc1.put("phone", "137****1111");
int[] int_arr = {11, 11};
doc1.put("int_arr", int_arr);
String[] literal_arr1 = {"Add doc1 in push mode", "Test adding doc1 in push mode"};
doc1.put("literal_arr", literal_arr1);
float[] float_arr = {(float) 1.1, (float) 1.1};
doc1.put("float_arr", float_arr);
doc1.put("cate_id", 1);
// ADD コマンドを使用して doc1 を JSONObject でラップします。
// 標準アプリケーションは UPDATE や部分的な更新をサポートしていません。
// ADD を使用して新しいドキュメントを追加するか、既存のドキュメントを完全に置き換えます。
JSONObject json1 = new JSONObject();
json1.put(DocumentConstants.DOC_KEY_CMD, Command.ADD.toString());
json1.put(DocumentConstants.DOC_KEY_FIELDS, doc1);
// doc2 を構築します。
Map<String, Object> doc2 = Maps.newLinkedHashMap();
doc2.put("id", value2);
String title_string2 = "Add doc2 in push mode"; // UTF-8 エンコード
byte[] bytes2;
try {
bytes2 = title_string2.getBytes("utf-8");
String utf8_string2 = new String(bytes2, "utf-8");
doc2.put("name", utf8_string2);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
doc2.put("phone", "137****2222");
int[] int_arr2 = {22, 22};
doc2.put("int_arr", int_arr2);
String[] literal_arr2 = {"Add doc2 in push mode", "Test adding doc2 in push mode"};
doc2.put("literal_arr", literal_arr2);
float[] float_arr2 = {(float) 2.2, (float) 2.2};
doc2.put("float_arr", float_arr2);
doc2.put("cate_id", 1);
// ADD は doc2 を追加します。プライマリキーとして value2 を持つドキュメントが既に存在する場合、そのドキュメントは完全に置き換えられます。
JSONObject json2 = new JSONObject();
json2.put(DocumentConstants.DOC_KEY_CMD, Command.ADD.toString());
json2.put(DocumentConstants.DOC_KEY_FIELDS, doc2);
// doc2 を更新する doc3 を構築します (同じプライマリキー: value2)。
Map<String, Object> doc3 = Maps.newLinkedHashMap();
doc3.put("id", value2);
String title_string3 = "Update doc2 to doc3 in push mode"; // UTF-8 エンコード
byte[] bytes3;
try {
bytes3 = title_string3.getBytes("utf-8");
String utf8_string3 = new String(bytes3, "utf-8");
doc3.put("name", utf8_string3);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
doc3.put("phone", "137****3333");
int[] int_arr3 = {33, 33};
doc3.put("int_arr", int_arr3);
String[] literal_arr3 = {"Update doc2 to doc3 in push mode", "Update doc2 to doc3 in push mode"};
doc3.put("literal_arr", literal_arr3);
float[] float_arr3 = {(float) 3.3, (float) 3.3};
doc3.put("float_arr", float_arr3);
doc3.put("cate_id", 1);
// プライマリキーとして value2 を持つ ADD は、doc2 を doc3 に置き換えます。
JSONObject json3 = new JSONObject();
json3.put(DocumentConstants.DOC_KEY_CMD, Command.ADD.toString());
json3.put(DocumentConstants.DOC_KEY_FIELDS, doc3);
// doc1 の DELETE コマンドを構築します。プライマリキーのみが必要です。
Map<String, Object> doc4 = Maps.newLinkedHashMap();
doc4.put("id", value1);
JSONObject json4 = new JSONObject();
json4.put(DocumentConstants.DOC_KEY_CMD, Command.DELETE.toString());
json4.put(DocumentConstants.DOC_KEY_FIELDS, doc4);
// バッチを組み立てます: doc1 を追加、doc2 を追加、doc2 を doc3 に更新、doc1 を削除。
JSONArray docsJsonArr = new JSONArray();
docsJsonArr.put(json1); // doc1 を追加
docsJsonArr.put(json2); // doc2 を追加
docsJsonArr.put(json3); // doc2 を doc3 に更新
docsJsonArr.put(json4); // doc1 を削除
String docsJson = docsJsonArr.toString();
// クライアントを初期化します。
OpenSearch openSearch = new OpenSearch(accesskey, secret, host);
OpenSearchClient serviceClient = new OpenSearchClient(openSearch);
DocumentClient documentClient = new DocumentClient(serviceClient);
try {
// バッチをプッシュします。
OpenSearchResult osr = documentClient.push(docsJson, appName, tableName);
// 応答が成功した場合は、プッシュリクエストが API レベルのエラーなしで受け入れられたことを意味します。
// プッシュ後も、アプリケーションでインデックス作成エラーが発生する可能性があります。例えば、
// フィールド値を期待される型に変換できない場合などです。
// OpenSearch コンソールでエラーログを確認し、すべてのドキュメントが正常にインデックス付けされたことを確認します。
if (osr.getResult().equalsIgnoreCase("true")) {
System.out.println("Push accepted. Request ID: " + osr.getTraceInfo().getRequestId());
} else {
System.out.println("Push failed: " + osr.getTraceInfo());
}
} catch (OpenSearchException e) {
e.printStackTrace();
} catch (OpenSearchClientException e) {
e.printStackTrace();
}
// スレッドを 1 秒間スリープさせます。
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// プッシュされたドキュメントをクエリします。
SearcherClient searcherClient = new SearcherClient(serviceClient);
// ページングと応答フォーマットを設定します。
Config config = new Config(Lists.newArrayList(appName));
config.setStart(0);
config.setHits(30);
// サポートされているフォーマット: XML と JSON。FULLJSON はサポートされていません。
config.setSearchFormat(SearchFormat.JSON);
// 返すフィールドを指定します。
config.setFetchFields(Lists.newArrayList("id", "name", "phone", "int_arr", "literal_arr", "float_arr", "cate_id"));
SearchParams searchParams = new SearchParams(config);
// プライマリキーでクエリします。単一の setQuery 呼び出しで複数の値を指定します —
// 複数の setQuery 呼び出しは互いに上書きします。
searchParams.setQuery("id:'" + value1 + "'|'" + value2 + "'");
// フィルター条件を適用します。
searchParams.setFilter("cate_id<=3");
// id (降順) でソートし、同じ id を持つドキュメントについては RANK (昇順) でソートします。
Sort sorter = new Sort();
sorter.addToSortFields(new SortField("id", Order.DECREASE));
sorter.addToSortFields(new SortField("RANK", Order.INCREASE));
searchParams.setSort(sorter);
SearchResult searchResult;
try {
searchResult = searcherClient.execute(searchParams);
String result = searchResult.getResult();
JSONObject obj = new JSONObject(result);
System.out.println(obj.toString());
} catch (OpenSearchException e) {
e.printStackTrace();
} catch (OpenSearchClientException e) {
e.printStackTrace();
}
}
}プッシュ結果について
プッシュの成功は、リクエストが API レベルのエラーなしで受け入れられたことを意味します。受け入れ後も、アプリケーションでインデックス作成エラーが発生する可能性があります。例えば、フィールド値を期待される型に変換できない場合などです。OpenSearch コンソールのエラーログを確認し、すべてのドキュメントが正常にインデックス付けされたことを確認してください。
次のステップ
データをプッシュした後、検索結果の品質を向上させるために、アプリケーションの関連度とランキングの設定を行います。