Как запросить вложенную информацию в RavenDB? - PullRequest
6 голосов
/ 21 октября 2011

У меня есть следующий документ под названием Резервирование:

{
    "CustomerId": 1,
    "Items": [
        {
            "EmployeeId": "employees/1",
            "StartTime": "2011-08-15T07:20:00.0000000+03:00",
            "EndTime": "2011-08-15T07:40:00.0000000+03:00"
        },
        {
            "EmployeeId": "employees/1",
            "StartTime": "2011-08-15T07:40:00.0000000+03:00",
            "EndTime": "2011-08-15T09:10:00.0000000+03:00"
        },
        {
            "EmployeeId": "employees/3",
            "StartTime": "2011-08-16T07:20:00.0000000+03:00",
            "EndTime": "2011-08-16T11:35:00.0000000+03:00"
        }
    ]
    "ReservedAt": "2011-10-20T15:28:21.9941878+03:00"
}

Кроме того, у меня есть следующий класс проекции:

public class ReservationItemProjection
{
    public string ReservationId { get; set; }
    public string CustomerId { get; set; }
    public string EmployeeId { get; set; }
    public DateTime StartTime { get; set; }
    public DateTime EndTime { get; set; }
}

Какой индекс и запрос я пишу, если я хочу найти соответствующий ReservationItemProjections? E.g.:

// invalid example query:
var matches = docs.Query<ReservationItemProjection,
    ReservationItemProjectionsIndex>()
    .Where(x =>
        x.EmployeeId == "employees/1" &&
        x.StartTime >= minTime &&
        x.EndTime <= maxTime)
    .ToList();

Обратите внимание, что я не хочу получать список документов бронирования, но список объектов ReservationItemProjection. документация гласит:

Но хотя получение документов, соответствующих определенному запросу, полезно, мы можем добиться большего. Вместо того чтобы получать сами документы, я хочу получать значения непосредственно из индекса, не получая полный документ.

Я уже пытался использовать такой индекс:

public class ReservationItemProjectionsIndex : 
    AbstractIndexCreationTask<Reservation, ReservationItemProjection>
{
    public ReservationItemProjectionsIndex()
    {
        Map = reservations => 
            from reservation in reservations
            from item in reservation.Items
            select new
            {
                ReservationId = reservation.Id,
                CustomerId = reservation.CustomerId,
                item.EmployeeId,
                item.StartTime,
                item.EndTime
            };
        Store(x => x.ReservationId, FieldStorage.Yes);
        Store(x => x.CustomerId, FieldStorage.Yes);
        Store(x => x.EmployeeId, FieldStorage.Yes);
        Store(x => x.StartTime, FieldStorage.Yes);
        Store(x => x.EndTime, FieldStorage.Yes);
    }
}

Почему-то я не могу заставить работать запрос и индекс: либо выдается исключение не может быть приведен из ReservationItemProjection в Reservation или, когда я были в состоянии получить объекты ReservationItemProjection, они будут иметь включил все предметы во все бронирования, в которых есть хотя бы один соответствующий предмет, даже хотя в моем запросе содержится предложение Where x.EmployeeId == "employee / 1".

Резюме: Что такое требуемый индекс? Индексу нужно только предложение Map, а также Reduce или TransformResults? Как мне написать запрос в C #?

1 Ответ

8 голосов
/ 23 октября 2011

Kasper, В RavenDB вы запрашиваете документы . Хотя технически возможно делать то, что вы хотите, обычно это бессмысленно, поскольку проецируемая информация не имеет необходимого контекста, чтобы что-то с ней делать.

Что вы пытаетесь сделать?

Для справки индекс будет выглядеть примерно так:

 from doc in docs.Items
 from reservation in doc.Reservations
 select new { reservation.EmployeeId, reservation.Start, reservation.End }

Затем отметьте EmployeeId, Start и End как Store.

Теперь в вашем запросе введите:

  session.Query<...,...>().AsProjection<ReservationProjection>().ToList();

Вызов AsProjection позволит БД узнать, что вам нужны значения из индекса, а не документа

...