2016-06-28 50 views
1

我有一個集合MongoDB中與貓鼬架構如何分組和排序在蒙戈DB

var collection = new Schema({ 
    name : String, 
    position : Number, 
    category : String 
}); 

collection.index({ category : 1, position : 1 }, { unique : true }); 

現在我想在獲取記錄,從而

它應該組的所有對基礎記錄類別,然後在每個類別(組)中,所有記錄應根據位置進行排序。

例如

我有以下收集

[ 
    { name : 'Mr X', position : 34, category : 'U' }, 
    { name : 'Mr Y', position : 14, category : 'T' }, 
    { name : 'Mr G', position : 55, category : 'T' }, 
    { name : 'Mr I', position : 5, category : 'L' }, 
    { name : 'Mr D', position : 51, category : 'L' }, 
    { name : 'Mr P', position : 14, category : 'U' }, 
    { name : 'Mr P', position : 20, category : 'U' }, 
    { name : 'Mr E', position : 14, category : 'L' } 
] 

現在應該是什麼這個高效的查詢?

我想取第三批(2條記錄每批)

db.ask.aggregate([{ 
      $group : { 
       _id : "$category" 
      } 
     }, { 
      $sort : { 
       position : 1 
      } 
     }, { 
      $skip : 4 
     }, { 
      $limit : 2 
     } 
    ]) 

,我很期待輸出:

[ 
    { name : 'Mr G', position : 55, category : 'T' }, 
    { name : 'Mr P', position : 14, category : 'U' } 
] 

,但實際上越來越沒有。

如果獲取的所有記錄(不加任何批次),預期輸出應該

[ 
    { name : 'Mr I', position : 5, category : 'L' }, 
    { name : 'Mr E', position : 14, category : 'L' } 
    { name : 'Mr D', position : 51, category : 'L' }, 
    { name : 'Mr Y', position : 14, category : 'T' }, 
    { name : 'Mr G', position : 55, category : 'T' }, 
    { name : 'Mr P', position : 14, category : 'U' }, 
    { name : 'Mr P', position : 20, category : 'U' }, 
    { name : 'Mr X', position : 34, category : 'U' }, 
] 

編輯:我在尋找一個查詢是柔性的以我的不斷變化的需求。 如果我想帶第一類T然後L然後U.

所以我的預期輸出(有限制,並跳過)應該是

[ 
    { name : 'Mr I', position : 5, category : 'L' }, 
    { name : 'Mr P', position : 14, category : 'U' } 
] 

回答

0

據我理解你的要求,你不希望將不惜一切,但只是希望通過兩個字段進行排序和然後做更多或更少的某種分頁。
這就是說,通過以下聚合管道,我得到了您想要的結果。

db.ask.aggregate([ 
    { 
     $sort : { 
      category : 1, 
      position : 1 
     } 
    }, 
    { 
     $project : { 
      _id : 0, 
      category : 1, 
      position : 1, 
      name : 1 
     } 
    }, 
    { 
     $skip : 4 
    }, 
    { 
     $limit : 2 
    }, 
]) 
+0

如果要改變類別的順序,先T然後L然後U?看我的編輯請 – codeofnode

0

那麼,你需要對複合鍵進行分組以獲得所需的結果。

db.collection.aggregate([ 
{$group : { _id : {category:"$category", position:"$position", name:"$name"}}}, 
{$project:{_id:0, category:"$_id.category", name:"$_id.name", position:"$_id.position"}}, 
{$sort : {"category" : 1, position:1} }, 
{$skip : 4 }, 
{$limit : 2 } 
]) 

這將打印:

{ 
    "category" : "T", 
    "name" : "Mr G", 
    "position" : 55.0 
} 
{ 
    "category" : "U", 
    "name" : "Mr P", 
    "position" : 14.0 
} 
+0

如果想改變類別的順序,先T然後L然後U?請看我的編輯 – codeofnode

+0

好吧,繼續嘗試 – Saleem

0

沒有必要進行分組和其他聚合階段 只是排序在正確的領域

我們可以有normal查詢

db.codofoode.find() 
.sort({ 
    category : 1, 
    position : 1 
}).skip(4).limit(2) 

或聚合

db.codofoode.aggregate([ 
{ 
      $sort : { 
       category:1, position : 1 
      } 
     }, 

     { 
      $skip : 4 
     }, 
     { 
      $limit : 2 
     }]) 
+0

如果要改變類別的順序,先T然後L然後U?由於您預期結果按升序排列,所以請編輯 – codeofnode

+0

,我們按升序排序,然後結果集將通過請求的測試標準:-) – profesor79