fgallego
fgallego

Reputation: 39

MongoDB Extract subarrays from documents

How do I pass from this collection of documents

/* 1 */
{
    "F" : [ 
        {
            "n" : "test1",
            "v" : "value1"
        }, 
        {
            "n" : "test2",
            "v" : "value2"
        }
    ],
    "POR" : [ 
        {
            "n" : "1test1",
            "v" : "1value1"
        }, 
        {
            "n" : "1test2",
            "v" : "1value2"
        }, 
        {
            "n" : "1test3",
            "v" : "1value3"
        }
    ]
}

/* 2 */
{
    "F" : [ 
        {
            "n" : "2test1",
            "v" : "2value1"
        }, 
        {
            "n" : "2test2",
            "v" : "2value2"
        }
    ],
    "POR" : [ 
        {
            "n" : "2test1",
            "v" : "2value1"
        }, 
        {
            "n" : "2test2",
            "v" : "2value2"
        }
    ]
}

/* 3 */
{
    "F" : [ 
        {
            "n" : "3test1",
            "v" : "3value1"
        }, 
        {
            "n" : "3test2",
            "v" : "3value2"
        }
    ],
    "POR" : [ 
        {
            "n" : "3test1",
            "v" : "3value1"
        }
    ]
}

to this:

{
    "ITEMS": [
        { "n": "2test1", "v": "2value1" },
        { "n": "2test2", "v": "2value2" },
        { "n": "1test1", "v": "1value1" },
        { "n": "1test2", "v": "1value2" },
        { "n": "1test3", "v": "1value3" },
        { "n": "3test1", "v": "3value1" }
    ]
}

I want to extract subarray elements from serveral documents and I can't find the way/method.

First approach tried:

db.test.aggregate( [ { $unwind : "$POR" } ] ).pretty();

Upvotes: 2

Views: 55

Answers (1)

robjwilkins
robjwilkins

Reputation: 5672

I think this does what you need:

> db.uwnd.aggregate([
     {$unwind:"$F"},
     {$unwind:"$POR"},
     {$group:{_id:null,items:{$addToSet:"$F",$addToSet:"$POR"}}}
   ]).pretty()

Given the data above this will return the following document:

{
        "_id" : null,
        "items" : [
                {
                        "n" : "1test3",
                        "v" : "1value3"
                },
                {
                        "n" : "1test1",
                        "v" : "1value1"
                },
                {
                        "n" : "1test2",
                        "v" : "1value2"
                },
                {
                        "n" : "2test1",
                        "v" : "2value1"
                },
                {
                        "n" : "2test2",
                        "v" : "2value2"
                },
                {
                        "n" : "3test1",
                        "v" : "3value1"
                }
        ]
}

So the query unwinds both of the arrays, then groups the data, adding entries to a new items array from both the "F" and "POR" objects

Upvotes: 1

Related Questions