class Datastore
extends DatastoreRequest

Idiomatic class for interacting with Cloud Datastore. Uses the lower-level DatastoreClient class under the hood.

In addition to the constructor options shown here, the Datastore class constructor accepts the same options accepted by DatastoreClient.

<h4>The Datastore Emulator</h4>

Make sure you have the <a href="https://cloud.google.com/sdk/downloads"> gcloud SDK installed</a>, then run:

<pre> $ gcloud beta emulators datastore start --no-legacy </pre>

You will see the following printed:

<pre> [datastore] API endpoint: http://localhost:8005 [datastore] If you are using a library that supports the DATASTORE_EMULATOR_HOST environment variable, run: [datastore] [datastore] export DATASTORE_EMULATOR_HOST=localhost:8005 [datastore] [datastore] Dev App Server is now running. </pre>

Set that environment variable and your localhost Datastore will automatically be used. You can also pass this address in manually with apiEndpoint.

Additionally, DATASTORE_PROJECT_ID is recognized. If you have this set, you don't need to provide a projectId.

See Cloud Datastore Concepts Overview

Examples

Import the client library

const {Datastore} = require('@google-cloud/datastore');

Create a client that uses <a href="https://cloud.google.com/docs/authentication/production#providing_credentials_to_your_application">Application Default Credentials (ADC)</a>:

const datastore = new Datastore();

Create a client with <a href="https://cloud.google.com/docs/authentication/production#obtaining_and_providing_service_account_credentials_manually">explicit credentials</a>:

const datastore = new Datastore({
  projectId: 'your-project-id',
  keyFilename: '/path/to/keyfile.json'
});

Retrieving Records

const {Datastore} = require('@google-cloud/datastore');
const datastore = new Datastore();

// Records, called "entities" in Datastore, are retrieved by using a key. The
// key is more than a numeric identifier, it is a complex data structure that
// can be used to model relationships. The simplest key has a string `kind`
// value, and either a numeric `id` value, or a string `name` value.
//
// A single record can be retrieved with Datastore#key and
// Datastore#get.
//-
const key = datastore.key(['Company', 'Google']);

datastore.get(key, function(err, entity) {
  // entity = The record.
  // entity[datastore.KEY] = The key for this entity.
});

//-
// <h3>Querying Records</h3>
//
// Create a query with Datastore#createQuery.
//-
const query = datastore.createQuery('Company');

//-
// Multiple records can be found that match criteria with
// Query#filter.
//-
query.filter('location', 'CA');

//-
// Records can also be ordered with Query#order.
//-
query.order('name');

//-
// The number of records returned can be specified with
// Query#limit.
//-
query.limit(5);

//-
// Records' key structures can also be queried with
// Query#hasAncestor.
//-
const ancestorKey = datastore.key(['ParentCompany', 'Alphabet']);

query.hasAncestor(ancestorKey);

//-
// Run the query with Datastore#runQuery.
//-
datastore.runQuery(query, (err, entities) => {
  // entities = An array of records.

  // Access the Key object for an entity.
  const firstEntityKey = entities[0][datastore.KEY];
});

Paginating Records

// Imagine building a website that allows a user to sift through hundreds of
// their contacts. You'll likely want to only display a subset of these at
// once, so you set a limit.
//-
const express = require('express');
const app = express();

const NUM_RESULTS_PER_PAGE = 15;

app.get('/contacts', (req, res) => {
  const query = datastore.createQuery('Contacts')
    .limit(NUM_RESULTS_PER_PAGE);

  if (req.query.nextPageCursor) {
    query.start(req.query.nextPageCursor);
  }

  datastore.runQuery(query, (err, entities, info) => {
    if (err) {
      // Error handling omitted.
      return;
    }

    // Respond to the front end with the contacts and the cursoring token
    // from the query we just ran.
    const frontEndResponse = {
      contacts: entities
    };

    // Check if  more results may exist.
    if (info.moreResults !== datastore.NO_MORE_RESULTS) {
      frontEndResponse.nextPageCursor = info.endCursor;
    }

    res.render('contacts', frontEndResponse);
  });
});

Creating Records

// New entities can be created and persisted with Datastore#save.
// The entitiy must have a key to be saved. If you don't specify an
// identifier for the key, one is generated for you.
//
// We will create a key with a `name` identifier, "Google".
//-
const key = datastore.key(['Company', 'Google']);

const data = {
  name: 'Google',
  location: 'CA'
};

datastore.save({
  key: key,
  data: data
}, (err) => {
  if (!err) {
    // Record saved successfully.
  }
});

