Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Reviewing RavenBurgerCo: What Could be Improved?

DZone's Guide to

Reviewing RavenBurgerCo: What Could be Improved?

· Java Zone ·
Free Resource

RavenDB vs MongoDB: Which is Better? This White Paper compares the two leading NoSQL Document Databases on 9 features to find out which is the best solution for your next project.  

There are two things that I would change in the RavenBurgerCo sample app.

The first would be session management, I dislike code like this:

image

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:

    public class SpatialIndex : AbstractIndexCreationTask<Restaurant>

    {

        public SpatialIndex()

        {

            Map = restaurants =>

                  from restaurant in restaurants

                  select new

                      {

                          _ = SpatialGenerate(restaurant.Latitude, restaurant.Longitude),

                         __ = restaurant.DriveThruArea == null ? 

                                       new object[0] : 

                                       SpatialGenerate("drivethru", restaurant.DriveThruArea),

                         ___ = restaurant.DeliveryArea == null ? 

                                       new object[0] : 

                                       SpatialGenerate("delivery", restaurant.DeliveryArea)

                     };

       }

   }

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):

    return session.Query<Restaurant, SpatialIndex>()

        .Customize(x =>

                       {

                           x.WithinRadiusOf(25, latitude, longitude);

                           x.SortByDistance();

                       })

        .Take(250)

        .Select( ... );

Getting the restaurants that deliver to my location (Delivery page):

    return session.Query<Restaurant, SpatialIndex>()

        .Customize(x => x.RelatesToShape("delivery", point, SpatialRelation.Intersects))

        // SpatialRelation.Contains is not supported

        // SpatialRelation.Intersects is OK because we are using a point as the query parameter

        .Take(250)

        .Select( ... ) ;

Getting the restaurants inside a particular rectangle (Map page):

 

    return session.Query<Restaurant, SpatialIndex>()

        .Customize(x => x.RelatesToShape(Constants.DefaultSpatialFieldName, rectangle, SpatialRelation.Within))

        .Take(512)

        .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):

    return session.Query<Restaurant, SpatialIndex>()

        .Customize(x => x.RelatesToShape("drivethru", lineString, SpatialRelation.Intersects))

        .Take(512)

        .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!




Get comfortable using NoSQL in a free, self-directed learning course provided by RavenDB. Learn to create fully-functional real-world programs on NoSQL Databases. Register today.

Topics:

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}