Google::Cloud::Datastore【訳】　


[Google::Cloud::Datastore](https://googlecloudplatform.github.io/google-cloud-ruby/#/docs/google-cloud-datastore/v0.23.0/google/cloud/datastore)の翻訳記事です。Ruby用のv0.23.0のものになります。

# Google Cloud Datastore

Google Cloud Datastoreは非リレーショナルデータを格納する完全に管理された、スキーマレスのデータベースです。リレーショナルデータベースに精通していればアットホームに感じるはずですが、Datastoreを最大限活用するために注意すべき点がいくつかあります。

google-cloudの目標は、Rubyistsにとって快適なAPIを提供することです。 認証はGoogle::Cloud#datastoreによって処理されます。 データストアサービスに接続するためのプロジェクトと認証情報を提供することができます。また、Google Compute Engineで実行している場合は、この設定が必要です。

```ruby
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`](https://googlecloudplatform.github.io/google-cloud-ruby/#/docs/google-cloud-datastore/v0.23.0/google/cloud/datastore/dataset?method=find-instance)を呼び出して、キーの部分を渡します。

```ruby
require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

# シンプルなキー
task = datastore.find "Task", "sampleTask"
```

```ruby
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](https://googlecloudplatform.github.io/google-cloud-ruby/#/docs/google-cloud-datastore/v0.23.0/google/cloud/datastore/query?method=where-instance)

```ruby
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](https://googlecloudplatform.github.io/google-cloud-ruby/#/docs/google-cloud-datastore/v0.23.0/google/cloud/datastore/query?method=order-instance)

```
require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

query = datastore.query("Task").order("created")

tasks = datastore.run query
```

返り値のレコード数を指定できます。[Google::Cloud::Datastore::Query#limit](https://googlecloudplatform.github.io/google-cloud-ruby/#/docs/google-cloud-datastore/v0.23.0/google/cloud/datastore/query?method=limit-instance)

```
require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

query = datastore.query("Task").limit(5)

tasks = datastore.run query
```

レコードのキー構造も照会できます。[Google::Cloud::Datastore::Query#ancestor](https://googlecloudplatform.github.io/google-cloud-ruby/#/docs/google-cloud-datastore/v0.23.0/google/cloud/datastore/query?method=ancestor-instance)

```
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](https://googlecloudplatform.github.io/google-cloud-ruby/#/docs/google-cloud-datastore/v0.23.0/google/cloud/datastore/dataset/lookupresults)と[Google::Cloud::Datastore::Dataset::QueryResults](https://googlecloudplatform.github.io/google-cloud-ruby/#/docs/google-cloud-datastore/v0.23.0/google/cloud/datastore/dataset/queryresults)

## Creating records

新しいエンティティを作成し、[Google::Cloud::Datastore::Dataset#save](https://googlecloudplatform.github.io/google-cloud-ruby/#/docs/google-cloud-datastore/v0.23.0/google/cloud/datastore/dataset?method=save-instance)を呼び出すことで永続化できます。 エンティティを保存するにはキーが必要です。 キーが不完全な場合は、保存時に完了します。

```
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](https://googlecloudplatform.github.io/google-cloud-ruby/#/docs/google-cloud-datastore/v0.23.0/google/cloud/datastore/dataset?method=save-instance)を呼ぶことで永続化されます。

```
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](https://googlecloudplatform.github.io/google-cloud-ruby/#/docs/google-cloud-datastore/v0.23.0/google/cloud/datastore/dataset?method=delete-instance)を呼び出して、エンティティオブジェクトまたはエンティティのキーオブジェクトを渡します。

```
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](https://googlecloudplatform.github.io/google-cloud-ruby/#/docs/google-cloud-datastore/v0.23.0/google/cloud/datastore/dataset?method=transaction-instance) ブロック内のすべてのクエリと更新は、トランザクションスコープ内で実行され、ブロックが完了すると自動的にコミットされます。

```
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](https://googlecloudplatform.github.io/google-cloud-ruby/#/docs/google-cloud-datastore/v0.23.0/google/cloud/datastore/transaction)と[Google::Cloud::Datastore::Dataset#transaction](https://googlecloudplatform.github.io/google-cloud-ruby/#/docs/google-cloud-datastore/v0.23.0/google/cloud/datastore/dataset?method=transaction-instance)を見てください。

## 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への接続の詳細については、「[認証ガイド](https://googlecloudplatform.github.io/google-cloud-ruby/#/docs/guides/authentication)」を参照してください。

### Prameters

||||
|---|---|---|
|project|String|接続先のデータストアのDataset ID|
|keyfile|Sting, Hash|Google Cloudからダウンロードしたキーファイル。 ファイルパスの場合、ファイルは読み込み可能でなければなりません。|
|scope|String, Array|OAuth 2.0スコープは、接続がアクセスできるリソースと操作のセットを制御します。[OAuth 2.0を使用したGoogle APIへのアクセス方法](https://developers.google.com/identity/protocols/OAuth2)を参照してください。デフォルトのスコープ: `https://www.googleapis.com/auth/datastore`|
|timeout|Integer|リクエストで使用するデフォルトのタイムアウト。 任意。|
|client_config|Hash|APIクライアントのデフォルト動作をオーバーライドする値のハッシュ。 Google::Gax::CallSettingsを参照してください。 任意。|

### Returns

- [Google::Cloud::Datastore::Dataset](https://googlecloudplatform.github.io/google-cloud-ruby/#/docs/google-cloud-datastore/v0.23.0/google/cloud/datastore/dataset)

### 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
```

### More Information

- [ソースコード](https://github.com/GoogleCloudPlatform/google-cloud-ruby/blob/google-cloud-datastore/v0.23.0/google-cloud-datastore/lib/google/cloud/datastore.rb#L568)