forked from ravendb/ravendb
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathHierarchicalInheritanceIndexing.cs
141 lines (126 loc) · 5.22 KB
/
HierarchicalInheritanceIndexing.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Linq;
using Raven.Client;
using Raven.Client.Indexes;
using Raven.Imports.Newtonsoft.Json;
using Raven.Client.Linq;
using Raven.Tests.Common;
using Xunit;
namespace Raven.Tests.MailingList
{
public class HierarchicalInheritanceIndexing : RavenTest
{
[Fact]
public void CanCreateIndex()
{
Guid rootId = Guid.NewGuid();
Guid childId = Guid.NewGuid();
Guid grandChildId = Guid.NewGuid();
using (var documentStore = NewDocumentStore())
{
using (var session = documentStore.OpenSession())
{
for (int i = 0; i < 20; i++)
{
var ex = new Example
{
OwnerId = rootId,
Name = string.Format("Example_{0}", i),
Description = "Ex Description"
};
var child = new ExampleOverride
{
OwnerId = childId,
OverriddenValues = new Dictionary<string, object>
{
{"Name", string.Format("Child_{0}", i)}
}
};
ex.Overrides.Add(child);
var grandChild = new ExampleOverride
{
OwnerId = grandChildId,
OverriddenValues = new Dictionary<string, object>
{
{"Name", string.Format("GrandChild_{0}", i)}
}
};
child.Overrides.Add(grandChild);
session.Store(ex);
}
session.SaveChanges();
}
new ExampleIndexCreationTask().Execute(documentStore);
using (var session = documentStore.OpenSession())
{
var examples =
session.Query<ExampleProjection, ExampleIndexCreationTask>()
.Customize(x => x.WaitForNonStaleResults())
.ProjectFromIndexFieldsInto<ExampleProjection>().ToList();
Assert.NotEmpty(examples);
}
}
}
}
[JsonObject(IsReference = true)]
public class Example
{
public Example()
{
Overrides = new BindingList<ExampleOverride>();
}
public Guid Id { get; set; }
public Guid OwnerId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public BindingList<ExampleOverride> Overrides { get; set; }
}
[JsonObject(IsReference = true)]
public class ExampleOverride
{
public ExampleOverride()
{
OverriddenValues = new Dictionary<string, object>();
Overrides = new BindingList<ExampleOverride>();
}
public Guid OwnerId { get; set; }
public ExampleOverride Parent { get; set; }
public Dictionary<string, object> OverriddenValues { get; set; }
public BindingList<ExampleOverride> Overrides { get; set; }
}
public class ExampleProjection
{
public string Id { get; set; }
public Guid OwnerId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
public class ExampleIndexCreationTask : AbstractMultiMapIndexCreationTask<ExampleProjection>
{
public ExampleIndexCreationTask()
{
AddMap<Example>(
examples => from ex in examples
select new { ex.Id, ex.OwnerId, ex.Name, ex.Description }
);
AddMap<Example>(
examples => from ex in examples
from ov in ex.Overrides
let ancestry = Recurse(ov, x => x.Parent)
select
new
{
ex.Id,
ov.OwnerId,
Name = ov.OverriddenValues["Name"] ?? (ancestry.Any(x => x.OverriddenValues["Name"] != null)
? ancestry.First(x => x.OverriddenValues["Name"] != null).OverriddenValues["Name"]
: ex.Name),
Description = ov.OverriddenValues["Description"] ?? (ancestry.Any(x => x.OverriddenValues["Description"] != null)
? ancestry.First(x => x.OverriddenValues["Description"] != null).OverriddenValues["Description"]
: ex.Description)
});
}
}
}