mirror of
https://github.com/typesense/typesense.git
synced 2025-05-18 20:52:50 +08:00
Allow facet query value to contain colon.
This commit is contained in:
parent
5cbf810fe5
commit
d1d8733968
@ -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.";
|
||||
|
@ -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");
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user