12
votes

Apache Avro: Carte utilise le charcuternence comme clé

J'utilise Apache Avro .

Mon schéma a Type de carte: P>

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

                ]
                }
               }
}


3 commentaires

Compte tenu de votre commentaire sur une réponse: avez-vous découvert exactement ce qui se brise pour vous? Comme dans, est-ce que la carte vous utilisez réellement des touches string ?


Millimoose, la charcuterie de la carte générée pour la clé.


La carte générée utilise UTF8 par défaut et vous pouvez choisir de le faire une chaîne. Chaluquant est juste une interface.


6 Réponses :


3
votes

Quoi qu'il soit possible de forcer Avro à utiliser une chaîne , à l'aide de de charcuternence directement est une mauvaise implémentation car charcuternence n'est pas < Code> comparable et ne spécifie même même pas l'égalité de deux séquences identiques. Je suggère de déposer cela comme un bug contre Avro.


2 commentaires

En fait, même dans un cas assez trivial ( chaîne et stringbuilder ) Les codes de hachage ne correspondent pas: ideone.com/cx76yn . (Ils font pour Stringbuffer et StringBuilder Mais c'est probablement une conséquence de ce dernier étant surtout une copie de l'ancien avec la synchronisation supprimée.)


@Millimoose Stringbuffer et StringBuilder abstractstringbuilder donc aucune surprise qu'elles agissent comme elles agissent. Accepter que ceci est un problème de mise en œuvre.



5
votes

Apparemment, par défaut, Avro utilise charcuternence . J'ai trouvé Un moyen de la configurer pour convertir en Chaîne

de l'avroi 1.6.0 en cours, il existe une option pour que Avro effectue toujours la conversion en chaîne. Il y a quelques façons d'y parvenir. Le premier est de définir la propriété Avro.java.string dans le schéma à String: xxx

Je n'ai pas testé cela.


2 commentaires

C'est la bonne façon de le faire, et cette propriété est présente pour faire face à ce problème exact.


Est-ce une configuration par champ? Comment faites-vous cela pour la clé de carte? En outre, le lien est mort.



8
votes

Apparemment, il existe une solution de contournement pour ce problème dans Avro 1.6. Vous spécifiez le type de chaîne dans le fichier POM du projet:

  <stringType>String</stringType>


3 commentaires

Selon cette question, d'ajouter une insulte à une blessure, le Chaucefence Sous-classe utilisée est en fait une classe d'avreurs ( utf8 ) qu'ils auraient pu facilement fabriquer hasable / équatable à < Code> String Pour réduire une partie de la douleur.


C'est un bon point. Cela pourrait être un changement intéressant pour Avro s'il n'a pas encore été ajouté. D'autre part, la Chaluquant ne garantit pas le comportement de l'égalité, alors il est peut-être préférable d'utiliser de toute façon une totring () dans ces cas.


@Millimoose Non, ce n'est pas possible. Vous ne pouvez pas le faire fonctionner avec une chaîne, car la première chose à faire est de vérifier si l'autre objet passé dans Equals est une chaîne. Aucun implémentation sans chaîne de la Chaluquant peut avoir HASHCODE / est égal à Interop avec chaîne.



11
votes

Cette discussion de Jira est pertinente. Le principal point de charcuternence toujours utilisé est la compatibilité à l'envers forte>.

Et comme Charles Forsythe a souligné, il a été ajouté une solution de contournement lorsque la chaîne est nécessaire, en définissant la propriété String dans le schéma. p> xxx pré>

Le type par défaut ici est leur propre classe UTF8. En plus de la spécification manuelle et de Le paramètre POM.XML , il existe même une option de compilation d'Avro-Tools, l'option code> à -string p>

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


0 commentaires

-1
votes

Une solution rapide (le type de valeur pourrait être d'autres objets, maintenant je suis):

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;
}


0 commentaires

4
votes

Je pense que convertir explicitement la chaîne en UTF8 fonctionnera. "Certains_key" -> Nouveau UTF8 ("Certains_key") et utilisez-le comme votre clé pour la carte.


0 commentaires