RAVENDB- MAPREDUCE复合物聚集



我有这样的文档:

 order : 1
     event : { timestamp: 1/1/2012, employeeName: "mick" },
     event : { timestamp: 1/1/2012, employeeName: "mick" },
     event : { timestamp: 1/2/2012, employeeName: "rick" },
     event : { timestamp: 1/3/2012, employeeName: "mick" }
  order : 2
     event : { timestamp: 1/2/2012, employeeName: "mick" },
     event : { timestamp: 1/2/2012, employeeName: "rick" }

我想运行一个地图 - 还原查询,以返回按日期分组的结果列表,每订单的员工事件计数。

在这种情况下,米克(Mick)在单个顺序上有2个事件。其他日子在11月2日和3日的每个订单上都有一个事件。因此,我需要一个图像功能,其结果看起来像:

{ orderId: 1, date: 1/1/2012, employee: "mick", orderEventsCount: 2 },
{ orderId: 1, date: 1/2/2012, employee: "rick", orderEventsCount: 1 },
{ orderId: 2, date: 1/2/2012, employee: "mick", orderEventsCount: 1 },
{ orderId: 2, date: 1/2/2012, employee: "rick", orderEventsCount: 1 },
{ orderId: 1, date: 1/3/2012, employee: "mick", orderEventsCount: 1 }

然后,我需要一个减少功能,该功能将仅按日期进行这些结果,并每天返回一项单一订单中有多个事件的员工计数:

{ date: 1/1/2012, multipleEventsPerOrdercount: 1 },
{ date: 1/2/2012, multipleEventsPerOrdercount: 0 },
{ date: 1/3/2012, multipleEventsPerOrdercount: 0 }

由于米克是唯一在单个订单上单个日期进行多个事件的员工,结果仅返回了一个雇员的计数,该雇员在日期订单上有多个事件。

使用.net中的linq编写此映射raven查询的最佳方法是什么?

谢谢

假设您的课程看起来像这样:

public class Order
{
  public string Id  { get; set; }
  public List<Event> Events { get; set; }
}
public class Event
{
  public DateTime Timestamp { get; set; }
  public string EmployeeName { get; set; }
}

然后您要要求的索引看起来像这样:

public class Orders_EventCountsByDate : 
    AbstractIndexCreationTask<Order, Orders_EventCountsByDate.Result>
{
  public class Result
  {
    public DateTime Date { get; set; }
    public double Count { get; set; }
  }
  public Orders_EventCountsByDate()
  {
    Map = orders => from order in orders
                    from evt in order.Events
                    let subtotal = order.Events.Count(x => x.EmployeeName == evt.EmployeeName && x.Timestamp == evt.Timestamp)
                    select new
                    {
                      evt.Timestamp.Date,
                      Count = subtotal > 1 ? (1.0 / subtotal) : 0
                    };
    Reduce = results => from result in results
                        group result by result.Date
                        into g
                        select new
                        {
                          Date = g.Key,
                          Count = g.Sum(x => x.Count)
                        };
  }
}

您会这样使用:

var counts = session.Query<Orders_EventCountsByDate.Result,
                           Orders_EventCountsByDate>();

这里的诀窍是,您在地图中确定了您希望每个事件对数量贡献的程度。如果只有一个事件,则贡献零。当有多个事件时,每个事件都会贡献总数的一小部分。这些分数随后将其求和在减少中,使您接近整数。双浮点数学应该使您回到整个数字,但是您仍然需要将客户端代码中的整个整数转到最接近的整个数字中。

这也假定所有事件都处于相同的时区,并且您不在乎日光储蓄的变化,或者时代在UTC中。如果两者都不是,那么您应该使用dateTimeOffset,并且在确定每个员工的一天概念是什么时有更多的考虑。

最新更新