【问题标题】:Is there a way to diff two Avro GenericRecords in Java to obtain only the fields and values that changed?有没有办法在 Java 中区分两个 Avro GenericRecords 以仅获取更改的字段和值?
【发布时间】:2025-12-11 00:20:16
【问题描述】:

我想编写 Java 代码来区分保存在内存中的两个 GenericRecord,它们都具有相同的模式。我一直无法找到有关如何执行此操作的任何库或任何 Apache Avro Javadoc。

我希望尽可能高效,将 GenericRecords 转换为 JSON,然后对它们进行比较,然后将 JSON 转换回 GenericRecord 是不可取的,除非这是唯一存在的选项。

protected GenericRecord generateDeltaFieldsOnly(GenericRecord storedRecord, GenericRecord newRecord) 
{

    ObjectMapper objectMapper = new ObjectMapper();
    JsonNode storedRecordJson = objectMapper.readTree(storedRecord.toString());
    JsonNode newRecordJson = objectMapper.readTree(newRecord.toString());

}

【问题讨论】:

    标签: json avro


    【解决方案1】:

    抱歉现在才看到这个……

    只需将两者都保留为 genericRecords,并从架构中迭代更改您想要的字段。我有点这样做,但使用来自两个不同模式的 genericRecords 并用关键字标记模式描述,这些关键字通知基本上愚蠢的转换器进行映射。

    @Override
    public GenericRecord transform(GenericRecord source, GenericRecord reference) {
        GenericRecordBuilder builder = new GenericRecordBuilder(targetSchema);
        buildGenericRecord(builder, source);
        buildGenericRecord(builder, reference);
        return builder.build();
    }
    
    private void buildGenericRecord(GenericRecordBuilder builder, GenericRecord genericRecord) {
        String fullName = genericRecord.getSchema().getFullName();
        String targetField;
        for (Entry<String, String> entry : fromFieldToField.entrySet()) {
            if (entry.getKey().startsWith(fullName)) {
                targetField = entry.getKey().substring(entry.getKey().lastIndexOf('.') + 1);
                builder.set(entry.getValue(), genericRecord.get(targetField));
            }
    
        }
    
    }
    

    如果您使用相同的架构,对您来说会容易得多。

    for (Field field : storedRecord.getSchema().getFields()) {
    
            //do your mapping field to field
    
    }
    

    【讨论】:

      最近更新 更多