Tarantool CE/EE Documentation portal logo
Помощь
Обновлена 15 сентября 2026 г. в 08:55

examples

Данный пример сработает на конфигурации из песочницы, описанной в предисловии, то есть создан спейс под названием tester с первичным числовым ключом. Функция в примере выполнит следующие действия:

  • выбрать кортеж, значение ключа которого – 1000;
  • вызвать ошибку, если кортеж уже существует и содержит 3 поля;
  • вставить или заменить кортеж следующими значениями:
    • field[1] = 1000
    • field[2] = UUID
    • field[3] = количество секунд с 1970-01-01;
  • получить field[3] из замененного кортежа;
  • отформатировать значение из field[3] в виде yyyy-mm-dd hh:mm:ss.ffff;
function example()  local a, b, c, table_of_selected_tuples, d  local replaced_tuple, time_field  local formatted_time_field  local fiber = require('fiber')  table_of_selected_tuples = box.space.tester:select{1000}  if table_of_selected_tuples ~= nil then    if table_of_selected_tuples[1] ~= nil then      if #table_of_selected_tuples[1] == 3 then        box.error({code=1, reason='This tuple already has 3 fields'})      end    end  end  replaced_tuple = box.space.tester:replace    {1000,  require('uuid').str(), tostring(fiber.time())}  time_field = tonumber(replaced_tuple[3])  formatted_time_field = os.date("%Y-%m-%d %H:%M:%S", time_field)  c = time_field % 1  d = string.sub(c, 3, 6)  formatted_time_field = formatted_time_field .. '.' .. d  return formatted_time_fieldend

Результат вызова функции:

tarantool> box.space.tester:delete(1000)---- [1000, '264ee2da03634f24972be76c43808254', '1391037015.6809']...tarantool> example(1000)---- 2014-01-29 16:11:51.1582...tarantool> example(1000)---- error: 'This tuple already has 3 fields'...

Пример использования пользовательского итератора

Здесь приведен пример того, как создать свой собственный итератор. Функция paged_iter представляет собой «функцию с итератором», что поймут только разработчики, которые ознакомились с разделом руководства по Lua Итераторы и замыкания. Она делает постраничную выборку, то есть возвращает 10 кортежей одновременно из таблицы под названием "t", первичный ключ которой определен с помощью create_index('primary',{parts={1,'string'}}).

function paged_iter(search_key, tuples_per_page)  local iterator_string = "GE"  return function ()  local page = box.space.t.index[0]:select(search_key,    {iterator = iterator_string, limit=tuples_per_page})  if #page == 0 then return nil end  search_key = page[#page][1]  iterator_string = "GT"  return page  endend

Разработчикам, использующим paged_iter, необязательно знать, почему она работает, следует лишь понимать, что вызвав функцию в цикле, можно получать 10 кортежей за раз до тех пор, пока кортежи не кончатся.

В данном примере кортежи лишь выводятся по странице за раз. Но легко изменить функцию, например, путем передачи управления после каждой выборки или с помощью прерывания, если кортежи не будут соответствовать дополнительным критериям.

