From 93f282dd8cdc73f89fab09380a422feffa1df112 Mon Sep 17 00:00:00 2001 From: Lorenz Herzberger Date: Tue, 14 Jun 2022 08:00:34 +0200 Subject: [PATCH] added indexed_pattern_search to basic lua, implemented text_search Signed-off-by: Lorenz Herzberger --- planetmint/backend/tarantool/basic.lua | 77 ++++++++++++++++++++++++++ planetmint/backend/tarantool/query.py | 7 +++ planetmint/backend/tarantool/schema.py | 5 +- 3 files changed, 87 insertions(+), 2 deletions(-) diff --git a/planetmint/backend/tarantool/basic.lua b/planetmint/backend/tarantool/basic.lua index bdea22b..fcc46eb 100644 --- a/planetmint/backend/tarantool/basic.lua +++ b/planetmint/backend/tarantool/basic.lua @@ -1 +1,78 @@ box.cfg{listen = 3303} + +function indexed_pattern_search(space_name, field_no, pattern) + if (box.space[space_name] == nil) then + print("Error: Failed to find the specified space") + return nil + end + local index_no = -1 + for i=0,box.schema.INDEX_MAX,1 do + if (box.space[space_name].index[i] == nil) then break end + if (box.space[space_name].index[i].type == "TREE" + and box.space[space_name].index[i].parts[1].fieldno == field_no + and (box.space[space_name].index[i].parts[1].type == "scalar" + or box.space[space_name].index[i].parts[1].type == "string")) then + index_no = i + break + end + end + if (index_no == -1) then + print("Error: Failed to find an appropriate index") + return nil + end + local index_search_key = "" + local index_search_key_length = 0 + local last_character = "" + local c = "" + local c2 = "" + for i=1,string.len(pattern),1 do + c = string.sub(pattern, i, i) + if (last_character ~= "%") then + if (c == '^' or c == "$" or c == "(" or c == ")" or c == "." + or c == "[" or c == "]" or c == "*" or c == "+" + or c == "-" or c == "?") then + break + end + if (c == "%") then + c2 = string.sub(pattern, i + 1, i + 1) + if (string.match(c2, "%p") == nil) then break end + index_search_key = index_search_key .. c2 + else + index_search_key = index_search_key .. c + end + end + last_character = c + end + index_search_key_length = string.len(index_search_key) + local result_set = {} + local number_of_tuples_in_result_set = 0 + local previous_tuple_field = "" + while true do + local number_of_tuples_since_last_yield = 0 + local is_time_for_a_yield = false + for _,tuple in box.space[space_name].index[index_no]: + pairs(index_search_key,{iterator = box.index.GE}) do + if (string.sub(tuple[field_no], 1, index_search_key_length) + > index_search_key) then + break + end + number_of_tuples_since_last_yield = number_of_tuples_since_last_yield + 1 + if (number_of_tuples_since_last_yield >= 10 + and tuple[field_no] ~= previous_tuple_field) then + index_search_key = tuple[field_no] + is_time_for_a_yield = true + break + end + previous_tuple_field = tuple[field_no] + if (string.match(tuple[field_no], pattern) ~= nil) then + number_of_tuples_in_result_set = number_of_tuples_in_result_set + 1 + result_set[number_of_tuples_in_result_set] = tuple + end + end + if (is_time_for_a_yield ~= true) then + break + end + require('fiber').yield() + end + return result_set +end \ No newline at end of file diff --git a/planetmint/backend/tarantool/query.py b/planetmint/backend/tarantool/query.py index 6a1b5b0..f9446ab 100644 --- a/planetmint/backend/tarantool/query.py +++ b/planetmint/backend/tarantool/query.py @@ -275,6 +275,13 @@ def get_txids_filtered(connection, asset_id: str, operation: str = None, # # return (_remove_text_score(obj) for obj in cursor) +@register_query(TarantoolDBConnection) +def text_search(conn, search, table='assets'): + pattern = ".{}.".format(search) + res = conn.run( + conn.space(table).call('indexed_pattern_search', (table, 1, pattern)) + ) + return res def _remove_text_score(asset): asset.pop('score', None) diff --git a/planetmint/backend/tarantool/schema.py b/planetmint/backend/tarantool/schema.py index 73b13dc..de3b384 100644 --- a/planetmint/backend/tarantool/schema.py +++ b/planetmint/backend/tarantool/schema.py @@ -39,7 +39,8 @@ INDEX_COMMANDS = { { "txid_search": "assets:create_index('txid_search', {type='hash', parts={'tx_id'}})", "assetid_search": "assets:create_index('assetid_search', {type='tree',unique=false, parts={'asset_id', 'tx_id'}})", - "only_asset_search": "assets:create_index('only_asset_search', {type='tree', unique=false, parts={'asset_id'}})" + "only_asset_search": "assets:create_index('only_asset_search', {type='tree', unique=false, parts={'asset_id'}})", + "secondary": "assets:create_index('secondary', {unique=false,parts={1,'string',2,'string',3,'string'}})" }, "blocks": { @@ -107,7 +108,7 @@ SCHEMA_COMMANDS = { "abci_chains": "abci_chains:format({{name='height' , type='integer'},{name='is_synched' , type='boolean'},{name='chain_id',type='string'}, {name='id', type='string'}})", "assets": - "assets:format({{name='data' , type='any'}, {name='tx_id', type='string'}, {name='asset_id', type='string'}})", + "assets:format({{name='data' , type='string'}, {name='tx_id', type='string'}, {name='asset_id', type='string'}})", "blocks": "blocks:format{{name='app_hash',type='string'},{name='height' , type='integer'},{name='block_id' , type='string'}}", "blocks_tx": "blocks_tx:format{{name='transaction_id', type = 'string'}, {name = 'block_id', type = 'string'}}",