我正在设置一个Presto集群,我想用它来查询MongoDB实例。我的Mongo实例中的数据具有以下结构:
{
_id: <value>
somefield: <value>
otherfield: <value>
nesting_1: {
nested_field_1_1: <value>
nested_field_1_2: <value>
...
}
nesting_2: {
nesting_2_1: {
nested_field_2_1_1: <value>
nested_field_2_1_2: <value>
...
}
nesting_2_2: {
nested_field_2_2_1: <value>
nested_field_2_2_2: <value>
...
}
}
}
只需插入它,Presto就可以正确地为顶级(例如somefield
、otherfield
(和第一个嵌套级别中的值识别和创建列——也就是说,它为nesting_1
创建了一列,其内容是row(nested_field_1_1 <type>, nested_field_1_2 <type>, ...)
,我可以查询table.nesting1.nested_field_1_1
。
但是,表模式中缺少具有额外嵌套层的字段(例如nesting_2
及其内的所有字段(。Presto的MongoDB连接器文档确实提到:
在启动时,此连接器尝试猜测字段的类型,但它可能不适合您的集合。在这种情况下,您需要手动修改它。CREATE TABLE和CREATE TABLE AS SELECT将为您创建一个条目。
虽然这似乎解释了我的用例,但关于如何"手动修改"还不太清楚——CREATE TABLE
语句似乎不合适,因为表已经存在了。文档中还有一节介绍了如何声明字段及其类型,但也不太清楚如何处理多个嵌套级别。
我的问题是:如何设置Presto的MongoDB连接器,以便查询第三个嵌套层中的字段
答案可以假设:
- 所有嵌套字段的名称都是已知的
- 只有3层
- 不需要保留分层表布局(即,我不介意我得到的Presto表是否将所有嵌套字段都作为唯一列(如
somefield
(,而不是像上述示例中的nesting_1
那样具有行的一个字段( - 如果解决方案不要求我显式声明第三层中所有列的名称和类型(因为我有1500多个列(,则需要额外说明——但这不是一个硬性要求
在mongodb.properties
上,属性mongodb.schema-collection
可用于描述MongoDB集合的模式。如文档中所述,此属性是可选的,默认值为_schema
。
关于如何"手动修改"还不太清楚——CREATE TABLE语句似乎不合适,因为表已经存在了。
它应该是自动创建和填充的,但我注意到,在执行某些查询之前,它一直被填充,并且它只为查询的集合生成模式。
但是,存在一个打开的错误,某些字段/列不会自动拾取。
此外,一旦创建/填充集合的条目,它就不会自动更新,任何更新都需要手动完成(如果集合开始有新字段,则不会自动检测到这些字段(。
要手动更新模式,字段列只是字段数组中的另一个条目,如文档中所述,它有三个部分:
name
Presto表中列的名称,它需要与集合的名称字段匹配- 列的
type
Presto类型以下是可用的类型,ROW类型可用于嵌套特性 hidden
从DESCRIBE <table name>
和SELECT *
隐藏列。默认为false
我的问题是:如何设置Presto的MongoDB连接器,以便查询第三个嵌套层中的字段?
像您发布的MongoDB集合的模式定义将包含以下内容:
...
"fields": [
{
"name": "_id",
"type": "ObjectId",
"hidden": true
},
{
"name": "somefield",
"type": "varchar",
"hidden": false
},
{
"name": "otherfield",
"type": "varchar",
"hidden": false
},
{
"name": "nesting_1",
"type": "row(nested_field_1_1 varchar, nested_field_1_2 bigint)",
"hidden": false
},
{
"name": "nesting_2",
"type": "row(nesting_2_1 row(nested_field_2_1_1 varchar, nested_field_2_1_2 varchar),nesting_2_2 row(nested_field_2_2_1 varchar, nested_field_2_2_2 varchar))",
"hidden": false
}
]
...
可以使用.
对列进行查询,如:
SELECT nesting_2.nesting_2_1.nested_field_2_1_1 FROM table;
如果被查询的mongo集合没有固定的架构,如_schema
集合中所示,则Presto无法推断文档结构。
如果您愿意,可以选择使用字段mongodb.schema-collection
在连接器配置中显式声明模式,如文档中所述。您可以将其设置为存储相同值的不同mongo集合,然后直接创建此集合。
嵌套字段可以使用ROW
数据类型来声明,该数据类型也在文档中进行了描述,其行为类似于其他编程语言中的结构或字典。
您可以在mongodb中创建一个集合,例如在数据库中的"presto_schema",并插入类似的示例模式
db.presto_schema.insertOne({
"table" : "your_collection",
"fields" : [
{
"name" : "_id",
"type" : "ObjectId",
"hidden" : true
},
{
"name" : "last_name",
"type" : "varchar",
"hidden" : false
},
{
"name" : "id",
"type" : "varchar",
"hidden" : false
}
]})
在presto mongodb.properties中,添加如下属性:
mongodb.schema-collection=presto_schema
从现在起,presto将使用"presto_schema"而不是默认的"_schema"进行查询。