我在RavenDB中有两个集合:一个用于产品,另一个用于每个产品的定价策略。每种定价策略都按产品ID引用单个产品。例如,产品可能如下所示:
products/1
{
"Brand":"Dewalt",
"Model":"ABC123",
"Category":"Tools"
}
并且策略可能如下所示:
strategies/1
{
"ProductId":"products/1",
"PriceCalculation":{
"$type":"...",
"Margin":0.2
}
}
我需要能够通过其属性查询策略,还可以通过相关产品的属性查询策略。例如 - 返回具有特定边距的所有策略,其中产品属于特定类别。如果产品数据被非规范化并与策略一起存储,那么我可以简单地将产品属性添加到索引中。有没有办法在没有非规范化的情况下做到这一点?
我知道Include方法允许在结果集中包含引用的实体,这样就不必加载它们,但它不支持在包含的实体上进行查询。实时投影也是如此 - 它们允许在结果集中包含引用的实体,但不支持引用实体的属性查询。
我可以跨两个索引运行两个查询 - 一个用于策略,另一个用于产品,然后在产品ID上加入两个结果集。这种情况下的问题是产品集合可能并不总是与策略引用的产品集同步。更具体地说,产品集合可能包含比策略引用的产品更多的产品,因此查询可能会返回没有定价策略的产品,因此在结果集中占据一个位置时无法加入策略
如果我可以在Map函数中解析引用的实体,然后在索引中包含引用实体的属性,那么可行的方法是什么。
修改 我似乎在寻找这个:https://groups.google.com/d/msg/ravendb/k3qvdEb870U/95OWtjL3U3YJ
答案 0 :(得分:1)
经过一些实验,我发现最好的方法是使用Multi-Maps / Reduce Index。指定了两个地图功能,一个用于产品,另一个用于策略。 reduce函数按产品ID对两个结果集进行分组,然后在输出中合并。这个索引的声明有点尴尬,因为你必须确保结果的形状匹配 - 如果Raven自动使用覆盖选项这样做会很好。此外,在reduce函数中合并结果很不方便,因为您必须从组中选择一个来自所需map函数的值。总的来说,多地图/缩小索引允许将不同的集合连接到单个索引投影中。