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
Post a Comment