0

I have several solutions, which in term may hold several projects. I modeled this relationship by embedding the projects in the solution document, e.g.

[{
    _id: "1",
    solutionTitle:  "Some Test Solution",        
    projects: [
      {
         _id: "12",
         type: "Java",
         title: "Test Project"
      },
      {
         _id: "13",
         type: "Misc",
         title: "Test Project"
      }
    ]
 },
 {
    _id: "2",
    solutionTitle:  "A Different Solution",  
    projects: [
      {
         _id: "21",
         type: "Java",
         title: "Another Java Project"
      }
    ]
 }]

Now I want to select all projects of a special type, e.g. Java. I tried the following query with aggregation:

db.Solutions.aggregate ( 
    { "$unwind": "$projects" }, 
    { "$match": {"projects.type": "Java" } }, 
    { "$project": {"projects" : 1, "_id": 0, "solutionTitle": 0 } } 
)

This works fine but the result doesn't look like what I expected. I get

{
    projects: {
        _id: "12",
        type: "Java",
        title: "Test Project"
    },
    projects: {
        _id: "21",
        type: "Java",
        title: "Another Java Project"
    }
}

How can I get the result to be a list of projects, e.g.

[
    { _id: "12", type: "Java", title: "Test Project" }
    ...
]

I checked this SO question and this one, but they do not really cover what I need. Any help is greatly appreciated.

1 Answer 1

1

If you want them to be in an array, you'll need to add them to an array:

db.Solutions.aggregate ([
    { "$unwind": "$projects" }, 
    { "$match": {"projects.type": "Java" } }, 
    { "$group": {"_id": null, "projects": { "$push": "$projects" } } }
])

In light of your comments below, it seems what you really want is to return the project subdocuments as if they were the documents you were searching. In which case you should $project your project values explicitly:

db.Solutions.aggregate ([
    { "$unwind": "$projects" }, 
    { "$match": {"projects.type": "Java" } }, 
    { "$project": {"_id": "$projects._id", "type": "$projects.type", "title": "$projects.title" } }
])
Sign up to request clarification or add additional context in comments.

4 Comments

Can I get it without the object wrapper as well? Just a list of projects directly? Now I get an object with a property projects, which is a list.
I have updated my answer to satisfy that requirement.
Thx! Is there a way to take all fields automatically? This is rather tiresome if you have a lot of columns.
I don't believe there is, but I'd be happy to be proved wrong on that.

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.