Querying Embedded Documents MongoDB

803 views Asked by At

Let me be straight with the question, OK I have document structure like

let the collection name be sample;

were i'll not be knowing the someIdAsString.

{
_id : ObjectId("someObjectId"),
test : {
    someIdAsString : {
        field1 : value1,
        field2 : value2
    },
            someOtherIdAsString : {}
            .....
            .....
            And so on
  }
}

I have the field1 & field2 values how do i query the collection using this information.

field1 & field2 will be known at run time lets say it's field1 = '33' & field2 = '3333' and the document like

{
_id : ObjectId("522182515f8wea670900001b"),
test : {
    522182515f8c4wd70900001b : {
    field1 : '33',
    field2 : '3333'
    },
        522182515f8cea670900001b : {}
        .....
        .....
        And so on
   }
}

Thanks

1

There are 1 answers

2
H.D. On

I suggest you to change the schema, so that this someIdAsString text becomes a value instead of a key, making the object in test become a list of objects. If you know every key, you can try

db.sample.find({$or: [
    {"test.someIdAsString.field1": value1,
     "test.someIdAsString.field2": value2},
    {"test.someOtherIdAsString.field1": value1,
     "test.someOtherIdAsString.field2": value2},
    ...
]})

For all your "someIdAsString" possibilities.

If you change the structure to:

{
    _id : ObjectId("someObjectId"),
    test : [
        {
            _id : someIdAsString,
            field1 : value1,
            field2 : value2
        },
        {
            _id : someOtherIdAsString,
            field1 : value3,
            field2 : value4
        },
        ...
    ]
}

You can change the query to:

db.sample.find({
    "test.field1": value1,
    "test.field2": value2
})

A workaround to use a query while still using your data structure without knowing the embedded key names would be a JavaScript in a $where operator.

db.sample.find(function(){
    var ttk;
    var tt = this.test;
    for(key in tt){
        ttk = tt[key]
        if(ttk.field1 === value1 && ttk.field2 === value2){
            return true;
        }
    }
    return false;
})