kos
kos

Reputation: 23

Find by nested document values with random keys in mongodb


I have the following collection structure:

{
   _id : ObjectId('...'),
   randomKeysSubdocument : {
       'jhaksdf' : 'something',
       'jio348akgqug' : 'something else',
       'kgowe98akjg' : 'more things',
   }
}

where randomKeysSubdocument is a subdocument with random keys generated programmatically (and i don't know their names).
Is there a way how I can query by randomKeysSubdocument values in the same way as I would query them if randomKeysSubdocument were an array:

{
   _id : ObjectId('...'),
   randomKeysSubdocument : [
       'something',
       'something else',
       'more things',
   ]
}

Query:

db.my_collection.find({
    randomKeysSubdocument : 'something'
})

Upvotes: 2

Views: 883

Answers (1)

user3561036
user3561036

Reputation:

So it should be clear that you should not do this. Structuring documents with different key names is not a good pattern, and certainly does not work well with MongoDB or general database searching.

Only "data" can be indexed, so a better structure for you would be:

{
   randomKeysSubdocument : [
       { "key": 'jhaksdf', "data": 'something' },
       { "key": 'jio348akgqug', "data": 'something else' }
       { "key": 'kgowe98akjg', "data": 'more things' }
   ]
}

Where searching in the array as you note is already easy:

db.collection.find({ "randomKeysSubdocument.data": "something" })

And of course that can use an index to make things faster.


The way you currently have things you have to rely on JavaScript processing of $where for the match and cannot use an index for this:

db.collection.find(function() {
    var doc = this.randomKeysSubDocument;
    return Object.keys(doc).some(function(key) {
       return doc[key] == "something";
    });
})

Which is going to be much slower than a standard query and must test every document in the collection.

For mine, I would change the structure and move away from the pattern of using "data" as the names of keys, but put it in data instead where it belongs and keeps structures consistent for searching.

Upvotes: 2

Related Questions