ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Apache Arrow C++ Dataset API 完全指南:多文件数据集发现、分区、扫描与写入实战

Apache Arrow C++ Dataset API 完全指南:多文件数据集发现、分区、扫描与写入实战 数据工程大数据序列化数据分析【免费下载链接】arrowApache Arrow is a multi-language toolbox for accelerated data interchange and in-memory processing项目地址https://gitcode.com/gh_mirrors/arrow13/arrow点击查看免费下载本文以 Apache Arrow 官方 C API 参考页 docs/source/cpp/api/dataset.rst 为骨架结合cpp/src/arrow/dataset下的真实源码与示例系统讲解arrow::dataset子模块的完整使用方式如何把散落在磁盘上、可能跨多种格式与目录结构的文件统一抽象为 Dataset如何通过分区Partitioning获得结构化元信息如何借助 Scanner 做列裁剪、行过滤与并行读取以及如何把内存数据写回为带分区的数据集。读完本文你将掌握 Dataset 七大 API 分组接口、分区、发现/工厂、扫描、具体实现、文件系统数据集、文件格式中每个类的职责、关键参数默认值与端到端编码流程。1. Dataset 模块定位与 API 文档的组织方式arrow::dataset是 Apache Arrow C 中负责语义化数据集读写的子模块。官方在 cpp/src/arrow/dataset/README.md 中的定位是为存放在不同位置、不同格式中的数据集提供统一的读写 API支持对分布在多个物理文件、多种序列化格式上的数据集做并行处理同时解决分区partitioning、过滤分区级与列级以及 schema 归一化等问题。其开发状态在 README 中明确标注为 Alpha/beta2020 年 4 月起API 可能变更且不保证弃用通知因此基于本仓库源码学习是掌握当前接口形态最可靠的途径。API 参考页 docs/source/cpp/api/dataset.rst 本身是 Doxygen 与 Sphinx 的聚合页面它把整个模块的组织结构清晰地划分为七个部分这与源码中的 Doxygen 分组一一对应参考页章节Doxygen 分组主要声明位置Interface直接doxygenclasscpp/src/arrow/dataset/dataset.h 中的Fragment、DatasetPartitioningdataset-partitioningcpp/src/arrow/dataset/partition.hDataset discovery/factoriesdataset-discoverycpp/src/arrow/dataset/discovery.hScanningdataset-scanningcpp/src/arrow/dataset/scanner.h 与 #L355Concrete implementationsdataset-implementationscpp/src/arrow/dataset/dataset.h#L231 中的InMemoryFragment、InMemoryDataset、UnionDataset等File System Datasetsdataset-filesystemcpp/src/arrow/dataset/file_base.h#L44 中的FileSource、FileSystemDatasetFile Formatsdataset-file-formatscpp/src/arrow/dataset/file_base.h#L43 及各格式实现在代码层面用户通常只需包含聚合头文件 cpp/src/arrow/dataset/api.h它会依次引入 dataset、discovery、file_base 等核心头并根据编译选项ARROW_CSV、ARROW_JSON、ARROW_ORC、ARROW_PARQUET条件性地引入对应格式头文件最后引入 scanner.h。此外如果要把数据集接入 Acero 执行引擎ExecNode需要先调用 cpp/src/arrow/dataset/plan.h 中的arrow::dataset::internal::Initialize()注册数据集相关的 exec 节点工厂。2. 核心接口Fragment 与 Dataset2.1 Fragment最小可独立扫描单元arrow::dataset::Fragmentcpp/src/arrow/dataset/dataset.h#L156表示 Dataset 中一个粒度化的数据片段典型实现就是一个文件。它的核心特征是可以脱离其他 Fragment 被单独读取/扫描扫描时产出一批RecordBatch。关键点在于每个 Fragment 都有自己定义良好的物理 schemaphysical schema这些物理 schema 可能与父 Dataset 的 schema 以及兄弟 Fragment 的物理 schema 不一致统一工作由容器 Dataset 负责——源码注释将其类比为 Avro 的 reader/writer schema 分离机制。Fragment 对外暴露的主要方法ReadPhysicalSchema()返回片段的物理 schema即 writer schema。这是一个可能发生高延迟文件系统 I/O 的阻塞调用schema 读取一次后会被缓存见 dataset.h#L161-L166。ScanBatchesAsync(options)异步版本的扫描入口返回RecordBatchGenerator即std::functionFuturestd::shared_ptrRecordBatch()。InspectFragment()扫描前对片段做检查学习列名等信息为后续的 schema 演化策略提供依据对应InspectedFragment结构dataset.h#L142-L146。BeginScan()基于FragmentScanRequest包含行过滤表达式、列选择FragmentSelection、格式相关扫描选项真正启动一次扫描返回可逐批读取的FragmentScanner。CountRows(predicate, options)仅基于元数据可能做少量 I/O 读元数据统计匹配过滤条件的行数如果无法满足则返回空optional。这是 Parquet 行组统计下推的基础。partition_expression()对该片段全部数据恒为真的表达式即分区信息表达式无分区信息时为kNoPartitionInformation即字面量true。FragmentScannerdataset.h#L113-L131是扫描片段的迭代器式对象ScanBatch(batch_number)按批次号异步读取一个RecordBatchEstimatedDataBytes(batch_number)估算该批次解码为 Arrow 格式后的数据字节数NumBatches()返回片段中的批次总数。源码特别保证FragmentScanner实例只会在所有进行中的扫描 Future 完成后才被销毁因此扫描过程中创建的回调可以安全地捕获this。2.2 Dataset零个或多个 Fragment 的容器arrow::dataset::Datasetdataset.h#L351-L410是 Fragment 的容器例如目录下深层嵌套的一组文件。它有一个统一的 schema扫描过程中所有 Fragment 都必须向该 schema 对齐。主要接口NewScan()返回一个ScannerBuilder用于构建新的扫描操作。GetFragments(predicate)/GetFragmentsAsync(predicate)根据谓词获取 Fragment 迭代器/异步生成器。schema()与partition_expression()分别返回统一 schema 和对整个数据集恒真的分区表达式。ReplaceSchema(new_schema)返回一个共享相同 Fragment、但使用不同 schema 的副本若新 schema 与原始 schema 不兼容则报错。Dataset 还持有DatasetEvolutionStrategy默认由MakeBasicDatasetEvolutionStrategy()创建它负责在扫描时把每个 Fragment 的物理 schema 演化到数据集 schema通过FragmentEvolutionStrategy::EvolveBatch完成类型转换例如磁盘上是 int32、数据集 schema 要求 int64 时自动 cast、通过DevolveSelection/DevolveFilter把数据集层的列选择与过滤表达式下放到 Fragment 层dataset.h#L271-L341。这解释了为什么不同文件可以拥有不同的物理 schema 却仍能被当作一个统一数据集读取。3. 数据集发现与工厂Dataset discovery/factories3.1 DatasetFactory 与检查流程arrow::dataset::DatasetFactorycpp/src/arrow/dataset/discovery.h#L85-L115提供先检查、后物化的两阶段流程InspectSchemas(options)取得各 Fragment 与分区的 schema 列表。Inspect(options)对这些 schema 做统一unify得到最终数据集 schema。Finish()/Finish(schema)/Finish(FinishOptions)物化出真正的Dataset。SetRootPartition(expr)为最终数据集设置根分区表达式。检查行为由InspectOptions控制discovery.h#L45-L65fragments决定检查多少个 Fragment 以推断统一 schema默认值为1只检查第一个片段对 schema 均匀的数据集这是最优值设为kInspectAllFragments-1则检查全部以稳健地统一可能不同的 schema设为0则完全不检查 Fragment只检查分区 schema。field_merge_options控制类型统一策略默认为严格合并类型必须完全一致但 null 可以与其他类型合并。FinishOptionsdiscovery.h#L67-L81则允许显式指定最终 schemaschema为空时通过inspect_options推断validate_fragments true时会对指定 schema 与各 Fragment schema 做校验校验多少片段同样由inspect_options控制。3.2 文件系统数据集工厂 FileSystemDatasetFactoryFileSystemDatasetFactorydiscovery.h#L204-L272是实践中使用频率最高的工厂它提供四种Make重载显式路径列表Make(filesystem, paths, format, options)FileSelector递归扫描Make(filesystem, selector, format, options)——selector 在调用时展开为FileInfo快照因此物化出的 Dataset 操作的是文件系统的快照带文件系统信息的 URIMake(uri, format, options)显式FileInfo列表Make(filesystem, files, format, options)其配套的FileSystemFactoryOptionsdiscovery.h#L150-L199包含四个关键配置partitioning显式的Partitioning或用于推断分区的PartitioningFactory。若提供工厂会基于文件/目录路径推断分区字段 schema 再构造 Partitioning默认是不产生任何分区信息的Partitioning::Default()。partition_base_dir应用分区前从路径中剥除的前缀。例如设为/dataset时/dataset/US/sales.csv会被交给分区器解析为US/sales.csv而/home/john/late_sales.csv不参与分区发现但仍属于 Dataset只是没有分区信息。对依赖目录顺序的DirectoryPartitioning尤为重要。exclude_invalid_files是否通过FileFormat::IsSupported逐个串行检查并剔除非法文件。开启会带来逐文件的串行 I/O 开销关闭则跳过检查但 Dataset 中可能混入不支持的非法文件扫描时报错。selector_ignore_prefixes当使用 Selector 发现文件时忽略匹配任一前缀的文件与目录默认值为{., _}即隐藏文件与下划线前缀如_metadata、.DS_STORE都会被跳过。示例代码 cpp/examples/arrow/dataset_documentation_example.cc#L161-L182 展示了最小发现流程构造FileSelectorbase_dir指向数据目录→FileSystemDatasetFactory::Make→factory-Finish()得到 dataset →dataset-GetFragments()打印每个 Fragment 路径 →dataset-NewScan()Finish()得到 scanner →ToTable()。3.3 UnionDatasetFactory合并多个数据源UnionDatasetFactorydiscovery.h#L122-L147接收一组子DatasetFactoryInspectSchemas会按精神上等同于检查首片段或全部片段的方式在每个子工厂上分别应用选项Finish后得到的是UnionDataset见下文。这是跨多个文件系统或目录合并数据集的入口。4. 分区Partitioning4.1 Partitioning 抽象arrow::dataset::Partitioningcpp/src/arrow/dataset/partition.h#L67-L104负责把字符串形式的分区标识符解析为分区表达式。例如标识符foo5可被解析为foo字段等于值5的相等表达式。路径从左到右消费必须相对于分区根目录前缀需先剥除。核心方法Parse(path)把路径解析为compute::Expression分区谓词。Format(expr)反向把表达式格式化为{directory, filename}。Partition(batch)若输入批次与分区共享字段则切分为满足互斥表达式的子批次。schema()分区 schema。PartitioningOrFactorypartition.h#L398-L427是一个可容纳显式 Partitioning 或 PartitioningFactory的变体类型正是FileSystemFactoryOptions::partitioning的字段类型通过GetOrInferSchema(paths)在需要时用工厂推断分区 schema。4.2 三种键值分区实现KeyValuePartitioningpartition.h#L172-L219是每段路径产出一个相等表达式这一常见场景的基类其下有三个具体实现DirectoryPartitioningpartition.h#L227-L250按 schema 字段顺序逐段解析路径所有字段都必须出现。例如 schemayear:int16, month:int8时路径/2009/11解析为(year 2009 and month 11)。类型通过MakeFactory(field_names)推断。HivePartitioningpartition.h#L274-L309源自 Apache Hive 的多级目录分区目录名为$key$value形式。字段顺序被忽略未知/缺失字段名也被忽略例如 schemayear:int16, month:int8, day:int8下路径/day321/ignored3.4/year2009解析为(year 2009 and day 321)。null 值使用硬编码回退字符串默认kDefaultHiveNullFallback __HIVE_DEFAULT_PARTITION__partition.h#L253可通过HivePartitioningOptions::DefaultsWithNullFallback自定义。FilenamePartitioningpartition.h#L353-L378从文件名而非目录中解析分区段同样支持MakeFactory(field_names)推断类型。此外FunctionPartitioningpartition.h#L312-L351允许用 lambda 直接提供Parse实现Format可选适用于完全自定义的分区逻辑。4.3 分区编码与工厂选项SegmentEncodingpartition.h#L107-L112枚举控制路径段的解码方式Uri默认表示路径段经过 URL 编码None表示无编码。PartitioningFactoryOptionspartition.h#L125-L140支持infer_dictionary推断为字典编码类型物化虚拟列更高效以及可选的期望schema仅校验发现的字段并更新内部字典状态。Hive 的工厂选项HivePartitioningFactoryOptions额外提供null_fallback字段。5. 扫描Scanning5.1 ScanOptions扫描级参数ScanOptionscpp/src/arrow/dataset/scanner.h#L60-L142定义了一次扫描的完整行为同一数据集可反复使用不同 ScanOptions 扫描。关键字段与默认值字段默认值说明filterliteral(true)行过滤表达式可下推给分区与读取层projection无投影表达式可增删/重命名列dataset_schema无读取批次的reader schema用于 CSV 等格式识别列类型projected_schema无投影后的批次 schema与 dataset_schema 相互独立batch_sizekDefaultBatchSize 1 17128Ki 行扫描批次的最大行数batch_readaheadkDefaultBatchReadahead 16片段内预读批次数量0 表示禁用use_threadsfalse时忽略fragment_readaheadkDefaultFragmentReadahead 4并行预读的片段数量poolarrow::default_memory_pool()物化与扫描数组的内存池use_threadsfalse是否并行扫描必须为 true 才会发生任何预读add_augmented_fieldstrue是否在输出 schema 中追加增强字段fragment_scan_options无片段级格式相关扫描选项backpressureAcero 默认慢消费者时计划暂停的参数MaterializedFields()scanner.h#L124-L137返回需要物化的字段集合——通常是投影与过滤表达式中引用字段的并集例如SELECT a, b WHERE a 2 c 1需要[a, b, a, c]这是 Fragment 实现做列子选择优化的依据。5.2 Scanner 与 ScannerBuilderScannerscanner.h#L380-L445负责把 Dataset 中每个 Fragment 变为扫描任务并可能地排序拼合 RecordBatch且默认不把整个数据集缓冲在内存中而是产出即可消费通过各类 readahead 参数控制在慢消费者追不上时暂停 I/O。主要方法ToTable()便捷方法串行物化全部扫描结果为Table需谨慎使用会占满内存。Scan(visitor)对每个TaggedRecordBatch记录批次 来源 Fragment调用访问器多线程时访问器需自行同步。ScanBatches()/ScanBatchesAsync()按序流式输出带 Fragment 标签的批次。ScanBatchesUnordered()/ScanBatchesUnorderedAsync()允许乱序输出以提升效率某些片段可能被缓存或更早被调度每个批次附带位置信息EnumeratedRecordBatch以便需要时恢复顺序。Head(n)、TakeRows(indices)取前 N 行、按行号取行。CountRows()/CountRowsAsync()尽可能基于片段元数据下推统计行数。ToRecordBatchReader()把 Scanner 包装为RecordBatchReader便于接入以 reader 为输入的 API。ScannerBuilderscanner.h#L450-L555是构造 Scanner 的工厂典型调用链为dataset-NewScan()获得 builder →Project/Filter/UseThreads/BatchSize/BatchReadahead/FragmentReadahead/Pool/FragmentScanOptions/Backpressure设置参数 →Finish()得到不可变的 Scanner。Project有两种重载按列名Project({b})或按表达式Project({expr1, expr2}, {col1, col2})。此外还提供FromRecordBatchReader(reader)从一次性的流式 reader 构造 scanner只能扫描一次用于流式写入场景。5.3 与 Acero 执行引擎的集成ScanNodeOptionsscanner.h#L562-L574把 Dataset 封装为 Acero 的 source ExecNode产出带片段/批次索引的批次以支持稳定排序ScanV2Optionsscanner.h#L157-L267提供更细粒度的列路径选择如只读取嵌套 struct 的某个子字段与target_bytes_readahead默认 32MiB跨所有片段统一预算等能力。使用这些 ExecNode 前需要调用 plan.h 中的internal::Initialize()注册节点工厂。6. 文件系统数据集File System Datasets6.1 FileSource统一的文件来源抽象FileSourcecpp/src/arrow/dataset/file_base.h#L50-L144描述文件实际所在位置支持四种形态路径 文件系统、FileInfo 文件系统、内存Buffer、以及自定义CustomOpen回调可附加压缩类型Compression::type。它提供Open()/OpenAsync()获得RandomAccessFile、OpenCompressed()获得按需解压的InputStream压缩类型可显式指定也可由文件名推断、Size()返回文件/缓冲区字节数。该抽象使同一套扫描逻辑既能作用于本地/远程文件系统也能作用于内存数据。6.2 FileFormat 与 FileFragmentFileFormatfile_base.h#L147-L213是所有格式实现Parquet、CSV、IPC、JSON、ORC的基类接口包括IsSupported(source)判断 FileSource 是否可被本格式读取。Inspect(source)返回文件 schema。MakeFragment(source, partition_expression, physical_schema)为 FileSource 创建FileFragment。ScanBatchesAsync/BeginScan/CountRows扫描与元数据计数。MakeWriter/DefaultWriteOptions写入相关DefaultWriteOptions()可能返回空指针表示该格式尚不支持数据集写入。FileFragmentfile_base.h#L216-L254是绑定已知格式与 FileSource 的 Fragment 实现ToString()直接返回源文件路径。FileSystemDatasetfile_base.h#L260-L330则由一个或多个FileFragment组成片段相互独立、不必共享格式或文件系统静态Make用于构造Write用于把扫描结果写回磁盘见第 7 节。注意同一个 FileSystemDataset 的 Fragment 不允许位于不同文件系统跨文件系统需使用UnionDataset。6.3 内存数据集与联合数据集InMemoryFragmentdataset.h#L237-L265从一个固定的RecordBatch集合产出扫描任务InMemoryDatasetdataset.h#L419-L447则由 schema 批次迭代器工厂或便捷地由Table构造UnionDatasetdataset.h#L450-L476包装多个子 Dataset要求子数据集 schema 与统一 schema 完全一致通过UnionDataset::Make构造。这三个类同属dataset-implementations分组配合工厂可实现内存数据 → 内存数据集 → 扫描 → 写入磁盘的完整闭环示例见 dataset_documentation_example.cc#L140-L156。7. 文件格式File Formats与数据集写入7.1 内置格式与条件编译本仓库的arrow::dataset内置五种格式实现均继承自FileFormatParquetcpp/src/arrow/dataset/file_parquet.h 中的ParquetFileFormatCSVcpp/src/arrow/dataset/file_csv.hIPC/Feathercpp/src/arrow/dataset/file_ipc.hJSONcpp/src/arrow/dataset/file_json.hORCcpp/src/arrow/dataset/file_orc.h格式是否可用由编译配置决定cpp/src/arrow/dataset/CMakeLists.txt 中ARROW_CSV、ARROW_JSON、ARROW_ORC、ARROW_PARQUET分别控制对应file_*.cc是否加入编译且 Parquet 会额外引入parquet_static/parquet_shared链接依赖聚合头 api.h 中的#ifdef与之对应。CMake 中ARROW_DATASET_PKG_CONFIG_REQUIRES为arrow-acero有 Parquet 时追加parquet表明 Dataset 依赖 Acero 执行引擎。以ParquetFileFormat为例file_parquet.h#L70-L119其ReaderOptions暴露dict_columns按列名指定字典列与coerce_int96_timestamp_unit默认NANO控制 Int96 时间戳的转换单位重载的MakeFragment(..., row_groups)支持把 Fragment 限制到指定行组集合配合CountRows的元数据统计即可实现按行组/统计信息裁剪的谓词下推这正是 Parquet 格式扫描性能的关键。7.2 数据集写入FileSystemDatasetWriteOptions写入入口是FileSystemDataset::Write(write_options, scanner)file_base.h#L284-L286全部行为由FileSystemDatasetWriteOptionsfile_base.h#L389-L463控制字段默认值说明file_write_options无单个片段文件的写入选项来自format-DefaultWriteOptions()filesystem/base_dir无目标文件系统与根目录partitioning无用于生成片段路径的分区器max_partitions1024单个批次最多可写入的分区数basename_template无片段基名模板{i}被自动递增整数替换可用basename_template_functor自定义如左填充零max_open_files900同时打开文件数上限配合 Linux 默认 1024 的文件描述符限制超限时关闭最久未用文件过低会导致数据碎片化max_rows_per_file0单文件行数上限0 表示不限制min_rows_per_group0积攒到足够行数才落盘写行组max_rows_per_group1 20大批次拆分为多个行组的阈值建议同时设置 min_rows_per_groupexisting_data_behaviorkError输出目录已存在时的行为create_dirtrue是否创建目录S3 等不需要目录的文件系统可关闭writer_pre_finish/writer_post_finish空回调每个 FileWriter 定稿前/后的钩子同一份选项也可包装为WriteNodeOptionsfile_base.h#L466-L486作为 Acero 的writeExecNode 选项并可携带custom_schema字段数/类型必须与输入一致可用于改元数据与可空性与custom_metadata。8. 端到端实战从发现、过滤、投影到分区读写仓库中的 cpp/examples/arrow/dataset_documentation_example.cc 是官方配套示例把上述 API 串成完整闭环。运行方式命令行示例为./dataset-documentation-example file:///some_path/some_directory parquet [mode]其中format支持feather、parquet、parquet_hivemode支持no_filter、filter、project、select_project、partitioned、filter_partitioned。各模式的代码要点如下。发现整个数据集no_filter用fs::FileSelector{base_dir}FileSystemDatasetFactory::Makefactory-Finish()得到 dataset再GetFragments()打印片段、NewScan()→Finish()→ToTable()读取全量数据示例ScanWholeDataset第 161-182 行。过滤 列裁剪filterauto scan_builder dataset-NewScan(); ARROW_RETURN_NOT_OK(scan_builder-Project({b})); ARROW_RETURN_NOT_OK(scan_builder-Filter( cp::less(cp::field_ref(b), cp::literal(4)))); auto scanner scan_builder-Finish(); return scanner-ToTable();其中cp即arrow::compute命名空间。注释明确指出Dataset 会把列选择下推尽可能减少实际读取的列数。表达式投影project/select_projectProject的表达式重载允许原地保留列、类型转换、按谓词派生布尔列scan_builder-Project( {cp::field_ref(a), cp::call(cast, {cp::field_ref(b)}, arrow::compute::CastOptions::Safe(arrow::float32())), cp::equal(cp::field_ref(c), cp::literal(1))}, {a_renamed, b_as_float32, c_1});select_project模式则先遍历dataset-schema()-fields()生成所有原列 一个派生列的表达式/名称列表再投影。分区数据写入parquet_hive先用InMemoryDataset(table)构造内存数据集经 scanner 后通过FileSystemDataset::Write写出auto partition_schema arrow::schema({arrow::field(part, arrow::utf8())}); auto partitioning std::make_sharedds::HivePartitioning(partition_schema); auto format std::make_sharedds::ParquetFileFormat(); ds::FileSystemDatasetWriteOptions write_options; write_options.file_write_options format-DefaultWriteOptions(); write_options.filesystem filesystem; write_options.base_dir base_path; write_options.partitioning partitioning; write_options.basename_template part{i}.parquet; ARROW_RETURN_NOT_OK(ds::FileSystemDataset::Write(write_options, scanner));分区发现与分区过滤partitioned/filter_partitioned发现时使用selector.recursive trueoptions.partitioning ds::HivePartitioning::MakeFactory()让工厂从目录路径推断分区 schema随后GetFragments()会打印每个片段的partition_expression()。分区过滤的威力在于对分区字段施加过滤如part b时不匹配分区的文件根本不会被读取示例FilterPartitionedDataset第 306-324 行。这与 discovery.h 中FileSystemFactoryOptions的partition_base_dir、selector_ignore_prefixes等配置配合可精确控制分区发现行为。9. 测试验证与延伸阅读模块内配套的测试文件为上述行为提供了可执行的事实依据值得按需查阅cpp/src/arrow/dataset/dataset_test.ccFragment/Dataset 接口、schema 演化EvolveBatch 类型转换与 InMemory/Union 实现的行为验证。cpp/src/arrow/dataset/discovery_test.ccInspectOptions 的fragments取值、FinishOptions 校验、四种 Make 重载与selector_ignore_prefixes等。cpp/src/arrow/dataset/partition_test.ccDirectory/Hive/Filename 分区解析、__HIVE_DEFAULT_PARTITION__空值回退与字典编码推断。cpp/src/arrow/dataset/scanner_test.cc 与 cpp/src/arrow/dataset/scanner_benchmark.cc扫描顺序、预读、CountRows 元数据下推及性能基准。cpp/src/arrow/dataset/file_parquet_test.cc、file_csv_test.cc、file_ipc_test.cc、file_json_test.cc、file_orc_test.cc各格式的扫描、写出与行为差异。若需要进阶探索还可参考cpp/examples/arrow/dataset_parquet_scan_example.cc与cpp/examples/arrow/dataset_skyhook_scan_example.cc两个扫描场景示例以及cpp/src/arrow/dataset/dataset_writer.cc中写入器的实际实现。结合本篇文章的分组地图参考页七个章节 ↔ 源码 Doxygen 分组 ↔ 头文件位置你即可在 docs/source/cpp/api/dataset.rst 的指引下按需深入任意一个类/分组的源码细节。赞分享数据工程大数据序列化数据分析【免费下载链接】arrowApache Arrow is a multi-language toolbox for accelerated data interchange and in-memory processing项目地址https://gitcode.com/gh_mirrors/arrow13/arrow点击查看免费下载相关推荐Apache Arrow C Dataset 完整 API 指南从 Fragment 扫描到多文件分区数据集Apache Arrow C Dataset 完整 API 指南从 Fragment 扫描到多文件分区数据集 Apache Arrow 的 arrow::大数据数据分析数据工程序列化Apache Arrow C Datasets 实战指南多文件表格式数据集的高效发现、扫描与分区读写Apache Arrow C Datasets 实战指南多文件表格式数据集的高效发现、扫描与分区读写 Apache Arrow C 的 Dataset数据工程数据分析大数据Apache Arrow 的 PyArrow Dataset API 权威指南多文件数据集读取、分区发现与写入Apache Arrow 的 PyArrow Dataset API 权威指南多文件数据集读取、分区发现与写入 本文围绕 Apache Arrow Pytho数据工程数据分析大数据创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表