我的两分钱。
如果您将性别索引保持为一个集合,您可以利用 ZINTERSTORE,并且每个用户的共同朋友计为一个 SortedSet(分数是共同朋友计数)。
此外,每个用户还需要一组朋友。
对于性别,请使用具有密钥格式的 Set:gender:{gender},每个项目都是一个用户 ID。
对于朋友,请使用带有密钥格式的 Set:friends:{userId},每个项目都是一个用户 ID。
对于共同的朋友,使用密钥格式为:mutual:{userId} 的 SortedSet,每个项目将是一个用户 ID,分数将是共同朋友的数量。
所以,当你添加一个用户时:
void AddUser(string user, string gender)
{
// Add to a gender set "gender:{gender}"->{users}
db.SetAdd($"gender:{gender}", user);
}
添加两个用户之间的友谊:
void AddFriendship(string user1, string user2)
{
// All friends of user1, should increment its mutual count with user2
var user1Friends = db.SetMembers($"friends:{user1}");
foreach(var user1Friend in user1Friends)
{
db.SortedSetIncrement($"mutual:{user1Friend}", user2, 1);
db.SortedSetIncrement($"mutual:{user2}", user1Friend, 1);
}
// All friends of user2, should increment its mutual count with user1
var user2Friends = db.SetMembers($"friends:{user2}");
foreach (var user2Friend in user2Friends)
{
db.SortedSetIncrement($"mutual:{user2Friend}", user1, 1);
db.SortedSetIncrement($"mutual:{user1}", user2Friend, 1);
}
// Add to friend sets "friends:{user}->{users}"
db.SetAdd($"friends:{user1}", user2);
db.SetAdd($"friends:{user2}", user1);
}
并按共同好友数量排序的性别获取用户:
static IEnumerable<string> GetUsersByGenderOrderByMutualFriends(string user, string gender)
{
var db = mux.GetDatabase();
var tempKey = "temp";
db.SortedSetCombineAndStore(SetOperation.Intersect, tempKey, $"gender:{gender}", $"mutual:{user}", Aggregate.Sum);
var result = db.SortedSetRangeByRank(tempKey, 0, -1, Order.Descending).Select(x => x.ToString());
db.KeyDelete(tempKey);
return result;
}