データの追加

表に行を追加します。表の行にデータを格納すると、表の情報の取得、追加または削除をアプリケーションで簡単に実行できます。

PutRequestクラスは、NoSQLHandle.put(oracle.nosql.driver.ops.PutRequest)操作への入力を表します。このリクエストは、次のような無条件および条件付きのputを実行するために使用できます。

  • 既存の行をすべて上書きします。上書きがデフォルトの機能です。
  • 行が存在しない場合にのみ成功します。この場合、PutRequest.Option.IfAbsentメソッドを使用します。
  • 行が存在する場合にのみ成功します。この場合、PutRequest.Option.IfPresentメソッドを使用します。
  • 行が存在し、バージョンが特定のバージョンと一致する場合にのみ成功します。この場合はPutRequest.Option.IfVersionメソッドを使用し、一致するバージョンを指定する場合はsetMatchVersion(oracle.nosql.driver.Version)メソッドを使用します。

ノート:

まず、クライアント・ドライバをOracle NoSQL Databaseに接続し、ハンドルを取得してから他のステップを実行します。このトピックでは、クライアント・ドライバの接続と表の作成に関するステップは省略しています。

まだ表がない場合は、表および索引の作成を参照してください。

表に行を追加するには、次のようにします。

/* use the MapValue class and input the contents of a new row */
MapValue value = new MapValue().put("id", 1).put("name", "myname");

/* create the PutRequest, setting the required value and table name */
PutRequest putRequest = new PutRequest().setValue(value)
                                        .setTableName("users");

/* use the handle to execute the PUT request
 * on success, PutResult.getVersion() returns a non-null value
 */
PutResult putRes = handle.put(putRequest);
if (putRes.getVersion() != null) {
  // success
} else {
 // failure
}

WriteMultipleRequestクラスを使用して、シャード・キーを共有する表に対して一連のPutRequest操作を実行できます。操作が正常に実行された場合、WriteMultipleResult.getSuccess()メソッドはtrueを返します。

JSONデータを表に追加することもできます。JSONデータを固定スキーマ表のレコードに変換することも、データ型がJSON型である列にJSONデータを挿入することもできます。

PutRequestクラスには、JSON文字列を取得し、それを使用して表に挿入する行に値を移入するsetValueFromJsonメソッドも用意されています。JSON文字列では、表のフィールド名に対応するフィールド名を指定する必要があります。

JSONデータを表に追加するには、次のようにします。
/* Construct a simple row, specifying the values for each 
 * field. The value for the row is this: 
 * 
 * { 
 *   "cookie_id": 123, 
 *   "audience_data": { 
 *     "ipaddr": "10.0.00.xxx", 
 *     "audience_segment": { 
 *        "sports_lover": "2018-11-30", 
 *        "book_reader": "2018-12-01" 
 *      } 
 *   } 
 * } 
 */
MapValue segments = new MapValue()
    .put("sports_lover", new TimestampValue("2018-11-30"))
    .put("book_reader", new TimestampValue("2018-12-01"));
MapValue value = new MapValue()
    .put("cookie_id", 123) // fill in cookie_id field
    .put("ipaddr", "10.0.00.xxx")
    .put("audience_segment", segments); 
PutRequest putRequest = new PutRequest()
    .setValue(value)
    .setTableName(tableName);
PutResult putRes = handle.put(putRequest);

同じ行をJSON文字列として表に挿入できます。

/* Construct a simple row in JSON */  
String jsonString = "{\"cookie_id\":123,\"ipaddr\":\"10.0.00.xxx\",
                      \"audience_segment\":{\"sports_lover\":\"2018-11-30\",
                      \"book_reader\":\"2018-12-01\"}}";   
PutRequest putRequest = new PutRequest()
      .setValueFromJson(jsonString, null) // no options
      .setTableName(tableName);  
PutResult putRes = handle.put(putRequest);
borneo.PutRequestクラスは、単一行の挿入に使用されるborneo.NoSQLHandle.put()メソッドへの入力を表します。このメソッドは、次のような無条件および条件付きのputに使用できます。
  • 既存の行をすべて上書きします。これがデフォルトです。
  • 行が存在しない場合にのみ成功します。この場合、borneo.PutOption.IF_ABSENTを使用します。
  • 行が存在する場合にのみ成功します。この場合、borneo.PutOption.IF_PRESENTを使用します。
  • 行が存在し、そのborneo.Versionが特定のborneo.Versionと一致する場合にのみ成功します。この場合、borneo.PutOption.IF_VERSIONを使用し、一致するバージョンを指定するためにborneo.PutRequest.set_match_version()を使用します。
