Repository navigation
Provide helper methods on entity.Key for Kind, parent, name, and ID #574
Description
Activity
- addedapi: datastoreIssues related to the Datastore API.Issues related to the Datastore API.
on May 9, 2015 Yeah this seems nice. I like this. Would this functionality mimic existing similar functionality from another gcloud library (python? ruby?) that we could take a look at? Or can we just run with this idea on our own?
I think the Python methods are modeled after
ext.dbandext.dbwhich is the closest we'll get to "being official" (see http://googlecloudplatform.github.io/gcloud-python/latest/datastore-keys.html and https://github.com/GoogleCloudPlatform/gcloud-python/blob/master/gcloud/datastore/key.py)I'll put this in queue for after #897 merges.
Here's what I've got. Look okay @jgeewax?
Your example
new Key({ path: ['Person', 'mom', 'Person', 'jim'] }) // returns: Key { namespace: undefined, path: [ 'Person', 'mom', 'Person', 'jim' ], name: 'jim', kind: 'Person', parent: Key { namespace: undefined, path: [ 'Person', 'mom' ], name: 'mom', kind: 'Person' } }
Example with extra level of hierarchy and numeric ID
new Key({ path: ['Person', 'mom', 'Person', 'jim', 'SmallPerson', 1] }) // returns: Key { namespace: undefined, path: [ 'Person', 'mom', 'Person', 'jim', 'SmallPerson', 1 ], id: 1, kind: 'SmallPerson', parent: Key { namespace: undefined, path: [ 'Person', 'mom', 'Person', 'jim' ], name: 'jim', kind: 'Person', parent: Key { namespace: undefined, path: [Object], name: 'mom', kind: 'Person' } } }
I don't spot anything crazy, but just to be sure -- this is a method that derives the results at eval time, right? Or is it duplicate information being stored?
At the time of instantiation, the parts of a key are split apart to create named properties for the given path array. So all of these things are stored in memory with the object. This is how all of our custom type constructors work.
The duplicate information, do you mean the path? I kept that around since I thought it would be unfair for the user to lose a reference to their original input.
- Ah, sorry, to be clear I'm basically saying... If I change one piece of information on this object, do the other pieces (that should be the same) change too ? Or is there only one way to change the information, and therefore they're always in sync ?
Gotcha. What types of changes should we support? We can prevent a parent from being overwritten for example, or just a kind, an ID, etc. Or, we allow everything.
We would have to compute the path when it's asked for or update it when one of its parts changes... probably easier to compute the path on request.
Here's a working constructor that allows anything to be changed and
pathwill follow:function Key(options) { this.namespace = options.namespace; if (options.path.length % 2 === 0) { var identifier = options.path.pop(); if (is.number(identifier)) { this.id = identifier; } else if (is.string(identifier)) { this.name = identifier; } } this.kind = options.path.pop(); if (options.path.length > 0) { this.parent = new Key(options); } // `path` is computed on demand to consider any changes that may have been // made to the key. Object.defineProperty(this, 'path', { enumerable: true, get: function () { return arrify(this.parent && this.parent.path) .concat([this.kind, this.name || this.id]); } }); } var key = new Key({ path: ['Person', 'mom', 'Person', 'jim'] }); console.log(key.path); // [ 'Person', 'mom', 'Person', 'jim' ] key.parent.name = 'sam'; console.log(key.path); // [ 'Person', 'sam', 'Person', 'jim' ] console.log(key.parent.path); // [ 'Person', 'sam' ]
The one case I can think of that isn't covered is if a user had an ID but now assigns a name. But then I'm back to how mutable we should allow a Key path to be?
Yep - the on-demand eval SGTM. Basically anything that is derived would ideally be on-demand evaluated... right? which would include ID / name, ie:
var key = new Key({ path: ['Person', 'mom', 'Person', 'jim'] }); console.log(key.path); // [ 'Person', 'mom', 'Person', 'jim' ] key.parent.name = null; key.parent.id = 1 console.log(key.path); // [ 'Person', 1, 'Person', 'jim' ] console.log(key.parent.path); // [ 'Person', 1 ]
Yeah that works fine. PR incoming!
27 remaining items
- added a commit that references this issue
on Feb 5, 2026 - added a commit that references this issue
on Feb 26, 2026 - added 2 commits that reference this issue
on Mar 5, 2026
(In reference to https://github.com/GoogleCloudPlatform/gcloud-node/blob/412598cad200198caaac5dbe83700fd1665b2102/lib/datastore/entity.js#L54)
It'd be really nice if we had some helper methods on the Key class, so that you could do the following...
Auto-generated ID example:
Specific name and parent example
Is this a reasonable request?