Pinot 嵌套 json 摄取
Pinot nested json ingestion
我有这个 json 架构
{
"name":"Pete"
"age":24,
"subjects":[
{
"name":"maths"
"grade":"A"
},
{
"name":"maths"
"grade":"B"
}
]
}
我想将它吸收到 pinot table 到 运行 这样的查询
select age,subjects_grade,count(*) from table group by age,subjects_grade
有没有办法在 pinot 工作中做到这一点?
Pinot 有两种处理 JSON 条记录的方法:
1.在摄取时间内压平记录:
在这种情况下,我们将每个嵌套字段视为一个单独的字段,因此需要:
- 在 table 模式中定义那些字段
- 在 table 配置中定义转换函数以展平嵌套字段
请参阅下面如何定义列 subjects_name
和 subjects_grade
。因为是数组,所以Pinot中这两个字段都是多值列。
2。直接提取 JSON 条记录
在这种情况下,我们将每个嵌套字段视为一个单独的字段,因此需要:
- 将 table 架构中的 JSON 字段定义为具有 maxLength 值的字符串
- 将此字段放入 noDictionaryColumns 和 jsonIndexColumns in table config
- 定义转换函数
jsonFormat
以将 table 配置中的 JSON 字段字符串化
请参阅下面如何定义第 subjects_str
列。
下面是示例 table schema/config/query:
示例 Pinot 架构:
{
"metricFieldSpecs": [],
"dimensionFieldSpecs": [
{
"dataType": "STRING",
"name": "name"
},
{
"dataType": "LONG",
"name": "age"
},
{
"dataType": "STRING",
"name": "subjects_str"
},
{
"dataType": "STRING",
"name": "subjects_name",
"singleValueField": false
},
{
"dataType": "STRING",
"name": "subjects_grade",
"singleValueField": false
}
],
"dateTimeFieldSpecs": [],
"schemaName": "myTable"
}
示例Table 配置:
{
"tableName": "myTable",
"tableType": "OFFLINE",
"segmentsConfig": {
"segmentPushType": "APPEND",
"segmentAssignmentStrategy": "BalanceNumSegmentAssignmentStrategy",
"schemaName": "myTable",
"replication": "1"
},
"tenants": {},
"tableIndexConfig": {
"loadMode": "MMAP",
"invertedIndexColumns": [],
"noDictionaryColumns": [
"subjects_str"
],
"jsonIndexColumns": [
"subjects_str"
]
},
"metadata": {
"customConfigs": {}
},
"ingestionConfig": {
"batchIngestionConfig": {
"segmentIngestionType": "APPEND",
"segmentIngestionFrequency": "DAILY",
"batchConfigMaps": [],
"segmentNameSpec": {},
"pushSpec": {}
},
"transformConfigs": [
{
"columnName": "subjects_str",
"transformFunction": "jsonFormat(subjects)"
},
{
"columnName": "subjects_name",
"transformFunction": "jsonPathArray(subjects, '$.[*].name')"
},
{
"columnName": "subjects_grade",
"transformFunction": "jsonPathArray(subjects, '$.[*].grade')"
}
]
}
}
示例查询:
select age, subjects_grade, count(*) from myTable GROUP BY age, subjects_grade
select age, json_extract_scalar(subjects_str, '$.[*].grade', 'STRING') as subjects_grade, count(*) from myTable GROUP BY age, subjects_grade
比较两种方式,我们推荐解决方案 1 以在字段密度高时展平嵌套字段(例如,每个文档都有字段 name 和 grade,那么值得将它们提取出来作为新列),它提供了更好的查询性能和更好的存储效率。
对于解决方案2,它的配置更简单,并且适用于稀疏字段(例如只有少数文档有某些字段)。需要使用json_extract_scalar函数来访问嵌套字段。
另请注意 Pinot GROUP BY 在多值列上的行为。
更多参考资料:
我有这个 json 架构
{
"name":"Pete"
"age":24,
"subjects":[
{
"name":"maths"
"grade":"A"
},
{
"name":"maths"
"grade":"B"
}
]
}
我想将它吸收到 pinot table 到 运行 这样的查询
select age,subjects_grade,count(*) from table group by age,subjects_grade
有没有办法在 pinot 工作中做到这一点?
Pinot 有两种处理 JSON 条记录的方法:
1.在摄取时间内压平记录: 在这种情况下,我们将每个嵌套字段视为一个单独的字段,因此需要:
- 在 table 模式中定义那些字段
- 在 table 配置中定义转换函数以展平嵌套字段
请参阅下面如何定义列 subjects_name
和 subjects_grade
。因为是数组,所以Pinot中这两个字段都是多值列。
2。直接提取 JSON 条记录
在这种情况下,我们将每个嵌套字段视为一个单独的字段,因此需要:
- 将 table 架构中的 JSON 字段定义为具有 maxLength 值的字符串
- 将此字段放入 noDictionaryColumns 和 jsonIndexColumns in table config
- 定义转换函数
jsonFormat
以将 table 配置中的 JSON 字段字符串化
请参阅下面如何定义第 subjects_str
列。
下面是示例 table schema/config/query:
示例 Pinot 架构:
{
"metricFieldSpecs": [],
"dimensionFieldSpecs": [
{
"dataType": "STRING",
"name": "name"
},
{
"dataType": "LONG",
"name": "age"
},
{
"dataType": "STRING",
"name": "subjects_str"
},
{
"dataType": "STRING",
"name": "subjects_name",
"singleValueField": false
},
{
"dataType": "STRING",
"name": "subjects_grade",
"singleValueField": false
}
],
"dateTimeFieldSpecs": [],
"schemaName": "myTable"
}
示例Table 配置:
{
"tableName": "myTable",
"tableType": "OFFLINE",
"segmentsConfig": {
"segmentPushType": "APPEND",
"segmentAssignmentStrategy": "BalanceNumSegmentAssignmentStrategy",
"schemaName": "myTable",
"replication": "1"
},
"tenants": {},
"tableIndexConfig": {
"loadMode": "MMAP",
"invertedIndexColumns": [],
"noDictionaryColumns": [
"subjects_str"
],
"jsonIndexColumns": [
"subjects_str"
]
},
"metadata": {
"customConfigs": {}
},
"ingestionConfig": {
"batchIngestionConfig": {
"segmentIngestionType": "APPEND",
"segmentIngestionFrequency": "DAILY",
"batchConfigMaps": [],
"segmentNameSpec": {},
"pushSpec": {}
},
"transformConfigs": [
{
"columnName": "subjects_str",
"transformFunction": "jsonFormat(subjects)"
},
{
"columnName": "subjects_name",
"transformFunction": "jsonPathArray(subjects, '$.[*].name')"
},
{
"columnName": "subjects_grade",
"transformFunction": "jsonPathArray(subjects, '$.[*].grade')"
}
]
}
}
示例查询:
select age, subjects_grade, count(*) from myTable GROUP BY age, subjects_grade
select age, json_extract_scalar(subjects_str, '$.[*].grade', 'STRING') as subjects_grade, count(*) from myTable GROUP BY age, subjects_grade
比较两种方式,我们推荐解决方案 1 以在字段密度高时展平嵌套字段(例如,每个文档都有字段 name 和 grade,那么值得将它们提取出来作为新列),它提供了更好的查询性能和更好的存储效率。
对于解决方案2,它的配置更简单,并且适用于稀疏字段(例如只有少数文档有某些字段)。需要使用json_extract_scalar函数来访问嵌套字段。
另请注意 Pinot GROUP BY 在多值列上的行为。
更多参考资料: