SearchTest.php 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605
  1. <?php
  2. declare(strict_types=1);
  3. namespace Tests\Endpoints;
  4. use MeiliSearch\Exceptions\ApiException;
  5. use Tests\TestCase;
  6. final class SearchTest extends TestCase
  7. {
  8. private $index;
  9. protected function setUp(): void
  10. {
  11. parent::setUp();
  12. $this->index = $this->client->createIndex('index');
  13. $promise = $this->index->updateDocuments(self::DOCUMENTS);
  14. $this->index->waitForPendingUpdate($promise['updateId']);
  15. }
  16. public function testBasicSearch(): void
  17. {
  18. $response = $this->index->search('prince');
  19. $this->assertArrayHasKey('hits', $response->toArray());
  20. $this->assertArrayHasKey('offset', $response->toArray());
  21. $this->assertArrayHasKey('limit', $response->toArray());
  22. $this->assertArrayHasKey('processingTimeMs', $response->toArray());
  23. $this->assertArrayHasKey('query', $response->toArray());
  24. $this->assertSame(2, $response->getNbHits());
  25. $this->assertCount(2, $response->getHits());
  26. $response = $this->index->search('prince', [], [
  27. 'raw' => true,
  28. ]);
  29. $this->assertArrayHasKey('hits', $response);
  30. $this->assertArrayHasKey('offset', $response);
  31. $this->assertArrayHasKey('limit', $response);
  32. $this->assertArrayHasKey('processingTimeMs', $response);
  33. $this->assertArrayHasKey('query', $response);
  34. $this->assertSame(2, $response['nbHits']);
  35. }
  36. public function testBasicEmptySearch(): void
  37. {
  38. $response = $this->index->search('');
  39. $this->assertArrayHasKey('hits', $response->toArray());
  40. $this->assertArrayHasKey('offset', $response->toArray());
  41. $this->assertArrayHasKey('limit', $response->toArray());
  42. $this->assertArrayHasKey('processingTimeMs', $response->toArray());
  43. $this->assertArrayHasKey('query', $response->toArray());
  44. $this->assertCount(7, $response->getHits());
  45. $response = $this->index->search('', [], [
  46. 'raw' => true,
  47. ]);
  48. $this->assertArrayHasKey('hits', $response);
  49. $this->assertArrayHasKey('offset', $response);
  50. $this->assertArrayHasKey('limit', $response);
  51. $this->assertArrayHasKey('processingTimeMs', $response);
  52. $this->assertArrayHasKey('query', $response);
  53. $this->assertSame(7, $response['nbHits']);
  54. }
  55. public function testBasicPlaceholderSearch(): void
  56. {
  57. $response = $this->index->search(null);
  58. $this->assertArrayHasKey('hits', $response->toArray());
  59. $this->assertArrayHasKey('offset', $response->toArray());
  60. $this->assertArrayHasKey('limit', $response->toArray());
  61. $this->assertArrayHasKey('processingTimeMs', $response->toArray());
  62. $this->assertArrayHasKey('query', $response->toArray());
  63. $this->assertCount(\count(self::DOCUMENTS), $response->getHits());
  64. $response = $this->index->search(null, [], [
  65. 'raw' => true,
  66. ]);
  67. $this->assertArrayHasKey('hits', $response);
  68. $this->assertArrayHasKey('offset', $response);
  69. $this->assertArrayHasKey('limit', $response);
  70. $this->assertArrayHasKey('processingTimeMs', $response);
  71. $this->assertArrayHasKey('query', $response);
  72. $this->assertSame(\count(self::DOCUMENTS), $response['nbHits']);
  73. }
  74. public function testSearchWithOptions(): void
  75. {
  76. $response = $this->index->search('prince', ['limit' => 1]);
  77. $this->assertCount(1, $response->getHits());
  78. $response = $this->index->search('prince', ['limit' => 1], [
  79. 'raw' => true,
  80. ]);
  81. $this->assertSame(1, \count($response['hits']));
  82. }
  83. public function testBasicSearchIfNoPrimaryKeyAndDocumentProvided(): void
  84. {
  85. $emptyIndex = $this->client->createIndex('empty');
  86. $res = $emptyIndex->search('prince');
  87. $this->assertArrayHasKey('hits', $res->toArray());
  88. $this->assertArrayHasKey('offset', $res->toArray());
  89. $this->assertArrayHasKey('limit', $res->toArray());
  90. $this->assertArrayHasKey('processingTimeMs', $res->toArray());
  91. $this->assertArrayHasKey('query', $res->toArray());
  92. $this->assertCount(0, $res->getHits());
  93. $res = $emptyIndex->search('prince', [], [
  94. 'raw' => true,
  95. ]);
  96. $this->assertArrayHasKey('hits', $res);
  97. $this->assertArrayHasKey('offset', $res);
  98. $this->assertArrayHasKey('limit', $res);
  99. $this->assertArrayHasKey('processingTimeMs', $res);
  100. $this->assertArrayHasKey('query', $res);
  101. $this->assertSame(0, $res['nbHits']);
  102. }
  103. public function testExceptionIfNoIndexWhenSearching(): void
  104. {
  105. $index = $this->client->createIndex('another-index');
  106. $index->delete();
  107. $this->expectException(ApiException::class);
  108. $index->search('prince');
  109. }
  110. public function testParametersArray(): void
  111. {
  112. $response = $this->index->search('prince', [
  113. 'limit' => 5,
  114. 'offset' => 0,
  115. 'attributesToRetrieve' => ['id', 'title'],
  116. 'attributesToCrop' => ['id', 'title'],
  117. 'cropLength' => 6,
  118. 'attributesToHighlight' => ['title'],
  119. 'filters' => 'title = "Le Petit Prince"',
  120. 'matches' => true,
  121. ]);
  122. $this->assertArrayHasKey('_matchesInfo', $response->getHit(0));
  123. $this->assertArrayHasKey('title', $response->getHit(0)['_matchesInfo']);
  124. $this->assertArrayHasKey('_formatted', $response->getHit(0));
  125. $this->assertArrayNotHasKey('comment', $response->getHit(0));
  126. $this->assertArrayNotHasKey('comment', $response->getHit(0)['_matchesInfo']);
  127. $this->assertSame('Petit <em>Prince</em>', $response->getHit(0)['_formatted']['title']);
  128. $response = $this->index->search('prince', [
  129. 'limit' => 5,
  130. 'offset' => 0,
  131. 'attributesToRetrieve' => ['id', 'title'],
  132. 'attributesToCrop' => ['id', 'title'],
  133. 'cropLength' => 6,
  134. 'attributesToHighlight' => ['title'],
  135. 'filters' => 'title = "Le Petit Prince"',
  136. 'matches' => true,
  137. ], [
  138. 'raw' => true,
  139. ]);
  140. $this->assertArrayHasKey('_matchesInfo', $response['hits'][0]);
  141. $this->assertArrayHasKey('title', $response['hits'][0]['_matchesInfo']);
  142. $this->assertArrayHasKey('_formatted', $response['hits'][0]);
  143. $this->assertArrayNotHasKey('comment', $response['hits'][0]);
  144. $this->assertArrayNotHasKey('comment', $response['hits'][0]['_matchesInfo']);
  145. $this->assertSame('Petit <em>Prince</em>', $response['hits'][0]['_formatted']['title']);
  146. }
  147. public function testParametersCanBeAStar(): void
  148. {
  149. $response = $this->index->search('prince', [
  150. 'limit' => 5,
  151. 'offset' => 0,
  152. 'attributesToRetrieve' => ['*'],
  153. 'attributesToCrop' => ['*'],
  154. 'cropLength' => 6,
  155. 'attributesToHighlight' => ['*'],
  156. 'filters' => 'title = "Le Petit Prince"',
  157. 'matches' => true,
  158. ]);
  159. $this->assertArrayHasKey('_matchesInfo', $response->getHit(0));
  160. $this->assertArrayHasKey('title', $response->getHit(0)['_matchesInfo']);
  161. $this->assertArrayHasKey('_formatted', $response->getHit(0));
  162. $this->assertArrayHasKey('comment', $response->getHit(0));
  163. $this->assertArrayNotHasKey('comment', $response->getHit(0)['_matchesInfo']);
  164. $this->assertSame('Petit <em>Prince</em>', $response->getHit(0)['_formatted']['title']);
  165. $response = $this->index->search('prince', [
  166. 'limit' => 5,
  167. 'offset' => 0,
  168. 'attributesToRetrieve' => ['*'],
  169. 'attributesToCrop' => ['*'],
  170. 'cropLength' => 6,
  171. 'attributesToHighlight' => ['*'],
  172. 'filters' => 'title = "Le Petit Prince"',
  173. 'matches' => true,
  174. ], [
  175. 'raw' => true,
  176. ]);
  177. $this->assertArrayHasKey('_matchesInfo', $response['hits'][0]);
  178. $this->assertArrayHasKey('title', $response['hits'][0]['_matchesInfo']);
  179. $this->assertArrayHasKey('_formatted', $response['hits'][0]);
  180. $this->assertArrayHasKey('comment', $response['hits'][0]);
  181. $this->assertArrayNotHasKey('comment', $response['hits'][0]['_matchesInfo']);
  182. $this->assertSame('Petit <em>Prince</em>', $response['hits'][0]['_formatted']['title']);
  183. }
  184. public function testBasicSearchWithFacetsDistribution(): void
  185. {
  186. $response = $this->index->updateAttributesForFaceting(['genre']);
  187. $this->index->waitForPendingUpdate($response['updateId']);
  188. $response = $this->index->search('prince', [
  189. 'facetsDistribution' => ['genre'],
  190. ]);
  191. $this->assertSame(2, $response->getHitsCount());
  192. $this->assertArrayHasKey('facetsDistribution', $response->toArray());
  193. $this->assertArrayHasKey('exhaustiveFacetsCount', $response->toArray());
  194. $this->assertArrayHasKey('genre', $response->getFacetsDistribution());
  195. $this->assertTrue($response->getExhaustiveFacetsCount());
  196. $this->assertSame($response->getFacetsDistribution()['genre']['fantasy'], 1);
  197. $this->assertSame($response->getFacetsDistribution()['genre']['adventure'], 1);
  198. $this->assertSame($response->getFacetsDistribution()['genre']['romance'], 0);
  199. $response = $this->index->search('prince', [
  200. 'facetsDistribution' => ['genre'],
  201. ], [
  202. 'raw' => true,
  203. ]);
  204. $this->assertSame(2, $response['nbHits']);
  205. $this->assertArrayHasKey('facetsDistribution', $response);
  206. $this->assertArrayHasKey('exhaustiveFacetsCount', $response);
  207. $this->assertArrayHasKey('genre', $response['facetsDistribution']);
  208. $this->assertTrue($response['exhaustiveFacetsCount']);
  209. $this->assertSame($response['facetsDistribution']['genre']['fantasy'], 1);
  210. $this->assertSame($response['facetsDistribution']['genre']['adventure'], 1);
  211. $this->assertSame($response['facetsDistribution']['genre']['romance'], 0);
  212. }
  213. public function testBasicSearchWithFacetFilters(): void
  214. {
  215. $response = $this->index->updateAttributesForFaceting(['genre']);
  216. $this->index->waitForPendingUpdate($response['updateId']);
  217. $response = $this->index->search('prince', [
  218. 'facetFilters' => [['genre:fantasy']],
  219. ]);
  220. $this->assertSame(1, $response->getHitsCount());
  221. $this->assertArrayNotHasKey('facetsDistribution', $response->getRaw());
  222. $this->assertArrayNotHasKey('exhaustiveFacetsCount', $response->getRaw());
  223. $this->assertSame(4, $response->getHit(0)['id']);
  224. $response = $this->index->search('prince', [
  225. 'facetFilters' => [['genre:fantasy']],
  226. ], [
  227. 'raw' => true,
  228. ]);
  229. $this->assertSame(1, $response['nbHits']);
  230. $this->assertArrayNotHasKey('facetsDistribution', $response);
  231. $this->assertArrayNotHasKey('exhaustiveFacetsCount', $response);
  232. $this->assertSame(4, $response['hits'][0]['id']);
  233. }
  234. public function testBasicSearchWithMultipleFacetFilters(): void
  235. {
  236. $response = $this->index->updateAttributesForFaceting(['genre']);
  237. $this->index->waitForPendingUpdate($response['updateId']);
  238. $response = $this->index->search('prince', [
  239. 'facetFilters' => ['genre:fantasy', ['genre:fantasy', 'genre:fantasy']],
  240. ]);
  241. $this->assertSame(1, $response->getHitsCount());
  242. $this->assertArrayNotHasKey('facetsDistribution', $response->getRaw());
  243. $this->assertArrayNotHasKey('exhaustiveFacetsCount', $response->getRaw());
  244. $this->assertSame(4, $response->getHit(0)['id']);
  245. $response = $this->index->search('prince', [
  246. 'facetFilters' => ['genre:fantasy', ['genre:fantasy', 'genre:fantasy']],
  247. ], [
  248. 'raw' => true,
  249. ]);
  250. $this->assertSame(1, $response['nbHits']);
  251. $this->assertArrayNotHasKey('facetsDistribution', $response);
  252. $this->assertArrayNotHasKey('exhaustiveFacetsCount', $response);
  253. $this->assertSame(4, $response['hits'][0]['id']);
  254. }
  255. public function testCustomSearchWithFacetFiltersAndAttributesToRetrieve(): void
  256. {
  257. $response = $this->index->updateAttributesForFaceting(['genre']);
  258. $this->index->waitForPendingUpdate($response['updateId']);
  259. $response = $this->index->search('prince', [
  260. 'facetFilters' => [['genre:fantasy']],
  261. 'attributesToRetrieve' => ['id', 'title'],
  262. ]);
  263. $this->assertSame(1, $response->getHitsCount());
  264. $this->assertArrayNotHasKey('facetsDistribution', $response->getRaw());
  265. $this->assertArrayNotHasKey('exhaustiveFacetsCount', $response->getRaw());
  266. $this->assertSame(4, $response->getHit(0)['id']);
  267. $this->assertArrayHasKey('id', $response->getHit(0));
  268. $this->assertArrayHasKey('title', $response->getHit(0));
  269. $this->assertArrayNotHasKey('comment', $response->getHit(0));
  270. $response = $this->index->search('prince', [
  271. 'facetFilters' => [['genre:fantasy']],
  272. 'attributesToRetrieve' => ['id', 'title'],
  273. ], [
  274. 'raw' => true,
  275. ]);
  276. $this->assertSame(1, $response['nbHits']);
  277. $this->assertArrayNotHasKey('facetsDistribution', $response);
  278. $this->assertArrayNotHasKey('exhaustiveFacetsCount', $response);
  279. $this->assertSame(4, $response['hits'][0]['id']);
  280. $this->assertArrayHasKey('id', $response['hits'][0]);
  281. $this->assertArrayHasKey('title', $response['hits'][0]);
  282. $this->assertArrayNotHasKey('comment', $response['hits'][0]);
  283. }
  284. public function testBasicSerachWithRawSearch(): void
  285. {
  286. $response = $this->index->rawSearch('prince');
  287. $this->assertArrayHasKey('hits', $response);
  288. $this->assertArrayHasKey('offset', $response);
  289. $this->assertArrayHasKey('limit', $response);
  290. $this->assertArrayHasKey('processingTimeMs', $response);
  291. $this->assertArrayHasKey('query', $response);
  292. $this->assertSame(2, $response['nbHits']);
  293. $this->assertCount(2, $response['hits']);
  294. $this->assertEquals('Le Petit Prince', $response['hits'][0]['title']);
  295. }
  296. public function testBasicSearchWithRawOption(): void
  297. {
  298. $response = $this->index->search('prince', [], ['raw' => true]);
  299. $this->assertArrayHasKey('hits', $response);
  300. $this->assertArrayHasKey('offset', $response);
  301. $this->assertArrayHasKey('limit', $response);
  302. $this->assertArrayHasKey('processingTimeMs', $response);
  303. $this->assertArrayHasKey('query', $response);
  304. $this->assertSame(2, $response['nbHits']);
  305. $this->assertCount(2, $response['hits']);
  306. }
  307. public function testBasicSearchWithTransformHitsOptionToFilter(): void
  308. {
  309. $keepLePetitPrinceFunc = function (array $hits) {
  310. return array_filter(
  311. $hits,
  312. function (array $hit) { return 'Le Petit Prince' === $hit['title']; }
  313. );
  314. };
  315. $response = $this->index->search('prince', [], $options = ['transformHits' => $keepLePetitPrinceFunc]);
  316. $this->assertArrayHasKey('hits', $response->toArray());
  317. $this->assertArrayHasKey('offset', $response->toArray());
  318. $this->assertArrayHasKey('limit', $response->toArray());
  319. $this->assertArrayHasKey('processingTimeMs', $response->toArray());
  320. $this->assertArrayHasKey('query', $response->toArray());
  321. $this->assertSame('Le Petit Prince', $response->getHit(0)['title']);
  322. $this->assertSame(2, $response->getNbHits());
  323. $this->assertSame(1, $response->getHitsCount());
  324. $this->assertSame(1, $response->count());
  325. }
  326. public function testBasicSearchWithTransformHitsOptionToMap(): void
  327. {
  328. $titlesToUpperCaseFunc = function (array $hits) {
  329. return array_map(
  330. function (array $hit) {
  331. $hit['title'] = strtoupper($hit['title']);
  332. return $hit;
  333. },
  334. $hits
  335. );
  336. };
  337. $response = $this->index->search('prince', [], ['transformHits' => $titlesToUpperCaseFunc]);
  338. $this->assertArrayHasKey('hits', $response->toArray());
  339. $this->assertArrayHasKey('offset', $response->toArray());
  340. $this->assertArrayHasKey('limit', $response->toArray());
  341. $this->assertArrayHasKey('processingTimeMs', $response->toArray());
  342. $this->assertArrayHasKey('query', $response->toArray());
  343. $this->assertSame(2, $response->getNbHits());
  344. $this->assertSame(2, $response->getHitsCount());
  345. $this->assertCount(2, $response->getHits());
  346. $this->assertSame('LE PETIT PRINCE', $response->getHits()[0]['title']);
  347. }
  348. public function testBasicSearchCannotBeFilteredOnRawResult(): void
  349. {
  350. $keepLePetitPrinceFunc = function (array $hits) {
  351. return array_filter(
  352. $hits,
  353. function (array $hit) { return 'Le Petit Prince' === $hit['title']; }
  354. );
  355. };
  356. $response = $this->index->search('prince', [], [
  357. 'raw' => true,
  358. 'transformHits' => $keepLePetitPrinceFunc,
  359. ]);
  360. $this->assertArrayHasKey('hits', $response);
  361. $this->assertArrayHasKey('offset', $response);
  362. $this->assertArrayHasKey('limit', $response);
  363. $this->assertArrayHasKey('processingTimeMs', $response);
  364. $this->assertArrayHasKey('query', $response);
  365. $this->assertSame(2, $response['nbHits']);
  366. $this->assertCount(2, $response['hits']);
  367. }
  368. public function testBasicSearchCanBeFilteredOnRawResultIfUsingToArray(): void
  369. {
  370. $keepLePetitPrinceFunc = function (array $hits) {
  371. return array_filter(
  372. $hits,
  373. function (array $hit) { return 'Le Petit Prince' === $hit['title']; }
  374. );
  375. };
  376. $response = $this->index->search('prince', [], ['transformHits' => $keepLePetitPrinceFunc])->toArray();
  377. $this->assertArrayHasKey('hits', $response);
  378. $this->assertArrayHasKey('offset', $response);
  379. $this->assertArrayHasKey('limit', $response);
  380. $this->assertArrayHasKey('processingTimeMs', $response);
  381. $this->assertArrayHasKey('query', $response);
  382. $this->assertSame(2, $response['nbHits']);
  383. $this->assertCount(1, $response['hits']);
  384. $this->assertEquals('Le Petit Prince', $response['hits'][0]['title']);
  385. }
  386. public function testBasicSearchWithRemoveZeroFacetsOption(): void
  387. {
  388. $response = $this->index->updateAttributesForFaceting(['genre']);
  389. $this->index->waitForPendingUpdate($response['updateId']);
  390. $response = $this->index->search(
  391. 'prince',
  392. ['facetsDistribution' => ['genre']],
  393. ['removeZeroFacets' => true]
  394. );
  395. $this->assertCount(2, $response->getFacetsDistribution()['genre']);
  396. $this->assertEquals(1, $response->getFacetsDistribution()['genre']['adventure']);
  397. $this->assertEquals(1, $response->getFacetsDistribution()['genre']['fantasy']);
  398. $this->assertCount(3, $response->getRaw()['facetsDistribution']['genre']);
  399. $this->assertEquals($response->getRaw()['hits'], $response->getHits());
  400. $this->assertNotEquals($response->getRaw()['facetsDistribution'], $response->getFacetsDistribution());
  401. }
  402. public function testBasicSearchWithRemoveZeroFacetsOptionAndMultipleFacets(): void
  403. {
  404. $response = $this->index->addDocuments([['id' => 32, 'title' => 'The Witcher', 'genre' => 'adventure', 'adaptation' => 'video game']]);
  405. $this->index->waitForPendingUpdate($response['updateId']);
  406. $response = $this->index->updateAttributesForFaceting(['genre', 'adaptation']);
  407. $this->index->waitForPendingUpdate($response['updateId']);
  408. $response = $this->index->search(
  409. 'prince',
  410. ['facetsDistribution' => ['genre', 'adaptation']],
  411. ['removeZeroFacets' => true]
  412. );
  413. $this->assertCount(2, $response->getFacetsDistribution()['genre']);
  414. $this->assertEquals(1, $response->getFacetsDistribution()['genre']['adventure']);
  415. $this->assertEquals(1, $response->getFacetsDistribution()['genre']['fantasy']);
  416. $this->assertEquals([], $response->getFacetsDistribution()['adaptation']);
  417. $this->assertCount(1, $response->getRaw()['facetsDistribution']['adaptation']);
  418. $this->assertCount(3, $response->getRaw()['facetsDistribution']['genre']);
  419. $this->assertEquals($response->getRaw()['hits'], $response->getHits());
  420. $this->assertNotEquals($response->getRaw()['facetsDistribution'], $response->getFacetsDistribution());
  421. }
  422. public function testBasicSearchWithTransformFacetsDritributionOptionToFilter(): void
  423. {
  424. $response = $this->index->updateAttributesForFaceting(['genre']);
  425. $this->index->waitForPendingUpdate($response['updateId']);
  426. $filterAllFacets = function (array $facets) {
  427. $filterOneFacet = function (array $facet) {
  428. return array_filter(
  429. $facet,
  430. function ($v, $k) { return $v > 1; },
  431. ARRAY_FILTER_USE_BOTH
  432. );
  433. };
  434. return array_map($filterOneFacet, $facets);
  435. };
  436. $response = $this->index->search(
  437. null,
  438. ['facetsDistribution' => ['genre']],
  439. ['transformFacetsDistribution' => $filterAllFacets]
  440. );
  441. $this->assertArrayHasKey('hits', $response->toArray());
  442. $this->assertArrayHasKey('facetsDistribution', $response->toArray());
  443. $this->assertArrayHasKey('offset', $response->toArray());
  444. $this->assertArrayHasKey('limit', $response->toArray());
  445. $this->assertArrayHasKey('processingTimeMs', $response->toArray());
  446. $this->assertArrayHasKey('query', $response->toArray());
  447. $this->assertEquals($response->getRaw()['hits'], $response->getHits());
  448. $this->assertNotEquals($response->getRaw()['facetsDistribution'], $response->getFacetsDistribution());
  449. $this->assertCount(3, $response->getRaw()['facetsDistribution']['genre']);
  450. $this->assertCount(2, $response->getFacetsDistribution()['genre']);
  451. $this->assertEquals(3, $response->getFacetsDistribution()['genre']['romance']);
  452. $this->assertEquals(2, $response->getFacetsDistribution()['genre']['fantasy']);
  453. }
  454. public function testBasicSearchWithTransformFacetsDritributionOptionToMap(): void
  455. {
  456. $response = $this->index->updateAttributesForFaceting(['genre']);
  457. $this->index->waitForPendingUpdate($response['updateId']);
  458. $facetsToUpperFunc = function (array $facets) {
  459. $changeOneFacet = function (array $facet) {
  460. $result = [];
  461. foreach ($facet as $k => $v) {
  462. $result[strtoupper($k)] = $v;
  463. }
  464. return $result;
  465. };
  466. return array_map($changeOneFacet, $facets);
  467. };
  468. $response = $this->index->search(
  469. null,
  470. ['facetsDistribution' => ['genre']],
  471. ['transformFacetsDistribution' => $facetsToUpperFunc]
  472. );
  473. $this->assertArrayHasKey('hits', $response->toArray());
  474. $this->assertArrayHasKey('facetsDistribution', $response->toArray());
  475. $this->assertArrayHasKey('offset', $response->toArray());
  476. $this->assertArrayHasKey('limit', $response->toArray());
  477. $this->assertArrayHasKey('processingTimeMs', $response->toArray());
  478. $this->assertArrayHasKey('query', $response->toArray());
  479. $this->assertEquals($response->getRaw()['hits'], $response->getHits());
  480. $this->assertNotEquals($response->getRaw()['facetsDistribution'], $response->getFacetsDistribution());
  481. $this->assertCount(3, $response->getFacetsDistribution()['genre']);
  482. $this->assertEquals(3, $response->getFacetsDistribution()['genre']['ROMANCE']);
  483. $this->assertEquals(2, $response->getFacetsDistribution()['genre']['FANTASY']);
  484. $this->assertEquals(1, $response->getFacetsDistribution()['genre']['ADVENTURE']);
  485. }
  486. public function testBasicSearchWithTransformFacetsDritributionOptionToOder(): void
  487. {
  488. $response = $this->index->updateAttributesForFaceting(['genre']);
  489. $this->index->waitForPendingUpdate($response['updateId']);
  490. $facetsToUpperFunc = function (array $facets) {
  491. $sortOneFacet = function (array $facet) {
  492. ksort($facet);
  493. return $facet;
  494. };
  495. return array_map($sortOneFacet, $facets);
  496. };
  497. $response = $this->index->search(
  498. null,
  499. ['facetsDistribution' => ['genre']],
  500. ['transformFacetsDistribution' => $facetsToUpperFunc]
  501. );
  502. $this->assertArrayHasKey('hits', $response->toArray());
  503. $this->assertArrayHasKey('facetsDistribution', $response->toArray());
  504. $this->assertArrayHasKey('offset', $response->toArray());
  505. $this->assertArrayHasKey('limit', $response->toArray());
  506. $this->assertArrayHasKey('processingTimeMs', $response->toArray());
  507. $this->assertArrayHasKey('query', $response->toArray());
  508. $this->assertEquals($response->getRaw()['hits'], $response->getHits());
  509. $this->assertEquals('adventure', array_key_first($response->getFacetsDistribution()['genre']));
  510. $this->assertEquals('romance', array_key_last($response->getFacetsDistribution()['genre']));
  511. $this->assertCount(3, $response->getFacetsDistribution()['genre']);
  512. $this->assertEquals(3, $response->getFacetsDistribution()['genre']['romance']);
  513. $this->assertEquals(2, $response->getFacetsDistribution()['genre']['fantasy']);
  514. $this->assertEquals(1, $response->getFacetsDistribution()['genre']['adventure']);
  515. }
  516. }