Add limit_hits param for restricting total results

This commit is contained in:
Jason Bosco 2021-01-22 21:37:36 -08:00
parent c110f8ecff
commit 0306242d59
4 changed files with 31 additions and 3 deletions

View File

@ -373,7 +373,8 @@ public:
const size_t group_limit = 0,
const std::string& highlight_start_tag="<mark>",
const std::string& highlight_end_tag="</mark>",
std::vector<size_t> query_by_weights={});
std::vector<size_t> query_by_weights={},
size_t limit_hits=UINT32_MAX);
Option<bool> get_filter_ids(const std::string & simple_filter_query,
std::vector<std::pair<size_t, uint32_t*>>& index_ids);

View File

@ -512,7 +512,8 @@ Option<nlohmann::json> Collection::search(const std::string & query, const std::
const size_t group_limit,
const std::string& highlight_start_tag,
const std::string& highlight_end_tag,
std::vector<size_t> query_by_weights) {
std::vector<size_t> query_by_weights,
size_t limit_hits) {
if(query != "*" && search_fields.empty()) {
return Option<nlohmann::json>(400, "No search fields specified for the query.");
@ -743,6 +744,11 @@ Option<nlohmann::json> Collection::search(const std::string & query, const std::
return Option<nlohmann::json>(422, message);
}
if((page * per_page) > limit_hits) {
std::string message = "Only upto " + std::to_string(limit_hits) + " hits can be fetched.";
return Option<nlohmann::json>(422, message);
}
size_t max_hits;
// ensure that `max_hits` never exceeds number of documents in collection

View File

@ -277,6 +277,7 @@ bool get_search(http_req & req, http_res & res) {
const char *GROUP_BY = "group_by";
const char *GROUP_LIMIT = "group_limit";
const char *LIMIT_HITS = "limit_hits";
const char *PER_PAGE = "per_page";
const char *PAGE = "page";
const char *CALLBACK = "callback";
@ -328,6 +329,10 @@ bool get_search(http_req & req, http_res & res) {
req.params[FACET_QUERY] = "";
}
if(req.params.count(LIMIT_HITS) == 0) {
req.params[LIMIT_HITS] = std::to_string(UINT32_MAX);
}
if(req.params.count(SNIPPET_THRESHOLD) == 0) {
req.params[SNIPPET_THRESHOLD] = "30";
}
@ -427,6 +432,11 @@ bool get_search(http_req & req, http_res & res) {
return false;
}
if(!StringUtils::is_uint32_t(req.params[LIMIT_HITS])) {
res.set_400("Parameter `" + std::string(LIMIT_HITS) + "` must be an unsigned integer.");
return false;
}
if(!StringUtils::is_uint32_t(req.params[SNIPPET_THRESHOLD])) {
res.set_400("Parameter `" + std::string(SNIPPET_THRESHOLD) + "` must be an unsigned integer.");
return false;
@ -531,7 +541,8 @@ bool get_search(http_req & req, http_res & res) {
static_cast<size_t>(std::stol(req.params[GROUP_LIMIT])),
req.params[HIGHLIGHT_START_TAG],
req.params[HIGHLIGHT_END_TAG],
query_by_weights
query_by_weights,
static_cast<size_t>(std::stol(req.params[LIMIT_HITS]))
);
uint64_t timeMillis = std::chrono::duration_cast<std::chrono::milliseconds>(

View File

@ -2566,6 +2566,16 @@ TEST_F(CollectionTest, WildcardQueryReturnsResultsBasedOnPerPageParam) {
ASSERT_EQ(5, results["hits"].size());
ASSERT_EQ(25, results["found"].get<int>());
// enforce limit_hits
res_op = collection->search("*", query_fields, "", facets, sort_fields, 0, 10, 3,
FREQUENCY, false, 1000,
spp::sparse_hash_set<std::string>(),
spp::sparse_hash_set<std::string>(), 10, "", 30, 4, "", 40, {}, {}, {}, 0,
"<mark>", "</mark>", {1}, 20);
ASSERT_FALSE(res_op.ok());
ASSERT_STREQ("Only upto 20 hits can be fetched.", res_op.error().c_str());
}
TEST_F(CollectionTest, RemoveIfFound) {