Как: написать udf фильтр aerospike без карты ИЛИ вернуть полную запись на карте

У меня есть поток udf с фильтром и картой в Aerospike.

Если я сопоставляю, как и во всех примерах, которые я видел, я могу выбрать поля из записи и вернуть новую карту с отфильтрованными и выбранными полями. Однако я не хочу этого делать. Я хочу взять любой поток, с любыми столбцами/ячейками, применить фильтр и вернуть полную запись. Один из подходов может состоять в том, чтобы использовать что-то вроде stream : fiter(my_filter) и не использовать карту. Интуитивно (по крайней мере, для меня) это просто фильтрует и ретранслирует поток. Это, кажется, не работает, к моему разочарованию. Следующее, что я попробую, это использовать карту, но просто передать полную запись. Это тоже не работает. В обоих случаях, когда я говорю, что это не работает, в результате я получаю пустой список.

Может кто-нибудь любезно объяснить, как это должно работать. Это сводит меня с ума. Учитывая, что это одна из самых основных вещей в мире, которые хотелось бы делать с udfs, я понимаю, что упускаю что-то очевидное. Я должен отметить, что я сделал много более сложных вещей с udfs, но по какой-то причине это проблема для меня.


person ismisesisko    schedule 18.06.2017    source источник


Ответы (2)


Вам не хватает того, что вы не можете возвращать типы записей или потоков в возвращаемом значении UDF. Я считаю, что все возвращаемые типы сопоставляются модулем lua системы aerospike с конкретными типами клиентов; он не может отображать запись «тип».

Если вы абсолютно хотите получить запись, сохраните свой ключ в корзине, верните эту корзину в виде карты, строкового или целочисленного типа — в зависимости от того, какой тип наиболее подходит для вашего приложения. Вы также можете получить дайджест записи из метаданных записи в типе карты. Я не тестировал извлечение и возврат дайджеста записей через UDF, но стоит попробовать.

Когда у вас есть пространство имен, набор и ваш ключ или пространство имен и дайджест записи, вы можете получить доступ к записи из клиентского API. Дайджест записи — это хэш RIPEMD160, вычисленный из комбинации имени набора и вашего ключа.

person pgupta    schedule 18.06.2017
comment
спасибо пгупта за ваш ответ. да, я знаю, что могу возвращать ключи и дайджесты, и я понимаю, что дайджест записи — это RIPEMD160 и т. д. из прочтения различной документации и технических документов. Моя настоящая забота об эффективности; я хотел бы вернуть все данные за один проход, поэтому кажется странным иметь данные прямо там, вернуть ключ, а затем вернуться за данными? Я также мог бы передать выбранные столбцы, которые мне нужны (все или нет), в UDF и итеративно построить карту, но опять же это кажется неэффективным. ИЛИ, я не пробовал это, но запись, кажется, имеет имена бинов... - person ismisesisko; 20.06.2017
comment
каков вариант использования простого возврата набора отфильтрованных записей из потока записей, т.е. вы хотите, чтобы все эти данные были отправлены на один клиентский узел и выполняли некоторые вычисления на клиентском узле? Aerospike предлагает 1) записывающие udf для изменения записи на сервере или 2) потоковые udf, которые воздействуют на набор записей в режиме только для чтения и позволяют агрегировать информацию в этих записях. таким образом, с помощью потоковой udfs вы получаете возможность вычисления типа уменьшения карты, используя каждый узел в кластере для выполнения вычислений на своем наборе записей и окончательного сокращения на клиентском узле. - person pgupta; 20.06.2017

Запись в Aerospike — это кортеж (ключ, метаданные, бины). Пользовательская функция Aerospike, написанная на Lua, будь то запись UDF или потоковая определяемая пользователем функция, может возвращать только один из поддерживаемых типов — строку, целое число, двойное число, список, карту, байты (см.: Известные ограничения).

В потоке UDF, если у вас есть только фильтр, вам все равно нужно привести пары bin-name/bin-value записи к карте и вернуть это:

local function bins_match_filter(bin1, bin2)
  return function(rec)
    if rec[bin1] and rec[bin2] and
       (type(rec[bin1]) == type(rec[bin2])) and
       rec[bin1] == rec[bin2] then
      return true
    end
    return false
  end
end

local function record_to_map(rec)
  local ret = map()
  for i, bin_name in ipairs(record.bin_names(rec)) do
    ret[bin_name] = rec[bin_name]
  end
  return ret
end

function check_bins_match(stream, bin1, bin2)
  return stream : filter(bins_match_filter(bin1, bin2)) : map(record_to_map)
end

Вы можете преобразовывать определенные потоковые UDF-фильтры в предикатный фильтр. . В приведенном выше примере это не сработает, потому что нет возможности сравнить значения двух бинов. Но в большинстве случаев операций предикатного выражения достаточно (см. PredExp клиента Java). Вам вообще не нужно будет вызывать UDF, который будет работать намного быстрее, лучше масштабироваться, и вам не нужно будет преобразовывать запись в карту пар имя/значение бина.

person Ronen Botzer    schedule 15.07.2017