Reputation: 5027
I have a City document, Site document. City can have multiple sites. Site document has the city information in it. There are about 100 city documents and 10000 site documents in RavenDB
City Document:
{
"CityCode": "NY",
"CityName": "New York"
}
Site Document:
{
"SiteName": "MOMA",
"CityCode": "NY"
}
Objective is to get a list of all cities and the number of sites for each like...
City Sites NY 12 CH 33 BO 56 and so on....
I am doing this.
int countSites = session.Query<Site>()
.Count();
var SiteCityList = session.Query<Site>()
.Take(countSites)
.ToList()
.GroupBy(x => x.CityCode)
.OrderBy(x => x.Count())
.ToDictionary(x => x.Key, x => x.Count());
This does not give all the data in the ravendb. I get only 11 rows of count by site at any time and even the counts are not accurate. What I want is to get a list of all 100 cities and number of sites for each city (in 100s) as a list as shown above. Thanks for the help.
Upvotes: 2
Views: 1093
Reputation: 8934
You've got 2 options:
To make a choice between the two, take into account that
While using a Map/Reduce index is straightforward and already covered by Daniel's answer, I provide below an example of using Facets:
var query = DbSession.Query<Site_IndexModel, Site_ForList>();
List<FacetValue> facetResults = (await query
.AggregateBy(builder => builder.ByField(s => s.CityCode ))
.ExecuteAsync()
).Single().Value.Values;
// Go through results, where each facetResult is { Range, Count } structure
return from result in facetResults
select new { CityCode = result.Range, Count = result.Count }
where
Site_ForList
is an existing index for Site
collection, which includes CityCode
fieldSite_IndexModel
is the stored structure of Site_ForList
indexUpvotes: 0
Reputation: 10291
If you want an alternative way, you can take a look at Faceted Search
It gives you slightly more flexibility than Map/Reduce, but will only work when you want a Count of items (which you do in your case).
Upvotes: 2
Reputation: 6839
Use a map/reduce index like this
public class CityCodeCount : AbstractIndexCreationTask<Site, CityCodeCount.ReduceResult>
{
public class ReduceResult
{
public string CityCode { get; set; }
public int Count { get; set; }
}
public CityCodeCount()
{
Map = sites => from site in sites
select new
{
site.CityCode,
Count = 1
};
Reduce = results => from result in results
group result by result.CityCode
into g
select new
{
CityCode = g.Key,
Count = g.Sum(x => x.Count)
};
}
}
Later then, you can query it easily.
var results = documentSession.Query<CityCodeCount.ReduceResult, CityCodeCount>()
.ToList();
Upvotes: 3