Группировать документы на основе динамических ключей и преобразовывать ключи в значения - PullRequest
0 голосов
/ 27 декабря 2018

У меня есть данные в MongoDB, такие как:

{
    "good": {
        "d1": 2,
        "d2": 56,
        "d3": 3
    },
    "school": {
        "d1": 4,
        "d3": 5,
        "d4": 12
    }
},
{
    "good": {
        "d5": 4,
        "d6": 5
    },
    "spark": {
        "d5": 6,
        "d6": 11,
        "d7": 10
    },
    "school": {
        "d5": 8,
        "d8": 7
    }
}

, и я хочу использовать pymongo mapreduce для генерации таких данных:

{
    'word': 'good',
    'info': [
        {
            'tbl_id': 'd1',
            'term_freq': 2
        },
        {
            'tbl_id': 'd2',
            'term_freq': 56
        },
        {
            'tbl_id': 'd3',
            'term_freq': 3
        },
        {
            'tbl_id': 'd5',
            'term_freq': 4
        },
        {
            'tbl_id': 'd6',
            'term_freq': 5
        }
    ]
}
{
    'word': 'school',
    'info': [
        {
            'tbl_id': 'd1',
            'term_freq': 4
        },
        {
            'tbl_id': 'd3',
            'term_freq': 5
        },
        {
            'tbl_id': 'd4',
            'term_freq': 12
        },
        {
            'tbl_id': 'd5',
            'term_freq': 8
        },
        {
            'tbl_id': 'd8',
            'term_freq': 7
        }
    ]
}
{
    'word': 'spark',
    'info': [
        {
            'tbl_id': 'd5',
            'term_freq': 6
        },
        {
            'tbl_id': 'd6',
            'term_freq': 11
        },
        {
            'tbl_id': 'd7',
            'term_freq': 10
        }
    ]
}

что должноЯ делаю?Или есть другие решения?

1 Ответ

0 голосов
/ 29 декабря 2018

Вам не нужно * mapReduce` здесь.Структура агрегации может справиться с этим красиво.

Что касается того, как это работает, я предлагаю вам взглянуть на каждый оператор в документации .

_filter = {
    "input": {"$objectToArray": "$$ROOT"},
    "cond": {"$ne": ["$$this.k", "_id"]}
}

_map = {
    "$map": {
        "input": {"$filter": _filter},
        "in": {
            "k": "$$this.k",
            "info": {
                "$map": {
                    "input": {"$objectToArray": "$$this.v"},
                    "in": {"tbl_id": "$$this.k", "freq_term": "$$this.v"}
                }
            }
        }
    }
}

pipeline = [
    {"$project": {"word": _map}},
    {"$unwind": "$word"},
    {
        "$group": {
            "_id": "$word.k",
            "info": {
                "$push": "$word.info"
            }
        }
    },
    {
        "$project": {
            "_id": 0,
            "word": "$_id",
            "info": {
                "$reduce": {
                    "input": "$info",
                    "initialValue": [

                    ],
                    "in": {
                        "$concatArrays": [
                            "$$value",
                            "$$this"
                        ]
                    }
                }
            }
        }
    }
]

Затем запустите метод .aggregate().

collection.aggregate(pipeline)
...