It may be that I'm trying to achieve too much with one index. Here are my documents:
clients/1
{
"Name" : "Fabrikam"
}
vacancies/2
{
"Position" : "Developer Genius Guy",
"ClientId" : "clients/1"
}
candidates/1
{
"Name": "John Doe"
}
candidates/2
{
"Name": "Bill Jones"
}
vacancyapplications/3
{
"VacancyId" : "vacancies/2",
"CandidateId" : "candidates/1",
"State" : "Unapproved"
}
vacancyapplications/4
{
"VacancyId" : "vacancies/2",
"CandidateId" : "candidates/2",
"State" : "Approved"
}
You can see that:
Vacancy holds a reference to Client.
VacancyApplication holds a reference to Vacancy and Candidate
Originally I wanted to:
GET ALL VACANCY APPLICATIONS THAT ARE UNAPPROVED
I want the following information:
- ApplicationId
- VacancyId
- CandidateId
- ClientId
- ClientName
- Position
- CandidateName
- StateId
Originally I was doing this with a regular index on State (since this was the only thing I was actually querying) and then getting all the other information in the transform results: This allowed me to effectively get from VacancyApplication to Client (via Vacancy):
public class VacancyApplications_Summary : AbstractIndexCreationTask<VacancyApplication, VacancyApplicationSummary>
{
public VacancyApplications_Summary()
{
Map = applications => from a in applications
select new
{
StateId = a.StateId,
};
TransformResults = (store, results) => from result in results
let candidate = store.Load<Candidate>(result.CandidateId)
let vacancy = store.Load<Vacancy>(result.VacancyId)
let client = store.Load<Client>(vacancy.ClientId)
orderby result.ReceivedDate descending
select new
{
Id = result.Id,
VacancyId = vacancy.Id,
CandidateId = candidate.Id,
ClientId = client.Id,
Position = vacancy.Position,
CandidateName = candidate.ContactDetails.FullName,
ReceivedDate = result.ReceivedDate,
StateId = result.StateId
};
}
}
The problem came when I needed to answer the following:
GET ME ALL VACANCIES FOR CLIENT 1
Of course if I try and query on ClientId I get:
System.ArgumentException: The field 'ClientId' is not indexed, cannot query on fields that are not indexed
because quite rightly, I am not indexing ClientId.
So I figured that maybe a multi map index is the way to go for this, something like:
AddMap<VacancyApplication>(applications => from a in applications
select new
{
Id = a.Id,
VacancyId = a.VacancyId,
CandidateId = a.CandidateId,
ClientId = (string)null,
StateId = a.StateId,
ReceivedDate = a.ReceivedDate,
Position = (string)null
});
AddMap<Vacancy>(vacancies => from v in vacancies
select new
{
Id = (string)null,
VacancyId = v.Id,
CandidateId = (string)null,
ClientId = v.ClientId,
StateId = (string)null,
ReceivedDate = DateTime.MinValue,
Position = v.Position
});
The thing is, I'm not sure how to group / reduce these results.
With the above documents I would end up 2 VacancyApplications and 1 Vacancy in the results. How can I reduce them so that I get 2 results (the applications) with the information I need from the Vacancy?