为什么apache orc recordreader.searchargument()没有正确过滤?

vddsk6oq  于 2021-06-01  发布在  Hadoop
关注(0)|答案(2)|浏览(514)

下面是一个简单的程序:
将记录写入orc文件
然后尝试使用 predicate 下推读取文件( searchArgument )
问题:
这是在orc中使用 predicate 下推的正确方法吗?
这个 read(..) 方法似乎返回所有记录,完全忽略 searchArguments . 为什么?
笔记:
我还没有找到任何有用的单元测试来演示orc(github上的orc)中 predicate 下推的工作方式。我也找不到任何关于这个特性的清晰文档。我试着查看spark和presto代码,但没有找到任何有用的东西。
下面的代码是https://github.com/melanio/codecheese-blog-examples/tree/master/orc-examples/src/main/java/codecheese/blog/examples/orc

  1. public class TestRoundTrip {
  2. public static void main(String[] args) throws IOException {
  3. final String file = "tmp/test-round-trip.orc";
  4. new File(file).delete();
  5. final long highestX = 10000L;
  6. final Configuration conf = new Configuration();
  7. write(file, highestX, conf);
  8. read(file, highestX, conf);
  9. }
  10. private static void read(String file, long highestX, Configuration conf) throws IOException {
  11. Reader reader = OrcFile.createReader(
  12. new Path(file),
  13. OrcFile.readerOptions(conf)
  14. );
  15. //Retrieve x that is "highestX - 1000". So, only 1 value should've been retrieved.
  16. Options readerOptions = new Options(conf)
  17. .searchArgument(
  18. SearchArgumentFactory
  19. .newBuilder()
  20. .equals("x", Type.LONG, highestX - 1000)
  21. .build(),
  22. new String[]{"x"}
  23. );
  24. RecordReader rows = reader.rows(readerOptions);
  25. VectorizedRowBatch batch = reader.getSchema().createRowBatch();
  26. while (rows.nextBatch(batch)) {
  27. LongColumnVector x = (LongColumnVector) batch.cols[0];
  28. LongColumnVector y = (LongColumnVector) batch.cols[1];
  29. for (int r = 0; r < batch.size; r++) {
  30. long xValue = x.vector[r];
  31. long yValue = y.vector[r];
  32. System.out.println(xValue + ", " + yValue);
  33. }
  34. }
  35. rows.close();
  36. }
  37. private static void write(String file, long highestX, Configuration conf) throws IOException {
  38. TypeDescription schema = TypeDescription.fromString("struct<x:int,y:int>");
  39. Writer writer = OrcFile.createWriter(
  40. new Path(file),
  41. OrcFile.writerOptions(conf).setSchema(schema)
  42. );
  43. VectorizedRowBatch batch = schema.createRowBatch();
  44. LongColumnVector x = (LongColumnVector) batch.cols[0];
  45. LongColumnVector y = (LongColumnVector) batch.cols[1];
  46. for (int r = 0; r < highestX; ++r) {
  47. int row = batch.size++;
  48. x.vector[row] = r;
  49. y.vector[row] = r * 3;
  50. // If the batch is full, write it out and start over.
  51. if (batch.size == batch.getMaxSize()) {
  52. writer.addRowBatch(batch);
  53. batch.reset();
  54. }
  55. }
  56. if (batch.size != 0) {
  57. writer.addRowBatch(batch);
  58. batch.reset();
  59. }
  60. writer.close();
  61. }

}

noj0wjuj

noj0wjuj1#

我知道这个问题由来已久,但也许答案对某些人有用(我刚刚看到mac写了一条评论,说基本上和我几个小时前一样,但我认为一个单独的答案更明显)
orc在内部将数据分成所谓的“行组”(每个默认值有10000行),其中每个行组都有自己的索引。search参数仅用于筛选出没有行可以与search参数匹配的行组。但是,它不会过滤出单独的行。甚至可能是索引表示行组与搜索参数匹配,而其中没有一行与搜索参数匹配。这是因为行组索引主要由行组中每列的最小值和最大值组成。
因此,您必须遍历返回的行,并跳过与搜索条件不匹配的行。

lnxxn5zx

lnxxn5zx2#

我也遇到了同样的问题,我认为是通过改变 .equals("x", Type.LONG,.equals("x",PredicateLeaf.Type.LONG 在使用这个函数时,读取器似乎只返回包含相关行的批,而不是只返回我们要求的一次。

相关问题