I'm going to be looking at getting multiple document types returned from raven querying some properties that both objects have.
We're going to be using Animals and Vehicles, and we want to be able to figure out which animals and vehicles operate on land. These documents don't share inheritance, so we can't just search the base properties - what we need is a mapping that collects all the common properties of these documents.
The objects are:
public class Animal | |
{ | |
public string Name { get; set; } | |
public string Habitat { get; set; } | |
public int TopSpeed { get; set; } | |
public string Status { get; set; } | |
} |
public class Vehicle | |
{ | |
public string Name { get; set; } | |
public string WorksOn { get; set; } | |
public int TopSpeed { get; set; } | |
public string Colour { get; set; } | |
} |
We need to start by mapping the common fields to a new object for use in our LINQ query.
We also create a mapping for each object type that we want to index, selecting the common fields into an anonymous type.
public class AnimalsAndVehicles : AbstractMultiMapIndexCreationTask | |
{ | |
public class CommonMap | |
{ | |
public int TopSpeed { get; set; } | |
public string Location { get; set; } | |
} | |
public AnimalsAndVehicles() | |
{ | |
AddMap<Animal>(animals => | |
from animal in animals | |
select new | |
{ | |
TopSpeed = animal.TopSpeed, | |
Location = animal.Habitat, | |
}); | |
AddMap<Vehicle>(vehicles => | |
from vehicle in vehicles | |
select new | |
{ | |
TopSpeed = vehicle.TopSpeed, | |
Location = vehicle.WorksOn | |
}); | |
} | |
} |
You may have heard a lot of talk about Map/Reduce in the document database world, but for this particular query we're just interested in the Map part - we don't want to reduce the results to a common object but rather return the original objects.
Now that we've defined our Map we need to tell Raven about it which is really easy. Just after calling DocumentStore.Initialize()
you call IndexCreation.CreateIndexes(typeof(AnimalsAndVehicles).Assembly, DocumentStore)
which takes care of creating the index, and now it's ready to use!
To use the MultiMap:
using (var session = raven.DocumentStore.OpenSession()) | |
{ | |
var objects = session.Query<AnimalsAndVehicles.CommonMap, AnimalsAndVehicles>() | |
.Where(a => a.Location == "Land") | |
.As<dynamic>() | |
.ToList(); | |
} |
As<dynamic>()
- this will let us return any object from the query.
A couple of helpful links in putting this together and thinking about how the mapping works were the Raven Documentation and Daniel Lang's blog about Multi Map Indexes