2011-08-31 108 views
4

我有一个稍微复杂的指标,我需要在给定的这个文件定义,就像一个RavenDB文件RavenDB指数地图缩小不同

public class PriceDocument 
{ 
    public string Id { get; set; } 
    public Guid PriceId { get; set; } 
    public decimal Price { get; set; } 
    public DateTime? PricingDate { get; set; } 
    public string Source { get; set; } 
    public int Version { get; set; }  
} 

我需要让所有的产品对于一个给定productId (我能做到这一点,当我查询) 通过PricingDate(最新)和Source

所以给出的以下数据是唯一的:

var priceDocument = new PriceDocument { 
    Price = 1m, 
    Id = productId + "/1", 
    PricingDate = new DateTime(2011, 4, 1, 8, 0, 0), 
    PriceId = productId, 
    Source = "Bloomberg", 
    Version = 1 
}; 

var priceDocument1 = new PriceDocument { 
    Price = 1m, 
    Id = productId + "/2", 
    PricingDate = new DateTime(2011, 4, 1,9,0,0), 
    PriceId = productId, 
    Source = "Bloomberg", 
    Version = 1 
}; 

我应该得到的结果priceDocument1,因为它的最新版本。

到目前为止,我已经像这样定义的索引:

Map = docs => 
    from priceDocument in docs 
    select new { 
     PricingDate = priceDocument.PricingDate, 
     PricingSource = priceDocument.Source, 
     Price = priceDocument.Price, 
     PriceId = priceDocument.PriceId 
    }; 

Reduce = results => 
    from result in results 
    group result by new { result.PricingDate, result.Source } into price 
    select new { 
     PricingDate = price.Max(p => price.Key.PricingDate), 
     PricingSource = price.Key.Source, 
    }; 

但它不运行时的工作,我发现了一个AbstractIndexingExecuter||8||Failed to index documents for index (my index name)

我在一个单独的项目重新创建此示例和我可以看到,在Raven Studio的统计数据中,我得到以下错误:

Cannot implicitly convert type 'System.DateTimeOffset' to 'int' changed the DateTime? to DateTime

并且没有运气。

从使用之日起使用,我可以依靠它递增所以现在的指数看起来是这样的切换:

Map = docs => 
    from priceDocument in docs 
    select new { 
     PricingDate = priceDocument.PricingDate, 
     PricingSource = priceDocument.Source, 
     ProductId = priceDocument.ProductId, 
     ProductVersion = priceDocument.Version 
    }; 

Reduce = results => 
    from result in results 
    group result by new { 
     result.PriceId, 
     result.PricingDate, 
     result.Source, 
     result.Version 
    } into price 
    select new { 
     PricingDate = price.Key.PricingDate, 
     PricingSource = price.Key, 
     ProductVersion = price.Max(p=> price.Key.Version) 
    }; 

现在不引发错误,但它也没有给出结果。

回答

5

它可能应该是这样的:

PricingDate = price.Max(p => (DateTimeOffset)price.Key.PricingDate) 

但你想要的东西没有按不需要地图缩小索引。你可以通过只使用:

session.Query<PriceDocument>() 
     .Where(x=>x.ProduceId == prodId) 
     .OrderByDescending(x=>x.PriceDate) 
     .FirstOrDefault(); 

的原因,你的Map/Reduce指数不工作是,你必须对地图&减少功能不同的输出。

+0

嗨Ayende:感谢您的答案,事情是它必须是唯一的PriceDate和PricingSource(即我可以有2行与同日,只要来源是不同的),并选择其中一个版本(或日期)是最高的 – roundcrisis

+0

然而,这wasnt全部答案,@ayende乌鸦讨论组https://groups.google在回答这个问题。 com/d/topic/ravendb/B9HCmi32YWw /讨论和解决方法在这里https://gist.github.com/1186051 – roundcrisis

3

试图改变指数的降低部分这条线,从

PricingDate = price.Max(p => price.Key.PricingDate) 

PricingDate = price.Max(p => (int)price.Key.PricingDate) 
+0

谢谢我已经尝试过,现在结果是没有错误,但没有结果 – roundcrisis