我有两种不同的对象类型存储在RavenDb中,它们是父/子类型关系,在
JSON中是这样的:
- Account/1
- {
- "Name": "Acc1",}
- Items/1
- {
- "Account": "Account/1","Value" : "100","Tags": [
- "tag1","tag2"]
- }
- Items/2
- {
- "Account": "Account/1","Value" : "50","Tags": [
- "tag2"]
- }
请注意,我不想将它们存储在同一文档中,因为一个帐户可能有数千个项目.
我正在尝试编写一个map / reduce索引,它会返回类似于:
- {
- "Account": "Acc1","TagInfo": [
- { "TagName" : "tag1","Count" : "1",//Count of all the "tag1" occurrences for acc1
- "Value" : "100" //Sum of all the Values for acc1 which are tagged 'tag1'
- },{ "TagName" : "tag2","Count" : "2",//Two items are tagged "tag2"
- "Value" : "150"
- }]
- }
我想我需要使用多地图将Account和Items集合映射到一起,但我无法找出reduce部分来创建结果的“TagInfo”部分.
这是可能的,还是我在Raven模拟这个错误?
编辑:
我想从这个查询中检索的类看起来像这样:
- public class QueryResult
- {
- public string AccountId {get;set;}
- public TagInfo Tags {get;set;}
- }
- public class TagInfo
- {
- public string TagName {get;set;}
- public int Count {get;set;}
- public int TotalSum {get;set;}
- }
解决方法
您不能使用Multi Map / Reduce索引,因为您需要在标签上放置一个地图而在帐户上放置另一个地图.他们没有共同的属性,所以你不能在这里有多个地图/减少.
但是,您可以使用TransformResult.这是怎么做的:
- public class Account
- {
- public string Id { get; set; }
- public string Name { get; set; }
- }
- public class Item
- {
- public string Id { get; set; }
- public string AccountId { get; set; }
- public int Value { get; set; }
- public List<string> Tags { get; set; }
- }
- public class TagsWithCountAndValues : AbstractIndexCreationTask<Item,TagsWithCountAndValues.ReduceResult>
- {
- public class ReduceResult
- {
- public string AccountId { get; set; }
- public string AccountName { get; set; }
- public string Tag { get; set; }
- public int Count { get; set; }
- public int TotalSum { get; set; }
- }
- public TagsWithCountAndValues()
- {
- Map = items => from item in items
- from tag in item.Tags
- select new
- {
- AccountId = item.AccountId,Tag = tag,Count = 1,TotalSum = item.Value
- };
- Reduce = results => from result in results
- group result by result.Tag
- into g
- select new
- {
- AccountId = g.Select(x => x.AccountId).FirstOrDefault(),Tag = g.Key,Count = g.Sum(x => x.Count),TotalSum = g.Sum(x => x.TotalSum)
- };
- TransformResults = (database,results) => from result in results
- let account = database.Load<Account>(result.AccountId)
- select new
- {
- AccountId = result.AccountId,AccountName = account.Name,Tag = result.Tag,Count = result.Count,TotalSum = result.TotalSum
- };
- }
- }
之后,您可以像这样查询:
- var results = session.Query<TagsWithCountAndValues.ReduceResult,TagsWithCountAndValues>()
- .Where(x => x.AccountId == "accounts/1")
- .ToList();