如何根据使用Java库的数组属性过滤Google Content Store数据

时间:2017-08-15 13:47:25

标签: java google-cloud-datastore gql

我有一个数据存储区,其中一个属性包含一个字符串数组。每个实体可以具有该阵列的不同大小。我想进行查询并过滤每个实体中数组的内容。

我目前生成一组过滤器,一个用于数组中每个必需的字符串。然后,我构建一个在EntityQuery中使用的复合过滤器。过滤器的生成如下:

// arrayProperty is the name on the property in my Datastore that contains the array of strings.
List<PropertyFilter> pathFilters = Arrays.stream(new String[] {"a","b","c"})
    .map(s -> PropertyFilter.eq("arrayProperty", s))
    .collect(Collectors.toList());

然而,这将使用arrayProperty = [a,b,c]和arrayProperty = [a,b,c,d]匹配两个实体。

我是否可以在com.google.cloud.datastore中使用来自JAVA库的Google Cloud Datastore查询来过滤掉属性值为具有完全相同元素的特定数组的实体(不多,不少且与订单无关)?也许通过某种大小的过滤器或完全不同的查询/过滤器。或者我可以使用GQL吗?

1 个答案:

答案 0 :(得分:1)

您不能对Array属性执行相等过滤(或完全匹配)。您只能查询包含一个或多个单独元素的实体。根据您的示例数据([a, b, c][a, b, c, d]),可以进行以下查询:

  • arrayProperty="a" - 返回两个实体
  • arrayProperty="a" AND arrayProperty="b" - 返回两个实体
  • arrayProperty="a" AND arrayProperty="b" AND arrayProperty="c" - 返回两个实体
  • arrayProperty="a" AND arrayProperty="b" AND arrayProperty="c" AND arrayProperty="d" - 只返回一个实体
  • arrayProperty='x' - 两者都不匹配

您可以期望Query / Filter和GQL具有相同的行为。

一个解决方法是将Array属性中的元素数存储在单独的字段中,然后在Count属性和Array属性上创建复合索引。然后你的查询可能是这样的:

WHERE count=3 AND arrayProperty="a" AND arrayProperty="b" AND arrayProperty="c" 

这将返回其arrayProperty正好具有3个元素且arrayProperty以任何顺序具有a,b和c的所有实体。

您还必须确保在创建/更新实体时新的计数属性保持同步。

虽然这应该会产生预期的结果,但您的索引大小会更多。

您也可以选择将计数转储到原始数组字段(作为整数),假设您的数组中的主数据是String类型。使用此方法,您可以避免使用复合索引。