2014-11-06 2 views
2

При запросе mongodb можно ли обработать («проект») результат, чтобы выполнить конкатенацию массива? я на самом деле есть 2 различных сценариев:Конкатенация контуров Mongodb

(1) Массивы из разных областей :, например:

Given: 
{companyName:'microsoft', managers:['ariel', 'bella'], employees:['charlie', 'don']} 
{companyName:'oracle', managers:['elena', 'frank'], employees:['george', 'hugh']} 

I'd like my query to return each company with its 'managers' and 'employees' concatenated: 
{companyName:'microsoft', allPersonnel:['ariel', 'bella','charlie', 'don']} 
{companyName:'oracle', allPersonnel:['elena', 'frank','george', 'hugh']} 

(2) Вложенные массивы :, например:

Given the following docs, where employees are separated into nested arrays (never mind why, it's a long story): 
{companyName:'microsoft', personnel:[ ['ariel', 'bella'], ['charlie', 'don']} 
{companyName:'oracle', personnel:[ ['elena', 'frank'], ['george', 'hugh']} 

I'd like my query to return each company with a flattened 'personal' array: 
{companyName:'microsoft', allPersonnel:['ariel', 'bella','charlie', 'don']} 
{companyName:'oracle', allPersonnel:['elena', 'frank','george', 'hugh']} 

Я был бы признателен за любые идеи, используя либо «найти», либо «заполнить» Спасибо большое :)

ответ

3

Конечно, в современных выпусках MongoDB мы можем просто использовать $concatArrays здесь:

db.collection.aggregate([ 
    { "$project": { 
    "companyNanme": 1, 
    "allPersonnel": { "$concatArrays": [ "$managers", "$employees" ] } 
    }} 
]) 

Или для второй формы с вложенными массивами, используя $reduce в комбинации:

db.collection.aggregate([ 
    { "$project": { 
    "companyName": 1, 
    "allEmployees": { 
     "$reduce": { 
     "input": "$personnel", 
     "initialValue": [], 
     "in": { "$concatArrays": [ "$$value", "$$this" ] } 
     } 
    } 
    }} 
]) 

Eсть оператор $setUnion, доступный для структуры агрегации. Ограничение здесь является то, что это «наборы» и все члены фактически «уникальный», как «набор» требует:

db.collection.aggregate([ 
    { "$project": { 
     "companyname": 1, 
     "allPersonnel": { "$setUnion": [ "$managers", "$employees" ] } 
    }} 
]) 

Так что это круто, до тех пор, как все «уникальный», и вы в сингулярные массивы.

В альтернативном случае вы всегда можете обрабатывать с $unwind и $group. Кадровые вложенный массив является простого двойной размотка

db.collection.aggregate([ 
    { "$unwind": "$personnel" }, 
    { "$unwind": "$personnel" }, 
    { "$group": { 
     "_id": "$_id", 
     "companyName": { "$first": "$companyName" }, 
     "allPersonnel": { "$push": { "$personnel" } } 
    }} 
]) 

Или то же самое, как и первым для ранних версий, чем MongoDB 2.6, где «набор операторы» не существовали:

db.collection.aggregate([ 
    { "$project": { 
     "type": { "$const": [ "M", "E" ] }, 
     "companyName": 1, 
     "managers": 1, 
     "employees": 1 
    }}, 
    { "$unwind": "$type" }, 
    { "$unwind": "$managers" }, 
    { "$unwind": "$employees" }, 
    { "$group": { 
     "_id": "$_id", 
     "companyName": { "$first": "$companyName" }, 
     "allPersonnel": { 
      "$addToSet": { 
       "$cond": [ 
        { "$eq": [ "$type", "M" ] }, 
        "$managers", 
        "$employees" 
       ] 
      } 
     } 
    }} 
]) 
+0

большого спасибо –

Смежные вопросы