Using mongodb aggregate to match documents and get all values for a field -


in mongo 3.4

i have collection documents in format:

type1:

{ "level1": {     "@version": "genr",     "@revision": "aux",     "level2": {         "container": {             "type": "array",             "categories": [                 {                     "category": [                         {                             "type": "string",                             "value": "currency"                         },                         {                             "type": "string",                             "value": "eur"                         }                     ]                 },                 {                     "category": [                         {                             "type": "string",                             "value": "portfolio"                         },                         {                             "type": "string",                             "value": "abcdef"                         }                     ]                 },              ]           }       }   } } 

type 2:

 { "level1": {     "@version": "genr",     "@revision": "aux",     "level2": {         "container": {             "type": "array",             "categories": [                 {                     "category": [                         {                             "type": "string",                             "value": "currency"                         },                         {                             "type": "string",                             "value": "eur"                         }                     ]                 },                 {                     "category": [                         {                             "type": "string",                             "value": "portfolio"                         },                         {                             "type": "string",                             "value": "abcdef"                         }                     ]                 },                 {                     "category": [                         {                             "type": "string",                             "value": "short description"                         },                         {                             "type": "string",                             "value": "cash only"                         }                     ]                 },              ]           }       }   } } 

how write aggregate statement currency values, documents portfolio matches value.

i have been using pymongo's aggregate framework below:

pipeline = [{"$unwind":"$level1.level2.container.categories"},{"$unwind":"$level1.level2.container.categories.category"},{"$match":{"level1.level2.container.categories.category.value":"portfolio"}}] pprint(db.command('aggregate',collection,pipeline=pipeline)) 

but no results. pymongo little confusing. if can point general approach, help.

the expected response assuming 4 matching documents (each varying number of category items) is:

{'currency': [{'level1': {'level2': {'container': {'categories': {'category': {'value': 'eur'}}}}}},           {'level1': {'level2': {'container': {'categories': {'category': {'value': 'eur'}}}}}},           {'level1': {'level2': {'container': {'categories': {'category': {'value': 'usd'}}}}}},           {'level1': {'level2': {'container': {'categories': {'category': {'value': 'eur'}}}}}}]} 

your structure not ideal can use below query.

the below $match stage $ands 2 conditions. looks in category array ($elemmatch) under categories ($elemmatch) array elements satisfying both ($all) portfolio match abcdef value condition followed condition element currrency value.

$unwind stage break down categories followed $match keep currency category embedded array documents.

$unwind stage break down category followed $match remove currency value embedded document.

final 2 stages $group + $push remaining data embedded array , $project currency value.

you can run 1 stage @ time view intermediate output better understanding.

db.collection.aggregate(     { $match :         {  $and :              [               { "level1.level2.container.categories":                   { $elemmatch:                     { "category":                        { $all:                           [                              { $elemmatch : { "type": "string", "value": "portfolio" } },                             { $elemmatch : { "type": "string", "value": "abcdef" } }                           ]                          }                       }                    }                },                 { "level1.level2.container.categories":                    { $elemmatch:                       { "category":                          { $elemmatch : { "type": "string", "value": "currency" } }                        }                     }                }            ]         }    },   { $unwind : "$level1.level2.container.categories" },   { $match : { "level1.level2.container.categories.category.value": "currency" } },   { $unwind : "$level1.level2.container.categories.category" },   { $match : { "level1.level2.container.categories.category.value": { $ne : "currency" } } },   { $group: { _id: null, "currency": { $push: "$$root" } } },    { $project: { _id: 0, "currency.level1.level2.container.categories.category.value": 1 } } ) 

Comments