最近在使用prestosql做跨库查询,在查询mongodb的时候遇到了问题。
MongoDB是非结构化数据,presto其实已经做了很多工作帮助我们通过SQL的方式去查询它,并且返回的结果也尽量往传统结构化数据库的形式上靠拢,比如在presto sql中使用UNNEST方法,可以将array或map格式的字段平铺开,借用Cross join语法可以实现级联查询。
上面提到的UNNEST操作,通过查看prestosql(338版本)只支持array和map格式的列,否则会报错。
在实际使用presto的过程中,发现presto会自行维护一套schema数据(表结构),但是由于mongodb的无结构性,在presto自己生成的这一套schema中会发现有很多列缺失与错误的情况。
基于上面的原因,会导致有的列无法UNNEST,原因可能是这一列本身就不是匹配的数据类型,也有可能是这一列的数据类型被presto识别错了。
通过继续查看presto的源码,发现其识别schema的原理是查找当前表中第一条数据,然后判断其所有列的数据类型,进而当做整个表的schema定义了。
所以如果在有需要的情况下,可以先手动插入一条标杆数据,用于标注正确的mongodb表结构,让presto能正确识别,然后再插入剩余的业务数据,这样就能保证presto的功能正确运行。
在已经生成了错误schema的情况,并且不想清空mongodb数据,可以尝试手动删除对应库中_schema表(presto默认存储表结构的地方)中的记录,然后修改目标表中第一行数据 或者 在最开头插入标杆数据,然后执行一次表数据查询,又会重新出发一次schema的扫描和生成。