Allow facet query value to contain colon.

This commit is contained in:
Kishore Nallan 2021-06-26 11:09:11 +05:30
parent 5cbf810fe5
commit d1d8733968
2 changed files with 62 additions and 15 deletions

View File

@ -675,30 +675,33 @@ Option<nlohmann::json> Collection::search(const std::string & query, const std::
}
// parse facet query
std::vector<std::string> facet_query_vec;
facet_query_t facet_query = {"", ""};
if(!simple_facet_query.empty() && simple_facet_query.find(':') == std::string::npos) {
std::string error = "Facet query must be in the `facet_field: value` format.";
return Option<nlohmann::json>(400, error);
}
if(!simple_facet_query.empty()) {
size_t found_colon_index = simple_facet_query.find(':');
if(found_colon_index == std::string::npos) {
std::string error = "Facet query must be in the `facet_field: value` format.";
return Option<nlohmann::json>(400, error);
}
StringUtils::split(simple_facet_query, facet_query_vec, ":");
if(!facet_query_vec.empty()) {
if(facet_fields.empty()) {
std::string error = "The `facet_query` parameter is supplied without a `facet_by` parameter.";
return Option<nlohmann::json>(400, error);
}
if(facet_query_vec.size() == 1) {
std::string&& facet_query_fname = simple_facet_query.substr(0, found_colon_index);
StringUtils::trim(facet_query_fname);
std::string&& facet_query_value = simple_facet_query.substr(found_colon_index+1, std::string::npos);
StringUtils::trim(facet_query_value);
if(facet_query_value.empty()) {
// empty facet value, we will treat it as no facet query
facet_query = {"", ""};
} else if(facet_query_vec.size() > 2) {
std::string error = "Facet query must be in the `facet_field: value` format.";
return Option<nlohmann::json>(400, error);
} else {
// facet query field must be part of facet fields requested
facet_query = { StringUtils::trim(facet_query_vec[0]), StringUtils::trim(facet_query_vec[1]) };
facet_query = { StringUtils::trim(facet_query_fname), facet_query_value };
if(std::find(facet_fields.begin(), facet_fields.end(), facet_query.field_name) == facet_fields.end()) {
std::string error = "Facet query refers to a facet field `" + facet_query.field_name + "` " +
"that is not part of `facet_by` parameter.";

View File

@ -337,14 +337,13 @@ TEST_F(CollectionFacetingTest, FacetCounts) {
ASSERT_FALSE(res_op.ok());
ASSERT_STREQ("Facet query refers to a facet field `name_facet` that is not part of `facet_by` parameter.", res_op.error().c_str());
// facet query with multiple colons
// facet query with multiple colons should be fine (only first colon will be treate as separator)
res_op = coll_array_fields->search("*", query_fields, "", facets, sort_fields, {0}, 10, 1, FREQUENCY,
{false}, Index::DROP_TOKENS_THRESHOLD,
spp::sparse_hash_set<std::string>(),
spp::sparse_hash_set<std::string>(), 10, "tags:foo:bar");
ASSERT_FALSE(res_op.ok());
ASSERT_STREQ("Facet query must be in the `facet_field: value` format.", res_op.error().c_str());
ASSERT_TRUE(res_op.ok());
collectionManager.drop_collection("coll_array_fields");
}
@ -679,3 +678,48 @@ TEST_F(CollectionFacetingTest, FacetCountOnSimilarStrings) {
collectionManager.drop_collection("coll1");
}
TEST_F(CollectionFacetingTest, FacetQueryOnStringWithColon) {
;
std::vector<field> fields = {field("title", field_types::STRING, true),
field("points", field_types::INT32, false)};
std::vector<sort_by> sort_fields = {sort_by("points", "DESC")};
Collection* coll1 = collectionManager.create_collection("coll1", 4, fields, "points").get();
nlohmann::json doc;
doc["id"] = "100";
doc["title"] = "foo:bar";
doc["points"] = 25;
ASSERT_TRUE(coll1->add(doc.dump()).ok());
auto res_op = coll1->search("*", {}, "", {"title"}, sort_fields, {0}, 10, 1,
token_ordering::FREQUENCY, {true}, 10, spp::sparse_hash_set<std::string>(),
spp::sparse_hash_set<std::string>(), 10, "title: foo:ba");
ASSERT_TRUE(res_op.ok());
auto results = res_op.get();
ASSERT_STREQ("foo:bar", results["facet_counts"][0]["counts"][0]["value"].get<std::string>().c_str());
ASSERT_STREQ("<mark>foo:ba</mark>r", results["facet_counts"][0]["counts"][0]["highlighted"].get<std::string>().c_str());
results = coll1->search("*", {}, "", {"title"}, sort_fields, {0}, 10, 1,
token_ordering::FREQUENCY, {true}, 10, spp::sparse_hash_set<std::string>(),
spp::sparse_hash_set<std::string>(), 10, "title: ").get();
ASSERT_STREQ("foo:bar", results["facet_counts"][0]["counts"][0]["value"].get<std::string>().c_str());
ASSERT_STREQ("foo:bar", results["facet_counts"][0]["counts"][0]["highlighted"].get<std::string>().c_str());
results = coll1->search("*", {}, "", {"title"}, sort_fields, {0}, 10, 1,
token_ordering::FREQUENCY, {true}, 10, spp::sparse_hash_set<std::string>(),
spp::sparse_hash_set<std::string>(), 10, "").get();
ASSERT_STREQ("foo:bar", results["facet_counts"][0]["counts"][0]["value"].get<std::string>().c_str());
ASSERT_STREQ("foo:bar", results["facet_counts"][0]["counts"][0]["highlighted"].get<std::string>().c_str());
collectionManager.drop_collection("coll1");
}