2013-02-27 2 views
2

Хотя я очень рад идее использования RavenDB в качестве хранилища OLTP-приложений, у меня проблемы с реализациями Linq/Map-Reduce.Индекс комплекса RavenDB

Вот что я пытаюсь сделать - У меня есть документы -

Event { 
    UserId: "1", 
    Location : "X", 
    EventDate : "1/1/2010", 
    EventType : "type A" 
} 
... 
Event { 
    UserId: "2", 
    Location : "Y", 
    EventDate : "1/1/2011", 
    EventType : "type B" 
} 

Действие запрос/индекс должен выполнить,

«Принеси мне подсчитать различные события для конкретного пользователя в конкретный диапазон дат, сгруппированные по местоположению, событие»

результат Например:

Location | Count(EventA) | Count(EventB) 
--------------------------------------- 
X  | 10   |  2 
Y  | 4   | 22 

Я считаю, что это должно быть прямолинейно. Вероятно, я просто что-то упустил.

Благодарим за помощь!

ответ

1

То, о чем вы просите, является типичным случаем для отчетности. И это одно, что RavenDB не подходит для (http://ravendb.net/docs/server/bundles/index-replication). Ваш вопрос похож на структуру куба в SQL Server Analysis Services.

enter image description here

Проблема в данном случае диапазон дат. Если диапазоны фиксированы, скажем, я хочу знать это за каждый месяц, вы можете сделать это в индексе, но если диапазоны являются ad hoc, то я считаю, что это невозможно в Вороне с помощью индекса и, по-видимому, даже не запрос, потому что вам придется выполнять группировку на стороне клиента и, следовательно, придется извлекать большое количество документов (гораздо больше, чем по умолчанию 128).

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

public class Index : AbstractIndexCreationTask<Index.Result> 
{ 
    public class Result 
    { 
     public string UserId { get; set; } 
     public string Location { get; set; } 
     public string EventType { get; set; } 
     public int Count { get; set; } 
    } 

    public Index() 
    { 
     Map = events => from e in events 
         select new Result 
         { 
          UserId = e.UserId, 
          Location = e.Location, 
          EventType = e.EventType, 
          Count = 1 
         }; 

     Reduce = results => from result in results 
          group result by new { result.UserId, result.Location, result.EventType } 
           into g 
           select new Result 
           { 
            UserId = g.Key.UserId, 
            Location = g.Key.Location, 
            EventType = g.Key.EventType, 
            Count = g.Sum(x => x.Count) 
           }; 
    } 
} 

Это даст вам этот результат

UserId | Location | EventType  | Count 
------------------------------------------- 
1  | X  | A    |  2 
1  | X  | B    |  4 
1  | Y  | A    | 22 
1  | Y  | B    |  6 
2  | X  | A    |  7 
2  | X  | B    |  3 
2  | Y  | A    |  9 
2  | Y  | B    | 16 

Вы можете запросить этот индекс и делать дополнительную группировку по результатам запроса.

+1

Хороший ответ. Вы попали в суть проблемы - вы не можете иметь произвольный диапазон дат. Если вы хотите, чтобы они группировались в день, неделю, месяц и т. Д., Тогда вы можете. Возможно, можно использовать несколько индексов и пересечь результаты, чтобы сделать его более произвольным. Я уже собираюсь это сделать некоторое время ... –