settings configurations
This commit is contained in:
parent
aabba9c2d0
commit
29ba864849
|
|
@ -78,5 +78,30 @@ app.initializers.add('blomstra-search', () => {
|
|||
label: app.translator.trans('blomstra-search.admin.elastic-index'),
|
||||
default: 'flarum',
|
||||
type: 'input',
|
||||
})
|
||||
.registerSetting({
|
||||
setting: 'blomstra-search.search-discussion-subjects',
|
||||
label: app.translator.trans('blomstra-search.admin.search-discussion-subjects'),
|
||||
type: 'switch',
|
||||
})
|
||||
.registerSetting({
|
||||
setting: 'blomstra-search.search-post-bodies',
|
||||
label: app.translator.trans('blomstra-search.admin.search-post-bodies'),
|
||||
type: 'switch',
|
||||
})
|
||||
.registerSetting({
|
||||
setting: 'blomstra-search.match-sentences',
|
||||
label: app.translator.trans('blomstra-search.admin.match-sentences'),
|
||||
type: 'switch',
|
||||
})
|
||||
.registerSetting({
|
||||
setting: 'blomstra-search.match-words',
|
||||
label: app.translator.trans('blomstra-search.admin.match-words'),
|
||||
type: 'switch',
|
||||
})
|
||||
.registerSetting({
|
||||
setting: 'blomstra-search.match-fragments',
|
||||
label: app.translator.trans('blomstra-search.admin.match-fragments'),
|
||||
type: 'switch',
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use Blomstra\Search\Elasticsearch\MatchPhraseQuery;
|
|||
use Blomstra\Search\Elasticsearch\MatchQuery;
|
||||
use Blomstra\Search\Save\Document as ElasticDocument;
|
||||
use Blomstra\Search\Elasticsearch\TermsQuery;
|
||||
use Blomstra\Search\Searchers\Searcher;
|
||||
use Elasticsearch\Client;
|
||||
use Flarum\Api\Controller\ListDiscussionsController;
|
||||
use Flarum\Api\Serializer\DiscussionSerializer;
|
||||
|
|
@ -14,6 +15,7 @@ use Flarum\Extension\ExtensionManager;
|
|||
use Flarum\Group\Group;
|
||||
use Flarum\Http\RequestUtil;
|
||||
use Flarum\Http\UrlGenerator;
|
||||
use Flarum\Settings\SettingsRepositoryInterface;
|
||||
use Flarum\User\User;
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
use Illuminate\Support\Arr;
|
||||
|
|
@ -37,8 +39,19 @@ class SearchController extends ListDiscussionsController
|
|||
'commentCount' => 'comment_count'
|
||||
];
|
||||
|
||||
public function __construct(protected Client $elastic, protected UrlGenerator $uri)
|
||||
{}
|
||||
protected iterable $searchers;
|
||||
protected bool $matchSentences;
|
||||
protected bool $matchWords;
|
||||
protected bool $matchFragments;
|
||||
|
||||
public function __construct(protected Client $elastic, protected UrlGenerator $uri, Container $container, SettingsRepositoryInterface $settings)
|
||||
{
|
||||
$this->searchers = $container->tagged('blomstra.search.searchers');
|
||||
|
||||
$this->matchSentences = (bool) $settings->get('blomstra-search.match-sentences', true);
|
||||
$this->matchWords = (bool) $settings->get('blomstra-search.match-words', true);
|
||||
$this->matchFragments = (bool) $settings->get('blomstra-search.match-fragments', true);
|
||||
}
|
||||
|
||||
protected function data(ServerRequestInterface $request, Document $document)
|
||||
{
|
||||
|
|
@ -59,13 +72,10 @@ class SearchController extends ListDiscussionsController
|
|||
$filterQuery = BoolQuery::create();
|
||||
|
||||
if (! empty($search)) {
|
||||
$filterQuery
|
||||
// @todo commented out to use only partial matching for now
|
||||
->add($this->sentenceMatch($search))
|
||||
->add($this->wordMatch($search, 'and'))
|
||||
->add($this->wordMatch($search, 'or'))
|
||||
// ->add($this->partialMatch($search))
|
||||
;
|
||||
if ($this->matchSentences) $filterQuery->add($this->sentenceMatch($search));
|
||||
if ($this->matchWords) $filterQuery->add($this->wordMatch($search, 'and'));
|
||||
if ($this->matchWords) $filterQuery->add($this->wordMatch($search, 'or'));
|
||||
if ($this->matchFragments) $filterQuery->add($this->partialMatch($search));
|
||||
}
|
||||
|
||||
$builder = (new Builder($this->elastic))
|
||||
|
|
@ -221,25 +231,28 @@ class SearchController extends ListDiscussionsController
|
|||
return $query;
|
||||
}
|
||||
|
||||
protected function boolQuery(Query $parent, float $boost = 1)
|
||||
{
|
||||
/** @var Searcher $searcher */
|
||||
foreach ($this->searchers as $searcher) {
|
||||
$searcher = new $searcher;
|
||||
|
||||
$parent->add(
|
||||
BoolQuery::create()
|
||||
->add(TermQuery::create('type', $searcher->type()), 'filter')
|
||||
->add($parent->boost($boost * $searcher->boost())),
|
||||
'should'
|
||||
);
|
||||
}
|
||||
|
||||
return $parent;
|
||||
}
|
||||
|
||||
protected function sentenceMatch(string $q): Query
|
||||
{
|
||||
$query = (new MatchPhraseQuery('content', $q));
|
||||
|
||||
return BoolQuery::create()
|
||||
// Discussion titles
|
||||
->add(
|
||||
BoolQuery::create()
|
||||
->add(TermQuery::create('type', 'discussions'), 'filter')
|
||||
->add($query->boost(2)),
|
||||
'should'
|
||||
)
|
||||
// Post bodies
|
||||
->add(
|
||||
BoolQuery::create()
|
||||
->add(TermQuery::create('type', 'posts'), 'filter')
|
||||
->add($query->boost(1.9)),
|
||||
'should'
|
||||
);
|
||||
return $this->boolQuery($query, 2);
|
||||
}
|
||||
|
||||
protected function wordMatch(string $q, string $operator = 'or')
|
||||
|
|
@ -249,42 +262,14 @@ class SearchController extends ListDiscussionsController
|
|||
|
||||
$boost = $operator === 'and' ? 1 : .8;
|
||||
|
||||
return BoolQuery::create()
|
||||
// Discussion titles
|
||||
->add(
|
||||
BoolQuery::create()
|
||||
->add(TermQuery::create('type', 'discussions'), 'filter')
|
||||
->add($query->boost($boost * 1.8)),
|
||||
'should'
|
||||
)
|
||||
// Post bodies
|
||||
->add(
|
||||
BoolQuery::create()
|
||||
->add(TermQuery::create('type', 'posts'), 'filter')
|
||||
->add($query->boost($boost * 1.8)),
|
||||
'should'
|
||||
);
|
||||
return $this->boolQuery($query, $boost);
|
||||
}
|
||||
|
||||
protected function partialMatch(string $q)
|
||||
{
|
||||
$query = (new MatchQuery('content', $q));
|
||||
|
||||
return BoolQuery::create()
|
||||
// Discussion titles
|
||||
->add(
|
||||
BoolQuery::create()
|
||||
->add(TermQuery::create('type', 'discussions'), 'filter')
|
||||
->add(clone $query->boost(1.6)),
|
||||
'should'
|
||||
)
|
||||
// Post bodies
|
||||
->add(
|
||||
BoolQuery::create()
|
||||
->add(TermQuery::create('type', 'posts'), 'filter')
|
||||
->add(clone $query->boost(1.3)),
|
||||
'should'
|
||||
);
|
||||
return $this->boolQuery($query, .6);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ namespace Blomstra\Search;
|
|||
use Blomstra\Search\Jobs\DeletingJob;
|
||||
use Blomstra\Search\Jobs\Job;
|
||||
use Blomstra\Search\Jobs\SavingJob;
|
||||
use Blomstra\Search\Searchers;
|
||||
use Blomstra\Search\Seeders;
|
||||
use Elasticsearch\Client as Elastic;
|
||||
use Elasticsearch\ClientBuilder;
|
||||
|
|
@ -79,6 +80,11 @@ class Provider extends AbstractServiceProvider
|
|||
return new Api\Client($pipe);
|
||||
}
|
||||
);
|
||||
|
||||
$this->container->tag([
|
||||
Searchers\DiscussionSearcher::class,
|
||||
Searchers\CommentPostSearcher::class,
|
||||
], 'blomstra.search.searchers');
|
||||
}
|
||||
|
||||
public function boot()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace Blomstra\Search\Searchers;
|
||||
|
||||
use Blomstra\Search\Seeders\CommentSeeder;
|
||||
|
||||
class CommentPostSearcher extends Searcher
|
||||
{
|
||||
protected string|null $seeder = CommentSeeder::class;
|
||||
|
||||
public function enabled(): bool
|
||||
{
|
||||
$enabled = $this->setting('blomstra-search.admin.search-post-bodies', true);
|
||||
|
||||
return boolval($enabled);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace Blomstra\Search\Searchers;
|
||||
|
||||
use Blomstra\Search\Seeders\DiscussionSeeder;
|
||||
|
||||
class DiscussionSearcher extends Searcher
|
||||
{
|
||||
protected string|null $seeder = DiscussionSeeder::class;
|
||||
|
||||
public function enabled(): bool
|
||||
{
|
||||
$enabled = $this->setting('blomstra-search.search-discussion-subjects', true);
|
||||
|
||||
return boolval($enabled);
|
||||
}
|
||||
|
||||
public function boost(): float
|
||||
{
|
||||
return 1.5;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace Blomstra\Search\Searchers;
|
||||
|
||||
use Blomstra\Search\Seeders\Seeder;
|
||||
use Flarum\Settings\SettingsRepositoryInterface;
|
||||
|
||||
abstract class Searcher
|
||||
{
|
||||
protected string|null $seeder = null;
|
||||
|
||||
public function type(): string
|
||||
{
|
||||
/** @var Seeder $seeder */
|
||||
$seeder = $this->seeder;
|
||||
|
||||
if (empty($seeder)) throw new \InvalidArgumentException("Implement type or add \$seeder");
|
||||
|
||||
return (new $seeder)->type();
|
||||
}
|
||||
|
||||
public function enabled(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function boost(): float
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
protected function setting(string $key, $default = null)
|
||||
{
|
||||
return resolve(SettingsRepositoryInterface::class)->get($key, $default);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue