Blog

Simple product search

31. 03. 2022

The problem

We have the data about our products stored in both ElasticSearch and MySQL database. The data in both storages is the same. We mainly query the ElasticSearch. However, from time to time, we need to fetch the data directly from MySQL, while we do some fancy experiments in ElasticSearch. We would like to access the data about a specific product from our frontend, so that we can display it to our customer.

As we do have quite a traffic, we also need some kind of caching mechanism implemented. A simple filesystem cache is sufficient for now, but we need to be able to switch it for something more advanced in the future, by just modifying the config file.

The business always wants to know what the most successful products are. Therefore, we also need to track the number of requests for each product. We are again ok with storing the information in the plain text file for now. Keep in mind that we will need to change the storage in the future, as well and swap it for something more robust. 

Your mission, dear candidate, should you decide to accept it, is the following:

You should create a new controller with a method, accepting id of the product as a parameter. The method should return json representation of the product data.

A basic workflow for the task:

  • Request with product id comes in.
  • If a product is cached retrieve from cache.
  • If a product is not cached, retrieve from ElasticSearch/MySQL and add to the cache.
  • Increment the number of requests for the given product.
  • Return product data in JSON.

A controller might look like the following:


class ProductController
{

    /**
     * @param string $id
     * @return string
     */
    public function detail($id)
    {
        // do stuff and return json
    }

}

 

Things that might help you out:

We do have drivers for both ElasticSearch and MySQL, so you do not have to write them. You can assume they work. By calling their methods, you will get an array of data for given product. Each of them implements its interface: 



interface IElasticSearchDriver
{
	/**
	 * @param string $id
	 * @return array
	 */
	public function findById($id);
}

interface IMySQLDriver
{
	/**
	 * @param string $id
	 * @return array
	 */
	public function findProduct($id);
}

You can also safely assume that:

  • The outer framework does exactly what you need it to do. If you need to pass some parameters to constructor of the controller, it always passes the correct ones.
  • Whatever product id is passed, the drivers always find the product. You do not have to deal with "Not found" exceptions.
  • The cache is infinite. You do not need to worry about cache invalidation. Once the data is cached, we do not need to remove it, ever.
  • The info about number of requests for given product is just a simple pair productId => numberOfRequests, no other information is needed.
Share on: