BeamSQL Group By проблема запроса со значением Float

Пытался получить уникальное значение из таблицы BigQuery, используя BeamSQL в Google Dataflow. С помощью предложения Group By реализовано условие в BeamSQL (пример запроса ниже). Один из столбцов имеет тип данных с плавающей точкой. Выполняя работу получил ниже исключений,

Вызывается: org.apache.beam.sdk.coders.Coder$NonDeterministicException: org.apache.beam.sdk.coders.RowCoder@81d6d10 не является детерминированным, поскольку: все поля должны иметь детерминистическую кодировку. Вызывается: org.apache.beam.sdk.coders.Coder$NonDeterministicException: FloatCoder не является детерминированным, потому что: не гарантируется, что кодировки с плавающей точкой будут детерминированными.

BeamSQL Query:

PCollection ST = mainColl.apply (SqlTransform.query ("ВЫБЕРИТЕ ID, ПУНКТ, УНИТПРИЦ ИЗ ГРУППЫ PCOLLECTION ПО ID, ПУНКТ, УНИТПРИЦ"));

Было бы хорошо, если бы кто-нибудь помог мне решить эту проблему.

Обратите внимание: если мы удалим столбец с плавающей точкой, запрос BeamSQL будет работать нормально.

1 ответ

Решение

Это указывает на то, что вы не должны использовать значения с плавающей запятой (в этом случае, вероятно, UNITPRICE value) в схеме агрегации (group by), потому что их выходные данные являются недетерминированными (то есть могут изменяться в зависимости от изменения точности). Например, рассмотрим этот пример:

WITH
  data AS (
  SELECT 100 AS id, 'abc' as item, 0.3448473362800000001 AS unitprice
  UNION ALL
  SELECT 200 AS id, 'xyz' as item, 0.49300013 AS unitprice
  UNION ALL
  SELECT 500 AS id, 'pqr' as item, 0.67322332200000212 AS unitprice
)
select id, item, unitprice from data
group by id, item, unitprice

Выход для этого будет:

100 abc 0.34484733628    
200 xyz 0.49300013   
500 pqr 0.6732233220000021

в котором unitprice значения выглядят немного иначе.

Чтобы избежать этого, вы можете пойти двумя путями:

  • Вы можете разыграть свою цену в виде строки, а затем продолжить группировку. Что-то вроде cast(unitprice as string) as unitprice в вашем запросе.
  • Вы можете просто выбрать сохранить unitprice как не сгруппированный объект (что является логическим вариантом в большинстве случаев), и просто сделать max(unitprice) as unitprice или же avg(unitprice) as unitprice в вашем запросе при группировании по id, item,

Надеюсь это поможет.

Другие вопросы по тегам