fix partial matching

This commit is contained in:
Daniel Klabbers 2022-01-03 16:53:45 +01:00
parent 88b3e57d8f
commit b6ac018a56
6 changed files with 41 additions and 5 deletions

View File

@ -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'
);
}

View File

@ -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']
]
]
]

View File

@ -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();

View File

@ -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
]
];

View File

@ -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,

View File

@ -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,