Ensure floating point precision is correct when faceted.

This commit is contained in:
Kishore Nallan 2021-05-21 19:01:39 +05:30
parent 89409bb6d6
commit c712cc0ca7
5 changed files with 49 additions and 5 deletions

View File

@ -294,4 +294,6 @@ struct StringUtils {
}
static std::map<std::string, std::string> parse_query_string(const std::string& query);
static std::string float_to_str(float value);
};

View File

@ -1370,11 +1370,11 @@ bool Collection::facet_value_to_string(const facet &a_facet, const facet_count_t
value = std::to_string(raw_val);
} else if(facet_schema.at(a_facet.field_name).type == field_types::FLOAT) {
float raw_val = document[a_facet.field_name].get<float>();
value = std::to_string(raw_val);
value = StringUtils::float_to_str(raw_val);
value.erase ( value.find_last_not_of('0') + 1, std::string::npos ); // remove trailing zeros
} else if(facet_schema.at(a_facet.field_name).type == field_types::FLOAT_ARRAY) {
float raw_val = document[a_facet.field_name][facet_count.array_pos].get<float>();
value = std::to_string(raw_val);
value = StringUtils::float_to_str(raw_val);
value.erase ( value.find_last_not_of('0') + 1, std::string::npos ); // remove trailing zeros
} else if(facet_schema.at(a_facet.field_name).type == field_types::BOOL) {
value = std::to_string(document[a_facet.field_name].get<bool>());

View File

@ -163,7 +163,7 @@ Option<uint32_t> Index::index_in_memory(const nlohmann::json &document, uint32_t
}
} else if(field_pair.second.type == field_types::FLOAT_ARRAY) {
for(float value: document[field_name]){
strings.push_back(std::to_string(value));
strings.push_back(StringUtils::float_to_str(value));
}
} else if(field_pair.second.type == field_types::BOOL_ARRAY) {
for(bool value: document[field_name]){
@ -179,7 +179,7 @@ Option<uint32_t> Index::index_in_memory(const nlohmann::json &document, uint32_t
} else if(field_pair.second.type == field_types::INT64) {
text = std::to_string(document[field_name].get<int64_t>());
} else if(field_pair.second.type == field_types::FLOAT) {
text = std::to_string(document[field_name].get<float>());
text = StringUtils::float_to_str(document[field_name].get<float>());
} else if(field_pair.second.type == field_types::BOOL) {
text = std::to_string(document[field_name].get<bool>());
}
@ -2608,7 +2608,7 @@ Option<uint32_t> Index::coerce_string(const DIRTY_VALUES& dirty_values, const st
}
else if(item.is_number_float()) {
item = std::to_string((float)item);
item = StringUtils::float_to_str((float)item);
}
else if(item.is_boolean()) {

View File

@ -180,6 +180,12 @@ void StringUtils::split_to_values(const std::string& vals_str, std::vector<std::
}
}
std::string StringUtils::float_to_str(float value) {
std::ostringstream os;
os << value;
return os.str();
}
/*size_t StringUtils::unicode_length(const std::string& bytes) {
std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> utf8conv;
return utf8conv.from_bytes(bytes).size();

View File

@ -404,6 +404,42 @@ TEST_F(CollectionFacetingTest, FacetCountsBool) {
collectionManager.drop_collection("coll1");
}
TEST_F(CollectionFacetingTest, FacetCountsFloatPrecision) {
Collection *coll1;
std::vector<field> fields = {field("title", field_types::STRING, false),
field("points", field_types::FLOAT, true)};
std::vector<sort_by> sort_fields = {sort_by("points", "DESC")};
coll1 = collectionManager.get_collection("coll1").get();
if (coll1 == nullptr) {
coll1 = collectionManager.create_collection("coll1", 4, fields, "points").get();
}
nlohmann::json doc;
doc["id"] = "100";
doc["title"] = "Ford Mustang";
doc["points"] = 113.4;
coll1->add(doc.dump());
std::vector<std::string> facets = {"points"};
nlohmann::json results = coll1->search("*", {"title"}, "", facets, sort_fields, {0}, 10, 1,
token_ordering::FREQUENCY, true).get();
ASSERT_EQ(1, results["facet_counts"].size());
ASSERT_EQ(1, results["facet_counts"][0]["counts"].size());
ASSERT_STREQ("points", results["facet_counts"][0]["field_name"].get<std::string>().c_str());
ASSERT_EQ(1, (int) results["facet_counts"][0]["counts"][0]["count"]);
ASSERT_STREQ("113.4", results["facet_counts"][0]["counts"][0]["value"].get<std::string>().c_str());
ASSERT_STREQ("113.4",results["facet_counts"][0]["counts"][0]["highlighted"].get<std::string>().c_str());
collectionManager.drop_collection("coll1");
}
TEST_F(CollectionFacetingTest, FacetCountsHighlighting) {
Collection *coll1;