为什么 Apache Orc RecordReader.searchArgument() 没有正确过滤?
Why is Apache Orc RecordReader.searchArgument() not filtering correctly?
这是一个简单的程序:
- 将记录写入 Orc 文件
- 然后尝试使用谓词下推 (
searchArgument
) 读取文件
问题:
- 这是在 Orc 中使用谓词下推的正确方法吗?
read(..)
方法似乎return所有记录,完全忽略了searchArguments
。这是为什么?
备注:
我找不到任何有用的单元测试来演示谓词下推在 Orc 中的工作原理(Orc on GitHub). Nor am I able to find any clear documentation on this feature. Tried looking at Spark and Presto 代码,但我找不到任何有用的东西。
的修改版本
public class TestRoundTrip {
public static void main(String[] args) throws IOException {
final String file = "tmp/test-round-trip.orc";
new File(file).delete();
final long highestX = 10000L;
final Configuration conf = new Configuration();
write(file, highestX, conf);
read(file, highestX, conf);
}
private static void read(String file, long highestX, Configuration conf) throws IOException {
Reader reader = OrcFile.createReader(
new Path(file),
OrcFile.readerOptions(conf)
);
//Retrieve x that is "highestX - 1000". So, only 1 value should've been retrieved.
Options readerOptions = new Options(conf)
.searchArgument(
SearchArgumentFactory
.newBuilder()
.equals("x", Type.LONG, highestX - 1000)
.build(),
new String[]{"x"}
);
RecordReader rows = reader.rows(readerOptions);
VectorizedRowBatch batch = reader.getSchema().createRowBatch();
while (rows.nextBatch(batch)) {
LongColumnVector x = (LongColumnVector) batch.cols[0];
LongColumnVector y = (LongColumnVector) batch.cols[1];
for (int r = 0; r < batch.size; r++) {
long xValue = x.vector[r];
long yValue = y.vector[r];
System.out.println(xValue + ", " + yValue);
}
}
rows.close();
}
private static void write(String file, long highestX, Configuration conf) throws IOException {
TypeDescription schema = TypeDescription.fromString("struct<x:int,y:int>");
Writer writer = OrcFile.createWriter(
new Path(file),
OrcFile.writerOptions(conf).setSchema(schema)
);
VectorizedRowBatch batch = schema.createRowBatch();
LongColumnVector x = (LongColumnVector) batch.cols[0];
LongColumnVector y = (LongColumnVector) batch.cols[1];
for (int r = 0; r < highestX; ++r) {
int row = batch.size++;
x.vector[row] = r;
y.vector[row] = r * 3;
// If the batch is full, write it out and start over.
if (batch.size == batch.getMaxSize()) {
writer.addRowBatch(batch);
batch.reset();
}
}
if (batch.size != 0) {
writer.addRowBatch(batch);
batch.reset();
}
writer.close();
}
}
我遇到了同样的问题,我认为已通过更改
得到纠正
.equals("x", Type.LONG,
至
.equals("x",PredicateLeaf.Type.LONG
在使用这个时,reader 似乎 return 只有具有相关行的批次 ,而不仅仅是我们要求的一次。
我知道这个问题很老,但也许答案对某些人有用。 (而且我刚刚看到mac几个小时前写了一个评论说和我基本一样,但是我觉得单独的回答更好看)
Orc 在内部将数据分成所谓的 "row groups"(默认情况下每行 10000 行),其中每个行组都有自己的索引。搜索参数仅用于过滤掉没有行可以匹配搜索参数的行组。但是,它不会过滤掉个别行。甚至可能是索引表明行组与搜索参数匹配,但实际上没有一行与搜索匹配。这是因为行组索引主要由行组中每一列的最小值和最大值组成。
因此您必须遍历返回的行并跳过与您的搜索条件不匹配的行。
这是一个简单的程序:
- 将记录写入 Orc 文件
- 然后尝试使用谓词下推 (
searchArgument
) 读取文件
问题:
- 这是在 Orc 中使用谓词下推的正确方法吗?
read(..)
方法似乎return所有记录,完全忽略了searchArguments
。这是为什么?
备注:
我找不到任何有用的单元测试来演示谓词下推在 Orc 中的工作原理(Orc on GitHub). Nor am I able to find any clear documentation on this feature. Tried looking at Spark and Presto 代码,但我找不到任何有用的东西。
的修改版本public class TestRoundTrip {
public static void main(String[] args) throws IOException {
final String file = "tmp/test-round-trip.orc";
new File(file).delete();
final long highestX = 10000L;
final Configuration conf = new Configuration();
write(file, highestX, conf);
read(file, highestX, conf);
}
private static void read(String file, long highestX, Configuration conf) throws IOException {
Reader reader = OrcFile.createReader(
new Path(file),
OrcFile.readerOptions(conf)
);
//Retrieve x that is "highestX - 1000". So, only 1 value should've been retrieved.
Options readerOptions = new Options(conf)
.searchArgument(
SearchArgumentFactory
.newBuilder()
.equals("x", Type.LONG, highestX - 1000)
.build(),
new String[]{"x"}
);
RecordReader rows = reader.rows(readerOptions);
VectorizedRowBatch batch = reader.getSchema().createRowBatch();
while (rows.nextBatch(batch)) {
LongColumnVector x = (LongColumnVector) batch.cols[0];
LongColumnVector y = (LongColumnVector) batch.cols[1];
for (int r = 0; r < batch.size; r++) {
long xValue = x.vector[r];
long yValue = y.vector[r];
System.out.println(xValue + ", " + yValue);
}
}
rows.close();
}
private static void write(String file, long highestX, Configuration conf) throws IOException {
TypeDescription schema = TypeDescription.fromString("struct<x:int,y:int>");
Writer writer = OrcFile.createWriter(
new Path(file),
OrcFile.writerOptions(conf).setSchema(schema)
);
VectorizedRowBatch batch = schema.createRowBatch();
LongColumnVector x = (LongColumnVector) batch.cols[0];
LongColumnVector y = (LongColumnVector) batch.cols[1];
for (int r = 0; r < highestX; ++r) {
int row = batch.size++;
x.vector[row] = r;
y.vector[row] = r * 3;
// If the batch is full, write it out and start over.
if (batch.size == batch.getMaxSize()) {
writer.addRowBatch(batch);
batch.reset();
}
}
if (batch.size != 0) {
writer.addRowBatch(batch);
batch.reset();
}
writer.close();
}
}
我遇到了同样的问题,我认为已通过更改
得到纠正.equals("x", Type.LONG,
至
.equals("x",PredicateLeaf.Type.LONG
在使用这个时,reader 似乎 return 只有具有相关行的批次 ,而不仅仅是我们要求的一次。
我知道这个问题很老,但也许答案对某些人有用。 (而且我刚刚看到mac几个小时前写了一个评论说和我基本一样,但是我觉得单独的回答更好看)
Orc 在内部将数据分成所谓的 "row groups"(默认情况下每行 10000 行),其中每个行组都有自己的索引。搜索参数仅用于过滤掉没有行可以匹配搜索参数的行组。但是,它不会过滤掉个别行。甚至可能是索引表明行组与搜索参数匹配,但实际上没有一行与搜索匹配。这是因为行组索引主要由行组中每一列的最小值和最大值组成。
因此您必须遍历返回的行并跳过与您的搜索条件不匹配的行。