Reviewing RavenBurgerCo: What could be improved?
There are two things that I would change in the RavenBurgerCo sample app.
The first would be session management, I dislike code like this:
I would much rather do that in a base controller and avoid manual session management. But that is most a design choice, and it ain’t really that important.
But what is important is the number of indexes that the application uses. We have:
- LocationIndex
- DeliveryIndex
- DriveThruIndex
And I am not really sure that we need all three. In fact, I am pretty sure that we don’t. What we can do is merge them all into a single index. I am pretty sure that the reason that there were three of them was because there there was a bug in RavenDB that made it error if you gave it a null WKT (vs. just recognize this an a valid opt out). I fixed that bug, but even with that issue in place, we can get things working:
1: public class SpatialIndex : AbstractIndexCreationTask<Restaurant>2: {
3: public SpatialIndex()4: {
5: Map = restaurants =>
6: from restaurant in restaurants7: select new8: {
9: _ = SpatialGenerate(restaurant.Latitude, restaurant.Longitude),
10: __ = restaurant.DriveThruArea == null ?11: new object[0] :12: SpatialGenerate("drivethru", restaurant.DriveThruArea),13: ___ = restaurant.DeliveryArea == null ?14: new object[0] :15: SpatialGenerate("delivery", restaurant.DeliveryArea)16: };
17: }
18: }
And from then, it is just a matter of updating the queries, which now looks like the following:
Getting the restaurants near my location (for Eat In page):
1: return session.Query<Restaurant, SpatialIndex>()2: .Customize(x =>
3: {
4: x.WithinRadiusOf(25, latitude, longitude);
5: x.SortByDistance();
6: })
7: .Take(250)
8: .Select( ... );
Getting the restaurants that deliver to my location (Delivery page):
1: return session.Query<Restaurant, SpatialIndex>()2: .Customize(x => x.RelatesToShape("delivery", point, SpatialRelation.Intersects))3: // SpatialRelation.Contains is not supported4: // SpatialRelation.Intersects is OK because we are using a point as the query parameter5: .Take(250)
6: .Select( ... ) ;
Getting the restaurants inside a particular rectangle (Map page):
1: return session.Query<Restaurant, SpatialIndex>()2: .Customize(x => x.RelatesToShape(Constants.DefaultSpatialFieldName, rectangle, SpatialRelation.Within))
3: .Take(512)
4: .Select( ... );
Note that we use DefaultSpatialFieldName, instead of indexing the location twice.
And finally, getting the restaurants that are applicable for drive through for my route (Drive Thru page):
1: return session.Query<Restaurant, SpatialIndex>()2: .Customize(x => x.RelatesToShape("drivethru", lineString, SpatialRelation.Intersects))3: .Take(512)
4: .Select( ... );
And that is that.
Really great project, and quite amazing, both client & server code. It is simple, it is elegant and it is effective. Well done Simon!
Comments
Any particular reason you'd go for a base controller instead of injecting the session via the constructor?
Bruno, It is easier to do things with a base controller.
Comment preview