cbr-1.0.0/src/Services/SimilarityCalculator.php
src/Services/SimilarityCalculator.php
<?
namespace Drupal\cbr\Services;
use Drupal\cbr\Plugin\Field\FieldType\CBRFieldInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Database\Connection;
/**
* Similarity calculator service.
* Calculates similarity between two cases.
*/
class SimilarityCalculator
{
protected $database;
function __construct(Connection $database)
{
$this->database = $database;
}
/**
* Calculate similarity between two cases.
* @param $entity1 The first case.
* @param $entity2 The second case.
* @return float The similarity [0-1] between the two cases.
*/
function calculate(EntityInterface $entity1, EntityInterface $entity2): float
{
$similarity = 0;
$sum_weight = 0;
/* @var FieldItemListInterface $field_item */
foreach ($entity1->getFields(false) as $field_item) {
if ($field_item->first() !== null && $field_item->first() instanceof CBRFieldInterface) {
/* @var FieldConfig $field_config */
$field_config = $field_item->getFieldDefinition()->getConfig($entity1->bundle());
$weight = $field_config->getThirdPartySetting('cbr', 'weight', 1);
/* @var CBRFieldInterface $field1 */
$field1 = $field_item->first();
$value1 = $field1->getValueForSimilarityCalculation($field_config);
/* @var CBRFieldInterface $field1 */
$field2 = $entity2->get($field_item->getName())->first();
if ($field2 != null) {
$value2 = $field2->getValueForSimilarityCalculation($field_config);
$similarity += $field1->calculateSimilarity($value1, $value2, $field_config) * $weight;
}
$sum_weight += $weight;
}
}
//Normalize similarity to [0-1]
if ($sum_weight != 0) {
$similarity = $similarity / $sum_weight;
} else {
$similarity = 0;
}
return $similarity;
}
/**
* Save similarity and remove cases from caclulation queue.
* @param $nid1 The first case id.
* @param $nid2 The second case id.
* @param $similarity The similarity [0-1] between the two cases.
*/
function saveSimilarity($nid1, $nid2, $similarity)
{
//Save similarity
$merge_query = $this->database->merge('cbr_similarity');
$merge_query->key(['nid1' => $nid1, 'nid2' => $nid2]);
$merge_query->fields(['similarity' => $similarity]);
$merge_query->execute();
//Remove from calculation queue
$delete_query = $this->database->delete('cbr_calculation_queue');
$delete_query->condition('nid', $nid1);
$delete_query->execute();
}
}