diff --git a/include/collection.h b/include/collection.h index bc949e61..d8b6309e 100644 --- a/include/collection.h +++ b/include/collection.h @@ -396,6 +396,8 @@ public: std::vector get_fields(); + bool contains_field(const std::string&); + std::unordered_map get_dynamic_fields(); tsl::htrie_map get_schema(); diff --git a/src/analytics_manager.cpp b/src/analytics_manager.cpp index 5f5d8c4c..b9e7e0b6 100644 --- a/src/analytics_manager.cpp +++ b/src/analytics_manager.cpp @@ -113,9 +113,13 @@ Option AnalyticsManager::create_queries_index(nlohmann::json &payload, boo return Option(400, "There's already another configuration for this destination collection."); } - auto coll_schema = CollectionManager::get_instance().get_collection(suggestion_collection)->get_schema(); - if(coll_schema.find(counter_field) == coll_schema.end()) { - return Option(404, "counter_field not found in destination collection."); + auto coll = CollectionManager::get_instance().get_collection(suggestion_collection).get(); + if(coll != nullptr) { + if (!coll->contains_field(counter_field)) { + return Option(404, "counter_field `" + counter_field + "` not found in destination collection."); + } + } else { + return Option(404, "Collection `" + suggestion_collection + "` not found."); } } diff --git a/src/collection.cpp b/src/collection.cpp index 45b0b0c4..063d22b9 100644 --- a/src/collection.cpp +++ b/src/collection.cpp @@ -4336,6 +4336,11 @@ std::vector Collection::get_fields() { return fields; } +bool Collection::contains_field(const std::string &field) { + std::shared_lock lock(mutex); + return search_schema.find(field) != search_schema.end(); +} + std::unordered_map Collection::get_dynamic_fields() { std::shared_lock lock(mutex); return dynamic_fields; diff --git a/test/analytics_manager_test.cpp b/test/analytics_manager_test.cpp index 97aa0edb..750cbbf8 100644 --- a/test/analytics_manager_test.cpp +++ b/test/analytics_manager_test.cpp @@ -893,4 +893,52 @@ TEST_F(AnalyticsManagerTest, PopularityScore) { ASSERT_EQ("1", results["hits"][1]["document"]["id"]); ASSERT_EQ(1, results["hits"][1]["document"]["popularity"]); ASSERT_EQ("Funky trousers", results["hits"][1]["document"]["title"]); +} + +TEST_F(AnalyticsManagerTest, PopularityScoreValidation) { + nlohmann::json products_schema = R"({ + "name": "books", + "fields": [ + {"name": "title", "type": "string"}, + {"name": "popularity", "type": "int32"} + ] + })"_json; + + Collection* products_coll = collectionManager.create_collection(products_schema).get(); + + nlohmann::json analytics_rule = R"({ + "name": "books_popularity", + "type": "popular_clicks", + "params": { + "source": { + "collections": ["books"] + }, + "destination": { + "collection": "popular_books", + "counter_field": "popularity" + } + } + })"_json; + + auto create_op = analyticsManager.create_rule(analytics_rule, false, true); + ASSERT_FALSE(create_op.ok()); + ASSERT_EQ("Collection `popular_books` not found.", create_op.error()); + + analytics_rule = R"({ + "name": "books_popularity", + "type": "popular_clicks", + "params": { + "source": { + "collections": ["books"] + }, + "destination": { + "collection": "books", + "counter_field": "popularity_score" + } + } + })"_json; + + create_op = analyticsManager.create_rule(analytics_rule, false, true); + ASSERT_FALSE(create_op.ok()); + ASSERT_EQ("counter_field `popularity_score` not found in destination collection.", create_op.error()); } \ No newline at end of file