Google::Cloud::Datastoreの翻訳記事です。Ruby用のv0.23.0のものになります。
Google Cloud Datastore
Google Cloud Datastoreは非リレーショナルデータを格納する完全に管理された、スキーマレスのデータベースです。リレーショナルデータベースに精通していればアットホームに感じるはずですが、Datastoreを最大限活用するために注意すべき点がいくつかあります。
google-cloudの目標は、Rubyistsにとって快適なAPIを提供することです。 認証はGoogle::Cloud#datastoreによって処理されます。 データストアサービスに接続するためのプロジェクトと認証情報を提供することができます。また、Google Compute Engineで実行している場合は、この設定が必要です。
require "google/cloud/datastore"
datastore = Google::Cloud::Datastore.new(
project: "my-todo-project",
keyfile: "/path/to/keyfile.json"
)
task = datastore.find "Task", "sampleTask"
task["priority"] = 5
datastore.save task
Retrieving records
データストア内の「エンティティ」と呼ばれるレコードは、キーを使って取得します。 キーは数値識別子以上のもので、複雑なデータ構造であり、関係をモデル化するために使用できます。 最も単純なキーには、文字列型の値と、数値のid値または文字列名の値があります。単一のレコードを取得するには、Google::Cloud::Datastore::Dataset#find
を呼び出して、キーの部分を渡します。
require "google/cloud/datastore"
datastore = Google::Cloud::Datastore.new
# シンプルなキー
task = datastore.find "Task", "sampleTask"
require "google/cloud/datastore"
datastore = Google::Cloud::Datastore.new
# 複雑なキーオブジェクト
task_key = datastore.key "Task", 123456
task = datastore.find task_key
Querying records
基準に一致する複数のレコードを見つけます。Google::Cloud::Datastore::Query#where
require "google/cloud/datastore"
datastore = Google::Cloud::Datastore.new
query = datastore.query("Task").where("done", "=", false)
tasks = datastore.run query
レコードを並べます。Google::Cloud::Datastore::Query#order
require "google/cloud/datastore"
datastore = Google::Cloud::Datastore.new
query = datastore.query("Task").order("created")
tasks = datastore.run query
返り値のレコード数を指定できます。Google::Cloud::Datastore::Query#limit
require "google/cloud/datastore"
datastore = Google::Cloud::Datastore.new
query = datastore.query("Task").limit(5)
tasks = datastore.run query
レコードのキー構造も照会できます。Google::Cloud::Datastore::Query#ancestor
require "google/cloud/datastore"
datastore = Google::Cloud::Datastore.new
task_list_key = datastore.key "TaskList", "default"
query = datastore.query("Task").ancestor(task_list_key)
tasks = datastore.run query
Paginating records
一度にすべてのレコードを返すことはできませんが、Datastoreを複数回呼び出してすべてを返すことができます。
require "google/cloud/datastore"
datastore = Google::Cloud::Datastore.new
query = datastore.query("Task")
tasks = datastore.run query
tasks.all do |task|
puts t["description"]
end
詳しくは、Google::Cloud::Datastore::Dataset::LookupResultsとGoogle::Cloud::Datastore::Dataset::QueryResults
Creating records
新しいエンティティを作成し、Google::Cloud::Datastore::Dataset#saveを呼び出すことで永続化できます。 エンティティを保存するにはキーが必要です。 キーが不完全な場合は、保存時に完了します。
require "google/cloud/datastore"
datastore = Google::Cloud::Datastore.new
task = datastore.entity "Task" do |t|
t["type"] = "Personal"
t["done"] = false
t["priority"] = 4
t["description"] = "Learn Cloud Datastore"
end
task.key.id #=> nil
datastore.save task
task.key.id #=> 123456
複数の新しいエンティティをバッチで作成することができます。
require "google/cloud/datastore"
datastore = Google::Cloud::Datastore.new
task1 = datastore.entity "Task" do |t|
t["type"] = "Personal"
t["done"] = false
t["priority"] = 4
t["description"] = "Learn Cloud Datastore"
end
task2 = datastore.entity "Task" do |t|
t["type"] = "Personal"
t["done"] = false
t["priority"] = 5
t["description"] = "Integrate Cloud Datastore"
end
tasks = datastore.save(task1, task2)
task_key1 = tasks[0].key
task_key2 = tasks[1].key
データストア内のエンティティは、ディレクトリ構造に似た階層構造を形成します。 エンティティを作成する場合、別のエンティティを親として指定することもできます。 新しいエンティティは親エンティティの子です。
require "google/cloud/datastore"
datastore = Google::Cloud::Datastore.new
task_key = datastore.key "Task", "sampleTask"
task_key.parent = datastore.key "TaskList", "default"
task = datastore.entity task_key do |t|
t["type"] = "Personal"
t["done"] = false
t["priority"] = 5
t["description"] = "Integrate Cloud Datastore"
end
Setting properties
エンティティはプロパティを保持します。 プロパティには、文字列またはシンボルである名前と、オブジェクトである値があります。 String、Integer、Date、Time、さらには他のエンティティまたはキーオブジェクトを含むほとんどの値オブジェクトがサポートされています。 エンティティのプロパティに対する変更は、Google::Cloud::Datastore::Dataset#saveを呼ぶことで永続化されます。
require "google/cloud/datastore"
datastore = Google::Cloud::Datastore.new
task = datastore.find "Task", "sampleTask"
# Read the priority property
task["priority"] #=> 4
# Write the priority property
task["priority"] = 5
# Persist the changes
datastore.save task
配列プロパティは、複数の値を格納するために使用できます。
require "google/cloud/datastore"
datastore = Google::Cloud::Datastore.new
task = datastore.entity "Task", "sampleTask" do |t|
t["tags"] = ["fun", "programming"]
t["collaborators"] = ["alice", "bob"]
end
Deleting records
データストアからエンティティを削除するには、Google::Cloud::Datastore::Dataset#deleteを呼び出して、エンティティオブジェクトまたはエンティティのキーオブジェクトを渡します。
require "google/cloud/datastore"
datastore = Google::Cloud::Datastore.new
task = datastore.find "Task", "sampleTask"
datastore.delete task
バッチで複数のエンティティを削除することができます。
require "google/cloud/datastore"
datastore = Google::Cloud::Datastore.new
task_key1 = datastore.key "Task", "sampleTask1"
task_key2 = datastore.key "Task", "sampleTask2"
datastore.delete task_key1, task_key2
Transactions
複雑なロジックをトランザクションにラップできます。Google::Cloud::Datastore::Dataset#transaction ブロック内のすべてのクエリと更新は、トランザクションスコープ内で実行され、ブロックが完了すると自動的にコミットされます。
require "google/cloud/datastore"
datastore = Google::Cloud::Datastore.new
task_key = datastore.key "Task", "sampleTask"
datastore.transaction do |tx|
if tx.find(task_key).nil?
task = datastore.entity task_key do |t|
t["type"] = "Personal"
t["done"] = false
t["priority"] = 4
t["description"] = "Learn Cloud Datastore"
end
tx.save task
end
end
また、ブロックが指定されていない場合は、トランザクションオブジェクトが返され、手動でコミットまたはロールバックできます。
require "google/cloud/datastore"
datastore = Google::Cloud::Datastore.new
task_key = datastore.key "Task", "sampleTask"
tx = datastore.transaction
begin
if tx.find(task_key).nil?
task = datastore.entity task_key do |t|
t["type"] = "Personal"
t["done"] = false
t["priority"] = 4
t["description"] = "Learn Cloud Datastore"
end
tx.save task
end
tx.commit
rescue
tx.rollback
end
詳しくはGoogle::Cloud::Datastore::TransactionとGoogle::Cloud::Datastore::Dataset#transactionを見てください。
Querying metadata
Datastoreは、メタプログラミングのサポート、バックエンド管理機能の実装、一貫したキャッシュの簡素化などの目的で、メタデータの一部にプログラムにへのアクセスを提供します。 利用可能なメタデータには、アプリケーションが使用するエンティティグループ、名前空間、エンティティの種類、プロパティ、および各プロパティのプロパティ表現に関する情報が含まれます。
__namespace__
という特殊なエンティティを使用して、アプリケーションエンティティで使用されているすべてのネームスペースを見つけることができます。
require "google/cloud/datastore"
datastore = Google::Cloud::Datastore.new
query = datastore.query("__namespace__").
select("__key__").
where("__key__", ">=", datastore.key("__namespace__", "g")).
where("__key__", "<", datastore.key("__namespace__", "h"))
namespaces = datastore.run(query).map do |entity|
entity.key.name
end
__kind__
という特殊なエンティティは、アプリケーションで使用されているすべての種類を返します。
require "google/cloud/datastore"
datastore = Google::Cloud::Datastore.new
query = datastore.query("__kind__").
select("__key__")
kinds = datastore.run(query).map do |entity|
entity.key.name
end
プロパティクエリは、索引付きプロパティを示す__property__
エンティティに関連付けられたエンティティを返します。 (インデックス化されていないプロパティは含まれません)。
require "google/cloud/datastore"
datastore = Google::Cloud::Datastore.new
query = datastore.query("__property__").
select("__key__")
entities = datastore.run(query)
properties_by_kind = entities.each_with_object({}) do |entity, memo|
kind = entity.key.parent.name
prop = entity.key.name
memo[kind] ||= []
memo[kind] << prop
end
プロパティクエリは、クエリ結果を単一の種類またはプロパティに限定するために、__kind__
または__property__
キーで祖先のフィルタリングをサポートします。 kのプロパティpを表すエンティティのproperty_representation
プロパティは、kの任意のエンティティにおけるpの値のすべての表現を含む配列です。
require "google/cloud/datastore"
datastore = Google::Cloud::Datastore.new
ancestor_key = datastore.key "__kind__", "Task"
query = datastore.query("__property__").
ancestor(ancestor_key)
entities = datastore.run(query)
representations = entities.each_with_object({}) do |entity, memo|
property_name = entity.key.name
property_types = entity["property_representation"]
memo[property_name] = property_types
end
また、__kind__
または__property__
エンティティのいずれかを示す疑似プロパティ__key__
を超える範囲でプロパティクエリをフィルタリングすることもできます。
require "google/cloud/datastore"
datastore = Google::Cloud::Datastore.new
start_key = datastore.key "__property__", "priority"
start_key.parent = datastore.key "__kind__", "Task"
query = datastore.query("__property__").
select("__key__").
where("__key__", ">=", start_key)
entities = datastore.run(query)
properties_by_kind = entities.each_with_object({}) do |entity, memo|
kind = entity.key.parent.name
prop = entity.key.name
memo[kind] ||= []
memo[kind] << prop
end
Configuring timeout
リクエストタイムアウト値は秒単位で設定できます。
require "google/cloud/datastore"
datastore = Google::Cloud::Datastore.new timeout: 120
The Cloud Datastore Emulator
今回のリリースで、gcloud SDKの一部であるCloud Datastoreエミュレータはgoogle-cloudとの互換性がなくなりました。 これは、gcloud SDKのCloud Datastoreエミュレータがまだトランスポート層としてgRPCをサポートしていないためです。
gRPC互換用エミュレータは、gcloud SDK Cloud DataStoreエミュレータがgRPCをサポートするまで利用可能です。 それを使用するには、gRPCエミュレータをダウンロードし、cloud_datastore_emulator
スクリプトを使用する必要があります。
Cloud Datastoreエミュレータを実行すると、次のようなメッセージが表示されます。
If you are using a library that supports the DATASTORE_EMULATOR_HOST
environment variable, run:
export DATASTORE_EMULATOR_HOST=localhost:8978
これで、環境変数DATASTORE_EMULATOR_HOSTを使用してエミュレータに接続できます。
require "google/cloud/datastore"
# Make Datastore use the emulator
ENV["DATASTORE_EMULATOR_HOST"] = "localhost:8978"
datastore = Google::Cloud::Datastore.new project: "emulator-project-id"
task = datastore.entity "Task", "emulatorTask" do |t|
t["type"] = "Testing"
t["done"] = false
t["priority"] = 5
t["description"] = "Use Datastore Emulator"
end
datastore.save task
new
Datastoreサービスに接続するための新しいオブジェクトを作成します。 各コールは新しい接続を作成します。
Google Cloudへの接続の詳細については、「認証ガイド」を参照してください。
Prameters
project | String | 接続先のデータストアのDataset ID |
keyfile | Sting, Hash | Google Cloudからダウンロードしたキーファイル。 ファイルパスの場合、ファイルは読み込み可能でなければなりません。 |
scope | String, Array | OAuth 2.0スコープは、接続がアクセスできるリソースと操作のセットを制御します。OAuth 2.0を使用したGoogle APIへのアクセス方法を参照してください。デフォルトのスコープ: https://www.googleapis.com/auth/datastore
|
timeout | Integer | リクエストで使用するデフォルトのタイムアウト。 任意。 |
client_config | Hash | APIクライアントのデフォルト動作をオーバーライドする値のハッシュ。 Google::Gax::CallSettingsを参照してください。 任意。 |
Returns
Example
require "google/cloud/datastore"
datastore = Google::Cloud::Datastore.new(
project: "my-todo-project",
keyfile: "/path/to/keyfile.json"
)
task = datastore.entity "Task", "sampleTask" do |t|
t["type"] = "Personal"
t["done"] = false
t["priority"] = 4
t["description"] = "Learn Cloud Datastore"
end
datastore.save task