Repository navigation
Datastore Key is not returned on runQuery with new entity change #1768
Description
Activity
Sorry about that. It looks like we haven't done a release since we updated the docs. We left behind many examples that were invalidated when we switched from the nested object.
The way to get the key is by using a special property (a
Symbolwe provide):var key = entity[datastore.KEY]
Sorry for the confusion, we should have a new release out soon so the docs can be refreshed.
Reacted by Fritz, Colin McDonnell and maadhaarReacted by Chris Russell- addedtype: questionRequest for information or clarification. Not an issue.Request for information or clarification. Not an issue.api: datastoreIssues related to the Datastore API.Issues related to the Datastore API.
on Nov 3, 2016 Can I ask what the benefit of changing
entity.keytoentity[datastore.KEY]is? It seems pretty unconventional to me and it breaks a lot of my code.Does not work, I tried the new way, and you can't get the key back via query.
The key is undefined for me when I used
entity[datastore.KEY].I am using "@google-cloud/datastore": "1.0.0".
// Batch get datastore.get(userKeys).then((userEntities) => { var entity = userEntities[0]; var key = entity[datastore.KEY]; // undefined });Update (there's no problem)
It turns out that there was an outer array that I had to access first. Examples in the docs also showed that you had to access element zero; I was tripped up because I was doing a batch get. I do wonder why there's a need for the outer array though.datastore.get(userKeys).then((result) => { var entities = result[0]; var firstEntity = entities[0]; var firstEntityKey = firstEntity[datastore.KEY]; });To illustrate:
If you pass in one key toget, the result is [entity] (if the entity exists).
If you pass in an array of keys toget, e.g. [key1, key2], the result is [ [entity1, entity2] ]Reacted by Laurent Pellegrino, Dan Arias, Davey, Luis Van Slageren, Andreas Lundgren, PG.Chief, Jorge Garcia, Austin (Thang Pham) and Bug-ReaperReacted by Dan Arias, Davey, Andreas Lundgren and Tom PiccirelloThanks for writing that up. Here are all the ways to use
get()and the results they give:// Callback with a single key datastore.get(key1, function(err, entity) { // entity = { key1's data object } }) // Callback with multiple keys datastore.get([key1, key2], function(err, entities) { // entities = [ // { key1's data object }, // { key2's data object } // ] }) // Promise with a single key datastore.get(key1) .then(function(data) { var entity = data[0] // entity = { key1's data object } }) // Promise with multiple keys datastore.get([key1, key2]) .then(function(data) { var entities = data[0] // entities = [ // { key1's data object }, // { key2's data object } // ] })
The history
Before we supported callbacks, we wanted
getto "make sense". So if you were only looking one thing up, you wouldn't get a pointless array back. We just wanted to give the thing you wanted.Our callbacks have a consistent signature, where possible:
method(function (err, thingOrThingsYouWanted, apiResponse) {})Because of that third argument,
apiResponse, we had two choices for the signature for promises:method() .then(function(data) { // an array: data = [ thingOrThingsYouWanted, apiResponse ] // an object: data = { thingOrThingsYouWanted: thingOrThingsYouWanted, apiResponse: apiResponse } })
The array was decided to be the best option. Because of that,
datastore.get([key1, key2])in promise mode ends up with an array inside an array. I'm not sure that we should remove that behavior, because it would be inconsistent from the rest of our API. (See #2167)Reacted by Maxime LironStephen, many thanks for the detailed explanation and sharing about the history. Now I understand why there is an array inside an array for the promise call. I'll comment on #2167.
Reacted by Stephen and Maxime Liron@mrkevinze You saved my life! I don't even remember how I got to this result, but I am glad I did! I am still trying to understand the mechanics of Google Datastore.
How do I get the keys of the entities if I use a query? I have a function like this
getByFiltersWithLimit( entityName, filters, limit, cursor )
{
let query = datastore.createQuery( entityName ).limit(limit);
filters.map( function( item ){
query.filter( item.param, item.operator, item.value )
});
if (cursor)
{
query = query.start(cursor);
}
return datastore.runQuery(query);
}
getByFiltersWithLimit(...).then(response=>{
var results = response[0];
var key = results[0][datastore.KEY]
})I tried to get the results key as above. But the resulting key is an object and it doesn't have my datastore key it has something like this
{"id":"4795031705616384","kind":"MyEntity","path":["MyEntity","4795031705616384"]}Can anyone help me with this?
@melvinmeshach-full greetings! Would you mind opening a new issue? It will make finding and answering much easier :)
- Sure will open a new one.Reacted by Justin Beckwith
took an hour to find out how to get the key from an entity using this odd syntax. Node.js docs for Datastore are quite frustrating.
Reacted by Bug-Reaper4 years later and this issue thread is the best documentation I could find explaining how to access the key from a queried entity result. You know, only useful if you ever need to do something arbitrary like update an existing entity or something.
Reacted by Ahmed Khalil- added 2 commits that reference this issue
on Feb 25, 2026 - added a commit that references this issue
on Mar 17, 2026 - added a commit that references this issue
on Mar 18, 2026
With the new change to Datastore where runQuery returns entities instead of the old nested json object, there seems to be no way to retrieve the key along with the entity.
I'm currently returning a list of 40 entities at a time with no way to save the ID's with the entities. I'm mapping into a GraphQL server where the ID's are used as part of the cursors.
The documentation has no information on this. Is there an option or am I missing something?
Thanks