Суммируйте значения, которые являются объектом поля на основе соответствия регулярному выражению в mongdb - PullRequest
1 голос
/ 16 апреля 2020

В Mongiodb у меня есть такой объект:

{
    "Brand" : "YY1",
    "Parent Company" : "XXX",
    "Week Ending 02-12-14" : 339.154407659,
    "Week Ending 01-19-14" : 458.614275287,
}
{
    "Brand" : "YY2",
    "Parent Company" : "XXX",
    "Week Ending 01-12-14" : 339.154407659,
    "Week Ending 03-19-14" : 458.614275287,
}
{
    "Brand" : "YY1",
    "Parent Company" : "XXX",
    "Week Ending 01-12-14" : 339.154407659,
    "Week Ending 04-19-14" : 458.614275287,
}
{
    "Brand" : "YY2",
    "Parent Company" : "XXX",
    "Week Ending 01-12-14" : 339.154407659,
    "Week Ending 01-20-14" : 458.614275287,
    "Week Ending 04-19-14" : 458.614275287,
}

Я пытался вот так. Я должен запросить, как поле должно начинаться с недельного окончания, должно иметь сумму и родительскую компанию как "XXX":

db.getCollection('collection name').aggregate([{
    "$addFields": {
        "finder": {
            "$objectToArray": "$$ROOT"
        }
    }
}, {
    "$match": {
        "finder.k": /^Week Ending/
    }
}, {
    "$group": {
        "_id": "Brand",
        "sum": {
            "$sum": "Week Ending 01-12-14"
        }
    }
}])

Но я могу суммировать поле, если оно определено как недельное окончание 01-12- 14, но я хочу суммировать поле, начинающееся с окончания недели.

В моей коллекции будет объект, который может содержать окончание недели или нет. Но если в объекте бренда не указан конец недели, значение pos будет равно 0.0,

И мой ожидаемый результат будет таким:

[{
    "parent":"XXX"
    "Brand" : "YY1",
    "pos_value":"float values"**(sum of all values starts with week ending in all YY1 brand object)**
}, {
    "parent":"XXX"
    "Brand" : "YY2",
    "pos_value":"float values"**(sum of all values starts with week ending in all YY2 brand object)**
}]

1 Ответ

0 голосов
/ 16 апреля 2020

Используйте эту агрегацию, которая использует $ filter и $ Reduction :

db.getCollection('collection name').aggregate(
    [
        {
            "$addFields": {
                "week_sum": {
                    "$reduce": {
                        "input": {
                            "$filter": {
                                "input": {"$objectToArray": "$$ROOT"},
                                "as": "field",
                                "cond": {"$gt": [{"$size": {"$split": ["$$field.k", "Week Ending"]}}, 1]}
                            }
                        },
                        "initialValue": 0,
                        "in": {"$sum": ["$$value.v", "$$this"]}
                    }
                }
            }
        },
        {
            "$group": {
                "_id": "Brand",
                "parent": {"$first": "$Parent Company"},
                "$sum": {"$sum": "$week_sum"}
            }
        },
        {
            "$project": {
                "_id": 0,
                "parent": "$parent",
                "brand": "$_id",
                "pos_value": "$sum"
            }
        }
    ])

При этом указанная структура документа крайне не масштабируется. Я рекомендую переосмыслить это и сделать что-то похожее на следующее:

{
    "Brand" : "YY1",
    "Parent Company" : "XXX",
    "Weeks": [
       {"date": ISODate("02-12-14"), value: 339.154407659),
       {"date": ISODate("01-19-14"), value: 458.614275287}
    ]
}
...