//-
// We can verify the data was saved by using Datastore#get.
//-
datastore.get(key, (err, entity) => {
  // entity = {
  //   name: 'Google',
  //   location: 'CA'
  // }
});

//-
// If we want to update this record, we can modify the data object and re-
// save it.
//-
data.symbol = 'GOOG';

datastore.save({
  key: key, // defined above (datastore.key(['Company', 'Google']))
  data: data
}, (err, entity) => {
  if (!err) {
    // Record updated successfully.
  }
});

Deleting Records

// Entities can be removed from Datastore by passing the entity's key object
// to Datastore#delete.
//-
const key = datastore.key(['Company', 'Google']);

datastore.delete(key, (err) => {
  if (!err) {
    // Record deleted successfully.
  }
});

Transactions

// Complex logic can be wrapped in a transaction with
// Datastore#transaction. All queries and updates run within
// the transaction will be applied when the `done` function is called.
//-
const transaction = datastore.transaction();

transaction.run((err) => {
  if (err) {
    // Error handling omitted.
  }

  const key = datastore.key(['Company', 'Google']);

  transaction.get(key, (err, entity) => {
    if (err) {
      // Error handling omitted.
    }

    entity.symbol = 'GOOG';

    transaction.save(entity);

    transaction.commit((err) => {
      if (!err) {
        // Transaction committed successfully.
      }
    });
  });
});

Queries with Ancestors

const {Datastore} = require('@google-cloud/datastore');
const datastore = new Datastore();

const customerId1 = 2993844;
const customerId2 = 4993882;
const customerKey1 = datastore.key(['Customer', customerId1]);
const customerKey2 = datastore.key(['Customer', customerId2]);
const cookieKey1 = datastore.key(['Customer', customerId1, 'Cookie',
'cookie28839']); // child entity const cookieKey2 =
datastore.key(['Customer', customerId1, 'Cookie', 'cookie78984']); // child
entity const cookieKey3 = datastore.key(['Customer', customerId2, 'Cookie',
'cookie93911']); // child entity

const entities = [];

entities.push({
  key: customerKey1,
  data: {
    name: 'Jane Doe',
    address: '4848 Liller'
  }
});

entities.push({
  key: customerKey2,
  data: {
    name: 'John Smith',
    address: '4848 Pine'
  }
});

entities.push({
  key: cookieKey1,
  data: {
    cookieVal: 'dj83kks88rkld'
  }
});

entities.push({
  key: cookieKey2,
  data: {
    cookieVal: 'sj843ka99s'
  }
});

entities.push({
  key: cookieKey3,
  data: {
    cookieVal: 'otk82k2kw'
  }
});

datastore.upsert(entities);

const query = datastore.createQuery().hasAncestor(customerKey1);

datastore.runQuery(query, (err, entities) => {
  for (let entity of entities) {
    console.log(entity[datastore.KEY]);
  }
});

const query2 = datastore.createQuery().hasAncestor(customerKey2);

datastore.runQuery(query2, (err, entities) => {
  for (let entity of entities) {
    console.log(entity[datastore.KEY]);
  }
});

datastore.runQuery(query2, (entities) => {
  console.log(entities);
});

Constructors

new
Datastore(options?: DatastoreOptions)

Static Properties

KEY: entity.KEY_SYMBOL

Access the Key from an Entity object.

This is one of three values which may be returned from Datastore#runQuery, Transaction#runQuery, and Query#run as info.moreResults.

There may be more results after the specified end cursor.

This is one of three values which may be returned from Datastore#runQuery, Transaction#runQuery, and Query#run as info.moreResults.

There may be more results after the specified limit.

This is one of three values which may be returned from Datastore#runQuery, Transaction#runQuery, and Query#run as info.moreResults.

There are no more results left to query for.

Static Methods

double(value: number): entity.Double

Helper function to get a Datastore Double object.

geoPoint(coordinates: entity.Coordinates): entity.GeoPoint

Helper function to get a Datastore Geo Point object.

int(value: number | string): entity.Int

Helper function to get a Datastore Integer object.

This is also useful when using an ID outside the bounds of a JavaScript Number object.

isDouble(value?: { }): boolean

Helper function to check if something is a Datastore Double object.

isGeoPoint(value?: { }): boolean

Helper function to check if something is a Datastore Geo Point object.

isInt(value?: { }): boolean

Helper function to check if something is a Datastore Integer object.

isKey(value?: { }): boolean

Helper function to check if something is a Datastore Key object.

Properties

DatastoreRequest: DatastoreRequest

DatastoreRequest class.

