gpt4 book ai didi

ravendb - 使用 nosql 的事件存储性能注意事项

转载 作者:行者123 更新时间:2023-12-02 11:02:48 24 4
gpt4 key购买 nike

这可能是一个更常见的 NOSQL 基础设施问题。

通过事件源系统,我将事件文档保存到 ravendb。

在我的域模型中,有多种类型的事件,下面是一个基本示例:

public abstract class Event
{
public Guid AggregateId { get; set; }

public Event(Guid aggregateId)
{
AggregateId = aggregateId;
}
}

public class NewPersonEvent : Event
{
public string Name { get; set; }

public NewPersonEvent(Guid id, string name) : Base(id)
{
Name = name;
}
}

public class NewOrderEvent : Event
{
public DateTime OrderDate { get; set; }
public double OrderCost { get; set;}


public NewOrderEvent(Guid id, DateTime date, double cost) : Base(id)
{
OrderDate = date;
OrderCost = cost;
}
}

无论事件来自哪种类型的聚合,事件都会保留为事件文档。

这是在 ravendb 中对所有事件使用一种文档类型的最佳方法吗?或者按聚合对文档类型进行分组是否有任何好处

不要只包含“Event”文档,而是包含“PersonEvent”文档和“OrderEvent”文档。

这两种方法各有什么优缺点,具体来说是否存在性能问题?

最佳答案

您是否将事件的默认标记名称覆盖为...

docStore.Conventions.FindTypeTagName = type => typeof(Event).IsAssignableFrom(type) ? DocumentConvention.DefaultTypeTagName(typeof(Event)) : DocumentConvention.DefaultTypeTagName(type);

然后每当您对 Event 进行查询时它只是工作并检索所有事件。 session.Query<Event>()

如果是这样,你可能会搬起石头砸自己的脚,因为如果你只想要事件的子集,那么你就这样做 session.Query<NewPersonEvent>()它将检索所有事件,因为您一开始就覆盖了标签约定。您仍然可以采用另一种方式,但不会那么简单(例如,使用事件类型的枚举并按枚举进行过滤)。

我投票赞成不覆盖默认的 RavenDB 行为,将不同的事件类型保留为它们自己的文档集合,并简单地使用多映射索引。

Raven 文档指出静态索引优于动态索引,因此不应成为性能问题。 docs :

如果您不破坏标签约定,但您可以为事件的子集创建更多索引,创建映射/归约索引以聚合每个事件类型的计数等等。

该索引将是一个多 map 索引,您有 2 种风格可供选择。

选项 1

    public class Events_All : AbstractMultiMapIndexCreationTask
{
public Events_All()
{
AddMap<NewPersonEvent>(newPersonEvents =>
from newPersonEvent in newPersonEvents
select new
{
Id = newPersonEvent.AggregateId
});

AddMap<NewOrderEvent>(newOrderEvents =>
from newOrderEvent in newOrderEvents
select new
{
Id = newOrderEvent.AggregateId
});
}

}

选项 2(反射)

public class Events_All2 : AbstractMultiMapIndexCreationTask
{
public Events_All2()
{
AddMapForAll<Event>(events =>
from @event in events
select new
{
Id = @event.AggregateId
});
}
}

这是使用 RavenDB.Tests.Helpers 的示例测试和Shouldly NuGet 包。它使用第一个示例索引,但您也可以修改它以使用第二个索引。

    public class MultimapIndexTest : RavenTestBase
{
private readonly Random _random = new Random();

[Fact]
public void GetAll_HasBoth_Success()
{
//Arrange
const string personName = "Jimmy";
double randomCost = _random.Next();

var event1 = new NewPersonEvent(Guid.NewGuid(), personName);
var event2 = new NewOrderEvent(Guid.NewGuid(), DateTime.Now, randomCost);

using (var docStore = NewDocumentStore())
{
docStore.ExecuteIndex(new Events_All());

using (var sesion = docStore.OpenSession())
{
sesion.Store(event1);
sesion.Store(event2);
sesion.SaveChanges();
}

docStore.WaitForStaleIndexesToComplete();

//Act
var events = GetAll(docStore).ToList();

//Assert
events.ShouldNotBeEmpty();
events.Count().ShouldBe(2);

var newPersonEvent = events.FirstOrDefault(x => x is NewPersonEvent) as NewPersonEvent;
newPersonEvent.ShouldNotBe(null);
newPersonEvent.Name.ShouldBe(personName);

var newOrderEvent = events.FirstOrDefault(x => x is NewOrderEvent) as NewOrderEvent;
newOrderEvent.ShouldNotBe(null);
newOrderEvent.OrderCost.ShouldBe(randomCost);
}
}

private IEnumerable<Event> GetAll(DocumentStore docStore)
{
using (var session = docStore.OpenSession())
{
return session.Query<Event, Events_All>();
}
}
}

关于ravendb - 使用 nosql 的事件存储性能注意事项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26929947/

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