1

I created an aggregate query that uses the 'parts' key as the '_id' and returns all the 'subparts' numbers associated in an array. The output from the aggregate query is undesirable as I get the array 'result' which contains 74755 dictionary objects. Each object contains an int 32 for the _id and an array for '#associated_subparts'. I can access sub-elements via:

db.agg_result.find({}, {_id: 0, result: { $slice: [0,2]}})      

but this is just a positional method. I tried variants of nested $elemMatch and $all queries with no success. I want to be able to return the object with id 468183339 for example. I might be projecting my original aggregate query incorrectly, but I'd like to return a collection without the nest so each object in the collection is one of these parts > subparts objects.

Example Query:

var agg_out = db.collection.aggregate( { $group :{ '_id' : "$parts#",
    'associated_subparts#' : { $addToSet : "$sub_part" }}});
db.agg_result.insert(agg_out);
db.agg_result.find();

Example Output:

{
    "_id" : ObjectId("52b4c4c6e984c01d69ff176f"),
    "result" : [ 
        {
            "_id" : 468183339,
            "associated_subparts#" : [ 
                -1408237536
            ]
        }, 
        {
            "_id" : 782155933,
            "associated_subparts#" : [ 
                -1408237536
            ]
        }, 
        {
            "_id" : 1583659973,
            "associated_subparts#" : [ 
                -1408237535, 
                -1408237535, 
                -1408237535, 
                -1408237535, 
                -1408237535, 
                -1408237535, 
                -1408237535, 
                -1408237535, 
                -1408237535, 
                -1408237535, 
                -1408237535, 
                -1408237535
            ]
        }
]
}

1 Answer 1

1

If I understand your problem correctly this time, the proper way to populate your agg_result collection would be to iterate over the result field of your aggregation query result document before inserting each subitem of the 'result' index in your agg_result collection, something like :

agg_out.result.forEach(function(x){db.agg_result.insert(x);});
Sign up to request clarification or add additional context in comments.

7 Comments

Hi Calimero, maybe I wasn't clear, I want to maintain the one to many relationship. So that I can see all the subparts related to unique parts. For example Car A would have Wheels X, Tires Y etc. Unwinding would get me Car A - Wheels X then another record Car A - Tires Y.
Thanks for the clarification, and sorry for the misunderstanding - just realized you did the exact opposite with your current aggregation query, and you posted the resulting collection. Hopefully my next update will be more helpful !
Ah thanks for making me re-read I just changed "example data" to "example result" that was confusing.
updated the answer. Haven't tested it though, but it should work as you expect.
Looks like you did it my friend :) I'm guessing there is no way to get the aggregate output like this in the first place, so I'll have to add this extra proc time. The _id gets converted from an int to a double with '.000000' appended to the original _id number (parts#), is there a way to specify that the _id remain the same? I know how to convert the variables after the fact, but I don't want to add extra computational overhead: db.collection.find({_id : {$exists : true}}).forEach(function(obj) { obj._id = new NumberInt(obj._id);
|

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.