KEY: entity.KEY_SYMBOL
Transaction: Transaction

Transaction class.

auth: GoogleAuth
optional
baseUrl_: string
clients_: Map<string, ClientStub>
optional
customEndpoint_: boolean
optional
namespace: string
optional
port_: number

Methods

createAggregationQuery(query: Query): AggregateQuery

Create an aggregation query from a Query.

createQuery(kind?: string): Query

Create a query for the specified kind. See Query for all of the available methods.

createQuery(kind?: string[]): Query
createQuery(
namespace: string,
kind: string,
): Query
createQuery(
namespace: string,
kind: string[],
): Query
determineBaseUrl_(customApiEndpoint?: string): void

Determine the appropriate endpoint to use for API requests. If not explicitly defined, check for the "DATASTORE_EMULATOR_HOST" environment variable, used to connect to a local Datastore server.

double(value: number): entity.Double
export(config: ExportEntitiesConfig): Promise<LongRunningResponse>

Export entities from this project to a Google Cloud Storage bucket.

export(
config: ExportEntitiesConfig,
callback: LongRunningCallback,
): void
geoPoint(coordinates: entity.Coordinates): entity.GeoPoint
getIndexes(options?: GetIndexesOptions): Promise<GetIndexesResponse>

Get all of the indexes in this project.

getIndexes(
options: GetIndexesOptions,
callback: GetIndexesCallback,
): void
getIndexes(callback: GetIndexesCallback): void
getIndexesStream(options?: GetIndexesOptions): NodeJS.ReadableStream

Get all of the indexes in this project as a readable object stream.

getProjectId(): Promise<string>
import(config: ImportEntitiesConfig): Promise<LongRunningResponse>

Import entities into this project from a remote file.

import(
config: ImportEntitiesConfig,
callback: LongRunningCallback,
): void
index(id: string): Index

Get a reference to an Index.

insert(entities: Entities): Promise<InsertResponse>

Maps to Datastore#save, forcing the method to be insert.

insert(
entities: Entities,
callback: InsertCallback,
): void
int(value: number | string): entity.Int
isDouble(value?: { }): boolean
isGeoPoint(value?: { }): boolean
isInt(value?: { }): boolean
isKey(value?: { }): boolean
key(options: entity.KeyOptions): entity.Key

Helper to create a Key object, scoped to the instance's namespace by default.

You may also specify a configuration object to define a namespace and path.

key(path: PathType[]): entity.Key
key(path: string): entity.Key
keyFromLegacyUrlsafe(key: string): entity.Key

Helper to convert URL safe key string to entity key object

This is intended to work with the "legacy" representation of a datastore "Key" used within Google App Engine (a so-called "Reference").

keyToLegacyUrlSafe(
key: entity.Key,
locationPrefix?: string,
): Promise<string>

Helper to create a URL safe key.

This is intended to work with the "legacy" representation of a datastore "Key" used within Google App Engine (a so-called "Reference"). The returned string can be used as the "urlsafe" The base64 encoded values will have padding removed.

keyToLegacyUrlSafe(
key: entity.Key,
callback: KeyToLegacyUrlSafeCallback,
): void
keyToLegacyUrlSafe(
key: entity.Key,
locationPrefix: string,
callback: KeyToLegacyUrlSafeCallback,
): void
save(
entities: Entities,
gaxOptions?: CallOptions,
): Promise<SaveResponse>

Insert or update the specified object(s). If a key is incomplete, its associated object is inserted and the original Key object is updated to contain the generated ID.

This method will determine the correct Datastore method to execute (upsert, insert, or update) by using the key(s) provided. For example, if you provide an incomplete key (one without an ID), the request will create a new entity and have its ID automatically assigned. If you provide a complete key, the entity will be updated with the data specified.

By default, all properties are indexed. To prevent a property from being included in all indexes, you must supply an excludeFromIndexes array.

To prevent large properties from being included in all indexes, you must supply excludeLargeProperties: true. See below for an example.

save(
entities: Entities,
gaxOptions: CallOptions,
callback: SaveCallback,
): void
save(
entities: Entities,
callback: SaveCallback,
): void
transaction(options?: TransactionOptions): Transaction

Create a new Transaction object.

update(entities: Entities): Promise<UpdateResponse>

Maps to Datastore#save, forcing the method to be update.

update(
entities: Entities,
callback: UpdateCallback,
): void
upsert(entities: Entities): Promise<UpsertResponse>

Maps to Datastore#save, forcing the method to be upsert.

upsert(
entities: Entities,
callback: UpsertCallback,
): void