for page in paged_iter("X", 10) do  print("New Page. Number Of Tuples = " .. #page)  for i = 1, #page, 1 do    print(page[i])  endend

Пример использования вложенного модуля box.index с индексом типа RTREE для пространственного поиска

Этот вложенный модуль может использоваться для поиска в пространственных данных, если тип индекса – RTREE. Существуют операции для поиска прямоугольников (геометрические фигуры с 4 углами и 4 сторонами) и параллелепипедов (геометрические фигуры с количеством углов более 4 и количеством сторон более 4, которые иногда называются гиперпрямоугольниками). В данном руководстве используется термин прямоугольник-или-параллелепипед для всего класса объектов, который включает в себя прямоугольники и параллелепипеды. Примерами иллюстрируются только прямоугольники.

Прямоугольники описаны в соответствии с координатами по оси X (горизонтальной оси) и оси Y (вертикальной оси) на сетке произвольного размера. Ниже представлен рисунок четырех прямоугольников на сетке с 11 горизонтальными точками и 11 вертикальными точками:

X AXIS     1   2   3   4   5   6   7   8   9   10  11  1  2  #-------+                                           <-Прямоугольник №1Y AXIS  3  |       |  4  +-------#  5          #-----------------------+                   <-Прямоугольник №2  6          |                       |  7          |   #---+               |                   <-Прямоугольник №3  8          |   |   |               |  9          |   +---#               |  10         +-----------------------#  11                                     #               <-Прямоугольник №4

Прямоугольники определяются в соответствии со следующей схемой: {верхняя левая координата по оси X, верхняя левая координата по оси Y, нижняя правая координата по оси X, нижняя правая координата по оси Y} – или коротко: {x1,y1,x2,y2}. Таким образом, на рисунке ... Прямоугольник № 1 начинается в точке 1 по оси X и точке 2 по оси Y, а заканчивается в точке 3 по оси X и точке 4 по оси Y, поэтому его координаты будут следующие: {1,2,3,4}. Координаты Прямоугольника № 2: {3,5,9,10}. Координаты Прямоугольника № 3: {4,7,5,9}. И наконец, координаты Прямоугольника № 4: {10,11,10,11}. Прямоугольник № 4, на самом деле, является точкой, поскольку у него нулевая ширина и нулевая высота, так что его можно описать всего двумя числами: {10,11}.

Некоторые отношения между прямоугольниками могут быть описаны так: "Прямоугольник №1 является ближайшим соседом Прямоугольника №2", а "Прямоугольник №3 полностью находится внутри Прямоугольника №2".

Сейчас создадим спейс и добавим RTREE-индекс.

tarantool> s = box.schema.space.create('rectangles')tarantool> i = s:create_index('primary', {         >   type = 'HASH',         >   parts = {1, 'unsigned'}         > })tarantool> r = s:create_index('rtree', {         >   type = 'RTREE',         >   unique = false,         >   parts = {2, 'ARRAY'}         > })

Поле №1 не имеет значения, мы создаем его лишь потому, что необходим первичный индекс. (RTREE-индексы не могут быть уникальными, поэтому не могут быть первичными индексами.) Второе поле должно быть массивом ("array"), что означает, что его значения должны представлять собой точки {x,y} или прямоугольники {x1,y1,x2,y2}. Заполним таблицу, вставив два кортежа с координатами Прямоугольника №2 и Прямоугольника №4.

tarantool> s:insert{1, {3, 5, 9, 10}}tarantool> s:insert{2, {10, 11}}

Затем, после описания типов RTREE-итераторов ([RTREE iterator types](#RTREE iterator types)), можно произвести поиск прямоугольников с помощью данных запросов:

tarantool> r:select({10, 11, 10, 11}, {iterator = 'EQ'})---- - [2, [10, 11]]...tarantool> r:select({4, 7, 5, 9}, {iterator = 'GT'})---- - [1, [3, 5, 9, 10]]...tarantool> r:select({1, 2, 3, 4}, {iterator = 'NEIGHBOR'})---- - [1, [3, 5, 9, 10]]  - [2, [10, 11]]...

Запрос №1 возвращает 1 кортеж, потому что точка {10,11} представляет собой то же, что и прямоугольник {10,11,10,11} ("Прямоугольник №4" на рисунке). Запрос № 2 возвращает 1 кортеж, потому что прямоугольник {4,7,5,9}, который был "Прямоугольником №3" на рисунке находится полностью внутри {3,5,9,10}, что представляет собой Прямоугольник № 2. Запрос № 3 возвращает 2 кортежа, потому что итератор NEIGHBOR (сосед) всегда возвращает все кортежи, а первым найденным кортежем будет {3,5,9,10} ("Прямоугольник №2" на рисунке), потому что он является ближайшим соседом {1,2,3,4} ("Прямоугольник №1" на рисунке).

Теперь создадим спейс и индекс для кубоидов. Он представляет собой прямоугольники или параллелепипеды, у которых 6 углов и 6 сторон.

tarantool> s = box.schema.space.create('R')tarantool> i = s:create_index('primary', {parts = {1, 'unsigned'}})tarantool> r = s:create_index('S', {         >   type = 'RTREE',         >   unique = false,         >   dimension = 3,         >   parts = {2, 'ARRAY'}         > })

Здесь задается дополнительный параметр dimension=3. По умолчанию, измерений 2, поэтому не было необходимости указывать данный параметр в примерах для прямоугольника. Максимальное количество измерений – 20. Что касается вставки и выборки, здесь будет 6 координат. Например:

tarantool> s:insert{1, {0, 3, 0, 3, 0, 3}}tarantool> r:select({1, 2, 1, 2, 1, 2}, {iterator = box.index.GT})

Теперь создадим спейс и индекс для пространственных объектов с метрикой расстояния городских кварталов (метрика Манхэттена), которые представляют собой прямоугольники-или-параллелепипеды; соседи для них рассчитываются иным образом.

tarantool> s = box.schema.space.create('R')tarantool> i = s:create_index('primary', {parts = {1, 'unsigned'}})tarantool> r = s:create_index('S', {         >   type = 'RTREE',         >   unique = false,         >   distance = 'manhattan',         >   parts = {2, 'ARRAY'}         > })

Здесь задается дополнительный параметр distance='manhattan'. По умолчанию, расстояние измеряется по Евклидовой метрике, что лучше всего подходит для измерений по прямой линии. Другой способ расчета расстояния по метрике Манхэттена ('manhattan'), который больше подходит, если необходимо следовать линиям сетки, а не по прямой.

tarantool> s:insert{1, {0, 3, 0, 3}}tarantool> r:select({1, 2, 1, 2}, {iterator = box.index.NEIGHBOR})

Другие примеры поиска в пространственных данных см. в разделе R-tree index quick start and usage.