次のようなモデルがあるとします。
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; }
}
評価の降順で並べ替えられた一致する場所を返すクエリを作成するにはどうすればよいですか?
ジオポイントの周囲の特定の半径内の場所を照会できるインデックスがあります。
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 インデックスではなく Map/Reduce インデックスでなければならないと思います。しかし、私はそれを書く方法がわかりません。
このコードを MongoDB から移行していますが、以前はクライアント側で評価によってドキュメントを並べ替えていましたが、サーバー側でこれを行うと思いました。