我有一个存储在RavenDB中的对象,它有三个属性:ID,Score,Date。
我想创建一个索引来检索给定日期范围内的前5个分数。但是,我只想检索每个ID一条记录。如果单个ID在最高分中显示多次,我只想检索该ID的最高分,然后转到下一个ID。
示例分数:
Score____ID____
1000 1
950 1
900 1
850 2
800 2
750 3
700 4
650 5
600 6
550 7
所需的查询结果:
Score____ID____
1000 1
850 2
750 3
700 4
650 5
我创建了一个类似于此的显式索引(为简单起见而调整):
Map = docs => from doc in docs
orderby doc.Score descending
select new
{
Score = doc.Score,
ID = doc.ID,
Date = doc.Date
};
我用类似于此的代码调用我的查询(为简单起见而调整):
HighScores = RavenSession.Query<Score, Scores_ByDate>()
.Customize(x => x.WaitForNonStaleResultsAsOfNow())
.Where(x => x.Date > StartDate)
.Where(x => x.Date < EndDate)
.OrderByDescending(x => x.Score)
.Take(5)
.ToList();
我不知道怎么说&#34;只能在列表中给我一次每个ID的结果。&#34;
答案 0 :(得分:3)
所以一些指示:
默认情况下,map / reduce假定排序是针对文本的,即使它是一个数字 - (I learned this the hard way并得到了帮助。)
所以..
只需将Map / Reduce索引定义为正常,并在最后添加排序条件,如下所示:
public class Score_TopScoringIndex : AbstractIndexCreationTask<Score, Score>
{
public Score_TopScoringIndex()
{
Map = docs => from doc in docs
select new
{
Score = doc.Score,
ID = doc.ID,
Date = doc.Date
};
Reduce = results => from result in results
group result by result.ID into g
select new
{
Score = g.First().Score,
ID = g.Key,
Date = g.First().Date
};
Sort(x=>x.Score, SortOptions.Int);
}
}
通过在应用程序启动时使用来确保索引位于数据库中:
IndexCreation.CreateIndexes(typeof(Score_TopScoringIndex).Assembly, documentStore);
现在,当您查询OrderByDescending
时,它会非常快。
using(var session = store.OpenSession())
{
var highScores = session.Query<Score>("Scores/TopScoringIndex")
.OrderByDescending(x=>x.Score)
.Take(5);
}
答案 1 :(得分:-2)