gpt4 book ai didi

asp.net-mvc - 在 asp.net 和 ravendb 中处理基于事件的提要的最佳方法

转载 作者:太空狗 更新时间:2023-10-30 01:57:51 29 4
gpt4 key购买 nike

我将为每个用户提供一个事件提要,显示与用户订阅的事件相关的所有事件,并且该提要将提取最近的 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 voodoo 可供使用。如果有很多事件,单个集合可能会增长到数百万个,并且当有成千上万的用户使用无穷无尽的订阅列表组合时,我可能会在缓存中存储数千个 key 。这些提要位于用户登录页面上,因此它受到了很多打击,我不想仅仅投入更多硬件来解决这个问题。

所以我真正想要的答案是,这是否是最好的查询,或者当我可以使用 list.Contains 查询数百万个文档时,是否有更好的方法在 Raven 中执行此操作。

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

最佳答案

下面是我将如何处理它。这是基于 RaccoonBlog PostComments

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

在 UserEvent 中,它将是一个包含 id 的简单文档、指向该文档引用的用户 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, 0, 0, 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);

关于asp.net-mvc - 在 asp.net 和 ravendb 中处理基于事件的提要的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13594816/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com