Search code examples
javamongodbspring-data-mongodb

Mongo query inside Hashmap with unknown hash key


Platform: MongoDB, Spring, SpringDataMongoDB

I have a collection called "Encounter" with below structure

Encounter:

{ "_id" : "49a0515b-e020-4e0d-aa6c-6f96bb867288", 
    "_class" : "com.keype.hawk.health.emr.api.transaction.model.Encounter",  
    "encounterTypeId" : "c4f657f0-015d-4b02-a216-f3beba2c64be", 
    "visitId" : "8b4c48c6-d969-4926-8b8f-05d2f58491ae", 
    "status" : "ACTIVE", 
    "form" : 
    { 
        "_id" : "be3cddc5-4cec-4ce5-8592-72f1d7a0f093", 
        "formCode" : "CBC", 
        "fields" : { 
            "dc" : { 
                "label" : "DC", 
                "name" : "tc", 
            }, 
            "tc" : { 
                "label" : "TC", 
                "name" : "tc", 


            }, 
            "notes" : { 
                "label" : "Notes", 
                "name" : "notes", 
            } 
        }, 
        "notes" : "Blood Test", 
        "dateCreated" : NumberLong("1376916746564"), 
        "dateModified" : NumberLong("1376916746564"), 
        "staffCreated" : 10013, 
        "staffModified" : 10013

    }, 
}

The element "fields" is represented using a Java Hashmap as:

protected LinkedHashMap<String, Field> fields;

The Key to the hashmap () is not fixed, but generated at run time.

How do I query to get all documents in the collection where "label" = "TC"?

It's not possible to query like db.encounter.find({'form.fields.dc.label':'TC'}) because the element name 'dc' is NOT known. I want to skip that postion and the execute query, something like:

db.encounter.find({'form.fields.*.label':'TC'});

Any ideas?

Also, how do I best use indexes in this scenario?


Solution

  • If fields were an array and your key a part of the sub-document instead:

    "fields" : [
       { "key"   : "dc",
         "label" : "DC",
         "name"  : "dc"
       },
       { "key"   : "tc",
         "label" : "TC",
         "name"  : "tc"
       }
    ]
    

    In this case, you could simply query for any sub-element inside the array:

    db.coll.find({"form.fields.label":"TC"})
    

    Not sure how you would integrate that with Spring, but perhaps the idea helps? As far as indexes are concerned, you can index into the array, which gives you a multi-key index. Basically, the index will have a separate entry pointing to the document for each array value.