Jay
Jay

Reputation: 24905

How to create a dot notation based PyMongo Query dynamically?

I have few documents stored in MongoDB, where one of the fields has the below format:

Document Field

{field1:{inner_field1:inner_value1, inner_field2:inner_value2, inner_field3:inner_value3}}

I know that to query documents based on inner_value1, I need to use the dot notation in Mongo query like below:

{field1.innerfield1:inner_value1}

In my case, the fields on which I need to search the documents from MongoDB will be provided by an external party and they may or may not be nested. In this scenario, how can I dynamically create "dot notation" based query if I have the original field as mentioned as in "Document Field" above? The original field value may or may not be nested.

Upvotes: 0

Views: 1559

Answers (3)

hrd
hrd

Reputation: 11

The Python package flatten-dict can convert to dot notation and back with, even with multiple nested levels.

from flatten_dict import flatten

doc = {
    "field1": {
        "sub_field1": "sub_value1",
        "sub_field2": "sub_value2",
        "sub_field3": "sub_value3",
    },
    "field2": "value2",
}

flatten(doc, reducer="dot")

Output

{
     'field1.sub_field1': 'sub_value1',
     'field1.sub_field2': 'sub_value2',
     'field1.sub_field3': 'sub_value3',
     'field2': 'value2'
}

Upvotes: 1

A. Jesse Jiryu Davis
A. Jesse Jiryu Davis

Reputation: 24007

Perhaps something like this:

field1 = "a"
innerfield = "b"
innvervalue = "c"

collection = MongoClient().db.collection
key = "%s.%s" % (field1, innerfield)
for doc in collection.find({key: innvervalue}):
    print(doc)

Upvotes: 1

Jay
Jay

Reputation: 24905

After some trials, I figured out a solution. Posting it here as it may serve as a reference to others:

input = {'field1':{'sub_field1':'sub_value1', 'sub_field2':'sub_value2', 'sub_field3':'sub_value3'}, 'field2':'value2'}

new_dict = {}

for k in input:
    if (isinstance(input[k], dict)):
        for l in input[k]:
            new_key = k+"."+l
            new_dict[new_key] = input[k][l]
    else:
        new_dict[k] = input[k]

Upvotes: 0

Related Questions