1
鑑於這樣的模式:如何按RavenDB中的嵌套兒童的財產的平均聚合來訂購文檔?
public class Location
{
public int Id { get; set; }
public string Name { get; set; }
public Coordinates Geo { get; set; }
public IList<Review> Reviews { get; set; }
}
public class Review
{
public string Comment { get; set; }
public int Rating { get; set; }
}
我如何編寫一個查詢,將返回匹配由他們的評分降序排序的位置嗎?
我,讓我身邊一個GeoPoint一定半徑內的查詢位置的索引:
public class Locations_ByCoordinates : AbstractIndexCreationTask<Location>
{
public Locations_ByCoordinates()
{
Map = locations => from l in locations
select new {_ = SpatialIndex.Generate(l.Geo.Lat, l.Geo.Lon)};
}
}
這似乎是工作,我能夠到的結果,像這樣排序:
RavenQueryStatistics stats;
var query = session.Advanced.LuceneQuery<Location>(Names.Indexes.LocationsByCoordinates)
.Statistics(out stats)
.WithinRadiusOf(radius, coordinates.Lat, coordinates.Lon);
switch (sort)
{
case Sort.Distance:
query = query.SortByDistance();
break;
case Sort.Rating:
query = query.AddOrder(l => l.Reviews.Average(r => r.Rating), true); // TODO: This throws an exception, perhaps a modified index with an aggregate is required? Maybe Map/Reduce?
break;
case Sort.Alphabetical:
query = query.OrderBy(l => l.Name);
break;
case Sort.Number_of_ratings:
query = query.AddOrder(l => l.Reviews.Count, true);
break;
case Sort.Relevance: // This is the default ordering in RavenDB.
break;
default:
throw new ArgumentOutOfRangeException("sort");
}
除了根據未知字段拋出異常的平均評分排序,每個選項都可以正常工作。我覺得這必須是Map/Reduce索引而不是Map索引。但我不知道如何寫它。
我正在從MongoDB遷移此代碼,但我曾經在客戶端按評分對文檔進行排序,我想我現在會在服務器端執行此操作。
這就是我不明白:),我一直以爲返回地圖的東西。如何使用AvgRating字段對結果進行排序?我是否需要將AvgRating屬性添加到Location類或什麼? –
地圖只是控制獲得索引的東西,即可以搜索和排序的字段。默認情況下,RavenDB將始終返回與查詢匹配的完整文檔。 –
我在理論上知道很多,但不知道如何在實踐中應用。 :)我改變了在我的'開關'塊的評級排序: 'query = query.AddOrder(「AvgRating」,true);' 它現在不會拋出錯誤,但它也排除沒有任何評論的地點。我仍然希望看到它們的評級爲0. 更改爲: AvgRating = l.Reviews.Count> 0? l.Reviews.Average(r => r.Rating):0' 現在效果很好。但我仍然想要做魔法,不完全理解正在發生的事情,那很糟糕。 :( –