2016-10-09 4 views
1

У меня есть проблема с моим запросом mongoDB (с использованием aggregate). И я был бы рад получить некоторые подсказки ...

Ниже мой MongoCollection:
Обратите внимание, что KLLS либо a, b или c, и есть 3 types: processus, work и viewing.

{_id: 1, KLLS: "a", action: "A", type: "Processus", date: Date, other:"abc" } 
{_id: 2, KLLS: "b", action: "B", type: "Processus", date: Date } 
{_id: 3, KLLS: "a", action: "C", type: "Work"  , date: Date, other:"xyz" } 
{_id: 4, KLLS: "b", action: "D", type: "Work"  , date: Date } 
{_id: 5, KLLS: "a", action: "E", type: "Viewing" , date: Date } 
{_id: 6, KLLS: "b", action: "F", type: "Viewing" , date: Date } 
... 

То, что я хотел бы достичь с помощью запроса:

[ { 
    _id: { KLLS: "a"}, 
    Processus: [[action: "A", date: "Date", other: "abc"]] 
    Work:  [[action: "C", date: "Date"]] 
    Viewing: [[action: "E", date: "Date"]] 
    }, 
    { 
    _id: { KLLS: "b"}, 
    Processus: [[action: "B", date: "Date"]] 
    Work:  [[action: "D", date: "Date", other: "xyz"]] 
    Viewing: [[action: "F", date: "Date"]] 
    } 
] 

На данный момент мой (отсутствии) запрос:

db.collection('events').aggregate([ 
    {$match: { 
     KLLS: {$in: something} 
    }}, 
    {$group: { 
     _id: { 
      klls: "$KLLS", 
      type: "$type" 
     }, 
     array: { 
      $push: "$$ROOT" 
     } 
    }} 
]) 

Однако я есть одна проблема: она делает composite id, но у меня нет 3 красиво названных arrays ...

[ 
{ 
    _id: { KLLS: "a", type: "Processus" }, 
    array: [[action: "A", date: "Date", other: "abc"]] 
}, 
{ 
    _id: { KLLS: "a", type: "Work" }, 
    array: [[action: "C", date: "Date"]] 
}, 
{ 
    _id: { KLLS: "a", type: "Viewing" }, 
    array: [[action: "E", date: "Date"]] 
}, 
{ 
    _id: { KLLS: "b", type: "Processus" }, 
    array: [[action: "B", date: "Date"]] 
}, 
{ 
    _id: { KLLS: "b", type: "Work" }, 
    array: [[action: "D", date: "Date", other: "xyz"]] 
}, 
{ 
    _id: { KLLS: "b", type: "Viewing" }, 
    array: [[action: "F", date: "Date"]] 
}, 
... 
] 

У вас есть идеи, как решить эту проблему? Спасибо.


******************** EDIT ********************* *

Давайте представим себе тот же коллекция содержит также:

{_id: 1, KLLS: "a", action: "A", type: "Processus", date: Date } 
{_id: 2, KLLS: "b", action: "B", type: "Processus", date: Date } 
{_id: 5, KLLS: "a", action: "E", type: "Viewing" , date: Date } 
{_id: 6, KLLS: "b", action: "F", type: "Viewing" , date: Date } 
    ... 
{_id: 3, KLLS: "a", action: "AB", type: "Work"  , date: Date, key:"123" } 
{_id: 4, KLLS: "b", action: "XY", type: "Work"  , date: Date, key: "123" } 
{_id: 3, KLLS: "a", action: "AB", type: "Work"  , date: Date, key:"456" } 
{_id: 4, KLLS: "b", action: "XY", type: "Work"  , date: Date, key: "456" } 
    ... 

(Обратите внимание, что для типа Work, я получил еще key).

Благодаря вашей помощи, в этот момент, я получил:

