Simple Rules Based MongoDB Queries
Simple process diagram of query generation engine

Simple Rules Based MongoDB Queries

"How can we scale this?" The question kept resonating in my mind as I built a Java service to search a MongoDB database using Spring Data. The problem wasn't whether the database would handle more traffic but how I could build all the queries needed to search the database for all possible combinations of search attributes. To give a little background, the search comes from our website product, a company specific website where users can search for properties available from a property management company. Think of the product like Airbnb, Booking.com or Expedia, but specific to one company. Below is an example of the search page.

Original Solution

To make the issue clear, I would like to present an example. On our search page, we allow the traveler to search for properties available in a range of dates, and we allow them to specify the number of guests. This results in three queries: one for the date range, one for the number of guests, and one for both guests and date range. We also allow the option to view only specific property types, as well as filtering properties by certain criteria and this results in the following 7 queries:

  • date range
  • date range with guests
  • date range with property type
  • date range with guests and property type
  • property type
  • guests
  • guests and property type

The astute reader will notice that this is a total of 2?-1 queries, where N is the number of attributes with which a user can search. Even though Spring Data allows us to code each of these queries in a single line in a MongoRepository interface extension, this is exponential growth. At the time the framework made that acceptable; after all, with our small N of 3 there are only 7 possible queries. However, we began to brainstorm ways in which the search could grow. We saw the opportunity for further, more specific filters, such as:

  • square feet
  • latitude and longitude
  • star rating
  • languages spoken
  • city
  • state
  • number of bathrooms
  • number of bedrooms
  • check in time
  • check out time
  • supports late checkout
  • allows children
  • allows infants
  • has multiple beds
  • specific bed type (king, queen, etc)
  • allows smoking
  • accepts specific payment options
  • has a pool
  • has air conditioning
  • has a hot tub
  • has a view

The math-savvy among us will calculate that with the 24 possible criteria, we now required more than 16 million queries; obviously not acceptable, despite the ability to write a query in a single line of code.

Necessity is the mother of invention

I needed another solution, and that's when I built something cool. I realized that, with some minor refactoring of the code, I could get all the attributes we would search as a map of attribute names and desired values. I could build a simple rules engine and pass the map to each rule, letting the rule build the final query to be executed. After some quick analysis, I determined that the interface should be a single method, taking the search attributes and returning a list of criteria as shown below:

Because each rule implements the interface, they can be injected as a list of all rules into the service. The service iterates the rules and applies the criteria to the query, as shown below:

Now we have a very simple rules engine for querying a MongoDB database that can be expanded quickly and easily by creating new rules as required. Let’s explore exactly how simple it is by adding a new rule. Our new filter criteria will allow users to specify a smoking preference. Step one in implementing this new requirement is a new rule implementation:

And step two is...non-existent. That's it. Now, obviously, this isn't production quality code because it isn't protecting itself from bad inputs (among other issues), and there really should be some unit tests for this new rule. However, we are now looking at 17 lines of code for a new search attribute, instead of the unsustainable 2?-1 per attribute in the original solution. It’s that simple.

Final Words

Although this isn't a perfect solution and doesn't implement some of the requirements for a full-fledged rules engine, such as scoring and priority, it works for our purposes and is extensible enough to allow us to incorporate new requirements as they become apparent. We are all about iterative solutions here and this is an effective version 1. I am always open to suggestions and I look forward to reading the community’s suggestions in the comments.


Shameless plug: If you are a vacation rental or hotel property manager, check out the platform we are building at JANIIS or follow me on LinkedIn or Medium for more technical posts about how we are building JANIIS

要查看或添加评论,请登录

Daniel Ranallo的更多文章

  • Lambda Architecture Overview

    Lambda Architecture Overview

    Overview The lambda architecture is a three-layer data analytics architecture designed to run analytics on large…

    1 条评论
  • Taints and Tolerations and Selectors, oh my

    Taints and Tolerations and Selectors, oh my

    Kubernetes is a very advanced orchestration framework with many features that allow for advanced scheduling and…

    3 条评论
  • Basic Kubernetes for Developers

    Basic Kubernetes for Developers

    Kubernetes is an open-source container orchestration framework. It handles allocating physical resources for containers…

  • ElasticSearch Phonetic Algorithms

    ElasticSearch Phonetic Algorithms

    What is a phonetic algorithm Phonetic algorithms are transformations on text to be indexed that modify the text…

    1 条评论
  • ElasticSearch Overview

    ElasticSearch Overview

    What is ElasticSearch ElasticSearch is a document-oriented near real-time NoSQL database that is exceptional at tasks…

  • Apache Flink Introduction

    Apache Flink Introduction

    What is Flink Apache Flink is a dataflow technology that enables developers to work with infinite streams of arbitrary…

  • Life Of A Feature Request

    Life Of A Feature Request

    I was recently asked what development methodology we use at JANIIS to produce software. If you don't know what a…

    1 条评论

社区洞察

其他会员也浏览了