如何在 Tarantool 上查询 "any"/"map" 数据类型?

How to query from "any"/"map" data type on Tarantool?

以下示例来自 。如果我创建的地图没有索引,如何查询地图的内部值?

box.schema.create_space('x', {format = {[1] = {'id', 'unsigned'}, [2] = {'obj', 'map'}}})
box.space.x:create_index('pk', {parts = {[1] = {field = 1, type = 'unsigned'}}})
box.space.x:insert({2, {text = 'second', timestamp = 123}}
box.execute [[ SELECT * FROM "x" ]]
-- [2, {'timestamp': 123, 'text': 'second'}]

如何在不创建索引的情况下直接从 SQL 获取 timestamptext 列?

试过这些但没有用:

SELECT "obj.text" FROM "x"
SELECT "obj"."text" FROM "x"
SELECT "obj"["text"] FROM "x"
SELECT "obj"->"text" FROM "x"

您可以注册一个 Lua 函数以从 SQL 调用它。我们 SQL + Lua manual 中的第一个示例完全符合您的要求。

解释想法的示例的简化版本:

box.schema.func.create('GETFIELD', {
    language = 'LUA',
    returns = 'any',
    body = [[
        function(msgpack_value, field)
            return require('msgpack').decode(msgpack_value)[field] 
        end]],
    is_sandboxed = false,
    param_list = {'string', 'string'},
    exports = {'SQL'},
    is_deterministic = true
})

注册函数后,您可以从SQL调用它:

tarantool> \set language sql
tarantool> select getfield("obj", 'text') from "x"
---
- metadata:
  - name: COLUMN_1
    type: any
  rows:
  - ['second']
...

tarantool> select getfield("obj", 'timestamp') from "x"
---
- metadata:
  - name: COLUMN_1
    type: any
  rows:
  - [123]
...

与手册中示例的差异:

  • 没有破解全局变量,但没有点语法 ('foo.bar.baz')。
  • 仅导出到 SQL。
  • return 类型是 'any':所以它可以用于,比如说,数字 'timestamp' 字段。缺点:结果集元信息中报告 'any'。

(我的队友 Nikita Pettik 提出的想法。)