MongoDB: Query over a hash with special chars in k

2019-02-22 05:41发布

问题:

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. :)

回答1:

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



回答2:

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.