在 Tarantool 中通过部分密钥使用 "space:delete" 的任何方法?
Any ways to use "space:delete" by part of partial key in Tarantool?
文档说 "delete cannot work with partial keys"。你有什么建议如何解决它。例如创建新索引,使用循环删除或任何方式?
您可以使用主键在循环中删除值。
#!/usr/bin/env tarantool
local json = require('json')
local function key_from_tuple(tuple, key_parts)
local key = {}
for _, part in ipairs(key_parts) do
table.insert(key, tuple[part.fieldno] or box.NULL)
end
return key
end
box.cfg{}
box.once('init', function()
box.schema.space.create('s')
box.space.s:create_index('pk')
box.space.s:create_index('sk', {
unique = false,
parts = {
{2, 'number'},
{3, 'number'},
}
})
end)
box.space.s:truncate()
box.space.s:insert{1, 1, 1}
box.space.s:insert{2, 1, 1}
print('before delete')
print('---')
box.space.s:pairs():each(function(tuple)
print(json.encode(tuple))
end)
print('...')
local key_parts = box.space.s.index.pk.parts
for _, tuple in box.space.s.index.sk:pairs({1}) do
local key = key_from_tuple(tuple, key_parts)
box.space.s.index.pk:delete(key)
end
print('after delete')
print('---')
box.space.s:pairs():each(function(tuple)
print(json.encode(tuple))
end)
print('...')
os.exit()
在上面的示例中,使用 key_from_tuple
函数处理常见情况。当您知道哪些字段构成主键时,事情可能会更简单。说,如果它是第一个字段:
for _, tuple in box.space.s.index.sk:pairs({1}) do
box.space.s.index.pk:delete(tuple[1])
end
tarantool-2.2.0-255-g22db9c264 中添加的新 key_def 模块(尚未发布,但可从我们的 2.2 存储库中获取)简化了从元组中提取密钥的过程,尤其是在json 路径索引:
#!/usr/bin/env tarantool
local json = require('json')
local key_def_lib = require('key_def')
box.cfg{}
box.once('init', function()
box.schema.space.create('s')
box.space.s:create_index('pk')
box.space.s:create_index('sk', {
unique = false,
parts = {
{2, 'number', path = 'a'},
{2, 'number', path = 'b'},
}
})
end)
box.space.s:truncate()
box.space.s:insert{1, {a = 1, b = 1}}
box.space.s:insert{2, {a = 1, b = 2}}
print('before delete')
print('---')
box.space.s:pairs():each(function(tuple)
print(json.encode(tuple))
end)
print('...')
local key_def = key_def_lib.new(box.space.s.index.pk.parts)
for _, tuple in box.space.s.index.sk:pairs({1}) do
local key = key_def:extract_key(tuple)
box.space.s.index.pk:delete(key)
end
print('after delete')
print('---')
box.space.s:pairs():each(function(tuple)
print(json.encode(tuple))
end)
print('...')
os.exit()
从 Tarantool 2.1 开始,您可以使用 SQL 语法 ('delete from ... where ...')。
但是,请注意 Tarantool 将尝试在事务中执行此操作,因此如果您尝试删除太多元组,它将锁定事务线程一段时间。
文档说 "delete cannot work with partial keys"。你有什么建议如何解决它。例如创建新索引,使用循环删除或任何方式?
您可以使用主键在循环中删除值。
#!/usr/bin/env tarantool
local json = require('json')
local function key_from_tuple(tuple, key_parts)
local key = {}
for _, part in ipairs(key_parts) do
table.insert(key, tuple[part.fieldno] or box.NULL)
end
return key
end
box.cfg{}
box.once('init', function()
box.schema.space.create('s')
box.space.s:create_index('pk')
box.space.s:create_index('sk', {
unique = false,
parts = {
{2, 'number'},
{3, 'number'},
}
})
end)
box.space.s:truncate()
box.space.s:insert{1, 1, 1}
box.space.s:insert{2, 1, 1}
print('before delete')
print('---')
box.space.s:pairs():each(function(tuple)
print(json.encode(tuple))
end)
print('...')
local key_parts = box.space.s.index.pk.parts
for _, tuple in box.space.s.index.sk:pairs({1}) do
local key = key_from_tuple(tuple, key_parts)
box.space.s.index.pk:delete(key)
end
print('after delete')
print('---')
box.space.s:pairs():each(function(tuple)
print(json.encode(tuple))
end)
print('...')
os.exit()
在上面的示例中,使用 key_from_tuple
函数处理常见情况。当您知道哪些字段构成主键时,事情可能会更简单。说,如果它是第一个字段:
for _, tuple in box.space.s.index.sk:pairs({1}) do
box.space.s.index.pk:delete(tuple[1])
end
tarantool-2.2.0-255-g22db9c264 中添加的新 key_def 模块(尚未发布,但可从我们的 2.2 存储库中获取)简化了从元组中提取密钥的过程,尤其是在json 路径索引:
#!/usr/bin/env tarantool
local json = require('json')
local key_def_lib = require('key_def')
box.cfg{}
box.once('init', function()
box.schema.space.create('s')
box.space.s:create_index('pk')
box.space.s:create_index('sk', {
unique = false,
parts = {
{2, 'number', path = 'a'},
{2, 'number', path = 'b'},
}
})
end)
box.space.s:truncate()
box.space.s:insert{1, {a = 1, b = 1}}
box.space.s:insert{2, {a = 1, b = 2}}
print('before delete')
print('---')
box.space.s:pairs():each(function(tuple)
print(json.encode(tuple))
end)
print('...')
local key_def = key_def_lib.new(box.space.s.index.pk.parts)
for _, tuple in box.space.s.index.sk:pairs({1}) do
local key = key_def:extract_key(tuple)
box.space.s.index.pk:delete(key)
end
print('after delete')
print('---')
box.space.s:pairs():each(function(tuple)
print(json.encode(tuple))
end)
print('...')
os.exit()
从 Tarantool 2.1 开始,您可以使用 SQL 语法 ('delete from ... where ...')。
但是,请注意 Tarantool 将尝试在事务中执行此操作,因此如果您尝试删除太多元组,它将锁定事务线程一段时间。