3

I'm trying to query a MongoDB database to find all results which contains an specific ID:

My schema looks like this:

_id: xyz
ad_accounts: [{"name":"abc, "ads:{"campaings":[123, 4456, 574]}}]

I need to find all the results which contain 123 in "campaigns"

Here is a better image of the schema:

DB Schema

I've tried the following:

results = db.data.find({"ad_accounts.ads.campaigns": 123})

But it doesn't work since ad_accounts is an array, I've also tried with a loop:

for data in all_data:
    for account in data['ad_accounts']:
        if first_ad in account['ads']['campaigns]:
            print("this is the one")

But I don't think it's the best.

Is there a built-in way to query nested data? Thanks

Brad Solomon
  • 38,521
  • 31
  • 149
  • 235
Costantin
  • 2,486
  • 6
  • 31
  • 48

1 Answers1

3

Going off your example, you can use this syntax:

>>> for match in collec.find({ "ad_accounts.0.ads.campaigns" : { "$in" : [123] } }):
...     print(match)
...     
{'_id': ObjectId('5adcd32690542e05e121bbdd'), 'ad_accounts': [{'name': 'abc', 'ads': {'campaigns': [123, 4456, 574]}}]}

$in is a command for matching any element from an array.

To reproduce this example with pymongo:

from pymongo import MongoClient

client = MongoClient()
test_db = client.test_db
collec = test_db.collec

val1 = {"ad_accounts": [{"name": "abc", "ads": {"campaigns": [123, 4456, 574]}}]}
val2 = {"ad_accounts": [{"name": "abc", "ads": {"campaigns": [999, 4456, 574]}}]}

collec.insert_many([val1, val2])

For a nested array, you would need elemMatch.

Brad Solomon
  • 38,521
  • 31
  • 149
  • 235
  • Hi Brad Thank you, but in your example you hardcoded the first element in the array e.g. `ad_accounts.0.ads.campaigns` what if it's the 3rd or 10th? – Costantin Apr 22 '18 at 19:50
  • @Costantin The 0 doesn't denote the first element of the campaigns array; it's the first element of ad_accounts. – Brad Solomon Apr 23 '18 at 10:52