from borneo import PutRequest
# PutRequest requires a table name 
request = PutRequest().set_table_name('users')
# set the value 
request.set_value({'id': i, 'name': 'Jane'})
result = handle.put(request)
# a successful put returns a non-empty version
if result.get_version() is not None: 
# success

データを追加する場合、指定された値は表のスキーマに正確に対応している必要があります。そうでない場合は、IllegalArgumentExceptionが発生します。デフォルト値またはnull可能値の列は、エラーなしで省略できますが、予期しないデフォルトを回避するために、すべての列に値を指定することをお薦めします。デフォルトでは、予期しない列は暗黙的に無視され、予期される列を使用して値が配置されます。

同じシャード・キーを共有する複数の行がある場合は、多数のPutRequestまたはDeleteRequestオブジェクトを使用して作成できるborneo.WriteMultipleRequestを使用して単一のリクエストに配置できます。JSONデータを表に追加することもできます。固定スキーマ表の場合、JSONはターゲット・スキーマに変換されます。JSONデータは、JSON型の列に直接挿入できます。JSONデータ型を使用すると、固定スキーマなしで表データを作成できるため、データの柔軟な使用が可能になります。

行またはキーに指定されたデータ値は、Python dictです。関連するリクエスト(GetRequest、PutRequest、DeleteRequest)には、複数の方法で指定できます。
  • Python dictとして直接:
    request.set_value({'id': 1})
    request.set_key({'id': 1 })
  • JSON文字列として:
    request.set_value_from_json('{"id": 1, "name": "Jane"}')
    request.set_key_from_json('{"id": 1}')

どちらの場合も、指定されたキーと値が表のスキーマに正確に対応している必要があります。これ以外の場合、borneo.IllegalArgumentException例外が発生します。データがJSONとして指定され、JSONを解析できない場合、ValueErrorが発生します。

nosqldb.PutRequestは、単一行の挿入に使用されるnosqldb.Put() 関数への入力を表します。この関数は、次のような無条件および条件付きのputに使用できます。
  • 既存の行をすべて上書きします。これがデフォルトです。
  • 行が存在しない場合にのみ成功します。この場合、PutRequest.PutOptionフィールドにtypes.PutIfAbsent を指定します。
  • 行が存在する場合にのみ成功します。この場合、PutRequest.PutOptionフィールドにtypes.PutIfPresentを指定します。
  • 行が存在し、そのバージョンが特定のバージョンと一致する場合にのみ成功します。この場合、PutRequest.PutOptionフィールドにtypes.PutIfVersionを指定し、PutRequest.MatchVersionフィールドに必要なバージョンを指定します。
行(PutRequest内)またはキー(GetRequestおよびDeleteRequest内)に指定されたデータ値は、*types.MapValueです。MapValueの各エントリのkey部分はターゲット表の列名と一致する必要があり、value部分は列の有効な値である必要があります。表に配置する行のMapValueを作成するには、いくつかの方法があります。
  1. 空のMapValueを作成し、各列に値を配置します。
    value:=&types.MapValue{}
    value.Put("id", 1).Put("name", "Jack")
    req:=&nosqldb.PutRequest{
        TableName: "users",
        Value: value,
    }
    res, err:=client.Put(req)
  2. map[string]interface{}からMapValueを作成します。
    m:=map[string]interface{}{
        "id": 1,
        "name": "Jack",
    }
    value:=types.NewMapValue(m)
    req:=&nosqldb.PutRequest{
        TableName: "users",
        Value: value,
    }
    res, err:=client.Put(req)
  3. JSONからMapValueを作成します。これは、JSONがターゲット・スキーマに変換される固定スキーマ表の場合に行の値を設定する際に便利です。たとえば:
    value, err:=types.NewMapValueFromJSON(`{"id": 1, "name": "Jack"}`)
    iferr!=nil {
        return
    }
    req:=&nosqldb.PutRequest{
        TableName: "users",
        Value: value,
    }
    res, err:=client.Put(req)

JSONデータは、JSON型の列に直接挿入することもできます。JSONデータ型を使用すると、固定スキーマなしで表データを作成できるため、データの柔軟な使用が可能になります。

メソッドputは、単一行を表に挿入するために使用します。表名、行値をプレーンJavaScriptオブジェクトとして使用し、オプションの3番目の引数として選択します。このメソッドは、次のような無条件および条件付きのputに使用できます。
  • 同じ主キーがある場合に既存の行を上書きします。これがデフォルトです。
  • 同じ主キーを持つ行が存在しない場合にのみ成功します。この場合、{ ifAbsent: true }というopt引数にifAbsentを指定します。または、putIfAbsentメソッドを使用することもできます。
  • 同じ主キーを持つ行が存在する場合にのみ成功します。この場合、{ ifPresent: true }というopt引数にifPresentを指定します。または、putIfPresentメソッドを使用することもできます。
  • 同じ主キーを持つ行が存在し、そのバージョンが特定のバージョン値と一致する場合にのみ成功します。この場合、opt引数のmatchVersionを特定のバージョン{ matchVersion: my_version }に設定します。または、putIfVersionメソッドを使用して、3番目の引数(表名と行の後)としてバージョン値を指定することもできます。

