加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – 在asp.net和ravendb中处理基于活动的feed的最佳

发布时间:2020-12-16 09:37:58 所属栏目:asp.Net 来源:网络整理
导读:我将为每个用户提供一个活动源,显示与用户订阅的事件相关的所有活动,并且Feed将引入最近的20个左右的活动.我设置的方式是所有活动,无论与其相关的事件是否存储在一个集合中,文档本身都有一个我查询和索引的“事件”属性.基本查询只是从集合中选择活动,其中事
我将为每个用户提供一个活动源,显示与用户订阅的事件相关的所有活动,并且Feed将引入最近的20个左右的活动.我设置的方式是所有活动,无论与其相关的事件是否存储在一个集合中,文档本身都有一个我查询和索引的“事件”属性.基本查询只是从集合中选择活动,其中事件在按日期排序的用户事件订阅列表中.我存储了用户事件订阅列表的哈希值,并使用哈希作为xx秒的密钥来缓存查询结果,因此如果另一个用户订阅了相同的确切事件,我可以从缓存中提取结果,我是不关心结果是xx秒陈旧.

编辑:添加模型和查询示例

楷模:

User
{
    // useless properties excluded
    // fixed: hashset not list,can be quite large
    HashSet<string> Subscriptions { get; set; }
    string SubscriptionHash { get; set; } // precomputed hash of all strings in subscriptions
}

Activity
{
    // Useless properties excluded
    string ActivityType { get; set; }
}

查询:

if (cache[user.SubscriptionHash] != null)
    results = (HashSet<Activity>)cache[user.SubscriptionHash];
else
    results = session.Query<Activity>().Where(user.Subscriptions.Contains(e => e.ActivityType)).Take(20).ToList();

// add results to cache

我担心的是,如果这是处理这个问题的最佳方法,或者是否有更好的ravendb伏都教可供使用.如果有很多活动,单个集合可能会增长到数百万,当有成千上万的用户拥有无限的订阅列表组合时,我可能会在缓存中存储数千个密钥.这些供稿位于用户登录页面上,所以它很多,我不想只是在这个问题上投入更多的硬件.

所以我真正想要的答案是,如果这是最好的查询,或者如果有更好的方法在Raven中使用list.Contains查询数百万个文档.

这是一个使用ravendb的asp.net 4.5 mvc 4项目.

解决方法

现在我将如何处理它.这是基于RaccoonBlog PostComments

我将每个用户事件存储在单独的文档中(即下面示例中的UserEvent),其中用户具有链接到它的附加属性以及与用户相关联的最后事件的多个事件和时间戳.这将使用户文档保持更小,但具有很多重要信息

在UserEvent中,它将是一个包含id的简单文档,指向此文档引用的用户标识的链接,“事件”集合和lasteventid.这样,如果需要,每个“事件”成为维护的子文档.

最后一个UserEvent索引,允许您轻松查询数据

public class User
{
    public string Id { get; set; }
    // other user properties

    public string UserEventId { get; set; }
    public int NumberOfEvents { get; set; }
    public DateTimeOffset LastEvent { get; set; }
}

public class UserEvent
{
    public string Id { get; set; }

    public string UserId { get; set; }

    public int LastEventId { get; set; }

    public ICollection<Event> Events { get; protected set; }

    public int GenerateEventId()
    {
        return ++LastEventId;
    }

    public class Event
    {
        public int Id { get; set; }
        public DateTimeOffset CreatedAt { get; set; }
        public string ActivityType { get; set; }
        // other event properties
    }
}

public class UserEvents_CreationDate : AbstractIndexCreationTask<UserEvent,UserEvents_CreationDate.ReduceResult>
{
    public UserEvents_CreationDate()
    {
        Map = userEvents => from userEvent in userEvents
                            from evt in userEvent.Events
                            select new
                            {
                                evt.CreatedAt,EventId = evt.Id,UserEventId = userEvent.Id,userEvent.UserId,evt.ActivityType
                            };
        Store(x => x.CreatedAt,FieldStorage.Yes);
        Store(x => x.EventId,FieldStorage.Yes);
        Store(x => x.UserEventId,FieldStorage.Yes);
        Store(x => x.UserId,FieldStorage.Yes);
        Store(x => x.ActivityType,FieldStorage.Yes);
    }

    public class ReduceResult
    {
        public DateTimeOffset CreatedAt { get; set; }
        public int EventId { get; set; }
        public string UserEventId { get; set; }
        public string UserId { get; set; }
        public string ActivityType { get; set; }
    }
}

public static class Helpers
{
    public static DateTimeOffset AsMinutes(this DateTimeOffset self)
    {
        return new DateTimeOffset(self.Year,self.Month,self.Day,self.Hour,self.Minute,self.Offset);
    }

    public static IList<Tuple<UserEvents_CreationDate.ReduceResult,User>> QueryForRecentEvents(
        this IDocumentSession documentSession,Func
            <IRavenQueryable<UserEvents_CreationDate.ReduceResult>,IQueryable<UserEvents_CreationDate.ReduceResult>
            > processQuery)
    {
        IRavenQueryable<UserEvents_CreationDate.ReduceResult> query = documentSession
            .Query<UserEvents_CreationDate.ReduceResult,UserEvents_CreationDate>()
            .Include(comment => comment.UserEventId)
            .Include(comment => comment.UserId)
            .OrderByDescending(x => x.CreatedAt)
            .Where(x => x.CreatedAt < DateTimeOffset.Now.AsMinutes())
            .AsProjection<UserEvents_CreationDate.ReduceResult>();

        List<UserEvents_CreationDate.ReduceResult> list = processQuery(query).ToList();

        return (from identifier in list
                let user = documentSession.Load<User>(identifier.UserId)
                select Tuple.Create(identifier,user))
            .ToList();
    }
}

然后你要做的就是查询.

documentSession.QueryForRecentEvents(q => q.Where(x => x.UserId == user.Id &&  x.ActivityType == "asfd").Take(20)).Select(x => x.Item1);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读