Apache Avro:map使用CharSequence作为密钥

时间:2013-11-01 14:33:18

标签: java avro

我正在使用Apache Avro

我的架构有地图类型:

{"name": "MyData", 
  "type" :  {"type": "map", 
              "values":{
                   "type": "record",
                   "name": "Person",
                   "fields":[
                      {"name": "name", "type": "string"},
                      {"name": "age", "type": "int"},

                ]
                }
               }
}

编译架构后,生成的Java类使用CharSequence作为Map MyData

CharSequence中使用Map作为关键非常不方便,有没有办法为Apache Avro中的String生成Map类型键?< / p>

P.S。

问题在于,例如dataMap.containsKey("SOME_KEY")将返回false,即使有那样的密钥,只是因为它是CharSequence。此外,使用现有密钥放置一个映射条目不会重新使用旧密钥。这就是为什么我说使用CharSequence作为关键是不方便的。

6 个答案:

答案 0 :(得分:8)

This JIRA discussion是相关的。仍然使用CharSequence的要点是向后兼容性

就像Charles Forsythe所指出的那样,通过在模式中设置字符串属性,已经为必要时添加了一个变通方法。

 { "type": "string", "avro.java.string": "String" }

这里的默认类型是他们自己的Utf8类。除了手动规范和the pom.xml setting之外,还有一个avro-tools编译选项,-string选项:

java -jar avro-tools.1.7.5.jar compile -string schema /path/to/schema .

答案 1 :(得分:6)

显然,Avro 1.6中存在解决此问题的方法。您在项目的POM文件中指定字符串类型:

  <stringType>String</stringType>

本期中提到的是AVRO-803 ...虽然插件的网络文档没有反映这一点。

答案 2 :(得分:4)

显然,默认情况下,Avro使用CharSequence。我找到了a way to configure it to convert to String

  

从Avro 1.6.0开始,可以选择让Avro始终执行到String的转换。有几种方法可以实现这一目标。第一种是将模式中的avro.java.string属性设置为String:

         { "type": "string", "avro.java.string": "String" }

我没有测试过这个。

答案 3 :(得分:2)

无论是否可以强制Avro使用String,直接使用CharSequence是一个糟糕的实现,因为CharSequence不是Comparable<CharSequence>,甚至不指定两个相同序列的相等性。我建议将其视为针对Avro的错误。

答案 4 :(得分:0)

快速解决方案(值类型可以是其他对象,现在我是):

Map<String, String> convertToStringMap(Map<CharSequence, CharSequence> map){
    if (null == map){
        return null;
    }
    HashMap<String, String> result = new  HashMap<String, String>();
    for(CharSequence key: map.keySet()){
        CharSequence k_value = map.get(key);
        String s_key = key.toString();
        String s_value = k_value.toString();
        result.put(s_key, s_value);
    }
    return result;
}

答案 5 :(得分:0)

我认为明确地将String转换为Utf8会起作用。 “some_key” - &gt;新的Utf8(“some_key”)并使用它作为地图的关键。