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 $and
s 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