title: MongoDB: Convert Array to CSV for Complex Data
body: <p>We have MongoDB documents called Notes that consist of a <code>Layout</code> section and a <code>Data</code> section. The <code>Data</code> section uses the <code>Layout</code> section to describe and label the fields. For example, here is a simplified sample of a Note document:</p>
  
  <pre><code>{
    "_id" : ObjectId("5aafefbecbf20b364c14d037"),
    "Title" : "Some Note Name",
      "CreatedDate" : ISODate("2018-10-22T13:12:20.343-04:00"),
    "Layout" : {
      "Name" : "Some Layout Name",
      "ComponentId" : "531a5112-2467-410c-a477-936c6527256b",
      "Tabs" : [
        {
          "Name" : "Some Tab Name",
          "Icon" : "tab",
          "Sections" : [
            {
              "Name" : "Some Section Name",
              "MappingId" : "SomeSectionId",
              "Sets" : [
                {
                  "SetId" : NumberLong("1"),
                  "Questions" : [
                    {
                      "MappingId" : "SomeShortAnswerId",
                      "Label" : "Some Short Answer Label",
                      "Set" : NumberLong("1"),
                      "QuestionType" : "ShortAnswer"
                    },
                    {
                      "MappingId" : "SomeMultipleChoiceId",
                      "Label" : "Some Multiple Choice Label",
                      "Set" : NumberLong("1"),
                      "QuestionType" : "MultipleChoice"
                    },
                    {
                      "MappingId" : "SomeYesNoId",
                      "Label" : "Some Yes No Label",
                      "Set" : NumberLong("1"),
                      "QuestionType" : "YesNo"
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    },
    "Data" : {
      "SomeSectionId" : [
        {
          "SomeShortAnswerId" : "blah blah blah",
          "SomeMultipleChoiceId" : [
            "Answer 1",
            "Answer 2",
            "Answer 3"
          ],
          "SomeYesNoId" : true
        }
      ]
    }
  }
  </code></pre>
  
  <p>You can see that the <code>Data</code> section field names correspond to the <code>Layout.Tabs.Sections</code> <code>MappingId</code> and <code>Questions.MappingId</code>. My current query works for returning just the data portion:</p>
  
  <pre><code>db.myCollection.aggregate( 
    [
      { $project: { CreatedDate: 1, Data: 1 } },
      { $unwind: "$Data.SomeSectionId" },
      {
          $addFields: {
              "Data.SomeSectionId.CreatedDate": "$CreatedDate",
              "Data.SomeSectionId._id": "$_id"
          }
      },
      { $replaceRoot: { newRoot: "$Data.SomeSectionId" } }
    ]
  )
  </code></pre>
  
  <p>and the data returned:</p>
  
  <pre><code>{
    "SomeShortAnswerId" : "blah blah blah",
    "SomeMultipleChoiceId" : [
      "Answer 1, Answer 2, Answer 3"
    ]
    "SomeYesNoId" : true
  }
  </code></pre>
  
  <p>Unfortunately, this data is passed on to a reporting application that has limitations and cannot handle the sub-array values for the multiple choice question answers. </p>
  
  <p>I need to format the data like this instead: </p>
  
  <pre><code>{
    "SomeShortAnswerId" : "blah blah blah",
    "SomeMultipleChoiceId" : "Answer 1, Answer 2, Answer 3",
    "SomeYesNoId" : true
  }
  </code></pre>
  
  <p>What makes this whole process so complicated is that besides the <code>Data</code> field name, all other field names are found in the <code>Layout</code> section (<code>MappingId</code>s).</p>
  
  <p>Can anyone suggest a way to convert the answer arrays to a single text comma separated value given the self-describing nature of our <code>Note</code> documents? This is killing me...</p>
  
  <p><strong>Update</strong></p>
  
  <p>I may not have made it clear that the Note contents above does not have fixed fields. I cannot count on <code>SomeShortAnswerId</code>, <code>SomeMultipleChoiceId</code>, or <code>SomeYesNoId</code> being there. Those fields might be or there might be additional multiple choice fields to convert to CSV format. It's all based on the contents of the <code>Layout</code> section.</p>
  
  <p>Is it possible to iterate through all the fields in a section (<code>Data</code>) without having to specify the actual field name? If that was possible, I could apply a $reduce to every field.</p>