Skip to content

Painless / Painful? Own ranking system in PHP/Elasticsearch

License

Notifications You must be signed in to change notification settings

lrynek/painless-car-rental

Repository files navigation

Painless Car Rental

Painless / Painful? Own ranking system in PHP/Elasticsearch

image

Purpose and constraints

This is the simple educational project prepared to support my presentation during PHPers Summit 2021 conference (more recently on Warszawskie Dni Informatyki 2022 and 4Developers 2022) and to allow participants to play with Elasticsearch scoring. It is not intended to expose any architectural patterns of the code itself, so please don't stick to the directory structure or the overall code architecture too much 😉.

Docplanner Tech PHPers Summit 2021 Warszawskie Dni Informatyki 2022 4Developers 2022
image image image image

Requirements

If you need to change the Elasticsearch host the application uses, it's defined in the ApiClient class as a constant (normally worth passing it from .env params file 😉 )

In order to run the project, it is advisable to install an instance of latest stable version of Elasticsearch (it's 7.16.0 version at the moment of the presentation https://www.elastic.co/guide/en/elasticsearch/reference/7.16/index.html)

Setup

  1. Create cars index in Elasticsearch (Index/Create HTTP request*)
  2. Populate the index with sample cars data (Index/Bulk HTTP request*)
  3. Go to project's root directory in the terminal
  4. Start Symfony server symfony server:start --no-tls
  5. Go to http://127.0.0.1:8000/

(*) - all HTTP requests can be executed either:

How to play with it?

All Elasticsearch implementation related code is placed in src/Elasticsearch directory.

The core ranking logic is built from specific Factors classes:

  • RawScoreFactor that propagates the originally calculated document score to the overall scoring (as it is being overwritten / replaced by all custom functions) in order to weight it along with other custom factors provided by the developer
  • DodgePromoFactor that promotes all documents that has producer field equal to Dodge (you can switch to any other)
  • ColorRelevanceFactor that ranks higher these documents / cars which has more intensive or exclusive color to the ones that are being filtered out on every app's request

Then the RecommendedSorter that includes all those ranking factors is set up in CarRepository to guarantee it applies to every search request:

<?php
// ...

final class RecommendedSorter implements FactorSorterInterface
{
  // ...

	public function __construct(private ?Factors $factors = null)
	{
		$this->factors ??= new Factors(
			new RawScoreFactor(new Weight(1)),
			new DodgePromoFactor(new Weight(100)),
			new ColorRelevanceFactor(new Weight(50)),
		);
	}

  // ...
}

💡 You can comment out any of the factors to see how they contribute to the ranking.

💡 You can add any other factor you want on base of those existing ones.

💡 You can also play with all those factors' weights as well in the RecommendedSorter constructor and see the influence on the overall ranking.

💡 In order to get rid of customly ranked results on the listing you can switch to DefaultSorter that sorts all results ascending by their id.

Copyrights

Apart from the project's LICENSE, all car photo samples used in the project are taken from Google search results and all copyrights applies to their respective authors and shouldn't be used further than private/educational use without their explicit consent.

About

Painless / Painful? Own ranking system in PHP/Elasticsearch

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •