Начиная с алгоритма на чистом языке запросов MongoDB: вы должны реструктурировать свои документы так, чтобы каждый документ содержал свой начальный массив sub
и массив всех других значений sub
. Для этого вам нужно запустить $ group вместе с $ unwind . Тогда становится просто запустить $ map с $ setIntersect $ filter из всех пустых и равных собственным массивам и получить размер, используя $ 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" ]}
]
}
}
}
}
}
}
])
Пн go Детская площадка
Поскольку агрегация довольно сложна, нет смысла запускать ее строго типизированным способом в 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();