cmsig/seal-memory-adapter
In-memory adapter for the SEAL search engine. Stores indexed documents in an array, making it ideal for tests and as a reference implementation. Use directly via Engine or via DSN: memory://
Installation:
composer require cmsig/seal cmsig/seal-memory-adapter
Ensure cmsig/seal is installed as the base abstraction layer.
First Use Case: Initialize the adapter for local development/testing of search functionality:
use CmsIg\Seal\Adapter\Memory\MemoryAdapter;
use CmsIg\Seal\Engine;
use CmsIg\Seal\Schema\Builder;
$schema = (new Builder())->addTextField('title')->addTextField('content');
$engine = new Engine(new MemoryAdapter(), $schema);
// Index a document
$engine->index('doc1', ['title' => 'Test', 'content' => 'Laravel Search']);
// Search
$results = $engine->search('Test');
DSN Configuration:
Use the memory:// DSN in Laravel’s .env for seamless integration:
SEAL_ADAPTER=memory://
Laravel Service Provider:
Bind the adapter in AppServiceProvider:
public function boot()
{
$this->app->singleton('seal.engine', function ($app) {
$schema = (new Builder())->addTextField('title');
return new Engine(new MemoryAdapter(), $schema);
});
}
Testing Search Logic: Replace external search dependencies in tests:
public function test_search_functionality()
{
$engine = new Engine(new MemoryAdapter(), $this->schema);
$engine->index('test', ['title' => 'Laravel']);
$results = $engine->search('Laravel');
$this->assertCount(1, $results);
}
Local Development Preview: Use the adapter for real-time search previews in admin panels:
public function showSearchPreview(Request $request)
{
$engine = app('seal.engine');
$results = $engine->search($request->query('q'));
return view('search.preview', compact('results'));
}
Dual-Write System: Sync memory to a production search engine via events:
// In a service class
public function indexDocument($id, $data)
{
$engine = app('seal.engine');
$engine->index($id, $data);
// Trigger sync to production engine
event(new DocumentIndexed($id, $data));
}
Schema Mapping: Align Laravel Eloquent models with SEAL schemas:
$schema = (new Builder())
->addStringField('id')
->addTextField('name')
->addIntegerField('price');
Query Builder: Use SEAL’s query DSL for complex searches:
$query = new Query\Builder();
$query->addMust('title', 'Laravel');
$query->addShould('content', 'Search');
$results = $engine->search($query->build());
Pagination: Leverage SEAL’s pagination support:
$results = $engine->search('query', 10, 0); // 10 results, page 0
Laravel Scout Alternative: Use as a local test double for Scout:
// config/seal.php
'adapter' => env('APP_ENV') === 'testing' ? 'memory://' : 'algolia://',
Non-Persistent Data:
Memory Limits:
memory_get_usage()) and set limits:
ini_set('memory_limit', '256M');
Concurrency Risks:
Mutex) if needed.Schema Mismatches:
$engine->assertSchema($document);
No Advanced Features:
Inspect Memory State:
$adapter = $engine->getAdapter();
dd($adapter->getDocuments()); // View all indexed documents
Clear Memory:
$adapter->clear(); // Reset the adapter
Log Queries: Decorate the adapter to log operations:
$adapter = new class extends MemoryAdapter {
public function index($id, $document)
{
\Log::debug("Indexed: {$id}", $document);
parent::index($id, $document);
}
};
Custom Adapter:
Extend MemoryAdapter for additional features:
class CachedMemoryAdapter extends MemoryAdapter {
public function __construct(private Cache $cache) {}
public function index($id, $document)
{
$this->cache->put("seal:{$id}", $document);
parent::index($id, $document);
}
}
Hybrid Adapter: Combine with a persistent adapter:
class HybridAdapter implements AdapterInterface {
public function __construct(
private MemoryAdapter $memory,
private AdapterInterface $persistent
) {}
public function index($id, $document)
{
$this->memory->index($id, $document);
$this->persistent->index($id, $document);
}
}
Laravel Facade: Create a facade for cleaner syntax:
// app/Facades/Search.php
public static function index($id, $data) {
return app('seal.engine')->index($id, $data);
}
DSN Format:
Only memory:// is supported; no additional options are configurable.
Case Sensitivity: Searches are case-sensitive by default. Normalize fields if needed:
$schema->addTextField('title')->setNormalizer(fn($value) => strtolower($value));
Field Types:
SEAL’s field types (e.g., TextField, IntegerField) must match document data. Use assertSchema() to validate.
Batch Indexing: Reduce overhead by batching operations:
$engine->indexBatch([
'doc1' => ['title' => 'Batch 1'],
'doc2' => ['title' => 'Batch 2'],
]);
Avoid Large Documents: Keep document sizes under 1MB to prevent memory bloat.
Use for Small Datasets:
Ideal for <10,000 documents. For larger datasets, switch to a disk-based adapter (e.g., cmsig/seal-filesystem-adapter).
How can I help you explore Laravel packages today?