在App Engine中,有没有办法获得所有子实体而不包括相同类型的父实体?

时间:2015-04-24 07:43:33

标签: java google-app-engine entity google-cloud-platform google-cloud-datastore

这是Datastore的这个父子结构

+ Entity:Place,ID:1 {'name':'Derp Region','type':'region'}
|
+---+ Entity:Place,ID:1a {'name':'Derpina Province','type','province'}
|
+---+ Entity:Place,ID:1b {'name':'Banana Province','type','province'}
|
+---+ Entity:Place,ID:1c {'name':'Potato Province','type','province'}

当尝试获取 Derp Region 的子项时,它在返回的数据中包含Derp Region,如下所示:

Derp Region
Derpina Province
Banana Province
Potato Province

不应该是这种情况。这是因为它们具有相同的Entity类型吗?

广告代码

DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();

Entity place = new Entity( "Place" , "1" );
place.setProperty( "name" , "Derp Region" );
place.setProperty( "type" , "region" );
datastore.put( place );

Key parentKey = KeyFactory.createKey( "Place" , "1" );

Entity placeA = new Entity( "Place" , "1a" , parentKey );
placeA.setProperty( "name" , "Derpina Province" );
placeA.setProperty( "type" , "province" );
datastore.put( placeA );

Entity placeB = new Entity( "Place" , "1b" , parentKey );
placeB.setProperty( "name" , "Banana Province" );
placeB.setProperty( "type" , "province" );
datastore.put( placeB );

Entity placeC = new Entity( "Place" , "1c" , parentKey );
placeC.setProperty( "name" , "Potato Province" );
placeC.setProperty( "type" , "province" );
datastore.put( placeC );

查询代码

DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();

Key parentKey = KeyFactory.createKey("Place", "1" );

Query placeQuery = new Query( "Place" ).setAncestor( parentKey ).addSort( "name" , SortDirection.ASCENDING );

PreparedQuery preparedQuery = datastore.prepare( placeQuery );

for( Entity result : preparedQuery.asIterable() )
    {
    resp.getWriter().println( result.getProperty( "name" ) );
    }

有没有办法让所有子实体不包含相同类型的父实体?

1 个答案:

答案 0 :(得分:0)

'祖先查询'不是儿童查询' - 虽然它很相似。将实体组视为树,将云数据存储视为密钥树文档数据库(而不仅仅是键值或文档数据库)。

祖先查询是指"让我看到这棵树中符合这些条件的每个实体"。 "这棵树"是由parentKey指定的那个,你的条件是" Kind = Place"。一旦理解了这个概念,这种类型的查询与"子查询的区别就越清楚了。

通常,这可以忽略,因为parentKey不符合Kind条件。这是第一个解决方案:使父级和子级实体具有不同的种类 - 例如PlaceRegionPlaceProvince,或者如果类型不与父Place和{{1}相关联}

第二种解决方案是通过索引。添加一个名为PlaceChild的整数字段,并根据树中的级别为其分配值。 1 =根/父,2 =直系子。创建包含此level字段的复合索引,现在您可以使用条件level发出查询以执行子查询。

第三个解决方案只是按level = 2 = key进行过滤,并弃置父级。