C# 在Redis中搜索用户并按最多的共同好友数排序?

C# 在Redis中搜索用户并按最多的共同好友数排序?,c#,sql,.net,sql-server,redis,C#,Sql,.net,Sql Server,Redis,我有一个500万用户的潜在数据库,每个用户都有一定数量的朋友。我需要做的是实现搜索,这样用户可以根据某些属性(即其他用户的性别等)进行过滤,这一部分相当简单 用户A搜索所有男性并获得结果集。用户B、用户C、用户D 但是,用户还应该可以选择按用户A与结果集中所有用户的共同好友数对搜索结果进行排序 假设 用户A和用户B=3个共同的朋友 用户A和用户C=8个共同的朋友 用户A和用户D=5个共同的朋友 然后,搜索应按以下顺序对结果进行排序 用户C、用户D、用户A 除此之外,由于结果将显示在网页上,我还需

我有一个500万用户的潜在数据库,每个用户都有一定数量的朋友。我需要做的是实现搜索,这样用户可以根据某些属性(即其他用户的性别等)进行过滤,这一部分相当简单

用户A搜索所有男性并获得结果集。用户B、用户C、用户D

但是,用户还应该可以选择按用户A与结果集中所有用户的共同好友数对搜索结果进行排序

假设
用户A和用户B=3个共同的朋友
用户A和用户C=8个共同的朋友
用户A和用户D=5个共同的朋友

然后,搜索应按以下顺序对结果进行排序

用户C、用户D、用户A

除此之外,由于结果将显示在网页上,我还需要对分页的支持,这样每次用户在搜索结果之间导航时,都不会处理大约500万条条目


web代码是用C#编写的,但在数据库方面,我非常开放,可以使用SQL、NoSQL或Redis。主要优先考虑的是高性能,因此Redis似乎是一个不错的选择。如何从数据存储和伪代码的角度实现这样的搜索要求?

在redis中,您可能希望将其存储在
zset
中;红色中没有内置的自动索引,因此在添加或删除好友时需要
zadd
zincrby
zincrby
减去负数)。然后您只需
zrange
zrangebyscore
来查询它。这些方法都可以在NuGet上的
StackExchange.Redis
包中的
SortedSet
前缀下使用。

我的2美分

如果您将性别索引作为一个集合进行维护,并且每个用户的共同好友数作为一个分类集(分数是共同好友数),则可以利用ZINTERSTORE。 此外,每个用户还需要一组朋友

对于性别,使用键格式为:
gender:{gender}
的集合,每个项都是用户id

对于朋友,请使用密钥格式为:
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;
}
静态IEnumerable GetUsersByGenderDerbyMutualFriends(字符串用户,字符串性别)
{
var db=mux.GetDatabase();
var tempKey=“temp”;
SortedSetCombineAndStore(SetOperation.Intersect,tempKey,$“性别:{gender}”,$“相互:{user}”,Aggregate.Sum);
var result=db.SortedSetRangeByRank(tempKey,0,-1,Order.Descending);
db.KeyDelete(tempKey);
返回结果;
}
所谓“将其存储在zset中”,您的意思是存储每个用户配置文件还是存储共同的朋友?如果是共同的朋友,那么这不会创造出N x N个集合,5百万个集合将是5万亿个集合。你能再详细说明一下你的方法吗?