Add error handling
This commit is contained in:
parent
5cea4d0c40
commit
9e0b857e25
@ -330,9 +330,9 @@ inline bool graph_has_text_index(mgp_graph *graph, const char *index_name) {
|
|||||||
return MgInvoke<int>(mgp_graph_has_text_index, graph, index_name);
|
return MgInvoke<int>(mgp_graph_has_text_index, graph, index_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline mgp_list *graph_search_text_index(mgp_graph *graph, mgp_memory *memory, const char *index_name,
|
inline mgp_map *graph_search_text_index(mgp_graph *graph, const char *index_name, const char *search_query,
|
||||||
const char *search_query) {
|
mgp_memory *memory) {
|
||||||
return MgInvoke<mgp_list *>(mgp_graph_search_text_index, graph, memory, index_name, search_query);
|
return MgInvoke<mgp_map *>(mgp_graph_search_text_index, graph, index_name, search_query, memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline mgp_vertices_iterator *graph_iter_vertices(mgp_graph *g, mgp_memory *memory) {
|
inline mgp_vertices_iterator *graph_iter_vertices(mgp_graph *g, mgp_memory *memory) {
|
||||||
|
@ -898,8 +898,8 @@ enum mgp_error mgp_graph_has_text_index(struct mgp_graph *graph, const char *ind
|
|||||||
/// Search the named text index for the given query. The result is a list of the vertices whose text properties match
|
/// Search the named text index for the given query. The result is a list of the vertices whose text properties match
|
||||||
/// the given query.
|
/// the given query.
|
||||||
/// Return mgp_error::MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate search result vertices.
|
/// Return mgp_error::MGP_ERROR_UNABLE_TO_ALLOCATE if unable to allocate search result vertices.
|
||||||
enum mgp_error mgp_graph_search_text_index(struct mgp_graph *graph, struct mgp_memory *memory, const char *index_name,
|
enum mgp_error mgp_graph_search_text_index(struct mgp_graph *graph, const char *index_name, const char *search_query,
|
||||||
const char *search_query, struct mgp_list **result);
|
struct mgp_memory *memory, struct mgp_map **result);
|
||||||
|
|
||||||
/// Creates label index for given label.
|
/// Creates label index for given label.
|
||||||
/// mgp_error::MGP_ERROR_NO_ERROR is always returned.
|
/// mgp_error::MGP_ERROR_NO_ERROR is always returned.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2023 Memgraph Ltd.
|
// Copyright 2024 Memgraph Ltd.
|
||||||
//
|
//
|
||||||
// Use of this software is governed by the Business Source License
|
// Use of this software is governed by the Business Source License
|
||||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||||
@ -4340,6 +4340,17 @@ inline List ListAllLabelPropertyIndices(mgp_graph *memgraph_graph) {
|
|||||||
return List(label_property_indices);
|
return List(label_property_indices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline List SearchTextIndex(mgp_graph *memgraph_graph, std::string_view index_name, std::string_view search_query) {
|
||||||
|
auto results_or_error =
|
||||||
|
Map(mgp::MemHandlerCallback(graph_search_text_index, memgraph_graph, index_name.data(), search_query.data()));
|
||||||
|
auto maybe_error = results_or_error["error_msg"].ValueString();
|
||||||
|
if (!maybe_error.empty()) {
|
||||||
|
throw std::runtime_error{maybe_error.data()};
|
||||||
|
}
|
||||||
|
|
||||||
|
return results_or_error["search_results"].ValueList();
|
||||||
|
}
|
||||||
|
|
||||||
inline bool CreateExistenceConstraint(mgp_graph *memgraph_graph, const std::string_view label,
|
inline bool CreateExistenceConstraint(mgp_graph *memgraph_graph, const std::string_view label,
|
||||||
const std::string_view property) {
|
const std::string_view property) {
|
||||||
return create_existence_constraint(memgraph_graph, label.data(), property.data());
|
return create_existence_constraint(memgraph_graph, label.data(), property.data());
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
namespace TextSearch {
|
namespace TextSearch {
|
||||||
constexpr std::string_view kProcedureSearch = "search";
|
constexpr std::string_view kProcedureSearch = "search";
|
||||||
constexpr std::string_view kParameterLabel = "label";
|
constexpr std::string_view kParameterIndexName = "index_name";
|
||||||
constexpr std::string_view kParameterSearchString = "search_query";
|
constexpr std::string_view kParameterSearchString = "search_query";
|
||||||
constexpr std::string_view kReturnNode = "node";
|
constexpr std::string_view kReturnNode = "node";
|
||||||
|
|
||||||
@ -31,22 +31,19 @@ void TextSearch::Search(mgp_list *args, mgp_graph *memgraph_graph, mgp_result *r
|
|||||||
auto arguments = mgp::List(args);
|
auto arguments = mgp::List(args);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto label = arguments[0].ValueString().data();
|
auto index_name = arguments[0].ValueString().data();
|
||||||
auto search_query = arguments[1].ValueString().data();
|
auto search_query = arguments[1].ValueString().data();
|
||||||
|
|
||||||
// 1. See if the given label is text-indexed
|
// 1. See if the given index_name is text-indexed
|
||||||
if (!mgp::graph_has_text_index(memgraph_graph, label)) {
|
if (!mgp::graph_has_text_index(memgraph_graph, index_name)) {
|
||||||
record_factory.SetErrorMessage(fmt::format("Text index \"{}\" doesn’t exist.", label));
|
record_factory.SetErrorMessage(fmt::format("Text index \"{}\" doesn’t exist.", index_name));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Run a text search of that index and return the search results
|
// 2. Run a text search of that index and return the search results
|
||||||
const auto results = mgp::graph_search_text_index(memgraph_graph, memory, label, search_query);
|
for (const auto &node : mgp::SearchTextIndex(memgraph_graph, index_name, search_query)) {
|
||||||
if (!results) return;
|
|
||||||
|
|
||||||
for (const auto &node : mgp::List(results)) {
|
|
||||||
auto record = record_factory.NewRecord();
|
auto record = record_factory.NewRecord();
|
||||||
record.Insert(TextSearch::kReturnNode.data(), node);
|
record.Insert(TextSearch::kReturnNode.data(), node.ValueNode());
|
||||||
}
|
}
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
record_factory.SetErrorMessage(e.what());
|
record_factory.SetErrorMessage(e.what());
|
||||||
@ -59,7 +56,7 @@ extern "C" int mgp_init_module(struct mgp_module *module, struct mgp_memory *mem
|
|||||||
|
|
||||||
AddProcedure(TextSearch::Search, TextSearch::kProcedureSearch, mgp::ProcedureType::Read,
|
AddProcedure(TextSearch::Search, TextSearch::kProcedureSearch, mgp::ProcedureType::Read,
|
||||||
{
|
{
|
||||||
mgp::Parameter(TextSearch::kParameterLabel, mgp::Type::String),
|
mgp::Parameter(TextSearch::kParameterIndexName, mgp::Type::String),
|
||||||
mgp::Parameter(TextSearch::kParameterSearchString, mgp::Type::String),
|
mgp::Parameter(TextSearch::kParameterSearchString, mgp::Type::String),
|
||||||
},
|
},
|
||||||
{mgp::Return(TextSearch::kReturnNode, mgp::Type::Node)}, module, memory);
|
{mgp::Return(TextSearch::kReturnNode, mgp::Type::Node)}, module, memory);
|
||||||
|
@ -3368,10 +3368,16 @@ mgp_vertex *GetVertexByGid(mgp_graph *graph, memgraph::storage::Gid id, mgp_memo
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WrapIntoVertexList(std::vector<memgraph::storage::Gid> vertex_ids, mgp_graph *graph, mgp_memory *memory,
|
void WrapTextSearch(std::vector<memgraph::storage::Gid> vertex_ids, std::string error_msg, mgp_graph *graph,
|
||||||
mgp_list **result) {
|
mgp_memory *memory, mgp_map **result) {
|
||||||
if (const auto err = mgp_list_make_empty(vertex_ids.size(), memory, result); err != mgp_error::MGP_ERROR_NO_ERROR) {
|
if (const auto err = mgp_map_make_empty(memory, result); err != mgp_error::MGP_ERROR_NO_ERROR) {
|
||||||
throw std::logic_error("Retrieving text search results failed during creation of a mgp_vertex");
|
throw std::logic_error("Retrieving text search results failed during creation of a mgp_map");
|
||||||
|
}
|
||||||
|
|
||||||
|
mgp_list *search_results{};
|
||||||
|
if (const auto err = mgp_list_make_empty(vertex_ids.size(), memory, &search_results);
|
||||||
|
err != mgp_error::MGP_ERROR_NO_ERROR) {
|
||||||
|
throw std::logic_error("Retrieving text search results failed during creation of a mgp_list");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &vertex_id : vertex_ids) {
|
for (const auto &vertex_id : vertex_ids) {
|
||||||
@ -3380,30 +3386,56 @@ void WrapIntoVertexList(std::vector<memgraph::storage::Gid> vertex_ids, mgp_grap
|
|||||||
err != mgp_error::MGP_ERROR_NO_ERROR) {
|
err != mgp_error::MGP_ERROR_NO_ERROR) {
|
||||||
throw std::logic_error("Retrieving text search results failed during creation of a vertex mgp_value");
|
throw std::logic_error("Retrieving text search results failed during creation of a vertex mgp_value");
|
||||||
}
|
}
|
||||||
if (const auto err_list = mgp_list_append(*result, vertex); err_list != mgp_error::MGP_ERROR_NO_ERROR) {
|
if (const auto err = mgp_list_append(search_results, vertex); err != mgp_error::MGP_ERROR_NO_ERROR) {
|
||||||
throw std::logic_error(
|
throw std::logic_error(
|
||||||
"Retrieving text search results failed during insertion of the mgp_value into the result list");
|
"Retrieving text search results failed during insertion of the mgp_value into the result list");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mgp_value *search_results_value;
|
||||||
|
if (const auto err = mgp_value_make_list(search_results, &search_results_value);
|
||||||
|
err != mgp_error::MGP_ERROR_NO_ERROR) {
|
||||||
|
throw std::logic_error("Retrieving text search results failed during creation of a map mgp_value");
|
||||||
|
}
|
||||||
|
mgp_value *error_msg_value;
|
||||||
|
if (const auto err = mgp_value_make_string(error_msg.data(), memory, &error_msg_value);
|
||||||
|
err != mgp_error::MGP_ERROR_NO_ERROR) {
|
||||||
|
throw std::logic_error("Retrieving text search results failed during creation of a map mgp_value");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const auto err = mgp_map_insert(*result, "search_results", search_results_value);
|
||||||
|
err != mgp_error::MGP_ERROR_NO_ERROR) {
|
||||||
|
throw std::logic_error("Retrieving text search results failed during insertion into mgp_map");
|
||||||
|
}
|
||||||
|
if (const auto err = mgp_map_insert(*result, "error_msg", error_msg_value); err != mgp_error::MGP_ERROR_NO_ERROR) {
|
||||||
|
throw std::logic_error("Retrieving text search results failed during insertion into mgp_map");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mgp_error mgp_graph_search_text_index(mgp_graph *graph, mgp_memory *memory, const char *index_name,
|
mgp_error mgp_graph_search_text_index(mgp_graph *graph, const char *index_name, const char *search_query,
|
||||||
const char *search_query, mgp_list **result) {
|
mgp_memory *memory, mgp_map **result) {
|
||||||
return WrapExceptions([graph, memory, index_name, search_query, result]() {
|
return WrapExceptions([graph, memory, index_name, search_query, result]() {
|
||||||
std::visit(memgraph::utils::Overloaded{
|
std::visit(memgraph::utils::Overloaded{[&](memgraph::query::DbAccessor *impl) {
|
||||||
[&](memgraph::query::DbAccessor *impl) {
|
std::vector<memgraph::storage::Gid> search_results;
|
||||||
if (!memgraph::flags::run_time::GetTextSearchEnabled()) {
|
std::string error_msg;
|
||||||
// TODO antepusic throw exception
|
try {
|
||||||
}
|
search_results = impl->TextIndexSearch(index_name, search_query);
|
||||||
WrapIntoVertexList(impl->SearchTextIndex(index_name, search_query), graph, memory, result);
|
} catch (memgraph::query::QueryException &e) {
|
||||||
},
|
error_msg = e.what();
|
||||||
[&](memgraph::query::SubgraphDbAccessor *impl) {
|
}
|
||||||
if (!memgraph::flags::run_time::GetTextSearchEnabled()) {
|
WrapTextSearch(search_results, error_msg, graph, memory, result);
|
||||||
// TODO antepusic throw exception
|
},
|
||||||
}
|
[&](memgraph::query::SubgraphDbAccessor *impl) {
|
||||||
WrapIntoVertexList(impl->GetAccessor()->SearchTextIndex(index_name, search_query), graph, memory,
|
std::vector<memgraph::storage::Gid> search_results;
|
||||||
result);
|
std::string error_msg;
|
||||||
}},
|
try {
|
||||||
|
search_results =
|
||||||
|
impl->GetAccessor()->TextIndexSearch(index_name, search_query);
|
||||||
|
} catch (memgraph::query::QueryException &e) {
|
||||||
|
error_msg = e.what();
|
||||||
|
}
|
||||||
|
WrapTextSearch(search_results, error_msg, graph, memory, result);
|
||||||
|
}},
|
||||||
graph->impl);
|
graph->impl);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ namespace memgraph::storage {
|
|||||||
void TextIndex::AddNode(Vertex *vertex_after_update, Storage *storage, const std::uint64_t transaction_start_timestamp,
|
void TextIndex::AddNode(Vertex *vertex_after_update, Storage *storage, const std::uint64_t transaction_start_timestamp,
|
||||||
const std::vector<mgcxx::text_search::Context *> &applicable_text_indices, bool skip_commit) {
|
const std::vector<mgcxx::text_search::Context *> &applicable_text_indices, bool skip_commit) {
|
||||||
if (!flags::run_time::GetTextSearchEnabled()) {
|
if (!flags::run_time::GetTextSearchEnabled()) {
|
||||||
// TODO antepusic throw exception
|
throw query::QueryException("To use text indices, enable the text search feature.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Text indexes are presently all-property indices. If we allow text indexes restricted to specific properties,
|
// NOTE: Text indexes are presently all-property indices. If we allow text indexes restricted to specific properties,
|
||||||
@ -73,7 +73,7 @@ void TextIndex::AddNode(Vertex *vertex_after_update, Storage *storage, const std
|
|||||||
void TextIndex::AddNode(Vertex *vertex_after_update, Storage *storage, const std::uint64_t transaction_start_timestamp,
|
void TextIndex::AddNode(Vertex *vertex_after_update, Storage *storage, const std::uint64_t transaction_start_timestamp,
|
||||||
bool skip_commit) {
|
bool skip_commit) {
|
||||||
if (!flags::run_time::GetTextSearchEnabled()) {
|
if (!flags::run_time::GetTextSearchEnabled()) {
|
||||||
// TODO antepusic throw exception
|
throw query::QueryException("To use text indices, enable the text search feature.");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto applicable_text_indices = GetApplicableTextIndices(vertex_after_update);
|
auto applicable_text_indices = GetApplicableTextIndices(vertex_after_update);
|
||||||
@ -84,7 +84,7 @@ void TextIndex::AddNode(Vertex *vertex_after_update, Storage *storage, const std
|
|||||||
void TextIndex::UpdateNode(Vertex *vertex_after_update, Storage *storage,
|
void TextIndex::UpdateNode(Vertex *vertex_after_update, Storage *storage,
|
||||||
const std::uint64_t transaction_start_timestamp) {
|
const std::uint64_t transaction_start_timestamp) {
|
||||||
if (!flags::run_time::GetTextSearchEnabled()) {
|
if (!flags::run_time::GetTextSearchEnabled()) {
|
||||||
// TODO antepusic throw exception
|
throw query::QueryException("To use text indices, enable the text search feature.");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto applicable_text_indices = GetApplicableTextIndices(vertex_after_update);
|
auto applicable_text_indices = GetApplicableTextIndices(vertex_after_update);
|
||||||
@ -97,7 +97,7 @@ void TextIndex::UpdateNode(Vertex *vertex_after_update, Storage *storage,
|
|||||||
const std::uint64_t transaction_start_timestamp,
|
const std::uint64_t transaction_start_timestamp,
|
||||||
const std::vector<LabelId> &removed_labels) {
|
const std::vector<LabelId> &removed_labels) {
|
||||||
if (!flags::run_time::GetTextSearchEnabled()) {
|
if (!flags::run_time::GetTextSearchEnabled()) {
|
||||||
// TODO antepusic throw exception
|
throw query::QueryException("To use text indices, enable the text search feature.");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto indexes_to_remove_node_from = GetApplicableTextIndices(removed_labels);
|
auto indexes_to_remove_node_from = GetApplicableTextIndices(removed_labels);
|
||||||
@ -112,7 +112,7 @@ void TextIndex::UpdateNode(Vertex *vertex_after_update, Storage *storage,
|
|||||||
void TextIndex::RemoveNode(Vertex *vertex_after_update,
|
void TextIndex::RemoveNode(Vertex *vertex_after_update,
|
||||||
const std::vector<mgcxx::text_search::Context *> &applicable_text_indices) {
|
const std::vector<mgcxx::text_search::Context *> &applicable_text_indices) {
|
||||||
if (!flags::run_time::GetTextSearchEnabled()) {
|
if (!flags::run_time::GetTextSearchEnabled()) {
|
||||||
// TODO antepusic throw exception
|
throw query::QueryException("To use text indices, enable the text search feature.");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto search_node_to_be_deleted =
|
auto search_node_to_be_deleted =
|
||||||
@ -129,7 +129,7 @@ void TextIndex::RemoveNode(Vertex *vertex_after_update,
|
|||||||
|
|
||||||
void TextIndex::RemoveNode(Vertex *vertex_after_update) {
|
void TextIndex::RemoveNode(Vertex *vertex_after_update) {
|
||||||
if (!flags::run_time::GetTextSearchEnabled()) {
|
if (!flags::run_time::GetTextSearchEnabled()) {
|
||||||
// TODO antepusic throw exception
|
throw query::QueryException("To use text indices, enable the text search feature.");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto applicable_text_indices = GetApplicableTextIndices(vertex_after_update);
|
auto applicable_text_indices = GetApplicableTextIndices(vertex_after_update);
|
||||||
@ -140,7 +140,7 @@ void TextIndex::RemoveNode(Vertex *vertex_after_update) {
|
|||||||
void TextIndex::UpdateOnAddLabel(LabelId added_label, Vertex *vertex_after_update, Storage *storage,
|
void TextIndex::UpdateOnAddLabel(LabelId added_label, Vertex *vertex_after_update, Storage *storage,
|
||||||
const std::uint64_t transaction_start_timestamp) {
|
const std::uint64_t transaction_start_timestamp) {
|
||||||
if (!flags::run_time::GetTextSearchEnabled()) {
|
if (!flags::run_time::GetTextSearchEnabled()) {
|
||||||
// TODO antepusic throw exception
|
throw query::QueryException("To use text indices, enable the text search feature.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!label_to_index_.contains(added_label)) {
|
if (!label_to_index_.contains(added_label)) {
|
||||||
@ -153,7 +153,7 @@ void TextIndex::UpdateOnAddLabel(LabelId added_label, Vertex *vertex_after_updat
|
|||||||
void TextIndex::UpdateOnRemoveLabel(LabelId removed_label, Vertex *vertex_after_update,
|
void TextIndex::UpdateOnRemoveLabel(LabelId removed_label, Vertex *vertex_after_update,
|
||||||
const std::uint64_t transaction_start_timestamp) {
|
const std::uint64_t transaction_start_timestamp) {
|
||||||
if (!flags::run_time::GetTextSearchEnabled()) {
|
if (!flags::run_time::GetTextSearchEnabled()) {
|
||||||
// TODO antepusic throw exception
|
throw query::QueryException("To use text indices, enable the text search feature.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!label_to_index_.contains(removed_label)) {
|
if (!label_to_index_.contains(removed_label)) {
|
||||||
@ -165,7 +165,7 @@ void TextIndex::UpdateOnRemoveLabel(LabelId removed_label, Vertex *vertex_after_
|
|||||||
void TextIndex::UpdateOnSetProperty(Vertex *vertex_after_update, Storage *storage,
|
void TextIndex::UpdateOnSetProperty(Vertex *vertex_after_update, Storage *storage,
|
||||||
std::uint64_t transaction_start_timestamp) {
|
std::uint64_t transaction_start_timestamp) {
|
||||||
if (!flags::run_time::GetTextSearchEnabled()) {
|
if (!flags::run_time::GetTextSearchEnabled()) {
|
||||||
// TODO antepusic throw exception
|
throw query::QueryException("To use text indices, enable the text search feature.");
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateNode(vertex_after_update, storage, transaction_start_timestamp);
|
UpdateNode(vertex_after_update, storage, transaction_start_timestamp);
|
||||||
@ -173,7 +173,7 @@ void TextIndex::UpdateOnSetProperty(Vertex *vertex_after_update, Storage *storag
|
|||||||
|
|
||||||
std::vector<mgcxx::text_search::Context *> TextIndex::GetApplicableTextIndices(const std::vector<LabelId> &labels) {
|
std::vector<mgcxx::text_search::Context *> TextIndex::GetApplicableTextIndices(const std::vector<LabelId> &labels) {
|
||||||
if (!flags::run_time::GetTextSearchEnabled()) {
|
if (!flags::run_time::GetTextSearchEnabled()) {
|
||||||
// TODO antepusic throw exception
|
throw query::QueryException("To use text indices, enable the text search feature.");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<mgcxx::text_search::Context *> applicable_text_indices;
|
std::vector<mgcxx::text_search::Context *> applicable_text_indices;
|
||||||
@ -187,7 +187,7 @@ std::vector<mgcxx::text_search::Context *> TextIndex::GetApplicableTextIndices(c
|
|||||||
|
|
||||||
std::vector<mgcxx::text_search::Context *> TextIndex::GetApplicableTextIndices(Vertex *vertex) {
|
std::vector<mgcxx::text_search::Context *> TextIndex::GetApplicableTextIndices(Vertex *vertex) {
|
||||||
if (!flags::run_time::GetTextSearchEnabled()) {
|
if (!flags::run_time::GetTextSearchEnabled()) {
|
||||||
// TODO antepusic throw exception
|
throw query::QueryException("To use text indices, enable the text search feature.");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<mgcxx::text_search::Context *> applicable_text_indices;
|
std::vector<mgcxx::text_search::Context *> applicable_text_indices;
|
||||||
@ -201,7 +201,7 @@ std::vector<mgcxx::text_search::Context *> TextIndex::GetApplicableTextIndices(V
|
|||||||
|
|
||||||
bool TextIndex::CreateIndex(std::string index_name, LabelId label, memgraph::query::DbAccessor *db) {
|
bool TextIndex::CreateIndex(std::string index_name, LabelId label, memgraph::query::DbAccessor *db) {
|
||||||
if (!flags::run_time::GetTextSearchEnabled()) {
|
if (!flags::run_time::GetTextSearchEnabled()) {
|
||||||
// TODO antepusic throw exception
|
throw query::QueryException("To use text indices, enable the text search feature.");
|
||||||
}
|
}
|
||||||
|
|
||||||
nlohmann::json mappings = {};
|
nlohmann::json mappings = {};
|
||||||
@ -222,13 +222,14 @@ bool TextIndex::CreateIndex(std::string index_name, LabelId label, memgraph::que
|
|||||||
bool has_schema = false;
|
bool has_schema = false;
|
||||||
std::vector<std::pair<PropertyId, std::string>> indexed_properties{};
|
std::vector<std::pair<PropertyId, std::string>> indexed_properties{};
|
||||||
auto &index_context = index_.at(index_name).context_;
|
auto &index_context = index_.at(index_name).context_;
|
||||||
for (const auto &v : db->Vertices(View::OLD)) {
|
for (const auto &v : db->Vertices(View::NEW)) {
|
||||||
if (!v.HasLabel(View::OLD, label).GetValue()) {
|
if (!v.HasLabel(View::NEW, label).GetValue()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!has_schema) [[unlikely]] {
|
if (!has_schema) [[unlikely]] {
|
||||||
for (const auto &[prop_id, prop_val] : v.Properties(View::OLD).GetValue()) {
|
auto properties = v.Properties(View::NEW).GetValue();
|
||||||
|
for (const auto &[prop_id, prop_val] : properties) {
|
||||||
if (prop_val.IsBool() || prop_val.IsInt() || prop_val.IsDouble() || prop_val.IsString()) {
|
if (prop_val.IsBool() || prop_val.IsInt() || prop_val.IsDouble() || prop_val.IsString()) {
|
||||||
indexed_properties.emplace_back(std::pair<PropertyId, std::string>{prop_id, db->PropertyToName(prop_id)});
|
indexed_properties.emplace_back(std::pair<PropertyId, std::string>{prop_id, db->PropertyToName(prop_id)});
|
||||||
}
|
}
|
||||||
@ -239,7 +240,7 @@ bool TextIndex::CreateIndex(std::string index_name, LabelId label, memgraph::que
|
|||||||
nlohmann::json document = {};
|
nlohmann::json document = {};
|
||||||
nlohmann::json properties = {};
|
nlohmann::json properties = {};
|
||||||
for (const auto &[prop_id, prop_name] : indexed_properties) {
|
for (const auto &[prop_id, prop_name] : indexed_properties) {
|
||||||
const auto &prop_value = v.GetProperty(View::OLD, prop_id).GetValue();
|
const auto prop_value = v.GetProperty(View::NEW, prop_id).GetValue();
|
||||||
switch (prop_value.type()) {
|
switch (prop_value.type()) {
|
||||||
case PropertyValue::Type::Bool:
|
case PropertyValue::Type::Bool:
|
||||||
properties[prop_name] = prop_value.ValueBool();
|
properties[prop_name] = prop_value.ValueBool();
|
||||||
@ -290,7 +291,7 @@ bool TextIndex::CreateIndex(std::string index_name, LabelId label, memgraph::que
|
|||||||
|
|
||||||
bool TextIndex::DropIndex(std::string index_name) {
|
bool TextIndex::DropIndex(std::string index_name) {
|
||||||
if (!flags::run_time::GetTextSearchEnabled()) {
|
if (!flags::run_time::GetTextSearchEnabled()) {
|
||||||
// TODO antepusic throw exception
|
throw query::QueryException("To use text indices, enable the text search feature.");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -307,7 +308,11 @@ bool TextIndex::IndexExists(std::string index_name) const { return index_.contai
|
|||||||
|
|
||||||
std::vector<Gid> TextIndex::Search(std::string index_name, std::string search_query) {
|
std::vector<Gid> TextIndex::Search(std::string index_name, std::string search_query) {
|
||||||
if (!flags::run_time::GetTextSearchEnabled()) {
|
if (!flags::run_time::GetTextSearchEnabled()) {
|
||||||
// TODO antepusic throw exception
|
throw query::QueryException("To use text indices, enable the text search feature.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!index_.contains(index_name)) {
|
||||||
|
throw query::QueryException(fmt::format("Text index \"{}\" doesn’t exist.", index_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto input = mgcxx::text_search::SearchInput{.search_query = search_query, .return_fields = {"data", "metadata"}};
|
auto input = mgcxx::text_search::SearchInput{.search_query = search_query, .return_fields = {"data", "metadata"}};
|
||||||
@ -317,11 +322,8 @@ std::vector<Gid> TextIndex::Search(std::string index_name, std::string search_qu
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Gid> found_nodes;
|
std::vector<Gid> found_nodes;
|
||||||
|
|
||||||
mgcxx::text_search::SearchOutput search_results;
|
mgcxx::text_search::SearchOutput search_results;
|
||||||
|
|
||||||
// if (!index_.contains(index_name)) throw InvalidArgumentException("InvalidArgumentException");
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
search_results = mgcxx::text_search::search(index_.at(index_name).context_, input);
|
search_results = mgcxx::text_search::search(index_.at(index_name).context_, input);
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
|
@ -23,7 +23,7 @@ class DbAccessor;
|
|||||||
namespace memgraph::storage {
|
namespace memgraph::storage {
|
||||||
class Storage;
|
class Storage;
|
||||||
|
|
||||||
constexpr bool KDoSkipCommit = true;
|
constexpr bool KDoSkipCommit = false;
|
||||||
|
|
||||||
struct TextIndexData {
|
struct TextIndexData {
|
||||||
mgcxx::text_search::Context context_;
|
mgcxx::text_search::Context context_;
|
||||||
@ -33,7 +33,7 @@ struct TextIndexData {
|
|||||||
class TextIndex {
|
class TextIndex {
|
||||||
private:
|
private:
|
||||||
void AddNode(Vertex *vertex, Storage *storage, const std::uint64_t transaction_start_timestamp,
|
void AddNode(Vertex *vertex, Storage *storage, const std::uint64_t transaction_start_timestamp,
|
||||||
const std::vector<mgcxx::text_search::Context *> &applicable_text_indices, bool skip_commit = true);
|
const std::vector<mgcxx::text_search::Context *> &applicable_text_indices, bool skip_commit = false);
|
||||||
|
|
||||||
std::vector<mgcxx::text_search::Context *> GetApplicableTextIndices(const std::vector<LabelId> &labels);
|
std::vector<mgcxx::text_search::Context *> GetApplicableTextIndices(const std::vector<LabelId> &labels);
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ class TextIndex {
|
|||||||
std::map<LabelId, std::string> label_to_index_;
|
std::map<LabelId, std::string> label_to_index_;
|
||||||
|
|
||||||
void AddNode(Vertex *vertex, Storage *storage, const std::uint64_t transaction_start_timestamp,
|
void AddNode(Vertex *vertex, Storage *storage, const std::uint64_t transaction_start_timestamp,
|
||||||
bool skip_commit = true);
|
bool skip_commit = false);
|
||||||
|
|
||||||
void UpdateNode(Vertex *vertex, Storage *storage, const std::uint64_t transaction_start_timestamp);
|
void UpdateNode(Vertex *vertex, Storage *storage, const std::uint64_t transaction_start_timestamp);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user