2011-03-23 19 views
6

Tenemos un sitio que contiene transmisión de video y queremos mostrar tres informes de los videos más vistos en la última semana, mes y año (una ventana emergente).Ravendb mapreduce agrupar por campos múltiples

Almacenamos un documento en ravendb cada vez que se observó un video:

public class ViewedContent 
{ 
    public string Id { get; set; } 
    public int ProductId { get; set; } 
    public DateTime DateViewed { get; set; } 
} 

Estamos teniendo problemas para encontrar la manera de definir los índices/mapreduces que mejor soporte de la generación de esos tres informes.

Hemos intentado el siguiente mapa/reducir.

public class ViewedContentResult 
{ 
    public int ProductId { get; set; } 
    public DateTime DateViewed { get; set; } 
    public int Count { get; set; } 
} 

public class ViewedContentIndex : 
     AbstractIndexCreationTask<ViewedContent, ViewedContentResult> 
{ 
    public ViewedContentIndex() 
    { 
     Map = docs => from doc in docs 
         select new 
           { 
            doc.ProductId, 
            DateViewed = doc.DateViewed.Date, 
            Count = 1 
           }; 

     Reduce = results => from result in results 
          group result by result.DateViewed 
          into agg 
          select new 
             { 
              ProductId = agg.Key, 
              Count = agg.Sum(x => x.Count) 
             }; 
    } 
} 

embargo, esta consulta devuelve un error:

var lastSevenDays = session.Query<ViewedContent, ViewedContentIndex>() 
       .Where(x => x.DateViewed > DateTime.UtcNow.Date.AddDays(-7)); 

Error: "DateViewed is not indexed"

En última instancia, que desea consultar algo como:

var lastSevenDays = session.Query<ViewedContent, ViewedContentIndex>() 
       .Where(x => x.DateViewed > DateTime.UtcNow.Date.AddDays(-7)) 
       .GroupBy(x => x.ProductId) 
       .OrderBy(x => x.Count) 

Esta realidad no compilar, debido a que la OrderBy está mal; Count no es una propiedad válida aquí.

Cualquier ayuda aquí sería apreciada.

Respuesta

9

Cada informe es un GRUPO BY diferente si está en SQL land, que le indica que necesita tres índices: uno con solo el mes, uno con entradas por semana, uno por mes y uno por año (o . tal vez un poco diferente dependiendo de cómo lo está realmente va a hacer la consulta

Ahora, usted tiene un DateTime allí - que presenta algunos problemas - lo que realmente quiere hacer es el índice del componente Año del DateTime, el componente Mes de la fecha y el componente Día de esa fecha y hora. (O solo uno o dos de estos dependiendo del informe que desea generar.

Solo estoy citando aquí el código así que obviamente no se compilará, pero:

public class ViewedContentIndex : 
    AbstractIndexCreationTask<ViewedContent, ViewedContentResult> 
{ 
public ViewedContentIndex() 
{ 
    Map = docs => from doc in docs 
        select new 
          { 
           doc.ProductId, 
           Day = doc.DateViewed.Day, 
           Month = doc.DateViewed.Month, 
           Year = doc.DateViewed.Year 
           Count = 1 
          }; 

    Reduce = results => from result in results 
         group result by new { 
          doc.ProductId, 
          doc.DateViewed.Day, 
          doc.DateViewed.Month, 
          doc.DateViewed.Year 
         } 
         into agg 
         select new 
            { 
             ProductId = agg.Key.ProductId, 
             Day = agg.Key.Day, 
             Month = agg.Key.Month, 
             Year = agg.Key.Year 
             Count = agg.Sum(x => x.Count) 
            }; 
} 

}

Esperemos que se puede ver lo que estoy tratando de lograr por esta - desea que todos los componentes de su grupo por, como son lo que hace que tu agrupación sea única.

No puedo recordar si RavenDB te permite hacer esto con DateTimes y no lo tengo en esta computadora, así que no puedo verificar esto, pero la teoría sigue siendo la misma.

lo tanto, para reiterar

¿Quieres un índice para su informe por semana + producto Identificación del ¿Quieres un índice para su informe por mes + producto Identificación del ¿Quieres un índice para su informe por año + Identificación del producto

Espero que esto ayude, lo siento no puedo dar un ejemplo compilables, la falta de cuervo hace que sea un poco difícil :-)

+0

Sí, eso fue todo! El cambio mental fue ver que podía agrupar un objeto y no solo un campo. En última instancia, tenemos que consultar en una ventana de fechas. Pero, esto me da exactamente lo que necesito. ¡Gracias de nuevo! –