|Number of votes:||5|
Over the last few months EPiServer Find has become my new favorite weapon of choice for many, many coding challenges. It’s so easy – yet so powerful. And as a search geek I love this new way of juggling information around.
One of the latest projects I’ve been working on with Find was a demo site, in the shape of a fictional airline called Fly Find. This was originally @joelabrahamsson ‘s baby, but I’ve been so lucky as to adopt it add a few gimmicks and put it live.
I figured I’d take this chance to give introduce this demo site from a user perspective – as well as give a small peek behind the scenes. So, let’s being the tour…
Start of by going to http://flyfind.demo.episerver.com. First thing you should notice is that pretty much everything on this site is driven behind the scenes by Find – both used as a search engine – but more importantly as a tool to allow advanced navigation for users to get to business critical information. Since this is an airline the important stuff is mostly destinations you can fly to – and the actual flights themselves.
In the bottom of the result page you’ll find 3 Find-boxes. 2 location based searches, searching for destinations close to (and far away) from your current location – as well as a listing of latest news items. The logic that produces the list is really simple – like in the case of the “Destinations Nearby”:
Note that we skip the first 1, since you probably don’t want to go where you already are
If you go to the “Destinations” page, in the top menu, you’ll get to a page where you can see all destinations – both on a map and in a list. And on the side you have your facets and filters.
Try to narrow down into a facet – or slide the temperature bar and see how the list updates on the fly (you guessed right – AJAX). This time, we build up the query in a few more lines of code to get all the filters and facets included.
Even, if you drill down and look at an individual destination, it’s filled with Find navigation like destinations close-by, destinations on same continent and similar destinations (based on their textual contents).
In the bottom of the Destination description you’ll also find the Arrivals / Departure board of the relevant airport – but I’ll talk more about flights soon. For now, let’s have a look at the classic Quick Search in the upper right corner.
Start typing and you’ll soon be happily surprised as it searches as you type. Hit enter and it’ll take you to the result page.
On the result page we see some other classic features:
Almost all of this stuff is done when the query is being built up:
And now lets look at the Flights
So…So far we haven’t done anything really out of the ordinary. It’s all based on a standard installation & index of Find for EPiServer CMS (in this case 6R2 with PageTypeBuilder), spiced up with some fancy querying around the site and made pretty by Twitter Bootstrap and Flickr images. In fact, I’m guessing most of the time spend on the site so far went into finding images with proper license rights and texts – and not really into the coding.
So I figured – why not spice things up a bit and add the one concept that all airlines have: Flights….Lots of flights. That’ll show both indexing content outside EPiServer as well as great performance when doing complex queries against rather large data sets. However, since this is a fictional airline we’ll also need fictional flights. So the first thing I did was to define what a flight was – and wrote a little scheduled job that I can run manually to generate them and index them. Once generated they purely live in Find’s index – although in a real-world scenario they would probably also live in some other big database.
Although I’m a frequent flyer I have never owned my own airline – however it doesn’t take much imagination to come up with what a flight essentially consist of data wise. It’s an aircraft going from 1 place to another at a specific time. Based on the aircraft model it has a certain number of seats, some of them might have already been sold.
A few Google searches allowed me to build up a fleet of aircraft types for FlyFind and then it basically just boiled down to generating flights between random destinations at random times, with random number of seats sold, with a random aircraft – but where the distance was within the aircraft range. Arrival time can then be calculated with the speed of the aircraft and the random departure time. And based on the distance, seats left and some random discount I even managed to come up with a price. Then it’s basically just a question of bulk indexing them in Find using the .Index(…) method.
Note how this code also has some handling to ensure you can stop/restart it and it’ll keep adding on a certain number of flights per day until it reaches a designated maximum in the database. For the demo site we set it up to 1 million flights at 3500 flights / day. In the backend UI you can explore the index:
Now that we have a bunch of flights it seems like a good idea to make a way to navigate them. For starters I figured it would be nice to get the classical overview of all the flights in the air right now. On http://flyfind.demo.episerver.com/Travel-Information/Flights-Status/ I made an easy way to drill-down into the planes in the air right now. Nothing really fancy about it, but the fact that there’s always ~500+ flights in the air gives you an idea about how big the size of FlyFind’s international operation is
Again, if you looked at other Find query code, this will hold no surprises.
So far, so good. Now we’re almost there. All that’s left to do is to build a booking engine – piece of cake
Now, for this demo I don’t really care about the e-commerce aspect of completing a booking, but I figured that allowing visitors to find flight connections that takes them where they want to go would be a fun challenge – and at the same time it would be a nice demo of the great performance Find can produce when searching in large datasets (such as flights). Personally I’ve always been fascinated by AI and AI-like technologies so this seemed like the perfect time to dip into the magic hat and pull out the good old A* algorithm for shortest path finding – and modify it slightly to use Find for querying and return multiple paths to choose from. But before we dive into the details, try it out: http://flyfind.demo.episerver.com/Find-Flights/.
Once again, note how this page uses Find for everything – even the contents of the drop-down lists are based on Find queries, the “From” ordering destinations based on your current location and the “To” presenting an alphabetical list of destinations.
Once you find some flight connections you’ll in the top see exactly how many Find Queries happened behind the scenes in order to find those flights – and how long time the server used on each query (in average). Now, you can read all about the A* algorithm in detail here, but essentially you work with an “open” and “closed” list, start with your origin in the open list and then do a breath-first search, adding destinations to the “closed” list as you reach them and stop when you’ve reached the desired destination – after which you backtrack to get the path. All paths prioritized by a heuristics algorithm that in this case just considers the geographical distance between current destination and the end goal (and the distance already traveled).
In other words – in the example above it starts by having Copenhagen on the open list, doing a query on all flights from Copenhagen from the start time (and 8 hours ahead – I don’t want to wait longer for a connecting flight). Of course it ensures all flights have seats available and that there is at least 30 min connection time between connections. Then, all possible destinations from those flights are added to the open list (while Copenhagen goes to the Closed list) and they are prioritized based on the heuristics mentioned above. This continues until a certain threshold (not implemented) – or the end-goal is reached – after which we’ll track back and see which flights that path is comprised of.
The code might not be the prettiest I’ve ever written – but it gets the job done.
Clever observers might point out that there are a lot of performance improvements to be done – like running queries in parallel – or doing bulk queries. However this works and is somewhat understandable so this is what I have now.
I hope you found this post enjoyable and perhaps even slightly educational. Feel free to drop comments or questions below.
Want to try out building your own search using Find? It’s easy, just go to find.episerver.com and create an account and a developer index to get started!