5
5
namespace Setono \SyliusMeilisearchPlugin \Engine ;
6
6
7
7
use Meilisearch \Client ;
8
+ use Meilisearch \Contracts \SearchQuery ;
8
9
use Meilisearch \Search \SearchResult ;
9
10
use Setono \SyliusMeilisearchPlugin \Config \Index ;
10
11
use Setono \SyliusMeilisearchPlugin \Document \Metadata \MetadataFactoryInterface ;
11
- use Setono \SyliusMeilisearchPlugin \Meilisearch \Builder \FilterBuilderInterface ;
12
+ use Setono \SyliusMeilisearchPlugin \Meilisearch \Filter \FilterBuilderInterface ;
13
+ use Setono \SyliusMeilisearchPlugin \Meilisearch \Query \MainQueryBuilderInterface ;
14
+ use Setono \SyliusMeilisearchPlugin \Meilisearch \Query \SubQueriesBuilderInterface ;
12
15
use Setono \SyliusMeilisearchPlugin \Resolver \IndexName \IndexNameResolverInterface ;
13
16
14
17
final class SearchEngine implements SearchEngineInterface
@@ -19,27 +22,51 @@ public function __construct(
19
22
private readonly Index $ index ,
20
23
private readonly IndexNameResolverInterface $ indexNameResolver ,
21
24
private readonly Client $ client ,
22
- private readonly int $ hitsPerPage ,
25
+ private readonly MainQueryBuilderInterface $ mainQueryBuilder ,
26
+ private readonly SubQueriesBuilderInterface $ subQueriesBuilder ,
23
27
) {
24
28
}
25
29
26
30
public function execute (?string $ query , array $ parameters = []): SearchResult
27
31
{
28
- $ page = max (1 , (int ) ($ parameters ['p ' ] ?? 1 ));
29
- $ sort = (string ) ($ parameters ['sort ' ] ?? '' );
30
-
32
+ $ indexName = $ this ->indexNameResolver ->resolve ($ this ->index );
31
33
$ metadata = $ this ->metadataFactory ->getMetadataFor ($ this ->index ->document );
34
+ $ facetsNames = $ metadata ->getFacetableAttributeNames ();
35
+ $ facets = $ metadata ->getFacetableAttributes ();
36
+
37
+ /** @var array<string, mixed> $facetsFilter */
38
+ $ facetsFilter = (array ) ($ parameters ['facets ' ] ?? []);
39
+ /** @var array<string, mixed> $filters */
40
+ $ filters = $ this ->filterBuilder ->build ($ facets , $ facetsFilter );
41
+
42
+ $ mainQuery = $ this ->mainQueryBuilder ->build (
43
+ $ indexName ,
44
+ $ query ?? '' ,
45
+ $ facetsNames ,
46
+ $ filters ,
47
+ max (1 , (int ) ($ parameters ['p ' ] ?? 1 )),
48
+ (string ) ($ parameters ['sort ' ] ?? '' ),
49
+ );
50
+
51
+ /** @var list<SearchQuery> $queries */
52
+ $ queries = array_merge (
53
+ [$ mainQuery ],
54
+ $ this ->subQueriesBuilder ->build ($ indexName , $ query ?? '' , $ facets , $ facetsFilter ),
55
+ );
56
+
57
+ /** @var array<SearchResult> $results */
58
+ $ results = $ this ->client ->multiSearch ($ queries )['results ' ] ?? [];
59
+
60
+ return $ this ->provideSearchResult ($ results );
61
+ }
62
+
63
+ private function provideSearchResult (array $ results ): SearchResult
64
+ {
65
+ /** @var array{facetDistribution: array<string, int>} $firstResult */
66
+ $ firstResult = current ($ results );
67
+ /** @psalm-suppress MixedArgument (just for now) */
68
+ $ firstResult ['facetDistribution ' ] = array_merge (...array_column ($ results , 'facetDistribution ' ));
32
69
33
- $ searchParams = [
34
- 'facets ' => $ metadata ->getFacetableAttributeNames (),
35
- 'filter ' => $ this ->filterBuilder ->build ($ parameters ),
36
- 'hitsPerPage ' => $ this ->hitsPerPage ,
37
- 'page ' => $ page ,
38
- ];
39
- if ('' !== $ sort ) {
40
- $ searchParams ['sort ' ] = [$ sort ];
41
- }
42
-
43
- return $ this ->client ->index ($ this ->indexNameResolver ->resolve ($ this ->index ))->search ($ query , $ searchParams );
70
+ return new SearchResult ($ firstResult );
44
71
}
45
72
}
0 commit comments