Datastore
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
.
Constructor
Datastore
new Datastore(options)
Parameter |
|||||||
---|---|---|---|---|---|---|---|
options |
Optional object Configuration options. Values in
|
- Extends
- DatastoreRequest
- See also
Examples
Import the client library
const {Datastore} = require('@google-cloud/datastore');
<caption>Create a client that uses <a
href="https://cloud.google.com/docs/authentication/production#providing_credentials_to_your_application">Application
Default Credentials (ADC)</a>:</caption> const datastore = new Datastore();
<caption>Create a client with <a
href="https://cloud.google.com/docs/authentication/production#obtaining_and_providing_service_account_credentials_manually">explicit
credentials</a>:</caption> 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, (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 {@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
}, (err) => {
if (!err) {
// Record saved successfully.
}
});
//-
// We can verify the data was saved by using {@link 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 {@link 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
// {@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((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);
});
Properties
DatastoreRequest
constructor
DatastoreRequest class.
- See also
- DatastoreRequest
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.
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.
Query
constructor
Query class.
- See also
- Query
Transaction
constructor
Transaction class.
- See also
- Transaction
v1
object
Property
Parameter |
|
---|---|
DatastoreClient |
constructor Reference to v1.DatastoreClient. |
- See also
- v1.DatastoreClient
KEY
symbol
Access the Key from an Entity object.
namespace
string
projectId
string
Methods
double
double(value) returns object
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
geoPoint(coordinates) returns object
Helper function to get a Datastore Geo Point object.
Parameter |
|||||||
---|---|---|---|---|---|---|---|
coordinates |
object Coordinate value. Values in
|
- 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
int(value) returns object
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
isDouble(value) returns boolean
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
isGeoPoint(value) returns boolean
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
isInt(value) returns boolean
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
isKey(value) returns boolean
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
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. Values in
|
||||||||
callback |
The callback function. Values in
|
- Inherited from
- DatastoreRequest#allocateIds
Example
const 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, (err, keys) => {});
//-
// Or, if you're using a transaction object.
//-
const transaction = datastore.transaction();
transaction.run((err) => {
if (err) {
// Error handling omitted.
}
transaction.allocateIds(incompleteKey, 100, (err, keys) => {
if (err) {
// Error handling omitted.
}
transaction.commit((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.
//-
const incompleteKey = datastore.key({
namespace: 'ns-test',
path: ['Company']
});
function callback(err, keys, apiResponse) {}
datastore.allocateIds(incompleteKey, 100, callback);
//-
// Returns a Promise if callback is omitted.
//-
datastore.allocateIds(incompleteKey, 100).then((data) => {
const keys = data[0];
const 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
- Query
- Returns
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
const keys = [
datastore.key(['Company', 123]),
datastore.key(['Product', 'Computer'])
];
datastore.createReadStream(keys)
.on('error', (err) => {})
.on('data', (entity) => {
// entity is an entity object.
})
.on('end', () => {
// 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. Values in
|
- Inherited from
- DatastoreRequest#delete
Example
const key = datastore.key(['Company', 123]);
datastore.delete(key, (err, apiResp) => {});
//-
// Or, if you're using a transaction object.
//-
const transaction = datastore.transaction();
transaction.run((err) => {
if (err) {
// Error handling omitted.
}
transaction.delete(key);
transaction.commit((err) => {
if (!err) {
// Transaction committed successfully.
}
});
});
//-
// Delete multiple entities at once.
//-
datastore.delete([
datastore.key(['Company', 123]),
datastore.key(['Product', 'Computer'])
], (err, apiResponse) => {});
//-
// Returns a Promise if callback is omitted.
//-
datastore.delete().then((data) => {
const apiResponse = data[0];
});
insert
insert(entities, callback)
Maps to Datastore#save, forcing the method to be insert
.
Parameter |
|||||||||
---|---|---|---|---|---|---|---|---|---|
entities |
Datastore key object(s). Values in
|
||||||||
callback |
The callback function. Values in
|
- Inherited from
- DatastoreRequest#insert
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. Values in
|
- Inherited from
- DatastoreRequest#runQueryStream
Example
datastore.runQueryStream(query)
.on('error', console.error)
.on('data', (entity) => {
// Access the Key object for this entity.
const key = entity[datastore.KEY];
})
.on('info', (info) => {})
.on('end', () => {
// 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', (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). Values in
|
||||||||||
gaxOptions |
Optional Request configuration options, outlined here: https://googleapis.github.io/gax-nodejs/global.html#CallOptions. |
||||||||||
callback |
The callback function. Values in
|
- 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.
//-
const key = datastore.key('Company');
const entity = {
key: key,
data: {
rating: '10'
}
};
datastore.save(entity, (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.
//-
const key = datastore.key(['Company', 'donutshack']);
const entity = {
key: key,
data: {
name: 'DonutShack',
rating: 8
}
};
datastore.save(entity, (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.
//-
const key = datastore.key({
namespace: 'my-namespace',
path: ['Company', 'donutshack']
});
const entity = {
key: key,
data: {
name: 'DonutShack',
rating: 8
}
};
datastore.save(entity, (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.
//-
const key = datastore.key('Company');
const 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: Buffer.from('\uD83C\uDF69'),
keywords: [
'donut',
'coffee',
'yum'
]
}
};
datastore.save(entity, (err, apiResponse) => {});
//-
// Use an array, `excludeFromIndexes`, to exclude properties from indexing.
// This will allow storing string values larger than 1500 bytes.
//-
const 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, (err, apiResponse) => {});
//-
// Save multiple entities at once.
//-
const companyKey = datastore.key(['Company', 123]);
const productKey = datastore.key(['Product', 'Computer']);
const entities = [
{
key: companyKey,
data: {
HQ: 'Dallas, TX'
}
},
{
key: productKey,
data: {
vendor: 'Dell'
}
}
];
datastore.save(entities, (err, apiResponse) => {});
//-
// Explicitly attempt to 'insert' a specific entity.
//-
const userKey = datastore.key(['User', 'chilts']);
const entity = {
key: userKey,
method: 'insert',
data: {
fullName: 'Andrew Chilton'
}
};
datastore.save(entity, (err, apiResponse) => {});
//-
// Returns a Promise if callback is omitted.
//-
datastore.save(entity).then((data) => {
const apiResponse = data[0];
});
transaction
transaction(options) returns Transaction
Create a new Transaction object.
Parameter |
|||||||
---|---|---|---|---|---|---|---|
options |
Optional object Configuration object. Values in
|
- Returns
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). Values in
|
||||||||
callback |
The callback function. Values in
|
- Inherited from
- DatastoreRequest#update
upsert
upsert(entities, callback)
Maps to Datastore#save, forcing the method to be upsert
.
Parameter |
|||||||||
---|---|---|---|---|---|---|---|---|---|
entities |
Datastore key object(s). Values in
|
||||||||
callback |
The callback function. Values in
|
- Inherited from
- DatastoreRequest#upsert