string sql = @"select c.Id, (select COUNT(distinct positivevotes) + 1 from Contributions where IsOnline = 1 And Country = c.Country And PositiveVotes > c.PositiveVotes) as Ranking from Contributions c where c.Id In (:id)"; ISQLQuery query = (ISQLQuery)context.CurrentSession.CreateSQLQuery(sql) .AddScalar("Id", NHibernateUtil.Int32) .AddScalar("Ranking", NHibernateUtil.Int32) .SetParameterList("id", contributionIds); IList<object[]> result = query.List<object[]>(); foreach (object[] item in result) { Contribution contribution = contributions.FirstOrDefault(x => x.Id == (int)item[0]); list.Add(contribution, (int)item[1]); }
A "Contribution" has properties for Id, PositiveVotes, IsOnline and Country. constributionIds is an array of ids.
Could 'ranking' be solved via the facets mechanisme?
Facets could return
Votes / count / dense_rank / rank
100 / 2 / 1 / 1
90 / 1 / 2 / 3
75 / 1 / 3 / 4
What do you think?
// Ryan
Facets would now return
Votes/ count
100 / 2
90 / 1
70 / 1
It would be easy to calc the rank from thereof.
Perhaps something like
new Facet {
Name = "Votes"
RankMode = RankOnValues ( or RankOnCounts | RankOnCountDesc |
RankOnValues | RankOnValuesDesc)
}
Which would return
Votes / count / dense_rank / rank
100 / 2 / 1 / 1
90 / 1 / 2 / 3
75 / 1 / 3 / 4
// usage
s.Query<Contribution>("VoteRank")
.Where(x => x.Country == "US")
.ToFacets("facets/VoteFacets");
I hope I am clear enough :)
// Ryan
public class RankingByCountry : AbstractIndexCreationTask<Contribution> { public RankingByCountry() { // map Map = docs => from contrib in docs where contrib.IsOnline select new { contrib.Country, VoteRanking = new[] { contrib.PositiveVotes } }; // Reduce Reduce = results => from result in results group result by result.Country into g select new { Country = g.Key, VoteRanking = g.SelectMany(x=>x.PositiveVotes).OrderByDescending(x=>x).Distinct() }; } }
However, Visual Studio highlights g.SelectMany(x => x.PositiveVotes) and says that:
The type arguments for method 'System.Linq.Enumerable.SelectMany<TSource,TResult>(System.Collections.Generic.IEnumerable<TSource>, System.Func<TSource,System.Collections.Generic.IEnumerable<TResult>>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
Any ideas?