Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB: Query a key having space in its name

I want to retrieve values of only certain keys from a MongoDB collection.

But, the collection has some keys which have a 'space' in their name like:

"Parent":{"key1": //some string,
          "key2": //some string,
          "key 3": //some string}

I know this is a wrong approach as there shouldn't ideally be spaces in a key name but nevertheless how do I query this key? I am using Python and PyMongo.

For normal keys I can do this:

db.coll_name.find({"key": "India"}, {"_id": 0, "Parent.key1": 1, "Parent.key2": 1})

So how do I use the key "Parent['key 3']" in the second argument of the above query? Is there any way to achieve this?

Here's the query which returns data(works):

db.coll_name.find({}, {"Parent.key1": 1, "_id": 0})

Here's the query which doesn't return data:

db.coll_name.find({}, {"Parent['key 3']": 1, "_id": 0})
like image 608
Tarun Dugar Avatar asked Jul 12 '15 11:07

Tarun Dugar


People also ask

What is name space in MongoDB?

The official definition of "namespace" is here: The canonical name for a collection or index in MongoDB. The namespace is a combination of the database name and the name of the collection or index, like so: [database-name]. [collection-or-index-name]. All documents belong to a namespace.

How do I trim a space in MongoDB?

The character(s) to trim from input . The argument can be any valid expression that resolves to a string. The $trim operator breaks down the string into individual UTF code point to trim from input . If unspecified, $trim removes whitespace characters, including the null character.

Is MongoDB keys case sensitive?

Database names and Collection names are case sensitive. You can always recreate the DB/Collection with the appropriate name. The Mongo Shell is a interactive JS interpreter. and because JS is case sensitive then the shell is.


2 Answers

Well the only way you could have constructed this is like:

content = {};
content["Parent"] = {}
content["Parent"]["key2"] = 1
content["Parent"]["key 3"] = 1

db.coll_name.insert(content)

But you seem to be missing that there is nothing wrong with doing this:

db.coll_name.find({ "Parent.key 3":  1} )

Or in projection

 db.coll_name.find({}, { "Parent.key 3": 1 })

It's "dot notation" and not object notation, and as long as you quote the key names ( which is mandatory for dot notation ) then all it fine and you can have a space in there.

like image 98
Blakes Seven Avatar answered Oct 16 '22 20:10

Blakes Seven


I know this is a wrong approach as there shouldn't ideally be spaces in a key name but nevertheless how do I query this key?

What I will suggest is:

  • Remove space from documents key using bulk write operations

    bulk = coll_name.initialize_unordered_bulk_op()
    count = 1000
    
    for doc in coll_name.find():
        parent = {}
        parent.setdefault('Parent', {})
        for key, val in doc['Parent'].items():
            parent['Parent'][key.replace(' ', '')] = val
            bulk.find({'_id': doc['_id']}).update({'$set': parent})
            count += 1
            if count % 1000 == 0:
                # Execute per 1000 operations and re-init.
                bulk.execute()
                bulk = coll_name.initialize_unordered_bulk_op()
    # Clean up queues
    if count % 1000 != 0:
        bulk.execute()
    
  • Then your projection become simpler

    db.coll_name.find({'key': 'India'}, {'_id': 0, 'Parent.key1': 1, 'Parent.key2': 1, 'Parent.key3': 1 })
    
like image 31
styvane Avatar answered Oct 16 '22 19:10

styvane