2

I have a valid JSON structure in MongoDB that needs to be changed on run time. Here is a valid snapshot of 3 such separate documents in a single collection: -

{
    company : "ABC",
    tags : ["ADMIN", "QA"],
    year : 2010,
    Project : [{
            Domain : "Telecom",
            tags : ["DEV", "ADMIN"],
            size : 15
        }, {
            Domain : "Retail",
            tags : ["ADMIN", "DEV"],
            size : 35
        }, {
            Domain : "Finance",
            tags : ["ADMIN"],
            size : 25
        }
    ]
}
{
    company : "ABC",
    tags : ["QA"],
    year : 2011,
    Project : [{
            Domain : "Telecom",
            tags : ["DEV"],
            size : 15
        }, {
            Domain : "Retail",
            tags : ["ADMIN", "DEV"],
            size : 35
        }, {
            Domain : "Finance",
            tags : ["ADMIN"],
            size : 25
        }
    ]
}
{
    company : "ABC",
    tags : ["QA"],
    year : 2012,
    Project : [{
            Domain : "Telecom",
            tags : ["DEV", "ADMIN"],
            size : 15
        }, {
            Domain : "Retail",
            tags : ["ADMIN", "DEV"],
            size : 35
        }, {
            Domain : "Finance",
            tags : ["ADMIN"],
            size : 25
        }
    ]
}

The structure needs to merge these 3 documents into 1 and then displayed in the following manner: -

{
    "company" : "ABC",
    "tags" : ["ADMIN", "QA"],
    "period" : {
        [{
                year : 2010,
                Project : [{
                        Domain : "Telecom",
                        tags : ["DEV", "ADMIN"],
                        size : 15
                    }, {
                        Domain : "Retail",
                        tags : ["ADMIN", "DEV"],
                        size : 35
                    }, {
                        Domain : "Finance",
                        tags : ["ADMIN"],
                        size : 25
                    }
                ]
            }
        ],
        [{
                year : 2011,
                Project : [{
                        Domain : "Telecom",
                        tags : ["DEV"],
                        size : 15
                    }, {
                        Domain : "Retail",
                        tags : ["ADMIN", "DEV"],
                        size : 35
                    }, {
                        Domain : "Finance",
                        tags : ["ADMIN"],
                        size : 25
                    }
                ]
            }
        ],
        [{
                year : 2012,
                Project : [{
                        Domain : "Telecom",
                        tags : ["DEV", "ADMIN"],
                        size : 15
                    }, {
                        Domain : "Retail",
                        tags : ["ADMIN", "DEV"],
                        size : 35
                    }, {
                        Domain : "Finance",
                        tags : ["ADMIN"],
                        size : 25
                    }
                ]
            }
        ]
    }
}

I know I can use map reduce and get this done. But I thought I should try writing a Java script function for this which could then be called whenever this needed to be done.

Assuming that the following function can be invoked using the collection , a recordset would be passed to the function below.

`var curlprojects = function()
{
    var arrSyn = new Array();
    var JSONString = "";
    var doc;
    var parent;
    var arrTop = new Array();
    while (myCursor.hasNext()) 
    {
        doc = myCursor.next();
        parent = doc.companyName;
        var fulltext = "{\"year\":" + tojson(doc.year) + ",\"project\":" + tojson(doc.project) + "}";
        JSONString = JSONString + fulltext;
    };
    arrSyn.push(JSONString);
    var outext = "{\"period\":" + JSONString + "}";
    print(outext);
}   `

Here's the problem. Eventhough the text appears to be JSON like when I generate it or print it out, it does not print to the screen.

The last line print(outext) displays some weird message asking whether I wish to display 181 preferences, and if I say yes - it lists all reserved words in java script !!!

Any suggestions would be appreciated.

1 Answer 1

2

As an alternative to using MapReduce or Javascript, you might want to consider using the aggregation framework instead.

The output you wanted could be generated in the Mongo shell using:

db.test.aggregate([

  //optional: match a single company
  {$match:{"company":"ABC"}},

  //expand the "tags" array
  {$unwind:"$tags"},

  //"group by" stage:
  {$group: {

    //group by company
    _id:"$company",

    //add unique tags into the "tags" array
    tags: {$addToSet:"$tags"},

    //add the "Project" details into the "period" array
    period: {$push: {year:"$year", Project:"$Project"}}
  }}
])
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.