解析:如何查询恰好包含两个对象的关系?

问题描述 投票:0回答:2

给定两个表:

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。听起来太复杂了。

执行此操作最有效的查询是什么?

swift parse-platform
2个回答
1
投票

显然你想要实现的目标没有一个简单的解决方案,因为 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
}

0
投票
// 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});
© www.soinside.com 2019 - 2024. All rights reserved.