I am kind of stuck on using the include with a RavenDB Transformer. Say I have the following document classes:
public class Processor
{
public string Id { get; set; }
// other properties
}
public class Job
{
public string Id { get; set; }
public string ProcessorId { get; set; }
// other properties
}
Hers is my view model:
public class ProcessorStatsViewModel
{
public string Id { get; set; }
public int JobCount { get; set; }
// other properties
}
In my tranformer I would like to query the Processors Document Store and do an include on the Jobs Store looking for every job with a matching Processor ID. All of the search results I found describe how to do this when the Processor class has the list of JobId's. Is there a way to do this in RavenDB?
The transformer I would like could look something like:
public Processors_StatsViewModel()
{
TransformerResults = procs =>
from p in procs
let jobs = Include<Jobs>(p.Id) // how can i specify something like where p.Id == j.ProcessorId ?
select new
{
p.Id
JobCount = jobs.Count
// other stuff
}
}
All of the Transformer LoadDocument, Include, and Recurse methods expect the class being queried to have a list reference ID's but in my case in need the opposite.
Is this something I can even do in RavenDB or am I missing something?
You can not do what you want to do with only a transformer and your current domain model. If the processors did indeed know about its jobs you could do this with a transformer kind of like the one you have.
However, you can achieve something similar with a Map/Reduce index and then a Transformer over the result of the Map/Reduce index. It all depends on what "other stuff" you want to present, but this is a way to get all Processes and its job count and then adding more information with a transformer:
Map/Reduce index to get job count by processor:
public class Jobs_ByProcessor : AbstractIndexCreationTask<Job, Jobs_ByProcessor.ReduceResult>
{
public class ReduceResult
{
public string ProcessorId { get; set; }
public int JobCount { get; set; }
}
public Jobs_ByProcessor()
{
Map = jobs => from job in jobs
select new ReduceResult
{
ProcessorId = job.ProcessorId,
JobCount = 1
};
Reduce = results => from result in results
group result by result.ProcessorId
into g
select new
{
ProcessorId = g.Key,
JobCount = g.Sum(x => x.JobCount)
};
}
}
Transformer:
public class ProcessorJobTransformer : AbstractTransformerCreationTask<Jobs_ByProcessor.ReduceResult>
{
public ProcessorJobTransformer()
{
TransformResults = results => from result in results
let processor = LoadDocument<Processor>(result.ProcessorId)
select new
{
Id = result.ProcessorId,
Name = processor.Name,
JobCount = result.JobCount
};
}
}
This would give you a result like this: Id and JobCount comes from the Reduce result of the index and the Name comes from the Transformer (via LoadDocument).
However, if you need this results but more information from the Job document, you might have to go a different route entirely.
Hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With