Je travaille avec MongoDB dans mon application Go, et extrait des données et les stocke dans un bson.M (qui. Voici un exemple, pour obtenir l'objet bson.M de la base de données, puis l'imprimer (appelons cet objet data):

[map[_id:ObjectID("XXXXXXX") address:XX decimal:18 providers:map[currency:value] symbol:LINK]

Ce qui me semble correct.

Je pense que je veux faire une boucle sur la carte dans le champ providers (comme vous pouvez le voir, c'est aussi une carte là-dedans). J'ai fait quelques tentatives, mais à chaque fois je suis bloqué.

En raison de ce que j'ai lu dans la documentation ici et les tests que j'ai fait, cela ressemble à un bson.M et primitive.M sont les mêmes, et ils sont chacun traités comme un map[string]interface{}.

Quand j'ai essayé de l'affirmer à un map[string]string, je fais une erreur de panique:

// code run
data["providers"].(map[string]string)

//error received
panic: interface conversion: interface {} is primitive.M, not map[string]string

La raison en est que je veux faire une boucle sur le champ providers, et lorsque j'essaye de faire une boucle telle quelle, j'obtiens cette erreur:

// code to run
for key, provider := range data["providers"] {...}

// error received
cannot range over data["providers"] (map index expression of type interface{})

J'ai lu que je devrais peut-être faire quelque chose avec le marshaling et le décodage, mais j'ai l'impression que je manque juste une étape pour savoir pourquoi j'aurais besoin de faire cela, ou comment ils pourraient aider.

En tout cas pour résumer:

  1. Comment une boucle sur une interface primitive.M / bson.M / map [string] {}?

  2. Comment convertir une interface primitive.M / bson.M / map [string] {} en une chaîne map [string]?

Il semble que j'essaie de faire le contraire de cette entrée, et il semble comme cette entrée me donne des informations contradictoires. En espérant modifier la question à mesure que je comprendrai mieux quel est mon vrai problème. Merci!

1
Patrick Collins 22 avril 2020 à 02:25

2 réponses

Meilleure réponse

Parler avec Burak Serdar a aidé à nous donner la réponse! Vous devez affirmer le data["providers"] à un primitive.M

for key, provider := range data["providers"].(primitive.M){...}

Point clé à noter: primitive.M est géré comme une interface map [string] {}

Comme Burak Serdar l'a mentionné, je ne peux pas affirmer cette instance d'un primitive.M à une chaîne map [string], car le interface dans map[string]interface{} est de type primitive.M. Donc à la place, je dois affirmer l'objet providers à un objet primitive.M, puis je peux faire une boucle dessus normalement.

Je ne parviens pas à convertir un primitive.M en une chaîne map [string]

1
Patrick Collins 22 avril 2020 à 00:10

Une assertion de type pour map[string]interface{} à map[string]string échouera, car il s'agit d'une assertion de type et non de conversion . Il vérifie uniquement si le type d'interface est ce que vous pensez être, et dans ce cas, il ne l'est pas. Vous devez itérer le map[string]interface{} et taper les valeurs:

for k,v:=range data.(primitive.M)["providers"] {
   if str, ok:=v.(string); ok {
      // Use k and str
   }
}
0
Burak Serdar 21 avril 2020 à 23:52