Как я могу считать предметы в коллекции монго, которые имеют пересекающиеся подколлекции?

Для каждого элемента в моей коллекции мне нужно найти количество других элементов, имеющих пересекающиеся подколлекции. Например, учитывая эту коллекцию

[{id:1,"sub":[1, 2, 3]},
{id:2,"sub":[2, 3, 4]},
{id:3,"sub":[4, 5, 6],
{id:4,"sub":[7, 8, 9]}]

ожидаемый результат

[{id:1,"count":1},
{id:2,"count":2},
{id:3,"count":1},
{id:4,"count":0"}]

Всего 1 ответ


Начиная с алгоритма на чистом языке запросов MongoDB: вы должны реструктурировать свои документы так, чтобы каждый документ содержал свой начальный подмассив и массив всех других поднаборов. Для этого вам нужно запустить $ group вместе с $ unwind . Тогда становится просто запустить $ map с фильтром $ setIntersect $ , все пустые и равные собственным массивам, и получить размер, используя $ size

db.collection.aggregate([
    {
        $group: {
            _id: null,
            current: { $push: "$$ROOT" },
            all: { $push: "$sub" }
        }
    },
    {
        $unwind: "$current"
    },
    {
        $project: {
            id: "$current.id",
            count: {
                $size: {
                    $filter: {
                        input: {
                            $map: {
                                input: "$all",
                                in: { $setIntersection: [ "$$this", "$current.sub" ] }
                            }
                        },
                        cond: {
                            $and: [ 
                                { $ne: [ "$$this", [] ] },
                                { $ne: [ "$$this", "$current.sub" ]}
                            ]
                        }
                    }
                }
            }
        }
    }
])

Монго Детская площадка

Поскольку агрегация довольно сложна, нет смысла запускать ее строго типизированным способом в C #. Все, что вы можете сделать, это использовать класс BsonDocument для построения вашего конвейера, например:

var groupDef = new BsonDocument()
        {
            { "_id", "" },
            { "current", new BsonDocument(){ { "$push", "$$ROOT" } } },
            { "all", new BsonDocument(){ { "$push", "$sub" } } },
        };

var projectDef = BsonDocument.Parse(@"{
        id: ""$current.id"",
        _id: 0,
        count: {
        $size: {
            $filter: {
            input: {
                $map: {
                input: ""$all"",
                in: {
                    $setIntersection: [
                    ""$$this"",
                    ""$current.sub""
                    ]
                }
                }
            },
            cond: {
                $and: [
                {
                    $ne: [
                    ""$$this"",
                    []
                    ]
                },
                {
                    $ne: [
                    ""$$this"",
                    ""$current.sub""
                    ]
                }
                ]
            }
            }
        }
        }
    }");

var result = mongoDBCollection.Aggregate()
                                .Group(groupDef)
                                .Unwind("current")
                                .Project(projectDef)
                                .ToList();

Есть идеи?

10000