ソリューション
次のパイプラインはあなたに望ましい結果
db.getCollection('account').aggregate(
[
{
$project: {
_id: '$product',
fields: [
{ name: { $literal: 'price' }, value: '$price', count: { $literal: 0 } },
{ name: { $literal: 'sale' }, value: '$sale', count: { $literal: 0 } },
{ name: { $literal: 'count' }, value: { $literal: 0 }, count: '$count' }
]
}
},
{
$unwind: {
path: '$fields'
}
},
{
$match: {
'fields.value': {
$exists: true
}
}
},
{
$group: {
_id: {
product: '$_id',
field: '$fields.name'
},
value: {
$last: '$fields.value'
},
count: {
$sum: '$fields.count'
}
}
},
{
$project: {
_id: '$_id.product',
price: {
$cond: { if: { $eq: [ '$_id.field', 'price' ] }, then: '$value', else: null }
},
sale: {
$cond: { if: { $eq: [ '$_id.field', 'sale' ] }, then: '$value', else: null }
},
count: {
$cond: { if: { $eq: [ '$_id.field', 'count' ] }, then: '$count', else: 0 }
}
}
},
{
$group: {
_id: '$_id',
price: {
$max: '$price'
},
sale: {
$max: '$sale'
},
count: {
$sum: '$count'
}
}
}
])
説明を与える必要があります
まず、フィールド名、フィールド値、およびカウント値を含むフィールドごとの要素を持つ新しい配列を作成します。 フィールドcount
は、最後の値を取得する代わりに蓄積する必要があるため、特別扱いとなります。第一段階の文書は次のようになり後 だから:
/* 1 */
{
"_id" : "2",
"fields" : [
{
"name" : "price",
"value" : 5400,
"count" : 0.0
},
{
"name" : "sale",
"count" : 0.0
},
{
"name" : "count",
"value" : 0.0,
"count" : 1
}
]
}
/* 2 */
{
"_id" : "2",
"fields" : [
{
"name" : "price",
"count" : 0.0
},
{
"name" : "sale",
"value" : 0.2,
"count" : 0.0
},
{
"name" : "count",
"value" : 0.0,
"count" : 0
}
]
}
/* 3 */
{
"_id" : "2",
"fields" : [
{
"name" : "price",
"count" : 0.0
},
{
"name" : "sale",
"count" : 0.0
},
{
"name" : "count",
"value" : 0.0,
"count" : 1
}
]
}
それは、それがnull値を取り除くために、配列やフィルタをほどき、そのステージの後2つの& 3文書は、次のようになります。
/* 1 */
{
"_id" : "2",
"fields" : {
"name" : "price",
"value" : 5400,
"count" : 0.0
}
}
/* 2 */
{
"_id" : "2",
"fields" : {
"name" : "count",
"value" : 0.0,
"count" : 1
}
}
/* 3 */
{
"_id" : "2",
"fields" : {
"name" : "sale",
"value" : 0.2,
"count" : 0.0
}
}
/* 4 */
{
"_id" : "2",
"fields" : {
"name" : "count",
"value" : 0.0,
"count" : 0
}
}
/* 5 */
{
"_id" : "2",
"fields" : {
"name" : "count",
"value" : 0.0,
"count" : 1
}
}
第4段階では、フィールドの最後の値と合計であるcount
が作成されます。結果は以下のようになります。値があるべき私達の望ましい結果とは異なる形状を持つ別の文書に今ある
/* 1 */
{
"_id" : {
"product" : "2",
"field" : "sale"
},
"value" : 0.2,
"count" : 0.0
}
/* 2 */
{
"_id" : {
"product" : "2",
"field" : "count"
},
"value" : 0.0,
"count" : 2
}
/* 3 */
{
"_id" : {
"product" : "2",
"field" : "price"
},
"value" : 5400,
"count" : 0.0
}
として、私たちはグループ最終的にできるものに戻ってそれらを投影する必要があります。したがって、5段目以降の文書は次のようになります。
/* 1 */
{
"_id" : "2",
"count" : 0.0,
"price" : null,
"sale" : 0.2
}
/* 2 */
{
"_id" : "2",
"count" : 2,
"price" : null,
"sale" : null
}
/* 3 */
{
"_id" : "2",
"count" : 0.0,
"price" : 5400,
"sale" : null
}
最後の段階では、製品ごとにこれらの文書を集計するだけです。
これは、選択した言語にデータを読み込む必要があると思います。任意のデータフレームライブラリ(Pythonの 'pandas'など)はこれを扱います。 –