Constructor

Datastore

new Datastore(options)

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

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

The Datastore Emulator

Make sure you have the gcloud SDK installed, then run:

  $ gcloud beta emulators datastore start --no-legacy

You will see the following printed:

  [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.

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. -

Parameter

options

Optional

object

Configuration options.

Extends
DatastoreRequest
See also

Cloud Datastore Concepts Overview

Examples

Import the client library

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

Create a client that uses Application Default Credentials (ADC):

const datastore = new Datastore();

Create a client with explicit credentials:

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 {@link Datastore#key} and
// {@link 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 {@link Datastore#createQuery}.
//-
const query = datastore.createQuery('Company');

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

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

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

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

query.hasAncestor(ancestorKey);

//-
// Run the query with {@link Datastore#runQuery}.
//-
datastore.runQuery(query, function(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', function(req, res) {
  const query = datastore.createQuery('Contacts')
    .limit(NUM_RESULTS_PER_PAGE);

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

  datastore.runQuery(query, function(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 {@link 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
}, function(err) {
  if (!err) {
    // Record saved successfully.
  }
});

//-
// We can verify the data was saved by using {@link Datastore#get}.
//-
datastore.get(key, function(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
}, function(err, entity) {
  if (!err) {
    // Record updated successfully.
  }
});

Deleting Records

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

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

Transactions

// Complex logic can be wrapped in a transaction with
// {@link 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(function(err) {
  if (err) {
    // Error handling omitted.
  }

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

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

    entity.symbol = 'GOOG';

    transaction.save(entity);

    transaction.commit(function(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);
});

Properties

DatastoreRequest

static

constructor

DatastoreRequest class.

See also
DatastoreRequest

KEY

static

symbol

Access the Key from an Entity object.

Query

static

constructor

Query class.

See also
Query

Transaction

static

constructor

Transaction class.

See also
Transaction

v1

static

object

Property

Parameter

DatastoreClient

constructor

Reference to v1.DatastoreClient.

See also
v1.DatastoreClient

double

Helper function to get a Datastore Double object.

Parameter

value

number

The double value.

Returns

object 

Example

const Datastore = require('@google-cloud/datastore');
const datastore = new Datastore();
const threeDouble = datastore.double(3.0);

geoPoint

Helper function to get a Datastore Geo Point object.

Parameter

coordinates

object

Coordinate value.

Returns

object 

Example

const Datastore = require('@google-cloud/datastore');
const datastore = new Datastore();
const coordinates = {
  latitude: 40.6894,
  longitude: -74.0447
};

const geoPoint = datastore.geoPoint(coordinates);

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.

Parameter

value

number

The integer value.

Returns

object 

Example

const Datastore = require('@google-cloud/datastore');
const datastore = new Datastore();
const sevenInteger = datastore.int(7);

//-
// Create an Int to support long Key IDs.
//-
const key = datastore.key([
  'Kind',
  datastore.int('100000000000001234')
]);

isDouble

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

Parameter

value

any type

Returns

boolean 

Example

const Datastore = require('@google-cloud/datastore');
const datastore = new Datastore();
datastore.isDouble(0.42); // false
datastore.isDouble(datastore.double(0.42)); // true

isGeoPoint

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

Parameter

value

any type

Returns

boolean 

Example

const Datastore = require('@google-cloud/datastore');
const datastore = new Datastore();
const coordinates = {
  latitude: 0,
  longitude: 0
};

datastore.isGeoPoint(coordinates); // false
datastore.isGeoPoint(datastore.geoPoint(coordinates)); // true

isInt

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

Parameter

value

any type

Returns

boolean 

Example

const Datastore = require('@google-cloud/datastore');
const datastore = new Datastore();
datastore.isInt(42); // false
datastore.isInt(datastore.int(42)); // true

isKey

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

Parameter

value

any type

Returns

boolean 

Example

const Datastore = require('@google-cloud/datastore');
const datastore = new Datastore();
datastore.isKey({path: ['Company', 123]}); // false
datastore.isKey(datastore.key(['Company', 123])); // true

KEY

symbol

Access the Key from an Entity object.

MORE_RESULTS_AFTER_CURSOR

string

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.

MORE_RESULTS_AFTER_LIMIT

string

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.

namespace

string

NO_MORE_RESULTS

string

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.

projectId

string

Methods

allocateIds

allocateIds(key, options, callback)

Generate IDs without creating entities.

Parameter

key

The key object to complete.

options

Either the number of IDs to allocate or an options object for further customization of the request.

callback

The callback function.

Inherited from
DatastoreRequest#allocateIds

Example

var incompleteKey = datastore.key(['Company']);

//-
// The following call will create 100 new IDs from the Company kind, which
// exists under the default namespace.
//-
datastore.allocateIds(incompleteKey, 100, function(err, keys) {});

//-
// Or, if you're using a transaction object.
//-
var transaction = datastore.transaction();

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

  transaction.allocateIds(incompleteKey, 100, function(err, keys) {
    if (err) {
      // Error handling omitted.
    }

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

//-
// You may prefer to create IDs from a non-default namespace by providing an
// incomplete key with a namespace. Similar to the previous example, the call
// below will create 100 new IDs, but from the Company kind that exists under
// the "ns-test" namespace.
//-
var incompleteKey = datastore.key({
  namespace: 'ns-test',
  path: ['Company']
});

function callback(err, keys, apiResponse) {}

datastore.allocateIds(incompleteKey, 100, callback);

//-
// If the callback is omitted, we'll return a Promise.
//-
datastore.allocateIds(incompleteKey, 100).then(function(data) {
  var keys = data[0];
  var apiResponse = data[1];
});

createQuery

createQuery(namespace, kind) returns Query

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

Parameter

namespace

Optional

string

Namespace.

kind

string

The kind to query.

See also

Datastore Queries

Query
Returns

Query 

Example

const Datastore = require('@google-cloud/datastore');
const datastore = new Datastore();
const query = datastore.createQuery('Company');

createReadStream

createReadStream(keys, options)

Retrieve the entities as a readable object stream.

Parameter

keys

Datastore key object(s).

options

Optional

Optional configuration. See Datastore#get for a complete list of options.

Inherited from
DatastoreRequest#createReadStream
Throws

If at least one Key object is not provided.

Example

var keys = [
  datastore.key(['Company', 123]),
  datastore.key(['Product', 'Computer'])
];

datastore.createReadStream(keys)
  .on('error', function(err) {})
  .on('data', function(entity) {
    // entity is an entity object.
  })
  .on('end', function() {
    // All entities retrieved.
  });

delete

delete(key, gaxOptions, callback)

Delete all entities identified with the specified key(s).

Parameter

key

Datastore key object(s).

gaxOptions

Optional

Request configuration options, outlined here: https://googleapis.github.io/gax-nodejs/global.html#CallOptions.

callback

The callback function.

Inherited from
DatastoreRequest#delete

Example

var key = datastore.key(['Company', 123]);
datastore.delete(key, function(err, apiResp) {});

//-
// Or, if you're using a transaction object.
//-
var transaction = datastore.transaction();

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

  transaction.delete(key);

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

//-
// Delete multiple entities at once.
//-
datastore.delete([
  datastore.key(['Company', 123]),
  datastore.key(['Product', 'Computer'])
], function(err, apiResponse) {});

//-
// If the callback is omitted, we'll return a Promise.
//-
datastore.delete().then(function(data) {
  var apiResponse = data[0];
});

get

get(keys, options, callback)

Retrieve the entities identified with the specified key(s) in the current transaction. Get operations require a valid key to retrieve the key-identified entity from Datastore.

Parameter

keys

Datastore key object(s).

options

Optional

Optional configuration.

callback

The callback function.

Inherited from
DatastoreRequest#get
Throws

If at least one Key object is not provided.

Example

//-
// Get a single entity.
//-
var key = datastore.key(['Company', 123]);

datastore.get(key, function(err, entity) {});

//-
// Or, if you're using a transaction object.
//-
var transaction = datastore.transaction();

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

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

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

//-
// Get multiple entities at once with a callback.
//-
var keys = [
  datastore.key(['Company', 123]),
  datastore.key(['Product', 'Computer'])
];

datastore.get(keys, function(err, entities) {});

//-
// Here's how you would update the value of an entity with the help of the
// `save` method.
//-
datastore.get(key, function(err, entity) {
  if (err) {
    // Error handling omitted.
  }

  entity.newValue = true;

  datastore.save({
    key: key,
    data: entity
  }, function(err) {});
});

//-
// If the callback is omitted, we'll return a Promise.
//-
datastore.get(keys).then(function(data) {
  var entities = data[0];
});

insert

insert(entities, callback)

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

Parameter

entities

Datastore key object(s).

callback

The callback function.

Inherited from
DatastoreRequest#insert

key

key(options) returns 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.

Parameter

options

Optional

(object, string, or array)

Key path. To specify or override a namespace, you must use an object here to explicitly state it.

Returns

Key 

A newly created Key from the options given.

Examples

Create an incomplete key with a kind value of `Company`.

const Datastore = require('@google-cloud/datastore');
const datastore = new Datastore();
const key = datastore.key('Company');

Create a complete key with a kind value of `Company` and id `123`.

const Datastore = require('@google-cloud/datastore');
const datastore = new Datastore();
const key = datastore.key(['Company', 123]);

If the ID integer is outside the bounds of a JavaScript Number object, create an Int.

const Datastore = require('@google-cloud/datastore');
const datastore = new Datastore();
const key = datastore.key([
  'Company',
  datastore.int('100000000000001234')
]);
const Datastore = require('@google-cloud/datastore');
const datastore = new Datastore();
// Create a complete key with a kind value of `Company` and name `Google`.
// Note: `id` is used for numeric identifiers and `name` is used otherwise.
const key = datastore.key(['Company', 'Google']);

Create a complete key from a provided namespace and path.

const Datastore = require('@google-cloud/datastore');
const datastore = new Datastore();
const key = datastore.key({
  namespace: 'My-NS',
  path: ['Company', 123]
});

runQuery

runQuery(query, options, callback)

Datastore allows you to query entities by kind, filter them by property filters, and sort them by a property name. Projection and pagination are also supported.

The query is run, and the results are returned as the second argument to your callback. A third argument may also exist, which is a query object that uses the end cursor from the previous query as the starting cursor for the next query. You can pass that object back to this method to see if more results exist.

Parameter

query

Query object.

options

Optional

Optional configuration.

callback

Optional

The callback function. If omitted, a readable stream instance is returned.

Inherited from
DatastoreRequest#runQuery

Example

//-
// Where you see `transaction`, assume this is the context that's relevant to
// your use, whether that be a Datastore or a Transaction object.
//-
var query = datastore.createQuery('Lion');

datastore.runQuery(query, function(err, entities, info) {
  // entities = An array of records.

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

//-
// Or, if you're using a transaction object.
//-
var transaction = datastore.transaction();

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

  transaction.runQuery(query, function(err, entities) {
    if (err) {
      // Error handling omitted.
    }

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

//-
// A keys-only query returns just the keys of the result entities instead of
// the entities themselves, at lower latency and cost.
//-
var keysOnlyQuery = datastore.createQuery('Lion').select('__key__');

datastore.runQuery(keysOnlyQuery, function(err, entities) {
  var keys = entities.map(function(entity) {
    return entity[datastore.KEY];
  });
});

//-
// If the callback is omitted, we'll return a Promise.
//-
datastore.runQuery(query).then(function(data) {
  var entities = data[0];
});

runQueryStream

runQueryStream(query, options)

Get a list of entities as a readable object stream.

See Datastore#runQuery for a list of all available options.

Parameter

query

Query object.

options

Optional

Optional configuration.

Inherited from
DatastoreRequest#runQueryStream

Example

datastore.runQueryStream(query)
  .on('error', console.error)
  .on('data', function(entity) {
    // Access the Key object for this entity.
    var key = entity[datastore.KEY];
  })
  .on('info', function(info) {})
  .on('end', function() {
    // All entities retrieved.
  });

//-
// If you anticipate many results, you can end a stream early to prevent
// unnecessary processing and API requests.
//-
datastore.runQueryStream(query)
  .on('data', function(entity) {
    this.end();
  });

save

save(entities, gaxOptions, callback)

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. See below for an example.

Parameter

entities

Datastore key object(s).

gaxOptions

Optional

Request configuration options, outlined here: https://googleapis.github.io/gax-nodejs/global.html#CallOptions.

callback

The callback function.

Inherited from
DatastoreRequest#save
Throws

If an unrecognized method is provided.

Example

//-
// Save a single entity.
//
// Notice that we are providing an incomplete key. After saving, the original
// Key object used to save will be updated to contain the path with its
// generated ID.
//-
var key = datastore.key('Company');
var entity = {
  key: key,
  data: {
    rating: '10'
  }
};

datastore.save(entity, function(err) {
  console.log(key.path); // [ 'Company', 5669468231434240 ]
  console.log(key.namespace); // undefined
});

//-
// Save a single entity using a provided name instead of auto-generated ID.
//
// Here we are providing a key with name instead of an ID. After saving, the
// original Key object used to save will be updated to contain the path with
// the name instead of a generated ID.
//-
var key = datastore.key(['Company', 'donutshack']);
var entity = {
  key: key,
  data: {
    name: 'DonutShack',
    rating: 8
  }
};

datastore.save(entity, function(err) {
  console.log(key.path); // ['Company', 'donutshack']
  console.log(key.namespace); // undefined
});

//-
// Save a single entity with a provided namespace. Namespaces allow for
// multitenancy. To read more about this, see
// [the Datastore docs on key concepts](https://goo.gl/M1LUAu).
//
// Here we are providing a key with namespace.
//-
var key = datastore.key({
  namespace: 'my-namespace',
  path: ['Company', 'donutshack']
});

var entity = {
  key: key,
  data: {
    name: 'DonutShack',
    rating: 8
  }
};

datastore.save(entity, function(err) {
  console.log(key.path); // ['Company', 'donutshack']
  console.log(key.namespace); // 'my-namespace'
});

//-
// Save different types of data, including ints, doubles, dates, booleans,
// blobs, and lists.
//
// Notice that we are providing an incomplete key. After saving, the original
// Key object used to save will be updated to contain the path with its
// generated ID.
//-
var key = datastore.key('Company');
var entity = {
  key: key,
  data: {
    name: 'DonutShack',
    rating: datastore.int(10),
    worth: datastore.double(123456.78),
    location: datastore.geoPoint({
      latitude: 40.6894,
      longitude: -74.0447
    }),
    numDonutsServed: 45,
    founded: new Date('Tue May 12 2015 15:30:00 GMT-0400 (EDT)'),
    isStartup: true,
    donutEmoji: new Buffer('\uD83C\uDF69'),
    keywords: [
      'donut',
      'coffee',
      'yum'
    ]
  }
};

datastore.save(entity, function(err, apiResponse) {});

//-
// Use an array, `excludeFromIndexes`, to exclude properties from indexing.
// This will allow storing string values larger than 1500 bytes.
//-
var entity = {
  key: datastore.key('Company'),
  excludeFromIndexes: [
    'description',
    'embeddedEntity.description',
    'arrayValue[]',
    'arrayValue[].description'
  ],
  data: {
    description: 'Long string (...)',
    embeddedEntity: {
      description: 'Long string (...)'
    },
    arrayValue: [
      'Long string (...)',
      {
        description: 'Long string (...)'
      }
    ]
  }
};

datastore.save(entity, function(err, apiResponse) {});

//-
// Save multiple entities at once.
//-
var companyKey = datastore.key(['Company', 123]);
var productKey = datastore.key(['Product', 'Computer']);
var entities = [
  {
    key: companyKey,
    data: {
      HQ: 'Dallas, TX'
    }
  },
  {
    key: productKey,
    data: {
      vendor: 'Dell'
    }
  }
];

datastore.save(entities, function(err, apiResponse) {});

//-
// Explicitly attempt to 'insert' a specific entity.
//-
var userKey = datastore.key(['User', 'chilts']);
var entity = {
  key: userKey,
  method: 'insert',
  data: {
    fullName: 'Andrew Chilton'
  }
};

datastore.save(entity, function(err, apiResponse) {});

//-
// If the callback is omitted, we'll return a Promise.
//-
datastore.save(entity).then(function(data) {
  var apiResponse = data[0];
});

transaction

transaction(options) returns Transaction

Create a new Transaction object.

Parameter

options

Optional

object

Configuration object.

Returns

Transaction 

Example

const Datastore = require('@google-cloud/datastore');
const datastore = new Datastore();
const transaction = datastore.transaction();

update

update(entities, callback)

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

Parameter

entities

Datastore key object(s).

callback

The callback function.

Inherited from
DatastoreRequest#update

upsert

upsert(entities, callback)

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

Parameter

entities

Datastore key object(s).

callback

The callback function.

Inherited from
DatastoreRequest#upsert