diff --git a/src/query/db_accessor.hpp b/src/query/db_accessor.hpp index b2e6fa826..d696e636b 100644 --- a/src/query/db_accessor.hpp +++ b/src/query/db_accessor.hpp @@ -636,7 +636,7 @@ class DbAccessor final { utils::BasicResult CreateTextIndex(std::string index_name, storage::LabelId label) { - return accessor_->CreateTextIndex(index_name, label); + return accessor_->CreateTextIndex(index_name, label, this); } utils::BasicResult DropTextIndex(std::string index_name) { diff --git a/src/storage/v2/indices/text_index.hpp b/src/storage/v2/indices/text_index.hpp index d96abc75c..6b51bbcf0 100644 --- a/src/storage/v2/indices/text_index.hpp +++ b/src/storage/v2/indices/text_index.hpp @@ -9,6 +9,7 @@ // by the Apache License, Version 2.0, included in the file // licenses/APL.txt. +#include "query/db_accessor.hpp" #include "storage/v2/mgcxx_mock.hpp" namespace memgraph::storage { @@ -28,6 +29,8 @@ class TextIndex { void UpdateOnRemoveLabel(LabelId removed_label, Vertex *vertex_after_update, const Transaction &tx) {} + void UpdateOnSetProperty(PropertyId property, const PropertyValue &value, Vertex *vertex, const Transaction &tx) {} + std::vector GetApplicableTextIndices(Vertex *vertex, Storage *storage) { std::vector applicable_text_indices; for (const auto &label : vertex->labels) { @@ -38,52 +41,54 @@ class TextIndex { return applicable_text_indices; } - /// @throw std::bad_alloc - bool CreateIndex(std::string index_name, LabelId label, - const std::optional ¶llel_exec_info) { - auto index_config = mgcxx_mock::text_search::IndexConfig{.mappings = "TODO antepusic"}; + bool CreateIndex(std::string index_name, LabelId label, memgraph::query::DbAccessor *db) { + auto index_config = mgcxx_mock::text_search::IndexConfig{ + .mappings = "TODO devise the mapping by reading the indexable nodes' properties"}; auto new_index = mgcxx_mock::text_search::Mock::create_index(index_name, index_config); index_[index_name] = new_index; + label_to_index_[label] = index_name; return true; - // TODO add documents to index + // TODO add documents (indexable nodes) to index } bool DropIndex(std::string index_name) { mgcxx_mock::text_search::Mock::drop_index(index_name); index_.erase(index_name); + std::erase_if(label_to_index_, [index_name](const auto &item) { return item.second == index_name; }); return true; } bool IndexExists(std::string index_name) { return index_.contains(index_name); } std::vector Search(std::string index_name, std::string search_query) { - auto input = mgcxx_mock::text_search::SearchInput{.search_query = search_query, .return_fields = {"metadata.gid"}}; - // Basic check for search fields in the query (Tantivy syntax delimits them with `:` to the right) - if (search_query.find(":") == std::string::npos) { - input.search_fields = {"data"}; + auto input = mgcxx_mock::text_search::SearchInput { + .search_query = search_query, .return_fields = {{"metadata.gid"}}; + // Basic check for search fields in the query (Tantivy syntax delimits them with a `:` to the right) + if (search_query.find(":") == std::string::npos) { + input.search_fields = {"data"}; + } + + std::vector found_nodes; + for (const auto &doc : mgcxx_mock::text_search::Mock::search(index_.at(index_name), input).docs) { + found_nodes.push_back(storage::Gid::FromString(doc.data)); + } + return found_nodes; } - std::vector found_nodes; - for (const auto &doc : mgcxx_mock::text_search::Mock::search(index_.at(index_name), input).docs) { - found_nodes.push_back(storage::Gid::FromString(doc.data)); + std::vector ListIndices() { + std::vector ret; + ret.reserve(index_.size()); + for (const auto &item : index_) { + ret.push_back(item.first); + } + return ret; } - return found_nodes; - } - std::vector ListIndices() { - std::vector ret; - ret.reserve(index_.size()); - for (const auto &item : index_) { - ret.push_back(item.first); - } - return ret; - } + uint64_t ApproximateVertexCount(std::string index_name) { return 10; } - uint64_t ApproximateVertexCount(std::string index_name) { return 10; } - - std::map index_; - std::map label_to_index_; -}; + std::map index_; + std::map label_to_index_; + }; } // namespace memgraph::storage diff --git a/src/storage/v2/storage.hpp b/src/storage/v2/storage.hpp index 3aa957aaf..2c44b717c 100644 --- a/src/storage/v2/storage.hpp +++ b/src/storage/v2/storage.hpp @@ -268,10 +268,9 @@ class Storage { virtual utils::BasicResult DropIndex(LabelId label, PropertyId property) = 0; - virtual utils::BasicResult CreateTextIndex(std::string index_name, - LabelId label) { - // TODO: pass vertices to CreateIndex - storage_->indices_.text_index_->CreateIndex(index_name, label, std::nullopt); + virtual utils::BasicResult CreateTextIndex(std::string index_name, LabelId label, + DbAccessor *db) { + storage_->indices_.text_index_->CreateIndex(index_name, label, db); return {}; } diff --git a/src/storage/v2/vertex_accessor.cpp b/src/storage/v2/vertex_accessor.cpp index 0578700ae..009624f93 100644 --- a/src/storage/v2/vertex_accessor.cpp +++ b/src/storage/v2/vertex_accessor.cpp @@ -15,6 +15,8 @@ #include #include +#include + #include "flags/run_time_configurable.hpp" #include "query/exceptions.hpp" #include "storage/v2/disk/storage.hpp" @@ -276,12 +278,13 @@ Result VertexAccessor::SetProperty(PropertyId property, const Pro CreateAndLinkDelta(transaction, vertex, Delta::SetPropertyTag(), property, current_value); if (flags::run_time::GetTextSearchEnabled()) { for (const auto *index_context : storage->indices_.text_index_->GetApplicableTextIndices(vertex, storage)) { - auto search_input = mgcxx_mock::text_search::SearchInput{}; + auto search_input = mgcxx_mock::text_search::SearchInput{ + .search_query = fmt::format("metadata.gid:{}", vertex->gid.AsInt()), .return_fields = {"data"}}; auto search_result = mgcxx_mock::text_search::Mock::search(*index_context, search_input); mgcxx_mock::text_search::Mock::delete_document(*index_context, search_input, true); - // parse result to JSON, set property in JSON and convert to string - auto new_properties = search_result.docs[0].data; + auto new_properties = search_result.docs[0].data; // TODO (pending real Tantivy results): parse result to + // JSON, set property and convert back to string auto new_properties_document = mgcxx_mock::text_search::DocumentInput{.data = new_properties}; mgcxx_mock::text_search::Mock::add(*index_context, new_properties_document, true); } @@ -321,7 +324,9 @@ Result VertexAccessor::InitProperties(const std::mapindices_.text_index_->GetApplicableTextIndices(vertex, storage)) { - auto new_properties_document = mgcxx_mock::text_search::DocumentInput{}; // empty properties + auto new_properties_document = + mgcxx_mock::text_search::DocumentInput{}; // TODO (pending real Tantivy operation): create a JSON, set + // properties and convert to string mgcxx_mock::text_search::Mock::add(*index_context, new_properties_document, true); } } @@ -362,12 +367,13 @@ Result>> Vertex id_old_new_change.emplace(vertex->properties.UpdateProperties(properties)); if (flags::run_time::GetTextSearchEnabled()) { for (const auto *index_context : storage->indices_.text_index_->GetApplicableTextIndices(vertex, storage)) { - auto search_input = mgcxx_mock::text_search::SearchInput{}; + auto search_input = mgcxx_mock::text_search::SearchInput{ + .search_query = fmt::format("metadata.gid:{}", vertex->gid.AsInt()), .return_fields = {"data"}}; auto search_result = mgcxx_mock::text_search::Mock::search(*index_context, search_input); mgcxx_mock::text_search::Mock::delete_document(*index_context, search_input, true); - // parse result to JSON, set property in JSON and convert to string - auto new_properties = search_result.docs[0].data; + auto new_properties = search_result.docs[0].data; // TODO (pending real Tantivy results): parse result to + // JSON, set property and convert back to string auto new_properties_document = mgcxx_mock::text_search::DocumentInput{.data = new_properties}; mgcxx_mock::text_search::Mock::add(*index_context, new_properties_document, true); } @@ -404,27 +410,28 @@ Result> VertexAccessor::ClearProperties() { using ReturnType = decltype(vertex_->properties.Properties()); std::optional properties; - utils::AtomicMemoryBlock atomic_memory_block{ - [storage = storage_, transaction = transaction_, vertex = vertex_, &properties]() { - properties.emplace(vertex->properties.Properties()); - if (!properties.has_value()) { - return; - } - for (const auto &[property, value] : *properties) { - CreateAndLinkDelta(transaction, vertex, Delta::SetPropertyTag(), property, value); - storage->indices_.UpdateOnSetProperty(property, PropertyValue(), vertex, *transaction); - transaction->constraint_verification_info.RemovedProperty(vertex); - transaction->manyDeltasCache.Invalidate(vertex, property); - } + utils::AtomicMemoryBlock atomic_memory_block{[storage = storage_, transaction = transaction_, vertex = vertex_, + &properties]() { + properties.emplace(vertex->properties.Properties()); + if (!properties.has_value()) { + return; + } + for (const auto &[property, value] : *properties) { + CreateAndLinkDelta(transaction, vertex, Delta::SetPropertyTag(), property, value); + storage->indices_.UpdateOnSetProperty(property, PropertyValue(), vertex, *transaction); + transaction->constraint_verification_info.RemovedProperty(vertex); + transaction->manyDeltasCache.Invalidate(vertex, property); + } - vertex->properties.ClearProperties(); - if (flags::run_time::GetTextSearchEnabled()) { - for (const auto *index_context : storage->indices_.text_index_->GetApplicableTextIndices(vertex, storage)) { - auto search_input = mgcxx_mock::text_search::SearchInput{}; - mgcxx_mock::text_search::Mock::delete_document(*index_context, search_input, true); - } - } - }}; + vertex->properties.ClearProperties(); + if (flags::run_time::GetTextSearchEnabled()) { + for (const auto *index_context : storage->indices_.text_index_->GetApplicableTextIndices(vertex, storage)) { + auto search_input = + mgcxx_mock::text_search::SearchInput{.search_query = fmt::format("metadata.gid:{}", vertex->gid.AsInt())}; + mgcxx_mock::text_search::Mock::delete_document(*index_context, search_input, true); + } + } + }}; std::invoke(atomic_memory_block); return properties.has_value() ? std::move(properties.value()) : ReturnType{};