added indexed_pattern_search to basic lua, implemented text_search

Signed-off-by: Lorenz Herzberger <lorenzherzberger@gmail.com>
This commit is contained in:
Lorenz Herzberger 2022-06-14 08:00:34 +02:00
parent ff2e429633
commit 93f282dd8c
No known key found for this signature in database
GPG Key ID: FA5EE906EB55316A
3 changed files with 87 additions and 2 deletions

View File

@ -1 +1,78 @@
box.cfg{listen = 3303} 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

View File

@ -275,6 +275,13 @@ def get_txids_filtered(connection, asset_id: str, operation: str = None,
# #
# return (_remove_text_score(obj) for obj in cursor) # 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): def _remove_text_score(asset):
asset.pop('score', None) asset.pop('score', None)

View File

@ -39,7 +39,8 @@ INDEX_COMMANDS = {
{ {
"txid_search": "assets:create_index('txid_search', {type='hash', parts={'tx_id'}})", "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'}})", "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": "blocks":
{ {
@ -107,7 +108,7 @@ SCHEMA_COMMANDS = {
"abci_chains": "abci_chains":
"abci_chains:format({{name='height' , type='integer'},{name='is_synched' , type='boolean'},{name='chain_id',type='string'}, {name='id', type='string'}})", "abci_chains:format({{name='height' , type='integer'},{name='is_synched' , type='boolean'},{name='chain_id',type='string'}, {name='id', type='string'}})",
"assets": "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":
"blocks:format{{name='app_hash',type='string'},{name='height' , type='integer'},{name='block_id' , type='string'}}", "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'}}", "blocks_tx": "blocks_tx:format{{name='transaction_id', type = 'string'}, {name = 'block_id', type = 'string'}}",