From 6c284dba1782db44d0dac28671b6635ae2db3421 Mon Sep 17 00:00:00 2001 From: kishorenc Date: Mon, 29 Mar 2021 20:09:00 +0530 Subject: [PATCH] Allow searching against string* fields. --- include/field.h | 2 +- src/collection.cpp | 20 +++++++++++++++++ src/index.cpp | 2 +- test/collection_all_fields_test.cpp | 33 +++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+), 2 deletions(-) diff --git a/include/field.h b/include/field.h index a000754e..9b6f21e1 100644 --- a/include/field.h +++ b/include/field.h @@ -114,7 +114,7 @@ struct field { } bool is_dynamic() const { - return name != ".*" && name.find(".*") != std::string::npos; + return type == "string*" || (name != ".*" && name.find(".*") != std::string::npos); } bool has_numerical_index() const { diff --git a/src/collection.cpp b/src/collection.cpp index b12b6330..9a111b69 100644 --- a/src/collection.cpp +++ b/src/collection.cpp @@ -2319,6 +2319,26 @@ Option Collection::check_and_update_schema(nlohmann::json& document, const if(std::regex_match (kv.key(), std::regex(dynamic_field.name))) { new_field = dynamic_field; new_field.name = fname; + + if (field_types::is_string_or_array(dynamic_field.type)) { + parseable = field::get_type(kv.value(), field_type); + if(!parseable) { + if(dirty_values == DIRTY_VALUES::REJECT || dirty_values == DIRTY_VALUES::COERCE_OR_REJECT) { + return Option(400, "Type of field `" + kv.key() + "` is invalid."); + } else { + // DROP or COERCE_OR_DROP + kv = document.erase(kv); + continue; + } + } + + if (field_type == field_types::STRING_ARRAY) { + new_field.type = field_types::STRING_ARRAY; + } else { + new_field.type = field_types::STRING; + } + } + goto UPDATE_SCHEMA; } } diff --git a/src/index.cpp b/src/index.cpp index 66227591..2054838b 100644 --- a/src/index.cpp +++ b/src/index.cpp @@ -2511,7 +2511,7 @@ void Index::refresh_schemas(const std::vector& new_fields) { sort_schema.emplace(new_field.name, new_field); if(search_index.count(new_field.name) == 0) { - if(new_field.is_string()) { + if(new_field.is_string() || field_types::is_string_or_array(new_field.type)) { art_tree *t = new art_tree; art_tree_init(t); search_index.emplace(new_field.name, t); diff --git a/test/collection_all_fields_test.cpp b/test/collection_all_fields_test.cpp index ff661bf8..47285e4b 100644 --- a/test/collection_all_fields_test.cpp +++ b/test/collection_all_fields_test.cpp @@ -442,6 +442,39 @@ TEST_F(CollectionAllFieldsTest, StringifyAllValues) { collectionManager.drop_collection("coll1"); } +TEST_F(CollectionAllFieldsTest, SearchStringifiedField) { + Collection *coll1; + + std::vector fields = {field("title", field_types::STRING, true), + field("department", "string*", true, true), + field(".*_name", "string*", true, true),}; + + coll1 = collectionManager.get_collection("coll1").get(); + if (coll1 == nullptr) { + const Option &coll_op = collectionManager.create_collection("coll1", 1, fields, "", 0, ""); + ASSERT_TRUE(coll_op.ok()); + coll1 = coll_op.get(); + } + + nlohmann::json doc; + doc["title"] = "FIRST"; + doc["department"] = "ENGINEERING"; + doc["company_name"] = "Stark Inc."; + + Option add_op = coll1->add(doc.dump(), CREATE, "0"); + ASSERT_TRUE(add_op.ok()); + + auto results_op = coll1->search("stark", {"company_name"}, "", {}, sort_fields, 0, 10, 1, FREQUENCY, false); + ASSERT_TRUE(results_op.ok()); + ASSERT_EQ(1, results_op.get()["hits"].size()); + + results_op = coll1->search("engineering", {"department"}, "", {}, sort_fields, 0, 10, 1, FREQUENCY, false); + ASSERT_TRUE(results_op.ok()); + ASSERT_EQ(1, results_op.get()["hits"].size()); + + collectionManager.drop_collection("coll1"); +} + TEST_F(CollectionAllFieldsTest, StringSingularAllValues) { Collection *coll1;