[{ 
    _id: { KLLS: "a"}, 
    Processus: [ everything is ok ], 
    Viewing: [ everything is ok ], 
    Details: [ everything is ok ], 
    Work:  [ 
     {_id: 3, KLLS: "a", action: "AB", type: "Work", date: Date, key:"123" } 
     {_id: 4, KLLS: "b", action: "XY", type: "Work", date: Date, key: "123" } 
     {_id: 3, KLLS: "a", action: "AB", type: "Work", date: Date, key:"456" } 
     {_id: 4, KLLS: "b", action: "XY", type: "Work", date: Date, key: "456" } 
    ] 
... 

Принимая во внимание, конечный результат я хотел бы это:

[{ 
    _id: { KLLS: "a"}, 
    Processus: [ everything is ok ], 
    Viewing: [ everything is ok ], 
    Details: [ everything is ok ], 
    Work:  [ 
     subArrayByKey [ // key = 123 
      {_id: 3, KLLS: "a", action: "AB", type: "Work", date: Date, key:"123" }, 
      {_id: 4, KLLS: "b", action: "XY", type: "Work", date: Date, key: "123" } 
     ], 
     subArrayByKey [ // key = 456 
      {_id: 3, KLLS: "a", action: "AB", type: "Work", date: Date, key:"456" }, 
      {_id: 4, KLLS: "b", action: "XY", type: "Work", date: Date, key: "456" } 
     ] 
    ] 
... 

Я пытался делать (1) вид nested $group, а также (2), чтобы добавить критерии в вашу первую группу $, чтобы сделать composite id (как я и пытался в самом начале). Но $eq Стыдно мне ...

{ $match: { something } }, 
{ $sort: { by date } }, 
{ $group: { what you wrote } }, 
{ $group: { a nested $group I tried } } 

Наконец, и не удивительно, что мне не удалось ... возвращение запрос не пустой .. Если я могу .. у вас есть какие-либо подсказки ...; -)

ответ

0

Оператор $cond можно использовать с $push, чтобы добавить значения в массив, соответствующий этому условию.

$cond - это тернарный оператор, и в приведенном ниже примере исходный документ добавляется к массиву при выполнении условия, а значение фиктивного значения false добавляется к массиву, когда условие не выполняется.

В конце $project этап, манекен false записей в массивах удаляются с помощью оператора setDifference.

db.events.aggregate([ 
    {"$group": { 
     "_id" : "$KLLS", 
     "Processus": { 
      "$push": { 
       "$cond": [{"$eq": ["$type", "Processus"]}, "$$ROOT", false] 
      } 
     }, 
     "Work": { 
      "$push": { 
       "$cond": [{"$eq": ["$type","Work"]}, "$$ROOT", false] 
      } 
     }, 
     "Viewing": { 
      "$push": { 
       "$cond": [{"$eq" : ["$type","Viewing"]}, "$$ROOT", false] 
      } 
     }, 
     "Details": {"$push" : "$other"} 
    }}, 

    {"$project": { 
     "_id": 0, 
     "KLLS": "$_id", 
     "Processus": {"$setDifference": ["$Processus", [false]]}, 
     "Work":  {"$setDifference": ["$Work",  [false]]}, 
     "Viewing": {"$setDifference": ["$Viewing", [false]]}, 
     "Details": 1 
    }} 
]) 

Кроме того, чтобы добавить только несколько полей в массив, вы можете попробовать что-то вроде ниже.

db.events.aggregate([ 
    {"$group": { 
     "_id": "$KLLS", 
     "Processus": { 
      "$push": { 
       "$cond": [{"$eq": ["$type","Processus"]}, {"action": "$action","other": "$other"}, false] 
      } 
      }, 
      "Work": { 
       "$push": { 
        "$cond": [{"$eq": ["$type","Work"]}, {"action": "$action","other": "$other"}, false] 
       } 
      }, 
      "Viewing":{ 
       "$push": { 
        "$cond": [{"$eq": ["$type","Viewing"]}, {"action": "$action","other": "$other"}, false] 
       } 
      }, 
      "Details": {"$push": "$other"} 
    }}, 

    {"$project": { 
     "_id": 0, 
     "KLLS": "$_id", 
     "Processus": {"$setDifference": ["$Processus", [false]]}, 
     "Work":  {"$setDifference": ["$Work",  [false]]}, 
     "Viewing": {"$setDifference": ["$Viewing", [false]]}, 
     "Details": 1 
    }} 
]) 
+0

Во-первых, большое спасибо. Он работает почти как шарм! Возможно ли создать «массив» другого массива (например, 'Processus',' Work' и 'Viewing'), который называется' Details ', который содержит 'other:' abc' ', взятый из моей записи с помощью' action: ' A "(см. Мой первоначальный пост). Еще раз спасибо: запрос в MongoDB и agregate не так-то просто ... – nerotulip

+0

Еще раз спасибо. Я редактирую свой первоначальный пост для окончательного вопроса относительно «вложенной группы» или «составного идентификатора». Очень мило, что ты мне так много помогаешь! – nerotulip

+0

Не могли бы вы опубликовать последнюю отредактированную часть как отдельный вопрос? Это привлечет больше пользователей. – 4J41