为了了解这类查询如何工作(或不工作),了解数据存储区如何索引实体非常重要。当您插入具有列表属性的实体时,数据存储区会将每个列表条目拆分为单独的索引行。例如,以下实体:
Entity(User):
id=15
name="Jim"
interests=["Drinking", "Banjos"]
将在自动索引中产生以下索引条目:
(User, "id", 15, Key("User", 1))
(User, "name", "Jim", Key("User", 1))
(User, "interests", "Drinking", Key("User", 1))
(User, "interests", "Banjos", Key("User", 1))
如果您还在 (name,interests) 上定义了复合索引,则其中的条目将如下所示:
("Jim", "Drinking", Key("User", 1))
("Jim", "Banjos", Key("User", 1))
建立后,我们可以按顺序解决您的特定查询查询:
- 这是不可能的,因为每个条目都在自己的索引行上。您可以通过为每个兴趣子集创建一个包含一个条目的列表来对此进行索引,并对其进行平等查询,但随着兴趣数量的增加,这会迅速增长,因此如果您希望用户拥有超过,比如说,5个兴趣,或者除非你可以对这个问题施加更多的限制。
- 您可以使用“IN”过滤器 - 例如,'SELECT * FROM User WHERE Interests IN ["Drinking", "Banjos"]' - 这将匹配至少具有“Drinking”和“Banjos”之一作为兴趣的任何记录. 请注意,这将被 SDK 分解为多个相等子查询,因此它相当于执行与查询列表中的条目一样多的查询。
- 这是 1 的倒数。同样,这并不实际,除非您已将完整(排序的)兴趣列表存储为字符串,并且您准备对礼物列表的每个子集执行单独的查询。
- 如果我没记错的话,这与 2 相同 - 您正在寻找两组之间的任何交集,这是一个对称操作。
对于数字 1 和 3,您可以通过执行更粗略的过滤器(例如,搜索一个或两个兴趣)并过滤内存中的结果以获得精确匹配来解决问题。