2012-08-07 138 views
0

我有一個標籤集合,他們只有一個值是標籤。它們可以是隨機的標籤或樹標籤(這裏沒有_id樣本):與快速/貓鼬嵌套查詢

{ 
    "label": "/test1" 
} 
{ 
    "label": "/test2" 
} 
{ 
    "label": "/test1/test1-1" 
} 
{ 
    "label": "/test2/test2-1" 
} 
{ 
    "label": "/test1/test1-1/test1-1-1" 
} 
{ 
    "label": "something" 
} 

我要的是有我的標籤的樹中的單個對象:

{ 
    "/test1": { 
     "name": "test1" 
     , "children": { 
      "/test1/test1-1" : { 
       "name": "test1-1" 
       , "children": { 
        "/test1/test1-1/test1-1-1" : { 
         "name": "test1-1-1" 
         , "children": {} 
        } 
       } 
      } 
     } 
    } 
    , "/test2": { 
     "name": "test2" 
     , "children": { 
      "/test2/test1-2" : { 
       "name": "test1-2" 
       , "children": {} 
      } 
     } 
    } 
} 

這裏我在我的應用程序的嘗試:

app.get('/tree', function(req, res, next) { 
    var tree = {}; 
    Tag 
    // If you have a better solution, I'm not really fan of this 
    .$where('this.label.split(new RegExp("/")).length === 2') 
    .exec(function(err, tags) { 
     tags.forEach(function(tag) { 
      tag.getChildren(function(children) { 
       tree[tag.label] = { 
        'title': tag.label 
        , 'children': children 
       } 
      }); 
     }); 
    }); 
    // do some stuff with the `tree` var 
    // which does not work because of the asynchronousity of mongo 
}); 

而且在我的模型我有,這是行不通的,一開始我想用tag.getChildren()回到樹的路徑,但後來,我想到了一個回調將是一個更好的選擇,我停在那裏。

Tag.methods.getChildren = function(callback) { 
    var tree = {}; 
    Tag 
    .$where('this.label.split(new RegExp("' + this.label + '/")).length === 2') 
    .exec(function(err, tags) { 
     tags.forEach(function(tag) { 
      tag.getChildren(function(children) { 
       tree[tag.label] = { 
        'title': tag.label 
        , 'children': children 
       } 
      }); 
     }); 
     return tree 
    }); 
}; 

我不知道如何應對這個問題,我是相當新的節點和異步編程,因此任何幫助將升值。

回答

1

做多蒙戈請求在這個例子愚蠢的,所以我也只有一個,解析結果,並創建我的樹,這裏是我的代碼,如果有人有同樣的問題:

app.get('/tree', function(req, res, next) { 
    var tree = {} 
    Tag 
    .find({ label: { $regex: /^\// } }, ['label']) 
    // Skip the "/" 
    .skip(1) 
    .exec(function(err, tags) { 
     tags.forEach(function(tag) { 
      var split = tag.label.split('/'); 
      // Root 
      if (split.length === 2) { 
       tree[_.slugify(split[1])] = { 
        title: split[1] 
        , children: {} 
       } 
      } else { 
       var name = split.pop() 
        , path = tag.label 
        , pathSlug = _.slugify(path.replace(/\//g, '-')) 
        , parentPath = path.split('/') 
        , parentSlug = '' 
        , parent; 
       parentPath.shift(); 
       parentPath.pop(); 
       parentPath.forEach(function(step) { 
        step = parentSlug ? parentSlug + '-' + _.slugify(step) : _.slugify(step); 
        parentSlug = step; 
        parent = parent ? parent.children[step] : tree[step]; 
       }); 
       if (!parent) { 
console.error('ERROR :') 
console.log(tag.label) 
console.log(path.split('/')) 
console.log(name) 
console.error('##################') 
       } else { 
        parent.children[pathSlug] = { 
         title: name 
         , children: {} 
        } 
       } 
      } 
     }); 
     res.send(tree, 200); 
    }); 
}); 
1

您可能應該查看一下async.js模塊,該模塊有一些支持,用於執行迭代,以在每個步驟調用異步代碼並在所有異步代碼完成時執行回調。