diff --git a/src/Api/Controllers/SearchController.php b/src/Api/Controllers/SearchController.php index 1697d85..3d0ee4f 100644 --- a/src/Api/Controllers/SearchController.php +++ b/src/Api/Controllers/SearchController.php @@ -60,7 +60,7 @@ class SearchController extends ListDiscussionsController $filterQuery ->add($this->sentenceMatch($search)) ->add($this->wordMatch($search)) -// ->add($this->partialMatch($search)) + ->add($this->partialMatch($search)) ; } @@ -240,9 +240,7 @@ class SearchController extends ListDiscussionsController protected function partialMatch(string $q) { - $wildcard = (new WildcardQuery('content', "*$q*")) - ->caseSensitivity(false) - ->rewrite('constant_score'); + $wildcard = (new MatchQuery('content_partial', $q)); return BoolQuery::create() // Discussion titles @@ -256,7 +254,7 @@ class SearchController extends ListDiscussionsController ->add( BoolQuery::create() ->add(TermQuery::create('type', 'posts'), 'filter') - ->add($wildcard->boost(.5)), + ->add($wildcard->boost(.2)), 'should' ); } diff --git a/src/Commands/BuildCommand.php b/src/Commands/BuildCommand.php index a1f433f..74271c1 100644 --- a/src/Commands/BuildCommand.php +++ b/src/Commands/BuildCommand.php @@ -44,6 +44,7 @@ class BuildCommand extends Command $properties = [ 'properties' => [ 'content' => ['type' => 'text', 'analyzer' => 'flarum_analyzer'], + 'content_partial' => ['type' => 'text', 'analyzer' => 'flarum_analyzer_partial', 'search_analyzer' => 'flarum_analyzer'], 'created_at' => ['type' => 'date'], 'updated_at' => ['type' => 'date'], 'is_private' => ['type' => 'boolean'], @@ -67,10 +68,27 @@ class BuildCommand extends Command 'index' => $index, 'body' => [ 'settings' => [ + 'index.max_ngram_diff' => 10, 'analysis' => [ 'analyzer' => [ 'flarum_analyzer' => [ 'type' => $settings->get('blomstra-search.analyzer-language') ?: 'english' + ], + 'flarum_analyzer_partial' => [ + 'type' => 'custom', + 'tokenizer' => 'standard', + 'filter' => [ + 'lowercase', + 'partial_search_filter' + ] + ] + ], + 'filter' => [ + 'partial_search_filter' => [ + 'type' => 'ngram', + 'min_gram' => 1, + 'max_gram' => 10, + 'token_chars' => ['letter', 'digit', 'symbol'] ] ] ] diff --git a/src/Elasticsearch/MatchQuery.php b/src/Elasticsearch/MatchQuery.php index b20ff0b..40d60d2 100644 --- a/src/Elasticsearch/MatchQuery.php +++ b/src/Elasticsearch/MatchQuery.php @@ -6,6 +6,7 @@ class MatchQuery extends \Spatie\ElasticsearchQueryBuilder\Queries\MatchQuery { protected string $operator = 'or'; protected float $boost = 1; + protected ?string $analyzer = null; public function and() { @@ -21,6 +22,13 @@ class MatchQuery extends \Spatie\ElasticsearchQueryBuilder\Queries\MatchQuery return $this; } + public function analyzer(string $analyzer) + { + $this->analyzer = $analyzer; + + return $this; + } + public function toArray(): array { $query = parent::toArray(); diff --git a/src/Elasticsearch/SimpleSearchQuery.php b/src/Elasticsearch/SimpleSearchQuery.php index 9bb6341..354d8a0 100644 --- a/src/Elasticsearch/SimpleSearchQuery.php +++ b/src/Elasticsearch/SimpleSearchQuery.php @@ -7,6 +7,7 @@ use Spatie\ElasticsearchQueryBuilder\Queries\Query; class SimpleSearchQuery implements Query { protected float $boost = 1; + protected ?string $analyzer = null; public static function create(array $field, string $value) { @@ -20,6 +21,13 @@ class SimpleSearchQuery implements Query return $this; } + public function analyzer(string $analyzer) + { + $this->analyzer = $analyzer; + + return $this; + } + public function __construct( protected array $fields, protected string $value @@ -32,6 +40,8 @@ class SimpleSearchQuery implements Query 'simple_query_string' => [ 'query' => $this->value, 'fields' => $this->fields, + 'analyzer' => $this->analyzer, + 'default_operator' => 'AND', 'boost' => $this->boost ] ]; diff --git a/src/Seeders/CommentSeeder.php b/src/Seeders/CommentSeeder.php index b6246da..4ac5849 100644 --- a/src/Seeders/CommentSeeder.php +++ b/src/Seeders/CommentSeeder.php @@ -61,6 +61,7 @@ class CommentSeeder extends Seeder 'type' => $this->type(), 'id' => $this->type() . ':' . $model->id, 'content' => $model->content, + 'content_partial' => $model->content, 'created_at' => $model->created_at?->toAtomString(), 'updated_at' => $model->edited_at?->toAtomString(), 'is_private' => $model->is_private, diff --git a/src/Seeders/DiscussionSeeder.php b/src/Seeders/DiscussionSeeder.php index d8704e7..2ebf29b 100644 --- a/src/Seeders/DiscussionSeeder.php +++ b/src/Seeders/DiscussionSeeder.php @@ -61,6 +61,7 @@ class DiscussionSeeder extends Seeder 'type' => $this->type(), 'id' => $this->type() . ':' . $model->id, 'content' => $model->title, + 'content_partial' => $model->title, 'created_at' => $model->created_at?->toAtomString(), 'updated_at' => $model->last_posted_at?->toAtomString(), 'is_private' => $model->is_private,