1

我正在使用Google App Engine作为我的REST服务后端,Google dataStore作为数据存储并将其作为访问数据存储的对象。 一个在我的实体的属性是带有objectify的Google DataStore - HashMap上的复合查询

Map<String,String> customAttrs; 

这是因为我不事先知道所有的参数可以来自客户端。我的要求是我希望能够在HashMap中对这些参数进行索引。 我看着下面的问题:

GAE w/ Objectify - Can you query a HashMap?

,并试图有什么在接受答复中提到,它为我工作,我能够基于在customAttrs属性的索引使用

filter("customAttrs .key1", "value1") 

根据客户端在REST API调用中传递的任何查询参数。

但是,问题出现在复合查询的情况下。我对此不了解太多,但根据我的理解,如果将排序或不等式筛选器与另一个筛选器结合使用,则必须在名为 datastore-indexes.xml的文件中定义组合。所以实体中的一个字段是creationTime,当我做任何查询时会返回一个用户列表,我想用creationTime对它进行排序。

那么我们来说说一个在地图customDaker中的钥匙城市。现在,如果我只想过滤所有说城市=伦敦的用户,它对我来说工作得很好。但是,如果我试图让所有用户在城市=伦敦排序creationTime,它会返回一个异常,不起作用。

<datastore-index kind="User" ancestor="false" source="manual"> 
     <property name="customAttrs.city" direction="asc" /> 
     <property name="creationTime" direction="asc" /> 
    </datastore-index> 

现在,这会损害使用HashMap的,因为在这里我需要知道里面前手customAttrs领域的目的:如果我添加的文件数据存储- indexes.xml下它才起作用。

那么有什么方法可以执行组合查询,而无需事先知道这些字段?

编辑:

如在由西答案提到的,有没有办法来执行这些类型的查询,没有前手将它和datastrore-indexes.xml添加。

我想到了另一种方法,但我面临着不同的问题。

在这种方法中,而不是定义属性为

Map<String,String> customAttrs; 

我已经把它定义为字符串

List<String> customAttrs; 

这其中存储的字符串列表的形式是“重点:值”。例如,名单的实体可能是“城市:ABC”,“国家:XYZ”,“名称:123”

在这种情况下,我只需要定义我数据存储的索引以下.XML

<datastore-index kind="User" ancestor="false" source="manual"> 
     <property name="customAttrs" direction="asc" /> 
     <property name="creationTime" direction="asc" /> 
    </datastore-index> 

这是为我好,因为我无处硬编码/预定义的属性,可能是什么。我能够通过城市= ABC使用

filter("customAttrs","city:abc") 

用这种方法,我可以通过这些参数中的任何一个过滤器,以及通过创建时间排序结果进行过滤。

但这种方法的问题是,我能够只做一种类型的自定义过滤器。 含义如果我想过滤城市是abc和国家是xyz(如果我使用Map方法,这是有效的),我无法做到这一点。有没有办法做到这一点。 所以基本上我的查询是,如果一个实体有一个属性是List,是否有一种方法来过滤所有那些在List中具有字符串“str1”和“str2”的实体?

回答

0

这与Objectfy无关,而是数据存储本身。只要您的查询在多个属性上搜索或像您提到的那样进行排序(搜索并排序两个不同的属性),Datastore就会期望匹配的组合索引。数据存储的设计使所有查询都可以从单个索引获得结果以提高性能。也就是说,如果您允许提前未知名的动态属性,就没有办法像您想要的那样执行查询。如果它是一个选项,你的应用程序应限制对这些动态属性的查询/排序,因此它们不需要组合索引。否则,您将不得不探索其他选项,例如全文搜索(AppEngine的全文搜索或弹性搜索),并查看它们是否有助于您的用例。

+0

谢谢。 我尝试了另一种方法来实现我的用例,但我面临着不同的问题。我已经更新了我的问题的细节。这可能使它与新方法一起工作吗? –

0

在过去的阵列性能上过滤你的最新问题 -

这是可以做到上的数组类型的AND查询,看看它是否包含两个或更多的元素。 GQL想 -

SELECT * FROM MyEntity WHERE ArrayProperty='value1' AND ArrayProperty='value2' 
+0

但我不知道它与objecitfy(这是我在我的代码中使用的) 我试过 'query = query.filter(“customAttrs”,“country:abc”)' 'query = query.filter(“customAttrs”,“city:xyz”)' 在这里,我有两个条目在我的数据库国家:abc但只有一个城市:xyz。但是,我得到了两个国家:abc –