这是这篇文章项目的延续。
我有以下模型:
public class Product
{
public string Id { get; set; }
public int CategoryId { get; set; }
public Dictionary<string, string> Specs { get; set; }
}
我想创建一个mapreduce索引,它按CategoryId对产品进行分组,然后聚合所有规格名称-值对。reduce函数的输出应该如下:
public class CategorySpecGroups
{
public int CategoryId { get; set; }
public SpecGroup[] SpecGroups { get; set; }
}
public class SpecGroup
{
public string Name { get; set; }
public SpecGroupValue[] Values { get; set; }
}
public class SpecGroupValue
{
public string Value { get; set; }
public int Count { get; set; }
}
在产品集合上支持分面搜索。输出类似于RavenDB分面搜索特性的FacetSetup文档。以下是索引的定义:
public class SpecGroups_ByCategoryId : AbstractIndexCreationTask<Product, CategorySpecGroups>
{
public SpecGroups_ByCategoryId()
{
this.Map = products => from product in products
where product.Specs != null
select new
{
CategoryId = product.CategoryId,
SpecGroups = from spec in product.Specs
select new
{
Name = spec.Key,
Values = new dynamic[] { new { Value = spec.Value, Count = 1 } }
}
};
this.Reduce = results => from categorySpecGroups in results
group categorySpecGroups by categorySpecGroups.CategoryId into g
select new
{
CategoryId = g.Key,
SpecGroups = from categorySpecGroups in g
from specGroup in categorySpecGroups.SpecGroups
group specGroup by specGroup.Name into g2
select new
{
Name = g2.Key,
Values = from specGroup in g2
from specGroupValue in specGroup.Values
group specGroupValue by specGroupValue.Value into g3
select new
{
Value = g3.Key,
Count = g3.Sum(x => x.Count)
}
}
};
}
}
保存此索引后,索引过程似乎运行,但输出缺少"SpecGroups"属性:
{
"CategoryId": "123"
}
我使用这个索引的目的是优化分面搜索特性。当仅按类别ID查询时,我可以使用该索引的输出返回facet结果,然后当按其他facet进行过滤时,可以使用该索引获取用于计算过滤结果集中的facet的术语。
我正在使用RavenDB Build 495。
我可以通过稍微改变模型来完成这个工作:
public class Product
{
public string Id { get; set; }
public int CategoryId { get; set; }
public ProductSpec[] Specs { get; set; }
}
public class ProductSpec
{
public string Key { get; set; }
public string Value { get; set; }
}
使用这个模型,问题中声明的MapReduce索引按预期工作,而且速度也很快!我认为潜在的问题是在编译了映射定义之后处理字典的方式。