Search code examples
mongodbdoctrineodm

How to get exact document result from key value type of embedded documents


Let say I have this kind of document structured, the attributes field will be the embedded document and I've already indexed the attributes.key and attributes.value

1-------------------------------------------------------------------------------------
{ 
  "_id" : ObjectId( "5191d8e5d00560402e000001" ),
  "attributes" : [ 
  { "key" : "pobox","value" : "QaKUWo" }, 
  { "key" : "city", "value" : "CBDRip" }, 
  { "key" : "address","value" : "zmycAa" } ],
  "email" : "FWAUdl_2@email.com",
  "firstname" : "FWAUdl_2" 
}
2-------------------------------------------------------------------------------------
{ 
  "_id" : ObjectId( "5191d8e7d00560402e000055" ),
  "attributes" : [ 
    { "key" : "pobox", "value" : "sNFriy" }, 
    { "key" : "city", "value" : "JPdVrI" }, 
    { "key" : "address", "value" : "phOluW" } ],
  "email" : "hqYNWH_86@email.com",
  "firstname" : "hqYNWH_86" 
}

My problem is how to get exact document when querying based only on the attributes field,

db.app.find({ attributes.key:address , attributes.value:/.*uw.*/i })

The query result is not as I expected, it should result only the 2nd document only without the 1st document. I know that I put regex on the attributes.value, I was expecting that it only check for attributes.key that have address value.

And what if I want to filter another key, such like,

db.app.find({ attributes.key:address , attributes.value:/.*uw.*/i , attributes.key:city , attributes.value:/.*ri.*/i })

Any opinion will be helpful guys. Thx.


Solution

  • Just investigated a little and figured out following. The following uses the index mentioned below. You can do a explain() on the find() to check more index usage details

    db.testing.getIndexKeys()
    [ { "_id" : 1 }, { "attributes.key" : 1, "attributes.value" : 1 } ]
    
    test:Mongo > db.testing.find({$and : [ { attributes : {$elemMatch : {key : 'address', value : /.*uw.*/i }} }, { attributes : {$elemMatch : {key : 'city', value : /.*ri.*/i }} }] }).pretty()
    {
        "_id" : ObjectId("5191d8e7d00560402e000055"),
        "attributes" : [
            {
                "key" : "pobox",
                "value" : "sNFriy"
            },
            {
                "key" : "city",
                "value" : "JPdVrI"
            },
            {
                "key" : "address",
                "value" : "phOluW"
            }
        ],
        "email" : "hqYNWH_86@email.com",
        "firstname" : "hqYNWH_86"
    }