2016-01-14 45 views
0

我有一個一維數組(作爲MongoDB的查詢的輸出) 排序基於字段「數字」」轉換1D陣列以二維數組的NodeJS和MongoDB

results = [{ 
    user: u1, 
    number: 1, 
    msg: m1 
}, { 
    user: u2, 
    number: 2, 
    msg: m2 
}, { 
    user: u3, 
    number: 3, 
    msg: m3 
}, { 
    user: u2, 
    number: 4, 
    msg: m4 
}, { 
    user: u1, 
    number: 5, 
    msg: m5 
}] 

我想轉換此數組到二維數組,如下所示。請注意,嵌套陣列是由具有2環路基於「數量」字段

newResults = [{ 
    user: u1, 
    msg: [{nmsg: m1, number: 1}, {nmsg: m5, number: 5}] 
}, { 
    user: u2, 
    msg: [{nmsg: m2, number: 2 }, {nmsg: m4, number: 4}] 

}, { 
    user: u3, 
    msg: [{nmsg: m3, number 3}] 
}  
}] 

我能做到這一點排序,然而,2 for循環似乎低效的,因爲數組可以增長到非常大的尺寸。

有沒有辦法,可能是使用庫或直接從mongoDB中實現相同的結果?

此外,MongoDB中的結構非常簡單

{ 
user 
number 
msg 
} 

感謝

回答

0

可以使用MongoDB的aggregation做到這一點。您需要按號碼(使用$sort)按用戶分組,並生成按鍵共享相同組的數據數組(使用$group$push)。

db.collection.aggregate([ 
    { $sort: {number: 1}}, 
    {$group: { 
    _id: "$user", 
    msg: {$push: {nmsg: "$msg", number: "$number" }} 
    }} 
]) 

得到了數據這樣的結果:

{ 
    "_id" : "u1", 
    "msg" : [ 
      { 
        "nmsg" : "m1", 
        "number" : 1 
      }, 
      { 
        "nmsg" : "m5", 
        "number" : 5 
      } 
    ] 
} 
{ 
    "_id" : "u2", 
    "msg" : [ 
      { 
        "nmsg" : "m2", 
        "number" : 2 
      }, 
      { 
        "nmsg" : "m4", 
        "number" : 4 
      } 
    ] 
} 
{ "_id" : "u3", "msg" : [ { "nmsg" : "m3", "number" : 3 } ] } 
+0

感謝弗拉基米爾,我會盡量今晚,讓你知道。感謝您的快速響應。 – pkpk

+0

這個工程,我也認爲聚合可能是一個更好的解決方案相比,lodash解決方案。所有的處理和計算都將在Mongo服務器上,而不是在主服務器上,因爲記錄可能很大。 – pkpk

0

您可以使用lodash減少和訂購您的結果。我在下面的例子中使用了_.chain(),因爲它使代碼更具可讀性並且可以提高效率。

var results = [ 
 
    { user: 'u1', number: 1, msg: 'm1' }, 
 
    { user: 'u2', number: 2, msg: 'm2' }, 
 
    { user: 'u3', number: 3, msg: 'm3' }, 
 
    { user: 'u2', number: 4, msg: 'm4' }, 
 
    { user: 'u1', number: 5, msg: 'm5' } 
 
]; 
 

 
var reduced = _.chain(results) 
 
    .groupBy('user').toArray().map(function(record) { 
 
    return { 
 
     user : _.chain(record).head().get('user'), 
 
     msg : _.chain(record).map(function(data) { 
 
      return { nmsg: data.msg, number: data.number }; 
 
     }).sortBy('number') 
 
    } 
 
    }).sortBy('user').value(); 
 

 
var types = [ 
 
    { name : 'str', pattern : /("(?:\\.|[^"\\])*")/g }, 
 
    { name : 'num', pattern : /(\b[-+]?[0-9]*\.?[0-9]+\b)/g } 
 
] 
 
document.querySelector('code.javascript').innerHTML = types.reduce(function(code, type) { 
 
    return code.replace(type.pattern, '<span class="' + type.name + '">$1</span>') 
 
}, JSON.stringify(reduced, null, ' '))
code.javascript { 
 
    font-family: Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,sans-serif; 
 
    font-size: 12px; 
 
    white-space: pre; 
 
} 
 
code.javascript .str { color: #007F00; } 
 
code.javascript .num { color: #7F007F; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.0.0/lodash.min.js"></script> 
 
<code class="javascript"></code>

+0

解決方案有效,但我認爲使用下面的聚合方法來解決可伸縮性問題是個好主意。你怎麼看 ? – pkpk