各putメソッドは、成功ステータスや結果の行バージョンなどの情報を含むプレーンなJavaScriptオブジェクトであるPutResultのPromiseを返します。指定された行オブジェクトのプロパティ名は、基礎となる表の列名と同じである必要があります。

表に行を追加するには、次のようにします。
const NoSQLClient = require('oracle-nosqldb').NoSQLClient;
const client = new NoSQLClient('config.json');

async function putRowsIntoUsersTable() {
    const tableName = 'users';
    try {
        // Uncondintional put, should succeed
        let result = await client.put(tableName, { id: 1, name: 'John' });

        // Will fail since the row with the same primary key exists
        result = await client.putIfAbsent(tableName, { id: 1, name: 'Jane' });
        // Expected output: putIfAbsent failed
        console.log('putIfAbsent ' + result.success ? 'succeeded' : 'failed');

        // Will succeed because the row with the same primary key exists
        res = await client.putIfPresent(tableName, { id: 1 , name: 'Jane' });
        // Expected output: putIfAbsent succeeded
        console.log('putIfPresent ' + result.success ?
            'succeeded' : 'failed');

        let version = result.version;
        // Will succeed because the version matches existing row
        result = await client.putIfVersion(tableName, { id: 1, name: 'Kim' },
            version);
        // Expected output: putIfVersion succeeded
        console.log('putIfVersion ' + result.success ? 'succeeded' : 'failed');

        // Will fail because the previous put has changed the row version, so
        // the old version no longer matches.
        result = await client.putIfVersion(tableName, { id: 1, name: 'June' },
            version);
        // Expected output: putIfVersion failed
        console.log('putIfVersion ' + result.success ? 'succeeded' : 'failed');

    } catch(error) {
        //handle errors
    }
}

条件付きput操作が満たされていないために失敗した場合のみ、successはfalse値になることに注意してください(たとえば、putIfAbsentの行が存在する、putIfPresentの行が存在しない、またはputIfVersionのバージョンが一致しないなど)。その他の理由でput操作が失敗した場合、結果のPromiseは(非同期関数で捕捉できる)エラーで拒否されます。たとえば、指定された列値の型が正しくない場合、これが発生する可能性があります。この場合、putはNoSQLArgumentErrorになります。

putManyメソッドを使用して、同じシャード・キーを共有する表に対して一連のput操作を実行できます。この順序は単一トランザクションのスコープ内で実行されるため、この操作をアトミックにします。この操作の結果は、WriteMultipleResultのPromiseです。シーケンスにputとdeleteの両方が含まれている場合は、writeManyを使用することもできます。

JSON型の列を使用すると、JSON列のデータに事前定義済スキーマがないため、データの使用の柔軟性が向上します。データをJSON列に配置するには、プレーンJavaScriptオブジェクトまたはJSON文字列を列値として指定します。プレーンJavaScriptオブジェクトのデータは、サポートされているJSON型である必要があります。

メソッドPutAsyncおよび関連メソッドPutIfAbsentAsyncPutIfPresentAsyncおよびPutIfVersionAsyncを使用して、表に単一行を挿入したり、単一行を更新します。

これらのメソッドは、次のような無条件および条件付きのputに使用できます。
  • PutAsync (条件付きオプションなし)を使用して、新しい行を挿入するか、同じ主キーの既存の行(存在する場合)を上書きします。これは無条件のputです。
  • 同じ主キーを持つ行が存在しない場合にのみ、PutIfAbsentAsyncを使用して新しい行を挿入します。
  • 同じ主キーを持つ行が存在する場合にのみ、PutIfPresentAsyncを使用して既存の行を上書きします。
  • 同じ主キーを持つ行が存在し、そのRowVersionが特定のバージョンと一致する場合にのみ、PutIfVersionAsyncを使用して既存の行を上書きします。
前述の各Putメソッドは、Task<PutResult<RecordValue>>を返します。PutResultインスタンスには、完了したPut操作に関する情報(成功ステータス(対応する条件が満たされなかった場合は条件付きput操作が失敗する可能性があります)および結果のRowVersionなど)が含まれています。
表に行を追加するには、次のようにします。
var client = new NoSQLClient("config.json");
var tableName = "users";

