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

How to filter Google Content Store data based on a property that is an array using Java library

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

我目前生成了一组过滤器,一个用于数组中的每个必需字符串。然后我构建了一个复合过滤器以用于 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 云数据存储查询来过滤掉 属性 值是具有完全相同元素的特定数组的实体吗(不多不少,与订单无关)?也许通过某种大小过滤器或完全不同的 query/filter。或者我可以使用 GQL 吗?

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

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

您可以期待与 Query/Filter 和 GQL 相同的行为。

一个解决方法是将Array属性中的元素个数存储在单独的字段中,然后在Count[=51=上创建复合索引] 和数组 属性。那么您的查询可能类似于:

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

这将 return 所有其数组 属性 恰好有 3 个元素且数组 属性 具有任意顺序的 a、b 和 c 的实体。

您还必须确保新计数 属性 在实体 created/updated 时保持同步。

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

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