2015-06-24 38 views
1

我的標籤列表,併爲每個標籤我要計數的文件(工種)的總數爲標籤。我應該怎麼做文檔的計數在每貓鼬相關文檔?

這正常工作與幾個標籤和幾個文件,但現在我有超過100個標籤和200個文件,所以查詢到每個標籤需要10-15秒,總之所有的文檔。

/** 
* Get tags 
*/ 
exports.list = function (req, res) { 
    Tag.find() 
     .execQ() 
     .then(function (tags) { 
      utils.tag.getJobCountByTags(tags, user) 
       .then(function(tagsWithCount){ 
        res.json(tagsWithCount); 
       }); 
     }) 
     .fail(function(err){ 
      res.send(err); 
     }); 
}; 


//utils.tag namespace 
tag.getJobCountByTags = function (tags, user){ 
    var queries = tags.map(function(tag){ 
     return getJobCountByTag(tag, user); 
    }); 

    return q.all(queries); 
}; 

function getJobCountByTag(tag, user){ 
    var Job = mongoose.model('Job'); 
    var whereData = {}; 
    var tagId = tag._id; 

    if (tag.type === 'skillTag') { 
     whereData.skillTags = tagId; 
    } else if (tag.type === 'roleTag') { 
     whereData.roleTags = tagId; 
    } 

    return Job 
     .find(whereData) 
     .execQ() 
     .then(function (jobs) { 
      tag._doc.count = jobs.length; 

      return tag; 
     }); 

} 

這是我能想出但其超慢查詢所有的標籤和每個標籤查詢所有標籤文檔的最佳。

編輯:這裏是工作模式...

/** 
* Job Schema 
*/ 
var JobSchema = new Schema({ 
    title: { type: String, required: true }, 
    location: { type: String, required: true }, 
    geoLocation: { type: [Number], index: '2d' }, 
    company: { type: String, required: true }, 
    description: { type: String, required: true }, 
    skillTags: [{ type: Schema.ObjectId, ref: 'Tag', index: true, required: true }], 
    roleTags: [{ type: Schema.ObjectId, ref: 'Tag', index: true, required: true }] 
}, { 
    toObject: { virtuals: true }, 
    toJSON: { virtuals: true } 
}); 
+0

我添加了作業模式。 – chovy

+0

我在下面提供了一個答案,但你的工作模式似乎並不具備'locationTags'字段中定義,因此聚集框架將具有該標籤類型的'count'爲0,如果'Job'模型沒有它。 – chridam

+0

謝謝我實際上還沒有使用位置標籤。 – chovy

回答

0

你可以嘗試聚合框架,以獲得期望的結果。以下聚合管道具有第一階段爲$uwnind操作員從輸入文檔解構陣列字段,以輸出爲每個元素的文檔。每個輸出文檔都是由元素替換的數組字段值的輸入文檔。然後,您可以使用$group操作員組的輸入文件由標籤類型標識符表達以前$uwnind管道和應用累加器表達$sum每個組得到計數:

function getJobCountByTag(tag){ 
    var Job = mongoose.model('Job', jobSchema);, 
     tagType = "$"+tag.type+"s", 
     pipeline = [ 
      { "$unwind": tagType }, 
      { 
       "$group": { 
        "_id": tagType, 
        "count": { "$sum": 1 } 
       } 
      } 
     ]; 

    return Job 
     .aggregate(pipeline) 
     .execQ() 
     .then(function (res) { 
      tag._doc.count = res.count; 

      return tag; 
     }); 
} 

,或者使用聚合管道建設者流利的API

function getJobCountByTag(tag){ 
    var Job = mongoose.model('Job'), 
     tagType = "$"+tag.type+"s", 

    return Job 
     .aggregate() 
     .unwind(tag.type+"s") 
     .group({ 
      "_id": tagType, 
      "count": { "$sum": 1 } 
     }) 
     .execQ() 
     .then(function (res) { 
      tag._doc.count = res.count; 

      return tag; 
     }); 
} 
+0

是否有可能把有條件進入工作崗位查詢?我只想獲得具有匹配標籤ID的職位。 – chovy