4

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?

2
  • 1
    Unfortunately your schema is at a disadvantage here since there is no easy way to do that, you would need to make fields an array of objects Commented Sep 10, 2013 at 21:40
  • Thanks. I'm getting it and moving in the direction you advised. Commented Sep 11, 2013 at 5:55

2 Answers 2

4

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.

Sign up to request clarification or add additional context in comments.

1 Comment

It sure helps. Thank you.
0

Faced a similar issue and found this: https://stackoverflow.com/a/75338607/1527469, i.e. just convert the object to array, do the filter, then convert back:

db.encounter.aggregate([
    {
        "$set": {
            "form.fields": {
                "$objectToArray": "$form.fields"
            }
        }
    }, {

        "$match":
            {
                "form.fields.v.label": "TC"
            }
    },
    {
        "$set": {
            "form.fields": {
                "$arrayToObject": "$form.fields"
            }
        }
    }
])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.