2015-06-26 68 views
2

扁平化的數組字段我有一個模式:總結和MongoDB中

var ProjectSchema = new Schema({ 
    name: { 
     type: String, 
     default: '' 
    }, 
    topics: [{ 
     type: Schema.ObjectId, 
     ref: 'Topic' 
    }], 
    user: { 
     type: Schema.ObjectId, 
     ref: 'User' 
    } 
}); 

我想要做的就是與所有項目的所有主題的數組。我無法直接查詢主題並獲得完整列表,因爲某些主題未分配,並且它們也沒有爲項目保留引用(因爲避免了雙向引用)。所以我需要查詢項目並彙總一些方法。我正在做類似於:

Project.aggregate([{$project:{topics:1}}]); 

但是,這是給我一個與主題字段的項目對象的數組。我想要的是一個包含主題對象的數組。

我該怎麼做?

+0

請將樣品輸出 – karthick

回答

5

當您通常要使用的數組成員第一$unwind陣列處理,然後$group找到不同的條目:

Project.aggregate(
    [ 
     { "$unwind": "$topics" }, 
     { "$group": { "_id": "$topics._id" } } 
    ], 
    function(err,docs) { 

    } 
) 

但這種情況下,它可能是simplier只使用.distinct()它會做上述相同,但只是結果,而不是文件的數組:

Project.distinct("topics._id",function(err,topics) { 

}); 

但那裏等候一分鐘,因爲我知道你是真的在這裏問。這不是您想要的_id值,但是您的Topic數據具有「姓名」之類的屬性。

由於您的項目是「引用的」,而在另一個集合中,您不能對另一個集合中的文檔的屬性執行聚合管道或.distinct()操作。把基本上「MongoDB不執行聯接」和貓鼬.populate()不是一個聯接,只是「模擬」與附加查詢(ies)的東西。

但是,您當然可以從「項目」中找到「不同的」值,然後從「主題」中獲取信息。如:

Project.distinct("topics._id",function(err,topics) { 
    Topic.find({ "_id": { "$in": topics } },function(err,topics) { 

    }); 
}); 

這是很方便,因爲.distinct()功能已經返回數組適用於$in使用。

+1

謝謝您的詳細解答。它只要我寫了Project.distinct(「topics」,function(err,topicIDs){}); –

+0

@MikeM我不好,因爲我通常在腦中「嵌入」或寫作時。當然,引用數組的值只是數組中沒有子屬性的ObjectId值。 –