Tarantool 中 PostgreSQL 的类似 JSONB 的可索引列?

问题描述

在 Postgresql 中,我们可以创建一个可以被索引和访问的 JSONB 列,如下所示:

CREATE TABLE foo (
   id BIGSERIAL PRIMARY KEY
   -- createdAt,updatedAt,deletedAt,createdBy,updatedBy,restoredBy,deletedBy
   data JSONB
);


CREATE INDEX ON foo((data->>'email'));
INSERT INTO foo(data) VALUES('{"name":"yay","email":"a@1.com"}');
SELECT data->>'name' FROM foo WHERE id = 1; 
SELECT data->>'name' FROM foo WHERE data->>'email' = 'a@1.com'; 

这在原型设计阶段非常有益(完全不需要迁移或添加列时锁定)。

我们可以在 Tarantool 中做类似的事情吗?

解决方法

当然,tarantool 支持 JSON path indices。例子:

-- Initialize / load the database.
tarantool> box.cfg{}

-- Create a space with two columns: id and obj.
-- The obj column supposed to contain dictionaries with nested data.
tarantool> box.schema.create_space('s',> {format = {[1] = {'id','unsigned'},[2] = {'obj','any'}}})

-- Create primary and secondary indices.
-- The secondary indices looks at the nested field obj.timestamp.
tarantool> box.space.s:create_index('pk',> {parts = {[1] = {field = 1,type = 'unsigned'}}})
tarantool> box.space.s:create_index('sk',> {parts = {[1] = {field = 2,path = 'timestamp',type = 'number'}}})

-- Insert three tuples: first,third and second.
tarantool> clock = require('clock')
tarantool> box.space.s:insert({1,{text = 'first',timestamp = clock.time()}})
tarantool> box.space.s:insert({3,{text = 'third',timestamp = clock.time()}})
tarantool> box.space.s:insert({2,{text = 'second',timestamp = clock.time()}})

-- Select tuples with timestamp of the last hour,1000 at max.
-- Sort them by timestamp.
tarantool> box.space.s.index.sk:select(
         > clock.time() - 3600,{iterator = box.index.GT,limit = 1000})
---
- - [1,{'timestamp': 1620820764.1213,'text': 'first'}]
  - [3,{'timestamp': 1620820780.4971,'text': 'third'}]
  - [2,{'timestamp': 1620820789.5737,'text': 'second'}]
...

JSON 路径索引自 tarantool 2.1.2 起可用。