Ensure that detected nested fields inherit field properties.

This commit is contained in:
Kishore Nallan 2022-11-01 17:19:45 +05:30
parent c87e0ddf9d
commit 4212a107ed
3 changed files with 53 additions and 8 deletions

View File

@ -84,6 +84,10 @@ struct field {
name(name), type(type), facet(facet), optional(optional), index(index), locale(locale),
nested(nested), nested_array(nested_array), num_dim(num_dim), vec_dist(vec_dist) {
set_computed_defaults(sort, infix);
}
void set_computed_defaults(int sort, int infix) {
if(sort != -1) {
this->sort = bool(sort);
} else {
@ -413,7 +417,8 @@ struct field {
}
static bool flatten_obj(nlohmann::json& doc, nlohmann::json& value, bool has_array, bool has_obj_array,
const std::string& flat_name, std::unordered_map<std::string, field>& flattened_fields);
const field& the_field, const std::string& flat_name,
std::unordered_map<std::string, field>& flattened_fields);
static Option<bool> flatten_field(nlohmann::json& doc, nlohmann::json& obj, const field& the_field,
std::vector<std::string>& path_parts, size_t path_index, bool has_array,

View File

@ -642,15 +642,16 @@ Option<bool> field::json_field_to_field(bool enable_nested_fields, nlohmann::jso
}
bool field::flatten_obj(nlohmann::json& doc, nlohmann::json& value, bool has_array, bool has_obj_array,
const std::string& flat_name, std::unordered_map<std::string, field>& flattened_fields) {
const field& the_field, const std::string& flat_name,
std::unordered_map<std::string, field>& flattened_fields) {
if(value.is_object()) {
has_obj_array = has_array;
for(const auto& kv: value.items()) {
flatten_obj(doc, kv.value(), has_array, has_obj_array, flat_name + "." + kv.key(), flattened_fields);
flatten_obj(doc, kv.value(), has_array, has_obj_array, the_field, flat_name + "." + kv.key(), flattened_fields);
}
} else if(value.is_array()) {
for(const auto& kv: value.items()) {
flatten_obj(doc, kv.value(), true, has_obj_array, flat_name, flattened_fields);
flatten_obj(doc, kv.value(), true, has_obj_array, the_field, flat_name, flattened_fields);
}
} else { // must be a primitive
if(doc.count(flat_name) != 0 && flattened_fields.find(flat_name) == flattened_fields.end()) {
@ -673,9 +674,13 @@ bool field::flatten_obj(nlohmann::json& doc, nlohmann::json& value, bool has_arr
detected_type += "[]";
}
field flattened_field(flat_name, detected_type, false, true);
field flattened_field = the_field;
flattened_field.name = flat_name;
flattened_field.type = detected_type;
flattened_field.optional = true;
flattened_field.nested = true;
flattened_field.nested_array = has_obj_array;
flattened_field.set_computed_defaults(-1, -1);
flattened_fields[flat_name] = flattened_field;
}
@ -708,7 +713,7 @@ Option<bool> field::flatten_field(nlohmann::json& doc, nlohmann::json& obj, cons
if(detected_type == the_field.type || is_numericaly_valid) {
if(the_field.is_object()) {
flatten_obj(doc, obj, has_array, has_obj_array, the_field.name, flattened_fields);
flatten_obj(doc, obj, has_array, has_obj_array, the_field, the_field.name, flattened_fields);
} else {
if(doc.count(the_field.name) != 0 && flattened_fields.find(the_field.name) == flattened_fields.end()) {
return Option<bool>(true);
@ -720,7 +725,8 @@ Option<bool> field::flatten_field(nlohmann::json& doc, nlohmann::json& obj, cons
doc[the_field.name] = obj;
}
field flattened_field(the_field.name, detected_type, false, true);
field flattened_field = the_field;
flattened_field.type = detected_type;
flattened_field.nested = (path_index > 1);
flattened_field.nested_array = has_obj_array;
flattened_fields[the_field.name] = flattened_field;

View File

@ -816,7 +816,7 @@ TEST_F(CollectionNestedFieldsTest, FieldsWithExplicitSchema) {
"enable_nested_fields": true,
"fields": [
{"name": "details", "type": "object", "optional": false },
{"name": "company.name", "type": "string", "optional": false },
{"name": "company.name", "type": "string", "optional": false, "facet": true },
{"name": "locations", "type": "object[]", "optional": false }
]
})"_json;
@ -848,6 +848,9 @@ TEST_F(CollectionNestedFieldsTest, FieldsWithExplicitSchema) {
auto add_op = coll1->add(doc.dump(), CREATE);
ASSERT_TRUE(add_op.ok());
ASSERT_TRUE(coll1->get_schema()["company.name"].facet);
ASSERT_FALSE(coll1->get_schema()["company.name"].optional);
// search both simply nested and deeply nested array-of-objects
auto results = coll1->search("brown fox", {"details", "locations"},
"", {}, sort_fields, {0}, 10, 1,
@ -1574,3 +1577,34 @@ TEST_F(CollectionNestedFieldsTest, NestedSchemaWithSingularType) {
add_op = coll2->add(doc1.dump(), CREATE);
ASSERT_TRUE(add_op.ok());
}
TEST_F(CollectionNestedFieldsTest, NestedSchemaAutoAndFacet) {
nlohmann::json schema = R"({
"name": "coll1",
"enable_nested_fields": true,
"fields": [
{"name": "person.*", "type": "auto", "facet": true},
{"name": "schools.*", "type": "auto", "facet": true}
]
})"_json;
auto op = collectionManager.create_collection(schema);
ASSERT_TRUE(op.ok());
Collection* coll1 = op.get();
auto doc1 = R"({
"id": "0",
"person": {"name": "Tony Stark"},
"schools": [{"name": "Primary School"}]
})"_json;
auto add_op = coll1->add(doc1.dump(), CREATE);
ASSERT_TRUE(add_op.ok());
auto fields = coll1->get_fields();
for(const auto&f : fields) {
ASSERT_TRUE(f.facet);
}
ASSERT_TRUE(coll1->get_schema()["schools.name"].optional);
}