2017-08-15 74 views
1

我有一个数据存储区,其中一个属性包含一个字符串数组。每个实体可以具有该阵列的不同大小。我想对每个实体中的数组内容进行查询和过滤。如何基于使用Java库的阵列属性过滤Google Content Store数据

我目前生成一组过滤器,一个用于数组中的每个必需字符串。然后构建一个复合过滤器,用于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 Query过滤掉其属性值是特定数组且具有完全相同元素(不多,不少于独立顺序)的实体吗?也许通过某种尺寸过滤器或完全不同的查询/过滤器。或者我可以使用GQL?

回答

1

您无法对数组属性执行相等过滤器(或完全匹配)。您只能查询包含一个或多个单独元素的实体。从您的示例数据([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' - 两者都不匹配

您可以期待与查询/筛选器和GQL具有相同的行为。

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

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

这将返回其arrayProperty恰好有3件和arrayProperty有一个,b和c以任何顺序所有实体。

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

虽然这应该会给你想要的结果,但你的索引尺寸会更大。

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

+0

谢谢!不是我希望的答案,但不能为此责怪你! :-P –