开发者

RavenDB: How to do a simple map/reduce aggregation

Ok given a collection of documents like this:

{ 
  "Name": "A开发者_Python百科",
  "Price": 1.50
}

How do I perform a simple aggregation on the prices in the list? I don't want to perform any grouping, just a simple scalar result.

ie. sum, avg etc

I have tried both of the following without success:

Map only:

for doc in docs
select new { sumPrices = Sum(d => d.Price) }

and

Map:

for doc in docs
select new { price = d.Price }

Reduce:

for result in results
select new { sumPrices = Sum(result) }


This should do the trick.

Map:

from doc in docs.Products
select new { Name = "Total", Total = doc.Price }

Reduce:

select new
{
    Name = g.Key,
    Total = g.Sum(x => (double)x.Total)
}

Each doc goes through the Map, and the aggregation happens in the Reduce. But the schema coming out of the Map still needs to match your result. The "Total" for each document is just its Price. These all then get summed in the reduce.

The Name property is kind of useless, its just there to give the reduce something to group every single document on.


Here's what I came up with.

Map:

from doc in docs 
where doc["@metadata"]["Raven-Entity-Name"] == "Books" 
select new { Name = "Total", Price = doc.Price };

Reduce:

from result in results 
group result by result.Name 
into g 
select new { Name = g.Key, Price = g.Sum(x => x.Price) }

However, I was only able to get this to work if I changed the price to an integer. So my two docs look like this:

{
    "Name":"B",
    "Price":4
}
{
    "Name":"A",
    "Price":10
}

And my JSON output looks like this:

{"Results":[{"Name":"Total","Price":"14","Price_Range":"14"}],"IsStale":false,"TotalResults":1}

Obviously, changing the price to integers is not the solution. It may be a bug in RavenDB, but I'm pretty new to it myself, so I'm hoping it's just the way I'm doing my Sum() or the way that the data is represented in the document.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