Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RavenDB index with map reduce distinct [closed]

I have a slightly complex index that I need over a RavenDB document

given this document definition like:

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; }    
}

I need to get all the products for a given productId (I can do that when I query) that are unique by PricingDate (latest) and Source

So given the following data:

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
};

I should get as a result priceDocument1, since its latest.

So far I have an index defined like this:

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,
    };

But it doesnt work at run time, I'm getting an AbstractIndexingExecuter||8||Failed to index documents for index (my index name)

I've recreated this sample in a separate project and I can see that in stats in Raven Studio that I get the error:

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

And no luck.

I switched from using the date to use the I can rely on it incrementing so now the index looks like this:

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)
    };

Now that throws no errors, however it also gives no results.

like image 461
roundcrisis Avatar asked Feb 23 '23 03:02

roundcrisis


1 Answers

It should probably be this:

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

But what you want doesn't require a map reduce index. You can get that by just using:

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

The reason your Map/Reduce index doesn't work is that you have different outputs for the map & reduce functions.

like image 165
Ayende Rahien Avatar answered May 03 '23 01:05

Ayende Rahien