try {
    // Uncondintional put, should succeed.
    var result = await client.PutAsync(tableName,
        new MapValue
        {
            ["id"] = 1,
            ["name"] = "John"
        });

    // This Put will fail because the row with the same primary
    // key already exists.
    result = await client.PutIfAbsentAsync(tableName,
        new MapValue
        {
            ["id"] = 1,
            ["name"] = "Jane"
        });
    
    // Expected output: PutIfAbsentAsync failed.
    Console.WriteLine("PutIfAbsentAsync {0}.",
        result.Success ? "succeeded" : "failed");

    // This Put will succeed because the row with the same primary
    // key exists.
    result = await client.PutIfPresentAsync(tableName,
        new MapValue
        {
            ["id"] = 1,
            ["name"] = "Jane"
        });

    // Expected output: PutIfPresentAsync succeeded.
    Console.WriteLine("PutIfPresentAsync {0}.",
        result.Success ? "succeeded" : "failed");
    var rowVersion = result.Version;

    // This Put will succeed because the version matches existing
    // row.
    result = await client.PutIfVersionAsync(
        tableName,
        new MapValue
        {
            ["id"] = 1,
            ["name"] = "Kim"
        }),
        rowVersion);

    // Expected output: PutIfVersionAsync succeeded.
    Console.WriteLine("PutIfVersionAsync {0}.",
        result.Success ? "succeeded" : "failed");

    // This Put will fail because the previous Put has changed
    // the row version, so the old version no longer matches.
    result = await client.PutIfVersionAsync(
        tableName,
        new MapValue
        {
            ["id"] = 1,
            ["name"] = "June"
        }),
        rowVersion);

    // Expected output: PutIfVersionAsync failed.
    Console.WriteLine("PutIfVersionAsync {0}.",
        result.Success ? "succeeded" : "failed");

    // Put a new row with TTL indicating expiration in 30 days.
    result = await client.PutAsync(tableName,
        new MapValue
        {
            ["id"] = 2,
            ["name"] = "Jack"
        }),
        new PutOptions
        {
            TTL = TimeToLive.OfDays(30)
        });
}
catch(Exception ex) {
    // handle exceptions
}

結果のSuccessプロパティは、条件付きPut操作に関連する正常な完了のみを示し、無条件のPutに対して常にtrueであることに注意してください。その他の理由でPut操作が失敗した場合、例外がスローされます。

PutManyAsyncメソッドを使用して、同じシャード・キーを共有する表に対して一連のput操作を実行できます。この順序は単一トランザクションのスコープ内で実行されるため、この操作をアトミックにします。WriteManyAsyncをコールして、Put操作とDelete操作の両方を含むシーケンスを実行することもできます。

JSONデータ型のフィールドを使用すると、JSONフィールドのデータに事前定義されたスキーマがないため、データの使用の柔軟性が向上します。値をJSONフィールドに入力するには、MapValueインスタンスを行値の一部としてフィールド値に指定します。また、FieldValue.FromJsonStringを使用してJSON文字列から値を作成することもできます。

次のいずれかの方法を使用して、表NosqlRepository save(entity_object)saveAll(Iterable<T> iterable)またはNosqlTemplate insert(entity)に行を追加します。詳細は、SDK for Spring Data APIリファレンスを参照してください。

この項では、repository.save(entity_object)メソッドを使用して行を追加します。

ノート:

まず、Oracle NoSQL Databaseの接続詳細を指定するために、AbstractNosqlConfigurationクラスを拡張するAppConfigクラスを作成します。詳細は、「NoSQL接続の取得」を参照してください。
表に行を追加するには、アプリケーションに次のコードを含めることができます。
@Override
public void run(String...args) throws Exception {
 
    /* Create a new User instance and load values into it.*/
 
    Users u1 = new Users();
    u1.firstName = "John";
    u1.lastName = "Doe";
 
    /* Save the User instance.*/
    repo.save(u1);
 
    /* Create a second User instance and load values into it. Save the instance.*/
    Users u2 = new Users();
    u2.firstName = "Angela";
    u2.lastName = "Willard";
 
    repo.save(u2);
}
これにより、2つのユーザー・エンティティが作成され、保存されます。エンティティごとに、Spring Data SDKによって次の2つの列が作成されます。
  1. 主キー列
  2. JSONデータ型列

ここで、主キーは自動生成されます。Usersクラスの@NosqlId注釈は、IDフィールドがIDとして機能し、基礎となるストレージ表の主キーになることを指定します。

generated=true属性は、このIDが順序で自動生成されることを指定します。残りのエンティティ・フィールド、つまり、firstNameおよびlastNameフィールドはJSON列に格納されます。