mongodbmongodb-querymorphianosql

MongoDB / Morphia - Projection not working on recursive objects?


I have a test object which works as nodes on a tree, containing 0 or more children instances of the same type. I'm persisting it on MongoDB and querying it with Morphia.

I perform the following query:

db.TestObject.find( {}, { _id: 1, childrenTestObjects: 1 } ).limit(6).sort( {_id: 1 } ).pretty();

Which results in:

{ "_id" : NumberLong(1) }
{ "_id" : NumberLong(2) }
{ "_id" : NumberLong(3) }
{ "_id" : NumberLong(4) }
{
        "_id" : NumberLong(5),
        "childrenTestObjects" : [
                {
                        "stringValue" : "6eb887126d24e8f1cd8ad5033482c781",
                        "creationDate" : ISODate("1997-05-24T00:00:00Z")
                        "childrenTestObjects" : [
                                {
                                        "stringValue" : "2ab8f86410b4f3bdcc747699295eb5a4",
                                        "creationDate" : ISODate("2024-10-10T00:00:00Z"),
                                        "_id" : NumberLong(7)
                                }
                        ],
                        "_id" : NumberLong(6)
                }
        ]
}

That's awesome, but also a little surprising. I'm having two issues with the results:

1) When I do a projection, it only applies to the top elements. The children elements still return other properties not in the projection (stringValue and creationDate). I'd like the field selection to apply to all documents and sub documents of the same type. This tree has an undermined number of sub items, so I can't specify that in the query explicitly. How to accomplish that?

2) To my surprise, limit applied to sub documents! You see that there was one embedded document with id 6. I was expecting to see 6 top level documents with N sub documents, but instead got just 5. How to tell MongoDB to return 6 top level elements, regardless of what is embedded in them? Without that having a consistent pagination system is impossible.

All your help has made learning MongoDB way faster and I really appreciate it! Thanks!


Solution

  • As for 1), projections retain fields in the results. In this case that field is childrenTestObjects which happens to be a document. So mongo returns that entire field which is, of course, the entire subdocument. Projections are not recursive so you'd have to specify each field explicitly.

    As for 2), that doesn't sound right. it would help to see the query results without the projections added (full documents in each return document) and we can take it from there.