1. Go to this page and download the library: Download honey-odm/loupe library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
honey-odm / loupe example snippets
use DateTimeInterface;
use Honey\ODM\Core\Config\AsDocument;
use Honey\ODM\Core\Config\AsField;
use Honey\ODM\Core\Mapper\PropertyTransformer\DateTimeImmutableTransformer;
use Honey\ODM\Loupe\Config\AsAttribute;
use Honey\ODM\Loupe\Config\AsIndex;
#[AsDocument(collection: 'movies')] // <-- One SQLite database per collection
#[AsIndex(languages: ['en'], stopWords: ['the'], typoTolerance: false)]
final class Movie
{
/**
* @param list<string> $genres
* @param array{lat: float, lng: float}|null $location
*/
public function __construct(
#[AsField(name: 'movie_id', primary: true)] // <-- Exactly 1 property must be marked as primary key
public int $id,
#[AsField(name: 'title')] // <-- Optionally set the field name on Loupe's side
#[AsAttribute(sortable: true, searchable: true)]
public string $name,
#[AsField]
#[AsAttribute(filterable: true)] // <-- Array attribute: `genres = 'Action'` means "contains"
public array $genres = [],
#[AsField]
#[AsAttribute(filterable: true, sortable: true)]
public ?int $year = null,
#[AsField]
#[AsAttribute(filterable: true)] // <-- Any attribute can carry geo filters, no reserved `_geo`
public ?array $location = null,
#[AsField(name: 'released_at', transformer: DateTimeImmutableTransformer::class)]
#[AsAttribute(sortable: true)]
public ?DateTimeInterface $releasedAt = null,
) {
}
}
use Honey\ODM\Loupe\ObjectManagerFactory;
// On disk: one SQLite database per collection, under $dataDir/{collection}/
$objectManager = ObjectManagerFactory::create(dataDir: __DIR__ . '/var/loupe');
// In memory: nothing touches the filesystem - great for tests and ephemeral use
$objectManager = ObjectManagerFactory::create();
// Get a repository for your entity
$movieRepository = $objectManager->getRepository(Movie::class); // <-- Reads the AsDocument / AsField attributes automatically
use Honey\ODM\Core\Config\ClassMetadataRegistry;
use Honey\ODM\Loupe\Schema\SchemaUpdater;
$updater = new SchemaUpdater(
$objectManager->transport->indexRegistry, // <-- LoupeTransport::$indexRegistry is public for exactly this
new ClassMetadataRegistry(configurations: [Movie::class]),
);
$updater->updateSchema();
use Honey\ODM\Core\Criteria\Criteria;
use function Honey\ODM\Core\Criteria\field;
// Find all movies
$movies = $movieRepository->findAll();
// Find by ID
$movie = $movieRepository->find(1);
// Find by criteria (array of equality filters, AND-combined)
$movies = $movieRepository->findBy(['year' => 1977]);
// Find one by criteria
$movie = $movieRepository->findOneBy(['year' => 1977]);
// Using the portable Criteria API for complex queries
$movies = $movieRepository->findBy(
Criteria::create()->where(field('genres')->equals('Action'))->orderBy('year', 'desc'),
);
use Honey\ODM\Core\Criteria\Criteria;
use function Honey\ODM\Core\Criteria\field;
use function Honey\ODM\Core\Criteria\not;
$results = $movieRepository->findBy(
Criteria::create()
->where(
field('genres')->equals('Action'),
not(field('year')->lessThan(1980)),
)
->orderBy('year', 'desc')
->limit(10),
);
use Honey\ODM\Core\Config\ClassMetadataRegistry;
use Honey\ODM\Loupe\Schema\SchemaUpdater;
$updater = new SchemaUpdater(
$objectManager->transport->indexRegistry,
new ClassMetadataRegistry(configurations: [Movie::class, Actor::class]),
);
$updater->updateSchema(function (string $class, $metadata, bool $needsReindex) {
if ($needsReindex) {
// Loupe froze this index's configuration at creation time - your #[AsAttribute] /
// #[AsIndex] attributes have since changed, and the stored data no longer matches them.
// Deciding whether (and how) to re-index is an application concern, not this library's:
// updateSchema() only ever reports drift, it never re-indexes on its own.
}
});
use Honey\ODM\Core\Config\TransformerMetadata;
#[AsField(transformer: new TransformerMetadata(
MyCustomTransformer::class,
['option1' => 'value1'],
))]
public mixed $myProperty;
use Honey\ODM\Core\Criteria\Criteria;
use Honey\ODM\Loupe\Repository\ObjectRepositoryInterface;
use Honey\ODM\Loupe\Repository\ObjectRepositoryTrait;
use function Honey\ODM\Core\Criteria\field;
/**
* @implements ObjectRepositoryInterface<Movie>
*/
final class MovieRepository implements ObjectRepositoryInterface
{
use ObjectRepositoryTrait;
public function findReleasedAfter(int $year): iterable
{
return $this->findBy(Criteria::create()->where(field('year')->greaterThan($year)));
}
}
$movieRepository = new MovieRepository($objectManager, Movie::class);
$objectManager->registerRepository(Movie::class, $movieRepository);
use Honey\ODM\Core\Event\PrePersistEvent;
use Honey\ODM\Loupe\ObjectManagerFactory;
$eventDispatcher = new EventDispatcher(); // <-- Any PSR-14 compliant dispatcher
$objectManager = ObjectManagerFactory::create(eventDispatcher: $eventDispatcher);
$eventDispatcher->addListener(PrePersistEvent::class, function (PrePersistEvent $event) {
var_dump($event->object); // <-- The object being persisted
});
use Honey\ODM\Core\Config\AsDocument;
use Honey\ODM\Loupe\ObjectManagerFactory;
use Loupe\Loupe\Configuration;
$objectManager = ObjectManagerFactory::create(
configurator: function (Configuration $configuration, AsDocument $classMetadata): Configuration {
// Replay whatever your production backend already declares - here, the settings you
// keep for Meilisearch indexes.
$settings = json_decode(file_get_contents(
sprintf('%s/config/indexes/%s.json', __DIR__, $classMetadata->collection),
), true);
return $configuration
->withFilterableAttributes($settings['filterableAttributes'])
->withSortableAttributes($settings['sortableAttributes'])
->withSearchableAttributes($settings['searchableAttributes']);
},
);