benui
benui

Reputation: 6798

MongoDB - Query by sub-tree

I have a document structure that the same as the simplified version shown below:

{
  some_other_props: { ... },
  systems: {
    sys1: {
      score: 24,
      metric: 52
    },
    another_sys: {
      score: 9,
      metric: 77
    },
    some_other_sys: {
      score: 12,
      metric: 5
    }
  }
}

I'd like to return all the documents where score : { "$gte" : 15 } is true for any of the sub-documents.

The only way I could think of doing this was to get the list of keys in system and concat that into some kind of or-statement mess. But it seems like I'm doing something wrong.

I could reformat the document structure so that each system is in its own document... but there's a lot of other information in some_other_props and reformatting now would be a pain.

In truth I'm trying to do something a bit more complex. Return all the documents where the difference between the score and metric of the same system are very different. But before I can do that I wanted to make sure I could just do simple queries on sub-trees as I've shown above.

Can anyone suggest how to query sub-trees in MongoDB?

Upvotes: 3

Views: 2056

Answers (2)

frail
frail

Reputation: 4118

If you now exactly what is getting scored you can make a fat "or" query :

$or : [{ systems.sys1.score : { "$gte" : 15 } }, {systems.another_sys.score : { "$gte" : 15 }}]

but it seems like a lame way to solve the problem. so my suggestion is make a different catalog for system_scores which have a many to one reference to system_props collection. That would make it much more easier to query.

Upvotes: 0

Thilo
Thilo

Reputation: 262474

You should consider storing the sub-documents as an array:

{
  some_other_props: { ... },
  systems: 
    [ {id: 'sys1',
      score: 24,
      metric: 52
    },
    { id: 'another_sys',
      score: 9,
      metric: 77
    }]

}

Then you can just query find 'systems.score' : { '$gte' : 15 } , and you can also build an index for 'systems.score' if you feel that you need it.

Upvotes: 4

Related Questions