2015-03-22 2 views
7

Это то, что мои документы выглядят какMongoDB Aggregation размотать более одного массива

{ 
    code: "A2df", 
    clicks: 7, 
    countries: [{"country":"IN", clicks:5},{"country":"US", clicks:2}], 
    domains: [{"domain":"a.com", clicks:4},{"country":"b.com", clicks:3}] 
}, 
{ 
    code: "B3ws", 
    clicks: 11, 
    countries: [{"country":"IN", clicks:6},{"country":"ND", clicks:5}], 
    domains: [{"domain":"a.com", clicks:7},{"country":"c.com", clicks:4}] 
}, 
{ 
    code: "A2df", 
    clicks: 5, 
    countries: [{"country":"IN", clicks:2},{"country":"ND", clicks:3}], 
    domains: [{"domain":"a.com", clicks:1},{"country":"c.com", clicks:4}] 
}... 

Это то, что мне нужно:

{ 
    code: "A2df", 
    clicks: 12, 
    countries: [ 
    { 
     "country": "IN", 
     clicks: 7 
    }, 
    { 
     "country": "US", 
     clicks: 2 
    }, 
    { 
     "country": "ND", 
     clicks: 3 
    } 
    ], 
    domains: [ 
    { 
     "domain": "a.com", 
     clicks: 5 
    }, 
    { 
     "country": "b.com", 
     clicks: 3 
    }, 
    { 
     "country": "c.com", 
     clicks: 4 
    } 
    ] 
} 

Я знаю, как сделать это в несколько запросов. Я могу выполнить групповую агрегацию и сумму за клики, разматывать массивы, а затем группировать их, а затем суммировать их. Но я хочу пропустить боль, вызвав три запроса в базу данных, а затем слияние трех результатов.

Есть ли способ в MongoDB, все это можно сделать в одном запросе. Я не могу изменить структуру документов. Любая помощь приветствуется. Даже если это невозможно сделать в одном запросе, любые предложения оценены, чтобы уменьшить боль. :)

Это то, что я пытался до сих пор, чтобы получить его работу в одном запросе:

[ 
    { 
    $match: { 
     date: { 
     $gte: fromDate, 
     $lt: toDate 
     }, 
     brand_id: brandId, 
     type: "item" 
    } 
    }, 
    { 
    $unwind: "$countries" 
    }, 
    { 
    $group: { 
     _id: { 
     code: "$code", 

     }, 
     clicks: { 
     $sum: "$countries.clicks" 
     }, 
     countries: { 
     $push: "$countries" 
     } 
    } 
    }, 
    { 
    $unwind: "$domains" 
    }, 
    { 
    $group: { 
     _id: { 
     code: "$code", 

     }, 
     clicks: { 
     $sum: "$domains.clicks" 
     }, 
     domains: { 
     $push: "$domains" 
     } 
    } 
    } 
] 

Это возвращает пустой массив, но если я просто сделать первую раскрутку и группу это дает мне требуемая продукция для стран. Так вот что я пытаюсь решить, попробуйте и все в одном запросе.

+0

Пожалуйста, введите ваши вопросы. Поскольку вы можете разматывать несколько массивов в одном агрегатном конвейере. сначала раскрутите-> группу->, затем повторите его для другого массива в том же конвейере. –

+0

okay позвольте мне попробовать, я отправлю запрос, а также вывод .. –

+0

Я добавил запрос, мой код не работает. Не могли бы вы предложить правильный способ сделать это? –

ответ

4
db.test.aggregate([ 
    // Summarize clicks and collect countries and domains for each code 
    { 
    $group: { 
     _id: "$code", 
     clicks: { $sum: "$clicks" }, 
     countries: { $push: "$countries" }, 
     domains: { $push: "$domains" }, 
    } 
    }, 
    // Unwind array of array of sub-countries 
    { 
    $unwind: "$countries" 
    }, 
    // Unwind each array of sub-countries 
    { 
    $unwind: "$countries" 
    }, 
    // Summarize clicks for each sub-country 
    { 
    $group: { 
     _id: { code: "$_id", country: "$countries.country"}, 
     clicks: { $min: "$clicks" }, // Keep clicks which we've summarized into the 1st $group 
     countryClick: { $sum: "$countries.clicks" }, 
     domains: { $first: "$domains" }, // Keep domains 
    } 
    }, 
    // Collect sub-countries into embedded document 
    { 
    $group: { 
     _id: "$_id.code", 
     clicks: { $min: "$clicks" }, // Keep clicks which we've summarized into the 1st $group 
     countries: { $push: { country: "$_id.country", clicks: "$countryClick" } }, 
     domains: { $first: "$domains" }, // Keep sub-domains 
    } 
    }, 
    // Unwind array of array of sub-domains 
    { 
    $unwind: "$domains" 
    }, 
    // Unwind each array of sub-domains 
    { 
    $unwind: "$domains" 
    }, 
    // Summarize clicks for each sub-domain 
    { 
    $group: { 
     _id: { code: "$_id", domain: "$domains.domain", country: "$domains.country" }, 
     clicks: { $min: "$clicks" }, // Keep clicks which we've summarized into the 1st $group 
     domainClick: { $sum: "$domains.clicks" }, 
     countries: { $first: "$countries" }, // Keep sub-countries 
    } 
    }, 
    // Collect sub-domains into embedded document 
    { 
    $group: { 
     _id: "$_id.code", 
     clicks: { $min: "$clicks" }, // Keep clicks which we've summarized into the 1st $group 
     domains: { $push: { domain: "$_id.domain", country: "$_id.country", clicks: "$domainClick" } }, 
     countries: { $first: "$countries" }, // Keep sub-countries 
    } 
    }, 
]).pretty() 
+1

Спасибо. Это было очень полезно. – Somesh

Смежные вопросы