2012-08-07 102 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模块,该模块有一些支持,用于执行迭代,以在每个步骤调用异步代码并在所有异步代码完成时执行回调。