使用 RavenDB "Traditional"一对多查询



我知道RavenDB的include-特性。它允许我在一次到数据库的往返中立即获取被引用的文档。但我的问题是:我首先获取的文档不包括对"其他"的引用。文档。但是"他者"文档有对当前文档的引用。

想象一个我们在世界各地都有站点的设置。每个site可能触发不同的告警。每个alarm都通过siteId引用site

现在我想获得所有站点的列表,包括所有警报。但看起来,这在RavenDB中是不可能的?因为include只接受"路径";在site-Document中保存一个id(或一个id数组)到被引用的文档。

这可以通过在site'-document and referencing this array in中提供alarmIds数组来解决,包括. But in contrast to a lot of examples featuring stuff like an命令withlineItemswhere the order is a self contained thing, mysite '将运行数年,收集0到100万之间的警报。在我看来这是个坏主意。

当然我也可以反过来:通过sitesId查询所有的告警和include站点。但是这不会返回一个没有警报的站点。

所以这只是我这边的设计错误吗?我有什么误解吗?或者只是不可能在一个查询中做到这一点,并防止"n+1查询"?

public class A
{
public string Id { get; set; }
}
public class B
{
public string Id { get; set; }
public string A { get; set; }
}
public class MultiMapIndex : AbstractMultiMapIndexCreationTask<MultiMapIndex.Result>
{
public class Result
{
public string Id { get; set; }
public IEnumerable<string> Bs { get; set; }
}
public MultiMapIndex()
{
AddMap<A>(items => from a in items
select new Result {Id = a.Id, Bs = new string[0]});
AddMap<B>(items => from b in items
select new Result {Id = b.A, Bs = new[] {b.Id}});
Reduce = results => from result in results
group result by result.Id
into g
select new Result {Id = g.Key, Bs = g.SelectMany(r => r.Bs)};
}
}
[Fact]
public async Task TestCase()
{
using var store = GetDocumentStore();
await new MultiMapIndex().ExecuteAsync(store);
using (var session = store.OpenAsyncSession())
{
await session.StoreAsync(new B {A = "a/1"}, "b/0");
await session.StoreAsync(new A(), "a/1");
await session.StoreAsync(new A(), "a/2");
await session.SaveChangesAsync();
}
WaitForIndexing(store);
using (var session = store.OpenAsyncSession())
{
var results = await session.Query<MultiMapIndex.Result, MultiMapIndex>()
.Include(r => r.Bs)
.ToArrayAsync();
var before = session.Advanced.NumberOfRequests;
var bs = session.LoadAsync<B>(results[0].Bs);
Assert.Equal(before, session.Advanced.NumberOfRequests);
}
}

如果您确实选择查询所有Alarms,如您所提到的,
那么您可以在警报集合上创建一个Map-Reduce索引,该索引将按站点分组。
然后可以查询这个Map-Reduce索引并知道每个站点有或没有警报的计数…

https://demo.ravendb.net/demos/csharp/static-indexes/map-reduce-index

最新更新