title: Loop over collections in mongodb and decode to various go structs
body: <p>I have a series of collections in a mongodb instance where I want to pull all the collections and decode all documents in the collections so I can mutate them as I go.</p>
  <p>I am using go to list the collection names:</p>
  <pre class="lang-golang prettyprint-override"><code>...
  collections, err := db.ListCollectionNames(context.TODO(), bson.M{})
  if err != nil {
      log.Fatalf(&quot;Failed to get coll names: %v&quot;, err)
  }
  
  for _, coll := range collections {
      collection := db.Collection(coll)
  ...
  </code></pre>
  <p>This works flawlessly and the next step would be to open a cursor to each collection and loop over the cursor and call decode on each object to its corresponding type.</p>
  <p>I have defined all the types in a types package:</p>
  <pre class="lang-golang prettyprint-override"><code>type Announcements struct {
      Id            string    `bson:&quot;_id&quot;`
      Content       string    `bson:&quot;content&quot;`
      Title         string    `bson:&quot;title&quot;`
      DateModified  time.Time `bson:&quot;dateModified,omitempty&quot;`
      ModifiedBy    string    `bson:&quot;modifiedBy,omitempty&quot;`
  }
  </code></pre>
  <p>The issue is that I cant define the variable to be used for decoding dynamically.</p>
  <p>This code would need to be repeated for every single collection</p>
  <pre class="lang-golang prettyprint-override"><code>var obj Announcements // This would need to be dynamic
  
  for cursor.Next(context.Background()) {
      err := cursor.Decode(&amp;obj)
      if err != nil {
          log.Fatal(err)
      }
  
      log.Printf(&quot;%#v\n&quot;, obj)
  }
  </code></pre>
  <p>Is there a way to do this without repeating this many times? I realize a dynamically typed language would be better for this. Wanted to ask before I migrate the work to a scripting language.</p>
  <p>I have tried using the reflect package and switch statements to instantiate the variable dynamnically and using the interface{} type but that force the decode to use bson types and not my defined structs.</p>
  <p>-- edit --</p>
  <p>I have tried to use a map to link collection names to types but to no avail.</p>
  <pre class="lang-golang prettyprint-override"><code>var Collections = map[string]interface{}{
      &quot;announcements&quot;:          Announcements{},
      &quot;badges&quot;:                 Badges{},
      &quot;betaUser&quot;:               BetaUser{},
      &quot;bonusLearningItems&quot;:     BonusLearningItems{},
      &quot;books&quot;:                  Books{},
  ...
  }
  </code></pre>
  <p>So that when I use the obj var I tried an assignment like:</p>
  <pre class="lang-golang prettyprint-override"><code>var obj types.Collections[coll]
  </code></pre>
  <p>hoping that would give me a variable of type Announcement if I was had looped to the announcements collection. but when I call decode it returns bson types.</p>
  <p>I need to dynamically define the obj variable type.</p>