首页 > 解决方案 > 如何使用 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 连接器,以便可以查询第三嵌套层中的字段?

答案可以假设:

标签: mongodbpresto

解决方案


On mongodb.properties,该属性mongodb.schema-collection可用于描述 MongoDB 集合的模式。如文档中所述,此属性是可选的,默认值为_schema.

关于如何“手动修改”不是很清楚—— CREATE TABLE 语句似乎不合适,因为表已经存在。

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

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

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

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

  • namePresto 表中的 名称,需要与集合字段的名称匹配。
  • 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;

推荐阅读