给定两个表:
Users
Groups
一个或多个用户可以属于一个组。每个组都包含一个与其所有用户的关系列。
如何查询在其关系字段中具有准确的用户列表的组?
我试过了
query.whereKey(users, containsAllObjectsInArray: [userA, userB])
但这给了我一个错误
Unsupported query operator on relation field: users (Code: 102, Version: 1.8.5)
另一方面,如果我使用
query.whereKey(users, containedIn: [userA, userB])
我还得到了比所需用户更多的群组。然后,我将循环遍历第一个查询中找到的所有组,并为每个组放置另一个查询,以检查该组的唯一成员是否是 userA + userB。听起来太复杂了。
执行此操作最有效的查询是什么?
显然你想要实现的目标没有一个简单的解决方案,因为 Parse 是为了可扩展性和速度而设计的,因此不直接支持复杂的模式匹配。使用
containsAllObjectsInArray
约束时出现的错误是因为该约束适用于 Array
类型的字段,但不能用于 Relation
字段。为了获得您想要的结果,您需要发挥一点创意。所以我想到了一个可以使用内部查询的解决方案。
首先,向您的
Number
类添加一个类型为 Group
的额外列(我们将其称为“计数器”)。此字段需要保留属于组的用户数量。因此,每次将用户添加到组中时,其值也会增加 1,而当您从该组中删除用户时,其值也会减少。在您的情况下,您可以使用此计数器值来快速找出哪一个组恰好有两个成员。
现在您可以编写一个查询,返回该计数器恰好为 2 且用户关系至少包含“user1”的组。这个查询将成为您的内部查询。您的主查询现在只需要检查此内部查询返回的内容,并仅选择用户关系也包含“user2”的记录。鉴于您的内部查询中满足“恰好有两个用户”条件,您最终会得到在其用户关系中恰好有两个用户(“user1”和“user2”)的所有组记录。
let innerQuery = PFQuery(className: "Groups")
innerQuery.whereKey("counter", equalTo: 2) // exactly two users
innerQuery.whereKey("users", equalTo: user1) // at least user1 is there
let query = PFQuery(className: "Groups")
query.whereKey("objectId", matchesQuery: innerQuery) // exactly two users including user1
query.whereKey("users", equalTo: user2) // select groups which also have user2
query.findObjectsInBackgroundWithBlock {
(comments: [PFObject]?, error: NSError?) -> Void in
// Groups with exactly two users, user1 and user2
}
// Create an array to hold subqueries
const subqueries = [];
// Create a subquery for each specific user
users.forEach(user => {
const Groups = Parse.Object.extend("Groups");
const query = new Parse.Query(Groups);
query.equalTo("users", user)
subqueries.push(query);
});
// Combine all subqueries with `Parse.Query.and`
const query = Parse.Query.and(...subqueries);
query.limit(batchSize);
// you will now get list of groups with specifically the 2 users
const results = await query.find({useMasterKey: true});