如何使用Presto查询MongoDB中的嵌套字段



我正在设置一个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就可以正确地为顶级(例如somefieldotherfield(和第一个嵌套级别中的值识别和创建列——也就是说,它为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语句似乎不合适,因为表已经存在了。

它应该是自动创建和填充的,但我注意到,在执行某些查询之前,它一直被填充,并且它只为查询的集合生成模式。

但是,存在一个打开的错误,某些字段/列不会自动拾取。

此外,一旦创建/填充集合的条目,它就不会自动更新,任何更新都需要手动完成(如果集合开始有新字段,则不会自动检测到这些字段(。

要手动更新模式,字段列只是字段数组中的另一个条目,如文档中所述,它有三个部分:

  • namePresto表中的名称,它需要与集合的名称字段匹配
  • 列的typePresto类型以下是可用的类型,ROW类型可用于嵌套特性
  • hiddenDESCRIBE <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"进行查询。

相关内容

  • 没有找到相关文章

最新更新