diff --git a/.code-samples.meilisearch.yaml b/.code-samples.meilisearch.yaml index 8bc5668f..e6fd5dae 100644 --- a/.code-samples.meilisearch.yaml +++ b/.code-samples.meilisearch.yaml @@ -827,3 +827,13 @@ get_similar_post_1: .setId("143") .setEmbedder("manual"); client.index("movies").searchSimilarDocuments(query) +search_parameter_reference_distinct_1: |- + SearchRequest searchRequest = SearchRequest.builder().q("QUERY TERMS").distinct("ATTRIBUTE_A").build(); + client.index("INDEX_NAME").search(searchRequest); +distinct_attribute_guide_filterable_1: |- + Settings settings = new Settings(); + settings.setFilterableAttributes(new String[] {"product_id", "SKU", "url"}); + client.index("products").updateSettings(settings); +distinct_attribute_guide_distinct_parameter_1: |- + SearchRequest searchRequest = SearchRequest.builder().q("white shirt").distinct("sku").build(); + client.index("products").search(searchRequest); diff --git a/src/main/java/com/meilisearch/sdk/IndexSearchRequest.java b/src/main/java/com/meilisearch/sdk/IndexSearchRequest.java index b4671fae..f13d81d8 100644 --- a/src/main/java/com/meilisearch/sdk/IndexSearchRequest.java +++ b/src/main/java/com/meilisearch/sdk/IndexSearchRequest.java @@ -36,12 +36,14 @@ public class IndexSearchRequest { protected Double rankingScoreThreshold; private String[] attributesToSearchOn; private FederationOptions federationOptions; + protected String distinct; /** * Constructor for MultiSearchRequest for building search queries with the default values: * offset: 0, limit: 20, attributesToRetrieve: ["*"], attributesToCrop: null, cropLength: 200, * attributesToHighlight: null, filter: null, showMatchesPosition: false, facets: null, sort: * null, showRankingScore: false, showRankingScoreDetails: false, rankingScoreThreshold: null + * distinct: null * * @param indexUid uid of the requested index String */ @@ -101,7 +103,8 @@ public String toString() { .putOpt("showRankingScore", this.showRankingScore) .putOpt("showRankingScoreDetails", this.showRankingScoreDetails) .putOpt("rankingScoreThreshold", this.rankingScoreThreshold) - .putOpt("attributesToSearchOn", this.attributesToSearchOn); + .putOpt("attributesToSearchOn", this.attributesToSearchOn) + .putOpt("distinct", this.distinct); return jsonObject.toString(); } diff --git a/src/main/java/com/meilisearch/sdk/SearchRequest.java b/src/main/java/com/meilisearch/sdk/SearchRequest.java index 25be1b3c..556e38cc 100644 --- a/src/main/java/com/meilisearch/sdk/SearchRequest.java +++ b/src/main/java/com/meilisearch/sdk/SearchRequest.java @@ -40,6 +40,7 @@ public class SearchRequest { protected Boolean showRankingScore; protected Boolean showRankingScoreDetails; protected Double rankingScoreThreshold; + protected String distinct; /** * Constructor for SearchRequest for building search queries with the default values: offset: 0, @@ -100,7 +101,8 @@ public String toString() { .putOpt("filter", this.filterArray) .putOpt("showRankingScore", this.showRankingScore) .putOpt("showRankingScoreDetails", this.showRankingScoreDetails) - .putOpt("rankingScoreThreshold", this.rankingScoreThreshold); + .putOpt("rankingScoreThreshold", this.rankingScoreThreshold) + .putOpt("distinct", this.distinct); return jsonObject.toString(); } diff --git a/src/test/java/com/meilisearch/integration/SearchTest.java b/src/test/java/com/meilisearch/integration/SearchTest.java index 1c7bf4dd..e4d8adaa 100644 --- a/src/test/java/com/meilisearch/integration/SearchTest.java +++ b/src/test/java/com/meilisearch/integration/SearchTest.java @@ -410,6 +410,29 @@ public void testSearchWithRankingScoreThreshold() throws Exception { assertThat(resGson.hits[0].getRankingScore(), is(greaterThanOrEqualTo(0.9))); } + /** Test with show distinct */ + @Test + public void testSearchWithDistinct() throws Exception { + String indexUid = "SearchDistinct"; + Index index = client.index(indexUid); + GsonJsonHandler jsonGson = new GsonJsonHandler(); + + TestData testData = this.getTestData(MOVIES_INDEX, Movie.class); + TaskInfo task = index.addDocuments(testData.getRaw()); + + index.waitForTask(task.getTaskUid()); + + Settings settings = index.getSettings(); + + settings.setFilterableAttributes(new String[] {"language"}); + index.waitForTask(index.updateSettings(settings).getTaskUid()); + + SearchRequest searchRequest = SearchRequest.builder().q("").distinct("language").build(); + + Results resGson = jsonGson.decode(index.rawSearch(searchRequest), Results.class); + assertThat(resGson.hits, is(arrayWithSize(4))); + } + /** Test search with phrase */ @Test public void testSearchPhrase() throws Exception { @@ -871,6 +894,43 @@ public void testMultiSearchWithRankingScoreThreshold() throws Exception { } } + /** Test multisearch with distinct */ + @Test + public void testMultiSearchWithDistinct() throws Exception { + HashSet indexUids = new HashSet(); + indexUids.add("MultiSearch1"); + indexUids.add("MultiSearch2"); + + for (String indexUid : indexUids) { + Index index = client.index(indexUid); + + TestData testData = this.getTestData(MOVIES_INDEX, Movie.class); + TaskInfo task = index.addDocuments(testData.getRaw()); + + Settings settings = new Settings(); + settings.setFilterableAttributes(new String[] {"language", "title"}); + + index.waitForTask(index.updateSettings(settings).getTaskUid()); + + index.waitForTask(task.getTaskUid()); + } + + MultiSearchRequest search = new MultiSearchRequest(); + + for (String indexUid : indexUids) { + search.addQuery(new IndexSearchRequest(indexUid).setQuery("").setDistinct("language")); + } + + MultiSearchResult[] results = client.multiSearch(search).getResults(); + + assertThat(results.length, is(2)); + + for (MultiSearchResult searchResult : results) { + assertThat(indexUids.contains(searchResult.getIndexUid()), is(true)); + assertThat(searchResult.getHits().size(), is(4)); + } + } + @Test public void testSimilarDocuments() throws Exception { HashMap features = new HashMap(); diff --git a/src/test/java/com/meilisearch/sdk/SearchRequestTest.java b/src/test/java/com/meilisearch/sdk/SearchRequestTest.java index fc1b648c..7578596b 100644 --- a/src/test/java/com/meilisearch/sdk/SearchRequestTest.java +++ b/src/test/java/com/meilisearch/sdk/SearchRequestTest.java @@ -133,7 +133,8 @@ void toStringEveryParameters() { .setFacets(new String[] {"facets"}) .setSort(new String[] {"sort"}) .setPage(10) - .setHitsPerPage(2); + .setHitsPerPage(2) + .setDistinct("distinct"); assertThat(classToTest.getQ(), is(equalTo("This is a Test"))); assertThat(classToTest.getOffset(), is(equalTo(200))); @@ -153,6 +154,7 @@ void toStringEveryParameters() { assertThat(classToTest.getCropLength(), is(equalTo(900))); assertThat(classToTest.getPage(), is(equalTo(10))); assertThat(classToTest.getHitsPerPage(), is(equalTo(2))); + assertThat(classToTest.getDistinct(), is(equalTo("distinct"))); } @Test @@ -172,6 +174,7 @@ void toStringEveryParametersWithBuilder() { .sort(new String[] {"sort"}) .page(10) .hitsPerPage(2) + .distinct("distinct") .build(); assertThat(classToTest.getQ(), is(equalTo("This is a Test"))); @@ -192,6 +195,7 @@ void toStringEveryParametersWithBuilder() { assertThat(classToTest.getCropLength(), is(equalTo(900))); assertThat(classToTest.getPage(), is(equalTo(10))); assertThat(classToTest.getHitsPerPage(), is(equalTo(2))); + assertThat(classToTest.getDistinct(), is(equalTo("distinct"))); } @Test @@ -217,9 +221,10 @@ void toStringEveryParametersWithArray() { .setFacets(new String[] {"facets"}) .setSort(new String[] {"sort"}) .setPage(0) - .setHitsPerPage(0); + .setHitsPerPage(0) + .setDistinct("distinct"); String expectedToString = - "{\"attributesToRetrieve\":[\"bubble\"],\"offset\":200,\"cropMarker\":\"123\",\"hitsPerPage\":0,\"attributesToSearchOn\":[\"searchOn\"],\"sort\":[\"sort\"],\"highlightPreTag\":\"abc\",\"facets\":[\"facets\"],\"filter\":[[\"test='test'\"],[\"test1='test1'\"]],\"q\":\"This is a Test\",\"matchingStrategy\":\"all\",\"showMatchesPosition\":true,\"limit\":900,\"cropLength\":900,\"highlightPostTag\":\"zyx\",\"attributesToHighlight\":[\"highlight\"],\"page\":0,\"attributesToCrop\":[\"crop\"]}"; + "{\"attributesToRetrieve\":[\"bubble\"],\"offset\":200,\"cropMarker\":\"123\",\"hitsPerPage\":0,\"attributesToSearchOn\":[\"searchOn\"],\"distinct\":\"distinct\",\"sort\":[\"sort\"],\"highlightPreTag\":\"abc\",\"facets\":[\"facets\"],\"filter\":[[\"test='test'\"],[\"test1='test1'\"]],\"q\":\"This is a Test\",\"matchingStrategy\":\"all\",\"showMatchesPosition\":true,\"limit\":900,\"cropLength\":900,\"highlightPostTag\":\"zyx\",\"attributesToHighlight\":[\"highlight\"],\"page\":0,\"attributesToCrop\":[\"crop\"]}"; assertThat(classToTest.getQ(), is(equalTo("This is a Test"))); assertThat(classToTest.getOffset(), is(equalTo(200))); @@ -241,6 +246,7 @@ void toStringEveryParametersWithArray() { assertThat(classToTest.getCropLength(), is(equalTo(900))); assertThat(classToTest.getPage(), is(equalTo(0))); assertThat(classToTest.getHitsPerPage(), is(equalTo(0))); + assertThat(classToTest.getDistinct(), is(equalTo("distinct"))); assertThat(classToTest.toString(), is(equalTo(expectedToString))); } @@ -269,9 +275,10 @@ void toStringEveryParametersWithArrayWithBuilder() { .sort(new String[] {"sort"}) .page(0) .hitsPerPage(0) + .distinct("distinct") .build(); String expectedToString = - "{\"attributesToRetrieve\":[\"bubble\"],\"offset\":200,\"cropMarker\":\"123\",\"hitsPerPage\":0,\"attributesToSearchOn\":[\"searchOn\"],\"sort\":[\"sort\"],\"highlightPreTag\":\"abc\",\"facets\":[\"facets\"],\"filter\":[[\"test='test'\"],[\"test1='test1'\"]],\"q\":\"This is a Test\",\"matchingStrategy\":\"all\",\"showMatchesPosition\":true,\"limit\":900,\"cropLength\":900,\"highlightPostTag\":\"zyx\",\"attributesToHighlight\":[\"highlight\"],\"page\":0,\"attributesToCrop\":[\"crop\"]}"; + "{\"attributesToRetrieve\":[\"bubble\"],\"offset\":200,\"cropMarker\":\"123\",\"hitsPerPage\":0,\"attributesToSearchOn\":[\"searchOn\"],\"distinct\":\"distinct\",\"sort\":[\"sort\"],\"highlightPreTag\":\"abc\",\"facets\":[\"facets\"],\"filter\":[[\"test='test'\"],[\"test1='test1'\"]],\"q\":\"This is a Test\",\"matchingStrategy\":\"all\",\"showMatchesPosition\":true,\"limit\":900,\"cropLength\":900,\"highlightPostTag\":\"zyx\",\"attributesToHighlight\":[\"highlight\"],\"page\":0,\"attributesToCrop\":[\"crop\"]}"; assertThat(classToTest.getQ(), is(equalTo("This is a Test"))); assertThat(classToTest.getOffset(), is(equalTo(200))); @@ -293,6 +300,7 @@ void toStringEveryParametersWithArrayWithBuilder() { assertThat(classToTest.getCropLength(), is(equalTo(900))); assertThat(classToTest.getPage(), is(equalTo(0))); assertThat(classToTest.getHitsPerPage(), is(equalTo(0))); + assertThat(classToTest.getDistinct(), is(equalTo("distinct"))); assertThat(classToTest.toString(), is(equalTo(expectedToString))); } @@ -321,9 +329,10 @@ void toStringEveryParametersWithArrayMatchingStrategyNull() { .sort(new String[] {"sort"}) .page(0) .hitsPerPage(0) + .distinct("distinct") .build(); String expectedToString = - "{\"attributesToRetrieve\":[\"bubble\"],\"offset\":200,\"cropMarker\":\"123\",\"hitsPerPage\":0,\"attributesToSearchOn\":[\"searchOn\"],\"sort\":[\"sort\"],\"highlightPreTag\":\"abc\",\"facets\":[\"facets\"],\"filter\":[[\"test='test'\"],[\"test1='test1'\"]],\"q\":\"This is a Test\",\"showMatchesPosition\":true,\"limit\":900,\"cropLength\":900,\"highlightPostTag\":\"zyx\",\"attributesToHighlight\":[\"highlight\"],\"page\":0,\"attributesToCrop\":[\"crop\"]}"; + "{\"attributesToRetrieve\":[\"bubble\"],\"offset\":200,\"cropMarker\":\"123\",\"hitsPerPage\":0,\"attributesToSearchOn\":[\"searchOn\"],\"distinct\":\"distinct\",\"sort\":[\"sort\"],\"highlightPreTag\":\"abc\",\"facets\":[\"facets\"],\"filter\":[[\"test='test'\"],[\"test1='test1'\"]],\"q\":\"This is a Test\",\"showMatchesPosition\":true,\"limit\":900,\"cropLength\":900,\"highlightPostTag\":\"zyx\",\"attributesToHighlight\":[\"highlight\"],\"page\":0,\"attributesToCrop\":[\"crop\"]}"; assertThat(classToTest.getQ(), is(equalTo("This is a Test"))); assertThat(classToTest.getOffset(), is(equalTo(200))); @@ -343,6 +352,7 @@ void toStringEveryParametersWithArrayMatchingStrategyNull() { assertThat(classToTest.getFacets()[0], is(equalTo("facets"))); assertThat(classToTest.getSort()[0], is(equalTo("sort"))); assertThat(classToTest.getCropLength(), is(equalTo(900))); + assertThat(classToTest.getDistinct(), is(equalTo("distinct"))); assertThat(classToTest.toString(), is(equalTo(expectedToString))); } }