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 |
---|---|---|---|
- PHP 8.2.2
- Symfony CLI (https://symfony.com/download)
- Elasticsearch 7.16.0 running on
localhost:9200
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)
- Create
cars
index in Elasticsearch (Index/Create
HTTP request*) - Populate the index with sample cars data (
Index/Bulk
HTTP request*) - Go to project's root directory in the terminal
- Start Symfony server
symfony server:start --no-tls
- Go to http://127.0.0.1:8000/
(*) - all HTTP requests can be executed either:
- from within PhpStorm's built-in REST HTTP client (samples in .elasticsearch-http-requests directory)
- in Insomnia REST HTTP client (import insomnia.json file with all the samples)
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 developerDodgePromoFactor
that promotes all documents that hasproducer
field equal toDodge
(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
.
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.