简体   繁体   English

JSON的Google云数据存储对象树

[英]Google cloud datastore object trees from json

I'm probably missing something obvious, but I can't find a way to store a JSON object with descendants in such a way that the Datastore DB has a hierarchy of entities that can be queried. 我可能缺少一些显而易见的东西,但是我找不到一种方法来存储带有后代的JSON对象,使得Datastore DB具有可以查询的实体层次结构。 Example code: 示例代码:

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

const ot1 = {
  // The kind and ID for the new entity
  key: datastore.key(['OT', '1']),
  data: {
    obj: [
      {
        var1: 'var1',
        var2: 'var2',
      },
      {
        var3: [{obj2:'var3'}, 'var5'],
        var4: 'var4',
      },
    ] // obj
  } // data
};

datastore.save(ot1);

If I now check my Datastore, it contains one entity 'obj' of type Array (as expected), but the value is one big JSON blob representing the array, ie I cannot drill down into descendant objects (which are obj[0] , obj[1] , obj[1].var3 , and obj[1].var3[0] ) from the Datastore console (whereas with AWS DynamoDB, and same JSON, I am able to drill down -- as though it handles the conversion from JS objects to DB format automatically). 如果现在检查我的数据存储,它包含一个类型为Array的实体“ obj”(如预期的那样),但是该值是代表该数组的一个大JSON Blob,即我无法下钻到后代对象(它们是obj[0] ,数据存储区控制台中的obj[1]obj[1].var3obj[1].var3[0] )(而使用AWS DynamoDB和相同的JSON,我可以向下钻取-就像它处理了自动从JS对象转换为DB格式)。 Yet, the docs indicate that the parent of an entity cannot be changed after entity created, so the parent entity has to be created before the child entity. 但是,文档指出,实体的父实体在创建实体后无法更改,因此必须在子实体之前创建父实体。 It seems like the API requires that I save in multiple steps: 看来API要求我分多个步骤保存:

  1. Save root object, with empty list 保存带有空列表的根对象
  2. Save each child of root, setting their parent to root ( obj ); 保存root的每个子代,将其父代设置为root( obj ); not clear how to add each child to the array; 不清楚如何将每个子级添加到数组中; obj[1] would have empty Array as var3 property value obj[1]将具有空数组作为var3属性值
  3. Save each element of obj[1].var3 array, setting their parent to obj[1] ; 保存obj[1].var3数组的每个元素,并将其父元素设置为obj[1] same issue about array 关于数组的相同问题

This is a lot of work, surely there is a library function that does this automatically, but I am unable to find one. 这是很多工作,肯定有一个库函数可以自动执行此操作,但是我找不到它。 And I'm not sure what this would look like in Datastore console, I suspect you would end up with 4 objects, ie hierarchy would only be indirectly known by observing the parent properties. 而且我不确定在Datastore控制台中会是什么样子,我怀疑您最终会有4个对象,即只能通过观察父属性来间接了解层次结构。

Update : I suspect the answer is to use an ORM like js-data. 更新 :我怀疑答案是使用像js-data这样的ORM。

IMHO it's not possible to automatically store the json data in a structured format without specifying that structured format - how would it be decided if a particular data portion should be indeed a separate entity or plain dumped in the same entity? 恕我直言,在不指定结构化格式的情况下无法自动以结构化格式存储json数据-如何确定某个特定数据部分的确应该是一个单独的实体还是应在同一实体中简单地转储? - either one can be desirable depending on the application. -根据应用情况,可以选择其中一个。

Not entirely sure about go (I'm not a go user), but python has support for Structured Properties which allow querying below the property level. 不能完全确定go(我不是go用户),但是python支持结构化属性 ,该属性允许在属性级别以下进行查询。

I see that go supports Structured Properties as well, but I found no good reference about querying and bulk-filling them. 我看到go也支持结构化属性 ,但是我找不到关于查询和批量填充它们的很好的参考。 From Properties and value types : 属性和值类型

You can also use a struct or slice to aggregate properties. 您也可以使用structslice来聚合属性。 See the Cloud Datastore reference for more details. 有关更多详细信息,请参见Cloud Datastore参考

This would be a somehow similar question, but for python (it does involve specifying the structured format): What is the best practice to populate a StructuredProperty through the ndb.Model constructor? 这在某种程度上将是一个类似的问题,但对于python(确实涉及指定结构化格式): 通过ndb.Model构造函数填充StructuredProperty的最佳实践是什么? Maybe a similar approach can be applied in go. 也许可以采用类似的方法。

I think this may be relevant, too: datastore: retrieving an entity's key as a struct field #453 认为这也可能有关: 数据存储区:检索实体的键作为struct字段#453

You said: 你说:

"the parent of an entity cannot be changed after entity created, so the parent entity has to be created before the child entity" “实体的父实体在创建实体后不能更改,因此必须在子实体之前创建父实体”

But I think it is not exactly like this since documentation says... 但是我认为这并不完全像这样,因为文档说...

"Because it is part of the entity's key, the identifier is associated permanently with the entity and cannot be changed ." “因为它是实体密钥的一部分, 所以标识符与该实体永久关联,并且不能更改 。” [1] [1]

and also: 并且:

"When you create an entity, you can optionally designate another entity as its parent; the new entity is a child of the parent entity (note that unlike in a file system, the parent entity need not actually exist )." “创建实体时,可以选择将另一个实体指定为其父实体;新实体是父实体的子实体(请注意,与文件系统不同, 父实体实际上不必存在 )。” [2] [2]

Anyway, if you can't work like you want in your language (Node.js) and the solutions provided by Dan Cornilescu are not enough for you (or even if they are), you always can open a future request here about your Cloud Datastore concerns in the Google's issuetracker with component "Public Trackers > Cloud Platform > Storage and Databases > Cloud Datastore", (like this [3] ) 无论如何,如果您无法使用自己的语言(Node.js)进行所需的工作,而Dan Cornilescu提供的解决方案对您来说(甚至即使不够),您仍然可以在此处针对您的Cloud提出未来的要求Google的IssueTracker中的数据存储带有组件“ Public Trackers> Cloud Platform>存储和数据库> Cloud Datastore”,(例如[3]

1.- https://cloud.google.com/datastore/docs/concepts/entities#kinds_and_identifiers 1.- https://cloud.google.com/datastore/docs/concepts/entities#kinds_and_identifiers

2.- https://cloud.google.com/datastore/docs/concepts/entities#ancestor_paths 2.- https://cloud.google.com/datastore/docs/concepts/entities#ancestor_paths

3.- https://issuetracker.google.com/issues/new?component=187197&template=1010240 3.- https://issuetracker.google.com/issues/new?component=187197&template=1010240

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM