Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB: Query over a hash with special chars in keys

I'm starting to work with MongoDB (it looks AWESOME, BTW) and I have a question about a Hash data type in one of my collections. I theoretically have something that looks like this:

{
    "account_id": "BNM-X10-0123456789",
    "account_profile": {
        "Client code": "0123456789",
        "Discount %": "15"
    }
}

As you can see, the keys in the account_profile hash has some white spaces and special chars! I know that you probably would suggest "just change it for client_code and discount_pct", but I do not have control over that keys, they are completely user defined and, by nature, they FOR SURE will contain white spaces and special chars.

So, the original question is: how can I perform queries over that info? I —obviously— know that the dot notation as in db.foo.find({"account_profile.discount_pct": "15"}) will not work, but are there alternatives?

And as a side question, is there a better way to accomplish the same functionality while keeping all the info nested in the collection?

Thank y'all. :)

like image 831
Joel Cuevas Avatar asked Nov 02 '11 02:11

Joel Cuevas


2 Answers

according to the source below, you can use any UTF8 character in the field name -- the only exception is the '.' character which is not allowed in field names (because it's used to query sub-documents), and field names can't start with a '$' character..

See:

https://jira.mongodb.org/browse/SERVER-3229

like image 149
Tilo Avatar answered Nov 13 '22 00:11

Tilo


If you know the key name you can just query by

db.foo.find({'account_profile.discount_pct' : '15'})

check out the test data

> db.foofoo.insert({name:'ram',account_profile : {"Client code": "0123456789",'discount_pct' : 2}})
> db.foofoo.insert({name:'ram',account_profile : {"Client code": "0123456789",'discount_pct' : 2}})
> db.foofoo.insert({name:'ram',account_profile : {"Client code": "01236789",'discount_pct' : 5}})
> db.foofoo.insert({name:'ram',account_profile : {"Client code": "01236789",'discount_pct' : 2}})
> db.foofoo.insert({name:'ram',account_profile : {"Client code": "01236789",'discount %' : 2}})
> db.foofoo.insert({name:'ram',account_profile : {"Client code": "01236789",'discount_pct' : 4}})
> db.foofoo.insert({name:'ram',account_profile : {"Client code": "01236789",'discount_%' : 4}})
> db.foofoo.insert({name:'ram',account_profile : {"Client code": "01236789",'discount_%' : 2}})
> db.foofoo.find({'account_profile.discount_%': 2})
{ "_id" : ObjectId("4eb0c9965325a7760cfda3db"), "name" : "ram", "account_profile" : { "Client code" : "01236789", "discount_%" : 2 } }
> db.foofoo.find({'account_profile.discount_pct': 2})
{ "_id" : ObjectId("4eb0c9725325a7760cfda3d5"), "name" : "ram", "account_profile" : { "Client code" : "0123456789", "discount_pct" : 2 } }
{ "_id" : ObjectId("4eb0c97c5325a7760cfda3d7"), "name" : "ram", "account_profile" : { "Client code" : "01236789", "discount_pct" : 2 } }

Thanks to @Tilo for pointing out in the above comment, you can't have the period character '.' in the field name, since its representing the dot notation.

like image 34
RameshVel Avatar answered Nov 13 '22 01:11

RameshVel