From e82bee7d8920607341f19244a90dcaceadc334ac Mon Sep 17 00:00:00 2001 From: kishorenc Date: Thu, 27 Feb 2020 07:29:34 +0530 Subject: [PATCH] Allow filter value of bool field to be multi-valued. --- src/collection.cpp | 25 +++++++++++++++++++++---- test/collection_test.cpp | 22 ++++++++++++++++++++-- 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/collection.cpp b/src/collection.cpp index 9852ed23..b0e27be8 100644 --- a/src/collection.cpp +++ b/src/collection.cpp @@ -416,11 +416,28 @@ Option Collection::search(const std::string & query, const std:: f = {field_name, {filter_value}, op_comparator.get()}; } } else if(_field.is_bool()) { - if(raw_value != "true" && raw_value != "false") { - return Option(400, "Value of field `" + _field.name + "`: must be `true` or `false`."); + if(raw_value[0] == '[' && raw_value[raw_value.size() - 1] == ']') { + std::vector filter_values; + StringUtils::split(raw_value.substr(1, raw_value.size() - 2), filter_values, ","); + + for(std::string & filter_value: filter_values) { + if(filter_value != "true" && filter_value != "false") { + return Option(400, "Values of field `" + _field.name + + "`: must be `true` or `false`."); + } + + filter_value = (filter_value == "true") ? "1" : "0"; + } + + f = {field_name, filter_values, EQUALS}; + } else { + if(raw_value != "true" && raw_value != "false") { + return Option(400, "Value of field `" + _field.name + "`: must be `true` or `false`."); + } + std::string bool_value = (raw_value == "true") ? "1" : "0"; + f = {field_name, {bool_value}, EQUALS}; } - std::string bool_value = (raw_value == "true") ? "1" : "0"; - f = {field_name, {bool_value}, EQUALS}; + } else if(_field.is_string()) { if(raw_value[0] == '[' && raw_value[raw_value.size() - 1] == ']') { std::vector filter_values; diff --git a/test/collection_test.cpp b/test/collection_test.cpp index ecbd90fc..d9692ab4 100644 --- a/test/collection_test.cpp +++ b/test/collection_test.cpp @@ -1608,10 +1608,13 @@ TEST_F(CollectionTest, QueryBoolFields) { // searching against a bool array field - // should be able to search only with a single boolean value + // should be able to filter with an array of boolean values Option res_op = coll_bool->search("the", query_fields, "bool_array:[true, false]", facets, sort_fields, 0, 10, 1, FREQUENCY, false); - ASSERT_FALSE(res_op.ok()); + ASSERT_TRUE(res_op.ok()); + results = res_op.get(); + + ASSERT_EQ(5, results["hits"].size()); results = coll_bool->search("the", query_fields, "bool_array: true", facets, sort_fields, 0, 10, 1, FREQUENCY, false).get(); ASSERT_EQ(4, results["hits"].size()); @@ -1624,6 +1627,21 @@ TEST_F(CollectionTest, QueryBoolFields) { ASSERT_STREQ(id.c_str(), result_id.c_str()); } + // should be able to search using array with a single element boolean value + + auto res = coll_bool->search("the", query_fields, "bool_array:[true]", facets, + sort_fields, 0, 10, 1, FREQUENCY, false).get(); + + results = coll_bool->search("the", query_fields, "bool_array: true", facets, sort_fields, 0, 10, 1, FREQUENCY, false).get(); + ASSERT_EQ(4, results["hits"].size()); + + for(size_t i = 0; i < results["hits"].size(); i++) { + nlohmann::json result = results["hits"].at(i); + std::string result_id = result["document"]["id"]; + std::string id = ids.at(i); + ASSERT_STREQ(id.c_str(), result_id.c_str()); + } + collectionManager.drop_collection("coll_bool"); }