Я группирую свои данные с MongoDb.Linq следующим образом:
group r1 by new { r1.SupId, r1.SupFullName } into g2
select new
{
g2.Key.SupFullName,
Volunteers = from v0 in g2
where v0.VolId != g2.Key.SupId
select new { v0.VolFullName, v0.VolPeopleCount }
}
То есть я хочу только в Volunteers
те, которые Id
s не совпадают с ключом группы. Я ожидал, что драйвер сгенерирует условное $push
, но вместо этого он выдает простое:
"$push" : {
"VolFullName" : "$VolFullName",
"VolPeopleCount" : "$VolPeopleCount"
}
Теперь, прочитав эту запись , я смог преобразовать вышеуказанный запрос в следующий:
"$push": {
"$cond": [
{ "$ne": [ "$VolId", "$SupId" ] },
{
"VolFullName": "$VolFullName",
"VolPeopleCount": "$VolPeopleCount"
},
null
]
}
Что дает мне желаемые результаты. Я хотел бы знать, как, если это возможно, дать команду драйверу csharp сгенерировать запрос, подобный приведенному выше. Заранее спасибо!
РЕДАКТИРОВАТЬ: После предложения @mickl мне удалось сгенерировать условное $push
(а также условное $sum
), но результат оказался не таким, как ожидалось. Предположим, у меня есть следующие документы в моей коллекции:
{ N: "P_1", S: { I: "S_1", FN: "S_1" }, C: { I: "S_1", FN: "S_1" } }
{ N: "P_2", S: { I: "S_1", FN: "S_1" }, C: { I: "S_1", FN: "S_1" } }
{ N: "P_3", S: { I: "S_1", FN: "S_1" }, C: { I: "S_1", FN: "S_1" } }
{ N: "P_4", S: { I: "S_1", FN: "S_1" }, C: { I: "C_2", FN: "C_2" } }
{ N: "P_5", S: { I: "S_1", FN: "S_1" }, C: { I: "C_2", FN: "C_2" } }
{ N: "P_6", S: { I: "S_1", FN: "S_1" }, C: { I: "C_2", FN: "C_2" } }
{ N: "P_7", S: { I: "S_1", FN: "S_1" }, C: { I: "C_3", FN: "C_3" } }
{ N: "P_8", S: { I: "S_1", FN: "S_1" }, C: { I: "C_3", FN: "C_3" } }
{ N: "P_9", S: { I: "S_1", FN: "S_1" }, C: { I: "C_3", FN: "C_3" } }
Здесь N
, I
, FN
, S
и C
означают имя, идентификатор, полное имя, руководителя и создателя соответственно. Итак, как вы можете видеть, супервизор S_1
контролирует каждый документ, создал 3 документа, и есть 6 документов, созданных 2 другими создателями, которые также контролируются S_1
. То, что я хочу сделать, это обобщить эти документы супервизорами, а затем создателями с количеством созданных документов (людей). Итак, мой запрос LINQ выглядит так:
var q = from p in col.AsQueryable()
group p by new
{
SupFullName = p.S.FN,
SupId = p.S.I,
CtorFullName = p.C.FN,
CtorId = p.C.I
} into g1
select new
{
g1.Key.SupFullName,
g1.Key.SupId,
VolFullName = g1.Key.CtorFullName,
VolId = g1.Key.CtorId,
VolPeopleCount = g1.LongCount()
} into r1
group r1 by new { r1.SupId, r1.SupFullName } into g2
select new
{
g2.Key.SupFullName,
g2.Key.SupId,
Volunteers = g2.Select(v => v.VolId != g2.Key.SupId
? new { v.VolId, v.VolFullName, v.VolPeopleCount }
: null),
SupPeopleCount = g2.Select(v => v.VolId == g2.Key.SupId
? v.VolPeopleCount
: 0).Sum()
} into r2
orderby r2.SupPeopleCount descending
select r2;
Вывод, который дает мне запрос:
Supervisor: S_1, PeopleCount: 0
Creator: C_3, PeopleCount: 3
Creator: C_2, PeopleCount: 3
Creator: S_1, PeopleCount: 3
Что не то, что я хочу. Правильный вывод будет
Supervisor: S_1, PeopleCount: 3
Creator: C_3, PeopleCount: 3
Creator: C_2, PeopleCount: 3
Создает условные агрегаторы следующим образом (если я удаляю префикс $_id
в условии и оставляю только $SupId
, он работает как талисман):
"__agg0": {
"$push": {
"$cond": [
{ "$ne": [ "$VolId", "$_id.SupId" ] },
{
"VolId": "$VolId",
"VolFullName": "$VolFullName",
"VolPeopleCount": "$VolPeopleCount"
},
null
]
}
},
"__agg1": {
"$sum": {
"$cond": [
{ "$eq": [ "$VolId", "$_id.SupId" ] },
"$VolPeopleCount",
NumberLong(0)
]
}
}
Спасибо!