Extend text index operations

This commit is contained in:
Ante Pušić 2024-01-10 01:23:28 +01:00
parent 00275f5736
commit ba581f58ef
4 changed files with 70 additions and 59 deletions

View File

@ -636,7 +636,7 @@ class DbAccessor final {
utils::BasicResult<storage::StorageIndexDefinitionError, void> CreateTextIndex(std::string index_name, utils::BasicResult<storage::StorageIndexDefinitionError, void> CreateTextIndex(std::string index_name,
storage::LabelId label) { storage::LabelId label) {
return accessor_->CreateTextIndex(index_name, label); return accessor_->CreateTextIndex(index_name, label, this);
} }
utils::BasicResult<storage::StorageIndexDefinitionError, void> DropTextIndex(std::string index_name) { utils::BasicResult<storage::StorageIndexDefinitionError, void> DropTextIndex(std::string index_name) {

View File

@ -9,6 +9,7 @@
// by the Apache License, Version 2.0, included in the file // by the Apache License, Version 2.0, included in the file
// licenses/APL.txt. // licenses/APL.txt.
#include "query/db_accessor.hpp"
#include "storage/v2/mgcxx_mock.hpp" #include "storage/v2/mgcxx_mock.hpp"
namespace memgraph::storage { namespace memgraph::storage {
@ -28,6 +29,8 @@ class TextIndex {
void UpdateOnRemoveLabel(LabelId removed_label, Vertex *vertex_after_update, const Transaction &tx) {} 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<mgcxx_mock::text_search::IndexContext *> GetApplicableTextIndices(Vertex *vertex, Storage *storage) { std::vector<mgcxx_mock::text_search::IndexContext *> GetApplicableTextIndices(Vertex *vertex, Storage *storage) {
std::vector<mgcxx_mock::text_search::IndexContext *> applicable_text_indices; std::vector<mgcxx_mock::text_search::IndexContext *> applicable_text_indices;
for (const auto &label : vertex->labels) { for (const auto &label : vertex->labels) {
@ -38,28 +41,30 @@ class TextIndex {
return applicable_text_indices; return applicable_text_indices;
} }
/// @throw std::bad_alloc bool CreateIndex(std::string index_name, LabelId label, memgraph::query::DbAccessor *db) {
bool CreateIndex(std::string index_name, LabelId label, auto index_config = mgcxx_mock::text_search::IndexConfig{
const std::optional<durability::ParallelizedSchemaCreationInfo> &parallel_exec_info) { .mappings = "TODO devise the mapping by reading the indexable nodes' properties"};
auto index_config = mgcxx_mock::text_search::IndexConfig{.mappings = "TODO antepusic"};
auto new_index = mgcxx_mock::text_search::Mock::create_index(index_name, index_config); auto new_index = mgcxx_mock::text_search::Mock::create_index(index_name, index_config);
index_[index_name] = new_index; index_[index_name] = new_index;
label_to_index_[label] = index_name;
return true; return true;
// TODO add documents to index // TODO add documents (indexable nodes) to index
} }
bool DropIndex(std::string index_name) { bool DropIndex(std::string index_name) {
mgcxx_mock::text_search::Mock::drop_index(index_name); mgcxx_mock::text_search::Mock::drop_index(index_name);
index_.erase(index_name); index_.erase(index_name);
std::erase_if(label_to_index_, [index_name](const auto &item) { return item.second == index_name; });
return true; return true;
} }
bool IndexExists(std::string index_name) { return index_.contains(index_name); } bool IndexExists(std::string index_name) { return index_.contains(index_name); }
std::vector<Gid> Search(std::string index_name, std::string search_query) { std::vector<Gid> Search(std::string index_name, std::string search_query) {
auto input = mgcxx_mock::text_search::SearchInput{.search_query = search_query, .return_fields = {"metadata.gid"}}; auto input = mgcxx_mock::text_search::SearchInput {
// Basic check for search fields in the query (Tantivy syntax delimits them with `:` to the right) .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) { if (search_query.find(":") == std::string::npos) {
input.search_fields = {"data"}; input.search_fields = {"data"};
} }
@ -84,6 +89,6 @@ class TextIndex {
std::map<std::string, mgcxx_mock::text_search::IndexContext> index_; std::map<std::string, mgcxx_mock::text_search::IndexContext> index_;
std::map<LabelId, std::string> label_to_index_; std::map<LabelId, std::string> label_to_index_;
}; };
} // namespace memgraph::storage } // namespace memgraph::storage

View File

@ -268,10 +268,9 @@ class Storage {
virtual utils::BasicResult<StorageIndexDefinitionError, void> DropIndex(LabelId label, PropertyId property) = 0; virtual utils::BasicResult<StorageIndexDefinitionError, void> DropIndex(LabelId label, PropertyId property) = 0;
virtual utils::BasicResult<StorageIndexDefinitionError, void> CreateTextIndex(std::string index_name, virtual utils::BasicResult<StorageIndexDefinitionError, void> CreateTextIndex(std::string index_name, LabelId label,
LabelId label) { DbAccessor *db) {
// TODO: pass vertices to CreateIndex storage_->indices_.text_index_->CreateIndex(index_name, label, db);
storage_->indices_.text_index_->CreateIndex(index_name, label, std::nullopt);
return {}; return {};
} }

View File

@ -15,6 +15,8 @@
#include <tuple> #include <tuple>
#include <utility> #include <utility>
#include <fmt/format.h>
#include "flags/run_time_configurable.hpp" #include "flags/run_time_configurable.hpp"
#include "query/exceptions.hpp" #include "query/exceptions.hpp"
#include "storage/v2/disk/storage.hpp" #include "storage/v2/disk/storage.hpp"
@ -276,12 +278,13 @@ Result<PropertyValue> VertexAccessor::SetProperty(PropertyId property, const Pro
CreateAndLinkDelta(transaction, vertex, Delta::SetPropertyTag(), property, current_value); CreateAndLinkDelta(transaction, vertex, Delta::SetPropertyTag(), property, current_value);
if (flags::run_time::GetTextSearchEnabled()) { if (flags::run_time::GetTextSearchEnabled()) {
for (const auto *index_context : storage->indices_.text_index_->GetApplicableTextIndices(vertex, storage)) { 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); 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); 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; // TODO (pending real Tantivy results): parse result to
auto new_properties = search_result.docs[0].data; // JSON, set property and convert back to string
auto new_properties_document = mgcxx_mock::text_search::DocumentInput{.data = new_properties}; auto new_properties_document = mgcxx_mock::text_search::DocumentInput{.data = new_properties};
mgcxx_mock::text_search::Mock::add(*index_context, new_properties_document, true); mgcxx_mock::text_search::Mock::add(*index_context, new_properties_document, true);
} }
@ -321,7 +324,9 @@ Result<bool> VertexAccessor::InitProperties(const std::map<storage::PropertyId,
} }
if (flags::run_time::GetTextSearchEnabled()) { if (flags::run_time::GetTextSearchEnabled()) {
for (const auto *index_context : storage->indices_.text_index_->GetApplicableTextIndices(vertex, storage)) { for (const auto *index_context : storage->indices_.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); mgcxx_mock::text_search::Mock::add(*index_context, new_properties_document, true);
} }
} }
@ -362,12 +367,13 @@ Result<std::vector<std::tuple<PropertyId, PropertyValue, PropertyValue>>> Vertex
id_old_new_change.emplace(vertex->properties.UpdateProperties(properties)); id_old_new_change.emplace(vertex->properties.UpdateProperties(properties));
if (flags::run_time::GetTextSearchEnabled()) { if (flags::run_time::GetTextSearchEnabled()) {
for (const auto *index_context : storage->indices_.text_index_->GetApplicableTextIndices(vertex, storage)) { 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); 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); 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; // TODO (pending real Tantivy results): parse result to
auto new_properties = search_result.docs[0].data; // JSON, set property and convert back to string
auto new_properties_document = mgcxx_mock::text_search::DocumentInput{.data = new_properties}; auto new_properties_document = mgcxx_mock::text_search::DocumentInput{.data = new_properties};
mgcxx_mock::text_search::Mock::add(*index_context, new_properties_document, true); mgcxx_mock::text_search::Mock::add(*index_context, new_properties_document, true);
} }
@ -404,8 +410,8 @@ Result<std::map<PropertyId, PropertyValue>> VertexAccessor::ClearProperties() {
using ReturnType = decltype(vertex_->properties.Properties()); using ReturnType = decltype(vertex_->properties.Properties());
std::optional<ReturnType> properties; std::optional<ReturnType> properties;
utils::AtomicMemoryBlock atomic_memory_block{ utils::AtomicMemoryBlock atomic_memory_block{[storage = storage_, transaction = transaction_, vertex = vertex_,
[storage = storage_, transaction = transaction_, vertex = vertex_, &properties]() { &properties]() {
properties.emplace(vertex->properties.Properties()); properties.emplace(vertex->properties.Properties());
if (!properties.has_value()) { if (!properties.has_value()) {
return; return;
@ -420,7 +426,8 @@ Result<std::map<PropertyId, PropertyValue>> VertexAccessor::ClearProperties() {
vertex->properties.ClearProperties(); vertex->properties.ClearProperties();
if (flags::run_time::GetTextSearchEnabled()) { if (flags::run_time::GetTextSearchEnabled()) {
for (const auto *index_context : storage->indices_.text_index_->GetApplicableTextIndices(vertex, storage)) { 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())};
mgcxx_mock::text_search::Mock::delete_document(*index_context, search_input, true); mgcxx_mock::text_search::Mock::delete_document(*index_context, search_input, true);
} }
} }