java - Google DataStore 与 objectify - HashMap 上的复合查询

标签 java google-app-engine google-cloud-datastore google-cloud-platform objectify

我使用 Google App Engine 作为 REST 服务后端,使用 Google dataStore 作为数据库,并使用 objectify 来访问数据存储。 我的实体中的属性之一是

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对其进行排序。

假设 map customAttrs 中的一个键是 city。现在,如果我只想过滤 city=London 的所有用户,它对我来说效果很好。但是,如果我尝试获取按创建时间排序的所有用户,则会返回异常并且不起作用。仅当我在文件 datastore-indexes.xml 中添加以下内容时,它才有效:

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

现在这将违背使用 HashMap 的目的,因为在这里我需要事先知道 customAttrs 中的字段。

那么有没有什么方法可以执行复合查询而不必事先知道字段?

编辑:

正如 Sai 的回答中提到的,如果不事先添加并将其添加到 datastore-indexes.xml 中,就无法执行这些类型的查询。

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

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

Map<String,String> customAttrs;

我将其定义为字符串列表

List<String> customAttrs;

这里存储的字符串的形式为“key:value”。例如,实体的列表可能是“city:abc”、“country:xyz”、“name:123”

在这种情况下,我只需要在 datastore-indexes.xml 中定义以下内容:

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

这对我来说很好,因为我无法对属性进行硬编码/预定义。我可以使用city=abc进行过滤

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

通过这种方法,我可以按任何一个参数进行过滤,并按创建时间对结果进行排序。

但这种方法的问题是我只能执行一种类型的自定义过滤器。 这意味着如果我想过滤城市是 abc 和国家是 xyz(如果我使用 map 方法,这将有效),我无法做到这一点。有什么办法可以做到吗。 所以基本上我的查询是,如果一个实体具有 List 属性,是否有办法过滤列表中具有字符串“str1”和“str2”的所有实体?

最佳答案

这与 Objectfy 无关,而是 Datastore 本身。每当您的查询搜索多个属性或像您提到的那样进行排序(对两个不同的属性进行搜索和排序)时,数据存储区都需要匹配的复合索引。数据存储区的设计使得所有查询都从单个索引获取结果以提高性能。也就是说,如果您允许提前不知道名称的动态属性,则实际上无法像您想要的那样执行查询。如果可以选择,您的应用程序应限制对这些动态属性的查询/排序,以便它们不需要复合索引。否则,您将不得不探索替代选项,例如全文搜索(AppEngine 的全文搜索或 Elasticsearch ),并查看它们是否对您的用例有帮助。

关于java - Google DataStore 与 objectify - HashMap 上的复合查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45322198/

相关文章:

java - 生产者/消费者线程根本没有输出数据

java - 谷歌应用引擎: CRUDing Instances

google-app-engine - 生成唯一 ID GAE 数据存储

java - 通过 Jackson 生成的 Json 应该按照 Json 元素值的排序顺序

java - java中使用正则表达式捕获变量

java - 如何使用 Hibernate 注释在连接表上创建索引?

python - Google App Engine 永远出现 NeedIndexError

python - Unicode解码错误: 'utf8' codec can't decode byte

google-app-engine - Objectify 库可以在 GAE 之外使用吗?

google-app-engine - 在 Google App Engine 中,Model.get(key) 和 Model.get_by_key_name(key_names) 有什么区别?