1

In my mongodb collection, I have a collection with two levels of embedded documents.

Collection
 - field1
 - field2
 - EmbeddedDocuments1
    - field_a
    - field_b
    - EmbeddedDocument_a
       - field_A
       - field_B
       - field_C
  - EmbeddedDocuments2
    - field_c
    - field_d
    - EmbeddedDocument_a
       - field_D
       - field_E
       - field_F
 - EmbeddedDocuments3
    - field_e
    - field_f
    - EmbeddedDocument_a
       - field_G
       - field_H
       - field_I

When I do a query to find a specific 2nd level document it takes a long time, ~= 500ms

The query I tried is something similar to the line below, which I only want to get the data from a 2nd level document.

db.collections.find({ "embedded_documents_1.embedded_documents_2._id":ObjectId("502e8f5565ce10780f00000c")  })

However, this returns the entire one collection, which contains field1, field2, all EmbeddedDocuments

Am I doing something wrong here?

Chris Heald
  • 61,439
  • 10
  • 123
  • 137
YP Hsiao
  • 57
  • 6

1 Answers1

0

Your query is searching for any document that matches "embedded_documents_1.embedded_documents_2._id":ObjectId("502e8f5565ce10780f00000c")

So it has returned in full each document that matches this. Embedded documents are by nature, documents within another document. So mongodb has returned the full document.

You need to limit the values returned to only the second level document. Have a look http://www.mongodb.org/display/DOCS/Querying#Querying-FieldSelection for information on how to limit your query.

daveh
  • 3,586
  • 1
  • 20
  • 13
  • I tied to limit by using db.collections.find({ "embedded_documents_1.embedded_documents_2._id":ObjectId("502e8f5565ce10780f00000c"), {"field_A"}:1 }) that returns all field A columns of data from the one collection. I just want to get that one 2nd level document. – YP Hsiao Sep 11 '12 at 02:13
  • Can you post the full document schema? You should be able to limit it using {"embedded_documents_2" : 1} Additionally, is your collection one massively nested document? Can you post the output of running count() on the collection. IE. db..count() – daveh Sep 11 '12 at 02:22
  • db..count() has about 10-20, each count has about one first level embedded document per day, and each first level document has about 300 2nd level documents. So it's growing everyday. I found this thread talking about getting a specific inner document, but it looks like there is no way to get it other than getting the entire array? http://stackoverflow.com/questions/10043965/how-to-get-a-specific-embedded-document-inside-a-mongodb-collection – YP Hsiao Sep 11 '12 at 02:32
  • looks like another person is trying to do the same. http://www.quora.com/MongoDB/Retrieving-an-embedded-document-from-the-a-mongo-document – YP Hsiao Sep 11 '12 at 02:47
  • 1
    @YPHsiao - Correct, there is no way to get a specific sub document only other than trying to limit to just that embedded document. The granularity of mongodb is at the document level. Embedded documents are sub objects of that original root document - thus anything matching a sub document causes the whole root to be considered a match. – daveh Sep 11 '12 at 02:55
  • so I guess the best practice is not to have anything to contain large set of embedded documents. I thought the purpose of using embedded document is to minimize the search area and hence faster search. – YP Hsiao Sep 11 '12 at 02:59
  • Not at all. Embedding documents can have the opposite effect. Having a number of documents and then a good index upon them is the better way of doing things. Work out what the granularity is of your data, ie what you need back from a single query and then work up from there. If your granularity involved having an embedded document, thats fine. But only because each time you query a relevant grain of data that embedded document is something worthwhile to your search – daveh Sep 11 '12 at 03:03
  • thx, time to modify the schema, good thing it's not difficult to change. – YP Hsiao Sep 11 '12 at 03:37