2016-12-17 62 views
0

我有一個具有子文檔的父模式。子文檔具有與嵌入的對象的陣列的屬性:在Mongoose中跳過一個嵌套級別的子文檔

兒童模式

var snippetSchema = new Schema({ 
    snippet: [ 
     { 
      language: String, 
      text: String, 
      _id: false 
     } 
    ] 
}); 

父模式

var itemSchema = new Schema({ 
    lsin: Number, 
    identifier: { 
     isbn13: Number, 
    }, 
    title: snippetSchema, 
}); 

其在Item.find返回類似的對象,以便:

[ 
    { 
     _id: (...), 
     lsin: 676765, 
     identifier: { 
      isbn13: 8797734598763 
     }, 
     title: { 
      _id: (...), 
      snippet: [ 
       { 
        language: 'se', 
        text: 'Pippi Långstrump' 
       } 
      ] 
     } 
    } 
] 

我想跳過子文檔的一層嵌套當對象被返回給客戶端:使用一個getter

function getter() { 
    return this.title.snippet[0]; 
} 

var itemSchema = new Schema({ 
    ... 
    title: { type: snippetSchema, get: getter } 
}); 

#1:

[ 
    { 
     _id: (...), 
     lsin: 676765, 
     identifier: { 
      isbn13: 8797734598763 
     }, 
     title: { 
      language: 'se', 
      text: 'Pippi Långstrump' 
     } 
    } 
] 

到目前爲止,我已經嘗試

但它創建了一個無限循環導致RangeError: Maximum call stack size exceeded

#2使用虛擬屬性

var itemSchema = new Schema({ 
    ..., { 
    toObject: { 
     virtuals: true 
    } 
}); 

itemSchema 
    .virtual('title2') 
    .get(function() { 
     return this.title.snippet[0]; 
}); 

這將產生所期望的嵌套級別,但下一個新的屬性,這是不能接受的。據我所知,沒有辦法覆蓋具有虛擬屬性的屬性。

現在的問題是:有沒有其他的方式去獲得所需的輸出?在整個應用程序中將會有幾處對snippetSchema的引用,並且DRY方法是首選。

我是MongoDB和Mongoose的新手。

回答

1

您需要在mongodb聚合管道中使用$project

在我的數據庫中,我有以下幾點:

> db.items.find().pretty() 
{ 
     "_id" : 123, 
     "lsin" : 676765, 
     "identifier" : { 
       "isbn13" : 8797734598763 
     }, 
     "title" : { 
       "_id" : 456, 
       "snippet" : [ 
         { 
           "language" : "se", 
           "text" : "Pippi Långstrump" 
         } 
       ] 
     } 
} 

然後,我們只需要創建一個簡單的彙總查詢:

db.items.aggregate([ 
    {$project: { lsin: 1, identifier: 1, title: { $arrayElemAt: [ '$title.snippet', 0 ] }}} 
]) 

這只是使用$項目(https://docs.mongodb.com/v3.2/reference/operator/aggregation/project/)和$ arrayElemAt (https://docs.mongodb.com/v3.2/reference/operator/aggregation/arrayElemAt/)將第一項投影出陣列。如果我們執行,我們將得到以下內容:

{ 
     "_id" : 123, 
     "lsin" : 676765, 
     "identifier" : { 
       "isbn13" : 8797734598763 
     }, 
     "title" : { 
       "language" : "se", 
       "text" : "Pippi Långstrump" 
     } 
} 
+0

乾淨,簡單。沒有找到來自Mongoose API的聚合文檔的很多文檔,這就是爲什麼我無法找到解決方案,但現在正在閱讀MongoDB文檔。我應該如何管理數據庫寫入?寧願爲GET和POST使用相同的JSON。 – unitario

+0

大多數語言驅動程序都將類似的設置複製到標準的JavaScript shell命令中。這是完全正確的,因爲你使用不同的JSON來投影你寫的東西,當你寫回數據庫時,你應該考慮使用更新運算符,比如'$ set','$ inc'等等...... –