12

我正在使用Apache Avro

我的架构有地图类型:

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

                ]
                }
               }
}

编译架构后,生成的JavaCharSequence用作 .Map MyData

CharSequence使用in作为键非常不方便Map,有没有办法在Apache AvroString中生成类型键?Map

附言

问题是,例如即使那里有这样的密钥dataMap.containsKey("SOME_KEY")也会返回,只是因为它是. 此外,使用现有键放置地图条目不会替换旧键。这就是为什么我说用作key不方便的原因。falseCharSequenceCharSequence

4

6 回答 6

11

这个 JIRA 讨论是相关的。仍在使用的 CharSequence 的要点是向后兼容

就像 Charles Forsythe 指出的那样,通过在模式中设置 string 属性,添加了一种解决方法,用于何时需要 String。

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

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

java -jar avro-tools.1.7.5.jar compile -string schema /path/to/schema .
于 2013-11-08T21:36:13.460 回答
8

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

  <stringType>String</stringType>

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

于 2013-11-01T15:04:28.177 回答
5

显然,默认情况下,Avro 使用CharSequence. 我找到了一种将其配置为转换为的方法String

从 Avro 1.6.0 开始,有一个选项可以让 Avro 始终执行到字符串的转换。有几种方法可以实现这一目标。首先是将架构中的 avro.java.string 属性设置为 String:

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

我没有测试过这个。

于 2013-11-01T15:02:06.707 回答
4

我认为将 String 显式转换为 Utf8 会起作用。"some_key" -> new Utf8("some_key") 并将其用作地图的键。

于 2016-05-06T21:52:18.257 回答
3

不管是否可以强制 Avro 使用 a StringCharSequence直接使用都是一个糟糕的实现,因为CharSequenceis 没有Comparable<CharSequence>,甚至没有指定两个相同序列的相等性。我建议将此作为针对 Avro 的错误提交。

于 2013-11-01T14:44:07.510 回答
-1

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

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;
}
于 2014-04-23T17:59:20.567 回答