diff --git a/include/collection.h b/include/collection.h index 5fa350e3..71afb27d 100644 --- a/include/collection.h +++ b/include/collection.h @@ -226,7 +226,7 @@ public: size_t drop_tokens_threshold = Index::DROP_TOKENS_THRESHOLD, const spp::sparse_hash_set & include_fields = spp::sparse_hash_set(), const spp::sparse_hash_set & exclude_fields = spp::sparse_hash_set(), - size_t max_facet_values=10, size_t max_hits=500, + size_t max_facet_values=10, int max_hits=500, const std::string & simple_facet_query = "", const size_t snippet_threshold = 30, const std::string & highlight_full_fields = "", diff --git a/src/collection.cpp b/src/collection.cpp index 01c7da07..bd077e05 100644 --- a/src/collection.cpp +++ b/src/collection.cpp @@ -316,7 +316,7 @@ Option Collection::search(const std::string & query, const std:: const size_t drop_tokens_threshold, const spp::sparse_hash_set & include_fields, const spp::sparse_hash_set & exclude_fields, - const size_t max_facet_values, const size_t max_hits, + const size_t max_facet_values, const int _max_hits, const std::string & simple_facet_query, const size_t snippet_threshold, const std::string & highlight_full_fields, @@ -570,11 +570,13 @@ Option Collection::search(const std::string & query, const std:: return Option(422, message); } - const size_t results_per_page = std::min(per_page, max_hits); + const size_t maximum_hits = (_max_hits < 0) ? std::max((size_t)100, get_num_documents()) : size_t(_max_hits); + + const size_t results_per_page = std::min(per_page, maximum_hits); const size_t num_results = (page * results_per_page); - if(num_results > max_hits) { - std::string message = "Only the first " + std::to_string(max_hits) + " results are available."; + if(num_results > maximum_hits) { + std::string message = "Only the first " + std::to_string(maximum_hits) + " results are available."; return Option(422, message); } @@ -589,7 +591,7 @@ Option Collection::search(const std::string & query, const std:: for(Index* index: indices) { index->search_params = search_args(query, search_fields, filters, facets, index_to_included_ids[index_id], index_to_excluded_ids[index_id], - sort_fields_std, facet_query, num_typos, max_facet_values, max_hits, + sort_fields_std, facet_query, num_typos, max_facet_values, maximum_hits, results_per_page, page, token_order, prefix, drop_tokens_threshold, typo_tokens_threshold); { diff --git a/src/core_api.cpp b/src/core_api.cpp index 4b82786f..489b9f4e 100644 --- a/src/core_api.cpp +++ b/src/core_api.cpp @@ -290,6 +290,9 @@ bool get_search(http_req & req, http_res & res) { } else { req.params[MAX_HITS] = "0"; } + } else if(req.params[MAX_HITS] == "all") { + // engine will default to size of collection + req.params[MAX_HITS] = "-1"; } if(req.params.count(SNIPPET_THRESHOLD) == 0) { diff --git a/test/collection_test.cpp b/test/collection_test.cpp index 23269f1f..98d1c70b 100644 --- a/test/collection_test.cpp +++ b/test/collection_test.cpp @@ -2265,3 +2265,41 @@ TEST_F(CollectionTest, OptionalFields) { collectionManager.drop_collection("coll1"); } + +TEST_F(CollectionTest, ReturnsResultsBasedOnMaxHitsParam) { + std::vector facets; + spp::sparse_hash_set empty; + nlohmann::json results = collection->search("*", query_fields, "", facets, sort_fields, 0, 100, 1, + FREQUENCY, false, 1000, empty, empty, 10, 12).get(); + + ASSERT_EQ(12, results["hits"].size()); + ASSERT_EQ(25, results["found"].get()); + + // should match collection size + + results = collection->search("*", query_fields, "", facets, sort_fields, 0, 100, 1, + FREQUENCY, false, 1000, empty, empty, 10, -1).get(); + + ASSERT_EQ(25, results["hits"].size()); + ASSERT_EQ(25, results["found"].get()); + + // should still respect pagination + + results = collection->search("*", query_fields, "", facets, sort_fields, 0, 10, 1, + FREQUENCY, false, 1000, empty, empty, 10, -1).get(); + + ASSERT_EQ(10, results["hits"].size()); + ASSERT_EQ(25, results["found"].get()); + + results = collection->search("*", query_fields, "", facets, sort_fields, 0, 10, 2, + FREQUENCY, false, 1000, empty, empty, 10, -1).get(); + + ASSERT_EQ(10, results["hits"].size()); + ASSERT_EQ(25, results["found"].get()); + + results = collection->search("*", query_fields, "", facets, sort_fields, 0, 10, 3, + FREQUENCY, false, 1000, empty, empty, 10, -1).get(); + + ASSERT_EQ(5, results["hits"].size()); + ASSERT_EQ(25, results["found"].get()); +}