skip full text search if request is too short and no operators

This commit is contained in:
Yuri Kuznetsov
2024-04-23 14:44:31 +03:00
parent 3dc29b1bae
commit 0d8a5ce5a1
3 changed files with 60 additions and 23 deletions
+25 -1
View File
@@ -60,7 +60,8 @@ class Applier
private User $user,
private MetadataProvider $metadataProvider,
private FullTextSearchDataComposerFactory $fullTextSearchDataComposerFactory,
private FilterFactory $filterFactory
private FilterFactory $filterFactory,
private ConfigProvider $config
) {}
/** @noinspection PhpUnusedParameterInspection */
@@ -90,6 +91,14 @@ class Applier
}
);
if (
$fullTextWhere &&
!$forceFullTextSearch &&
$this->toSkipFullText($filter)
) {
$fullTextWhere = Expr::value(false);
}
$skipWildcards = false;
if (mb_strpos($filter, '*') !== false) {
@@ -167,4 +176,19 @@ class Applier
return Expr::notEqual($expression, 0);
}
private function toSkipFullText(string $filter): bool
{
$min = $this->config->getFullTextSearchMinLength();
if ($min === null || strlen($filter) >= $min) {
return false;
}
return
!str_contains($filter, '*') &&
!str_contains($filter, '"') &&
!str_contains($filter, '+') &&
!str_contains($filter, '-');
}
}
@@ -38,6 +38,17 @@ class ConfigProvider
public function __construct(private Config $config)
{}
/**
* Full-text search min indexed word length.
*
* @internal Do not use.
* @since 8.3.0
*/
public function getFullTextSearchMinLength(): ?int
{
return $this->config->get('fullTextSearchMinLength');
}
public function getMinLengthForContentSearch(): int
{
return $this->config->get('textFilterContainsMinLength') ??
@@ -29,30 +29,29 @@
namespace tests\unit\Espo\Core\Select\Applier\Appliers;
use Espo\Core\{
Select\Text\Applier as TextFilterApplier,
Utils\Config,
Select\Text\MetadataProvider,
Select\Text\FilterParams,
Select\Text\FullTextSearch\Data as FullTextSearchData,
Select\Text\FullTextSearch\DefaultDataComposer as FullTextSearchDataComposer,
Select\Text\FullTextSearch\DataComposerFactory as FullTextSearchDataComposerFactory,
Select\Text\FullTextSearch\DataComposer\Params as FullTextSearchDataComposerParams,
Select\Text\FilterFactory,
Select\Text\DefaultFilter,
Select\Text\ConfigProvider,
};
use Espo\Core\Select\Text\Applier as TextFilterApplier;
use Espo\Core\Select\Text\ConfigProvider;
use Espo\Core\Select\Text\DefaultFilter;
use Espo\Core\Select\Text\FilterFactory;
use Espo\Core\Select\Text\FilterParams;
use Espo\Core\Select\Text\FullTextSearch\Data as FullTextSearchData;
use Espo\Core\Select\Text\FullTextSearch\DataComposer\Params as FullTextSearchDataComposerParams;
use Espo\Core\Select\Text\FullTextSearch\DataComposerFactory as FullTextSearchDataComposerFactory;
use Espo\Core\Select\Text\FullTextSearch\DefaultDataComposer as FullTextSearchDataComposer;
use Espo\Core\Select\Text\MetadataProvider;
use Espo\Core\Utils\Config;
use Espo\{
ORM\Query\SelectBuilder as QueryBuilder,
ORM\Query\Part\Where\OrGroup,
ORM\Query\Part\Expression as Expr,
ORM\Entity,
Entities\User,
};
use Espo\Entities\User;
use Espo\ORM\Entity;
use Espo\ORM\Query\Part\Expression as Expr;
use Espo\ORM\Query\Part\Where\OrGroup;
use Espo\ORM\Query\SelectBuilder as QueryBuilder;
use PHPUnit\Framework\TestCase;
class TextFilterApplierTest extends \PHPUnit\Framework\TestCase
class TextFilterApplierTest extends TestCase
{
private ?ConfigProvider $configProvider = null;
protected function setUp(): void
{
$this->user = $this->createMock(User::class);
@@ -63,6 +62,8 @@ class TextFilterApplierTest extends \PHPUnit\Framework\TestCase
$this->fullTextSearchDataComposerFactory = $this->createMock(FullTextSearchDataComposerFactory::class);
$this->filterFactory = $this->createMock(FilterFactory::class);
$this->configProvider = $this->createMock(ConfigProvider::class);
$this->entityType = 'Test';
$this->applier = new TextFilterApplier(
@@ -70,7 +71,8 @@ class TextFilterApplierTest extends \PHPUnit\Framework\TestCase
$this->user,
$this->metadataProvider,
$this->fullTextSearchDataComposerFactory,
$this->filterFactory
$this->filterFactory,
$this->configProvider
);
}