RavenDB实现传统一对多反向关联查询的相关问题咨询
RavenDB反向关联批量查询解决方案
你对Include特性的理解和现有文档设计都没有问题,该需求完全可以通过单次数据库往返实现,不会产生n+1查询问题。
推荐方案:批量懒查询(无需修改现有结构)
RavenDB原生支持将多个查询打包为单个请求批量发送,全程仅需一次数据库往返,适配所有反向关联查询场景:
- 分别定义站点查询、告警查询两个懒查询,定义阶段不会发起网络请求
- 一次性触发两个查询的执行,单次往返拿到完整的站点、告警结果集
- 内存中按
siteId对告警分组,关联到对应站点对象即可,天然支持无告警的站点返回
示例代码(C#):
using var session = documentStore.OpenSession(); // 定义两个懒查询,支持按需添加过滤、分页条件 var lazySites = session.Query<Site>() // 可选添加站点过滤条件,例如:.Where(s => s.Region == "Asia") .Lazily(); var lazyAlarms = session.Query<Alarm>() // 可选过滤仅拉取返回站点对应的告警,减少数据传输 .Where(a => a.SiteId.In(lazySites.Select(s => s.Id))) .Lazily(); // 单次数据库往返拿到两个结果集 List<Site> allSites = lazySites.Value; List<Alarm> allAlarms = lazyAlarms.Value; // 内存关联站点与告警 Dictionary<string, List<Alarm>> alarmsBySite = allAlarms .GroupBy(a => a.SiteId) .ToDictionary(g => g.Key, g => g.ToList()); foreach (var site in allSites) { site.Alarms = alarmsBySite.TryGetValue(site.Id, out var alarms) ? alarms : new List<Alarm>(); }
备选方案:关联索引查询
如果数据量极大、内存关联开销较高,可创建同时映射Site和Alarm集合的多Map索引,查询时直接返回带告警列表的站点投影结果,同样仅需单次往返,缺点是需要额外维护索引资源。
内容的提问来源于stack exchange,提问作者Sven Eppler
相关产品推荐
相关产品推荐

