我是RavenDB的新手,我正在尝试使用下面的索引查询下面的文档模型。该索引几乎按预期工作,但现在我只需要在总数中包含日期的最新状态。例如,客户端可能具有多个日期的导入状态,但只有最后一个状态应计入结果总计中。
public class Client
{
public int Id { get; set; }
public string Name { get; set; }
public IList<ImportStatusMessage> ImportStatuses { get; set; }
}
public class ImportStatusMessage
{
public DateTime TimeStamp { get; set; }
public ImportStatus Status { get; set; }
}
public enum ImportStatus
{
Complete,
Running,
Failed,
Waiting,
NoReport
}
我使用以下索引:
public class Client_ImportSummaryByDate : AbstractIndexCreationTask<Client, ImportSummary>
{
public Client_ImportSummaryByDate()
{
Map = clients => from client in clients
from status in client.ImportStatuses
select new
{
status.Status,
Date = status.TimeStamp.Date,
Count = 1
};
Reduce = results => from result in results
group result by new { result.Status, result.Date }
into g
select new
{
g.Key.Status,
g.Key.Date,
Count = g.Sum(x => x.Count)
};
}
}
public class ImportSummary
{
public ImportStatus Status { get; set; }
public DateTime Date { get; set; }
public int Count { get; set; }
}
这可以用索引完成吗?我需要一种不同的方法来解决这个问题吗?
答案 0 :(得分:1)
而不是:
from status in client.ImportStatuses
考虑:
let status = client.ImportStatuses.Last()
如果列表中可能出现故障,您可以这样做:
let status = client.ImportStatuses.OrderBy(x => x.TimeStamp).Last()
如果按此方式订购,您也可以使用First
代替Last
。
其中任何一个都只能为每个客户端索引一个状态。如果你的意思是你想要多个状态,但只想在任何给定日期的最后状态,你可以这样做:
Map = clients => clients.SelectMany(x => x.ImportStatuses, (x, y) => new {x.Id, y.Status, y.TimeStamp})
.GroupBy(x => new {x.Id, x.TimeStamp.Date})
.Select(g => g.OrderBy(x => x.TimeStamp).Last())
.Select(x => new
{
x.Status,
x.TimeStamp.Date,
Count = 1
});
所有这些都将在索引的地图部分中,因为列表在每个文档中都是自包含的。