diff --git a/include/field.h b/include/field.h index bd75334e..8dc8ac55 100644 --- a/include/field.h +++ b/include/field.h @@ -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& flattened_fields); + const field& the_field, const std::string& flat_name, + std::unordered_map& flattened_fields); static Option flatten_field(nlohmann::json& doc, nlohmann::json& obj, const field& the_field, std::vector& path_parts, size_t path_index, bool has_array, diff --git a/src/field.cpp b/src/field.cpp index 312e85ec..f892a9f5 100644 --- a/src/field.cpp +++ b/src/field.cpp @@ -642,15 +642,16 @@ Option 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& flattened_fields) { + const field& the_field, const std::string& flat_name, + std::unordered_map& 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 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(true); @@ -720,7 +725,8 @@ Option 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; diff --git a/test/collection_nested_fields_test.cpp b/test/collection_nested_fields_test.cpp index 69e6ca78..e1dc4c61 100644 --- a/test/collection_nested_fields_test.cpp +++ b/test/collection_nested_fields_test.cpp @@ -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); +}