44
55use DirectoryTree \OpenSearchAdapter \Search \SearchRequest as OpenSearchRequest ;
66use DirectoryTree \OpenSearchScoutDriver \SearchRequest ;
7+ use Illuminate \Contracts \Support \Arrayable ;
78use Laravel \Scout \Builder ;
89use stdClass ;
910
@@ -19,23 +20,78 @@ class SearchRequestFactory implements SearchRequestFactoryInterface
1920 */
2021 public function makeFromBuilder (Builder $ builder , array $ options = []): SearchRequest
2122 {
23+ if ($ compiled = $ this ->compileBuilder ($ builder , $ options )) {
24+ return $ this ->makeFromCompiled ($ builder , $ compiled );
25+ }
26+
2227 $ request = new OpenSearchRequest ($ this ->makeQuery ($ builder ));
2328
2429 if ($ sort = $ this ->makeSort ($ builder )) {
2530 $ request ->sort ($ sort );
2631 }
2732
28- if ($ from = $ this ->makeFrom ($ options )) {
33+ if (! is_null ( $ from = $ this ->makeFrom ($ options) )) {
2934 $ request ->from ($ from );
3035 }
3136
32- if ($ size = $ this ->makeSize ($ builder , $ options )) {
37+ if (! is_null ( $ size = $ this ->makeSize ($ builder , $ options) )) {
3338 $ request ->size ($ size );
3439 }
3540
41+ $ this ->applyOptions ($ request , $ builder ->options );
42+
43+ return new SearchRequest ($ this ->makeIndex ($ builder ), $ request );
44+ }
45+
46+ /**
47+ * Make an OpenSearch request from a compiled builder payload.
48+ *
49+ * @param array{query?: array<string, mixed>|null, sort?: array<int|string, mixed>|null, from?: int|null, size?: int|string|null, aggs?: array<string, mixed>|null, aggregations?: array<string, mixed>|null} $compiled
50+ */
51+ protected function makeFromCompiled (Builder $ builder , array $ compiled ): SearchRequest
52+ {
53+ $ request = new OpenSearchRequest ($ compiled ['query ' ] ?? []);
54+
55+ if (! empty ($ compiled ['sort ' ])) {
56+ $ request ->sort ($ compiled ['sort ' ]);
57+ }
58+
59+ if (! empty ($ compiled ['from ' ])) {
60+ $ request ->from ((int ) $ compiled ['from ' ]);
61+ }
62+
63+ if (isset ($ compiled ['size ' ]) && is_numeric ($ compiled ['size ' ])) {
64+ $ request ->size ((int ) $ compiled ['size ' ]);
65+ }
66+
67+ if (! empty ($ compiled ['aggs ' ])) {
68+ $ request ->aggregations ($ compiled ['aggs ' ]);
69+ }
70+
71+ if (! empty ($ compiled ['aggregations ' ])) {
72+ $ request ->aggregations ($ compiled ['aggregations ' ]);
73+ }
74+
75+ $ this ->applyOptions ($ request , $ builder ->options );
76+
3677 return new SearchRequest ($ this ->makeIndex ($ builder ), $ request );
3778 }
3879
80+ /**
81+ * Compile builders that expose their own OpenSearch payload.
82+ *
83+ * @param array<string, mixed> $options
84+ * @return array<string, mixed>|null
85+ */
86+ protected function compileBuilder (Builder $ builder , array $ options ): ?array
87+ {
88+ if (! $ builder instanceof Arrayable) {
89+ return null ;
90+ }
91+
92+ return $ builder ->toArray ($ options );
93+ }
94+
3995 /**
4096 * Get the OpenSearch index name for the builder.
4197 */
@@ -139,6 +195,72 @@ protected function makeFrom(array $options): ?int
139195 */
140196 protected function makeSize (Builder $ builder , array $ options ): ?int
141197 {
142- return $ options ['perPage ' ] ?? $ builder ->limit ;
198+ $ size = $ options ['perPage ' ] ?? $ builder ->limit ;
199+
200+ return is_numeric ($ size ) ? (int ) $ size : null ;
201+ }
202+
203+ /**
204+ * Apply Scout builder options to the OpenSearch search request.
205+ *
206+ * @param array<string, mixed> $options
207+ */
208+ protected function applyOptions (OpenSearchRequest $ request , array $ options ): void
209+ {
210+ if (isset ($ options ['highlight ' ])) {
211+ $ request ->highlight ($ options ['highlight ' ]);
212+ }
213+
214+ if (isset ($ options ['rescore ' ])) {
215+ $ request ->rescore ($ options ['rescore ' ]);
216+ }
217+
218+ if (isset ($ options ['suggest ' ])) {
219+ $ request ->suggest ($ options ['suggest ' ]);
220+ }
221+
222+ if (isset ($ options ['collapse ' ])) {
223+ $ request ->collapse ($ options ['collapse ' ]);
224+ }
225+
226+ if (isset ($ options ['aggregations ' ])) {
227+ $ request ->aggregations ($ options ['aggregations ' ]);
228+ }
229+
230+ if (isset ($ options ['post_filter ' ])) {
231+ $ request ->postFilter ($ options ['post_filter ' ]);
232+ }
233+
234+ if (isset ($ options ['indices_boost ' ])) {
235+ $ request ->indicesBoost ($ options ['indices_boost ' ]);
236+ }
237+
238+ if (isset ($ options ['min_score ' ])) {
239+ $ request ->minScore ($ options ['min_score ' ]);
240+ }
241+
242+ if (isset ($ options ['script_fields ' ])) {
243+ $ request ->scriptFields ($ options ['script_fields ' ]);
244+ }
245+
246+ if (isset ($ options ['search_type ' ])) {
247+ $ request ->searchType ($ options ['search_type ' ]);
248+ }
249+
250+ if (isset ($ options ['preference ' ])) {
251+ $ request ->preference ($ options ['preference ' ]);
252+ }
253+
254+ if (array_key_exists ('_source ' , $ options )) {
255+ $ request ->source ($ options ['_source ' ]);
256+ }
257+
258+ if (array_key_exists ('track_total_hits ' , $ options )) {
259+ $ request ->trackTotalHits ($ options ['track_total_hits ' ]);
260+ }
261+
262+ if (array_key_exists ('track_scores ' , $ options )) {
263+ $ request ->trackScores ($ options ['track_scores ' ]);
264+ }
143265 }
144266}
0 commit comments