Search by

omniscient / omnisearch

GlitchArt

Omnisearch: search the way Doctrine is for SQL, whatever the engine - indexes declared on the classes by attributes (#[Index], #[Field]), connections and drivers, requests and responses (DBAL), a manager, finders, queries, results and objects loaded back, the indexing rule (ORM); an in-memory engine

Package info

github.com/glitchr-studio/omnisearch

pkg:composer/omniscient/omnisearch

Statistics

Installs: 16

Dependents: 1

Suggesters: 0

Stars: 0

Open Issues: 0

1.x-dev 2026-10-20 06:16 UTC

This package is auto-updated.

Last update: 2026-10-20 06:17:49 UTC


README

Search the way Doctrine is for SQL, whatever the engine: the classes declare their index by attributes, a manager hands out finders, a query is written once, the objects come back from the hits. A DBAL - connections, drivers, requests and responses - under an ORM - metadata, finders, queries, results, the indexing rule.

use Omnisearch\Mapping\{Field, Index, Type};

#[Index('article')]
#[Field('title', type: Type::STRINGS, property: 'translations.title')]
#[Field('tags', type: Type::STRINGS, property: 'tags.slug', facet: true)]
#[Field('publishedAt', type: Type::DATETIME, sort: true)]
class Article { /* your entity, implementing nothing of omnisearch */ }

$result = $manager->finder(Article::class)->search(
    (new Query('fuji'))->in('title')->where('tags', 'en-musique')->facet('tags')->sortBy('publishedAt', 'desc')->perPage(10)
);
$result->objects();                                 // Article entities, in the order of the hits
$result->hit($result->objects()[0])->matchedTokens();   // the words it matched
$result->facets(checked: ['tags' => ['en-musique']]);   // each tag, its count, checked or not

This package holds the contract and the layers above it; it requires PHP alone. The engines are packages of their own:

Package Engine
omnisearch/typesense Typesense, over glitchr/typesense-bundle's framework-free part: infix search, matched tokens, facets, discriminator sub-collections; in Symfony, that bundle hosts the indexes
Omnisearch\Memory (here) the PHP process itself: for tests and first steps

The shape comes from glitchr/typesense-bundle, whose DBAL request/response and ORM manager/finder/mapping/transformer it generalises to any engine: what the bundle's YAML said of a collection, an attribute says on the class.

The layers

Mapping\ #[Index], #[Field], Type; AttributeLoader (reflection), ClassMetadata, MetadataRegistry
DBAL\ Driver (what an engine does), DriverFactory, Connection, Request, Filter, Response, Hit, Facet, Batch (writes gathered, sent together)
ORM\ Manager, Finder, Query, Result, Indexer (the rule: what to index on persist, update, remove), Transformer (object to document), PropertyReader, ObjectStore (where the objects live)
Registry the connections by name, from their configuration
Bridge\Doctrine DoctrineObjectStore (entities identified, loaded back in the hits' order), IndexListener (the rule on Doctrine's events)
Bridge\Symfony OmnisearchBundle, its commands, Host (an engine's own bundle hosting its indexes)

Doctrine and Symfony are suggested, never required: nothing of either is loaded unless their bridge is.

Documentation

Verified, and not

  • Verified (docker compose run --rm omnisearch test in docker/, with Typesense 30.0): the whole layer on the memory engine; Doctrine entities indexed on flush and loaded back in the hits' order (SQLite); in plain PHP, nothing of Symfony nor Doctrine loaded on the memory engine and no class of a framework through omnisearch/typesense (BareTest); the Symfony bundle with the memory engine, and hosted by glitchr/typesense-bundle (omnisearch/typesense's HostedTest).
  • Verified on an application: glitchr's lesringostars declares four of its five collections with these attributes, through omnisearch/typesense and hosted by glitchr/typesense-bundle: the schemas are those its server held, byte for byte, its 628 documents and its blog's searches (pages, terms, the tags facet) unchanged; the entities load in its Laravel twin with nothing of Symfony.
  • Not verified: an engine other than Typesense and memory; Doctrine's MongoDB ODM (the store falls back on findBy(), never run); Laravel (no bridge yet: one is written when an application under Laravel indexes).

Licence

MIT. Omnisearch and its drivers are unofficial clients, affiliated with no search engine's vendor.