mongodb - 如何使用 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 就可以正确识别并为顶层(例如somefield
, otherfield
)和第一个嵌套层中的值创建列——也就是说,它为 创建一个列nesting_1
,其内容是 a 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 个列——但这不是硬性要求。
解决方案
On mongodb.properties
,该属性mongodb.schema-collection
可用于描述 MongoDB 集合的模式。如文档中所述,此属性是可选的,默认值为_schema
.
关于如何“手动修改”不是很清楚—— CREATE TABLE 语句似乎不合适,因为表已经存在。
它应该是自动创建和填充的,但我注意到它会在某些查询被执行之前被填充,并且它只为被查询的集合生成模式。
但是,有一个开放的错误,某些字段/列不会自动拾取。
此外,一旦创建/填充了集合的条目,它将不会自动更新,任何更新都需要手动完成(如果集合开始具有新字段,则不会自动检测到它们)。
要手动更新架构,字段列只是字段数组中的另一个条目,如文档中所述,它具有三个部分:
name
Presto 表中列的 名称,需要与集合字段的名称匹配。type
列的 Presto 类型。以下是可用的类型,ROW 类型可用于嵌套属性。hidden
隐藏 和 中的DESCRIBE <table name>
列SELECT *
。默认为假。
我的问题是:如何设置 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;
推荐阅读
- java - 方法不会替换列表中的最后一个元素
- ruby-on-rails - 善用动作线
- hadoop - 使用 Hive Left Outer Join 的以下区别
- python - 根据 Python3 中的值传递可选参数
- php - 如何将字符串从 php 回显到 android studio
- oracle - oracle中CLOB的数据长度是多少?
- python - TensorFlow MovingAverageOptimizer 在 V1 和 V2 之间的兼容性
- laravel - 即使产品不可用,我怎样才能让买家仍然能够购买该产品?
- node.js - 当真正的 sequelize 连接在 require 树中时,为什么这个 sequelize-test-helper 调用不起作用?
- node.js - 尝试在项目中安装依赖项时出错