Подсчет совпадений с использованием структуры агрегации Монго - PullRequest
1 голос
/ 11 октября 2019

У меня есть эти документы с продуктами, с которыми взаимодействовал клиент (без повторных продуктов):

{ "client_interactions": [{"productType": "A", "productId": "1"}, {"productType": "A", "productId": "2"}, {"productType": "B", "productId": "9"}]}
{ "client_interactions": [{"productType": "A", "productId": "1"}, {"productType": "A", "productId": "2"}]}
{ "client_interactions": [{"productType": "A", "productId": "1"}, {"productType": "A", "productId": "3"}, {"productType": "C", "productId": "10"}]}

Я хочу рассчитать количество сопутствующих явлений для каждого продукта типа "A", вощущение, что продукт "1" возник вместе с продуктом "2", если клиент взаимодействовал с ними обоими.

Что-то вроде:

{ "co-ocurrences-count" : { "1" : [{ "2": 2}, { "3" : 1}]}, { "2" : [{ "1": 2}]}, { "3" : [{ "1": 1}]}}

У меня есть решение с использованием map-сократить функции javascript, но я действительно хочу, чтобы это делалось с использованием механизма агрегирования MongoDB, возможно ли это?

Заранее спасибо.

1 Ответ

1 голос
/ 11 октября 2019

Агрегация довольно длинная, но она работает. Идея состоит в том, что вам нужно построить пары (x,y) на основе массива client_interactions. Это можно сделать, используя $ lower и $ map . Затем вам нужно запустить $ unwind и пару $ group этапов, чтобы "свернуть" ваши агрегированные данные. Вам также необходимо $ arrayToObject для динамического создания ключей.

db.collection.aggregate([
    {
        $addFields: {
            "client_interactions": {
                $filter: { input: "$client_interactions", cond: { $eq: [ "$$this.productType", "A" ] } }
            }
        }
    },
    {
        $project: {
            a: {
                $reduce: {
                    input: "$client_interactions",
                    initialValue: [],
                    in: {
                        $concatArrays: [
                            "$$value",
                            { $map: { input: "$client_interactions", as: "c",  in: { x: "$$this.productId", y: "$$c.productId" } } }
                        ]
                    }
                }
            }
        }
    },
    {
        $unwind: "$a"
    },
    {
        $match: {
            $expr: {
                $ne: [ "$a.x", "$a.y" ]
            }
        }
    },
    {
        $sort: {
            "a.x": 1,
            "a.y": 1
        }
    },
    {
        $group: {
            _id: "$a",
            count: { $sum: 1 }
        }
    },
    {
        $group: {
            _id: "$_id.x",
            arr: { $push: { k: "$_id.y", v: "$count" } }
        }
    },
    {
        $group: {
            _id: null,
            "co-ocurrences-count": { $push: { k: "$_id", v: { $arrayToObject: "$arr" } } }
        }
    },
    {
        $project: {
            _id: 0,
            "co-ocurrences-count": { $arrayToObject: "$co-ocurrences-count" }
        }
    }
])

Mongo Playground

...