Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor index manager #8

Merged
merged 8 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

83 changes: 62 additions & 21 deletions src/Loupe/Index.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
namespace Daun\StatamicLoupe\Loupe;

use Daun\StatamicLoupe\Search\Snippets;
use Exception;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Loupe\Loupe\Config\TypoTolerance;
use Loupe\Loupe\Configuration;
use Loupe\Loupe\Loupe;
use Loupe\Loupe\LoupeFactory;
use Loupe\Loupe\SearchParameters;
use Statamic\Contracts\Search\Searchable;
use Statamic\Search\Documents;
Expand All @@ -16,7 +19,7 @@

class Index extends BaseIndex
{
protected Loupe $client;
protected ?Loupe $client = null;

protected array $defaults = [
'fields' => ['title'],
Expand All @@ -37,19 +40,38 @@ class Index extends BaseIndex
protected ?array $snippetAttributes = null;

public function __construct(
protected Manager $manager,
protected LoupeFactory $factory,
protected Filesystem $filesystem,
string $name,
array $config,
?string $locale = null
) {
$config = [...$this->defaults, ...$config];
parent::__construct($name, $config, $locale);
}

protected function base(): string
{
return Str::finish($this->config['path'] ?? storage_path('statamic/loupe'), '/');
}

protected function dir(): string
{
return $this->base().$this->name;
}

$this->client = $this->manager->get($this->name, $this->configuration());
protected function path(): string
{
return $this->base().$this->name.'/loupe.db';
}

public function client(): Loupe
{
if (! $this->client) {
$this->createIndex();
$this->client = $this->factory->create($this->dir(), $this->configuration());
}

return $this->client;
}

Expand All @@ -71,7 +93,7 @@ public function lookup($query)
$this->config['highlight_tags'][1]
);

$result = $this->client->search($parameters);
$result = $this->client()->search($parameters);

return collect($result->getHits())
->map(fn ($hit) => [
Expand Down Expand Up @@ -100,22 +122,22 @@ protected function configuration(): Configuration

public function delete($document)
{
$this->client->deleteDocument($document->getSearchReference());
$this->client()->deleteDocument($document->getSearchReference());
}

public function exists()
{
return $this->manager->indexExists($this->name);
return $this->filesystem->exists($this->path());
}

protected function insertDocuments(Documents $documents)
{
// After upgrading Loupe, a reindex might be required
if ($this->client->needsReindex()) {
$this->resetIndex();
if ($this->client()->needsReindex()) {
$this->truncateIndex();
}

$this->client->addDocuments($documents->all());
$this->client()->addDocuments($documents->all());
}

public function insertMultiple($documents)
Expand All @@ -138,7 +160,7 @@ public function insertMultiple($documents)

public function update()
{
$this->resetIndex();
$this->truncateIndex();

$this->searchables()->lazy()->each(fn ($searchables) => $this->insertMultiple($searchables));

Expand All @@ -147,18 +169,31 @@ public function update()

protected function deleteIndex()
{
$this->manager->dropIndex($this->name);
$this->filesystem->cleanDirectory($this->path());
}

protected function createIndex()
{
$this->manager->createIndex($this->name);
$dir = $this->dir();
$db = $this->path();

if (! $this->filesystem->exists($db)) {
$this->filesystem->ensureDirectoryExists($dir);
$this->filesystem->put($db, '');
}

if (! $this->filesystem->isFile($db)) {
throw new Exception(sprintf('The Loupe index "%s" does not exist and cannot be created.', $db));
}

if (! $this->filesystem->isWritable($db)) {
throw new Exception(sprintf('The Loupe index "%s" is not writable.', $db));
}
}

protected function resetIndex()
protected function truncateIndex()
{
$this->deleteIndex();
$this->createIndex();
$this->client()->deleteAllDocuments();
}

public function extraAugmentedResultData(Result $result)
Expand All @@ -167,13 +202,19 @@ public function extraAugmentedResultData(Result $result)

return [
'search_score' => $raw['_rankingScore'] ?? null,
'search_highlights' => Arr::only($raw['_formatted'] ?? [], $this->config['highlight_attributes']),
'search_snippets' => $this->createSnippets($raw['_formatted'] ?? [], $this->config['snippet_attributes']),
'search_highlights' => $this->getHighlights($raw['_formatted'] ?? []),
'search_snippets' => $this->getSnippets($raw['_formatted'] ?? []),
];
}

protected function createSnippets(array $highlights, array $attributes): array
protected function getHighlights(array $fields): array
{
return Arr::only($fields, $this->config['highlight_attributes'] ?? []);
}

protected function getSnippets(array $fields): array
{
$attributes = $this->config['snippet_attributes'] ?? [];
if (empty($attributes)) {
return [];
}
Expand All @@ -186,11 +227,11 @@ protected function createSnippets(array $highlights, array $attributes): array
[$start, $end] = $this->config['highlight_tags'];

return collect($this->snippetAttributes)
->map(function ($words, $attr) use ($highlights, $start, $end) {
->map(function ($words, $attr) use ($fields, $start, $end) {
try {
return (new Snippets($start, $end, $words))->generate($highlights[$attr]);
return (new Snippets($start, $end, $words))->generate($fields[$attr]);
} catch (\Exception $e) {
return Str::limit($highlights[$attr], limit: 200, preserveWords: true);
return Str::limit($fields[$attr], limit: 200, preserveWords: true);
}
})
->all();
Expand Down
67 changes: 0 additions & 67 deletions src/Loupe/Manager.php

This file was deleted.

4 changes: 1 addition & 3 deletions src/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace Daun\StatamicLoupe;

use Daun\StatamicLoupe\Loupe\Manager;
use Illuminate\Foundation\Application;
use Statamic\Facades\Search;
use Statamic\Providers\AddonServiceProvider;
Expand All @@ -13,9 +12,8 @@ public function bootAddon(): void
{
Search::extend('loupe', function (Application $app, array $config, string $name, ?string $locale = null) {
return $app->makeWith(Loupe\Index::class, [
'manager' => new Manager($config['path'] ?? storage_path('statamic/loupe')),
'config' => $config,
'name' => $name,
'config' => $config,
'locale' => $locale,
]);
});
Expand Down
Loading